[vlc-devel] [PATCH 5/6] vout: handle the case where the clock is paused

Thomas Guillem thomas at gllm.fr
Thu Sep 5 16:40:31 CEST 2019


On Thu, Sep 5, 2019, at 16:36, Rémi Denis-Courmont wrote:
> Hi,
> 
> I don't follow the comments. We need to support rendering when paused, to update OSD (and potentially to handle seeking while paused).

Yes, this behavior is not changed. What changes with this commit, when the clock is paused before the vout:
 - The next picture is not updated, so we keep displaying the current picture.
 - Fix the system date that we pass to plugins: it won't be INT64_MAX but tick_now()

> 
> Le 5 septembre 2019 14:40:02 GMT+03:00, Thomas Guillem <thomas at gllm.fr> a écrit :
>> This case can happen during a very short timespan, when the clock is paused
>> before the vout thread processed the pause event.
>> 
>> There are two way to handle it:
>> 
>>  - In the prepare step: continue processing the picture but don't display it,
>>    (keep displaying the old one, that is sys->displayed.current).
>> 
>>  - In the render step: make the picture as forced and display it now. It's too
>>    late to fallback to the previous picture. src/video_output/video_output.c | 56 ++++++++++++++++++++++++++++-----
>>  1 file changed, 48 insertions(+), 8 deletions(-)
>> 
>> diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
>> index 2c63624808..5badb35321 100644
>> --- a/src/video_output/video_output.c
>> +++ b/src/video_output/video_output.c
>> @@ -865,7 +865,8 @@ static void ThreadChangeFilters(vout_thread_t *vout,
>>  
>>  
>>  /* */
>> -static int ThreadDisplayPreparePicture(vout_thread_t *vout, bool reuse, bool frame_by_frame)
>> +static int ThreadDisplayPreparePicture(vout_thread_t *vout, bool reuse,
>> +                                       bool frame_by_frame, bool *paused)
>>  {
>>      bool is_late_dropped = vout->p->is_late_dropped && !vout->p->pause.is_on && !frame_by_frame;
>>      vout_thread_sys_t *sys = vout->p;
>> @@ -888,7 +889,19 @@ static int ThreadDisplayPreparePicture(vout_thread_t *vout, bool reuse, bool fra
>>                      const vlc_tick_t system_pts =
>>                          vlc_clock_ConvertToSystem(vout->p->clock, date,
>>                                                    decoded->date, sys->rate);
>> -                    const vlc_tick_t late = date - system_pts;
>> +
>> +                    vlc_tick_t late;
>> +                    if (system_pts == INT64_MAX)
>> +                    {
>> +                        /* The clock is paused, notify it (so that the current
>> +                         * picture is displayed but not the next one), this
>> +                         * current picture can't be be late. */
>> +                        *paused = true;
>> +                        late = 0;
>> +                    }
>> +                    else
>> +                        late = date - system_pts;
>> +
>>                      vlc_tick_t late_threshold;
>>                      if (decoded->format.i_frame_rate && decoded->format.i_frame_rate_base)
>>                          late_threshold = VLC_TICK_FROM_MS(500) * decoded->format.i_frame_rate_base / decoded->format.i_frame_rate;
>> @@ -1021,10 +1034,21 @@ static int ThreadDisplayRenderPicture(vout_thread_t *vout, bool is_forced)
>>      if (sys->pause.is_on)
>>          render_subtitle_date = sys->pause.date;
>>      else
>> +    {
>>          render_subtitle_date = filtered->date <= 1 ? system_now :
>>              vlc_clock_ConvertToSystem(sys->clock, system_now, filtered->date,
>>                                        sys->rate);
>>  
>> +        /* The clock is paused, it's too late to fallback to the previous
>> +         * picture, display the current picture anyway and force the rendering
>> +         * to now. */
>> +        if (unlikely(render_subtitle_date == INT64_MAX))
>> +        {
>> +            render_subtitle_date = system_now;
>> +            is_forced = true;
>> +        }
>> +    }
>> +
>>      /*
>>       * Get the subpicture to be displayed
>>       */
>> @@ -1154,6 +1178,14 @@ static int ThreadDisplayRenderPicture(vout_thread_t *vout, bool is_forced)
>>      const vlc_tick_t pts = todisplay->date;
>>      vlc_tick_t system_pts = is_forced ? system_now :
>>          vlc_clock_ConvertToSystem(sys->clock, system_now, pts, sys->rate);
>> +    if (unlikely(system_pts == INT64_MAX))
>> +    {
>> +        /* The clock is paused, it's too late to fallback to the previous
>> +         * picture, display the current picture anyway and force the rendering
>> +         * to now. */
>> +        system_pts = system_now;
>> +        is_forced = true;
>> +    }
>>  
>>      if (vd->prepare != NULL)
>>          vd->prepare(vd, todisplay, do_dr_spu ? subpic : NULL, system_pts);
>> @@ -1207,11 +1239,12 @@ static int ThreadDisplayPicture(vout_thread_t *vout, vlc_tick_t *deadline)
>>      assert(sys->clock);
>>  
>>      if (first)
>> -        if (ThreadDisplayPreparePicture(vout, true, frame_by_frame)) /* FIXME not sure it is ok */
>> +        if (ThreadDisplayPreparePicture(vout, true, frame_by_frame, &paused)) /* FIXME not sure it is ok */
>>              return VLC_EGENERIC;
>>  
>>      if (!paused || frame_by_frame)
>> -        while (!sys->displayed.next && !ThreadDisplayPreparePicture(vout, false, frame_by_frame))
>> +        while (!sys->displayed.next
>> +            && !ThreadDisplayPreparePicture(vout, false, frame_by_frame, &paused))
>>              ;
>>  
>>      const vlc_tick_t system_now = vlc_tick_now();
>> @@ -1224,10 +1257,17 @@ static int ThreadDisplayPicture(vout_thread_t *vout, vlc_tick_t *deadline)
>>          const vlc_tick_t next_system_pts =
>>              vlc_clock_ConvertToSystem(sys->clock, system_now,
>>                                        sys->displayed.next->date, sys->rate);
>> -
>> -        date_next = next_system_pts - render_delay;
>> -        if (date_next <= system_now)
>> -            drop_next_frame = true;
>> +        if (unlikely(next_system_pts == INT64_MAX))
>> +        {
>> +            /* The clock was just paused, don't display the next frame (keep
>> +             * the current one). */
>> +            paused = true;
>> +        }
>> +        {
>> +            date_next = next_system_pts - render_delay;
>> +            if (date_next <= system_now)
>> +                drop_next_frame = true;
>> +        }
>>      }
>>  
>>      /* FIXME/XXX we must redisplay the last decoded picture (because
> 
> -- 
> Envoyé de mon appareil Android avec Courriel K-9 Mail. Veuillez excuser ma brièveté. 
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20190905/315d0e33/attachment-0001.html>


More information about the vlc-devel mailing list