diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c
index db98c75073..df622d9c7d 100644
--- a/libavcodec/qsv.c
+++ b/libavcodec/qsv.c
@@ -362,7 +362,11 @@ static int ff_qsv_set_display_handle(AVCodecContext *avctx, QSVSession *qs)
 int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs,
                                  const char *load_plugins, int gpu_copy)
 {
+#ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE
     mfxIMPL          impl = MFX_IMPL_AUTO_ANY;
+#else
+    mfxIMPL          impl = MFX_IMPL_AUTO_ANY | MFX_IMPL_VIA_D3D11;
+#endif
     mfxVersion        ver = { { QSV_VERSION_MINOR, QSV_VERSION_MAJOR } };
     mfxInitParam init_par = { MFX_IMPL_AUTO_ANY };
 
@@ -452,6 +456,7 @@ static AVBufferRef *qsv_create_mids(AVBufferRef *hw_frames_ref)
     for (i = 0; i < nb_surfaces; i++) {
         QSVMid *mid = &mids[i];
         mid->handle        = frames_hwctx->surfaces[i].Data.MemId;
+        mid->texture       = frames_hwctx->texture;
         mid->hw_frames_ref = hw_frames_ref1;
     }
 
@@ -661,7 +666,13 @@ static mfxStatus qsv_frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
 static mfxStatus qsv_frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl)
 {
     QSVMid *qsv_mid = (QSVMid*)mid;
-    *hdl = qsv_mid->handle;
+    if (qsv_mid->texture) {
+        mfxHDLPair *pair  =  (mfxHDLPair*)hdl;
+        pair->first  = qsv_mid->texture;
+        pair->second = qsv_mid->handle;
+    } else {
+        *hdl = qsv_mid->handle;
+    }
     return MFX_ERR_NONE;
 }
 
