Mercurial > mplayer.hg
changeset 28933:b0badbd680c6
Initial support for advanced VDPAU deinterlacers (software-decoded video
only).
With a lot of help from Reimar
author | cehoyos |
---|---|
date | Sun, 15 Mar 2009 21:20:06 +0000 |
parents | 41aa8200c7c9 |
children | e8c117f5758a |
files | DOCS/man/en/mplayer.1 libvo/vo_vdpau.c |
diffstat | 2 files changed, 39 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/DOCS/man/en/mplayer.1 Sun Mar 15 20:40:48 2009 +0000 +++ b/DOCS/man/en/mplayer.1 Sun Mar 15 21:20:06 2009 +0000 @@ -3464,13 +3464,15 @@ .IPs 1 Show only first field, similar to \-vf field. .IPs 2 -Bob deinterlacing (current fallback for advanced deinterlacers). +Bob deinterlacing +(current fallback for advanced deinterlacers and hardware decoding). .IPs 3 -Motion adaptive temporal deinterlacing (not yet working). +Motion adaptive temporal deinterlacing +(currently only working with software-decoded video). This is the default if "D" is used to enable deinterlacing. .IPs 4 Motion adaptive temporal deinterlacing with edge-guided spatial interpolation -(not yet working). +(currently only working with software-decoded video). .RE .IPs pullup Try to apply inverse telecine, needs temporal deinterlacing.
--- a/libvo/vo_vdpau.c Sun Mar 15 20:40:48 2009 +0000 +++ b/libvo/vo_vdpau.c Sun Mar 15 21:20:06 2009 +0000 @@ -147,11 +147,13 @@ /* 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 VdpVideoSurface deint_surfaces[3]; static int output_surface_width, output_surface_height; static VdpVideoMixer video_mixer; static int deint; static int deint_type; +static int deint_counter; static int pullup; static float denoise; static float sharpen; @@ -212,11 +214,9 @@ VdpTime dummy; VdpStatus vdp_st; int i; - if (vid_surface_num < 0) + if (vid_surface_num < 0 || deint_surfaces[0] == 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,10 @@ 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, 2, deint_surfaces + 1, + deint_surfaces[0], + 1, &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 +408,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 +425,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) @@ -472,7 +474,7 @@ XSetWindowAttributes xswa; XWindowAttributes attribs; unsigned long xswamask; - int depth; + int depth, i; #ifdef CONFIG_XF86VM int vm = flags & VOFLAG_MODESWITCHING; @@ -541,6 +543,9 @@ vid_surface_num = -1; resize(); + for (i = 0; i < 3; i++) + deint_surfaces[i] = VDP_INVALID_HANDLE; + return 0; } @@ -837,10 +842,12 @@ 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); + deint_counter = (deint_counter + 1) & 3; vid_surface_num = rndr - surface_render; vdp_st = vdp_video_surface_put_bits_y_cb_cr(rndr->surface, VDP_YCBCR_FORMAT_YV12, @@ -850,7 +857,12 @@ } top_field_first = !!(mpi->fields & MP_IMGFIELD_TOP_FIRST); + if (deint < 3) + deint_surfaces[0] = surface_render[vid_surface_num].surface; video_to_output_surface(); + deint_surfaces[2] = deint_surfaces[1]; + deint_surfaces[1] = deint_surfaces[0]; + deint_surfaces[0] = surface_render[vid_surface_num].surface; return VO_TRUE; } @@ -984,6 +996,7 @@ deint = 0; deint_type = 3; + deint_counter = 0; pullup = 0; denoise = 0; sharpen = 0; @@ -1087,6 +1100,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 changing deinterlacing settings") + } return VO_TRUE; case VOCTRL_PAUSE: return (int_pause = 1);