kodi
DXVAEnumeratorHD.h
1 /*
2  * Copyright (C) 2005-2023 Team Kodi
3  * This file is part of Kodi - https://kodi.tv
4  *
5  * SPDX-License-Identifier: GPL-2.0-or-later
6  * See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include "DVDCodecs/Video/DXVA.h"
12 #include "VideoRenderers/Windows/RendererBase.h"
13 #include "guilib/D3DResource.h"
14 
15 #include <mutex>
16 
17 #include <wrl/client.h>
18 
19 namespace DXVA
20 {
21 
22 using namespace Microsoft::WRL;
23 
24 // ProcAmp filters d3d11 filters
26 {
27  D3D11_VIDEO_PROCESSOR_FILTER filter;
28  D3D11_VIDEO_PROCESSOR_FILTER_CAPS cap;
29  const char* name;
30 };
31 
32 // clang-format off
33 const ProcAmpFilter PROCAMP_FILTERS[] = {
34  {D3D11_VIDEO_PROCESSOR_FILTER_BRIGHTNESS,
35  D3D11_VIDEO_PROCESSOR_FILTER_CAPS_BRIGHTNESS, "Brightness"},
36  {D3D11_VIDEO_PROCESSOR_FILTER_CONTRAST,
37  D3D11_VIDEO_PROCESSOR_FILTER_CAPS_CONTRAST, "Contrast"},
38  {D3D11_VIDEO_PROCESSOR_FILTER_HUE,
39  D3D11_VIDEO_PROCESSOR_FILTER_CAPS_HUE, "Hue"},
40  {D3D11_VIDEO_PROCESSOR_FILTER_SATURATION,
41  D3D11_VIDEO_PROCESSOR_FILTER_CAPS_SATURATION, "Saturation"},
42  {D3D11_VIDEO_PROCESSOR_FILTER_NOISE_REDUCTION,
43  D3D11_VIDEO_PROCESSOR_FILTER_CAPS_NOISE_REDUCTION, "Noise Reduction"},
44  {D3D11_VIDEO_PROCESSOR_FILTER_EDGE_ENHANCEMENT,
45  D3D11_VIDEO_PROCESSOR_FILTER_CAPS_EDGE_ENHANCEMENT, "Edge Enhancement"},
46  {D3D11_VIDEO_PROCESSOR_FILTER_ANAMORPHIC_SCALING,
47  D3D11_VIDEO_PROCESSOR_FILTER_CAPS_ANAMORPHIC_SCALING, "Anamorphic Scaling"},
48  {D3D11_VIDEO_PROCESSOR_FILTER_STEREO_ADJUSTMENT,
49  D3D11_VIDEO_PROCESSOR_FILTER_CAPS_STEREO_ADJUSTMENT, "Stereo Adjustment"}};
50 // clang-format on
51 
52 constexpr size_t NUM_FILTERS = ARRAYSIZE(PROCAMP_FILTERS);
53 
55 {
56  bool bSupported;
57  D3D11_VIDEO_PROCESSOR_FILTER_RANGE Range;
58 };
59 
61 {
62  bool m_valid{false};
63 
64  uint32_t m_procIndex{0};
65  D3D11_VIDEO_PROCESSOR_CAPS m_vcaps{};
66  D3D11_VIDEO_PROCESSOR_RATE_CONVERSION_CAPS m_rateCaps{};
67  ProcAmpInfo m_Filters[NUM_FILTERS]{};
68  bool m_hasMetadataHDR10Support{false};
69 };
70 
71 enum InputFormat
72 {
73  None,
74  TopLeft,
75  Left
76 };
77 
79 {
80  std::vector<DXGI_FORMAT> m_input;
81  std::vector<DXGI_FORMAT> m_output;
82  bool m_valid{false};
83 };
84 
86 {
87  DXGI_FORMAT m_inputFormat{DXGI_FORMAT_UNKNOWN};
88  DXGI_COLOR_SPACE_TYPE m_inputCS{DXGI_COLOR_SPACE_RESERVED};
89  DXGI_FORMAT m_outputFormat{DXGI_FORMAT_UNKNOWN};
90  DXGI_COLOR_SPACE_TYPE m_outputCS{DXGI_COLOR_SPACE_RESERVED};
91 
92  ProcessorConversion() = default;
93  ProcessorConversion(const DXGI_FORMAT& inputFormat,
94  const DXGI_COLOR_SPACE_TYPE& inputCS,
95  const DXGI_FORMAT& outputFormat,
96  const DXGI_COLOR_SPACE_TYPE& outputCS)
97  : m_inputFormat(inputFormat),
98  m_inputCS(inputCS),
99  m_outputFormat(outputFormat),
100  m_outputCS(outputCS)
101  {
102  }
103 
104  const std::string ToString() const;
105 
106  bool operator!=(const ProcessorConversion& other) const
107  {
108  return m_inputFormat != other.m_inputFormat ||
109  m_inputCS != other.m_inputCS && m_outputFormat != other.m_outputFormat ||
110  m_outputCS != other.m_outputCS;
111  }
112 };
113 
114 using ProcessorConversions = std::vector<ProcessorConversion>;
115 
117 {
118  AVColorPrimaries m_colorPrimaries{AVCOL_PRI_UNSPECIFIED};
119  AVColorSpace m_colorSpace{AVCOL_SPC_UNSPECIFIED};
120  AVColorTransferCharacteristic m_colorTransfer{AVCOL_TRC_UNSPECIFIED};
121  bool m_fullRange{false};
122  bool m_hdrOutput{false};
123 
124  SupportedConversionsArgs() = default;
125 
126  SupportedConversionsArgs(const VideoPicture& picture, bool isHdrOutput)
127  {
128  m_colorPrimaries = picture.color_primaries;
129  m_colorSpace = picture.color_space;
130  m_colorTransfer = picture.color_transfer;
131  m_fullRange = picture.color_range == 1;
132  m_hdrOutput = isHdrOutput;
133  }
134 
135  SupportedConversionsArgs(const AVColorPrimaries& colorPrimaries,
136  const AVColorSpace& colorSpace,
137  const AVColorTransferCharacteristic& colorTransfer,
138  bool fullRange,
139  bool hdrOutput)
140  : m_colorPrimaries(colorPrimaries),
141  m_colorSpace(colorSpace),
142  m_colorTransfer(colorTransfer),
143  m_fullRange(fullRange),
144  m_hdrOutput(hdrOutput)
145  {
146  }
147 
148  bool operator!=(const SupportedConversionsArgs& other) const
149  {
150  return m_colorPrimaries != other.m_colorPrimaries || m_colorTransfer != other.m_colorTransfer ||
151  m_fullRange != other.m_fullRange || m_hdrOutput != other.m_hdrOutput;
152  }
153 };
154 
156 {
157  AVColorPrimaries primaries = AVCOL_PRI_UNSPECIFIED;
158  AVColorSpace color_space = AVCOL_SPC_UNSPECIFIED;
159  AVColorTransferCharacteristic color_transfer = AVCOL_TRC_UNSPECIFIED;
160  bool full_range = false;
161  AVChromaLocation chroma_location = AVCHROMA_LOC_UNSPECIFIED;
162 
163  DXGIColorSpaceArgs(const VideoPicture& picture)
164  {
165  primaries = picture.color_primaries;
166  color_space = picture.color_space;
167  color_transfer = picture.color_transfer;
168  full_range = picture.color_range == 1;
169  chroma_location = picture.chroma_position;
170  }
171 
172  DXGIColorSpaceArgs(AVColorPrimaries primaries,
173  AVColorSpace color_space,
174  AVColorTransferCharacteristic color_transfer,
175  bool full_range,
176  AVChromaLocation chroma_location)
177  {
178  this->primaries = primaries;
179  this->color_space = color_space;
180  this->color_transfer = color_transfer;
181  this->full_range = full_range;
182  this->chroma_location = chroma_location;
183  }
184 };
185 
187 {
188 public:
189  CEnumeratorHD();
190  virtual ~CEnumeratorHD();
191 
192  bool Open(unsigned int width, unsigned int height, DXGI_FORMAT input_dxgi_format);
193  void Close();
194 
195  // ID3DResource overrides
196  void OnCreateDevice() override
197  {
198  std::unique_lock<CCriticalSection> lock(m_section);
199  if (m_width > 0 && m_height > 0)
200  OpenEnumerator();
201  }
202 
203  void OnDestroyDevice(bool) override
204  {
205  std::unique_lock<CCriticalSection> lock(m_section);
206  UnInit();
207  }
208 
209  ProcessorCapabilities ProbeProcessorCaps();
219  bool CheckConversion(DXGI_FORMAT inputFormat,
220  DXGI_COLOR_SPACE_TYPE inputCS,
221  DXGI_FORMAT outputFormat,
222  DXGI_COLOR_SPACE_TYPE outputCS);
228  bool IsFormatSupportedInput(DXGI_FORMAT format);
234  bool IsFormatSupportedOutput(DXGI_FORMAT format);
241  void LogSupportedConversions(const DXGI_FORMAT inputFormat,
242  const DXGI_COLOR_SPACE_TYPE inputNativeCS);
243 
244  bool IsInitialized() const { return m_pEnumerator; }
250  bool IsEnumerator1Available() { return m_pEnumerator1; }
251 
252  ComPtr<ID3D11VideoProcessor> CreateVideoProcessor(UINT RateConversionIndex);
253  ComPtr<ID3D11VideoProcessorInputView> CreateVideoProcessorInputView(
254  ID3D11Resource* pResource, const D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC* pDesc);
255  ComPtr<ID3D11VideoProcessorOutputView> CreateVideoProcessorOutputView(
256  ID3D11Resource* pResource, const D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC* pDesc);
257 
263  ProcessorConversions SupportedConversions(const SupportedConversionsArgs& args);
264 
270  static DXGI_COLOR_SPACE_TYPE AvToDxgiColorSpace(const DXGIColorSpaceArgs& csArgs);
271 
272 protected:
273  void UnInit();
274  bool OpenEnumerator();
275 
282  ProcessorFormats GetProcessorFormats(bool inputFormats, bool outputFormats) const;
287  std::vector<DXGI_FORMAT> GetProcessorRGBOutputFormats() const;
297  bool CheckConversionInternal(DXGI_FORMAT inputFormat,
298  DXGI_COLOR_SPACE_TYPE inputCS,
299  DXGI_FORMAT outputFormat,
300  DXGI_COLOR_SPACE_TYPE outputCS) const;
306  bool IsFormatSupportedInternal(DXGI_FORMAT format,
307  D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT support) const;
308 
318  ProcessorConversions ListConversions(
319  DXGI_FORMAT inputFormat,
320  const std::vector<DXGI_COLOR_SPACE_TYPE>& inputColorSpaces,
321  const std::vector<DXGI_FORMAT>& outputFormats,
322  const std::vector<DXGI_COLOR_SPACE_TYPE>& outputColorSpaces) const;
323 
331  ProcessorConversions LogAndListConversions(const DXGIColorSpaceArgs& inputArgs,
332  const DXGIColorSpaceArgs& outputArgs) const;
339  AVChromaLocation DefaultChromaSiting(const SupportedConversionsArgs& args) const;
346  AVChromaLocation AlternativeChromaSiting(const AVChromaLocation& location) const;
347 
348  CCriticalSection m_section;
349 
350  uint32_t m_width = 0;
351  uint32_t m_height = 0;
352 
353  ComPtr<ID3D11VideoDevice> m_pVideoDevice;
354  ComPtr<ID3D11VideoProcessorEnumerator> m_pEnumerator;
355  ComPtr<ID3D11VideoProcessorEnumerator1> m_pEnumerator1;
356  DXGI_FORMAT m_input_dxgi_format{DXGI_FORMAT_UNKNOWN};
357 };
358 }; // namespace DXVA
bool IsEnumerator1Available()
Returns the availability of the interface ID3D11VideoProcessorEnumerator1 (Windows 10 supporting HDR ...
Definition: DXVAEnumeratorHD.h:250
Definition: DXVAEnumeratorHD.h:54
Definition: DXVAEnumeratorHD.h:186
Definition: DXVAEnumeratorHD.h:155
Definition: DXVA.h:27
Definition: DXVAEnumeratorHD.h:25
Definition: DXVAEnumeratorHD.h:85
Definition: D3DResource.h:36
Definition: DXVAEnumeratorHD.h:78
Definition: DVDVideoCodec.h:36
Definition: DXVAEnumeratorHD.h:60
Definition: DXVAEnumeratorHD.h:116