diff mbox series

[FFmpeg-devel,v3,2/2] dxva: add a ID3D11DeviceContext to the old D3D11VA API

Message ID 20200805100712.16834-2-robux4@ycbcr.xyz
State New
Headers show
Series [FFmpeg-devel,v3,1/2] dxva: wait until D3D11 buffer copies are done before submitting them
Related show

Checks

Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

Steve Lhomme Aug. 5, 2020, 10:07 a.m. UTC
This way it's possible to use the wait_copy feature with the old API as well.

If it's NULL, wait_copies remains NULL and is not used.
---
 doc/APIchanges       |  3 +++
 libavcodec/d3d11va.h |  6 ++++++
 libavcodec/dxva2.c   | 38 +++++++++++++++++++++++++++++++-------
 libavcodec/version.h |  2 +-
 4 files changed, 41 insertions(+), 8 deletions(-)

Comments

Steve Lhomme Aug. 5, 2020, 10:10 a.m. UTC | #1
v3 with support for the old API as well.

On 2020-08-05 12:07, Steve Lhomme wrote:
> This way it's possible to use the wait_copy feature with the old API as well.
> 
> If it's NULL, wait_copies remains NULL and is not used.
> ---
>   doc/APIchanges       |  3 +++
>   libavcodec/d3d11va.h |  6 ++++++
>   libavcodec/dxva2.c   | 38 +++++++++++++++++++++++++++++++-------
>   libavcodec/version.h |  2 +-
>   4 files changed, 41 insertions(+), 8 deletions(-)
> 
> diff --git a/doc/APIchanges b/doc/APIchanges
> index a9bf1afd4c..11a10ddb16 100644
> --- a/doc/APIchanges
> +++ b/doc/APIchanges
> @@ -15,6 +15,9 @@ libavutil:     2017-10-21
>   
>   API changes, most recent first:
>   
> +2020-08-05 - xxxxxxxxxx - lavu 56.100.100 - d3d11va.h
> +  Add a ID3D11VideoContext to AVD3D11VAContext matching the ID3D11VideoContext.
> +
>   2020-08-04 - xxxxxxxxxx - lavu 56.58.100 - channel_layout.h
>     Add AV_CH_LAYOUT_22POINT2 together with its newly required pieces:
>     AV_CH_TOP_SIDE_LEFT, AV_CH_TOP_SIDE_RIGHT, AV_CH_BOTTOM_FRONT_CENTER,
> diff --git a/libavcodec/d3d11va.h b/libavcodec/d3d11va.h
> index 6816b6c1e6..134dee388c 100644
> --- a/libavcodec/d3d11va.h
> +++ b/libavcodec/d3d11va.h
> @@ -96,6 +96,12 @@ typedef struct AVD3D11VAContext {
>         * Mutex to access video_context
>         */
>       HANDLE  context_mutex;
> +
> +    /**
> +      * Device Context on which to send the D3D11VA commands.
> +      * It should be the same used to get the ID3D11VideoDecoder or NULL.
> +      */
> +    ID3D11DeviceContext *device_context;
>   } AVD3D11VAContext;
>   
>   /**
> diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c
> index 1a0e5b69b2..fd4685305e 100644
> --- a/libavcodec/dxva2.c
> +++ b/libavcodec/dxva2.c
> @@ -656,7 +656,27 @@ int ff_dxva2_decode_init(AVCodecContext *avctx)
>   
>       // Old API.
>       if (avctx->hwaccel_context)
> +    {
> +#if CONFIG_D3D11VA
> +        if (avctx->hwaccel->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
> +            AVDXVAContext *ctx = DXVA_CONTEXT(avctx);
> +
> +            if (D3D11VA_CONTEXT(ctx)->device_context) {
> +                ID3D11Device *d3ddevice;
> +                ID3D11DeviceContext_GetDevice(D3D11VA_CONTEXT(ctx)->device_context, &d3ddevice);
> +
> +                D3D11_QUERY_DESC query = { 0 };
> +                query.Query = D3D11_QUERY_EVENT;
> +                if (FAILED(ID3D11Device_CreateQuery(d3ddevice, &query,
> +                                                    (ID3D11Query**)&sctx->wait_copies)))
> +                    sctx->wait_copies = NULL;
> +
> +                ID3D11Device_Release(d3ddevice);
> +            }
> +        }
> +#endif
>           return 0;
> +    }
>   
>       // (avctx->pix_fmt is not updated yet at this point)
>       sctx->pix_fmt = avctx->hwaccel->pix_fmt;
> @@ -896,6 +916,7 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
>       unsigned               buffer_count = 0;
>   #if CONFIG_D3D11VA
>       D3D11_VIDEO_DECODER_BUFFER_DESC buffer11[4];
> +    ID3D11DeviceContext *device_context;
>   #endif
>   #if CONFIG_DXVA2
>       DXVA2_DecodeBufferDesc          buffer2[4];
> @@ -941,9 +962,14 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
>   #if CONFIG_D3D11VA
>       if (ff_dxva2_is_d3d11(avctx)) {
>           if (sctx->wait_copies) {
> -            AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
> -            AVD3D11VADeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
> -            ID3D11DeviceContext_Begin(device_hwctx->device_context, sctx->wait_copies);
> +            if (avctx->hwaccel_context)
> +                device_context = D3D11VA_CONTEXT(ctx)->device_context;
> +            else {
> +                AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
> +                AVD3D11VADeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
> +                device_context = device_hwctx->device_context;
> +            }
> +            ID3D11DeviceContext_Begin(device_context, sctx->wait_copies);
>           }
>   
>           buffer = &buffer11[buffer_count];
> @@ -1024,12 +1050,10 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
>           /* wait until all the buffer release is done copying data to the GPU
>            * before doing the submit command */
>           if (sctx->wait_copies) {
> -            AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
> -            AVD3D11VADeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
> -            ID3D11DeviceContext_End(device_hwctx->device_context, sctx->wait_copies);
> +            ID3D11DeviceContext_End(device_context, sctx->wait_copies);
>   
>               while (maxWait-- && S_FALSE ==
> -                   ID3D11DeviceContext_GetData(device_hwctx->device_context,
> +                   ID3D11DeviceContext_GetData(device_context,
>                                                  sctx->wait_copies, NULL, 0, 0)) {
>                   ff_dxva2_unlock(avctx);
>                   SleepEx(2, TRUE);
> diff --git a/libavcodec/version.h b/libavcodec/version.h
> index f66919617a..a3f9f828ee 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  99
> +#define LIBAVCODEC_VERSION_MINOR 100
>   #define LIBAVCODEC_VERSION_MICRO 100
>   
>   #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
> -- 
> 2.26.2
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>
diff mbox series

Patch

diff --git a/doc/APIchanges b/doc/APIchanges
index a9bf1afd4c..11a10ddb16 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -15,6 +15,9 @@  libavutil:     2017-10-21
 
 API changes, most recent first:
 
+2020-08-05 - xxxxxxxxxx - lavu 56.100.100 - d3d11va.h
+  Add a ID3D11VideoContext to AVD3D11VAContext matching the ID3D11VideoContext.
+
 2020-08-04 - xxxxxxxxxx - lavu 56.58.100 - channel_layout.h
   Add AV_CH_LAYOUT_22POINT2 together with its newly required pieces:
   AV_CH_TOP_SIDE_LEFT, AV_CH_TOP_SIDE_RIGHT, AV_CH_BOTTOM_FRONT_CENTER,
diff --git a/libavcodec/d3d11va.h b/libavcodec/d3d11va.h
index 6816b6c1e6..134dee388c 100644
--- a/libavcodec/d3d11va.h
+++ b/libavcodec/d3d11va.h
@@ -96,6 +96,12 @@  typedef struct AVD3D11VAContext {
       * Mutex to access video_context
       */
     HANDLE  context_mutex;
+
+    /**
+      * Device Context on which to send the D3D11VA commands.
+      * It should be the same used to get the ID3D11VideoDecoder or NULL.
+      */
+    ID3D11DeviceContext *device_context;
 } AVD3D11VAContext;
 
 /**
diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c
index 1a0e5b69b2..fd4685305e 100644
--- a/libavcodec/dxva2.c
+++ b/libavcodec/dxva2.c
@@ -656,7 +656,27 @@  int ff_dxva2_decode_init(AVCodecContext *avctx)
 
     // Old API.
     if (avctx->hwaccel_context)
+    {
+#if CONFIG_D3D11VA
+        if (avctx->hwaccel->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
+            AVDXVAContext *ctx = DXVA_CONTEXT(avctx);
+
+            if (D3D11VA_CONTEXT(ctx)->device_context) {
+                ID3D11Device *d3ddevice;
+                ID3D11DeviceContext_GetDevice(D3D11VA_CONTEXT(ctx)->device_context, &d3ddevice);
+
+                D3D11_QUERY_DESC query = { 0 };
+                query.Query = D3D11_QUERY_EVENT;
+                if (FAILED(ID3D11Device_CreateQuery(d3ddevice, &query,
+                                                    (ID3D11Query**)&sctx->wait_copies)))
+                    sctx->wait_copies = NULL;
+
+                ID3D11Device_Release(d3ddevice);
+            }
+        }
+#endif
         return 0;
+    }
 
     // (avctx->pix_fmt is not updated yet at this point)
     sctx->pix_fmt = avctx->hwaccel->pix_fmt;
@@ -896,6 +916,7 @@  int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
     unsigned               buffer_count = 0;
 #if CONFIG_D3D11VA
     D3D11_VIDEO_DECODER_BUFFER_DESC buffer11[4];
+    ID3D11DeviceContext *device_context;
 #endif
 #if CONFIG_DXVA2
     DXVA2_DecodeBufferDesc          buffer2[4];
@@ -941,9 +962,14 @@  int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
 #if CONFIG_D3D11VA
     if (ff_dxva2_is_d3d11(avctx)) {
         if (sctx->wait_copies) {
-            AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
-            AVD3D11VADeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
-            ID3D11DeviceContext_Begin(device_hwctx->device_context, sctx->wait_copies);
+            if (avctx->hwaccel_context)
+                device_context = D3D11VA_CONTEXT(ctx)->device_context;
+            else {
+                AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
+                AVD3D11VADeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
+                device_context = device_hwctx->device_context;
+            }
+            ID3D11DeviceContext_Begin(device_context, sctx->wait_copies);
         }
 
         buffer = &buffer11[buffer_count];
@@ -1024,12 +1050,10 @@  int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
         /* wait until all the buffer release is done copying data to the GPU
          * before doing the submit command */
         if (sctx->wait_copies) {
-            AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
-            AVD3D11VADeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
-            ID3D11DeviceContext_End(device_hwctx->device_context, sctx->wait_copies);
+            ID3D11DeviceContext_End(device_context, sctx->wait_copies);
 
             while (maxWait-- && S_FALSE ==
-                   ID3D11DeviceContext_GetData(device_hwctx->device_context,
+                   ID3D11DeviceContext_GetData(device_context,
                                                sctx->wait_copies, NULL, 0, 0)) {
                 ff_dxva2_unlock(avctx);
                 SleepEx(2, TRUE);
diff --git a/libavcodec/version.h b/libavcodec/version.h
index f66919617a..a3f9f828ee 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  99
+#define LIBAVCODEC_VERSION_MINOR 100
 #define LIBAVCODEC_VERSION_MICRO 100
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \