[vlc-commits] demux: provide fallback for pause, PTS delay and pace control

Rémi Denis-Courmont git at videolan.org
Tue Oct 20 22:33:13 CEST 2015


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Tue Oct 20 21:08:47 2015 +0300| [a2beb67ed706e299010c28d8733e2c0123b57168] | committer: Rémi Denis-Courmont

demux: provide fallback for pause, PTS delay and pace control

Many existing demuxers do not use the generic control helper providing
those control queries. But as we now need to support those queries for
manifest-based or asynchronous demuxers, this fallback becomes
necessary.

We could also just do ahead and implement the controls in all demuxers.
Help yourself.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=a2beb67ed706e299010c28d8733e2c0123b57168
---

 src/input/demux.c |   57 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/src/input/demux.c b/src/input/demux.c
index 22c3f91..41cd4d9 100644
--- a/src/input/demux.c
+++ b/src/input/demux.c
@@ -262,8 +262,65 @@ void demux_Delete( demux_t *p_demux )
 #define static_control_match(foo) \
     static_assert((unsigned) DEMUX_##foo == STREAM_##foo, "Mismatch")
 
+static int demux_ControlInternal( demux_t *demux, int query, ... )
+{
+    int ret;
+    va_list ap;
+
+    va_start( ap, query );
+    ret = demux->pf_control( demux, query, ap );
+    va_end( ap );
+    return ret;
+}
+
 int demux_vaControl( demux_t *demux, int query, va_list args )
 {
+    if( demux->s != NULL )
+        switch( query )
+        {
+            /* Legacy fallback for missing getters in synchronous demuxers */
+            case DEMUX_CAN_PAUSE:
+            case DEMUX_CAN_CONTROL_PACE:
+            case DEMUX_GET_PTS_DELAY:
+            {
+                int ret;
+                va_list ap;
+
+                va_copy( ap, args );
+                ret = demux->pf_control( demux, query, args );
+                if( ret != VLC_SUCCESS )
+                    ret = stream_vaControl( demux->s, query, ap );
+                va_end( ap );
+                return ret;
+            }
+
+            /* Some demuxers need to control pause directly (e.g. adaptive),
+             * but many legacy demuxers do not understand pause at all.
+             * If DEMUX_CAN_PAUSE is not implemented, bypass the demuxer and
+             * byte stream. If DEMUX_CAN_PAUSE is implemented and pause is
+             * supported, pause the demuxer normally. Else, something went very
+             * wrong.
+             *
+             * Note that this requires asynchronous/threaded demuxers to
+             * always return VLC_SUCCESS for DEMUX_CAN_PAUSE, so that they are
+             * never bypassed. Otherwise, we would reenter demux->s callbacks
+             * and break thread safety. At the time of writing, asynchronous or
+             * threaded *non-access* demuxers do not exist and are not fully
+             * supported by the input thread, so this is theoretical. */
+            case DEMUX_SET_PAUSE_STATE:
+            {
+                bool can_pause;
+
+                if( demux_ControlInternal( demux, DEMUX_CAN_PAUSE,
+                                           &can_pause ) )
+                    return stream_vaControl( demux->s, query, args );
+
+                /* The caller shall not pause if pause is unsupported. */
+                assert( can_pause );
+                break;
+            }
+        }
+
     return demux->pf_control( demux, query, args );
 }
 



More information about the vlc-commits mailing list