| /* |
| * 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 |
| //==<Functions>======================================================= |
| |
| 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; |
| |
| if (hevcMvBuffIndex == CODEC_NUM_HEVC_MV_BUFFERS) |
| { |
| // 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); |
| |
| for (uint32_t i = 0; i < CODEC_NUM_HEVC_MV_BUFFERS; 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; |
| |
| // 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"); |
| 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); |
| |
| 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::attrBitstream, |
| "_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(!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)); |
| |
| 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); |
| |
| 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; |
| |
| 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) |
| { |
| 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; |
| } |
| } |
| } |
| |
| 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; |
| } |
| } |
| |
| 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<uint32_t>(m_debugInterface->m_refIndex)) + "]"; |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface( |
| &dstSurface, |
| CodechalDbgAttr::attrReferenceSurfaces, |
| refSurfName.c_str())); |
| } |
| |
| if (m_picMhwParams.PipeBufAddrParams->presColMvTempBuffer[n]) |
| { |
| m_debugInterface->m_refIndex = n; |
| // dump mvdata |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( |
| m_picMhwParams.PipeBufAddrParams->presColMvTempBuffer[n], |
| CodechalDbgAttr::attrMvData, |
| "DEC", |
| 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::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)); |
| |
| m_hcpInUse = true; |
| } |
| |
| #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; |
| } |
| |
| #endif |