summaryrefslogtreecommitdiffstats
path: root/video/vdpau.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/vdpau.c')
-rw-r--r--video/vdpau.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/video/vdpau.c b/video/vdpau.c
index 73aa844abd..dffb02e22f 100644
--- a/video/vdpau.c
+++ b/video/vdpau.c
@@ -28,6 +28,53 @@
#include "mp_image_pool.h"
#include "vdpau_mixer.h"
+static struct mp_image *download_image_yuv(struct mp_hwdec_ctx *hwctx,
+ struct mp_image *mpi,
+ struct mp_image_pool *swpool)
+{
+ struct mp_vdpau_ctx *ctx = hwctx->ctx;
+ struct vdp_functions *vdp = &ctx->vdp;
+ VdpStatus vdp_st;
+
+ if (mpi->imgfmt != IMGFMT_VDPAU || mp_vdpau_mixed_frame_get(mpi))
+ return NULL;
+
+ VdpVideoSurface surface = (uintptr_t)mpi->planes[3];
+
+ VdpChromaType s_chroma_type;
+ uint32_t s_w, s_h;
+ vdp_st = vdp->video_surface_get_parameters(surface, &s_chroma_type, &s_w, &s_h);
+ CHECK_VDP_ERROR_NORETURN(ctx,
+ "Error when calling vdp_video_surface_get_parameters");
+ if (vdp_st != VDP_STATUS_OK)
+ return NULL;
+
+ // Don't bother supporting other types for now.
+ if (s_chroma_type != VDP_CHROMA_TYPE_420)
+ return NULL;
+
+ // The allocation needs to be uncropped, because get_bits writes to it.
+ struct mp_image *out = mp_image_pool_get(swpool, IMGFMT_NV12, s_w, s_h);
+ if (!out)
+ return NULL;
+
+ mp_image_set_size(out, mpi->w, mpi->h);
+ mp_image_copy_attributes(out, mpi);
+
+ vdp_st = vdp->video_surface_get_bits_y_cb_cr(surface,
+ VDP_YCBCR_FORMAT_NV12,
+ (void * const *)out->planes,
+ out->stride);
+ CHECK_VDP_ERROR_NORETURN(ctx,
+ "Error when calling vdp_output_surface_get_bits_y_cb_cr");
+ if (vdp_st != VDP_STATUS_OK) {
+ talloc_free(out);
+ return NULL;
+ }
+
+ return out;
+}
+
static struct mp_image *download_image(struct mp_hwdec_ctx *hwctx,
struct mp_image *mpi,
struct mp_image_pool *swpool)
@@ -43,6 +90,10 @@ static struct mp_image *download_image(struct mp_hwdec_ctx *hwctx,
int w, h;
mp_image_params_get_dsize(&mpi->params, &w, &h);
+ res = download_image_yuv(hwctx, mpi, swpool);
+ if (res)
+ return res;
+
// Abuse this lock for our own purposes. It could use its own lock instead.
pthread_mutex_lock(&ctx->pool_lock);