// Hmm - default all consumers to yuv422 :-/
this->format = mlt_image_yuv422;
+
+ mlt_events_register( properties, "consumer-stopped", NULL );
}
return error;
}
return frame;
}
+/** Callback for the implementation to indicate a stopped condition.
+*/
+
+void mlt_consumer_stopped( mlt_consumer this )
+{
+ mlt_properties_set_int( mlt_consumer_properties( this ), "running", 0 );
+ mlt_events_fire( mlt_consumer_properties( this ), "consumer-stopped", NULL );
+}
+
/** Stop the consumer.
*/
extern mlt_frame mlt_consumer_rt_frame( mlt_consumer self );
extern int mlt_consumer_stop( mlt_consumer self );
extern int mlt_consumer_is_stopped( mlt_consumer self );
+extern void mlt_consumer_stopped( mlt_consumer self );
extern void mlt_consumer_close( mlt_consumer );
#endif
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
+#include <pthread.h>
#include "mlt_properties.h"
#include "mlt_events.h"
void mlt_event_inc_ref( mlt_event this )
{
- if ( this != NULL && this->owner != NULL )
+ if ( this != NULL )
this->ref_count ++;
}
void mlt_event_close( mlt_event this )
{
- if ( this != NULL && this->owner != NULL )
+ if ( this != NULL )
{
if ( -- this->ref_count == 1 )
this->owner = NULL;
}
}
+typedef struct
+{
+ int done;
+ pthread_cond_t cond;
+ pthread_mutex_t mutex;
+}
+condition_pair;
+
+static void mlt_events_listen_for( mlt_properties this, condition_pair *pair )
+{
+ pthread_mutex_lock( &pair->mutex );
+ if ( pair->done == 0 )
+ {
+ pthread_cond_signal( &pair->cond );
+ pthread_mutex_unlock( &pair->mutex );
+ }
+}
+
+mlt_event mlt_events_setup_wait_for( mlt_properties this, char *id )
+{
+ condition_pair *pair = malloc( sizeof( condition_pair ) );
+ pair->done = 0;
+ pthread_cond_init( &pair->cond, NULL );
+ pthread_mutex_init( &pair->mutex, NULL );
+ pthread_mutex_lock( &pair->mutex );
+ return mlt_events_listen( this, pair, id, ( mlt_listener )mlt_events_listen_for );
+}
+
+void mlt_events_wait_for( mlt_properties this, mlt_event event )
+{
+ if ( event != NULL )
+ {
+ condition_pair *pair = event->service;
+ pthread_cond_wait( &pair->cond, &pair->mutex );
+ }
+}
+
+void mlt_events_close_wait_for( mlt_properties this, mlt_event event )
+{
+ if ( event != NULL )
+ {
+ condition_pair *pair = event->service;
+ event->owner = NULL;
+ pair->done = 0;
+ pthread_mutex_unlock( &pair->mutex );
+ pthread_mutex_destroy( &pair->mutex );
+ pthread_cond_destroy( &pair->cond );
+ }
+}
+
/** Fetch the events object.
*/
extern void mlt_events_unblock( mlt_properties self, void *service );
extern void mlt_events_disconnect( mlt_properties self, void *service );
+extern mlt_event mlt_events_setup_wait_for( mlt_properties self, char *id );
+extern void mlt_events_wait_for( mlt_properties self, mlt_event event );
+extern void mlt_events_close_wait_for( mlt_properties self, mlt_event event );
+
extern void mlt_event_inc_ref( mlt_event self );
extern void mlt_event_block( mlt_event self );
extern void mlt_event_unblock( mlt_event self );
this->list[ this->count ]->frame_out = out;
this->list[ this->count ]->frame_count = out - in + 1;
this->list[ this->count ]->event = mlt_events_listen( properties, this, "producer-changed", ( mlt_listener )mlt_playlist_listener );
+ mlt_event_inc_ref( this->list[ this->count ]->event );
mlt_properties_set( properties, "eof", "pause" );
// Just in case we terminated on pause
mlt_properties_set_int( properties, "running", 0 );
+ mlt_consumer_stopped( this );
+
return NULL;
}
}
}
+ // Indicate that the consumer is stopped
+ mlt_consumer_stopped( this );
+
return NULL;
}
// Tidy up
mlt_pool_release( dv_frame );
+ mlt_consumer_stopped( this );
+
return NULL;
}
mlt_frame_close( next );
}
+ mlt_consumer_stopped( &this->parent );
+
return NULL;
}
mlt_consumer_stop( this );
+ mlt_consumer_stopped( this );
+
return 0;
}