(cherry picked from commit aa51bb3d2756ed912ee40645efccf5f4a9609696)
Unified · Split
| @@ -792,21 +792,96 @@ static mfxIMPL choose_implementation(const char *device) · 791 unmodified lines | |||
| 792 | return impl; | 792 | return impl; |
| 793 | } | 793 | } |
| 794 | 794 | ||
| 795 | static int qsv_device_create(AVHWDeviceContext *ctx, const char *device, | 795 | static int qsv_device_derive_from_child(AVHWDeviceContext *ctx, |
| 796 | AVDictionary *opts, int flags) | 796 | mfxIMPL implementation, |
| 797 | AVHWDeviceContext *child_device_ctx, | ||
| 798 | int flags) | ||
| 797 | { | 799 | { |
| 798 | AVQSVDeviceContext *hwctx = ctx->hwctx; | 800 | AVQSVDeviceContext *hwctx = ctx->hwctx; |
| 799 | QSVDevicePriv *priv; | 801 | QSVDeviceContext *s = ctx->internal->priv; |
| 800 | enum AVHWDeviceType child_device_type; | ||
| 801 | AVDictionaryEntry *e; | ||
| 802 | 802 | ||
| 803 | mfxVersion ver = { { 3, 1 } }; | 803 | mfxVersion ver = { { 3, 1 } }; |
| 804 | mfxIMPL impl; | ||
| 805 | mfxHDL handle; | 804 | mfxHDL handle; |
| 806 | mfxHandleType handle_type; | 805 | mfxHandleType handle_type; |
| 807 | mfxStatus err; | 806 | mfxStatus err; |
| 808 | int ret; | 807 | int ret; |
| 809 | 808 | ||
| 809 | switch (child_device_ctx->type) { | ||
| 810 | #if CONFIG_VAAPI | ||
| 811 | case AV_HWDEVICE_TYPE_VAAPI: | ||
| 812 | { | ||
| 813 | AVVAAPIDeviceContext *child_device_hwctx = child_device_ctx->hwctx; | ||
| 814 | handle_type = MFX_HANDLE_VA_DISPLAY; | ||
| 815 | handle = (mfxHDL)child_device_hwctx->display; | ||
| 816 | } | ||
| 817 | break; | ||
| 818 | #endif | ||
| 819 | #if CONFIG_DXVA2 | ||
| 820 | case AV_HWDEVICE_TYPE_DXVA2: | ||
| 821 | { | ||
| 822 | AVDXVA2DeviceContext *child_device_hwctx = child_device_ctx->hwctx; | ||
| 823 | handle_type = MFX_HANDLE_D3D9_DEVICE_MANAGER; | ||
| 824 | handle = (mfxHDL)child_device_hwctx->devmgr; | ||
| 825 | } | ||
| 826 | break; | ||
| 827 | #endif | ||
| 828 | default: | ||
| 829 | ret = AVERROR(ENOSYS); | ||
| 830 | goto fail; | ||
| 831 | } | ||
| 832 | |||
| 833 | err = MFXInit(implementation, &ver, &hwctx->session); | ||
| 834 | if (err != MFX_ERR_NONE) { | ||
| 835 | av_log(ctx, AV_LOG_ERROR, "Error initializing an MFX session: " | ||
| 836 | "%d.\n", err); | ||
| 837 | ret = AVERROR_UNKNOWN; | ||
| 838 | goto fail; | ||
| 839 | } | ||
| 840 | |||
| 841 | err = MFXVideoCORE_SetHandle(hwctx->session, handle_type, handle); | ||
| 842 | if (err != MFX_ERR_NONE) { | ||
| 843 | av_log(ctx, AV_LOG_ERROR, "Error setting child device handle: " | ||
| 844 | "%d\n", err); | ||
| 845 | ret = AVERROR_UNKNOWN; | ||
| 846 | goto fail; | ||
| 847 | } | ||
| 848 | |||
| 849 | ret = qsv_device_init(ctx); | ||
| 850 | if (ret < 0) | ||
| 851 | goto fail; | ||
| 852 | if (s->handle_type != handle_type) { | ||
| 853 | av_log(ctx, AV_LOG_ERROR, "Error in child device handle setup: " | ||
| 854 | "type mismatch (%d != %d).\n", s->handle_type, handle_type); | ||
| 855 | err = AVERROR_UNKNOWN; | ||
| 856 | goto fail; | ||
| 857 | } | ||
| 858 | |||
| 859 | return 0; | ||
| 860 | |||
| 861 | fail: | ||
| 862 | if (hwctx->session) | ||
| 863 | MFXClose(hwctx->session); | ||
| 864 | return ret; | ||
| 865 | } | ||
| 866 | |||
| 867 | static int qsv_device_derive(AVHWDeviceContext *ctx, | ||
| 868 | AVHWDeviceContext *child_device_ctx, int flags) | ||
| 869 | { | ||
| 870 | return qsv_device_derive_from_child(ctx, MFX_IMPL_HARDWARE_ANY, | ||
| 871 | child_device_ctx, flags); | ||
| 872 | } | ||
| 873 | |||
| 874 | static int qsv_device_create(AVHWDeviceContext *ctx, const char *device, | ||
| 875 | AVDictionary *opts, int flags) | ||
| 876 | { | ||
| 877 | QSVDevicePriv *priv; | ||
| 878 | enum AVHWDeviceType child_device_type; | ||
| 879 | AVHWDeviceContext *child_device; | ||
| 880 | AVDictionaryEntry *e; | ||
| 881 | |||
| 882 | mfxIMPL impl; | ||
| 883 | int ret; | ||
| 884 | |||
| 810 | priv = av_mallocz(sizeof(*priv)); | 885 | priv = av_mallocz(sizeof(*priv)); |
| 811 | if (!priv) | 886 | if (!priv) |
| 812 | return AVERROR(ENOMEM); | 887 | return AVERROR(ENOMEM); |
| @@ -830,32 +905,11 @@ static int qsv_device_create(AVHWDeviceContext *ctx, const char *device, · 17 unmodified lines | |||
| 830 | if (ret < 0) | 905 | if (ret < 0) |
| 831 | return ret; | 906 | return ret; |
| 832 | 907 | ||
| 833 | { | 908 | child_device = (AVHWDeviceContext*)priv->child_device_ctx->data; |
| 834 | AVHWDeviceContext *child_device_ctx = (AVHWDeviceContext*)priv->child_device_ctx->data; | ||
| 835 | #if CONFIG_VAAPI | ||
| 836 | AVVAAPIDeviceContext *child_device_hwctx = child_device_ctx->hwctx; | ||
| 837 | handle_type = MFX_HANDLE_VA_DISPLAY; | ||
| 838 | handle = (mfxHDL)child_device_hwctx->display; | ||
| 839 | #elif CONFIG_DXVA2 | ||
| 840 | AVDXVA2DeviceContext *child_device_hwctx = child_device_ctx->hwctx; | ||
| 841 | handle_type = MFX_HANDLE_D3D9_DEVICE_MANAGER; | ||
| 842 | handle = (mfxHDL)child_device_hwctx->devmgr; | ||
| 843 | #endif | ||
| 844 | } | ||
| 845 | 909 | ||
| 846 | impl = choose_implementation(device); | 910 | impl = choose_implementation(device); |
| 847 | 911 | ||
| 848 | err = MFXInit(impl, &ver, &hwctx->session); | 912 | return qsv_device_derive_from_child(ctx, impl, child_device, 0); |
| 849 | if (err != MFX_ERR_NONE) { | ||
| 850 | av_log(ctx, AV_LOG_ERROR, "Error initializing an MFX session\n"); | ||
| 851 | return AVERROR_UNKNOWN; | ||
| 852 | } | ||
| 853 | |||
| 854 | err = MFXVideoCORE_SetHandle(hwctx->session, handle_type, handle); | ||
| 855 | if (err != MFX_ERR_NONE) | ||
| 856 | return AVERROR_UNKNOWN; | ||
| 857 | |||
| 858 | return 0; | ||
| 859 | } | 913 | } |
| 860 | 914 | ||
| 861 | const HWContextType ff_hwcontext_type_qsv = { | 915 | const HWContextType ff_hwcontext_type_qsv = { |
| @@ -868,6 +922,7 @@ const HWContextType ff_hwcontext_type_qsv = { · 6 unmodified lines | |||
| 868 | .frames_priv_size = sizeof(QSVFramesContext), | 922 | .frames_priv_size = sizeof(QSVFramesContext), |
| 869 | 923 | ||
| 870 | .device_create = qsv_device_create, | 924 | .device_create = qsv_device_create, |
| 925 | .device_derive = qsv_device_derive, | ||
| 871 | .device_init = qsv_device_init, | 926 | .device_init = qsv_device_init, |
| 872 | .frames_get_constraints = qsv_frames_get_constraints, | 927 | .frames_get_constraints = qsv_frames_get_constraints, |
| 873 | .frames_init = qsv_frames_init, | 928 | .frames_init = qsv_frames_init, |