X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fframework%2Fmlt_service.c;h=7a66a577e417b40224d71bd2ce121080a9ddb26e;hb=52c1bb26fcbb895824cd9237c228ea4834ce1433;hp=62112d9653f20f66a572c50bb436b28f8de4b724;hpb=12d4027b3039f13c4b5f9fdb12f2fb4b7d3c3f44;p=mlt diff --git a/src/framework/mlt_service.c b/src/framework/mlt_service.c index 62112d96..7a66a577 100644 --- a/src/framework/mlt_service.c +++ b/src/framework/mlt_service.c @@ -47,7 +47,7 @@ typedef struct } mlt_service_base; -/** Friends? +/** Private methods */ static void mlt_service_disconnect( mlt_service this ); @@ -59,20 +59,29 @@ static int service_get_frame( mlt_service this, mlt_frame_ptr frame, int index ) 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. @@ -87,15 +96,7 @@ int mlt_service_connect_producer( mlt_service this, mlt_service producer, int in 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 ++ ) @@ -118,6 +119,13 @@ int mlt_service_connect_producer( mlt_service this, mlt_service producer, int in // 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 ); @@ -131,6 +139,9 @@ int mlt_service_connect_producer( mlt_service this, mlt_service producer, int in // 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; } @@ -143,120 +154,79 @@ int mlt_service_connect_producer( mlt_service this, mlt_service producer, int in /** 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 ]; @@ -267,9 +237,23 @@ static int service_get_frame( mlt_service this, mlt_frame_ptr frame, int 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. @@ -277,9 +261,24 @@ int mlt_service_get_frame( mlt_service this, mlt_frame_ptr frame, int index ) 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 ); + } + } }