int i = 0;
// Get the properties of the transition
- mlt_properties properties = mlt_transition_properties( this );
+ mlt_properties properties = MLT_TRANSITION_PROPERTIES( this );
// Get the in and out position
mlt_position in = mlt_transition_get_in( this );
// Pointer
struct geometry_s *ptr = start;
- // Parse the start property
- geometry_parse( start, NULL, mlt_properties_get( properties, "start" ), normalised_width, normalised_height );
-
- // Parse the keys in between
- for ( i = 0; i < mlt_properties_count( properties ); i ++ )
+ // Check if we're using the new style geometry
+ if ( mlt_properties_get( properties, "geometry" ) )
{
- // Get the name of the property
- char *name = mlt_properties_get_name( properties, i );
+ // Sundry vars
+ int i;
+ int frame = 0;
+
+ // Obtain the geometry data - this is presented in the form:
+ // x,y:WxH[!][:mix][;f=x,y:WxH[!][:mix]]*
+ char *data = mlt_properties_get( properties, "geometry" );
+
+ // Split the data on the ; to seperate the values
+ mlt_tokeniser tokens = mlt_tokeniser_init( );
+ mlt_tokeniser_parse_new( tokens, data, ";" );
- // Check that it's valid
- if ( !strncmp( name, "key[", 4 ) )
+ // Parse the first entry
+ geometry_parse( start, NULL, mlt_tokeniser_get_string( tokens, 0 ), normalised_width, normalised_height );
+
+ // Iterate through the remainder
+ for ( i = 1; i < mlt_tokeniser_count( tokens ); i ++ )
{
- // Get the value of the property
- char *value = mlt_properties_get_value( properties, i );
+ // Get the current value
+ char *value = mlt_tokeniser_get_string( tokens, i );
+
+ // Used to determine the position
+ float position = 0;
- // Determine the frame number
- int frame = atoi( name + 4 );
+ // Determine the position of the / delimiter
+ char *p = strchr( value, '=' );
+
+ // Ensure that it has a frame and extract that value
+ if ( p )
+ {
+ frame = atoi( value );
+ value = p + 1;
+ }
+ else
+ {
+ fprintf( stderr, "Malformed geometry - no frame in %s (%d)\n", value, i );
+ }
// Determine the position
- float position = 0;
-
if ( frame >= 0 && frame < ( out - in ) )
position = ( float )frame / ( float )( out - in + 1 );
else if ( frame < 0 && - frame < ( out - in ) )
// Allow the next to be appended after this one
ptr = temp;
}
- else
+ }
+
+ // Close the tokens
+ mlt_tokeniser_close( tokens );
+
+ // Parse the end
+ geometry_parse( end, ptr, NULL, normalised_width, normalised_height );
+ if ( out > 0 )
+ end->position = ( float )( out - in ) / ( float )( out - in + 1 );
+ else
+ end->position = 1;
+ }
+ else
+ {
+ // DEPRECATED: Multiple keys for geometry information is inefficient and too rigid for
+ // practical use
+
+ // Parse the start property
+ geometry_parse( start, NULL, mlt_properties_get( properties, "start" ), normalised_width, normalised_height );
+
+ // Parse the keys in between
+ for ( i = 0; i < mlt_properties_count( properties ); i ++ )
+ {
+ // Get the name of the property
+ char *name = mlt_properties_get_name( properties, i );
+
+ // Check that it's valid
+ if ( !strncmp( name, "key[", 4 ) )
{
- fprintf( stderr, "Key out of order - skipping %s\n", name );
+ // Get the value of the property
+ char *value = mlt_properties_get_value( properties, i );
+
+ // Determine the frame number
+ int frame = atoi( name + 4 );
+
+ // Determine the position
+ float position = 0;
+
+ if ( frame >= 0 && frame < ( out - in ) )
+ position = ( float )frame / ( float )( out - in + 1 );
+ else if ( frame < 0 && - frame < ( out - in ) )
+ position = ( float )( out - in + frame ) / ( float )( out - in + 1 );
+
+ // For now, we'll exclude all keys received out of order
+ if ( position > ptr->position )
+ {
+ // Create a new geometry
+ struct geometry_s *temp = calloc( 1, sizeof( struct geometry_s ) );
+
+ // Parse and add to the list
+ geometry_parse( temp, ptr, value, normalised_width, normalised_height );
+
+ // Assign the position and frame
+ temp->frame = frame;
+ temp->position = position;
+
+ // Allow the next to be appended after this one
+ ptr = temp;
+ }
+ else
+ {
+ fprintf( stderr, "Key out of order - skipping %s\n", name );
+ }
}
}
+
+ // Parse the end
+ geometry_parse( end, ptr, mlt_properties_get( properties, "end" ), normalised_width, normalised_height );
+ if ( out > 0 )
+ end->position = ( float )( out - in ) / ( float )( out - in + 1 );
+ else
+ end->position = 1;
}
- // Parse the end
- geometry_parse( end, ptr, mlt_properties_get( properties, "end" ), normalised_width, normalised_height );
- if ( out > 0 )
- end->position = ( float )( out - in ) / ( float )( out - in + 1 );
- else
- end->position = 1;
-
return start;
}
mlt_position out = mlt_transition_get_out( this );
// Get the position of the frame
- char *name = mlt_properties_get( mlt_transition_properties( this ), "_unique_id" );
- mlt_position position = mlt_properties_get_position( mlt_frame_properties( frame ), name );
+ char *name = mlt_properties_get( MLT_TRANSITION_PROPERTIES( this ), "_unique_id" );
+ mlt_position position = mlt_properties_get_position( MLT_FRAME_PROPERTIES( frame ), name );
// Now do the calcs
float x = ( float )( position - in ) / ( float )( out - in + 1 );
int alpha_stride = stride_src / bpp;
if ( uneven )
- p_src -= 2;
+ {
+ p_dest += 2;
+ width_src --;
+ }
// now do the compositing only to cropped extents
if ( line_fn != NULL )
if ( producer != NULL )
{
// Get the producer properties
- mlt_properties producer_properties = mlt_producer_properties( producer );
+ mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer );
// Ensure that we loop
mlt_properties_set( producer_properties, "eof", "loop" );
mlt_frame luma_frame = NULL;
// Get the luma frame
- if ( mlt_service_get_frame( mlt_producer_service( producer ), &luma_frame, 0 ) == 0 )
+ if ( mlt_service_get_frame( MLT_PRODUCER_SERVICE( producer ), &luma_frame, 0 ) == 0 )
{
uint8_t *luma_image;
mlt_image_format luma_format = mlt_image_yuv422;
// Get image from the luma producer
- mlt_properties_set( mlt_frame_properties( luma_frame ), "rescale.interp", "none" );
+ mlt_properties_set( MLT_FRAME_PROPERTIES( luma_frame ), "rescale.interp", "none" );
mlt_frame_get_image( luma_frame, &luma_image, &luma_format, &luma_width, &luma_height, 0 );
// Generate the luma map
mlt_image_format format = mlt_image_yuv422;
// Get the properties objects
- mlt_properties b_props = mlt_frame_properties( b_frame );
- mlt_properties properties = mlt_transition_properties( this );
+ mlt_properties b_props = MLT_FRAME_PROPERTIES( b_frame );
+ mlt_properties properties = MLT_TRANSITION_PROPERTIES( this );
if ( mlt_properties_get( properties, "distort" ) == NULL && mlt_properties_get( b_props, "distort" ) == NULL && geometry->distort == 0 )
{
mlt_properties_set( b_props, "distort", "true" );
// Take into consideration alignment for optimisation
- alignment_calculate( geometry );
+ if ( !mlt_properties_get_int( properties, "titles" ) )
+ alignment_calculate( geometry );
// Adjust to consumer scale
int x = geometry->x * *width / geometry->nw;
static struct geometry_s *composite_calculate( struct geometry_s *result, mlt_transition this, mlt_frame a_frame, float position )
{
// Get the properties from the transition
- mlt_properties properties = mlt_transition_properties( this );
+ mlt_properties properties = MLT_TRANSITION_PROPERTIES( this );
// Get the properties from the frame
- mlt_properties a_props = mlt_frame_properties( a_frame );
+ mlt_properties a_props = MLT_FRAME_PROPERTIES( a_frame );
// Structures for geometry
struct geometry_s *start = mlt_properties_get_data( properties, "geometries", NULL );
mlt_frame b_frame = mlt_frame_init( );
// Get the properties of the a frame
- mlt_properties a_props = mlt_frame_properties( a_frame );
+ mlt_properties a_props = MLT_FRAME_PROPERTIES( a_frame );
// Get the properties of the b frame
- mlt_properties b_props = mlt_frame_properties( b_frame );
+ mlt_properties b_props = MLT_FRAME_PROPERTIES( b_frame );
// Get the position
float position = position_calculate( this, frame_position );
mlt_frame_get_image( a_frame, image, format, width, height, 1 );
// Get the properties from the transition
- mlt_properties properties = mlt_transition_properties( this );
+ mlt_properties properties = MLT_TRANSITION_PROPERTIES( this );
if ( b_frame != NULL )
{
// Get the properties of the a frame
- mlt_properties a_props = mlt_frame_properties( a_frame );
+ mlt_properties a_props = MLT_FRAME_PROPERTIES( a_frame );
// Get the properties of the b frame
- mlt_properties b_props = mlt_frame_properties( b_frame );
+ mlt_properties b_props = MLT_FRAME_PROPERTIES( b_frame );
// Structures for geometry
struct geometry_s result;
if ( mlt_properties_get_int( properties, "titles" ) )
{
if ( mlt_properties_get( b_props, "rescale.interp" ) == NULL )
- mlt_properties_set( b_props, "rescale.interp", "nearest" );
+ mlt_properties_set( b_props, "rescale.interp", "hyper" );
mlt_properties_set( properties, "fill", NULL );
width_b = mlt_properties_get_int( a_props, "dest_width" );
height_b = mlt_properties_get_int( a_props, "dest_height" );
// Do the calculation if we need to
geometry_calculate( &result, start, field_position );
+ if ( mlt_properties_get_int( properties, "titles" ) )
+ {
+ result.nw = result.w = *width;
+ result.nh = result.h = *height;
+ result.sw = width_b;
+ result.sh = height_b;
+ }
+
// Align
alignment_calculate( &result );
static mlt_frame composite_process( mlt_transition this, mlt_frame a_frame, mlt_frame b_frame )
{
// Get a unique name to store the frame position
- char *name = mlt_properties_get( mlt_transition_properties( this ), "_unique_id" );
+ char *name = mlt_properties_get( MLT_TRANSITION_PROPERTIES( this ), "_unique_id" );
// Assign the current position to the name
- mlt_properties_set_position( mlt_frame_properties( a_frame ), name, mlt_frame_get_position( a_frame ) );
+ mlt_properties_set_position( MLT_FRAME_PROPERTIES( a_frame ), name, mlt_frame_get_position( a_frame ) );
// Propogate the transition properties to the b frame
- mlt_properties_set_double( mlt_frame_properties( b_frame ), "relative_position", position_calculate( this, mlt_frame_get_position( a_frame ) ) );
+ mlt_properties_set_double( MLT_FRAME_PROPERTIES( b_frame ), "relative_position", position_calculate( this, mlt_frame_get_position( a_frame ) ) );
mlt_frame_push_service( a_frame, this );
mlt_frame_push_frame( a_frame, b_frame );
mlt_transition this = calloc( sizeof( struct mlt_transition_s ), 1 );
if ( this != NULL && mlt_transition_init( this, NULL ) == 0 )
{
- mlt_properties properties = mlt_transition_properties( this );
+ mlt_properties properties = MLT_TRANSITION_PROPERTIES( this );
this->process = composite_process;