1 /* 2 * Copyright (c) 2018-2020, 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_vdenc_roi_strategy.h 24 //! \brief Defines of the ROI strategy 25 //! 26 27 #ifndef __CODECHAL_HEVC_VDENC_ROI_STRATEGY_H__ 28 #define __CODECHAL_HEVC_VDENC_ROI_STRATEGY_H__ 29 30 #include "encode_recycle_resource.h" 31 #include "encode_hevc_basic_feature.h" 32 #include "encode_hevc_brc.h" 33 #include "encode_hevc_vdenc_roi_overlap.h" 34 #include "encode_hevc_vdenc_const_settings.h" 35 #include "mhw_vdbox_huc_itf.h" 36 37 namespace encode 38 { 39 struct HevcVdencStreamInState 40 { 41 // DWORD 0 42 union 43 { 44 struct 45 { 46 uint32_t RoiCtrl : MOS_BITFIELD_RANGE(0, 7); 47 uint32_t MaxTuSize : MOS_BITFIELD_RANGE(8, 9); 48 uint32_t MaxCuSize : MOS_BITFIELD_RANGE(10, 11); 49 uint32_t NumImePredictors : MOS_BITFIELD_RANGE(12, 15); 50 uint32_t Reserved_0 : MOS_BITFIELD_RANGE(16, 20); 51 uint32_t ForceQPDelta : MOS_BITFIELD_BIT(21); 52 uint32_t PaletteDisable : MOS_BITFIELD_BIT(22); 53 uint32_t Reserved_1 : MOS_BITFIELD_BIT(23); 54 uint32_t PuTypeCtrl : MOS_BITFIELD_RANGE(24, 31); 55 }; 56 uint32_t Value; 57 } DW0; 58 59 // DWORD 1-4 60 union 61 { 62 struct 63 { 64 uint32_t ForceMvX : MOS_BITFIELD_RANGE(0, 15); 65 uint32_t ForceMvY : MOS_BITFIELD_RANGE(16, 31); 66 }; 67 uint32_t Value; 68 } DW1[4]; 69 70 // DWORD 5 71 union 72 { 73 struct 74 { 75 uint32_t Reserved : MOS_BITFIELD_RANGE(0, 31); 76 }; 77 uint32_t Value; 78 } DW5; 79 80 // DWORD 6 81 union 82 { 83 struct 84 { 85 uint32_t ForceRefIdx : MOS_BITFIELD_RANGE(0, 15); //4-bits per 16x16 block 86 uint32_t NumMergeCandidateCu8x8 : MOS_BITFIELD_RANGE(16, 19); 87 uint32_t NumMergeCandidateCu16x16 : MOS_BITFIELD_RANGE(20, 23); 88 uint32_t NumMergeCandidateCu32x32 : MOS_BITFIELD_RANGE(24, 27); 89 uint32_t NumMergeCandidateCu64x64 : MOS_BITFIELD_RANGE(28, 31); 90 }; 91 uint32_t Value; 92 } DW6; 93 94 // DWORD 7 95 union 96 { 97 struct 98 { 99 uint32_t SegID : MOS_BITFIELD_RANGE(0, 15); //4-bits per 16x16 block 100 uint32_t QpEnable : MOS_BITFIELD_RANGE(16, 19); 101 uint32_t SegIDEnable : MOS_BITFIELD_RANGE(20, 20); 102 uint32_t Reserved : MOS_BITFIELD_RANGE(21, 22); 103 uint32_t ForceRefIdEnable : MOS_BITFIELD_RANGE(23, 23); 104 uint32_t ImePredictorSelect : MOS_BITFIELD_RANGE(24, 31); 105 }; 106 uint32_t Value; 107 } DW7; 108 109 // DWORD 8-11 110 union 111 { 112 struct 113 { 114 uint32_t ImePredictorMvX : MOS_BITFIELD_RANGE(0, 15); 115 uint32_t ImePredictorMvY : MOS_BITFIELD_RANGE(16, 31); 116 }; 117 uint32_t Value; 118 } DW8[4]; 119 120 // DWORD 12 121 union 122 { 123 struct 124 { 125 uint32_t ImePredictorRefIdx : MOS_BITFIELD_RANGE(0, 15); //4-bits per 16x16 block 126 uint32_t Reserved : MOS_BITFIELD_RANGE(16, 31); 127 }; 128 uint32_t Value; 129 } DW12; 130 131 // DWORD 13 132 union 133 { 134 struct 135 { 136 uint32_t PanicModeLCUThreshold : MOS_BITFIELD_RANGE(0, 15); 137 uint32_t Reserved : MOS_BITFIELD_RANGE(16, 31); 138 }; 139 uint32_t Value; 140 } DW13; 141 142 // DWORD 14 143 union 144 { 145 struct 146 { 147 uint32_t ForceQp_0 : MOS_BITFIELD_RANGE(0, 7); 148 uint32_t ForceQp_1 : MOS_BITFIELD_RANGE(8, 15); 149 uint32_t ForceQp_2 : MOS_BITFIELD_RANGE(16, 23); 150 uint32_t ForceQp_3 : MOS_BITFIELD_RANGE(24, 31); 151 }; 152 uint32_t Value; 153 } DW14; 154 155 // DWORD 15 156 union 157 { 158 struct 159 { 160 uint32_t Reserved : MOS_BITFIELD_RANGE(0, 31); 161 }; 162 uint32_t Value; 163 } DW15; 164 165 inline bool operator==(const HevcVdencStreamInState &ps) const 166 { 167 if ((this->DW0.Value == ps.DW0.Value) && 168 (this->DW1[0].Value == ps.DW1[0].Value) && 169 this->DW1[1].Value == ps.DW1[1].Value && 170 this->DW1[2].Value == ps.DW1[2].Value && 171 this->DW1[3].Value == ps.DW1[3].Value && 172 this->DW5.Value == ps.DW5.Value && 173 this->DW6.Value == ps.DW6.Value && 174 this->DW7.Value == ps.DW7.Value && 175 this->DW8[0].Value == ps.DW8[0].Value && 176 this->DW8[1].Value == ps.DW8[1].Value && 177 this->DW8[2].Value == ps.DW8[2].Value && 178 this->DW8[3].Value == ps.DW8[3].Value && 179 this->DW12.Value == ps.DW12.Value && 180 this->DW13.Value == ps.DW13.Value && 181 this->DW14.Value == ps.DW14.Value && 182 this->DW15.Value == ps.DW15.Value) 183 return true; 184 return false; 185 } 186 }; 187 //! 188 //! \struct DeltaQpForRoi 189 //! \brief This struct is defined for BRC Update HUC kernel 190 //! region 10 - Delta Qp for ROI Buffer 191 //! 192 struct DeltaQpForRoi 193 { 194 int8_t iDeltaQp; 195 }; 196 197 using SeqParams = CODEC_HEVC_ENCODE_SEQUENCE_PARAMS; 198 using PicParams = CODEC_HEVC_ENCODE_PICTURE_PARAMS; 199 using SlcParams = CODEC_HEVC_ENCODE_SLICE_PARAMS; 200 using StreamInParams = mhw::vdbox::vdenc::_MHW_PAR_T(VDENC_STREAMIN_STATE); 201 using UintVector = std::vector<uint32_t>; 202 203 //! 204 //! \class RoiStrategy 205 //! 206 //! \brief Base class of Native ROI. ForceQP ROI, HuC based ForceQP ROI and 207 //! Dirty ROI. 208 //! 209 //! \detail This class provided unified interface of all ROI, and implemented 210 //! some common functions which will be used by the sub classes. 211 //! 212 class RoiStrategy : public mhw::vdbox::huc::Itf::ParSetting 213 { 214 public: RoiStrategy(EncodeAllocator * allocator,MediaFeatureManager * featureManager,PMOS_INTERFACE osInterface)215 RoiStrategy(EncodeAllocator *allocator, 216 MediaFeatureManager *featureManager, 217 PMOS_INTERFACE osInterface) : 218 m_allocator(allocator), 219 m_featureManager(featureManager), 220 m_osInterface(osInterface) 221 { 222 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_featureManager); 223 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_osInterface); 224 225 m_basicFeature = dynamic_cast<HevcBasicFeature *>(m_featureManager->GetFeature(FeatureIDs::basicFeature)); 226 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_basicFeature); 227 228 m_recycle = m_basicFeature->m_recycleBuf; 229 } 230 ~RoiStrategy()231 virtual ~RoiStrategy() {} 232 233 //! 234 //! \brief Prepare parameters 235 //! 236 //! \param [in] hevcSeqParams 237 //! pointer of sequence parameters 238 //! \param [in] hevcPicParams 239 //! pointer of picture parameters 240 //! \param [in] hevcSlcParams 241 //! pointer of slice parameters 242 //! \return MOS_STATUS 243 //! MOS_STATUS_SUCCESS if success, else fail reason 244 //! 245 virtual MOS_STATUS PrepareParams( 246 SeqParams *hevcSeqParams, 247 PicParams *hevcPicParams, 248 SlcParams *hevcSlcParams); 249 250 //! 251 //! \brief Setup the ROI regione 252 //! 253 //! \param [in] overlap 254 //! Overlap between ROI and dirty ROI 255 //! \return MOS_STATUS 256 //! MOS_STATUS_SUCCESS if success, else fail reason 257 //! 258 virtual MOS_STATUS SetupRoi(RoiOverlap &overlap); 259 260 //! 261 //! \brief Write the Streamin data according to marker. 262 //! \param [in] lcuIndex 263 //! Index of LCU 264 //! \param [in] marker 265 //! overlap marker 266 //! \param [in] roiRegionIndex 267 //! Index of ROI region 268 //! \param [out] streamInBuffer 269 //! Streamin buffer 270 //! \return MOS_STATUS 271 //! MOS_STATUS_SUCCESS if success, else fail reason 272 //! 273 virtual MOS_STATUS WriteStreaminData(uint32_t lcuIndex, 274 RoiOverlap::OverlapMarker marker, 275 uint32_t roiRegionIndex, 276 uint8_t *streamInBuffer); 277 278 //! 279 //! \brief Set VDENC_PIPE_BUF_ADDR parameters 280 //! 281 //! \param [in] streamIn 282 //! Stream in buffer 283 //! \param [out] PipeBufAddrParams 284 //! Pipe buf addr parameters 285 //! 286 //! \return void 287 //! SetVdencPipeBufAddrParams(PMOS_RESOURCE streamin,MHW_VDBOX_PIPE_BUF_ADDR_PARAMS & pipeBufAddrParams)288 virtual void SetVdencPipeBufAddrParams(PMOS_RESOURCE streamin, 289 MHW_VDBOX_PIPE_BUF_ADDR_PARAMS &pipeBufAddrParams) 290 { 291 pipeBufAddrParams.presVdencStreamInBuffer = streamin; 292 return; 293 } 294 295 //! 296 //! \brief Get stream in buffer 297 //! 298 //! \return PMOS_RESOURCE 299 //! Stream in buffer 300 //! GetStreamInBuf()301 virtual PMOS_RESOURCE GetStreamInBuf() const { return nullptr; } 302 303 //! 304 //! \brief Setup HuC BRC init/reset parameters 305 //! 306 //! \param [out] hucVdencBrcInitDmem 307 //! pointer of PCODECHAL_VDENC_HEVC_HUC_BRC_INIT_DMEM_G12 308 //! \return MOS_STATUS 309 //! MOS_STATUS_SUCCESS if success, else fail reason 310 //! SetDmemHuCBrcInitReset(VdencHevcHucBrcInitDmem * hucVdencBrcInitDmem)311 virtual MOS_STATUS SetDmemHuCBrcInitReset( 312 VdencHevcHucBrcInitDmem *hucVdencBrcInitDmem) 313 { 314 return MOS_STATUS_SUCCESS; 315 } 316 SetFeatureSetting(HevcVdencFeatureSettings * settings)317 void SetFeatureSetting(HevcVdencFeatureSettings *settings) { m_FeatureSettings = settings; } 318 319 protected: 320 //! 321 //! \brief Calculate X/Y offsets for zigzag scan within 64 LCU 322 //! 323 //! \param [in] streamInWidth 324 //! StreamInWidth, location of top left corner 325 //! \param [in] x 326 //! Position X 327 //! \param [in] y 328 //! Position Y 329 //! \param [out] offset 330 //! Offsets into the stream-in surface 331 //! \param [out] xyOffset 332 //! XY Offsets into the stream-in surface 333 //! 334 //! \return void 335 //! 336 void StreaminZigZagToLinearMap( 337 uint32_t streamInWidth, 338 uint32_t x, 339 uint32_t y, 340 uint32_t *offset, 341 uint32_t *xyOffset); 342 343 //! 344 //! \brief Calculate X/Y position for linear scan in current frame 345 //! 346 //! \param [in] streamInWidth 347 //! StreamInWidth, location of top left corner 348 //! \param [in] lcuIndex 349 //! Index for 32x32 cu in current frame 350 //! \param [out] x 351 //! Position X 352 //! \param [out] y 353 //! Position Y 354 //! 355 //! \return void 356 //! 357 void ZigZagToRaster( 358 uint32_t streamInWidth, 359 uint32_t lcuIndex, 360 uint32_t &x, 361 uint32_t &y); 362 363 //! 364 //! \brief Get LCUs' index In ROI region 365 //! 366 //! \param [in] streamInWidth 367 //! StreamInWidth, location of top left corner 368 //! \param [in] top 369 //! top of the ROI region 370 //! \param [in] bottom 371 //! bottom of the ROI region 372 //! \param [in] left 373 //! left of the ROI region 374 //! \param [in] bottom 375 //! right of the ROI region 376 //! \param [out] lcuVector 377 //! vector of LCUs' index 378 //! 379 //! \return void 380 //! 381 void GetLCUsInRoiRegion( 382 uint32_t streamInWidth, 383 uint32_t top, 384 uint32_t bottom, 385 uint32_t left, 386 uint32_t right, 387 UintVector &lcuVector); 388 389 //! 390 //! \brief Get LCUs' index In ROI region in Tile 391 //! 392 //! \param [in] streamInWidth 393 //! StreamInWidth, location of top left corner 394 //! \param [in] top 395 //! top of the ROI region 396 //! \param [in] bottom 397 //! bottom of the ROI region 398 //! \param [in] left 399 //! left of the ROI region 400 //! \param [in] bottom 401 //! right of the ROI region 402 //! \param [out] lcuVector 403 //! vector of LCUs' index 404 //! 405 //! \return void 406 //! 407 void GetLCUsInRoiRegionForTile( 408 uint32_t streamInWidth, 409 uint32_t top, 410 uint32_t bottom, 411 uint32_t left, 412 uint32_t right, 413 UintVector &lcuVector); 414 415 //! 416 //! \brief Setup stream-in data per region 417 //! 418 //! \param [in] lcuVector 419 //! vector of LCUs' index 420 //! \param [in] streaminParams 421 //! pointer to MHW_VDBOX_VDENC_STREAMIN_STATE_PARAMS 422 //! \param [out] streaminData 423 //! pointer to streaminData 424 //! 425 //! \return void 426 //! 427 void SetStreaminDataPerRegion( 428 const UintVector &lcuVector, 429 StreamInParams *streaminParams, 430 void *streaminData); 431 432 //! 433 //! \brief Write out stream-in data for each LCU 434 //! 435 //! \param [in] streaminParams 436 //! Params to write into stream in surface 437 //! \param [out] streaminData 438 //! Pointer to streaminData 439 //! 440 //! \return void 441 //! 442 void SetStreaminDataPerLcu( 443 StreamInParams *streaminParams, 444 void *streaminData); 445 446 //! 447 //! \brief Set streamin parameter according to the TU 448 //! 449 //! \param [in] cu64Align 450 //! Whether CU is 64 aligned 451 //! \param [out] streaminDataParams 452 //! Streamin data parameters 453 //! 454 //! \return void 455 //! 456 virtual void SetStreaminParamByTU( 457 bool cu64Align, 458 StreamInParams &streaminDataParams); 459 460 //! 461 //! \brief Set the ROI ctrol mode(Native/ForceQP) 462 //! 463 //! \param [in] roiCtrl 464 //! ROI control 465 //! \param [in] forceQp 466 //! force QP value 467 //! \param [out] streaminDataParams 468 //! Streamin data parameters 469 //! 470 //! \return void 471 //! SetRoiCtrlMode(uint32_t lcuIndex,uint32_t regionIndex,StreamInParams & streaminParams)472 virtual void SetRoiCtrlMode( 473 uint32_t lcuIndex, 474 uint32_t regionIndex, 475 StreamInParams &streaminParams) {} 476 477 //! 478 //! \brief Set ROI Control/Force QP Data per LCU 479 //! 480 //! \param [in] streaminDataParams 481 //! Streamin data parameters 482 //! \param [out] data 483 //! Streamin data 484 //! 485 //! \return void 486 //! SetQpRoiCtrlPerLcu(StreamInParams * streaminParams,HevcVdencStreamInState * data)487 virtual void SetQpRoiCtrlPerLcu( 488 StreamInParams *streaminParams, 489 HevcVdencStreamInState *data) {} 490 491 static constexpr uint8_t m_maxNumRoi = 16; //!< VDEnc maximum number of ROI supported 492 static constexpr uint8_t m_maxNumNativeRoi = 3; //!< Number of native ROI supported by VDEnc HW 493 static constexpr uint8_t m_imgStateImePredictors = 8; //!< Number of predictors for IME 494 495 uint8_t m_numRoi = 0; //!< Number of ROI 496 CODEC_ROI *m_roiRegions = nullptr; //!< ROI regions 497 498 uint8_t m_targetUsage = 0; //!< Target Usage 499 500 int8_t m_qpY = 0; 501 int8_t m_sliceQpDelta = 0; 502 503 uint8_t m_numDistinctDeltaQp = 0; 504 int8_t *m_roiDistinctDeltaQp = nullptr; 505 506 bool m_isTileModeEnabled = false; 507 uint32_t m_minCodingBlockSize = 0; 508 509 EncodeAllocator *m_allocator = nullptr; 510 RecycleResource *m_recycle = nullptr; 511 HevcBasicFeature *m_basicFeature = nullptr; 512 MediaFeatureManager *m_featureManager = nullptr; 513 HevcVdencFeatureSettings *m_FeatureSettings = nullptr; 514 PMOS_INTERFACE m_osInterface = nullptr; 515 516 MEDIA_CLASS_DEFINE_END(encode__RoiStrategy) 517 }; 518 519 //! 520 //! \class RoiStrategyFactory 521 //! 522 //! \brief This is help class to create ROI and Dirty ROI 523 //! 524 //! \detail At the same time, Navtive ROI, 525 //! ForceQP ROI and Huc based ForceQP, we can only use one of them in 526 //! one frame, which we can treat them as traditional ROI. Different 527 //! with traditional ROI, dirty ROI can exist with them simultaneously. 528 //! We should create traditinal ROI and dirty ROI seperately if they 529 //! exist in the same time. 530 //! 531 class RoiStrategyFactory 532 { 533 public: 534 //! 535 //! \brief Create ROIs, include Native ROI, ForceQP ROI, Huc based ROI and 536 //! dirty ROI according to the input parameters 537 //! 538 //! \param [in] allocator 539 //! Encode allocator 540 //! \param [in] recycle 541 //! Recycle buffer 542 //! \param [in] params 543 //! Encode parameters 544 //! \param [in] isDirtyRoi 545 //! Whether is dirty ROI or not. 546 //! \param [in] isNativeRoi 547 //! Whether is native ROI or not. 548 //! 549 //! \return RoiStrategy * 550 //! Pointer of RoiStrategy 551 //! 552 RoiStrategy *CreateStrategy( 553 EncodeAllocator *allocator, 554 MediaFeatureManager *featureManager, 555 PMOS_INTERFACE m_osInterface, 556 bool isArb, 557 bool isDirtyRoi, 558 bool isNativeRoi, 559 bool isQPMap = false); 560 561 //! 562 //! \brief Create ROIs, include force delta qp ROI, 563 //! 564 //! 565 //! \param [in] allocator 566 //! Encode allocator 567 //! \param [in] featureManager 568 //! Media feature manager. 569 //! 570 //! \return RoiStrategy * 571 //! Pointer of RoiStrategy 572 //! 573 RoiStrategy *CreateStrategyForceDeltaQP( 574 EncodeAllocator *allocator, 575 MediaFeatureManager *featureManager, 576 PMOS_INTERFACE m_osInterface); 577 578 ~RoiStrategyFactory(); 579 580 //! 581 //! \brief Get dirty ROI for current frame 582 //! 583 //! \return RoiStrategy * 584 //! Pointer of RoiStrategy 585 //! GetDirtyRoi()586 RoiStrategy *GetDirtyRoi() const { return m_dirtyRoi; } 587 //! 588 //! \brief Get traditional ROI for current frame 589 //! 590 //! \return RoiStrategy * 591 //! Pointer of RoiStrategy 592 //! GetRoi()593 RoiStrategy *GetRoi() const { return m_currentRoi; } 594 595 private: 596 RoiStrategy *m_nativeRoi = nullptr; 597 RoiStrategy *m_arbRoi = nullptr; 598 RoiStrategy *m_forceQpRoi = nullptr; 599 RoiStrategy *m_hucForceQpRoi = nullptr; 600 RoiStrategy *m_currentRoi = nullptr; 601 RoiStrategy *m_dirtyRoi = nullptr; 602 RoiStrategy *m_QPMapROI = nullptr; 603 RoiStrategy *m_deltaQpRoi = nullptr; 604 605 MEDIA_CLASS_DEFINE_END(encode__RoiStrategyFactory) 606 }; 607 608 } // namespace encode 609 #endif //<! __CODECHAL_HEVC_VDENC_ROI_STRATEGY_H__ 610