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