summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcehoyos <cehoyos@b3059339-0415-0410-9bf9-f77b7e298cf2>2009-03-15 21:20:06 +0000
committercehoyos <cehoyos@b3059339-0415-0410-9bf9-f77b7e298cf2>2009-03-15 21:20:06 +0000
commite8113dc1c7f33da79ca11e6f96594a4d9c7ac6dc (patch)
tree671493564bb899396f3de27611073f8b365e8f7f
parentefd426578c6a2513d48fc43a8a91326a13eb8a8d (diff)
downloadmpv-e8113dc1c7f33da79ca11e6f96594a4d9c7ac6dc.tar.bz2
mpv-e8113dc1c7f33da79ca11e6f96594a4d9c7ac6dc.tar.xz
Initial support for advanced VDPAU deinterlacers (software-decoded video
only). With a lot of help from Reimar git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@28968 b3059339-0415-0410-9bf9-f77b7e298cf2
-rw-r--r--DOCS/man/en/mplayer.18
-rw-r--r--libvo/vo_vdpau.c43
2 files changed, 39 insertions, 12 deletions
diff --git a/DOCS/man/en/mplayer.1 b/DOCS/man/en/mplayer.1
index 0f40662238..6f866c8c16 100644
--- a/DOCS/man/en/mplayer.1
+++ b/DOCS/man/en/mplayer.1
@@ -3464,13 +3464,15 @@ No deinterlacing.
.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.
diff --git a/libvo/vo_vdpau.c b/libvo/vo_vdpau.c
index f7f2450751..246c0cfdc1 100644
--- a/libvo/vo_vdpau.c
+++ b/libvo/vo_vdpau.c
@@ -147,11 +147,13 @@ static void *vdpau_lib_handle;
/* 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 @@ static void video_to_output_surface(void)
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 @@ static void video_to_output_surface(void)
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 @@ static int create_vdp_mixer(VdpChromaType vdp_chroma_type) {
&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 @@ static int create_vdp_mixer(VdpChromaType vdp_chroma_type) {
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 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width,
XSetWindowAttributes xswa;
XWindowAttributes attribs;
unsigned long xswamask;
- int depth;
+ int depth, i;
#ifdef CONFIG_XF86VM
int vm = flags & VOFLAG_MODESWITCHING;
@@ -541,6 +543,9 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width,
vid_surface_num = -1;
resize();
+ for (i = 0; i < 3; i++)
+ deint_surfaces[i] = VDP_INVALID_HANDLE;
+
return 0;
}
@@ -837,10 +842,12 @@ static uint32_t draw_image(mp_image_t *mpi)
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 @@ static uint32_t draw_image(mp_image_t *mpi)
}
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 @@ static int preinit(const char *arg)
deint = 0;
deint_type = 3;
+ deint_counter = 0;
pullup = 0;
denoise = 0;
sharpen = 0;
@@ -1087,6 +1100,18 @@ static int control(uint32_t request, void *data, ...)
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);