]> git.sesse.net Git - mlt/blobdiff - src/modules/rtaudio/consumer_rtaudio.cpp
Move burningtv into plusgpl module.
[mlt] / src / modules / rtaudio / consumer_rtaudio.cpp
index 01f5955407bd4573fabedf26b8d797e1b4e02d1a..8b6e599e0cd60bf897666d243431480eaabbcd05 100644 (file)
@@ -50,18 +50,23 @@ public:
        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()
        {
@@ -205,6 +210,24 @@ public:
                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
@@ -222,7 +245,10 @@ public:
                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 )
@@ -270,8 +296,16 @@ public:
                                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
@@ -389,6 +423,7 @@ public:
                // 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;
@@ -420,6 +455,9 @@ public:
                                parameters.deviceName = mlt_properties_get( properties, "resource" );
 
                        try {
+                               if ( rt.isStreamOpen() ) {
+                                   rt.closeStream();
+                               }
                                rt.openStream( &parameters, NULL, RTAUDIO_SINT16,
                                        frequency, &bufferFrames, &rtaudio_callback, this, &options );
                                rt.startStream();
@@ -441,7 +479,7 @@ public:
                                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 );
@@ -612,6 +650,12 @@ static int is_stopped( mlt_consumer consumer )
        return !rtaudio->running;
 }
 
+static void purge( mlt_consumer consumer )
+{
+       RtAudioConsumer* rtaudio = (RtAudioConsumer*) consumer->child;
+       rtaudio->purge();
+}
+
 /** Close the consumer.
  */
 
@@ -648,6 +692,7 @@ mlt_consumer consumer_rtaudio_init( mlt_profile profile, mlt_service_type type,
                        consumer->start = start;
                        consumer->stop = stop;
                        consumer->is_stopped = is_stopped;
+                       consumer->purge = purge;
                }
                else
                {