}
mlt_service_base;
-/** Friends?
+/** Private methods
*/
static void mlt_service_disconnect( mlt_service this );
int mlt_service_init( mlt_service this, void *child )
{
+ int error = 0;
+
// Initialise everything to NULL
memset( this, 0, sizeof( struct mlt_service_s ) );
// Assign the child
this->child = child;
- // Generate private space
- this->private = calloc( sizeof( mlt_service_base ), 1 );
+ // Generate local space
+ this->local = calloc( sizeof( mlt_service_base ), 1 );
// Associate the methods
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;
+ }
+
+ return error;
}
/** Connect a producer service.
int i = 0;
// Get the service base
- mlt_service_base *base = this->private;
-
- // Does this service accept input?
- if ( mlt_service_accepts_input( this ) == 0 )
- return 1;
-
- // Does the producer service accept output connections?
- if ( mlt_service_accepts_output( producer ) == 0 )
- return 2;
+ mlt_service_base *base = this->local;
// Check if the producer is already registered with this service
for ( i = 0; i < base->count; i ++ )
// 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;
}
/** Disconnect this service from its consumer.
*/
-void mlt_service_disconnect( mlt_service this )
+static void mlt_service_disconnect( mlt_service this )
{
- // Get the service base
- mlt_service_base *base = this->private;
+ if ( this != NULL )
+ {
+ // Get the service base
+ mlt_service_base *base = this->local;
- // There's a bit more required here...
- base->out = NULL;
+ // Disconnect
+ base->out = NULL;
+ }
}
-/** Associate this service to the its consumer.
+/** Obtain the consumer this service is connected to.
*/
-void mlt_service_connect( mlt_service this, mlt_service that )
+mlt_service mlt_service_consumer( mlt_service this )
{
// Get the service base
- mlt_service_base *base = this->private;
+ mlt_service_base *base = this->local;
- // There's a bit more required here...
- base->out = that;
+ // Return the connected consumer
+ return base->out;
}
-
-/** Get the first connected producer service.
+/** Obtain the producer this service is connected to.
*/
-mlt_service mlt_service_get_producer( mlt_service this )
+mlt_service mlt_service_producer( mlt_service this )
{
- mlt_service producer = NULL;
-
// Get the service base
- mlt_service_base *base = this->private;
+ mlt_service_base *base = this->local;
- if ( base->in != NULL )
- producer = base->in[ 0 ];
-
- return producer;
-}
-
-
-/** Get the service state.
-*/
-
-mlt_service_state mlt_service_get_state( mlt_service this )
-{
- mlt_service_state state = mlt_state_unknown;
- if ( mlt_service_has_input( this ) )
- state |= mlt_state_providing;
- if ( mlt_service_has_output( this ) )
- state |= mlt_state_connected;
- if ( state != ( mlt_state_providing | mlt_state_connected ) )
- state |= mlt_state_dormant;
- return state;
+ // Return the connected producer
+ return base->count > 0 ? base->in[ base->count - 1 ] : NULL;
}
-/** Get the maximum number of inputs accepted.
- Returns: -1 for many, 0 for none or n for fixed.
+/** Associate this service to the consumer.
*/
-int mlt_service_accepts_input( mlt_service this )
+static void mlt_service_connect( mlt_service this, mlt_service that )
{
- if ( this->accepts_input == NULL )
- return -1;
- else
- return this->accepts_input( this );
-}
-
-/** Get the maximum number of outputs accepted.
-*/
-
-int mlt_service_accepts_output( mlt_service this )
-{
- if ( this->accepts_output == NULL )
- return 1;
- else
- return this->accepts_output( this );
-}
-
-/** Determines if this service has input
-*/
+ if ( this != NULL )
+ {
+ // Get the service base
+ mlt_service_base *base = this->local;
-int mlt_service_has_input( mlt_service this )
-{
- if ( this->has_input == NULL )
- return 1;
- else
- return this->has_input( this );
+ // There's a bit more required here...
+ base->out = that;
+ }
}
-/** Determine if this service has output
+/** Get the first connected producer service.
*/
-int mlt_service_has_output( mlt_service this )
+mlt_service mlt_service_get_producer( mlt_service this )
{
- mlt_service_base *base = this->private;
- if ( this->has_output == NULL )
- return base->out != NULL;
- else
- return this->has_output( this );
-}
+ mlt_service producer = NULL;
-/** Check if the service is active.
-*/
+ // Get the service base
+ mlt_service_base *base = this->local;
-int mlt_service_is_active( mlt_service this )
-{
- return !( mlt_service_get_state( this ) & mlt_state_dormant );
+ if ( base->in != NULL )
+ producer = base->in[ 0 ];
+
+ return producer;
}
-/** Obtain a frame to pass on.
+/** Default implementation of get_frame.
*/
static int service_get_frame( mlt_service this, mlt_frame_ptr frame, int index )
{
- mlt_service_base *base = this->private;
+ mlt_service_base *base = this->local;
if ( index < base->count )
{
mlt_service producer = base->in[ index ];
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->private;
- 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 );
+ }
+ }
}