[vlc-devel] [PATCH 4/5] video_output: only get the next decoded picture when the current one is late

Steve Lhomme robux4 at ycbcr.xyz
Thu Jan 21 12:13:14 UTC 2021


If displayed.current is bound to be displayed late, we look for the next
decoded (+statically filtered) picture that is not late.

We do not preemptively store the next picture in displayed.next anymore. If we
get a new picture we will overwrite displayed.current with it.

The date_refresh (new deadline) is computed once we know if we are using a new
picture or program a redisplay of the current one.
---
 src/video_output/video_output.c | 64 +++++++++++++++++----------------
 1 file changed, 33 insertions(+), 31 deletions(-)

diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
index c0bcb89ba8a..c861f8df6c3 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -1529,53 +1529,55 @@ static int ThreadDisplayPicture(vout_thread_sys_t *vout, vlc_tick_t *deadline)
 
         vlc_tick_t date_refresh = VLC_TICK_INVALID;
 
+        picture_t *next = NULL;
         if (!sys->displayed.current)
         {
-            assert(!sys->displayed.next);
-            sys->displayed.current =
+            next =
                 ThreadDisplayPreparePicture(vout, true, false, &paused);
-            if (!sys->displayed.current)
+            if (!next)
                 return VLC_EGENERIC; // wait with no known deadline
         }
-
-        if (!paused)
+        else if (!paused)
         {
-            if (!sys->displayed.next)
-            {
-                sys->displayed.next =
-                    ThreadDisplayPreparePicture(vout, false, false, &paused);
-            }
-        }
-
-        if (sys->displayed.date != VLC_TICK_INVALID) {
-            date_refresh = sys->displayed.date + VOUT_REDISPLAY_DELAY - render_delay;
-            refresh = date_refresh <= system_now;
-        }
-        render_now = refresh;
-
-        if (!paused && sys->displayed.next) {
             const vlc_tick_t next_system_pts =
                 vlc_clock_ConvertToSystem(sys->clock, system_now,
-                                        sys->displayed.next->date, sys->rate);
+                                          sys->displayed.current->date, sys->rate);
             if (likely(next_system_pts != INT64_MAX))
             {
                 vlc_tick_t date_next = next_system_pts - render_delay;
-                if (date_refresh == VLC_TICK_INVALID || date_next < date_refresh)
-                    date_refresh = date_next;
-
                 if (date_next <= system_now)
                 {
-                    // next frame will still need some waiting before display
-                    dropped_current_frame = true;
-                    render_now = false;
-
-                    if (likely(sys->displayed.current != NULL))
-                        picture_Release(sys->displayed.current);
-                    sys->displayed.current = sys->displayed.next;
-                    sys->displayed.next    = NULL;
+                    // the current frame will be late, look for the next not late one
+                    next =
+                        ThreadDisplayPreparePicture(vout, false, false, &paused);
                 }
             }
         }
+
+        if (next != NULL)
+        {
+            const vlc_tick_t swap_next_pts =
+                vlc_clock_ConvertToSystem(sys->clock, vlc_tick_now(),
+                                            next->date, sys->rate);
+            if (likely(swap_next_pts != INT64_MAX))
+                date_refresh = swap_next_pts - render_delay;
+
+            // next frame will still need some waiting before display
+            dropped_current_frame = true;
+            render_now = false;
+
+            if (likely(sys->displayed.current != NULL))
+                picture_Release(sys->displayed.current);
+            sys->displayed.current = next;
+        }
+        else if (likely(sys->displayed.date != VLC_TICK_INVALID))
+        {
+            // next date we need to display again the current picture
+            date_refresh = sys->displayed.date + VOUT_REDISPLAY_DELAY - render_delay;
+            refresh = date_refresh <= system_now;
+            render_now = refresh;
+        }
+
         if (date_refresh != VLC_TICK_INVALID)
             *deadline = date_refresh;
 
-- 
2.29.2



More information about the vlc-devel mailing list