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

Carl Eugen Hoyos cehoyos at rainbow.studorg.tuwien.ac.at
Sat Mar 14 18:02:29 CET 2009


Hi!

Attached patch allows vo vdpau to use both advanced deinterlacers if 
software decoders are used.
This is already useful because the deinterlacing quality comes for a cheap 
price - measured in CPU cycles;-)

Reimar, could you comment if the overall idea is ok and how to avoid to 
always feature_enable DEINTERLACE_TEMPORAL? I would really like to have 
temporal deinterlacing the standard if "D" is pressed.

Thank you, Carl Eugen
-------------- next part --------------
Index: libvo/vo_vdpau.c
===================================================================
--- libvo/vo_vdpau.c	(revision 28934)
+++ libvo/vo_vdpau.c	(working copy)
@@ -76,7 +76,7 @@
                message, vdp_get_error_string(vdp_st));
 
 /* number of video and output surfaces */
-#define NUM_OUTPUT_SURFACES                2
+#define NUM_OUTPUT_SURFACES                5
 #define MAX_VIDEO_SURFACES                 50
 
 /* number of palette entries */
@@ -152,6 +152,7 @@
 static VdpVideoMixer                      video_mixer;
 static int                                deint;
 static int                                deint_type;
+static int                                deint_counter;
 static int                                pullup;
 static float                              denoise;
 static float                              sharpen;
@@ -220,6 +221,11 @@
     for (i = 0; i <= !!(deint > 1); i++) {
         int field = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME;
         VdpOutputSurface output_surface;
+        VdpVideoSurface const past_pict[2] = {surface_render[(vid_surface_num+2)&3].surface,
+                                              surface_render[(vid_surface_num+1)&3].surface};
+        int current_pict = (deint > 2) ? (vid_surface_num + 3) & 3 : vid_surface_num;
+        if (surface_render[current_pict].surface == VDP_INVALID_HANDLE)
+            return;
         if (i) {
             draw_eosd();
             draw_osd();
@@ -236,9 +242,11 @@
         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,
-                                        surface_render[vid_surface_num].surface,
-                                        0, NULL, &src_rect_vid,
+                                        field, (deint > 2) ? 2 : 0, past_pict,
+                                        surface_render[current_pict].surface,
+                                        (deint > 2) ? 1 : 0,
+                                        &surface_render[vid_surface_num].surface,
+                                        &src_rect_vid,
                                         output_surface,
                                         NULL, &out_rect_vid, 0, NULL);
         CHECK_ST_WARNING("Error when calling vdp_video_mixer_render")
@@ -407,7 +415,7 @@
         &vid_height,
         &vdp_chroma_type
     };
-    if (deint == 3)
+//    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;
@@ -837,10 +845,11 @@
     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]};
-        struct vdpau_render_state *rndr = get_surface(0);
+        struct vdpau_render_state *rndr = get_surface(deint_counter);
         vid_surface_num = rndr - surface_render;
         vdp_st = vdp_video_surface_put_bits_y_cb_cr(rndr->surface,
                                                     VDP_YCBCR_FORMAT_YV12,
@@ -851,6 +860,7 @@
     top_field_first = !!(mpi->fields & MP_IMGFIELD_TOP_FIRST);
 
     video_to_output_surface();
+    deint_counter = (deint_counter + 1) & 3; 
     return VO_TRUE;
 }
 
@@ -984,6 +994,7 @@
 
     deint = 0;
     deint_type = 3;
+    deint_counter = 0;
     pullup = 0;
     denoise = 0;
     sharpen = 0;


More information about the MPlayer-dev-eng mailing list