]> git.sesse.net Git - mlt/blobdiff - src/modules/gtk2/producer_pixbuf.c
Avoid unnecessary compilation when running "./configure; make; make install" multiple...
[mlt] / src / modules / gtk2 / producer_pixbuf.c
index d1e15eaf2b562e74e4526e58ba2f80b60149e638..1ec705e3e6fd4e8e24d3524079accccfadda1760 100644 (file)
 #include <framework/mlt_frame.h>
 #include <framework/mlt_cache.h>
 #include <framework/mlt_log.h>
+#include <framework/mlt_tokeniser.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 
-#include "config.h"
-
 #ifdef USE_EXIF
 #include <libexif/exif-data.h>
 #endif
@@ -91,6 +90,7 @@ mlt_producer producer_pixbuf_init( char *filename )
                mlt_properties_set_int( properties, "aspect_ratio", 1 );
                mlt_properties_set_int( properties, "progressive", 1 );
                mlt_properties_set_int( properties, "seekable", 1 );
+               mlt_properties_set_int( properties, "loop", 1 );
 
                // Validate the resource
                if ( filename )
@@ -103,7 +103,6 @@ mlt_producer producer_pixbuf_init( char *filename )
                                mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame );
                                mlt_properties_set_data( frame_properties, "producer_pixbuf", self, 0, NULL, NULL );
                                mlt_frame_set_position( frame, mlt_producer_position( producer ) );
-                               mlt_properties_set_position( frame_properties, "pixbuf_position", mlt_producer_position( producer ) );
                                refresh_pixbuf( self, frame );
                                mlt_cache_item_close( self->pixbuf_cache );
                                mlt_frame_close( frame );
@@ -156,7 +155,7 @@ static int load_svg( producer_pixbuf self, mlt_properties properties, const char
        return result;
 }
 
