16.02.12 18:56, Dan Dennedy написав(ла):
2012/2/16 Maksym Veremeyenko<ve...@m1stereo.tv>:
02.02.12 19:03, Maksym Veremeyenko написав(ла):
Hi,
i am trying to decrease cpu usage, so i would like to use
PIX_FMT_YUVA420P animation instead of PIX_FMT_BGRA (or other rgb with
alpha channel) but has no luck..
video with such pixel format in *nut* container has detected by ffmpeg
properly, but mlt did not use it alpha channel.
i can provide a sample if required...
alpha been ignored for PIX_FMT_YUVA420P and PIX_FMT_YUVA444P pixel format.
moreover current implementation of libswscale drop alpha channel if
destination format has no alpha and not planar (even if buffer specified)
attached patch extract alpha plane during image decoding. it works almost
fine except moments when image fetched from cache (even if *noimagecache*
specified). another problem is artifact that appear if last frame in movie
is not transparent but producer specifies *out* out of animation.
another attempt to fix this was to fix mlt_frame_clone (patch attached) but
it has no luck too...
OK, thank you for the start of this effort. I will look at it this weekend.
attached updated version that works with cache.
second patch is optional but could be usefull if frame with alpha been
cloned.
--
________________________________________
Maksym Veremeyenko
>From d13a842181a9bc55c40b84af9c385ddbd0965987 Mon Sep 17 00:00:00 2001
From: Maksym Veremeyenko <ve...@m1stereo.tv>
Date: Fri, 17 Feb 2012 12:01:40 +0200
Subject: [PATCH] alpha extracting from planar formats
---
src/modules/avformat/producer_avformat.c | 59 ++++++++++++++++++++++++++----
1 files changed, 51 insertions(+), 8 deletions(-)
diff --git a/src/modules/avformat/producer_avformat.c b/src/modules/avformat/producer_avformat.c
index 87b87af..f58e287 100644
--- a/src/modules/avformat/producer_avformat.c
+++ b/src/modules/avformat/producer_avformat.c
@@ -115,6 +115,7 @@ struct producer_avformat_s
unsigned int invalid_pts_counter;
double resample_factor;
mlt_cache image_cache;
+ mlt_cache alpha_cache;
int colorspace;
pthread_mutex_t video_mutex;
pthread_mutex_t audio_mutex;
@@ -1243,7 +1244,7 @@ static mlt_image_format pick_format( enum PixelFormat pix_fmt )
}
static void convert_image( AVFrame *frame, uint8_t *buffer, int pix_fmt,
- mlt_image_format *format, int width, int height, int colorspace )
+ mlt_image_format *format, int width, int height, int colorspace, uint8_t **alpha )
{
#ifdef SWSCALE
int full_range = -1;
@@ -1256,6 +1257,21 @@ static void convert_image( AVFrame *frame, uint8_t *buffer, int pix_fmt,
flags |= SWS_CPU_CAPS_MMX2;
#endif
+ /* extract alpha from planar formats */
+ if ( ( pix_fmt == PIX_FMT_YUVA420P || pix_fmt == PIX_FMT_YUVA444P ) &&
+ *format != mlt_image_rgb24a && *format != mlt_image_opengl &&
+ frame->data[3] && frame->linesize[3] )
+ {
+ int i;
+ uint8_t *src, *dst;
+
+ dst = *alpha = mlt_pool_alloc( width * height );
+ src = frame->data[3];
+
+ for(i = 0; i < height; dst += width, src += frame->linesize[3], i++)
+ memcpy(dst, src, FFMIN(width, frame->linesize[3]));
+ }
+
if ( *format == mlt_image_yuv420p )
{
struct SwsContext *context = sws_getContext( width, height, pix_fmt,
@@ -1388,9 +1404,14 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
// Get codec context
AVCodecContext *codec_context = stream->codec;
+ uint8_t *alpha = NULL;
+
// Get the image cache
if ( ! self->image_cache && ! mlt_properties_get_int( properties, "noimagecache" ) )
+ {
self->image_cache = mlt_cache_init();
+ self->alpha_cache = mlt_cache_init();
+ }
if ( self->image_cache )
{
mlt_cache_item item = mlt_cache_get( self->image_cache, (void*) position );
@@ -1422,6 +1443,16 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
}
self->got_picture = 1;
+ /* check for alpha */
+ item = mlt_cache_get( self->alpha_cache, (void*) position );
+ original = mlt_cache_item_data( item, &size );
+ if( original )
+ {
+ alpha = mlt_pool_alloc( size );
+ memcpy( alpha, original, size );
+ mlt_cache_item_close( item );
+ }
+
goto exit_get_image;
}
}
@@ -1464,7 +1495,6 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
context = self->video_format;
stream = context->streams[ self->video_index ];
codec_context = stream->codec;
-
if ( *format == mlt_image_none ||
codec_context->pix_fmt == PIX_FMT_ARGB ||
codec_context->pix_fmt == PIX_FMT_RGBA ||
@@ -1495,12 +1525,12 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
picture.linesize[1] = codec_context->width / 2;
picture.linesize[2] = codec_context->width / 2;
convert_image( (AVFrame*) &picture, *buffer,
- PIX_FMT_YUV420P, format, *width, *height, self->colorspace );
+ PIX_FMT_YUV420P, format, *width, *height, self->colorspace, &alpha );
}
else
#endif
convert_image( self->av_frame, *buffer, codec_context->pix_fmt,
- format, *width, *height, self->colorspace );
+ format, *width, *height, self->colorspace, &alpha );
}
else
mlt_frame_get_image( frame, buffer, format, width, height, writable );
@@ -1690,7 +1720,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
if ( status == VDP_STATUS_OK )
{
convert_image( self->av_frame, *buffer, PIX_FMT_YUV420P,
- format, *width, *height, self->colorspace );
+ format, *width, *height, self->colorspace, &alpha );
}
else
{
@@ -1707,7 +1737,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
else
#endif
convert_image( self->av_frame, *buffer, codec_context->pix_fmt,
- format, *width, *height, self->colorspace );
+ format, *width, *height, self->colorspace, &alpha );
self->top_field_first |= self->av_frame->top_field_first;
self->current_position = int_position;
self->got_picture = 1;
@@ -1728,6 +1758,13 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
uint8_t *image = mlt_pool_alloc( image_size );
memcpy( image, *buffer, image_size );
mlt_cache_put( self->image_cache, (void*) position, image, *format, mlt_pool_release );
+ if( alpha )
+ {
+ int alpha_size = (*width) * (*height);
+ image = mlt_pool_alloc( alpha_size );
+ memcpy( image, alpha, alpha_size );
+ mlt_cache_put( self->alpha_cache, (void*) position, image, alpha_size, mlt_pool_release );
+ }
}
// Try to duplicate last image if there was a decoding failure
else if ( !image_size && self->av_frame && self->av_frame->linesize[0] )
@@ -1749,12 +1786,12 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
picture.linesize[1] = codec_context->width / 2;
picture.linesize[2] = codec_context->width / 2;
convert_image( (AVFrame*) &picture, *buffer,
- PIX_FMT_YUV420P, format, *width, *height, self->colorspace );
+ PIX_FMT_YUV420P, format, *width, *height, self->colorspace, &alpha );
}
else
#endif
convert_image( self->av_frame, *buffer, codec_context->pix_fmt,
- format, *width, *height, self->colorspace );
+ format, *width, *height, self->colorspace, &alpha );
self->got_picture = 1;
}
else
@@ -1786,6 +1823,10 @@ exit_get_image:
mlt_properties_set_int( properties, "meta.media.progressive", mlt_properties_get_int( frame_properties, "progressive" ) );
mlt_service_unlock( MLT_PRODUCER_SERVICE( producer ) );
+ // set alpha
+ if ( alpha )
+ mlt_frame_set_alpha( frame, alpha, (*width) * (*height), mlt_pool_release );
+
return !self->got_picture;
}
@@ -2725,6 +2766,8 @@ static void producer_avformat_close( producer_avformat self )
#endif
if ( self->image_cache )
mlt_cache_close( self->image_cache );
+ if ( self->alpha_cache )
+ mlt_cache_close( self->alpha_cache );
// Cleanup the mutexes
pthread_mutex_destroy( &self->audio_mutex );
--
1.7.7.6
>From d9c8b56c155b1b24f9998ed7728afe2a39db554d Mon Sep 17 00:00:00 2001
From: Maksym Veremeyenko <ve...@m1stereo.tv>
Date: Thu, 16 Feb 2012 17:45:22 +0200
Subject: [PATCH 2/2] clone alpha on whan cloning image
---
src/framework/mlt_frame.c | 13 +++++++++++++
1 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/src/framework/mlt_frame.c b/src/framework/mlt_frame.c
index d08c5cb..90b3214 100644
--- a/src/framework/mlt_frame.c
+++ b/src/framework/mlt_frame.c
@@ -1033,6 +1033,17 @@ mlt_frame mlt_frame_clone( mlt_frame self, int is_deep )
copy = mlt_pool_alloc( size );
memcpy( copy, data, size );
mlt_properties_set_data( new_props, "image", copy, size, mlt_pool_release, NULL );
+
+ data = mlt_properties_get_data( properties, "alpha", &size );
+ if ( data )
+ {
+ if ( ! size )
+ size = mlt_properties_get_int( properties, "width" ) *
+ mlt_properties_get_int( properties, "height" );
+ copy = mlt_pool_alloc( size );
+ memcpy( copy, data, size );
+ mlt_properties_set_data( new_props, "alpha", copy, size, mlt_pool_release, NULL );
+ };
}
}
else
@@ -1047,6 +1058,8 @@ mlt_frame mlt_frame_clone( mlt_frame self, int is_deep )
mlt_properties_set_data( new_props, "audio", data, size, NULL, NULL );
data = mlt_properties_get_data( properties, "image", &size );
mlt_properties_set_data( new_props, "image", data, size, NULL, NULL );
+ data = mlt_properties_get_data( properties, "alpha", &size );
+ mlt_properties_set_data( new_props, "alpha", data, size, NULL, NULL );
}
return new_frame;
--
1.7.7.6
------------------------------------------------------------------------------
Virtualization & Cloud Management Using Capacity Planning
Cloud computing makes use of virtualization - but cloud computing
also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/
_______________________________________________
Mlt-devel mailing list
Mlt-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mlt-devel