#include "mlt_service.h"
#include "mlt_filter.h"
#include "mlt_transition.h"
+#include "mlt_multitrack.h"
+#include "mlt_tractor.h"
#include <stdlib.h>
#include <string.h>
struct mlt_field_s
{
- // We extending service here
- struct mlt_service_s parent;
-
// This is the producer we're connected to
mlt_service producer;
+
+ // Multitrack
+ mlt_multitrack multitrack;
+
+ // Tractor
+ mlt_tractor tractor;
};
-/** Forward declarations
+/** Constructor.
+
+ We construct a multitrack and a tractor here.
*/
-static int service_get_frame( mlt_service service, mlt_frame_ptr frame, int index );
+mlt_field mlt_field_init( )
+{
+ // Initialise the field
+ mlt_field this = calloc( sizeof( struct mlt_field_s ), 1 );
-/** Constructor. This service needs to know its producer at construction.
+ // Initialise it
+ if ( this != NULL )
+ {
+ // Construct a multitrack
+ this->multitrack = mlt_multitrack_init( );
- When the first filter or transition is planted, we connect it immediately to
- the producer of the field, and all subsequent plants are then connected to the
- previous plant. This immediate connection requires the producer prior to the first
- plant.
-
- It's a kind of arbitrary decsion - we could generate a dummy service here and
- then connect the dummy in the normal connect manner. Behaviour may change in the
- future (say, constructing a dummy when producer service is NULL). However, the
- current solution is quite clean, if slightly out of sync with the rest of the
- mlt framework.
-*/
+ // Construct a tractor
+ this->tractor = mlt_tractor_init( );
-mlt_field mlt_field_init( mlt_service producer )
+ // 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;
+}
+
+mlt_field mlt_field_new( mlt_multitrack multitrack, mlt_tractor tractor )
{
// Initialise the field
mlt_field this = calloc( sizeof( struct mlt_field_s ), 1 );
- // Get the service
- mlt_service service = &this->parent;
+ // Initialise it
+ if ( this != NULL )
+ {
+ // Construct a multitrack
+ this->multitrack = multitrack;
- // Initialise the service
- mlt_service_init( service, this );
+ // Construct a tractor
+ this->tractor = tractor;
- // Override the get_frame method
- service->get_frame = service_get_frame;
+ // The first plant will be connected to the mulitrack
+ this->producer = MLT_MULTITRACK_SERVICE( this->multitrack );
- // Connect to the producer immediately
- if ( mlt_service_connect_producer( service, producer, 0 ) == 0 )
- this->producer = producer;
+ // Connect the tractor to the multitrack
+ mlt_tractor_connect( this->tractor, this->producer );
+ }
// Return this
return this;
mlt_service mlt_field_service( mlt_field this )
{
- return &this->parent;
+ return MLT_TRACTOR_SERVICE( this->tractor );
+}
+
+/** Get the multi track.
+*/
+
+mlt_multitrack mlt_field_multitrack( mlt_field this )
+{
+ return this != NULL ? this->multitrack : NULL;
+}
+
+/** Get the tractor.
+*/
+
+mlt_tractor mlt_field_tractor( mlt_field this )
+{
+ return this != NULL ? this->tractor : NULL;
}
/** Get the properties associated to this field.
mlt_properties mlt_field_properties( mlt_field this )
{
- return mlt_service_properties( &this->parent );
+ return MLT_SERVICE_PROPERTIES( mlt_field_service( this ) );
}
/** Plant a filter.
// If sucessful, then we'll use this for connecting in the future
if ( result == 0 )
{
- // Update last
- this->producer = mlt_filter_service( that );
+ // This is now the new producer
+ this->producer = MLT_FILTER_SERVICE( that );
+
+ // Reconnect tractor to new producer
+ mlt_tractor_connect( this->tractor, this->producer );
+
+ // Fire an event
+ mlt_events_fire( mlt_field_properties( this ), "service-changed", NULL );
}
return result;
// If sucessful, then we'll use this for connecting in the future
if ( result == 0 )
{
- // Update last
- this->producer = mlt_transition_service( that );
- }
+ // This is now the new producer
+ this->producer = MLT_TRANSITION_SERVICE( that );
- return 0;
-}
+ // Reconnect tractor to new producer
+ mlt_tractor_connect( this->tractor, this->producer );
-/** Get a frame.
-*/
+ // Fire an event
+ mlt_events_fire( mlt_field_properties( this ), "service-changed", NULL );
+ }
-static int service_get_frame( mlt_service service, mlt_frame_ptr frame, int index )
-{
- mlt_field this = service->child;
- return mlt_service_get_frame( this->producer, frame, index );
+ return 0;
}
/** Close the field.
void mlt_field_close( mlt_field this )
{
- mlt_service_close( &this->parent );
- free( this );
+ if ( this != NULL && mlt_properties_dec_ref( mlt_field_properties( this ) ) <= 0 )
+ {
+ //mlt_tractor_close( this->tractor );
+ //mlt_multitrack_close( this->multitrack );
+ free( this );
+ }
}