char *test_card = mlt_properties_get( properties, "test_card" );
// Just to make sure nothing is hanging around...
- mlt_frame_close( this->put );
this->put = NULL;
this->put_active = 1;
{
pthread_create( &this->ahead_thread, NULL, consumer_read_ahead_thread, this );
}
+ this->started = 1;
}
/** Start the worker threads.
mlt_deque_push_back( this->worker_threads, thread );
}
}
+ this->started = 1;
}
/** Stop the read/render thread.
static void consumer_read_ahead_stop( mlt_consumer this )
{
// Make sure we're running
- if ( this->ahead )
+ if ( this->started )
{
// Inform thread to stop
this->ahead = 0;
// Join the thread
pthread_join( this->ahead_thread, NULL );
+ this->started = 0;
// Destroy the frame queue mutex
pthread_mutex_destroy( &this->queue_mutex );
static void consumer_work_stop( mlt_consumer this )
{
// Make sure we're running
- if ( this->ahead )
+ if ( this->started )
{
// Inform thread to stop
this->ahead = 0;
pthread_cond_broadcast( &this->put_cond );
pthread_mutex_unlock( &this->put_mutex );
+ // Broadcast to the done condition in case it's waiting
+ pthread_mutex_lock( &this->done_mutex );
+ pthread_cond_broadcast( &this->done_cond );
+ pthread_mutex_unlock( &this->done_mutex );
+
// Join the threads
pthread_t *thread;
while ( ( thread = mlt_deque_pop_front( this->worker_threads ) ) )
pthread_join( *thread, NULL );
+ this->started = 0;
// Destroy the mutexes
pthread_mutex_destroy( &this->queue_mutex );
// Fill the work queue.
int i = buffer;
- while ( i-- )
+ while ( this->ahead && i-- )
{
frame = mlt_consumer_get_frame( this );
if ( frame )
this->process_head = size;
}
- mlt_log_debug( MLT_CONSUMER_SERVICE(this), "size %d done count %d work count %d process_head %d\n",
- size, first_unprocessed_frame( this ), mlt_deque_count( this->queue ), this->process_head );
+// mlt_log_verbose( MLT_CONSUMER_SERVICE(this), "size %d done count %d work count %d process_head %d\n",
+// size, first_unprocessed_frame( this ), mlt_deque_count( this->queue ), this->process_head );
// Feed the work queue
- frame = mlt_consumer_get_frame( this );
- if ( ! frame )
- return frame;
- pthread_mutex_lock( &this->queue_mutex );
- mlt_deque_push_back( this->queue, frame );
- pthread_cond_signal( &this->queue_cond );
- pthread_mutex_unlock( &this->queue_mutex );
+ while ( this->ahead && mlt_deque_count( this->queue ) < buffer )
+ {
+ frame = mlt_consumer_get_frame( this );
+ if ( ! frame )
+ return frame;
+ pthread_mutex_lock( &this->queue_mutex );
+ mlt_deque_push_back( this->queue, frame );
+ pthread_cond_signal( &this->queue_cond );
+ pthread_mutex_unlock( &this->queue_mutex );
+ }
// Wait if not realtime.
while( this->ahead && this->real_time < 0 &&
else
this->consecutive_dropped++;
}
- mlt_log_debug( MLT_CONSUMER_SERVICE(this), "dropped %d rendered %d process_head %d\n",
- this->consecutive_dropped, this->consecutive_rendered, this->process_head );
+// mlt_log_verbose( MLT_CONSUMER_SERVICE(this), "dropped %d rendered %d process_head %d\n",
+// this->consecutive_dropped, this->consecutive_rendered, this->process_head );
}
return frame;
// Stop the consumer
mlt_log( MLT_CONSUMER_SERVICE( this ), MLT_LOG_DEBUG, "stopping consumer\n" );
+
+ // Cancel the read ahead threads
+ this->ahead = 0;
+ if ( this->started )
+ {
+ // Unblock the consumer calling mlt_consumer_rt_frame
+ pthread_mutex_lock( &this->queue_mutex );
+ pthread_cond_broadcast( &this->queue_cond );
+ pthread_mutex_unlock( &this->queue_mutex );
+ }
+
+ // Invoke the child callback
if ( this->stop != NULL )
this->stop( this );
#include <framework/mlt_frame.h>
#include <framework/mlt_factory.h>
#include <framework/mlt_producer.h>
+#include <framework/mlt_log.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <SDL.h>
#include <SDL_syswm.h>
-#include <assert.h>
+#include <sys/time.h>
extern pthread_mutex_t mlt_sdl_mutex;
mlt_position duration = mlt_producer_get_playtime( producer );
int pause = 0;
+#ifndef SKIP_WAIT_EOS
if ( this->active == this->play )
{
// Do not interrupt the play consumer near the end
}
else
{
- // Send frame with speed 0 once to stop it
- if ( frame && !eos && speed == 0.0 )
+ // Send frame with speed 0 to stop it
+ if ( frame && !mlt_consumer_is_stopped( this->play ) )
{
mlt_consumer_put_frame( this->play, frame );
+ frame = NULL;
eos = 1;
}
if ( mlt_consumer_is_stopped( this->play ) )
{
// Stream has ended
+ mlt_log_verbose( MLT_CONSUMER_SERVICE( consumer ), "END OF STREAM\n" );
pause = 1;
- eos = 0; // reset eof indicator
+ eos = 0; // reset eos indicator
+ }
+ else
+ {
+ // Prevent a tight busy loop
+ struct timespec tm = { 0, 100000L }; // 100 usec
+ nanosleep( &tm, NULL );
}
}
}
+#else
+ pause = this->active == this->play;
+#endif
if ( pause )
{
// Start the still consumer