From 073ee146eabaae80e58b8770876078fa8fa60e2a Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 29 Apr 2014 15:10:57 +0200 Subject: vf_vdpaupp: allow non-vdpau input So you can use vdpau deinterlacing without using vdpau hardware decoding. vf_vavpp does something similar. --- video/filter/vf_vdpaupp.c | 47 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/video/filter/vf_vdpaupp.c b/video/filter/vf_vdpaupp.c index 2e3a298855..9fb8a028b8 100644 --- a/video/filter/vf_vdpaupp.c +++ b/video/filter/vf_vdpaupp.c @@ -51,6 +51,35 @@ struct vf_priv_s { struct mp_vdpau_mixer_opts opts; }; +static struct mp_image *upload(struct vf_instance *vf, struct mp_image *mpi) +{ + struct vf_priv_s *p = vf->priv; + struct vdp_functions *vdp = &p->ctx->vdp; + VdpStatus vdp_st; + + VdpChromaType chroma_type = (VdpChromaType)-1; + VdpYCbCrFormat pixel_format = (VdpYCbCrFormat)-1; + mp_vdpau_get_format(mpi->imgfmt, &chroma_type, &pixel_format); + + struct mp_image *hwmpi = + mp_vdpau_get_video_surface(p->ctx, chroma_type, mpi->w, mpi->h); + if (!hwmpi) + return mpi; + + VdpVideoSurface surface = (intptr_t)hwmpi->planes[3]; + const void *destdata[3] = {mpi->planes[0], mpi->planes[2], mpi->planes[1]}; + if (mpi->imgfmt == IMGFMT_NV12) + destdata[1] = destdata[2]; + vdp_st = vdp->video_surface_put_bits_y_cb_cr(surface, + pixel_format, destdata, mpi->stride); + CHECK_VDP_WARNING(vf, "Error when calling vdp_video_surface_put_bits_y_cb_cr"); + + mp_image_copy_attributes(hwmpi, mpi); + + talloc_free(mpi); + return hwmpi; +} + static void forget_frames(struct vf_instance *vf) { struct vf_priv_s *p = vf->priv; @@ -122,13 +151,21 @@ static int filter_ext(struct vf_instance *vf, struct mp_image *mpi) int maxbuffer = p->opts.deint ? MP_ARRAY_SIZE(p->buffered) : 1; bool eof = !mpi; - if (mpi->planes[2]) { - MP_ERR(vf, "Can't apply vdpaupp filter multiple times.\n"); - vf_add_output_frame(vf, mpi); - return -1; + if (mpi && mpi->imgfmt != IMGFMT_VDPAU) { + mpi = upload(vf, mpi); + if (mpi->imgfmt != IMGFMT_VDPAU) { + talloc_free(mpi); + return -1; + } } if (mpi) { + if (mpi->planes[2]) { + MP_ERR(vf, "Can't apply vdpaupp filter multiple times.\n"); + vf_add_output_frame(vf, mpi); + return -1; + } + if (p->num_buffered == maxbuffer) { talloc_free(p->buffered[p->num_buffered - 1]); p->num_buffered--; @@ -170,7 +207,7 @@ static int reconfig(struct vf_instance *vf, struct mp_image_params *in, static int query_format(struct vf_instance *vf, unsigned int fmt) { - if (fmt == IMGFMT_VDPAU) + if (fmt == IMGFMT_VDPAU || mp_vdpau_get_format(fmt, NULL, NULL)) return vf_next_query_format(vf, IMGFMT_VDPAU); return 0; } -- cgit v1.2.3