15.02.12 20:49, Dan Dennedy написав(ла):
[...]
In the pixbuf patch, you should not call the convert_image virtual
function directly; use mlt_frame_get_image().
use mlt_frame_get_image for converting image did not work - call to that function return blank frame...

i updated patch and added the same functionality to pango producer, but calling convert_image virtual function directly left till i find another way to convert it...

--
________________________________________
Maksym Veremeyenko
>From 061535dd2d7675cbb7596f3be0ff4a7c1fc272ac Mon Sep 17 00:00:00 2001
From: Maksym Veremeyenko <ve...@m1stereo.tv>
Date: Fri, 17 Feb 2012 16:17:32 +0200
Subject: [PATCH 1/2] save converted frame of pixbuf producer

---
 src/modules/gtk2/producer_pixbuf.c |   74 +++++++++++++++++++++++++++++++-----
 1 files changed, 64 insertions(+), 10 deletions(-)

diff --git a/src/modules/gtk2/producer_pixbuf.c b/src/modules/gtk2/producer_pixbuf.c
index b7da50b..3adce16 100644
--- a/src/modules/gtk2/producer_pixbuf.c
+++ b/src/modules/gtk2/producer_pixbuf.c
@@ -59,8 +59,24 @@ struct producer_pixbuf_s
 	uint8_t *image;
 	mlt_cache_item image_cache;
 	pthread_mutex_t mutex;
+	struct
+	{
+		uint8_t *image, *alpha;
+		int image_size, alpha_size;
+		mlt_image_format format;
+	} clone;
 };
 
+static void clean_clone( producer_pixbuf self )
+{
+	if ( self->clone.image )
+		mlt_pool_release( self->clone.image );
+	self->clone.image = NULL;
+	if ( self->clone.alpha )
+		mlt_pool_release( self->clone.alpha );
+	self->clone.alpha = NULL;
+}
+
 static void load_filenames( producer_pixbuf self, mlt_properties producer_properties );
 static void refresh_image( producer_pixbuf self, mlt_frame frame, int width, int height );
 static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int index );
