]> git.sesse.net Git - mlt/commitdiff
4 new tests, bugfixes in pango, pixbuf, transition_luma, and mlt_frame_audio_mix
authorddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
Sun, 11 Jan 2004 09:58:26 +0000 (09:58 +0000)
committerddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
Sun, 11 Jan 2004 09:58:26 +0000 (09:58 +0000)
git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@53 d19143bc-622f-0410-bfdd-b5b2a6649095

24 files changed:
mlt/src/framework/mlt_frame.c
mlt/src/modules/core/transition_luma.c
mlt/src/modules/gtk2/producer_pango.c
mlt/src/modules/gtk2/producer_pixbuf.c
mlt/src/tests/Makefile
mlt/src/tests/clock16ntsc.pgm [new file with mode: 0644]
mlt/src/tests/clock16pal.pgm [new file with mode: 0644]
mlt/src/tests/dan.c
mlt/src/tests/dissolve.c [new file with mode: 0644]
mlt/src/tests/luma.c [new file with mode: 0644]
mlt/src/tests/pango.c [new file with mode: 0644]
mlt/src/tests/pixbuf.c [new file with mode: 0644]
src/framework/mlt_frame.c
src/modules/core/transition_luma.c
src/modules/gtk2/producer_pango.c
src/modules/gtk2/producer_pixbuf.c
src/tests/Makefile
src/tests/clock16ntsc.pgm [new file with mode: 0644]
src/tests/clock16pal.pgm [new file with mode: 0644]
src/tests/dan.c
src/tests/dissolve.c [new file with mode: 0644]
src/tests/luma.c [new file with mode: 0644]
src/tests/pango.c [new file with mode: 0644]
src/tests/pixbuf.c [new file with mode: 0644]

index 3b11fcf1357317f3819f2dd7ecdde1cc2d562f21..ba59ad9609cf21fedd0273cd51a8ae0e86474203 100644 (file)
@@ -412,10 +412,15 @@ int mlt_frame_composite_yuv( mlt_frame this, mlt_frame that, int x, int y, float
 
        format_src = mlt_image_yuv422;
        format_dest = mlt_image_yuv422;
-       
+
+       //fprintf( stderr, "call get_image on frame a\n"), fflush( stderr );
        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 */ );
-       
+       //fprintf( stderr, "call get_image on frame b\n"), fflush( stderr );
+       mlt_frame_get_image( that, &p_src, &format_src, &width_src, &height_src, 1 /* writable */ );
+
+       //fprintf( stderr, "mlt_frame_composite_yuv %dx%d -> %dx%d\n", width_src, height_src, width_dest, height_dest );
+       //fflush(stderr);
+       //return ret;
        stride_src = width_src * 2;
        stride_dest = width_dest * 2;
        
@@ -698,16 +703,23 @@ int mlt_frame_mix_audio( mlt_frame this, mlt_frame that, float weight, int16_t *
        int16_t *src, *dest;
        static int16_t *extra_src = NULL, *extra_dest = NULL;
        static int extra_src_samples = 0, extra_dest_samples = 0;
-       int frequency_src, frequency_dest;
-       int channels_src, channels_dest;
-       int samples_src, samples_dest;
+       int frequency_src = 0, frequency_dest = 0;
+       int channels_src = 0, channels_dest = 0;
+       int samples_src = 0, samples_dest = 0;
        int i, j;
 
        mlt_frame_get_audio( this, &p_dest, format, &frequency_dest, &channels_dest, &samples_dest );
+       //fprintf( stderr, "frame dest samples %d channels %d timecode %f\n", samples_dest, channels_dest, mlt_properties_get_timecode( mlt_frame_properties( this ), "timecode" ) );
        mlt_frame_get_audio( that, &p_src, format, &frequency_src, &channels_src, &samples_src );
-       //fprintf( stderr, "frame dest samples %d channels %d\n", samples_dest, channels_dest );
        //fprintf( stderr, "frame src  samples %d channels %d\n", samples_src, channels_src );
-       
+       if ( channels_src > 6 )
+               channels_src = 0;
+       if ( channels_dest > 6 )
+               channels_dest = 0;
+       if ( samples_src > 4000 )
+               samples_src = 0;
+       if ( samples_dest > 4000 )
+               samples_dest = 0;
 
 #if 0
        // Append new samples to leftovers
index f5be459836fc8ee18cbb0ea50b9867572e218dda..a3ae3dc7796090a8a392a16966a139da226125f1 100644 (file)
@@ -34,7 +34,7 @@ typedef struct
        struct mlt_transition_s parent;
        char *filename;
        int width;
-       int height;
+       int height;                                                     
        double *bitmap;
 }
 transition_luma;
@@ -313,7 +313,7 @@ static mlt_frame transition_process( mlt_transition transition, mlt_frame a_fram
 
        // If the filename property changed, reload the map
        char *luma_file = mlt_properties_get( properties, "filename" );
-       if ( luma_file != NULL && luma_file != this->filename )
+       if ( luma_file != NULL && ( this->filename == NULL || ( this->filename && strcmp( luma_file, this->filename ) ) ) )
        {
                int width = mlt_properties_get_int( b_props, "width" );
                int height = mlt_properties_get_int( b_props, "height" );
@@ -321,12 +321,16 @@ static mlt_frame transition_process( mlt_transition transition, mlt_frame a_fram
                FILE *pipe;
                
                command[ 511 ] = '\0';
-               this->filename = luma_file;
+               if ( this->filename )
+                       free( this->filename );
+               this->filename = strdup( luma_file );
                snprintf( command, 511, "anytopnm %s | pnmscale -width %d -height %d", luma_file, width, height );
                //pipe = popen( command, "r" );
                pipe = fopen( luma_file, "r" );
                if ( pipe != NULL )
                {
+                       if ( this->bitmap )
+                               free( this->bitmap );
                        luma_read_pgm( pipe, &this->bitmap, &this->width, &this->height );
                        //pclose( pipe );
                        fclose( pipe );
@@ -393,8 +397,9 @@ static void transition_close( mlt_transition parent )
        if ( this->bitmap )
                free( this->bitmap );
        
-       parent->close = NULL;
-       mlt_transition_close( parent );
+       if ( this->filename )
+               free( this->filename );
+
        free( this );
 }
 
index c1bf1d3f467ac4f8d42e1f5e3597731cdde9da8f..6609ce97756523c4295137c84c7dfec37b8058f6 100644 (file)
@@ -288,8 +288,8 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
                mlt_properties_set_double( properties, "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, 0, NULL, NULL );
-               mlt_properties_set_data( properties, "alpha", this->alpha, 0, NULL, NULL );
+               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;
index f1f1f45fe10d38cfce0342d7fe6e6a249e535acf..3bfe553de848529427d3c63d731eb2a79520edec 100644 (file)
@@ -197,8 +197,11 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
        // Obtain properties of frame
        mlt_properties properties = mlt_frame_properties( *frame );
 
+       // Obtain properties of producer
+       mlt_properties producer_props = mlt_producer_properties( producer );
+
        // Get the time to live for each frame
-       double ttl = mlt_properties_get_double( mlt_producer_properties( producer ), "ttl" );
+       double ttl = mlt_properties_get_double( producer_props, "ttl" );
 
        // Image index
        int image_idx = ( int )floor( mlt_producer_position( producer ) / ttl ) % this->count;
@@ -213,6 +216,11 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
                mlt_properties_set_int( properties, "width", this->width );
                mlt_properties_set_int( properties, "height", this->height );
 
+               // 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" ) );
+
                // 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 );
@@ -292,13 +300,18 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
                mlt_properties_set_int( properties, "width", this->width );
                mlt_properties_set_int( properties, "height", this->height );
 
+               // 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 alpha and image on properties with or without destructor
                this->image = image;
                this->alpha = alpha;
 
                // 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 );
+               mlt_properties_set_data( properties, "image", image, this->width * this->height * 2, NULL, NULL );
+               mlt_properties_set_data( properties, "alpha", alpha, this->width * this->height, NULL, NULL );
 
                // Set alpha call back
                ( *frame )->get_alpha_mask = producer_get_alpha_mask;
index 448e44e1bfc77d8e6f9fad26855f2689927933ac..3c7dd7898279be12d779b235801351e22b383087 100644 (file)
@@ -1,4 +1,4 @@
-TARGET = dan charlie
+TARGET = dan charlie pango pixbuf dissolve luma
 
 CFLAGS = -I .. -Wall -rdynamic -pthread
 
@@ -6,6 +6,18 @@ LDFLAGS = -L ../framework -lmlt
 
 all: $(TARGET)
 
+pango:         pango.o
+                       $(CC) pango.o -o $@ $(LDFLAGS)
+
+pixbuf:                pixbuf.o
+                       $(CC) pixbuf.o -o $@ $(LDFLAGS)
+
+dissolve:              dissolve.o
+                       $(CC) dissolve.o -o $@ $(LDFLAGS)
+
+luma:          luma.o
+                       $(CC) luma.o -o $@ $(LDFLAGS)
+
 dan:           dan.o 
                        $(CC) dan.o -o $@ $(LDFLAGS)
 
diff --git a/mlt/src/tests/clock16ntsc.pgm b/mlt/src/tests/clock16ntsc.pgm
new file mode 100644 (file)
index 0000000..61e64ad
Binary files /dev/null and b/mlt/src/tests/clock16ntsc.pgm differ
diff --git a/mlt/src/tests/clock16pal.pgm b/mlt/src/tests/clock16pal.pgm
new file mode 100644 (file)
index 0000000..4d7b0fc
Binary files /dev/null and b/mlt/src/tests/clock16pal.pgm differ
index b33cb7e89bbe039f18dc60fbf537797cebbe10da..0035b26958e8184647da93c5037d1aa6ad5cc641 100644 (file)
@@ -19,13 +19,13 @@ int main( int argc, char **argv )
        // Start the consumer...
        int vstd = mlt_video_standard_ntsc;
        //mlt_consumer consumer = mlt_factory_consumer( "bluefish", &vstd );
-       mlt_consumer consumer = mlt_factory_consumer( "sdl", "NTSC" );
+       mlt_consumer consumer = mlt_factory_consumer( "sdl", "PAL" );
 
        // Create the producer(s)
-       mlt_producer dv1 = mlt_factory_producer( "mcdv", file1 );
-       mlt_producer_set_in_and_out( dv1, 300, 305 );
+       mlt_producer dv1 = mlt_factory_producer( "libdv", file1 );
+       mlt_producer_set_in_and_out( dv1, 0, 5 );
        
-       mlt_producer dv2 = mlt_factory_producer( "mcdv", file2 );
+       mlt_producer dv2 = mlt_factory_producer( "libdv", file2 );
        //mlt_producer_set_in_and_out( dv2, 10.0, 30.0 );
 
 #if 0
@@ -56,6 +56,7 @@ int main( int argc, char **argv )
 
        mlt_playlist playlist1 = mlt_playlist_init();
        mlt_playlist_append( playlist1, dv1 );
+       mlt_playlist_blank( playlist1, 1.0 );
 
        mlt_playlist playlist2 = mlt_playlist_init();
        mlt_playlist_blank( playlist2, 3.0 );
@@ -75,7 +76,7 @@ int main( int argc, char **argv )
        mlt_transition transition = mlt_factory_transition( "luma", NULL );
        mlt_transition_connect( transition, mlt_multitrack_service( multitrack ), 0, 1 );
        mlt_transition_set_in_and_out( transition, 3.0, 5.0 );
-       mlt_properties_set( mlt_transition_properties( transition ), "filename", "clock.pgm" );
+       //mlt_properties_set( mlt_transition_properties( transition ), "filename", "clock.pgm" );
        mlt_properties_set_double( mlt_transition_properties( transition ), "softness", 0.1 );
 
        // Buy a tractor and connect it to the filter
diff --git a/mlt/src/tests/dissolve.c b/mlt/src/tests/dissolve.c
new file mode 100644 (file)
index 0000000..c911ae5
--- /dev/null
@@ -0,0 +1,72 @@
+
+#include <framework/mlt.h>
+
+#include <stdio.h>
+
+int main( int argc, char **argv )
+{
+       char temp[ 132 ];
+       char *file1 = NULL;
+       char *file2 = NULL;
+
+       mlt_factory_init( "../modules" );
+
+       if ( argc < 3 )
+       {
+               fprintf( stderr, "usage: dissolve file1.mpeg file2.mpeg\n" );
+               return 1;
+       }
+       else
+       {
+               file1 = argv[ 1 ];
+               file2 = argv[ 2 ];
+       }
+
+       // Start the consumer...
+       mlt_consumer consumer = mlt_factory_consumer( "sdl", "PAL" );
+
+       // Create the producer(s)
+       mlt_producer dv1 = mlt_factory_producer( "mcmpeg", file1 );
+       mlt_producer dv2 = mlt_factory_producer( "mcmpeg", file2 );
+
+       mlt_playlist playlist1 = mlt_playlist_init();
+       mlt_playlist_append_io( playlist1, dv1, 0.0, 5.0 );
+       mlt_playlist_blank( playlist1, 1.0 );
+
+       mlt_playlist playlist2 = mlt_playlist_init();
+       mlt_playlist_blank( playlist2, 2.9 );
+       mlt_playlist_append( playlist2, dv2 );
+       
+       // Register producers(s) with a multitrack object
+       mlt_multitrack multitrack = mlt_multitrack_init( );
+       mlt_multitrack_connect( multitrack, mlt_playlist_producer( playlist1 ), 0 );
+       mlt_multitrack_connect( multitrack, mlt_playlist_producer( playlist2 ), 1 );
+
+       // Define a transition
+       mlt_transition transition = mlt_factory_transition( "luma", NULL );
+       mlt_transition_connect( transition, mlt_multitrack_service( multitrack ), 0, 1 );
+       mlt_transition_set_in_and_out( transition, 3.0, 5.0 );
+
+       // Buy a tractor and connect it to the filter
+       mlt_tractor tractor = mlt_tractor_init( );
+       mlt_tractor_connect( tractor, mlt_transition_service( transition ) );
+
+       // Connect the tractor to the consumer
+       mlt_consumer_connect( consumer, mlt_tractor_service( tractor ) );
+
+       // 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 );
+       mlt_transition_close( transition );
+       mlt_multitrack_close( multitrack );
+       mlt_playlist_close( playlist1 );
+       mlt_playlist_close( playlist2 );
+       mlt_producer_close( dv1 );
+       mlt_producer_close( dv2 );
+
+       return 0;
+}
diff --git a/mlt/src/tests/luma.c b/mlt/src/tests/luma.c
new file mode 100644 (file)
index 0000000..d964adb
--- /dev/null
@@ -0,0 +1,76 @@
+
+#include <framework/mlt.h>
+
+#include <stdio.h>
+
+int main( int argc, char **argv )
+{
+       char temp[ 132 ];
+       char *file1 = NULL;
+       char *file2 = NULL;
+       char *wipe = NULL;
+
+       mlt_factory_init( "../modules" );
+
+       if ( argc < 4 )
+       {
+               fprintf( stderr, "usage: luma file1.mpeg file2.mpeg wipe.pgm\n" );
+               return 1;
+       }
+       else
+       {
+               file1 = argv[ 1 ];
+               file2 = argv[ 2 ];
+               wipe = argv[ 3 ];
+       }
+
+       // Start the consumer...
+       mlt_consumer consumer = mlt_factory_consumer( "sdl", "PAL" );
+
+       // Create the producer(s)
+       mlt_producer dv1 = mlt_factory_producer( "mcmpeg", file1 );
+       mlt_producer dv2 = mlt_factory_producer( "mcmpeg", file2 );
+
+       mlt_playlist playlist1 = mlt_playlist_init();
+       mlt_playlist_append_io( playlist1, dv1, 0.0, 5.0 );
+       mlt_playlist_blank( playlist1, 1.0 );
+
+       mlt_playlist playlist2 = mlt_playlist_init();
+       mlt_playlist_blank( playlist2, 2.9 );
+       mlt_playlist_append( playlist2, dv2 );
+       
+       // Register producers(s) with a multitrack object
+       mlt_multitrack multitrack = mlt_multitrack_init( );
+       mlt_multitrack_connect( multitrack, mlt_playlist_producer( playlist1 ), 0 );
+       mlt_multitrack_connect( multitrack, mlt_playlist_producer( playlist2 ), 1 );
+
+       // Define a transition
+       mlt_transition transition = mlt_factory_transition( "luma", wipe );
+       mlt_properties_set( mlt_transition_properties( transition ), "filename", wipe );
+       mlt_properties_set_double( mlt_transition_properties( transition ), "softness", 0.1 );
+       mlt_transition_connect( transition, mlt_multitrack_service( multitrack ), 0, 1 );
+       mlt_transition_set_in_and_out( transition, 3.0, 5.0 );
+
+       // Buy a tractor and connect it to the filter
+       mlt_tractor tractor = mlt_tractor_init( );
+       mlt_tractor_connect( tractor, mlt_transition_service( transition ) );
+
+       // Connect the tractor to the consumer
+       mlt_consumer_connect( consumer, mlt_tractor_service( tractor ) );
+
+       // 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 );
+       mlt_transition_close( transition );
+       mlt_multitrack_close( multitrack );
+       mlt_playlist_close( playlist1 );
+       mlt_playlist_close( playlist2 );
+       mlt_producer_close( dv1 );
+       mlt_producer_close( dv2 );
+
+       return 0;
+}
diff --git a/mlt/src/tests/pango.c b/mlt/src/tests/pango.c
new file mode 100644 (file)
index 0000000..eaf9758
--- /dev/null
@@ -0,0 +1,78 @@
+
+#include <framework/mlt.h>
+
+#include <stdio.h>
+
+int main( int argc, char **argv )
+{
+       char temp[ 132 ];
+       char *file1 = NULL;
+       char *text = NULL;
+
+       mlt_factory_init( "../modules" );
+
+       if ( argc < 3 )
+       {
+               fprintf( stderr, "usage: pango file.mpeg  text_to_display\n" );
+               return 1;
+       }
+       else
+       {
+               file1 = argv[ 1 ];
+               text = argv[ 2 ];
+       }
+
+       // Start the consumer...
+       mlt_consumer consumer = mlt_factory_consumer( "sdl", "PAL" );
+
+       // Create the producer(s)
+       mlt_playlist pl1 = mlt_playlist_init();
+       mlt_producer dv1 = mlt_factory_producer( "mcmpeg", file1 );
+       mlt_playlist_append( pl1, dv1 );
+
+       mlt_playlist pl2 = mlt_playlist_init();
+       mlt_producer title = 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_playlist_append( pl2, title );
+       mlt_properties_set_int( mlt_producer_properties( title ), "video_standard", mlt_video_standard_pal );
+       mlt_properties_set( mlt_producer_properties( title ), "font", "Sans Bold 36" );
+       mlt_properties_set( mlt_producer_properties( title ), "text", text );
+       mlt_properties_set_int( mlt_producer_properties( title ), "bgcolor", 0x0000007f );
+       mlt_properties_set_int( mlt_producer_properties( title ), "pad", 8 );
+       mlt_properties_set_int( mlt_producer_properties( title ), "align", 1 );
+       mlt_properties_set_int( mlt_producer_properties( title ), "x", 20 );
+       mlt_properties_set_int( mlt_producer_properties( title ), "y", 40 );
+       mlt_properties_set_double( mlt_producer_properties( title ), "mix", 0.8 );
+
+       // Register producers(s) with a multitrack object
+       mlt_multitrack multitrack = mlt_multitrack_init( );
+       mlt_multitrack_connect( multitrack, mlt_playlist_producer( pl1 ), 0 );
+       mlt_multitrack_connect( multitrack, mlt_playlist_producer( pl2 ), 1 );
+
+       // 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.0, 9999.0 );
+
+       // Buy a tractor and connect it to the filter
+       mlt_tractor tractor = mlt_tractor_init( );
+       mlt_tractor_connect( tractor, mlt_transition_service( transition ) );
+
+       // Connect the tractor to the consumer
+       mlt_consumer_connect( consumer, mlt_tractor_service( tractor ) );
+
+       // 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 );
+       mlt_transition_close( transition );
+       mlt_multitrack_close( multitrack );
+       mlt_playlist_close( pl1 );
+       mlt_playlist_close( pl2 );
+       mlt_producer_close( dv1 );
+       mlt_producer_close( title );
+
+       return 0;
+}
diff --git a/mlt/src/tests/pixbuf.c b/mlt/src/tests/pixbuf.c
new file mode 100644 (file)
index 0000000..64a23b7
--- /dev/null
@@ -0,0 +1,73 @@
+
+#include <framework/mlt.h>
+
+#include <stdio.h>
+
+int main( int argc, char **argv )
+{
+       char temp[ 132 ];
+       char *file1 = NULL;
+       char *file2 = NULL;
+
+       mlt_factory_init( "../modules" );
+
+       if ( argc < 3 )
+       {
+               fprintf( stderr, "usage: pixbuf file.mpeg file.{png,jpg,etc}\n" );
+               return 1;
+       }
+       else
+       {
+               file1 = argv[ 1 ];
+               file2 = argv[ 2 ];
+       }
+
+       // Start the consumer...
+       mlt_consumer consumer = mlt_factory_consumer( "sdl", "PAL" );
+
+       // Create the producer(s)
+       mlt_playlist pl1 = mlt_playlist_init();
+       mlt_producer dv1 = mlt_factory_producer( "mcmpeg", file1 );
+       mlt_playlist_append( pl1, dv1 );
+
+       mlt_playlist pl2 = mlt_playlist_init();
+       mlt_producer overlay = mlt_factory_producer( "pixbuf", file2 );
+       mlt_playlist_append( pl2, overlay );
+       mlt_properties_set_int( mlt_producer_properties( overlay ), "video_standard", mlt_video_standard_pal );
+       mlt_properties_set_int( mlt_producer_properties( overlay ), "x", 600 );
+       mlt_properties_set_int( mlt_producer_properties( overlay ), "y", 460 );
+       mlt_properties_set_double( mlt_producer_properties( overlay ), "mix", 0.8 );
+
+       // Register producers(s) with a multitrack object
+       mlt_multitrack multitrack = mlt_multitrack_init( );
+       mlt_multitrack_connect( multitrack, mlt_playlist_producer( pl1 ), 0 );
+       mlt_multitrack_connect( multitrack, mlt_playlist_producer( pl2 ), 1 );
+
+       // 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.0, 9999.0 );
+
+       // Buy a tractor and connect it to the filter
+       mlt_tractor tractor = mlt_tractor_init( );
+       mlt_tractor_connect( tractor, mlt_transition_service( transition ) );
+
+       // Connect the tractor to the consumer
+       mlt_consumer_connect( consumer, mlt_tractor_service( tractor ) );
+
+       // 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 );
+       mlt_transition_close( transition );
+       mlt_multitrack_close( multitrack );
+       mlt_playlist_close( pl1 );
+       mlt_playlist_close( pl2 );
+       mlt_producer_close( dv1 );
+       mlt_producer_close( overlay );
+
+       return 0;
+}
index 3b11fcf1357317f3819f2dd7ecdde1cc2d562f21..ba59ad9609cf21fedd0273cd51a8ae0e86474203 100644 (file)
@@ -412,10 +412,15 @@ int mlt_frame_composite_yuv( mlt_frame this, mlt_frame that, int x, int y, float
 
        format_src = mlt_image_yuv422;
        format_dest = mlt_image_yuv422;
-       
+
+       //fprintf( stderr, "call get_image on frame a\n"), fflush( stderr );
        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 */ );
-       
+       //fprintf( stderr, "call get_image on frame b\n"), fflush( stderr );
+       mlt_frame_get_image( that, &p_src, &format_src, &width_src, &height_src, 1 /* writable */ );
+
+       //fprintf( stderr, "mlt_frame_composite_yuv %dx%d -> %dx%d\n", width_src, height_src, width_dest, height_dest );
+       //fflush(stderr);
+       //return ret;
        stride_src = width_src * 2;
        stride_dest = width_dest * 2;
        
@@ -698,16 +703,23 @@ int mlt_frame_mix_audio( mlt_frame this, mlt_frame that, float weight, int16_t *
        int16_t *src, *dest;
        static int16_t *extra_src = NULL, *extra_dest = NULL;
        static int extra_src_samples = 0, extra_dest_samples = 0;
-       int frequency_src, frequency_dest;
-       int channels_src, channels_dest;
-       int samples_src, samples_dest;
+       int frequency_src = 0, frequency_dest = 0;
+       int channels_src = 0, channels_dest = 0;
+       int samples_src = 0, samples_dest = 0;
        int i, j;
 
        mlt_frame_get_audio( this, &p_dest, format, &frequency_dest, &channels_dest, &samples_dest );
+       //fprintf( stderr, "frame dest samples %d channels %d timecode %f\n", samples_dest, channels_dest, mlt_properties_get_timecode( mlt_frame_properties( this ), "timecode" ) );
        mlt_frame_get_audio( that, &p_src, format, &frequency_src, &channels_src, &samples_src );
-       //fprintf( stderr, "frame dest samples %d channels %d\n", samples_dest, channels_dest );
        //fprintf( stderr, "frame src  samples %d channels %d\n", samples_src, channels_src );
-       
+       if ( channels_src > 6 )
+               channels_src = 0;
+       if ( channels_dest > 6 )
+               channels_dest = 0;
+       if ( samples_src > 4000 )
+               samples_src = 0;
+       if ( samples_dest > 4000 )
+               samples_dest = 0;
 
 #if 0
        // Append new samples to leftovers
index f5be459836fc8ee18cbb0ea50b9867572e218dda..a3ae3dc7796090a8a392a16966a139da226125f1 100644 (file)
@@ -34,7 +34,7 @@ typedef struct
        struct mlt_transition_s parent;
        char *filename;
        int width;
-       int height;
+       int height;                                                     
        double *bitmap;
 }
 transition_luma;
@@ -313,7 +313,7 @@ static mlt_frame transition_process( mlt_transition transition, mlt_frame a_fram
 
        // If the filename property changed, reload the map
        char *luma_file = mlt_properties_get( properties, "filename" );
-       if ( luma_file != NULL && luma_file != this->filename )
+       if ( luma_file != NULL && ( this->filename == NULL || ( this->filename && strcmp( luma_file, this->filename ) ) ) )
        {
                int width = mlt_properties_get_int( b_props, "width" );
                int height = mlt_properties_get_int( b_props, "height" );
@@ -321,12 +321,16 @@ static mlt_frame transition_process( mlt_transition transition, mlt_frame a_fram
                FILE *pipe;
                
                command[ 511 ] = '\0';
-               this->filename = luma_file;
+               if ( this->filename )
+                       free( this->filename );
+               this->filename = strdup( luma_file );
                snprintf( command, 511, "anytopnm %s | pnmscale -width %d -height %d", luma_file, width, height );
                //pipe = popen( command, "r" );
                pipe = fopen( luma_file, "r" );
                if ( pipe != NULL )
                {
+                       if ( this->bitmap )
+                               free( this->bitmap );
                        luma_read_pgm( pipe, &this->bitmap, &this->width, &this->height );
                        //pclose( pipe );
                        fclose( pipe );
@@ -393,8 +397,9 @@ static void transition_close( mlt_transition parent )
        if ( this->bitmap )
                free( this->bitmap );
        
-       parent->close = NULL;
-       mlt_transition_close( parent );
+       if ( this->filename )
+               free( this->filename );
+
        free( this );
 }
 
index c1bf1d3f467ac4f8d42e1f5e3597731cdde9da8f..6609ce97756523c4295137c84c7dfec37b8058f6 100644 (file)
@@ -288,8 +288,8 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
                mlt_properties_set_double( properties, "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, 0, NULL, NULL );
-               mlt_properties_set_data( properties, "alpha", this->alpha, 0, NULL, NULL );
+               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;
index f1f1f45fe10d38cfce0342d7fe6e6a249e535acf..3bfe553de848529427d3c63d731eb2a79520edec 100644 (file)
@@ -197,8 +197,11 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
        // Obtain properties of frame
        mlt_properties properties = mlt_frame_properties( *frame );
 
+       // Obtain properties of producer
+       mlt_properties producer_props = mlt_producer_properties( producer );
+
        // Get the time to live for each frame
-       double ttl = mlt_properties_get_double( mlt_producer_properties( producer ), "ttl" );
+       double ttl = mlt_properties_get_double( producer_props, "ttl" );
 
        // Image index
        int image_idx = ( int )floor( mlt_producer_position( producer ) / ttl ) % this->count;
@@ -213,6 +216,11 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
                mlt_properties_set_int( properties, "width", this->width );
                mlt_properties_set_int( properties, "height", this->height );
 
+               // 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" ) );
+
                // 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 );
@@ -292,13 +300,18 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
                mlt_properties_set_int( properties, "width", this->width );
                mlt_properties_set_int( properties, "height", this->height );
 
+               // 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 alpha and image on properties with or without destructor
                this->image = image;
                this->alpha = alpha;
 
                // 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 );
+               mlt_properties_set_data( properties, "image", image, this->width * this->height * 2, NULL, NULL );
+               mlt_properties_set_data( properties, "alpha", alpha, this->width * this->height, NULL, NULL );
 
                // Set alpha call back
                ( *frame )->get_alpha_mask = producer_get_alpha_mask;
index 448e44e1bfc77d8e6f9fad26855f2689927933ac..3c7dd7898279be12d779b235801351e22b383087 100644 (file)
@@ -1,4 +1,4 @@
-TARGET = dan charlie
+TARGET = dan charlie pango pixbuf dissolve luma
 
 CFLAGS = -I .. -Wall -rdynamic -pthread
 
@@ -6,6 +6,18 @@ LDFLAGS = -L ../framework -lmlt
 
 all: $(TARGET)
 
+pango:         pango.o
+                       $(CC) pango.o -o $@ $(LDFLAGS)
+
+pixbuf:                pixbuf.o
+                       $(CC) pixbuf.o -o $@ $(LDFLAGS)
+
+dissolve:              dissolve.o
+                       $(CC) dissolve.o -o $@ $(LDFLAGS)
+
+luma:          luma.o
+                       $(CC) luma.o -o $@ $(LDFLAGS)
+
 dan:           dan.o 
                        $(CC) dan.o -o $@ $(LDFLAGS)
 
diff --git a/src/tests/clock16ntsc.pgm b/src/tests/clock16ntsc.pgm
new file mode 100644 (file)
index 0000000..61e64ad
Binary files /dev/null and b/src/tests/clock16ntsc.pgm differ
diff --git a/src/tests/clock16pal.pgm b/src/tests/clock16pal.pgm
new file mode 100644 (file)
index 0000000..4d7b0fc
Binary files /dev/null and b/src/tests/clock16pal.pgm differ
index b33cb7e89bbe039f18dc60fbf537797cebbe10da..0035b26958e8184647da93c5037d1aa6ad5cc641 100644 (file)
@@ -19,13 +19,13 @@ int main( int argc, char **argv )
        // Start the consumer...
        int vstd = mlt_video_standard_ntsc;
        //mlt_consumer consumer = mlt_factory_consumer( "bluefish", &vstd );
-       mlt_consumer consumer = mlt_factory_consumer( "sdl", "NTSC" );
+       mlt_consumer consumer = mlt_factory_consumer( "sdl", "PAL" );
 
        // Create the producer(s)
-       mlt_producer dv1 = mlt_factory_producer( "mcdv", file1 );
-       mlt_producer_set_in_and_out( dv1, 300, 305 );
+       mlt_producer dv1 = mlt_factory_producer( "libdv", file1 );
+       mlt_producer_set_in_and_out( dv1, 0, 5 );
        
-       mlt_producer dv2 = mlt_factory_producer( "mcdv", file2 );
+       mlt_producer dv2 = mlt_factory_producer( "libdv", file2 );
        //mlt_producer_set_in_and_out( dv2, 10.0, 30.0 );
 
 #if 0
@@ -56,6 +56,7 @@ int main( int argc, char **argv )
 
        mlt_playlist playlist1 = mlt_playlist_init();
        mlt_playlist_append( playlist1, dv1 );
+       mlt_playlist_blank( playlist1, 1.0 );
 
        mlt_playlist playlist2 = mlt_playlist_init();
        mlt_playlist_blank( playlist2, 3.0 );
@@ -75,7 +76,7 @@ int main( int argc, char **argv )
        mlt_transition transition = mlt_factory_transition( "luma", NULL );
        mlt_transition_connect( transition, mlt_multitrack_service( multitrack ), 0, 1 );
        mlt_transition_set_in_and_out( transition, 3.0, 5.0 );
-       mlt_properties_set( mlt_transition_properties( transition ), "filename", "clock.pgm" );
+       //mlt_properties_set( mlt_transition_properties( transition ), "filename", "clock.pgm" );
        mlt_properties_set_double( mlt_transition_properties( transition ), "softness", 0.1 );
 
        // Buy a tractor and connect it to the filter
diff --git a/src/tests/dissolve.c b/src/tests/dissolve.c
new file mode 100644 (file)
index 0000000..c911ae5
--- /dev/null
@@ -0,0 +1,72 @@
+
+#include <framework/mlt.h>
+
+#include <stdio.h>
+
+int main( int argc, char **argv )
+{
+       char temp[ 132 ];
+       char *file1 = NULL;
+       char *file2 = NULL;
+
+       mlt_factory_init( "../modules" );
+
+       if ( argc < 3 )
+       {
+               fprintf( stderr, "usage: dissolve file1.mpeg file2.mpeg\n" );
+               return 1;
+       }
+       else
+       {
+               file1 = argv[ 1 ];
+               file2 = argv[ 2 ];
+       }
+
+       // Start the consumer...
+       mlt_consumer consumer = mlt_factory_consumer( "sdl", "PAL" );
+
+       // Create the producer(s)
+       mlt_producer dv1 = mlt_factory_producer( "mcmpeg", file1 );
+       mlt_producer dv2 = mlt_factory_producer( "mcmpeg", file2 );
+
+       mlt_playlist playlist1 = mlt_playlist_init();
+       mlt_playlist_append_io( playlist1, dv1, 0.0, 5.0 );
+       mlt_playlist_blank( playlist1, 1.0 );
+
+       mlt_playlist playlist2 = mlt_playlist_init();
+       mlt_playlist_blank( playlist2, 2.9 );
+       mlt_playlist_append( playlist2, dv2 );
+       
+       // Register producers(s) with a multitrack object
+       mlt_multitrack multitrack = mlt_multitrack_init( );
+       mlt_multitrack_connect( multitrack, mlt_playlist_producer( playlist1 ), 0 );
+       mlt_multitrack_connect( multitrack, mlt_playlist_producer( playlist2 ), 1 );
+
+       // Define a transition
+       mlt_transition transition = mlt_factory_transition( "luma", NULL );
+       mlt_transition_connect( transition, mlt_multitrack_service( multitrack ), 0, 1 );
+       mlt_transition_set_in_and_out( transition, 3.0, 5.0 );
+
+       // Buy a tractor and connect it to the filter
+       mlt_tractor tractor = mlt_tractor_init( );
+       mlt_tractor_connect( tractor, mlt_transition_service( transition ) );
+
+       // Connect the tractor to the consumer
+       mlt_consumer_connect( consumer, mlt_tractor_service( tractor ) );
+
+       // 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 );
+       mlt_transition_close( transition );
+       mlt_multitrack_close( multitrack );
+       mlt_playlist_close( playlist1 );
+       mlt_playlist_close( playlist2 );
+       mlt_producer_close( dv1 );
+       mlt_producer_close( dv2 );
+
+       return 0;
+}
diff --git a/src/tests/luma.c b/src/tests/luma.c
new file mode 100644 (file)
index 0000000..d964adb
--- /dev/null
@@ -0,0 +1,76 @@
+
+#include <framework/mlt.h>
+
+#include <stdio.h>
+
+int main( int argc, char **argv )
+{
+       char temp[ 132 ];
+       char *file1 = NULL;
+       char *file2 = NULL;
+       char *wipe = NULL;
+
+       mlt_factory_init( "../modules" );
+
+       if ( argc < 4 )
+       {
+               fprintf( stderr, "usage: luma file1.mpeg file2.mpeg wipe.pgm\n" );
+               return 1;
+       }
+       else
+       {
+               file1 = argv[ 1 ];
+               file2 = argv[ 2 ];
+               wipe = argv[ 3 ];
+       }
+
+       // Start the consumer...
+       mlt_consumer consumer = mlt_factory_consumer( "sdl", "PAL" );
+
+       // Create the producer(s)
+       mlt_producer dv1 = mlt_factory_producer( "mcmpeg", file1 );
+       mlt_producer dv2 = mlt_factory_producer( "mcmpeg", file2 );
+
+       mlt_playlist playlist1 = mlt_playlist_init();
+       mlt_playlist_append_io( playlist1, dv1, 0.0, 5.0 );
+       mlt_playlist_blank( playlist1, 1.0 );
+
+       mlt_playlist playlist2 = mlt_playlist_init();
+       mlt_playlist_blank( playlist2, 2.9 );
+       mlt_playlist_append( playlist2, dv2 );
+       
+       // Register producers(s) with a multitrack object
+       mlt_multitrack multitrack = mlt_multitrack_init( );
+       mlt_multitrack_connect( multitrack, mlt_playlist_producer( playlist1 ), 0 );
+       mlt_multitrack_connect( multitrack, mlt_playlist_producer( playlist2 ), 1 );
+
+       // Define a transition
+       mlt_transition transition = mlt_factory_transition( "luma", wipe );
+       mlt_properties_set( mlt_transition_properties( transition ), "filename", wipe );
+       mlt_properties_set_double( mlt_transition_properties( transition ), "softness", 0.1 );
+       mlt_transition_connect( transition, mlt_multitrack_service( multitrack ), 0, 1 );
+       mlt_transition_set_in_and_out( transition, 3.0, 5.0 );
+
+       // Buy a tractor and connect it to the filter
+       mlt_tractor tractor = mlt_tractor_init( );
+       mlt_tractor_connect( tractor, mlt_transition_service( transition ) );
+
+       // Connect the tractor to the consumer
+       mlt_consumer_connect( consumer, mlt_tractor_service( tractor ) );
+
+       // 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 );
+       mlt_transition_close( transition );
+       mlt_multitrack_close( multitrack );
+       mlt_playlist_close( playlist1 );
+       mlt_playlist_close( playlist2 );
+       mlt_producer_close( dv1 );
+       mlt_producer_close( dv2 );
+
+       return 0;
+}
diff --git a/src/tests/pango.c b/src/tests/pango.c
new file mode 100644 (file)
index 0000000..eaf9758
--- /dev/null
@@ -0,0 +1,78 @@
+
+#include <framework/mlt.h>
+
+#include <stdio.h>
+
+int main( int argc, char **argv )
+{
+       char temp[ 132 ];
+       char *file1 = NULL;
+       char *text = NULL;
+
+       mlt_factory_init( "../modules" );
+
+       if ( argc < 3 )
+       {
+               fprintf( stderr, "usage: pango file.mpeg  text_to_display\n" );
+               return 1;
+       }
+       else
+       {
+               file1 = argv[ 1 ];
+               text = argv[ 2 ];
+       }
+
+       // Start the consumer...
+       mlt_consumer consumer = mlt_factory_consumer( "sdl", "PAL" );
+
+       // Create the producer(s)
+       mlt_playlist pl1 = mlt_playlist_init();
+       mlt_producer dv1 = mlt_factory_producer( "mcmpeg", file1 );
+       mlt_playlist_append( pl1, dv1 );
+
+       mlt_playlist pl2 = mlt_playlist_init();
+       mlt_producer title = 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_playlist_append( pl2, title );
+       mlt_properties_set_int( mlt_producer_properties( title ), "video_standard", mlt_video_standard_pal );
+       mlt_properties_set( mlt_producer_properties( title ), "font", "Sans Bold 36" );
+       mlt_properties_set( mlt_producer_properties( title ), "text", text );
+       mlt_properties_set_int( mlt_producer_properties( title ), "bgcolor", 0x0000007f );
+       mlt_properties_set_int( mlt_producer_properties( title ), "pad", 8 );
+       mlt_properties_set_int( mlt_producer_properties( title ), "align", 1 );
+       mlt_properties_set_int( mlt_producer_properties( title ), "x", 20 );
+       mlt_properties_set_int( mlt_producer_properties( title ), "y", 40 );
+       mlt_properties_set_double( mlt_producer_properties( title ), "mix", 0.8 );
+
+       // Register producers(s) with a multitrack object
+       mlt_multitrack multitrack = mlt_multitrack_init( );
+       mlt_multitrack_connect( multitrack, mlt_playlist_producer( pl1 ), 0 );
+       mlt_multitrack_connect( multitrack, mlt_playlist_producer( pl2 ), 1 );
+
+       // 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.0, 9999.0 );
+
+       // Buy a tractor and connect it to the filter
+       mlt_tractor tractor = mlt_tractor_init( );
+       mlt_tractor_connect( tractor, mlt_transition_service( transition ) );
+
+       // Connect the tractor to the consumer
+       mlt_consumer_connect( consumer, mlt_tractor_service( tractor ) );
+
+       // 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 );
+       mlt_transition_close( transition );
+       mlt_multitrack_close( multitrack );
+       mlt_playlist_close( pl1 );
+       mlt_playlist_close( pl2 );
+       mlt_producer_close( dv1 );
+       mlt_producer_close( title );
+
+       return 0;
+}
diff --git a/src/tests/pixbuf.c b/src/tests/pixbuf.c
new file mode 100644 (file)
index 0000000..64a23b7
--- /dev/null
@@ -0,0 +1,73 @@
+
+#include <framework/mlt.h>
+
+#include <stdio.h>
+
+int main( int argc, char **argv )
+{
+       char temp[ 132 ];
+       char *file1 = NULL;
+       char *file2 = NULL;
+
+       mlt_factory_init( "../modules" );
+
+       if ( argc < 3 )
+       {
+               fprintf( stderr, "usage: pixbuf file.mpeg file.{png,jpg,etc}\n" );
+               return 1;
+       }
+       else
+       {
+               file1 = argv[ 1 ];
+               file2 = argv[ 2 ];
+       }
+
+       // Start the consumer...
+       mlt_consumer consumer = mlt_factory_consumer( "sdl", "PAL" );
+
+       // Create the producer(s)
+       mlt_playlist pl1 = mlt_playlist_init();
+       mlt_producer dv1 = mlt_factory_producer( "mcmpeg", file1 );
+       mlt_playlist_append( pl1, dv1 );
+
+       mlt_playlist pl2 = mlt_playlist_init();
+       mlt_producer overlay = mlt_factory_producer( "pixbuf", file2 );
+       mlt_playlist_append( pl2, overlay );
+       mlt_properties_set_int( mlt_producer_properties( overlay ), "video_standard", mlt_video_standard_pal );
+       mlt_properties_set_int( mlt_producer_properties( overlay ), "x", 600 );
+       mlt_properties_set_int( mlt_producer_properties( overlay ), "y", 460 );
+       mlt_properties_set_double( mlt_producer_properties( overlay ), "mix", 0.8 );
+
+       // Register producers(s) with a multitrack object
+       mlt_multitrack multitrack = mlt_multitrack_init( );
+       mlt_multitrack_connect( multitrack, mlt_playlist_producer( pl1 ), 0 );
+       mlt_multitrack_connect( multitrack, mlt_playlist_producer( pl2 ), 1 );
+
+       // 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.0, 9999.0 );
+
+       // Buy a tractor and connect it to the filter
+       mlt_tractor tractor = mlt_tractor_init( );
+       mlt_tractor_connect( tractor, mlt_transition_service( transition ) );
+
+       // Connect the tractor to the consumer
+       mlt_consumer_connect( consumer, mlt_tractor_service( tractor ) );
+
+       // 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 );
+       mlt_transition_close( transition );
+       mlt_multitrack_close( multitrack );
+       mlt_playlist_close( pl1 );
+       mlt_playlist_close( pl2 );
+       mlt_producer_close( dv1 );
+       mlt_producer_close( overlay );
+
+       return 0;
+}