From b698c58e57643e9df6941d91b07a40c997bd7e64 Mon Sep 17 00:00:00 2001 From: Dan Dennedy Date: Thu, 4 Mar 2010 21:28:16 -0800 Subject: [PATCH] Add service locks for parallelism. RGB filters and transitions from frei0r and burningtv are still not safe enough. --- src/modules/avformat/filter_avresample.c | 8 ++++++++ src/modules/avformat/filter_swscale.c | 2 +- src/modules/avformat/producer_avformat.c | 15 ++++++++++++++- src/modules/core/filter_data_show.c | 4 ++++ src/modules/core/filter_luma.c | 5 +++++ src/modules/core/filter_watermark.c | 4 ++++ src/modules/core/producer_colour.c | 8 ++++++++ src/modules/core/transition_composite.c | 2 ++ src/modules/core/transition_luma.c | 4 ++++ src/modules/core/transition_region.c | 4 ++++ src/modules/effectv/filter_burn.c | 11 ++++++----- src/modules/frei0r/filter_frei0r.c | 4 +++- src/modules/frei0r/producer_frei0r.c | 2 ++ src/modules/frei0r/transition_frei0r.c | 2 ++ src/modules/gtk2/producer_pango.c | 3 +++ src/modules/gtk2/producer_pixbuf.c | 3 +++ src/modules/kdenlive/filter_freeze.c | 3 +++ src/modules/kdenlive/producer_framebuffer.c | 3 +++ src/modules/resample/filter_resample.c | 7 +++++++ 19 files changed, 86 insertions(+), 8 deletions(-) diff --git a/src/modules/avformat/filter_avresample.c b/src/modules/avformat/filter_avresample.c index 38e0d571..f78dff87 100644 --- a/src/modules/avformat/filter_avresample.c +++ b/src/modules/avformat/filter_avresample.c @@ -42,6 +42,8 @@ static int resample_get_audio( mlt_frame frame, void **buffer, mlt_audio_format // Get the filter properties mlt_properties filter_properties = MLT_FILTER_PROPERTIES( filter ); + mlt_service_lock( MLT_FILTER_SERVICE( filter ) ); + // Get the resample information int output_rate = mlt_properties_get_int( filter_properties, "frequency" ); int16_t *sample_buffer = mlt_properties_get_data( filter_properties, "buffer", NULL ); @@ -128,6 +130,8 @@ static int resample_get_audio( mlt_frame frame, void **buffer, mlt_audio_format mlt_properties_set_int( filter_properties, "last_frequency", *frequency ); } + mlt_service_unlock( MLT_FILTER_SERVICE( filter ) ); + // Resample the audio used = audio_resample( resample, sample_buffer, *buffer, *samples ); int size = used * *channels * sizeof( int16_t ); @@ -146,6 +150,10 @@ static int resample_get_audio( mlt_frame frame, void **buffer, mlt_audio_format *samples = used; *frequency = output_rate; } + else + { + mlt_service_unlock( MLT_FILTER_SERVICE( filter ) ); + } return 0; } diff --git a/src/modules/avformat/filter_swscale.c b/src/modules/avformat/filter_swscale.c index 0fd7f0bd..990be787 100644 --- a/src/modules/avformat/filter_swscale.c +++ b/src/modules/avformat/filter_swscale.c @@ -47,7 +47,7 @@ static inline int convert_mlt_to_av_cs( mlt_image_format format ) break; case mlt_image_rgb24a: case mlt_image_opengl: - value = PIX_FMT_RGB32; + value = PIX_FMT_RGBA; break; case mlt_image_yuv422: value = PIX_FMT_YUYV422; diff --git a/src/modules/avformat/producer_avformat.c b/src/modules/avformat/producer_avformat.c index 4860a933..8c4171b7 100644 --- a/src/modules/avformat/producer_avformat.c +++ b/src/modules/avformat/producer_avformat.c @@ -947,6 +947,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form { // Get the producer producer_avformat this = mlt_frame_pop_service( frame ); + mlt_service_lock( MLT_PRODUCER_SERVICE(this->parent) ); mlt_producer producer = this->parent; // Get the properties from the frame @@ -1134,7 +1135,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form } } - // Duplicate the last image if necessary (see comment on rawvideo below) + // Duplicate the last image if necessary if ( this->av_frame && this->av_frame->linesize[0] && this->got_picture && this->seekable && ( paused || this->current_position == req_position @@ -1402,6 +1403,8 @@ exit_get_image: mlt_properties_set_int( properties, "meta.media.top_field_first", this->top_field_first ); mlt_properties_set_int( properties, "meta.media.progressive", mlt_properties_get_int( frame_properties, "progressive" ) ); + mlt_service_unlock( MLT_PRODUCER_SERVICE(this->parent) ); + return !this->got_picture; } @@ -1720,8 +1723,10 @@ static int seek_audio( producer_avformat this, mlt_position position, double tim timestamp = 0; // Set to the real timecode + avformat_lock(); if ( av_seek_frame( context, -1, timestamp, AVSEEK_FLAG_BACKWARD ) != 0 ) paused = 1; + avformat_unlock(); // Clear the usage in the audio buffer int i = MAX_AUDIO_STREAMS + 1; @@ -1794,7 +1799,9 @@ static int decode_audio( producer_avformat this, int *ignore, AVPacket pkt, int // Copy to audio buffer while resampling int16_t *source = decode_buffer; int16_t *dest = &audio_buffer[ audio_used * channels ]; + avformat_lock(); audio_used += audio_resample( resample, dest, source, convert_samples ); + avformat_unlock(); } else { @@ -1847,6 +1854,8 @@ static int producer_get_audio( mlt_frame frame, void **buffer, mlt_audio_format // Get the producer producer_avformat this = mlt_frame_pop_audio( frame ); + mlt_service_lock( MLT_PRODUCER_SERVICE(this->parent) ); + // Obtain the frame number of this frame mlt_position position = mlt_properties_get_position( MLT_FRAME_PROPERTIES( frame ), "avformat_position" ); @@ -1944,7 +1953,9 @@ static int producer_get_audio( mlt_frame frame, void **buffer, mlt_audio_format } // Read a packet + avformat_lock(); ret = av_read_frame( context, &pkt ); + avformat_unlock(); // We only deal with audio from the selected audio index if ( ret >= 0 && pkt.data && pkt.size > 0 && ( pkt.stream_index == this->audio_index || @@ -2035,6 +2046,8 @@ static int producer_get_audio( mlt_frame frame, void **buffer, mlt_audio_format if ( !paused ) this->audio_expected = position + 1; + mlt_service_unlock( MLT_PRODUCER_SERVICE(this->parent) ); + return 0; } diff --git a/src/modules/core/filter_data_show.c b/src/modules/core/filter_data_show.c index 54c35111..73d7d778 100644 --- a/src/modules/core/filter_data_show.c +++ b/src/modules/core/filter_data_show.c @@ -300,12 +300,16 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format // Get the frame properties mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame ); + mlt_service_lock( MLT_FILTER_SERVICE( filter ) ); + // Track specific process_queue( mlt_properties_get_data( frame_properties, "data_queue", NULL ), frame, filter ); // Global process_queue( mlt_properties_get_data( frame_properties, "global_queue", NULL ), frame, filter ); + mlt_service_unlock( MLT_FILTER_SERVICE( filter ) ); + // Need to get the image return mlt_frame_get_image( frame, image, format, width, height, 1 ); } diff --git a/src/modules/core/filter_luma.c b/src/modules/core/filter_luma.c index 28b2d6ee..0a146beb 100644 --- a/src/modules/core/filter_luma.c +++ b/src/modules/core/filter_luma.c @@ -37,6 +37,9 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format * int error = 0; mlt_filter filter = mlt_frame_pop_service( this ); mlt_properties properties = MLT_FILTER_PROPERTIES( filter ); + + mlt_service_lock( MLT_FILTER_SERVICE( filter ) ); + mlt_transition luma = mlt_properties_get_data( properties, "luma", NULL ); mlt_frame b_frame = mlt_properties_get_data( properties, "frame", NULL ); mlt_properties b_frame_props = b_frame ? MLT_FRAME_PROPERTIES( b_frame ) : NULL; @@ -111,6 +114,8 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format * } } + mlt_service_unlock( MLT_FILTER_SERVICE( filter ) ); + return error; } diff --git a/src/modules/core/filter_watermark.c b/src/modules/core/filter_watermark.c index e1e95d62..bb9ffd88 100644 --- a/src/modules/core/filter_watermark.c +++ b/src/modules/core/filter_watermark.c @@ -42,6 +42,8 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format // Get the properties of the filter mlt_properties properties = MLT_FILTER_PROPERTIES( this ); + mlt_service_lock( MLT_FILTER_SERVICE( this ) ); + // Get the producer from the filter mlt_producer producer = mlt_properties_get_data( properties, "producer", NULL ); @@ -115,6 +117,8 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format mlt_properties_pass( producer_properties, properties, "producer." ); } + mlt_service_unlock( MLT_FILTER_SERVICE( this ) ); + // Only continue if we have both producer and composite if ( composite != NULL && producer != NULL ) { diff --git a/src/modules/core/producer_colour.c b/src/modules/core/producer_colour.c index a43adeda..8667e453 100644 --- a/src/modules/core/producer_colour.c +++ b/src/modules/core/producer_colour.c @@ -99,6 +99,8 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form // Obtain the producer for this frame mlt_producer producer = mlt_properties_get_data( properties, "producer_colour", NULL ); + mlt_service_lock( MLT_PRODUCER_SERVICE( producer ) ); + // Obtain properties of producer mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer ); @@ -154,6 +156,8 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form mlt_properties_set_int( producer_props, "_format", *format ); mlt_properties_set( producer_props, "_resource", now ); + mlt_service_unlock( MLT_PRODUCER_SERVICE( producer ) ); + switch ( *format ) { case mlt_image_yuv422: @@ -204,6 +208,10 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form break; } } + else + { + mlt_service_unlock( MLT_PRODUCER_SERVICE( producer ) ); + } // Create the alpha channel int alpha_size = *width * *height; diff --git a/src/modules/core/transition_composite.c b/src/modules/core/transition_composite.c index 2e29ac80..14e00575 100644 --- a/src/modules/core/transition_composite.c +++ b/src/modules/core/transition_composite.c @@ -1223,7 +1223,9 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f int field; double luma_softness = mlt_properties_get_double( properties, "softness" ); + mlt_service_lock( MLT_TRANSITION_SERVICE( this ) ); uint16_t *luma_bitmap = get_luma( this, properties, width_b, height_b ); + mlt_service_unlock( MLT_TRANSITION_SERVICE( this ) ); char *operator = mlt_properties_get( properties, "operator" ); alpha_b = alpha_b == NULL ? mlt_frame_get_alpha_mask( b_frame ) : alpha_b; diff --git a/src/modules/core/transition_luma.c b/src/modules/core/transition_luma.c index 67a044d4..52ea292a 100644 --- a/src/modules/core/transition_luma.c +++ b/src/modules/core/transition_luma.c @@ -368,6 +368,8 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f // This compositer is yuv422 only *format = mlt_image_yuv422; + mlt_service_lock( MLT_TRANSITION_SERVICE( transition ) ); + // The cached luma map information int luma_width = mlt_properties_get_int( properties, "width" ); int luma_height = mlt_properties_get_int( properties, "height" ); @@ -480,6 +482,8 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f } } + mlt_service_unlock( MLT_TRANSITION_SERVICE( transition ) ); + // Arbitrary composite defaults float mix = position_calculate( transition, a_frame ); float frame_delta = delta_calculate( transition, a_frame ); diff --git a/src/modules/core/transition_region.c b/src/modules/core/transition_region.c index bd072120..9524dfc9 100644 --- a/src/modules/core/transition_region.c +++ b/src/modules/core/transition_region.c @@ -152,6 +152,8 @@ static int transition_get_image( mlt_frame frame, uint8_t **image, mlt_image_for // Get the properties of the transition mlt_properties properties = MLT_TRANSITION_PROPERTIES( this ); + mlt_service_lock( MLT_TRANSITION_SERVICE( this ) ); + // Get the composite from the transition mlt_transition composite = mlt_properties_get_data( properties, "composite", NULL ); @@ -386,6 +388,8 @@ static int transition_get_image( mlt_frame frame, uint8_t **image, mlt_image_for error = mlt_frame_get_image( frame, image, format, width, height, 0 ); } + mlt_service_unlock( MLT_TRANSITION_SERVICE( this ) ); + return error; } diff --git a/src/modules/effectv/filter_burn.c b/src/modules/effectv/filter_burn.c index 42a1f2d8..aefa76cf 100644 --- a/src/modules/effectv/filter_burn.c +++ b/src/modules/effectv/filter_burn.c @@ -103,8 +103,9 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format * unsigned char v, w; RGB32 a, b; - diff = mlt_properties_get_data( MLT_FILTER_PROPERTIES( filter ), - "_diff", NULL ); + mlt_service_lock( MLT_FILTER_SERVICE( filter ) ); + + diff = mlt_properties_get_data( MLT_FILTER_PROPERTIES( filter ), "_diff", NULL ); if (diff == NULL) { diff = mlt_pool_alloc(video_area*sizeof(unsigned char)); @@ -112,8 +113,7 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format * diff, video_area*sizeof(unsigned char), mlt_pool_release, NULL ); } - buffer = mlt_properties_get_data( MLT_FILTER_PROPERTIES( filter ), - "_buffer", NULL ); + buffer = mlt_properties_get_data( MLT_FILTER_PROPERTIES( filter ), "_buffer", NULL ); if (buffer == NULL) { buffer = mlt_pool_alloc(video_area*sizeof(unsigned char)); @@ -122,7 +122,6 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format * buffer, video_area*sizeof(unsigned char), mlt_pool_release, NULL ); } - if (burn_foreground == 1) { /* to burn the foreground, we need a background */ background = mlt_properties_get_data( MLT_FILTER_PROPERTIES( filter ), @@ -136,6 +135,8 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format * } } + mlt_service_unlock( MLT_FILTER_SERVICE( filter ) ); + if (burn_foreground == 1) { image_bgsubtract_y(diff, background, src, video_area, y_threshold); } else { diff --git a/src/modules/frei0r/filter_frei0r.c b/src/modules/frei0r/filter_frei0r.c index fde17336..046597ea 100644 --- a/src/modules/frei0r/filter_frei0r.c +++ b/src/modules/frei0r/filter_frei0r.c @@ -21,6 +21,7 @@ #include "frei0r_helper.h" #include + static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) { @@ -36,8 +37,9 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format * mlt_position time = mlt_properties_get_position( properties, "_filter_position" ); double position = ( double )( time ) / ( double )( length ); + mlt_service_lock( MLT_FILTER_SERVICE( filter ) ); process_frei0r_item( filter_type, position, properties, this, image, width, height ); - + mlt_service_unlock( MLT_FILTER_SERVICE( filter ) ); } return error; diff --git a/src/modules/frei0r/producer_frei0r.c b/src/modules/frei0r/producer_frei0r.c index 0f16c862..291ee47f 100644 --- a/src/modules/frei0r/producer_frei0r.c +++ b/src/modules/frei0r/producer_frei0r.c @@ -54,7 +54,9 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form mlt_position out = mlt_producer_get_out( producer ); mlt_position time = mlt_frame_get_position( frame ); double position = ( double )( time - in ) / ( double )( out - in + 1 ); + mlt_service_lock( MLT_PRODUCER_SERVICE( producer ) ); process_frei0r_item( producer_type, position, producer_props, frame, buffer, width, height ); + mlt_service_unlock( MLT_PRODUCER_SERVICE( producer ) ); } return 0; diff --git a/src/modules/frei0r/transition_frei0r.c b/src/modules/frei0r/transition_frei0r.c index df0226d1..b1aaf8ba 100644 --- a/src/modules/frei0r/transition_frei0r.c +++ b/src/modules/frei0r/transition_frei0r.c @@ -59,7 +59,9 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f float pos=( float )( position - in ) / ( float )( out - in + 1 ); + mlt_service_lock( MLT_TRANSITION_SERVICE( transition ) ); process_frei0r_item( transition_type, pos, properties, !invert ? a_frame : b_frame, images, width, height ); + mlt_service_unlock( MLT_TRANSITION_SERVICE( transition ) ); *width = mlt_properties_get_int( !invert ? a_props : b_props, "width" ); *height = mlt_properties_get_int( !invert ? a_props : b_props, "height" ); diff --git a/src/modules/gtk2/producer_pango.c b/src/modules/gtk2/producer_pango.c index 7c85ae88..814541b2 100644 --- a/src/modules/gtk2/producer_pango.c +++ b/src/modules/gtk2/producer_pango.c @@ -466,6 +466,8 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form *width = mlt_properties_get_int( properties, "rescale_width" ); *height = mlt_properties_get_int( properties, "rescale_height" ); + mlt_service_lock( MLT_PRODUCER_SERVICE( &this->parent ) ); + // Refresh the image pthread_mutex_lock( &pango_mutex ); refresh_image( frame, *width, *height ); @@ -492,6 +494,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form } pthread_mutex_unlock( &pango_mutex ); + mlt_service_unlock( MLT_PRODUCER_SERVICE( &this->parent ) ); return error; } diff --git a/src/modules/gtk2/producer_pixbuf.c b/src/modules/gtk2/producer_pixbuf.c index 6fd127d6..ab4aa66c 100644 --- a/src/modules/gtk2/producer_pixbuf.c +++ b/src/modules/gtk2/producer_pixbuf.c @@ -461,6 +461,8 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form *width = mlt_properties_get_int( properties, "rescale_width" ); *height = mlt_properties_get_int( properties, "rescale_height" ); + mlt_service_lock( MLT_PRODUCER_SERVICE( &this->parent ) ); + // Refresh the image refresh_image( this, frame, *width, *height ); @@ -492,6 +494,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form // Release references and locks pthread_mutex_unlock( &this->mutex ); mlt_cache_item_close( this->image_cache ); + mlt_service_unlock( MLT_PRODUCER_SERVICE( &this->parent ) ); return error; } diff --git a/src/modules/kdenlive/filter_freeze.c b/src/modules/kdenlive/filter_freeze.c index 3198ff31..c4768e27 100755 --- a/src/modules/kdenlive/filter_freeze.c +++ b/src/modules/kdenlive/filter_freeze.c @@ -50,6 +50,7 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format * } if (do_freeze == 1) { + mlt_service_lock( MLT_FILTER_SERVICE( filter ) ); freeze_frame = mlt_properties_get_data( properties, "freeze_frame", NULL ); if ( freeze_frame == NULL || mlt_properties_get_position( properties, "_frame" ) != pos ) { @@ -99,6 +100,8 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format * memcpy( image_copy, buffer, size ); *image = image_copy; mlt_properties_set_data( props, "image", *image, size, ( mlt_destructor ) mlt_pool_release, NULL ); + mlt_service_unlock( MLT_FILTER_SERVICE( filter ) ); + return error; } diff --git a/src/modules/kdenlive/producer_framebuffer.c b/src/modules/kdenlive/producer_framebuffer.c index 8e436125..64c9ce07 100644 --- a/src/modules/kdenlive/producer_framebuffer.c +++ b/src/modules/kdenlive/producer_framebuffer.c @@ -41,6 +41,8 @@ static int framebuffer_get_image( mlt_frame this, uint8_t **image, mlt_image_for int index = ( int )mlt_frame_pop_service( this ); mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); + mlt_service_lock( MLT_PRODUCER_SERVICE( producer ) ); + // Frame properties objects mlt_properties frame_properties = MLT_FRAME_PROPERTIES( this ); mlt_frame first_frame = mlt_properties_get_data( properties, "first_frame", NULL ); @@ -179,6 +181,7 @@ static int framebuffer_get_image( mlt_frame this, uint8_t **image, mlt_image_for mlt_properties_set_int( properties, "_output_format", *format ); } + mlt_service_unlock( MLT_PRODUCER_SERVICE( producer ) ); // Create a copy uint8_t *image_copy = mlt_pool_alloc( size ); diff --git a/src/modules/resample/filter_resample.c b/src/modules/resample/filter_resample.c index 8a4543ee..4533a0b2 100644 --- a/src/modules/resample/filter_resample.c +++ b/src/modules/resample/filter_resample.c @@ -63,6 +63,9 @@ static int resample_get_audio( mlt_frame frame, void **buffer, mlt_audio_format *format = mlt_audio_float; mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples ); } + + mlt_service_lock( MLT_FILTER_SERVICE(filter) ); + float *input_buffer = mlt_properties_get_data( filter_properties, "input_buffer", NULL ); float *output_buffer = mlt_properties_get_data( filter_properties, "output_buffer", NULL ); SRC_DATA data; @@ -119,9 +122,13 @@ static int resample_get_audio( mlt_frame frame, void **buffer, mlt_audio_format // Update output variables *samples = data.output_frames_gen; *frequency = output_rate; + } else + { mlt_log_error( MLT_FILTER_SERVICE( filter ), "%s %d,%d,%d\n", src_strerror( error ), *frequency, *samples, output_rate ); + } + mlt_service_unlock( MLT_FILTER_SERVICE(filter) ); } return error; -- 2.39.2