1 /*
2 * Copyright (c) 2018, 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_hevc_brc.h
24 //! \brief    Defines the common interface for hevc brc features
25 //!
26 #ifndef __ENCODE_HEVC_BRC_H__
27 #define __ENCODE_HEVC_BRC_H__
28 
29 #include "media_feature.h"
30 #include "encode_allocator.h"
31 #include "codec_hw_next.h"
32 #include "encode_recycle_resource.h"
33 #include "encode_basic_feature.h"
34 #include "mhw_vdbox_vdenc_itf.h"
35 #include "mhw_vdbox_hcp_itf.h"
36 #include "mhw_vdbox_huc_itf.h"
37 
38 namespace encode
39 {
40     //!
41     //! \struct    CodechalVdencHevcPakInfo
42     //! \brief     Codechal Vdenc HEVC Pak info
43     //!
44     struct CodechalVdencHevcPakInfo
45     {
46         uint32_t  FrameByteCount;
47         uint8_t   PAKPassNum;
48     };
49 
50     //!
51     //! \struct    HevcVdencBrcBuffers
52     //! \brief     Hevc Vdenc brc buffers
53     //!
54     struct HevcVdencBrcBuffers
55     {
56         PMOS_RESOURCE resBrcPakStatisticBuffer[CODECHAL_ENCODE_RECYCLED_BUFFER_NUM];
57         uint32_t     currBrcPakStasIdxForRead;
58         uint32_t     currBrcPakStasIdxForWrite;
59     };
60 
61     struct VdencHevcHucBrcInitDmem
62     {
63         uint32_t BRCFunc_U32;   // 0: Init; 2: Reset, bit7 0: frame-based; 1: tile-based
64         uint32_t UserMaxFrame;  // ProfileLevelMaxFrame_U32
65         uint32_t InitBufFull_U32;
66         uint32_t BufSize_U32;
67         uint32_t TargetBitrate_U32;
68         uint32_t MaxRate_U32;
69         uint32_t MinRate_U32;
70         uint32_t FrameRateM_U32;
71         uint32_t FrameRateD_U32;
72         uint32_t LumaLog2WeightDenom_U32;
73         uint32_t ChromaLog2WeightDenom_U32;
74         uint8_t  BRCFlag : 7;  // ACQP/ICQ=0, CBR=1, VBR=2, VCM=3, LOWDELAY=4
75         uint8_t  SSCFlag : 1;  // SSC: 0x80
76         uint8_t  Reserved;
77         uint16_t GopP_U16;
78         uint16_t GopB_U16;
79         uint16_t FrameWidth_U16;
80         uint16_t FrameHeight_U16;
81         uint16_t GopB1_U16;
82         uint16_t GopB2_U16;
83         uint8_t  MinQP_U8;
84         uint8_t  MaxQP_U8;
85         uint8_t  MaxBRCLevel_U8;
86         uint8_t  LumaBitDepth_U8;
87         uint8_t  ChromaBitDepth_U8;
88         uint8_t  CuQpCtrl_U8;  // 0=No CUQP; 1=CUQP for I-frame; 2=CUQP for P/B-frame
89 
90         uint8_t RSVD0[4];
91         int8_t  DevThreshPB0_S8[8];
92         int8_t  DevThreshVBR0_S8[8];
93         int8_t  DevThreshI0_S8[8];
94         int8_t  InstRateThreshP0_S8[4];
95         int8_t  InstRateThreshB0_S8[4];
96         int8_t  InstRateThreshI0_S8[4];
97         uint8_t LowDelayMode_U8;
98         uint8_t InitQPIP_U8;
99         uint8_t InitQPB_U8;  // In CQP mode, InitQPB_U8= InitQPIP_U8
100         uint8_t QPDeltaThrForAdapt2Pass_U8;
101         uint8_t TopFrmSzThrForAdapt2Pass_U8;
102         uint8_t BotFrmSzThrForAdapt2Pass_U8;
103         uint8_t QPSelectForFirstPass_U8;
104         uint8_t MBHeaderCompensation_U8;
105         uint8_t OverShootCarryFlag_U8;
106         uint8_t OverShootSkipFramePct_U8;
107         uint8_t EstRateThreshP0_U8[7];
108         uint8_t EstRateThreshB0_U8[7];
109 
110         uint8_t  EstRateThreshI0_U8[7];
111         uint8_t  QPP_U8;
112         uint8_t  StreamInSurfaceEnable_U8;       // 0-disabled, 1-enabled
113         uint8_t  StreamInROIEnable_U8;           // 0-disabled, 1-enabled
114         uint8_t  TimingBudget_Enable_U8;         // 0-disabled, 1-enabled
115         uint8_t  TopQPDeltaThrForAdapt2Pass_U8;  // 2
116         uint8_t  BotQPDeltaThrForAdapt2Pass_U8;  // 1
117         uint8_t  RESERVED;
118         uint8_t  NetworkTraceEnable_U8;                   // 0-disabled, 1-enabled
119         uint8_t  LowDelaySceneChangeXFrameSizeEnable_U8;  // 0-disabled, 1-enabled
120         uint32_t ACQP_U32;                                // 1
121         uint32_t SlidingWindow_Size_U32;                  // 30
122 
123         uint8_t SLIDINGWINDOW_MaxRateRatio;
124         uint8_t LookaheadDepth_U8;
125         int8_t  CbQPOffset;
126         int8_t  CrQPOffset;
127 
128         uint32_t ProfileLevelMaxFramePB_U32;
129 
130         // tile-based BRC
131         uint16_t SlideWindowRC;  // Reserved now
132         uint16_t MaxLogCUSize;
133 
134         uint16_t FrameWidthInLCU;
135         uint16_t FrameHeightInLCU;
136 
137         uint8_t  BRCPyramidEnable_U8;
138         uint8_t  LongTermRefEnable_U8;
139         uint16_t LongTermRefInterval_U16;
140         uint8_t  LongTermRefMsdk_U8;
141         uint8_t  IsLowDelay_U8;
142         uint16_t RSVD3;
143         uint32_t RSVD1[4];  // 64 bytes aligned
144     };
145     C_ASSERT(192 == sizeof(VdencHevcHucBrcInitDmem));
146 
147     //!
148     //! \struct    EncodeReadBrcPakStatsParams
149     //! \brief     Encode read brc pak states parameters
150     //!
151     struct EncodeReadBrcPakStatsParams
152     {
153         CodechalHwInterfaceNext    *pHwInterface;
154         PMOS_RESOURCE           presBrcPakStatisticBuffer;
155         PMOS_RESOURCE           presStatusBuffer;
156         uint32_t                dwStatusBufNumPassesOffset;
157         uint8_t                 ucPass;
158         MOS_GPU_CONTEXT         VideoContext;
159     };
160 
161     class HEVCEncodeBRC : public MediaFeature, public mhw::vdbox::vdenc::Itf::ParSetting, public mhw::vdbox::hcp::Itf::ParSetting, public mhw::vdbox::huc::Itf::ParSetting
162     {
163     public:
164         HEVCEncodeBRC(MediaFeatureManager *featureManager, EncodeAllocator *allocator, CodechalHwInterfaceNext *hwInterface, void *constSettings);
165 
166         virtual ~HEVCEncodeBRC();
167 
168         //!
169         //! \brief  Init cqp basic features related parameter
170         //! \param  [in] settings
171         //!         Pointer to settings
172         //! \return MOS_STATUS
173         //!         MOS_STATUS_SUCCESS if success, else fail reason
174         //!
175         MOS_STATUS Init(void *settings) override;
176 
177         //!
178         //! \brief  Update cqp basic features related parameter
179         //! \param  [in] params
180         //!         Pointer to parameters
181         //! \return MOS_STATUS
182         //!         MOS_STATUS_SUCCESS if success, else fail reason
183         //!
184         MOS_STATUS Update(void *params) override;
185 
186         //!
187         //! \brief    Set ACQP status
188         //!
189         //! \param    [in]bool
190         //!           expected ACQP status
191         //!
SetACQPStatus(bool isEnabled)192         void SetACQPStatus(bool isEnabled) { m_hevcVDEncAcqpEnabled = isEnabled; }
193 
194         //!
195         //! \brief    Check if ACQP enabled
196         //!
197         //! \return   bool
198         //!           true if ACQP enabled, else ACQP disabled.
199         //!
IsACQPEnabled()200         bool IsACQPEnabled() { return m_hevcVDEncAcqpEnabled; }
201 
RateControlMethod()202         uint8_t RateControlMethod(){ return m_rcMode; }
203 
204         //!
205         //! \brief    Check if BRC enabled
206         //!
207         //! \return   bool
208         //!           true if BRC enabled, else BRC disabled.
209         //!
IsBRCEnabled()210         bool IsBRCEnabled() { return m_brcEnabled; }
211 
212         //!
213         //! \brief    Disable Brc Init and Reset after BRC update
214         //!
DisableBrcInitReset()215         void DisableBrcInitReset() { m_brcInit = m_brcReset = false; };
216 
217         //!
218         //! \brief    Check if BRC Init enabled
219         //!
220         //! \return   bool
221         //!           true if BRC Init enabled, else Brc Init disabled.
222         //!
IsBRCInit()223         bool IsBRCInit() { return m_brcInit; }
224 
225         //!
226         //! \brief    Check if BRC Reset enabled
227         //!
228         //! \return   bool
229         //!           true if BRC Reset enabled, else BRC Reset disabled.
230         //!
IsBRCInitRequired()231         virtual bool IsBRCInitRequired()        { return m_vdencHucUsed & (m_brcInit || m_brcReset); }
232 
233         //!
234         //! \brief    Check if BRC Update enabled
235         //!
236         //! \return   bool
237         //!           true if BRC Reset enabled, else BRC Reset disabled.
238         //!
IsBRCUpdateRequired()239         virtual bool IsBRCUpdateRequired() { return m_vdencHucUsed; }
240 
241         //!
242         //! \brief    Check whether VDEnc HuC using
243         //!
244         //! \return   bool
245         //!           true if VDEnc HuC using, otherwise false.
246         //!
IsVdencHucUsed()247         bool IsVdencHucUsed() const { return m_vdencHucUsed; }
248 
249         //!
250         //! \brief    Help function to check if the rate control method is BRC
251         //!
252         //! \param    [in] rc
253         //!           Rate control method
254         //!
255         //! \return   True if using BRC , else return false
256         //!
IsRateControlBrc(uint8_t rc)257         bool IsRateControlBrc(uint8_t rc)
258         {
259             return (rc == RATECONTROL_CBR) ||
260                    (rc == RATECONTROL_VBR) ||
261                    (rc == RATECONTROL_AVBR) ||
262                    (rc == RATECONTROL_VCM) ||
263                    (rc == RATECONTROL_QVBR) ||
264                    (rc == RATECONTROL_ICQ);
265         }
266 
GetVdenc2ndLevelBatchBuffer(uint32_t currRecycledBufIdx)267         PMHW_BATCH_BUFFER GetVdenc2ndLevelBatchBuffer(uint32_t currRecycledBufIdx) {
268             return &m_vdenc2ndLevelBatchBuffer[currRecycledBufIdx];
269         };
270 
271         MOS_STATUS GetBrcDataBuffer(MOS_RESOURCE *&buffer);
272 
273         //!
274         //! \brief  Set Dmem buffer for brc update
275         //! \param  [in] params
276         //!         Pointer to parameters
277         //! \return MOS_STATUS
278         //!         MOS_STATUS_SUCCESS if success, else fail reason
279         //!
280         MOS_STATUS SetDmemForUpdate(void *params);
281 
282         //!
283         //! \brief  Set Const data for brc update
284         //! \param  [in] params
285         //!         Pointer to parameters
286         //! \return MOS_STATUS
287         //!         MOS_STATUS_SUCCESS if success, else fail reason
288         //!
289         MOS_STATUS SetConstForUpdate(void *params);
290 
291         //!
292         //! \brief  Set Const Lambda data for brc update
293         //! \param  [in] params
294         //!         Pointer to parameters
295         //! \param  [in] lambdaType
296         //!         Indicate whether to use depth based calculation
297         //! \return MOS_STATUS
298         //!         MOS_STATUS_SUCCESS if success, else fail reason
299         //!
300         MOS_STATUS SetConstLambdaForUpdate(void *params, bool lambdaType = false);
301 
302         MOS_STATUS SetHevcDepthBasedLambda(
303             PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS hevcSeqParams,
304             PCODEC_HEVC_ENCODE_PICTURE_PARAMS  hevcPicParams,
305             uint8_t                            qp,
306             uint16_t &                         SADQPLambda,
307             uint16_t &                         RDQPLambda);
308 
309         //!
310         //! \brief  Set Dmem buffer for brc Init
311         //! \param  [in] params
312         //!         Pointer to parameters
313         //! \return MOS_STATUS
314         //!         MOS_STATUS_SUCCESS if success, else fail reason
315         //!
316         MOS_STATUS SetDmemForInit(void *params);
317 
318         //!
319         //! \brief    Read stats for BRC from PAK
320         //!
321         //! \param    [in] ucPass
322         //!            current pass number
323         //! \param    [in] offset
324         //!            number pass offset in status buffer
325         //! \param    [in] osResource
326         //!            Pointer to resource of status buffer
327         //! \param    [in] cmdBuffer
328         //!            Pointer to command buffer
329         //!
330         //! \return   MOS_STATUS
331         //!           MOS_STATUS_SUCCESS if success, else fail reason
332         //!
333         virtual MOS_STATUS SetReadBrcPakStatsParams(
334             uint8_t                      ucPass,
335             uint32_t                     offset,
336             PMOS_RESOURCE                osResource,
337             EncodeReadBrcPakStatsParams &readBrcPakStatsParams);
338 
GetHevcVdencBrcBuffers()339         HevcVdencBrcBuffers* GetHevcVdencBrcBuffers()
340         {
341             return &m_vdencBrcBuffers;
342         };
343 
GetHevcVdenc2ndLevelBatchBuffer(uint32_t currRecycledBufIdx)344         PMOS_RESOURCE GetHevcVdenc2ndLevelBatchBuffer(uint32_t currRecycledBufIdx)
345         {
346             return &m_vdenc2ndLevelBatchBuffer[currRecycledBufIdx].OsResource;
347         };
348 
349         MOS_STATUS SetVdencBatchBufferState(
350             const uint32_t    currRecycledBufIdx,
351             const uint32_t    slcIdx,
352             PMHW_BATCH_BUFFER &vdencBatchBuffer,
353             bool &            vdencHucUsed);
354 
355         MHW_SETPAR_DECL_HDR(VDENC_PIPE_MODE_SELECT);
356 
357         MHW_SETPAR_DECL_HDR(VDENC_CMD2);
358 
359         MHW_SETPAR_DECL_HDR(HCP_PIPE_MODE_SELECT);
360 
361         MHW_SETPAR_DECL_HDR(HUC_VIRTUAL_ADDR_STATE);
362 
363         MOS_STATUS SetCurrRecycledBufIdx(const uint8_t index);
364 
365     protected:
366         //! \brief  Allocate feature related resources
367         //! \return MOS_STATUS
368         //!         MOS_STATUS_SUCCESS if success, else fail reason
369         //!
370         virtual MOS_STATUS AllocateResources() override;
371 
372         //!
373         //! \brief  Update feature related resources
374         //! \return MOS_STATUS
375         //!         MOS_STATUS_SUCCESS if success, else fail reason
376         //!
377         virtual MOS_STATUS UpdateBrcResources(void *params);
378 
379         //!
380         //! \brief  Free resources
381         //! \return MOS_STATUS
382         //!         MOS_STATUS_SUCCESS if success, else fail reason
383         //!
384         virtual MOS_STATUS FreeBrcResources();
385 
386         MOS_STATUS SetBrcSettings(void *params);
387 
388         MOS_STATUS SetAcqpSettings(void *params);
389 
390         void ComputeVDEncInitQP(int32_t& initQPIP, int32_t& initQPB);
391 
392         void SetLcuBrc();
393 
394         MOS_STATUS SetSequenceStructs();
395 
396         // const data
397         static constexpr uint32_t m_brcHistoryBufSize       = 6092;  //!< BRC history buffer size
398         static constexpr uint32_t m_vdencBRCStatsBufferSize = 1216;  //!< Vdenc bitrate control buffer size
399         static constexpr uint32_t m_deltaQpRoiBufferSize    = 65536;
400         static constexpr uint32_t m_brcDebugBufSize         = 0x1000;                          //!< BRC debug buffer size
401         static constexpr uint32_t m_roiStreamInBufferSize   = 65536 * CODECHAL_CACHELINE_SIZE; //!< ROI Streamin buffer size (part of BRC Update)
402 
403         const uint32_t m_brc_kbps = 1000;     // 1000bps for disk storage, aligned with industry usage
404 
405         CodechalHwInterfaceNext  *m_hwInterface  = nullptr;
406         EncodeAllocator      *m_allocator    = nullptr;
407         HevcBasicFeature     *m_basicFeature = nullptr;  //!< EncodeBasicFeature
408 
409         uint8_t  m_rcMode         = 0;
410 
411         bool m_brcInit              = true;   //!< BRC init flag
412         bool m_brcReset             = false;  //!< BRC reset flag
413         bool m_brcEnabled           = false;  //!< BRC enable flag
414         bool m_lcuBrcEnabled        = false;  //!< LCU BRC enable flag
415         bool m_hevcVDEncAcqpEnabled = false;  //!< ACQP enable flag
416         bool m_vdencBrcEnabled      = false;  //!< Vdenc bitrate control enabled flag
417         bool m_vdencHucUsed         = false;  //!< HUC usage flag
418         bool m_fastPakEnable        = true;
419 
420         //Resources
421         MHW_BATCH_BUFFER m_vdenc2ndLevelBatchBuffer[CODECHAL_ENCODE_RECYCLED_BUFFER_NUM] = {};  //!< VDEnc 2nd level batch buffer
422         MOS_RESOURCE     m_vdencOutputROIStreaminBuffer                                  = {};  //!< VDEnc Output ROI Streamin Buffer
423         MOS_RESOURCE     m_vdencBrcDbgBuffer                                             = {};  //!< VDEnc brc debug buffer
424         MOS_RESOURCE        m_resBrcDataBuffer                                           = {};  //!< Resource of bitrate control data buffer, only as an output of PAKintegrate Kernel
425         HevcVdencBrcBuffers m_vdencBrcBuffers                                            = {};  //!< VDEnc Brc buffers
426         uint16_t           *m_rdLambdaArray                                              = nullptr;
427         uint16_t           *m_sadLambdaArray                                             = nullptr;
428 
429         MHW_VDBOX_NODE_IND m_vdboxIndex = MHW_VDBOX_NODE_1;
430         uint32_t           m_currRecycledBufIdx = 0;
431 
432     MEDIA_CLASS_DEFINE_END(encode__HEVCEncodeBRC)
433     };
434 
435 }  // namespace encode
436 
437 #endif  // !__ENCODE_HEVC_BRC_H__
438