diff options
Diffstat (limited to 'video/decode/vd_lavc.c')
-rw-r--r-- | video/decode/vd_lavc.c | 77 |
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; |