blob: ea0c21b08a90d7302131248f13126b8b19da020f [file] [log] [blame]
/*
* Copyright (c) 2019-2022, 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 decode_hevc_picture_packet_xe_m_base.cpp
//! \brief Defines the interface for hevc decode picture packet
//!
#include "codechal_utilities.h"
#include "decode_hevc_picture_packet_xe_m_base.h"
#include "decode_hevc_phase_real_tile.h"
#include "decode_hevc_phase_front_end.h"
#include "decode_hevc_phase_back_end.h"
#include "decode_common_feature_defs.h"
#include "decode_hevc_mem_compression.h"
#include "decode_resource_auto_lock.h"
namespace decode
{
HevcDecodePicPktXe_M_Base::~HevcDecodePicPktXe_M_Base()
{
FreeResources();
}
MOS_STATUS HevcDecodePicPktXe_M_Base::FreeResources()
{
DECODE_FUNC_CALL();
if (m_allocator != nullptr)
{
m_allocator->Destroy(m_resMfdDeblockingFilterRowStoreScratchBuffer);
m_allocator->Destroy(m_resMfdDeblockingFilterRowStoreScratchBuffer);
m_allocator->Destroy(m_resDeblockingFilterTileRowStoreScratchBuffer);
m_allocator->Destroy(m_resDeblockingFilterColumnRowStoreScratchBuffer);
m_allocator->Destroy(m_resMetadataLineBuffer);
m_allocator->Destroy(m_resMetadataTileLineBuffer);
m_allocator->Destroy(m_resMetadataTileColumnBuffer);
m_allocator->Destroy(m_resSaoLineBuffer);
m_allocator->Destroy(m_resSaoTileLineBuffer);
m_allocator->Destroy(m_resSaoTileColumnBuffer);
m_allocator->Destroy(m_resSliceStateStreamOutBuffer);
m_allocator->Destroy(m_resMvUpRightColStoreBuffer);
m_allocator->Destroy(m_resIntraPredUpRightColStoreBuffer);
m_allocator->Destroy(m_resIntraPredLeftReconColStoreBuffer);
m_allocator->Destroy(m_resCABACSyntaxStreamOutBuffer);
m_allocator->Destroy(m_resCABACStreamOutSizeBuffer);
#if MOS_EVENT_TRACE_DUMP_SUPPORTED
m_allocator->Destroy(m_tempRefSurf);
#endif
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS HevcDecodePicPktXe_M_Base::Init()
{
DECODE_FUNC_CALL();
DECODE_CHK_NULL(m_featureManager);
DECODE_CHK_NULL(m_hwInterface);
DECODE_CHK_NULL(m_osInterface);
DECODE_CHK_NULL(m_miInterface);
DECODE_CHK_NULL(m_hevcPipeline);
DECODE_CHK_NULL(m_hcpInterface);
m_hevcBasicFeature = dynamic_cast<HevcBasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
DECODE_CHK_NULL(m_hevcBasicFeature);
#ifdef _DECODE_PROCESSING_SUPPORTED
m_downSamplingFeature = dynamic_cast<DecodeDownSamplingFeature*>(m_featureManager->GetFeature(DecodeFeatureIDs::decodeDownSampling));
DecodeSubPacket* subPacket = m_hevcPipeline->GetSubPacket(DecodePacketId(m_hevcPipeline, downSamplingSubPacketId));
m_downSamplingPkt = dynamic_cast<DecodeDownSamplingPkt *>(subPacket);
#endif
m_allocator = m_pipeline ->GetDecodeAllocator();
DECODE_CHK_NULL(m_allocator);
DECODE_CHK_STATUS(AllocateFixedResources());
return MOS_STATUS_SUCCESS;
}
MOS_STATUS HevcDecodePicPktXe_M_Base::Prepare()
{
DECODE_FUNC_CALL();
m_hevcPicParams = m_hevcBasicFeature->m_hevcPicParams;
m_hevcIqMatrixParams = m_hevcBasicFeature->m_hevcIqMatrixParams;
m_hevcRextPicParams = m_hevcBasicFeature->m_hevcRextPicParams;
m_hevcSccPicParams = m_hevcBasicFeature->m_hevcSccPicParams;
#ifdef _MMC_SUPPORTED
m_mmcState = m_hevcPipeline->GetMmcState();
DECODE_CHK_NULL(m_mmcState);
#endif
DECODE_CHK_STATUS(SetRowstoreCachingOffsets());
DECODE_CHK_STATUS(AllocateVariableResources());
return MOS_STATUS_SUCCESS;
}
MOS_STATUS HevcDecodePicPktXe_M_Base::SetPhase(DecodePhase *phase)
{
DECODE_FUNC_CALL();
m_phase = phase;
return MOS_STATUS_SUCCESS;
}
MOS_STATUS HevcDecodePicPktXe_M_Base::ReportCabacStreamOutSize(MOS_COMMAND_BUFFER &cmdBuffer)
{
DECODE_FUNC_CALL();
DECODE_CHK_NULL(m_resCABACStreamOutSizeBuffer);
auto mmioRegistersHcp = m_hwInterface->GetHcpInterface()->GetMmioRegisters(MHW_VDBOX_NODE_1);
MHW_MI_STORE_REGISTER_MEM_PARAMS params;
MOS_ZeroMemory(&params, sizeof(MHW_MI_STORE_REGISTER_MEM_PARAMS));
params.presStoreBuffer = &m_resCABACStreamOutSizeBuffer->OsResource;
params.dwOffset = 0;
params.dwRegister = mmioRegistersHcp->hcpDebugFEStreamOutSizeRegOffset;
DECODE_CHK_STATUS(m_miInterface->AddMiStoreRegisterMemCmd(
&cmdBuffer,
&params));
return MOS_STATUS_SUCCESS;
}
bool HevcDecodePicPktXe_M_Base::IsRealTilePhase()
{
if (m_phase == nullptr)
{
return false;
}
HevcPhaseRealTile *realtilePhase = dynamic_cast<HevcPhaseRealTile *>(m_phase);
return (realtilePhase != nullptr);
}
bool HevcDecodePicPktXe_M_Base::IsFrontEndPhase()
{
if (m_phase == nullptr)
{
return false;
}
HevcPhaseFrontEnd *frontEndPhase = dynamic_cast<HevcPhaseFrontEnd *>(m_phase);
return (frontEndPhase != nullptr);
}
bool HevcDecodePicPktXe_M_Base::IsBackEndPhase()
{
if (m_phase == nullptr)
{
return false;
}
HevcPhaseBackEnd *backEndPhase = dynamic_cast<HevcPhaseBackEnd *>(m_phase);
return (backEndPhase != nullptr);
}
MOS_STATUS HevcDecodePicPktXe_M_Base::SetRowstoreCachingOffsets()
{
if (m_hcpInterface->IsRowStoreCachingSupported())
{
MHW_VDBOX_ROWSTORE_PARAMS rowstoreParams;
rowstoreParams.Mode = CODECHAL_DECODE_MODE_HEVCVLD;
rowstoreParams.dwPicWidth = m_hevcBasicFeature->m_width;
rowstoreParams.bMbaff = false;
rowstoreParams.ucBitDepthMinus8 = (uint8_t)MOS_MAX(m_hevcPicParams->bit_depth_luma_minus8,
m_hevcPicParams->bit_depth_chroma_minus8);
rowstoreParams.ucChromaFormat = m_hevcPicParams->chroma_format_idc;
rowstoreParams.ucLCUSize = (uint8_t)m_hevcBasicFeature->m_ctbSize;
DECODE_CHK_STATUS(m_hwInterface->SetRowstoreCachingOffsets(&rowstoreParams));
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS HevcDecodePicPktXe_M_Base::AllocateFixedResources()
{
DECODE_FUNC_CALL();
if (m_resSliceStateStreamOutBuffer == nullptr)
{
uint32_t sizeOfBuffer = CODECHAL_HEVC_MAX_NUM_SLICES_LVL_6 * sliceStateCachelinesPerSlice * CODECHAL_CACHELINE_SIZE;
m_resSliceStateStreamOutBuffer = m_allocator->AllocateBuffer(
sizeOfBuffer,
"SliceStateStreamOut",
resourceInternalReadWriteCache,
notLockableVideoMem);
DECODE_CHK_NULL(m_resSliceStateStreamOutBuffer);
}
if (m_resCABACStreamOutSizeBuffer == nullptr)
{
m_resCABACStreamOutSizeBuffer = m_allocator->AllocateBuffer(
sizeof(uint64_t),
"CABACStreamOutSizeBuffer",
resourceInternalReadWriteCache,
notLockableVideoMem);
DECODE_CHK_NULL(m_resCABACStreamOutSizeBuffer);
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS HevcDecodePicPktXe_M_Base::AllocateVariableResources()
{
DECODE_FUNC_CALL();
MHW_VDBOX_HCP_BUFFER_SIZE_PARAMS hcpBufSizeParam;
MOS_ZeroMemory(&hcpBufSizeParam, sizeof(hcpBufSizeParam));
hcpBufSizeParam.ucMaxBitDepth = m_hevcBasicFeature->m_bitDepth;
hcpBufSizeParam.ucChromaFormat = m_hevcBasicFeature->m_chromaFormat;
hcpBufSizeParam.dwCtbLog2SizeY = m_hevcPicParams->log2_diff_max_min_luma_coding_block_size +
m_hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3;
hcpBufSizeParam.dwPicWidth = m_hevcBasicFeature->m_width;
hcpBufSizeParam.dwPicHeight = m_hevcBasicFeature->m_height;
hcpBufSizeParam.dwMaxFrameSize = m_hevcBasicFeature->m_dataSize;
auto AllocateBuffer = [&] (PMOS_BUFFER &buffer, MHW_VDBOX_HCP_INTERNAL_BUFFER_TYPE bufferType, const char *bufferName)
{
DECODE_CHK_STATUS(m_hcpInterface->GetHevcBufferSize(bufferType, &hcpBufSizeParam));
if (buffer == nullptr)
{
buffer = m_allocator->AllocateBuffer(
hcpBufSizeParam.dwBufferSize, bufferName, resourceInternalReadWriteCache, notLockableVideoMem);
DECODE_CHK_NULL(buffer);
}
else
{
DECODE_CHK_STATUS(m_allocator->Resize(
buffer, hcpBufSizeParam.dwBufferSize, notLockableVideoMem));
}
return MOS_STATUS_SUCCESS;
};
if (!m_hcpInterface->IsHevcDfRowstoreCacheEnabled())
{
// Deblocking Filter Row Store Scratch buffer
DECODE_CHK_STATUS(AllocateBuffer(
m_resMfdDeblockingFilterRowStoreScratchBuffer,
MHW_VDBOX_HCP_INTERNAL_BUFFER_DBLK_LINE,
"DeblockingScratchBuffer"));
}
// Deblocking Filter Tile Row Store Scratch data surface
DECODE_CHK_STATUS(AllocateBuffer(
m_resDeblockingFilterTileRowStoreScratchBuffer,
MHW_VDBOX_HCP_INTERNAL_BUFFER_DBLK_TILE_LINE,
"DeblockingTileScratchBuffer"));
// Deblocking Filter Column Row Store Scratch data surface
DECODE_CHK_STATUS(AllocateBuffer(
m_resDeblockingFilterColumnRowStoreScratchBuffer,
MHW_VDBOX_HCP_INTERNAL_BUFFER_DBLK_TILE_COL,
"DeblockingColumnScratchBuffer"));
if (!m_hcpInterface->IsHevcDatRowstoreCacheEnabled())
{
// Metadata Line buffer
DECODE_CHK_STATUS(AllocateBuffer(
m_resMetadataLineBuffer,
MHW_VDBOX_HCP_INTERNAL_BUFFER_META_LINE,
"MetadataLineBuffer"));
}
// Metadata Tile Line buffer
DECODE_CHK_STATUS(AllocateBuffer(
m_resMetadataTileLineBuffer,
MHW_VDBOX_HCP_INTERNAL_BUFFER_META_TILE_LINE,
"MetadataTileLineBuffer"));
// Metadata Tile Column buffer
DECODE_CHK_STATUS(AllocateBuffer(
m_resMetadataTileColumnBuffer,
MHW_VDBOX_HCP_INTERNAL_BUFFER_META_TILE_COL,
"MetadataTileColumnBuffer"));
if (!m_hcpInterface->IsHevcSaoRowstoreCacheEnabled())
{
// SAO Line buffer
DECODE_CHK_STATUS(AllocateBuffer(
m_resSaoLineBuffer,
MHW_VDBOX_HCP_INTERNAL_BUFFER_SAO_LINE,
"SaoLineBuffer"));
}
// SAO Tile Line buffer
DECODE_CHK_STATUS(AllocateBuffer(
m_resSaoTileLineBuffer,
MHW_VDBOX_HCP_INTERNAL_BUFFER_SAO_TILE_LINE,
"SaoTileLineBuffer"));
// SAO Tile Column buffer
DECODE_CHK_STATUS(AllocateBuffer(
m_resSaoTileColumnBuffer,
MHW_VDBOX_HCP_INTERNAL_BUFFER_SAO_TILE_COL,
"SaoTileColumnBuffer"));
// MV up right column store buffer
DECODE_CHK_STATUS(AllocateBuffer(
m_resMvUpRightColStoreBuffer,
MHW_VDBOX_HCP_INTERNAL_BUFFER_MV_UP_RT_COL,
"MVUpperRightColumnStore"));
// Intra prediction up right column store buffer
DECODE_CHK_STATUS(AllocateBuffer(
m_resIntraPredUpRightColStoreBuffer,
MHW_VDBOX_HCP_INTERNAL_BUFFER_INTRA_PRED_UP_RIGHT_COL,
"MVUpperRightColumnStore"));
// Intra prediction left recon column store buffer
DECODE_CHK_STATUS(AllocateBuffer(
m_resIntraPredLeftReconColStoreBuffer,
MHW_VDBOX_HCP_INTERNAL_BUFFER_INTRA_PRED_LFT_RECON_COL,
"IntraPredLeftReconColumnStore"));
// Cabac stream out buffer
DECODE_CHK_STATUS(AllocateBuffer(
m_resCABACSyntaxStreamOutBuffer,
MHW_VDBOX_HCP_INTERNAL_BUFFER_CABAC_STREAMOUT,
"CABACStreamOutBuffer"));
return MOS_STATUS_SUCCESS;
}
void HevcDecodePicPktXe_M_Base::SetHcpPipeModeSelectParams(MHW_VDBOX_PIPE_MODE_SELECT_PARAMS& pipeModeSelectParams)
{
DECODE_FUNC_CALL();
pipeModeSelectParams.Mode = m_hevcBasicFeature->m_mode;
pipeModeSelectParams.bStreamOutEnabled = false;
pipeModeSelectParams.bShortFormatInUse = m_hevcPipeline->IsShortFormat();
}
MOS_STATUS HevcDecodePicPktXe_M_Base::SetHcpDstSurfaceParams(MHW_VDBOX_SURFACE_PARAMS& dstSurfaceParams)
{
DECODE_FUNC_CALL();
dstSurfaceParams.Mode = CODECHAL_DECODE_MODE_HEVCVLD;
dstSurfaceParams.psSurface = &m_hevcBasicFeature->m_destSurface;
dstSurfaceParams.ucSurfaceStateId = CODECHAL_HCP_DECODED_SURFACE_ID;
dstSurfaceParams.ChromaType = m_hevcPicParams->chroma_format_idc;
dstSurfaceParams.ucBitDepthLumaMinus8 = m_hevcPicParams->bit_depth_luma_minus8;
dstSurfaceParams.ucBitDepthChromaMinus8 = m_hevcPicParams->bit_depth_chroma_minus8;
dstSurfaceParams.dwUVPlaneAlignment = 1 << (m_hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3);
#ifdef _MMC_SUPPORTED
DECODE_CHK_STATUS(m_mmcState->SetSurfaceMmcState(dstSurfaceParams.psSurface));
DECODE_CHK_STATUS(m_mmcState->GetSurfaceMmcState(dstSurfaceParams.psSurface, &dstSurfaceParams.mmcState));
DECODE_CHK_STATUS(m_mmcState->GetSurfaceMmcFormat(dstSurfaceParams.psSurface, &dstSurfaceParams.dwCompressionFormat));
#endif
return MOS_STATUS_SUCCESS;
}
MOS_STATUS HevcDecodePicPktXe_M_Base::SetHcpRefSurfaceParams(
const MHW_VDBOX_PIPE_BUF_ADDR_PARAMS &pipeBufAddrParams, MHW_VDBOX_SURFACE_PARAMS& refSurfaceParams)
{
DECODE_FUNC_CALL();
refSurfaceParams.Mode = CODECHAL_DECODE_MODE_HEVCVLD;
refSurfaceParams.psSurface = &m_hevcBasicFeature->m_destSurface; // For HEVC decode, reference should be same format as dest surface
refSurfaceParams.ucSurfaceStateId = CODECHAL_HCP_REF_SURFACE_ID;
refSurfaceParams.ChromaType = m_hevcPicParams->chroma_format_idc;
refSurfaceParams.ucBitDepthLumaMinus8 = m_hevcPicParams->bit_depth_luma_minus8;
refSurfaceParams.ucBitDepthChromaMinus8 = m_hevcPicParams->bit_depth_chroma_minus8;
refSurfaceParams.dwUVPlaneAlignment = 1 << (m_hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3);
#ifdef _MMC_SUPPORTED
HevcDecodeMemComp *hevcDecodeMemComp = dynamic_cast<HevcDecodeMemComp *>(m_mmcState);
DECODE_CHK_NULL(hevcDecodeMemComp);
// Set refSurfaceParams mmcState as MOS_MEMCOMP_MC to satisfy MmcEnable in AddHcpSurfaceCmd
// The actual mmcstate is recorded by refSurfaceParams.mmcSkipMask
refSurfaceParams.mmcState = MOS_MEMCOMP_MC;
DECODE_CHK_STATUS(hevcDecodeMemComp->SetRefSurfaceMask(*m_hevcBasicFeature, pipeBufAddrParams.presReferences, refSurfaceParams.mmcSkipMask));
DECODE_CHK_STATUS(hevcDecodeMemComp->SetRefSurfaceCompressionFormat(*m_hevcBasicFeature, pipeBufAddrParams.presReferences, refSurfaceParams.dwCompressionFormat));
#endif
return MOS_STATUS_SUCCESS;
}
MOS_STATUS HevcDecodePicPktXe_M_Base::AddHcpSurfaces(MOS_COMMAND_BUFFER &cmdBuffer, const MHW_VDBOX_PIPE_BUF_ADDR_PARAMS &pipeBufAddrParams)
{
DECODE_FUNC_CALL();
MHW_VDBOX_SURFACE_PARAMS dstSurfaceParams;
MOS_ZeroMemory(&dstSurfaceParams, sizeof(dstSurfaceParams));
DECODE_CHK_STATUS(SetHcpDstSurfaceParams(dstSurfaceParams));
DECODE_CHK_STATUS(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &dstSurfaceParams));
MHW_VDBOX_SURFACE_PARAMS refSurfaceParams;
MOS_ZeroMemory(&refSurfaceParams, sizeof(refSurfaceParams));
SetHcpRefSurfaceParams(pipeBufAddrParams, refSurfaceParams);
DECODE_CHK_STATUS(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &refSurfaceParams));
return MOS_STATUS_SUCCESS;
}
MOS_STATUS HevcDecodePicPktXe_M_Base::FixHcpPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS& pipeBufAddrParams)
{
if (m_hevcBasicFeature->m_refFrames.m_curIsIntra)
{
PMOS_RESOURCE dummyRef = &(m_hevcBasicFeature->m_dummyReference.OsResource);
if (m_hevcBasicFeature->m_useDummyReference &&
!m_allocator->ResourceIsNull(dummyRef))
{
// set all ref pic addresses to valid addresses for error concealment purpose
for (uint32_t i = 0; i < CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC; i++)
{
if (pipeBufAddrParams.presReferences[i] == nullptr)
{
pipeBufAddrParams.presReferences[i] = dummyRef;
m_hevcBasicFeature->m_dummyReferenceSlot[i] = true;
}
}
}
}
else
{
PMOS_RESOURCE validRef = m_hevcBasicFeature->m_refFrames.GetValidReference();
for (uint8_t i = 0; i < CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC; i++)
{
// error concealment for the unset reference addresses and unset mv buffers
if (pipeBufAddrParams.presReferences[i] == nullptr)
{
pipeBufAddrParams.presReferences[i] = validRef;
}
}
PMOS_BUFFER validMvBuf = m_hevcBasicFeature->m_mvBuffers.GetValidBufferForReference(
m_hevcBasicFeature->m_refFrameIndexList);
for (uint32_t i = 0; i < CODEC_NUM_HEVC_MV_BUFFERS; i++)
{
if (pipeBufAddrParams.presColMvTempBuffer[i] == nullptr)
{
pipeBufAddrParams.presColMvTempBuffer[i] = &validMvBuf->OsResource;
}
}
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS HevcDecodePicPktXe_M_Base::SetHcpPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS& pipeBufAddrParams)
{
DECODE_FUNC_CALL();
pipeBufAddrParams.Mode = m_hevcBasicFeature->m_mode;
PMOS_SURFACE destSurface = &(m_hevcBasicFeature->m_destSurface);
pipeBufAddrParams.psPreDeblockSurface = destSurface;
#ifdef _MMC_SUPPORTED
DECODE_CHK_STATUS(m_mmcState->GetSurfaceMmcState(destSurface, &pipeBufAddrParams.PreDeblockSurfMmcState));
#endif
pipeBufAddrParams.presMfdDeblockingFilterRowStoreScratchBuffer =
&(m_resMfdDeblockingFilterRowStoreScratchBuffer->OsResource);
pipeBufAddrParams.presDeblockingFilterTileRowStoreScratchBuffer =
&(m_resDeblockingFilterTileRowStoreScratchBuffer->OsResource);
pipeBufAddrParams.presDeblockingFilterColumnRowStoreScratchBuffer =
&(m_resDeblockingFilterColumnRowStoreScratchBuffer->OsResource);
pipeBufAddrParams.presMetadataLineBuffer = &(m_resMetadataLineBuffer->OsResource);
pipeBufAddrParams.presMetadataTileLineBuffer = &(m_resMetadataTileLineBuffer->OsResource);
pipeBufAddrParams.presMetadataTileColumnBuffer = &(m_resMetadataTileColumnBuffer->OsResource);
pipeBufAddrParams.presSaoLineBuffer = &(m_resSaoLineBuffer->OsResource);
pipeBufAddrParams.presSaoTileLineBuffer = &(m_resSaoTileLineBuffer->OsResource);
pipeBufAddrParams.presSaoTileColumnBuffer = &(m_resSaoTileColumnBuffer->OsResource);
auto mvBuffers = &(m_hevcBasicFeature->m_mvBuffers);
PMOS_BUFFER curMvBuffer = mvBuffers->GetCurBuffer();
DECODE_CHK_NULL(curMvBuffer);
pipeBufAddrParams.presCurMvTempBuffer = &(curMvBuffer->OsResource);
HevcReferenceFrames &refFrames = m_hevcBasicFeature->m_refFrames;
const std::vector<uint8_t> & activeRefList = refFrames.GetActiveReferenceList(*m_hevcPicParams);
if (!refFrames.m_curIsIntra)
{
DECODE_ASSERT(activeRefList.size() <= 8);
for (uint8_t i = 0; i < activeRefList.size(); i++)
{
uint8_t frameIdx = activeRefList[i];
if (frameIdx >= CODECHAL_NUM_UNCOMPRESSED_SURFACE_HEVC)
{
continue;
}
pipeBufAddrParams.presReferences[i] = refFrames.GetReferenceByFrameIndex(frameIdx);
if (pipeBufAddrParams.presReferences[i] == nullptr)
{
PCODEC_REF_LIST curFrameInRefList = refFrames.m_refList[m_hevcPicParams->CurrPic.FrameIdx];
DECODE_CHK_NULL(curFrameInRefList);
MOS_ZeroMemory(&curFrameInRefList->resRefPic, sizeof(MOS_RESOURCE));
DECODE_ASSERTMESSAGE("Reference frame for current Frame is not exist, current frame will be skipped. Thus, clear current frame resource in reference list.");
return MOS_STATUS_INVALID_PARAMETER;
}
PMOS_BUFFER mvBuf = mvBuffers->GetBufferByFrameIndex(frameIdx);
pipeBufAddrParams.presColMvTempBuffer[i] = mvBuf ? (&mvBuf->OsResource) : nullptr;
// Return error if reference surface's pitch * height is less than dest surface.
MOS_SURFACE refSurface;
refSurface.OsResource = *(pipeBufAddrParams.presReferences[i]);
DECODE_CHK_STATUS(m_allocator->GetSurfaceInfo(&refSurface));
DECODE_CHK_COND((refSurface.dwPitch * refSurface.dwHeight) < (destSurface->dwPitch * destSurface->dwHeight),
"Reference surface's pitch * height is less than Dest surface.");
}
}
DECODE_CHK_STATUS(FixHcpPipeBufAddrParams(pipeBufAddrParams));
if (m_hevcBasicFeature->m_isSCCIBCMode)
{
uint8_t IBCRefIdx = refFrames.m_IBCRefIdx;
DECODE_CHK_COND(activeRefList.size() <= IBCRefIdx, "Invalid IBC reference index.");
uint8_t refIdxMask = 0;
for (uint8_t i = 0; i < CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC; i++)
{
uint8_t IBCFrameIdx = activeRefList[IBCRefIdx];
if (pipeBufAddrParams.presReferences[i] == refFrames.GetReferenceByFrameIndex(IBCFrameIdx))
{
refIdxMask |= (1 << i);
}
}
pipeBufAddrParams.IBCRefIdxMask = refIdxMask;
}
CODECHAL_DEBUG_TOOL(
CodechalDebugInterface *debugInterface = m_pipeline->GetDebugInterface();
DECODE_CHK_NULL(debugInterface);
for (uint32_t n = 0; n < CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC; n++)
{
if (pipeBufAddrParams.presReferences[n] != nullptr)
{
MOS_SURFACE dstSurface;
MOS_ZeroMemory(&dstSurface, sizeof(MOS_SURFACE));
dstSurface.OsResource = *(pipeBufAddrParams.presReferences[n]);
DECODE_CHK_STATUS(CodecHalGetResourceInfo(m_osInterface, &dstSurface));
std::string refSurfDumpName = "RefSurf_" + std::to_string(n);
DECODE_CHK_STATUS(debugInterface->DumpYUVSurface(
&dstSurface,
CodechalDbgAttr::attrReferenceSurfaces,
refSurfDumpName.c_str()));
}
if (pipeBufAddrParams.presColMvTempBuffer[n] != nullptr)
{
std::string mvBufDumpName = "_DEC_" + std::to_string(n);
DECODE_CHK_STATUS(debugInterface->DumpBuffer(
pipeBufAddrParams.presColMvTempBuffer[n],
CodechalDbgAttr::attrMvData,
mvBufDumpName.c_str(),
curMvBuffer->size));
}
})
#if MOS_EVENT_TRACE_DUMP_SUPPORTED
if (MOS_TraceKeyEnabled(TR_KEY_DECODE_MV))
{
TraceDataDumpMV(pipeBufAddrParams);
}
if (MOS_TraceKeyEnabled(TR_KEY_DECODE_REFYUV))
{
TraceDataDumpReferences(pipeBufAddrParams);
}
#endif
return MOS_STATUS_SUCCESS;
}
#if MOS_EVENT_TRACE_DUMP_SUPPORTED
MOS_STATUS HevcDecodePicPktXe_M_Base::TraceDataDumpMV(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS &pipeBufAddrParams)
{
auto mvBuffers = &(m_hevcBasicFeature->m_mvBuffers);
PMOS_BUFFER curMvBuffer = mvBuffers->GetCurBuffer();
DECODE_CHK_NULL(curMvBuffer);
for (uint32_t n = 0; n < CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC; n++)
{
if (!m_allocator->ResourceIsNull(pipeBufAddrParams.presReferences[n]))
{
if (pipeBufAddrParams.presColMvTempBuffer[n] != nullptr)
{
ResourceAutoLock resLock(m_allocator, pipeBufAddrParams.presColMvTempBuffer[n]);
auto pData = (uint8_t *)resLock.LockResourceForRead();
DECODE_CHK_NULL(pData);
MOS_TraceDataDump(
"Decode_HevcColMvTempBuffer",
n,
pData,
curMvBuffer->size);
m_allocator->UnLock(pipeBufAddrParams.presColMvTempBuffer[n]);
}
}
}
if (!m_allocator->ResourceIsNull(pipeBufAddrParams.presCurMvTempBuffer))
{
ResourceAutoLock resLock(m_allocator, pipeBufAddrParams.presCurMvTempBuffer);
auto pData = (uint8_t *)resLock.LockResourceForRead();
DECODE_CHK_NULL(pData);
MOS_TraceDataDump(
"Decode_HevcCurMvTempBuffer",
0,
pData,
curMvBuffer->size);
m_allocator->UnLock(pipeBufAddrParams.presCurMvTempBuffer);
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS HevcDecodePicPktXe_M_Base::TraceDataDumpReferences(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS &pipeBufAddrParams)
{
bool bReport = false;
for (uint32_t n = 0; n < CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC; n++)
{
if (!m_allocator->ResourceIsNull(pipeBufAddrParams.presReferences[n]))
{
bool bAllocate = false;
MOS_SURFACE dstSurface;
MOS_ZeroMemory(&dstSurface, sizeof(MOS_SURFACE));
dstSurface.OsResource = *(pipeBufAddrParams.presReferences[n]);
DECODE_CHK_STATUS(m_allocator->GetSurfaceInfo(&dstSurface));
if (!m_allocator->ResourceIsNull(&dstSurface.OsResource))
{
if (m_tempRefSurf == nullptr || m_allocator->ResourceIsNull(&m_tempRefSurf->OsResource))
{
bAllocate = true;
}
else if (m_tempRefSurf->dwWidth < dstSurface.dwWidth ||
m_tempRefSurf->dwHeight < dstSurface.dwHeight)
{
bAllocate = true;
}
else
{
bAllocate = false;
}
if (bAllocate)
{
if (!m_allocator->ResourceIsNull(&m_tempRefSurf->OsResource))
{
m_allocator->Destroy(m_tempRefSurf);
}
m_tempRefSurf = m_allocator->AllocateLinearSurface(
dstSurface.dwWidth,
dstSurface.dwHeight,
"Decode Ref Surf",
dstSurface.Format,
dstSurface.bIsCompressed,
resourceInputReference,
lockableSystemMem,
MOS_TILE_LINEAR_GMM);
}
DECODE_CHK_STATUS(m_osInterface->pfnDoubleBufferCopyResource(
m_osInterface,
&dstSurface.OsResource,
&m_tempRefSurf->OsResource,
false));
if (!bReport)
{
DECODE_EVENTDATA_YUV_SURFACE_INFO eventData =
{
PICTURE_FRAME,
0,
m_tempRefSurf->dwOffset,
m_tempRefSurf->YPlaneOffset.iYOffset,
m_tempRefSurf->dwPitch,
m_tempRefSurf->dwWidth,
m_tempRefSurf->dwHeight,
(uint32_t)m_tempRefSurf->Format,
m_tempRefSurf->UPlaneOffset.iLockSurfaceOffset,
m_tempRefSurf->VPlaneOffset.iLockSurfaceOffset,
m_tempRefSurf->UPlaneOffset.iSurfaceOffset,
m_tempRefSurf->VPlaneOffset.iSurfaceOffset,
};
MOS_TraceEvent(EVENT_DECODE_REF_DUMPINFO, EVENT_TYPE_INFO, &eventData, sizeof(eventData), NULL, 0);
bReport = true;
}
ResourceAutoLock resLock(m_allocator, &m_tempRefSurf->OsResource);
auto pData = (uint8_t *)resLock.LockResourceForRead();
DECODE_CHK_NULL(pData);
MOS_TraceDataDump(
"Decode_HEVCRefSurf",
n,
pData,
(uint32_t)m_tempRefSurf->OsResource.pGmmResInfo->GetSizeMainSurface());
m_allocator->UnLock(&m_tempRefSurf->OsResource);
}
}
}
return MOS_STATUS_SUCCESS;
}
#endif
void HevcDecodePicPktXe_M_Base::SetHcpIndObjBaseAddrParams(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS& indObjBaseAddrParams)
{
DECODE_FUNC_CALL();
indObjBaseAddrParams.Mode = m_hevcBasicFeature->m_mode;
indObjBaseAddrParams.dwDataSize = m_hevcBasicFeature->m_dataSize;
indObjBaseAddrParams.dwDataOffset = m_hevcBasicFeature->m_dataOffset;
indObjBaseAddrParams.presDataBuffer = &(m_hevcBasicFeature->m_resDataBuffer.OsResource);
}
MOS_STATUS HevcDecodePicPktXe_M_Base::AddHcpIndObjBaseAddrCmd(MOS_COMMAND_BUFFER &cmdBuffer)
{
DECODE_FUNC_CALL();
MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams;
MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams));
SetHcpIndObjBaseAddrParams(indObjBaseAddrParams);
DECODE_CHK_STATUS(m_hcpInterface->AddHcpIndObjBaseAddrCmd(&cmdBuffer, &indObjBaseAddrParams));
return MOS_STATUS_SUCCESS;
}
void HevcDecodePicPktXe_M_Base::SetHcpQmStateParams(MHW_VDBOX_QM_PARAMS& qmParams)
{
DECODE_FUNC_CALL();
qmParams.Standard = CODECHAL_HEVC;
qmParams.pHevcIqMatrix = (PMHW_VDBOX_HEVC_QM_PARAMS)m_hevcIqMatrixParams;
}
MOS_STATUS HevcDecodePicPktXe_M_Base::AddHcpQmStateCmd(MOS_COMMAND_BUFFER &cmdBuffer)
{
DECODE_FUNC_CALL();
MHW_VDBOX_QM_PARAMS qmParams;
MOS_ZeroMemory(&qmParams, sizeof(qmParams));
SetHcpQmStateParams(qmParams);
DECODE_CHK_STATUS(m_hcpInterface->AddHcpQmStateCmd(&cmdBuffer, &qmParams));
return MOS_STATUS_SUCCESS;
}
void HevcDecodePicPktXe_M_Base::SetHcpPicStateParams(MHW_VDBOX_HEVC_PIC_STATE& picStateParams)
{
DECODE_FUNC_CALL();
picStateParams.pHevcPicParams = m_hevcPicParams;
}
void HevcDecodePicPktXe_M_Base::SetHcpTileStateParams(MHW_VDBOX_HEVC_TILE_STATE& tileStateParams)
{
DECODE_FUNC_CALL();
tileStateParams.pHevcPicParams = m_hevcPicParams;
tileStateParams.pTileColWidth = (uint16_t *)m_hevcBasicFeature->m_tileCoding.GetTileColWidth();
tileStateParams.pTileRowHeight = (uint16_t *)m_hevcBasicFeature->m_tileCoding.GetTileRowHeight();
}
MOS_STATUS HevcDecodePicPktXe_M_Base::AddHcpTileStateCmd(MOS_COMMAND_BUFFER &cmdBuffer)
{
DECODE_FUNC_CALL();
MHW_VDBOX_HEVC_TILE_STATE tileStateParams;
MOS_ZeroMemory(&tileStateParams, sizeof(tileStateParams));
SetHcpTileStateParams(tileStateParams);
DECODE_CHK_STATUS(m_hcpInterface->AddHcpTileStateCmd(&cmdBuffer, &tileStateParams));
return MOS_STATUS_SUCCESS;
}
}