[vlc-devel] [PATCH v2 1/7] video_output: rework the deadline parameter return

Steve Lhomme robux4 at ycbcr.xyz
Fri Aug 14 11:57:26 CEST 2020


It's not a deadline that we get, but a value we return.

We should always return a value, even if the picture wasn't rendered yet.
Setting a dummy value before calling the function seems more hackish.

Do not compare a next_deadline value if it's VLC_TICK_INVALID.
Set it to date_refresh even if it's VLC_TICK_INVALID.

Substract the render delay once we have the date we want the next render,
outside of ThreadDisplayPicture().

Reorder the code to avoid intermediate variables and so we can compare the
display refresh deadline and the render time of the next picture.

date_next was computed even when next_system_pts is INT64_MAX.
---
 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 6cf7a426673..c5115ce3009 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -1434,15 +1434,18 @@ static int ThreadDisplayRenderPicture(vout_thread_sys_t *vout, bool is_forced)
     return VLC_SUCCESS;
 }
 
-static int ThreadDisplayPicture(vout_thread_sys_t *vout, vlc_tick_t *deadline)
+static int ThreadDisplayPicture(vout_thread_sys_t *vout, vlc_tick_t *next_render)
 {
     vout_thread_sys_t *sys = vout;
-    bool frame_by_frame = !deadline;
+    bool frame_by_frame = !next_render;
     bool paused = sys->pause.is_on;
     bool first = !sys->displayed.current;
 
     assert(sys->clock);
 
+    if (next_render)
+        *next_render = VLC_TICK_INVALID;
+
     if (first)
         if (ThreadDisplayPreparePicture(vout, true, frame_by_frame, &paused)) /* FIXME not sure it is ok */
             return VLC_EGENERIC;
@@ -1453,27 +1456,8 @@ static int ThreadDisplayPicture(vout_thread_sys_t *vout, vlc_tick_t *deadline)
             ;
 
     const vlc_tick_t system_now = vlc_tick_now();
-    const vlc_tick_t render_delay = vout_chrono_GetHigh(&sys->render) + VOUT_MWAIT_TOLERANCE;
 
     bool drop_next_frame = frame_by_frame;
-    vlc_tick_t date_next = VLC_TICK_INVALID;
-
-    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);
-        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
      * of potential vout updated, or filters update or SPU update)
@@ -1486,20 +1470,37 @@ static int ThreadDisplayPicture(vout_thread_sys_t *vout, vlc_tick_t *deadline)
      */
     bool refresh = false;
 
-    vlc_tick_t date_refresh = VLC_TICK_INVALID;
     if (sys->displayed.date != VLC_TICK_INVALID) {
-        date_refresh = sys->displayed.date + VOUT_REDISPLAY_DELAY - render_delay;
+        vlc_tick_t date_refresh = sys->displayed.date + VOUT_REDISPLAY_DELAY;
         refresh = date_refresh <= system_now;
+        if (!frame_by_frame)
+            *next_render = date_refresh;
     }
-    bool force_refresh = !drop_next_frame && refresh;
 
-    if (!frame_by_frame) {
-        if (date_refresh != VLC_TICK_INVALID)
-            *deadline = date_refresh;
-        if (date_next != VLC_TICK_INVALID && date_next < *deadline)
-            *deadline = date_next;
+    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);
+        if (unlikely(next_system_pts == INT64_MAX))
+        {
+            /* The clock was just paused, don't display the next frame (keep
+             * the current one). */
+            paused = true;
+        }
+        else
+        {
+            if (!frame_by_frame) {
+                if (*next_render == VLC_TICK_INVALID || *next_render > next_system_pts)
+                    *next_render = next_system_pts;
+            }
+
+            if (next_system_pts <= system_now)
+                drop_next_frame = true;
+        }
     }
 
+    bool force_refresh = !drop_next_frame && refresh;
+
     if (!first && !refresh && !drop_next_frame) {
         return VLC_EGENERIC;
     }
@@ -1599,7 +1600,7 @@ void vout_NextPicture(vout_thread_t *vout, vlc_tick_t *duration)
     if (sys->step.last == VLC_TICK_INVALID)
         sys->step.last = sys->displayed.timestamp;
 
-    if (ThreadDisplayPicture(sys, NULL) == 0) {
+    if (ThreadDisplayPicture(sys, NULL) == VLC_SUCCESS) {
         sys->step.timestamp = sys->displayed.timestamp;
 
         if (sys->step.last != VLC_TICK_INVALID &&
@@ -1876,8 +1877,9 @@ static void *Thread(void *object)
             vout_control_cmd_Clean(&cmd);
         }
 
-        deadline = VLC_TICK_INVALID;
         wait = ThreadDisplayPicture(vout, &deadline) != VLC_SUCCESS;
+        if (deadline != VLC_TICK_INVALID)
+            deadline -= vout_chrono_GetHigh(&sys->render) + VOUT_MWAIT_TOLERANCE;
 
         const bool picture_interlaced = sys->displayed.is_interlaced;
 
-- 
2.26.2



More information about the vlc-devel mailing list