blob: 0ed10c5aa3b9a3898b3268d6031e524165a3cc91 [file] [log] [blame]
/*
* 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.bSFC)
{
VP_RENDER_CHK_STATUS_RETURN(CalculateSfcEngineParams());
}
else if (m_executeCaps.bVebox)
{
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;
}
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_sfcCSCParams->inputColorSpcase = m_cscParams.colorSpaceInput;
m_sfcCSCParams->inputFormat = m_executeCaps.bDI ? Format_YUY2 : 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(SetChromaParams(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::SetChromaParams(
VP_EXECUTE_CAPS vpExecuteCaps)
{
VP_FUNC_CALL();
VP_RENDER_CHK_NULL_RETURN(m_sfcCSCParams);
// 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.
m_sfcCSCParams->inputChromaSubSampling = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_400;
m_sfcCSCParams->b8tapChromafiltering = false;
if (vpExecuteCaps.bIECP)
{
m_sfcCSCParams->inputChromaSubSampling = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_444;
m_sfcCSCParams->sfcSrcChromaSiting = MHW_CHROMA_SITING_HORZ_LEFT | MHW_CHROMA_SITING_VERT_TOP;
m_sfcCSCParams->b8tapChromafiltering = true;
}
else if (vpExecuteCaps.bDI)
{
m_sfcCSCParams->inputChromaSubSampling = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_422H;
}
else
{
VP_RENDER_CHK_STATUS_RETURN(SetSubSampling());
}
m_sfcCSCParams->chromaDownSamplingVerticalCoef = (m_cscParams.chromaSitingOutput & MHW_CHROMA_SITING_VERT_CENTER) ?
MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_4_OVER_8 : MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_0_OVER_8;
m_sfcCSCParams->chromaDownSamplingHorizontalCoef = (m_cscParams.chromaSitingOutput & MHW_CHROMA_SITING_HORZ_CENTER) ?
MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_4_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::SetSubSampling()
{
VP_FUNC_CALL();
VP_RENDER_CHK_NULL_RETURN(m_sfcCSCParams);
if (m_sfcCSCParams->inputFormat == Format_NV12 ||
(m_sfcCSCParams->inputFormat == Format_P010) ||
(m_sfcCSCParams->inputFormat == Format_P016))
{
m_sfcCSCParams->inputChromaSubSampling = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_420;
}
else if (VpHal_GetSurfaceColorPack(m_sfcCSCParams->inputFormat) == VPHAL_COLORPACK_422)
{
m_sfcCSCParams->inputChromaSubSampling = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_422H;
}
else if (VpHal_GetSurfaceColorPack(m_sfcCSCParams->inputFormat) == VPHAL_COLORPACK_444)
{
m_sfcCSCParams->inputChromaSubSampling = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_444;
m_sfcCSCParams->b8tapChromafiltering = true;
}
m_sfcCSCParams->sfcSrcChromaSiting = m_cscParams.chromaSitingInput;
if (m_sfcCSCParams->sfcSrcChromaSiting == MHW_CHROMA_SITING_NONE)
{
m_sfcCSCParams->sfcSrcChromaSiting = (CHROMA_SITING_HORZ_LEFT | CHROMA_SITING_VERT_CENTER);
}
switch (VpHal_GetSurfaceColorPack(m_sfcCSCParams->inputFormat))
{
case VPHAL_COLORPACK_422:
m_sfcCSCParams->sfcSrcChromaSiting = (m_sfcCSCParams->sfcSrcChromaSiting & 0x7) | CHROMA_SITING_VERT_TOP;
break;
case VPHAL_COLORPACK_444:
m_sfcCSCParams->sfcSrcChromaSiting = CHROMA_SITING_HORZ_LEFT | CHROMA_SITING_VERT_TOP;
break;
default:
break;
}
// Prevent invalid input for output surface and format
if (m_cscParams.chromaSitingOutput == MHW_CHROMA_SITING_NONE)
{
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 &param, 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 &param)
{
m_Params = param;
return MOS_STATUS_SUCCESS;
}
/****************************************************************************************************/
/* Packet Sfc Csc Parameter */
/****************************************************************************************************/
VpPacketParameter *VpSfcCscParameter::Create(HW_FILTER_CSC_PARAM &param)
{
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 &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;
}
/****************************************************************************************************/
/* 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 &param = 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 &param = 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;
}
}
}