1 /* 2 * Copyright (c) 2016-2017, 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 codechal_encode_hevc.h 24 //! \brief Defines base class for HEVC dual-pipe encoder. 25 //! 26 27 #ifndef __CODECHAL_ENCODE_HEVC_H__ 28 #define __CODECHAL_ENCODE_HEVC_H__ 29 30 #include "codechal_encode_hevc_base.h" 31 #include "codechal_kernel_hme.h" 32 33 #define HUC_CMD_LIST_MODE 1 34 #define HUC_BATCH_BUFFER_END 0x05000000 35 36 //! QP type 37 enum { 38 QP_TYPE_CONSTANT = 0, 39 QP_TYPE_FRAME, 40 QP_TYPE_CU_LEVEL 41 }; 42 43 //! 44 //! \struct HucCommandData 45 //! \brief The struct of Huc commands data 46 //! 47 struct HucCommandData 48 { 49 uint32_t TotalCommands; //!< Total Commands in the Data buffer 50 struct 51 { 52 uint16_t ID; //!< Command ID, defined and order must be same as that in DMEM 53 uint16_t SizeOfData; //!< data size in uint32_t 54 uint32_t data[40]; 55 } InputCOM[10]; 56 }; 57 58 //! \class CodechalEncHevcState 59 //! \brief HEVC dual-pipe encoder base class 60 //! \details This class defines the base class for HEVC dual-pipe encoder, it includes 61 //! common member fields, functions, interfaces etc shared by all GENs. 62 //! Gen specific definitions, features should be put into their corresponding classes. 63 //! To create a HEVC dual-pipe encoder instance, client needs to call CodechalEncHevcState::CreateHevcState() 64 //! 65 class CodechalEncHevcState : public CodechalEncodeHevcBase 66 { 67 public: 68 //! QP type 69 enum { 70 QP_TYPE_CONSTANT = 0, 71 QP_TYPE_FRAME, 72 QP_TYPE_CU_LEVEL 73 }; 74 75 enum { 76 BRCINIT_USEHUCBRC = 0x0001, 77 BRCINIT_ISCBR = 0x0010, 78 BRCINIT_ISVBR = 0x0020, 79 BRCINIT_ISAVBR = 0x0040, 80 BRCINIT_ISQVBR = 0x0080, 81 BRCINIT_FIELD_PIC = 0x0100, 82 BRCINIT_ISICQ = 0x0200, 83 BRCINIT_ISVCM = 0x0400, 84 BRCINIT_PANIC_MODE_ISENABLED = 0x1000, 85 BRCINIT_IGNORE_PICTURE_HEADER_SIZE = 0x2000, 86 BRCINIT_ISCQP = 0x4000, 87 BRCINIT_DISABLE_MBBRC = 0x8000 88 }; 89 90 //! 91 //! \brief HEVC BRC buffers 92 //! 93 struct HevcEncBrcBuffers 94 { 95 MOS_RESOURCE resBrcHistoryBuffer; // BRC history buffer 96 MOS_RESOURCE resBrcPakStatisticBuffer[CODECHAL_ENCODE_RECYCLED_BUFFER_NUM]; 97 uint32_t uiCurrBrcPakStasIdxForRead; 98 uint32_t uiCurrBrcPakStasIdxForWrite; 99 MOS_RESOURCE resBrcImageStatesReadBuffer[CODECHAL_ENCODE_RECYCLED_BUFFER_NUM]; // read only BRC image state buffer 100 MOS_RESOURCE resBrcImageStatesWriteBuffer[CODECHAL_ENCODE_RECYCLED_BUFFER_NUM]; //!< Write only HEVC BRC image state buffers 101 uint32_t dwBrcHcpPicStateSize; 102 MOS_SURFACE sBrcConstantDataBuffer[CODECHAL_ENCODE_RECYCLED_BUFFER_NUM]; 103 MOS_RESOURCE resMbBrcConstDataBuffer[CODECHAL_ENCODE_RECYCLED_BUFFER_NUM]; 104 uint32_t dwBrcConstantSurfaceWidth; 105 uint32_t dwBrcConstantSurfaceHeight; 106 MOS_SURFACE sBrcIntraDistortionBuffer; //!< BRC Intra distortion buffer 107 MOS_SURFACE sMeBrcDistortionBuffer; 108 uint32_t dwMeBrcDistortionBottomFieldOffset; 109 MOS_SURFACE sBrcMbQpBuffer; 110 uint32_t dwBrcMbQpBottomFieldOffset; 111 MOS_RESOURCE resBrcPicHeaderInputBuffer; 112 MOS_RESOURCE resBrcPicHeaderOutputBuffer; 113 MOS_RESOURCE resMbEncAdvancedDsh; 114 MOS_RESOURCE resMbEncBrcBuffer; 115 MOS_SURFACE sBrcRoiSurface; // BRC ROI surface 116 PMOS_SURFACE pMbStatisticsSurface; 117 PCODECHAL_ENCODE_BUFFER pMvAndDistortionSumSurface; 118 PMHW_KERNEL_STATE pMbEncKernelStateInUse; 119 CmSurface2D* brcIntraDistortionSurface = nullptr; 120 CmSurface2D* meBrcDistortionSurface = nullptr; 121 CmBuffer* mvAndDistortionSumSurface = nullptr; 122 }; 123 124 //! 125 //! \struct EncStatsBuffers 126 //! \brief MbEnc statistic buffers 127 //! 128 struct EncStatsBuffers 129 { 130 MOS_SURFACE m_puStatsSurface; 131 MOS_SURFACE m_8x8PuHaarDist; 132 CODECHAL_ENCODE_BUFFER m_8x8PuFrameStats; 133 MOS_SURFACE m_mbEncStatsSurface; 134 CODECHAL_ENCODE_BUFFER m_mbEncFrameStats; 135 }; 136 137 static const uint32_t m_8x8PuFrameStatsSize = 32; //!< The size of 8x8 PU frame statistic buffer 138 static const uint32_t m_mbEncFrameStatsSize = 32; 139 static constexpr uint32_t NUM_FORMAT_CONV_FRAMES = (CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC + 1); //!< Number of format conversion frames 140 141 uint32_t m_widthAlignedLcu32 = 0; //!< Picture width aligned to LCU32 142 uint32_t m_heightAlignedLcu32 = 0; //!< Picture height aligned to LCU32 143 144 uint32_t m_numRegionsInSlice = 1; //!< Number of Regions 145 146 // Resources for the render engine 147 MOS_SURFACE m_formatConvertedSurface[NUM_FORMAT_CONV_FRAMES]; //!< // Handle of the format converted surface 148 149 // ME 150 CodechalKernelHme *m_hmeKernel = nullptr; //!< ME kernel object 151 PMHW_KERNEL_STATE m_meKernelState = nullptr; //!< ME kernel state 152 PCODECHAL_ENCODE_BINDING_TABLE_GENERIC m_meKernelBindingTable = nullptr; //!< ME kernel binding table 153 154 // BRC 155 PMHW_KERNEL_STATE m_brcKernelStates = nullptr; //!< Pointer to BRC kernel state 156 PCODECHAL_ENCODE_BINDING_TABLE_GENERIC m_brcKernelBindingTable = nullptr; //!< BRC kernel binding table 157 PMOS_SURFACE m_brcDistortion = nullptr; //!< Pointer to BRC distortion surface 158 HevcEncBrcBuffers m_brcBuffers; //!< BRC buffers 159 uint32_t m_numBrcKrnStates = 0; //!< Number of BRC kernel states 160 uint8_t m_slidingWindowSize = 0; //!< Sliding window size in number of frames 161 bool m_roiRegionSmoothEnabled = false; //!< ROI region smooth transition enable flag 162 HEVC_BRC_FRAME_TYPE m_currFrameBrcLevel = HEVC_BRC_FRAME_TYPE_I; //!< frame brc level 163 164 // MBENC 165 PMHW_KERNEL_STATE m_mbEncKernelStates = nullptr; //!< Pointer to MbEnc kernel state 166 PCODECHAL_ENCODE_BINDING_TABLE_GENERIC m_mbEncKernelBindingTable = nullptr; //!< MbEnc kernel binding table 167 uint32_t m_numMbEncEncKrnStates = 0; //!< Number of MbEnc kernel states 168 EncStatsBuffers m_encStatsBuffers; 169 uint8_t m_mbCodeIdxForTempMVP = 0xFF; //!< buf index for current frame temporal mvp 170 uint8_t m_roundingIntraInUse = 10; //!< rounding intra actually used 171 uint8_t m_roundingInterInUse = 4; //!< rounding inter actually used 172 173 // ScalingAndConversion 174 PMHW_KERNEL_STATE m_scalingAndConversionKernelState = nullptr; //!< Pointer to ScalingAndConversion kernel state 175 PCODECHAL_ENCODE_BINDING_TABLE_GENERIC m_scalingAndConversionKernelBindingTable = nullptr; //!< ScalingAndConversion kernel binding table 176 177 bool m_pakOnlyTest = false; //!< PAK only test enable flag 178 char m_pakOnlyDataFolder[MOS_USER_CONTROL_MAX_DATA_SIZE] = {0}; //!< Pak only test data folder name 179 bool m_cqpEnabled = false; //!< CQP Rate Control 180 bool m_sseSupported = false; //!< PAK SSE support flag 181 182 // Below values will be set if qp control params are sent by app 183 bool m_minMaxQpControlEnabled = false; //!< Flag to indicate if min/max QP feature is enabled or not. 184 int16_t m_minQpForI = 0; //!< I frame Minimum QP. 185 int16_t m_maxQpForI = 0; //!< I frame Maximum QP. 186 int16_t m_minQpForP = 0; //!< P frame Minimum QP. 187 int16_t m_maxQpForP = 0; //!< P frame Maximum QP. 188 int16_t m_minQpForB = 0; //!< B frame Minimum QP. 189 int16_t m_maxQpForB = 0; //!< B frame Maximum QP. 190 bool m_minMaxQpControlForP = false; //!< Indicates min/max QP values for P-frames are set separately or not. 191 bool m_minMaxQpControlForB = false; //!< Indicates min/max QP values for B-frames are set separately or not. 192 193 protected: 194 //! 195 //! \brief Constructor 196 //! 197 CodechalEncHevcState(CodechalHwInterface* hwInterface, 198 CodechalDebugInterface* debugInterface, 199 PCODECHAL_STANDARD_INFO standardInfo); 200 201 public: 202 //! 203 //! \brief Copy constructor 204 //! 205 CodechalEncHevcState(const CodechalEncHevcState&) = delete; 206 207 //! 208 //! \brief Copy assignment operator 209 //! 210 CodechalEncHevcState& operator=(const CodechalEncHevcState&) = delete; 211 212 //! 213 //! \brief Destructor 214 //! 215 virtual ~CodechalEncHevcState(); 216 217 //! 218 //! \brief Help function to initialize surface parameters for 1D buffer 219 //! 220 //! \param [in, out] params 221 //! Pointer to surface codec parameters 222 //! \param [in] buffer 223 //! Pointer to buffer resource 224 //! \param [in] size 225 //! Buffer size 226 //! \param [in] offset 227 //! Offset within the buffer 228 //! \param [in] cacheabilityControl 229 //! Buffer cache control setting 230 //! \param [in] bindingTableOffset 231 //! Binding table offset for the buffer 232 //! \param [in] isWritable 233 //! True if buffer is writable, false if it is read only 234 //! 235 //! \return MOS_STATUS 236 //! MOS_STATUS_SUCCESS if success, else fail reason 237 //! 238 MOS_STATUS InitSurfaceCodecParams1D( 239 CODECHAL_SURFACE_CODEC_PARAMS* params, 240 PMOS_RESOURCE buffer, 241 uint32_t size, 242 uint32_t offset, 243 uint32_t cacheabilityControl, 244 uint32_t bindingTableOffset, 245 bool isWritable); 246 247 //! 248 //! \brief Help function to initialize surface parameters for 2D surface 249 //! 250 //! \param [in, out] params 251 //! Pointer to surface codec parameters 252 //! \param [in] surface 253 //! Pointer to surface resource 254 //! \param [in] cacheabilityControl 255 //! Cache control setting for the surface 256 //! \param [in] bindingTableOffset 257 //! Binding table offset for the surface 258 //! \param [in] verticalLineStride 259 //! Vertical line stride for the surface 260 //! \param [in] isWritable 261 //! True if surface is writable, false if it is read only 262 //! 263 //! \return MOS_STATUS 264 //! MOS_STATUS_SUCCESS if success, else fail reason 265 //! 266 MOS_STATUS InitSurfaceCodecParams2D( 267 CODECHAL_SURFACE_CODEC_PARAMS* params, 268 PMOS_SURFACE surface, 269 uint32_t cacheabilityControl, 270 uint32_t bindingTableOffset, 271 uint32_t verticalLineStride, 272 bool isWritable); 273 274 //! 275 //! \brief Help function to initialize surface parameters for VME surface 276 //! 277 //! \param [in, out] params 278 //! Pointer to surface codec parameters 279 //! \param [in] surface 280 //! Pointer to surface resource 281 //! \param [in] cacheabilityControl 282 //! Cache control setting for the surface 283 //! \param [in] bindingTableOffset 284 //! Binding table offset for the surface 285 //! 286 //! \return MOS_STATUS 287 //! MOS_STATUS_SUCCESS if success, else fail reason 288 //! 289 MOS_STATUS InitSurfaceCodecParamsVME( 290 CODECHAL_SURFACE_CODEC_PARAMS* params, 291 PMOS_SURFACE surface, 292 uint32_t cacheabilityControl, 293 uint32_t bindingTableOffset); 294 295 //! 296 //! \brief Help function to calcuate ROI Ratio need by BRC Kernel 297 //! 298 //! \return ROI ratio 299 //! 300 uint8_t CalculateROIRatio(); 301 302 //! 303 //! \brief Help function to calcuate the temporal difference between current and reference picture 304 //! 305 //! \param [in] refPic 306 //! Reference picture. 307 //! 308 //! \return Temporal difference between current and reference picture 309 //! 310 int16_t ComputeTemporalDifference(const CODEC_PICTURE& refPic); 311 312 //! 313 //! \brief Help function to get start code offset 314 //! \details Search the start code from address addr to (addr + size) 315 //! 316 //! \param [in] addr 317 //! Pointer to memory location to start searching for start code 318 //! \param [in] size 319 //! End of the memory address to search for start code is [addr + size] 320 //! 321 //! \return Offset of start code 322 //! 323 uint32_t GetStartCodeOffset(uint8_t* addr, uint32_t size); 324 325 //! 326 //! \brief Help function to get picture header size 327 //! 328 //! \return Size of picture header 329 //! 330 uint32_t GetPicHdrSize(); 331 332 //! 333 //! \brief Wait for PAK engine ready 334 //! 335 //! \return MOS_STATUS 336 //! MOS_STATUS_SUCCESS if success, else fail reason 337 //! 338 MOS_STATUS WaitForPak(); 339 340 //! 341 //! \brief Wait for reference frame ready 342 //! 343 //! \param [in] mbCodeIdx 344 //! Mb code index for reference frame 345 //! 346 //! \return MOS_STATUS 347 //! MOS_STATUS_SUCCESS if success, else fail reason 348 //! 349 MOS_STATUS WaitForRefFrameReady(uint8_t mbCodeIdx); 350 351 //! 352 //! \brief Add HCP_WEIGHT_OFFSET_STATE command to command buffer 353 //! 354 //! \param [in, out] cmdBuffer 355 //! Pointer to the command buffer 356 //! \param [in] hevcSlcParams 357 //! Pointer to HEVC slice parameters 358 //! 359 //! \return MOS_STATUS 360 //! MOS_STATUS_SUCCESS if success, else fail reason 361 //! 362 virtual MOS_STATUS AddHcpWeightOffsetStateCmd( 363 PMOS_COMMAND_BUFFER cmdBuffer, 364 PMHW_BATCH_BUFFER batchBuffer, 365 PCODEC_HEVC_ENCODE_SLICE_PARAMS hevcSlcParams); 366 367 //! 368 //! \brief Put slice level commands in command buffer 369 //! 370 //! \param [in] cmdBuffer 371 //! Pointer to command buffer 372 //! \param [in] params 373 //! Pointer to slice state parameters 374 //! 375 //! \return MOS_STATUS 376 //! MOS_STATUS_SUCCESS if success, else fail reason 377 //! 378 virtual MOS_STATUS SendHwSliceEncodeCommand( 379 PMOS_COMMAND_BUFFER cmdBuffer, 380 PMHW_VDBOX_HEVC_SLICE_STATE params); 381 382 //! 383 //! \brief Allocate encoder states resources 384 //! 385 //! \return MOS_STATUS 386 //! MOS_STATUS_SUCCESS if success, else fail reason 387 //! 388 MOS_STATUS AllocateEncStatsResources(); 389 390 //! 391 //! \brief Free encoder states resources 392 //! 393 //! \return MOS_STATUS 394 //! MOS_STATUS_SUCCESS if success, else fail reason 395 //! 396 MOS_STATUS FreeEncStatsResources(); 397 398 //! 399 //! \brief Get Current Frame BRC Level 400 //! 401 //! \return MOS_STATUS 402 //! MOS_STATUS_SUCCESS if success, else fail reason 403 //! 404 virtual MOS_STATUS GetFrameBrcLevel(); 405 406 //! Inherited virtual functions 407 virtual bool CheckSupportedFormat(PMOS_SURFACE surface); 408 virtual MOS_STATUS Initialize(CodechalSetting * settings); 409 virtual MOS_STATUS AllocateBrcResources(); 410 virtual MOS_STATUS FreeBrcResources(); 411 virtual MOS_STATUS InitializePicture(const EncoderParams& params); 412 virtual MOS_STATUS SetSequenceStructs(); 413 virtual MOS_STATUS SetPictureStructs(); 414 virtual MOS_STATUS SetSliceStructs(); 415 virtual MOS_STATUS ReadHcpStatus(PMOS_COMMAND_BUFFER cmdBuffer); 416 virtual MOS_STATUS UserFeatureKeyReport(); 417 virtual MOS_STATUS ValidateRefFrameData(PCODEC_HEVC_ENCODE_SLICE_PARAMS slcParams); 418 virtual MOS_STATUS ExecutePictureLevel(); 419 virtual MOS_STATUS ExecuteSliceLevel(); 420 421 //! 422 //! \brief Read stats for BRC from PAK 423 //! 424 //! \param [in] cmdBuffer 425 //! Pointer to command buffer 426 //! 427 //! \return MOS_STATUS 428 //! MOS_STATUS_SUCCESS if success, else fail reason 429 //! 430 virtual MOS_STATUS ReadBrcPakStats(PMOS_COMMAND_BUFFER cmdBuffer); 431 432 //! 433 //! \brief Setup ME curbe params 434 //! 435 //! \param [in, out] curbeParams 436 //! ME curbe params to be initialized in this function 437 //! 438 //! \return MOS_STATUS 439 //! MOS_STATUS_SUCCESS if success, else fail reason 440 //! 441 virtual MOS_STATUS SetMeCurbeParams( 442 CodechalKernelHme::CurbeParam &curbeParams); 443 444 //! 445 //! \brief Setup ME surface params 446 //! 447 //! \param [in] surfaceParams 448 //! ME curbe params 449 //! \param [in, out] surfaceParams 450 //! ME surface params to be initialized in this function 451 //! 452 //! \return MOS_STATUS 453 //! MOS_STATUS_SUCCESS if success, else fail reason 454 //! 455 virtual MOS_STATUS SetMeSurfaceParams( 456 CodechalKernelHme::SurfaceParams &surfaceParams); 457 458 //! 459 //! \brief Top level function for ME kernel 460 //! 461 //! \return MOS_STATUS 462 //! MOS_STATUS_SUCCESS if success, else fail reason 463 //! 464 virtual MOS_STATUS EncodeMeKernel(); 465 466 //! 467 //! \brief Allocate ENC resources when LCU size is 64 468 //! 469 //! \return MOS_STATUS 470 //! MOS_STATUS_SUCCESS if success, else fail reason 471 //! AllocateEncResourcesLCU64()472 virtual MOS_STATUS AllocateEncResourcesLCU64() 473 { 474 return MOS_STATUS_SUCCESS; 475 } 476 477 //! 478 //! \brief Get max supported number of reference frames 479 //! 480 //! \param [out] maxNumRef0 481 //! Max suppoted number of referenace frame 0 482 //! \param [out] maxNumRef1 483 //! Max suppoted number of referenace frame 1 484 //! 485 //! \return void 486 //! 487 virtual void GetMaxRefFrames(uint8_t& maxNumRef0, uint8_t& maxNumRef1) = 0; 488 489 //! 490 //! \brief Prepare and add Hcp Pipe Mode Select Cmd 491 //! 492 //! \param [out] cmdBuffer 493 //! CmdBuffer to add the cmd 494 //! 495 //! \return MOS_STATUS 496 //! MOS_STATUS_SUCCESS if success, else fail reason 497 //! 498 virtual MOS_STATUS AddHcpPipeModeSelectCmd(MOS_COMMAND_BUFFER* cmdBuffer); 499 500 //! 501 //! \brief Prepare and add all Hcp Surface State Cmds 502 //! 503 //! \param [out] cmdBuffer 504 //! CmdBuffer to add the cmd 505 //! 506 //! \return MOS_STATUS 507 //! MOS_STATUS_SUCCESS if success, else fail reason 508 //! 509 virtual MOS_STATUS AddHcpSurfaceStateCmds(MOS_COMMAND_BUFFER* cmdBuffer); 510 511 //! 512 //! \brief Prepare and add Hcp Picture State Cmd 513 //! 514 //! \param [out] cmdBuffer 515 //! CmdBuffer to add the cmd 516 //! 517 //! \return MOS_STATUS 518 //! MOS_STATUS_SUCCESS if success, else fail reason 519 //! 520 virtual MOS_STATUS AddHcpPictureStateCmd(MOS_COMMAND_BUFFER* cmdBuffer); 521 522 //! 523 //! \brief Create ROI surfaces for BRC LCU Update kernel 524 //! 525 //! \return MOS_STATUS 526 //! MOS_STATUS_SUCCESS if success, else fail reason 527 //! 528 MOS_STATUS SetupROISurface(); 529 //! 530 //! \brief Generate codechal dumps for HME kernel 531 //! 532 //! \return MOS_STATUS 533 //! MOS_STATUS_SUCCESS if success, else fail reason 534 //! 535 MOS_STATUS DumpHMESurfaces(); 536 //! 537 //! \brief Get rounding inter/intra for current frame to use 538 //! 539 //! \return MOS_STATUS 540 //! MOS_STATUS_SUCCESS if success, else fail reason 541 //! 542 virtual MOS_STATUS GetRoundingIntraInterToUse(); 543 }; 544 #endif // __CODECHAL_ENCODE_HEVC_H__ 545