]> git.sesse.net Git - mlt/commitdiff
fixup and optimize edge conditions of composite; updated property handling of produce...
authorddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
Fri, 2 Jan 2004 20:44:28 +0000 (20:44 +0000)
committerddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
Fri, 2 Jan 2004 20:44:28 +0000 (20:44 +0000)
git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@35 d19143bc-622f-0410-bfdd-b5b2a6649095

mlt/src/framework/mlt_frame.c
mlt/src/modules/core/transition_composite.c
mlt/src/modules/gtk2/producer_pango.c
mlt/src/modules/gtk2/producer_pango.h
mlt/src/tests/dan.c
src/framework/mlt_frame.c
src/modules/core/transition_composite.c
src/modules/gtk2/producer_pango.c
src/modules/gtk2/producer_pango.h
src/tests/dan.c

index 368e861291ca6dd4f4bd9810191d7a160cb78f5f..16d51f89adc78e9c96d8c4efc90cbb1c350316a1 100644 (file)
@@ -394,15 +394,18 @@ int mlt_convert_yuv420p_to_yuv422( uint8_t *yuv420p, int width, int height, int
 int mlt_frame_composite_yuv( mlt_frame this, mlt_frame that, int x, int y, float weight )
 {
        int ret = 0;
-       int x_start = 0;
        int width_src, height_src;
        int width_dest, height_dest;
        mlt_image_format format_src, format_dest;
        uint8_t *p_src, *p_dest;
-       int x_end;
        int i, j;
        int stride_src;
        int stride_dest;
+       int x_src = 0, y_src = 0;
+
+       // optimization point - no work to do
+       if ( ( x < 0 && -x >= width_src ) || ( y < 0 && -y >= height_src ) )
+               return ret;
 
        format_src = mlt_image_yuv422;
        format_dest = mlt_image_yuv422;
@@ -410,52 +413,68 @@ int mlt_frame_composite_yuv( mlt_frame this, mlt_frame that, int x, int y, float
        mlt_frame_get_image( this, &p_dest, &format_dest, &width_dest, &height_dest, 1 /* writable */ );
        mlt_frame_get_image( that, &p_src, &format_src, &width_src, &height_src, 0 /* writable */ );
        
-       x_end = width_src;
-       
        stride_src = width_src * 2;
        stride_dest = width_dest * 2;
-       uint8_t *lower = p_dest;
-       uint8_t *upper = p_dest + height_dest * stride_dest;
-
-       p_dest += ( y * stride_dest ) + ( x * 2 );
-
+       
+       // crop overlay off the left edge of frame
        if ( x < 0 )
        {
-               x_start = -x;
-               x_end += x_start;
+               x_src = -x;
+               width_src -= x_src;
+               x = 0;
+       }
+       
+       // crop overlay beyond right edge of frame
+       else if ( x + width_src > width_dest )
+               width_src = width_dest - x;
+
+       // crop overlay off the top edge of the frame
+       if ( y < 0 )
+       {
+               y_src = -y;
+               height_src -= y_src;
        }
+       // crop overlay below bottom edge of frame
+       else if ( y + height_src > height_dest )
+               height_src = height_dest - y;
+
+       // offset pointer into overlay buffer based on cropping
+       p_src += x_src * 2 + y_src * stride_src;
+
+       // offset pointer into frame buffer based upon positive, even coordinates only!
+//     if ( interlaced && y % 2 )
+//             ++y;
+       p_dest += ( x < 0 ? 0 : x ) * 2 + ( y < 0 ? 0 : y ) * stride_dest;
+
+       // Get the alpha channel of the overlay
+       uint8_t *p_alpha = mlt_frame_get_alpha_mask( that );
 
-       uint8_t *z = mlt_frame_get_alpha_mask( that );
+       // offset pointer into alpha channel based upon cropping
+       if ( p_alpha )
+               p_alpha += x_src + y_src * stride_src / 2;
 
+       // now do the compositing only to cropped extents
        for ( i = 0; i < height_src; i++ )
        {
                uint8_t *p = p_src;
                uint8_t *q = p_dest;
                uint8_t *o = p_dest;
+               uint8_t *z = p_alpha;
 
                for ( j = 0; j < width_src; j ++ )
                {
-                       if ( q >= lower && q < upper && j >= x_start && j < x_end )
-                       {
                                uint8_t y = *p ++;
                                uint8_t uv = *p ++;
                                uint8_t a = ( z == NULL ) ? 255 : *z ++;
                                float value = ( weight * ( float ) a / 255.0 );
                                *o ++ = (uint8_t)( y * value + *q++ * ( 1 - value ) );
                                *o ++ = (uint8_t)( uv * value + *q++ * ( 1 - value ) );
-                       }
-                       else
-                       {
-                               p += 2;
-                               o += 2;
-                               q += 2;
-                               if ( z != NULL )
-                                       z += 1;
-                       }
                }
 
                p_src += stride_src;
                p_dest += stride_dest;
+               if ( p_alpha )
+                       p_alpha += stride_src / 2;
        }
 
        return ret;
index 8418f2f3a4d5b3459ffc10bcc407fa64e2675067..f56c6778a6e9cd968f3a319fd36f8e6abebe9685 100644 (file)
@@ -48,20 +48,20 @@ static int transition_get_image( mlt_frame this, uint8_t **image, mlt_image_form
        mlt_properties b_props = mlt_frame_properties( b_frame );
 
        // Arbitrary composite defaults
-       int x = 50;
-       int y = 50;
-       double weight = 1.0;
+       int x = 0;
+       int y = 0;
+       double mix = 1.0;
 
        // Override from b frame properties if provided
        if ( mlt_properties_get( b_props, "x" ) != NULL )
                x = mlt_properties_get_int( b_props, "x" );
        if ( mlt_properties_get( b_props, "y" ) != NULL )
                y = mlt_properties_get_int( b_props, "y" );
-       if ( mlt_properties_get( b_props, "weight" ) != NULL )
-               weight = mlt_properties_get_double( b_props, "weight" );
+       if ( mlt_properties_get( b_props, "mix" ) != NULL )
+               mix = mlt_properties_get_double( b_props, "mix" );
 
        // Composite the b_frame on the a_frame
-       mlt_frame_composite_yuv( this, b_frame, x, y, weight );
+       mlt_frame_composite_yuv( this, b_frame, x, y, mix );
 
        // Extract the a_frame image info
        *width = mlt_properties_get_int( a_props, "width" );
index d113ce69cf9df99f98fc6070e3971a14eedf91b0..5877d52402da1fa0a962329b237697e269317e76 100644 (file)
 #include <pango/pangoft2.h>
 #include <freetype/freetype.h>
 
+struct producer_pango_s
+{
+       struct mlt_producer_s parent;
+       int width;
+       int height;
+       uint8_t *image;
+       uint8_t *alpha;
+       int   fgcolor;
+       int   bgcolor;
+       int   align;
+       int   pad;
+       char *markup;
+       char *text;
+       char *font;
+};
+
 // special color type used by internal pango routines
 typedef struct
 {
@@ -36,7 +52,8 @@ typedef struct
 static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int index );
 static void producer_close( mlt_producer parent );
 static void pango_draw_background( GdkPixbuf *pixbuf, rgba_color bg );
-static GdkPixbuf *pango_get_pixbuf( const char *markup, rgba_color fg, rgba_color bg, int pad, int align );
+static GdkPixbuf *pango_get_pixbuf( const char *markup, const char *text, const char *font,
+       rgba_color fg, rgba_color bg, int pad, int align );
 
 mlt_producer producer_pango_init( const char *markup )
 {
@@ -48,7 +65,7 @@ mlt_producer producer_pango_init( const char *markup )
                producer->get_frame = producer_get_frame;
                producer->close = producer_close;
 
-               this->markup = strdup( markup );
+               // This is required to initialise gdk-pixbuf
                g_type_init();
 
                // Get the properties interface
@@ -60,6 +77,12 @@ mlt_producer producer_pango_init( const char *markup )
                mlt_properties_set_int( properties, "bgcolor", 0x00000000 );
                mlt_properties_set_int( properties, "align", pango_align_left );
                mlt_properties_set_int( properties, "pad", 0 );
+               mlt_properties_set( properties, "markup", ( char * ) ( markup == NULL ? "" : markup ) );
+               mlt_properties_set( properties, "text", "" );
+               mlt_properties_set( properties, "font", "Sans 48" );
+               mlt_properties_set_int( properties, "x", 0 );
+               mlt_properties_set_int( properties, "y", 0 );
+               mlt_properties_set_double( properties, "mix", 1.0 );
 
                return producer;
        }
@@ -119,37 +142,54 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
        // Generate a frame
        *frame = mlt_frame_init( );
 
-       // Obtain properties of frame
+       // Obtain properties of frame and producer
        mlt_properties properties = mlt_frame_properties( *frame );
-
-    // optimization for subsequent iterations on single picture
-       if ( this->image != NULL )
+       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" );
+       int align = mlt_properties_get_int( producer_props, "align" );
+       int pad = mlt_properties_get_int( producer_props, "pad" );
+       char *markup = mlt_properties_get( producer_props, "markup" );
+       char *text = mlt_properties_get( producer_props, "text" );
+       char *font = mlt_properties_get( producer_props, "font" );
+
+       // See if any properties changed
+       int property_changed = ( fg != this->fgcolor );
+       property_changed = property_changed || ( bg != this->bgcolor );
+       property_changed = property_changed || ( align != this->align );
+       property_changed = property_changed || ( pad != this->pad );
+       property_changed = property_changed || ( markup && this->markup && strcmp( markup, this->markup ) );
+       property_changed = property_changed || ( text && this->text && strcmp( text, this->text ) );
+       property_changed = property_changed || ( font && this->font && strcmp( font, this->font ) );
+
+       // Save the properties for next comparison
+       this->fgcolor = fg;
+       this->bgcolor = bg;
+       this->align = align;
+       this->pad = pad;
+       if ( markup != NULL )
        {
-               // Set width/height
-               mlt_properties_set_int( properties, "width", this->width );
-               mlt_properties_set_int( properties, "height", this->height );
-
-               // if picture sequence pass the image and alpha data without destructor
-               mlt_properties_set_data( properties, "image", this->image, 0, NULL, NULL );
-               mlt_properties_set_data( properties, "alpha", this->alpha, 0, 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 );
-
+               if ( this->markup != NULL )
+                       free( this->markup );
+               this->markup = strdup( markup );
        }
-       else
+       if ( text != NULL )
+       {
+               if ( this->text != NULL )
+                       free( this->text );
+               this->text = strdup( text );
+       }
+       if ( font != NULL )
+       {
+               if ( this->font != NULL )
+                       free( this->font );
+               this->font = strdup( font );
+       }
+
+       if ( property_changed )
        {
-               // Obtain properties of producer
-               mlt_properties props = mlt_producer_properties( producer );
-
-               // Get properties
-               int fg = mlt_properties_get_int( props, "fgcolor" );
-               int bg = mlt_properties_get_int( props, "bgcolor" );
-               int align = mlt_properties_get_int( props, "align" );
-               int pad = mlt_properties_get_int( props, "pad" );
                rgba_color fgcolor =
                {
                        ( fg & 0xff000000 ) >> 24,
@@ -164,9 +204,9 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
                        ( bg & 0x0000ff00 ) >> 8,
                        ( bg & 0x000000ff )
                };
-               
+
                // Render the title
-               pixbuf = pango_get_pixbuf( this->markup, fgcolor, bgcolor, pad, align );
+               pixbuf = pango_get_pixbuf( markup, text, font, fgcolor, bgcolor, pad, align );
        }
 
        // If we have a pixbuf
@@ -223,23 +263,36 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
 
                // Finished with pixbuf now
                g_object_unref( pixbuf );
+               
+               // if single picture, reference the image and alpha in the producer
+               if ( this->image != NULL )
+                       free( this->image );
+               this->image = image;
+               if ( this->alpha != NULL )
+                       free( this->alpha );
+               this->alpha = alpha;
+
+       }
 
-               // Set width/height of frame
+       if ( this->image != NULL )
+       {
+               // Set width/height
                mlt_properties_set_int( properties, "width", this->width );
                mlt_properties_set_int( properties, "height", this->height );
 
-               // if single picture, reference the image and alpha in the producer
-               this->image = image;
-               this->alpha = alpha;
+               // Set the compositing properties
+               mlt_properties_set_int( properties, "x", mlt_properties_get_int( producer_props, "x" ) );
+               mlt_properties_set_int( properties, "y", mlt_properties_get_int( producer_props, "y" ) );
+               mlt_properties_set_double( properties, "mix",  mlt_properties_get_double( producer_props, "mix" ) );
 
-               // pass the image and alpha data without destructor
-               mlt_properties_set_data( properties, "image", image, 0, NULL, NULL );
-               mlt_properties_set_data( properties, "alpha", alpha, 0, NULL, NULL );
+               // if picture sequence pass the image and alpha data without destructor
+               mlt_properties_set_data( properties, "image", this->image, 0, NULL, NULL );
+               mlt_properties_set_data( properties, "alpha", this->alpha, 0, NULL, NULL );
 
-               // Set alpha call back
+               // Set alpha mask call back
                ( *frame )->get_alpha_mask = producer_get_alpha_mask;
 
-               // Push the get_image method
+               // Stack the get image callback
                mlt_frame_push_get_image( *frame, producer_get_image );
        }
 
@@ -255,12 +308,16 @@ 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->markup )
-               free( this->markup );
-       if ( this->image )
+       if ( this->image != NULL )
                free( this->image );
-       if ( this->alpha )
+       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 );
        parent->close = NULL;
        mlt_producer_close( parent );
        free( this );
@@ -285,12 +342,11 @@ static void pango_draw_background( GdkPixbuf *pixbuf, rgba_color bg )
        }
 }
 
-static GdkPixbuf *pango_get_pixbuf( const char *markup, rgba_color fg, rgba_color bg, int pad, int align )
+static GdkPixbuf *pango_get_pixbuf( const char *markup, const char *text, const char *font, rgba_color fg, rgba_color bg, int pad, int align )
 {
        PangoFT2FontMap *fontmap = (PangoFT2FontMap*) pango_ft2_font_map_new();
        PangoContext *context = pango_ft2_font_map_create_context( fontmap );
        PangoLayout *layout = pango_layout_new( context );
-//     PangoFontDescription *font;
        int w, h, x;
        int i, j;
        GdkPixbuf *pixbuf = NULL;
@@ -301,10 +357,15 @@ static GdkPixbuf *pango_get_pixbuf( const char *markup, rgba_color fg, rgba_colo
 
        pango_ft2_font_map_set_resolution( fontmap, 72, 72 );
        pango_layout_set_width( layout, -1 ); // set wrapping constraints
-//     pango_layout_set_font_description( layout, "Sans 48" );
+       pango_layout_set_font_description( layout, pango_font_description_from_string( font ) );
 //     pango_layout_set_spacing( layout, space );
        pango_layout_set_alignment( layout, ( PangoAlignment ) align  );
-       pango_layout_set_markup( layout, markup, (markup == NULL ? 0 : strlen( markup ) ) );
+       if ( markup != NULL && strcmp( markup, "" ) != 0 )
+               pango_layout_set_markup( layout, markup, strlen( markup ) );
+       else if ( text != NULL && strcmp( text, "" ) != 0 )
+               pango_layout_set_text( layout, text, strlen( text ) );
+       else
+               return NULL;
        pango_layout_get_pixel_size( layout, &w, &h );
 
        pixbuf = gdk_pixbuf_new( GDK_COLORSPACE_RGB, TRUE /* has alpha */, 8, w + 2 * pad, h + 2 * pad );
index 1e2b1c85b2fd3703742ac85c90fe18ffcb6b7e9b..ade19775dcbe4a49c1e5eb0cbad001f852923ed1 100644 (file)
 
 typedef struct producer_pango_s *producer_pango;
 
-struct producer_pango_s
-{
-       struct mlt_producer_s parent;
-       char *markup;
-       int width;
-       int height;
-       uint8_t *image;
-       uint8_t *alpha;
-};
-
 typedef enum
 {
        pango_align_left = 0,
index cdfd211839fd7e7247bc8837a04ef1428f692f00..8e499bcdeb059b6001e81a1b686c22ce4147eedf 100644 (file)
@@ -18,8 +18,8 @@ int main( int argc, char **argv )
 
        // Start the consumer...
        int vstd = mlt_video_standard_ntsc;
-       mlt_consumer consumer = mlt_factory_consumer( "bluefish", &vstd );
-       mlt_properties_set_int( mlt_consumer_properties( consumer ), "video_standard", mlt_video_standard_ntsc );
+       //mlt_consumer consumer = mlt_factory_consumer( "bluefish", &vstd );
+       mlt_consumer consumer = mlt_factory_consumer( "sdl", "NTSC" );
 
        // Create the producer(s)
        mlt_producer dv1 = mlt_factory_producer( "mcmpeg", file1 );
@@ -38,10 +38,15 @@ int main( int argc, char **argv )
        //mlt_producer dv1 = producer_pixbuf_init( file1 );
        //mlt_producer dv2 = producer_libdv_init( file2 );
        //mlt_producer dv2 = mlt_factory_producer( "pixbuf", file2 );
-       mlt_producer dv2 = mlt_factory_producer( "pango", "<span font_desc=\"Sans Bold 36\">Mutton <span font_desc=\"Luxi Serif Bold Oblique 36\">Lettuce</span> Tomato</span>" );
+       mlt_producer dv2 = mlt_factory_producer( "pango", NULL ); //"<span font_desc=\"Sans Bold 36\">Mutton <span font_desc=\"Luxi Serif Bold Oblique 36\">Lettuce</span> Tomato</span>" );
+       mlt_properties_set( mlt_producer_properties( dv2 ), "font", "Sans Bold 36" );
+       mlt_properties_set( mlt_producer_properties( dv2 ), "text", "Mutton Lettuce\nTomato" );
        mlt_properties_set_int( mlt_producer_properties( dv2 ), "video_standard", mlt_video_standard_ntsc );
        mlt_properties_set_int( mlt_producer_properties( dv2 ), "bgcolor", 0x0000007f );
        mlt_properties_set_int( mlt_producer_properties( dv2 ), "pad", 8 );
+       mlt_properties_set_int( mlt_producer_properties( dv2 ), "align", 1 );
+       mlt_properties_set_int( mlt_producer_properties( dv2 ), "x", -20 );
+       mlt_properties_set_int( mlt_producer_properties( dv2 ), "y", 40 );
 
        // Register producers(s) with a multitrack object
        mlt_multitrack multitrack = mlt_multitrack_init( );
@@ -49,14 +54,14 @@ int main( int argc, char **argv )
        mlt_multitrack_connect( multitrack, dv2, 1 );
 
        // Create a filter and associate it to track 0
-//     mlt_filter filter = mlt_factory_filter( "deinterlace", NULL );
-//     mlt_filter_connect( filter, mlt_multitrack_service( multitrack ), 0 );
-//     mlt_filter_set_in_and_out( filter, 0, 1000 );
+       mlt_filter filter = mlt_factory_filter( "deinterlace", NULL );
+       mlt_filter_connect( filter, mlt_multitrack_service( multitrack ), 0 );
+       mlt_filter_set_in_and_out( filter, 0, 1000 );
 
        // Define a transition
        mlt_transition transition = mlt_factory_transition( "composite", NULL );
-       mlt_transition_connect( transition, mlt_multitrack_service( multitrack ), 0, 1 );
-       mlt_transition_set_in_and_out( transition, 0, 1000 );
+       mlt_transition_connect( transition, mlt_filter_service( filter ), 0, 1 );
+       mlt_transition_set_in_and_out( transition, 0, 5.0 );
 
        // Buy a tractor and connect it to the filter
        mlt_tractor tractor = mlt_tractor_init( );
@@ -69,6 +74,13 @@ int main( int argc, char **argv )
        fprintf( stderr, "Press return to continue\n" );
        fgets( temp, 132, stdin );
 
+       mlt_properties_set( mlt_producer_properties( dv2 ), "font", "Sans Oblique 36" );
+       mlt_properties_set( mlt_producer_properties( dv2 ), "text", "Mutton\nLettuce Tomato" );
+
+       // Do stuff until we're told otherwise...
+       fprintf( stderr, "Press return to continue\n" );
+       fgets( temp, 132, stdin );
+       
        // Close everything...
        mlt_consumer_close( consumer );
        mlt_tractor_close( tractor );
index 368e861291ca6dd4f4bd9810191d7a160cb78f5f..16d51f89adc78e9c96d8c4efc90cbb1c350316a1 100644 (file)
@@ -394,15 +394,18 @@ int mlt_convert_yuv420p_to_yuv422( uint8_t *yuv420p, int width, int height, int
 int mlt_frame_composite_yuv( mlt_frame this, mlt_frame that, int x, int y, float weight )
 {
        int ret = 0;
-       int x_start = 0;
        int width_src, height_src;
        int width_dest, height_dest;
        mlt_image_format format_src, format_dest;
        uint8_t *p_src, *p_dest;
-       int x_end;
        int i, j;
        int stride_src;
        int stride_dest;
+       int x_src = 0, y_src = 0;
+
+       // optimization point - no work to do
+       if ( ( x < 0 && -x >= width_src ) || ( y < 0 && -y >= height_src ) )
+               return ret;
 
        format_src = mlt_image_yuv422;
        format_dest = mlt_image_yuv422;
@@ -410,52 +413,68 @@ int mlt_frame_composite_yuv( mlt_frame this, mlt_frame that, int x, int y, float
        mlt_frame_get_image( this, &p_dest, &format_dest, &width_dest, &height_dest, 1 /* writable */ );
        mlt_frame_get_image( that, &p_src, &format_src, &width_src, &height_src, 0 /* writable */ );
        
-       x_end = width_src;
-       
        stride_src = width_src * 2;
        stride_dest = width_dest * 2;
-       uint8_t *lower = p_dest;
-       uint8_t *upper = p_dest + height_dest * stride_dest;
-
-       p_dest += ( y * stride_dest ) + ( x * 2 );
-
+       
+       // crop overlay off the left edge of frame
        if ( x < 0 )
        {
-               x_start = -x;
-               x_end += x_start;
+               x_src = -x;
+               width_src -= x_src;
+               x = 0;
+       }
+       
+       // crop overlay beyond right edge of frame
+       else if ( x + width_src > width_dest )
+               width_src = width_dest - x;
+
+       // crop overlay off the top edge of the frame
+       if ( y < 0 )
+       {
+               y_src = -y;
+               height_src -= y_src;
        }
+       // crop overlay below bottom edge of frame
+       else if ( y + height_src > height_dest )
+               height_src = height_dest - y;
+
+       // offset pointer into overlay buffer based on cropping
+       p_src += x_src * 2 + y_src * stride_src;
+
+       // offset pointer into frame buffer based upon positive, even coordinates only!
+//     if ( interlaced && y % 2 )
+//             ++y;
+       p_dest += ( x < 0 ? 0 : x ) * 2 + ( y < 0 ? 0 : y ) * stride_dest;
+
+       // Get the alpha channel of the overlay
+       uint8_t *p_alpha = mlt_frame_get_alpha_mask( that );
 
-       uint8_t *z = mlt_frame_get_alpha_mask( that );
+       // offset pointer into alpha channel based upon cropping
+       if ( p_alpha )
+               p_alpha += x_src + y_src * stride_src / 2;
 
+       // now do the compositing only to cropped extents
        for ( i = 0; i < height_src; i++ )
        {
                uint8_t *p = p_src;
                uint8_t *q = p_dest;
                uint8_t *o = p_dest;
+               uint8_t *z = p_alpha;
 
                for ( j = 0; j < width_src; j ++ )
                {
-                       if ( q >= lower && q < upper && j >= x_start && j < x_end )
-                       {
                                uint8_t y = *p ++;
                                uint8_t uv = *p ++;
                                uint8_t a = ( z == NULL ) ? 255 : *z ++;
                                float value = ( weight * ( float ) a / 255.0 );
                                *o ++ = (uint8_t)( y * value + *q++ * ( 1 - value ) );
                                *o ++ = (uint8_t)( uv * value + *q++ * ( 1 - value ) );
-                       }
-                       else
-                       {
-                               p += 2;
-                               o += 2;
-                               q += 2;
-                               if ( z != NULL )
-                                       z += 1;
-                       }
                }
 
                p_src += stride_src;
                p_dest += stride_dest;
+               if ( p_alpha )
+                       p_alpha += stride_src / 2;
        }
 
        return ret;
index 8418f2f3a4d5b3459ffc10bcc407fa64e2675067..f56c6778a6e9cd968f3a319fd36f8e6abebe9685 100644 (file)
@@ -48,20 +48,20 @@ static int transition_get_image( mlt_frame this, uint8_t **image, mlt_image_form
        mlt_properties b_props = mlt_frame_properties( b_frame );
 
        // Arbitrary composite defaults
-       int x = 50;
-       int y = 50;
-       double weight = 1.0;
+       int x = 0;
+       int y = 0;
+       double mix = 1.0;
 
        // Override from b frame properties if provided
        if ( mlt_properties_get( b_props, "x" ) != NULL )
                x = mlt_properties_get_int( b_props, "x" );
        if ( mlt_properties_get( b_props, "y" ) != NULL )
                y = mlt_properties_get_int( b_props, "y" );
-       if ( mlt_properties_get( b_props, "weight" ) != NULL )
-               weight = mlt_properties_get_double( b_props, "weight" );
+       if ( mlt_properties_get( b_props, "mix" ) != NULL )
+               mix = mlt_properties_get_double( b_props, "mix" );
 
        // Composite the b_frame on the a_frame
-       mlt_frame_composite_yuv( this, b_frame, x, y, weight );
+       mlt_frame_composite_yuv( this, b_frame, x, y, mix );
 
        // Extract the a_frame image info
        *width = mlt_properties_get_int( a_props, "width" );
index d113ce69cf9df99f98fc6070e3971a14eedf91b0..5877d52402da1fa0a962329b237697e269317e76 100644 (file)
 #include <pango/pangoft2.h>
 #include <freetype/freetype.h>
 
+struct producer_pango_s
+{
+       struct mlt_producer_s parent;
+       int width;
+       int height;
+       uint8_t *image;
+       uint8_t *alpha;
+       int   fgcolor;
+       int   bgcolor;
+       int   align;
+       int   pad;
+       char *markup;
+       char *text;
+       char *font;
+};
+
 // special color type used by internal pango routines
 typedef struct
 {
@@ -36,7 +52,8 @@ typedef struct
 static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int index );
 static void producer_close( mlt_producer parent );
 static void pango_draw_background( GdkPixbuf *pixbuf, rgba_color bg );
-static GdkPixbuf *pango_get_pixbuf( const char *markup, rgba_color fg, rgba_color bg, int pad, int align );
+static GdkPixbuf *pango_get_pixbuf( const char *markup, const char *text, const char *font,
+       rgba_color fg, rgba_color bg, int pad, int align );
 
 mlt_producer producer_pango_init( const char *markup )
 {
@@ -48,7 +65,7 @@ mlt_producer producer_pango_init( const char *markup )
                producer->get_frame = producer_get_frame;
                producer->close = producer_close;
 
-               this->markup = strdup( markup );
+               // This is required to initialise gdk-pixbuf
                g_type_init();
 
                // Get the properties interface
@@ -60,6 +77,12 @@ mlt_producer producer_pango_init( const char *markup )
                mlt_properties_set_int( properties, "bgcolor", 0x00000000 );
                mlt_properties_set_int( properties, "align", pango_align_left );
                mlt_properties_set_int( properties, "pad", 0 );
+               mlt_properties_set( properties, "markup", ( char * ) ( markup == NULL ? "" : markup ) );
+               mlt_properties_set( properties, "text", "" );
+               mlt_properties_set( properties, "font", "Sans 48" );
+               mlt_properties_set_int( properties, "x", 0 );
+               mlt_properties_set_int( properties, "y", 0 );
+               mlt_properties_set_double( properties, "mix", 1.0 );
 
                return producer;
        }
@@ -119,37 +142,54 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
        // Generate a frame
        *frame = mlt_frame_init( );
 
-       // Obtain properties of frame
+       // Obtain properties of frame and producer
        mlt_properties properties = mlt_frame_properties( *frame );
-
-    // optimization for subsequent iterations on single picture
-       if ( this->image != NULL )
+       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" );
+       int align = mlt_properties_get_int( producer_props, "align" );
+       int pad = mlt_properties_get_int( producer_props, "pad" );
+       char *markup = mlt_properties_get( producer_props, "markup" );
+       char *text = mlt_properties_get( producer_props, "text" );
+       char *font = mlt_properties_get( producer_props, "font" );
+
+       // See if any properties changed
+       int property_changed = ( fg != this->fgcolor );
+       property_changed = property_changed || ( bg != this->bgcolor );
+       property_changed = property_changed || ( align != this->align );
+       property_changed = property_changed || ( pad != this->pad );
+       property_changed = property_changed || ( markup && this->markup && strcmp( markup, this->markup ) );
+       property_changed = property_changed || ( text && this->text && strcmp( text, this->text ) );
+       property_changed = property_changed || ( font && this->font && strcmp( font, this->font ) );
+
+       // Save the properties for next comparison
+       this->fgcolor = fg;
+       this->bgcolor = bg;
+       this->align = align;
+       this->pad = pad;
+       if ( markup != NULL )
        {
-               // Set width/height
-               mlt_properties_set_int( properties, "width", this->width );
-               mlt_properties_set_int( properties, "height", this->height );
-
-               // if picture sequence pass the image and alpha data without destructor
-               mlt_properties_set_data( properties, "image", this->image, 0, NULL, NULL );
-               mlt_properties_set_data( properties, "alpha", this->alpha, 0, 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 );
-
+               if ( this->markup != NULL )
+                       free( this->markup );
+               this->markup = strdup( markup );
        }
-       else
+       if ( text != NULL )
+       {
+               if ( this->text != NULL )
+                       free( this->text );
+               this->text = strdup( text );
+       }
+       if ( font != NULL )
+       {
+               if ( this->font != NULL )
+                       free( this->font );
+               this->font = strdup( font );
+       }
+
+       if ( property_changed )
        {
-               // Obtain properties of producer
-               mlt_properties props = mlt_producer_properties( producer );
-
-               // Get properties
-               int fg = mlt_properties_get_int( props, "fgcolor" );
-               int bg = mlt_properties_get_int( props, "bgcolor" );
-               int align = mlt_properties_get_int( props, "align" );
-               int pad = mlt_properties_get_int( props, "pad" );
                rgba_color fgcolor =
                {
                        ( fg & 0xff000000 ) >> 24,
@@ -164,9 +204,9 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
                        ( bg & 0x0000ff00 ) >> 8,
                        ( bg & 0x000000ff )
                };
-               
+
                // Render the title
-               pixbuf = pango_get_pixbuf( this->markup, fgcolor, bgcolor, pad, align );
+               pixbuf = pango_get_pixbuf( markup, text, font, fgcolor, bgcolor, pad, align );
        }
 
        // If we have a pixbuf
@@ -223,23 +263,36 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
 
                // Finished with pixbuf now
                g_object_unref( pixbuf );
+               
+               // if single picture, reference the image and alpha in the producer
+               if ( this->image != NULL )
+                       free( this->image );
+               this->image = image;
+               if ( this->alpha != NULL )
+                       free( this->alpha );
+               this->alpha = alpha;
+
+       }
 
-               // Set width/height of frame
+       if ( this->image != NULL )
+       {
+               // Set width/height
                mlt_properties_set_int( properties, "width", this->width );
                mlt_properties_set_int( properties, "height", this->height );
 
-               // if single picture, reference the image and alpha in the producer
-               this->image = image;
-               this->alpha = alpha;
+               // Set the compositing properties
+               mlt_properties_set_int( properties, "x", mlt_properties_get_int( producer_props, "x" ) );
+               mlt_properties_set_int( properties, "y", mlt_properties_get_int( producer_props, "y" ) );
+               mlt_properties_set_double( properties, "mix",  mlt_properties_get_double( producer_props, "mix" ) );
 
-               // pass the image and alpha data without destructor
-               mlt_properties_set_data( properties, "image", image, 0, NULL, NULL );
-               mlt_properties_set_data( properties, "alpha", alpha, 0, NULL, NULL );
+               // if picture sequence pass the image and alpha data without destructor
+               mlt_properties_set_data( properties, "image", this->image, 0, NULL, NULL );
+               mlt_properties_set_data( properties, "alpha", this->alpha, 0, NULL, NULL );
 
-               // Set alpha call back
+               // Set alpha mask call back
                ( *frame )->get_alpha_mask = producer_get_alpha_mask;
 
-               // Push the get_image method
+               // Stack the get image callback
                mlt_frame_push_get_image( *frame, producer_get_image );
        }
 
@@ -255,12 +308,16 @@ 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->markup )
-               free( this->markup );
-       if ( this->image )
+       if ( this->image != NULL )
                free( this->image );
-       if ( this->alpha )
+       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 );
        parent->close = NULL;
        mlt_producer_close( parent );
        free( this );
@@ -285,12 +342,11 @@ static void pango_draw_background( GdkPixbuf *pixbuf, rgba_color bg )
        }
 }
 
-static GdkPixbuf *pango_get_pixbuf( const char *markup, rgba_color fg, rgba_color bg, int pad, int align )
+static GdkPixbuf *pango_get_pixbuf( const char *markup, const char *text, const char *font, rgba_color fg, rgba_color bg, int pad, int align )
 {
        PangoFT2FontMap *fontmap = (PangoFT2FontMap*) pango_ft2_font_map_new();
        PangoContext *context = pango_ft2_font_map_create_context( fontmap );
        PangoLayout *layout = pango_layout_new( context );
-//     PangoFontDescription *font;
        int w, h, x;
        int i, j;
        GdkPixbuf *pixbuf = NULL;
@@ -301,10 +357,15 @@ static GdkPixbuf *pango_get_pixbuf( const char *markup, rgba_color fg, rgba_colo
 
        pango_ft2_font_map_set_resolution( fontmap, 72, 72 );
        pango_layout_set_width( layout, -1 ); // set wrapping constraints
-//     pango_layout_set_font_description( layout, "Sans 48" );
+       pango_layout_set_font_description( layout, pango_font_description_from_string( font ) );
 //     pango_layout_set_spacing( layout, space );
        pango_layout_set_alignment( layout, ( PangoAlignment ) align  );
-       pango_layout_set_markup( layout, markup, (markup == NULL ? 0 : strlen( markup ) ) );
+       if ( markup != NULL && strcmp( markup, "" ) != 0 )
+               pango_layout_set_markup( layout, markup, strlen( markup ) );
+       else if ( text != NULL && strcmp( text, "" ) != 0 )
+               pango_layout_set_text( layout, text, strlen( text ) );
+       else
+               return NULL;
        pango_layout_get_pixel_size( layout, &w, &h );
 
        pixbuf = gdk_pixbuf_new( GDK_COLORSPACE_RGB, TRUE /* has alpha */, 8, w + 2 * pad, h + 2 * pad );
index 1e2b1c85b2fd3703742ac85c90fe18ffcb6b7e9b..ade19775dcbe4a49c1e5eb0cbad001f852923ed1 100644 (file)
 
 typedef struct producer_pango_s *producer_pango;
 
-struct producer_pango_s
-{
-       struct mlt_producer_s parent;
-       char *markup;
-       int width;
-       int height;
-       uint8_t *image;
-       uint8_t *alpha;
-};
-
 typedef enum
 {
        pango_align_left = 0,
index cdfd211839fd7e7247bc8837a04ef1428f692f00..8e499bcdeb059b6001e81a1b686c22ce4147eedf 100644 (file)
@@ -18,8 +18,8 @@ int main( int argc, char **argv )
 
        // Start the consumer...
        int vstd = mlt_video_standard_ntsc;
-       mlt_consumer consumer = mlt_factory_consumer( "bluefish", &vstd );
-       mlt_properties_set_int( mlt_consumer_properties( consumer ), "video_standard", mlt_video_standard_ntsc );
+       //mlt_consumer consumer = mlt_factory_consumer( "bluefish", &vstd );
+       mlt_consumer consumer = mlt_factory_consumer( "sdl", "NTSC" );
 
        // Create the producer(s)
        mlt_producer dv1 = mlt_factory_producer( "mcmpeg", file1 );
@@ -38,10 +38,15 @@ int main( int argc, char **argv )
        //mlt_producer dv1 = producer_pixbuf_init( file1 );
        //mlt_producer dv2 = producer_libdv_init( file2 );
        //mlt_producer dv2 = mlt_factory_producer( "pixbuf", file2 );
-       mlt_producer dv2 = mlt_factory_producer( "pango", "<span font_desc=\"Sans Bold 36\">Mutton <span font_desc=\"Luxi Serif Bold Oblique 36\">Lettuce</span> Tomato</span>" );
+       mlt_producer dv2 = mlt_factory_producer( "pango", NULL ); //"<span font_desc=\"Sans Bold 36\">Mutton <span font_desc=\"Luxi Serif Bold Oblique 36\">Lettuce</span> Tomato</span>" );
+       mlt_properties_set( mlt_producer_properties( dv2 ), "font", "Sans Bold 36" );
+       mlt_properties_set( mlt_producer_properties( dv2 ), "text", "Mutton Lettuce\nTomato" );
        mlt_properties_set_int( mlt_producer_properties( dv2 ), "video_standard", mlt_video_standard_ntsc );
        mlt_properties_set_int( mlt_producer_properties( dv2 ), "bgcolor", 0x0000007f );
        mlt_properties_set_int( mlt_producer_properties( dv2 ), "pad", 8 );
+       mlt_properties_set_int( mlt_producer_properties( dv2 ), "align", 1 );
+       mlt_properties_set_int( mlt_producer_properties( dv2 ), "x", -20 );
+       mlt_properties_set_int( mlt_producer_properties( dv2 ), "y", 40 );
 
        // Register producers(s) with a multitrack object
        mlt_multitrack multitrack = mlt_multitrack_init( );
@@ -49,14 +54,14 @@ int main( int argc, char **argv )
        mlt_multitrack_connect( multitrack, dv2, 1 );
 
        // Create a filter and associate it to track 0
-//     mlt_filter filter = mlt_factory_filter( "deinterlace", NULL );
-//     mlt_filter_connect( filter, mlt_multitrack_service( multitrack ), 0 );
-//     mlt_filter_set_in_and_out( filter, 0, 1000 );
+       mlt_filter filter = mlt_factory_filter( "deinterlace", NULL );
+       mlt_filter_connect( filter, mlt_multitrack_service( multitrack ), 0 );
+       mlt_filter_set_in_and_out( filter, 0, 1000 );
 
        // Define a transition
        mlt_transition transition = mlt_factory_transition( "composite", NULL );
-       mlt_transition_connect( transition, mlt_multitrack_service( multitrack ), 0, 1 );
-       mlt_transition_set_in_and_out( transition, 0, 1000 );
+       mlt_transition_connect( transition, mlt_filter_service( filter ), 0, 1 );
+       mlt_transition_set_in_and_out( transition, 0, 5.0 );
 
        // Buy a tractor and connect it to the filter
        mlt_tractor tractor = mlt_tractor_init( );
@@ -69,6 +74,13 @@ int main( int argc, char **argv )
        fprintf( stderr, "Press return to continue\n" );
        fgets( temp, 132, stdin );
 
+       mlt_properties_set( mlt_producer_properties( dv2 ), "font", "Sans Oblique 36" );
+       mlt_properties_set( mlt_producer_properties( dv2 ), "text", "Mutton\nLettuce Tomato" );
+
+       // Do stuff until we're told otherwise...
+       fprintf( stderr, "Press return to continue\n" );
+       fgets( temp, 132, stdin );
+       
        // Close everything...
        mlt_consumer_close( consumer );
        mlt_tractor_close( tractor );