From 115bfb976270169e34bdf2e8e4a82c473dc83dbb Mon Sep 17 00:00:00 2001 From: cehoyos Date: Wed, 18 Mar 2009 17:02:29 +0000 Subject: Allow to use vdpau temporal deinterlacers with hardware accelerated decoding. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@28991 b3059339-0415-0410-9bf9-f77b7e298cf2 --- DOCS/man/en/mplayer.1 | 11 +++++------ libmpcodecs/mp_image.h | 3 +-- libmpcodecs/vd_ffmpeg.c | 2 +- libmpcodecs/vf.c | 4 ++-- libvo/vo_vdpau.c | 28 ++++++++++++++++++++++++---- 5 files changed, 33 insertions(+), 15 deletions(-) diff --git a/DOCS/man/en/mplayer.1 b/DOCS/man/en/mplayer.1 index fb685f78c8..2472df4151 100644 --- a/DOCS/man/en/mplayer.1 +++ b/DOCS/man/en/mplayer.1 @@ -3464,15 +3464,14 @@ No deinterlacing. .IPs 1 Show only first field, similar to \-vf field. .IPs 2 -Bob deinterlacing -(current fallback for advanced deinterlacers and hardware decoding). +Bob deinterlacing, similar to \-vf tfields=1. .IPs 3 -Motion adaptive temporal deinterlacing -(currently only working with software-decoded video). +Motion adaptive temporal deinterlacing. +May lead to A/V desync with slow video hardware and/or high resolution. This is the default if "D" is used to enable deinterlacing. .IPs 4 -Motion adaptive temporal deinterlacing with edge-guided spatial interpolation -(currently only working with software-decoded video). +Motion adaptive temporal deinterlacing with edge-guided spatial interpolation. +Needs fast video hardware. .RE .IPs chroma\-deint Makes temporal deinterlacers operate both on luma and chroma (default). diff --git a/libmpcodecs/mp_image.h b/libmpcodecs/mp_image.h index 7d82707d10..ddf52c71c5 100644 --- a/libmpcodecs/mp_image.h +++ b/libmpcodecs/mp_image.h @@ -54,8 +54,6 @@ // buffer type was printed (do NOT set this flag - it's for INTERNAL USE!!!) #define MP_IMGFLAG_TYPE_DISPLAYED 0x8000 -// set if it can not be reused yet (for MP_IMGTYPE_NUMBERED) -#define MP_IMGFLAG_IN_USE 0x10000 // codec doesn't support any form of direct rendering - it has own buffer // allocation. so we just export its buffer pointers: @@ -101,6 +99,7 @@ typedef struct mp_image_s { int chroma_height; int chroma_x_shift; // horizontal int chroma_y_shift; // vertical + int usage_count; /* for private use by filter or vo driver (to store buffer id or dmpi) */ void* priv; } mp_image_t; diff --git a/libmpcodecs/vd_ffmpeg.c b/libmpcodecs/vd_ffmpeg.c index a35f4ddd2c..e8e53cae2b 100644 --- a/libmpcodecs/vd_ffmpeg.c +++ b/libmpcodecs/vd_ffmpeg.c @@ -719,7 +719,7 @@ static void release_buffer(struct AVCodecContext *avctx, AVFrame *pic){ } #endif // release mpi (in case MPI_IMGTYPE_NUMBERED is used, e.g. for VDPAU) - mpi->flags &= ~MP_IMGFLAG_IN_USE; + mpi->usage_count--; } if(pic->type!=FF_BUFFER_TYPE_USER){ diff --git a/libmpcodecs/vf.c b/libmpcodecs/vf.c index ad72f304d3..0f286d6e3e 100644 --- a/libmpcodecs/vf.c +++ b/libmpcodecs/vf.c @@ -304,7 +304,7 @@ mp_image_t* vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype, if (number == -1) { int i; for (i = 0; i < NUM_NUMBERED_MPI; i++) - if (!vf->imgctx.numbered_images[i] || !(vf->imgctx.numbered_images[i]->flags & MP_IMGFLAG_IN_USE)) + if (!vf->imgctx.numbered_images[i] || !vf->imgctx.numbered_images[i]->usage_count) break; number = i; } @@ -431,7 +431,7 @@ mp_image_t* vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype, mpi->qscale = NULL; } - mpi->flags |= MP_IMGFLAG_IN_USE; + mpi->usage_count++; // printf("\rVF_MPI: %p %p %p %d %d %d \n", // mpi->planes[0],mpi->planes[1],mpi->planes[2], // mpi->stride[0],mpi->stride[1],mpi->stride[2]); diff --git a/libvo/vo_vdpau.c b/libvo/vo_vdpau.c index 05f2f68ee4..6bda1b55e5 100644 --- a/libvo/vo_vdpau.c +++ b/libvo/vo_vdpau.c @@ -148,12 +148,14 @@ static void *vdpau_lib_handle; #define osd_surface output_surfaces[NUM_OUTPUT_SURFACES] static VdpOutputSurface output_surfaces[NUM_OUTPUT_SURFACES + 1]; static VdpVideoSurface deint_surfaces[3]; +static mp_image_t *deint_mpi[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 deint_buffer_past_frames; static int pullup; static float denoise; static float sharpen; @@ -456,6 +458,12 @@ static void free_video_specific(void) { for (i = 0; i < 3; i++) deint_surfaces[i] = VDP_INVALID_HANDLE; + for (i = 0; i < 3; i++) + if (deint_mpi[i]) { + deint_mpi[i]->usage_count--; + deint_mpi[i] = NULL; + } + for (i = 0; i < MAX_VIDEO_SURFACES; i++) { if (surface_render[i].surface != VDP_INVALID_HANDLE) { vdp_st = vdp_video_surface_destroy(surface_render[i].surface); @@ -848,7 +856,14 @@ 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); + if (deint_buffer_past_frames) { + mpi->usage_count++; + if (deint_mpi[2]) + deint_mpi[2]->usage_count--; + deint_mpi[2] = deint_mpi[1]; + deint_mpi[1] = deint_mpi[0]; + deint_mpi[0] = mpi; + } } else if (!(mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)) { VdpStatus vdp_st; void *destdata[3] = {mpi->planes[0], mpi->planes[2], mpi->planes[1]}; @@ -984,9 +999,9 @@ static const char help_msg[] = " deint (all modes > 0 respect -field-dominance)\n" " 0: no deinterlacing\n" " 1: only show first field\n" - " 2: bob deinterlacing (current fallback for hardware decoding)\n" - " 3: temporal deinterlacing (only works with software codecs)\n" - " 4: temporal-spatial deinterlacing (only works with software codecs)\n" + " 2: bob deinterlacing\n" + " 3: temporal deinterlacing (resource-hungry)\n" + " 4: temporal-spatial deinterlacing (very resource-hungry)\n" " chroma-deint\n" " Operate on luma and chroma when using temporal deinterlacing (default)\n" " Use nochroma-deint to speed up temporal deinterlacing\n" @@ -1007,6 +1022,8 @@ static int preinit(const char *arg) deint = 0; deint_type = 3; deint_counter = 0; + deint_buffer_past_frames = 0; + deint_mpi[0] = deint_mpi[1] = deint_mpi[2] = NULL; chroma_deint = 1; pullup = 0; denoise = 0; @@ -1017,6 +1034,8 @@ static int preinit(const char *arg) } if (deint) deint_type = deint; + if (deint > 2) + deint_buffer_past_frames = 1; vdpau_lib_handle = dlopen(vdpaulibrary, RTLD_LAZY); if (!vdpau_lib_handle) { @@ -1122,6 +1141,7 @@ static int control(uint32_t request, void *data, ...) features, feature_enables); CHECK_ST_WARNING("Error changing deinterlacing settings") + deint_buffer_past_frames = 1; } return VO_TRUE; case VOCTRL_PAUSE: -- cgit v1.2.3