#include "mlt_playlist.h"
#include "mlt_frame.h"
+#include <stdio.h>
#include <stdlib.h>
/** Virtual playlist entry.
// Initialise blank
mlt_producer_init( &this->blank, NULL );
+
+ // Indicate that this producer is a playlist
+ mlt_properties_set_data( mlt_playlist_properties( this ), "playlist", this, 0, NULL, NULL );
}
return this;
return mlt_producer_service( &this->parent );
}
+/** Get the propertues associated to this playlist.
+*/
+
+mlt_properties mlt_playlist_properties( mlt_playlist this )
+{
+ return mlt_producer_properties( &this->parent );
+}
+
/** Append to the virtual playlist.
*/
static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer, mlt_timecode in, mlt_timecode out )
{
+ // Get the fps of the first producer
+ double fps = mlt_properties_get_double( mlt_playlist_properties( this ), "first_fps" );
+
+ // 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 that we have room
if ( this->count >= this->size )
{
this->count ++;
+ mlt_properties_set_double( mlt_playlist_properties( this ), "first_fps", fps );
+ mlt_properties_set_double( mlt_playlist_properties( this ), "fps", fps );
+
return 0;
}
return producer;
}
+static mlt_producer mlt_playlist_virtual_set_out( mlt_playlist this )
+{
+ // Default producer to blank
+ mlt_producer producer = &this->blank;
+
+ // Map playlist position to real producer in virtual playlist
+ mlt_timecode position = mlt_producer_position( &this->parent );
+
+ // Loop through the virtual playlist
+ int i = 0;
+
+ for ( i = 0; i < this->count; i ++ )
+ {
+ if ( position < this->list[ i ]->playtime )
+ {
+ // Found it, now break
+ producer = this->list[ i ]->producer;
+ position += this->list[ i ]->in;
+ break;
+ }
+ else
+ {
+ // Decrement position by length of this entry
+ position -= this->list[ i ]->playtime;
+ }
+ }
+
+ // Seek in real producer to relative position
+ if ( i < this->count )
+ {
+ fprintf( stderr, "END OF CLIP %d AT %e\n", i, position );
+ this->list[ i ]->playtime = position - this->list[ i ]->in;
+ }
+
+ return producer;
+}
+
+static int mlt_playlist_current_clip( mlt_playlist this )
+{
+ // Map playlist position to real producer in virtual playlist
+ mlt_timecode position = mlt_producer_position( &this->parent );
+
+ // Loop through the virtual playlist
+ int i = 0;
+
+ for ( i = 0; i < this->count; i ++ )
+ {
+ if ( position < this->list[ i ]->playtime )
+ {
+ // Found it, now break
+ break;
+ }
+ else
+ {
+ // Decrement position by length of this entry
+ position -= this->list[ i ]->playtime;
+ }
+ }
+
+ return i;
+}
+
+/** Get the timecode which corresponds to the start of the next clip.
+*/
+
+mlt_timecode mlt_playlist_clip( mlt_playlist this, mlt_whence whence, int index )
+{
+ mlt_timecode position = 0;
+ int absolute_clip = index;
+ int i = 0;
+
+ // Determine the absolute clip
+ switch ( whence )
+ {
+ case mlt_whence_relative_start:
+ absolute_clip = index;
+ break;
+
+ case mlt_whence_relative_current:
+ absolute_clip = mlt_playlist_current_clip( this ) + index;
+ break;
+
+ case mlt_whence_relative_end:
+ absolute_clip = this->count - index;
+ break;
+ }
+
+ // Check that we're in a valid range
+ if ( absolute_clip < 0 )
+ absolute_clip = 0;
+ else if ( absolute_clip > this->count )
+ absolute_clip = this->count;
+
+ // Now determine the timecode
+ for ( i = 0; i < absolute_clip; i ++ )
+ position += this->list[ i ]->playtime;
+
+ return position;
+}
+
/** Append a producer to the playlist.
*/
// Get the frame
mlt_service_get_frame( mlt_producer_service( real ), frame, index );
+ // Check if we're at the end of the clip
+ mlt_properties properties = mlt_frame_properties( *frame );
+ if ( mlt_properties_get_int( properties, "end_of_clip" ) )
+ mlt_playlist_virtual_set_out( this );
+
// Update timecode on the frame we're creating
mlt_frame_set_timecode( *frame, mlt_producer_position( producer ) );