1 /*
2 * Copyright (c) 2018-2022, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file     encode_vp9_brc.h
24 //! \brief    Defines the common interface for vp9 brc features
25 //!
26 #ifndef __ENCODE_VP9_BRC_H__
27 #define __ENCODE_VP9_BRC_H__
28 
29 #include "media_feature.h"
30 #include "encode_allocator.h"
31 #include "codec_hw_next.h"
32 #include "encode_pipeline.h"
33 #include "encode_vp9_basic_feature.h"
34 #include "media_vp9_packet_defs.h"
35 
36 namespace encode
37 {
38 #define CODECHAL_ENCODE_VP9_PIC_STATE_BUFFER_SIZE_PER_PASS 192  // 42 DWORDs for Pic State one uint32_t for BB End + 5 uint32_tS reserved to make it aligned for kernel read
39 #define CODECHAL_ENCODE_VP9_CQP_NUM_OF_PASSES 2
40 #define CODECHAL_ENCODE_VP9_BRC_DEFAULT_NUM_OF_PASSES 2  // 2 Passes minimum so HuC is Run twice, second PAK is conditional.
41 #define CODECHAL_ENCODE_VP9_BRC_CONSTANTSURFACE_SIZE 17792
42 #define CODECHAL_ENCODE_VP9_SEGMENT_STATE_BUFFER_SIZE 256
43 #define CODECHAL_ENCODE_VP9_BRC_BITSTREAM_SIZE_BUFFER_SIZE 16
44 #define CODECHAL_ENCODE_VP9_BRC_MSDK_PAK_BUFFER_SIZE 64
45 #define CODECHAL_ENCODE_VP9_PAK_INSERT_UNCOMPRESSED_HEADER 80
46 #define CODECHAL_ENCODE_VP9_VDENC_DATA_EXTENSION_SIZE 32
47 #define CODECHAL_ENCODE_VP9_HUC_BRC_DATA_BUFFER_SIZE (16*4)
48 #define CODECHAL_ENCODE_VP9_BRC_MAX_NUM_OF_PASSES 4
49 //!
50 //! \struct    BRC_BITSTREAM_SIZE_BUFFER
51 //! \brief     Brc bitstream size buffer
52 //!
53 struct EncodeVp9BSBuffer
54 {
55     uint32_t dwHcpBitstreamByteCountFrame;
56     uint32_t dwHcpImageStatusControl;
57     uint32_t Reserved[2];
58 };
59 
60 //!
61 //! \struct    HucBrcBuffers
62 //! \brief     HUC brc buffers
63 //!
64 struct HucBrcBuffers
65 {
66     MOS_RESOURCE resBrcHistoryBuffer;
67     MOS_RESOURCE resBrcConstantDataBuffer[2]; // 0 == I, 1 == P
68     MOS_RESOURCE resBrcMsdkPakBuffer;
69     MOS_RESOURCE resBrcMbEncCurbeWriteBuffer;
70     MOS_RESOURCE resMbEncAdvancedDsh;
71     MOS_RESOURCE resPicStateBrcReadBuffer;
72     MOS_RESOURCE resPicStateBrcWriteHucReadBuffer;
73     MOS_RESOURCE resPicStateHucWriteBuffer;
74     MOS_RESOURCE resSegmentStateBrcReadBuffer;
75     MOS_RESOURCE resSegmentStateBrcWriteBuffer;
76     MOS_RESOURCE resBrcBitstreamSizeBuffer;
77     MOS_RESOURCE resBrcHucDataBuffer;
78 };
79 
80 class Vp9EncodeBrc : public MediaFeature, public mhw::vdbox::huc::Itf::ParSetting, public mhw::vdbox::hcp::Itf::ParSetting, public mhw::vdbox::vdenc::Itf::ParSetting
81 {
82 public:
83     Vp9EncodeBrc(MediaFeatureManager *featureManager, EncodeAllocator *allocator, CodechalHwInterfaceNext *hwInterface, void *constSettings);
84 
85     virtual ~Vp9EncodeBrc();
86 
87     //!
88     //! \brief  Init cqp basic features related parameter
89     //! \param  [in] settings
90     //!         Pointer to settings
91     //! \return MOS_STATUS
92     //!         MOS_STATUS_SUCCESS if success, else fail reason
93     //!
94     MOS_STATUS Init(void *settings) override;
95 
96     //!
97     //! \brief  Update cqp basic features related parameter
98     //! \param  [in] params
99     //!         Pointer to parameters
100     //! \return MOS_STATUS
101     //!         MOS_STATUS_SUCCESS if success, else fail reason
102     //!
103     MOS_STATUS Update(void *params) override;
104 
105     //!
106     //! \brief    Check if BRC enabled
107     //! \return   bool
108     //!           true if BRC enabled, else BRC disabled.
109     //!
IsBrcEnabled()110     bool IsBrcEnabled() { return m_brcEnabled; }
111 
112     //!
113     //! \brief    Check if VDENC BRC enabled
114     //! \return   bool
115     //!           true if VDENC BRC enabled, else VDENC BRC disabled.
116     //!
IsVdencBrcEnabled()117     bool IsVdencBrcEnabled() { return m_vdencBrcEnabled; }
118 
119     //!
120     //! \brief    Disable Brc Init and Reset after BRC update
121     //!
DisableBrcInitReset()122     void DisableBrcInitReset() { m_brcInit = m_brcReset = false; };
123 
BrcReset(bool val)124     void BrcReset(bool val) { m_brcReset = val; };
IsBrcReset()125     bool IsBrcReset() { return m_brcReset; };
126 
127     //!
128     //! \brief    Check if BRC Init enabled
129     //! \return   bool
130     //!           true if BRC Init enabled, else Brc Init disabled.
131     //!
IsBrcInit()132     bool IsBrcInit() const { return m_brcInit; }
133 
134     //!
135     //! \brief    Check if BRC Reset enabled
136     //! \return   bool
137     //!           true if BRC Reset enabled, else BRC Reset disabled.
138     //!
IsBrcInitRequired()139     bool IsBrcInitRequired() { return m_vdencBrcEnabled & (m_brcInit || m_brcReset); }
140 
141     //!
142     //! \brief    Check if BRC Update enabled
143     //! \return   bool
144     //!           true if BRC Reset enabled, else BRC Reset disabled.
145     //!
IsBrcUpdateRequired()146     bool IsBrcUpdateRequired() { return m_vdencBrcEnabled; }
147 
148     //!
149     //! \brief    Help function to check if the rate control method is BRC
150     //! \param    [in] rc
151     //!           Rate control method
152     //! \return   True if using BRC , else return false
153     //!
IsRateControlBrc(uint8_t rc)154     bool IsRateControlBrc(uint8_t rc)
155     {
156         return (rc == RATECONTROL_CBR) ||
157                (rc == RATECONTROL_VBR) ||
158                (rc == RATECONTROL_AVBR) ||
159                (rc == RATECONTROL_VCM) ||
160                (rc == RATECONTROL_ICQ) ||
161                (rc == RATECONTROL_QVBR);
162     }
163 
164     //!
165     //! \brief    Check whether multi-pass brc supported
166     //! \return   bool
167     //!           true if adaptive repak supported, otherwise false.
168     //!
IsMultipassBrcSupported()169     bool IsMultipassBrcSupported() const { return m_multipassBrcSupported; }
170 
171     //!
172     //! \brief  Set regions for brc update
173     //! \param  [in] params
174     //!         Pointer to parameters
175     //! \return MOS_STATUS
176     //!         MOS_STATUS_SUCCESS if success, else fail reason
177     //!
178     MOS_STATUS SetRegionsForBrcUpdate(
179         mhw::vdbox::huc::HUC_VIRTUAL_ADDR_STATE_PAR &params) const;
180 
181     //!
182     //! \brief  Set Dmem buffer for brc update
183     //! \param  [in] params
184     //!         Pointer to parameters
185     //! \param  [in] isFirstPass
186     //!         Indicate is this first pass
187     //! \return MOS_STATUS
188     //!         MOS_STATUS_SUCCESS if success, else fail reason
189     //!
190     MOS_STATUS SetDmemForUpdate(void *params, bool isFirstPass) const;
191 
192     //!
193     //! \brief  Set Dmem buffer for brc Init
194     //! \param  [in] params
195     //!         Pointer to parameters
196     //! \return MOS_STATUS
197     //!         MOS_STATUS_SUCCESS if success, else fail reason
198     //!
199     MOS_STATUS SetDmemForInit(void *params) const;
200 
201     //!
202     //! \brief  Get huc brc buffers
203     //! \param  [out] buffers
204     //!         Reference to the huc brc buffers get from Brc feature
205     //! \return MOS_STATUS
206     //!         MOS_STATUS_SUCCESS if success, else fail reason
207     //!
208     virtual MOS_STATUS GetHucBrcBuffers(
209         HucBrcBuffers *&buffers);
210 
211     //!
212     //! \brief  Get brc history buffer size
213     //! \param  [out] size
214     //!         Brc history buffer size
215     //! \return MOS_STATUS
216     //!         MOS_STATUS_SUCCESS if success, else fail reason
217     //!
218     virtual MOS_STATUS GetBrcHistoryBufferSize(
219         uint32_t &size);
220 
221     //!
222     //! \brief  Get vdenc brc stats buffer size
223     //! \param  [out] size
224     //!         Vdenc brc stats buffer size
225     //! \return MOS_STATUS
226     //!         MOS_STATUS_SUCCESS if success, else fail reason
227     //!
228     virtual MOS_STATUS GetVdencBrcStatsBufferSize(
229         uint32_t &size);
230 
231     //!
232     //! \brief  Get vdenc brc pak stats buffer size
233     //! \param  [out] size
234     //!         Vdenc brc stats buffer size
235     //! \return MOS_STATUS
236     //!         MOS_STATUS_SUCCESS if success, else fail reason
237     //!
238     virtual MOS_STATUS GetVdencBrcPakStatsBufferSize(
239         uint32_t &size);
240 
241     //!
242     //! \brief  Initialize brc constant data buffer
243     //! \return MOS_STATUS
244     //!         MOS_STATUS_SUCCESS if success, else fail reason
245     //!
246     MOS_STATUS InitConstantDataBuffer() const;
247 
248     //!
249     //! \brief MHW parameters declaration
250     //!
251     MHW_SETPAR_DECL_HDR(HCP_VP9_PIC_STATE);
252     MHW_SETPAR_DECL_HDR(HCP_PIPE_BUF_ADDR_STATE);
253     MHW_SETPAR_DECL_HDR(VDENC_PIPE_BUF_ADDR_STATE);
254 
255     // Shared constants
256     static constexpr uint32_t m_brcMaxNumPasses        = 3;
257     static constexpr uint32_t m_brcStatsBufSize        = ((48 + 256) * sizeof(uint32_t));
258     static constexpr uint32_t m_brcPakStatsBufSize     = (64 * sizeof(uint32_t));
259     static constexpr uint32_t m_brcConstantSurfaceSize = 1664;
260 
261     mutable double m_inputBitsPerFrame = 0.0;
262     mutable double m_curTargetFullness = 0.0;
263 
264 protected:
265     //! \brief  Allocate feature related resources
266     //! \return MOS_STATUS
267     //!         MOS_STATUS_SUCCESS if success, else fail reason
268     //!
269     virtual MOS_STATUS AllocateResources() override;
270 
271     //!
272     //! \brief  Free resources
273     //! \return MOS_STATUS
274     //!         MOS_STATUS_SUCCESS if success, else fail reason
275     //!
276     virtual MOS_STATUS FreeResources();
277 
278     //!
279     //! \brief  Prepare BRC related settings
280     //! \return MOS_STATUS
281     //!         MOS_STATUS_SUCCESS if success, else fail reason
282     //!
283     virtual MOS_STATUS SetBrcSettings(void *params) const;
284 
285     //!
286     //! \brief  Calculate VP9 BRC init QP value
287     //!
288     //! \param  [in, out] initQpI
289     //!         Calculated initial QP value for I-frame
290     //! \param  [in, out] initQpP
291     //!         Calculated initial QP value for P-frame
292     //! \return MOS_STATUS
293     //!         MOS_STATUS_SUCCESS if success, else fail reason
294     //!
295     MOS_STATUS ComputeVDEncInitQP(int32_t &initQpI, int32_t &initQpP) const;
296 
297     //!
298     //! \brief      Calculate temporal ratios
299     //!
300     //! \param      [in] numberOfLayers
301     //!             Number of layers
302     //! \param      [in] maxTemporalBitrate
303     //!             Max temporal frame rate
304     //! \param      [in] maxTemporalFrameRate
305     //!             Frame rate
306     //! \param      [in] maxLevelRatios
307     //!             Max level ratios
308     //!
309     //! \return     MOS_STATUS
310     //!             MOS_STATUS_SUCCESS if success, else fail reason
311     //!
312     MOS_STATUS CalculateTemporalRatios(
313         uint16_t   numberOfLayers,
314         uint32_t   maxTemporalBitrate,
315         FRAME_RATE maxTemporalFrameRate,
316         uint8_t *  maxLevelRatios) const;
317 
318     //!
319     //! \brief      Calculate normalized denominator
320     //!
321     //! \param      [in] frameRates
322     //!             Pointer to frame rate
323     //! \param      [in] numberOfLayers
324     //!             Number of layers
325     //! \param      [in] normalizedDenominator
326     //!             Normalized denominator
327     //!
328     //! \return     uint32_t
329     //!             Return 0 if call success, else -1 if fail
330     //!
331     uint32_t CalculateNormalizedDenominator(
332         FRAME_RATE *frameRates,
333         uint16_t    numberOfLayers,
334         uint32_t    normalizedDenominator) const;
335 
336     //!
337     //! \brief  Set sequence structures
338     //! \return MOS_STATUS
339     //!         MOS_STATUS_SUCCESS if success, else fail reason
340     //!
341     MOS_STATUS SetSequenceStructs();
342 
343     //!
344     //! \brief  GetB Brc const buffer accoring to picture coding type
345     //! \param  [in] pictureCodingType
346     //!         coding type of picture
347     //! \return PMOS_RESOURCE
348     //!         Pointer to Brc const buffer
349     //!
350     const MOS_RESOURCE* GetBrcConstantBuffer() const;
351 
352     static constexpr uint32_t CODECHAL_ENCODE_BRCINIT_ISCBR                      = 0x0010;
353     static constexpr uint32_t CODECHAL_ENCODE_BRCINIT_ISVBR                      = 0x0020;
354     static constexpr uint32_t CODECHAL_ENCODE_BRCINIT_ISAVBR                     = 0x0040;
355     static constexpr uint32_t CODECHAL_ENCODE_BRCINIT_ISCQL                      = 0x0080;
356     static constexpr uint32_t CODECHAL_ENCODE_BRCINIT_FIELD_PIC                  = 0x0100;
357     static constexpr uint32_t CODECHAL_ENCODE_BRCINIT_ISICQ                      = 0x0200;
358     static constexpr uint32_t CODECHAL_ENCODE_BRCINIT_ISVCM                      = 0x0400;
359     static constexpr uint32_t CODECHAL_ENCODE_BRCINIT_IGNORE_PICTURE_HEADER_SIZE = 0x2000;
360     static constexpr uint32_t CODECHAL_ENCODE_BRCINIT_ISQVBR                     = 0x4000;
361     static constexpr uint32_t CODECHAL_ENCODE_BRCINIT_DISABLE_MBBRC              = 0x8000;
362 
363     static const uint32_t     m_brcConstData[2][416];
364 
365     static constexpr float m_devStdFps    = 30.0;
366     static constexpr float m_bpsRatioLow  = 0.1f;
367     static constexpr float m_bpsRatioHigh = 3.5;
368 
369     static constexpr int32_t m_numInstRateThresholds = 4;
370     static constexpr int32_t m_numDevThresholds      = 8;
371     static constexpr int32_t m_posMultPb             = 50;
372     static constexpr int32_t m_negMultPb             = -50;
373     static constexpr int32_t m_posMultVbr            = 100;
374     static constexpr int32_t m_negMultVbr            = -50;
375 
376     static constexpr int8_t m_instRateThresholdI[m_numInstRateThresholds] = {30, 50, 90, 115};
377     static constexpr int8_t m_instRateThresholdP[m_numInstRateThresholds] = {30, 50, 70, 120};
378     static constexpr double m_devThresholdFpNegI[m_numDevThresholds / 2]  = {0.80, 0.60, 0.34, 0.2};
379     static constexpr double m_devThresholdFpPosI[m_numDevThresholds / 2]  = {0.2, 0.4, 0.66, 0.9};
380     static constexpr double m_devThresholdFpNegPB[m_numDevThresholds / 2] = {0.90, 0.66, 0.46, 0.3};
381     static constexpr double m_devThresholdFpPosPB[m_numDevThresholds / 2] = {0.3, 0.46, 0.70, 0.90};
382     static constexpr double m_devThresholdVbrNeg[m_numDevThresholds / 2]  = {0.90, 0.70, 0.50, 0.3};
383     static constexpr double m_devThresholdVbrPos[m_numDevThresholds / 2]  = {0.4, 0.5, 0.75, 0.90};
384 
385     // VDENC BRC related buffer size
386     static constexpr uint32_t m_brcHistoryBufSize = 1152;
387 
388     CodechalHwInterfaceNext *   m_hwInterface    = nullptr;
389     EncodeAllocator *       m_allocator      = nullptr;
390     Vp9BasicFeature *       m_basicFeature   = nullptr;
391 
392     std::shared_ptr<mhw::vdbox::hcp::Itf>   m_hcpInterfaceNew   = nullptr;
393     std::shared_ptr<mhw::vdbox::vdenc::Itf> m_vdencInterfaceNew = nullptr;
394 
395     bool m_brcInit         = true;   //!< BRC init flag
396     bool m_brcReset        = false;  //!< BRC reset flag
397     bool m_brcEnabled      = false;  //!< BRC enable flag
398     bool m_vdencEnabled    = false;  //!< Vdenc enabled flag
399     bool m_vdencBrcEnabled = false;  //!< Vdenc bitrate control enabled flag
400 
401     // BRC Resources/Buffers
402     HucBrcBuffers m_brcBuffers                  = {};
403     uint32_t      m_brcHistoryBufferSize        = 0;    //!< Bitrate control history buffer size
404     uint32_t      m_vdencBrcStatsBufferSize     = 0;    //!< VDENC bitrate control buffer size
405     MOS_RESOURCE  m_resFrameStatStreamOutBuffer = {0};  //!< Frame statistics stream out buffer
406     uint32_t      m_vdencBrcPakStatsBufferSize  = 0;    //!< VDENC bitrate control PAK buffer size
407     bool          m_multipassBrcSupported       = true;  //!< Multi-pass bitrate control supported flag
408     bool          m_initBrcConstantDataBuffer   = false; //!< BrcConstantDataBuffer init flag
409 
410 MEDIA_CLASS_DEFINE_END(encode__Vp9EncodeBrc)
411 };
412 }  // namespace encode
413 
414 #endif
415