[vlc-commits] [Git][videolan/vlc][master] 9 commits: autodel: use PCR to delete late/inactive tracks

Steve Lhomme (@robUx4) gitlab at videolan.org
Fri Feb 17 13:05:34 UTC 2023



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
edf84ec4 by Alaric Senat at 2023-02-17T12:47:49+00:00
autodel: use PCR to delete late/inactive tracks

- - - - -
134b5213 by Alaric Senat at 2023-02-17T12:47:49+00:00
autodel: add a drop-delay parameter

This allow the user to be more or less severe on when the track is
determined inactive or late relative to the PCR.

- - - - -
00765d0a by Alaric Senat at 2023-02-17T12:47:49+00:00
autodel: clarify the intent of the module

- - - - -
2576f118 by Alaric Senat at 2023-02-17T12:47:49+00:00
delay: split delaying code in a function

- - - - -
fb82c485 by Alaric Senat at 2023-02-17T12:47:49+00:00
delay: fix negative delay handling

Apply the delay to all the ES except the selected one in negative delay
scenarios. This has the same effect than substracting the selected ES
timestamps but avoid PCR changes and potential below-zero timestamps.

- - - - -
70e3e2cb by Alaric Senat at 2023-02-17T12:47:49+00:00
delay: forward SetPCR

- - - - -
310dfc78 by Alaric Senat at 2023-02-17T12:47:49+00:00
duplicate: forward SetPCR

The PCR is sent as-is to the duplicated streams.

- - - - -
3520c389 by Alaric Senat at 2023-02-17T12:47:49+00:00
setid: forward SetPCR

- - - - -
96a097c4 by Alaric Senat at 2023-02-17T12:47:49+00:00
stats: forward SetPCR

Simply forward the PCR value for now. It would be best to also trace and
include the PCR to the stat output but the current GNUPlot format is
specifically made for frame timestamps and PCR won't satisfy a lot of
the output columns.

- - - - -


5 changed files:

- modules/stream_out/autodel.c
- modules/stream_out/delay.c
- modules/stream_out/duplicate.c
- modules/stream_out/setid.c
- modules/stream_out/stats.c


Changes:

=====================================
modules/stream_out/autodel.c
=====================================
@@ -20,6 +20,13 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
+/**
+ * The autodel module remove inactive or late tracks relative to the PCR and
+ * only adds ESs that contains at least one frame. It is mainly here to cope the
+ * fact that PCR isn't forwarded to Muxers right now, which make them unable to
+ * close inactive ES.
+ */
+
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
@@ -46,6 +53,8 @@ struct sout_stream_id_sys_t
 
 typedef struct
 {
+    vlc_tick_t last_pcr;
+    vlc_tick_t drop_delay;
     struct vlc_list ids;
 } sout_stream_sys_t;
 
@@ -81,9 +90,9 @@ static int Send( sout_stream_t *p_stream, void *_p_es, block_t *p_buffer )
 {
     sout_stream_sys_t *p_sys = (sout_stream_sys_t *)p_stream->p_sys;
     sout_stream_id_sys_t *p_es = (sout_stream_id_sys_t *)_p_es;
-    vlc_tick_t i_current = vlc_tick_now();
 
-    p_es->i_last = p_buffer->i_dts;
+    p_es->i_last = ( p_buffer->i_dts != VLC_TICK_INVALID ) ? p_buffer->i_dts
+                                                           : p_sys->last_pcr;
     if ( !p_es->id && !p_es->b_error )
     {
         p_es->id = sout_StreamIdAdd( p_stream->p_next, &p_es->fmt );
@@ -103,7 +112,7 @@ static int Send( sout_stream_t *p_stream, void *_p_es, block_t *p_buffer )
     vlc_list_foreach (p_es, &p_sys->ids, node)
         if (p_es->id != NULL
          && (p_es->fmt.i_cat == VIDEO_ES || p_es->fmt.i_cat == AUDIO_ES)
-         && p_es->i_last < i_current)
+         && p_es->i_last + p_sys->drop_delay < p_sys->last_pcr )
         {
             sout_StreamIdDel(p_stream->p_next, p_es->id);
             p_es->id = NULL;
@@ -112,8 +121,18 @@ static int Send( sout_stream_t *p_stream, void *_p_es, block_t *p_buffer )
     return VLC_SUCCESS;
 }
 
+static void SetPCR( sout_stream_t *stream, vlc_tick_t pcr )
+{
+    sout_stream_sys_t *sys = stream->p_sys;
+    sys->last_pcr = pcr;
+
+    sout_StreamSetPCR( stream->p_next, pcr );
+}
+
+#define SOUT_CFG_PREFIX "sout-autodel-"
+
 static const struct sout_stream_operations ops = {
-    Add, Del, Send, NULL, NULL, NULL,
+    Add, Del, Send, NULL, NULL, SetPCR,
 };
 
 static int Open( vlc_object_t *p_this )
@@ -121,9 +140,15 @@ static int Open( vlc_object_t *p_this )
     sout_stream_t     *p_stream = (sout_stream_t*)p_this;
     sout_stream_sys_t *p_sys = vlc_obj_malloc(p_this, sizeof (*p_sys));
 
+    static const char *sout_options[] = {"drop-delay", NULL};
+    config_ChainParse(p_stream, SOUT_CFG_PREFIX, sout_options, p_stream->p_cfg);
+
     if (unlikely(p_sys == NULL))
         return VLC_ENOMEM;
 
+    p_sys->last_pcr = VLC_TICK_INVALID;
+    p_sys->drop_delay = VLC_TICK_FROM_MS(
+        var_GetInteger(p_stream, SOUT_CFG_PREFIX "drop-delay"));
     vlc_list_init(&p_sys->ids);
     p_stream->ops = &ops;
     p_stream->p_sys = p_sys;
@@ -131,7 +156,12 @@ static int Open( vlc_object_t *p_this )
     return VLC_SUCCESS;
 }
 
