static void mlt_producer_property_changed( mlt_service owner, mlt_producer this, char *name )
{
if ( !strcmp( name, "in" ) || !strcmp( name, "out" ) || !strcmp( name, "length" ) )
- mlt_events_fire( mlt_producer_properties( this ), "producer-changed", NULL );
+ mlt_events_fire( mlt_producer_properties( mlt_producer_cut_parent( this ) ), "producer-changed", NULL );
}
/** Listener for service changes.
static void mlt_producer_service_changed( mlt_service owner, mlt_producer this )
{
- mlt_events_fire( mlt_producer_properties( this ), "producer-changed", NULL );
+ mlt_events_fire( mlt_producer_properties( mlt_producer_cut_parent( this ) ), "producer-changed", NULL );
}
/** Create a new producer.
return this;
}
+/** Determine if producer is a cut.
+*/
+
+int mlt_producer_is_cut( mlt_producer this )
+{
+ return mlt_properties_get_int( mlt_producer_properties( this ), "_cut" );
+}
+
+/** Obtain the parent producer.
+*/
+
+mlt_producer mlt_producer_cut_parent( mlt_producer this )
+{
+ mlt_properties properties = mlt_producer_properties( this );
+ if ( mlt_producer_is_cut( this ) )
+ return mlt_properties_get_data( properties, "_cut_parent", NULL );
+ else
+ return this;
+}
+
+/** Create a cut of this producer
+*/
+
+mlt_producer mlt_producer_cut( mlt_producer this, int in, int out )
+{
+ mlt_producer result = mlt_producer_new( );
+ mlt_producer parent = mlt_producer_cut_parent( this );
+ mlt_properties properties = mlt_producer_properties( result );
+ mlt_properties parent_props = mlt_producer_properties( parent );
+
+ // Special case - allow for a cut of the entire producer (this will squeeze all other cuts to 0)
+ if ( in <= 0 )
+ in = 0;
+ if ( out >= mlt_producer_get_playtime( parent ) )
+ out = mlt_producer_get_playtime( parent ) - 1;
+
+ mlt_properties_inc_ref( parent_props );
+ 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_position( properties, "in", 0 );
+ mlt_properties_set_position( properties, "out", 0 );
+ mlt_producer_set_in_and_out( result, in, out );
+
+ return result;
+}
+
/** Get the parent service object.
*/
int mlt_producer_seek( mlt_producer this, mlt_position position )
{
// Determine eof handling
- char *eof = mlt_properties_get( mlt_producer_properties( this ), "eof" );
- int use_points = 1 - mlt_properties_get_int( mlt_producer_properties( this ), "ignore_points" );
+ mlt_properties properties = mlt_producer_properties( this );
+ char *eof = mlt_properties_get( properties, "eof" );
+ int use_points = 1 - mlt_properties_get_int( properties, "ignore_points" );
+
+ // Recursive behaviour for cuts...
+ if ( mlt_producer_is_cut( this ) )
+ mlt_producer_seek( mlt_producer_cut_parent( this ), position + mlt_producer_get_in( this ) );
// Check bounds
if ( position < 0 )
// Set the values
mlt_events_block( properties, properties );
mlt_properties_set_position( properties, "in", in );
- mlt_properties_set_position( properties, "out", out );
mlt_events_unblock( properties, properties );
- mlt_events_fire( properties, "producer-changed", NULL );
+ mlt_properties_set_position( properties, "out", out );
return 0;
}
+/** Physically reduce the producer (typically a cut) to a 0 length.
+ Essentially, all 0 length cuts should be immediately removed by containers.
+*/
+
+int mlt_producer_clear( mlt_producer this )
+{
+ if ( this != NULL )
+ {
+ mlt_properties properties = mlt_producer_properties( this );
+ mlt_events_block( properties, properties );
+ mlt_properties_set_position( properties, "in", 0 );
+ mlt_events_unblock( properties, properties );
+ mlt_properties_set_position( properties, "out", -1 );
+ }
+ return 0;
+}
+
/** Get the in point.
*/
int result = 1;
mlt_producer this = service->child;
- // Determine eof handling
- char *eof = mlt_properties_get( mlt_producer_properties( this ), "eof" );
-
- // A properly instatiated producer will have a get_frame method...
- if ( this->get_frame == NULL || ( !strcmp( eof, "continue" ) && mlt_producer_position( this ) > mlt_producer_get_out( this ) ) )
+ if ( !mlt_producer_is_cut( this ) )
{
- // Generate a test frame
- *frame = mlt_frame_init( );
+ // Determine eof handling
+ char *eof = mlt_properties_get( mlt_producer_properties( this ), "eof" );
- // Set the position
- result = mlt_frame_set_position( *frame, mlt_producer_position( this ) );
+ // A properly instatiated producer will have a get_frame method...
+ if ( this->get_frame == NULL || ( !strcmp( eof, "continue" ) && mlt_producer_position( this ) > mlt_producer_get_out( this ) ) )
+ {
+ // Generate a test frame
+ *frame = mlt_frame_init( );
- // Mark as a test card
- mlt_properties_set_int( mlt_frame_properties( *frame ), "test_image", 1 );
- mlt_properties_set_int( mlt_frame_properties( *frame ), "test_audio", 1 );
+ // Set the position
+ result = mlt_frame_set_position( *frame, mlt_producer_position( this ) );
- // Calculate the next position
- mlt_producer_prepare_next( this );
+ // Mark as a test card
+ mlt_properties_set_int( mlt_frame_properties( *frame ), "test_image", 1 );
+ mlt_properties_set_int( mlt_frame_properties( *frame ), "test_audio", 1 );
+
+ // Calculate the next position
+ mlt_producer_prepare_next( this );
+ }
+ else
+ {
+ // Get the frame from the implementation
+ result = this->get_frame( this, frame, index );
+ }
+
+ // Copy the fps and speed of the producer onto the frame
+ mlt_properties properties = mlt_frame_properties( *frame );
+ double speed = mlt_producer_get_speed( this );
+ mlt_properties_set_double( properties, "_speed", speed );
+ mlt_properties_set_double( properties, "fps", mlt_producer_get_fps( this ) );
+ mlt_properties_set_int( properties, "test_audio", mlt_frame_is_test_audio( *frame ) );
+ mlt_properties_set_int( properties, "test_image", mlt_frame_is_test_card( *frame ) );
}
else
{
- // Get the frame from the implementation
- result = this->get_frame( this, frame, index );
+ mlt_properties properties = mlt_producer_properties( this );
+ mlt_producer_seek( this, mlt_properties_get_int( properties, "_position" ) );
+ result = producer_get_frame( mlt_producer_service( mlt_producer_cut_parent( this ) ), frame, index );
+ double speed = mlt_producer_get_speed( this );
+ mlt_properties_set_double( mlt_frame_properties( *frame ), "_speed", speed );
+ mlt_producer_prepare_next( this );
}
- // Copy the fps and speed of the producer onto the frame
- mlt_properties properties = mlt_frame_properties( *frame );
- mlt_properties_set_double( properties, "fps", mlt_producer_get_fps( this ) );
- double speed = mlt_producer_get_speed( this );
- mlt_properties_set_double( properties, "_speed", speed );
- mlt_properties_set_int( properties, "test_audio", mlt_frame_is_test_audio( *frame ) );
- mlt_properties_set_int( properties, "test_image", mlt_frame_is_test_card( *frame ) );
-
- return 0;
+ return result;
}
/** Attach a filter.