@@ -669,14 +680,10 @@ int ff_qsv_init_session_device(AVCodecContext *avctx, mfxSession *psession,
                                AVBufferRef *device_ref, const char *load_plugins,
                                int gpu_copy)
 {
-    static const mfxHandleType handle_types[] = {
-        MFX_HANDLE_VA_DISPLAY,
-        MFX_HANDLE_D3D9_DEVICE_MANAGER,
-        MFX_HANDLE_D3D11_DEVICE,
-    };
     AVHWDeviceContext    *device_ctx = (AVHWDeviceContext*)device_ref->data;
     AVQSVDeviceContext *device_hwctx = device_ctx->hwctx;
     mfxSession        parent_session = device_hwctx->session;
+    mfxHandleType parent_handle_type = device_hwctx->handle_type;
     mfxInitParam            init_par = { MFX_IMPL_AUTO_ANY };
     mfxHDL                    handle = NULL;
 
@@ -686,7 +693,7 @@ int ff_qsv_init_session_device(AVCodecContext *avctx, mfxSession *psession,
     mfxHandleType handle_type;
     mfxStatus err;
 
-    int i, ret;
+    int ret;
 
     err = MFXQueryIMPL(parent_session, &impl);
     if (err == MFX_ERR_NONE)
@@ -695,17 +702,12 @@ int ff_qsv_init_session_device(AVCodecContext *avctx, mfxSession *psession,
         return ff_qsv_print_error(avctx, err,
                                   "Error querying the session attributes");
 
-    for (i = 0; i < FF_ARRAY_ELEMS(handle_types); i++) {
-        err = MFXVideoCORE_GetHandle(parent_session, handle_types[i], &handle);
-        if (err == MFX_ERR_NONE) {
-            handle_type = handle_types[i];
-            break;
-        }
-        handle = NULL;
-    }
-    if (!handle) {
-        av_log(avctx, AV_LOG_VERBOSE, "No supported hw handle could be retrieved "
-               "from the session\n");
+    err = MFXVideoCORE_GetHandle(parent_session, parent_handle_type, &handle);
+    if (err == MFX_ERR_NONE) {
+        handle_type = parent_handle_type;
+    } else {
+        return ff_qsv_print_error(avctx, err,
+            "Error no supported hw handle could be retrieved from the session");
     }
 
 #if QSV_VERSION_ATLEAST(1, 16)
diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h
index 6489836a67..c985f227ec 100644
--- a/libavcodec/qsv_internal.h
+++ b/libavcodec/qsv_internal.h
@@ -65,6 +65,11 @@ typedef struct QSVMid {
     AVFrame *locked_frame;
     AVFrame *hw_frame;
     mfxFrameSurface1 surf;
+    /**
+     * ID3D11Texture2D texture in which the frame is located for D3D11VA device. 
+     * Null in case of DXVA2 device.
+     */
+    void *texture;
 } QSVMid;
 
 typedef struct QSVFrame {
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 6cf333eeb6..2fba26e8d0 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -28,7 +28,7 @@
 #include "libavutil/version.h"
 
 #define LIBAVCODEC_VERSION_MAJOR  58
-#define LIBAVCODEC_VERSION_MINOR  66
+#define LIBAVCODEC_VERSION_MINOR  67
 #define LIBAVCODEC_VERSION_MICRO 100
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c
index 8d5ff2eb65..298c10718e 100644
--- a/libavfilter/qsvvpp.c
+++ b/libavfilter/qsvvpp.c
@@ -68,12 +68,6 @@ struct QSVVPPContext {
     int                 nb_ext_buffers;
 };
 
-static const mfxHandleType handle_types[] = {
-    MFX_HANDLE_VA_DISPLAY,
-    MFX_HANDLE_D3D9_DEVICE_MANAGER,
-    MFX_HANDLE_D3D11_DEVICE,
-};
-
 static const AVRational default_tb = { 1, 90000 };
 
 /* functions for frameAlloc */
@@ -497,15 +491,10 @@ static int init_vpp_session(AVFilterContext *avctx, QSVVPPContext *s)
         return AVERROR_UNKNOWN;
     }
 
-    for (i = 0; i < FF_ARRAY_ELEMS(handle_types); i++) {
-        ret = MFXVideoCORE_GetHandle(device_hwctx->session, handle_types[i], &handle);
-        if (ret == MFX_ERR_NONE) {
-            handle_type = handle_types[i];
-            break;
-        }
-    }
-
-    if (ret != MFX_ERR_NONE) {
+    ret = MFXVideoCORE_GetHandle(device_hwctx->session, device_hwctx->handle_type, &handle);
+    if (ret == MFX_ERR_NONE) {
+        handle_type = device_hwctx->handle_type;
+    } else {
         av_log(avctx, AV_LOG_ERROR, "Error getting the session handle\n");
         return AVERROR_UNKNOWN;
     }
diff --git a/libavutil/hwcontext_d3d11va.c b/libavutil/hwcontext_d3d11va.c
index 6670c47579..a08479fd96 100644
--- a/libavutil/hwcontext_d3d11va.c
+++ b/libavutil/hwcontext_d3d11va.c
@@ -244,7 +244,7 @@ static int d3d11va_frames_init(AVHWFramesContext *ctx)
         return AVERROR(EINVAL);
     }
 
-    texDesc = (D3D11_TEXTURE2D_DESC){
+    texDesc = (D3D11_TEXTURE2D_DESC) {
         .Width      = ctx->width,
         .Height     = ctx->height,
         .MipLevels  = 1,
@@ -510,6 +510,46 @@ static void d3d11va_device_uninit(AVHWDeviceContext *hwdev)
     }
 }
 
+static int d3d11va_device_find_qsv_adapter(AVHWDeviceContext *ctx, UINT creationFlags)
+{
+    HRESULT hr;
+    IDXGIAdapter *adapter = NULL;
+    int adapter_id = 0;
+    int vendor_id = 0x8086;
+    IDXGIFactory2 *factory;
+    hr = mCreateDXGIFactory(&IID_IDXGIFactory2, (void **)&factory);
+    while (IDXGIFactory2_EnumAdapters(factory, adapter_id++, &adapter) != DXGI_ERROR_NOT_FOUND)
+    {
+        ID3D11Device* device = NULL;
+        DXGI_ADAPTER_DESC adapter_desc;
+
+        hr = mD3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, creationFlags, NULL, 0, D3D11_SDK_VERSION, &device, NULL, NULL);
+        if (FAILED(hr)) {
+            av_log(ctx, AV_LOG_ERROR, "D3D11CreateDevice returned error\n");
+            continue;
+        }
+
+        hr = IDXGIAdapter2_GetDesc(adapter, &adapter_desc);
+        if (FAILED(hr)) {
+            av_log(ctx, AV_LOG_ERROR, "IDXGIAdapter2_GetDesc returned error\n");
+            continue;
+        }
+
+        if(device)
+            ID3D11Device_Release(device);
+
+        if (adapter)
+            IDXGIAdapter_Release(adapter);
+
+        if (adapter_desc.VendorId == vendor_id) {
+            IDXGIFactory2_Release(factory);
+            return adapter_id - 1;
+        }
+    }
+    IDXGIFactory2_Release(factory);
+    return -1;
+}
+
 static int d3d11va_device_create(AVHWDeviceContext *ctx, const char *device,
                                  AVDictionary *opts, int flags)
 {
@@ -519,7 +559,9 @@ static int d3d11va_device_create(AVHWDeviceContext *ctx, const char *device,
     IDXGIAdapter           *pAdapter = NULL;
     ID3D10Multithread      *pMultithread;
     UINT creationFlags = D3D11_CREATE_DEVICE_VIDEO_SUPPORT;
+    int adapter = -1;
     int is_debug       = !!av_dict_get(opts, "debug", NULL, 0);
+    int is_qsv         = !!av_dict_get(opts, "d3d11va_qsv", NULL, 0);
     int ret;
 
     // (On UWP we can't check this.)
@@ -538,11 +580,22 @@ static int d3d11va_device_create(AVHWDeviceContext *ctx, const char *device,
         return AVERROR_UNKNOWN;
     }
 
+    if (is_qsv) {
+        adapter = d3d11va_device_find_qsv_adapter(ctx, creationFlags);
+        if (adapter < 0) {
+            av_log(ctx, AV_LOG_ERROR, "Failed to find DX11 adapter with QSV support\n");
+            return AVERROR_UNKNOWN;
+        }
+    }
+
     if (device) {
+        adapter = atoi(device);
+    }
+
+    if (adapter >= 0) {
         IDXGIFactory2 *pDXGIFactory;
         hr = mCreateDXGIFactory(&IID_IDXGIFactory2, (void **)&pDXGIFactory);
         if (SUCCEEDED(hr)) {
-            int adapter = atoi(device);
             if (FAILED(IDXGIFactory2_EnumAdapters(pDXGIFactory, adapter, &pAdapter)))
                 pAdapter = NULL;
             IDXGIFactory2_Release(pDXGIFactory);
diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c
index b1b67400de..05b2ed3333 100644
--- a/libavutil/hwcontext_qsv.c
+++ b/libavutil/hwcontext_qsv.c
@@ -27,9 +27,13 @@
 #include <pthread.h>
 #endif
 
+#define COBJMACROS
 #if CONFIG_VAAPI
 #include "hwcontext_vaapi.h"
 #endif
+#if CONFIG_D3D11VA
+#include "hwcontext_d3d11va.h"
+#endif
 #if CONFIG_DXVA2
 #include "hwcontext_dxva2.h"
 #endif
@@ -89,6 +93,9 @@ static const struct {
 #if CONFIG_VAAPI
     { MFX_HANDLE_VA_DISPLAY,          AV_HWDEVICE_TYPE_VAAPI, AV_PIX_FMT_VAAPI },
 #endif
+#if CONFIG_D3D11VA
+    { MFX_HANDLE_D3D11_DEVICE, AV_HWDEVICE_TYPE_D3D11VA, AV_PIX_FMT_D3D11 },
+#endif
 #if CONFIG_DXVA2
     { MFX_HANDLE_D3D9_DEVICE_MANAGER, AV_HWDEVICE_TYPE_DXVA2, AV_PIX_FMT_DXVA2_VLD },
 #endif
@@ -124,18 +131,21 @@ static int qsv_device_init(AVHWDeviceContext *ctx)
     int i;
 
     for (i = 0; supported_handle_types[i].handle_type; i++) {
-        err = MFXVideoCORE_GetHandle(hwctx->session, supported_handle_types[i].handle_type,
-                                     &s->handle);
-        if (err == MFX_ERR_NONE) {
-            s->handle_type       = supported_handle_types[i].handle_type;
-            s->child_device_type = supported_handle_types[i].device_type;
-            s->child_pix_fmt     = supported_handle_types[i].pix_fmt;
-            break;
+        if (supported_handle_types[i].handle_type == hwctx->handle_type) {
+            err = MFXVideoCORE_GetHandle(hwctx->session, supported_handle_types[i].handle_type,
+                                        &s->handle);
+            if (err == MFX_ERR_NONE) {
+                s->handle_type       = supported_handle_types[i].handle_type;
+                s->child_device_type = supported_handle_types[i].device_type;
+                s->child_pix_fmt     = supported_handle_types[i].pix_fmt;
+                break;
+            }
         }
     }
     if (!s->handle) {
         av_log(ctx, AV_LOG_VERBOSE, "No supported hw handle could be retrieved "
                "from the session\n");
+        return AVERROR_UNKNOWN;
     }
 
     err = MFXQueryIMPL(hwctx->session, &s->impl);
@@ -229,9 +239,17 @@ static int qsv_init_child_ctx(AVHWFramesContext *ctx)
         child_device_hwctx->display = (VADisplay)device_priv->handle;
     }
 #endif
+#if CONFIG_D3D11VA
+    if (child_device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) {
+        AVD3D11VADeviceContext *child_device_hwctx = child_device_ctx->hwctx;
+        ID3D11Device_AddRef((ID3D11Device*)device_priv->handle);
+        child_device_hwctx->device = (ID3D11Device*)device_priv->handle;
+    }
+#endif
 #if CONFIG_DXVA2
     if (child_device_ctx->type == AV_HWDEVICE_TYPE_DXVA2) {
         AVDXVA2DeviceContext *child_device_hwctx = child_device_ctx->hwctx;
+        IDirect3DDeviceManager9_AddRef((IDirect3DDeviceManager9*)device_priv->handle);
         child_device_hwctx->devmgr = (IDirect3DDeviceManager9*)device_priv->handle;
     }
 #endif
@@ -255,6 +273,16 @@ static int qsv_init_child_ctx(AVHWFramesContext *ctx)
     child_frames_ctx->width             = FFALIGN(ctx->width, 16);
     child_frames_ctx->height            = FFALIGN(ctx->height, 16);
 
+#if CONFIG_D3D11VA
+    if (child_device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) {
+        AVD3D11VAFramesContext *child_frames_hwctx = child_frames_ctx->hwctx;
+        child_frames_hwctx->MiscFlags |= D3D11_RESOURCE_MISC_SHARED;
+        if (hwctx->frame_type & MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET)
+            child_frames_hwctx->BindFlags = D3D11_BIND_RENDER_TARGET ;
+        else
+            child_frames_hwctx->BindFlags = D3D11_BIND_DECODER;
+    }
+#endif
 #if CONFIG_DXVA2
     if (child_device_ctx->type == AV_HWDEVICE_TYPE_DXVA2) {
         AVDXVA2FramesContext *child_frames_hwctx = child_frames_ctx->hwctx;
@@ -279,6 +307,18 @@ static int qsv_init_child_ctx(AVHWFramesContext *ctx)
         hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
     }
 #endif
+#if CONFIG_D3D11VA
+    if (child_device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) {
+        AVD3D11VAFramesContext *child_frames_hwctx = child_frames_ctx->hwctx;
+        hwctx->texture = child_frames_hwctx->texture;
+        for (i = 0; i < ctx->initial_pool_size; i++)
+            s->surfaces_internal[i].Data.MemId = (mfxMemId)(int64_t)i;
+        if (child_frames_hwctx->BindFlags == D3D11_BIND_DECODER)
+            hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
+        else
+            hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET;
+    }
+#endif
 #if CONFIG_DXVA2
     if (child_device_ctx->type == AV_HWDEVICE_TYPE_DXVA2) {
         AVDXVA2FramesContext *child_frames_hwctx = child_frames_ctx->hwctx;
@@ -421,7 +461,16 @@ static mfxStatus frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
 
 static mfxStatus frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl)
 {
-    *hdl = mid;
+    AVHWFramesContext    *ctx = pthis;
+    AVQSVFramesContext *hwctx = ctx->hwctx;
+
+    if (hwctx->texture) {
+        mfxHDLPair *pair  =  (mfxHDLPair*)hdl;
+        pair->first  = hwctx->texture;
+        pair->second = mid;
+    } else {
+        *hdl = mid;
+    }
     return MFX_ERR_NONE;
 }
 
@@ -492,7 +541,7 @@ static int qsv_init_internal_session(AVHWFramesContext *ctx,
 
     err = MFXVideoVPP_Init(*session, &par);
     if (err != MFX_ERR_NONE) {
-        av_log(ctx, AV_LOG_VERBOSE, "Error opening the internal VPP session."
+        av_log(ctx, AV_LOG_ERROR, "Error opening the internal VPP session."
                "Surface upload/download will not be possible\n");
         MFXClose(*session);
         *session = NULL;
@@ -668,6 +717,11 @@ static int qsv_map_from(AVHWFramesContext *ctx,
         child_data = (uint8_t*)(intptr_t)*(VASurfaceID*)surf->Data.MemId;
         break;
 #endif
+#if CONFIG_D3D11VA
+    case AV_HWDEVICE_TYPE_D3D11VA:
+        child_data = surf->Data.MemId;
+        break;
+#endif
 #if CONFIG_DXVA2
     case AV_HWDEVICE_TYPE_DXVA2:
         child_data = surf->Data.MemId;
@@ -972,6 +1026,27 @@ static int qsv_frames_derive_to(AVHWFramesContext *dst_ctx,
         }
         break;
 #endif
+#if CONFIG_D3D11VA
+    case AV_HWDEVICE_TYPE_D3D11VA:
+        {
+            AVD3D11VAFramesContext *src_hwctx = src_ctx->hwctx;
+            s->surfaces_internal = av_mallocz_array(src_ctx->initial_pool_size,
+                                                    sizeof(*s->surfaces_internal));
+            if (!s->surfaces_internal)
+                return AVERROR(ENOMEM);
+            dst_hwctx->texture = src_hwctx->texture;
+            for (i = 0; i < src_ctx->initial_pool_size; i++) {
+                qsv_init_surface(dst_ctx, &s->surfaces_internal[i]);
+                s->surfaces_internal[i].Data.MemId = (mfxMemId)(int64_t)i;
+            }
+            dst_hwctx->nb_surfaces = src_ctx->initial_pool_size;
+            if (src_hwctx->BindFlags == D3D11_BIND_DECODER)
+                dst_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
+            else
+                dst_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET;
+        }
+        break;
+#endif
 #if CONFIG_DXVA2
     case AV_HWDEVICE_TYPE_DXVA2:
         {
@@ -1004,19 +1079,37 @@ static int qsv_frames_derive_to(AVHWFramesContext *dst_ctx,
 static int qsv_map_to(AVHWFramesContext *dst_ctx,
                       AVFrame *dst, const AVFrame *src, int flags)
 {
-    AVQSVFramesContext *hwctx = dst_ctx->hwctx;
+    AVHWFramesContext *src_frames;
     int i, err;
+    enum AVHWDeviceType type = AV_HWDEVICE_TYPE_NONE;
+    AVQSVFramesContext *hwctx = dst_ctx->hwctx;
+    if (src->hw_frames_ctx) {
+        src_frames = (AVHWFramesContext*)src->hw_frames_ctx->data;
+        type = src_frames->internal->hw_type->type;
+    }
 
     for (i = 0; i < hwctx->nb_surfaces; i++) {
 #if CONFIG_VAAPI
-        if (*(VASurfaceID*)hwctx->surfaces[i].Data.MemId ==
-            (VASurfaceID)(uintptr_t)src->data[3])
-            break;
+        if (AV_HWDEVICE_TYPE_VAAPI == type) {
+            if (*(VASurfaceID*)hwctx->surfaces[i].Data.MemId ==
+                (VASurfaceID)(uintptr_t)src->data[3])
+                break;
+        }
+#endif
+#if CONFIG_D3D11VA
+        if (AV_HWDEVICE_TYPE_D3D11VA == type) {
+            if ((hwctx->texture == (ID3D11Texture2D*)(uintptr_t)src->data[0]) &&
+                ((ID3D11Texture2D*)hwctx->surfaces[i].Data.MemId ==
+                (ID3D11Texture2D*)(uintptr_t)src->data[1]))
+                break;
+        }
 #endif
 #if CONFIG_DXVA2
-        if ((IDirect3DSurface9*)hwctx->surfaces[i].Data.MemId ==
-            (IDirect3DSurface9*)(uintptr_t)src->data[3])
-            break;
+        if (AV_HWDEVICE_TYPE_DXVA2 == type) {
+            if ((IDirect3DSurface9*)hwctx->surfaces[i].Data.MemId ==
+                (IDirect3DSurface9*)(uintptr_t)src->data[3])
+                break;
+        }
 #endif
     }
     if (i >= hwctx->nb_surfaces) {
@@ -1074,7 +1167,7 @@ static void qsv_device_free(AVHWDeviceContext *ctx)
     av_freep(&priv);
 }
 
-static mfxIMPL choose_implementation(const char *device)
+static mfxIMPL choose_implementation(const char *device, enum AVHWDeviceType child_device_type)
 {
     static const struct {
         const char *name;
@@ -1103,6 +1196,10 @@ static mfxIMPL choose_implementation(const char *device)
             impl = strtol(device, NULL, 0);
     }
 
+    if ( (child_device_type == AV_HWDEVICE_TYPE_D3D11VA) && (impl != MFX_IMPL_SOFTWARE) ) {
+        impl |= MFX_IMPL_VIA_D3D11;
+    }
+
     return impl;
 }
 
@@ -1129,6 +1226,15 @@ static int qsv_device_derive_from_child(AVHWDeviceContext *ctx,
         }
         break;
 #endif
+#if CONFIG_D3D11VA
+    case AV_HWDEVICE_TYPE_D3D11VA:
+        {
+            AVD3D11VADeviceContext *child_device_hwctx = child_device_ctx->hwctx;
+            handle_type = MFX_HANDLE_D3D11_DEVICE;
+            handle = (mfxHDL)child_device_hwctx->device;
+        }
+        break;
+#endif
 #if CONFIG_DXVA2
     case AV_HWDEVICE_TYPE_DXVA2:
         {
@@ -1180,6 +1286,7 @@ static int qsv_device_derive_from_child(AVHWDeviceContext *ctx,
         goto fail;
     }
 
+    hwctx->handle_type = handle_type;
     return 0;
 
 fail:
@@ -1191,7 +1298,9 @@ fail:
 static int qsv_device_derive(AVHWDeviceContext *ctx,
                              AVHWDeviceContext *child_device_ctx, int flags)
 {
-    return qsv_device_derive_from_child(ctx, MFX_IMPL_HARDWARE_ANY,
+    mfxIMPL impl;
+    impl = choose_implementation("hw_any", child_device_ctx->type);
+    return qsv_device_derive_from_child(ctx, impl,
                                         child_device_ctx, flags);
 }
 
@@ -1226,23 +1335,35 @@ static int qsv_device_create(AVHWDeviceContext *ctx, const char *device,
         // possible, even when multiple devices and drivers are available.
         av_dict_set(&child_device_opts, "kernel_driver", "i915", 0);
         av_dict_set(&child_device_opts, "driver",        "iHD",  0);
-    } else if (CONFIG_DXVA2)
+    } else if (CONFIG_D3D11VA) {
+        child_device_type = AV_HWDEVICE_TYPE_D3D11VA;
+        av_dict_set(&child_device_opts, "d3d11va_qsv",   "enabled",  0);
+    } else if (CONFIG_DXVA2) {
         child_device_type = AV_HWDEVICE_TYPE_DXVA2;
-    else {
+    } else {
         av_log(ctx, AV_LOG_ERROR, "No supported child device type is enabled\n");
         return AVERROR(ENOSYS);
     }
 
     ret = av_hwdevice_ctx_create(&priv->child_device_ctx, child_device_type,
                                  e ? e->value : NULL, child_device_opts, 0);
-
     av_dict_free(&child_device_opts);
-    if (ret < 0)
-        return ret;
+    if (ret < 0) {
+        if (CONFIG_DXVA2 && (child_device_type == AV_HWDEVICE_TYPE_D3D11VA)) {
+            // in case of d3d11va fail, try one more chance to create device via dxva2
+            child_device_type = AV_HWDEVICE_TYPE_DXVA2;
+            child_device_opts = NULL;
+            ret = av_hwdevice_ctx_create(&priv->child_device_ctx, child_device_type,
+                            e ? e->value : NULL, child_device_opts, 0);
+        }
+        if (ret < 0) {
+            return ret;
+        }
+    }
 
     child_device = (AVHWDeviceContext*)priv->child_device_ctx->data;
 
-    impl = choose_implementation(device);
+    impl = choose_implementation(device, child_device_type);
 
     return qsv_device_derive_from_child(ctx, impl, child_device, 0);
 }
diff --git a/libavutil/hwcontext_qsv.h b/libavutil/hwcontext_qsv.h
index b98d611cfc..3a322037e5 100644
--- a/libavutil/hwcontext_qsv.h
+++ b/libavutil/hwcontext_qsv.h
@@ -34,6 +34,15 @@
  */
 typedef struct AVQSVDeviceContext {
     mfxSession session;
+    /**
+     * Need to store actual handle type that session uses
+     * MFXVideoCORE_GetHandle() function returns mfxHandleType
+     * always equal to MFX_HANDLE_D3D9_DEVICE_MANAGER
+     * even when MFX_HANDLE_D3D11_DEVICE was set as handle before by
+     * MFXVideoCORE_SetHandle() to mfx session.
+     * Fixed already but will be available only with latest driver.
+     */
+    mfxHandleType handle_type;
 } AVQSVDeviceContext;
 
 /**
@@ -42,11 +51,11 @@ typedef struct AVQSVDeviceContext {
 typedef struct AVQSVFramesContext {
     mfxFrameSurface1 *surfaces;
     int            nb_surfaces;
-
     /**
      * A combination of MFX_MEMTYPE_* describing the frame pool.
      */
-    int frame_type;
+    int             frame_type;
+    void              *texture;
 } AVQSVFramesContext;
 
 #endif /* AVUTIL_HWCONTEXT_QSV_H */
diff --git a/libavutil/version.h b/libavutil/version.h
index af8f614aff..2bc1b98615 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -79,7 +79,7 @@
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  56
-#define LIBAVUTIL_VERSION_MINOR  38
+#define LIBAVUTIL_VERSION_MINOR  39
 #define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
