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

Reply via email to