[vlc-devel] [PATCH 3/7] directx_va: pass the dxva mode to the output setup callback

Steve Lhomme robux4 at ycbcr.xyz
Fri Oct 4 15:15:54 CEST 2019


---
 modules/codec/avcodec/d3d11va.c    | 29 ++++++++++++-----------------
 modules/codec/avcodec/directx_va.c | 20 ++++----------------
 modules/codec/avcodec/directx_va.h | 11 +++++++++--
 modules/codec/avcodec/dxva2.c      | 12 +++++-------
 4 files changed, 30 insertions(+), 42 deletions(-)

diff --git a/modules/codec/avcodec/d3d11va.c b/modules/codec/avcodec/d3d11va.c
index c34430bed66..68681b9f115 100644
--- a/modules/codec/avcodec/d3d11va.c
+++ b/modules/codec/avcodec/d3d11va.c
@@ -130,7 +130,7 @@ static int D3dCreateDevice(vlc_va_t *);
 static void D3dDestroyDevice(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 directx_va_mode_t *, const video_format_t *);
 
 static int DxCreateDecoderSurfaces(vlc_va_t *, int codec_id,
                                    const video_format_t *fmt, unsigned surface_count);
@@ -519,7 +519,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 directx_va_mode_t *mode, const video_format_t *fmt)
 {
     vlc_va_sys_t *sys = va->sys;
     HRESULT hr;
@@ -527,7 +527,7 @@ static int DxSetupOutput(vlc_va_t *va, const GUID *input, const video_format_t *
 #ifndef NDEBUG
     BOOL bSupported = false;
     for (int format = 0; format < 188; format++) {
-        hr = ID3D11VideoDevice_CheckVideoDecoderFormat(sys->d3ddec, input, format, &bSupported);
+        hr = ID3D11VideoDevice_CheckVideoDecoderFormat(sys->d3ddec, mode->guid, format, &bSupported);
         if (SUCCEEDED(hr) && bSupported)
             msg_Dbg(va, "format %s is supported for output", DxgiFormatToStr(format));
     }
@@ -543,13 +543,10 @@ static int DxSetupOutput(vlc_va_t *va, const GUID *input, const video_format_t *
     if (FAILED(hr))
         return VLC_EGENERIC;
 
-    char *psz_decoder_name = directx_va_GetDecoderName(input);
-
     if (!directx_va_canUseDecoder(va, adapterDesc.VendorId, adapterDesc.DeviceId,
-                                  input, sys->d3d_dev.WDDM.build))
+                                  mode->guid, sys->d3d_dev.WDDM.build))
     {
-        msg_Warn(va, "GPU blacklisted for %s codec", psz_decoder_name);
-        free(psz_decoder_name);
+        msg_Warn(va, "GPU blacklisted for %s codec", mode->name);
         return VLC_EGENERIC;
     }
 
@@ -557,7 +554,7 @@ static int DxSetupOutput(vlc_va_t *va, const GUID *input, const video_format_t *
     int idx = 0;
     if ( sys->render != DXGI_FORMAT_UNKNOWN )
         processorInput[idx++] = sys->render;
-    if (IsEqualGUID(input, &DXVA_ModeHEVC_VLD_Main10) || IsEqualGUID(input, &DXVA_ModeVP9_VLD_10bit_Profile2))
+    if (IsEqualGUID(mode->guid, &DXVA_ModeHEVC_VLD_Main10) || IsEqualGUID(mode->guid, &DXVA_ModeVP9_VLD_10bit_Profile2))
         processorInput[idx++] = DXGI_FORMAT_P010;
     processorInput[idx++] = DXGI_FORMAT_NV12;
     processorInput[idx++] = DXGI_FORMAT_420_OPAQUE;
@@ -567,12 +564,12 @@ static int DxSetupOutput(vlc_va_t *va, const GUID *input, const video_format_t *
     for (idx = 0; processorInput[idx] != DXGI_FORMAT_UNKNOWN; ++idx)
     {
         BOOL is_supported = false;
-        hr = ID3D11VideoDevice_CheckVideoDecoderFormat(sys->d3ddec, input, processorInput[idx], &is_supported);
+        hr = ID3D11VideoDevice_CheckVideoDecoderFormat(sys->d3ddec, mode->guid, processorInput[idx], &is_supported);
         if (SUCCEEDED(hr) && is_supported)
-            msg_Dbg(va, "%s output is supported for decoder %s.", DxgiFormatToStr(processorInput[idx]), psz_decoder_name);
+            msg_Dbg(va, "%s output is supported for decoder %s.", DxgiFormatToStr(processorInput[idx]), mode->name);
         else
         {
-            msg_Dbg(va, "Can't get a decoder output format %s for decoder %s.", DxgiFormatToStr(processorInput[idx]), psz_decoder_name);
+            msg_Dbg(va, "Can't get a decoder output format %s for decoder %s.", DxgiFormatToStr(processorInput[idx]), mode->name);
             continue;
         }
 
@@ -597,7 +594,7 @@ 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.Guid = *mode->guid;
         decoderDesc.SampleWidth = fmt->i_width;
         decoderDesc.SampleHeight = fmt->i_height;
         decoderDesc.OutputFormat = processorInput[idx];
@@ -606,7 +603,7 @@ static int DxSetupOutput(vlc_va_t *va, const GUID *input, const video_format_t *
         hr = ID3D11VideoDevice_GetVideoDecoderConfigCount( sys->d3ddec, &decoderDesc, &cfg_count );
         if (FAILED(hr))
         {
-            msg_Err( va, "Failed to get configuration for decoder %s. (hr=0x%lX)", psz_decoder_name, hr );
+            msg_Err( va, "Failed to get configuration for decoder %s. (hr=0x%lX)", mode->name, hr );
             continue;
         }
         if (cfg_count == 0) {
@@ -616,7 +613,7 @@ static int DxSetupOutput(vlc_va_t *va, const GUID *input, const video_format_t *
             continue;
         }
 
-        msg_Dbg(va, "Using output format %s for decoder %s", DxgiFormatToStr(processorInput[idx]), psz_decoder_name);
+        msg_Dbg(va, "Using output format %s for decoder %s", DxgiFormatToStr(processorInput[idx]), mode->name);
         if ( sys->render == processorInput[idx] && sys->totalTextureSlices > 4)
         {
             if (CanUseVoutPool(&sys->d3d_dev, sys->totalTextureSlices))
@@ -625,10 +622,8 @@ static int DxSetupOutput(vlc_va_t *va, const GUID *input, const video_format_t *
                 msg_Warn( va, "use internal pool" );
         }
         sys->render = processorInput[idx];
-        free(psz_decoder_name);
         return VLC_SUCCESS;
     }
-    free(psz_decoder_name);
 
     msg_Dbg(va, "Output format from picture source not supported.");
     return VLC_EGENERIC;
diff --git a/modules/codec/avcodec/directx_va.c b/modules/codec/avcodec/directx_va.c
index cbe8cf26f9a..7bd1f636b63 100644
--- a/modules/codec/avcodec/directx_va.c
+++ b/modules/codec/avcodec/directx_va.c
@@ -159,14 +159,6 @@ DEFINE_GUID(DXVA_ModeVP9_VLD_Profile0,              0x463707f8, 0xa1d0, 0x4585,
 DEFINE_GUID(DXVA_ModeVP9_VLD_10bit_Profile2,        0xa4c749ef, 0x6ecf, 0x48aa, 0x84, 0x48, 0x50, 0xa7, 0xa1, 0x16, 0x5f, 0xf7);
 DEFINE_GUID(DXVA_ModeVP9_VLD_Intel,                 0x76988a52, 0xdf13, 0x419a, 0x8e, 0x64, 0xff, 0xcf, 0x4a, 0x33, 0x6c, 0xf5);
 
-typedef struct {
-    const char   *name;
-    const GUID   *guid;
-    int           bit_depth;
-    enum AVCodecID codec;
-    const int    *p_profiles; // NULL or ends with 0
-} directx_va_mode_t;
-
 /* XXX Prefered modes must come first */
 static const directx_va_mode_t DXVA_MODES[] = {
     /* MPEG-1/2 */
@@ -271,7 +263,7 @@ static const directx_va_mode_t DXVA_MODES[] = {
 static int FindVideoServiceConversion(vlc_va_t *, const directx_sys_t *, const es_format_t *, video_format_t *fmt_out,
                                       const AVCodecContext *, const AVPixFmtDescriptor *, GUID *found_guid);
 
-char *directx_va_GetDecoderName(const GUID *guid)
+static char *directx_va_GetDecoderName(const GUID *guid)
 {
     for (unsigned i = 0; DXVA_MODES[i].name; i++) {
         if (IsEqualGUID(DXVA_MODES[i].guid, guid))
@@ -432,25 +424,21 @@ static int FindVideoServiceConversion(vlc_va_t *va, const directx_sys_t *dx_sys,
         int src_bit_depth = (desc && desc->nb_components) ? desc->comp[0].depth : 8;
         if (src_bit_depth != mode->bit_depth)
         {
-            char *psz_name = directx_va_GetDecoderName(mode->guid);
             msg_Warn( va, "Unsupported bitdepth %d for %s ",
-                    src_bit_depth, psz_name );
-            free( psz_name );
+                    src_bit_depth, mode->name );
             continue;
         }
 
         if (!profile_supported( mode, fmt, avctx ))
         {
-            char *psz_name = directx_va_GetDecoderName(mode->guid);
             msg_Warn( va, "Unsupported profile %d for %s ",
-                    fmt->i_profile, psz_name );
-            free( psz_name );
+                    fmt->i_profile, mode->name );
             continue;
         }
 
         /* */
         msg_Dbg(va, "Trying to use '%s' as input", mode->name);
-        if (dx_sys->pf_setup_output(va, mode->guid, fmt_out)==VLC_SUCCESS)
+        if (dx_sys->pf_setup_output(va, mode, fmt_out)==VLC_SUCCESS)
         {
             *found_guid = *mode->guid;
             err = VLC_SUCCESS;
diff --git a/modules/codec/avcodec/directx_va.h b/modules/codec/avcodec/directx_va.h
index e3cfea9e37c..9b26b7f8471 100644
--- a/modules/codec/avcodec/directx_va.h
+++ b/modules/codec/avcodec/directx_va.h
@@ -49,6 +49,14 @@ typedef struct input_list_t {
     unsigned count;
 } input_list_t;
 
+typedef struct {
+    const char   *name;
+    const GUID   *guid;
+    int           bit_depth;
+    enum AVCodecID codec;
+    const int    *p_profiles; // NULL or ends with 0
+} directx_va_mode_t;
+
 #define MAX_SURFACE_COUNT (64)
 typedef struct
 {
@@ -60,14 +68,13 @@ 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 directx_va_mode_t *, const video_format_t *fmt);
 
 } directx_sys_t;
 
 int directx_va_Setup(vlc_va_t *, const directx_sys_t *, const AVCodecContext *, const AVPixFmtDescriptor *,
                      const es_format_t *, int flag_xbox,
                      video_format_t *fmt_out, unsigned *surface_count, GUID *found_guid);
-char *directx_va_GetDecoderName(const GUID *guid);
 bool directx_va_canUseDecoder(vlc_va_t *, UINT VendorId, UINT DeviceId, const GUID *pCodec, UINT driverBuild);
 
 #endif /* AVCODEC_DIRECTX_VA_H */
diff --git a/modules/codec/avcodec/dxva2.c b/modules/codec/avcodec/dxva2.c
index 68e8727e696..7f1a40c3216 100644
--- a/modules/codec/avcodec/dxva2.c
+++ b/modules/codec/avcodec/dxva2.c
@@ -139,7 +139,7 @@ static int D3dCreateDevice(vlc_va_t *);
 static void D3dDestroyDevice(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 directx_va_mode_t *, const video_format_t *);
 
 static int DxCreateVideoDecoder(vlc_va_t *, int codec_id,
                                 const video_format_t *, unsigned surface_count);
@@ -440,7 +440,7 @@ 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 directx_va_mode_t *mode, const video_format_t *fmt)
 {
     VLC_UNUSED(fmt);
     vlc_va_sys_t *sys = va->sys;
@@ -457,11 +457,9 @@ static int DxSetupOutput(vlc_va_t *va, const GUID *input, const video_format_t *
         driverBuild += ((identifier.DriverVersion.LowPart >> 16) - 100) * 1000;
     }
     if (!directx_va_canUseDecoder(va, identifier.VendorId, identifier.DeviceId,
-                                  input, driverBuild))
+                                  mode->guid, driverBuild))
     {
-        char* psz_decoder_name = directx_va_GetDecoderName(input);
-        msg_Warn(va, "GPU blacklisted for %s codec", psz_decoder_name);
-        free(psz_decoder_name);
+        msg_Warn(va, "GPU blacklisted for %s codec", mode->name);
         return VLC_EGENERIC;
     }
 
@@ -469,7 +467,7 @@ static int DxSetupOutput(vlc_va_t *va, const GUID *input, const video_format_t *
     UINT      output_count = 0;
     D3DFORMAT *output_list = NULL;
     if (FAILED(IDirectXVideoDecoderService_GetDecoderRenderTargets(sys->d3ddec,
-                                                                   input,
+                                                                   mode->guid,
                                                                    &output_count,
                                                                    &output_list))) {
         msg_Err(va, "IDirectXVideoDecoderService_GetDecoderRenderTargets failed");
-- 
2.17.1



More information about the vlc-devel mailing list