diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c
index b9418b6791..7cdf17a972 100644
--- a/libavcodec/amfenc.c
+++ b/libavcodec/amfenc.c
@@ -24,6 +24,9 @@
 #if CONFIG_D3D11VA
 #include "libavutil/hwcontext_d3d11va.h"
 #endif
+#if CONFIG_DXVA2
+#include "libavutil/hwcontext_dxva2.h"
+#endif
 #include "libavutil/mem.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/time.h"
@@ -50,6 +53,9 @@ const enum AVPixelFormat ff_amf_pix_fmts[] = {
     AV_PIX_FMT_YUV420P,
 #if CONFIG_D3D11VA
     AV_PIX_FMT_D3D11,
+#endif
+#if CONFIG_DXVA2
+    AV_PIX_FMT_DXVA2_VLD,
 #endif
     AV_PIX_FMT_NONE
 };
@@ -68,7 +74,6 @@ static const FormatMap format_map[] =
     { AV_PIX_FMT_GRAY8,      AMF_SURFACE_GRAY8 },
     { AV_PIX_FMT_YUV420P,    AMF_SURFACE_YUV420P },
     { AV_PIX_FMT_YUYV422,    AMF_SURFACE_YUY2 },
-    { AV_PIX_FMT_D3D11,      AMF_SURFACE_NV12 },
 };
 
 
@@ -152,6 +157,26 @@ static int amf_load_library(AVCodecContext *avctx)
     return 0;
 }
 
+#if CONFIG_DXVA2
+static HRESULT get_dx9_device_from_devmgr(IDirect3DDeviceManager9 *devmgr, IDirect3DDevice9 **device, void *avcl)
+{
+    HRESULT hr;
+    HANDLE device_handle;
+
+    if (SUCCEEDED(hr = devmgr->lpVtbl->OpenDeviceHandle(devmgr, &device_handle))) {
+        if (SUCCEEDED(hr = devmgr->lpVtbl->LockDevice(devmgr, device_handle, device, FALSE))) {
+            devmgr->lpVtbl->UnlockDevice(devmgr, device_handle, FALSE);
+        } else {
+            av_log(avcl, AV_LOG_INFO, "Failed to lock device handle for Direct3D9 device: %lx.\n", (unsigned long)hr);
+        }
+        devmgr->lpVtbl->CloseDeviceHandle(devmgr, device_handle);
+    } else {
+        av_log(avcl, AV_LOG_INFO, "Failed to open device handle for Direct3D9 device: %lx.\n", (unsigned long)hr);
+    }
+    return hr;
+}
+#endif
+
 static int amf_init_context(AVCodecContext *avctx)
 {
     AmfContext         *ctx = avctx->priv_data;
@@ -177,34 +202,61 @@ static int amf_init_context(AVCodecContext *avctx)
     res = ctx->factory->pVtbl->CreateContext(ctx->factory, &ctx->context);
     AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "CreateContext() failed with error %d\n", res);
     // try to reuse existing DX device
