| +------+ | +-------------+ +-------+
+----------+
- In reality, we create a field first, and from that we obtain a multitrack
- and a tractor. We can then populate the multitrack, field and finally,
- connect the tractor to the consumer.
-
- The reasoning behind this is possibly flawed - it might have made more
- sense to produce the tractor and have it encapsulate the field and the
- multitrack as that is how it looks to a connected consumer:
+ So, we need to create the tractor first, and from that we obtain the
+ multitrack and field objects. We can populate these and finally
+ connect the tractor to a consumer.
+
+ In essence, this is how it looks to the consumer:
+-----------------------------------------------+
|tractor +--------------------------+ |
mlt_producer create_tracks( int argc, char **argv )
{
- // Create the field
- mlt_field field = mlt_field_init( );
+ // Create the tractor
+ mlt_tractor tractor = mlt_tractor_new( );
+
+ // Obtain the field
+ mlt_field field = mlt_tractor_field( tractor );
// Obtain the multitrack
- mlt_multitrack multitrack = mlt_field_multitrack( field );
-
- // Obtain the tractor
- mlt_tractor tractor = mlt_field_tractor( field );
+ mlt_multitrack multitrack = mlt_tractor_multitrack( tractor );
- // Obtain a composite transition
+ // Create a composite transition
mlt_transition transition = mlt_factory_transition( "composite", "10%,10%:15%x15%" );
// Create track 0
// Now plant the transition
mlt_field_plant_transition( field, transition, 0, 1 );
-
- // Now set the properties on the tractor
- properties = mlt_tractor_properties( tractor );
- mlt_properties_set_data( properties, "multitrack", multitrack, 0, ( mlt_destructor )mlt_multitrack_close, NULL );
- mlt_properties_set_data( properties, "field", field, 0, ( mlt_destructor )mlt_field_close, NULL );
- mlt_properties_set_data( properties, "track0", track0, 0, ( mlt_destructor )mlt_producer_close, NULL );
- mlt_properties_set_data( properties, "track1", track1, 0, ( mlt_destructor )mlt_producer_close, NULL );
- mlt_properties_set_data( properties, "transition", transition, 0, ( mlt_destructor )mlt_transition_close, NULL );
-
+
+ // Close our references
+ mlt_producer_close( track0 );
+ mlt_producer_close( track1 );
+ mlt_transition_close( transition );
+
// Return the tractor
return mlt_tractor_producer( tractor );
}
return this;
}
+mlt_field mlt_field_new( mlt_multitrack multitrack, mlt_tractor tractor )
+{
+ // Initialise the field
+ mlt_field this = calloc( sizeof( struct mlt_field_s ), 1 );
+
+ // Initialise it
+ if ( this != NULL )
+ {
+ // Construct a multitrack
+ this->multitrack = multitrack;
+
+ // Construct a tractor
+ this->tractor = tractor;
+
+ // The first plant will be connected to the mulitrack
+ this->producer = mlt_multitrack_service( this->multitrack );
+
+ // Connect the tractor to the multitrack
+ mlt_tractor_connect( this->tractor, this->producer );
+ }
+
+ // Return this
+ return this;
+}
+
/** Get the service associated to this field.
*/
#include "mlt_types.h"
extern mlt_field mlt_field_init( );
+extern mlt_field mlt_field_new( mlt_multitrack multitrack, mlt_tractor tractor );
extern mlt_service mlt_field_service( mlt_field self );
extern mlt_tractor mlt_field_tractor( mlt_field self );
extern mlt_multitrack mlt_field_multitrack( mlt_field self );
#include "mlt_tractor.h"
#include "mlt_frame.h"
#include "mlt_multitrack.h"
+#include "mlt_field.h"
#include <stdio.h>
#include <stdlib.h>
return this;
}
+mlt_tractor mlt_tractor_new( )
+{
+ mlt_tractor this = calloc( sizeof( struct mlt_tractor_s ), 1 );
+ if ( this != NULL )
+ {
+ mlt_producer producer = &this->parent;
+ if ( mlt_producer_init( producer, this ) == 0 )
+ {
+ mlt_multitrack multitrack = mlt_multitrack_init( );
+ mlt_field field = mlt_field_new( multitrack, this );
+ mlt_properties props = mlt_producer_properties( producer );
+
+ mlt_properties_set( props, "resource", "<tractor>" );
+ mlt_properties_set( props, "mlt_type", "mlt_producer" );
+ mlt_properties_set( props, "mlt_service", "tractor" );
+ mlt_properties_set_data( props, "multitrack", multitrack, 0, ( mlt_destructor )mlt_multitrack_close, NULL );
+ mlt_properties_set_data( props, "field", field, 0, ( mlt_destructor )mlt_field_close, NULL );
+
+ producer->get_frame = producer_get_frame;
+ producer->close = ( mlt_destructor )mlt_tractor_close;
+ producer->close_object = this;
+ }
+ else
+ {
+ free( this );
+ this = NULL;
+ }
+ }
+ return this;
+}
+
/** Get the service object associated to the tractor.
*/
return mlt_producer_properties( &this->parent );
}
+/** Get the field this tractor is harvesting.
+*/
+
+mlt_field mlt_tractor_field( mlt_tractor this )
+{
+ return mlt_properties_get_data( mlt_tractor_properties( this ), "field", NULL );
+}
+
+/** Get the multitrack this tractor is pulling.
+*/
+
+mlt_multitrack mlt_tractor_multitrack( mlt_tractor this )
+{
+ return mlt_properties_get_data( mlt_tractor_properties( this ), "multitrack", NULL );
+}
+
/** Connect the tractor.
*/
#include "mlt_producer.h"
extern mlt_tractor mlt_tractor_init( );
+extern mlt_tractor mlt_tractor_new( );
extern mlt_service mlt_tractor_service( mlt_tractor self );
extern mlt_producer mlt_tractor_producer( mlt_tractor self );
extern mlt_properties mlt_tractor_properties( mlt_tractor self );
+extern mlt_field mlt_tractor_field( mlt_tractor self );
+extern mlt_multitrack mlt_tractor_multitrack( mlt_tractor self );
extern int mlt_tractor_connect( mlt_tractor self, mlt_service service );
extern void mlt_tractor_close( mlt_tractor self );
mlt_playlist playlist = mlt_playlist_init( );
mlt_properties group = mlt_properties_new( );
mlt_properties properties = group;
- mlt_field field = mlt_field_init( );
+ mlt_tractor tractor = mlt_tractor_new( );
+ mlt_field field = mlt_tractor_field( tractor );
mlt_properties field_properties = mlt_field_properties( field );
- mlt_multitrack multitrack = mlt_field_multitrack( field );
+ mlt_multitrack multitrack = mlt_tractor_multitrack( tractor );
// We need to track the number of registered filters
mlt_properties_set_int( field_properties, "registered", 0 );
if ( mlt_playlist_count( playlist ) > 0 )
mlt_multitrack_connect( multitrack, mlt_playlist_producer( playlist ), track );
- mlt_tractor tractor = mlt_field_tractor( field );
mlt_producer prod = mlt_tractor_producer( tractor );
mlt_properties props = mlt_tractor_properties( tractor );
- mlt_properties_set_data( props, "multitrack", multitrack, 0, ( mlt_destructor )mlt_multitrack_close, NULL );
- mlt_properties_set_data( props, "field", field, 0, ( mlt_destructor )mlt_field_close, NULL );
mlt_properties_set_data( props, "group", group, 0, ( mlt_destructor )mlt_properties_close, NULL );
mlt_properties_set_position( props, "length", mlt_producer_get_out( mlt_multitrack_producer( multitrack ) ) + 1 );
mlt_producer_set_in_and_out( prod, 0, mlt_producer_get_out( mlt_multitrack_producer( multitrack ) ) );
mlt_properties_set_double( props, "fps", mlt_producer_get_fps( mlt_multitrack_producer( multitrack ) ) );
- return mlt_tractor_producer( tractor );
+ return prod;
}
while( mlt_deque_count( context->filter_queue ) )
{
mlt_properties filter_properties = mlt_deque_pop_front( context->filter_queue );
- mlt_properties_debug( filter_properties, "Filter?", stderr );
mlt_filter filter = mlt_factory_filter( mlt_properties_get( filter_properties, "mlt_service" ), NULL );
if ( filter != NULL )
{