(cherry picked from commit aa51bb3d2756ed912ee40645efccf5f4a9609696)
Unified · Split
| @@ -792,21 +792,96 @@ static mfxIMPL choose_implementation(const char *device) · 791 unmodified lines | ||
| 792 | 792 | return impl; |
| 793 | 793 | } |
| 794 | 794 | |
| 795 | −static int qsv_device_create(AVHWDeviceContext *ctx, const char *device, | |
| 796 | − AVDictionary *opts, int flags) | |
| 795 | +static int qsv_device_derive_from_child(AVHWDeviceContext *ctx, | |
| 796 | + mfxIMPL implementation, | |
| 797 | + AVHWDeviceContext *child_device_ctx, | |
| 798 | + int flags) | |
| 797 | 799 | { |
| 798 | 800 | AVQSVDeviceContext *hwctx = ctx->hwctx; |
| 799 | − QSVDevicePriv *priv; | |
| 800 | − enum AVHWDeviceType child_device_type; | |
| 801 | − AVDictionaryEntry *e; | |
| 801 | + QSVDeviceContext *s = ctx->internal->priv; | |
| 802 | 802 | |
| 803 | 803 | mfxVersion ver = { { 3, 1 } }; |
| 804 | − mfxIMPL impl; | |
| 805 | 804 | mfxHDL handle; |
| 806 | 805 | mfxHandleType handle_type; |
| 807 | 806 | mfxStatus err; |
| 808 | 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 | 885 | priv = av_mallocz(sizeof(*priv)); |
| 811 | 886 | if (!priv) |
| 812 | 887 | return AVERROR(ENOMEM); |
| @@ -830,32 +905,11 @@ static int qsv_device_create(AVHWDeviceContext *ctx, const char *device, · 17 unmodified lines | ||
| 830 | 905 | if (ret < 0) |
| 831 | 906 | return ret; |
| 832 | 907 | |
| 833 | − { | |
| 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 | − } | |
| 908 | + child_device = (AVHWDeviceContext*)priv->child_device_ctx->data; | |
| 845 | 909 | |
| 846 | 910 | impl = choose_implementation(device); |
| 847 | 911 | |
| 848 | − err = MFXInit(impl, &ver, &hwctx->session); | |
| 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; | |
| 912 | + return qsv_device_derive_from_child(ctx, impl, child_device, 0); | |
| 859 | 913 | } |
| 860 | 914 | |
| 861 | 915 | const HWContextType ff_hwcontext_type_qsv = { |
| @@ -868,6 +922,7 @@ const HWContextType ff_hwcontext_type_qsv = { · 6 unmodified lines | ||
| 868 | 922 | .frames_priv_size = sizeof(QSVFramesContext), |
| 869 | 923 | |
| 870 | 924 | .device_create = qsv_device_create, |
| 925 | + .device_derive = qsv_device_derive, | |
| 871 | 926 | .device_init = qsv_device_init, |
| 872 | 927 | .frames_get_constraints = qsv_frames_get_constraints, |
| 873 | 928 | .frames_init = qsv_frames_init, |