-#if CONFIG_D3D11VA
     if (avctx->hw_frames_ctx) {
-        AVHWFramesContext *device_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
-        if (device_ctx->device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) {
-            if (amf_av_to_amf_format(device_ctx->sw_format) != AMF_SURFACE_UNKNOWN) {
-                if (device_ctx->device_ctx->hwctx) {
-                    AVD3D11VADeviceContext *device_d3d11 = (AVD3D11VADeviceContext *)device_ctx->device_ctx->hwctx;
+        AVHWFramesContext *frames_ctx = (AVHWFramesContext *)avctx->hw_frames_ctx->data;
+        if (amf_av_to_amf_format(frames_ctx->sw_format) != AMF_SURFACE_UNKNOWN) {
+            if (frames_ctx->device_ctx->hwctx) {
+#if CONFIG_D3D11VA
+                if (frames_ctx->device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) {
+                    AVD3D11VADeviceContext *device_d3d11 = (AVD3D11VADeviceContext *)frames_ctx->device_ctx->hwctx;
                     res = ctx->context->pVtbl->InitDX11(ctx->context, device_d3d11->device, AMF_DX11_1);
                     if (res == AMF_OK) {
                         ctx->hw_frames_ctx = av_buffer_ref(avctx->hw_frames_ctx);
                         if (!ctx->hw_frames_ctx) {
                             return AVERROR(ENOMEM);
                         }
-                        if (device_ctx->initial_pool_size > 0)
-                            ctx->hwsurfaces_in_queue_max = device_ctx->initial_pool_size - 1;
+                        if (frames_ctx->initial_pool_size > 0)
+                            ctx->hwsurfaces_in_queue_max = frames_ctx->initial_pool_size - 1;
                     } else {
-                        if(res == AMF_NOT_SUPPORTED)
-                            av_log(avctx, AV_LOG_INFO, "avctx->hw_frames_ctx has D3D11 device which doesn't have D3D11VA interface, switching to default\n");
+                        if (res == AMF_NOT_SUPPORTED)
+                            av_log(avctx, AV_LOG_INFO, "avctx->hw_frames_ctx has D3D11 device which doesn't have D3D11VA interface\n");
                         else
-                            av_log(avctx, AV_LOG_INFO, "avctx->hw_frames_ctx has non-AMD device, switching to default\n");
+                            av_log(avctx, AV_LOG_INFO, "avctx->hw_frames_ctx has non-AMD device\n");
+                        return AVERROR(ENODEV);
                     }
                 }
-            } else {
-                av_log(avctx, AV_LOG_INFO, "avctx->hw_frames_ctx has format not uspported by AMF, switching to default\n");
+#endif
+#if CONFIG_DXVA2
+                if (frames_ctx->device_ctx->type == AV_HWDEVICE_TYPE_DXVA2) {
+                    AVDXVA2DeviceContext *device_dxva2 = (AVDXVA2DeviceContext *)frames_ctx->device_ctx->hwctx;
+                    IDirect3DDevice9 *device_dx9 = NULL;
+                    if(SUCCEEDED(get_dx9_device_from_devmgr(device_dxva2->devmgr, &device_dx9, avctx))) {
+                        res = ctx->context->pVtbl->InitDX9(ctx->context, device_dx9);
+                        device_dx9->lpVtbl->Release(device_dx9);
+                        if (res == AMF_OK) {
+                            ctx->hw_frames_ctx = av_buffer_ref(avctx->hw_frames_ctx);
+                            if (!ctx->hw_frames_ctx) {
+                                return AVERROR(ENOMEM);
+                            }
+                            if (frames_ctx->initial_pool_size > 0)
+                                ctx->hwsurfaces_in_queue_max = frames_ctx->initial_pool_size - 1;
+                        } else {
+                            if (res == AMF_NOT_SUPPORTED)
+                                av_log(avctx, AV_LOG_INFO, "avctx->hw_frames_ctx has D3D device which doesn't have DXVA2 interface\n");
+                            else
+                                av_log(avctx, AV_LOG_INFO, "avctx->hw_frames_ctx has non-AMD device\n");
+                            return AVERROR(ENODEV);
+                        }
+                    }
+                }
+#endif
             }
+        } else {
+            av_log(avctx, AV_LOG_INFO, "avctx->hw_frames_ctx has format not uspported by AMF\n");
         }
     } else if (avctx->hw_device_ctx) {
-        AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)(avctx->hw_device_ctx->data);
+        AVHWDeviceContext *device_ctx = (AVHWDeviceContext *)(avctx->hw_device_ctx->data);
+#if CONFIG_D3D11VA
         if (device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) {
             if (device_ctx->hwctx) {
                 AVD3D11VADeviceContext *device_d3d11 = (AVD3D11VADeviceContext *)device_ctx->hwctx;
@@ -216,19 +268,42 @@ static int amf_init_context(AVCodecContext *avctx)
                     }
                 } else {
                     if (res == AMF_NOT_SUPPORTED)
-                        av_log(avctx, AV_LOG_INFO, "avctx->hw_device_ctx has D3D11 device which doesn't have D3D11VA interface, switching to default\n");
+                        av_log(avctx, AV_LOG_INFO, "avctx->hw_device_ctx has D3D11 device which doesn't have D3D11VA interface\n");
                     else
-                        av_log(avctx, AV_LOG_INFO, "avctx->hw_device_ctx has non-AMD device, switching to default\n");
+                        av_log(avctx, AV_LOG_INFO, "avctx->hw_device_ctx has non-AMD device\n");
+                    return AVERROR(ENODEV);
+                }
+            }
+        }
+#endif        
+#if CONFIG_DXVA2
+        if (device_ctx->type == AV_HWDEVICE_TYPE_DXVA2) {
+            AVDXVA2DeviceContext *device_dxva2 = (AVDXVA2DeviceContext *)device_ctx->hwctx;
+            IDirect3DDevice9 *device_dx9 = NULL;
+            if(SUCCEEDED(get_dx9_device_from_devmgr(device_dxva2->devmgr, &device_dx9, avctx))) {
+                res = ctx->context->pVtbl->InitDX9(ctx->context, device_dx9);
+                device_dx9->lpVtbl->Release(device_dx9);
+                if (res == AMF_OK) {
+                    ctx->hw_device_ctx = av_buffer_ref(avctx->hw_device_ctx);
+                    if (!ctx->hw_device_ctx) {
+                        return AVERROR(ENOMEM);
+                    }
+                } else {
+                    if (res == AMF_NOT_SUPPORTED)
+                        av_log(avctx, AV_LOG_INFO, "avctx->hw_device_ctx has D3D device which doesn't have DXVA2 interface\n");
+                    else
+                        av_log(avctx, AV_LOG_INFO, "avctx->hw_device_ctx has non-AMD device\n");
+                    return AVERROR(ENODEV);
                 }
             }
         }
-    }
 #endif