-#define SOUT_CFG_PREFIX "sout-autodel-"
+#define DROP_DELAY_TEXT N_("Delay (ms) before track deletion")
+#define DROP_DELAY_LONGTEXT                                                    \
+    N_("Specify a delay (ms) applied to incoming frame timestamps when we "    \
+       "choose whether they should be dropped or not. Tweak this parameter "   \
+       "if you believe your tracks are deleted too early.")
+
 
 vlc_module_begin()
     set_shortname(N_("Autodel"))
@@ -139,4 +169,6 @@ vlc_module_begin()
     set_capability("sout filter", 50)
     add_shortcut("autodel")
     set_callback(Open)
+
+    add_integer(SOUT_CFG_PREFIX "drop-delay", 0, DROP_DELAY_TEXT, DROP_DELAY_LONGTEXT)
 vlc_module_end()


=====================================
modules/stream_out/delay.c
=====================================
@@ -66,28 +66,41 @@ static void Del( sout_stream_t *p_stream, void *id )
     sout_StreamIdDel( p_stream->p_next, id );
 }
 
+static void block_ChainApplyDelay( block_t *chain, vlc_tick_t delay )
+{
+    for ( block_t *frame = chain; frame != NULL; frame = frame->p_next )
+    {
+        if ( frame->i_dts != VLC_TICK_INVALID )
+            frame->i_dts += delay;
+        if ( frame->i_pts != VLC_TICK_INVALID )
+            frame->i_pts += delay;
+    }
+}
+
 static int Send( sout_stream_t *p_stream, void *id, block_t *p_buffer )
 {
     sout_stream_sys_t *p_sys = (sout_stream_sys_t *)p_stream->p_sys;
 
-    if ( id == p_sys->id )
-    {
-        block_t *p_block = p_buffer;
-        while ( p_block != NULL )
-        {
-            if ( p_block->i_pts != VLC_TICK_INVALID )
-                p_block->i_pts += p_sys->i_delay;
-            if ( p_block->i_dts != VLC_TICK_INVALID )
-                p_block->i_dts += p_sys->i_delay;
-            p_block = p_block->p_next;
-        }
-    }
+    /**
+     * Positive delay is added to the selected ES timestamps while negative
+     * delay is added to every other ES except the selected one. This avoids
+     * any negative timestamps.
+     */
+    if ( p_sys->i_delay < 0 && id != p_sys->id )
+        block_ChainApplyDelay( p_buffer, -p_sys->i_delay );
+    else if ( p_sys->i_delay > 0 && id == p_sys->id )
+        block_ChainApplyDelay( p_buffer, p_sys->i_delay );
 
     return sout_StreamIdSend( p_stream->p_next, id, p_buffer );
 }
 
