| /* |
| * Copyright (c) 2018-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 vp_csc_filter.h |
| //! \brief Defines the common interface for CSC |
| //! this file is for the base interface which is shared by all CSC in driver. |
| //! |
| |
| #include "vp_csc_filter.h" |
| #include "vp_vebox_cmd_packet.h" |
| #include "hw_filter.h" |
| #include "sw_filter_pipe.h" |
| |
| namespace vp { |
| |
| //! |
| //! \brief Chroma Downsampling and Upsampling for CNL+ |
| //! |
| #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE0_HORZ_OFFSET 0 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE1_HORZ_OFFSET 1 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE2_HORZ_OFFSET 0 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE3_HORZ_OFFSET 1 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE4_HORZ_OFFSET 0 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE5_HORZ_OFFSET 1 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE0_VERT_OFFSET 2 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE1_VERT_OFFSET 2 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE2_VERT_OFFSET 0 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE3_VERT_OFFSET 0 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE4_VERT_OFFSET 4 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE5_VERT_OFFSET 4 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE0_HORZ_OFFSET 0 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE1_HORZ_OFFSET 1 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE2_HORZ_OFFSET 0 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE3_HORZ_OFFSET 1 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE4_HORZ_OFFSET 0 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE5_HORZ_OFFSET 1 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE0_VERT_OFFSET 1 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE1_VERT_OFFSET 1 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE2_VERT_OFFSET 0 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE3_VERT_OFFSET 0 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE4_VERT_OFFSET 2 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE5_VERT_OFFSET 2 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_422_TYPE2_HORZ_OFFSET 0 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_422_TYPE3_HORZ_OFFSET 1 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_422_TYPE2_VERT_OFFSET 0 |
| #define VP_VEBOX_CHROMA_UPSAMPLING_422_TYPE3_VERT_OFFSET 0 |
| #define VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE0_HORZ_OFFSET 0 |
| #define VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE1_HORZ_OFFSET 1 |
| #define VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE2_HORZ_OFFSET 0 |
| #define VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE3_HORZ_OFFSET 1 |
| #define VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE4_HORZ_OFFSET 0 |
| #define VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE5_HORZ_OFFSET 1 |
| #define VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE0_VERT_OFFSET 1 |
| #define VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE1_VERT_OFFSET 1 |
| #define VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE2_VERT_OFFSET 0 |
| #define VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE3_VERT_OFFSET 0 |
| #define VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE4_VERT_OFFSET 2 |
| #define VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE5_VERT_OFFSET 2 |
| #define VP_VEBOX_CHROMA_DOWNSAMPLING_422_TYPE2_HORZ_OFFSET 0 |
| #define VP_VEBOX_CHROMA_DOWNSAMPLING_422_TYPE3_HORZ_OFFSET 1 |
| #define VP_VEBOX_CHROMA_DOWNSAMPLING_422_TYPE2_VERT_OFFSET 0 |
| #define VP_VEBOX_CHROMA_DOWNSAMPLING_422_TYPE3_VERT_OFFSET 0 |
| |
| VpCscFilter::VpCscFilter(PVP_MHWINTERFACE vpMhwInterface) : |
| VpFilter(vpMhwInterface) |
| { |
| } |
| |
| MOS_STATUS VpCscFilter::Init() |
| { |
| VP_FUNC_CALL(); |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS VpCscFilter::Prepare() |
| { |
| VP_FUNC_CALL(); |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS VpCscFilter::Destroy() |
| { |
| VP_FUNC_CALL(); |
| |
| if (m_sfcCSCParams) |
| { |
| MOS_FreeMemory(m_sfcCSCParams); |
| m_sfcCSCParams = nullptr; |
| } |
| |
| if (m_veboxCSCParams) |
| { |
| MOS_FreeMemory(m_veboxCSCParams); |
| m_veboxCSCParams = nullptr; |
| } |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS VpCscFilter::SetExecuteEngineCaps( |
| FeatureParamCsc &cscParams, |
| VP_EXECUTE_CAPS vpExecuteCaps) |
| { |
| VP_FUNC_CALL(); |
| |
| m_cscParams = cscParams; |
| m_executeCaps = vpExecuteCaps; |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS VpCscFilter::CalculateEngineParams() |
| { |
| VP_FUNC_CALL(); |
| |
| if (m_executeCaps.bSfcCsc) |
| { |
| VP_RENDER_CHK_STATUS_RETURN(CalculateSfcEngineParams()); |
| } |
| else if (m_executeCaps.bBeCSC) |
| { |
| VP_RENDER_CHK_STATUS_RETURN(CalculateVeboxEngineParams()); |
| } |
| else if (m_executeCaps.bRender) |
| { |
| // place hold for Render solution |
| VP_PUBLIC_ASSERTMESSAGE("No function support CSC in Render path now"); |
| } |
| else |
| { |
| VP_PUBLIC_ASSERTMESSAGE("Error call, No function support CSC with such config"); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| VPHAL_CSPACE GetSfcInputColorSpace(VP_EXECUTE_CAPS &executeCaps, VPHAL_CSPACE inputColorSpace, VPHAL_CSPACE colorSpaceOutput) |
| { |
| if (executeCaps.bHDR3DLUT) |
| { |
| return IS_COLOR_SPACE_BT2020(colorSpaceOutput) ? CSpace_BT2020_RGB : CSpace_sRGB; |
| } |
| return inputColorSpace; |
| } |
| |
| MOS_FORMAT GetSfcInputFormat(VP_EXECUTE_CAPS &executeCaps, MOS_FORMAT inputFormat, VPHAL_CSPACE colorSpaceOutput) |
| { |
| if (executeCaps.bIECP) |
| { |
| if (executeCaps.bHDR3DLUT) |
| { |
| return IS_COLOR_SPACE_BT2020(colorSpaceOutput) ? Format_R10G10B10A2 : Format_A8B8G8R8; |
| } |
| // Upsampling to yuv444 for IECP input/output. |
| return Format_AYUV; |
| } |
| else if (executeCaps.bDI && VpHal_GetSurfaceColorPack(inputFormat) == VPHAL_COLORPACK_420) |
| { |
| // If the input is 4:2:0, then chroma data is doubled vertically to 4:2:2 |
| return Format_YUY2; |
| } |
| |
| return inputFormat; |
| } |
| |
| MOS_STATUS VpCscFilter::CalculateSfcEngineParams() |
| { |
| VP_FUNC_CALL(); |
| |
| if (!m_executeCaps.bSFC) |
| { |
| VP_PUBLIC_ASSERTMESSAGE("Error call, function only support SFC CSC"); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| if (!m_sfcCSCParams) |
| { |
| m_sfcCSCParams = (PSFC_CSC_PARAMS)MOS_AllocAndZeroMemory(sizeof(SFC_CSC_PARAMS)); |
| |
| if (m_sfcCSCParams == nullptr) |
| { |
| VP_PUBLIC_ASSERTMESSAGE("sfc CSC Pamas buffer allocate failed, return nullpointer"); |
| return MOS_STATUS_NO_SPACE; |
| } |
| } |
| else |
| { |
| MOS_ZeroMemory(m_sfcCSCParams, sizeof(SFC_CSC_PARAMS)); |
| } |
| |
| m_sfcCSCParams->bIEFEnable = (m_cscParams.pIEFParams && |
| m_cscParams.pIEFParams->bEnabled && |
| m_cscParams.pIEFParams->fIEFFactor > 0.0F) ? true : false; |
| |
| if (m_sfcCSCParams->bIEFEnable) |
| { |
| m_sfcCSCParams->iefParams = m_cscParams.pIEFParams; |
| } |
| |
| m_cscParams.colorSpaceInput = GetSfcInputColorSpace(m_executeCaps, m_cscParams.colorSpaceInput, m_cscParams.colorSpaceOutput); |
| m_sfcCSCParams->inputColorSpcase = m_cscParams.colorSpaceInput; |
| |
| m_cscParams.formatInput = GetSfcInputFormat(m_executeCaps, m_cscParams.formatInput, m_cscParams.colorSpaceOutput); |
| m_sfcCSCParams->inputFormat = m_cscParams.formatInput; |
| m_sfcCSCParams->outputFormat = m_cscParams.formatOutput; |
| |
| if (m_sfcCSCParams->inputColorSpcase != m_cscParams.colorSpaceOutput) |
| { |
| m_sfcCSCParams->bCSCEnabled = true; |
| } |
| |
| if (IS_RGB_CSPACE(m_cscParams.colorSpaceInput)) |
| { |
| m_sfcCSCParams->bInputColorSpace = true; |
| } |
| else |
| { |
| m_sfcCSCParams->bInputColorSpace = false; |
| } |
| |
| // Set Chromasting Params |
| VP_RENDER_CHK_STATUS_RETURN(SetSfcChromaParams(m_executeCaps)); |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS VpCscFilter::CalculateVeboxEngineParams() |
| { |
| VP_FUNC_CALL(); |
| |
| if (!m_executeCaps.bVebox) |
| { |
| VP_PUBLIC_ASSERTMESSAGE("Error call, function only support Vebox CSC"); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| if (!m_veboxCSCParams) |
| { |
| m_veboxCSCParams = (PVEBOX_CSC_PARAMS)MOS_AllocAndZeroMemory(sizeof(VEBOX_CSC_PARAMS)); |
| |
| if (m_veboxCSCParams == nullptr) |
| { |
| VP_PUBLIC_ASSERTMESSAGE("sfc CSC Pamas buffer allocate failed, return nullpointer"); |
| return MOS_STATUS_NO_SPACE; |
| } |
| } |
| else |
| { |
| MOS_ZeroMemory(m_veboxCSCParams, sizeof(VEBOX_CSC_PARAMS)); |
| } |
| |
| m_veboxCSCParams->inputColorSpcase = m_cscParams.colorSpaceInput; |
| m_veboxCSCParams->outputColorSpcase = m_cscParams.colorSpaceOutput; |
| m_veboxCSCParams->inputFormat = m_cscParams.formatInput; |
| m_veboxCSCParams->outputFormat = m_cscParams.formatOutput; |
| |
| m_veboxCSCParams->bCSCEnabled = (m_cscParams.colorSpaceInput != m_cscParams.colorSpaceOutput); |
| m_veboxCSCParams->alphaParams = m_cscParams.pAlphaParams; |
| |
| VP_RENDER_CHK_STATUS_RETURN(SetVeboxCUSChromaParams(m_executeCaps)); |
| VP_RENDER_CHK_STATUS_RETURN(SetVeboxCDSChromaParams(m_executeCaps)); |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS VpCscFilter::SetSfcChromaParams( |
| VP_EXECUTE_CAPS vpExecuteCaps) |
| { |
| VP_FUNC_CALL(); |
| |
| VP_RENDER_CHK_NULL_RETURN(m_sfcCSCParams); |
| |
| // Update chroma sitting according to updated input format. |
| VP_RENDER_CHK_STATUS_RETURN(UpdateSfcChromaSiting()); |
| |
| // Setup General params |
| // Set chroma subsampling type according to the Vebox output, but |
| // when Vebox is bypassed, set it according to the source surface format. |
| |
| if (VpHal_GetSurfaceColorPack(m_sfcCSCParams->inputFormat) == VPHAL_COLORPACK_444) |
| { |
| m_sfcCSCParams->b8tapChromafiltering = true; |
| } |
| else |
| { |
| m_sfcCSCParams->b8tapChromafiltering = false; |
| } |
| |
| m_sfcCSCParams->chromaDownSamplingHorizontalCoef = (m_cscParams.chromaSitingOutput & MHW_CHROMA_SITING_HORZ_CENTER) ? MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_4_OVER_8 : |
| ((m_cscParams.chromaSitingOutput & MHW_CHROMA_SITING_HORZ_RIGHT) ? MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_8_OVER_8 : |
| MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_0_OVER_8); |
| m_sfcCSCParams->chromaDownSamplingVerticalCoef = (m_cscParams.chromaSitingOutput & MHW_CHROMA_SITING_VERT_CENTER) ? MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_4_OVER_8 : |
| ((m_cscParams.chromaSitingOutput & MHW_CHROMA_SITING_VERT_BOTTOM) ? MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_8_OVER_8 : |
| MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_0_OVER_8); |
| |
| m_sfcCSCParams->bChromaUpSamplingEnable = IsChromaUpSamplingNeeded(); |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS VpCscFilter::SetVeboxCUSChromaParams(VP_EXECUTE_CAPS vpExecuteCaps) |
| { |
| VP_FUNC_CALL(); |
| |
| VP_RENDER_CHK_NULL_RETURN(m_veboxCSCParams); |
| |
| VPHAL_COLORPACK srcColorPack; |
| bool bNeedUpSampling = vpExecuteCaps.bIECP; |
| bool bDIEnabled = vpExecuteCaps.bDI; |
| |
| srcColorPack = VpHal_GetSurfaceColorPack(m_cscParams.formatInput); |
| |
| // Init CUS as disabled |
| m_veboxCSCParams->bypassCUS = true; |
| |
| if (bNeedUpSampling) |
| { |
| // Type 0 |
| if ((m_cscParams.chromaSitingInput & MHW_CHROMA_SITING_HORZ_LEFT) && |
| (m_cscParams.chromaSitingInput & MHW_CHROMA_SITING_VERT_CENTER)) |
| { |
| if (srcColorPack == VPHAL_COLORPACK_420) |
| { |
| m_veboxCSCParams->bypassCUS = false; |
| if (bDIEnabled) |
| { |
| m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE0_HORZ_OFFSET; |
| m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE0_VERT_OFFSET; |
| } |
| else |
| { |
| m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE0_HORZ_OFFSET; |
| m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE0_VERT_OFFSET; |
| } |
| } |
| } |
| // Type 1 |
| else if ((m_cscParams.chromaSitingInput & MHW_CHROMA_SITING_HORZ_CENTER) && |
| (m_cscParams.chromaSitingInput & MHW_CHROMA_SITING_VERT_CENTER)) |
| { |
| if (srcColorPack == VPHAL_COLORPACK_420) |
| { |
| m_veboxCSCParams->bypassCUS = false; |
| if (bDIEnabled) |
| { |
| m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE1_HORZ_OFFSET; |
| m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE1_VERT_OFFSET; |
| } |
| else |
| { |
| m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE1_HORZ_OFFSET; |
| m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE1_VERT_OFFSET; |
| } |
| } |
| } |
| // Type 2 |
| else if ((m_cscParams.chromaSitingInput & MHW_CHROMA_SITING_HORZ_LEFT) && |
| (m_cscParams.chromaSitingInput & MHW_CHROMA_SITING_VERT_TOP)) |
| { |
| if (srcColorPack == VPHAL_COLORPACK_420) |
| { |
| m_veboxCSCParams->bypassCUS = false; |
| if (bDIEnabled) |
| { |
| m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE2_HORZ_OFFSET; |
| m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE2_VERT_OFFSET; |
| } |
| else |
| { |
| m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE2_HORZ_OFFSET; |
| m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE2_VERT_OFFSET; |
| } |
| } |
| else if (srcColorPack == VPHAL_COLORPACK_422) |
| { |
| m_veboxCSCParams->bypassCUS = false; |
| m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_422_TYPE2_HORZ_OFFSET; |
| m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_422_TYPE2_VERT_OFFSET; |
| } |
| } |
| // Type 3 |
| else if ((m_cscParams.chromaSitingInput & MHW_CHROMA_SITING_HORZ_CENTER) && |
| (m_cscParams.chromaSitingInput & MHW_CHROMA_SITING_VERT_TOP)) |
| { |
| if (srcColorPack == VPHAL_COLORPACK_420) |
| { |
| m_veboxCSCParams->bypassCUS = false; |
| if (bDIEnabled) |
| { |
| m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE3_HORZ_OFFSET; |
| m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE3_VERT_OFFSET; |
| } |
| else |
| { |
| m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE3_HORZ_OFFSET; |
| m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE3_VERT_OFFSET; |
| } |
| } |
| else if (srcColorPack == VPHAL_COLORPACK_422) |
| { |
| m_veboxCSCParams->bypassCUS = false; |
| m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_422_TYPE3_HORZ_OFFSET; |
| m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_422_TYPE3_VERT_OFFSET; |
| } |
| } |
| // Type 4 |
| else if ((m_cscParams.chromaSitingInput & MHW_CHROMA_SITING_HORZ_LEFT) && |
| (m_cscParams.chromaSitingInput & MHW_CHROMA_SITING_VERT_BOTTOM)) |
| { |
| if (srcColorPack == VPHAL_COLORPACK_420) |
| { |
| m_veboxCSCParams->bypassCUS = false; |
| if (bDIEnabled) |
| { |
| m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE4_HORZ_OFFSET; |
| m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE4_VERT_OFFSET; |
| } |
| else |
| { |
| m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE4_HORZ_OFFSET; |
| m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE4_VERT_OFFSET; |
| } |
| } |
| } |
| // Type 5 |
| else if ((m_cscParams.chromaSitingInput & MHW_CHROMA_SITING_HORZ_CENTER) && |
| (m_cscParams.chromaSitingInput & MHW_CHROMA_SITING_VERT_BOTTOM)) |
| { |
| if (srcColorPack == VPHAL_COLORPACK_420) |
| { |
| m_veboxCSCParams->bypassCUS = false; |
| if (bDIEnabled) |
| { |
| m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE5_HORZ_OFFSET; |
| m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITH_DI_TYPE5_VERT_OFFSET; |
| } |
| else |
| { |
| m_veboxCSCParams->chromaUpSamplingHorizontalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE5_HORZ_OFFSET; |
| m_veboxCSCParams->chromaUpSamplingVerticalCoef = VP_VEBOX_CHROMA_UPSAMPLING_420_WITHOUT_DI_TYPE5_VERT_OFFSET; |
| } |
| } |
| } |
| } |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS VpCscFilter::SetVeboxCDSChromaParams(VP_EXECUTE_CAPS vpExecuteCaps) |
| { |
| VP_FUNC_CALL(); |
| |
| bool bNeedDownSampling = false; |
| |
| // Only VEBOX output, we use VEO to do downsampling. |
| // Else, we use SFC/FC path to do downscaling. |
| // if VEBOX intermediate buffer format is non_YUY2 on DI case, enable downsampling as center-left |
| if (vpExecuteCaps.bDI && (m_cscParams.formatOutput != Format_YUY2)) |
| { |
| bNeedDownSampling = true; |
| } |
| else |
| { |
| bNeedDownSampling = vpExecuteCaps.bVebox && !vpExecuteCaps.bSFC; |
| } |
| |
| |
| VPHAL_COLORPACK dstColorPack; |
| dstColorPack = VpHal_GetSurfaceColorPack(m_cscParams.formatOutput); |
| |
| // Init as CDS disabled |
| m_veboxCSCParams->bypassCDS = true; |
| |
| if (bNeedDownSampling) |
| { |
| // Type 0 |
| if ((m_cscParams.chromaSitingOutput & MHW_CHROMA_SITING_HORZ_LEFT) && |
| (m_cscParams.chromaSitingOutput & MHW_CHROMA_SITING_VERT_CENTER)) |
| { |
| if (dstColorPack == VPHAL_COLORPACK_420) |
| { |
| m_veboxCSCParams->bypassCDS = false; |
| m_veboxCSCParams->chromaDownSamplingHorizontalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE0_HORZ_OFFSET; |
| m_veboxCSCParams->chromaDownSamplingVerticalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE0_VERT_OFFSET; |
| } |
| } |
| // Type 1 |
| else if ((m_cscParams.chromaSitingOutput & MHW_CHROMA_SITING_HORZ_CENTER) && |
| (m_cscParams.chromaSitingOutput & MHW_CHROMA_SITING_VERT_CENTER)) |
| { |
| if (dstColorPack == VPHAL_COLORPACK_420) |
| { |
| m_veboxCSCParams->bypassCDS = false; |
| m_veboxCSCParams->chromaDownSamplingHorizontalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE1_HORZ_OFFSET; |
| m_veboxCSCParams->chromaDownSamplingVerticalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE1_VERT_OFFSET; |
| } |
| } |
| // Type 2 |
| else if ((m_cscParams.chromaSitingOutput & MHW_CHROMA_SITING_HORZ_LEFT) && |
| (m_cscParams.chromaSitingOutput & MHW_CHROMA_SITING_VERT_TOP)) |
| { |
| if (dstColorPack == VPHAL_COLORPACK_420) |
| { |
| m_veboxCSCParams->bypassCDS = false; |
| m_veboxCSCParams->chromaDownSamplingHorizontalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE2_HORZ_OFFSET; |
| m_veboxCSCParams->chromaDownSamplingVerticalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE2_VERT_OFFSET; |
| } |
| else if (dstColorPack == VPHAL_COLORPACK_422) |
| { |
| m_veboxCSCParams->bypassCDS = false; |
| m_veboxCSCParams->chromaDownSamplingHorizontalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_422_TYPE2_HORZ_OFFSET; |
| m_veboxCSCParams->chromaDownSamplingVerticalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_422_TYPE2_VERT_OFFSET; |
| } |
| } |
| // Type 3 |
| else if ((m_cscParams.chromaSitingOutput & MHW_CHROMA_SITING_HORZ_CENTER) && |
| (m_cscParams.chromaSitingOutput & MHW_CHROMA_SITING_VERT_TOP)) |
| { |
| if (dstColorPack == VPHAL_COLORPACK_420) |
| { |
| m_veboxCSCParams->bypassCDS = false; |
| m_veboxCSCParams->chromaDownSamplingHorizontalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE3_HORZ_OFFSET; |
| m_veboxCSCParams->chromaDownSamplingVerticalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE3_VERT_OFFSET; |
| } |
| else if (dstColorPack == VPHAL_COLORPACK_422) |
| { |
| m_veboxCSCParams->bypassCDS = false; |
| m_veboxCSCParams->chromaDownSamplingHorizontalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_422_TYPE3_HORZ_OFFSET; |
| m_veboxCSCParams->chromaDownSamplingVerticalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_422_TYPE3_VERT_OFFSET; |
| } |
| } |
| // Type 4 |
| else if ((m_cscParams.chromaSitingOutput & MHW_CHROMA_SITING_HORZ_LEFT) && |
| (m_cscParams.chromaSitingOutput & MHW_CHROMA_SITING_VERT_BOTTOM)) |
| { |
| if (dstColorPack == VPHAL_COLORPACK_420) |
| { |
| m_veboxCSCParams->bypassCDS = false; |
| m_veboxCSCParams->chromaDownSamplingHorizontalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE4_HORZ_OFFSET; |
| m_veboxCSCParams->chromaDownSamplingVerticalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE4_VERT_OFFSET; |
| } |
| } |
| // Type 5 |
| else if ((m_cscParams.chromaSitingOutput & MHW_CHROMA_SITING_HORZ_CENTER) && |
| (m_cscParams.chromaSitingOutput & MHW_CHROMA_SITING_VERT_BOTTOM)) |
| { |
| if (dstColorPack == VPHAL_COLORPACK_420) |
| { |
| m_veboxCSCParams->bypassCDS = false; |
| m_veboxCSCParams->chromaDownSamplingHorizontalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE5_HORZ_OFFSET; |
| m_veboxCSCParams->chromaDownSamplingVerticalCoef = VP_VEBOX_CHROMA_DOWNSAMPLING_420_TYPE5_VERT_OFFSET; |
| } |
| } |
| } |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS VpCscFilter::UpdateSfcChromaSiting() |
| { |
| VP_FUNC_CALL(); |
| |
| VP_RENDER_CHK_NULL_RETURN(m_sfcCSCParams); |
| |
| if (MHW_CHROMA_SITING_NONE == m_cscParams.chromaSitingInput) |
| { |
| m_cscParams.chromaSitingInput = (CHROMA_SITING_HORZ_LEFT | CHROMA_SITING_VERT_CENTER); |
| } |
| switch (VpHal_GetSurfaceColorPack(m_cscParams.formatInput)) |
| { |
| case VPHAL_COLORPACK_422: |
| m_cscParams.chromaSitingInput = (m_cscParams.chromaSitingInput & 0x7) | CHROMA_SITING_VERT_TOP; |
| break; |
| case VPHAL_COLORPACK_444: |
| m_cscParams.chromaSitingInput = CHROMA_SITING_HORZ_LEFT | CHROMA_SITING_VERT_TOP; |
| break; |
| default: |
| break; |
| } |
| |
| m_sfcCSCParams->sfcSrcChromaSiting = m_cscParams.chromaSitingInput; |
| |
| if (MHW_CHROMA_SITING_NONE == m_cscParams.chromaSitingOutput) |
| { |
| m_cscParams.chromaSitingOutput = (CHROMA_SITING_HORZ_LEFT | CHROMA_SITING_VERT_CENTER); |
| } |
| switch (VpHal_GetSurfaceColorPack(m_cscParams.formatOutput)) |
| { |
| case VPHAL_COLORPACK_422: |
| m_cscParams.chromaSitingOutput = (m_cscParams.chromaSitingOutput & 0x7) | CHROMA_SITING_VERT_TOP; |
| break; |
| case VPHAL_COLORPACK_444: |
| m_cscParams.chromaSitingOutput = CHROMA_SITING_HORZ_LEFT | CHROMA_SITING_VERT_TOP; |
| break; |
| default: |
| break; |
| } |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| bool VpCscFilter::IsChromaUpSamplingNeeded() |
| { |
| bool bChromaUpSampling = false; |
| VPHAL_COLORPACK srcColorPack, dstColorPack; |
| |
| srcColorPack = VpHal_GetSurfaceColorPack(m_cscParams.formatInput); |
| dstColorPack = VpHal_GetSurfaceColorPack(m_cscParams.formatOutput); |
| |
| if ((srcColorPack == VPHAL_COLORPACK_420 && |
| (dstColorPack == VPHAL_COLORPACK_422 || dstColorPack == VPHAL_COLORPACK_444)) || |
| (srcColorPack == VPHAL_COLORPACK_422 && dstColorPack == VPHAL_COLORPACK_444)) |
| { |
| bChromaUpSampling = true; |
| } |
| |
| return bChromaUpSampling; |
| } |
| |
| /****************************************************************************************************/ |
| /* HwFilter Csc Parameter */ |
| /****************************************************************************************************/ |
| HwFilterParameter *HwFilterCscParameter::Create(HW_FILTER_CSC_PARAM ¶m, FeatureType featureType) |
| { |
| HwFilterCscParameter *p = MOS_New(HwFilterCscParameter, featureType); |
| if (p) |
| { |
| if (MOS_FAILED(p->Initialize(param))) |
| { |
| MOS_Delete(p); |
| return nullptr; |
| } |
| } |
| return p; |
| } |
| |
| HwFilterCscParameter::HwFilterCscParameter(FeatureType featureType) : HwFilterParameter(featureType) |
| { |
| } |
| |
| HwFilterCscParameter::~HwFilterCscParameter() |
| { |
| } |
| |
| MOS_STATUS HwFilterCscParameter::ConfigParams(HwFilter &hwFilter) |
| { |
| return hwFilter.ConfigParam(m_Params); |
| } |
| |
| MOS_STATUS HwFilterCscParameter::Initialize(HW_FILTER_CSC_PARAM ¶m) |
| { |
| m_Params = param; |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| /****************************************************************************************************/ |
| /* Packet Sfc Csc Parameter */ |
| /****************************************************************************************************/ |
| VpPacketParameter *VpSfcCscParameter::Create(HW_FILTER_CSC_PARAM ¶m) |
| { |
| if (nullptr == param.pPacketParamFactory) |
| { |
| return nullptr; |
| } |
| VpSfcCscParameter *p = dynamic_cast<VpSfcCscParameter *>(param.pPacketParamFactory->GetPacketParameter(param.pHwInterface)); |
| if (p) |
| { |
| if (MOS_FAILED(p->Initialize(param))) |
| { |
| VpPacketParameter *pParam = p; |
| param.pPacketParamFactory->ReturnPacketParameter(pParam); |
| return nullptr; |
| } |
| } |
| return p; |
| } |
| |
| VpSfcCscParameter::VpSfcCscParameter(PVP_MHWINTERFACE pHwInterface, PacketParamFactoryBase *packetParamFactory) : |
| VpPacketParameter(packetParamFactory), m_CscFilter(pHwInterface) |
| { |
| } |
| VpSfcCscParameter::~VpSfcCscParameter() {} |
| |
| bool VpSfcCscParameter::SetPacketParam(VpCmdPacket *pPacket) |
| { |
| VpVeboxCmdPacket *pVeboxPacket = dynamic_cast<VpVeboxCmdPacket *>(pPacket); |
| if (nullptr == pVeboxPacket) |
| { |
| return false; |
| } |
| |
| SFC_CSC_PARAMS *pParams = m_CscFilter.GetSfcParams(); |
| if (nullptr == pParams) |
| { |
| return false; |
| } |
| return MOS_SUCCEEDED(pVeboxPacket->SetSfcCSCParams(pParams)); |
| } |
| |
| MOS_STATUS VpSfcCscParameter::Initialize(HW_FILTER_CSC_PARAM ¶ms) |
| { |
| VP_PUBLIC_CHK_STATUS_RETURN(m_CscFilter.Init()); |
| VP_PUBLIC_CHK_STATUS_RETURN(m_CscFilter.SetExecuteEngineCaps(params.cscParams, params.vpExecuteCaps)); |
| VP_PUBLIC_CHK_STATUS_RETURN(m_CscFilter.CalculateEngineParams()); |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| /****************************************************************************************************/ |
| /* Policy Sfc Csc Handler */ |
| /****************************************************************************************************/ |
| PolicySfcCscHandler::PolicySfcCscHandler() |
| { |
| m_Type = FeatureTypeCscOnSfc; |
| } |
| PolicySfcCscHandler::~PolicySfcCscHandler() |
| { |
| } |
| |
| bool PolicySfcCscHandler::IsFeatureEnabled(VP_EXECUTE_CAPS vpExecuteCaps) |
| { |
| return vpExecuteCaps.bSfcCsc; |
| } |
| |
| HwFilterParameter *PolicySfcCscHandler::CreateHwFilterParam(VP_EXECUTE_CAPS vpExecuteCaps, SwFilterPipe &swFilterPipe, PVP_MHWINTERFACE pHwInterface) |
| { |
| if (IsFeatureEnabled(vpExecuteCaps)) |
| { |
| if (SwFilterPipeType1To1 != swFilterPipe.GetSwFilterPipeType()) |
| { |
| VP_PUBLIC_ASSERTMESSAGE("Invalid parameter! Sfc only support 1To1 swFilterPipe!"); |
| return nullptr; |
| } |
| |
| SwFilterCsc *swFilter = dynamic_cast<SwFilterCsc *>(swFilterPipe.GetSwFilter(true, 0, FeatureTypeCscOnSfc)); |
| |
| if (nullptr == swFilter) |
| { |
| VP_PUBLIC_ASSERTMESSAGE("Invalid parameter! Feature enabled in vpExecuteCaps but no swFilter exists!"); |
| return nullptr; |
| } |
| |
| FeatureParamCsc ¶m = swFilter->GetSwFilterParams(); |
| |
| HW_FILTER_CSC_PARAM paramCsc = {}; |
| paramCsc.type = m_Type; |
| paramCsc.pHwInterface = pHwInterface; |
| paramCsc.vpExecuteCaps = vpExecuteCaps; |
| paramCsc.pPacketParamFactory = &m_PacketParamFactory; |
| paramCsc.cscParams = param; |
| paramCsc.pfnCreatePacketParam = PolicySfcCscHandler::CreatePacketParam; |
| |
| HwFilterParameter *pHwFilterParam = GetHwFeatureParameterFromPool(); |
| |
| if (pHwFilterParam) |
| { |
| if (MOS_FAILED(((HwFilterCscParameter*)pHwFilterParam)->Initialize(paramCsc))) |
| { |
| ReleaseHwFeatureParameter(pHwFilterParam); |
| } |
| } |
| else |
| { |
| pHwFilterParam = HwFilterCscParameter::Create(paramCsc, m_Type); |
| } |
| |
| return pHwFilterParam; |
| } |
| else |
| { |
| return nullptr; |
| } |
| } |
| VpPacketParameter* VpVeboxCscParameter::Create(HW_FILTER_CSC_PARAM& param) |
| { |
| if (nullptr == param.pPacketParamFactory) |
| { |
| return nullptr; |
| } |
| VpVeboxCscParameter* p = dynamic_cast<VpVeboxCscParameter*>(param.pPacketParamFactory->GetPacketParameter(param.pHwInterface)); |
| if (p) |
| { |
| if (MOS_FAILED(p->Initialize(param))) |
| { |
| VpPacketParameter* pParam = p; |
| param.pPacketParamFactory->ReturnPacketParameter(pParam); |
| return nullptr; |
| } |
| } |
| return p; |
| } |
| VpVeboxCscParameter::VpVeboxCscParameter(PVP_MHWINTERFACE pHwInterface, PacketParamFactoryBase* packetParamFactory) : |
| VpPacketParameter(packetParamFactory), m_CscFilter(pHwInterface) |
| { |
| } |
| VpVeboxCscParameter::~VpVeboxCscParameter() |
| { |
| } |
| bool VpVeboxCscParameter::SetPacketParam(VpCmdPacket* pPacket) |
| { |
| VpVeboxCmdPacket* pVeboxPacket = dynamic_cast<VpVeboxCmdPacket*>(pPacket); |
| if (nullptr == pVeboxPacket) |
| { |
| return false; |
| } |
| |
| VEBOX_CSC_PARAMS* pParams = m_CscFilter.GetVeboxParams(); |
| if (nullptr == pParams) |
| { |
| return false; |
| } |
| return MOS_SUCCEEDED(pVeboxPacket->SetVeboxBeCSCParams(pParams)); |
| } |
| MOS_STATUS VpVeboxCscParameter::Initialize(HW_FILTER_CSC_PARAM& params) |
| { |
| VP_PUBLIC_CHK_STATUS_RETURN(m_CscFilter.Init()); |
| VP_PUBLIC_CHK_STATUS_RETURN(m_CscFilter.SetExecuteEngineCaps(params.cscParams, params.vpExecuteCaps)); |
| VP_PUBLIC_CHK_STATUS_RETURN(m_CscFilter.CalculateEngineParams()); |
| return MOS_STATUS_SUCCESS; |
| } |
| PolicyVeboxCscHandler::PolicyVeboxCscHandler() |
| { |
| m_Type = FeatureTypeCscOnVebox; |
| } |
| PolicyVeboxCscHandler::~PolicyVeboxCscHandler() |
| { |
| } |
| bool PolicyVeboxCscHandler::IsFeatureEnabled(VP_EXECUTE_CAPS vpExecuteCaps) |
| { |
| return vpExecuteCaps.bBeCSC; |
| } |
| HwFilterParameter* PolicyVeboxCscHandler::CreateHwFilterParam(VP_EXECUTE_CAPS vpExecuteCaps, SwFilterPipe& swFilterPipe, PVP_MHWINTERFACE pHwInterface) |
| { |
| if (IsFeatureEnabled(vpExecuteCaps)) |
| { |
| if (SwFilterPipeType1To1 != swFilterPipe.GetSwFilterPipeType()) |
| { |
| VP_PUBLIC_ASSERTMESSAGE("Invalid parameter! Sfc only support 1To1 swFilterPipe!"); |
| return nullptr; |
| } |
| |
| SwFilterCsc *swFilter = dynamic_cast<SwFilterCsc *>(swFilterPipe.GetSwFilter(true, 0, FeatureTypeCscOnVebox)); |
| |
| if (nullptr == swFilter) |
| { |
| VP_PUBLIC_ASSERTMESSAGE("Invalid parameter! Feature enabled in vpExecuteCaps but no swFilter exists!"); |
| return nullptr; |
| } |
| |
| FeatureParamCsc ¶m = swFilter->GetSwFilterParams(); |
| |
| HW_FILTER_CSC_PARAM paramCsc = {}; |
| paramCsc.type = m_Type; |
| paramCsc.pHwInterface = pHwInterface; |
| paramCsc.vpExecuteCaps = vpExecuteCaps; |
| paramCsc.pPacketParamFactory = &m_PacketParamFactory; |
| paramCsc.cscParams = param; |
| paramCsc.pfnCreatePacketParam = PolicyVeboxCscHandler::CreatePacketParam; |
| |
| HwFilterParameter *pHwFilterParam = GetHwFeatureParameterFromPool(); |
| |
| if (pHwFilterParam) |
| { |
| if (MOS_FAILED(((HwFilterCscParameter*)pHwFilterParam)->Initialize(paramCsc))) |
| { |
| ReleaseHwFeatureParameter(pHwFilterParam); |
| } |
| } |
| else |
| { |
| pHwFilterParam = HwFilterCscParameter::Create(paramCsc, m_Type); |
| } |
| |
| return pHwFilterParam; |
| } |
| else |
| { |
| return nullptr; |
| } |
| } |
| } |