+    }
     if (!ctx->hw_frames_ctx && !ctx->hw_device_ctx) {
         res = ctx->context->pVtbl->InitDX11(ctx->context, NULL, AMF_DX11_1);
         if (res != AMF_OK) {
             res = ctx->context->pVtbl->InitDX9(ctx->context, NULL);
-            AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "InitDX9() failed with error %d\n", res);
+            AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR(ENODEV), "InitDX9() failed with error %d\n", res);
         }
     }
     return 0;
@@ -239,6 +314,7 @@ static int amf_init_encoder(AVCodecContext *avctx)
     AmfContext          *ctx = avctx->priv_data;
     const wchar_t       *codec_id = NULL;
     AMF_RESULT           res = AMF_OK;
+    enum AVPixelFormat   pix_fmt;
 
     switch (avctx->codec->id) {
         case AV_CODEC_ID_H264:
@@ -252,8 +328,13 @@ static int amf_init_encoder(AVCodecContext *avctx)
     }
     AMF_RETURN_IF_FALSE(ctx, codec_id != NULL, AVERROR(EINVAL), "Codec %d is not supported\n", avctx->codec->id);
 
-    ctx->format = amf_av_to_amf_format(avctx->pix_fmt);
-    AMF_RETURN_IF_FALSE(ctx, ctx->format != AMF_SURFACE_UNKNOWN, AVERROR(EINVAL), "Format %d is not supported\n", avctx->pix_fmt);
+    if(is_hwaccel_pix_fmt(avctx->pix_fmt)) {
+        pix_fmt = avctx->sw_pix_fmt;
+    } else {
+        pix_fmt = avctx->pix_fmt;
+    }
+    ctx->format = amf_av_to_amf_format(pix_fmt);
+    AMF_RETURN_IF_FALSE(ctx, ctx->format != AMF_SURFACE_UNKNOWN, AVERROR(EINVAL), "Format %d is not supported\n", pix_fmt);
 
     res = ctx->factory->pVtbl->CreateComponent(ctx->factory, ctx->context, codec_id, &ctx->encoder);
     AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_ENCODER_NOT_FOUND, "CreateComponent(%ls) failed with error %d\n", codec_id, res);
