1 /*
2 * Copyright (c) 2020-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_avc_brc.h
24 //! \brief    Defines the common interface for avc brc features
25 //!
26 #ifndef __ENCODE_AVC_BRC_H__
27 #define __ENCODE_AVC_BRC_H__
28 
29 #include "media_feature.h"
30 #include "encode_allocator.h"
31 #include "codec_hw_next.h"
32 #include "encode_avc_basic_feature.h"
33 #include "mhw_vdbox_vdenc_itf.h"
34 #include "mhw_vdbox_mfx_itf.h"
35 #include "mhw_mi_itf.h"
36 
37 #if (_SW_BRC)
38 #include "encode_sw_brc.h"
39 #endif  // !_SW_BRC
40 
41 namespace encode
42 {
43 struct VdencAvcHucBrcUpdateDmem;
44 
45 class AvcEncodeBRC : public MediaFeature,
46     public mhw::vdbox::vdenc::Itf::ParSetting,
47     public mhw::vdbox::huc::Itf::ParSetting
48 {
49     enum AvcBrcFrameType
50     {
51         P_FRAME  = 0,
52         B_FRAME  = 1,
53         I_FRAME  = 2,
54         B1_FRAME = 3,
55         B2_FRAME = 4,
56     };
57 
58 public:
59     AvcEncodeBRC(MediaFeatureManager *featureManager,
60                  EncodeAllocator *allocator,
61                  CodechalHwInterfaceNext *hwInterface,
62                  void *constSettings);
63 
64     virtual ~AvcEncodeBRC();
65 
66     //!
67     //! \brief  Init cqp basic features related parameter
68     //! \param  [in] settings
69     //!         Pointer to settings
70     //! \return MOS_STATUS
71     //!         MOS_STATUS_SUCCESS if success, else fail reason
72     //!
73     MOS_STATUS Init(void *settings) override;
74 
75     //!
76     //! \brief  Update cqp basic features related parameter
77     //! \param  [in] params
78     //!         Pointer to parameters
79     //! \return MOS_STATUS
80     //!         MOS_STATUS_SUCCESS if success, else fail reason
81     //!
82     MOS_STATUS Update(void *params) override;
83 
84     //!
85     //! \brief    Disable Brc Init and Reset after BRC update
86     //!
DisableBrcInitReset()87     void DisableBrcInitReset() { m_brcInit = m_brcReset = false; }
88 
89     //!
90     //! \brief    Enable VDEnc single pass
91     //!
EnableVdencSinglePass()92     void EnableVdencSinglePass() { m_vdencSinglePassEnable = true; }
93 
94     //!
95     //! \brief    Check if BRC Init enabled
96     //!
97     //! \return   bool
98     //!           true if BRC Init enabled, else Brc Init disabled.
99     //!
IsBRCInit()100     bool IsBRCInit() { return m_brcInit; }
101 
102     //!
103     //! \brief    Check if BRC Reset enabled
104     //!
105     //! \return   bool
106     //!           true if BRC Reset enabled, else BRC Reset disabled.
107     //!
IsBRCInitRequired()108     virtual bool IsBRCInitRequired() { return m_vdencBrcEnabled & (m_brcInit || m_brcReset); }
109 
110     //!
111     //! \brief    Check if BRC Update enabled
112     //!
113     //! \return   bool
114     //!           true if BRC Reset enabled, else BRC Reset disabled.
115     //!
IsBRCUpdateRequired()116     virtual bool IsBRCUpdateRequired() { return m_vdencBrcEnabled; }
117 
118     //!
119     //! \brief    Check whether VDEnc BRC enabled
120     //!
121     //! \return   bool
122     //!           true if VDEnc BRC enabled, otherwise false.
123     //!
IsVdencBrcEnabled()124     virtual bool IsVdencBrcEnabled() { return m_vdencBrcEnabled; }
125 
126     //!
127     //! \brief    Check whether VDEnc BRC is supported
128     //!
129     //! \param    [in] params
130     //!           Pointer to AVC Sequence parameters
131     //! \return   bool
132     //!           true if VDEnc BRC is supported, otherwise false.
133     //!
134     bool IsVdencBrcSupported(PCODEC_AVC_ENCODE_SEQUENCE_PARAMS avcSeqParams);
135 
136     //!
137     //! \brief    Check whether MBBRC enabled
138     //!
139     //! \return   bool
140     //!           true if MBBRC enabled, otherwise false.
141     //!
IsMbBrcEnabled()142     virtual bool IsMbBrcEnabled()  { return m_mbBrcEnabled; }
143 
144     //!
145     //! \brief    Help function to check if the rate control method is BRC
146     //!
147     //! \param    [in] rc
148     //!           Rate control method
149     //!
150     //! \return   True if using BRC , else return false
151     //!
IsRateControlBrc(uint8_t rc)152     bool IsRateControlBrc(uint8_t rc)
153     {
154         return (rc == RATECONTROL_CBR) ||
155                (rc == RATECONTROL_VBR) ||
156                (rc == RATECONTROL_AVBR) ||
157                (rc == RATECONTROL_CQL) ||
158                (rc == RATECONTROL_VCM) ||
159                (rc == RATECONTROL_ICQ) ||
160                (rc == RATECONTROL_QVBR) ||
161                (rc == RATECONTROL_IWD_VBR);
162     }
163 
GetBatchBufferForVdencImgStat()164     PMHW_BATCH_BUFFER GetBatchBufferForVdencImgStat()  { return &m_batchBufferForVdencImgStat; }
165 
166     //!
167     //! \brief  Set Dmem buffer for brc Init
168     //! \param  [in] params
169     //!         Pointer to parameters
170     //! \return MOS_STATUS
171     //!         MOS_STATUS_SUCCESS if success, else fail reason
172     //!
173     MOS_STATUS SetDmemForInit(void *params);
174 
175     //!
176     //! \brief  Set Dmem buffer for brc update
177     //! \param  [in] params
178     //!         Pointer to parameters
179     //! \param  [in] currPass
180     //!         Current pass number
181     //! \return MOS_STATUS
182     //!         MOS_STATUS_SUCCESS if success, else fail reason
183     //!
184     MOS_STATUS SetDmemForUpdate(void *params, uint16_t currPass, bool bIsLastPass);
185 
186     virtual MOS_STATUS FillHucConstData(uint8_t *data, uint8_t pictureType);
187 
188     //!
189     //! \brief    Add params to read the MFC status
190     //!
191     //! \param    params
192     //!           [out] the parameters for Mfc status read
193     //!
194     //! \return   MOS_STATUS
195     //!           MOS_STATUS_SUCCESS if success, else fail reason
196     //!
197     MOS_STATUS SetMfcStatusParams(EncodeStatusReadParams &params);
198 
199     virtual MOS_STATUS SaveBrcUpdateDmemBufferPtr(
200         PMOS_RESOURCE vdencBrcUpdateDmemBuffer0,
201         PMOS_RESOURCE vdencBrcUpdateDmemBuffer1);
202 
203     virtual MOS_STATUS SaveHucStatus2Buffer(PMOS_RESOURCE hucStatus2Buffer);
204 
GetHucStatus2Buffer()205     virtual PMOS_RESOURCE GetHucStatus2Buffer() { return m_hucStatus2BufferPtr; }
206 
GetAdaptiveRoundingNumSlices()207     uint16_t GetAdaptiveRoundingNumSlices() const { return static_cast<uint16_t>(m_basicFeature->m_numSlices); }
208 
209     uint32_t GetVdencBRCImgStateBufferSize();
210 
211     uint32_t GetVdencOneSliceStateSize();
212 
213     bool IsBPyramidWithGoldenBGOP();
214 
215     MHW_SETPAR_DECL_HDR(VDENC_PIPE_MODE_SELECT);
216     MHW_SETPAR_DECL_HDR(HUC_VIRTUAL_ADDR_STATE);
217 
218 #if _SW_BRC
219     std::shared_ptr<EncodeSwBrc> m_swBrc = nullptr;
220 #endif
221 
222 protected:
223     //! \brief  Allocate feature related resources
224     //! \return MOS_STATUS
225     //!         MOS_STATUS_SUCCESS if success, else fail reason
226     //!
227     virtual MOS_STATUS AllocateResources() override;
228 
229     //!
230     //! \brief  Free resources
231     //! \return MOS_STATUS
232     //!         MOS_STATUS_SUCCESS if success, else fail reason
233     //!
234     virtual MOS_STATUS FreeBrcResources();
235 
236     MOS_STATUS SetSequenceStructs();
237 
238     void SetMbBrc();
239 
240     virtual MOS_STATUS LoadConstTable0(uint8_t constTable[8][42]);
241     virtual MOS_STATUS LoadConstTable3(uint8_t pictureType, uint8_t ConstTable3[42]);
242     virtual MOS_STATUS LoadConstTable5(uint8_t pictureType, uint16_t ConstTable5[42]);
243     virtual MOS_STATUS LoadConstTable6(uint8_t pictureType, uint16_t ConstTable6[42]);
244     virtual MOS_STATUS LoadConstTable7(uint8_t pictureType, uint8_t ConstTable7[42]);
245     virtual MOS_STATUS LoadConstTable8(uint8_t pictureType, uint8_t ConstTable8[42]);
246 
247     //!
248     //! \brief    VDENC Compute BRC Init QP..
249     //! \return   initQP
250     //!
251     int32_t ComputeBRCInitQP();
252 
253     MOS_STATUS DeltaQPUpdate(uint8_t qpModulationStrength, bool bIsLastPass);
254 
255     void SetFrameTypeForUpdate(VdencAvcHucBrcUpdateDmem *dmem, uint16_t currPass);
256 
257     void CalculateCurLvlInBGop(uint16_t curFrameIdxInBGop, uint16_t begin, uint16_t end, uint16_t curLvl, uint16_t &curOrder, uint16_t &retLvl);
258 
259     CodechalHwInterfaceNext    *m_hwInterface    = nullptr;
260     EncodeAllocator        *m_allocator      = nullptr;
261     AvcBasicFeature        *m_basicFeature   = nullptr;  //!< EncodeBasicFeature
262 
263     std::shared_ptr<mhw::vdbox::vdenc::Itf> m_vdencItf = nullptr;
264     std::shared_ptr<mhw::vdbox::mfx::Itf>   m_mfxItf   = nullptr;
265     std::shared_ptr<mhw::mi::Itf>           m_miItf    = nullptr;
266 
267     // Batch Buffers
268     MHW_BATCH_BUFFER       m_batchBufferForVdencImgStat = {}; //!< VDEnc image state batch buffers
269 
270     //!< One for 1st pass of next frame, and the other for the next pass of current frame.
271     PMOS_RESOURCE m_vdencBrcUpdateDmemBufferPtr[2] = {nullptr, nullptr};
272     PMOS_RESOURCE m_hucStatus2BufferPtr            = nullptr;
273 
274     uint8_t  m_rcMode = 0;
275 
276     bool m_brcInit                     = true;   //!< BRC init flag
277     bool m_brcReset                    = false;  //!< BRC reset flag
278     bool m_mbBrcEnabled                = false;  //!< MBBrc enable flag.
279     bool m_mbBrcUserFeatureKeyControl  = false;  //!< MBBRC user feature control enable flag.
280     bool m_vdencBrcEnabled             = false;  //!< Vdenc bitrate control enabled flag
281     bool m_vdencSinglePassEnable       = false;  //!< Enable VDEnc single pass
282     bool m_isFirstDeltaQPCalculation   = true;   //!< Check if it's first time delta qp modulation calculation
283 
284     double   m_dBrcInitCurrentTargetBufFullInBits = 0;  //!< BRC init current target buffer full in bits
285     double   m_dBrcInitResetInputBitsPerFrame     = 0;  //!< BrcInitReset Input Bits Per Frame
286     uint32_t m_brcInitPreviousTargetBufFullInBits = 0;  //!< BRC Init Previous Target Buffer Full In Bits
287     double   m_dBrcTargetSize                     = 0;  //!< BRC target size.
288     uint8_t  m_qpModulationStrength               = 0;  //!< Current QP modulation strength
289 
290     uint16_t m_frameIdxInBGop                     = 0;  //!< Current frame index in BGOP in encoding order
291 
292 #if (_DEBUG || _RELEASE_INTERNAL)
293     static const uint32_t m_bufferFulnessDataSize = 600;
294     uint32_t       m_bufferFulnessData_csv[m_bufferFulnessDataSize] = {};     //!< bufFulness for lpla. Read from file
295     bool           m_useBufferFulnessData       = false; //!< To force using bufFulness for lpla from input file
296 #endif
297 
298 MEDIA_CLASS_DEFINE_END(encode__AvcEncodeBRC)
299 };
300 
301 }  // namespace encode
302 
303 #endif  // !__ENCODE_AVC_BRC_H__
304