@@ -391,6 +407,7 @@ static void refresh_image( producer_pixbuf self, mlt_frame frame, int width, int
 		int dst_stride = self->width * ( self->alpha ? 4 : 3 );
 		int image_size = dst_stride * ( height + 1 );
 		self->image = mlt_pool_alloc( image_size );
+		clean_clone( self );
 
 		if ( src_stride != dst_stride )
 		{
@@ -454,7 +471,8 @@ static void refresh_image( producer_pixbuf self, mlt_frame frame, int width, int
 static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable )
 {
 	int error = 0;
-	
+	mlt_image_format format_origin;
+
 	// Obtain properties of frame
 	mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
 
@@ -472,20 +490,55 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
 	// Get width and height (may have changed during the refresh)
 	*width = self->width;
 	*height = self->height;
-	*format = self->alpha ? mlt_image_rgb24a : mlt_image_rgb24;
+	format_origin = self->alpha ? mlt_image_rgb24a : mlt_image_rgb24;
+	if ( mlt_image_none == *format)
+		*format = format_origin;
 
 	// NB: Cloning is necessary with this producer (due to processing of images ahead of use)
 	// The fault is not in the design of mlt, but in the implementation of the pixbuf producer...
 	if ( self->image )
 	{
-		// Clone the image
-		int image_size = self->width * self->height * ( self->alpha ? 4 :3 );
-		uint8_t *image_copy = mlt_pool_alloc( image_size );
-		memcpy( image_copy, self->image, image_size );
-		// Now update properties so we free the copy after
-		mlt_frame_set_image( frame, image_copy, image_size, mlt_pool_release );
-		// We're going to pass the copy on
-		*buffer = image_copy;
+		int size;
+		uint8_t* image;
+
+		if ( self->clone.image && self->clone.format == *format)
+		{
+			image = mlt_pool_alloc( self->clone.image_size );
+			memcpy( image, self->clone.image, self->clone.image_size );
+			mlt_frame_set_image( frame, image, self->clone.image_size, mlt_pool_release );
+			*buffer = image;
+			if ( self->clone.alpha )
+			{
+				image = mlt_pool_alloc( self->clone.alpha_size );
+				memcpy( image, self->clone.alpha, self->clone.alpha_size );
+				mlt_frame_set_alpha( frame, image, self->clone.alpha_size, mlt_pool_release );
+			};
+		}
+		else
+		{
+			clean_clone( self );
+			size = self->width * self->height * ( self->alpha ? 4 :3 );
+			image = mlt_pool_alloc( size );
+			memcpy( image, self->image, size );
+			if(frame->convert_image && format_origin != *format)
+			{
+				frame->convert_image( frame, &image, &format_origin, *format );
+				*format = format_origin;
+			}
+			mlt_frame_set_image( frame, image, size, mlt_pool_release );
+			*buffer = image;
+			self->clone.format = *format;
+			self->clone.image_size = mlt_image_format_size( *format, *width, *height, NULL );
+			self->clone.image = mlt_pool_alloc( self->clone.image_size );
+			memcpy(self->clone.image, image, self->clone.image_size);
+			image = mlt_frame_get_alpha_mask(frame);
+			if ( image )
+			{
+				self->clone.alpha_size = (*width) * (*height);
+				self->clone.alpha = mlt_pool_alloc( self->clone.alpha_size );
+				memcpy(self->clone.alpha, image, self->clone.alpha_size);
+			};
+		}
 		mlt_log_debug( MLT_PRODUCER_SERVICE( &self->parent ), "%dx%d (%s)\n",
 			self->width, self->height, mlt_image_format_name( *format ) );
 	}
@@ -555,6 +608,7 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
 static void producer_close( mlt_producer parent )
 {
 	producer_pixbuf self = parent->child;
+	clean_clone( self );
 	pthread_mutex_destroy( &self->mutex );
 	parent->close = NULL;
 	mlt_service_cache_purge( MLT_PRODUCER_SERVICE(parent) );
-- 
1.7.7.6

>From 47dc4d7d2e085bdf153cbccc9adad1c4e7578293 Mon Sep 17 00:00:00 2001
From: Maksym Veremeyenko <ve...@m1stereo.tv>
Date: Fri, 17 Feb 2012 16:17:42 +0200
Subject: [PATCH 2/2] save converted frame of pango producer

---
 src/modules/gtk2/producer_pango.c |   69 +++++++++++++++++++++++++++++++++----
 1 files changed, 62 insertions(+), 7 deletions(-)

diff --git a/src/modules/gtk2/producer_pango.c b/src/modules/gtk2/producer_pango.c
index ef4985c..12ee4cb 100644
--- a/src/modules/gtk2/producer_pango.c
+++ b/src/modules/gtk2/producer_pango.c
@@ -60,8 +60,24 @@ struct producer_pango_s
 	int   size;
 	int   style;
 	int   weight;
+	struct
+	{
+		uint8_t *image, *alpha;
+		int image_size, alpha_size;
+		mlt_image_format format;
+	} clone;
 };
 
+static void clean_clone( producer_pango self )
+{
+	if ( self->clone.image )
+		mlt_pool_release( self->clone.image );
+	self->clone.image = NULL;
+	if ( self->clone.alpha )
+		mlt_pool_release( self->clone.alpha );
+	self->clone.alpha = NULL;
+}
+
 // special color type used by internal pango routines
 typedef struct
 {
@@ -475,6 +491,7 @@ static void refresh_image( mlt_frame frame, int width, int height )
 
 		// Note - the original pixbuf is already safe and ready for destruction
 		this->pixbuf = gdk_pixbuf_scale_simple( pixbuf, width, height, interp );
+		clean_clone( this );
 
 		// Store width and height
 		this->width = width;
@@ -492,6 +509,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
 {
 	int error = 0;
 	producer_pango this = ( producer_pango ) mlt_frame_pop_service( frame );
+	mlt_image_format format_origin;
 
 	// Obtain properties of frame
 	mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
@@ -508,18 +526,54 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
 	// Get width and height
 	*width = this->width;
 	*height = this->height;
-	*format = mlt_image_rgb24a;
+	format_origin = mlt_image_rgb24a;
+	if ( mlt_image_none == *format)
+		*format = format_origin;
 
 	// Always clone here to allow 'animated' text
 	if ( this->pixbuf )
 	{
-		// Clone the image
-		int image_size = this->width * this->height * 4;
-		*buffer = mlt_pool_alloc( image_size );
-		memcpy( *buffer, gdk_pixbuf_get_pixels( this->pixbuf ), image_size );
+		int size;
+		uint8_t* image;
 
-		// Now update properties so we free the copy after
-		mlt_frame_set_image( frame, *buffer, image_size, mlt_pool_release );
+		if ( this->clone.image && this->clone.format == *format)
+		{
+			image = mlt_pool_alloc( this->clone.image_size );
+			memcpy( image, this->clone.image, this->clone.image_size );
+			mlt_frame_set_image( frame, image, this->clone.image_size, mlt_pool_release );
+			*buffer = image;
+			if ( this->clone.alpha )
+			{
+				image = mlt_pool_alloc( this->clone.alpha_size );
+				memcpy( image, this->clone.alpha, this->clone.alpha_size );
+				mlt_frame_set_alpha( frame, image, this->clone.alpha_size, mlt_pool_release );
+			};
+		}
+		else
+		{
+			clean_clone( this );
+			size = this->width * this->height * 4;
+			image = mlt_pool_alloc( size );
+			memcpy( image, gdk_pixbuf_get_pixels( this->pixbuf ), size );
+			if(frame->convert_image && format_origin != *format)
+			{
+				frame->convert_image( frame, &image, &format_origin, *format );
+				*format = format_origin;
+			}
+			mlt_frame_set_image( frame, image, size, mlt_pool_release );
+			*buffer = image;
+			this->clone.format = *format;
+			this->clone.image_size = mlt_image_format_size( *format, *width, *height, NULL );
+			this->clone.image = mlt_pool_alloc( this->clone.image_size );
+			memcpy(this->clone.image, image, this->clone.image_size);
+			image = mlt_frame_get_alpha_mask(frame);
+			if ( image )
+			{
+				this->clone.alpha_size = (*width) * (*height);
+				this->clone.alpha = mlt_pool_alloc( this->clone.alpha_size );
+				memcpy(this->clone.alpha, image, this->clone.alpha_size);
+			};
+		}
 	}
 	else
 	{
@@ -587,6 +641,7 @@ static void producer_close( mlt_producer parent )
 	free( this->text );
 	free( this->font );
 	free( this->family );
+	clean_clone( this );
 	parent->close = NULL;
 	mlt_producer_close( parent );
 	free( this );
-- 
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