framework: remove global profile, rather share one mlt_profile across a service netwo...
[melted] / src / framework / mlt_playlist.c
index 68c0dc7..b5e7fb3 100644 (file)
@@ -3,19 +3,19 @@
  * Copyright (C) 2003-2004 Ushodaya Enterprises Limited
  * Author: Charles Yates <charles.yates@pandora.be>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
  *
- * This program is distributed in the hope that it will be useful,
+ * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #include "config.h"
@@ -127,9 +127,6 @@ static int mlt_playlist_virtual_refresh( mlt_playlist this )
 {
        // Obtain the properties
        mlt_properties properties = MLT_PLAYLIST_PROPERTIES( this );
-
-       // Get the fps of the first producer
-       double fps = mlt_properties_get_double( properties, "first_fps" );
        int i = 0;
        mlt_position frame_count = 0;
 
@@ -139,21 +136,6 @@ static int mlt_playlist_virtual_refresh( mlt_playlist this )
                mlt_producer producer = this->list[ i ]->producer;
                int current_length = mlt_producer_get_out( producer ) - mlt_producer_get_in( producer ) + 1;
 
-               // If fps is 0
-               if ( fps == 0 )
-               {
-                       // Inherit it from the producer
-                       fps = mlt_producer_get_fps( producer );
-               }
-               else if ( fps != mlt_properties_get_double( MLT_PRODUCER_PROPERTIES( producer ), "fps" ) )
-               {
-                       // Generate a warning for now - the following attempt to fix may fail
-                       fprintf( stderr, "Warning: fps mismatch on playlist producer %d\n", this->count );
-
-                       // It should be safe to impose fps on an image producer, but not necessarily safe for video
-                       mlt_properties_set_double( MLT_PRODUCER_PROPERTIES( producer ), "fps", fps );
-               }
-
                // Check if the length of the producer has changed
                if ( this->list[ i ]->frame_in != mlt_producer_get_in( producer ) ||
                         this->list[ i ]->frame_out != mlt_producer_get_out( producer ) )
@@ -184,8 +166,6 @@ static int mlt_playlist_virtual_refresh( mlt_playlist this )
        }
 
        // Refresh all properties
-       mlt_properties_set_double( properties, "first_fps", fps );
-       mlt_properties_set_double( properties, "fps", fps == 0 ? 25 : fps );
        mlt_events_block( properties, properties );
        mlt_properties_set_position( properties, "length", frame_count );
        mlt_events_unblock( properties, properties );