@@ -555,22 +636,35 @@ int ff_amf_send_frame(AVCodecContext *avctx, const AVFrame *frame)
             // check if the same hw_frames_ctx as used in initialization
             (ctx->hw_frames_ctx && frame->hw_frames_ctx->data == ctx->hw_frames_ctx->data) ||
             // check if the same hw_device_ctx as used in initialization
-            (ctx->hw_device_ctx && ((AVHWFramesContext*)frame->hw_frames_ctx->data)->device_ctx ==
-            (AVHWDeviceContext*)ctx->hw_device_ctx->data)
+            (ctx->hw_device_ctx && ((AVHWFramesContext *)frame->hw_frames_ctx->data)->device_ctx ==
+            (AVHWDeviceContext *)ctx->hw_device_ctx->data)
         )) {
             AMFBuffer *frame_ref_storage_buffer;
-
 #if CONFIG_D3D11VA
-            static const GUID AMFTextureArrayIndexGUID = { 0x28115527, 0xe7c3, 0x4b66, { 0x99, 0xd3, 0x4f, 0x2a, 0xe6, 0xb4, 0x7f, 0xaf } };
-            ID3D11Texture2D *texture = (ID3D11Texture2D*)frame->data[0]; // actual texture
-            int index = (int)(size_t)frame->data[1]; // index is a slice in texture array is - set to tell AMF which slice to use
-            texture->lpVtbl->SetPrivateData(texture, &AMFTextureArrayIndexGUID, sizeof(index), &index);
+            if (((AVHWFramesContext *)frame->hw_frames_ctx->data)->device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) {
+                static const GUID AMFTextureArrayIndexGUID = { 0x28115527, 0xe7c3, 0x4b66, { 0x99, 0xd3, 0x4f, 0x2a, 0xe6, 0xb4, 0x7f, 0xaf } };
+
+                ID3D11Texture2D *texture = (ID3D11Texture2D *)frame->data[0]; // actual texture
+                int index = (int)(size_t)frame->data[1]; // index is a slice in texture array is - set to tell AMF which slice to use
+                texture->lpVtbl->SetPrivateData(texture, &AMFTextureArrayIndexGUID, sizeof(index), &index);
 
-            res = ctx->context->pVtbl->CreateSurfaceFromDX11Native(ctx->context, texture, &surface, NULL); // wrap to AMF surface
-            AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR(ENOMEM), "CreateSurfaceFromDX11Native() failed  with error %d\n", res);
+                res = ctx->context->pVtbl->CreateSurfaceFromDX11Native(ctx->context, texture, &surface, NULL); // wrap to AMF surface
+                AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR(ENOMEM), "CreateSurfaceFromDX11Native() failed  with error %d\n", res);
 
-            // input HW surfaces can be vertically aligned by 16; tell AMF the real size
-            surface->pVtbl->SetCrop(surface, 0, 0, frame->width, frame->height);
+                // input HW surfaces can be vertically aligned by 16; tell AMF the real size
+                surface->pVtbl->SetCrop(surface, 0, 0, frame->width, frame->height);
+            }
+#endif
+#if CONFIG_DXVA2
+            if (((AVHWFramesContext *)frame->hw_frames_ctx->data)->device_ctx->type == AV_HWDEVICE_TYPE_DXVA2) {
+                IDirect3DSurface9 *texture = (IDirect3DSurface9 *)frame->data[3]; // actual texture
+
+                res = ctx->context->pVtbl->CreateSurfaceFromDX9Native(ctx->context, texture, &surface, NULL); // wrap to AMF surface
+                AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR(ENOMEM), "CreateSurfaceFromDX9Native() failed  with error %d\n", res);
+
+                // input HW surfaces can be vertically aligned by 16; tell AMF the real size
+                surface->pVtbl->SetCrop(surface, 0, 0, frame->width, frame->height);
+            }
 #endif
 
             frame_ref_storage_buffer = amf_create_buffer_with_frame_ref(frame, ctx->context);
