From b6232c93db568b3becc00019ca18e31bd92e54b5 Mon Sep 17 00:00:00 2001 From: lilo_booter Date: Sat, 16 Jul 2005 13:36:24 +0000 Subject: [PATCH] rc/framework/mlt_frame.c + image_count added to assist the 'transition filter' in knowing when to act... src/framework/mlt_playlist.c + Complete rework of fx cuts - now only the fx are output on a frame src/framework/mlt_producer.c + Aspect ratio of cuts inherited from parent src/framework/mlt_service.c + Get frame reworked and cleaned up src/framework/mlt_tractor.c - Removed erroneous width/height pass down prior to image fetching + Corrected types on other properties for pass down + Complete rework of fx cuts - they're now received as producer-less frames from a track + Added image_count logic for transition filter assistance src/modules/core/filter_resize.c + Added state retention of aspect ratio (may withdraw this later - it assumes producer knows a/r on frame creation/prior to image fetch) src/modules/core/filter_transition.c + Checks that two images are available before processing + Checks test image/audio cases src/modules/core/transition_composite.c + Major correction in aspect ratio handling (the b frame image is 'distorted' to the consumers aspect ratio) + Minor clean up of silly and/or/xor - now have 'operator=[and/or/xor]' (more clean up to follow) src/modules/dv/producer_libdv.c + Frame stored width and height are no longer assumed to be 'safe' here (investigating) git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@762 d19143bc-622f-0410-bfdd-b5b2a6649095 --- src/framework/mlt_frame.c | 1 + src/framework/mlt_playlist.c | 18 +++++++- src/framework/mlt_producer.c | 1 + src/framework/mlt_service.c | 30 ++++++++----- src/framework/mlt_tractor.c | 58 +++++-------------------- src/modules/core/filter_resize.c | 18 ++++++-- src/modules/core/filter_transition.c | 7 +-- src/modules/core/transition_composite.c | 21 ++++++--- src/modules/dv/producer_libdv.c | 8 ++-- 9 files changed, 87 insertions(+), 75 deletions(-) diff --git a/src/framework/mlt_frame.c b/src/framework/mlt_frame.c index dcd5ec75..0f54d4df 100644 --- a/src/framework/mlt_frame.c +++ b/src/framework/mlt_frame.c @@ -267,6 +267,7 @@ int mlt_frame_get_image( mlt_frame this, uint8_t **buffer, mlt_image_format *for if ( get_image != NULL ) { + mlt_properties_set_int( properties, "image_count", mlt_properties_get_int( properties, "image_count" ) - 1 ); mlt_position position = mlt_frame_get_position( this ); error = get_image( this, buffer, format, width, height, writable ); mlt_frame_set_position( this, position ); diff --git a/src/framework/mlt_playlist.c b/src/framework/mlt_playlist.c index 632eefb1..ddb84a38 100644 --- a/src/framework/mlt_playlist.c +++ b/src/framework/mlt_playlist.c @@ -273,6 +273,7 @@ static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer source, mlt_service_detach( service, filter ); filter = mlt_service_filter( service, 0 ); } + mlt_properties_set_int( MLT_PRODUCER_PROPERTIES( producer ), "meta.fx_cut", 1 ); } // Check that we have room @@ -1450,7 +1451,22 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i } // Get the frame - mlt_service_get_frame( real, frame, index ); + if ( !mlt_properties_get_int( MLT_SERVICE_PROPERTIES( real ), "meta.fx_cut" ) ) + { + mlt_service_get_frame( real, frame, index ); + } + else + { + mlt_producer parent = mlt_producer_cut_parent( ( mlt_producer )real ); + *frame = mlt_frame_init( ); + mlt_properties_set_int( MLT_FRAME_PROPERTIES( *frame ), "fx_cut", 1 ); + mlt_frame_push_service( *frame, NULL ); + mlt_frame_push_audio( *frame, NULL ); + mlt_service_apply_filters( parent, *frame, 0 ); + mlt_service_apply_filters( real, *frame, 0 ); + mlt_deque_pop_front( MLT_FRAME_IMAGE_STACK( *frame ) ); + mlt_deque_pop_front( MLT_FRAME_AUDIO_STACK( *frame ) ); + } // Check if we're at the end of the clip mlt_properties properties = MLT_FRAME_PROPERTIES( *frame ); diff --git a/src/framework/mlt_producer.c b/src/framework/mlt_producer.c index f3233f92..f137973a 100644 --- a/src/framework/mlt_producer.c +++ b/src/framework/mlt_producer.c @@ -205,6 +205,7 @@ mlt_producer mlt_producer_cut( mlt_producer this, int in, int out ) mlt_properties_set_int( properties, "_cut", 1 ); mlt_properties_set_data( properties, "_cut_parent", parent, 0, ( mlt_destructor )mlt_producer_close, NULL ); mlt_properties_set_position( properties, "length", mlt_properties_get_position( parent_props, "length" ) ); + mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( parent_props, "aspect_ratio" ) ); mlt_producer_set_in_and_out( result, in, out ); // Mini fezzik :-/ diff --git a/src/framework/mlt_service.c b/src/framework/mlt_service.c index 46197804..1301fd27 100644 --- a/src/framework/mlt_service.c +++ b/src/framework/mlt_service.c @@ -355,17 +355,26 @@ void mlt_service_apply_filters( mlt_service this, mlt_frame frame, int index ) int mlt_service_get_frame( mlt_service this, mlt_frame_ptr frame, int index ) { + int result = 0; + + // Lock the service mlt_service_lock( this ); + + // Ensure that the frame is NULL + *frame = NULL; + + // Only process if we have a valid service if ( this != NULL && this->get_frame != NULL ) { - int result = 0; mlt_properties properties = MLT_SERVICE_PROPERTIES( this ); mlt_position in = mlt_properties_get_position( properties, "in" ); mlt_position out = mlt_properties_get_position( properties, "out" ); - mlt_properties_inc_ref( properties ); + result = this->get_frame( this, frame, index ); + if ( result == 0 ) { + mlt_properties_inc_ref( properties ); properties = MLT_FRAME_PROPERTIES( *frame ); if ( in >=0 && out > 0 ) { @@ -374,18 +383,17 @@ int mlt_service_get_frame( mlt_service this, mlt_frame_ptr frame, int index ) } mlt_service_apply_filters( this, *frame, 1 ); mlt_deque_push_back( MLT_FRAME_SERVICE_STACK( *frame ), this ); - mlt_service_unlock( this ); } - else - { - mlt_service_unlock( this ); - mlt_service_close( this ); - } - return result; } + + // Make sure we return a frame + if ( *frame == NULL ) + *frame = mlt_frame_init( ); + + // Unlock the service mlt_service_unlock( this ); - *frame = mlt_frame_init( ); - return 0; + + return result; } static void mlt_service_filter_changed( mlt_service owner, mlt_service this ) diff --git a/src/framework/mlt_tractor.c b/src/framework/mlt_tractor.c index 3bcf0201..120d4fb2 100644 --- a/src/framework/mlt_tractor.c +++ b/src/framework/mlt_tractor.c @@ -204,15 +204,13 @@ static int producer_get_image( mlt_frame this, uint8_t **buffer, mlt_image_forma mlt_properties properties = MLT_FRAME_PROPERTIES( this ); mlt_frame frame = mlt_frame_pop_service( this ); mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame ); - mlt_properties_set_int( frame_properties, "width", mlt_properties_get_int( properties, "width" ) ); - mlt_properties_set_int( frame_properties, "height", mlt_properties_get_int( properties, "height" ) ); mlt_properties_set( frame_properties, "rescale.interp", mlt_properties_get( properties, "rescale.interp" ) ); mlt_properties_set_int( frame_properties, "distort", mlt_properties_get_int( properties, "distort" ) ); mlt_properties_set_double( frame_properties, "consumer_aspect_ratio", mlt_properties_get_double( properties, "consumer_aspect_ratio" ) ); - mlt_properties_set_int( frame_properties, "consumer_deinterlace", mlt_properties_get_double( properties, "consumer_deinterlace" ) ); + mlt_properties_set_int( frame_properties, "consumer_deinterlace", mlt_properties_get_int( properties, "consumer_deinterlace" ) ); mlt_properties_set( frame_properties, "deinterlace_method", mlt_properties_get( properties, "deinterlace_method" ) ); - mlt_properties_set_int( frame_properties, "normalised_width", mlt_properties_get_double( properties, "normalised_width" ) ); - mlt_properties_set_int( frame_properties, "normalised_height", mlt_properties_get_double( properties, "normalised_height" ) ); + mlt_properties_set_int( frame_properties, "normalised_width", mlt_properties_get_int( properties, "normalised_width" ) ); + mlt_properties_set_int( frame_properties, "normalised_height", mlt_properties_get_int( properties, "normalised_height" ) ); mlt_frame_get_image( frame, buffer, format, width, height, writable ); mlt_properties_set_data( properties, "image", *buffer, *width * *height * 2, NULL, NULL ); mlt_properties_set_int( properties, "width", *width ); @@ -268,6 +266,7 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int tra int done = 0; mlt_frame temp = NULL; int count = 0; + int image_count = 0; // Get the properties of the parent producer mlt_properties properties = MLT_PRODUCER_PROPERTIES( parent ); @@ -327,50 +326,10 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int tra done = mlt_properties_get_int( temp_properties, "last_track" ); // Handle fx only tracks - if ( mlt_properties_get_int( temp_properties, "meta.fx_cut" ) ) + if ( mlt_properties_get_int( temp_properties, "fx_cut" ) ) { - mlt_properties copy = video == NULL ? frame_properties : MLT_FRAME_PROPERTIES( video ); - int i = 0; - - for ( i = 0; i < mlt_properties_count( temp_properties ); i ++ ) - { - char *name = mlt_properties_get_name( temp_properties, i ); - char *value = mlt_properties_get_value( temp_properties, i ); - // For animated filters - if ( isdigit( name[ 0 ] ) && value != NULL ) - mlt_properties_set( copy, name, value ); - } - - if ( video ) - { - // Take all but the first placeholding producer and dump on to the image stack - void *p = mlt_deque_pop_front( MLT_FRAME_IMAGE_STACK( temp ) ); - while ( ( p = mlt_deque_pop_front( MLT_FRAME_IMAGE_STACK( temp ) ) ) != NULL ) - mlt_deque_push_back( MLT_FRAME_IMAGE_STACK( video ), p ); - } - else - { - mlt_frame_push_service( *frame, temp ); - mlt_frame_push_service( *frame, producer_get_image ); - mlt_properties_set_int( frame_properties, "meta.fx_cut", 1 ); - } - - if ( audio ) - { - // Take all but the first placeholding producer and dump on to the audio stack - void *p = !mlt_frame_is_test_audio( temp ) ? mlt_deque_pop_front( MLT_FRAME_AUDIO_STACK( temp ) ) : NULL; - while ( ( p = mlt_deque_pop_front( MLT_FRAME_AUDIO_STACK( temp ) ) ) != NULL ) - mlt_deque_push_back( MLT_FRAME_AUDIO_STACK( audio ), p ); - } - else - { - mlt_frame_push_audio( *frame, temp ); - mlt_frame_push_audio( *frame, producer_get_audio ); - mlt_properties_set_int( frame_properties, "meta.fx_cut", 1 ); - } - - // Ensure everything is hidden - mlt_properties_set_int( temp_properties, "hide", 3 ); + int hide = ( video == NULL ? 1 : 0 ) | ( audio == NULL ? 2 : 0 ); + mlt_properties_set_int( temp_properties, "hide", hide ); } // We store all frames with a destructor on the output frame @@ -426,6 +385,8 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int tra mlt_deque_push_front( MLT_FRAME_IMAGE_STACK( temp ), video ); } video = temp; + mlt_properties_set_int( MLT_FRAME_PROPERTIES( temp ), "image_count", ++ image_count ); + image_count = 1; } } @@ -450,6 +411,7 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int tra mlt_properties_set_int( frame_properties, "real_height", mlt_properties_get_int( video_properties, "real_height" ) ); mlt_properties_set_int( frame_properties, "progressive", mlt_properties_get_int( video_properties, "progressive" ) ); mlt_properties_set_double( frame_properties, "aspect_ratio", mlt_properties_get_double( video_properties, "aspect_ratio" ) ); + mlt_properties_set_int( frame_properties, "image_count", image_count ); } else { diff --git a/src/modules/core/filter_resize.c b/src/modules/core/filter_resize.c index c9884e8b..bd8841b0 100644 --- a/src/modules/core/filter_resize.c +++ b/src/modules/core/filter_resize.c @@ -39,13 +39,19 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format * // Pop the top of stack now mlt_filter filter = mlt_frame_pop_service( this ); + // Retrieve the aspect ratio + double aspect_ratio = mlt_deque_pop_back_double( MLT_FRAME_IMAGE_STACK( this ) ); + // Assign requested width/height from our subordinate int owidth = *width; int oheight = *height; // Check for the special case - no aspect ratio means no problem :-) - if ( mlt_frame_get_aspect_ratio( this ) == 0 ) - mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( properties, "consumer_aspect_ratio" ) ); + if ( aspect_ratio == 0.0 ) + aspect_ratio = mlt_properties_get_double( properties, "consumer_aspect_ratio" ); + + // Reset the aspect ratio + mlt_properties_set_double( properties, "aspect_ratio", aspect_ratio ); // Hmmm... char *rescale = mlt_properties_get( properties, "rescale.interp" ); @@ -63,9 +69,8 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format * real_width = mlt_properties_get_int( properties, "width" ); if ( real_height == 0 ) real_height = mlt_properties_get_int( properties, "height" ); - double input_ar = mlt_frame_get_aspect_ratio( this ) * real_width / real_height; + double input_ar = aspect_ratio * real_width / real_height; double output_ar = mlt_properties_get_double( properties, "consumer_aspect_ratio" ) * owidth / oheight; - //fprintf( stderr, "normalised %dx%d output %dx%d %f %f\n", normalised_width, normalised_height, owidth, oheight, ( float )output_ar, ( float )mlt_properties_get_double( properties, "consumer_aspect_ratio" ) * owidth / oheight ); @@ -88,6 +93,8 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format * mlt_frame_set_aspect_ratio( this, mlt_properties_get_double( properties, "consumer_aspect_ratio" ) ); } + mlt_properties_set_int( properties, "distort", 0 ); + // Now pass on the calculations down the line mlt_properties_set_int( properties, "resize_width", *width ); mlt_properties_set_int( properties, "resize_height", *height ); @@ -148,6 +155,9 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format * static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) { + // Store the aspect ratio reported by the source + mlt_deque_push_back_double( MLT_FRAME_IMAGE_STACK( frame ), mlt_frame_get_aspect_ratio( frame ) ); + // Push this on to the service stack mlt_frame_push_service( frame, this ); diff --git a/src/modules/core/filter_transition.c b/src/modules/core/filter_transition.c index 61c38bef..bdd106aa 100644 --- a/src/modules/core/filter_transition.c +++ b/src/modules/core/filter_transition.c @@ -30,7 +30,8 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) { mlt_transition transition = mlt_frame_pop_service( this ); - mlt_transition_process( transition, this, this ); + if ( mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "image_count" ) >= 1 ) + mlt_transition_process( transition, this, this ); return mlt_frame_get_image( this, image, format, width, height, writable ); } @@ -75,12 +76,12 @@ static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) // Refresh with current user values mlt_properties_pass( MLT_TRANSITION_PROPERTIES( transition ), MLT_FILTER_PROPERTIES( this ), "transition." ); - if ( type & 1 ) + if ( type & 1 && !mlt_frame_is_test_card( frame ) && !( mlt_properties_get_int( MLT_FRAME_PROPERTIES( frame ), "hide" ) & 1 ) ) { mlt_frame_push_service( frame, transition ); mlt_frame_push_get_image( frame, filter_get_image ); } - if ( type & 2 ) + if ( type & 2 && !mlt_frame_is_test_audio( frame ) && !( mlt_properties_get_int( MLT_FRAME_PROPERTIES( frame ), "hide" ) & 2 ) ) { mlt_frame_push_audio( frame, transition ); mlt_frame_push_audio( frame, filter_get_audio ); diff --git a/src/modules/core/transition_composite.c b/src/modules/core/transition_composite.c index 1b4c5eec..df24e61f 100644 --- a/src/modules/core/transition_composite.c +++ b/src/modules/core/transition_composite.c @@ -732,9 +732,8 @@ static int get_b_frame_image( mlt_transition this, mlt_frame b_frame, uint8_t ** int normalised_height = geometry->item.h; int real_width = get_value( b_props, "real_width", "width" ); int real_height = get_value( b_props, "real_height", "height" ); - double input_ar = mlt_frame_get_aspect_ratio( b_frame ); + double input_ar = mlt_properties_get_double( b_props, "consumer_aspect_ratio" ); double output_ar = mlt_properties_get_double( b_props, "consumer_aspect_ratio" ); - if ( input_ar == 0.0 ) input_ar = output_ar; int scaled_width = input_ar / output_ar * real_width; int scaled_height = real_height; @@ -1030,8 +1029,6 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f // consumer properties from the a_frame mlt_properties_set_double( b_props, "consumer_deinterlace", mlt_properties_get_double( a_props, "consumer_deinterlace" ) ); mlt_properties_set_double( b_props, "consumer_aspect_ratio", mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) ); - mlt_properties_set_int( b_props, "normalised_width", mlt_properties_get_double( a_props, "normalised_width" ) ); - mlt_properties_set_int( b_props, "normalised_height", mlt_properties_get_double( a_props, "normalised_height" ) ); // TODO: Dangerous/temporary optimisation - if nothing to do, then do nothing if ( mlt_properties_get_int( properties, "no_alpha" ) && @@ -1080,7 +1077,7 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f height_b = mlt_properties_get_int( a_props, "dest_height" ); } - if ( image_b != NULL || get_b_frame_image( this, b_frame, &image_b, &width_b, &height_b, &result ) == 0 ) + if ( *image != image_b && ( image_b != NULL || get_b_frame_image( this, b_frame, &image_b, &width_b, &height_b, &result ) == 0 ) ) { uint8_t *dest = *image; uint8_t *src = image_b; @@ -1091,11 +1088,13 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f int32_t luma_softness = mlt_properties_get_double( properties, "softness" ) * ( 1 << 16 ); uint16_t *luma_bitmap = get_luma( properties, width_b, height_b ); + char *operator = mlt_properties_get( properties, "operator" ); alpha_b = alpha_b == NULL ? mlt_frame_get_alpha_mask( b_frame ) : alpha_b; composite_line_fn line_fn = composite_line_yuv; + // Silly - this isn't a good solution - deprecating if ( mlt_properties_get_int( properties, "or" ) ) line_fn = composite_line_yuv_or; if ( mlt_properties_get_int( properties, "and" ) ) @@ -1103,6 +1102,18 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f if ( mlt_properties_get_int( properties, "xor" ) ) line_fn = composite_line_yuv_xor; + // Replacement and override + if ( operator != NULL ) + { + if ( !strcmp( operator, "or" ) ) + line_fn = composite_line_yuv_or; + if ( !strcmp( operator, "and" ) ) + line_fn = composite_line_yuv_and; + if ( !strcmp( operator, "xor" ) ) + line_fn = composite_line_yuv_xor; + } + + // Allow the user to completely obliterate the alpha channels from both frames if ( mlt_properties_get( properties, "alpha_a" ) ) memset( alpha_a, mlt_properties_get_int( properties, "alpha_a" ), *width * *height ); diff --git a/src/modules/dv/producer_libdv.c b/src/modules/dv/producer_libdv.c index 5cde8eb3..f2cc3897 100644 --- a/src/modules/dv/producer_libdv.c +++ b/src/modules/dv/producer_libdv.c @@ -300,9 +300,10 @@ static int producer_get_image( mlt_frame this, uint8_t **buffer, mlt_image_forma // Parse the header for meta info dv_parse_header( decoder, dv_data ); - // Assign width and height from properties - *width = mlt_properties_get_int( properties, "width" ); - *height = mlt_properties_get_int( properties, "height" ); + // Assign width and height according to the frame + *width = 720; + *height = dv_data[ 3 ] & 0x80 ? 576 : 480; + // Extract an image of the format requested if ( *format == mlt_image_yuv422 ) @@ -475,6 +476,7 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i //mlt_properties_set_int( properties, "progressive", dv_is_progressive( dv_decoder ) ); mlt_properties_set_double( properties, "aspect_ratio", dv_format_wide( dv_decoder ) ? ( this->is_pal ? 118.0/81.0 : 40.0/33.0 ) : ( this->is_pal ? 59.0/54.0 : 10.0/11.0 ) ); + mlt_properties_set_double( properties, "dv_aspect_ratio", mlt_properties_get_double( properties, "aspect_ratio" ) ); // Hmm - register audio callback mlt_frame_push_audio( *frame, producer_get_audio ); -- 2.39.2