pthread_cond_t refresh_cond;
pthread_mutex_t refresh_mutex;
int refresh_count;
+ bool is_purge;
mlt_consumer getConsumer()
{ return &consumer; }
RtAudioConsumer()
: device_id(-1)
+ , queue(NULL)
, joined(0)
, running(0)
, audio_avail(0)
, playing(0)
, refresh_count(0)
- {}
+ , is_purge(false)
+ {
+ memset( &consumer, 0, sizeof( consumer ) );
+ }
~RtAudioConsumer()
{
return 0;
}
+ void purge()
+ {
+ if ( running )
+ {
+ pthread_mutex_lock( &video_mutex );
+ mlt_frame frame = MLT_FRAME( mlt_deque_peek_back( queue ) );
+ // When playing rewind or fast forward then we need to keep one
+ // frame in the queue to prevent playback stalling.
+ double speed = frame? mlt_properties_get_double( MLT_FRAME_PROPERTIES(frame), "_speed" ) : 0;
+ int n = ( speed == 0.0 || speed == 1.0 ) ? 0 : 1;
+ while ( mlt_deque_count( queue ) > n )
+ mlt_frame_close( MLT_FRAME( mlt_deque_pop_back( queue ) ) );
+ is_purge = true;
+ pthread_cond_broadcast( &video_cond );
+ pthread_mutex_unlock( &video_mutex );
+ }
+ }
+
void consumer_thread()
{
// Get the properties
int64_t playtime = 0;
struct timespec tm = { 0, 100000 };
// int last_position = -1;
+
+ pthread_mutex_lock( &refresh_mutex );
refresh_count = 0;
+ pthread_mutex_unlock( &refresh_mutex );
// Loop until told not to
while ( running )
if ( running && speed )
{
pthread_mutex_lock( &video_mutex );
- mlt_deque_push_back( queue, frame );
- pthread_cond_broadcast( &video_cond );
+ if ( is_purge && speed == 1.0 )
+ {
+ mlt_frame_close( frame );
+ is_purge = false;
+ }
+ else
+ {
+ mlt_deque_push_back( queue, frame );
+ pthread_cond_broadcast( &video_cond );
+ }
pthread_mutex_unlock( &video_mutex );
// Calculate the next playtime
// Set the preferred params of the test card signal
int channels = mlt_properties_get_int( properties, "channels" );
int frequency = mlt_properties_get_int( properties, "frequency" );
+ int scrub = mlt_properties_get_int( properties, "scrub_audio" );
static int counter = 0;
int samples = mlt_sample_calculator( mlt_properties_get_double( properties, "fps" ), frequency, counter++ );
int16_t *pcm;
parameters.deviceName = mlt_properties_get( properties, "resource" );
try {
+ if ( rt.isStreamOpen() ) {
+ rt.closeStream();
+ }
rt.openStream( ¶meters, NULL, RTAUDIO_SINT16,
frequency, &bufferFrames, &rtaudio_callback, this, &options );
rt.startStream();
pthread_cond_wait( &audio_cond, &audio_mutex );
if ( running )
{
- if ( mlt_properties_get_double( properties, "_speed" ) == 1 )
+ if ( scrub || mlt_properties_get_double( properties, "_speed" ) == 1 )
memcpy( &audio_buffer[ audio_avail ], pcm, bytes );
else
memset( &audio_buffer[ audio_avail ], 0, bytes );
return !rtaudio->running;
}
+static void purge( mlt_consumer consumer )
+{
+ RtAudioConsumer* rtaudio = (RtAudioConsumer*) consumer->child;
+ rtaudio->purge();
+}
+
/** Close the consumer.
*/
consumer->start = start;
consumer->stop = stop;
consumer->is_stopped = is_stopped;
+ consumer->purge = purge;
}
else
{