@@ -263,6 +243,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 )
        {
@@ -350,7 +343,7 @@ static mlt_service mlt_playlist_virtual_seek( mlt_playlist this, int *progressiv
        {
                int count = this->list[ i ]->frame_count / this->list[ i ]->repeat;
                *progressive = count == 1;
-               mlt_producer_seek( producer, position % count );
+               mlt_producer_seek( producer, (int)position % count );
        }
        else if ( !strcmp( eof, "pause" ) && total > 0 )
        {
@@ -359,7 +352,7 @@ static mlt_service mlt_playlist_virtual_seek( mlt_playlist this, int *progressiv
                mlt_producer this_producer = MLT_PLAYLIST_PRODUCER( this );
                mlt_producer_seek( this_producer, original - 1 );
                producer = entry->producer;
-               mlt_producer_seek( producer, entry->frame_out % count );
+               mlt_producer_seek( producer, (int)entry->frame_out % count );
                mlt_producer_set_speed( this_producer, 0 );
                mlt_producer_set_speed( producer, 0 );
                *progressive = count == 1;
@@ -548,7 +541,6 @@ int mlt_playlist_clear( mlt_playlist this )
                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 );
 }
 
@@ -872,14 +864,14 @@ int mlt_playlist_split_at( mlt_playlist this, mlt_position position, int left )
 
 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 ];
@@ -1022,7 +1014,7 @@ mlt_producer mlt_playlist_get_clip( mlt_playlist this, int clip )
 /** Return the clip at the specified position.
 */
 
-mlt_producer mlt_playlist_get_clip_at( mlt_playlist this, int position )
+mlt_producer mlt_playlist_get_clip_at( mlt_playlist this, mlt_position position )
 {
        int index = 0, total = 0;
        return mlt_playlist_locate( this, &position, &index, &total );
@@ -1031,7 +1023,7 @@ mlt_producer mlt_playlist_get_clip_at( mlt_playlist this, int position )
 /** Return the clip index of the specified position.
 */
 
-int mlt_playlist_get_clip_index_at( mlt_playlist this, int position )
+int mlt_playlist_get_clip_index_at( mlt_playlist this, mlt_position position )
 {
        int index = 0, total = 0;
        mlt_playlist_locate( this, &position, &index, &total );
@@ -1195,7 +1187,7 @@ int mlt_playlist_is_blank( mlt_playlist this, int clip )
 /** Determine if the specified position is a blank.
 */
 
-int mlt_playlist_is_blank_at( mlt_playlist this, int position )
+int mlt_playlist_is_blank_at( mlt_playlist this, mlt_position position )
 {
        return this == NULL || mlt_producer_is_blank( mlt_playlist_get_clip_at( this, position ) );
 }
@@ -1238,7 +1230,7 @@ void mlt_playlist_insert_blank( mlt_playlist this, int clip, int length )
        }
 }
 
-void mlt_playlist_pad_blanks( mlt_playlist this, int position, int length, int find )
+void mlt_playlist_pad_blanks( mlt_playlist this, mlt_position position, int length, int find )
 {
        if ( this != NULL && length != 0 )
        {
@@ -1265,7 +1257,7 @@ void mlt_playlist_pad_blanks( mlt_playlist this, int position, int length, int f
        }
 }
 
-int mlt_playlist_insert_at( mlt_playlist this, int position, mlt_producer producer, int mode )
+int mlt_playlist_insert_at( mlt_playlist this, mlt_position position, mlt_producer producer, int mode )
 {
        int ret = this == NULL || position < 0 || producer == NULL;
        if ( ret == 0 )
@@ -1279,7 +1271,7 @@ int mlt_playlist_insert_at( mlt_playlist this, int position, mlt_producer produc
                if ( clip < this->count && mlt_playlist_is_blank( this, clip ) )
                {
                        // Split and move to new clip if need be
-                       if ( position != info.start && mlt_playlist_split( this, clip, position - info.start ) == 0 )
+                       if ( position != info.start && mlt_playlist_split( this, clip, position - info.start - 1 ) == 0 )
                                mlt_playlist_get_clip_info( this, &info, ++ clip );
 
                        // Split again if need be
@@ -1309,8 +1301,12 @@ int mlt_playlist_insert_at( mlt_playlist this, int position, mlt_producer produc
                }
                else 
                {
-                       if ( mode == 1 )
-                               mlt_playlist_blank( this, position - mlt_properties_get_int( properties, "length" ) );
+                       if ( mode == 1 ) {
+                               if ( position == info.start ) 
+                                       mlt_playlist_remove( this, clip );
+                               else
+                                       mlt_playlist_blank( this, position - mlt_properties_get_int( properties, "length" ) - 1 );
+                       }
                        mlt_playlist_append( this, producer );
                        ret = this->count - 1;
                }
@@ -1329,7 +1325,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 clip < 0 ? 0 : mlt_producer_get_playtime( MLT_PLAYLIST_PRODUCER( this ) ) + 1;
+       return clip < 0 ? 0 : mlt_producer_get_playtime( MLT_PLAYLIST_PRODUCER( this ) );
 }
 
 int mlt_playlist_clip_length( mlt_playlist this, int clip )
@@ -1363,7 +1359,7 @@ int mlt_playlist_blanks_from( mlt_playlist this, int clip, int bounded )
        return count;
 }
 
-int mlt_playlist_remove_region( mlt_playlist this, int position, int length )
+int mlt_playlist_remove_region( mlt_playlist this, mlt_position position, int length )
 {
        int index = mlt_playlist_get_clip_index_at( this, position );
        if ( index >= 0 && index < this->count )
@@ -1401,7 +1397,7 @@ int mlt_playlist_remove_region( mlt_playlist this, int position, int length )
        return index;
 }
 
-int mlt_playlist_move_region( mlt_playlist this, int position, int length, int new_position )
+int mlt_playlist_move_region( mlt_playlist this, mlt_position position, int length, int new_position )
 {
        if ( this != NULL )
        {
@@ -1417,8 +1413,8 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
        // Check that we have a producer
        if ( producer == NULL )
        {
-               *frame = mlt_frame_init( );
-               return 0;
+               *frame = NULL;
+               return -1;
        }
 
        // Get this mlt_playlist
@@ -1433,12 +1429,27 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
        // Check that we have a producer
        if ( real == NULL )
        {
-               *frame = mlt_frame_init( );
+               *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) );
                return 0;
        }
 
        // 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_PRODUCER_SERVICE( parent ) );
+               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( MLT_PRODUCER_SERVICE( 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 );