summaryrefslogtreecommitdiffstats
path: root/video/decode/vd_lavc.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-02-20 08:39:55 +0100
committerwm4 <wm4@nowhere>2017-02-20 08:39:55 +0100
commit6aa4efd1e3205c9b1385865df1b5b09646d2160c (patch)
tree4a0f78718f21f7f644f9ca7de4fbcfb8a83aafa9 /video/decode/vd_lavc.c
parent6e2d3d991912f230ee66448307e8e2657237ffd2 (diff)
downloadmpv-6aa4efd1e3205c9b1385865df1b5b09646d2160c.tar.bz2
mpv-6aa4efd1e3205c9b1385865df1b5b09646d2160c.tar.xz
vd_lavc, vaapi: move hw device creation to generic code
hw_vaapi.c didn't do much interesting anymore. Other than the function to create a device for decoding with vaapi-copy, everything can be done by generic code. Other libavcodec hwaccels are planned to provide the same API as vaapi. It will be possible to drop the other hw_ files in the future. They will use this generic code instead.
Diffstat (limited to 'video/decode/vd_lavc.c')
-rw-r--r--video/decode/vd_lavc.c77
1 files changed, 71 insertions, 6 deletions
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index cd054f7ea4..f89ec7e6cd 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -129,8 +129,6 @@ extern const struct vd_lavc_hwdec mp_vd_lavc_vdpau;
extern const struct vd_lavc_hwdec mp_vd_lavc_vdpau_copy;
extern const struct vd_lavc_hwdec mp_vd_lavc_videotoolbox;
extern const struct vd_lavc_hwdec mp_vd_lavc_videotoolbox_copy;
-extern const struct vd_lavc_hwdec mp_vd_lavc_vaapi;
-extern const struct vd_lavc_hwdec mp_vd_lavc_vaapi_copy;
extern const struct vd_lavc_hwdec mp_vd_lavc_dxva2;
extern const struct vd_lavc_hwdec mp_vd_lavc_dxva2_copy;
extern const struct vd_lavc_hwdec mp_vd_lavc_d3d11va;
@@ -172,6 +170,41 @@ static const struct vd_lavc_hwdec mp_vd_lavc_crystalhd = {
.copying = true,
};
+#if HAVE_VAAPI_HWACCEL
+#if HAVE_VAAPI_HWACCEL_NEW
+const struct vd_lavc_hwdec mp_vd_lavc_vaapi = {
+ .type = HWDEC_VAAPI,
+ .image_format = IMGFMT_VAAPI,
+ .generic_hwaccel = true,
+ .static_pool = true,
+ .pixfmt_map = (const enum AVPixelFormat[][2]) {
+ {AV_PIX_FMT_YUV420P10, AV_PIX_FMT_P010},
+ {AV_PIX_FMT_YUV420P, AV_PIX_FMT_NV12},
+ {AV_PIX_FMT_NONE}
+ },
+};
+
+#include "video/vaapi.h"
+
+const struct vd_lavc_hwdec mp_vd_lavc_vaapi_copy = {
+ .type = HWDEC_VAAPI_COPY,
+ .copying = true,
+ .image_format = IMGFMT_VAAPI,
+ .generic_hwaccel = true,
+ .static_pool = true,
+ .create_dev = va_create_standalone,
+ .pixfmt_map = (const enum AVPixelFormat[][2]) {
+ {AV_PIX_FMT_YUV420P10, AV_PIX_FMT_P010},
+ {AV_PIX_FMT_YUV420P, AV_PIX_FMT_NV12},
+ {AV_PIX_FMT_NONE}
+ },
+};
+#else
+extern const struct vd_lavc_hwdec mp_vd_lavc_vaapi;
+extern const struct vd_lavc_hwdec mp_vd_lavc_vaapi_copy;
+#endif
+#endif
+
static const struct vd_lavc_hwdec *const hwdec_list[] = {
#if HAVE_RPI
&mp_vd_lavc_rpi,
@@ -309,13 +342,37 @@ static bool hwdec_is_wrapper(struct vd_lavc_hwdec *hwdec, const char *decoder)
return bstr_endswith0(bstr0(decoder), hwdec->lavc_suffix);
}
+static struct mp_hwdec_ctx *hwdec_create_dev(struct dec_video *vd,
+ struct vd_lavc_hwdec *hwdec,
+ bool autoprobe)
+{
+ if (hwdec->create_dev)
+ return hwdec->create_dev(vd->global, vd->log, autoprobe);
+ if (vd->hwdec_devs) {
+ hwdec_devices_request(vd->hwdec_devs, hwdec->type);
+ return hwdec_devices_get(vd->hwdec_devs, hwdec->type);
+ }
+ return NULL;
+}
+
static int hwdec_probe(struct dec_video *vd, struct vd_lavc_hwdec *hwdec,
- const char *codec)
+ const char *codec, bool autoprobe)
{
vd_ffmpeg_ctx *ctx = vd->priv;
int r = 0;
if (hwdec->probe)
r = hwdec->probe(ctx, hwdec, codec);
+ if (hwdec->generic_hwaccel) {
+ assert(!hwdec->probe && !hwdec->init && !hwdec->init_decoder &&
+ !hwdec->uninit && !hwdec->allocate_image && !hwdec->process_image);
+ struct mp_hwdec_ctx *dev = hwdec_create_dev(vd, hwdec, autoprobe);
+ if (!dev)
+ return hwdec->copying ? -1 : HWDEC_ERR_NO_CTX;
+ if (dev->emulated)
+ r = HWDEC_ERR_EMULATED;
+ if (hwdec->create_dev && dev->destroy)
+ dev->destroy(dev);
+ }
if (r >= 0) {
if (hwdec->lavc_suffix && !hwdec_find_decoder(codec, hwdec->lavc_suffix))
return HWDEC_ERR_NO_CODEC;
@@ -333,7 +390,7 @@ static struct vd_lavc_hwdec *probe_hwdec(struct dec_video *vd, bool autoprobe,
MP_VERBOSE(vd, "Requested hardware decoder not compiled.\n");
return NULL;
}
- int r = hwdec_probe(vd, hwdec, codec);
+ int r = hwdec_probe(vd, hwdec, codec, autoprobe);
if (r == HWDEC_ERR_EMULATED) {
if (autoprobe)
return NULL;
@@ -421,8 +478,6 @@ static void reinit(struct dec_video *vd)
if (hwdec) {
const char *orig_decoder = decoder;
- if (hwdec->get_codec)
- decoder = hwdec->get_codec(ctx, decoder);
if (hwdec->lavc_suffix)
decoder = hwdec_find_decoder(codec, hwdec->lavc_suffix);
MP_VERBOSE(vd, "Trying hardware decoding.\n");
@@ -505,6 +560,11 @@ static void init_avctx(struct dec_video *vd, const char *decoder,
avctx->get_buffer2 = get_buffer2_hwdec;
if (ctx->hwdec->init && ctx->hwdec->init(ctx) < 0)
goto error;
+ if (ctx->hwdec->generic_hwaccel) {
+ ctx->hwdec_dev = hwdec_create_dev(vd, ctx->hwdec, false);
+ if (!ctx->hwdec_dev)
+ goto error;
+ }
ctx->max_delay_queue = ctx->hwdec->delay_queue;
ctx->hw_probing = true;
} else {
@@ -584,6 +644,11 @@ static void uninit_avctx(struct dec_video *vd)
av_freep(&ctx->avctx->extradata);
}
+ if (ctx->hwdec_dev && ctx->hwdec && ctx->hwdec->generic_hwaccel &&
+ ctx->hwdec_dev->destroy)
+ ctx->hwdec_dev->destroy(ctx->hwdec_dev);
+ ctx->hwdec_dev = NULL;
+
if (ctx->hwdec && ctx->hwdec->uninit)
ctx->hwdec->uninit(ctx);
ctx->hwdec = NULL;