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 );
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
}
// 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 );
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 :-/
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 )
{
}
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 )
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 );
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 );
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
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;
}
}
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
{
// 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" );
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 );
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 );
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 );
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 );
}
// 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 );
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;
// 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" ) &&
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;
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" ) )
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 );
// 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 )
//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 );