static void mlt_service_disconnect( mlt_service this );
static void mlt_service_connect( mlt_service this, mlt_service that );
static int service_get_frame( mlt_service this, mlt_frame_ptr frame, int index );
+static void mlt_service_property_changed( mlt_listener, mlt_properties owner, mlt_service this, void **args );
/** Constructor
*/
int mlt_service_init( mlt_service this, void *child )
{
+ int error = 0;
+
// Initialise everything to NULL
memset( this, 0, sizeof( struct mlt_service_s ) );
this->get_frame = service_get_frame;
// Initialise the properties
- return mlt_properties_init( &this->parent, this );
+ error = mlt_properties_init( &this->parent, this );
+ if ( error == 0 )
+ {
+ this->parent.close = ( mlt_destructor )mlt_service_close;
+ this->parent.close_object = this;
+
+ mlt_events_init( &this->parent );
+ mlt_events_register( &this->parent, "property-changed", ( mlt_transmitter )mlt_service_property_changed );
+ }
+
+ return error;
+}
+
+static void mlt_service_property_changed( mlt_listener listener, mlt_properties owner, mlt_service this, void **args )
+{
+ if ( listener != NULL )
+ listener( owner, this, ( char * )args[ 0 ] );
}
/** Connect a producer service.
// If we have space, assign the input
if ( base->in != NULL && index >= 0 && index < base->size )
{
+ // Get the current service
+ mlt_service current = base->in[ index ];
+
+ // Increment the reference count on this producer
+ if ( producer != NULL )
+ mlt_properties_inc_ref( mlt_service_properties( producer ) );
+
// Now we disconnect the producer service from its consumer
mlt_service_disconnect( producer );
// Now we connect the producer to its connected consumer
mlt_service_connect( producer, this );
+ // Close the current service
+ mlt_service_close( current );
+
// Inform caller that all went well
return 0;
}
static void mlt_service_disconnect( mlt_service this )
{
+ if ( this != NULL )
+ {
+ // Get the service base
+ mlt_service_base *base = this->local;
+
+ // Disconnect
+ base->out = NULL;
+ }
+}
+
+/** Obtain the consumer this service is connected to.
+*/
+
+mlt_service mlt_service_consumer( mlt_service this )
+{
// Get the service base
mlt_service_base *base = this->local;
- // There's a bit more required here...
- base->out = NULL;
+ // Return the connected consumer
+ return base->out;
}
-/** Associate this service to the its consumer.
+/** Obtain the producer this service is connected to.
*/
-static void mlt_service_connect( mlt_service this, mlt_service that )
+mlt_service mlt_service_producer( mlt_service this )
{
// Get the service base
mlt_service_base *base = this->local;
- // There's a bit more required here...
- base->out = that;
+ // Return the connected producer
+ return base->count > 0 ? base->in[ base->count - 1 ] : NULL;
+}
+
+/** Associate this service to the consumer.
+*/
+
+static void mlt_service_connect( mlt_service this, mlt_service that )
+{
+ if ( this != NULL )
+ {
+ // Get the service base
+ mlt_service_base *base = this->local;
+
+ // There's a bit more required here...
+ base->out = that;
+ }
}
/** Get the first connected producer service.
return 0;
}
+/** Return the properties object.
+*/
+
+mlt_properties mlt_service_properties( mlt_service self )
+{
+ return self != NULL ? &self->parent : NULL;
+}
+
/** Obtain a frame.
*/
int mlt_service_get_frame( mlt_service this, mlt_frame_ptr frame, int index )
{
- return this->get_frame( this, frame, index );
+ if ( this != NULL )
+ return this->get_frame( this, frame, index );
+ *frame = mlt_frame_init( );
+ return 0;
}
/** Close the service.
void mlt_service_close( mlt_service this )
{
- mlt_service_base *base = this->local;
- free( base->in );
- free( base );
- mlt_properties_close( &this->parent );
+ if ( this != NULL && mlt_properties_dec_ref( mlt_service_properties( this ) ) <= 0 )
+ {
+ if ( this->close != NULL )
+ {
+ this->close( this->close_object );
+ }
+ else
+ {
+ mlt_service_base *base = this->local;
+ int i = 0;
+ for ( i = 0; i < base->count; i ++ )
+ if ( base->in[ i ] != NULL )
+ mlt_service_close( base->in[ i ] );
+ free( base->in );
+ free( base );
+ this->parent.close = NULL;
+ mlt_properties_close( &this->parent );
+ }
+ }
}