/* * Copyright (c) 2012-2020, 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_decode_hevc.cpp //! \brief Implements the decode interface extension for HEVC. //! \details Implements all functions required by CodecHal for HEVC decoding. //! #include "codechal_decoder.h" #include "codechal_secure_decode_interface.h" #include "codechal_decode_hevc.h" #include "codechal_mmc_decode_hevc.h" #include "codechal_decode_nv12top010.h" #include "media_interfaces_nv12top010.h" #include "hal_oca_interface.h" #if USE_CODECHAL_DEBUG_TOOL #include "codechal_debug.h" #endif //========================================================= uint8_t CodechalDecodeHevc::GetMvBufferIndex( uint8_t frameIdx) { PCODECHAL_DECODE_HEVC_MV_LIST hevcMVBufList = &m_hevcMvList[0]; uint8_t i; for (i = 0; i < CODEC_NUM_HEVC_MV_BUFFERS; i++) { if (!hevcMVBufList[i].bInUse) { hevcMVBufList[i].bInUse = true; hevcMVBufList[i].u8FrameId = frameIdx; break; } } if (i == CODEC_NUM_HEVC_MV_BUFFERS) { // Should never happen, something must be wrong CODECHAL_DECODE_ASSERTMESSAGE("Failed to get avaiable MV buffer."); } return i; } MOS_STATUS CodechalDecodeHevc::AllocateResourcesFixedSizes() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_DECODE_FUNCTION_ENTER; CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateSyncResource( m_osInterface, &m_resSyncObjectWaContextInUse)); CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalAllocateDataList( m_hevcRefList, CODECHAL_NUM_UNCOMPRESSED_SURFACE_HEVC)); MOS_ZeroMemory(&m_secondLevelBatchBuffer, CODEC_HEVC_NUM_SECOND_BB * sizeof(MHW_BATCH_BUFFER)); if (m_shortFormatInUse) { // Second level batch buffer for HuC FW to use uint32_t u32Size = MOS_ALIGN_CEIL(CODECHAL_HEVC_MAX_NUM_SLICES_LVL_6 * m_standardDecodeSizeNeeded, CODECHAL_PAGE_SIZE); for (int i = 0; i < CODEC_HEVC_NUM_SECOND_BB; i++) { CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_AllocateBb( m_osInterface, &m_secondLevelBatchBuffer[i], nullptr, u32Size)); m_secondLevelBatchBuffer[i].bSecondLevel = true; } // DMEM buffer send to HuC FW m_dmemBufferSize = GetDmemBufferSize(); for (uint32_t i = 0; i < CODECHAL_HEVC_NUM_DMEM_BUFFERS; i++) { CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer( &m_resDmemBuffer[i], m_dmemBufferSize, "DmemBuffer"), "Failed to allocate Dmem Buffer."); } } return eStatus; } MOS_STATUS CodechalDecodeHevc::AllocateResourcesVariableSizes() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_DECODE_FUNCTION_ENTER; uint32_t widthMax = MOS_MAX(m_width, m_widthLastMaxAlloced); uint32_t heightMax = MOS_MAX(m_height, m_heightLastMaxAlloced); CODECHAL_DECODE_VERBOSEMESSAGE("m_width = %d, Max Width = %d, m_height %d, Max Height = %d", m_width, widthMax, m_height, heightMax); uint8_t maxBitDepth = (m_is12BitHevc) ? 12 :((m_is10BitHevc) ? 10 : 8); uint8_t chromaFormatPic = m_hevcPicParams->chroma_format_idc; uint8_t chromaFormat = m_chromaFormatinProfile; CODECHAL_DECODE_ASSERT(chromaFormat >= chromaFormatPic); uint32_t u32CtbLog2SizeYPic = m_hevcPicParams->log2_diff_max_min_luma_coding_block_size + m_hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3; uint32_t ctbLog2SizeY = MOS_MAX(u32CtbLog2SizeYPic, m_ctbLog2SizeYMax); MHW_VDBOX_HCP_BUFFER_SIZE_PARAMS hcpBufSizeParam; MOS_ZeroMemory(&hcpBufSizeParam, sizeof(hcpBufSizeParam)); hcpBufSizeParam.ucMaxBitDepth = maxBitDepth; hcpBufSizeParam.ucChromaFormat = chromaFormat; hcpBufSizeParam.dwCtbLog2SizeY = ctbLog2SizeY; MHW_VDBOX_HCP_BUFFER_REALLOC_PARAMS reallocParam; MOS_ZeroMemory(&reallocParam, sizeof(reallocParam)); reallocParam.ucMaxBitDepth = maxBitDepth; reallocParam.ucChromaFormat = chromaFormat; reallocParam.dwCtbLog2SizeY = ctbLog2SizeY; reallocParam.dwCtbLog2SizeYMax = m_ctbLog2SizeYMax; if (m_is8BitFrameIn10BitHevc) { uint32_t i; // Init 8bitRTIndexMap array, 0xff means doesn't map to any InternalNV12RTSurface. if (!m_internalNv12RtIndexMapInitilized) { for (i = 0; i < CODECHAL_NUM_UNCOMPRESSED_SURFACE_HEVC; i++) { m_internalNv12RtIndexMap[i] = 0xff; } m_internalNv12RtIndexMapInitilized = true; } if (m_internalNv12RtIndexMap[m_currPic.FrameIdx] != 0xff) { if (!Mos_ResourceIsNull(&m_internalNv12RtSurfaces[m_internalNv12RtIndexMap[m_currPic.FrameIdx]].OsResource)) { m_osInterface->pfnFreeResource(m_osInterface, &m_internalNv12RtSurfaces[m_internalNv12RtIndexMap[m_currPic.FrameIdx]].OsResource); } } // Seek an available surface in InternalNV12RTSurface array. for (i = 0; i < CODECHAL_NUM_INTERNAL_NV12_RT_HEVC; i++) { if (Mos_ResourceIsNull(&m_internalNv12RtSurfaces[i].OsResource)) { m_internalNv12RtIndexMap[m_currPic.FrameIdx] = i; break; } } // If there is no available InternalNV12RTSurface in the array. if (i == CODECHAL_NUM_INTERNAL_NV12_RT_HEVC) { // Search an InternalNV12RTSurface to reuse. for (uint32_t j = 0; j < CODECHAL_NUM_UNCOMPRESSED_SURFACE_HEVC; j++) { if (m_internalNv12RtIndexMap[j] != 0xff && j != m_currPic.FrameIdx) { uint32_t k; // Check if InternalNV12RTSurface in reference list. for (k = 0; k < CODEC_MAX_NUM_REF_FRAME_HEVC; k++) { if (j == m_hevcPicParams->RefFrameList[k].FrameIdx) { break; } } // If InternalNV12RTSurface is not in reference list, reuse it. if (k == CODEC_MAX_NUM_REF_FRAME_HEVC) { m_internalNv12RtIndexMap[m_currPic.FrameIdx] = m_internalNv12RtIndexMap[j]; m_internalNv12RtIndexMap[j] = 0xff; break; } } } } uint32_t internalNV12RTIndex = m_internalNv12RtIndexMap[m_currPic.FrameIdx]; if (Mos_ResourceIsNull(&m_internalNv12RtSurfaces[internalNV12RTIndex].OsResource) || m_destSurface.dwWidth != m_internalNv12RtSurfaces[internalNV12RTIndex].dwWidth || m_destSurface.dwHeight != m_internalNv12RtSurfaces[internalNV12RTIndex].dwHeight) { if (!Mos_ResourceIsNull(&m_internalNv12RtSurfaces[internalNV12RTIndex].OsResource)) { m_osInterface->pfnFreeResource(m_osInterface, &m_internalNv12RtSurfaces[internalNV12RTIndex].OsResource); } CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateSurface( &m_internalNv12RtSurfaces[internalNV12RTIndex], m_destSurface.dwWidth, m_destSurface.dwHeight, "HevcInternalNV12RTSurfaces"), "Failed to allocate Hevc Internal NV12 dest surface data buffer."); } } if (!m_hcpInterface->IsHevcDfRowstoreCacheEnabled()) { uint32_t mfdDeblockingFilterRowStoreScratchBufferPicWidthMax = MOS_MAX(m_width, m_mfdDeblockingFilterRowStoreScratchBufferPicWidth); reallocParam.dwPicWidth = mfdDeblockingFilterRowStoreScratchBufferPicWidthMax; reallocParam.dwPicWidthAlloced = m_mfdDeblockingFilterRowStoreScratchBufferPicWidth; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->IsHevcBufferReallocNeeded( MHW_VDBOX_HCP_INTERNAL_BUFFER_DBLK_LINE, &reallocParam)); if (reallocParam.bNeedBiggerSize || Mos_ResourceIsNull(&m_resMfdDeblockingFilterRowStoreScratchBuffer)) { if (!Mos_ResourceIsNull(&m_resMfdDeblockingFilterRowStoreScratchBuffer)) { m_osInterface->pfnFreeResource( m_osInterface, &m_resMfdDeblockingFilterRowStoreScratchBuffer); } // Deblocking Filter Row Store Scratch buffer hcpBufSizeParam.dwPicWidth = mfdDeblockingFilterRowStoreScratchBufferPicWidthMax; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->GetHevcBufferSize( MHW_VDBOX_HCP_INTERNAL_BUFFER_DBLK_LINE, &hcpBufSizeParam)); CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer( &m_resMfdDeblockingFilterRowStoreScratchBuffer, hcpBufSizeParam.dwBufferSize, "DeblockingScratchBuffer"), "Failed to allocate Deblocking Filter Row Store Scratch Buffer."); } //record the width and height used for allocation internal resources. m_mfdDeblockingFilterRowStoreScratchBufferPicWidth = mfdDeblockingFilterRowStoreScratchBufferPicWidthMax; } reallocParam.dwPicWidth = widthMax; reallocParam.dwPicWidthAlloced = m_widthLastMaxAlloced; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->IsHevcBufferReallocNeeded( MHW_VDBOX_HCP_INTERNAL_BUFFER_DBLK_TILE_LINE, &reallocParam)); if (reallocParam.bNeedBiggerSize || Mos_ResourceIsNull(&m_resDeblockingFilterTileRowStoreScratchBuffer)) { if (!Mos_ResourceIsNull(&m_resDeblockingFilterTileRowStoreScratchBuffer)) { m_osInterface->pfnFreeResource( m_osInterface, &m_resDeblockingFilterTileRowStoreScratchBuffer); } // Deblocking Filter Tile Row Store Scratch data surface hcpBufSizeParam.dwPicWidth = widthMax; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->GetHevcBufferSize( MHW_VDBOX_HCP_INTERNAL_BUFFER_DBLK_TILE_LINE, &hcpBufSizeParam)); CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer( &m_resDeblockingFilterTileRowStoreScratchBuffer, hcpBufSizeParam.dwBufferSize, "DeblockingTileScratchBuffer"), "Failed to allocate Deblocking Filter Tile Row Store Scratch Buffer."); } reallocParam.dwPicHeight = heightMax; reallocParam.dwPicHeightAlloced = m_heightLastMaxAlloced; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->IsHevcBufferReallocNeeded( MHW_VDBOX_HCP_INTERNAL_BUFFER_DBLK_TILE_COL, &reallocParam)); if (reallocParam.bNeedBiggerSize || Mos_ResourceIsNull(&m_resDeblockingFilterColumnRowStoreScratchBuffer)) { if (!Mos_ResourceIsNull(&m_resDeblockingFilterColumnRowStoreScratchBuffer)) { m_osInterface->pfnFreeResource( m_osInterface, &m_resDeblockingFilterColumnRowStoreScratchBuffer); } // Deblocking Filter Column Row Store Scratch data surface hcpBufSizeParam.dwPicHeight = heightMax; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->GetHevcBufferSize( MHW_VDBOX_HCP_INTERNAL_BUFFER_DBLK_TILE_COL, &hcpBufSizeParam)); CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer( &m_resDeblockingFilterColumnRowStoreScratchBuffer, hcpBufSizeParam.dwBufferSize, "DeblockingColumnScratchBuffer"), "Failed to allocate Deblocking Filter Column Row Store Scratch Buffer."); } if (!m_hcpInterface->IsHevcDatRowstoreCacheEnabled()) { uint32_t metadataLineBufferPicWidthMax = MOS_MAX(m_width, m_metadataLineBufferPicWidth); reallocParam.dwPicWidth = metadataLineBufferPicWidthMax; reallocParam.dwPicWidthAlloced = m_metadataLineBufferPicWidth; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->IsHevcBufferReallocNeeded( MHW_VDBOX_HCP_INTERNAL_BUFFER_META_LINE, &reallocParam)); if (reallocParam.bNeedBiggerSize || Mos_ResourceIsNull(&m_resMetadataLineBuffer)) { if (!Mos_ResourceIsNull(&m_resMetadataLineBuffer)) { m_osInterface->pfnFreeResource( m_osInterface, &m_resMetadataLineBuffer); } // Metadata Line buffer hcpBufSizeParam.dwPicWidth = metadataLineBufferPicWidthMax; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->GetHevcBufferSize( MHW_VDBOX_HCP_INTERNAL_BUFFER_META_LINE, &hcpBufSizeParam)); CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer( &m_resMetadataLineBuffer, hcpBufSizeParam.dwBufferSize, "MetadataLineBuffer"), "Failed to allocate Metadata Line Buffer."); } //record the width and height used for allocation internal resources. m_metadataLineBufferPicWidth = metadataLineBufferPicWidthMax; } reallocParam.dwPicWidth = widthMax; reallocParam.dwPicWidthAlloced = m_widthLastMaxAlloced; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->IsHevcBufferReallocNeeded( MHW_VDBOX_HCP_INTERNAL_BUFFER_META_TILE_LINE, &reallocParam)); if (reallocParam.bNeedBiggerSize || Mos_ResourceIsNull(&m_resMetadataTileLineBuffer)) { if (!Mos_ResourceIsNull(&m_resMetadataTileLineBuffer)) { m_osInterface->pfnFreeResource( m_osInterface, &m_resMetadataTileLineBuffer); } // Metadata Tile Line buffer hcpBufSizeParam.dwPicWidth = widthMax; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->GetHevcBufferSize( MHW_VDBOX_HCP_INTERNAL_BUFFER_META_TILE_LINE, &hcpBufSizeParam)); CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer( &m_resMetadataTileLineBuffer, hcpBufSizeParam.dwBufferSize, "MetadataTileLineBuffer"), "Failed to allocate Metadata Tile Line Buffer."); } reallocParam.dwPicHeight = heightMax; reallocParam.dwPicHeightAlloced = m_heightLastMaxAlloced; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->IsHevcBufferReallocNeeded( MHW_VDBOX_HCP_INTERNAL_BUFFER_META_TILE_COL, &reallocParam)); if (reallocParam.bNeedBiggerSize || Mos_ResourceIsNull(&m_resMetadataTileColumnBuffer)) { if (!Mos_ResourceIsNull(&m_resMetadataTileColumnBuffer)) { m_osInterface->pfnFreeResource( m_osInterface, &m_resMetadataTileColumnBuffer); } // Metadata Tile Column buffer hcpBufSizeParam.dwPicHeight = heightMax; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->GetHevcBufferSize( MHW_VDBOX_HCP_INTERNAL_BUFFER_META_TILE_COL, &hcpBufSizeParam)); CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer( &m_resMetadataTileColumnBuffer, hcpBufSizeParam.dwBufferSize, "MetadataTileColumnBuffer"), "Failed to allocate Metadata Tile Column Buffer."); } if (!m_hcpInterface->IsHevcSaoRowstoreCacheEnabled()) { uint32_t saoLineBufferPicWidthMax = MOS_MAX(m_width, m_saoLineBufferPicWidth); reallocParam.dwPicWidth = saoLineBufferPicWidthMax; reallocParam.dwPicWidthAlloced = m_saoLineBufferPicWidth; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->IsHevcBufferReallocNeeded( MHW_VDBOX_HCP_INTERNAL_BUFFER_SAO_LINE, &reallocParam)); if (reallocParam.bNeedBiggerSize || Mos_ResourceIsNull(&m_resSaoLineBuffer)) { if (!Mos_ResourceIsNull(&m_resSaoLineBuffer)) { m_osInterface->pfnFreeResource( m_osInterface, &m_resSaoLineBuffer); } // SAO Line buffer hcpBufSizeParam.dwPicWidth = saoLineBufferPicWidthMax; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->GetHevcBufferSize( MHW_VDBOX_HCP_INTERNAL_BUFFER_SAO_LINE, &hcpBufSizeParam)); CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer( &m_resSaoLineBuffer, hcpBufSizeParam.dwBufferSize, "SaoLineBuffer"), "Failed to allocate SAO Line Buffer."); } //record the width and height used for allocation internal resources. m_saoLineBufferPicWidth = saoLineBufferPicWidthMax; } reallocParam.dwPicWidth = widthMax; reallocParam.dwPicWidthAlloced = m_widthLastMaxAlloced; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->IsHevcBufferReallocNeeded( MHW_VDBOX_HCP_INTERNAL_BUFFER_SAO_TILE_LINE, &reallocParam)); if (reallocParam.bNeedBiggerSize || Mos_ResourceIsNull(&m_resSaoTileLineBuffer)) { if (!Mos_ResourceIsNull(&m_resSaoTileLineBuffer)) { m_osInterface->pfnFreeResource( m_osInterface, &m_resSaoTileLineBuffer); } // SAO Tile Line buffer hcpBufSizeParam.dwPicWidth = widthMax; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->GetHevcBufferSize( MHW_VDBOX_HCP_INTERNAL_BUFFER_SAO_TILE_LINE, &hcpBufSizeParam)); CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer( &m_resSaoTileLineBuffer, hcpBufSizeParam.dwBufferSize, "SaoTileLineBuffer"), "Failed to allocate SAO Tile Line Buffer."); } reallocParam.dwPicHeight = heightMax; reallocParam.dwPicHeightAlloced = m_heightLastMaxAlloced; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->IsHevcBufferReallocNeeded( MHW_VDBOX_HCP_INTERNAL_BUFFER_SAO_TILE_COL, &reallocParam)); if (reallocParam.bNeedBiggerSize || Mos_ResourceIsNull(&m_resSaoTileColumnBuffer)) { if (!Mos_ResourceIsNull(&m_resSaoTileColumnBuffer)) { m_osInterface->pfnFreeResource( m_osInterface, &m_resSaoTileColumnBuffer); } // SAO Tile Column buffer hcpBufSizeParam.dwPicHeight = heightMax; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->GetHevcBufferSize( MHW_VDBOX_HCP_INTERNAL_BUFFER_SAO_TILE_COL, &hcpBufSizeParam)); CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer( &m_resSaoTileColumnBuffer, hcpBufSizeParam.dwBufferSize, "SaoTileColumnBuffer"), "Failed to allocate SAO Tile Column Buffer."); } for (uint8_t i = 0; i < CODEC_NUM_HEVC_INITIAL_MV_BUFFERS; i++) { AllocateMvTemporalBuffer(i); } m_mvBufferProgrammed = true; if (m_secureDecoder) { CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->AllocateResource(this)); } m_widthLastMaxAlloced = widthMax; m_heightLastMaxAlloced = heightMax; m_ctbLog2SizeYMax = ctbLog2SizeY; return eStatus; } MOS_STATUS CodechalDecodeHevc::AllocateMvTemporalBuffer( uint8_t hevcMvBuffIndex) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_DECODE_FUNCTION_ENTER; // Non-mismatch order programming mode has the limiation of mv buffer num CODEC_NUM_HEVC_MV_BUFFERS if (hevcMvBuffIndex == CODEC_NUM_HEVC_MV_BUFFERS && !m_osInterface->pfnIsMismatchOrderProgrammingSupported()) { // Should never happen, something must be wrong CODECHAL_DECODE_ASSERTMESSAGE("Failed to get avaiable MV buffer."); return MOS_STATUS_INVALID_PARAMETER; } uint32_t widthMax = MOS_MAX(m_width, m_widthLastMaxAlloced); uint32_t heightMax = MOS_MAX(m_height, m_heightLastMaxAlloced); MHW_VDBOX_HCP_BUFFER_REALLOC_PARAMS reallocParam; MOS_ZeroMemory(&reallocParam, sizeof(reallocParam)); reallocParam.dwPicWidth = widthMax; reallocParam.dwPicWidthAlloced = m_widthLastMaxAlloced; reallocParam.dwPicHeight = heightMax; reallocParam.dwPicHeightAlloced = m_heightLastMaxAlloced; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->IsHevcBufferReallocNeeded( MHW_VDBOX_HCP_INTERNAL_BUFFER_CURR_MV_TEMPORAL, &reallocParam)); int32_t isResMvTemporalBufferNull = Mos_ResourceIsNull(&m_resMvTemporalBuffer[hevcMvBuffIndex]); if (reallocParam.bNeedBiggerSize || isResMvTemporalBufferNull) { MHW_VDBOX_HCP_BUFFER_SIZE_PARAMS hcpBufSizeParam; MOS_ZeroMemory(&hcpBufSizeParam, sizeof(hcpBufSizeParam)); if (!isResMvTemporalBufferNull) { m_osInterface->pfnFreeResource( m_osInterface, &m_resMvTemporalBuffer[hevcMvBuffIndex]); } // MV Temporal buffers hcpBufSizeParam.dwPicWidth = widthMax; hcpBufSizeParam.dwPicHeight = heightMax; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->GetHevcBufferSize( MHW_VDBOX_HCP_INTERNAL_BUFFER_CURR_MV_TEMPORAL, &hcpBufSizeParam)); m_mvBufferSize = hcpBufSizeParam.dwBufferSize; CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer( &m_resMvTemporalBuffer[hevcMvBuffIndex], hcpBufSizeParam.dwBufferSize, "CurrentMvTemporalBuffer"), "Failed to allocate MV Temporal Buffer."); } return eStatus; } CodechalDecodeHevc::~CodechalDecodeHevc () { CODECHAL_DECODE_FUNCTION_ENTER; CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(m_osInterface); CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(m_hwInterface); m_osInterface->pfnDestroySyncResource(m_osInterface, &m_resSyncObjectWaContextInUse); CodecHalFreeDataList(m_hevcRefList, CODECHAL_NUM_UNCOMPRESSED_SURFACE_HEVC); if (!Mos_ResourceIsNull(&m_resMfdDeblockingFilterRowStoreScratchBuffer)) { m_osInterface->pfnFreeResource( m_osInterface, &m_resMfdDeblockingFilterRowStoreScratchBuffer); } m_osInterface->pfnFreeResource( m_osInterface, &m_resDeblockingFilterTileRowStoreScratchBuffer); m_osInterface->pfnFreeResource( m_osInterface, &m_resDeblockingFilterColumnRowStoreScratchBuffer); if (!Mos_ResourceIsNull(&m_resMetadataLineBuffer)) { m_osInterface->pfnFreeResource( m_osInterface, &m_resMetadataLineBuffer); } m_osInterface->pfnFreeResource( m_osInterface, &m_resMetadataTileLineBuffer); m_osInterface->pfnFreeResource( m_osInterface, &m_resMetadataTileColumnBuffer); if (!Mos_ResourceIsNull(&m_resSaoLineBuffer)) { m_osInterface->pfnFreeResource( m_osInterface, &m_resSaoLineBuffer); } m_osInterface->pfnFreeResource( m_osInterface, &m_resSaoTileLineBuffer); m_osInterface->pfnFreeResource( m_osInterface, &m_resSaoTileColumnBuffer); uint32_t mvBufNum = m_osInterface->pfnIsMismatchOrderProgrammingSupported() ? CODECHAL_NUM_UNCOMPRESSED_SURFACE_HEVC : CODEC_NUM_HEVC_MV_BUFFERS; for (uint32_t i = 0; i < mvBufNum; i++) { m_osInterface->pfnFreeResource( m_osInterface, &m_resMvTemporalBuffer[i]); } if (m_shortFormatInUse) { for (uint32_t i = 0; i < CODEC_HEVC_NUM_SECOND_BB; i++) { Mhw_FreeBb(m_osInterface, &m_secondLevelBatchBuffer[i], nullptr); } for (uint32_t i = 0; i < CODECHAL_HEVC_NUM_DMEM_BUFFERS; i++) { m_osInterface->pfnFreeResource(m_osInterface, &m_resDmemBuffer[i]); } } if (!Mos_ResourceIsNull(&m_resCopyDataBuffer)) { m_osInterface->pfnFreeResource( m_osInterface, &m_resCopyDataBuffer); } for (uint32_t i = 0; i < CODECHAL_NUM_INTERNAL_NV12_RT_HEVC; i++) { m_osInterface->pfnFreeResource( m_osInterface, &m_internalNv12RtSurfaces[i].OsResource); } if (m_decodeNV12ToP010 != nullptr) { MOS_Delete(m_decodeNV12ToP010); } #ifdef _DECODE_PROCESSING_SUPPORTED if (m_sfcState) { MOS_Delete(m_sfcState); m_sfcState = nullptr; } #endif if (m_picMhwParams.PipeModeSelectParams) { MOS_Delete(m_picMhwParams.PipeModeSelectParams); m_picMhwParams.PipeModeSelectParams = nullptr; } if (m_picMhwParams.SurfaceParams) { MOS_Delete(m_picMhwParams.SurfaceParams); m_picMhwParams.SurfaceParams = nullptr; } if (m_picMhwParams.PipeBufAddrParams) { MOS_Delete(m_picMhwParams.PipeBufAddrParams); m_picMhwParams.PipeBufAddrParams = nullptr; } if (m_picMhwParams.IndObjBaseAddrParams) { MOS_Delete(m_picMhwParams.IndObjBaseAddrParams); m_picMhwParams.IndObjBaseAddrParams = nullptr; } if (m_picMhwParams.QmParams) { MOS_Delete(m_picMhwParams.QmParams); m_picMhwParams.QmParams = nullptr; } if (m_picMhwParams.HevcPicState) { MOS_Delete(m_picMhwParams.HevcPicState); m_picMhwParams.HevcPicState = nullptr; } if (m_picMhwParams.HevcTileState) { MOS_Delete(m_picMhwParams.HevcTileState); m_picMhwParams.HevcTileState = nullptr; } return; } uint32_t CodechalDecodeHevc::GetDmemBufferSize() { return MOS_ALIGN_CEIL(sizeof(HUC_HEVC_S2L_BSS), CODECHAL_CACHELINE_SIZE); } MOS_STATUS CodechalDecodeHevc::SetHucDmemS2LPictureBss( PHUC_HEVC_S2L_PIC_BSS hucHevcS2LPicBss) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_DECODE_FUNCTION_ENTER; CODECHAL_DECODE_CHK_NULL_RETURN(hucHevcS2LPicBss); hucHevcS2LPicBss->pic_width_in_min_cbs_y = m_hevcPicParams->PicWidthInMinCbsY; hucHevcS2LPicBss->pic_height_in_min_cbs_y = m_hevcPicParams->PicHeightInMinCbsY; hucHevcS2LPicBss->log2_min_luma_coding_block_size_minus3 = m_hevcPicParams->log2_min_luma_coding_block_size_minus3; hucHevcS2LPicBss->log2_diff_max_min_luma_coding_block_size = m_hevcPicParams->log2_diff_max_min_luma_coding_block_size; hucHevcS2LPicBss->chroma_format_idc = m_hevcPicParams->chroma_format_idc; hucHevcS2LPicBss->separate_colour_plane_flag = m_hevcPicParams->separate_colour_plane_flag; hucHevcS2LPicBss->bit_depth_luma_minus8 = m_hevcPicParams->bit_depth_luma_minus8; hucHevcS2LPicBss->bit_depth_chroma_minus8 = m_hevcPicParams->bit_depth_chroma_minus8; hucHevcS2LPicBss->log2_max_pic_order_cnt_lsb_minus4 = m_hevcPicParams->log2_max_pic_order_cnt_lsb_minus4; hucHevcS2LPicBss->sample_adaptive_offset_enabled_flag = m_hevcPicParams->sample_adaptive_offset_enabled_flag; hucHevcS2LPicBss->num_short_term_ref_pic_sets = m_hevcPicParams->num_short_term_ref_pic_sets; hucHevcS2LPicBss->long_term_ref_pics_present_flag = m_hevcPicParams->long_term_ref_pics_present_flag; hucHevcS2LPicBss->num_long_term_ref_pics_sps = m_hevcPicParams->num_long_term_ref_pic_sps; hucHevcS2LPicBss->sps_temporal_mvp_enable_flag = m_hevcPicParams->sps_temporal_mvp_enabled_flag; hucHevcS2LPicBss->num_ref_idx_l0_default_active_minus1 = m_hevcPicParams->num_ref_idx_l0_default_active_minus1; hucHevcS2LPicBss->num_ref_idx_l1_default_active_minus1 = m_hevcPicParams->num_ref_idx_l1_default_active_minus1; hucHevcS2LPicBss->pic_init_qp_minus26 = m_hevcPicParams->init_qp_minus26; hucHevcS2LPicBss->dependent_slice_segments_enabled_flag = m_hevcPicParams->dependent_slice_segments_enabled_flag; hucHevcS2LPicBss->cabac_init_present_flag = m_hevcPicParams->cabac_init_present_flag; hucHevcS2LPicBss->pps_slice_chroma_qp_offsets_present_flag = m_hevcPicParams->pps_slice_chroma_qp_offsets_present_flag; hucHevcS2LPicBss->weighted_pred_flag = m_hevcPicParams->weighted_pred_flag; hucHevcS2LPicBss->weighted_bipred_flag = m_hevcPicParams->weighted_bipred_flag; hucHevcS2LPicBss->output_flag_present_flag = m_hevcPicParams->output_flag_present_flag; hucHevcS2LPicBss->tiles_enabled_flag = m_hevcPicParams->tiles_enabled_flag; hucHevcS2LPicBss->entropy_coding_sync_enabled_flag = m_hevcPicParams->entropy_coding_sync_enabled_flag; hucHevcS2LPicBss->loop_filter_across_slices_enabled_flag = m_hevcPicParams->pps_loop_filter_across_slices_enabled_flag; hucHevcS2LPicBss->deblocking_filter_override_enabled_flag = m_hevcPicParams->deblocking_filter_override_enabled_flag; hucHevcS2LPicBss->pic_disable_deblocking_filter_flag = m_hevcPicParams->pps_deblocking_filter_disabled_flag; hucHevcS2LPicBss->lists_modification_present_flag = m_hevcPicParams->lists_modification_present_flag; hucHevcS2LPicBss->slice_segment_header_extension_present_flag = m_hevcPicParams->slice_segment_header_extension_present_flag; hucHevcS2LPicBss->high_precision_offsets_enabled_flag = 0; hucHevcS2LPicBss->chroma_qp_offset_list_enabled_flag = 0; uint32_t i; hucHevcS2LPicBss->CurrPicOrderCntVal = m_hevcPicParams->CurrPicOrderCntVal; for (i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++) { hucHevcS2LPicBss->PicOrderCntValList[i] = m_hevcPicParams->PicOrderCntValList[i]; } for (i = 0; i < 8; i++) { hucHevcS2LPicBss->RefPicSetStCurrBefore[i] = m_hevcPicParams->RefPicSetStCurrBefore[i]; hucHevcS2LPicBss->RefPicSetStCurrAfter[i] = m_hevcPicParams->RefPicSetStCurrAfter[i]; hucHevcS2LPicBss->RefPicSetLtCurr[i] = m_hevcPicParams->RefPicSetLtCurr[i]; } hucHevcS2LPicBss->RefFieldPicFlag = m_hevcPicParams->RefFieldPicFlag; hucHevcS2LPicBss->RefBottomFieldFlag = (uint8_t)m_hevcPicParams->RefBottomFieldFlag; hucHevcS2LPicBss->pps_beta_offset_div2 = m_hevcPicParams->pps_beta_offset_div2; hucHevcS2LPicBss->pps_tc_offset_div2 = m_hevcPicParams->pps_tc_offset_div2; hucHevcS2LPicBss->StRPSBits = m_hevcPicParams->wNumBitsForShortTermRPSInSlice; if (m_hevcPicParams->tiles_enabled_flag) { hucHevcS2LPicBss->num_tile_columns_minus1 = m_hevcPicParams->num_tile_columns_minus1; hucHevcS2LPicBss->num_tile_rows_minus1 = m_hevcPicParams->num_tile_rows_minus1; for (i = 0; i < HEVC_NUM_MAX_TILE_COLUMN; i++) { hucHevcS2LPicBss->column_width[i] = m_tileColWidth[i]; } for (i = 0; i < HEVC_NUM_MAX_TILE_ROW; i++) { hucHevcS2LPicBss->row_height[i] = m_tileRowHeight[i]; } } hucHevcS2LPicBss->NumSlices = (uint16_t)m_numSlices; hucHevcS2LPicBss->num_extra_slice_header_bits = m_hevcPicParams->num_extra_slice_header_bits; for (i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++) { hucHevcS2LPicBss->RefIdxMapping[i] = m_refIdxMapping[i]; } return eStatus; } MOS_STATUS CodechalDecodeHevc::SetHucDmemS2LSliceBss( PHUC_HEVC_S2L_SLICE_BSS hucHevcS2LSliceBss) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_DECODE_FUNCTION_ENTER; CODECHAL_DECODE_CHK_NULL_RETURN(hucHevcS2LSliceBss); for (uint32_t i = 0; i < m_numSlices; i++) { hucHevcS2LSliceBss->BSNALunitDataLocation = m_hevcSliceParams[i].slice_data_offset; hucHevcS2LSliceBss->SliceBytesInBuffer = m_hevcSliceParams[i].slice_data_size; hucHevcS2LSliceBss++; } return eStatus; } MOS_STATUS CodechalDecodeHevc::SetHucDmemParams( PMOS_RESOURCE dmemBuffer) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_DECODE_FUNCTION_ENTER; CODECHAL_DECODE_CHK_NULL_RETURN(dmemBuffer); CodechalResLock DmemLock(m_osInterface, dmemBuffer); auto hucHevcS2LBss = (PHUC_HEVC_S2L_BSS)DmemLock.Lock(CodechalResLock::writeOnly); CODECHAL_DECODE_CHK_NULL_RETURN(hucHevcS2LBss); hucHevcS2LBss->ProductFamily = m_hucInterface->GetHucProductFamily(); hucHevcS2LBss->RevId = m_hwInterface->GetPlatform().usRevId; hucHevcS2LBss->DummyRefIdxState = MEDIA_IS_WA(m_waTable, WaDummyReference) && !m_osInterface->bSimIsActive; CODECHAL_DECODE_CHK_STATUS_RETURN(SetHucDmemS2LPictureBss(&hucHevcS2LBss->PictureBss)); CODECHAL_DECODE_CHK_STATUS_RETURN(SetHucDmemS2LSliceBss(&hucHevcS2LBss->SliceBss[0])); if (m_secureDecoder) { CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->SetHevcHucDmemS2LBss(this, &hucHevcS2LBss->PictureBss, &hucHevcS2LBss->SliceBss[0])); } if (m_numSlices < CODECHAL_HEVC_MAX_NUM_SLICES_LVL_6) { m_dmemTransferSize = (uint32_t)((uint8_t *)&(hucHevcS2LBss->SliceBss[m_numSlices]) - (uint8_t *)hucHevcS2LBss); m_dmemTransferSize = MOS_ALIGN_CEIL(m_dmemTransferSize, CODECHAL_CACHELINE_SIZE); } else { m_dmemTransferSize = m_dmemBufferSize; } return eStatus; } MOS_STATUS CodechalDecodeHevc::GetAllTileInfo() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_DECODE_FUNCTION_ENTER; if ((m_hevcPicParams->num_tile_columns_minus1 >= HEVC_NUM_MAX_TILE_COLUMN) || (m_hevcPicParams->num_tile_rows_minus1 >= HEVC_NUM_MAX_TILE_ROW)) { CODECHAL_DECODE_ASSERTMESSAGE("num_tile_columns_minus1 or num_tile_rows_minus1 is out of range!"); return MOS_STATUS_INVALID_PARAMETER; } uint32_t ctbSize = 1 << (m_hevcPicParams->log2_diff_max_min_luma_coding_block_size + m_hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3); uint32_t widthInPix = (1 << (m_hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3)) * (m_hevcPicParams->PicWidthInMinCbsY); uint32_t heightInPix = (1 << (m_hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3)) * (m_hevcPicParams->PicHeightInMinCbsY); uint32_t widthInCtb = MOS_ROUNDUP_DIVIDE(widthInPix, ctbSize); uint32_t heightInCtb = MOS_ROUNDUP_DIVIDE(heightInPix, ctbSize); uint16_t *tileColWidth, *tileRowHeight; tileColWidth = &m_tileColWidth[0]; tileRowHeight = &m_tileRowHeight[0]; if (m_hevcPicParams->uniform_spacing_flag == 1) { uint8_t i; for (i = 0; i <= m_hevcPicParams->num_tile_columns_minus1; i++) { tileColWidth[i] = ((i + 1) * widthInCtb) / (m_hevcPicParams->num_tile_columns_minus1 + 1) - (i * widthInCtb) / (m_hevcPicParams->num_tile_columns_minus1 + 1); } for (i = 0; i <= m_hevcPicParams->num_tile_rows_minus1; i++) { tileRowHeight[i] = ((i + 1) * heightInCtb) / (m_hevcPicParams->num_tile_rows_minus1 + 1) - (i * heightInCtb) / (m_hevcPicParams->num_tile_rows_minus1 + 1); } } else { uint8_t i; tileColWidth[m_hevcPicParams->num_tile_columns_minus1] = widthInCtb & 0xffff; for (i = 0; i < m_hevcPicParams->num_tile_columns_minus1; i++) { tileColWidth[i] = m_hevcPicParams->column_width_minus1[i] + 1; tileColWidth[m_hevcPicParams->num_tile_columns_minus1] -= tileColWidth[i]; } tileRowHeight[m_hevcPicParams->num_tile_rows_minus1] = heightInCtb & 0xffff; for (i = 0; i < m_hevcPicParams->num_tile_rows_minus1; i++) { tileRowHeight[i] = m_hevcPicParams->row_height_minus1[i] + 1; tileRowHeight[m_hevcPicParams->num_tile_rows_minus1] -= tileRowHeight[i]; } } return eStatus; } MOS_STATUS CodechalDecodeHevc::InitializeBitstreamCat () { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_DECODE_FUNCTION_ENTER; if (m_cencBuf) { return eStatus; } m_incompletePicture = false; m_copyDataBufferInUse = false; m_copyDataOffset = 0; // For multiple execution case, each execution for one frame will increase pDecoderInterface->dwFrameNum in CodecHalDecode_Decode. // This will lead to dump index error. // Need to make sure that pDecoderInterface->CurrPic won't update until all bitstream is copied. m_crrPic.PicFlags = PICTURE_INVALID; if (m_numSlices == 0) { CODECHAL_DECODE_ASSERTMESSAGE("Invalid Slice Number = 0"); return MOS_STATUS_INVALID_PARAMETER; } // Estimate Bytes in Bitstream per frame PCODEC_HEVC_SLICE_PARAMS hevcLastSliceParamsInFrame = m_hevcSliceParams + (m_numSlices - 1); m_estiBytesInBitstream = MOS_ALIGN_CEIL(hevcLastSliceParamsInFrame->slice_data_offset + hevcLastSliceParamsInFrame->slice_data_size, 64); CODECHAL_DECODE_NORMALMESSAGE("Estimate bitstream size in this Frame: %u", m_estiBytesInBitstream); return eStatus; } MOS_STATUS CodechalDecodeHevc::CopyDataSurface() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_DECODE_FUNCTION_ENTER; CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext( m_osInterface, m_videoContextForWa)); m_osInterface->pfnResetOsStates(m_osInterface); m_osInterface->pfnSetPerfTag( m_osInterface, (uint16_t)(((m_mode << 4) & 0xF0) | COPY_TYPE)); m_osInterface->pfnResetPerfBufferID(m_osInterface); MOS_COMMAND_BUFFER cmdBuffer; CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer( m_osInterface, &cmdBuffer, 0)); CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking( &cmdBuffer, false)); CODECHAL_DECODE_CHK_STATUS_RETURN(HucCopy( &cmdBuffer, // pCmdBuffer &m_resDataBuffer, // presSrc &m_resCopyDataBuffer, // presDst m_dataSize, // u32CopyLength m_dataOffset, // u32CopyInputOffset m_copyDataOffset)); // u32CopyOutputOffset m_copyDataOffset += MOS_ALIGN_CEIL(m_dataSize, MHW_CACHELINE_SIZE); MHW_MI_FLUSH_DW_PARAMS flushDwParams; MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams)); CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd( &cmdBuffer, &flushDwParams)); CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd( &cmdBuffer, nullptr)); m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); // sync resource if (!m_incompletePicture) { MOS_SYNC_PARAMS syncParams = g_cInitSyncParams; syncParams.GpuContext = m_videoContext; syncParams.presSyncResource = &m_resSyncObjectWaContextInUse; CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams)); syncParams = g_cInitSyncParams; syncParams.GpuContext = m_videoContextForWa; syncParams.presSyncResource = &m_resSyncObjectWaContextInUse; CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams)); } CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer( m_osInterface, &cmdBuffer, m_videoContextForWaUsesNullHw)); CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext( m_osInterface, m_videoContext)); return eStatus; } MOS_STATUS CodechalDecodeHevc::CheckAndCopyBitstream() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_DECODE_FUNCTION_ENTER; if (m_cencBuf) { return eStatus; } if (IsFirstExecuteCall()) // first exec to decide allocate a larger buf or not { if (m_estiBytesInBitstream > MOS_ALIGN_CEIL(m_dataOffset + m_dataSize, 64)) // bitstream contains more bytes than current data. { CODECHAL_DECODE_NORMALMESSAGE("Multiple Execution Call for HEVC triggered!"); if (m_copyDataBufferSize < m_estiBytesInBitstream) // allocate an appropriate buffer { if (!Mos_ResourceIsNull(&m_resCopyDataBuffer)) { m_osInterface->pfnFreeResource( m_osInterface, &m_resCopyDataBuffer); } CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer( &m_resCopyDataBuffer, m_estiBytesInBitstream, "HevcCopyDataBuffer"), "Failed to allocate Hevc copy data buffer."); m_copyDataBufferSize = m_estiBytesInBitstream; CODECHAL_DECODE_NORMALMESSAGE("Create buffersize %d for MEC.", m_copyDataBufferSize); } if (m_dataSize) { CODECHAL_DECODE_CHK_STATUS_RETURN(CopyDataSurface()); m_copyDataBufferInUse = true; } m_incompletePicture = true; } } else { if (m_copyDataOffset + m_dataSize > m_copyDataBufferSize) { CODECHAL_DECODE_ASSERTMESSAGE("Bitstream size exceeds copy data buffer size!"); return MOS_STATUS_UNKNOWN; } if (m_dataSize) { CODECHAL_DECODE_CHK_STATUS_RETURN(CopyDataSurface()); m_frameIdx--; // to keep u32FrameIdx as normal logic meaning. } if (m_copyDataOffset >= m_estiBytesInBitstream) { m_incompletePicture = false; } } return eStatus; } MOS_STATUS CodechalDecodeHevc::SetFrameStates () { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_HAL); CODECHAL_DECODE_FUNCTION_ENTER; CODECHAL_DECODE_CHK_NULL_RETURN(m_decodeParams.m_destSurface); CODECHAL_DECODE_CHK_NULL_RETURN(m_decodeParams.m_dataBuffer); m_frameIdx++; // Check HuC_status2 Imem loaded bit, if 0,return error // As driver doesn't know when can get reg value afer storing HuC_Status2 register, // Check the reg value here at the beginning of next frame // Check twice, first entry and second entry if (m_shortFormatInUse && m_frameIdx < 3 && m_statusQueryReportingEnabled && (((m_decodeStatusBuf.m_decodeStatus->m_hucErrorStatus2 >> 32) & m_hucInterface->GetHucStatus2ImemLoadedMask()) == 0)) { CODECHAL_DECODE_ASSERTMESSAGE("HuC IMEM Loaded fails"); MT_ERR1(MT_DEC_HEVC, MT_DEC_HUC_ERROR_STATUS2, (m_decodeStatusBuf.m_decodeStatus->m_hucErrorStatus2 >> 32)); return MOS_STATUS_UNKNOWN; } m_cencBuf = m_decodeParams.m_cencBuf; if (IsFirstExecuteCall()) // For DRC Multiple Execution Call, no need to update every value in pHevcState except first execute { m_dataSize = m_decodeParams.m_dataSize; m_dataOffset = m_decodeParams.m_dataOffset; m_numSlices = m_decodeParams.m_numSlices; if (m_numSlices > CODECHAL_HEVC_MAX_NUM_SLICES_LVL_6) { CODECHAL_DECODE_ASSERTMESSAGE("Slice number doesn't support!"); return MOS_STATUS_INVALID_PARAMETER; } m_hevcPicParams = (PCODEC_HEVC_PIC_PARAMS)m_decodeParams.m_picParams; CODECHAL_DECODE_CHK_NULL_RETURN(m_decodeParams.m_sliceParams); m_hevcSliceParams = (PCODEC_HEVC_SLICE_PARAMS)m_decodeParams.m_sliceParams; m_hevcIqMatrixParams = (PCODECHAL_HEVC_IQ_MATRIX_PARAMS)m_decodeParams.m_iqMatrixBuffer; m_destSurface = *(m_decodeParams.m_destSurface); m_resDataBuffer = *(m_decodeParams.m_dataBuffer); CODECHAL_DECODE_CHK_STATUS_RETURN(InitializeBitstreamCat()); } else { m_dataSize = m_decodeParams.m_dataSize; m_dataOffset = 0; m_resDataBuffer = *(m_decodeParams.m_dataBuffer); } CODECHAL_DECODE_CHK_STATUS_RETURN(CheckAndCopyBitstream()); //For CENC case, the Entry has been initialized with value in SetParamsForDecode PCODEC_REF_LIST destEntry = m_hevcRefList[m_hevcPicParams->CurrPic.FrameIdx]; MOS_ZeroMemory(destEntry, sizeof(CODEC_REF_LIST)); if (m_incompletePicture) { return MOS_STATUS_SUCCESS; } CODECHAL_DECODE_CHK_NULL_RETURN(m_hevcPicParams); CODECHAL_DECODE_CHK_NULL_RETURN(m_hevcIqMatrixParams); // Calculate bIs8bitFrameIn10bitHevc if (MEDIA_IS_WA(m_waTable, Wa8BitFrameIn10BitHevc) && m_is10BitHevc && m_hevcPicParams->bit_depth_luma_minus8 == 0 && m_hevcPicParams->bit_depth_chroma_minus8 == 0 && m_decodeParams.m_destSurface->Format == Format_P010) { m_is8BitFrameIn10BitHevc = true; } else { m_is8BitFrameIn10BitHevc = false; } // InitNV12ToP010Context if (m_is8BitFrameIn10BitHevc && m_decodeNV12ToP010 == nullptr) { m_decodeNV12ToP010 = Nv12ToP010Device::CreateFactory(m_osInterface); CODECHAL_DECODE_CHK_NULL_RETURN(m_decodeNV12ToP010); } // Calculate bCurPicIntra m_curPicIntra = true; if (m_hevcPicParams->IntraPicFlag == 0) { for (uint32_t i = 0; i < CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC; i++) { uint8_t frameIdx = m_hevcPicParams->RefPicSetStCurrBefore[i]; if (frameIdx < 15) { m_curPicIntra = false; break; } frameIdx = m_hevcPicParams->RefPicSetStCurrAfter[i]; if (frameIdx < 15) { m_curPicIntra = false; break; } frameIdx = m_hevcPicParams->RefPicSetLtCurr[i]; if (frameIdx < 15) { m_curPicIntra = false; break; } } } CODECHAL_DECODE_CHK_STATUS_RETURN(SetPictureStructs()); uint32_t i; for (i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++) { m_frameUsedAsCurRef[i] = false; m_refIdxMapping[i] = -1; } // Calculate RefIdxMapping for (i = 0; i < CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC; i++) { uint8_t frameIdx = m_hevcPicParams->RefPicSetStCurrBefore[i]; if (frameIdx < CODEC_MAX_NUM_REF_FRAME_HEVC) { m_frameUsedAsCurRef[frameIdx] = true; } frameIdx = m_hevcPicParams->RefPicSetStCurrAfter[i]; if (frameIdx < CODEC_MAX_NUM_REF_FRAME_HEVC) { m_frameUsedAsCurRef[frameIdx] = true; } frameIdx = m_hevcPicParams->RefPicSetLtCurr[i]; if (frameIdx < CODEC_MAX_NUM_REF_FRAME_HEVC) { m_frameUsedAsCurRef[frameIdx] = true; } } uint8_t curRefIdx = 0; for (i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++) { if (m_frameUsedAsCurRef[i]) { m_refIdxMapping[i] = curRefIdx++; } } CODECHAL_DECODE_CHK_COND_RETURN(curRefIdx > 8,"bitstream has more than 8 references"); m_minCtbSize = 1 << (m_hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3); m_width = m_hevcPicParams->PicWidthInMinCbsY * m_minCtbSize; m_height = m_hevcPicParams->PicHeightInMinCbsY * m_minCtbSize; if (m_hcpInterface->IsRowStoreCachingSupported()) { MHW_VDBOX_ROWSTORE_PARAMS rowstoreParams; rowstoreParams.Mode = CODECHAL_DECODE_MODE_HEVCVLD; rowstoreParams.dwPicWidth = 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 = 1 << (m_hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3 + m_hevcPicParams->log2_diff_max_min_luma_coding_block_size); m_hwInterface->SetRowstoreCachingOffsets(&rowstoreParams); } CODECHAL_DECODE_CHK_STATUS_RETURN(AllocateResourcesVariableSizes()); // Calculate Tile info if (m_hevcPicParams->tiles_enabled_flag) { CODECHAL_DECODE_CHK_STATUS_RETURN(GetAllTileInfo()); } m_hcpDecPhase = CodechalHcpDecodePhaseInitialized; if (m_curPicIntra) { m_perfType = I_TYPE; } else { // Not possible to determine whether P or B is used for short format. // For long format iterating through all of the slices to determine P vs // B, so in order to avoid this, declare all other pictures MIXED_TYPE. m_perfType = MIXED_TYPE; } m_crrPic = m_hevcPicParams->CurrPic; m_secondField = CodecHal_PictureIsBottomField(m_hevcPicParams->CurrPic); if (m_pCodechalOcaDumper) { m_pCodechalOcaDumper->SetHevcDecodeParam( m_hevcPicParams, nullptr, nullptr, m_hevcSliceParams, nullptr, m_numSlices, m_shortFormatInUse); } CODECHAL_DEBUG_TOOL( m_debugInterface->m_currPic = m_crrPic; m_debugInterface->m_secondField = m_secondField; m_debugInterface->m_frameType = m_perfType; CODECHAL_DECODE_CHK_STATUS_RETURN(DumpPicParams( m_hevcPicParams, nullptr)); if (m_hevcIqMatrixParams) { CODECHAL_DECODE_CHK_STATUS_RETURN(DumpIQParams(m_hevcIqMatrixParams)); } if (m_hevcSliceParams) { CODECHAL_DECODE_CHK_STATUS_RETURN(DumpSliceParams( m_hevcSliceParams, nullptr, m_numSlices, m_shortFormatInUse)); }) // Clear DMEM buffer program flag and increase the Dmem buffer index to program if (m_shortFormatInUse) { m_dmemBufferProgrammed = false; m_dmemBufferIdx++; m_dmemBufferIdx %= CODECHAL_HEVC_NUM_DMEM_BUFFERS; } #ifdef _DECODE_PROCESSING_SUPPORTED // Check if SFC can be supported CODECHAL_DECODE_CHK_STATUS_RETURN(m_sfcState->CheckAndInitialize((DecodeProcessingParams *)m_decodeParams.m_procParams, m_hevcPicParams)); #endif CODECHAL_DEBUG_TOOL( if (!m_incompletePicture && !IsFirstExecuteCall()) { CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( &m_resCopyDataBuffer, CodechalDbgAttr::attrDecodeBitstream, "_DEC", m_estiBytesInBitstream, 0, CODECHAL_NUM_MEDIA_STATES)); }) return eStatus; } MOS_STATUS CodechalDecodeHevc::SetPictureStructs() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_DECODE_FUNCTION_ENTER; PCODEC_HEVC_PIC_PARAMS picParams = m_hevcPicParams; PCODEC_REF_LIST * hevcRefList = &m_hevcRefList[0]; PCODECHAL_DECODE_HEVC_MV_LIST hevcMVBufferList = &m_hevcMvList[0]; CODEC_PICTURE prevPic = m_currPic; m_currPic = picParams->CurrPic; m_statusReportFeedbackNumber = picParams->StatusReportFeedbackNumber; if (m_currPic.FrameIdx >= CODECHAL_NUM_UNCOMPRESSED_SURFACE_HEVC) { CODECHAL_DECODE_ASSERTMESSAGE("currPic.FrameIdx is out of range!"); return MOS_STATUS_INVALID_PARAMETER; } hevcRefList[m_currPic.FrameIdx]->RefPic = m_currPic; hevcRefList[m_currPic.FrameIdx]->sFrameNumber = (int16_t)picParams->CurrPicOrderCntVal; hevcRefList[m_currPic.FrameIdx]->iFieldOrderCnt[0] = picParams->CurrPicOrderCntVal; hevcRefList[m_currPic.FrameIdx]->bIsIntra = m_curPicIntra; hevcRefList[m_currPic.FrameIdx]->resRefPic = m_destSurface.OsResource; uint8_t i; for(i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++) { hevcRefList[m_currPic.FrameIdx]->RefList[i] = picParams->RefFrameList[i]; } if(m_osInterface->pfnIsMismatchOrderProgrammingSupported()) { for (i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++) { auto frameIdx = picParams->RefFrameList[i].FrameIdx; if (frameIdx != CODECHAL_NUM_UNCOMPRESSED_SURFACE_HEVC) { hevcRefList[frameIdx]->resRefPic = m_decodeParams.m_refFrameSurface[frameIdx].OsResource; hevcRefList[frameIdx]->sFrameNumber = (int16_t)picParams->PicOrderCntValList[i]; hevcRefList[frameIdx]->iFieldOrderCnt[0] = picParams->PicOrderCntValList[i]; hevcRefList[frameIdx]->RefPic = picParams->RefFrameList[i]; } } } if (m_osInterface->pfnIsMismatchOrderProgrammingSupported()) { for (i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++) { auto frameIdx = picParams->RefFrameList[i].FrameIdx; if (frameIdx != CODECHAL_NUM_UNCOMPRESSED_SURFACE_HEVC) { AllocateMvTemporalBuffer(frameIdx); } } AllocateMvTemporalBuffer(m_currPic.FrameIdx); m_hevcMvBufferIndex = m_currPic.FrameIdx; } else { if (!CodecHal_PictureIsInvalid(prevPic)) { for (i = 0; i < CODEC_NUM_HEVC_MV_BUFFERS; i++) { hevcMVBufferList[i].bInUse = false; hevcMVBufferList[i].u8FrameId = 0; } //Mark Referenced frame's MV buffer as used for (i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++) { uint8_t index = picParams->RefFrameList[i].FrameIdx; if (!CodecHal_PictureIsInvalid(picParams->RefFrameList[i]) && index != picParams->CurrPic.FrameIdx) { if (index < CODECHAL_NUM_UNCOMPRESSED_SURFACE_HEVC) { hevcMVBufferList[hevcRefList[index]->ucDMVIdx[0]].bInUse = true; hevcMVBufferList[hevcRefList[index]->ucDMVIdx[0]].u8FrameId = index; } } } } //Find out an unused MvBuffer for current frame m_hevcMvBufferIndex = GetMvBufferIndex( m_currPic.FrameIdx); if (m_mvBufferProgrammed) { AllocateMvTemporalBuffer(m_hevcMvBufferIndex); } hevcRefList[m_currPic.FrameIdx]->ucDMVIdx[0] = m_hevcMvBufferIndex; } return eStatus; } MOS_STATUS CodechalDecodeHevc::DetermineDecodePhase() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_DECODE_FUNCTION_ENTER; uint32_t curPhase = m_hcpDecPhase; switch (curPhase) { case CodechalHcpDecodePhaseInitialized: if (m_shortFormatInUse) { m_hcpDecPhase = CodechalHcpDecodePhaseLegacyS2L; } else { m_hcpDecPhase = CodechalHcpDecodePhaseLegacyLong; } break; case CodechalHcpDecodePhaseLegacyS2L: if (!m_shortFormatInUse) { CODECHAL_DECODE_ASSERTMESSAGE("invalid decode phase."); return MOS_STATUS_INVALID_PARAMETER; } m_hcpDecPhase = CodechalHcpDecodePhaseLegacyLong; break; default: CODECHAL_DECODE_ASSERTMESSAGE("invalid decode phase."); return MOS_STATUS_INVALID_PARAMETER; } return eStatus; } MOS_STATUS CodechalDecodeHevc::DecodeStateLevel() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_HAL); CODECHAL_DECODE_FUNCTION_ENTER; //HEVC Decode Phase State Machine CODECHAL_DECODE_CHK_STATUS_RETURN(DetermineDecodePhase()); // Set HEVC Decode Phase, and execute it. if (m_shortFormatInUse && m_hcpDecPhase == CodechalHcpDecodePhaseLegacyS2L) { if (m_secureDecoder) { CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->Execute(this)); } CODECHAL_DECODE_CHK_STATUS_RETURN(SendPictureS2L()); } else { CODECHAL_DECODE_CHK_STATUS_RETURN(SendPictureLongFormat()); } return eStatus; } MOS_STATUS CodechalDecodeHevc::AddPictureS2LCmds( PMOS_COMMAND_BUFFER cmdBufferInUse) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_DECODE_FUNCTION_ENTER; CODECHAL_DECODE_CHK_NULL_RETURN(cmdBufferInUse); if (m_statusQueryReportingEnabled) { CODECHAL_DECODE_CHK_STATUS_RETURN(StartStatusReport(cmdBufferInUse)); } // Load HuC FW Kernel from WOPCM. MHW_VDBOX_HUC_IMEM_STATE_PARAMS hucImemStateParams; MOS_ZeroMemory(&hucImemStateParams, sizeof(hucImemStateParams)); hucImemStateParams.dwKernelDescriptor = m_hucS2lKernelId; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hucInterface->AddHucImemStateCmd( cmdBufferInUse, &hucImemStateParams)); // Pipe mode select MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams; pipeModeSelectParams.Mode = m_mode; pipeModeSelectParams.bStreamOutEnabled = m_streamOutEnabled; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hucInterface->AddHucPipeModeSelectCmd( cmdBufferInUse, &pipeModeSelectParams)); // Indirect object base addr MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams; MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams)); indObjBaseAddrParams.Mode = m_mode; indObjBaseAddrParams.dwDataSize = m_copyDataBufferInUse ? m_copyDataBufferSize : m_dataSize; indObjBaseAddrParams.dwDataOffset = m_copyDataBufferInUse ? 0 : m_dataOffset; indObjBaseAddrParams.presDataBuffer = m_copyDataBufferInUse ? &m_resCopyDataBuffer : &m_resDataBuffer; if (m_secureDecoder) { CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->SetBitstreamBuffer(&indObjBaseAddrParams)); } CODECHAL_DECODE_CHK_STATUS_RETURN(m_hucInterface->AddHucIndObjBaseAddrStateCmd( cmdBufferInUse, &indObjBaseAddrParams)); // Virtual addr state MHW_VDBOX_HUC_VIRTUAL_ADDR_PARAMS hucVirtualStateParams; MOS_ZeroMemory(&hucVirtualStateParams, sizeof(hucVirtualStateParams)); hucVirtualStateParams.regionParams[0].presRegion = &m_secondLevelBatchBuffer[m_secondLevelBatchBufferIndex].OsResource; hucVirtualStateParams.regionParams[0].isWritable = true; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hucInterface->AddHucVirtualAddrStateCmd( cmdBufferInUse, &hucVirtualStateParams)); // DMEM state. Pass data from driver to HuC FW. MHW_VDBOX_HUC_DMEM_STATE_PARAMS hucDmemStateParams; MOS_ZeroMemory(&hucDmemStateParams, sizeof(hucDmemStateParams)); hucDmemStateParams.presHucDataSource = &m_resDmemBuffer[m_dmemBufferIdx]; hucDmemStateParams.dwDmemOffset = HUC_DMEM_OFFSET_RTOS_GEMS; // If RTOS is GEMS, offset is 0x2000. if (!m_dmemBufferProgrammed) { CODECHAL_DECODE_CHK_STATUS_RETURN(SetHucDmemParams(&m_resDmemBuffer[m_dmemBufferIdx])); m_dmemBufferProgrammed = true; } hucDmemStateParams.dwDataLength = m_dmemTransferSize; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hucInterface->AddHucDmemStateCmd( cmdBufferInUse, &hucDmemStateParams)); CODECHAL_DEBUG_TOOL( CODECHAL_DECODE_CHK_STATUS_RETURN(DumpHucS2l(&hucDmemStateParams));) return eStatus; } MOS_STATUS CodechalDecodeHevc::SendPictureS2L() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_DECODE_FUNCTION_ENTER; if (m_enableSf2DmaSubmits) { m_osInterface->pfnSetPerfTag( m_osInterface, (uint16_t)(((CODECHAL_DECODE_MODE_HUC << 4) & 0xF0) | (m_perfType & 0xF))); } MOS_COMMAND_BUFFER cmdBuffer; CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking( &cmdBuffer, true)); PMOS_COMMAND_BUFFER cmdBufferInUse = &cmdBuffer; CODECHAL_DECODE_CHK_STATUS_RETURN(AddPictureS2LCmds(cmdBufferInUse)); m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); return eStatus; } MOS_STATUS CodechalDecodeHevc::InitPicLongFormatMhwParams() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_DECODE_FUNCTION_ENTER; // Reset all pic Mhw Params *m_picMhwParams.PipeModeSelectParams = {}; *m_picMhwParams.PipeBufAddrParams = {}; *m_picMhwParams.HevcPicState = {}; MOS_ZeroMemory(m_picMhwParams.SurfaceParams, sizeof(MHW_VDBOX_SURFACE_PARAMS )); MOS_ZeroMemory(m_picMhwParams.IndObjBaseAddrParams, sizeof(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS)); MOS_ZeroMemory(m_picMhwParams.QmParams, sizeof(MHW_VDBOX_QM_PARAMS )); MOS_ZeroMemory(m_picMhwParams.HevcTileState, sizeof(MHW_VDBOX_HEVC_TILE_STATE )); PMOS_SURFACE destSurface = nullptr; if (m_is8BitFrameIn10BitHevc) { destSurface = &m_internalNv12RtSurfaces[m_internalNv12RtIndexMap[m_hevcPicParams->CurrPic.FrameIdx]]; } else { destSurface = &m_destSurface; } m_picMhwParams.PipeModeSelectParams->Mode = m_mode; m_picMhwParams.PipeModeSelectParams->bStreamOutEnabled = m_streamOutEnabled; m_picMhwParams.PipeModeSelectParams->bShortFormatInUse = m_shortFormatInUse; m_picMhwParams.SurfaceParams->Mode = CODECHAL_DECODE_MODE_HEVCVLD; m_picMhwParams.SurfaceParams->psSurface = destSurface; m_picMhwParams.SurfaceParams->ucSurfaceStateId = CODECHAL_HCP_DECODED_SURFACE_ID; m_picMhwParams.SurfaceParams->ChromaType = m_hevcPicParams->chroma_format_idc; m_picMhwParams.SurfaceParams->ucBitDepthLumaMinus8 = m_hevcPicParams->bit_depth_luma_minus8; m_picMhwParams.SurfaceParams->ucBitDepthChromaMinus8 = m_hevcPicParams->bit_depth_chroma_minus8; m_picMhwParams.SurfaceParams->dwUVPlaneAlignment = 1 << (m_hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3); m_picMhwParams.PipeBufAddrParams->Mode = m_mode; m_picMhwParams.PipeBufAddrParams->psPreDeblockSurface = destSurface; if (m_is8BitFrameIn10BitHevc) { m_picMhwParams.PipeBufAddrParams->presP010RTSurface = &m_destSurface; } #ifdef _MMC_SUPPORTED CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetPipeBufAddr(m_picMhwParams.PipeBufAddrParams)); #endif m_picMhwParams.PipeBufAddrParams->presMfdDeblockingFilterRowStoreScratchBuffer = &m_resMfdDeblockingFilterRowStoreScratchBuffer; m_picMhwParams.PipeBufAddrParams->presDeblockingFilterTileRowStoreScratchBuffer = &m_resDeblockingFilterTileRowStoreScratchBuffer; m_picMhwParams.PipeBufAddrParams->presDeblockingFilterColumnRowStoreScratchBuffer = &m_resDeblockingFilterColumnRowStoreScratchBuffer; m_picMhwParams.PipeBufAddrParams->presMetadataLineBuffer = &m_resMetadataLineBuffer; m_picMhwParams.PipeBufAddrParams->presMetadataTileLineBuffer = &m_resMetadataTileLineBuffer; m_picMhwParams.PipeBufAddrParams->presMetadataTileColumnBuffer = &m_resMetadataTileColumnBuffer; m_picMhwParams.PipeBufAddrParams->presSaoLineBuffer = &m_resSaoLineBuffer; m_picMhwParams.PipeBufAddrParams->presSaoTileLineBuffer = &m_resSaoTileLineBuffer; m_picMhwParams.PipeBufAddrParams->presSaoTileColumnBuffer = &m_resSaoTileColumnBuffer; m_picMhwParams.PipeBufAddrParams->presCurMvTempBuffer = &m_resMvTemporalBuffer[m_hevcMvBufferIndex]; MOS_ZeroMemory(m_presReferences, sizeof(PMOS_RESOURCE) * CODEC_MAX_NUM_REF_FRAME_HEVC); MOS_ZeroMemory(m_dummyReferenceSlot, sizeof(m_dummyReferenceSlot)); if (!m_curPicIntra) { uint8_t i, k = 0, m = 0; PMOS_RESOURCE firstValidFrame = nullptr; PMOS_RESOURCE firstValidMvBuf = nullptr; for (i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++) { if (m_frameUsedAsCurRef[i]) { uint8_t refFrameValue = m_hevcPicParams->RefFrameList[i].FrameIdx; if (refFrameValue < CODECHAL_NUM_UNCOMPRESSED_SURFACE_HEVC) { m_presReferences[k] = &(m_hevcRefList[refFrameValue]->resRefPic); if (m_osInterface->pfnIsMismatchOrderProgrammingSupported()) { m_picMhwParams.PipeBufAddrParams->presColMvTempBuffer[m++] = &m_resMvTemporalBuffer[refFrameValue]; if (firstValidMvBuf == nullptr) { firstValidMvBuf = &m_resMvTemporalBuffer[refFrameValue]; } } else { for (uint8_t j = 0; j < CODEC_NUM_HEVC_MV_BUFFERS; j++) { if ((m_hevcMvList[j].bInUse) && (m_hevcMvList[j].u8FrameId == refFrameValue) && !Mos_ResourceIsNull(&m_resMvTemporalBuffer[j])) { m_picMhwParams.PipeBufAddrParams->presColMvTempBuffer[m++] = &m_resMvTemporalBuffer[j]; if (firstValidMvBuf == nullptr) { firstValidMvBuf = &m_resMvTemporalBuffer[j]; } break; } } } if (firstValidFrame == nullptr) { firstValidFrame = m_presReferences[k]; } k++; } } } CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy( m_picMhwParams.PipeBufAddrParams->presReferences, sizeof(PMOS_RESOURCE) * CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC, m_presReferences, sizeof(PMOS_RESOURCE) * CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC)); CODECHAL_DECODE_ASSERT(k <= 8); CODECHAL_DECODE_ASSERT(m <= 8); // Return error if reference surface's pitch * height is less than dest surface. MOS_SURFACE destSurfaceDetails; MOS_SURFACE refSurfaceDetails; bool hasRefs = false; MOS_ZeroMemory(&destSurfaceDetails, sizeof(destSurfaceDetails)); destSurfaceDetails.Format = Format_Invalid; MOS_ZeroMemory(&refSurfaceDetails, sizeof(refSurfaceDetails)); refSurfaceDetails.Format = Format_Invalid; CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetResourceInfo( m_osInterface, &destSurface->OsResource, &destSurfaceDetails)); for (uint8_t i = 0; i < CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC; i++) { if (m_picMhwParams.PipeBufAddrParams->presReferences[i] != nullptr) { if (Mos_ResourceIsNull(m_picMhwParams.PipeBufAddrParams->presReferences[i])) { MOS_ZeroMemory(&m_hevcRefList[m_hevcPicParams->CurrPic.FrameIdx]->resRefPic, sizeof(MOS_RESOURCE)); CODECHAL_DECODE_ASSERTMESSAGE("Ref frame for Current Frame is not exist. Current frame will be skipped. Thus, clear current frame Ref List."); return MOS_STATUS_INVALID_PARAMETER; } CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetResourceInfo( m_osInterface, m_picMhwParams.PipeBufAddrParams->presReferences[i], &refSurfaceDetails)); if ((refSurfaceDetails.dwPitch * refSurfaceDetails.dwHeight) < (destSurfaceDetails.dwPitch * destSurfaceDetails.dwHeight)) { CODECHAL_DECODE_ASSERTMESSAGE("Reference surface's pitch * height is less than Dest surface."); return MOS_STATUS_INVALID_PARAMETER; } hasRefs = true; } } if (!m_curPicIntra && !hasRefs) { MOS_ZeroMemory(&m_hevcRefList[m_hevcPicParams->CurrPic.FrameIdx]->resRefPic, sizeof(MOS_RESOURCE)); CODECHAL_DECODE_ASSERTMESSAGE("No any Ref frame for Current Frame. Current frame will be skipped. Thus, clear current frame Ref List."); return MOS_STATUS_INVALID_PARAMETER; } if (firstValidFrame == nullptr) { firstValidFrame = &destSurface->OsResource; } if (firstValidMvBuf == nullptr && !Mos_ResourceIsNull(&m_resMvTemporalBuffer[m_hevcMvBufferIndex])) { firstValidMvBuf = &m_resMvTemporalBuffer[m_hevcMvBufferIndex]; } 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 (m_picMhwParams.PipeBufAddrParams->presReferences[i] == nullptr) { m_picMhwParams.PipeBufAddrParams->presReferences[i] = firstValidFrame; } } if (m_osInterface->pfnIsMismatchOrderProgrammingSupported()) { for (uint32_t n = 0; n < CODEC_NUM_HEVC_MV_BUFFERS; n++) { if (m_picMhwParams.PipeBufAddrParams->presColMvTempBuffer[n] == nullptr) { m_picMhwParams.PipeBufAddrParams->presColMvTempBuffer[n] = firstValidMvBuf; } } } else { for (uint32_t n = 0; n < CODEC_NUM_HEVC_MV_BUFFERS; n++) { if (m_picMhwParams.PipeBufAddrParams->presColMvTempBuffer[n] == nullptr && !Mos_ResourceIsNull(&m_resMvTemporalBuffer[n])) { m_picMhwParams.PipeBufAddrParams->presColMvTempBuffer[n] = &m_resMvTemporalBuffer[n]; } } } } // 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 (m_picMhwParams.PipeBufAddrParams->presReferences[i] == nullptr && MEDIA_IS_WA(m_waTable, WaDummyReference) && !Mos_ResourceIsNull(&m_dummyReference.OsResource)) { m_picMhwParams.PipeBufAddrParams->presReferences[i] = &m_dummyReference.OsResource; m_dummyReferenceSlot[i] = true; } } #ifdef _MMC_SUPPORTED CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->CheckReferenceList(m_picMhwParams.PipeBufAddrParams)); CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetRefrenceSync(m_disableDecodeSyncLock, m_disableLockForTranscode)); #endif m_picMhwParams.IndObjBaseAddrParams->Mode = m_mode; m_picMhwParams.IndObjBaseAddrParams->dwDataSize = m_copyDataBufferInUse ? m_copyDataBufferSize : m_dataSize; m_picMhwParams.IndObjBaseAddrParams->dwDataOffset = m_copyDataBufferInUse ? 0 : m_dataOffset; m_picMhwParams.IndObjBaseAddrParams->presDataBuffer = m_copyDataBufferInUse ? &m_resCopyDataBuffer : &m_resDataBuffer; if (m_secureDecoder) { CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->SetBitstreamBuffer(m_picMhwParams.IndObjBaseAddrParams)); } m_picMhwParams.QmParams->Standard = CODECHAL_HEVC; m_picMhwParams.QmParams->pHevcIqMatrix = (PMHW_VDBOX_HEVC_QM_PARAMS)m_hevcIqMatrixParams; m_picMhwParams.HevcPicState->pHevcPicParams = m_hevcPicParams; m_picMhwParams.HevcTileState->pHevcPicParams = m_hevcPicParams; m_picMhwParams.HevcTileState->pTileColWidth = m_tileColWidth; m_picMhwParams.HevcTileState->pTileRowHeight = m_tileRowHeight; return eStatus; } MOS_STATUS CodechalDecodeHevc::AddPictureLongFormatCmds( PMOS_COMMAND_BUFFER cmdBufferInUse, PIC_LONG_FORMAT_MHW_PARAMS *picMhwParams) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_DECODE_FUNCTION_ENTER; CODECHAL_DECODE_CHK_NULL_RETURN(cmdBufferInUse); CODECHAL_DECODE_CHK_NULL_RETURN(picMhwParams); CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpPipeModeSelectCmd( cmdBufferInUse, picMhwParams->PipeModeSelectParams)); CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpSurfaceCmd( cmdBufferInUse, picMhwParams->SurfaceParams)); CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpPipeBufAddrCmd( cmdBufferInUse, picMhwParams->PipeBufAddrParams)); CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpIndObjBaseAddrCmd( cmdBufferInUse, picMhwParams->IndObjBaseAddrParams)); CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpQmStateCmd( cmdBufferInUse, picMhwParams->QmParams)); CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpPicStateCmd( cmdBufferInUse, picMhwParams->HevcPicState)); if (m_hevcPicParams->tiles_enabled_flag) { CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpTileStateCmd( cmdBufferInUse, picMhwParams->HevcTileState)); } return eStatus; } MOS_STATUS CodechalDecodeHevc::SendPictureLongFormat() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_DECODE_FUNCTION_ENTER; if (m_enableSf2DmaSubmits) { m_osInterface->pfnSetPerfTag( m_osInterface, (uint16_t)(((CODECHAL_DECODE_MODE_HEVCVLD << 4) & 0xF0) | (m_perfType & 0xF))); } MOS_COMMAND_BUFFER cmdBuffer; CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); auto mmioRegisters = m_hwInterface->GetMfxInterface()->GetMmioRegisters(m_vdboxIndex); HalOcaInterface::On1stLevelBBStart(cmdBuffer, *m_osInterface->pOsContext, m_osInterface->CurrentGpuContextHandle, *m_miInterface, *mmioRegisters); bool sendPrologWithFrameTracking = false; if (m_shortFormatInUse) { sendPrologWithFrameTracking = m_enableSf2DmaSubmits; } else { sendPrologWithFrameTracking = true; } CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking( &cmdBuffer, sendPrologWithFrameTracking)); CODECHAL_DECODE_CHK_STATUS_RETURN(InitPicLongFormatMhwParams()); CODECHAL_DEBUG_TOOL( for (uint16_t n = 0; n < CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC; n++) { if (m_picMhwParams.PipeBufAddrParams->presReferences[n]) { MOS_SURFACE dstSurface; MOS_ZeroMemory(&dstSurface, sizeof(MOS_SURFACE)); dstSurface.OsResource = *(m_picMhwParams.PipeBufAddrParams->presReferences[n]); CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo( m_osInterface, &dstSurface)); m_debugInterface->m_refIndex = n; std::string refSurfName = "RefSurf[" + std::to_string(static_cast(m_debugInterface->m_refIndex)) + "]"; CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface( &dstSurface, CodechalDbgAttr::attrDecodeReferenceSurfaces, refSurfName.c_str())); } if (m_picMhwParams.PipeBufAddrParams->presColMvTempBuffer[n]) { m_debugInterface->m_refIndex = n; // dump mvdata std::string mvBufDumpName = "_DEC_" + std::to_string(int32_t(n)); CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( m_picMhwParams.PipeBufAddrParams->presColMvTempBuffer[n], CodechalDbgAttr::attrMvData, mvBufDumpName.c_str(), m_mvBufferSize)); } } ); PMOS_COMMAND_BUFFER cmdBufferInUse = &cmdBuffer; //Send status report Start if (m_statusQueryReportingEnabled) { CODECHAL_DECODE_CHK_STATUS_RETURN(StartStatusReport(cmdBufferInUse)); } if (m_statusQueryReportingEnabled && m_shortFormatInUse && m_hcpDecPhase == CodechalHcpDecodePhaseLegacyLong) { uint32_t statusBufferOffset = (m_decodeStatusBuf.m_currIndex * sizeof(CodechalDecodeStatus)) + m_decodeStatusBuf.m_storeDataOffset + sizeof(uint32_t) * 2; // Check HuC_STATUS bit15, HW continue if bit15 > 0, otherwise send COND BB END cmd. CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->SendCondBbEndCmd( &m_decodeStatusBuf.m_statusBuffer, statusBufferOffset + m_decodeStatusBuf.m_hucErrorStatusMaskOffset, 0, false, cmdBufferInUse)); } CODECHAL_DECODE_CHK_STATUS_RETURN(AddPictureLongFormatCmds(cmdBufferInUse, &m_picMhwParams)); m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); return eStatus; } MOS_STATUS CodechalDecodeHevc::SendSliceS2L( PMOS_COMMAND_BUFFER cmdBuffer, PMHW_VDBOX_HEVC_SLICE_STATE hevcSliceState) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_DECODE_CHK_NULL_RETURN(cmdBuffer); CODECHAL_DECODE_CHK_NULL_RETURN(hevcSliceState); CODECHAL_DECODE_CHK_NULL_RETURN(hevcSliceState->pHevcSliceParams); CODECHAL_DECODE_CHK_COND_RETURN( (m_vdboxIndex > m_mfxInterface->GetMaxVdboxIndex()), "ERROR - vdbox index exceed the maximum"); auto mmioRegisters = m_hucInterface->GetMmioRegisters(m_vdboxIndex); if (m_secureDecoder) { CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->AddHucSecureState( this, hevcSliceState, cmdBuffer)); } // Send HuC Stream Obj cmd PCODEC_HEVC_SLICE_PARAMS slc = hevcSliceState->pHevcSliceParams; MHW_VDBOX_HUC_STREAM_OBJ_PARAMS hucStreamObjParams; MOS_ZeroMemory(&hucStreamObjParams, sizeof(hucStreamObjParams)); hucStreamObjParams.dwIndStreamInLength = hevcSliceState->dwLength; hucStreamObjParams.bStreamOutEnable = hevcSliceState->bHucStreamOut ? 1 : 0; hucStreamObjParams.dwIndStreamInStartAddrOffset = slc->slice_data_offset; hucStreamObjParams.bHucProcessing = true; if (m_secureDecoder) { CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->SetHucStreamObj( &hucStreamObjParams)); } hucStreamObjParams.bStreamInEnable = 1; hucStreamObjParams.bEmulPreventionByteRemoval = 1; hucStreamObjParams.bStartCodeSearchEngine = 1; hucStreamObjParams.ucStartCodeByte0 = 0; hucStreamObjParams.ucStartCodeByte1 = 0; hucStreamObjParams.ucStartCodeByte2 = 1; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hucInterface->AddHucStreamObjectCmd( cmdBuffer, &hucStreamObjParams)); if (m_statusQueryReportingEnabled && hevcSliceState->bLastSlice && !hevcSliceState->bHucStreamOut) { uint32_t statusBufferOffset = (m_decodeStatusBuf.m_currIndex * sizeof(CodechalDecodeStatus)) + m_decodeStatusBuf.m_storeDataOffset + sizeof(uint32_t) * 2; // Write HUC_STATUS2 mask MHW_MI_STORE_DATA_PARAMS storeDataParams; MOS_ZeroMemory(&storeDataParams, sizeof(storeDataParams)); storeDataParams.pOsResource = &m_decodeStatusBuf.m_statusBuffer; storeDataParams.dwResourceOffset = statusBufferOffset + m_decodeStatusBuf.m_hucErrorStatus2MaskOffset; storeDataParams.dwValue = m_hucInterface->GetHucStatus2ImemLoadedMask(); CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd( cmdBuffer, &storeDataParams)); // store HUC_STATUS2 register MHW_MI_STORE_REGISTER_MEM_PARAMS storeRegParams; MOS_ZeroMemory(&storeRegParams, sizeof(storeRegParams)); storeRegParams.presStoreBuffer = &m_decodeStatusBuf.m_statusBuffer; storeRegParams.dwOffset = statusBufferOffset + m_decodeStatusBuf.m_hucErrorStatus2RegOffset; storeRegParams.dwRegister = mmioRegisters->hucStatus2RegOffset; CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd( cmdBuffer, &storeRegParams)); } // Send HuC Start CODECHAL_DECODE_CHK_STATUS_RETURN(m_hucInterface->AddHucStartCmd( cmdBuffer, hevcSliceState->bLastSlice ? true : false)); return eStatus; } MOS_STATUS CodechalDecodeHevc::SendSliceLongFormat( PMOS_COMMAND_BUFFER cmdBuffer, PMHW_VDBOX_HEVC_SLICE_STATE hevcSliceState) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_DECODE_CHK_NULL_RETURN(cmdBuffer); CODECHAL_DECODE_CHK_NULL_RETURN(hevcSliceState); CODECHAL_DECODE_CHK_NULL_RETURN(hevcSliceState->pHevcSliceParams); PCODEC_HEVC_SLICE_PARAMS slc = hevcSliceState->pHevcSliceParams; // Disable the flag when ref list is empty for P/B slices to avoid the GPU hang if (m_curPicIntra && !m_hcpInterface->IsHevcISlice(slc->LongSliceFlags.fields.slice_type)) { slc->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag = 0; } CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpSliceStateCmd( cmdBuffer, hevcSliceState)); CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpProtectStateCmd( cmdBuffer, hevcSliceState)); if (! m_hcpInterface->IsHevcISlice(slc->LongSliceFlags.fields.slice_type)) { MHW_VDBOX_HEVC_REF_IDX_PARAMS refIdxParams; refIdxParams.CurrPic = m_hevcPicParams->CurrPic; refIdxParams.ucList = 0; refIdxParams.ucNumRefForList = slc->num_ref_idx_l0_active_minus1 + 1; eStatus = MOS_SecureMemcpy(&refIdxParams.RefPicList, sizeof(refIdxParams.RefPicList), &slc->RefPicList, sizeof(slc->RefPicList)); CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(eStatus, "Failed to copy memory."); refIdxParams.hevcRefList = (void**)m_hevcRefList; refIdxParams.poc_curr_pic = m_hevcPicParams->CurrPicOrderCntVal; for (uint8_t i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++) { refIdxParams.poc_list[i] = m_hevcPicParams->PicOrderCntValList[i]; } refIdxParams.pRefIdxMapping = hevcSliceState->pRefIdxMapping; refIdxParams.RefFieldPicFlag = m_hevcPicParams->RefFieldPicFlag; refIdxParams.RefBottomFieldFlag = m_hevcPicParams->RefBottomFieldFlag; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpRefIdxStateCmd( cmdBuffer, nullptr, &refIdxParams)); if (m_hcpInterface->IsHevcBSlice(slc->LongSliceFlags.fields.slice_type)) { refIdxParams.ucList = 1; refIdxParams.ucNumRefForList = slc->num_ref_idx_l1_active_minus1 + 1; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpRefIdxStateCmd( cmdBuffer, nullptr, &refIdxParams)); } } else if (MEDIA_IS_WA(m_waTable, WaDummyReference) && !m_osInterface->bSimIsActive) { MHW_VDBOX_HEVC_REF_IDX_PARAMS refIdxParams; MOS_ZeroMemory(&refIdxParams, sizeof(MHW_VDBOX_HEVC_REF_IDX_PARAMS)); refIdxParams.bDummyReference = true; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpRefIdxStateCmd( cmdBuffer, nullptr, &refIdxParams)); } if ((m_hevcPicParams->weighted_pred_flag && m_hcpInterface->IsHevcPSlice(slc->LongSliceFlags.fields.slice_type)) || (m_hevcPicParams->weighted_bipred_flag && m_hcpInterface->IsHevcBSlice(slc->LongSliceFlags.fields.slice_type))) { MHW_VDBOX_HEVC_WEIGHTOFFSET_PARAMS weightOffsetParams; weightOffsetParams.ucList = 0; eStatus = MOS_SecureMemcpy( &weightOffsetParams.LumaWeights[0], sizeof(weightOffsetParams.LumaWeights[0]), &slc->delta_luma_weight_l0, sizeof(slc->delta_luma_weight_l0)); CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(eStatus, "Failed to copy memory."); eStatus = MOS_SecureMemcpy( &weightOffsetParams.LumaWeights[1], sizeof(weightOffsetParams.LumaWeights[1]), &slc->delta_luma_weight_l1, sizeof(slc->delta_luma_weight_l1)); CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(eStatus, "Failed to copy memory."); for (int32_t i = 0; i < 15; i++) { weightOffsetParams.LumaOffsets[0][i] = (int16_t)slc->luma_offset_l0[i]; weightOffsetParams.LumaOffsets[1][i] = (int16_t)slc->luma_offset_l1[i]; for (int32_t j = 0; j < 2; j++) { weightOffsetParams.ChromaOffsets[0][i][j] = (int16_t)slc->ChromaOffsetL0[i][j]; weightOffsetParams.ChromaOffsets[1][i][j] = (int16_t)slc->ChromaOffsetL1[i][j]; } } eStatus = MOS_SecureMemcpy( &weightOffsetParams.ChromaWeights[0], sizeof(weightOffsetParams.ChromaWeights[0]), &slc->delta_chroma_weight_l0, sizeof(slc->delta_chroma_weight_l0)); CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(eStatus, "Failed to copy memory."); eStatus = MOS_SecureMemcpy( &weightOffsetParams.ChromaWeights[1], sizeof(weightOffsetParams.ChromaWeights[1]), &slc->delta_chroma_weight_l1, sizeof(slc->delta_chroma_weight_l1)); CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(eStatus, "Failed to copy memory."); CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpWeightOffsetStateCmd( cmdBuffer, nullptr, &weightOffsetParams)); if (m_hcpInterface->IsHevcBSlice(slc->LongSliceFlags.fields.slice_type)) { weightOffsetParams.ucList = 1; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpWeightOffsetStateCmd( cmdBuffer, nullptr, &weightOffsetParams)); } } if (m_secureDecoder) { CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->AddHcpSecureState( cmdBuffer, hevcSliceState)); } MHW_VDBOX_HCP_BSD_PARAMS bsdParams; MOS_ZeroMemory(&bsdParams, sizeof(bsdParams)); bsdParams.dwBsdDataLength = hevcSliceState->dwLength; bsdParams.dwBsdDataStartOffset = slc->slice_data_offset + hevcSliceState->dwOffset; CODECHAL_DECODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpBsdObjectCmd( cmdBuffer, &bsdParams)); return eStatus; } MOS_STATUS CodechalDecodeHevc::DecodePrimitiveLevel() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_DECODE_FUNCTION_ENTER; // Bitstream is incomplete, don't do any decoding work. if (m_incompletePicture) { return MOS_STATUS_SUCCESS; } CODECHAL_DECODE_CHK_COND_RETURN( (m_vdboxIndex > m_mfxInterface->GetMaxVdboxIndex()), "ERROR - vdbox index exceed the maximum"); auto mmioRegisters = m_hucInterface->GetMmioRegisters(m_vdboxIndex); uint32_t statusBufferOffset = (m_decodeStatusBuf.m_currIndex * sizeof(CodechalDecodeStatus)) + m_decodeStatusBuf.m_storeDataOffset + sizeof(uint32_t) * 2; uint32_t renderingFlags = m_videoContextUsesNullHw; MOS_COMMAND_BUFFER cmdBuffer; CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); PMOS_COMMAND_BUFFER cmdBufferInUse = &cmdBuffer; // If S2L and 2nd pass, ... // ... jump to 2nd level batch buffer. if ((m_shortFormatInUse && m_hcpDecPhase == CodechalHcpDecodePhaseLegacyLong) || m_cencBuf) { if (m_enableSf2DmaSubmits) { #if (_DEBUG || _RELEASE_INTERNAL) m_secondLevelBatchBuffer[m_secondLevelBatchBufferIndex].iLastCurrent = m_secondLevelBatchBuffer[m_secondLevelBatchBufferIndex].iSize; #endif CODECHAL_DEBUG_TOOL( CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->Dump2ndLvlBatch( &m_secondLevelBatchBuffer[m_secondLevelBatchBufferIndex], CODECHAL_NUM_MEDIA_STATES, "DEC"));) } if (m_cencBuf) { CODECHAL_DECODE_CHK_STATUS_RETURN(SetCencBatchBuffer(cmdBufferInUse)); } else { // this is S2L conversion CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd( cmdBufferInUse, &m_secondLevelBatchBuffer[m_secondLevelBatchBufferIndex])); } } else { // Setup static slice state parameters MHW_VDBOX_HEVC_SLICE_STATE hevcSliceState; hevcSliceState.presDataBuffer = m_copyDataBufferInUse ? &m_resCopyDataBuffer : &m_resDataBuffer; hevcSliceState.pHevcPicParams = m_hevcPicParams; hevcSliceState.pRefIdxMapping = &m_refIdxMapping[0]; PCODEC_HEVC_SLICE_PARAMS slc = m_hevcSliceParams; for (uint32_t slcCount = 0; slcCount < m_numSlices; slcCount++) { hevcSliceState.pHevcSliceParams = slc; hevcSliceState.dwLength = slc->slice_data_size; hevcSliceState.dwSliceIndex = slcCount; hevcSliceState.bLastSlice = (slcCount == (m_numSlices - 1)); // If S2L and 1st pass, send HuC commands. if (m_shortFormatInUse) { CODECHAL_DECODE_CHK_STATUS_RETURN(SendSliceS2L(cmdBufferInUse, &hevcSliceState)); } else { CODECHAL_DECODE_CHK_STATUS_RETURN(SendSliceLongFormat(cmdBufferInUse, &hevcSliceState)); } slc++; } // If S2L and 1st pass if (m_shortFormatInUse && m_hcpDecPhase == CodechalHcpDecodePhaseLegacyS2L) { // Send VD Pipe Flush command for SKL+ MHW_VDBOX_VD_PIPE_FLUSH_PARAMS vdpipeFlushParams; MOS_ZeroMemory(&vdpipeFlushParams , sizeof(vdpipeFlushParams)); vdpipeFlushParams.Flags.bWaitDoneHEVC = 1; vdpipeFlushParams.Flags.bFlushHEVC = 1; vdpipeFlushParams.Flags.bWaitDoneVDCmdMsgParser = 1; CODECHAL_DECODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdPipelineFlushCmd( cmdBufferInUse, &vdpipeFlushParams)); MHW_MI_FLUSH_DW_PARAMS flushDwParams; MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams)); CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd( cmdBufferInUse, &flushDwParams)); if (m_statusQueryReportingEnabled) { // Check HuC_STATUS2 bit6, if bit6 > 0 HW continue execution following cmd, otherwise it send a COND BB END cmd. eStatus = m_hwInterface->SendCondBbEndCmd( &m_decodeStatusBuf.m_statusBuffer, statusBufferOffset + m_decodeStatusBuf.m_hucErrorStatus2MaskOffset, 0, false, cmdBufferInUse); CODECHAL_DECODE_CHK_STATUS_RETURN(eStatus); // Write HUC_STATUS mask MHW_MI_STORE_DATA_PARAMS storeDataParams; MOS_ZeroMemory(&storeDataParams, sizeof(storeDataParams)); storeDataParams.pOsResource = &m_decodeStatusBuf.m_statusBuffer; storeDataParams.dwResourceOffset = statusBufferOffset + m_decodeStatusBuf.m_hucErrorStatusMaskOffset; storeDataParams.dwValue = m_hucInterface->GetHucStatusHevcS2lFailureMask(); CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd( cmdBufferInUse, &storeDataParams)); // store HUC_STATUS register MHW_MI_STORE_REGISTER_MEM_PARAMS storeRegParams; MOS_ZeroMemory(&storeRegParams, sizeof(storeRegParams)); storeRegParams.presStoreBuffer = &m_decodeStatusBuf.m_statusBuffer; storeRegParams.dwOffset = statusBufferOffset + m_decodeStatusBuf.m_hucErrorStatusRegOffset; storeRegParams.dwRegister = mmioRegisters->hucStatusRegOffset; CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd( cmdBufferInUse, &storeRegParams)); } if (m_enableSf2DmaSubmits) { CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd( cmdBufferInUse, nullptr)); } m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); if (m_enableSf2DmaSubmits) { CODECHAL_DEBUG_TOOL( CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer( cmdBufferInUse, CODECHAL_NUM_MEDIA_STATES, "DEC")); //CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHal_DbgReplaceAllCommands( // m_debugInterface, // cmdBufferInUse)); ); //CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer( // m_osInterface, // cmdBufferInUse, // renderingFlags)); } return eStatus; } } // Send VD Pipe Flush command for SKL+ MHW_VDBOX_VD_PIPE_FLUSH_PARAMS vdpipeFlushParams; MOS_ZeroMemory(&vdpipeFlushParams , sizeof(vdpipeFlushParams)); vdpipeFlushParams.Flags.bWaitDoneHEVC = 1; vdpipeFlushParams.Flags.bFlushHEVC = 1; vdpipeFlushParams.Flags.bWaitDoneVDCmdMsgParser = 1; CODECHAL_DECODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdPipelineFlushCmd( cmdBufferInUse, &vdpipeFlushParams)); MHW_MI_FLUSH_DW_PARAMS flushDwParams; MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams)); CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd( cmdBufferInUse, &flushDwParams)); MOS_SYNC_PARAMS syncParams = g_cInitSyncParams; syncParams.GpuContext = m_videoContext; if (m_is8BitFrameIn10BitHevc) { syncParams.presSyncResource = &m_internalNv12RtSurfaces[m_internalNv12RtIndexMap[m_hevcPicParams->CurrPic.FrameIdx]].OsResource; } else { syncParams.presSyncResource = &m_destSurface.OsResource; } syncParams.bReadOnly = false; syncParams.bDisableDecodeSyncLock = m_disableDecodeSyncLock; syncParams.bDisableLockForTranscode = m_disableLockForTranscode; if (!CodecHal_PictureIsField(m_hevcPicParams->CurrPic)) { CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(m_osInterface, &syncParams)); CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams)); // Update the resource tag (s/w tag) for On-Demand Sync m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams); } // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag if (m_osInterface->bTagResourceSync) { CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource( cmdBufferInUse, &syncParams)); } if (m_statusQueryReportingEnabled) { CodechalDecodeStatusReport decodeStatusReport; decodeStatusReport.m_statusReportNumber = m_statusReportFeedbackNumber; decodeStatusReport.m_currDecodedPic = m_hevcPicParams->CurrPic; decodeStatusReport.m_currDeblockedPic = m_hevcPicParams->CurrPic; decodeStatusReport.m_codecStatus = CODECHAL_STATUS_UNAVAILABLE; if (m_is8BitFrameIn10BitHevc) { decodeStatusReport.m_currDecodedPicRes = m_destSurface.OsResource; } else { decodeStatusReport.m_currDecodedPicRes = m_hevcRefList[m_hevcPicParams->CurrPic.FrameIdx]->resRefPic; } #ifdef _DECODE_PROCESSING_SUPPORTED CODECHAL_DEBUG_TOOL( if (m_downsampledSurfaces && m_sfcState && m_sfcState->m_sfcOutputSurface) { m_downsampledSurfaces[m_hevcPicParams->CurrPic.FrameIdx].OsResource = m_sfcState->m_sfcOutputSurface->OsResource; decodeStatusReport.m_currSfcOutputPicRes = &m_downsampledSurfaces[m_hevcPicParams->CurrPic.FrameIdx].OsResource; }) #endif CODECHAL_DEBUG_TOOL( decodeStatusReport.m_secondField = CodecHal_PictureIsBottomField(m_hevcPicParams->CurrPic); decodeStatusReport.m_frameType = m_perfType;); CODECHAL_DECODE_CHK_STATUS_RETURN(EndStatusReport( decodeStatusReport, cmdBufferInUse)); } MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams)); CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd( cmdBufferInUse, &flushDwParams)); CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd( cmdBufferInUse, nullptr)); m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); bool syncCompleteFrame = m_copyDataBufferInUse; if (syncCompleteFrame) { //Sync up complete frame MOS_SYNC_PARAMS copyDataSyncParams = g_cInitSyncParams; copyDataSyncParams.GpuContext = m_videoContextForWa; copyDataSyncParams.presSyncResource = &m_resSyncObjectWaContextInUse; CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, ©DataSyncParams)); copyDataSyncParams = g_cInitSyncParams; copyDataSyncParams.GpuContext = m_videoContext; copyDataSyncParams.presSyncResource = &m_resSyncObjectWaContextInUse; CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, ©DataSyncParams)); } CODECHAL_DEBUG_TOOL( { CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer( cmdBufferInUse, CODECHAL_NUM_MEDIA_STATES, "DEC")); //CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHal_DbgReplaceAllCommands( // m_debugInterface, // cmdBufferInUse)); } ); HalOcaInterface::DumpCodechalParam(cmdBuffer, (MOS_CONTEXT_HANDLE)m_osInterface->pOsContext, m_pCodechalOcaDumper, CODECHAL_HEVC); HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface); CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer( m_osInterface, cmdBufferInUse, renderingFlags)); CODECHAL_DEBUG_TOOL( m_mmc->UpdateUserFeatureKey(&m_destSurface);) // Reset status report if (m_statusQueryReportingEnabled) { bool resetStatusReport = true; if (resetStatusReport) { CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport( m_videoContextUsesNullHw)); } } if (m_is8BitFrameIn10BitHevc) { CODECHAL_DECODE_CHK_NULL_RETURN(m_decodeNV12ToP010); CODECHAL_DECODE_CHK_STATUS_RETURN(m_decodeNV12ToP010->Execute( &m_internalNv12RtSurfaces[m_internalNv12RtIndexMap[m_hevcPicParams->CurrPic.FrameIdx]].OsResource, &m_destSurface.OsResource)); } // Needs to be re-set for Linux buffer re-use scenarios if (m_is8BitFrameIn10BitHevc) { m_hevcRefList[m_hevcPicParams->CurrPic.FrameIdx]->resRefPic = m_internalNv12RtSurfaces[m_internalNv12RtIndexMap[m_hevcPicParams->CurrPic.FrameIdx]].OsResource; } else { m_hevcRefList[m_hevcPicParams->CurrPic.FrameIdx]->resRefPic = m_destSurface.OsResource; } // Send the signal to indicate decode completion, in case On-Demand Sync is not present if (!CodecHal_PictureIsField(m_hevcPicParams->CurrPic)) { MOS_SYNC_PARAMS syncParams = g_cInitSyncParams; syncParams.GpuContext = m_videoContext; syncParams.presSyncResource = &m_destSurface.OsResource; CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams)); } #ifdef _DECODE_PROCESSING_SUPPORTED // Send Vebox and SFC cmds if (m_sfcState->m_sfcPipeOut) { CODECHAL_DECODE_CHK_STATUS_RETURN(m_sfcState->RenderStart()); } #endif return eStatus; } MOS_STATUS CodechalDecodeHevc::CalcDownsamplingParams( void *picParams, uint32_t *refSurfWidth, uint32_t *refSurfHeight, MOS_FORMAT *format, uint8_t *frameIdx) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_DECODE_CHK_NULL_RETURN(picParams); CODECHAL_DECODE_CHK_NULL_RETURN(refSurfWidth); CODECHAL_DECODE_CHK_NULL_RETURN(refSurfHeight); CODECHAL_DECODE_CHK_NULL_RETURN(format); CODECHAL_DECODE_CHK_NULL_RETURN(frameIdx); PCODEC_HEVC_PIC_PARAMS hevcPicParams = (PCODEC_HEVC_PIC_PARAMS)picParams; *refSurfWidth = 0; *refSurfHeight = 0; *format = Format_NV12; *frameIdx = hevcPicParams->CurrPic.FrameIdx; uint32_t widthInPix, heightInPix; widthInPix = (1 << (hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3)) * (hevcPicParams->PicWidthInMinCbsY); heightInPix = (1 << (hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3)) * (hevcPicParams->PicHeightInMinCbsY); *refSurfWidth = MOS_ALIGN_CEIL(widthInPix, 64); *refSurfHeight = MOS_ALIGN_CEIL(heightInPix, 64); if (m_is10BitHevc) { *format = Format_P010; } return eStatus; } MOS_STATUS CodechalDecodeHevc::InitMmcState() { #ifdef _MMC_SUPPORTED m_mmc = MOS_New(CodechalMmcDecodeHevc, m_hwInterface, this); CODECHAL_DECODE_CHK_NULL_RETURN(m_mmc); #endif return MOS_STATUS_SUCCESS; } MOS_STATUS CodechalDecodeHevc::AllocateStandard ( CodechalSetting *settings) { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; CODECHAL_DECODE_FUNCTION_ENTER; CODECHAL_DECODE_CHK_NULL_RETURN(settings); CODECHAL_DECODE_CHK_STATUS_RETURN(InitMmcState()); m_width = settings->width; m_height = settings->height; m_is10BitHevc = (settings->lumaChromaDepth & CODECHAL_LUMA_CHROMA_DEPTH_10_BITS) ? true : false; m_is12BitHevc = (settings->lumaChromaDepth & CODECHAL_LUMA_CHROMA_DEPTH_12_BITS) ? true : false; m_chromaFormatinProfile = settings->chromaFormat; m_shortFormatInUse = settings->shortFormatInUse; #ifdef _DECODE_PROCESSING_SUPPORTED m_sfcState = MOS_New(CodechalHevcSfcState); CODECHAL_DECODE_CHK_NULL_RETURN(m_sfcState); CODECHAL_DECODE_CHK_STATUS_RETURN(m_sfcState->InitializeSfcState( this, m_hwInterface, m_osInterface)); #endif MOS_ZeroMemory(&m_currPic, sizeof(m_currPic)); m_frameIdx = 0; if (m_shortFormatInUse) { // Legacy SF has 2 passes, 1st pass is S2L, 2nd pass is HEVC Long decode. m_decodePassNum = 2; MOS_USER_FEATURE_VALUE_DATA userFeatureData; MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); MOS_UserFeature_ReadValue_ID( nullptr, __MEDIA_USER_FEATURE_VALUE_HEVC_SF_2_DMA_SUBMITS_ENABLE_ID, &userFeatureData, m_osInterface->pOsContext); m_enableSf2DmaSubmits = userFeatureData.u32Data ? true : false; } MHW_VDBOX_STATE_CMDSIZE_PARAMS stateCmdSizeParams; stateCmdSizeParams.bShortFormat = m_shortFormatInUse; stateCmdSizeParams.bHucDummyStream = (m_secureDecoder ? m_secureDecoder->IsDummyStreamEnabled() : false); // Picture Level Commands CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->GetHxxStateCommandSize( m_mode, &m_commandBufferSizeNeeded, &m_commandPatchListSizeNeeded, &stateCmdSizeParams)); // Primitive Level Commands CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->GetHxxPrimitiveCommandSize( m_mode, &m_standardDecodeSizeNeeded, &m_standardDecodePatchListSizeNeeded, m_shortFormatInUse)); CODECHAL_DECODE_CHK_STATUS_RETURN(AllocateResourcesFixedSizes()); // Prepare Pic Params m_picMhwParams.PipeModeSelectParams = MOS_New(MHW_VDBOX_PIPE_MODE_SELECT_PARAMS); m_picMhwParams.SurfaceParams = MOS_New(MHW_VDBOX_SURFACE_PARAMS); m_picMhwParams.PipeBufAddrParams = MOS_New(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS); m_picMhwParams.IndObjBaseAddrParams = MOS_New(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS); m_picMhwParams.QmParams = MOS_New(MHW_VDBOX_QM_PARAMS); m_picMhwParams.HevcPicState = MOS_New(MHW_VDBOX_HEVC_PIC_STATE); m_picMhwParams.HevcTileState = MOS_New(MHW_VDBOX_HEVC_TILE_STATE); CODECHAL_DECODE_CHK_NULL_RETURN(m_picMhwParams.PipeModeSelectParams); CODECHAL_DECODE_CHK_NULL_RETURN(m_picMhwParams.SurfaceParams); CODECHAL_DECODE_CHK_NULL_RETURN(m_picMhwParams.PipeBufAddrParams); CODECHAL_DECODE_CHK_NULL_RETURN(m_picMhwParams.IndObjBaseAddrParams); CODECHAL_DECODE_CHK_NULL_RETURN(m_picMhwParams.QmParams); CODECHAL_DECODE_CHK_NULL_RETURN(m_picMhwParams.HevcPicState); CODECHAL_DECODE_CHK_NULL_RETURN(m_picMhwParams.HevcTileState); MOS_ZeroMemory(m_picMhwParams.SurfaceParams, sizeof(MHW_VDBOX_SURFACE_PARAMS)); MOS_ZeroMemory(m_picMhwParams.IndObjBaseAddrParams, sizeof(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS)); MOS_ZeroMemory(m_picMhwParams.QmParams, sizeof(MHW_VDBOX_QM_PARAMS)); MOS_ZeroMemory(m_picMhwParams.HevcTileState, sizeof(MHW_VDBOX_HEVC_TILE_STATE)); return eStatus; } CodechalDecodeHevc::CodechalDecodeHevc( CodechalHwInterface * hwInterface, CodechalDebugInterface *debugInterface, PCODECHAL_STANDARD_INFO standardInfo) : CodechalDecode(hwInterface, debugInterface, standardInfo), m_minCtbSize(0), m_is10BitHevc(false), m_is12BitHevc(false), m_chromaFormatinProfile(0), m_shortFormatInUse(false), m_dataSize(0), m_dataOffset(0), m_numSlices(0), m_is8BitFrameIn10BitHevc(false), m_internalNv12RtIndexMapInitilized(false), m_mfdDeblockingFilterRowStoreScratchBufferPicWidth(0), m_metadataLineBufferPicWidth(0), m_saoLineBufferPicWidth(0), m_mvBufferProgrammed(false), m_secondLevelBatchBufferIndex(0), m_dmemBufferIdx(0), m_dmemBufferSize(0), m_dmemTransferSize(0), m_dmemBufferProgrammed(false), m_copyDataBufferSize(0), m_copyDataOffset(0), m_copyDataBufferInUse(false), m_estiBytesInBitstream(0), m_curPicIntra(false), m_mvBufferSize(0), m_hevcMvBufferIndex(0), m_frameIdx(0), m_enableSf2DmaSubmits(false), m_widthLastMaxAlloced(0), m_heightLastMaxAlloced(0), m_ctbLog2SizeYMax(0), m_hcpDecPhase(0) { CODECHAL_DECODE_FUNCTION_ENTER; MOS_ZeroMemory(m_internalNv12RtSurfaces, sizeof(m_internalNv12RtSurfaces)); MOS_ZeroMemory(&m_resDataBuffer, sizeof(m_resDataBuffer)); MOS_ZeroMemory(&m_resMfdDeblockingFilterRowStoreScratchBuffer, sizeof(m_resMfdDeblockingFilterRowStoreScratchBuffer)); MOS_ZeroMemory(&m_resDeblockingFilterTileRowStoreScratchBuffer, sizeof(m_resDeblockingFilterTileRowStoreScratchBuffer)); MOS_ZeroMemory(&m_resDeblockingFilterColumnRowStoreScratchBuffer, sizeof(m_resDeblockingFilterColumnRowStoreScratchBuffer)); MOS_ZeroMemory(&m_resMetadataLineBuffer, sizeof(m_resMetadataLineBuffer)); MOS_ZeroMemory(&m_resMetadataTileLineBuffer, sizeof(m_resMetadataTileLineBuffer)); MOS_ZeroMemory(&m_resMetadataTileColumnBuffer, sizeof(m_resMetadataTileColumnBuffer)); MOS_ZeroMemory(&m_resSaoLineBuffer, sizeof(m_resSaoLineBuffer)); MOS_ZeroMemory(&m_resSaoTileLineBuffer, sizeof(m_resSaoTileLineBuffer)); MOS_ZeroMemory(&m_resSaoTileColumnBuffer, sizeof(m_resSaoTileColumnBuffer)); MOS_ZeroMemory(m_resMvTemporalBuffer, sizeof(m_resMvTemporalBuffer)); MOS_ZeroMemory(m_resDmemBuffer, sizeof(m_resDmemBuffer)); MOS_ZeroMemory(&m_resCopyDataBuffer, sizeof(m_resCopyDataBuffer)); MOS_ZeroMemory(&m_resSyncObjectWaContextInUse, sizeof(m_resSyncObjectWaContextInUse)); MOS_ZeroMemory(&m_picMhwParams,sizeof(m_picMhwParams)); MOS_ZeroMemory(&m_hevcPicParams,sizeof(m_hevcPicParams)); MOS_ZeroMemory(&m_hevcSliceParams,sizeof(m_hevcSliceParams)); MOS_ZeroMemory(&m_hevcIqMatrixParams,sizeof(m_hevcIqMatrixParams)); MOS_ZeroMemory(&m_destSurface,sizeof(m_destSurface)); MOS_ZeroMemory(&m_currPic,sizeof(m_currPic)); MOS_ZeroMemory(&m_hevcMvList, CODEC_NUM_HEVC_MV_BUFFERS * sizeof(CODECHAL_DECODE_HEVC_MV_LIST)); MOS_ZeroMemory(m_presReferences, sizeof(PMOS_RESOURCE) * CODEC_MAX_NUM_REF_FRAME_HEVC); m_hcpInUse = true; m_hwInterface = hwInterface; } #if USE_CODECHAL_DEBUG_TOOL MOS_STATUS CodechalDecodeHevc::DumpPicParams( PCODEC_HEVC_PIC_PARAMS picParams, void* extPicParams) { CODECHAL_DEBUG_FUNCTION_ENTER; if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrPicParams)) { return MOS_STATUS_SUCCESS; } CODECHAL_DEBUG_CHK_NULL(picParams); std::ostringstream oss; oss.setf(std::ios::showbase | std::ios::uppercase); oss.setf(std::ios::hex, std::ios::basefield); oss << "PicWidthInMinCbsY: " << +picParams->PicWidthInMinCbsY << std::endl; oss << "PicHeightInMinCbsY: " << +picParams->PicHeightInMinCbsY << std::endl; //wFormatAndSequenceInfoFlags oss << "chroma_format_idc: " << +picParams->chroma_format_idc << std::endl; oss << "separate_colour_plane_flag: " << +picParams->separate_colour_plane_flag << std::endl; oss << "bit_depth_luma_minus8: " << +picParams->bit_depth_luma_minus8 << std::endl; oss << "bit_depth_chroma_minus8: " << +picParams->bit_depth_chroma_minus8 << std::endl; oss << "log2_max_pic_order_cnt_lsb_minus4: " << +picParams->log2_max_pic_order_cnt_lsb_minus4 << std::endl; oss << "NoPicReorderingFlag: " << +picParams->NoPicReorderingFlag << std::endl; oss << "ReservedBits1: " << +picParams->ReservedBits1 << std::endl; oss << "wFormatAndSequenceInfoFlags: " << +picParams->wFormatAndSequenceInfoFlags << std::endl; oss << "CurrPic FrameIdx: " << +picParams->CurrPic.FrameIdx << std::endl; oss << "CurrPic PicFlags: " << +picParams->CurrPic.PicFlags << std::endl; oss << "sps_max_dec_pic_buffering_minus1: " << +picParams->sps_max_dec_pic_buffering_minus1 << std::endl; oss << "log2_min_luma_coding_block_size_minus3: " << +picParams->log2_min_luma_coding_block_size_minus3 << std::endl; oss << "log2_diff_max_min_luma_coding_block_size: " << +picParams->log2_diff_max_min_luma_coding_block_size << std::endl; oss << "log2_min_transform_block_size_minus2: " << +picParams->log2_min_transform_block_size_minus2 << std::endl; oss << "log2_diff_max_min_transform_block_size: " << +picParams->log2_diff_max_min_transform_block_size << std::endl; oss << "max_transform_hierarchy_depth_intra: " << +picParams->max_transform_hierarchy_depth_intra << std::endl; oss << "max_transform_hierarchy_depth_inter: " << +picParams->max_transform_hierarchy_depth_inter << std::endl; oss << "num_short_term_ref_pic_sets: " << +picParams->num_short_term_ref_pic_sets << std::endl; oss << "num_long_term_ref_pic_sps: " << +picParams->num_long_term_ref_pic_sps << std::endl; oss << "num_ref_idx_l0_default_active_minus1: " << +picParams->num_ref_idx_l0_default_active_minus1 << std::endl; oss << "num_ref_idx_l1_default_active_minus1: " << +picParams->num_ref_idx_l1_default_active_minus1 << std::endl; oss << "init_qp_minus26: " << +picParams->init_qp_minus26 << std::endl; oss << "ucNumDeltaPocsOfRefRpsIdx: " << +picParams->ucNumDeltaPocsOfRefRpsIdx << std::endl; oss << "wNumBitsForShortTermRPSInSlice: " << +picParams->wNumBitsForShortTermRPSInSlice << std::endl; oss << "ReservedBits2: " << +picParams->ReservedBits2 << std::endl; //dwCodingParamToolFlags oss << "scaling_list_enabled_flag: " << +picParams->scaling_list_enabled_flag << std::endl; oss << "amp_enabled_flag: " << +picParams->amp_enabled_flag << std::endl; oss << "sample_adaptive_offset_enabled_flag: " << +picParams->sample_adaptive_offset_enabled_flag << std::endl; oss << "pcm_enabled_flag: " << +picParams->pcm_enabled_flag << std::endl; oss << "pcm_sample_bit_depth_luma_minus1: " << +picParams->pcm_sample_bit_depth_luma_minus1 << std::endl; oss << "pcm_sample_bit_depth_chroma_minus1: " << +picParams->pcm_sample_bit_depth_chroma_minus1 << std::endl; oss << "log2_min_pcm_luma_coding_block_size_minus3: " << +picParams->log2_min_pcm_luma_coding_block_size_minus3 << std::endl; oss << "log2_diff_max_min_pcm_luma_coding_block_size: " << +picParams->log2_diff_max_min_pcm_luma_coding_block_size << std::endl; oss << "pcm_loop_filter_disabled_flag: " << +picParams->pcm_loop_filter_disabled_flag << std::endl; oss << "long_term_ref_pics_present_flag: " << +picParams->long_term_ref_pics_present_flag << std::endl; oss << "sps_temporal_mvp_enabled_flag: " << +picParams->sps_temporal_mvp_enabled_flag << std::endl; oss << "strong_intra_smoothing_enabled_flag: " << +picParams->strong_intra_smoothing_enabled_flag << std::endl; oss << "dependent_slice_segments_enabled_flag: " << +picParams->dependent_slice_segments_enabled_flag << std::endl; oss << "output_flag_present_flag: " << +picParams->output_flag_present_flag << std::endl; oss << "num_extra_slice_header_bits: " << +picParams->num_extra_slice_header_bits << std::endl; oss << "sign_data_hiding_enabled_flag: " << +picParams->sign_data_hiding_enabled_flag << std::endl; oss << "cabac_init_present_flag: " << +picParams->cabac_init_present_flag << std::endl; oss << "ReservedBits3: " << +picParams->ReservedBits3 << std::endl; oss << "dwCodingParamToolFlags: " << +picParams->dwCodingParamToolFlags << std::endl; //dwCodingSettingPicturePropertyFlags oss << "constrained_intra_pred_flag: " << +picParams->constrained_intra_pred_flag << std::endl; oss << "transform_skip_enabled_flag: " << +picParams->transform_skip_enabled_flag << std::endl; oss << "cu_qp_delta_enabled_flag: " << +picParams->cu_qp_delta_enabled_flag << std::endl; oss << "diff_cu_qp_delta_depth: " << +picParams->diff_cu_qp_delta_depth << std::endl; oss << "pps_slice_chroma_qp_offsets_present_flag: " << +picParams->pps_slice_chroma_qp_offsets_present_flag << std::endl; oss << "weighted_pred_flag: " << +picParams->weighted_pred_flag << std::endl; oss << "weighted_bipred_flag: " << +picParams->weighted_bipred_flag << std::endl; oss << "transquant_bypass_enabled_flag: " << +picParams->transquant_bypass_enabled_flag << std::endl; oss << "tiles_enabled_flag: " << +picParams->tiles_enabled_flag << std::endl; oss << "entropy_coding_sync_enabled_flag: " << +picParams->entropy_coding_sync_enabled_flag << std::endl; oss << "uniform_spacing_flag: " << +picParams->uniform_spacing_flag << std::endl; oss << "loop_filter_across_tiles_enabled_flag: " << +picParams->loop_filter_across_tiles_enabled_flag << std::endl; oss << "pps_loop_filter_across_slices_enabled_flag: " << +picParams->pps_loop_filter_across_slices_enabled_flag << std::endl; oss << "deblocking_filter_override_enabled_flag: " << +picParams->deblocking_filter_override_enabled_flag << std::endl; oss << "pps_deblocking_filter_disabled_flag: " << +picParams->pps_deblocking_filter_disabled_flag << std::endl; oss << "lists_modification_present_flag: " << +picParams->lists_modification_present_flag << std::endl; oss << "slice_segment_header_extension_present_flag: " << +picParams->slice_segment_header_extension_present_flag << std::endl; oss << "IrapPicFlag: " << +picParams->IrapPicFlag << std::endl; oss << "IdrPicFlag: " << +picParams->IdrPicFlag << std::endl; oss << "IntraPicFlag: " << +picParams->IntraPicFlag << std::endl; oss << "ReservedBits4: " << +picParams->ReservedBits4 << std::endl; oss << "dwCodingSettingPicturePropertyFlags: " << +picParams->dwCodingSettingPicturePropertyFlags << std::endl; oss << "pps_cb_qp_offset: " << +picParams->pps_cb_qp_offset << std::endl; oss << "pps_cr_qp_offset: " << +picParams->pps_cr_qp_offset << std::endl; oss << "num_tile_columns_minus1: " << +picParams->num_tile_columns_minus1 << std::endl; oss << "num_tile_rows_minus1: " << +picParams->num_tile_rows_minus1 << std::endl; //Dump column width oss << "column_width_minus1[19]:"; for (uint8_t i = 0; i < 19; i++) oss << picParams->column_width_minus1[i] << " "; oss << std::endl; //Dump row height oss << "row_height_minus1[21]:"; for (uint8_t i = 0; i < 21; i++) oss << picParams->row_height_minus1[i] << " "; oss << std::endl; oss << "pps_beta_offset_div2: " << +picParams->pps_beta_offset_div2 << std::endl; oss << "pps_tc_offset_div2: " << +picParams->pps_tc_offset_div2 << std::endl; oss << "log2_parallel_merge_level_minus2: " << +picParams->log2_parallel_merge_level_minus2 << std::endl; oss << "CurrPicOrderCntVal: " << +picParams->CurrPicOrderCntVal << std::endl; oss.setf(std::ios::dec, std::ios::basefield); //Dump RefFrameList[15] for (uint8_t i = 0; i < 15; ++i) { oss << "RefFrameList[" << +i << "] FrameIdx:" << +picParams->RefFrameList[i].FrameIdx << std::endl; oss << "RefFrameList[" << +i << "] PicFlags:" << +picParams->RefFrameList[i].PicFlags << std::endl; } //Dump POC List oss << "PicOrderCntValList[15]:"; for (uint8_t i = 0; i < 15; i++) oss << std::hex << picParams->PicOrderCntValList[i] << " "; oss << std::endl; //Dump Ref RefPicSetStCurrBefore List oss << "RefPicSetStCurrBefore[8]:"; for (uint8_t i = 0; i < 8; i++) oss << picParams->RefPicSetStCurrBefore[i] << " "; oss << std::endl; //Dump Ref RefPicSetStCurrAfter List oss << "RefPicSetStCurrAfter[16]:"; for (uint8_t i = 0; i < 8; i++) oss << picParams->RefPicSetStCurrAfter[i] << " "; oss << std::endl; //Dump Ref PicSetStCurr List oss << "RefPicSetLtCurr[16]:"; for (uint8_t i = 0; i < 8; i++) oss << picParams->RefPicSetLtCurr[i] << " "; oss << std::endl; //Dump Ref RefPicSetStCurrBefore List with POC oss << "RefPicSetStCurrBefore[8] (POC): "; for (uint8_t i = 0; i < 8; i++) oss << picParams->PicOrderCntValList[picParams->RefPicSetStCurrBefore[i]] << " "; oss << std::endl; //Dump Ref RefPicSetStCurrAfter List with POC oss << "RefPicSetStCurrAfter[16] (POC):"; for (uint8_t i = 0; i < 8; i++) oss << picParams->PicOrderCntValList[picParams->RefPicSetStCurrAfter[i]] << " "; oss << std::endl; //Dump Ref PicSetStCurr List with POC oss << "RefPicSetLtCurr[16] (POC): "; for (uint8_t i = 0; i < 8; i++) oss << picParams->PicOrderCntValList[picParams->RefPicSetLtCurr[i]] << " "; oss << std::endl; oss << "RefFieldPicFlag: " << +picParams->RefFieldPicFlag << std::endl; oss << "RefBottomFieldFlag: " << +picParams->RefBottomFieldFlag << std::endl; oss << "StatusReportFeedbackNumber: " << +picParams->StatusReportFeedbackNumber << std::endl; const char *fileName = m_debugInterface->CreateFileName( "_DEC", CodechalDbgBufferType::bufPicParams, CodechalDbgExtType::txt); std::ofstream ofs(fileName, std::ios::out); ofs << oss.str(); ofs.close(); return MOS_STATUS_SUCCESS; } MOS_STATUS CodechalDecodeHevc::DumpSliceParams( PCODEC_HEVC_SLICE_PARAMS sliceParams, void* extSliceParams, uint32_t numSlices, bool shortFormatInUse) { CODECHAL_DEBUG_FUNCTION_ENTER; if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSlcParams)) { return MOS_STATUS_SUCCESS; } CODECHAL_DEBUG_CHK_NULL(sliceParams); PCODEC_HEVC_SLICE_PARAMS hevcSliceControl = nullptr; std::ostringstream oss; oss.setf(std::ios::showbase | std::ios::uppercase); for (uint16_t j = 0; j < numSlices; j++) { hevcSliceControl = &sliceParams[j]; oss << "====================================================================================================" << std::endl; oss << "Data for Slice number = " << +j << std::endl; oss << "slice_data_size: " << +hevcSliceControl->slice_data_size << std::endl; oss << "slice_data_offset: " << +hevcSliceControl->slice_data_offset << std::endl; if (!shortFormatInUse) { //Dump Long format specific oss << "ByteOffsetToSliceData: " << +hevcSliceControl->ByteOffsetToSliceData << std::endl; oss << "slice_segment_address: " << +hevcSliceControl->slice_segment_address << std::endl; //Dump RefPicList[2][15] for (uint8_t i = 0; i < 15; ++i) { oss << "RefPicList[0][" << +i << "]"; oss << "FrameIdx: " << +hevcSliceControl->RefPicList[0][i].FrameIdx; oss << ", PicFlags: " << +hevcSliceControl->RefPicList[0][i].PicFlags; oss << std::endl; } for (uint8_t i = 0; i < 15; ++i) { oss << "RefPicList[1][" << +i << "]"; oss << "FrameIdx: " << +hevcSliceControl->RefPicList[1][i].FrameIdx; oss << ", PicFlags: " << +hevcSliceControl->RefPicList[1][i].PicFlags; oss << std::endl; } oss << "last_slice_of_pic: " << +hevcSliceControl->LongSliceFlags.fields.LastSliceOfPic << std::endl; oss << "dependent_slice_segment_flag: " << +hevcSliceControl->LongSliceFlags.fields.dependent_slice_segment_flag << std::endl; oss << "slice_type: " << +hevcSliceControl->LongSliceFlags.fields.slice_type << std::endl; oss << "color_plane_id: " << +hevcSliceControl->LongSliceFlags.fields.color_plane_id << std::endl; oss << "slice_sao_luma_flag: " << +hevcSliceControl->LongSliceFlags.fields.slice_sao_luma_flag << std::endl; oss << "slice_sao_chroma_flag: " << +hevcSliceControl->LongSliceFlags.fields.slice_sao_chroma_flag << std::endl; oss << "mvd_l1_zero_flag: " << +hevcSliceControl->LongSliceFlags.fields.mvd_l1_zero_flag << std::endl; oss << "cabac_init_flag: " << +hevcSliceControl->LongSliceFlags.fields.cabac_init_flag << std::endl; oss << "slice_temporal_mvp_enabled_flag: " << +hevcSliceControl->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag << std::endl; oss << "slice_deblocking_filter_disabled_flag: " << +hevcSliceControl->LongSliceFlags.fields.slice_deblocking_filter_disabled_flag << std::endl; oss << "collocated_from_l0_flag: " << +hevcSliceControl->LongSliceFlags.fields.collocated_from_l0_flag << std::endl; oss << "slice_loop_filter_across_slices_enabled_flag: " << +hevcSliceControl->LongSliceFlags.fields.slice_loop_filter_across_slices_enabled_flag << std::endl; oss << "reserved: " << +hevcSliceControl->LongSliceFlags.fields.reserved << std::endl; oss << "collocated_ref_idx: " << +hevcSliceControl->collocated_ref_idx << std::endl; oss << "num_ref_idx_l0_active_minus1: " << +hevcSliceControl->num_ref_idx_l0_active_minus1 << std::endl; oss << "num_ref_idx_l1_active_minus1: " << +hevcSliceControl->num_ref_idx_l1_active_minus1 << std::endl; oss << "slice_qp_delta: " << +hevcSliceControl->slice_qp_delta << std::endl; oss << "slice_cb_qp_offset: " << +hevcSliceControl->slice_cb_qp_offset << std::endl; oss << "slice_cr_qp_offset: " << +hevcSliceControl->slice_cr_qp_offset << std::endl; oss << "slice_beta_offset_div2: " << +hevcSliceControl->slice_beta_offset_div2 << std::endl; oss << "slice_tc_offset_div2: " << +hevcSliceControl->slice_tc_offset_div2 << std::endl; oss << "luma_log2_weight_denom: " << +hevcSliceControl->luma_log2_weight_denom << std::endl; oss << "delta_chroma_log2_weight_denom: " << +hevcSliceControl->delta_chroma_log2_weight_denom << std::endl; //Dump luma_offset[2][15] for (uint8_t i = 0; i < 15; i++) { oss << "luma_offset_l0[" << +i << "]: " << (+hevcSliceControl->luma_offset_l0[i]) << std::endl; oss << "luma_offset_l1[" << +i << "]: " << (+hevcSliceControl->luma_offset_l1[i]) << std::endl; } //Dump delta_luma_weight[2][15] for (uint8_t i = 0; i < 15; i++) { oss << "delta_luma_weight_l0[" << +i << "]: " << +hevcSliceControl->delta_luma_weight_l0[i] << std::endl; oss << "delta_luma_weight_l1[" << +i << "]: " << +hevcSliceControl->delta_luma_weight_l0[i] << std::endl; } //Dump chroma_offset[2][15][2] for (uint8_t i = 0; i < 15; i++) { oss << "ChromaOffsetL0[" << +i << "][0]: " << (+hevcSliceControl->ChromaOffsetL0[i][0]) << std::endl; oss << "ChromaOffsetL0[" << +i << "][1]: " << (+hevcSliceControl->ChromaOffsetL0[i][1]) << std::endl; oss << "ChromaOffsetL1[" << +i << "][0]: " << (+hevcSliceControl->ChromaOffsetL1[i][0]) << std::endl; oss << "ChromaOffsetL1[" << +i << "][1]: " << (+hevcSliceControl->ChromaOffsetL1[i][1]) << std::endl; } //Dump delta_chroma_weight[2][15][2] for (uint8_t i = 0; i < 15; i++) { oss << "delta_chroma_weight_l0[" << +i << "][0]: " << +hevcSliceControl->delta_chroma_weight_l0[i][0] << std::endl; oss << "delta_chroma_weight_l0[" << +i << "][1]: " << +hevcSliceControl->delta_chroma_weight_l0[i][1] << std::endl; oss << "delta_chroma_weight_l1[" << +i << "][0]: " << +hevcSliceControl->delta_chroma_weight_l1[i][0] << std::endl; oss << "delta_chroma_weight_l1[" << +i << "][1]: " << +hevcSliceControl->delta_chroma_weight_l1[i][1] << std::endl; } oss << "five_minus_max_num_merge_cand: " << +hevcSliceControl->five_minus_max_num_merge_cand << std::endl; } const char *fileName = m_debugInterface->CreateFileName( "_DEC", CodechalDbgBufferType::bufSlcParams, CodechalDbgExtType::txt); std::ofstream ofs; if (j == 0) { ofs.open(fileName, std::ios::out); } else { ofs.open(fileName, std::ios::app); } ofs << oss.str(); ofs.close(); } return MOS_STATUS_SUCCESS; } MOS_STATUS CodechalDecodeHevc::DumpIQParams( PCODECHAL_HEVC_IQ_MATRIX_PARAMS matrixData) { CODECHAL_DEBUG_FUNCTION_ENTER; if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrIqParams)) { return MOS_STATUS_SUCCESS; } CODECHAL_DEBUG_CHK_NULL(matrixData); std::ostringstream oss; oss.setf(std::ios::showbase | std::ios::uppercase); uint32_t idx; uint32_t idx2; // 4x4 block for (idx2 = 0; idx2 < 6; idx2++) { oss << "Qmatrix_HEVC_ucScalingLists0[" << std::dec << +idx2 << "]:" << std::endl; oss << "ucScalingLists0[" << +idx2 << "]:"; for (uint8_t i = 0; i < 16; i++) oss << std::hex << +matrixData->ucScalingLists0[idx2][i] << " "; oss << std::endl; } // 8x8 block for (idx2 = 0; idx2 < 6; idx2++) { oss << "ucScalingLists1[" << std::dec << +idx2 << "]:" << std::endl; for (idx = 0; idx < 64; idx += 8) { oss << "ucScalingLists1[" << std::dec << +idx / 8 << "]:" << std::endl; for (uint8_t i = 0; i < 8; i++) oss << std::hex << +matrixData->ucScalingLists1[idx2][idx + i] << " "; oss << std::endl; } } // 16x16 block for (idx2 = 0; idx2 < 6; idx2++) { oss << "ucScalingLists2[" << std::dec << +idx2 << "]:" << std::endl; for (idx = 0; idx < 64; idx += 8) { oss << "ucScalingLists2[" << std::dec << +idx / 8 << "]:" << std::endl; for (uint8_t i = 0; i < 8; i++) oss << std::hex << +matrixData->ucScalingLists2[idx2][idx + i] << " "; oss << std::endl; } } // 32x32 block for (idx2 = 0; idx2 < 2; idx2++) { oss << "ucScalingLists3[" << std::dec << +idx2 << "]:" << std::endl; for (idx = 0; idx < 64; idx += 8) { oss << "ucScalingLists3[" << std::dec << +idx / 8 << "]:" << std::endl; for (uint8_t i = 0; i < 8; i++) oss << std::hex << +matrixData->ucScalingLists3[idx2][idx + i] << " "; oss << std::endl; } } //DC16x16 block oss << "ucScalingListDCCoefSizeID2: "; for (uint8_t i = 0; i < 6; i++) oss << std::hex << +matrixData->ucScalingListDCCoefSizeID2[i] << " "; oss << std::endl; //DC32x32 block oss << "ucScalingListDCCoefSizeID3: "; oss << +matrixData->ucScalingListDCCoefSizeID3[0] << " " << +matrixData->ucScalingListDCCoefSizeID3[1] << std::endl; const char *fileName = m_debugInterface->CreateFileName( "_DEC", CodechalDbgBufferType::bufIqParams, CodechalDbgExtType::txt); std::ofstream ofs(fileName, std::ios::out); ofs << oss.str(); ofs.close(); return MOS_STATUS_SUCCESS; } MOS_STATUS CodechalDecodeHevc::DumpHucS2l(PMHW_VDBOX_HUC_DMEM_STATE_PARAMS hucDmemStateParams) { CODECHAL_DEBUG_FUNCTION_ENTER; CODECHAL_DEBUG_CHK_NULL(m_debugInterface); CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucDmem( hucDmemStateParams->presHucDataSource, m_dmemTransferSize, 0, hucRegionDumpDefault)); return MOS_STATUS_SUCCESS; } #endif