]> git.sesse.net Git - mlt/commitdiff
pixbuf, composite and fezzik mirrors
authorlilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
Sun, 8 Feb 2004 14:29:40 +0000 (14:29 +0000)
committerlilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
Sun, 8 Feb 2004 14:29:40 +0000 (14:29 +0000)
git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@124 d19143bc-622f-0410-bfdd-b5b2a6649095

src/framework/mlt_properties.c
src/framework/mlt_properties.h
src/modules/core/transition_composite.c
src/modules/fezzik/producer_fezzik.c
src/modules/gtk2/filter_rescale.c
src/modules/gtk2/producer_pango.c
src/modules/gtk2/producer_pixbuf.c

index be4d66fc811f705bfb6c092ae39cfe2768ef58ec..27f4a27b6e41c3b43b0b25c3f43dd7db88a4eb32 100644 (file)
@@ -72,6 +72,30 @@ mlt_properties mlt_properties_new( )
        return this;
 }
 
+/** Special case - when a container (such as fezzik) is protecting another 
+       producer, we need to ensure that properties are passed through to the
+       real producer.
+*/
+
+static void mlt_properties_do_mirror( mlt_properties this, char *name )
+{
+       mlt_properties mirror = mlt_properties_get_data( this, "mlt_mirror", NULL );
+       if ( mirror != NULL )
+       {
+               char *value = mlt_properties_get( this, name );
+               if ( value != NULL )
+                       mlt_properties_set( mirror, name, value );
+       }
+}
+
+/** Allow the specification of a mirror.
+*/
+
+void mlt_properties_mirror( mlt_properties this, mlt_properties that )
+{
+       mlt_properties_set_data( this, "mlt_mirror", that, 0, NULL, NULL );
+}
+
 /** Inherit all serialisable properties from that into this.
 */
 
@@ -158,7 +182,10 @@ int mlt_properties_set( mlt_properties this, char *name, char *value )
 
        // Set it if not NULL
        if ( property != NULL )
+       {
                error = mlt_property_set_string( property, value );
+               mlt_properties_do_mirror( this, name );
+       }
 
        return error;
 }
@@ -251,7 +278,10 @@ int mlt_properties_set_int( mlt_properties this, char *name, int value )
 
        // Set it if not NULL
        if ( property != NULL )
+       {
                error = mlt_property_set_int( property, value );
+               mlt_properties_do_mirror( this, name );
+       }
 
        return error;
 }
@@ -277,7 +307,10 @@ int mlt_properties_set_double( mlt_properties this, char *name, double value )
 
        // Set it if not NULL
        if ( property != NULL )
+       {
                error = mlt_property_set_double( property, value );
+               mlt_properties_do_mirror( this, name );
+       }
 
        return error;
 }
@@ -303,7 +336,10 @@ int mlt_properties_set_position( mlt_properties this, char *name, mlt_position v
 
        // Set it if not NULL
        if ( property != NULL )
+       {
                error = mlt_property_set_position( property, value );
+               mlt_properties_do_mirror( this, name );
+       }
 
        return error;
 }
index 2cacc9f8d5bf07538c5fae040e3a013b9c85e470..1527f3887818e6e132ee08f5ccc7470f1bfc6833 100644 (file)
@@ -38,6 +38,7 @@ struct mlt_properties_s
 
 extern int mlt_properties_init( mlt_properties, void *child );
 extern mlt_properties mlt_properties_new( );
+extern void mlt_properties_mirror( mlt_properties this, mlt_properties that );
 extern int mlt_properties_inherit( mlt_properties this, mlt_properties that );
 extern int mlt_properties_set( mlt_properties this, char *name, char *value );
 extern int mlt_properties_parse( mlt_properties this, char *namevalue );
