[vlc-devel] [RFC PATCH 1/2] vout: Allow vout plugins to provide vsync time

Julian Scheel julian at jusst.de
Thu Jun 19 11:34:21 CEST 2014


If the display refresh rate matches the video rate it is desired to show
exactly one picture per frame. Some video renderers take care of this
internally others don't. For those that don't do it we allow the vout to
provide a reference timestamp on which a vsync happened. Using the assumption
that frame and display duration are equal we compute a phase delay and derive
an offset to shift the phase to 25% of the frame duration.

Signed-off-by: Julian Scheel <julian at jusst.de>
---
 include/vlc_vout_display.h      |  1 +
 src/video_output/video_output.c | 29 +++++++++++++++++++++++++++--
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/include/vlc_vout_display.h b/include/vlc_vout_display.h
index 591adc0..9f138c2 100644
--- a/include/vlc_vout_display.h
+++ b/include/vlc_vout_display.h
@@ -127,6 +127,7 @@ typedef struct {
     bool has_event_thread;                  /* Will events (key at least) be emitted using an independent thread */
     const vlc_fourcc_t *subpicture_chromas; /* List of supported chromas for subpicture rendering. */
     int extra_video_filter_pictures;        /* Allocate additional pictures in the private_pool for video filters */
+    mtime_t vsync_date;                     /* Provide a timestamp on which vsync occured. This can be used to center display time into vsync phase */
 } vout_display_info_t;
 
 /**
diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
index 18f22ce..fa10697 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -1064,8 +1064,33 @@ static int ThreadDisplayRenderPicture(vout_thread_t *vout, bool is_forced)
     if (delay < 1000)
         msg_Warn(vout, "picture is late (%lld ms)", delay / 1000);
 #endif
-    if (!is_forced)
-        mwait(todisplay->date);
+    if (!is_forced) {
+        /* Try to target the display time at 25% vsync cycle, to ensure
+         * each frame is shown properly. This is only done if vsync provides
+         * a vsync reference time, which it should only do if video rate
+         * and vsync do match */
+        mtime_t offset = 0;
+        if (vd->info.vsync_date > 0) {
+            int32_t duration = 1000000 /
+                ((double)todisplay->format.i_frame_rate /
+                 todisplay->format.i_frame_rate_base);
+            mtime_t sync_phase = vd->info.vsync_date % duration;
+            mtime_t frame_phase = todisplay->date % duration;
+            mtime_t delta = sync_phase - frame_phase;
+
+            if (delta < 0)
+                delta += duration;
+
+            offset = delta - 0.75 * duration;
+
+#ifndef NDEBUG
+            msg_Dbg(vd, "Wait for display date %"PRId64" phase %"PRId64"/%"PRId64,
+                    todisplay->date, sync_phase, frame_phase);
+            msg_Dbg(vd, "Apply offset %"PRId64" duration: %"PRId64, offset, duration);
+#endif
+        }
+        mwait(todisplay->date + offset);
+    }
 
     /* Display the direct buffer returned by vout_RenderPicture */
     vout->p->displayed.date = mdate();
-- 
2.0.0




More information about the vlc-devel mailing list