| /* |
| * Copyright (c) 2020-2021, 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 meida_vdbox_sfc_render.cpp |
| //! \brief Common interface for sfc |
| //! \details Common interface for sfc |
| //! |
| #include "vp_feature_manager.h" |
| #include "media_sfc_interface.h" |
| #include "media_vdbox_sfc_render.h" |
| #include "mos_os.h" |
| #include "vp_render_sfc_base.h" |
| #include "vp_render_ief.h" |
| #include "vp_mem_compression.h" |
| |
| using namespace vp; |
| |
| MediaVdboxSfcRender::MediaVdboxSfcRender() |
| { |
| } |
| |
| MediaVdboxSfcRender::~MediaVdboxSfcRender() |
| { |
| Destroy(); |
| } |
| |
| void MediaVdboxSfcRender::Destroy() |
| { |
| MOS_Delete(m_sfcRender); |
| MOS_Delete(m_cscFilter); |
| MOS_Delete(m_scalingFilter); |
| MOS_Delete(m_rotMirFilter); |
| MOS_Delete(m_allocator); |
| if (m_isMmcAllocated) |
| { |
| MOS_Delete(m_mmc); |
| } |
| } |
| |
| //! |
| //! \brief MediaSfcInterface initialize |
| //! \details Initialize the BltState, create BLT context. |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS MediaVdboxSfcRender::Initialize(VP_MHWINTERFACE &vpMhwinterface, MediaMemComp *mmc) |
| { |
| VP_PUBLIC_CHK_NULL_RETURN(vpMhwinterface.m_vpPlatformInterface); |
| VP_PUBLIC_CHK_NULL_RETURN(vpMhwinterface.m_osInterface); |
| |
| m_vpMhwInterface = vpMhwinterface; |
| m_osInterface = m_vpMhwInterface.m_osInterface; |
| |
| if (mmc) |
| { |
| m_mmc = mmc; |
| m_isMmcAllocated = false; |
| } |
| else |
| { |
| m_mmc = MOS_New(VPMediaMemComp, m_osInterface, m_vpMhwInterface); |
| VP_PUBLIC_CHK_NULL_RETURN(m_mmc); |
| m_isMmcAllocated = true; |
| } |
| |
| m_allocator = MOS_New(VpAllocator, m_osInterface, m_mmc); |
| VP_PUBLIC_CHK_NULL_RETURN(m_allocator); |
| m_cscFilter = MOS_New(VpCscFilter, &m_vpMhwInterface); |
| VP_PUBLIC_CHK_NULL_RETURN(m_cscFilter); |
| m_scalingFilter = MOS_New(VpScalingFilter, &m_vpMhwInterface); |
| VP_PUBLIC_CHK_NULL_RETURN(m_scalingFilter); |
| m_rotMirFilter = MOS_New(VpRotMirFilter, &m_vpMhwInterface); |
| VP_PUBLIC_CHK_NULL_RETURN(m_rotMirFilter); |
| VP_PUBLIC_CHK_STATUS_RETURN(m_vpMhwInterface.m_vpPlatformInterface->CreateSfcRender(m_sfcRender, m_vpMhwInterface, m_allocator)); |
| VP_PUBLIC_CHK_NULL_RETURN(m_sfcRender); |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS MediaVdboxSfcRender::SetCSCParams(VDBOX_SFC_PARAMS &sfcParam, VP_EXECUTE_CAPS &vpExecuteCaps) |
| { |
| VP_PUBLIC_CHK_NULL_RETURN(m_sfcRender); |
| VP_PUBLIC_CHK_NULL_RETURN(m_cscFilter); |
| FeatureParamCsc cscParams = {}; |
| cscParams.type = FeatureTypeCscOnSfc; |
| cscParams.formatInput = sfcParam.input.format; |
| cscParams.formatOutput = sfcParam.output.surface->Format; |
| cscParams.input.colorSpace = sfcParam.input.colorSpace; |
| cscParams.output.colorSpace = sfcParam.output.colorSpace; |
| cscParams.input.chromaSiting = sfcParam.input.chromaSiting; |
| cscParams.output.chromaSiting = sfcParam.output.chromaSiting; |
| |
| m_cscFilter->Init(); |
| m_cscFilter->SetExecuteEngineCaps(cscParams, vpExecuteCaps); |
| m_cscFilter->CalculateEngineParams(); |
| |
| return m_sfcRender->SetCSCParams(m_cscFilter->GetSfcParams()); |
| } |
| |
| MOS_STATUS MediaVdboxSfcRender::SetScalingParams(VDBOX_SFC_PARAMS &sfcParam, VP_EXECUTE_CAPS &vpExecuteCaps) |
| { |
| VP_PUBLIC_CHK_NULL_RETURN(m_sfcRender); |
| VP_PUBLIC_CHK_NULL_RETURN(m_scalingFilter); |
| |
| RECT rcSrcInput = {0, 0, (int32_t)sfcParam.input.width, (int32_t)sfcParam.input.height }; |
| RECT rcOutput = {0, 0, (int32_t)sfcParam.output.surface->dwWidth, (int32_t)sfcParam.output.surface->dwHeight }; |
| FeatureParamScaling scalingParams = {}; |
| scalingParams.type = FeatureTypeScalingOnSfc; |
| scalingParams.formatInput = sfcParam.input.format; |
| scalingParams.formatOutput = sfcParam.output.surface->Format; |
| scalingParams.scalingMode = GetScalingMode(sfcParam.scalingMode); |
| scalingParams.scalingPreference = VPHAL_SCALING_PREFER_SFC; //!< DDI indicate Scaling preference |
| scalingParams.bDirectionalScalar = false; //!< Vebox Directional Scalar |
| scalingParams.input.rcSrc = rcSrcInput; //!< No input crop support for VD mode. rcSrcInput must have same width/height of input image. |
| scalingParams.input.rcDst = sfcParam.output.rcDst; |
| scalingParams.input.rcMaxSrc = rcSrcInput; |
| scalingParams.input.dwWidth = sfcParam.input.width; |
| scalingParams.input.dwHeight = sfcParam.input.height; |
| scalingParams.output.rcSrc = rcOutput; |
| scalingParams.output.rcDst = rcOutput; |
| scalingParams.output.rcMaxSrc = rcOutput; |
| scalingParams.output.dwWidth = sfcParam.output.surface->dwWidth; |
| scalingParams.output.dwHeight = sfcParam.output.surface->dwHeight; |
| scalingParams.pColorFillParams = nullptr; |
| scalingParams.pCompAlpha = nullptr; |
| scalingParams.csc.colorSpaceOutput = sfcParam.output.colorSpace; |
| scalingParams.interlacedScalingType = sfcParam.videoParams.fieldParams.isFieldToInterleaved ? ISCALING_FIELD_TO_INTERLEAVED : ISCALING_NONE; |
| if (sfcParam.videoParams.fieldParams.isFieldToInterleaved) |
| { |
| scalingParams.input.sampleType = sfcParam.videoParams.fieldParams.isBottomField ? SAMPLE_SINGLE_BOTTOM_FIELD : SAMPLE_SINGLE_TOP_FIELD; |
| scalingParams.output.sampleType = sfcParam.videoParams.fieldParams.isBottomFirst ? SAMPLE_INTERLEAVED_ODD_FIRST_BOTTOM_FIELD : SAMPLE_INTERLEAVED_EVEN_FIRST_TOP_FIELD; |
| } |
| else |
| { |
| scalingParams.input.sampleType = SAMPLE_PROGRESSIVE; |
| scalingParams.output.sampleType = SAMPLE_PROGRESSIVE; |
| } |
| |
| m_scalingFilter->Init(sfcParam.videoParams.codecStandard, sfcParam.videoParams.jpeg.jpegChromaType); |
| m_scalingFilter->SetExecuteEngineCaps(scalingParams, vpExecuteCaps); |
| m_scalingFilter->CalculateEngineParams(); |
| |
| return m_sfcRender->SetScalingParams(m_scalingFilter->GetSfcParams()); |
| } |
| |
| MOS_STATUS MediaVdboxSfcRender::SetSfcMmcParams(VDBOX_SFC_PARAMS &sfcParam) |
| { |
| VP_PUBLIC_CHK_STATUS_RETURN(m_mmc->SetSurfaceMmcState(sfcParam.output.surface)); |
| VP_PUBLIC_CHK_STATUS_RETURN(m_mmc->SetSurfaceMmcMode(sfcParam.output.surface)); |
| VP_PUBLIC_CHK_STATUS_RETURN(m_mmc->SetSurfaceMmcFormat(sfcParam.output.surface)); |
| return m_sfcRender->SetMmcParams(sfcParam.output.surface, true, m_mmc->IsMmcEnabled()); |
| } |
| |
| MOS_STATUS MediaVdboxSfcRender::SetRotMirParams(VDBOX_SFC_PARAMS &sfcParam, VP_EXECUTE_CAPS &vpExecuteCaps) |
| { |
| VP_PUBLIC_CHK_NULL_RETURN(m_sfcRender); |
| VP_PUBLIC_CHK_NULL_RETURN(m_rotMirFilter); |
| FeatureParamRotMir rotMirParams = {}; |
| rotMirParams.type = FeatureTypeRotMirOnSfc; |
| rotMirParams.formatInput = sfcParam.input.format; |
| rotMirParams.formatOutput = sfcParam.output.surface->Format; |
| rotMirParams.rotation = sfcParam.input.mirrorEnabled ? VPHAL_MIRROR_HORIZONTAL : VPHAL_ROTATION_IDENTITY; |
| rotMirParams.surfInfo.tileOutput = sfcParam.output.surface->TileType; |
| |
| m_rotMirFilter->Init(); |
| m_rotMirFilter->SetExecuteEngineCaps(rotMirParams, vpExecuteCaps); |
| m_rotMirFilter->CalculateEngineParams(); |
| |
| return m_sfcRender->SetRotMirParams(m_rotMirFilter->GetSfcParams()); |
| } |
| |
| MOS_STATUS MediaVdboxSfcRender::SetHistogramParams(VDBOX_SFC_PARAMS& sfcParam) |
| { |
| return m_sfcRender->SetHistogramBuf(sfcParam.output.histogramBuf); |
| } |
| |
| MOS_STATUS MediaVdboxSfcRender::AddSfcStates(MOS_COMMAND_BUFFER *cmdBuffer, VDBOX_SFC_PARAMS &sfcParam) |
| { |
| VP_PUBLIC_CHK_NULL_RETURN(m_sfcRender); |
| VP_PUBLIC_CHK_NULL_RETURN(sfcParam.output.surface); |
| VP_PUBLIC_CHK_NULL_RETURN(cmdBuffer); |
| |
| VP_EXECUTE_CAPS vpExecuteCaps = {}; |
| vpExecuteCaps.bSFC = 1; |
| vpExecuteCaps.bSfcCsc = 1; |
| vpExecuteCaps.bSfcScaling = 1; |
| vpExecuteCaps.bSfcRotMir = 1; |
| |
| VP_PUBLIC_CHK_STATUS_RETURN(m_sfcRender->Init(sfcParam.videoParams)); |
| VP_PUBLIC_CHK_STATUS_RETURN(SetCSCParams(sfcParam, vpExecuteCaps)); |
| VP_PUBLIC_CHK_STATUS_RETURN(SetScalingParams(sfcParam, vpExecuteCaps)); |
| VP_PUBLIC_CHK_STATUS_RETURN(SetRotMirParams(sfcParam, vpExecuteCaps)); |
| VP_PUBLIC_CHK_STATUS_RETURN(SetHistogramParams(sfcParam)); |
| VP_PUBLIC_CHK_STATUS_RETURN(SetSfcMmcParams(sfcParam)); |
| |
| RECT rcOutput = {0, 0, (int32_t)sfcParam.output.surface->dwWidth, (int32_t)sfcParam.output.surface->dwHeight}; |
| // The value of plane offset are different between vp and codec. updatePlaneOffset need be set to true when create vp surface |
| // with mos surface from codec hal. |
| VP_SURFACE *renderTarget = m_allocator->AllocateVpSurface(*sfcParam.output.surface, |
| sfcParam.output.colorSpace, |
| sfcParam.output.chromaSiting, |
| rcOutput, |
| rcOutput, |
| SURF_OUT_RENDERTARGET, |
| true); |
| |
| //--------------------------------- |
| // Send CMD: SFC pipe commands |
| //--------------------------------- |
| |
| VP_RENDER_CHK_STATUS_RETURN(m_sfcRender->SetupSfcState(renderTarget)); |
| VP_RENDER_CHK_STATUS_RETURN(m_sfcRender->SendSfcCmd( |
| CODECHAL_JPEG != sfcParam.videoParams.codecStandard, |
| cmdBuffer)); |
| |
| m_allocator->DestroyVpSurface(renderTarget); |
| m_allocator->CleanRecycler(); |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| VPHAL_SCALING_MODE MediaVdboxSfcRender::GetScalingMode(CODECHAL_SCALING_MODE scalingMode) |
| { |
| // Default mode is VPHAL_SCALING_AVS |
| VPHAL_SCALING_MODE sfcScalingMode = VPHAL_SCALING_AVS; |
| |
| switch(scalingMode) |
| { |
| case CODECHAL_SCALING_BILINEAR: |
| sfcScalingMode = VPHAL_SCALING_BILINEAR; |
| break; |
| case CODECHAL_SCALING_NEAREST: |
| case CODECHAL_SCALING_AVS: |
| case CODECHAL_SCALING_ADV_QUALITY: |
| default: |
| sfcScalingMode = VPHAL_SCALING_AVS; |
| break; |
| } |
| |
| return sfcScalingMode; |
| } |
| |
| bool MediaVdboxSfcRender::IsVdboxSfcFormatSupported( |
| CODECHAL_STANDARD codecStandard, |
| MOS_FORMAT inputFormat, |
| MOS_FORMAT outputFormat) |
| { |
| if (nullptr == m_sfcRender) |
| { |
| return false; |
| } |
| return m_sfcRender->IsVdboxSfcFormatSupported(codecStandard, inputFormat, outputFormat); |
| } |