]> git.sesse.net Git - mlt/commitdiff
Add prefill property to decklink producer.
authorDan Dennedy <dan@dennedy.org>
Sat, 11 Jun 2011 19:52:51 +0000 (12:52 -0700)
committerDan Dennedy <dan@dennedy.org>
Sat, 11 Jun 2011 19:52:51 +0000 (12:52 -0700)
src/modules/decklink/producer_decklink.cpp
src/modules/decklink/producer_decklink.yml

index 7c32ced3e339961d8a0754f2acbfb65bb017f428..8f0411276e5e32c3b4902315bc12a0284a13ec17 100644 (file)
@@ -38,6 +38,7 @@ private:
        pthread_cond_t   m_condition;
        bool             m_started;
        int              m_dropped;
+       bool             m_isBuffering;
 
        BMDDisplayMode getDisplayMode( mlt_profile profile )
        {
@@ -116,6 +117,7 @@ public:
                        m_queue = mlt_deque_init();
                        m_started = false;
                        m_dropped = 0;
+                       m_isBuffering = true;
                }
                catch ( const char *error )
                {
@@ -196,6 +198,30 @@ public:
                mlt_frame frame = NULL;
                struct timeval now;
                struct timespec tm;
+               double fps = mlt_producer_get_fps( getProducer() );
+
+               // Allow the buffer to fill to the requested initial buffer level.
+               if ( m_isBuffering )
+               {
+                       int prefill = mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( getProducer() ), "prefill" );
+                       int buffer = mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( getProducer() ), "buffer" );
+
+                       m_isBuffering = false;
+                       prefill = prefill > buffer ? buffer : prefill;
+                       pthread_mutex_lock( &m_mutex );
+                       while ( mlt_deque_count( m_queue ) < prefill )
+                       {
+                               // Wait up to buffer/fps seconds
+                               gettimeofday( &now, NULL );
+                               long usec = now.tv_sec * 1000000 + now.tv_usec;
+                               usec += 1000000 * buffer / fps;
+                               tm.tv_sec = usec / 1000000;
+                               tm.tv_nsec = (usec % 1000000) * 1000;
+                               if ( pthread_cond_timedwait( &m_condition, &m_mutex, &tm ) )
+                                       break;
+                       }
+                       pthread_mutex_unlock( &m_mutex );
+               }
 
                // Wait if queue is empty
                pthread_mutex_lock( &m_mutex );
@@ -204,7 +230,7 @@ public:
                        // Wait up to twice frame duration
                        gettimeofday( &now, NULL );
                        tm.tv_sec = now.tv_sec;
-                       now.tv_usec += 2000000 / mlt_producer_get_fps( getProducer() );
+                       now.tv_usec += 2000000 / fps;
                        tm.tv_nsec = now.tv_usec * 1000;
                        if ( pthread_cond_timedwait( &m_condition, &m_mutex, &tm ) )
                                // Stop waiting if error (timed out)
@@ -410,6 +436,9 @@ mlt_producer producer_decklink_init( mlt_profile profile, mlt_service_type type,
                        mlt_properties_set( properties, "resource", arg? arg : "0" );
                        mlt_properties_set_int( properties, "channels", 2 );
                        mlt_properties_set_int( properties, "buffer", 25 );
+                       mlt_properties_set_int( properties, "prefill", 25 );
+
+                       // These properties effectively make it infinite.
                        mlt_properties_set_int( properties, "length", INT_MAX );
                        mlt_properties_set_int( properties, "out", INT_MAX - 1 );
                        mlt_properties_set( properties, "eof", "loop" );
index 4cb74b64bd85c80c3d4e66341b86914bd9678b7e..d7215fce68b92c283e80277c1a8bd9089aea8498 100644 (file)
@@ -28,9 +28,6 @@ parameters:
   - identifier: argument
     title: Card
     type: integer
-    readonly: no
-    required: no
-    mutable: no
     default: 0
     minimum: 0
     widget: spinner
@@ -41,18 +38,15 @@ parameters:
     readonly: yes
 
   - identifier: channels
-    title: Audio Channels
+    title: Audio channels
     type: integer
-    readonly: no
-    required: no
-    mutable: no
     default: 2
     minimum: 2
     maximum: 16
     widget: spinner
 
   - identifier: buffer
-    title: Maximum Buffer
+    title: Maximum buffer
     description: >
       There is a queue of frames between this plugin and its consumer.
       If the consumer has a little, intermittent delay then it reduces the
@@ -60,9 +54,15 @@ parameters:
       frames that can be buffered to prevent consuming memory unbounded in
       the case of frequent or sustained delays.
     type: integer
-    readonly: no
-    required: no
-    mutable: no
+    default: 25
+    minimum: 0
+    unit: frames
+    widget: spinner
+
+  - identifier: prefill
+    title: Initial buffer
+    description: Initially fill the buffer with a number of frames.
+    type: integer
     default: 25
     minimum: 0
     unit: frames