[vlc-commits] [Git][videolan/vlc][3.0.x] dxva: use the actual surface size to test decoder support

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Thu Jul 6 07:59:22 UTC 2023



Jean-Baptiste Kempf pushed to branch 3.0.x at VideoLAN / VLC


Commits:
ba02ef60 by Steve Lhomme at 2023-07-03T09:05:31+02:00
dxva: use the actual surface size to test decoder support

The container may lie but the size that libavcodec requests is the one it
will use. We need this size to probe the decoder in D3D11. There doesn't
seem to be a way to check the size support in dxva2.

Similar to e4cc2f846b020e4e5a89046669c1eaddbebe0a34 but without setting
an output video_format_t.

- - - - -


6 changed files:

- modules/codec/avcodec/d3d11va.c
- modules/codec/avcodec/directx_va.c
- modules/codec/avcodec/directx_va.h
- modules/codec/avcodec/dxva2.c
- modules/codec/avcodec/va_surface.c
- modules/codec/avcodec/va_surface_internal.h


Changes:

=====================================
modules/codec/avcodec/d3d11va.c
=====================================
@@ -131,7 +131,7 @@ static char *DxDescribe(vlc_va_sys_t *);
 static int DxCreateVideoService(vlc_va_t *);
 static void DxDestroyVideoService(vlc_va_t *);
 static int DxGetInputList(vlc_va_t *, input_list_t *);
-static int DxSetupOutput(vlc_va_t *, const GUID *, const video_format_t *);
+static int DxSetupOutput(vlc_va_t *, const GUID *, int surface_width, int surface_height);
 
 static int DxCreateDecoderSurfaces(vlc_va_t *, int codec_id,
                                    const video_format_t *fmt, unsigned surface_count);
@@ -555,7 +555,7 @@ static int DxGetInputList(vlc_va_t *va, input_list_t *p_list)
 extern const GUID DXVA_ModeHEVC_VLD_Main10;
 extern const GUID DXVA_ModeVP9_VLD_10bit_Profile2;
 