index 2903bb0300bf53b0fc6f894764d2fe617dcef27b..106b193a20df5a28b7586a43f48804482b2fbca8 100644 (file)
@@ -108,8 +108,32 @@ static int composite_yuv( uint8_t *p_dest, mlt_image_format format_dest, int wid
        int width_src = ( int )( ( float )width_dest * geometry.w / 100 );
        int height_src = ( int )( ( float )height_dest * geometry.h / 100 );
 
+       mlt_properties b_props = mlt_frame_properties( that );
+       mlt_transition this = mlt_properties_get_data( b_props, "transition_composite", NULL );
+       mlt_properties properties = mlt_transition_properties( this );
+
+       if ( mlt_properties_get( properties, "distort" ) == NULL &&
+                mlt_properties_get( mlt_frame_properties( that ), "real_width" ) != NULL )
+       {
+               int width_b = mlt_properties_get_int( mlt_frame_properties( that ), "real_width" );
+               int height_b = mlt_properties_get_int( mlt_frame_properties( that ), "real_height" );
+
+               if ( width_b < width_src )
+                       width_src = width_b;
+               if ( height_b < height_src )
+                       height_src = height_b;
+               mlt_properties_set( mlt_frame_properties( that ), "rescale.interp", "none" );
+       }
+       else if ( mlt_properties_get( mlt_frame_properties( that ), "real_width" ) != NULL )
+       {
+               mlt_properties_set( mlt_frame_properties( that ), "rescale.interp", "none" );
+       }
+
        x -= x % 2;
 
+       if ( width_src <= 0 || height_src <= 0 )
+               return ret;
+
        // optimization point - no work to do
        if ( ( x < 0 && -x >= width_src ) || ( y < 0 && -y >= height_src ) )
                return ret;
index 4ff34eb7cbd09be82aac3e8bbe68889bb1619123..bd43e1ccb75757fe60caba1524af4a995af4ef1e 100644 (file)
@@ -149,6 +149,9 @@ mlt_producer producer_fezzik_init( char *arg )
                        // and fezzik doesn't overdo it with throwing rocks...
                        mlt_properties_set( properties, "westley", "was here" );
 
+                       // We need to ensure that all further properties are mirrored in the producer
+                       mlt_properties_mirror( properties, mlt_producer_properties( producer ) );
+
                        // Now, we return the producer of the tractor
                        producer = mlt_tractor_producer( tractor );
                }
index d9c7f83a2a2d38ecc74d52d830dd0a5792e77968..f061038c5efa0046865c0ff81fc015eb6f54d26c 100644 (file)
@@ -71,7 +71,7 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
 #endif
        
        // If width and height are correct, don't do anything
-       if ( input != NULL && ( iwidth != owidth || iheight != oheight ) )
+       if ( strcmp( interps, "none" ) && input != NULL && ( iwidth != owidth || iheight != oheight ) )
        {
                if ( *format == mlt_image_yuv422 )
                {
index 1b307438e73e79b9060089cab4f98dd51844ad97..523238982053e7787d68871ac3df11db80c8efd1 100644 (file)
@@ -88,6 +88,16 @@ mlt_producer producer_pango_init( const char *filename )
                        mlt_properties_set( properties, "resource", "pango" );
                        mlt_properties_set( properties, "markup", "" );
                }
+               else if ( filename[ 0 ] == '+' )
+               {
+                       char *markup = strdup( filename + 1 );
+                       ( *strrchr( markup, '.' ) ) = '\0';
+                       while ( strchr( markup, '~' ) )
+                               ( *strchr( markup, '~' ) ) = '\n';
+                       mlt_properties_set( properties, "resource", ( char * )filename );
+                       mlt_properties_set( properties, "markup", markup );
+                       free( markup );
+               }
                else
                {
                        FILE *f = fopen( filename, "r" );
@@ -112,10 +122,13 @@ mlt_producer producer_pango_init( const char *filename )
                                        }
                                }
                                fclose( f );
+
+                               if ( markup[ strlen( markup ) - 1 ] == '\n' ) 
+                                       markup[ strlen( markup ) - 1 ] = '\0';
+
                                mlt_properties_set( properties, "resource", ( char * ) filename );
                                mlt_properties_set( properties, "markup", ( char * ) ( markup == NULL ? "" : markup ) );
-                               if ( markup )
-                                       free( markup );
+                               free( markup );
                        }
                        else
                        {
@@ -211,12 +224,15 @@ static void refresh_image( mlt_frame frame, int width, int height )
                        // Register this pixbuf for destruction and reuse
                        mlt_properties_set_data( producer_props, "pixbuf", pixbuf, 0, ( mlt_destructor )g_object_unref, NULL );
 
+                       mlt_properties_set_int( producer_props, "real_width", gdk_pixbuf_get_width( pixbuf ) );
+                       mlt_properties_set_int( producer_props, "real_height", gdk_pixbuf_get_height( pixbuf ) );
+
                        // Store the width/height of the pixbuf temporarily
                        this->width = gdk_pixbuf_get_width( pixbuf );
                        this->height = gdk_pixbuf_get_height( pixbuf );
                }
        }
-       else if ( width != this->width || height != this->height )
+       else if ( this->image == NULL || width != this->width || height != this->height )
        {
                pixbuf = mlt_properties_get_data( producer_props, "pixbuf", NULL );
        }
@@ -224,15 +240,8 @@ static void refresh_image( mlt_frame frame, int width, int height )
        // 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 )
-               {
-                       // Note - the original pixbuf is already safe and ready for destruction
-                       pixbuf = gdk_pixbuf_scale_simple( pixbuf, width, height, GDK_INTERP_HYPER );
-                       delete = 1;
-               }
+               // Note - the original pixbuf is already safe and ready for destruction
+               pixbuf = gdk_pixbuf_scale_simple( pixbuf, width, height, GDK_INTERP_HYPER );
 
                // Store width and height
                this->width = gdk_pixbuf_get_width( pixbuf );
@@ -264,8 +273,7 @@ static void refresh_image( mlt_frame frame, int width, int height )
                }
 
                // Finished with pixbuf now
-               if ( delete )
-                       g_object_unref( pixbuf );
+               g_object_unref( pixbuf );
                
                // if single picture, reference the image and alpha in the producer
                free( this->image );
@@ -277,6 +285,8 @@ static void refresh_image( mlt_frame frame, int width, int height )
        // Set width/height
        mlt_properties_set_int( properties, "width", this->width );
        mlt_properties_set_int( properties, "height", this->height );
+       mlt_properties_set_int( properties, "real_width", mlt_properties_get_int( producer_props, "real_width" ) );
+       mlt_properties_set_int( properties, "real_height", mlt_properties_get_int( producer_props, "real_height" ) );
 
        // pass the image and alpha data without destructor
        mlt_properties_set_data( properties, "image", this->image, this->width * this->height * 2, NULL, NULL );
index 81255d737760ec16005caff735365ce2e600c414..699550d92d31b9286c0f2112466c36e7b60b1cf4 100644 (file)
@@ -65,7 +65,7 @@ mlt_producer producer_pixbuf_init( char *filename )
                // Set the default properties
                mlt_properties_set( properties, "resource", filename );
                mlt_properties_set_int( properties, "video_standard", mlt_video_standard_pal );
-               mlt_properties_set_double( properties, "ttl", 5 );
+               mlt_properties_set_int( properties, "ttl", 25 );
                
                // Obtain filenames
                if ( strchr( filename, '%' ) != NULL )
@@ -117,7 +117,6 @@ mlt_producer producer_pixbuf_init( char *filename )
                                free( de[ i ] );
                        }
 
-                       mlt_properties_set_position( properties, "out", this->count * 25 );
                        free( de );
                        free( dir_name );
                }
@@ -137,139 +136,73 @@ mlt_producer producer_pixbuf_init( 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 )
-{
-       // 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
-       // NB: Cloning is necessary with this producer (due to processing of images ahead of use)
-       // The fault is not in the design of mlt, but in the implementation of pixbuf...
-       //if ( writable )
-       {
-               size = *width * *height * 2;
-
-               // 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 )
+static void refresh_image( mlt_frame frame, int width, int height )
 {
-       // 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_pixbuf this = producer->child;
+       // Pixbuf 
        GdkPixbuf *pixbuf = NULL;
        GError *error = NULL;
 
-       // Generate a frame
-       *frame = mlt_frame_init( );
-
        // Obtain properties of frame
-       mlt_properties properties = mlt_frame_properties( *frame );
+       mlt_properties properties = mlt_frame_properties( frame );
+
+       // Obtain the producer pango for this frame
+       producer_pixbuf this = mlt_properties_get_data( properties, "producer_pixbuf", NULL );
+
+       // Obtain the producer 
+       mlt_producer producer = &this->parent;
 
        // 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( producer_props, "ttl" );
+       double ttl = mlt_properties_get_int( producer_props, "ttl" );
 
        // Image index
        int image_idx = ( int )floor( mlt_producer_position( producer ) / ttl ) % this->count;
 
        // Update timecode on the frame we're creating
-       mlt_frame_set_position( *frame, mlt_producer_position( producer ) );
+       mlt_frame_set_position( frame, mlt_producer_position( producer ) );
 
     // optimization for subsequent iterations on single picture
        if ( this->image != NULL && image_idx == this->image_idx )
        {
-               // 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, 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 ( width != this->width || height != this->height )
+               {
+                       pixbuf = mlt_properties_get_data( producer_props, "pixbuf", NULL );
+               }
        }
        else 
        {
                free( this->image );
+               this->image = NULL;
                free( this->alpha );
+               this->alpha = NULL;
                this->image_idx = image_idx;
                pixbuf = gdk_pixbuf_new_from_file( this->filenames[ image_idx ], &error );
+
+               if ( pixbuf != NULL )
+               {
+                       // Register this pixbuf for destruction and reuse
+                       mlt_properties_set_data( producer_props, "pixbuf", pixbuf, 0, ( mlt_destructor )g_object_unref, NULL );
+
+                       mlt_properties_set_int( producer_props, "real_width", gdk_pixbuf_get_width( pixbuf ) );
+                       mlt_properties_set_int( producer_props, "real_height", gdk_pixbuf_get_height( pixbuf ) );
+
+                       // Store the width/height of the pixbuf temporarily
+                       this->width = gdk_pixbuf_get_width( pixbuf );
+                       this->height = gdk_pixbuf_get_height( pixbuf );
+               }
        }
 
        // If we have a pixbuf
-       if ( pixbuf )
+       if ( pixbuf && width > 0 )
        {
-               // Scale to adjust for sample aspect ratio
-               if ( mlt_properties_get_int( properties, "video_standard" ) == mlt_video_standard_pal )
-               {
-                       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 );
-               }
-               else
-               {
-                       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 );
 
                // Store width and height
                this->width = gdk_pixbuf_get_width( pixbuf );
                this->height = gdk_pixbuf_get_height( pixbuf );
-               this->width -= this->width % 4;
-               this->height -= this->height % 2;
 
                // Allocate/define image and alpha
                uint8_t *image = malloc( this->width * this->height * 2 );
@@ -299,33 +232,96 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
                // Finished with pixbuf now
                g_object_unref( pixbuf );
 
-               // Set width/height of frame
-               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, "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, this->width * this->height * 2, NULL, NULL );
-               mlt_properties_set_data( properties, "alpha", alpha, this->width * this->height, NULL, NULL );
+       // Set width/height of frame
+       mlt_properties_set_int( properties, "width", this->width );
+       mlt_properties_set_int( properties, "height", this->height );
+       mlt_properties_set_int( properties, "real_width", mlt_properties_get_int( producer_props, "real_width" ) );
+       mlt_properties_set_int( properties, "real_height", mlt_properties_get_int( producer_props, "real_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 );
 
-               // Set alpha call back
-               ( *frame )->get_alpha_mask = producer_get_alpha_mask;
+       // Get width and height
+       *width = mlt_properties_get_int( properties, "width" );
+       *height = mlt_properties_get_int( properties, "height" );
+
+       // Clone if necessary
+       // NB: Cloning is necessary with this producer (due to processing of images ahead of use)
+       // The fault is not in the design of mlt, but in the implementation of pixbuf...
+       //if ( writable )
+       {
+               size = *width * *height * 2;
+
+               // Clone our image
+               uint8_t *copy = malloc( size );
+               memcpy( copy, image, size );
+
+               // We're going to pass the copy on
+               image = copy;
 
-               // Push the get_image method
-               mlt_frame_push_get_image( *frame, producer_get_image );
+               // 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 )
+{
+       // Get the real structure for this producer
+       producer_pixbuf 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_pixbuf", this, 0, NULL, NULL );
+
+       // Refresh the pango image
+       refresh_image( *frame, 0, 0 );
+
+       // Set alpha call back
+       ( *frame )->get_alpha_mask = producer_get_alpha_mask;
+
+       // Push the get_image method
+       mlt_frame_push_get_image( *frame, producer_get_image );
+
        // Calculate the next timecode
        mlt_producer_prepare_next( producer );
 
@@ -335,10 +331,8 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
 static void producer_close( mlt_producer parent )
 {
        producer_pixbuf this = parent->child;
-       if ( this->image )
-               free( this->image );
-       if ( this->alpha )
-               free( this->alpha );
+       free( this->image );
+       free( this->alpha );
        parent->close = NULL;
        mlt_producer_close( parent );
        free( this );