-static int load_sequence( producer_pixbuf self, mlt_properties properties, const char *filename )
+static int load_sequence_sprintf( producer_pixbuf self, mlt_properties properties, const char *filename )
 {
        int result = 0;
 
@@ -194,11 +193,12 @@ static int load_sequence( producer_pixbuf self, mlt_properties properties, const
        return result;
 }
 
-static int load_sequence2( producer_pixbuf self, mlt_properties properties, const char *filename )
+static int load_sequence_deprecated( producer_pixbuf self, mlt_properties properties, const char *filename )
 {
        int result = 0;
        const char *start;
 
+       // This approach is deprecated in favor of the begin querystring parameter.
        // Obtain filenames with pattern containing a begin value, e.g. foo%1234d.png
        if ( ( start = strchr( filename, '%' ) ) )
        {
@@ -211,16 +211,39 @@ static int load_sequence2( producer_pixbuf self, mlt_properties properties, cons
                        strncpy( s, start, n );
                        mlt_properties_set( properties, "begin", s );
                        free( s );
-                       s = calloc( 1, strlen( filename ) );
+                       s = calloc( 1, strlen( filename ) + 2 );
                        strncpy( s, filename, start - filename );
                        sprintf( s + ( start - filename ), ".%d%s", n, end );
-                       result = load_sequence( self, properties, s );
+                       result = load_sequence_sprintf( self, properties, s );
                        free( s );
                }
        }
        return result;
 }
 
+static int load_sequence_querystring( producer_pixbuf self, mlt_properties properties, const char *filename )
+{
+       int result = 0;
+
+       // Obtain filenames with pattern and begin value in query string
+       if ( strchr( filename, '%' ) && strchr( filename, '?' ) )
+       {
+               // Split filename into pattern and query string
+               char *s = strdup( filename );
+               char *querystring = strrchr( s, '?' );
+               *querystring++ = '\0';
+               if ( strstr( filename, "begin=" ) )
+                       mlt_properties_set( properties, "begin", strstr( querystring, "begin=" ) + 6 );
+               else if ( strstr( filename, "begin:" ) )
+                       mlt_properties_set( properties, "begin", strstr( querystring, "begin:" ) + 6 );
+               // Coerce to an int value so serialization does not have any extra query string cruft
+               mlt_properties_set_int( properties, "begin", mlt_properties_get_int( properties, "begin" ) );
+               result = load_sequence_sprintf( self, properties, s );
+               free( s );
+       }
+       return result;
+}
+
 static int load_folder( producer_pixbuf self, mlt_properties properties, const char *filename )
 {
        int result = 0;
@@ -249,8 +272,9 @@ static void load_filenames( producer_pixbuf self, mlt_properties properties )
        self->filenames = mlt_properties_new( );
 
        if (!load_svg( self, properties, filename ) &&
-               !load_sequence( self, properties, filename ) &&
-               !load_sequence2( self, properties, filename ) &&
+               !load_sequence_querystring( self, properties, filename ) &&
+               !load_sequence_sprintf( self, properties, filename ) &&
+               !load_sequence_deprecated( self, properties, filename ) &&
                !load_folder( self, properties, filename ) )
        {
                mlt_properties_set( self->filenames, "0", filename );
@@ -342,11 +366,17 @@ static int refresh_pixbuf( producer_pixbuf self, mlt_frame frame )
        double ttl = mlt_properties_get_int( producer_props, "ttl" );
 
        // Get the original position of this frame
-       mlt_position position = mlt_properties_get_position( properties, "pixbuf_position" );
+       mlt_position position = mlt_frame_original_position( frame );
        position += mlt_producer_get_in( producer );
 
        // Image index
-       int current_idx = ( int )floor( ( double )position / ttl ) % self->count;
+       int loop = mlt_properties_get_int( producer_props, "loop" );
+       int current_idx;
+       if (loop) {
+               current_idx = ( int )floor( ( double )position / ttl ) % self->count;
+       } else {
+               current_idx = MIN(( double )position / ttl, self->count - 1);
+       }
 
        // Key for the cache
        char image_key[ 10 ];
@@ -415,14 +445,19 @@ static void refresh_image( producer_pixbuf self, mlt_frame frame, mlt_image_form
        if ( self->pixbuf && ( !self->image || ( format != mlt_image_none && format != self->format ) ) )
        {
                char *interps = mlt_properties_get( properties, "rescale.interp" );
+               if ( interps ) interps = strdup( interps );
                int interp = GDK_INTERP_BILINEAR;
 
-               if ( strcmp( interps, "nearest" ) == 0 )
+               if ( !interps ) {
+                       // Keep bilinear by default
+               }
+               else if ( strcmp( interps, "nearest" ) == 0 )
                        interp = GDK_INTERP_NEAREST;
                else if ( strcmp( interps, "tiles" ) == 0 )
                        interp = GDK_INTERP_TILES;
                else if ( strcmp( interps, "hyper" ) == 0 || strcmp( interps, "bicubic" ) == 0 )
                        interp = GDK_INTERP_HYPER;
+               if ( interps ) free( interps );
 
                // Note - the original pixbuf is already safe and ready for destruction
                pthread_mutex_lock( &g_mutex );
@@ -518,8 +553,10 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
        mlt_producer producer = &self->parent;
 
        // Use the width and height suggested by the rescale filter because we can do our own scaling.
-       *width = mlt_properties_get_int( properties, "rescale_width" );
-       *height = mlt_properties_get_int( properties, "rescale_height" );
+       if ( mlt_properties_get_int( properties, "rescale_width" ) > 0 )
+               *width = mlt_properties_get_int( properties, "rescale_width" );
+       if ( mlt_properties_get_int( properties, "rescale_height" ) > 0 )
+               *height = mlt_properties_get_int( properties, "rescale_height" );
 
        // Restore pixbuf and image
        mlt_service_lock( MLT_PRODUCER_SERVICE( producer ) );
@@ -599,9 +636,6 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
                // Update timecode on the frame we're creating
                mlt_frame_set_position( *frame, mlt_producer_position( producer ) );
 
-               // Ensure that we have a way to obtain the position in the get_image
-               mlt_properties_set_position( properties, "pixbuf_position", mlt_producer_position( producer ) );
-
                // Refresh the pixbuf
                self->pixbuf_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "pixbuf.pixbuf" );
                self->pixbuf = mlt_cache_item_data( self->pixbuf_cache, NULL );