[vlc-devel] [RFC PATCH 2/2] video_output/mmal: Provide vsync time to core

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


As the latency target alone is not ensuring that we start with a sane phase
shift between vsync and draw we add a vsync detection to provide an initial
vsync timestamp to the vout core. This is used in the core to compute an
initial phase shift, so that the frames are initially drawn at a proper time
within the vsync cycle. From there on the latency target takes care of keeping
it there.
This is only enabled if mmal-adjust-refreshrate is enabled, because the whole
vsync synchronisation makes only sense if display and videorate match.

Signed-off-by: Julian Scheel <julian at jusst.de>
---
 modules/video_output/mmal.c | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/modules/video_output/mmal.c b/modules/video_output/mmal.c
index 7cf8447..f1f4434 100644
--- a/modules/video_output/mmal.c
+++ b/modules/video_output/mmal.c
@@ -158,6 +158,7 @@ static void dmx_region_update(struct dmx_region_t *dmx_region,
 static void dmx_region_delete(struct dmx_region_t *dmx_region,
                 DISPMANX_UPDATE_HANDLE_T update);
 static void show_background(vout_display_t *vd, bool enable);
+static void detect_vsync(vout_display_t *vd);
 
 static int Open(vlc_object_t *object)
 {
@@ -655,6 +656,8 @@ static void vd_manage(vout_display_t *vd)
             vout_display_SendEventDisplaySize(vd, width, height, vd->cfg->is_fullscreen);
         }
 
+        if (sys->opaque)
+            detect_vsync(vd);
         sys->need_configure_display = false;
     }
 
@@ -809,6 +812,9 @@ static void adjust_refresh_rate(vout_display_t *vd)
                             supported_modes[best_id].code);
         }
     }
+
+    if (vd->sys->opaque)
+        detect_vsync(vd);
 }
 
 static void display_subpicture(vout_display_t *vd, subpicture_t *subpicture)
@@ -947,6 +953,41 @@ static void dmx_region_delete(struct dmx_region_t *dmx_region,
     free(dmx_region);
 }
 
+static void vsync_cb(DISPMANX_UPDATE_HANDLE_T update, void *arg)
+{
+    VLC_UNUSED(update);
+
+    vout_display_t *vd = arg;
+    vout_display_sys_t *sys = vd->sys;
+    mtime_t date = mdate();
+
+    vlc_mutex_lock(&sys->manage_mutex);
+    vd->info.vsync_date = date;
+    vlc_mutex_unlock(&sys->manage_mutex);
+}
+
+static void detect_vsync(vout_display_t *vd)
+{
+    vout_display_sys_t *sys = vd->sys;
+    DISPMANX_UPDATE_HANDLE_T update;
+    DISPMANX_RESOURCE_HANDLE_T res;
+    DISPMANX_ELEMENT_HANDLE_T el;
+    uint32_t color = 0;
+    uint32_t image_ptr;
+    VC_RECT_T rect;
+
+    res = vc_dispmanx_resource_create(VC_IMAGE_RGBA32, 1, 1, &image_ptr);
+    vc_dispmanx_rect_set(&rect, 0, 0, 1, 1);
+    vc_dispmanx_resource_write_data(res, VC_IMAGE_RGBA32, sizeof(color),
+            &color, &rect);
+    update = vc_dispmanx_update_start(10);
+    el = vc_dispmanx_element_add(update, sys->dmx_handle, 0, &rect,
+            res, &rect, DISPMANX_PROTECTION_NONE, NULL, NULL, VC_IMAGE_ROT0);
+    vc_dispmanx_element_remove(update, el);
+    vc_dispmanx_resource_delete(res);
+    vc_dispmanx_update_submit(update, vsync_cb, vd);
+}
+
 static void show_background(vout_display_t *vd, bool enable)
 {
     vout_display_sys_t *sys = vd->sys;
-- 
2.0.0




More information about the vlc-devel mailing list