summaryrefslogtreecommitdiffstats
path: root/video/vdpau.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/vdpau.c')
-rw-r--r--video/vdpau.c62
1 files changed, 57 insertions, 5 deletions
diff --git a/video/vdpau.c b/video/vdpau.c
index 9dfbc2bc6e..dffb02e22f 100644
--- a/video/vdpau.c
+++ b/video/vdpau.c
@@ -28,11 +28,61 @@
#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)
{
- struct mp_vdpau_ctx *ctx = hwctx->vdpau_ctx;
+ if (mpi->imgfmt != IMGFMT_VDPAU && mpi->imgfmt != IMGFMT_VDPAU_OUTPUT)
+ return NULL;
+
+ struct mp_vdpau_ctx *ctx = hwctx->ctx;
struct vdp_functions *vdp = &ctx->vdp;
VdpStatus vdp_st;
@@ -40,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);
@@ -268,8 +322,7 @@ static struct mp_image *create_ref(struct mp_vdpau_ctx *ctx, int index)
struct surface_ref *ref = talloc_ptrtype(NULL, ref);
*ref = (struct surface_ref){ctx, index};
struct mp_image *res =
- mp_image_new_custom_ref(&(struct mp_image){0}, ref,
- release_decoder_surface);
+ mp_image_new_custom_ref(NULL, ref, release_decoder_surface);
if (res) {
mp_image_setfmt(res, e->rgb ? IMGFMT_VDPAU_OUTPUT : IMGFMT_VDPAU);
mp_image_set_size(res, e->w, e->h);
@@ -396,8 +449,7 @@ struct mp_vdpau_ctx *mp_vdpau_create_device_x11(struct mp_log *log, Display *x11
.preemption_counter = 1,
.hwctx = {
.type = HWDEC_VDPAU,
- .priv = ctx,
- .vdpau_ctx = ctx,
+ .ctx = ctx,
.download_image = download_image,
},
.getimg_surface = VDP_INVALID_HANDLE,