// Push it on to the queue
mlt_deque_push_back( data_queue, feed );
+
+ // Make sure this attribute only gets processed once
+ mlt_properties_set_int( frame_properties, name, 0 );
}
}
}
// Fetch the filter associated to this type
mlt_filter requested = mlt_properties_get_data( filter_properties, type, NULL );
- // Calculate the length of the feed
- int length = mlt_properties_get_int( feed, "out" ) - mlt_properties_get_int( feed, "in" ) + 1;
-
// If it doesn't exist, then create it now
if ( requested == NULL )
{
static char *prefix = "properties.";
int len = strlen( prefix );
+ // Determine if this is an absolute or relative feed
+ int absolute = mlt_properties_get_int( feed, "absolute" );
+
+ // Make do with what we have
+ int length = !absolute ?
+ mlt_properties_get_int( feed, "out" ) - mlt_properties_get_int( feed, "in" ) + 1 :
+ mlt_properties_get_int( feed, "out" ) + 1;
+
+ // Repeat period
+ int period = mlt_properties_get_int( properties, "period" );
+ period = period == 0 ? 1 : period;
+
// Pass properties from feed into requested
for ( i = 0; i < mlt_properties_count( properties ); i ++ )
{
{
if ( !strncmp( name + len, "length[", 7 ) )
{
- int period = mlt_properties_get_int( properties, "period" );
- period = period == 0 ? 1 : period;
mlt_properties_set_position( properties, key, length / period );
}
else
}
// Set the original position on the frame
- mlt_frame_set_position( frame, mlt_properties_get_int( feed, "position" ) - mlt_properties_get_int( feed, "in" ) );
+ if ( absolute == 0 )
+ mlt_frame_set_position( frame, mlt_properties_get_int( feed, "position" ) - mlt_properties_get_int( feed, "in" ) );
+ else
+ mlt_frame_set_position( frame, mlt_properties_get_int( feed, "position" ) );
// Process the filter
mlt_filter_process( requested, frame );
char temp[ 132 ];
int count = 0;
uint8_t *alpha = NULL;
+ char *rescale = mlt_properties_get( a_props, "rescale.interp" );
+ if ( rescale == NULL || !strcmp( rescale, "none" ) )
+ rescale = "hyper";
mlt_transition_process( composite, b_frame, frame );
mlt_properties_set_double( b_props, "consumer_aspect_ratio", mlt_properties_get_int( a_props, "consumer_aspect_ratio" ) );
mlt_properties_set_int( a_props, "consumer_deinterlace", 1 );
mlt_properties_set_int( b_props, "consumer_deinterlace", 1 );
- mlt_properties_set( a_props, "rescale.interp", "nearest" );
- mlt_properties_set( b_props, "rescale.interp", "nearest" );
+ mlt_properties_set( a_props, "rescale.interp", rescale );
+ mlt_properties_set( b_props, "rescale.interp", rescale );
mlt_service_apply_filters( MLT_FILTER_SERVICE( this ), b_frame, 0 );
error = mlt_frame_get_image( b_frame, image, format, width, height, 1 );
alpha = mlt_frame_get_alpha_mask( b_frame );
// Get the in and out position
mlt_position in = mlt_transition_get_in( this );
mlt_position out = mlt_transition_get_out( this );
+ int length = out - in + 1;
// Get the new style geometry string
char *property = mlt_properties_get( properties, "geometry" );
+ // Allow a geometry repeat cycle
+ if ( mlt_properties_get_int( properties, "cycle" ) )
+ length = mlt_properties_get_int( properties, "cycle" );
+
// Parse the geometry if we have one
- mlt_geometry_parse( geometry, property, out - in + 1, normalised_width, normalised_height );
+ mlt_geometry_parse( geometry, property, length, normalised_width, normalised_height );
// Check if we're using the old style geometry
if ( property == NULL )
// field 1 = upper field and y should be even.
if ( ( field > -1 ) && ( y % 2 == field ) )
{
- //fprintf( stderr, "field %d y %d\n", field, y );
if ( ( field == 1 && y < height_dest - 1 ) || ( field == 0 && y == 0 ) )
p_dest += stride_dest;
else
scaled_height = normalised_height;
}
+ // Honour the fill request - this will scale the image to fill width or height while maintaining a/r
+ // ????: Shouln't this be the default behaviour?
if ( mlt_properties_get_int( properties, "fill" ) )
{
if ( scaled_height < normalised_height && scaled_width * normalised_height / scaled_height < normalised_width )
else
{
int length = mlt_transition_get_out( this ) - mlt_transition_get_in( this ) + 1;
+ if ( mlt_properties_get_int( properties, "cycle" ) )
+ length = mlt_properties_get_int( properties, "cycle" );
mlt_geometry_refresh( start, mlt_properties_get( properties, "geometry" ), length, normalised_width, normalised_height );
}
if ( mlt_playlist_count( playlist ) > 0 )
{
mlt_playlist_clip_info info;
- mlt_playlist_join( playlist, mlt_playlist_count( playlist ) - clips - 1, clips, 0 );
+ int clip = clips <= 0 ? 0 : mlt_playlist_count( playlist ) - clips - 1;
+ if ( clip < 0 ) clip = 0;
+ if ( clip >= mlt_playlist_count( playlist ) ) clip = mlt_playlist_count( playlist ) - 2;
+ if ( clips < 0 ) clips = mlt_playlist_count( playlist ) - 1;
+ mlt_playlist_join( playlist, clip, clips, 0 );
mlt_playlist_get_clip_info( playlist, &info, mlt_playlist_count( playlist ) - 1 );
producer = info.cut;
properties = MLT_PRODUCER_PROPERTIES( producer );