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...

--
________________________________________
Maksym Veremeyenko

>From 7efb254ffa82b34d289cf7a0bb574be061541259 Mon Sep 17 00:00:00 2001
From: Maksym Veremeyenko <ve...@m1stereo.tv>
Date: Thu, 16 Feb 2012 17:44:40 +0200
Subject: [PATCH 1/2] alpha extracting from planar formats

---
 src/modules/avformat/producer_avformat.c |   36 +++++++++++++++++++++++------
 1 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/src/modules/avformat/producer_avformat.c b/src/modules/avformat/producer_avformat.c
index 87b87af..8938fa4 100644
--- a/src/modules/avformat/producer_avformat.c
+++ b/src/modules/avformat/producer_avformat.c
@@ -1243,7 +1243,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 +1256,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,6 +1403,8 @@ 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();
@@ -1464,7 +1481,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 +1511,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 +1706,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 +1723,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;
@@ -1749,12 +1765,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 +1802,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;
 }
 
-- 
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