[vlc-devel] [PATCH 1/4] es_out: fix flapping PREROLL flag on non dated packets

Steve Lhomme robux4 at ycbcr.xyz
Thu Oct 1 08:01:35 CEST 2020


On 2020-09-30 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
> (...) multiple times, simplified to 1 occurence
> PCR 1
> SEND 719996
> SEND 0

It would be better named INVALID instead of 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;

I don't understand the "i_rool_level" name. Looking at the code it looks 
more like a "i_last_preroll_end".

>       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 i_date is interpolated, because the p_block has no PTS/DTS. It seems 
fair to assume the p_block will also not have an i_length. So I'm not 
sure what this value will lead to.

(I think we should use INT64_MAX for VLC_TICK_INVALID)

>       }
>   
>       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