-static int DxSetupOutput(vlc_va_t *va, const GUID *input, const video_format_t *fmt)
+static int DxSetupOutput(vlc_va_t *va, const GUID *input, int surface_width, int surface_height)
 {
     vlc_va_sys_t *sys = va->sys;
     directx_sys_t *dx_sys = &sys->dx_sys;
@@ -625,8 +625,8 @@ static int DxSetupOutput(vlc_va_t *va, const GUID *input, const video_format_t *
         D3D11_VIDEO_DECODER_DESC decoderDesc;
         ZeroMemory(&decoderDesc, sizeof(decoderDesc));
         decoderDesc.Guid = *input;
-        decoderDesc.SampleWidth = fmt->i_width;
-        decoderDesc.SampleHeight = fmt->i_height;
+        decoderDesc.SampleWidth = surface_width;
+        decoderDesc.SampleHeight = surface_height;
         decoderDesc.OutputFormat = processorInput[idx];
 
         UINT cfg_count = 0;


=====================================
modules/codec/avcodec/directx_va.c
=====================================
@@ -300,7 +300,8 @@ static const directx_va_mode_t DXVA_MODES[] = {
 };
 
 static int FindVideoServiceConversion(vlc_va_t *, directx_sys_t *, const es_format_t *,
-                                      const AVCodecContext *, const AVPixFmtDescriptor *);
+                                      const AVCodecContext *, const AVPixFmtDescriptor *,
+                                      int surface_width, int surface_height);
 
 char *directx_va_GetDecoderName(const GUID *guid)
 {
@@ -320,12 +321,6 @@ int directx_va_Setup(vlc_va_t *va, directx_sys_t *dx_sys,
                      const AVCodecContext *avctx, const AVPixFmtDescriptor *desc,
                      const es_format_t *fmt, int flag_xbox)
 {
-    /* */
-    if (FindVideoServiceConversion(va, dx_sys, fmt, avctx, desc)) {
-        msg_Err(va, "FindVideoServiceConversion failed");
-        return VLC_EGENERIC;
-    }
-
     int surface_alignment = 16;
     unsigned surface_count = 2;
 
@@ -365,7 +360,26 @@ int directx_va_Setup(vlc_va_t *va, directx_sys_t *dx_sys,
     if ( avctx->active_thread_type & FF_THREAD_FRAME )
         surface_count += avctx->thread_count;
 
-    int err = va_pool_SetupDecoder(va, &dx_sys->va_pool, avctx, surface_count, surface_alignment);
+    if (avctx->coded_width <= 0 || avctx->coded_height <= 0)
+        return VLC_EGENERIC;
+
+    assert((surface_alignment & (surface_alignment - 1)) == 0); /* power of 2 */
+#define ALIGN(x, y) (((x) + ((y) - 1)) & ~((y) - 1))
+    int surface_width  = ALIGN(avctx->coded_width,  surface_alignment);
+    int surface_height = ALIGN(avctx->coded_height, surface_alignment);
+
+    if (avctx->coded_width != surface_width || avctx->coded_height != surface_height)
+        msg_Warn( va, "surface dimensions (%dx%d) differ from avcodec dimensions (%dx%d)",
+                  surface_width, surface_height,
+                  avctx->coded_width, avctx->coded_height);
+
+    /* */
+    if (FindVideoServiceConversion(va, dx_sys, fmt, avctx, desc, surface_width, surface_height)) {
+        msg_Err(va, "FindVideoServiceConversion failed");
+        return VLC_EGENERIC;
+    }
+
+    int err = va_pool_SetupDecoder(va, &dx_sys->va_pool, avctx, surface_count, surface_width, surface_height);
     if (err != VLC_SUCCESS)
         return err;
     if (dx_sys->can_extern_pool)
@@ -428,7 +442,8 @@ static bool profile_supported(const directx_va_mode_t *mode, const es_format_t *
  */
 static int FindVideoServiceConversion(vlc_va_t *va, directx_sys_t *dx_sys,
                                       const es_format_t *fmt,
-                                      const AVCodecContext *avctx, const AVPixFmtDescriptor *desc)
+                                      const AVCodecContext *avctx, const AVPixFmtDescriptor *desc,
+                                      int surface_width, int surface_height)
 {
     input_list_t p_list = { 0 };
     int err = dx_sys->pf_get_input_list(va, &p_list);
@@ -483,7 +498,7 @@ static int FindVideoServiceConversion(vlc_va_t *va, directx_sys_t *dx_sys,
 
         /* */
         msg_Dbg(va, "Trying to use '%s' as input", mode->name);
-        if (dx_sys->pf_setup_output(va, mode->guid, &fmt->video)==VLC_SUCCESS)
+        if (dx_sys->pf_setup_output(va, mode->guid, surface_width, surface_height)==VLC_SUCCESS)
         {
             dx_sys->input = *mode->guid;
             err = VLC_SUCCESS;


=====================================
modules/codec/avcodec/directx_va.h
=====================================
@@ -74,7 +74,7 @@ typedef struct
      * Find a suitable decoder configuration for the input and set the
      * internal state to use that output
      */
-    int (*pf_setup_output)(vlc_va_t *, const GUID *input, const video_format_t *fmt);
+    int (*pf_setup_output)(vlc_va_t *, const GUID *input, int surface_width, int surface_height);
 
 } directx_sys_t;
 


=====================================
modules/codec/avcodec/dxva2.c
=====================================
@@ -138,7 +138,7 @@ static void D3dDestroyDeviceManager(vlc_va_t *);
 static int DxCreateVideoService(vlc_va_t *);
 static void DxDestroyVideoService(vlc_va_t *);
 static int DxGetInputList(vlc_va_t *, input_list_t *);
-static int DxSetupOutput(vlc_va_t *, const GUID *, const video_format_t *);
+static int DxSetupOutput(vlc_va_t *, const GUID *, int surface_width, int surface_height);
 
 static int DxCreateVideoDecoder(vlc_va_t *, int codec_id,
                                 const video_format_t *, unsigned surface_count);
@@ -490,9 +490,9 @@ static int DxGetInputList(vlc_va_t *va, input_list_t *p_list)
     return VLC_SUCCESS;
 }
 
-static int DxSetupOutput(vlc_va_t *va, const GUID *input, const video_format_t *fmt)
+static int DxSetupOutput(vlc_va_t *va, const GUID *input, int surface_width, int surface_height)
 {
-    VLC_UNUSED(fmt);
+    VLC_UNUSED(surface_width); VLC_UNUSED(surface_height);
     vlc_va_sys_t *sys = va->sys;
 
     const D3DADAPTER_IDENTIFIER9 *identifier = &sys->d3d_dev.identifier;


=====================================
modules/codec/avcodec/va_surface.c
=====================================
@@ -54,24 +54,12 @@ static void DestroyVideoDecoder(vlc_va_t *va, va_pool_t *va_pool)
 }
 
 /* */
-int va_pool_SetupDecoder(vlc_va_t *va, va_pool_t *va_pool, const AVCodecContext *avctx, unsigned count, int alignment)
+int va_pool_SetupDecoder(vlc_va_t *va, va_pool_t *va_pool, const AVCodecContext *avctx, unsigned count,
+                         int surface_width, int surface_height)
 {
     int err = VLC_ENOMEM;
     unsigned i = va_pool->surface_count;
 
-    if (avctx->coded_width <= 0 || avctx->coded_height <= 0)
-        return VLC_EGENERIC;
-
-    assert((alignment & (alignment - 1)) == 0); /* power of 2 */
-#define ALIGN(x, y) (((x) + ((y) - 1)) & ~((y) - 1))
-    int surface_width  = ALIGN(avctx->coded_width,  alignment);
-    int surface_height = ALIGN(avctx->coded_height, alignment);
-
-    if (avctx->coded_width != surface_width || avctx->coded_height != surface_height)
-        msg_Warn( va, "surface dimensions (%dx%d) differ from avcodec dimensions (%dx%d)",
-                  surface_width, surface_height,
-                  avctx->coded_width, avctx->coded_height);
-
     if ( va_pool->surface_count >= count &&
          va_pool->surface_width == surface_width &&
          va_pool->surface_height == surface_height )


=====================================
modules/codec/avcodec/va_surface_internal.h
=====================================
@@ -80,7 +80,7 @@ typedef struct
 
 int va_pool_Open(vlc_va_t *, va_pool_t *);
 void va_pool_Close(vlc_va_t *va, va_pool_t *);
-int va_pool_SetupDecoder(vlc_va_t *, va_pool_t *, const AVCodecContext *, unsigned count, int alignment);
+int va_pool_SetupDecoder(vlc_va_t *, va_pool_t *, const AVCodecContext *, unsigned count, int surface_width, int surface_height);
 int va_pool_SetupSurfaces(vlc_va_t *, va_pool_t *, unsigned count);
 int va_pool_Get(va_pool_t *, picture_t *);
 void va_surface_AddRef(vlc_va_surface_t *surface);



View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/ba02ef605699a3d659fb24286284ed66b0f91dc5

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/ba02ef605699a3d659fb24286284ed66b0f91dc5
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list