mlt_playlist_insert( this, &this->blank, clip + 1, 0, out - position - 1 );
}
mlt_events_unblock( mlt_playlist_properties( this ), this );
- mlt_events_fire( mlt_playlist_properties( this ), "producer-changed", NULL );
+ mlt_playlist_virtual_refresh( this );
}
else
{
mlt_properties_set_data( properties, "mlt_mix", NULL, 0, NULL, NULL );
mlt_playlist_remove( this, clip );
mlt_events_unblock( mlt_playlist_properties( this ), this );
- mlt_events_fire( mlt_playlist_properties( this ), "producer-changed", NULL );
+ mlt_playlist_virtual_refresh( this );
}
return error;
}
return producer;
}
+void mlt_playlist_insert_blank( mlt_playlist this, int clip, int length )
+{
+ if ( this != NULL && length > 0 )
+ {
+ mlt_properties properties = mlt_playlist_properties( this );
+ mlt_events_block( properties, properties );
+ mlt_playlist_blank( this, length );
+ mlt_playlist_move( this, this->count - 1, clip );
+ mlt_events_unblock( properties, properties );
+ mlt_playlist_virtual_refresh( this );
+ }
+}
+
+void mlt_playlist_pad_blanks( mlt_playlist this, int position, int length, int find )
+{
+ if ( this != NULL && length != 0 )
+ {
+ int clip = mlt_playlist_get_clip_index_at( this, position );
+ mlt_properties properties = mlt_playlist_properties( this );
+ mlt_events_block( properties, properties );
+ if ( find && clip < this->count && !mlt_playlist_is_blank( this, clip ) )
+ clip ++;
+ if ( clip < this->count && mlt_playlist_is_blank( this, clip ) )
+ {
+ mlt_playlist_clip_info info;
+ mlt_playlist_get_clip_info( this, &info, clip );
+ if ( info.frame_out + length > info.frame_in )
+ mlt_playlist_resize_clip( this, clip, info.frame_in, info.frame_out + length );
+ else
+ mlt_playlist_remove( this, clip );
+ }
+ else if ( find && clip < this->count && length > 0 )
+ {
+ mlt_playlist_insert_blank( this, clip, length );
+ }
+ mlt_events_unblock( properties, properties );
+ mlt_playlist_virtual_refresh( this );
+ }
+}
+
+int mlt_playlist_insert_at( mlt_playlist this, int position, mlt_producer producer, int mode )
+{
+ int ret = this == NULL || position < 0 || producer == NULL;
+ if ( ret == 0 )
+ {
+ mlt_properties properties = mlt_playlist_properties( this );
+ int length = mlt_producer_get_playtime( producer );
+ int clip = mlt_playlist_get_clip_index_at( this, position );
+ mlt_playlist_clip_info info;
+ mlt_playlist_get_clip_info( this, &info, clip );
+ mlt_events_block( properties, this );
+ if ( clip < this->count && mlt_playlist_is_blank( this, clip ) )
+ {
+ mlt_playlist_split( this, clip, position - info.start );
+ mlt_playlist_get_clip_info( this, &info, ++ clip );
+ if ( length < info.frame_count )
+ mlt_playlist_split( this, clip, length );
+ mlt_playlist_remove( this, clip );
+ mlt_playlist_insert( this, producer, clip, -1, -1 );
+ ret = clip;
+ }
+ else if ( clip < this->count )
+ {
+ if ( position > info.start + info.frame_count / 2 )
+ clip ++;
+ if ( mode == 1 && clip < this->count && mlt_playlist_is_blank( this, clip ) )
+ {
+ mlt_playlist_get_clip_info( this, &info, clip );
+ if ( length < info.frame_count )
+ mlt_playlist_split( this, clip, length );
+ mlt_playlist_remove( this, clip );
+ }
+ mlt_playlist_insert( this, producer, clip, -1, -1 );
+ ret = clip;
+ }
+ else
+ {
+ if ( mode == 1 )
+ mlt_playlist_blank( this, position - mlt_properties_get_int( properties, "length" ) );
+ mlt_playlist_append( this, producer );
+ ret = this->count - 1;
+ }
+ mlt_events_unblock( properties, this );
+ mlt_playlist_virtual_refresh( this );
+ }
+ else
+ {
+ ret = -1;
+ }
+ return ret;
+}
+
+int mlt_playlist_clip_start( mlt_playlist this, int clip )
+{
+ mlt_playlist_clip_info info;
+ if ( mlt_playlist_get_clip_info( this, &info, clip ) == 0 )
+ return info.start;
+ return 0;
+}
+
+int mlt_playlist_clip_length( mlt_playlist this, int clip )
+{
+ mlt_playlist_clip_info info;
+ if ( mlt_playlist_get_clip_info( this, &info, clip ) == 0 )
+ return info.frame_count;
+ return 0;
+}
+
+int mlt_playlist_blanks_from( mlt_playlist this, int clip, int bounded )
+{
+ int count = 0;
+ mlt_playlist_clip_info info;
+ if ( this != NULL && clip < this->count )
+ {
+ mlt_playlist_get_clip_info( this, &info, clip );
+ if ( mlt_playlist_is_blank( this, clip ) )
+ count += info.frame_count;
+ if ( bounded == 0 )
+ bounded = this->count;
+ for ( clip ++; clip < this->count && bounded >= 0; clip ++ )
+ {
+ mlt_playlist_get_clip_info( this, &info, clip );
+ if ( mlt_playlist_is_blank( this, clip ) )
+ count += info.frame_count;
+ else
+ bounded --;
+ }
+ }
+ return count;
+}
+
+int mlt_playlist_remove_region( mlt_playlist this, int position, int length )
+{
+ int index = mlt_playlist_get_clip_index_at( this, position );
+ if ( index >= 0 && index < this->count )
+ {
+ mlt_properties properties = mlt_playlist_properties( this );
+ int clip_start = mlt_playlist_clip_start( this, index );
+ int clip_length = mlt_playlist_clip_length( this, index );
+ int list_length = mlt_producer_get_playtime( mlt_playlist_producer( this ) );
+ mlt_events_block( properties, this );
+
+ if ( position + length > list_length )
+ length -= ( position + length - list_length );
+
+ if ( clip_start < position )
+ {
+ mlt_playlist_split( this, index ++, position - clip_start );
+ clip_length -= position - clip_start;
+ }
+
+ while( length > 0 )
+ {
+ if ( mlt_playlist_clip_length( this, index ) > length )
+ mlt_playlist_split( this, index, length );
+ length -= mlt_playlist_clip_length( this, index );
+ mlt_playlist_remove( this, index );
+ }
+
+ mlt_playlist_consolidate_blanks( this, 0 );
+ mlt_events_unblock( properties, this );
+ mlt_playlist_virtual_refresh( this );
+
+ // Just to be sure, we'll get the clip index again...
+ index = mlt_playlist_get_clip_index_at( this, position );
+ }
+ return index;
+}
+
+int mlt_playlist_move_region( mlt_playlist this, int position, int length, int new_position )
+{
+ if ( this != NULL )
+ {
+ mlt_playlist temp = mlt_playlist_init( );
+ int original_size = mlt_producer_get_playtime( mlt_playlist_producer( temp ) );
+ mlt_playlist_close( temp );
+ }
+ return 0;
+}
+
/** Get the current frame.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <pthread.h>
/** IMPORTANT NOTES
int filter_count;
int filter_size;
mlt_filter *filters;
+ pthread_mutex_t mutex;
}
mlt_service_base;
mlt_events_init( &this->parent );
mlt_events_register( &this->parent, "service-changed", NULL );
mlt_events_register( &this->parent, "property-changed", ( mlt_transmitter )mlt_service_property_changed );
+ pthread_mutex_init( &( ( mlt_service_base * )this->local )->mutex, NULL );
}
return error;
listener( owner, this, ( char * )args[ 0 ] );
}
+void mlt_service_lock( mlt_service this )
+{
+ if ( this != NULL )
+ pthread_mutex_lock( &( ( mlt_service_base * )this->local )->mutex );
+}
+
+void mlt_service_unlock( mlt_service this )
+{
+ if ( this != NULL )
+ pthread_mutex_unlock( &( ( mlt_service_base * )this->local )->mutex );
+}
+
mlt_service_type mlt_service_identify( mlt_service this )
{
mlt_service_type type = invalid_type;
// Increment the reference count on this producer
if ( producer != NULL )
+ {
+ mlt_service_lock( producer );
mlt_properties_inc_ref( mlt_service_properties( producer ) );
+ mlt_service_unlock( producer );
+ }
// Now we disconnect the producer service from its consumer
mlt_service_disconnect( producer );
int mlt_service_get_frame( mlt_service this, mlt_frame_ptr frame, int index )
{
+ mlt_service_lock( this );
if ( this != NULL && this->get_frame != NULL )
{
+ char uniq[ 20 ];
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 );
+ mlt_service_unlock( this );
result = this->get_frame( this, frame, index );
if ( result == 0 )
{
+ properties = mlt_frame_properties( *frame );
if ( in >=0 && out > 0 )
{
- properties = mlt_frame_properties( *frame );
mlt_properties_set_position( properties, "in", in );
mlt_properties_set_position( properties, "out", out );
}
mlt_service_apply_filters( this, *frame, 1 );
+ sprintf( uniq, "gf_%p", this );
+ if ( mlt_properties_get_data( properties, uniq, NULL ) != NULL )
+ fprintf( stderr, "%s is not unique in this frame\n", uniq );
+ mlt_properties_set_data( properties, uniq, this, 0, ( mlt_destructor )mlt_service_close, NULL );
+ }
+ else
+ {
+ fprintf( stderr, "Ugh case\n" );
+ mlt_service_close( this );
}
return result;
}
+ mlt_service_unlock( this );
*frame = mlt_frame_init( );
return 0;
}
void mlt_service_close( mlt_service this )
{
+ mlt_service_lock( this );
if ( this != NULL && mlt_properties_dec_ref( mlt_service_properties( this ) ) <= 0 )
{
+ mlt_service_unlock( this );
if ( this->close != NULL )
{
this->close( this->close_object );
mlt_service_close( base->in[ i ] );
this->parent.close = NULL;
free( base->in );
+ pthread_mutex_destroy( &base->mutex );
free( base );
mlt_properties_close( &this->parent );
}
}
+ else
+ {
+ mlt_service_unlock( this );
+ }
}