From: Dan Dennedy Date: Fri, 20 Dec 2013 17:46:32 +0000 (-0800) Subject: Fix concurrency bug in image producers. X-Git-Url: https://git.sesse.net/?p=mlt;a=commitdiff_plain;h=9a19d7b3ccc4af7cb37bb958eefd4f421c51a04d Fix concurrency bug in image producers. Reported by Michael Marina. --- diff --git a/src/modules/gtk2/producer_pixbuf.c b/src/modules/gtk2/producer_pixbuf.c index 351cd8e6..01203874 100644 --- a/src/modules/gtk2/producer_pixbuf.c +++ b/src/modules/gtk2/producer_pixbuf.c @@ -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 ) ); diff --git a/src/modules/qt/producer_qimage.c b/src/modules/qt/producer_qimage.c index e65e9244..f15cf1a7 100644 --- a/src/modules/qt/producer_qimage.c +++ b/src/modules/qt/producer_qimage.c @@ -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 ) ); diff --git a/src/modules/qt/qimage_wrapper.cpp b/src/modules/qt/qimage_wrapper.cpp index fc871e6c..4fb64545 100644 --- a/src/modules/qt/qimage_wrapper.cpp +++ b/src/modules/qt/qimage_wrapper.cpp @@ -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( 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();