[vlc-commits] [Git][videolan/vlc][3.0.x] es_out: fix flapping PREROLL flag on non dated packets

Hugo Beauzée-Luyssen (@chouquette) gitlab at videolan.org
Tue Nov 9 09:19:20 UTC 2021



Hugo Beauzée-Luyssen pushed to branch 3.0.x at VideoLAN / VLC


Commits:
dfb2c624 by Francois Cartegnie at 2021-11-08T02:03:48+01:00
es_out: fix flapping PREROLL flag on non dated packets

Saves pts to perform preroll target comparison against.
refs #25129

In some cases, the packets are sent interleaved with non dated packets
SEND 1
SEND TS_INVALID
(...) multiple times, simplified to 1 occurence
PCR 1
SEND 719996
SEND TS_INVALID
PCR 719996
SEND 1439992
SEND TS_INVALID
PCR 1439992
SEND 2160008
SEND TS_INVALID
PCR 2160008

Until preroll_end (file caching) is reached, all packets
are flagged as PREROLL.

Entering preroll has effect on audio output by flushing
previous content, and silencing dropped buffers.

Due to non dated interleaving, the stateless es_out keeps
flipping PREROLL packets and triggering the in-stream PREROLL
behaviour (like SET_NEXT_DISPLAY_TIME).
The effect being (here with alsa) to re-enter preroll each
time, extending decoder preroll until pts >= preroll_end
and flushing decoders.

Stream buffering done (1439 ms in 0 ms)
ModuleThread_PlayAudio pts 1 preroll end -9223372036854775808
inserting 3840 zeroes / 80 ms
cannot write samples: Relais brisé (pipe)
ModuleThread_PlayAudio pts 120001 preroll end 9223372036854775807
(...)
ModuleThread_PlayAudio pts 719996 preroll end 719996
end of audio preroll
inserting 34804 zeroes / 725 ms 719996
ModuleThread_PlayAudio pts 839996 preroll end 9223372036854775807
(...)
ModuleThread_PlayAudio pts 1439992 preroll end 1439992
end of audio preroll
inserting 69172 zeroes / 1441 ms 1439992
ModuleThread_PlayAudio pts 1559992 preroll end 9223372036854775807
(...)
ModuleThread_PlayAudio pts 2160008 preroll end 2160008
end of audio preroll
inserting 103601 zeroes / 2158 ms 2160008
ModuleThread_PlayAudio pts 2280008 preroll end -9223372036854775808
(...)

(manual backport from commit b752ffe13b605de5dfc40ff48ad4659dd4df0d15)
Signed-off-by: Marvin Scholz <epirat07 at gmail.com>

- - - - -


1 changed file:

- src/input/es_out.c


Changes:

=====================================
src/input/es_out.c
=====================================
@@ -71,6 +71,8 @@ typedef struct
     /* Clock for this program */
     input_clock_t *p_clock;
 
+    mtime_t i_last_pcr;
+
     vlc_meta_t *p_meta;
 } es_out_pgrm_t;
 
@@ -92,6 +94,8 @@ struct es_out_id_t
     decoder_t   *p_dec;
     decoder_t   *p_dec_record;
 
+    mtime_t     i_pts_level;
+
     /* Fields for Video with CC */
     struct
     {
@@ -617,10 +621,13 @@ static void EsOutChangePosition( es_out_t *out )
                     input_DecoderStartWait( p_es->p_dec_record );
             }
         }
+        p_es->i_pts_level = VLC_TS_INVALID;
     }
 
-    for( int i = 0; i < p_sys->i_pgrm; i++ )
+    for( int i = 0; i < p_sys->i_pgrm; i++ ) {
         input_clock_Reset( p_sys->pgrm[i]->p_clock );
+        p_sys->pgrm[i]->i_last_pcr = VLC_TS_INVALID;
+    }
 
     p_sys->b_buffering = true;
     p_sys->i_buffering_extra_initial = 0;
@@ -1095,6 +1102,7 @@ static es_out_pgrm_t *EsOutProgramAdd( es_out_t *out, int i_group )
     p_pgrm->i_es = 0;
     p_pgrm->b_selected = false;
     p_pgrm->b_scrambled = false;
+    p_pgrm->i_last_pcr = VLC_TS_INVALID;
     p_pgrm->p_meta = NULL;
     p_pgrm->p_clock = input_clock_New( p_sys->i_rate );
     if( !p_pgrm->p_clock )
@@ -1639,6 +1647,7 @@ static es_out_id_t *EsOutAddSlave( es_out_t *out, const es_format_t *fmt, es_out
     es->cc.type = 0;
     es->cc.i_bitmap = 0;
     es->p_master = p_master;
+    es->i_pts_level = VLC_TS_INVALID;
 
     TAB_APPEND( p_sys->i_es, p_sys->es, es );
 
@@ -2081,7 +2090,24 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
         if( p_block->i_pts <= VLC_TS_INVALID )
             i_date = p_block->i_dts;
 
-        if( i_date + p_block->i_length < p_sys->i_preroll_end )
+        /* In some cases, the demuxer sends non dated packets.
+           We use interpolation, previous, or pcr value to compare with
+           preroll target timestamp */
+        if( i_date == VLC_TS_INVALID )
+        {
+            if( es->i_pts_level != VLC_TS_INVALID )
+                i_date = es->i_pts_level;
+            else if( es->p_pgrm->i_last_pcr != VLC_TS_INVALID )
+                i_date = es->p_pgrm->i_last_pcr;
+        }
+
+        if( i_date != VLC_TS_INVALID )
+            es->i_pts_level = i_date + p_block->i_length;
+
+        /* If i_date is still invalid (first/all non dated), expect to be in preroll */
+
+        if( i_date == VLC_TS_INVALID ||
+            es->i_pts_level < p_sys->i_preroll_end )
             p_block->i_flags |= BLOCK_FLAG_PREROLL;
     }
 
@@ -2492,6 +2518,8 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
             return VLC_EGENERIC;
         }
 
+        p_pgrm->i_last_pcr = i_pcr;
+
         /* TODO do not use mdate() but proper stream acquisition date */
         bool b_late;
         input_clock_Update( p_pgrm->p_clock, VLC_OBJECT(p_sys->p_input),



View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/dfb2c62402b4441b411724e35298093f8546b474

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/dfb2c62402b4441b411724e35298093f8546b474
You're receiving this email because of your account on code.videolan.org.




More information about the vlc-commits mailing list