1 /*
2 * Copyright (c) 2018-2024, 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_status_report.h
24 //! \brief    Defines the class for encode status report
25 //! \details
26 //!
27 #ifndef __ENCODE_STATUS_REPORT_H__
28 #define __ENCODE_STATUS_REPORT_H__
29 
30 #include "media_status_report.h"
31 #include "encode_status_report_defs.h"
32 #include "encode_utils.h"
33 #include "encode_allocator.h"
34 #include "codec_def_common_encode.h"
35 #include "media_status_report.h"
36 
37 namespace encode {
38 
39     //!
40     //! \struct EncodeStatusReportData
41     //! \brief  Encode status report structure
42     //!
43     struct EncodeStatusReportData
44     {
45         enum BLOCK_SIZE
46         {
47             BLOCK_4X4   = 0,
48             BLOCK_16X16 = 1,
49         };
50 
51         struct FRAME_STATS_INFO
52         {
53             float    PSNRLuma;
54             float    PSNRCb;
55             float    PSNRCr;
56             uint64_t SADLuma;
57             float    Qp;
58 
59             union
60             {
61                 uint32_t NumMB;
62                 uint32_t NumCTU;
63             };
64 
65             BLOCK_SIZE BlockSize;
66             uint32_t   NumIntraBlock;
67             uint32_t   NumInterBlock;
68             uint32_t   NumSkippedBlock;
69             uint32_t   reserved[8];
70         };
71 
72         struct CTUHeader
73         {
74             union
75             {
76                 struct
77                 {
78                     uint32_t CUcountminus1 : 6;
79                     uint32_t MaxDepth : 2;
80                     uint32_t reserved : 24;
81                 };
82                 uint32_t DW0;
83             };
84             uint16_t CurrXAddr;
85             uint16_t CurrYAddr;
86             uint32_t reserved1;
87         };
88 
89         struct Int16Pair
90         {
91             int16_t x;
92             int16_t y;
93         };
94 
95         struct CUInfo
96         {
97             union
98             {
99                 struct
100                 {
101                     uint32_t CU_Size : 2;
102                     uint32_t CU_pred_mode : 1;
103                     uint32_t CU_part_mode : 3;
104                     uint32_t InterPred_IDC_MV0 : 2;
105                     uint32_t InterPred_IDC_MV1 : 2;
106                     uint32_t LumaIntraMode : 6;
107                     uint32_t ChromaIntraMode : 3;
108                     uint32_t reserved : 13;
109                 };
110                 uint32_t DW0;
111             };
112 
113             union
114             {
115                 struct
116                 {
117                     uint32_t LumaIntraMode4x4_1 : 6;
118                     uint32_t LumaIntraMode4x4_2 : 6;
119                     uint32_t LumaIntraMode4x4_3 : 6;
120                     uint32_t reserved1 : 14;
121                 };
122                 uint32_t DW1;
123             };
124 
125             int8_t   QP;
126             uint8_t  reserved2[3];
127             uint32_t SAD;
128 
129             Int16Pair MV[2][2];
130 
131             union
132             {
133                 struct
134                 {
135                     uint32_t L0_MV0_RefID : 4;
136                     uint32_t L0_MV1_RefID : 4;
137                     uint32_t L1_MV0_RefID : 4;
138                     uint32_t L1_MV1_RefID : 4;
139                     uint32_t reserved3 : 16;
140                 };
141                 uint32_t DW8;
142             };
143 
144             uint32_t reserved4[10];
145         };
146 
147         struct CTUInfo
148         {
149             CTUHeader CtuHeader;
150             CUInfo    CuInfo[64];
151             uint32_t  reserved;
152         };
153 
154         struct MBInfo
155         {
156             union
157             {
158                 struct
159                 {
160                     uint32_t MBType : 5;
161                     uint32_t InterMBMode : 2;
162                     uint32_t IntraMBMode : 2;
163                     uint32_t IntraMBFlag : 1;
164                     uint32_t SubMBShapes : 8;
165                     uint32_t SubMBShapeMode : 8;
166                     uint32_t ChromaIntraPredMode : 2;
167                     uint32_t reserved : 4;
168                 };
169                 uint32_t DW0;
170             };
171 
172             uint32_t SAD;
173             int8_t   Qp;
174             uint8_t  reserved1[3];
175 
176             uint16_t LumaIntraMode[4];
177 
178             uint32_t reserved2;
179         };
180 
181         struct BLOCK_STATS_INFO
182         {
183             union
184             {
185                 uint32_t NumMB;
186                 uint32_t NumCTU;
187             };
188 
189             union
190             {
191                 CTUInfo *HEVCCTUArray;
192                 MBInfo  *AVCMBArray;
193             };
194 
195             uint32_t reserved[8];
196         };
197 
198         struct BLOCK_SSIM_INFO
199         {
200             uint32_t NumBlockInColumns;
201             uint32_t NumBlockInRows;
202             uint8_t* BlockSsimArray;
203             uint32_t reserved1[2];
204             uint64_t reserved2[2];
205         };
206 
207         struct BLOCK_QUALITY_INFO
208         {
209             BLOCK_SSIM_INFO BlockSsim2DS;
210             BLOCK_SSIM_INFO BlockSsim4DS;
211             BLOCK_SSIM_INFO BlockSsim8DS;
212             BLOCK_SSIM_INFO BlockSsim16DS;
213             uint32_t        reserved1[32];
214             uint64_t        reserved2[12];
215         };
216 
217         CODECHAL_STATUS                 codecStatus;            //!< Status for the picture associated with this status report
218         uint32_t                        statusReportNumber;     //!< Status report number associated with the picture in this status report provided in CodechalEncoderState::Execute()
219         CODEC_PICTURE                   currOriginalPic;        //!< Uncompressed frame information for the picture associated with this status report
220         CODECHAL_ENCODE_FUNCTION_ID     func;                   //!< Encode function requested at CodechalEncoderState::Execute()
221         const void                      *currRefList;           //!< Reference list for the current frame, used for dump purposes with CodecHal Debug Tool
222                                                                 /*! \brief Specifies the order in which the statuses are expected.
223                                                                 *
224                                                                 *   The order in which a status is returned is requested at the DDI level and the order itself is determined by StatusReportNumber.
225                                                                 *       FALSE indicates the statuses should be returned in reverse order.
226                                                                 *       TRUE indicates the statuses should be returned in sequential order.
227                                                                 */
228         bool                            sequential;
229         /*! \brief Coded bitstream size reported by HW.
230         *
231         *   The size reported by HW is the total bitstream size that is encoded by HW including any bitstream buffer overrun.  That is, HW continues counting the encoded bytes past the programmed upperbound based on the allocated bitstream buffer size.  The framework can compare this value to the allocated buffer size to determine if there was overflow for this frame and can act accordingly.
232         */
233         uint32_t                        bitstreamSize;
234         /*! \brief Qp value for Y used for the first PAK pass.
235         *
236         *   It is not valid if CQP is set by framework.
237         */
238         int8_t                          qpY;
239         /*! \brief Suggested Qp delta value for Y.
240         *
241         *   Framework can add this delta Qp with the first pass QpY to get the final Qp used for multi-pass.  It is not valid if CQP is set by framework.
242         *   Note: Framework can use this reported QpY and suggestedQpYDelta to set QpY in picture parameter to minimize LCU level Qp delta.
243         */
244         int8_t                          suggestedQPYDelta;
245         uint8_t                         numberPasses;       //!< Number of PAK passes executed.
246         uint8_t                         averageQP;          //!< The average QP of all MBs or LCUs of the frame.
247         HwCounter                       hwCounterValue;
248         uint64_t *                      hwCtr;
249 
250         union
251         {
252             struct
253             {
254                 uint32_t panicMode              : 1;    //!< Indicates that panic mode was triggered by HW for this frame.
255                 uint32_t sliceSizeOverflow      : 1;    //!< When SliceLevelRateCtrl is used, indicates the requested slice size was not met for one or more generated slices.
256                 uint32_t numSlicesNonCompliant  : 1;    //!< When SliceLevelRateCtrl is used, indicates whether or not the number of generated slices exceeds specification limits.
257                 uint32_t longTermReference      : 1;
258                 uint32_t frameSkipped           : 1;
259                 uint32_t sceneChangeDetected    : 1;
260                 uint32_t                        : 26;
261             };
262             uint32_t queryStatusFlags;
263         };
264         /*! \brief The average MAD (Mean Absolute Difference) across all macroblocks in the Y plane.
265         *
266         *    The MAD value is the mean of the absolute difference between the pixels in the original block and the corresponding pixels in the block being used for comparison, from motion compensation or intra spatial prediction. MAD reporting is disabled by default.
267         */
268         uint32_t                        mad;
269         uint32_t                        loopFilterLevel;        //!< [VP9]
270         int8_t                          longTermIndication;     //!< [VP9]
271         uint16_t                        nextFrameWidthMinus1;   //!< [VP9]
272         uint16_t                        nextFrameHeightMinus1;  //!< [VP9]
273         uint8_t                         numberSlices;           //!< Number of slices generated for the frame.
274         uint16_t                        psnrX100[3];            //!< PSNR for different channels
275         uint32_t                        numberTilesInFrame;     //!< Number of tiles generated for the frame.
276         uint8_t                         usedVdBoxNumber;        //!< Number of vdbox used.
277         uint32_t                        sizeOfSliceSizesBuffer; //!< Store the size of slice size buffer
278         uint16_t                        *sliceSizes;           //!< Pointer to the slice size buffer
279         uint32_t                        sizeOfTileInfoBuffer;   //!< Store the size of tile info buffer
280         CodechalTileInfo*               hevcTileinfo;          //!< Pointer to the tile info buffer
281         uint32_t                        numTileReported;        //!< The number of tiles reported in status
282 
283         /*! \brief indicate whether it is single stream encoder or MFE.
284         *
285         *    For single stream encoder (regular), this value should be set to default 0. For Multi-Frame-Encoder (MFE), this value is the StreamId that is set by application.
286         */
287         uint32_t                        streamId;
288 
289         LookaheadReport                 *pLookaheadStatus;     //!< Pointer to the lookahead status buffer. Valid in lookahead pass only.
290 
291         FRAME_STATS_INFO *pFrmStatsInfo;
292         BLOCK_STATS_INFO *pBlkStatsInfo;
293 
294         // Store Data for Av1 Back Annotation
295         uint32_t                        av1FrameHdrOBUSizeByteOffset;
296         uint32_t                        av1EnableFrameOBU;
297         uint32_t                        frameWidth;
298         uint32_t                        frameHeight;
299 
300         uint32_t                        MSE[3];
301 
302         BLOCK_QUALITY_INFO* pBlkQualityInfo;
303     };
304 
305     class EncoderStatusReport : public MediaStatusReport
306     {
307     public:
308         //!
309         //! \brief  Constructor
310         //! \param  [in] hwInterface
311         //!         Pointer to CodechalHwInterface
312         //! \param  [in] allocator
313         //!         Pointer to EncodeAllocator
314         //! \param  [in] enableMfx
315         //!         Enable Mfx status buffer contarol if true
316         //! \param  [in] enableRcs
317         //!         Enable Rcs status buffer contarol if true
318         //!
319         EncoderStatusReport(EncodeAllocator *allocator, PMOS_INTERFACE pOsInterface, bool enableMfx, bool enableRcs, bool enableCp);
320         virtual ~EncoderStatusReport();
321 
322         //!
323         //! \brief  Create resources for status report and do initialization
324         //! \return MOS_STATUS
325         //!         MOS_STATUS_SUCCESS if success, else fail reason
326         //!
327         virtual MOS_STATUS Create() override;
328         //!
329         //! \brief  Destroy resources for status report
330         //! \return MOS_STATUS
331         //!         MOS_STATUS_SUCCESS if success, else fail reason
332         //!
333         MOS_STATUS Destroy();
334         //!
335         //! \brief  Initialize the status in report for each item
336         //!
337         //! \details Called per frame for normal usages.
338         //!          It can be called per tilerow if enable tile replay mode.
339         //!
340         //! \param  [in] inputPar
341         //!         Pointer to parameters pass to status report.
342         //! \return MOS_STATUS
343         //!         MOS_STATUS_SUCCESS if success, else fail reason
344         //!
345         virtual MOS_STATUS Init(void *inputPar) override;
346         //!
347         //! \brief  Reset Status
348         //!
349         //! \details Called per frame for normal usages.
350         //!          It can be called per tilerow if enable tile replay mode.
351         //!
352         //! \return MOS_STATUS
353         //!         MOS_STATUS_SUCCESS if success, else fail reason
354         //!
355         virtual MOS_STATUS Reset() override;
356 
357         virtual PMOS_RESOURCE GetHwCtrBuf();
358 
359     protected:
360         //!
361         //! \brief  Collect the status report information into report buffer.
362         //! \param  [in] report
363         //!         The report buffer address provided by DDI.
364         //! \param  [in] index
365         //!         The index of current requesting report.
366         //! \return MOS_STATUS
367         //!         MOS_STATUS_SUCCESS if success, else fail reason
368         //!
369         virtual MOS_STATUS ParseStatus(void *report, uint32_t index) override;
370 
371         virtual MOS_STATUS SetStatus(void *report, uint32_t index, bool outOfRange = false) override;
372 
373         //!
374         //! \brief  Set offsets for Mfx status buffer.
375         //! \return void
376         //!
377         void SetOffsetsForStatusBufMfx();
378 
379         //!
380         //! \brief  Collect the common MFX status report data.
381         //! \param  [in] statusReportData
382         //!         The pointer to EncodeStatusReportData.
383         //! \param  [in] index
384         //!         The index of current requesting report.
385         //! \return MOS_STATUS
386         //!         MOS_STATUS_SUCCESS if success, else fail reason
387         //!
388         MOS_STATUS GetCommonMfxReportData(
389             EncodeStatusReportData *statusReportData,
390             uint32_t index);
391 
392         //!
393         //! \brief  Update the status result of current report.
394         //! \param  [in] statusReportData
395         //!         The pointer to EncodeStatusReportData.
396         //! \param  [in] encodeStatusRcs
397         //!         The RCS status report buffer.
398         //! \param  [in] completed
399         //!         Whether the request frame compelted.
400         //! \return MOS_STATUS
401         //!         MOS_STATUS_SUCCESS if success, else fail reason
402         //!
403         MOS_STATUS UpdateCodecStatus(
404             EncodeStatusReportData *statusReportData,
405             EncodeStatusRcs *encodeStatusRcs,
406             bool completed);
407 
408         //!
409         //! \brief  Get the index accroding the inputed codec function.
410         //! \param  [in] func
411         //!         The value of Codec Function
412         //! \return uint32_t
413         //!         Return pair index of CodecFuncToFuncIdPairs
414         //!
GetIdForCodecFuncToFuncIdPairs(uint32_t func)415         inline uint32_t GetIdForCodecFuncToFuncIdPairs(uint32_t func) const
416         {
417             uint32_t ret = 0;
418             while (func > 1)
419             {
420                 func >>= 1;
421                 ret++;
422             }
423 
424             return ret;
425         }
426 
427     protected:
428         EncodeStatusReportData m_statusReportData[m_statusNum] = {};
429         PMOS_INTERFACE         m_osInterface = nullptr;
430         bool                   m_enableMfx = false;
431         bool                   m_enableRcs = false;
432         bool                   m_enableCp  = false;
433 
434         const uint32_t         m_statusBufSizeMfx = MOS_ALIGN_CEIL(sizeof(EncodeStatusMfx), sizeof(uint64_t));
435         const uint32_t         m_statusBufSizeRcs = MOS_ALIGN_CEIL(sizeof(EncodeStatusRcs), sizeof(uint64_t));
436 
437         PMOS_RESOURCE          m_statusBufMfx = nullptr;
438         PMOS_RESOURCE          m_statusBufRcs = nullptr;
439         uint8_t                *m_dataStatusMfx = nullptr;
440         uint8_t                *m_dataStatusRcs = nullptr;
441         PMOS_RESOURCE           m_hwcounterBuf  = nullptr;
442         uint64_t *              m_hwcounter     = nullptr;
443         uint32_t *              m_hwcounterBase = nullptr;
444 
445         EncodeAllocator        *m_allocator = nullptr;  //!< encoder allocator
446 
447         bool                   m_hwWalker = false;
448         uint16_t               m_picWidthInMb = 0;
449         uint16_t               m_frameFieldHeightInMb = 0;
450         uint32_t               m_maxNumSlicesAllowed = 0;
451 
452         static const uint32_t  m_maxCodecFuncNum = 12;
453         static const uint32_t  m_codecFuncToFuncIdPairs[m_maxCodecFuncNum];
454 
455     MEDIA_CLASS_DEFINE_END(encode__EncoderStatusReport)
456     };
457 }
458 
459 #endif // !__ENCODE_STATUS_REPORT_H__
460