+static void SetPCR( sout_stream_t *stream, vlc_tick_t pcr )
+{
+    sout_StreamSetPCR( stream->p_next, pcr );
+}
+
 static const struct sout_stream_operations ops = {
-    Add, Del, Send, NULL, NULL, NULL,
+    Add, Del, Send, NULL, NULL, SetPCR,
 };
 
 static const char *ppsz_sout_options[] = {


=====================================
modules/stream_out/duplicate.c
=====================================
@@ -58,6 +58,7 @@ vlc_module_end ()
 static void *Add( sout_stream_t *, const es_format_t * );
 static void  Del( sout_stream_t *, void * );
 static int   Send( sout_stream_t *, void *, block_t * );
+static void  SetPCR( sout_stream_t *, vlc_tick_t );
 
 typedef struct
 {
@@ -105,7 +106,7 @@ static int Control( sout_stream_t *p_stream, int i_query, va_list args )
 }
 
 static const struct sout_stream_operations ops = {
-    Add, Del, Send, Control, NULL, NULL,
+    Add, Del, Send, Control, NULL, SetPCR,
 };
 
 /*****************************************************************************
@@ -326,6 +327,16 @@ static int Send( sout_stream_t *p_stream, void *_id, block_t *p_buffer )
     return VLC_SUCCESS;
 }
 
+static void SetPCR( sout_stream_t *stream, vlc_tick_t pcr )
+{
+    sout_stream_sys_t *sys = stream->p_sys;
+
+    for ( int i = 0; i < sys->i_nb_streams; ++i )
+    {
+        sout_StreamSetPCR( sys->pp_streams[i], pcr );
+    }
+}
+
 /*****************************************************************************
  * Divers
  *****************************************************************************/


=====================================
modules/stream_out/setid.c
=====================================
@@ -96,6 +96,7 @@ static void *AddId  ( sout_stream_t *, const es_format_t * );
 static void *AddLang( sout_stream_t *, const es_format_t * );
 static void  Del    ( sout_stream_t *, void * );
 static int   Send   ( sout_stream_t *, void *, block_t * );
+static void  SetPCR ( sout_stream_t *, vlc_tick_t );
 
 typedef struct
 {
@@ -122,7 +123,7 @@ static int OpenCommon( vlc_object_t *p_this )
 }
 
 static const struct sout_stream_operations id_ops = {
-    AddId, Del, Send, NULL, NULL, NULL,
+    AddId, Del, Send, NULL, NULL, SetPCR,
 };
 
 static int OpenId( vlc_object_t *p_this )
@@ -147,7 +148,7 @@ static int OpenId( vlc_object_t *p_this )
 }
 
 static const struct sout_stream_operations lang_ops = {
-    AddLang, Del, Send, NULL, NULL, NULL,
+    AddLang, Del, Send, NULL, NULL, SetPCR,
 };
 
 static int OpenLang( vlc_object_t *p_this )
@@ -229,3 +230,8 @@ static int Send( sout_stream_t *p_stream, void *id, block_t *p_buffer )
 {
     return sout_StreamIdSend( p_stream->p_next, id, p_buffer );
 }
+
+static void SetPCR( sout_stream_t *stream, vlc_tick_t pcr )
+{
+    sout_StreamSetPCR( stream->p_next, pcr );
+}


=====================================
modules/stream_out/stats.c
=====================================
@@ -152,6 +152,15 @@ static int Send( sout_stream_t *p_stream, void *_id, block_t *p_buffer )
     return VLC_SUCCESS;
 }
 
+static void SetPCR( sout_stream_t *stream, vlc_tick_t pcr )
+{
+    /*
+     * XXX: Don't trace the PCR for now as it wouldn't match the tracing scheme
+     * already decided in `Send()`.
+     */
+    sout_StreamSetPCR( stream->p_next, pcr );
+}
+
 /*****************************************************************************
  * Open:
  *****************************************************************************/
@@ -251,7 +260,7 @@ static int FilterSend(sout_stream_t *stream, void *opaque, block_t *block)
 }
 
 static const struct sout_stream_operations filter_ops = {
-    FilterAdd, FilterDel, FilterSend, NULL, NULL, NULL,
+    FilterAdd, FilterDel, FilterSend, NULL, NULL, SetPCR,
 };
 
 static int FilterOpen(vlc_object_t *obj)



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/2ce189cc177f1b7ae923c9a40ea0c4c1660c9d9c...96a097c46a11625a65a2baadc1903441e0850604

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/2ce189cc177f1b7ae923c9a40ea0c4c1660c9d9c...96a097c46a11625a65a2baadc1903441e0850604
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list