// Override the producer get_frame
producer->get_frame = producer_get_frame;
+ // Define the destructor
+ producer->close = ( mlt_destructor )mlt_playlist_close;
+ producer->close_object = this;
+
// Initialise blank
mlt_producer_init( &this->blank, NULL );
mlt_properties_set( mlt_producer_properties( &this->blank ), "mlt_service", "blank" );
mlt_properties_set( mlt_playlist_properties( this ), "eof", "pause" );
mlt_properties_set( mlt_playlist_properties( this ), "resource", "<playlist>" );
mlt_properties_set( mlt_playlist_properties( this ), "mlt_type", "mlt_producer" );
+ mlt_properties_set_position( mlt_playlist_properties( this ), "in", 0 );
+ mlt_properties_set_position( mlt_playlist_properties( this ), "out", 0 );
+ mlt_properties_set_position( mlt_playlist_properties( this ), "length", 0 );
+
+ this->size = 10;
+ this->list = malloc( this->size * sizeof( playlist_entry * ) );
}
return this;
mlt_producer mlt_playlist_producer( mlt_playlist this )
{
- return &this->parent;
+ return this != NULL ? &this->parent : NULL;
}
/** Get the service associated to this playlist.
{
int i;
this->list = realloc( this->list, ( this->size + 10 ) * sizeof( playlist_entry * ) );
- for ( i = this->size; i < this->size + 10; i ++ )
- this->list[ i ] = NULL;
+ for ( i = this->size; i < this->size + 10; i ++ ) this->list[ i ] = NULL;
this->size += 10;
}
this->count ++;
+ mlt_properties_inc_ref( mlt_producer_properties( producer ) );
+
return mlt_playlist_virtual_refresh( this );
}
/** Seek in the virtual playlist.
*/
-static mlt_producer mlt_playlist_virtual_seek( mlt_playlist this )
+static mlt_service mlt_playlist_virtual_seek( mlt_playlist this )
{
// Default producer to blank
mlt_producer producer = NULL;
producer = &this->blank;
}
- return producer;
+ return mlt_producer_service( producer );
}
/** Invoked when a producer indicates that it has prematurely reached its end.
info->length = mlt_producer_get_length( producer );
info->fps = mlt_producer_get_fps( producer );
}
+
+ // Determine the consuming filter service
+ if ( info->producer != NULL )
+ {
+ info->service = mlt_producer_service( info->producer );
+ while ( mlt_service_consumer( info->service ) != NULL )
+ info->service = mlt_service_consumer( info->service );
+ }
+
return error;
}
int mlt_playlist_clear( mlt_playlist this )
{
+ int i;
+ for ( i = 0; i < this->count; i ++ )
+ mlt_producer_close( this->list[ i ]->producer );
this->count = 0;
mlt_properties_set_double( mlt_playlist_properties( this ), "first_fps", 0 );
return mlt_playlist_virtual_refresh( this );
// Get the clip info of the clip to be removed
mlt_playlist_get_clip_info( this, &where_info, where );
+ // Close the producer associated to the clip info
+ mlt_producer_close( where_info.producer );
+
// Reorganise the list
for ( i = where + 1; i < this->count; i ++ )
this->list[ i - 1 ] = this->list[ i ];
return error;
}
+/** Split a clip on the playlist at the given position.
+*/
+
+int mlt_playlist_split( mlt_playlist this, int clip, mlt_position position )
+{
+ int error = clip < 0 || clip >= this->count;
+ if ( error == 0 )
+ {
+ playlist_entry *entry = this->list[ clip ];
+ if ( position > 0 && position < entry->frame_count )
+ {
+ int in = entry->frame_in;
+ int out = entry->frame_out;
+ mlt_playlist_resize_clip( this, clip, in, in + position );
+ mlt_playlist_insert( this, entry->producer, clip + 1, in + position + 1, out );
+ }
+ else
+ {
+ error = 1;
+ }
+ }
+ return error;
+}
+
+/** Join 1 or more consecutive clips.
+*/
+
+int mlt_playlist_join( mlt_playlist this, int clip, int count, int merge )
+{
+ int error = clip < 0 || ( clip + 1 ) >= this->count;
+ if ( error == 0 )
+ {
+ int i = clip;
+ mlt_playlist new_clip = mlt_playlist_init( );
+ if ( clip + count >= this->count )
+ count = this->count - clip;
+ for ( i = 0; i <= count; i ++ )
+ {
+ playlist_entry *entry = this->list[ clip ];
+ mlt_playlist_append_io( new_clip, entry->producer, entry->frame_in, entry->frame_out );
+ mlt_playlist_remove( this, clip );
+ }
+ mlt_playlist_insert( this, mlt_playlist_producer( new_clip ), clip, 0, -1 );
+ mlt_playlist_close( new_clip );
+ }
+ return error;
+}
+
/** Get the current frame.
*/
mlt_playlist this = producer->child;
// Get the real producer
- mlt_producer real = mlt_playlist_virtual_seek( this );
+ mlt_service real = mlt_playlist_virtual_seek( this );
// Get the frame
- mlt_service_get_frame( mlt_producer_service( real ), frame, index );
+ mlt_service_get_frame( real, frame, index );
// Check if we're at the end of the clip
mlt_properties properties = mlt_frame_properties( *frame );
void mlt_playlist_close( mlt_playlist this )
{
- mlt_producer_close( &this->parent );
- mlt_producer_close( &this->blank );
- free( this );
+ if ( this != NULL && mlt_properties_dec_ref( mlt_playlist_properties( this ) ) <= 0 )
+ {
+ int i = 0;
+ this->parent.close = NULL;
+ mlt_producer_close( &this->parent );
+ mlt_producer_close( &this->blank );
+ for ( i = 0; i < this->count; i ++ )
+ {
+ mlt_producer_close( this->list[ i ]->producer );
+ free( this->list[ i ] );
+ }
+ free( this->list );
+ free( this );
+ }
}