]> git.sesse.net Git - mlt/commitdiff
Fix concurrency bug in image producers.
authorDan Dennedy <dan@dennedy.org>
Fri, 20 Dec 2013 17:46:32 +0000 (09:46 -0800)
committerDan Dennedy <dan@dennedy.org>
Fri, 20 Dec 2013 17:46:32 +0000 (09:46 -0800)
Reported by Michael Marina.

src/modules/gtk2/producer_pixbuf.c
src/modules/qt/producer_qimage.c
src/modules/qt/qimage_wrapper.cpp

index 351cd8e69c7ff79c7c60f22b63b93183738766eb..01203874af3788cbe5bbcabe08d5dddb4347543e 100644 (file)
@@ -92,7 +92,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 );
+               mlt_properties_set_int( properties, "loop", 1 );
 
                // Validate the resource
                if ( filename )
@@ -372,13 +372,13 @@ static int refresh_pixbuf( producer_pixbuf self, mlt_frame frame )
        position += mlt_producer_get_in( producer );
 
        // Image index
-        int loop = mlt_properties_get_int( producer_props, "loop" );
-        int current_idx;
-        if (loop) {
+       int loop = mlt_properties_get_int( producer_props, "loop" );
+       int current_idx;
+       if (loop) {
                current_idx = ( int )floor( ( double )position / ttl ) % self->count;
-        } else {
+       } else {
                current_idx = MIN(( double )position / ttl, self->count - 1);
-        }
+       }
 
        // Key for the cache
        char image_key[ 10 ];
@@ -447,6 +447,7 @@ 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 ( !interps ) {
@@ -458,6 +459,7 @@ static void refresh_image( producer_pixbuf self, mlt_frame frame, mlt_image_form
                        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 );
@@ -553,8 +555,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 ) );
index e65e92444d79913ea4d71b9cedb25d14b98c1fd2..f15cf1a706f1e4e1acfecf7ebfa3663d9b2b929a 100644 (file)
@@ -237,8 +237,11 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
        producer_qimage self = mlt_properties_get_data( properties, "producer_qimage", NULL );
        mlt_producer producer = &self->parent;
 
-       *width = mlt_properties_get_int( properties, "rescale_width" );
-       *height = mlt_properties_get_int( properties, "rescale_height" );
+       // Use the width and height suggested by the rescale filter because we can do our own scaling.
+       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" );
 
        mlt_service_lock( MLT_PRODUCER_SERVICE( &self->parent ) );
 
index fc871e6cb45d201d2e3f42060843c1070f723a46..4fb645455f9d36e7e77d1ff74d5eb6605a6922ef 100644 (file)
@@ -249,16 +249,10 @@ void refresh_image( producer_qimage self, mlt_frame frame, mlt_image_format form
        // If we have a qimage and need a new scaled image
        if ( self->qimage && ( !self->current_image || ( format != mlt_image_none  && format != self->format ) ) )
        {
-               char *interps = mlt_properties_get( properties, "rescale.interp" );
-               int interp = 0;
+               QString interps = mlt_properties_get( properties, "rescale.interp" );
+               bool interp = ( interps != "nearest" ) && ( interps != "none" );
                QImage *qimage = static_cast<QImage*>( self->qimage );
 
-               // QImage has two scaling modes - we'll toggle between them here
-               if ( strcmp( interps, "tiles" ) == 0
-                       || strcmp( interps, "hyper" ) == 0
-                       || strcmp( interps, "bicubic" ) == 0 )
-                       interp = 1;
-
                // Note - the original qimage is already safe and ready for destruction
                if ( qimage->depth() == 1 )
                {
@@ -267,7 +261,7 @@ void refresh_image( producer_qimage self, mlt_frame frame, mlt_image_format form
                        qimage = new QImage( temp );
                        self->qimage = qimage;
                }
-               QImage scaled = interp == 0 ? qimage->scaled( QSize( width, height ) ) :
+               QImage scaled = interp? qimage->scaled( QSize( width, height ) ) :
                        qimage->scaled( QSize(width, height), Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
                int has_alpha = scaled.hasAlphaChannel();