aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Thompson <sw@jkqxz.net>2017-03-04 23:57:43 +0000
committerMark Thompson <sw@jkqxz.net>2017-06-14 22:27:07 +0100
commit045ff8d30a6942b72c8be064c3b8415b037dab02 (patch)
tree9486a082b0da5080decd47f3e9cec8d45e232617
parent7ce47090ce36fbe72f807d1e35fea3a699adad17 (diff)
downloadffmpeg-045ff8d30a6942b72c8be064c3b8415b037dab02.tar.gz
hwcontext_qsv: Support derivation from child devices
(cherry picked from commit aa51bb3d2756ed912ee40645efccf5f4a9609696)
-rw-r--r--libavutil/hwcontext_qsv.c113
1 files changed, 84 insertions, 29 deletions
diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c
index 5550ffe143..505a8e709d 100644
--- a/libavutil/hwcontext_qsv.c
+++ b/libavutil/hwcontext_qsv.c
@@ -792,21 +792,96 @@ static mfxIMPL choose_implementation(const char *device)
return impl;
}
-static int qsv_device_create(AVHWDeviceContext *ctx, const char *device,
- AVDictionary *opts, int flags)
+static int qsv_device_derive_from_child(AVHWDeviceContext *ctx,
+ mfxIMPL implementation,
+ AVHWDeviceContext *child_device_ctx,
+ int flags)
{
AVQSVDeviceContext *hwctx = ctx->hwctx;
- QSVDevicePriv *priv;
- enum AVHWDeviceType child_device_type;
- AVDictionaryEntry *e;
+ QSVDeviceContext *s = ctx->internal->priv;
mfxVersion ver = { { 3, 1 } };
- mfxIMPL impl;
mfxHDL handle;
mfxHandleType handle_type;
mfxStatus err;
int ret;
+ switch (child_device_ctx->type) {
+#if CONFIG_VAAPI
+ case AV_HWDEVICE_TYPE_VAAPI:
+ {
+ AVVAAPIDeviceContext *child_device_hwctx = child_device_ctx->hwctx;
+ handle_type = MFX_HANDLE_VA_DISPLAY;
+ handle = (mfxHDL)child_device_hwctx->display;
+ }
+ break;
+#endif
+#if CONFIG_DXVA2
+ case AV_HWDEVICE_TYPE_DXVA2:
+ {
+ AVDXVA2DeviceContext *child_device_hwctx = child_device_ctx->hwctx;
+ handle_type = MFX_HANDLE_D3D9_DEVICE_MANAGER;
+ handle = (mfxHDL)child_device_hwctx->devmgr;
+ }
+ break;
+#endif
+ default:
+ ret = AVERROR(ENOSYS);
+ goto fail;
+ }
+
+ err = MFXInit(implementation, &ver, &hwctx->session);
+ if (err != MFX_ERR_NONE) {
+ av_log(ctx, AV_LOG_ERROR, "Error initializing an MFX session: "
+ "%d.\n", err);
+ ret = AVERROR_UNKNOWN;
+ goto fail;
+ }
+
+ err = MFXVideoCORE_SetHandle(hwctx->session, handle_type, handle);
+ if (err != MFX_ERR_NONE) {
+ av_log(ctx, AV_LOG_ERROR, "Error setting child device handle: "
+ "%d\n", err);
+ ret = AVERROR_UNKNOWN;
+ goto fail;
+ }
+
+ ret = qsv_device_init(ctx);
+ if (ret < 0)
+ goto fail;
+ if (s->handle_type != handle_type) {
+ av_log(ctx, AV_LOG_ERROR, "Error in child device handle setup: "
+ "type mismatch (%d != %d).\n", s->handle_type, handle_type);
+ err = AVERROR_UNKNOWN;
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ if (hwctx->session)
+ MFXClose(hwctx->session);
+ return ret;
+}
+
+static int qsv_device_derive(AVHWDeviceContext *ctx,
+ AVHWDeviceContext *child_device_ctx, int flags)
+{
+ return qsv_device_derive_from_child(ctx, MFX_IMPL_HARDWARE_ANY,
+ child_device_ctx, flags);
+}
+
+static int qsv_device_create(AVHWDeviceContext *ctx, const char *device,
+ AVDictionary *opts, int flags)
+{
+ QSVDevicePriv *priv;
+ enum AVHWDeviceType child_device_type;
+ AVHWDeviceContext *child_device;
+ AVDictionaryEntry *e;
+
+ mfxIMPL impl;
+ int ret;
+
priv = av_mallocz(sizeof(*priv));
if (!priv)
return AVERROR(ENOMEM);
@@ -830,32 +905,11 @@ static int qsv_device_create(AVHWDeviceContext *ctx, const char *device,
if (ret < 0)
return ret;
- {
- AVHWDeviceContext *child_device_ctx = (AVHWDeviceContext*)priv->child_device_ctx->data;
-#if CONFIG_VAAPI
- AVVAAPIDeviceContext *child_device_hwctx = child_device_ctx->hwctx;
- handle_type = MFX_HANDLE_VA_DISPLAY;
- handle = (mfxHDL)child_device_hwctx->display;
-#elif CONFIG_DXVA2
- AVDXVA2DeviceContext *child_device_hwctx = child_device_ctx->hwctx;
- handle_type = MFX_HANDLE_D3D9_DEVICE_MANAGER;
- handle = (mfxHDL)child_device_hwctx->devmgr;
-#endif
- }
+ child_device = (AVHWDeviceContext*)priv->child_device_ctx->data;
impl = choose_implementation(device);
- err = MFXInit(impl, &ver, &hwctx->session);
- if (err != MFX_ERR_NONE) {
- av_log(ctx, AV_LOG_ERROR, "Error initializing an MFX session\n");
- return AVERROR_UNKNOWN;
- }
-
- err = MFXVideoCORE_SetHandle(hwctx->session, handle_type, handle);
- if (err != MFX_ERR_NONE)
- return AVERROR_UNKNOWN;
-
- return 0;
+ return qsv_device_derive_from_child(ctx, impl, child_device, 0);
}
const HWContextType ff_hwcontext_type_qsv = {
@@ -868,6 +922,7 @@ const HWContextType ff_hwcontext_type_qsv = {
.frames_priv_size = sizeof(QSVFramesContext),
.device_create = qsv_device_create,
+ .device_derive = qsv_device_derive,
.device_init = qsv_device_init,
.frames_get_constraints = qsv_frames_get_constraints,
.frames_init = qsv_frames_init,