summaryrefslogtreecommitdiffstats
path: root/video/filter/vf_vdpaupp.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-04-29 15:10:57 +0200
committerwm4 <wm4@nowhere>2014-05-02 01:08:04 +0200
commit073ee146eabaae80e58b8770876078fa8fa60e2a (patch)
tree99e174472c0ec6efe1a7a9b697babf817e8003c3 /video/filter/vf_vdpaupp.c
parentec60669cd10d726054bb5472cfe4eedf6010d154 (diff)
downloadmpv-073ee146eabaae80e58b8770876078fa8fa60e2a.tar.bz2
mpv-073ee146eabaae80e58b8770876078fa8fa60e2a.tar.xz
vf_vdpaupp: allow non-vdpau input
So you can use vdpau deinterlacing without using vdpau hardware decoding. vf_vavpp does something similar.
Diffstat (limited to 'video/filter/vf_vdpaupp.c')
-rw-r--r--video/filter/vf_vdpaupp.c47
1 files 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;
}