| /* |
| * Copyright (c) 2017-2019, 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_vc1_g12.cpp |
| //! \brief Implements the decode interface extension for Gen12 VC1. |
| //! \details Implements all functions required by CodecHal for Gen12 VC1 decoding. |
| //! |
| |
| #include "codeckrnheader.h" |
| |
| #if defined(ENABLE_KERNELS) && !defined(_FULL_OPEN_SOURCE) |
| #include "igcodeckrn_g12.h" |
| #endif |
| |
| #include "codechal_decode_vc1_g12.h" |
| #include "codechal_secure_decode_interface.h" |
| #include "mhw_vdbox_mfx_g12_X.h" |
| #include "codechal_mmc_decode_vc1_g12.h" |
| #include "mhw_render_g12_X.h" |
| #include "hal_oca_interface.h" |
| |
| MOS_STATUS CodechalDecodeVc1G12::InitMmcState() |
| { |
| #ifdef _MMC_SUPPORTED |
| m_mmc = MOS_New(CodechalMmcDecodeVc1G12, m_hwInterface, this); |
| CODECHAL_DECODE_CHK_NULL_RETURN(m_mmc); |
| #endif |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS CodechalDecodeVc1G12::AllocateStandard( |
| CodechalSetting * settings) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_DECODE_FUNCTION_ENTER; |
| |
| CODECHAL_DECODE_CHK_NULL_RETURN(settings); |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(CodechalDecodeVc1::AllocateStandard(settings)); |
| |
| if ( MOS_VE_SUPPORTED(m_osInterface)) |
| { |
| static_cast<MhwVdboxMfxInterfaceG12*>(m_mfxInterface)->DisableScalabilitySupport(); |
| |
| //single pipe VE initialize |
| m_veState = (PCODECHAL_DECODE_SINGLEPIPE_VIRTUALENGINE_STATE)MOS_AllocAndZeroMemory(sizeof(CODECHAL_DECODE_SINGLEPIPE_VIRTUALENGINE_STATE)); |
| CODECHAL_DECODE_CHK_NULL_RETURN(m_veState); |
| CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_InitInterface(m_osInterface, m_veState)); |
| } |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalDecodeVc1G12::SetGpuCtxCreatOption( |
| CodechalSetting *codecHalSetting) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_DECODE_FUNCTION_ENTER; |
| |
| if (!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface)) |
| { |
| CodechalDecode::SetGpuCtxCreatOption(codecHalSetting); |
| } |
| else |
| { |
| m_gpuCtxCreatOpt = MOS_New(MOS_GPUCTX_CREATOPTIONS_ENHANCED); |
| bool sfcInUse = (codecHalSetting->sfcInUseHinted && codecHalSetting->downsamplingHinted |
| && (MEDIA_IS_SKU(m_skuTable, FtrSFCPipe) && !MEDIA_IS_SKU(m_skuTable, FtrDisableVDBox2SFC))); |
| CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_ConstructParmsForGpuCtxCreation( |
| m_veState, |
| (PMOS_GPUCTX_CREATOPTIONS_ENHANCED)m_gpuCtxCreatOpt, |
| sfcInUse)); |
| m_videoContext = MOS_GPU_CONTEXT_VIDEO; |
| } |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalDecodeVc1G12::SetFrameStates() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_DECODE_FUNCTION_ENTER; |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(CodechalDecodeVc1::SetFrameStates()); |
| |
| if (MOS_VE_SUPPORTED(m_osInterface) && !MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface)) |
| { |
| MOS_VIRTUALENGINE_SET_PARAMS vesetParams; |
| |
| MOS_ZeroMemory(&vesetParams, sizeof(vesetParams)); |
| vesetParams.bSFCInUse = false; |
| vesetParams.bNeedSyncWithPrevious = true; |
| vesetParams.bSameEngineAsLastSubmission = false; |
| CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_SetHintParams(m_veState, &vesetParams)); |
| } |
| |
| #ifdef _MMC_SUPPORTED |
| // To WA invalid aux data caused HW issue when MMC on |
| if (m_mmc && m_mmc->IsMmcEnabled() && MEDIA_IS_WA(m_waTable, Wa_1408785368) && |
| !Mos_ResourceIsNull(&m_destSurface.OsResource) && |
| m_destSurface.OsResource.bConvertedFromDDIResource) |
| { |
| CODECHAL_DECODE_VERBOSEMESSAGE("Clear CCS by VE resolve before frame %d submission", m_frameNum); |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnDecompResource(m_osInterface, &m_destSurface.OsResource)); |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(m_osInterface, m_videoContext)); |
| } |
| |
| bool isBPicture = m_mfxInterface->IsVc1BPicture( |
| m_vc1PicParams->CurrPic, |
| m_vc1PicParams->picture_fields.is_first_field, |
| m_vc1PicParams->picture_fields.picture_type); |
| |
| bool isOverlapSmoothingFilter = false; |
| |
| isOverlapSmoothingFilter |= m_vc1PicParams->sequence_fields.AdvancedProfileFlag && |
| m_vc1PicParams->sequence_fields.overlap; |
| |
| isOverlapSmoothingFilter |= !(isBPicture || |
| (m_vc1PicParams->pic_quantizer_fields.pic_quantizer_scale < 9) || |
| !m_vc1PicParams->sequence_fields.overlap); |
| |
| isOverlapSmoothingFilter |= m_intelEntrypointInUse && |
| (m_mode == CODECHAL_DECODE_MODE_VC1VLD) && |
| m_vc1PicParams->conditional_overlap_flag; |
| |
| //For VC1 frame with overlap smoothing filter enabled, force to post-deblock if MMC on |
| if (m_mmc && m_mmc->IsMmcEnabled() && isOverlapSmoothingFilter) |
| { |
| m_deblockingEnabled = true; |
| } |
| #endif |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalDecodeVc1G12::DecodeStateLevel() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_DECODE_FUNCTION_ENTER; |
| |
| PCODEC_REF_LIST *vc1RefList; |
| vc1RefList = &(m_vc1RefList[0]); |
| |
| uint8_t destIdx = m_vc1PicParams->CurrPic.FrameIdx; |
| uint8_t fwdRefIdx = (uint8_t)m_vc1PicParams->ForwardRefIdx; |
| uint8_t bwdRefIdx = (uint8_t)m_vc1PicParams->BackwardRefIdx; |
| |
| bool isIPicture = m_mfxInterface->IsVc1IPicture( |
| m_vc1PicParams->CurrPic, |
| m_vc1PicParams->picture_fields.is_first_field, |
| m_vc1PicParams->picture_fields.picture_type) |
| ? true |
| : false; |
| bool isPPicture = m_mfxInterface->IsVc1PPicture( |
| m_vc1PicParams->CurrPic, |
| m_vc1PicParams->picture_fields.is_first_field, |
| m_vc1PicParams->picture_fields.picture_type) |
| ? true |
| : false; |
| bool isBPicture = m_mfxInterface->IsVc1BPicture( |
| m_vc1PicParams->CurrPic, |
| m_vc1PicParams->picture_fields.is_first_field, |
| m_vc1PicParams->picture_fields.picture_type) |
| ? true |
| : false; |
| |
| PMOS_SURFACE destSurface; |
| PMOS_RESOURCE fwdRefSurface, bwdRefSurface; |
| if (m_unequalFieldWaInUse && CodecHal_PictureIsField(m_vc1PicParams->CurrPic)) |
| { |
| destSurface = |
| &(m_unequalFieldSurface[vc1RefList[destIdx]->dwUnequalFieldSurfaceIdx]); |
| fwdRefSurface = |
| &(m_unequalFieldSurface[vc1RefList[fwdRefIdx]->dwUnequalFieldSurfaceIdx].OsResource); |
| bwdRefSurface = |
| &(m_unequalFieldSurface[vc1RefList[bwdRefIdx]->dwUnequalFieldSurfaceIdx].OsResource); |
| |
| // Overwrite the actual surface height with the coded height and width of the frame |
| // for VC1 since it's possible for a VC1 frame to change size during playback |
| destSurface->dwWidth = m_width; |
| destSurface->dwHeight = m_height; |
| } |
| else |
| { |
| destSurface = &m_destSurface; |
| fwdRefSurface = &(vc1RefList[fwdRefIdx]->resRefPic); |
| bwdRefSurface = &(vc1RefList[bwdRefIdx]->resRefPic); |
| } |
| |
| // WA for SP/MP short format |
| if (m_shortFormatInUse && |
| !m_vc1PicParams->sequence_fields.AdvancedProfileFlag) |
| { |
| CODECHAL_DECODE_CHK_STATUS_RETURN(ConstructBistreamBuffer()); |
| } |
| |
| 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); |
| |
| MHW_MI_FORCE_WAKEUP_PARAMS forceWakeupParams; |
| MOS_ZeroMemory(&forceWakeupParams, sizeof(MHW_MI_FORCE_WAKEUP_PARAMS)); |
| forceWakeupParams.bMFXPowerWellControl = true; |
| forceWakeupParams.bMFXPowerWellControlMask = true; |
| forceWakeupParams.bHEVCPowerWellControl = false; |
| forceWakeupParams.bHEVCPowerWellControlMask = true; |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiForceWakeupCmd( |
| &cmdBuffer, |
| &forceWakeupParams)); |
| |
| MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams; |
| pipeModeSelectParams.Mode = m_mode; |
| pipeModeSelectParams.bStreamOutEnabled = m_streamOutEnabled; |
| pipeModeSelectParams.bPostDeblockOutEnable = m_deblockingEnabled; |
| pipeModeSelectParams.bPreDeblockOutEnable = !m_deblockingEnabled; |
| pipeModeSelectParams.bShortFormatInUse = m_shortFormatInUse; |
| pipeModeSelectParams.bVC1OddFrameHeight = m_vc1OddFrameHeight; |
| |
| MHW_VDBOX_SURFACE_PARAMS surfaceParams; |
| MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams)); |
| surfaceParams.Mode = m_mode; |
| surfaceParams.psSurface = destSurface; |
| |
| MHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams; |
| pipeBufAddrParams.Mode = m_mode; |
| if (m_deblockingEnabled) |
| { |
| pipeBufAddrParams.psPostDeblockSurface = destSurface; |
| } |
| else |
| { |
| pipeBufAddrParams.psPreDeblockSurface = destSurface; |
| } |
| |
| #ifdef _MMC_SUPPORTED |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetPipeBufAddr(&pipeBufAddrParams)); |
| #endif |
| |
| // when there is not a forward or backward reference, |
| // the index is set to the destination frame index |
| m_presReferences[CodechalDecodeFwdRefTop] = |
| m_presReferences[CodechalDecodeFwdRefBottom] = |
| fwdRefSurface; |
| m_presReferences[CodechalDecodeBwdRefTop] = |
| m_presReferences[CodechalDecodeBwdRefBottom] = |
| bwdRefSurface; |
| // special case for second fields |
| if (!m_vc1PicParams->picture_fields.is_first_field && |
| !m_mfxInterface->IsVc1IPicture( |
| m_vc1PicParams->CurrPic, |
| m_vc1PicParams->picture_fields.is_first_field, |
| m_vc1PicParams->picture_fields.picture_type)) |
| { |
| if (m_vc1PicParams->picture_fields.top_field_first) |
| { |
| m_presReferences[CodechalDecodeFwdRefTop] = |
| &destSurface->OsResource; |
| } |
| else |
| { |
| m_presReferences[CodechalDecodeFwdRefBottom] = |
| &destSurface->OsResource; |
| } |
| } |
| |
| // set all ref pic addresses to valid addresses for error concealment purpose |
| for (uint32_t i = 0; i < CODEC_MAX_NUM_REF_FRAME_NON_AVC; i++) |
| { |
| if (m_presReferences[i] == nullptr && |
| MEDIA_IS_WA(m_waTable, WaDummyReference) && |
| !Mos_ResourceIsNull(&m_dummyReference.OsResource)) |
| { |
| m_presReferences[i] = &m_dummyReference.OsResource; |
| } |
| } |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(pipeBufAddrParams.presReferences, sizeof(PMOS_RESOURCE) * CODEC_MAX_NUM_REF_FRAME_NON_AVC, m_presReferences, sizeof(PMOS_RESOURCE) * CODEC_MAX_NUM_REF_FRAME_NON_AVC)); |
| |
| pipeBufAddrParams.presMfdDeblockingFilterRowStoreScratchBuffer = |
| &m_resMfdDeblockingFilterRowStoreScratchBuffer; |
| |
| if (m_streamOutEnabled) |
| { |
| pipeBufAddrParams.presStreamOutBuffer = |
| &(m_streamOutBuffer[m_streamOutCurrBufIdx]); |
| } |
| |
| #ifdef _MMC_SUPPORTED |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->CheckReferenceList(&pipeBufAddrParams)); |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetRefrenceSync(m_disableDecodeSyncLock, m_disableLockForTranscode)); |
| #endif |
| |
| CODECHAL_DEBUG_TOOL( |
| for (int i = 0; i < CODEC_MAX_NUM_REF_FRAME_NON_AVC; i++) |
| { |
| if (pipeBufAddrParams.presReferences[i]) |
| { |
| MOS_SURFACE dstSurface; |
| |
| MOS_ZeroMemory(&dstSurface, sizeof(MOS_SURFACE)); |
| dstSurface.Format = Format_NV12; |
| dstSurface.OsResource = *(pipeBufAddrParams.presReferences[i]); |
| CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo( |
| m_osInterface, |
| &dstSurface)); |
| |
| m_debugInterface->m_refIndex = (uint16_t)i; |
| 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.data())); |
| } |
| } |
| ) |
| |
| MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams; |
| MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams)); |
| indObjBaseAddrParams.Mode = m_mode; |
| if (m_shortFormatInUse && |
| !m_vc1PicParams->sequence_fields.AdvancedProfileFlag) |
| { |
| indObjBaseAddrParams.dwDataSize = m_dataSize + CODECHAL_DECODE_VC1_STUFFING_BYTES; |
| indObjBaseAddrParams.presDataBuffer = &m_resPrivateBistreamBuffer; |
| } |
| else |
| { |
| indObjBaseAddrParams.dwDataSize = m_dataSize; |
| indObjBaseAddrParams.presDataBuffer = &m_resDataBuffer; |
| } |
| |
| MHW_VDBOX_BSP_BUF_BASE_ADDR_PARAMS bspBufBaseAddrParams; |
| MOS_ZeroMemory(&bspBufBaseAddrParams, sizeof(bspBufBaseAddrParams)); |
| bspBufBaseAddrParams.presBsdMpcRowStoreScratchBuffer = &m_resBsdMpcRowStoreScratchBuffer; |
| |
| if (m_vc1PicParams->raw_coding.bitplane_present || m_shortFormatInUse) |
| { |
| bspBufBaseAddrParams.presBitplaneBuffer = &m_resBitplaneBuffer; |
| } |
| |
| MHW_VDBOX_VC1_PRED_PIPE_PARAMS vc1PredPipeParams; |
| vc1PredPipeParams.pVc1PicParams = m_vc1PicParams; |
| vc1PredPipeParams.ppVc1RefList = vc1RefList; |
| |
| MHW_VDBOX_VC1_PIC_STATE vc1PicState; |
| vc1PicState.pVc1PicParams = m_vc1PicParams; |
| vc1PicState.Mode = m_mode; |
| vc1PicState.ppVc1RefList = vc1RefList; |
| vc1PicState.wPrevAnchorPictureTFF = m_prevAnchorPictureTff; |
| vc1PicState.bPrevEvenAnchorPictureIsP = m_prevEvenAnchorPictureIsP; |
| vc1PicState.bPrevOddAnchorPictureIsP = m_prevOddAnchorPictureIsP; |
| |
| if (m_shortFormatInUse) |
| { |
| // WA for WMP. WMP does not provide REFDIST for I/P pictures correctly |
| if (m_vc1PicParams->sequence_fields.AdvancedProfileFlag && |
| CodecHal_PictureIsField(m_vc1PicParams->CurrPic) && |
| (isIPicture || isPPicture) && |
| m_vc1PicParams->reference_fields.reference_distance_flag) |
| { |
| if (m_vc1PicParams->picture_fields.is_first_field) |
| { |
| CODECHAL_DECODE_CHK_STATUS_RETURN(ParsePictureHeader()); |
| m_referenceDistance = m_vc1PicParams->reference_fields.reference_distance; |
| } |
| else |
| { |
| m_vc1PicParams->reference_fields.reference_distance = m_referenceDistance; |
| } |
| } |
| |
| // WA for WMP. WMP does not provide BFRACTION correctly. So parse picture header to get BFRACTION |
| if (isBPicture) |
| { |
| if (m_vc1PicParams->picture_fields.is_first_field) |
| { |
| CODECHAL_DECODE_CHK_STATUS_RETURN(ParsePictureHeader()); |
| } |
| } |
| } |
| |
| MHW_VDBOX_VC1_DIRECTMODE_PARAMS vc1DirectmodeParams; |
| if (m_mode == CODECHAL_DECODE_MODE_VC1VLD) |
| { |
| uint8_t dmvBufferIdx = (m_vc1PicParams->CurrPic.PicFlags == PICTURE_BOTTOM_FIELD) ? CODECHAL_DECODE_VC1_DMV_ODD : CODECHAL_DECODE_VC1_DMV_EVEN; |
| vc1DirectmodeParams.presDmvReadBuffer = &m_resVc1BsdMvData[dmvBufferIdx]; |
| vc1DirectmodeParams.presDmvWriteBuffer = &m_resVc1BsdMvData[dmvBufferIdx]; |
| } |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, !m_olpNeeded)); |
| |
| if (m_statusQueryReportingEnabled) |
| { |
| CODECHAL_DECODE_CHK_STATUS_RETURN(StartStatusReport(&cmdBuffer)); |
| } |
| |
| if (!CodecHal_PictureIsField(m_vc1PicParams->CurrPic) && |
| m_vc1PicParams->picture_fields.picture_type == vc1SkippedFrame) |
| { |
| // no further picture level commands needed for skipped frames |
| m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); |
| |
| return eStatus; |
| } |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeModeSelectCmd(&cmdBuffer, &pipeModeSelectParams)); |
| |
| #ifdef _MMC_SUPPORTED |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetSurfaceState(&surfaceParams)); |
| #endif |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(&cmdBuffer, &surfaceParams)); |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeBufAddrCmd(&cmdBuffer, &pipeBufAddrParams)); |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxIndObjBaseAddrCmd(&cmdBuffer, &indObjBaseAddrParams)); |
| |
| if (m_mode == CODECHAL_DECODE_MODE_VC1VLD) |
| { |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxBspBufBaseAddrCmd(&cmdBuffer, &bspBufBaseAddrParams)); |
| } |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxVc1PredPipeCmd(&cmdBuffer, &vc1PredPipeParams)); |
| |
| if (m_intelEntrypointInUse || m_mode == CODECHAL_DECODE_MODE_VC1IT) |
| { |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxVc1LongPicCmd(&cmdBuffer, &vc1PicState)); |
| } |
| else if (m_shortFormatInUse) |
| { |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdVc1ShortPicCmd(&cmdBuffer, &vc1PicState)); |
| } |
| else |
| { |
| CODECHAL_DECODE_ASSERTMESSAGE("Unsupported decode mode."); |
| eStatus = MOS_STATUS_UNKNOWN; |
| return eStatus; |
| } |
| |
| if (m_mode == CODECHAL_DECODE_MODE_VC1VLD) |
| { |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxVc1DirectmodeCmd(&cmdBuffer, &vc1DirectmodeParams)); |
| } |
| |
| m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalDecodeVc1G12::DecodePrimitiveLevelVLD() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_DECODE_FUNCTION_ENTER; |
| |
| MOS_SYNC_PARAMS syncParams; |
| |
| // static VC1 slice parameters |
| MHW_VDBOX_VC1_SLICE_STATE vc1SliceState; |
| vc1SliceState.presDataBuffer = &m_resDataBuffer; |
| |
| uint16_t frameFieldHeightInMb; |
| CodecHal_GetFrameFieldHeightInMb( |
| m_vc1PicParams->CurrPic, |
| m_picHeightInMb, |
| frameFieldHeightInMb); |
| |
| CODECHAL_DECODE_CHK_NULL_RETURN(m_osInterface); |
| |
| MOS_COMMAND_BUFFER cmdBuffer; |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); |
| |
| if (m_incompletePicture) |
| { |
| MHW_MI_FORCE_WAKEUP_PARAMS forceWakeupParams; |
| MOS_ZeroMemory(&forceWakeupParams, sizeof(MHW_MI_FORCE_WAKEUP_PARAMS)); |
| forceWakeupParams.bMFXPowerWellControl = true; |
| forceWakeupParams.bMFXPowerWellControlMask = true; |
| forceWakeupParams.bHEVCPowerWellControl = false; |
| forceWakeupParams.bHEVCPowerWellControlMask = true; |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiForceWakeupCmd( |
| &cmdBuffer, |
| &forceWakeupParams)); |
| } |
| |
| if (!CodecHal_PictureIsField(m_vc1PicParams->CurrPic) && |
| m_vc1PicParams->picture_fields.picture_type == vc1SkippedFrame) |
| { |
| CODECHAL_DECODE_CHK_STATUS_RETURN(HandleSkipFrame()); |
| goto submit; |
| } |
| else |
| { |
| PCODEC_VC1_SLICE_PARAMS slc = m_vc1SliceParams; |
| bool firstValidSlice = true; |
| int prevValidSlc = 0; |
| for (uint32_t slcCount = 0; slcCount < m_numSlices; slcCount++) |
| { |
| m_vldSliceRecord[slcCount].dwSliceYOffset = slc->slice_vertical_position; |
| m_vldSliceRecord[slcCount].dwNextSliceYOffset = frameFieldHeightInMb; // init to last slice |
| |
| int32_t lLength = slc->slice_data_size >> 3; |
| int32_t lOffset = slc->macroblock_offset >> 3; |
| |
| CodechalResLock ResourceLock(m_osInterface, &m_resDataBuffer); |
| auto buf = (uint8_t*)ResourceLock.Lock(CodechalResLock::readOnly); |
| buf += slc->slice_data_offset; |
| if (lOffset > 3 && buf != nullptr && |
| m_vc1PicParams->sequence_fields.AdvancedProfileFlag) |
| { |
| int i = 0; |
| int j = 0; |
| for (i = 0, j = 0; i < lOffset - 1; i++, j++) |
| { |
| if (!buf[j] && !buf[j + 1] && buf[j + 2] == 3 && buf[j + 3] < 4) |
| { |
| i++, j += 2; |
| } |
| } |
| if (i == lOffset - 1) |
| { |
| if (!buf[j] && !buf[j + 1] && buf[j + 2] == 3 && buf[j + 3] < 4) |
| { |
| buf[j + 2] = 0; |
| j++; |
| } |
| j++; |
| } |
| lOffset = (8 * j + slc->macroblock_offset % 8)>>3; |
| } |
| |
| // Check that the slice data does not overrun the bitstream buffer size |
| if ((slc->slice_data_offset + lLength) > m_dataSize) |
| { |
| lLength = m_dataSize - slc->slice_data_offset; |
| |
| if (lLength < 0) |
| { |
| lLength = 0; |
| } |
| } |
| |
| // Error handling for garbage data |
| if (slc->slice_data_offset > m_dataSize) |
| { |
| slc++; |
| m_vldSliceRecord[slcCount].dwSkip = true; |
| continue; |
| } |
| |
| // Check offset not larger than slice length, can have slice length of 0 |
| if (lOffset > lLength) |
| { |
| slc++; |
| m_vldSliceRecord[slcCount].dwSkip = true; |
| continue; |
| } |
| |
| // Check that the slices do not overlap, else do not send the lower slice |
| if (!firstValidSlice && |
| (m_vldSliceRecord[slcCount].dwSliceYOffset <= m_vldSliceRecord[prevValidSlc].dwSliceYOffset)) |
| { |
| slc++; |
| m_vldSliceRecord[slcCount].dwSkip = true; |
| continue; |
| } |
| |
| if (firstValidSlice) |
| { |
| // Ensure that the first slice starts from 0 |
| m_vldSliceRecord[slcCount].dwSliceYOffset = 0; |
| slc->slice_vertical_position = 0; |
| } |
| else |
| { |
| // Set next slice start Y offset of previous slice |
| m_vldSliceRecord[prevValidSlc].dwNextSliceYOffset = |
| m_vldSliceRecord[slcCount].dwSliceYOffset; |
| } |
| |
| if (m_shortFormatInUse) |
| { |
| if (m_vc1PicParams->sequence_fields.AdvancedProfileFlag) |
| { |
| if ((slc->macroblock_offset >> 3) < CODECHAL_DECODE_VC1_SC_PREFIX_LENGTH) |
| { |
| slc++; |
| m_vldSliceRecord[slcCount].dwSkip = true; |
| continue; |
| } |
| |
| // set macroblock_offset of the first slice to 0 to avoid crash |
| if (slcCount == 0) |
| { |
| slc->macroblock_offset = CODECHAL_DECODE_VC1_SC_PREFIX_LENGTH << 3; |
| } |
| |
| lOffset = CODECHAL_DECODE_VC1_SC_PREFIX_LENGTH; |
| } |
| else // Simple Profile or Main Profile |
| { |
| { |
| lOffset = CODECHAL_DECODE_VC1_STUFFING_BYTES - 1; |
| lLength += CODECHAL_DECODE_VC1_STUFFING_BYTES; |
| slc->macroblock_offset += CODECHAL_DECODE_VC1_STUFFING_BYTES << 3; |
| slc->macroblock_offset &= (~0x7); // Clear bit offset of first MB for short format |
| } |
| } |
| } |
| |
| m_vldSliceRecord[slcCount].dwOffset = lOffset; |
| m_vldSliceRecord[slcCount].dwLength = lLength - lOffset; |
| firstValidSlice = false; |
| prevValidSlc = slcCount; |
| slc++; |
| } |
| |
| if (m_shortFormatInUse && |
| m_vc1PicParams->sequence_fields.AdvancedProfileFlag) |
| { |
| CODECHAL_DECODE_CHK_STATUS_RETURN(GetSliceMbDataOffset()); |
| } |
| |
| // Reset slc pointer |
| slc -= m_numSlices; |
| |
| //------------------------------------ |
| // Fill BSD Object Commands |
| //------------------------------------ |
| for (uint32_t slcCount = 0; slcCount < m_numSlices; slcCount++) |
| { |
| if (m_vldSliceRecord[slcCount].dwSkip) |
| { |
| slc++; |
| continue; |
| } |
| |
| vc1SliceState.pSlc = slc; |
| vc1SliceState.dwOffset = m_vldSliceRecord[slcCount].dwOffset; |
| vc1SliceState.dwLength = m_vldSliceRecord[slcCount].dwLength; |
| vc1SliceState.dwNextVerticalPosition = m_vldSliceRecord[slcCount].dwNextSliceYOffset; |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdVc1BsdObjectCmd(&cmdBuffer, &vc1SliceState)); |
| |
| slc++; |
| } |
| |
| // Free VLD slice record |
| MOS_ZeroMemory(m_vldSliceRecord, (m_numSlices * sizeof(CODECHAL_VC1_VLD_SLICE_RECORD))); |
| } |
| |
| // Check if destination surface needs to be synchronized |
| if (m_unequalFieldWaInUse && |
| CodecHal_PictureIsField(m_vc1PicParams->CurrPic) && |
| !m_vc1PicParams->picture_fields.is_first_field) |
| { |
| MHW_MI_FLUSH_DW_PARAMS flushDwParams; |
| MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams)); |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams)); |
| } |
| else |
| { |
| // Check if destination surface needs to be synchronized |
| syncParams = g_cInitSyncParams; |
| syncParams.GpuContext = m_videoContext; |
| syncParams.presSyncResource = &m_destSurface.OsResource; |
| syncParams.bReadOnly = false; |
| syncParams.bDisableDecodeSyncLock = m_disableDecodeSyncLock; |
| syncParams.bDisableLockForTranscode = m_disableLockForTranscode; |
| |
| if (!CodecHal_PictureIsField(m_vc1PicParams->CurrPic) || |
| m_vc1PicParams->picture_fields.is_first_field) |
| { |
| 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); |
| } |
| |
| MHW_MI_FLUSH_DW_PARAMS flushDwParams; |
| MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams)); |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams)); |
| |
| // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag |
| if (m_osInterface->bTagResourceSync && |
| !(CodecHal_PictureIsField(m_vc1PicParams->CurrPic) && m_vc1PicParams->picture_fields.is_first_field)) |
| { |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(&cmdBuffer, &syncParams)); |
| } |
| } |
| |
| submit: |
| if (m_statusQueryReportingEnabled) |
| { |
| CodechalDecodeStatusReport decodeStatusReport; |
| |
| decodeStatusReport.m_statusReportNumber = m_statusReportFeedbackNumber; |
| decodeStatusReport.m_currDecodedPic = m_vc1PicParams->CurrPic; |
| if (m_olpNeeded) |
| { |
| CODECHAL_DEBUG_TOOL( |
| decodeStatusReport.m_currDeblockedPic.FrameIdx = (uint8_t)m_vc1PicParams->DeblockedPicIdx; |
| decodeStatusReport.m_currDeblockedPic.PicFlags = PICTURE_FRAME;) |
| decodeStatusReport.m_deblockedPicResOlp = m_deblockSurface.OsResource; |
| } |
| else |
| { |
| decodeStatusReport.m_currDeblockedPic = m_vc1PicParams->CurrPic; |
| } |
| decodeStatusReport.m_codecStatus = CODECHAL_STATUS_UNAVAILABLE; |
| decodeStatusReport.m_currDecodedPicRes = m_vc1RefList[m_vc1PicParams->CurrPic.FrameIdx]->resRefPic; |
| |
| CODECHAL_DEBUG_TOOL( |
| decodeStatusReport.m_secondField = |
| (m_vc1PicParams->picture_fields.is_first_field == 1) ? false : true; |
| decodeStatusReport.m_olpNeeded = m_olpNeeded; |
| decodeStatusReport.m_frameType = m_perfType;) |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(EndStatusReport(decodeStatusReport, &cmdBuffer)); |
| } |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr)); |
| |
| m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); |
| |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer( |
| &cmdBuffer, |
| CODECHAL_NUM_MEDIA_STATES, |
| "_DEC")); |
| |
| //CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHal_DbgReplaceAllCommands( |
| // m_debugInterface, |
| // &cmdBuffer)); |
| ) |
| |
| if ( MOS_VE_SUPPORTED(m_osInterface)) |
| { |
| CodecHalDecodeSinglePipeVE_PopulateHintParams(m_veState, &cmdBuffer, false); |
| } |
| |
| if (m_huCCopyInUse) |
| { |
| syncParams = g_cInitSyncParams; |
| syncParams.GpuContext = m_videoContextForWa; |
| syncParams.presSyncResource = &m_resSyncObjectWaContextInUse; |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams)); |
| |
| syncParams = g_cInitSyncParams; |
| syncParams.GpuContext = m_videoContext; |
| syncParams.presSyncResource = &m_resSyncObjectWaContextInUse; |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams)); |
| |
| m_huCCopyInUse = false; |
| } |
| |
| if (m_osInterface->osCpInterface->IsHMEnabled()) |
| { |
| HalOcaInterface::DumpCpParam(cmdBuffer, *m_osInterface->pOsContext, m_osInterface->osCpInterface->GetOcaDumper()); |
| } |
| |
| HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface->pOsContext); |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_videoContextUsesNullHw)); |
| |
| CODECHAL_DEBUG_TOOL( |
| m_mmc->UpdateUserFeatureKey(&m_destSurface);) |
| |
| if (m_unequalFieldWaInUse && |
| CodecHal_PictureIsField(m_vc1PicParams->CurrPic) && |
| !m_vc1PicParams->picture_fields.is_first_field) |
| { |
| CODECHAL_DECODE_CHK_NULL_RETURN(m_vc1RefList); |
| |
| uint32_t destFrameIdx = m_vc1PicParams->CurrPic.FrameIdx; |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(FormatUnequalFieldPicture( |
| m_unequalFieldSurface[m_vc1RefList[destFrameIdx]->dwUnequalFieldSurfaceIdx], |
| m_destSurface, |
| true, |
| m_videoContextUsesNullHw ? true : false)); |
| } |
| |
| if (m_olpNeeded) |
| { |
| CODECHAL_DECODE_CHK_STATUS_RETURN(PerformVc1Olp()); |
| } |
| else |
| { |
| if (m_statusQueryReportingEnabled) |
| { |
| CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(m_videoContextUsesNullHw)); |
| } |
| } |
| |
| // Needs to be re-set for Linux buffer re-use scenarios |
| m_vc1RefList[m_vc1PicParams->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_vc1PicParams->CurrPic) && |
| m_vc1PicParams->picture_fields.is_first_field)) |
| { |
| MOS_SYNC_PARAMS syncParams; |
| syncParams = g_cInitSyncParams; |
| syncParams.GpuContext = m_videoContext; |
| syncParams.presSyncResource = &m_destSurface.OsResource; |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams)); |
| |
| if (m_olpNeeded) |
| { |
| syncParams = g_cInitSyncParams; |
| syncParams.GpuContext = m_renderContext; |
| syncParams.presSyncResource = &m_deblockSurface.OsResource; |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams)); |
| } |
| } |
| |
| m_olpNeeded = false; |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalDecodeVc1G12::DecodePrimitiveLevelIT() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_DECODE_FUNCTION_ENTER; |
| |
| MOS_SYNC_PARAMS syncParams; |
| |
| PCODEC_VC1_MB_PARAMS mb = m_vc1MbParams; |
| |
| MHW_VDBOX_VC1_MB_STATE vc1MbState; |
| MOS_ZeroMemory(&vc1MbState, sizeof(vc1MbState)); |
| |
| // static VC1 MB parameters |
| vc1MbState.presDataBuffer = &m_resDataBuffer; |
| vc1MbState.pVc1PicParams = m_vc1PicParams; |
| vc1MbState.pWaTable = m_waTable; |
| vc1MbState.pDeblockDataBuffer = m_deblockDataBuffer; |
| vc1MbState.dwDataSize = m_dataSize; |
| vc1MbState.wPicWidthInMb = m_picWidthInMb; |
| vc1MbState.wPicHeightInMb = m_picHeightInMb; |
| vc1MbState.PicFlags = m_vc1PicParams->CurrPic.PicFlags; |
| vc1MbState.bFieldPolarity = m_fieldPolarity; |
| |
| uint16_t frameFieldHeightInMb; |
| CodecHal_GetFrameFieldHeightInMb( |
| m_vc1PicParams->CurrPic, |
| m_picHeightInMb, |
| frameFieldHeightInMb); |
| |
| CODECHAL_DECODE_CHK_NULL_RETURN(m_osInterface); |
| |
| MOS_COMMAND_BUFFER cmdBuffer; |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); |
| |
| if (m_incompletePicture) |
| { |
| MHW_MI_FORCE_WAKEUP_PARAMS forceWakeupParams; |
| MOS_ZeroMemory(&forceWakeupParams, sizeof(MHW_MI_FORCE_WAKEUP_PARAMS)); |
| forceWakeupParams.bMFXPowerWellControl = true; |
| forceWakeupParams.bMFXPowerWellControlMask = true; |
| forceWakeupParams.bHEVCPowerWellControl = false; |
| forceWakeupParams.bHEVCPowerWellControlMask = true; |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiForceWakeupCmd( |
| &cmdBuffer, |
| &forceWakeupParams)); |
| } |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(&cmdBuffer, &m_itObjectBatchBuffer)); |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_LockBb(m_osInterface, &m_itObjectBatchBuffer)); |
| |
| PMHW_BATCH_BUFFER batchBuffer = &m_itObjectBatchBuffer; |
| |
| uint32_t mbAddress = 0; |
| uint32_t mbCount; |
| for (mbCount = 0; mbCount < m_numMacroblocks; mbCount++) |
| { |
| vc1MbState.pMb = mb + mbCount; |
| |
| // Skipped MBs before current MB |
| uint16_t skippedMBs = (mbCount) ? |
| (mb[mbCount].mb_address - mb[mbCount - 1].mb_address - 1) : |
| (mb[mbCount].mb_address); |
| |
| while (skippedMBs--) |
| { |
| vc1MbState.bMbHorizOrigin = (uint8_t)(mbAddress % m_picWidthInMb); |
| vc1MbState.bMbVertOrigin = (uint8_t)(mbAddress / m_picWidthInMb); |
| vc1MbState.bSkipped = true; |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdVc1ItObjectCmd(batchBuffer, &vc1MbState)); |
| |
| mbAddress++; |
| } |
| |
| // Current MB |
| if (mbCount + 1 == m_numMacroblocks) |
| { |
| vc1MbState.dwLength = m_dataSize - mb[mbCount].data_offset; |
| } |
| else |
| { |
| vc1MbState.dwLength = mb[mbCount + 1].data_offset - mb[mbCount].data_offset; |
| } |
| |
| vc1MbState.bMbHorizOrigin = mb[mbCount].mb_address % m_picWidthInMb; |
| vc1MbState.bMbVertOrigin = mb[mbCount].mb_address / m_picWidthInMb; |
| vc1MbState.dwOffset = (vc1MbState.dwLength) ? mb[mbCount].data_offset : 0; |
| vc1MbState.bSkipped = false; |
| |
| if (m_vc1PicParams->entrypoint_fields.loopfilter) |
| { |
| eStatus = MOS_SecureMemcpy(vc1MbState.DeblockData, |
| CODEC_NUM_BLOCK_PER_MB, |
| m_deblockDataBuffer + CODEC_NUM_BLOCK_PER_MB * mb[mbCount].mb_address, |
| CODEC_NUM_BLOCK_PER_MB); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| CODECHAL_DECODE_ASSERTMESSAGE("Failed to copy memory."); |
| m_olpNeeded = false; |
| return eStatus; |
| } |
| } |
| |
| if (!mb[mbCount].mb_type.intra_mb) |
| { |
| if (mb[mbCount].mb_type.motion_forward || mb[mbCount].mb_type.motion_backward) |
| { |
| PackMotionVectors( |
| &vc1MbState, |
| (short *)mb[mbCount].motion_vector, |
| (short *)vc1MbState.PackedLumaMvs, |
| (short *)&vc1MbState.PackedChromaMv); |
| } |
| else |
| { |
| mb[mbCount].mb_type.motion_forward = 1; |
| MOS_ZeroMemory(vc1MbState.PackedLumaMvs, sizeof(vc1MbState.PackedLumaMvs)); // MV's of zero |
| vc1MbState.bMotionSwitch = 0; |
| } |
| } |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdVc1ItObjectCmd(batchBuffer, &vc1MbState)); |
| |
| mbAddress = mb[mbCount].mb_address; |
| } |
| |
| m_fieldPolarity = vc1MbState.bFieldPolarity; |
| |
| // skipped MBs at the end |
| uint16_t skippedMBs = m_picWidthInMb * frameFieldHeightInMb - mb[mbCount - 1].mb_address - 1; |
| |
| while (skippedMBs--) |
| { |
| vc1MbState.bSkipped = true; |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdVc1ItObjectCmd(batchBuffer, &vc1MbState)); |
| } |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(nullptr, &m_itObjectBatchBuffer)); |
| |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->Dump2ndLvlBatch( |
| batchBuffer, |
| CODECHAL_NUM_MEDIA_STATES, |
| "_DEC")); |
| ) |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_UnlockBb(m_osInterface, &m_itObjectBatchBuffer, true)); |
| |
| // Check if destination surface needs to be synchronized |
| if (m_unequalFieldWaInUse && |
| CodecHal_PictureIsField(m_vc1PicParams->CurrPic)) |
| { |
| if (!m_vc1PicParams->picture_fields.is_first_field) |
| { |
| MHW_MI_FLUSH_DW_PARAMS flushDwParams; |
| MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams)); |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams)); |
| } |
| } |
| else |
| { |
| syncParams = g_cInitSyncParams; |
| syncParams.GpuContext = m_videoContext; |
| syncParams.presSyncResource = &m_destSurface.OsResource; |
| syncParams.bReadOnly = false; |
| syncParams.bDisableDecodeSyncLock = m_disableDecodeSyncLock; |
| syncParams.bDisableLockForTranscode = m_disableLockForTranscode; |
| |
| if (!CodecHal_PictureIsField(m_vc1PicParams->CurrPic) || |
| m_vc1PicParams->picture_fields.is_first_field) |
| { |
| 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); |
| } |
| |
| MHW_MI_FLUSH_DW_PARAMS flushDwParams; |
| MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams)); |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams)); |
| |
| // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag |
| if (m_osInterface->bTagResourceSync && |
| !(CodecHal_PictureIsField(m_vc1PicParams->CurrPic) && m_vc1PicParams->picture_fields.is_first_field)) |
| { |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(&cmdBuffer, &syncParams)); |
| } |
| } |
| |
| if (m_statusQueryReportingEnabled) |
| { |
| CodechalDecodeStatusReport decodeStatusReport; |
| |
| decodeStatusReport.m_statusReportNumber = m_statusReportFeedbackNumber; |
| decodeStatusReport.m_currDecodedPic = m_vc1PicParams->CurrPic; |
| if (m_olpNeeded) |
| { |
| CODECHAL_DEBUG_TOOL( |
| decodeStatusReport.m_currDeblockedPic.FrameIdx = (uint8_t)m_vc1PicParams->DeblockedPicIdx; |
| decodeStatusReport.m_currDeblockedPic.PicFlags = PICTURE_FRAME;) |
| decodeStatusReport.m_deblockedPicResOlp = m_deblockSurface.OsResource; |
| } |
| else |
| { |
| decodeStatusReport.m_currDeblockedPic = m_vc1PicParams->CurrPic; |
| } |
| decodeStatusReport.m_codecStatus = CODECHAL_STATUS_UNAVAILABLE; |
| decodeStatusReport.m_currDecodedPicRes = m_vc1RefList[m_vc1PicParams->CurrPic.FrameIdx]->resRefPic; |
| |
| CODECHAL_DEBUG_TOOL( |
| decodeStatusReport.m_secondField = |
| (m_vc1PicParams->picture_fields.is_first_field == 1) ? false : true; |
| decodeStatusReport.m_olpNeeded = m_olpNeeded; |
| decodeStatusReport.m_frameType = m_perfType;) |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(EndStatusReport(decodeStatusReport, &cmdBuffer)); |
| } |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr)); |
| |
| m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); |
| |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer( |
| &cmdBuffer, |
| CODECHAL_NUM_MEDIA_STATES, |
| "_DEC")); |
| |
| //CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHal_DbgReplaceAllCommands( |
| // m_debugInterface, |
| // &cmdBuffer)); |
| ) |
| |
| if ( MOS_VE_SUPPORTED(m_osInterface)) |
| { |
| CodecHalDecodeSinglePipeVE_PopulateHintParams(m_veState, &cmdBuffer, false); |
| } |
| |
| if (m_huCCopyInUse) |
| { |
| syncParams = g_cInitSyncParams; |
| syncParams.GpuContext = m_videoContextForWa; |
| syncParams.presSyncResource = &m_resSyncObjectWaContextInUse; |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams)); |
| |
| syncParams = g_cInitSyncParams; |
| syncParams.GpuContext = m_videoContext; |
| syncParams.presSyncResource = &m_resSyncObjectWaContextInUse; |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams)); |
| |
| m_huCCopyInUse = false; |
| } |
| |
| if (m_osInterface->osCpInterface->IsHMEnabled()) |
| { |
| HalOcaInterface::DumpCpParam(cmdBuffer, *m_osInterface->pOsContext, m_osInterface->osCpInterface->GetOcaDumper()); |
| } |
| |
| HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface->pOsContext); |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_videoContextUsesNullHw)); |
| |
| CODECHAL_DEBUG_TOOL( |
| m_mmc->UpdateUserFeatureKey(&m_destSurface);) |
| |
| if (m_unequalFieldWaInUse && |
| CodecHal_PictureIsField(m_vc1PicParams->CurrPic) && |
| !m_vc1PicParams->picture_fields.is_first_field) |
| { |
| CODECHAL_DECODE_CHK_NULL_RETURN(m_vc1RefList); |
| |
| uint32_t destFrameIdx = m_vc1PicParams->CurrPic.FrameIdx; |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(FormatUnequalFieldPicture( |
| m_unequalFieldSurface[m_vc1RefList[destFrameIdx]->dwUnequalFieldSurfaceIdx], |
| m_destSurface, |
| true, |
| m_videoContextUsesNullHw ? true : false)); |
| } |
| |
| if (m_olpNeeded) |
| { |
| CODECHAL_DECODE_CHK_STATUS_RETURN(PerformVc1Olp()); |
| } |
| else |
| { |
| if (m_statusQueryReportingEnabled) |
| { |
| CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(m_videoContextUsesNullHw)); |
| } |
| } |
| |
| // Needs to be re-set for Linux buffer re-use scenarios |
| m_vc1RefList[m_vc1PicParams->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_vc1PicParams->CurrPic) && |
| m_vc1PicParams->picture_fields.is_first_field)) |
| { |
| MOS_SYNC_PARAMS syncParams; |
| syncParams = g_cInitSyncParams; |
| syncParams.GpuContext = m_videoContext; |
| syncParams.presSyncResource = &m_destSurface.OsResource; |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams)); |
| |
| if (m_olpNeeded) |
| { |
| syncParams = g_cInitSyncParams; |
| syncParams.GpuContext = m_renderContext; |
| syncParams.presSyncResource = &m_deblockSurface.OsResource; |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams)); |
| } |
| } |
| |
| m_olpNeeded = false; |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalDecodeVc1G12::HandleSkipFrame() |
| { |
| MOS_COMMAND_BUFFER cmdBuffer; |
| MHW_MI_FLUSH_DW_PARAMS flushDwParams; |
| MHW_GENERIC_PROLOG_PARAMS genericPrologParams; |
| MOS_SURFACE srcSurface; |
| uint8_t fwdRefIdx; |
| uint32_t surfaceSize; |
| MOS_SYNC_PARAMS syncParams; |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_DECODE_FUNCTION_ENTER; |
| |
| fwdRefIdx = (uint8_t)m_vc1PicParams->ForwardRefIdx; |
| |
| MOS_ZeroMemory(&srcSurface, sizeof(MOS_SURFACE)); |
| srcSurface.Format = Format_NV12; |
| srcSurface.OsResource = m_vc1RefList[fwdRefIdx]->resRefPic; |
| CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, &srcSurface)); |
| |
| CODECHAL_DECODE_CHK_NULL_RETURN(srcSurface.OsResource.pGmmResInfo); |
| surfaceSize = ((srcSurface.OsResource.pGmmResInfo->GetArraySize()) > 1) ? |
| ((uint32_t)(srcSurface.OsResource.pGmmResInfo->GetQPitchPlanar(GMM_PLANE_Y) * |
| srcSurface.OsResource.pGmmResInfo->GetRenderPitch())) : |
| (uint32_t)(srcSurface.OsResource.pGmmResInfo->GetSizeMainSurface()); |
| |
| if (m_hwInterface->m_noHuC) |
| { |
| CodechalDataCopyParams dataCopyParams; |
| MOS_ZeroMemory(&dataCopyParams, sizeof(CodechalDataCopyParams)); |
| dataCopyParams.srcResource = &srcSurface.OsResource; |
| dataCopyParams.srcSize = surfaceSize; |
| dataCopyParams.srcOffset = srcSurface.dwOffset; |
| dataCopyParams.dstResource = &m_destSurface.OsResource; |
| dataCopyParams.dstSize = surfaceSize; |
| dataCopyParams.dstOffset = m_destSurface.dwOffset; |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->CopyDataSourceWithDrv(&dataCopyParams)); |
| } |
| else |
| { |
| m_huCCopyInUse = true; |
| |
| syncParams = g_cInitSyncParams; |
| syncParams.GpuContext = m_videoContext; |
| syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse; |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams)); |
| |
| syncParams = g_cInitSyncParams; |
| syncParams.GpuContext = m_videoContextForWa; |
| syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse; |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams)); |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(m_osInterface, m_videoContextForWa)); |
| m_osInterface->pfnResetOsStates(m_osInterface); |
| |
| 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 |
| &srcSurface.OsResource, // presSrc |
| &m_destSurface.OsResource, // presDst |
| surfaceSize, // u32CopyLength |
| srcSurface.dwOffset, // u32CopyInputOffset |
| m_destSurface.dwOffset)); // u32CopyOutputOffset |
| #ifdef _MMC_SUPPORTED |
| auto mmc = static_cast<CodechalMmcDecodeVc1G12*>(m_mmc); |
| CODECHAL_DECODE_CHK_STATUS_RETURN(mmc->CopyAuxSurfForSkip(&cmdBuffer, &srcSurface.OsResource, &m_destSurface.OsResource)); |
| #endif |
| syncParams = g_cInitSyncParams; |
| syncParams.GpuContext = m_videoContextForWa; |
| syncParams.presSyncResource = &m_destSurface.OsResource; |
| syncParams.bReadOnly = false; |
| syncParams.bDisableDecodeSyncLock = m_disableDecodeSyncLock; |
| syncParams.bDisableLockForTranscode = m_disableLockForTranscode; |
| |
| 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( |
| &cmdBuffer, |
| &syncParams)); |
| } |
| |
| 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); |
| |
| if ( MOS_VE_SUPPORTED(m_osInterface)) |
| { |
| CodecHalDecodeSinglePipeVE_PopulateHintParams(m_veState, &cmdBuffer, false); |
| } |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_videoContextUsesNullHw)); |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(m_osInterface, m_videoContext)); |
| } |
| |
| return (MOS_STATUS)eStatus; |
| } |
| |
| MOS_STATUS CodechalDecodeVc1G12::PerformVc1Olp() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_DECODE_FUNCTION_ENTER; |
| |
| MhwRenderInterface *renderEngineInterface = m_hwInterface->GetRenderInterface(); |
| PMHW_KERNEL_STATE kernelState = &m_olpKernelState; |
| PMHW_STATE_HEAP_INTERFACE stateHeapInterface = renderEngineInterface->m_stateHeapInterface; |
| |
| CODECHAL_DECODE_CHK_NULL_RETURN(stateHeapInterface); |
| |
| MOS_SYNC_PARAMS syncParams; |
| syncParams = g_cInitSyncParams; |
| syncParams.GpuContext = m_videoContext; |
| syncParams.presSyncResource = &m_resSyncObject; |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams)); |
| |
| syncParams = g_cInitSyncParams; |
| syncParams.GpuContext = m_renderContext; |
| syncParams.presSyncResource = &m_resSyncObject; |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams)); |
| |
| // Initialize DSH kernel region |
| m_osInterface->pfnSetGpuContext(m_osInterface, m_renderContext); |
| m_osInterface->pfnResetOsStates(m_osInterface); |
| |
| m_osInterface->pfnSetPerfTag( |
| m_osInterface, |
| (uint16_t)(((m_mode << 4) & 0xF0) | OLP_TYPE)); |
| m_osInterface->pfnResetPerfBufferID(m_osInterface); |
| |
| CodecHalGetResourceInfo(m_osInterface, &m_deblockSurface); // DstSurface |
| |
| #ifdef _MMC_SUPPORTED |
| if (m_mmc && !m_mmc->IsMmcEnabled()) |
| { |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->DisableSurfaceMmcState(&m_deblockSurface)); |
| } |
| #endif |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnRequestSshSpaceForCmdBuf( |
| stateHeapInterface, |
| kernelState->KernelParams.iBTCount)); |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace( |
| stateHeapInterface, |
| kernelState, |
| false, |
| m_olpDshSize, |
| false, |
| m_decodeStatusBuf.m_swStoreData)); |
| |
| MHW_INTERFACE_DESCRIPTOR_PARAMS idParams; |
| MOS_ZeroMemory(&idParams, sizeof(idParams)); |
| idParams.pKernelState = kernelState; |
| CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnSetInterfaceDescriptor( |
| stateHeapInterface, |
| 1, |
| &idParams)); |
| CODECHAL_DECODE_CHK_STATUS_RETURN(SetCurbeOlp()); |
| |
| // Send HW commands (including SSH) |
| MOS_COMMAND_BUFFER cmdBuffer; |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); |
| |
| MHW_PIPE_CONTROL_PARAMS pipeControlParams; |
| MOS_ZeroMemory(&pipeControlParams, sizeof(pipeControlParams)); |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->GetDefaultSSEuSetting(CODECHAL_MEDIA_STATE_OLP, false, false, false)); |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking( |
| &cmdBuffer, true)); |
| |
| if (renderEngineInterface->GetL3CacheConfig()->bL3CachingEnabled) |
| { |
| CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->SetL3Cache(&cmdBuffer)); |
| } |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->EnablePreemption(&cmdBuffer)); |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddPipelineSelectCmd(&cmdBuffer, false)); |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnSetBindingTable( |
| stateHeapInterface, |
| kernelState)); |
| |
| // common function for codec needed when we make change for AVC |
| MHW_RCS_SURFACE_PARAMS surfaceParamsSrc; |
| MOS_ZeroMemory(&surfaceParamsSrc, sizeof(surfaceParamsSrc)); |
| surfaceParamsSrc.dwNumPlanes = 2; // Y, UV |
| surfaceParamsSrc.psSurface = &m_destSurface; |
| surfaceParamsSrc.psSurface->dwDepth = 1; // depth needs to be 0 for codec 2D surface |
| // Y Plane |
| surfaceParamsSrc.dwBindingTableOffset[MHW_Y_PLANE] = CODECHAL_DECODE_VC1_OLP_SRC_Y; |
| surfaceParamsSrc.ForceSurfaceFormat[MHW_Y_PLANE] = MHW_GFX3DSTATE_SURFACEFORMAT_R8_UNORM; |
| // UV Plane |
| surfaceParamsSrc.dwBindingTableOffset[MHW_U_PLANE] = CODECHAL_DECODE_VC1_OLP_SRC_UV; |
| surfaceParamsSrc.ForceSurfaceFormat[MHW_U_PLANE] = MHW_GFX3DSTATE_SURFACEFORMAT_R16_UINT; |
| surfaceParamsSrc.dwBaseAddrOffset[MHW_U_PLANE] = |
| m_destSurface.dwPitch * |
| MOS_ALIGN_FLOOR(m_destSurface.UPlaneOffset.iYOffset, MOS_YTILE_H_ALIGNMENT); |
| surfaceParamsSrc.dwHeightToUse[MHW_U_PLANE] = surfaceParamsSrc.psSurface->dwHeight / 2; |
| surfaceParamsSrc.dwYOffset[MHW_U_PLANE] = |
| (m_destSurface.UPlaneOffset.iYOffset % MOS_YTILE_H_ALIGNMENT); |
| |
| #ifdef _MMC_SUPPORTED |
| if (m_mmc) |
| { |
| CODECHAL_SURFACE_CODEC_PARAMS srcSurfaceParam = {}; |
| srcSurfaceParam.psSurface = &m_destSurface; |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetSurfaceParams(&srcSurfaceParam)); |
| } |
| #endif |
| |
| MHW_RCS_SURFACE_PARAMS surfaceParamsDst; |
| MOS_ZeroMemory(&surfaceParamsDst, sizeof(surfaceParamsDst)); |
| surfaceParamsDst = surfaceParamsSrc; |
| surfaceParamsDst.bIsWritable = true; |
| surfaceParamsDst.psSurface = &m_deblockSurface; |
| surfaceParamsDst.psSurface->dwDepth = 1; // depth needs to be 0 for codec 2D surface |
| surfaceParamsDst.dwBindingTableOffset[MHW_Y_PLANE] = CODECHAL_DECODE_VC1_OLP_DST_Y; |
| surfaceParamsDst.dwBindingTableOffset[MHW_U_PLANE] = CODECHAL_DECODE_VC1_OLP_DST_UV; |
| |
| #ifdef _MMC_SUPPORTED |
| if (m_mmc) |
| { |
| CODECHAL_SURFACE_CODEC_PARAMS dstSurfaceParam = {}; |
| dstSurfaceParam.psSurface = &m_deblockSurface; |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetSurfaceParams(&dstSurfaceParam)); |
| } |
| #endif |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnSetSurfaceState( |
| stateHeapInterface, |
| kernelState, |
| &cmdBuffer, |
| 1, |
| &surfaceParamsSrc)); |
| CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnSetSurfaceState( |
| stateHeapInterface, |
| kernelState, |
| &cmdBuffer, |
| 1, |
| &surfaceParamsDst)); |
| |
| MHW_STATE_BASE_ADDR_PARAMS stateBaseAddrParams; |
| MOS_ZeroMemory(&stateBaseAddrParams, sizeof(stateBaseAddrParams)); |
| MOS_RESOURCE *dsh = nullptr, *ish = nullptr; |
| CODECHAL_DECODE_CHK_NULL_RETURN(dsh = kernelState->m_dshRegion.GetResource()); |
| CODECHAL_DECODE_CHK_NULL_RETURN(ish = kernelState->m_ishRegion.GetResource()); |
| stateBaseAddrParams.presDynamicState = dsh; |
| stateBaseAddrParams.dwDynamicStateSize = kernelState->m_dshRegion.GetHeapSize(); |
| stateBaseAddrParams.presInstructionBuffer = ish; |
| stateBaseAddrParams.dwInstructionBufferSize = kernelState->m_ishRegion.GetHeapSize(); |
| CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddStateBaseAddrCmd(&cmdBuffer, &stateBaseAddrParams)); |
| |
| MHW_VFE_PARAMS_G12 vfeParams= {}; |
| vfeParams.pKernelState = kernelState; |
| CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddMediaVfeCmd(&cmdBuffer, &vfeParams)); |
| |
| MHW_CURBE_LOAD_PARAMS curbeLoadParams; |
| MOS_ZeroMemory(&curbeLoadParams, sizeof(curbeLoadParams)); |
| curbeLoadParams.pKernelState = kernelState; |
| CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddMediaCurbeLoadCmd(&cmdBuffer, &curbeLoadParams)); |
| |
| MHW_ID_LOAD_PARAMS idLoadParams; |
| MOS_ZeroMemory(&idLoadParams, sizeof(idLoadParams)); |
| idLoadParams.pKernelState = kernelState; |
| idLoadParams.dwNumKernelsLoaded = 1; |
| CODECHAL_DECODE_CHK_STATUS_RETURN(renderEngineInterface->AddMediaIDLoadCmd(&cmdBuffer, &idLoadParams)); |
| |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( |
| CODECHAL_MEDIA_STATE_OLP, |
| MHW_DSH_TYPE, |
| kernelState)); |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( |
| CODECHAL_MEDIA_STATE_OLP, |
| MHW_SSH_TYPE, |
| kernelState)); |
| ) |
| |
| CODECHAL_DECODE_VC1_OLP_PARAMS vc1OlpParams; |
| vc1OlpParams.pCmdBuffer = &cmdBuffer; |
| vc1OlpParams.pPipeControlParams = &pipeControlParams; |
| vc1OlpParams.pStateBaseAddrParams = &stateBaseAddrParams; |
| vc1OlpParams.pVfeParams = &vfeParams; |
| vc1OlpParams.pCurbeLoadParams = &curbeLoadParams; |
| vc1OlpParams.pIdLoadParams = &idLoadParams; |
| CODECHAL_DECODE_CHK_STATUS_RETURN(AddVc1OlpCmd(&vc1OlpParams)); |
| |
| // Check if destination surface needs to be synchronized, before command buffer submission |
| syncParams = g_cInitSyncParams; |
| syncParams.GpuContext = m_renderContext; |
| syncParams.presSyncResource = &m_deblockSurface.OsResource; |
| syncParams.bReadOnly = false; |
| syncParams.bDisableDecodeSyncLock = m_disableDecodeSyncLock; |
| syncParams.bDisableLockForTranscode = m_disableLockForTranscode; |
| |
| 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 GPU Sync tag for on demand synchronization |
| if (m_osInterface->bTagResourceSync) |
| { |
| pipeControlParams.dwFlushMode = MHW_FLUSH_WRITE_CACHE; |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddPipeControl(&cmdBuffer, nullptr, &pipeControlParams)); |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(&cmdBuffer, &syncParams)); |
| } |
| CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnSubmitBlocks( |
| stateHeapInterface, |
| kernelState)); |
| CODECHAL_DECODE_CHK_STATUS_RETURN(stateHeapInterface->pfnUpdateGlobalCmdBufId( |
| stateHeapInterface)); |
| |
| // Add PipeControl to invalidate ISP and MediaState to avoid PageFault issue |
| // This code is temporal and it will be moved to batch buffer end in short |
| if (GFX_IS_GEN_9_OR_LATER(m_hwInterface->GetPlatform())) |
| { |
| MHW_PIPE_CONTROL_PARAMS pipeControlParams; |
| |
| MOS_ZeroMemory(&pipeControlParams, sizeof(pipeControlParams)); |
| pipeControlParams.dwFlushMode = MHW_FLUSH_WRITE_CACHE; |
| pipeControlParams.bGenericMediaStateClear = true; |
| pipeControlParams.bIndirectStatePointersDisable = true; |
| pipeControlParams.bDisableCSStall = false; |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddPipeControl(&cmdBuffer, nullptr, &pipeControlParams)); |
| |
| } |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr)); |
| |
| // To clear the SSEU values in the hw interface struct, so next kernel can be programmed correctly |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, false, true)); |
| |
| m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); |
| |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer( |
| &cmdBuffer, |
| CODECHAL_MEDIA_STATE_OLP, |
| "_DEC")); |
| ) |
| |
| if ( MOS_VE_SUPPORTED(m_osInterface)) |
| { |
| CodecHalDecodeSinglePipeVE_PopulateHintParams(m_veState, &cmdBuffer, false); |
| } |
| |
| CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw)); |
| |
| if (m_statusQueryReportingEnabled) |
| { |
| CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(m_renderContextUsesNullHw)); |
| } |
| |
| m_osInterface->pfnSetGpuContext(m_osInterface, m_videoContext); |
| |
| return eStatus; |
| } |
| |
| CodechalDecodeVc1G12::CodechalDecodeVc1G12( |
| CodechalHwInterface *hwInterface, |
| CodechalDebugInterface* debugInterface, |
| PCODECHAL_STANDARD_INFO standardInfo) : |
| CodechalDecodeVc1(hwInterface, debugInterface, standardInfo) |
| { |
| CODECHAL_DECODE_FUNCTION_ENTER; |
| |
| CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(hwInterface); |
| CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(m_osInterface); |
| |
| Mos_CheckVirtualEngineSupported(m_osInterface, true, true); |
| |
| m_olpCurbeStaticDataLength = CODECHAL_DECODE_VC1_CURBE_SIZE_OLP; |
| |
| uint32_t kuid = 0; |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| #if defined(ENABLE_KERNELS) && !defined(_FULL_OPEN_SOURCE) |
| eStatus = CodecHalGetKernelBinaryAndSize( |
| (uint8_t *)IGCODECKRN_G12, |
| IDR_CODEC_AllVC1_NV12, |
| &m_olpKernelBase, |
| &m_olpKernelSize); |
| #endif |
| |
| CODECHAL_DECODE_ASSERT(eStatus == MOS_STATUS_SUCCESS); |
| |
| hwInterface->GetStateHeapSettings()->dwNumSyncTags = CODECHAL_DECODE_VC1_NUM_SYNC_TAGS; |
| hwInterface->GetStateHeapSettings()->dwIshSize = |
| MOS_ALIGN_CEIL(m_olpKernelSize, (1 << MHW_KERNEL_OFFSET_SHIFT)); |
| hwInterface->GetStateHeapSettings()->dwDshSize = CODECHAL_DECODE_VC1_INITIAL_DSH_SIZE; |
| } |
| |
| CodechalDecodeVc1G12::~CodechalDecodeVc1G12() |
| { |
| CODECHAL_DECODE_FUNCTION_ENTER; |
| |
| if (m_veState != nullptr) |
| { |
| MOS_FreeMemAndSetNull(m_veState); |
| m_veState = nullptr; |
| } |
| } |