[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