Hi,

attached patch implement caching converted image produced by pango producer.

--
________________________________________
Maksym Veremeyenko
>From 4a330251059ec781ce296f145980e33b08a37e44 Mon Sep 17 00:00:00 2001
From: Maksym Veremeyenko <ve...@m1.tv>
Date: Thu, 29 Jan 2015 19:40:00 +0200
Subject: [PATCH 7/7] implement caching converted image for producer pango

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

diff --git a/src/modules/gtk2/producer_pango.c b/src/modules/gtk2/producer_pango.c
index 669d9be..00c8034 100644
--- a/src/modules/gtk2/producer_pango.c
+++ b/src/modules/gtk2/producer_pango.c
@@ -59,8 +59,24 @@ struct producer_pango_s
 	int   size;
 	int   style;
 	int   weight;
+	struct
+	{
+		uint8_t *image, *alpha;
+		mlt_image_format format;
+		int width, height;
+	} cached;
 };
 
+static void clean_cached( producer_pango self )
+{
+	if ( self->cached.image )
+		mlt_pool_release( self->cached.image );
+	self->cached.image = NULL;
+	if ( self->cached.alpha )
+		mlt_pool_release( self->cached.alpha );
+	self->cached.alpha = NULL;
+}
+
 // special color type used by internal pango routines
 typedef struct
 {
@@ -425,6 +441,7 @@ static void refresh_image( mlt_frame frame, int width, int height )
 		if ( this->pixbuf )
 			g_object_unref( this->pixbuf );
 		this->pixbuf = NULL;
+		clean_cached( this );
 
 		// Convert from specified encoding to UTF-8
 		if ( encoding != NULL && !strncaseeq( encoding, "utf-8", 5 ) && !strncaseeq( encoding, "utf8", 4 ) )
@@ -464,6 +481,7 @@ static void refresh_image( mlt_frame frame, int width, int height )
 		if ( this->pixbuf )
 			g_object_unref( this->pixbuf );
 		this->pixbuf = NULL;
+		clean_cached( this );
 		pixbuf = mlt_properties_get_data( producer_props, "pixbuf", NULL );
 	}
 
@@ -484,6 +502,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_cached( this );
 
 		// Store width and height
 		this->width = width;
@@ -515,18 +534,92 @@ 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 = mlt_image_rgb24a;
 
 	// 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, bpp;
+		uint8_t *image, *alpha;
+
+		// destroy cached data if request is differ
+		if ( this->cached.format != *format || this->cached.width != *width || this->cached.height != *height )
+			clean_cached( this );
+
+		// create cached image
+		if ( !this->cached.image )
+		{
+			int dst_stride, src_stride;
+
+			this->cached.width = this->width;
+			this->cached.height = this->height;
+			this->cached.format = gdk_pixbuf_get_has_alpha( this->pixbuf ) ? mlt_image_rgb24a : mlt_image_rgb24;
 
-		// Now update properties so we free the copy after
-		mlt_frame_set_image( frame, *buffer, image_size, mlt_pool_release );
+			src_stride = gdk_pixbuf_get_rowstride( this->pixbuf );
+			dst_stride = this->width * ( mlt_image_rgb24a == this->cached.format ? 4 : 3 );
+
+			size = dst_stride * ( this->height + 1 );
+			image = mlt_pool_alloc( size );
+
+			if ( src_stride != dst_stride )
+			{
+				int y = this->height;
+				uint8_t *src = gdk_pixbuf_get_pixels( this->pixbuf );
+				uint8_t *dst = image;
+				while ( y-- )
+				{
+					memcpy( dst, src, dst_stride );
+					dst += dst_stride;
+					src += src_stride;
+				}
+			}
+			else
+			{
+				memcpy( image, gdk_pixbuf_get_pixels( this->pixbuf ), src_stride * this->height );
+			}
+
+			// First, set the image so it can be converted when we get it
+			mlt_frame_replace_image( frame, image, this->cached.format, this->cached.width, this->cached.height );
+			mlt_frame_set_image( frame, image, size, mlt_pool_release );
+
+			// convert
+			mlt_frame_get_image( frame, &image, format, &this->cached.width, &this->cached.height, 0 );
+			this->cached.format = *format;
+
+			// cache copies of the image and alpha buffers
+			if ( image )
+			{
+				size = mlt_image_format_size( this->cached.format, this->cached.width, this->cached.height, NULL );
+				this->cached.image = mlt_pool_alloc( size );
+				memcpy( this->cached.image, image, size );
+			}
+			if ( ( image = mlt_frame_get_alpha_mask_nc( frame ) ) )
+			{
+				size = this->cached.width * this->cached.height;
+				this->cached.alpha = mlt_pool_alloc( size );
+				memcpy( this->cached.alpha, image, size );
+			}
+		}
+		else
+		{
+			// clone image surface
+			size = mlt_image_format_size(this->cached.format, this->cached.width, this->cached.height, &bpp );
+			image = mlt_pool_alloc( size );
+			memcpy( image, this->cached.image, size );
+
+			// set image surface
+			mlt_frame_set_image( frame, image, size, mlt_pool_release );
+			*buffer = image;
+
+			// set alpha
+			if ( this->cached.alpha )
+			{
+				size = this->cached.width * this->cached.height;
+				alpha = mlt_pool_alloc( size );
+				memcpy( alpha, this->cached.alpha, size );
+				mlt_frame_set_alpha( frame, alpha, size, mlt_pool_release );
+			}
+		};
 	}
 	else
 	{
@@ -593,6 +686,7 @@ static void producer_close( mlt_producer parent )
 	free( this->text );
 	free( this->font );
 	free( this->family );
+	clean_cached( this );
 	parent->close = NULL;
 	mlt_producer_close( parent );
 	free( this );
-- 
1.7.7.6

------------------------------------------------------------------------------
Dive into the World of Parallel Programming. The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Mlt-devel mailing list
Mlt-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mlt-devel

Reply via email to