X-Git-Url: http://research.m1stereo.tv/gitweb?a=blobdiff_plain;f=src%2Fframework%2Fmlt_playlist.c;h=ddb84a389a09cb581a021388476b1d310caef5e2;hb=b6232c93db568b3becc00019ca18e31bd92e54b5;hp=d563d7dcaf12afa80881bf2fd02b87e2ddd61a38;hpb=f00476101550ec7d8e863f6516aa83bc1b524570;p=melted diff --git a/src/framework/mlt_playlist.c b/src/framework/mlt_playlist.c index d563d7d..ddb84a3 100644 --- a/src/framework/mlt_playlist.c +++ b/src/framework/mlt_playlist.c @@ -263,6 +263,19 @@ static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer source, // Fetch the cuts parent properties parent = MLT_PRODUCER_PROPERTIES( mlt_producer_cut_parent( producer ) ); + // Remove fezzik normalisers for fx cuts + if ( mlt_properties_get_int( parent, "meta.fx_cut" ) ) + { + mlt_service service = MLT_PRODUCER_SERVICE( mlt_producer_cut_parent( producer ) ); + mlt_filter filter = mlt_service_filter( service, 0 ); + while ( filter != NULL && mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "_fezzik" ) ) + { + mlt_service_detach( service, filter ); + filter = mlt_service_filter( service, 0 ); + } + mlt_properties_set_int( MLT_PRODUCER_PROPERTIES( producer ), "meta.fx_cut", 1 ); + } + // Check that we have room if ( this->count >= this->size ) { @@ -755,6 +768,9 @@ int mlt_playlist_resize_clip( mlt_playlist this, int clip, mlt_position in, mlt_ { playlist_entry *entry = this->list[ clip ]; mlt_producer producer = entry->producer; + mlt_properties properties = MLT_PLAYLIST_PROPERTIES( this ); + + mlt_events_block( properties, properties ); if ( mlt_producer_is_blank( producer ) ) { @@ -762,9 +778,9 @@ int mlt_playlist_resize_clip( mlt_playlist this, int clip, mlt_position in, mlt_ if ( out - in + 1 > mlt_producer_get_length( &this->blank ) ) { mlt_properties blank_props = MLT_PRODUCER_PROPERTIES( &this->blank ); - mlt_events_block( blank_props, blank_props ); - mlt_producer_set_in_and_out( &this->blank, in, out ); - mlt_events_unblock( blank_props, blank_props ); + mlt_properties_set_int( blank_props, "length", out - in + 1 ); + mlt_properties_set_int( MLT_PRODUCER_PROPERTIES( producer ), "length", out - in + 1 ); + mlt_producer_set_in_and_out( &this->blank, 0, out - in ); } } @@ -781,6 +797,8 @@ int mlt_playlist_resize_clip( mlt_playlist this, int clip, mlt_position in, mlt_ } mlt_producer_set_in_and_out( producer, in, out ); + mlt_events_unblock( properties, properties ); + mlt_playlist_virtual_refresh( this ); } return error; } @@ -795,7 +813,7 @@ int mlt_playlist_split( mlt_playlist this, int clip, mlt_position position ) { playlist_entry *entry = this->list[ clip ]; position = position < 0 ? entry->frame_count + position - 1 : position; - if ( position >= 0 && position <= entry->frame_count ) + if ( position >= 0 && position < entry->frame_count - 1 ) { int in = entry->frame_in; int out = entry->frame_out; @@ -803,8 +821,17 @@ int mlt_playlist_split( mlt_playlist this, int clip, mlt_position position ) mlt_playlist_resize_clip( this, clip, in, in + position ); if ( !mlt_producer_is_blank( entry->producer ) ) { + int i = 0; + mlt_properties entry_properties = MLT_PRODUCER_PROPERTIES( entry->producer ); mlt_producer split = mlt_producer_cut( entry->producer, in + position + 1, out ); + mlt_properties split_properties = MLT_PRODUCER_PROPERTIES( split ); mlt_playlist_insert( this, split, clip + 1, 0, -1 ); + for ( i = 0; i < mlt_properties_count( entry_properties ); i ++ ) + { + char *name = mlt_properties_get_name( entry_properties, i ); + if ( name != NULL && !strncmp( name, "meta.", 5 ) ) + mlt_properties_set( split_properties, name, mlt_properties_get_value( entry_properties, i ) ); + } mlt_producer_close( split ); } else @@ -822,19 +849,50 @@ int mlt_playlist_split( mlt_playlist this, int clip, mlt_position position ) return error; } +/** Split the playlist at the absolute position. +*/ + +int mlt_playlist_split_at( mlt_playlist this, mlt_position position, int left ) +{ + int result = this == NULL ? -1 : 0; + if ( !result ) + { + if ( position >= 0 && position < mlt_producer_get_playtime( MLT_PLAYLIST_PRODUCER( this ) ) ) + { + int clip = mlt_playlist_get_clip_index_at( this, position ); + mlt_playlist_clip_info info; + mlt_playlist_get_clip_info( this, &info, clip ); + if ( left && position != info.start ) + mlt_playlist_split( this, clip, position - info.start - 1 ); + else if ( !left ) + mlt_playlist_split( this, clip, position - info.start ); + result = position; + } + else if ( position <= 0 ) + { + result = 0; + } + else + { + result = mlt_producer_get_playtime( MLT_PLAYLIST_PRODUCER( this ) ); + } + } + return result; +} + /** Join 1 or more consecutive clips. */ int mlt_playlist_join( mlt_playlist this, int clip, int count, int merge ) { - int error = clip < 0 || ( clip ) >= this->count; + int error = clip < 0 || clip >= this->count; if ( error == 0 ) { int i = clip; mlt_playlist new_clip = mlt_playlist_init( ); mlt_events_block( MLT_PLAYLIST_PROPERTIES( this ), this ); if ( clip + count >= this->count ) - count = this->count - clip; + count = this->count - clip - 1; for ( i = 0; i <= count; i ++ ) { playlist_entry *entry = this->list[ clip ]; @@ -1120,15 +1178,14 @@ void mlt_playlist_consolidate_blanks( mlt_playlist this, int keep_length ) playlist_entry *left = this->list[ i - 1 ]; playlist_entry *right = this->list[ i ]; - if ( mlt_producer_cut_parent( left->producer ) == mlt_producer_cut_parent( right->producer ) && - mlt_producer_is_blank( left->producer ) ) + if ( mlt_producer_is_blank( left->producer ) && mlt_producer_is_blank( right->producer ) ) { mlt_playlist_resize_clip( this, i - 1, 0, left->frame_count + right->frame_count - 1 ); mlt_playlist_remove( this, i -- ); } } - if ( !keep_length ) + if ( !keep_length && this->count > 0 ) { playlist_entry *last = this->list[ this->count - 1 ]; if ( mlt_producer_is_blank( last->producer ) ) @@ -1148,6 +1205,14 @@ int mlt_playlist_is_blank( mlt_playlist this, int clip ) return this == NULL || mlt_producer_is_blank( mlt_playlist_get_clip( this, clip ) ); } +/** Determine if the specified position is a blank. +*/ + +int mlt_playlist_is_blank_at( mlt_playlist this, int position ) +{ + return this == NULL || mlt_producer_is_blank( mlt_playlist_get_clip_at( this, position ) ); +} + /** Replace the specified clip with a blank and return the clip. */ @@ -1166,16 +1231,16 @@ mlt_producer mlt_playlist_replace_with_blank( mlt_playlist this, int clip ) mlt_playlist_remove( this, clip ); mlt_playlist_blank( this, out - in ); mlt_playlist_move( this, this->count - 1, clip ); - mlt_producer_set_in_and_out( producer, in, out ); mlt_events_unblock( properties, properties ); mlt_playlist_virtual_refresh( this ); + mlt_producer_set_in_and_out( producer, in, out ); } return producer; } void mlt_playlist_insert_blank( mlt_playlist this, int clip, int length ) { - if ( this != NULL && length > 0 ) + if ( this != NULL && length >= 0 ) { mlt_properties properties = MLT_PLAYLIST_PROPERTIES( this ); mlt_events_block( properties, properties ); @@ -1226,11 +1291,18 @@ int mlt_playlist_insert_at( mlt_playlist this, int position, mlt_producer produc 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 ); + // Split and move to new clip if need be + if ( position != info.start && mlt_playlist_split( this, clip, position - info.start ) == 0 ) + mlt_playlist_get_clip_info( this, &info, ++ clip ); + + // Split again if need be if ( length < info.frame_count ) - mlt_playlist_split( this, clip, length ); + mlt_playlist_split( this, clip, length - 1 ); + + // Remove mlt_playlist_remove( this, clip ); + + // Insert mlt_playlist_insert( this, producer, clip, -1, -1 ); ret = clip; } @@ -1270,7 +1342,7 @@ 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; + return clip < 0 ? 0 : mlt_producer_get_playtime( MLT_PLAYLIST_PRODUCER( this ) ); } int mlt_playlist_clip_length( mlt_playlist this, int clip ) @@ -1379,7 +1451,22 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i } // Get the frame - mlt_service_get_frame( real, frame, index ); + if ( !mlt_properties_get_int( MLT_SERVICE_PROPERTIES( real ), "meta.fx_cut" ) ) + { + mlt_service_get_frame( real, frame, index ); + } + else + { + mlt_producer parent = mlt_producer_cut_parent( ( mlt_producer )real ); + *frame = mlt_frame_init( ); + mlt_properties_set_int( MLT_FRAME_PROPERTIES( *frame ), "fx_cut", 1 ); + mlt_frame_push_service( *frame, NULL ); + mlt_frame_push_audio( *frame, NULL ); + mlt_service_apply_filters( parent, *frame, 0 ); + mlt_service_apply_filters( real, *frame, 0 ); + mlt_deque_pop_front( MLT_FRAME_IMAGE_STACK( *frame ) ); + mlt_deque_pop_front( MLT_FRAME_AUDIO_STACK( *frame ) ); + } // Check if we're at the end of the clip mlt_properties properties = MLT_FRAME_PROPERTIES( *frame );