| @@ -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, | |||