| /* |
| * Copyright (c) 2016-2017, Intel Corporation |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| * and/or sell copies of the Software, and to permit persons to whom the |
| * Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included |
| * in all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
| * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
| * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| * OTHER DEALINGS IN THE SOFTWARE. |
| */ |
| //! |
| //! \file codechal_encode_hevc.h |
| //! \brief Defines base class for HEVC dual-pipe encoder. |
| //! |
| |
| #ifndef __CODECHAL_ENCODE_HEVC_H__ |
| #define __CODECHAL_ENCODE_HEVC_H__ |
| |
| #include "codechal_encode_hevc_base.h" |
| #include "codechal_kernel_hme.h" |
| |
| #define HUC_CMD_LIST_MODE 1 |
| #define HUC_BATCH_BUFFER_END 0x05000000 |
| |
| //! QP type |
| enum { |
| QP_TYPE_CONSTANT = 0, |
| QP_TYPE_FRAME, |
| QP_TYPE_CU_LEVEL |
| }; |
| |
| //! |
| //! \struct HucCommandData |
| //! \brief The struct of Huc commands data |
| //! |
| struct HucCommandData |
| { |
| uint32_t TotalCommands; //!< Total Commands in the Data buffer |
| struct |
| { |
| uint16_t ID; //!< Command ID, defined and order must be same as that in DMEM |
| uint16_t SizeOfData; //!< data size in uint32_t |
| uint32_t data[40]; |
| } InputCOM[10]; |
| }; |
| |
| //! \class CodechalEncHevcState |
| //! \brief HEVC dual-pipe encoder base class |
| //! \details This class defines the base class for HEVC dual-pipe encoder, it includes |
| //! common member fields, functions, interfaces etc shared by all GENs. |
| //! Gen specific definitions, features should be put into their corresponding classes. |
| //! To create a HEVC dual-pipe encoder instance, client needs to call CodechalEncHevcState::CreateHevcState() |
| //! |
| class CodechalEncHevcState : public CodechalEncodeHevcBase |
| { |
| public: |
| //! QP type |
| enum { |
| QP_TYPE_CONSTANT = 0, |
| QP_TYPE_FRAME, |
| QP_TYPE_CU_LEVEL |
| }; |
| |
| enum { |
| BRCINIT_USEHUCBRC = 0x0001, |
| BRCINIT_ISCBR = 0x0010, |
| BRCINIT_ISVBR = 0x0020, |
| BRCINIT_ISAVBR = 0x0040, |
| BRCINIT_ISQVBR = 0x0080, |
| BRCINIT_FIELD_PIC = 0x0100, |
| BRCINIT_ISICQ = 0x0200, |
| BRCINIT_ISVCM = 0x0400, |
| BRCINIT_PANIC_MODE_ISENABLED = 0x1000, |
| BRCINIT_IGNORE_PICTURE_HEADER_SIZE = 0x2000, |
| BRCINIT_ISCQP = 0x4000, |
| BRCINIT_DISABLE_MBBRC = 0x8000 |
| }; |
| |
| //! |
| //! \brief HEVC BRC buffers |
| //! |
| struct HevcEncBrcBuffers |
| { |
| MOS_RESOURCE resBrcHistoryBuffer; // BRC history buffer |
| MOS_RESOURCE resBrcPakStatisticBuffer[CODECHAL_ENCODE_RECYCLED_BUFFER_NUM]; |
| uint32_t uiCurrBrcPakStasIdxForRead; |
| uint32_t uiCurrBrcPakStasIdxForWrite; |
| MOS_RESOURCE resBrcImageStatesReadBuffer[CODECHAL_ENCODE_RECYCLED_BUFFER_NUM]; // read only BRC image state buffer |
| MOS_RESOURCE resBrcImageStatesWriteBuffer[CODECHAL_ENCODE_RECYCLED_BUFFER_NUM]; //!< Write only HEVC BRC image state buffers |
| uint32_t dwBrcHcpPicStateSize; |
| MOS_SURFACE sBrcConstantDataBuffer[CODECHAL_ENCODE_RECYCLED_BUFFER_NUM]; |
| MOS_RESOURCE resMbBrcConstDataBuffer[CODECHAL_ENCODE_RECYCLED_BUFFER_NUM]; |
| uint32_t dwBrcConstantSurfaceWidth; |
| uint32_t dwBrcConstantSurfaceHeight; |
| MOS_SURFACE sBrcIntraDistortionBuffer; //!< BRC Intra distortion buffer |
| MOS_SURFACE sMeBrcDistortionBuffer; |
| uint32_t dwMeBrcDistortionBottomFieldOffset; |
| MOS_SURFACE sBrcMbQpBuffer; |
| uint32_t dwBrcMbQpBottomFieldOffset; |
| MOS_RESOURCE resBrcPicHeaderInputBuffer; |
| MOS_RESOURCE resBrcPicHeaderOutputBuffer; |
| MOS_RESOURCE resMbEncAdvancedDsh; |
| MOS_RESOURCE resMbEncBrcBuffer; |
| MOS_SURFACE sBrcRoiSurface; // BRC ROI surface |
| PMOS_SURFACE pMbStatisticsSurface; |
| PCODECHAL_ENCODE_BUFFER pMvAndDistortionSumSurface; |
| PMHW_KERNEL_STATE pMbEncKernelStateInUse; |
| CmSurface2D* brcIntraDistortionSurface = nullptr; |
| CmSurface2D* meBrcDistortionSurface = nullptr; |
| CmBuffer* mvAndDistortionSumSurface = nullptr; |
| }; |
| |
| //! |
| //! \struct EncStatsBuffers |
| //! \brief MbEnc statistic buffers |
| //! |
| struct EncStatsBuffers |
| { |
| MOS_SURFACE m_puStatsSurface; |
| MOS_SURFACE m_8x8PuHaarDist; |
| CODECHAL_ENCODE_BUFFER m_8x8PuFrameStats; |
| MOS_SURFACE m_mbEncStatsSurface; |
| CODECHAL_ENCODE_BUFFER m_mbEncFrameStats; |
| }; |
| |
| static const uint32_t m_8x8PuFrameStatsSize = 32; //!< The size of 8x8 PU frame statistic buffer |
| static const uint32_t m_mbEncFrameStatsSize = 32; |
| static constexpr uint32_t NUM_FORMAT_CONV_FRAMES = (CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC + 1); //!< Number of format conversion frames |
| |
| uint32_t m_widthAlignedLcu32 = 0; //!< Picture width aligned to LCU32 |
| uint32_t m_heightAlignedLcu32 = 0; //!< Picture height aligned to LCU32 |
| |
| uint32_t m_numRegionsInSlice = 1; //!< Number of Regions |
| |
| // Resources for the render engine |
| MOS_SURFACE m_formatConvertedSurface[NUM_FORMAT_CONV_FRAMES]; //!< // Handle of the format converted surface |
| |
| // ME |
| CodechalKernelHme *m_hmeKernel = nullptr; //!< ME kernel object |
| PMHW_KERNEL_STATE m_meKernelState = nullptr; //!< ME kernel state |
| PCODECHAL_ENCODE_BINDING_TABLE_GENERIC m_meKernelBindingTable = nullptr; //!< ME kernel binding table |
| |
| // BRC |
| PMHW_KERNEL_STATE m_brcKernelStates = nullptr; //!< Pointer to BRC kernel state |
| PCODECHAL_ENCODE_BINDING_TABLE_GENERIC m_brcKernelBindingTable = nullptr; //!< BRC kernel binding table |
| PMOS_SURFACE m_brcDistortion = nullptr; //!< Pointer to BRC distortion surface |
| HevcEncBrcBuffers m_brcBuffers; //!< BRC buffers |
| uint32_t m_numBrcKrnStates = 0; //!< Number of BRC kernel states |
| uint8_t m_slidingWindowSize = 0; //!< Sliding window size in number of frames |
| bool m_roiRegionSmoothEnabled = false; //!< ROI region smooth transition enable flag |
| HEVC_BRC_FRAME_TYPE m_currFrameBrcLevel = HEVC_BRC_FRAME_TYPE_I; //!< frame brc level |
| |
| // MBENC |
| PMHW_KERNEL_STATE m_mbEncKernelStates = nullptr; //!< Pointer to MbEnc kernel state |
| PCODECHAL_ENCODE_BINDING_TABLE_GENERIC m_mbEncKernelBindingTable = nullptr; //!< MbEnc kernel binding table |
| uint32_t m_numMbEncEncKrnStates = 0; //!< Number of MbEnc kernel states |
| EncStatsBuffers m_encStatsBuffers; |
| uint8_t m_mbCodeIdxForTempMVP = 0xFF; //!< buf index for current frame temporal mvp |
| uint8_t m_roundingIntraInUse = 10; //!< rounding intra actually used |
| uint8_t m_roundingInterInUse = 4; //!< rounding inter actually used |
| |
| // ScalingAndConversion |
| PMHW_KERNEL_STATE m_scalingAndConversionKernelState = nullptr; //!< Pointer to ScalingAndConversion kernel state |
| PCODECHAL_ENCODE_BINDING_TABLE_GENERIC m_scalingAndConversionKernelBindingTable = nullptr; //!< ScalingAndConversion kernel binding table |
| |
| bool m_pakOnlyTest = false; //!< PAK only test enable flag |
| char m_pakOnlyDataFolder[MOS_USER_CONTROL_MAX_DATA_SIZE] = {0}; //!< Pak only test data folder name |
| bool m_cqpEnabled = false; //!< CQP Rate Control |
| bool m_sseSupported = false; //!< PAK SSE support flag |
| |
| // Below values will be set if qp control params are sent by app |
| bool m_minMaxQpControlEnabled = false; //!< Flag to indicate if min/max QP feature is enabled or not. |
| int16_t m_minQpForI = 0; //!< I frame Minimum QP. |
| int16_t m_maxQpForI = 0; //!< I frame Maximum QP. |
| int16_t m_minQpForP = 0; //!< P frame Minimum QP. |
| int16_t m_maxQpForP = 0; //!< P frame Maximum QP. |
| int16_t m_minQpForB = 0; //!< B frame Minimum QP. |
| int16_t m_maxQpForB = 0; //!< B frame Maximum QP. |
| bool m_minMaxQpControlForP = false; //!< Indicates min/max QP values for P-frames are set separately or not. |
| bool m_minMaxQpControlForB = false; //!< Indicates min/max QP values for B-frames are set separately or not. |
| |
| protected: |
| //! |
| //! \brief Constructor |
| //! |
| CodechalEncHevcState(CodechalHwInterface* hwInterface, |
| CodechalDebugInterface* debugInterface, |
| PCODECHAL_STANDARD_INFO standardInfo); |
| |
| public: |
| //! |
| //! \brief Copy constructor |
| //! |
| CodechalEncHevcState(const CodechalEncHevcState&) = delete; |
| |
| //! |
| //! \brief Copy assignment operator |
| //! |
| CodechalEncHevcState& operator=(const CodechalEncHevcState&) = delete; |
| |
| //! |
| //! \brief Destructor |
| //! |
| virtual ~CodechalEncHevcState(); |
| |
| //! |
| //! \brief Help function to initialize surface parameters for 1D buffer |
| //! |
| //! \param [in, out] params |
| //! Pointer to surface codec parameters |
| //! \param [in] buffer |
| //! Pointer to buffer resource |
| //! \param [in] size |
| //! Buffer size |
| //! \param [in] offset |
| //! Offset within the buffer |
| //! \param [in] cacheabilityControl |
| //! Buffer cache control setting |
| //! \param [in] bindingTableOffset |
| //! Binding table offset for the buffer |
| //! \param [in] isWritable |
| //! True if buffer is writable, false if it is read only |
| //! |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS InitSurfaceCodecParams1D( |
| CODECHAL_SURFACE_CODEC_PARAMS* params, |
| PMOS_RESOURCE buffer, |
| uint32_t size, |
| uint32_t offset, |
| uint32_t cacheabilityControl, |
| uint32_t bindingTableOffset, |
| bool isWritable); |
| |
| //! |
| //! \brief Help function to initialize surface parameters for 2D surface |
| //! |
| //! \param [in, out] params |
| //! Pointer to surface codec parameters |
| //! \param [in] surface |
| //! Pointer to surface resource |
| //! \param [in] cacheabilityControl |
| //! Cache control setting for the surface |
| //! \param [in] bindingTableOffset |
| //! Binding table offset for the surface |
| //! \param [in] verticalLineStride |
| //! Vertical line stride for the surface |
| //! \param [in] isWritable |
| //! True if surface is writable, false if it is read only |
| //! |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS InitSurfaceCodecParams2D( |
| CODECHAL_SURFACE_CODEC_PARAMS* params, |
| PMOS_SURFACE surface, |
| uint32_t cacheabilityControl, |
| uint32_t bindingTableOffset, |
| uint32_t verticalLineStride, |
| bool isWritable); |
| |
| //! |
| //! \brief Help function to initialize surface parameters for VME surface |
| //! |
| //! \param [in, out] params |
| //! Pointer to surface codec parameters |
| //! \param [in] surface |
| //! Pointer to surface resource |
| //! \param [in] cacheabilityControl |
| //! Cache control setting for the surface |
| //! \param [in] bindingTableOffset |
| //! Binding table offset for the surface |
| //! |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS InitSurfaceCodecParamsVME( |
| CODECHAL_SURFACE_CODEC_PARAMS* params, |
| PMOS_SURFACE surface, |
| uint32_t cacheabilityControl, |
| uint32_t bindingTableOffset); |
| |
| //! |
| //! \brief Help function to calcuate ROI Ratio need by BRC Kernel |
| //! |
| //! \return ROI ratio |
| //! |
| uint8_t CalculateROIRatio(); |
| |
| //! |
| //! \brief Help function to calcuate the temporal difference between current and reference picture |
| //! |
| //! \param [in] refPic |
| //! Reference picture. |
| //! |
| //! \return Temporal difference between current and reference picture |
| //! |
| int16_t ComputeTemporalDifference(const CODEC_PICTURE& refPic); |
| |
| //! |
| //! \brief Help function to get start code offset |
| //! \details Search the start code from address addr to (addr + size) |
| //! |
| //! \param [in] addr |
| //! Pointer to memory location to start searching for start code |
| //! \param [in] size |
| //! End of the memory address to search for start code is [addr + size] |
| //! |
| //! \return Offset of start code |
| //! |
| uint32_t GetStartCodeOffset(uint8_t* addr, uint32_t size); |
| |
| //! |
| //! \brief Help function to get picture header size |
| //! |
| //! \return Size of picture header |
| //! |
| uint32_t GetPicHdrSize(); |
| |
| //! |
| //! \brief Wait for PAK engine ready |
| //! |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS WaitForPak(); |
| |
| //! |
| //! \brief Wait for reference frame ready |
| //! |
| //! \param [in] mbCodeIdx |
| //! Mb code index for reference frame |
| //! |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS WaitForRefFrameReady(uint8_t mbCodeIdx); |
| |
| //! |
| //! \brief Add HCP_WEIGHT_OFFSET_STATE command to command buffer |
| //! |
| //! \param [in, out] cmdBuffer |
| //! Pointer to the command buffer |
| //! \param [in] hevcSlcParams |
| //! Pointer to HEVC slice parameters |
| //! |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| virtual MOS_STATUS AddHcpWeightOffsetStateCmd( |
| PMOS_COMMAND_BUFFER cmdBuffer, |
| PMHW_BATCH_BUFFER batchBuffer, |
| PCODEC_HEVC_ENCODE_SLICE_PARAMS hevcSlcParams); |
| |
| //! |
| //! \brief Put slice level commands in command buffer |
| //! |
| //! \param [in] cmdBuffer |
| //! Pointer to command buffer |
| //! \param [in] params |
| //! Pointer to slice state parameters |
| //! |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| virtual MOS_STATUS SendHwSliceEncodeCommand( |
| PMOS_COMMAND_BUFFER cmdBuffer, |
| PMHW_VDBOX_HEVC_SLICE_STATE params); |
| |
| //! |
| //! \brief Allocate encoder states resources |
| //! |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS AllocateEncStatsResources(); |
| |
| //! |
| //! \brief Free encoder states resources |
| //! |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS FreeEncStatsResources(); |
| |
| //! |
| //! \brief Get Current Frame BRC Level |
| //! |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| virtual MOS_STATUS GetFrameBrcLevel(); |
| |
| //! Inherited virtual functions |
| virtual bool CheckSupportedFormat(PMOS_SURFACE surface); |
| virtual MOS_STATUS Initialize(CodechalSetting * settings); |
| virtual MOS_STATUS AllocateBrcResources(); |
| virtual MOS_STATUS FreeBrcResources(); |
| virtual MOS_STATUS InitializePicture(const EncoderParams& params); |
| virtual MOS_STATUS SetSequenceStructs(); |
| virtual MOS_STATUS SetPictureStructs(); |
| virtual MOS_STATUS SetSliceStructs(); |
| virtual MOS_STATUS ReadHcpStatus(PMOS_COMMAND_BUFFER cmdBuffer); |
| virtual MOS_STATUS UserFeatureKeyReport(); |
| virtual MOS_STATUS ValidateRefFrameData(PCODEC_HEVC_ENCODE_SLICE_PARAMS slcParams); |
| virtual MOS_STATUS ExecutePictureLevel(); |
| virtual MOS_STATUS ExecuteSliceLevel(); |
| |
| //! |
| //! \brief Read stats for BRC from PAK |
| //! |
| //! \param [in] cmdBuffer |
| //! Pointer to command buffer |
| //! |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| virtual MOS_STATUS ReadBrcPakStats(PMOS_COMMAND_BUFFER cmdBuffer); |
| |
| //! |
| //! \brief Setup ME curbe params |
| //! |
| //! \param [in, out] curbeParams |
| //! ME curbe params to be initialized in this function |
| //! |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| virtual MOS_STATUS SetMeCurbeParams( |
| CodechalKernelHme::CurbeParam &curbeParams); |
| |
| //! |
| //! \brief Setup ME surface params |
| //! |
| //! \param [in] surfaceParams |
| //! ME curbe params |
| //! \param [in, out] surfaceParams |
| //! ME surface params to be initialized in this function |
| //! |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| virtual MOS_STATUS SetMeSurfaceParams( |
| CodechalKernelHme::SurfaceParams &surfaceParams); |
| |
| //! |
| //! \brief Top level function for ME kernel |
| //! |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| virtual MOS_STATUS EncodeMeKernel(); |
| |
| //! |
| //! \brief Allocate ENC resources when LCU size is 64 |
| //! |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| virtual MOS_STATUS AllocateEncResourcesLCU64() |
| { |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Get max supported number of reference frames |
| //! |
| //! \param [out] maxNumRef0 |
| //! Max suppoted number of referenace frame 0 |
| //! \param [out] maxNumRef1 |
| //! Max suppoted number of referenace frame 1 |
| //! |
| //! \return void |
| //! |
| virtual void GetMaxRefFrames(uint8_t& maxNumRef0, uint8_t& maxNumRef1) = 0; |
| |
| //! |
| //! \brief Prepare and add Hcp Pipe Mode Select Cmd |
| //! |
| //! \param [out] cmdBuffer |
| //! CmdBuffer to add the cmd |
| //! |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| virtual MOS_STATUS AddHcpPipeModeSelectCmd(MOS_COMMAND_BUFFER* cmdBuffer); |
| |
| //! |
| //! \brief Prepare and add all Hcp Surface State Cmds |
| //! |
| //! \param [out] cmdBuffer |
| //! CmdBuffer to add the cmd |
| //! |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| virtual MOS_STATUS AddHcpSurfaceStateCmds(MOS_COMMAND_BUFFER* cmdBuffer); |
| |
| //! |
| //! \brief Prepare and add Hcp Picture State Cmd |
| //! |
| //! \param [out] cmdBuffer |
| //! CmdBuffer to add the cmd |
| //! |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| virtual MOS_STATUS AddHcpPictureStateCmd(MOS_COMMAND_BUFFER* cmdBuffer); |
| |
| //! |
| //! \brief Create ROI surfaces for BRC LCU Update kernel |
| //! |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS SetupROISurface(); |
| //! |
| //! \brief Generate codechal dumps for HME kernel |
| //! |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| MOS_STATUS DumpHMESurfaces(); |
| //! |
| //! \brief Get rounding inter/intra for current frame to use |
| //! |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, else fail reason |
| //! |
| virtual MOS_STATUS GetRoundingIntraInterToUse(); |
| }; |
| #endif // __CODECHAL_ENCODE_HEVC_H__ |