[MPlayer-dev-eng] [PATCH] reduce flashing on resize with VDPAU

Reimar Döffinger Reimar.Doeffinger at gmx.de
Wed Mar 18 10:34:33 CET 2009


On Wed, Mar 18, 2009 at 10:02:02AM +0100, Dan Oscarsson wrote:
> ons 2009-03-18 klockan 09:35 +0100 skrev Reimar Döffinger:
> > On Wed, Mar 18, 2009 at 08:29:39AM +0100, Dan Oscarsson wrote:
> > > My code do not wait for vsyncs, instead it discards a frame if display
> > > has not displayed the previous frame.
> > 
> > There are already other patches to do that part. Their advantage is that they
> > change _only_ that which means they are far easier to review, don't
> > conflict with other patches all over the place and e.g. still allow
> > selecting the number of queued frames.
> 
> I can do my patch for just the vsync handling, but if there is a better
> one I can try it. Which patches are you thinking of?

You can try attached patch. There are some issues though: I only tested
with the blit engine, which behaves a bit weirdly, it should be possible
to disable it, and it should be possible to adjust the number of output
surfaces used.
It might also be nicer to allow skipping in the draw_image part for
cases where the GPU usage is the issue, but that has higher jitter.

> Note: the moment you allow several frames to be queued, audio easily
> gets slightly out of sync without mplayer noticing it as frames may be
> shown long after they were queued by flip_page.

Which some people may still prefer over frame-dropping.
-------------- next part --------------
Index: libvo/vo_vdpau.c
===================================================================
--- libvo/vo_vdpau.c	(revision 28982)
+++ libvo/vo_vdpau.c	(working copy)
@@ -75,8 +75,8 @@
         mp_msg(MSGT_VO, MSGL_WARN, "[vdpau] %s: %s\n", \
                message, vdp_get_error_string(vdp_st));
 
-/* number of video and output surfaces */
-#define NUM_OUTPUT_SURFACES                2
+/** number of output surfaces, with deint < 2 3 would be enough/better */
+#define NUM_OUTPUT_SURFACES                4
 #define MAX_VIDEO_SURFACES                 50
 
 /* number of palette entries */
@@ -126,6 +126,7 @@
 static VdpPresentationQueueCreate        *vdp_presentation_queue_create;
 static VdpPresentationQueueDestroy       *vdp_presentation_queue_destroy;
 static VdpPresentationQueueDisplay       *vdp_presentation_queue_display;
+static VdpPresentationQueueQuerySurfaceStatus    *vdp_presentation_queue_query_surface_status;
 static VdpPresentationQueueBlockUntilSurfaceIdle *vdp_presentation_queue_block_until_surface_idle;
 static VdpPresentationQueueTargetCreateX11       *vdp_presentation_queue_target_create_x11;
 
@@ -333,6 +334,8 @@
                         &vdp_presentation_queue_destroy},
         {VDP_FUNC_ID_PRESENTATION_QUEUE_DISPLAY,
                         &vdp_presentation_queue_display},
+        {VDP_FUNC_ID_PRESENTATION_QUEUE_QUERY_SURFACE_STATUS,
+                        &vdp_presentation_queue_query_surface_status},
         {VDP_FUNC_ID_PRESENTATION_QUEUE_BLOCK_UNTIL_SURFACE_IDLE,
                         &vdp_presentation_queue_block_until_surface_idle},
         {VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_CREATE_X11,
@@ -763,6 +766,16 @@
 static void flip_page(void)
 {
     VdpStatus vdp_st;
+    VdpPresentationQueueStatus next_status = VDP_PRESENTATION_QUEUE_STATUS_IDLE;
+    VdpTime time_dummy;
+    int next_surface = (surface_num + 1) % NUM_OUTPUT_SURFACES;
+    vdp_st = vdp_presentation_queue_query_surface_status(vdp_flip_queue,
+                output_surfaces[next_surface], &next_status, &time_dummy);
+    if (NUM_OUTPUT_SURFACES > 2 && vdp_st == VDP_STATUS_OK &&
+        next_status != VDP_PRESENTATION_QUEUE_STATUS_IDLE) {
+        mp_msg(MSGT_VO, MSGL_V, "[vdpau] dropping frame\n");
+        return;
+    }
     mp_msg(MSGT_VO, MSGL_DBG2, "\nFLIP_PAGE VID:%u -> OUT:%u\n",
            surface_render[vid_surface_num].surface, output_surfaces[surface_num]);
 
@@ -771,7 +784,7 @@
                                             0);
     CHECK_ST_WARNING("Error when calling vdp_presentation_queue_display")
 
-    surface_num = (surface_num + 1) % NUM_OUTPUT_SURFACES;
+    surface_num = next_surface;
     visible_buf = 1;
 }
 


More information about the MPlayer-dev-eng mailing list