mirror of https://git.ffmpeg.org/ffmpeg.git
hwcontext_qsv: Support derivation from child devices
This commit is contained in:
parent
e669db7610
commit
aa51bb3d27
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue