[MPlayer-dev-eng] [PATCH]Implement advanced deinterlacing for vdpau with SW decoders, try 2

Carl Eugen Hoyos cehoyos at rainbow.studorg.tuwien.ac.at
Sun Mar 15 14:29:35 CET 2009


Hi!

I tried to follow Reimar's advice to improve the patch.
Note that using the patch shows problems (that the original version of the 
patch did not have), but I'd still like to read comments if this approach 
is better.

Thank you, Carl Eugen
-------------- next part --------------
Index: libvo/vo_vdpau.c
===================================================================
--- libvo/vo_vdpau.c	(revision 28934)
+++ libvo/vo_vdpau.c	(working copy)
@@ -147,6 +147,7 @@
 /* output_surfaces[NUM_OUTPUT_SURFACES] is misused for OSD. */
 #define osd_surface output_surfaces[NUM_OUTPUT_SURFACES]
 static VdpOutputSurface                   output_surfaces[NUM_OUTPUT_SURFACES + 1];
+static VdpOutputSurface                   deint_surfaces[3];
 static int                                output_surface_width, output_surface_height;
 
 static VdpVideoMixer                      video_mixer;
@@ -212,11 +213,10 @@
     VdpTime dummy;
     VdpStatus vdp_st;
     int i;
-    if (vid_surface_num < 0)
+    if (vid_surface_num < 0 ||
+        surface_render[vid_surface_num].surface == VDP_INVALID_HANDLE)
         return;
 
-    // we would need to provide 2 past and 1 future frames to allow advanced
-    // deinterlacing, which is not really possible currently.
     for (i = 0; i <= !!(deint > 1); i++) {
         int field = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME;
         VdpOutputSurface output_surface;
@@ -236,9 +236,9 @@
         CHECK_ST_WARNING("Error when calling vdp_presentation_queue_block_until_surface_idle")
 
         vdp_st = vdp_video_mixer_render(video_mixer, VDP_INVALID_HANDLE, 0,
-                                        field, 0, NULL,
+                                        field, 2, deint_surfaces,
                                         surface_render[vid_surface_num].surface,
-                                        0, NULL, &src_rect_vid,
+                                        1, &deint_surfaces[2], &src_rect_vid,
                                         output_surface,
                                         NULL, &out_rect_vid, 0, NULL);
         CHECK_ST_WARNING("Error when calling vdp_video_mixer_render")
@@ -407,7 +407,6 @@
         &vid_height,
         &vdp_chroma_type
     };
-    if (deint == 3)
         features[feature_count++] = VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL;
     if (deint == 4)
         features[feature_count++] = VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL;
@@ -425,6 +424,8 @@
     CHECK_ST_ERROR("Error when calling vdp_video_mixer_create")
 
     for (i = 0; i < feature_count; i++) feature_enables[i] = VDP_TRUE;
+    if (deint != 3)
+        feature_enables[0] = VDP_FALSE;
     if (feature_count)
         vdp_video_mixer_set_feature_enables(video_mixer, feature_count, features, feature_enables);
     if (denoise)
@@ -837,6 +838,7 @@
     if (IMGFMT_IS_VDPAU(image_format)) {
         struct vdpau_render_state *rndr = mpi->priv;
         vid_surface_num = rndr - surface_render;
+        deint = FFMIN(deint, 2);
     } else if (!(mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)) {
         VdpStatus vdp_st;
         void *destdata[3] = {mpi->planes[0], mpi->planes[2], mpi->planes[1]};
@@ -850,7 +852,12 @@
     }
     top_field_first = !!(mpi->fields & MP_IMGFIELD_TOP_FIRST);
 
+    FFSWAP(VdpOutputSurface, deint_surfaces[2], surface_render[vid_surface_num].surface);
+    if (deint < 3)
+        surface_render[vid_surface_num].surface = deint_surfaces[2];
     video_to_output_surface();
+    deint_surfaces[0] = deint_surfaces[1];
+    deint_surfaces[1] = surface_render[vid_surface_num].surface;
     return VO_TRUE;
 }
 
@@ -1015,6 +1022,8 @@
     video_mixer = VDP_INVALID_HANDLE;
     for (i = 0; i <= NUM_OUTPUT_SURFACES; i++)
         output_surfaces[i] = VDP_INVALID_HANDLE;
+    for (i = 0; i <= 2; i++)
+        deint_surfaces[i] = VDP_INVALID_HANDLE;
     vdp_flip_queue = VDP_INVALID_HANDLE;
     output_surface_width = output_surface_height = -1;
 
@@ -1087,6 +1096,18 @@
             deint = *(int*)data;
             if (deint)
                 deint = deint_type;
+            if (deint_type > 2) {
+                VdpStatus vdp_st;
+                VdpVideoMixerFeature features[1] =
+                    {deint_type == 3 ?
+                     VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL :
+                     VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL};
+                VdpBool feature_enables[1] = {deint ? VDP_TRUE : VDP_FALSE};
+                vdp_st = vdp_video_mixer_set_feature_enables(video_mixer, 1, 
+                                                             features,
+                                                             feature_enables);
+                CHECK_ST_WARNING("Error when manipulating advanced deinterlacing")
+            }
             return VO_TRUE;
         case VOCTRL_PAUSE:
             return (int_pause = 1);


More information about the MPlayer-dev-eng mailing list