From: lilo_booter Date: Sat, 7 Feb 2004 13:09:44 +0000 (+0000) Subject: pango producer rework X-Git-Url: http://research.m1stereo.tv/gitweb?a=commitdiff_plain;h=36bac6f151e7e97a3caa2ec9169df7e97190b1e3;p=melted pango producer rework git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@122 d19143bc-622f-0410-bfdd-b5b2a6649095 --- diff --git a/src/modules/gtk2/producer_pango.c b/src/modules/gtk2/producer_pango.c index 7f842e4..1b30743 100644 --- a/src/modules/gtk2/producer_pango.c +++ b/src/modules/gtk2/producer_pango.c @@ -130,62 +130,23 @@ mlt_producer producer_pango_init( const char *filename ) return NULL; } -static int producer_get_image( mlt_frame this, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) +static void refresh_image( mlt_frame frame, int width, int height ) { - // Obtain properties of frame - mlt_properties properties = mlt_frame_properties( this ); - - // May need to know the size of the image to clone it - int size = 0; - - // Get the image - uint8_t *image = mlt_properties_get_data( properties, "image", &size ); - - // Get width and height - *width = mlt_properties_get_int( properties, "width" ); - *height = mlt_properties_get_int( properties, "height" ); - - // Clone if necessary - if ( writable ) - { - // Clone our image - uint8_t *copy = malloc( size ); - memcpy( copy, image, size ); - - // We're going to pass the copy on - image = copy; - - // Now update properties so we free the copy after - mlt_properties_set_data( properties, "image", copy, size, free, NULL ); - } - - // Pass on the image - *buffer = image; - - return 0; -} + // Pixbuf + GdkPixbuf *pixbuf = NULL; -static uint8_t *producer_get_alpha_mask( mlt_frame this ) -{ // Obtain properties of frame - mlt_properties properties = mlt_frame_properties( this ); - - // Return the alpha mask - return mlt_properties_get_data( properties, "alpha", NULL ); -} + mlt_properties properties = mlt_frame_properties( frame ); -static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ) -{ - producer_pango this = producer->child; - GdkPixbuf *pixbuf = NULL; + // Obtain the producer pango for this frame + producer_pango this = mlt_properties_get_data( properties, "producer_pango", NULL ); - // Generate a frame - *frame = mlt_frame_init( ); + // Obtain the producer + mlt_producer producer = &this->parent; - // Obtain properties of frame and producer - mlt_properties properties = mlt_frame_properties( *frame ); + // Obtain the producer properties mlt_properties producer_props = mlt_producer_properties( producer ); - + // Get producer properties int fg = mlt_properties_get_int( producer_props, "fgcolor" ); int bg = mlt_properties_get_int( producer_props, "bgcolor" ); @@ -211,20 +172,17 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i this->pad = pad; if ( markup != NULL ) { - if ( this->markup != NULL ) - free( this->markup ); + free( this->markup ); this->markup = strdup( markup ); } if ( text != NULL ) { - if ( this->text != NULL ) - free( this->text ); + free( this->text ); this->text = strdup( text ); } if ( font != NULL ) { - if ( this->font != NULL ) - free( this->font ); + free( this->font ); this->font = strdup( font ); } @@ -247,29 +205,33 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i // Render the title pixbuf = pango_get_pixbuf( markup, text, font, fgcolor, bgcolor, pad, align ); - } - // If we have a pixbuf - if ( pixbuf ) - { - // Scale to adjust for sample aspect ratio - if ( mlt_properties_get_int( properties, "video_standard" ) == mlt_video_standard_pal ) + if ( pixbuf != NULL ) { - GdkPixbuf *temp = pixbuf; - GdkPixbuf *scaled = gdk_pixbuf_scale_simple( pixbuf, - (gint) ( (float) gdk_pixbuf_get_width( pixbuf ) * 45.0/48.0), - gdk_pixbuf_get_height( pixbuf ), GDK_INTERP_HYPER ); - pixbuf = scaled; - g_object_unref( temp ); + // Register this pixbuf for destruction and reuse + mlt_properties_set_data( producer_props, "pixbuf", pixbuf, 0, ( mlt_destructor )g_object_unref, NULL ); + + // Store the width/height of the pixbuf temporarily + this->width = gdk_pixbuf_get_width( pixbuf ); + this->height = gdk_pixbuf_get_height( pixbuf ); } - else + } + else if ( width != this->width || height != this->height ) + { + pixbuf = mlt_properties_get_data( producer_props, "pixbuf", NULL ); + } + + // If we have a pixbuf and a valid width + if ( pixbuf && width > 0 ) + { + int delete = 0; + + // Scale to width/height requested + if ( width != this->width && height != this->height ) { - GdkPixbuf *temp = pixbuf; - GdkPixbuf *scaled = gdk_pixbuf_scale_simple( pixbuf, - (gint) ( (float) gdk_pixbuf_get_width( pixbuf ) * 9.0/8.0 ), - gdk_pixbuf_get_height( pixbuf ), GDK_INTERP_HYPER ); - pixbuf = scaled; - g_object_unref( temp ); + // Note - the original pixbuf is already safe and ready for destruction + pixbuf = gdk_pixbuf_scale_simple( pixbuf, width, height, GDK_INTERP_HYPER ); + delete = 1; } // Store width and height @@ -302,43 +264,94 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i } // Finished with pixbuf now - g_object_unref( pixbuf ); + if ( delete ) + g_object_unref( pixbuf ); // if single picture, reference the image and alpha in the producer - if ( this->image != NULL ) - free( this->image ); + free( this->image ); this->image = image; - if ( this->alpha != NULL ) - free( this->alpha ); + free( this->alpha ); this->alpha = alpha; - } - if ( this->image != NULL ) + // Set width/height + mlt_properties_set_int( properties, "width", this->width ); + mlt_properties_set_int( properties, "height", this->height ); + + // pass the image and alpha data without destructor + mlt_properties_set_data( properties, "image", this->image, this->width * this->height * 2, NULL, NULL ); + mlt_properties_set_data( properties, "alpha", this->alpha, this->width * this->height, NULL, NULL ); +} + +static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) +{ + // Obtain properties of frame + mlt_properties properties = mlt_frame_properties( frame ); + + // Refresh the image + refresh_image( frame, *width, *height ); + + // May need to know the size of the image to clone it + int size = 0; + + // Get the image + uint8_t *image = mlt_properties_get_data( properties, "image", &size ); + + // Get width and height + *width = mlt_properties_get_int( properties, "width" ); + *height = mlt_properties_get_int( properties, "height" ); + + // Clone if necessary + if ( writable ) { - // Set width/height - mlt_properties_set_int( properties, "width", this->width ); - mlt_properties_set_int( properties, "height", this->height ); - - // Set the compositing properties - if ( mlt_properties_get( producer_props, "x" ) != NULL ) - mlt_properties_set_int( properties, "x", mlt_properties_get_int( producer_props, "x" ) ); - if ( mlt_properties_get( producer_props, "y" ) != NULL ) - mlt_properties_set_int( properties, "y", mlt_properties_get_int( producer_props, "y" ) ); - if ( mlt_properties_get( producer_props, "mix" ) != NULL ) - mlt_properties_set_double( properties, "image.mix", mlt_properties_get_double( producer_props, "mix" ) ); - - // if picture sequence pass the image and alpha data without destructor - mlt_properties_set_data( properties, "image", this->image, this->width * this->height * 2, NULL, NULL ); - mlt_properties_set_data( properties, "alpha", this->alpha, this->width * this->height, NULL, NULL ); - - // Set alpha mask call back - ( *frame )->get_alpha_mask = producer_get_alpha_mask; - - // Stack the get image callback - mlt_frame_push_get_image( *frame, producer_get_image ); + // Clone our image + uint8_t *copy = malloc( size ); + memcpy( copy, image, size ); + + // We're going to pass the copy on + image = copy; + + // Now update properties so we free the copy after + mlt_properties_set_data( properties, "image", copy, size, free, NULL ); } + // Pass on the image + *buffer = image; + + return 0; +} + +static uint8_t *producer_get_alpha_mask( mlt_frame this ) +{ + // Obtain properties of frame + mlt_properties properties = mlt_frame_properties( this ); + + // Return the alpha mask + return mlt_properties_get_data( properties, "alpha", NULL ); +} + +static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ) +{ + producer_pango this = producer->child; + + // Generate a frame + *frame = mlt_frame_init( ); + + // Obtain properties of frame and producer + mlt_properties properties = mlt_frame_properties( *frame ); + + // Set the producer on the frame properties + mlt_properties_set_data( properties, "producer_pango", this, 0, NULL, NULL ); + + // Refresh the pango image + refresh_image( *frame, 0, 0 ); + + // Set alpha mask call back + ( *frame )->get_alpha_mask = producer_get_alpha_mask; + + // Stack the get image callback + mlt_frame_push_get_image( *frame, producer_get_image ); + // Update timecode on the frame we're creating mlt_frame_set_position( *frame, mlt_producer_position( producer ) ); @@ -351,16 +364,11 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i static void producer_close( mlt_producer parent ) { producer_pango this = parent->child; - if ( this->image != NULL ) - free( this->image ); - if ( this->alpha != NULL ) - free( this->alpha ); - if ( this->markup != NULL ) - free( this->markup ); - if ( this->text != NULL ) - free( this->text ); - if ( this->font != NULL ) - free( this->font ); + free( this->image ); + free( this->alpha ); + free( this->markup ); + free( this->text ); + free( this->font ); parent->close = NULL; mlt_producer_close( parent ); free( this );