-/*
- * mlt_multitrack.c -- multitrack service class
- * Copyright (C) 2003-2004 Ushodaya Enterprises Limited
- * Author: Charles Yates <charles.yates@pandora.be>
+/**
+ * \file mlt_multitrack.c
+ * \brief multitrack service class
+ *
+ * Copyright (C) 2003-2008 Ushodaya Enterprises Limited
+ * \author Charles Yates <charles.yates@pandora.be>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "config.h"
-
#include "mlt_multitrack.h"
#include "mlt_playlist.h"
#include "mlt_frame.h"
this = NULL;
}
}
-
+
return this;
}
// We need to ensure that the multitrack reports the longest track as its length
mlt_position length = 0;
- // We need to ensure that fps are the same on all services
- double fps = 0;
-
// Obtain stats on all connected services
for ( i = 0; i < this->count; i ++ )
{
// If we have more than 1 track, we must be in continue mode
if ( this->count > 1 )
mlt_properties_set( MLT_PRODUCER_PROPERTIES( producer ), "eof", "continue" );
-
+
// Determine the longest length
//if ( !mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( producer ), "hide" ) )
length = mlt_producer_get_playtime( producer ) > length ? mlt_producer_get_playtime( producer ) : length;
-
- // Handle fps
- if ( fps == 0 )
- {
- // This is the first producer, so it controls the fps
- fps = mlt_producer_get_fps( producer );
- }
- else if ( fps != mlt_producer_get_fps( producer ) )
- {
- // Generate a warning for now - the following attempt to fix may fail
- fprintf( stderr, "Warning: fps mismatch on track %d\n", i );
-
- // 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 );
- }
}
}
mlt_properties_set_position( properties, "length", length );
mlt_events_unblock( properties, properties );
mlt_properties_set_position( properties, "out", length - 1 );
- mlt_properties_set_double( properties, "fps", fps );
}
/** Listener for producers on the playlist.
// Assign the track in our list here
this->list[ track ]->producer = producer;
- this->list[ track ]->event = mlt_events_listen( MLT_PRODUCER_PROPERTIES( producer ), this,
+ this->list[ track ]->event = mlt_events_listen( MLT_PRODUCER_PROPERTIES( producer ), this,
"producer-changed", ( mlt_listener )mlt_multitrack_listener );
mlt_properties_inc_ref( MLT_PRODUCER_PROPERTIES( producer ) );
mlt_event_inc_ref( this->list[ track ]->event );
-
+
// Increment the track count if need be
if ( track >= this->count )
this->count = track + 1;
-
+
// Refresh our stats
mlt_multitrack_refresh( this );
}
int mlt_multitrack_count( mlt_multitrack this )
{
- return this->count;
+ return this->count;
}
/** Get an individual track as a producer.
mlt_producer mlt_multitrack_track( mlt_multitrack this, int track )
{
mlt_producer producer = NULL;
-
+
if ( this->list != NULL && track < this->count )
producer = this->list[ track ]->producer;
/** Determine the clip point.
- Special case here: a 'producer' has no concept of multiple clips - only the
- playlist and multitrack producers have clip functionality. Further to that a
- multitrack determines clip information from any connected tracks that happen
+ Special case here: a 'producer' has no concept of multiple clips - only the
+ playlist and multitrack producers have clip functionality. Further to that a
+ multitrack determines clip information from any connected tracks that happen
to be playlists.
Additionally, it must locate clips in the correct order, for example, consider
case mlt_whence_relative_current:
position = mlt_producer_position( MLT_MULTITRACK_PRODUCER( this ) );
- for ( i = 0; i < count - 2; i ++ )
+ for ( i = 0; i < count - 2; i ++ )
if ( position >= map[ i ] && position < map[ i + 1 ] )
break;
index += i;
Producer2 - multitrack - { filters/transitions } - tractor - consumer
Producer3 /
- The get_frame of a tractor pulls frames from it's connected service on all tracks and
- will terminate as soon as it receives a test card with a last_track property. The
+ The get_frame of a tractor pulls frames from it's connected service on all tracks and
+ will terminate as soon as it receives a test card with a last_track property. The
important case here is that the mulitrack does not move to the next frame until all
- tracks have been pulled.
+ tracks have been pulled.
Reasoning: In order to seek on a network such as above, the multitrack needs to ensure
that all producers are positioned on the same frame. It uses the 'last track' logic
else
{
// Generate a test frame
- *frame = mlt_frame_init( );
+ *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( parent ) );
// Update position on the frame we're creating
mlt_frame_set_position( *frame, mlt_producer_position( parent ) );