blob: 8efd02f0ac435df58a7d884a57991c82f24fe974 [file] [log] [blame]
/*
* 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__