[vlc-devel] [PATCH 1/4] es_out: fix flapping PREROLL flag on non dated packets
Thomas Guillem
thomas at gllm.fr
Fri Oct 2 11:03:46 CEST 2020
LGTM,
On Wed, Sep 30, 2020, at 17:44, Francois Cartegnie wrote:
> 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 0
Just replace 0 with TICK_INVALID like mentioned in the review.
> (...) multiple times, simplified to 1 occurence
> PCR 1
> SEND 719996
> SEND 0
> PCR 719996
> SEND 1439992
> SEND 0
> PCR 1439992
> SEND 2160008
> SEND 0
> 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
> (...)
> ---
> src/input/es_out.c | 28 +++++++++++++++++++++++++++-
> 1 file changed, 27 insertions(+), 1 deletion(-)
>
> diff --git a/src/input/es_out.c b/src/input/es_out.c
> index e4b840ed75..a95f804f70 100644
> --- a/src/input/es_out.c
> +++ b/src/input/es_out.c
> @@ -79,6 +79,8 @@ typedef struct
> vlc_clock_main_t *p_main_clock;
> vlc_clock_t *p_master_clock;
>
> + vlc_tick_t i_last_pcr;
> +
> vlc_meta_t *p_meta;
> struct vlc_list node;
> } es_out_pgrm_t;
> @@ -133,6 +135,7 @@ struct es_out_id_t
> /* Used by vlc_clock_cbs, need to be const during the lifetime of
> the clock */
> bool master;
>
> + vlc_tick_t i_roll_level;
> vlc_tick_t delay;
>
> /* Fields for Video with CC */
> @@ -896,6 +899,7 @@ static void EsOutChangePosition( es_out_t *out,
> bool b_flush )
> input_SendEventCache( p_sys->p_input, 0.0 );
>
> foreach_es_then_es_slaves(p_es)
> + {
> if( p_es->p_dec != NULL )
> {
> if( b_flush )
> @@ -907,12 +911,15 @@ static void EsOutChangePosition( es_out_t *out,
> bool b_flush )
> vlc_input_decoder_StartWait( p_es->p_dec_record );
> }
> }
> + p_es->i_roll_level = VLC_TICK_INVALID;
> + }
>
> es_out_pgrm_t *pgrm;
> vlc_list_foreach(pgrm, &p_sys->programs, node)
> {
> input_clock_Reset(pgrm->p_input_clock);
> vlc_clock_main_Reset(pgrm->p_main_clock);
> + pgrm->i_last_pcr = VLC_TICK_INVALID;
> }
>
> p_sys->b_buffering = true;
> @@ -1371,6 +1378,7 @@ static es_out_pgrm_t *EsOutProgramAdd( es_out_t
> *out, input_source_t *source, in
> p_pgrm->i_es = 0;
> p_pgrm->b_selected = false;
> p_pgrm->b_scrambled = false;
> + p_pgrm->i_last_pcr = VLC_TICK_INVALID;
> p_pgrm->p_meta = NULL;
>
> p_pgrm->p_master_clock = NULL;
> @@ -2083,6 +2091,7 @@ static es_out_id_t *EsOutAddLocked( es_out_t
> *out, input_source_t *source,
> es->p_master = p_master;
> es->mouse_event_cb = NULL;
> es->mouse_event_userdata = NULL;
> + es->i_roll_level = VLC_TICK_INVALID;
> es->delay = INT64_MAX;
>
> vlc_list_append(&es->node, es->p_master ? &p_sys->es_slaves :
> &p_sys->es);
> @@ -2764,8 +2773,23 @@ static int EsOutSend( es_out_t *out, es_out_id_t
> *es, block_t *p_block )
> if( p_block->i_pts == VLC_TICK_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_TICK_INVALID )
> + {
> + if( es->i_roll_level != VLC_TICK_INVALID )
> + i_date = es->i_roll_level;
> + else if( es->p_pgrm->i_last_pcr != VLC_TICK_INVALID )
> + i_date = es->p_pgrm->i_last_pcr;
> + }
> +
> + /* If i_date is still invalid (first/all non dated), expect to
> be in preroll */
> + if( i_date == VLC_TICK_INVALID ||
> + i_date + p_block->i_length < p_sys->i_preroll_end )
> p_block->i_flags |= BLOCK_FLAG_PREROLL;
> +
> + es->i_roll_level = i_date + p_block->i_length;
> }
>
> if( !es->p_dec )
> @@ -3169,6 +3193,8 @@ static int EsOutVaControlLocked( es_out_t *out,
> input_source_t *source,
> return VLC_EGENERIC;
> }
>
> + p_pgrm->i_last_pcr = i_pcr;
> +
> input_thread_private_t *priv = input_priv(p_sys->p_input);
>
> /* TODO do not use vlc_tick_now() but proper stream acquisition date */
> --
> 2.25.4
>
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
More information about the vlc-devel
mailing list