X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmodules%2Fgtk2%2Fproducer_pixbuf.c;h=1ec705e3e6fd4e8e24d3524079accccfadda1760;hb=6f8293d53fc21742d9d43f94f0e590e1bfcb8ee0;hp=d1e15eaf2b562e74e4526e58ba2f80b60149e638;hpb=830202089a59519a23009370325823c1a34e1e60;p=mlt diff --git a/src/modules/gtk2/producer_pixbuf.c b/src/modules/gtk2/producer_pixbuf.c index d1e15eaf..1ec705e3 100644 --- a/src/modules/gtk2/producer_pixbuf.c +++ b/src/modules/gtk2/producer_pixbuf.c @@ -22,10 +22,9 @@ #include #include #include +#include #include -#include "config.h" - #ifdef USE_EXIF #include #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 );