blob: 1f544749bcacfa15e004367c2c04a59b79d6f61f [file] [log] [blame]
/*
* Copyright (c) 2009-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 media_libva_vp.c
//! \brief LibVA Video Processing extension interface implementation
//!
#include <va/va.h>
#include <va/va_vpp.h>
#include <va/va_backend.h>
#include <dlfcn.h>
#include <limits.h>
#include "vphal_ddi.h"
#include "media_libva.h"
#include "media_libva_vp.h"
#include "media_libva_util.h"
#include "hwinfo_linux.h"
#include "mos_solo_generic.h"
#include "media_libva_vp_tools.h"
#if (_DEBUG || _RELEASE_INTERNAL)
#if ANDROID
#include "media_libva_vp_tools_android.h"
#endif
#endif // #if (_DEBUG || _RELEASE_INTERNAL)
#define VP_SETTING_MAX_PHASES 1
#define VP_SETTING_MEDIA_STATES 32
#define VP_SETTING_SAME_SAMPLE_THRESHOLD 1000
// ITU-T H.265 Table E.3: Colour Primaries
#define COLOUR_PRIMARY_BT2020 9
#define COLOUR_PRIMARY_BT709 1
#define COLOUR_PRIMARY_BT601 5
// ITU-T H.265 Table E.4 Transfer characteristics
#define TRANSFER_CHARACTERISTICS_BT709 1
#define TRANSFER_CHARACTERISTICS_GMAMA2P2 4
#define TRANSFER_CHARACTERISTICS_LINEAR 8
#define TRANSFER_CHARACTERISTICS_BT2020 14
#define TRANSFER_CHARACTERISTICS_ST2084 16
VAStatus DdiMedia_MapBuffer (
VADriverContextP ctx,
VABufferID buf_id,
void **pbuf
);
VAStatus DdiMedia_UnMapBuffer (
VADriverContextP ctx,
VABufferID buf_id
);
// VP internal APIs to access VP acceleration capability in VPG drivers
VAStatus DdiVp_InitVpHal(PDDI_VP_CONTEXT);
VAStatus DdiVp_DestroyVpHal(PDDI_VP_CONTEXT);
VAStatus DdiVp_DestroyVpHalSurface(PVPHAL_SURFACE pSurf);
VAStatus DdiVp_DestroySrcParams(PDDI_VP_CONTEXT pVpCtx);
VAStatus DdiVp_DestroyTargetParams(PDDI_VP_CONTEXT pVpCtx);
VAStatus DdiVp_DestroyRenderParams(PDDI_VP_CONTEXT pVpCtx);
VAStatus DdiVp_InitCtx(VADriverContextP, PDDI_VP_CONTEXT);
VAStatus DdiVp_UpdateFilterParamBuffer(PDDI_VP_CONTEXT, uint32_t, int32_t, void *, uint32_t, DDI_VP_STATE*);
VAStatus DdiVp_ClearFilterParamBuffer(PDDI_VP_CONTEXT , uint32_t, DDI_VP_STATE);
VAStatus DdiVp_SetProcFilterDinterlaceParams(PDDI_VP_CONTEXT, uint32_t, VAProcFilterParameterBufferDeinterlacing*);
VAStatus DdiVp_SetProcFilterDenoiseParams(PDDI_VP_CONTEXT, uint32_t, VAProcFilterParameterBuffer*);
VAStatus DdiVp_SetProcFilterSharpnessParams(PDDI_VP_CONTEXT, uint32_t, VAProcFilterParameterBuffer*);
VAStatus DdiVp_SetProcFilterColorBalanceParams(PDDI_VP_CONTEXT, uint32_t, VAProcFilterParameterBufferColorBalance*, uint32_t );
VAStatus DdiVp_SetProcFilterSkinToneEnhancementParams(PDDI_VP_CONTEXT, uint32_t, VAProcFilterParameterBuffer*);
VAStatus DdiVp_SetProcFilterTotalColorCorrectionParams(PDDI_VP_CONTEXT, uint32_t, VAProcFilterParameterBufferTotalColorCorrection*, uint32_t);
VAStatus DdiVp_SetProcFilterHdrTmParams(PDDI_VP_CONTEXT, uint32_t, VAProcFilterParameterBufferHDRToneMapping*);
VAStatus DdiVp_SetProcPipelineBlendingParams(PDDI_VP_CONTEXT pVpCtx, uint32_t uiSurfIndex, VAProcPipelineParameterBuffer* pPipelineParam);
VAStatus DdiVp_ConvertSurface (VADriverContextP ctx, DDI_MEDIA_SURFACE *srcSurface, int16_t srcx, int16_t srcy, uint16_t srcw, uint16_t srch, DDI_MEDIA_SURFACE *dstSurface, int16_t destx, int16_t desty, uint16_t destw, uint16_t desth );
VAStatus DdiVp_UpdateProcPipelineForwardReferenceFrames(PDDI_VP_CONTEXT pVpCtx, VADriverContextP pVaDrvCtx, PVPHAL_SURFACE pVpHalSrcSurf, VAProcPipelineParameterBuffer* pPipelineParam);
VAStatus DdiVp_UpdateProcPipelineBackwardReferenceFrames(PDDI_VP_CONTEXT pVpCtx, VADriverContextP pVaDrvCtx, PVPHAL_SURFACE pVpHalSrcSurf, VAProcPipelineParameterBuffer* pPipelineParam);
VAStatus DdiVp_UpdateVphalTargetSurfColorSpace(VADriverContextP, PDDI_VP_CONTEXT, VAProcPipelineParameterBuffer*, uint32_t targetIndex);
VAStatus DdiVp_BeginPictureInt(VADriverContextP pVaDrvCtx, PDDI_VP_CONTEXT pVpCtx, VASurfaceID vaSurfID);
#if (VA_MAJOR_VERSION < 1)
VAStatus DdiVp_GetColorSpace(PVPHAL_SURFACE pVpHalSurf, VAProcColorStandardType colorStandard, uint32_t flag);
#else
VAStatus DdiVp_GetColorSpace(PVPHAL_SURFACE pVpHalSurf, VAProcColorStandardType colorStandard, VAProcColorProperties colorProperties);
#endif
/////////////////////////////////////////////////////////////////////////////
//! \purpose Get vp context form context ID
//! \params
//! [in] VADriverContextP
//! [in] VAContextID
//! \returns PDDI_VP_CONTEXT
/////////////////////////////////////////////////////////////////////////////
PDDI_VP_CONTEXT DdiVp_GetVpContextFromContextID(VADriverContextP ctx, VAContextID vaCtxID)
{
uint32_t uiCtxType;
return (PDDI_VP_CONTEXT)DdiMedia_GetContextFromContextID(ctx, vaCtxID, &uiCtxType);
}
////////////////////////////////////////////////////////////////////////////////
//! \purpose judge whether the pitch size match 16aligned usrptr path require or not
//! \params
//! [in] pitch: surface pitch size.
//! [in] format : surface foramt
//! \returns true if matched
//! for YV12 format, if pitch aligned with 128, go legacy path; if aligned with 16/32/64, go 16usrptr path
//! for other formats, legcy path for aligned with 64, 16usrpt path for aligned with 16/32
////////////////////////////////////////////////////////////////////////////////
bool VpIs16UsrPtrPitch(uint32_t pitch, DDI_MEDIA_FORMAT format)
{
uint32_t PitchAligned = 64;
bool status = false;
if (Media_Format_YV12 == format)
{
PitchAligned = 128;
}
if (!(pitch % 16) && (pitch % PitchAligned))
{
status = true;
}
else
{
status = false;
}
VP_DDI_NORMALMESSAGE("[VP] 16Usrptr check, surface pitch is %d, go to %s path.", pitch, status?"16Usrptr":"legacy");
return status;
}
/////////////////////////////////////////////////////////////////////////////
//! \purpose map from media format to vphal format
//! \params
//! [in] DDI_MEDIA_FORMAT
//! [out] None
//! \returns MOS_FORMAT
/////////////////////////////////////////////////////////////////////////////
MOS_FORMAT VpGetFormatFromMediaFormat(DDI_MEDIA_FORMAT mf)
{
MOS_FORMAT format = Format_Invalid;
VP_DDI_FUNCTION_ENTER;
switch (mf)
{
case Media_Format_NV12:
format = Format_NV12;
break;
case Media_Format_NV21:
format = Format_NV21;
break;
case Media_Format_X8R8G8B8:
format = Format_X8R8G8B8;
break;
case Media_Format_X8B8G8R8:
format = Format_X8B8G8R8;
break;
case Media_Format_A8R8G8B8:
format = Format_A8R8G8B8;
break;
case Media_Format_A8B8G8R8:
case Media_Format_R8G8B8A8:
format = Format_A8B8G8R8;
break;
case Media_Format_R5G6B5:
format = Format_R5G6B5;
break;
case Media_Format_R8G8B8:
format = Format_R8G8B8;
break;
case Media_Format_YUY2 :
format = Format_YUY2;
break;
case Media_Format_UYVY:
format = Format_UYVY;
break;
case Media_Format_YV12 :
format = Format_YV12;
break;
case Media_Format_I420 :
format = Format_I420;
break;
case Media_Format_IYUV :
format = Format_IYUV;
break;
case Media_Format_422H:
format = Format_422H;
break;
case Media_Format_422V:
format = Format_422V;
break;
case Media_Format_400P:
format = Format_400P;
break;
case Media_Format_411P:
format = Format_411P;
break;
case Media_Format_444P:
format = Format_444P;
break;
case Media_Format_IMC3:
format = Format_IMC3;
break;
case Media_Format_P010:
format = Format_P010;
break;
case Media_Format_P012:
case Media_Format_P016:
format = Format_P016;
break;
case Media_Format_R10G10B10A2:
case Media_Format_R10G10B10X2:
format = Format_R10G10B10A2;
break;
case Media_Format_B10G10R10A2:
case Media_Format_B10G10R10X2:
format =Format_B10G10R10A2;
break;
case Media_Format_RGBP:
format = Format_RGBP;
break;
case Media_Format_BGRP:
format = Format_BGRP;
break;
case Media_Format_Y210:
format = Format_Y210;
break;
#if VA_CHECK_VERSION(1, 9, 0)
case Media_Format_Y212:
#endif
case Media_Format_Y216:
format = Format_Y216;
break;
case Media_Format_Y410:
format = Format_Y410;
break;
#if VA_CHECK_VERSION(1, 9, 0)
case Media_Format_Y412:
#endif
case Media_Format_Y416:
format = Format_Y416;
break;
case Media_Format_AYUV:
format = Format_AYUV;
break;
case Media_Format_Y8:
format = Format_Y8;
break;
case Media_Format_Y16S:
format = Format_Y16S;
break;
case Media_Format_Y16U:
format = Format_Y16U;
break;
case Media_Format_VYUY:
format = Format_VYUY;
break;
case Media_Format_YVYU:
format = Format_YVYU;
break;
case Media_Format_A16R16G16B16:
format = Format_A16R16G16B16;
break;
case Media_Format_A16B16G16R16:
format = Format_A16B16G16R16;
break;
default:
VP_DDI_ASSERTMESSAGE("ERROR media format to vphal format.");
format = Format_Invalid;
break;
}
return format;
}
/////////////////////////////////////////////////////////////////////////////
//! \purpose Get the VP Tile Type from Media Tile Type.
//! \params
//! [in] mediaTileType : input mediaTileType
//! [out] None
//! \returns Vp tile Type if call succeeds
/////////////////////////////////////////////////////////////////////////////
MOS_TILE_TYPE VpGetTileTypeFromMediaTileType(uint32_t mediaTileType)
{
MOS_TILE_TYPE tileType;
VP_DDI_FUNCTION_ENTER;
switch(mediaTileType)
{
case I915_TILING_Y:
tileType = MOS_TILE_Y;
break;
case I915_TILING_X:
tileType = MOS_TILE_X;
break;
case I915_TILING_NONE:
tileType = MOS_TILE_LINEAR;
break;
default:
tileType = MOS_TILE_LINEAR;
}
return tileType;
}
/////////////////////////////////////////////////////////////////////////////
//! \purpose Get the render parameters from Va Driver Context.
//! \params
//! [in] pVpCtx : VP context
//! [out] None
//! \returns Pointer of render parameters
/////////////////////////////////////////////////////////////////////////////
PVPHAL_RENDER_PARAMS VpGetRenderParams(PDDI_VP_CONTEXT pVpCtx)
{
VP_DDI_FUNCTION_ENTER;
DDI_CHK_NULL(pVpCtx, "Null pVpCtx.", nullptr);
return pVpCtx->pVpHalRenderParams;
}
/////////////////////////////////////////////////////////////////////////////
//! \purpose Destroy VPHAL Driver Reference Params
//! \params
//! [in] pSurf : VPHAL surface
//! [out] None
//! \returns VA_STATUS_SUCCESS if call succeeds
/////////////////////////////////////////////////////////////////////////////
VAStatus DdiVp_DestroyVpHalSurface(PVPHAL_SURFACE pSurf)
{
VP_DDI_FUNCTION_ENTER;
DDI_CHK_NULL(pSurf, "Null pSurf.", VA_STATUS_ERROR_INVALID_PARAMETER);
if (pSurf->pFwdRef)
{
DdiVp_DestroyVpHalSurface(pSurf->pFwdRef);
}
if (pSurf->pBwdRef)
{
DdiVp_DestroyVpHalSurface(pSurf->pBwdRef);
}
MOS_FreeMemAndSetNull(pSurf);
return VA_STATUS_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////
//! \purpose Destroy VPHAL Driver Source Params
//! \params
//! [in] pVpCtx : VP context
//! [out] None
//! \returns VA_STATUS_SUCCESS if call succeeds
/////////////////////////////////////////////////////////////////////////////
VAStatus
DdiVp_DestroySrcParams(PDDI_VP_CONTEXT pVpCtx)
{
uint32_t uSurfIndex;
VP_DDI_FUNCTION_ENTER;
DDI_CHK_NULL(pVpCtx, "Null pVpCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
// initialize
uSurfIndex = 0;
if (nullptr != pVpCtx)
{
if (nullptr != pVpCtx->pVpHalRenderParams)
{
for (uSurfIndex = 0; uSurfIndex < VPHAL_MAX_SOURCES; uSurfIndex++)
{
if (nullptr != pVpCtx->pVpHalRenderParams->pSrc[uSurfIndex])
{
MOS_FreeMemAndSetNull(pVpCtx->pVpHalRenderParams->pSrc[uSurfIndex]->pProcampParams);
MOS_FreeMemAndSetNull(pVpCtx->pVpHalRenderParams->pSrc[uSurfIndex]->pDeinterlaceParams);
MOS_FreeMemAndSetNull(pVpCtx->pVpHalRenderParams->pSrc[uSurfIndex]->pDenoiseParams);
if (pVpCtx->pVpHalRenderParams->pSrc[uSurfIndex]->pIEFParams)
{
MOS_FreeMemAndSetNull(pVpCtx->pVpHalRenderParams->pSrc[uSurfIndex]->pIEFParams->pExtParam);
MOS_FreeMemAndSetNull(pVpCtx->pVpHalRenderParams->pSrc[uSurfIndex]->pIEFParams);
}
MOS_FreeMemAndSetNull(pVpCtx->pVpHalRenderParams->pSrc[uSurfIndex]->pBlendingParams);
MOS_FreeMemAndSetNull(pVpCtx->pVpHalRenderParams->pSrc[uSurfIndex]->pLumaKeyParams);
MOS_FreeMemAndSetNull(pVpCtx->pVpHalRenderParams->pSrc[uSurfIndex]->pColorPipeParams);
MOS_FreeMemAndSetNull(pVpCtx->pVpHalRenderParams->pSrc[uSurfIndex]->pHDRParams);
DdiVp_DestroyVpHalSurface(pVpCtx->pVpHalRenderParams->pSrc[uSurfIndex]);
pVpCtx->pVpHalRenderParams->pSrc[uSurfIndex] = nullptr;
}
}
}
}
return VA_STATUS_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////
//! \purpose Destroy VPHAL Driver Target Params
//! \params
//! [in] pVpCtx : VP context
//! [out] None
//! \returns VA_STATUS_SUCCESS if call succeeds
/////////////////////////////////////////////////////////////////////////////
VAStatus
DdiVp_DestroyTargetParams(PDDI_VP_CONTEXT pVpCtx)
{
PVPHAL_RENDER_PARAMS pParams;
PVPHAL_SURFACE pTarget;
uint32_t targetIndex;
VP_DDI_FUNCTION_ENTER;
DDI_CHK_NULL(pVpCtx, "Null pVpCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
if (pVpCtx->pVpHalRenderParams)
{
pParams = pVpCtx->pVpHalRenderParams;
for (targetIndex = 0; targetIndex < VPHAL_MAX_TARGETS; targetIndex++)
{
pTarget = pParams->pTarget[targetIndex];
if (pTarget)
{
if (pTarget->OsResource.bo)
{
pTarget->OsResource.bo = nullptr;
}
if (pTarget->pProcampParams)
{
MOS_FreeMemAndSetNull(pTarget->pProcampParams);
}
if (pTarget->pDeinterlaceParams)
{
MOS_FreeMemAndSetNull(pTarget->pDeinterlaceParams);
}
if (pTarget->pDenoiseParams)
{
MOS_FreeMemAndSetNull(pTarget->pDenoiseParams);
}
if (pTarget->pHDRParams)
{
MOS_FreeMemAndSetNull(pTarget->pHDRParams);
}
MOS_FreeMemAndSetNull(pParams->pTarget[targetIndex]);
}
}
// reset render target count
pParams->uDstCount = 0;
}
return VA_STATUS_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////
//! \purpose Destroy VPHAL Driver Render Params
//! \params
//! [in] pVpCtx : VP context
//! [out] None
//! \returns VA_STATUS_SUCCESS if call succeeds
/////////////////////////////////////////////////////////////////////////////
VAStatus
DdiVp_DestroyRenderParams(PDDI_VP_CONTEXT pVpCtx)
{
VP_DDI_FUNCTION_ENTER;
DDI_CHK_NULL(pVpCtx, "Null pVpCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
DdiVp_DestroySrcParams(pVpCtx);
DdiVp_DestroyTargetParams(pVpCtx);
if (nullptr != pVpCtx)
{
if (nullptr != pVpCtx->pVpHalRenderParams)
{
MOS_FreeMemAndSetNull(pVpCtx->pVpHalRenderParams->pSplitScreenDemoModeParams);
MOS_FreeMemAndSetNull(pVpCtx->pVpHalRenderParams->pCompAlpha);
if (nullptr != pVpCtx->pVpHalRenderParams->pColorFillParams)
{
MOS_FreeMemAndSetNull(pVpCtx->pVpHalRenderParams->pColorFillParams);
}
MOS_FreeMemAndSetNull(pVpCtx->pVpHalRenderParams);
}
}
return VA_STATUS_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////
//! \purpose Destroy VPHAL Driver context
//! \params
//! [in] pVpCtx : VP context
//! [out] None
//! \returns VA_STATUS_SUCCESS if call succeeds
/////////////////////////////////////////////////////////////////////////////
VAStatus
DdiVp_DestroyVpHal(PDDI_VP_CONTEXT pVpCtx)
{
VP_DDI_FUNCTION_ENTER;
DDI_CHK_NULL(pVpCtx, "Null pVpCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
DdiVp_DestroyRenderParams(pVpCtx);
// Destroy VPHAL context
if (nullptr != pVpCtx)
{
pVpCtx->MosDrvCtx.SkuTable.reset();
pVpCtx->MosDrvCtx.WaTable.reset();
if (nullptr != pVpCtx->pVpHal)
{
MOS_Delete(pVpCtx->pVpHal);
pVpCtx->pVpHal = nullptr;
}
#if (_DEBUG || _RELEASE_INTERNAL)
VpDestoryDumpConfig(pVpCtx);
#endif //(_DEBUG || _RELEASE_INTERNAL)
}
return VA_STATUS_SUCCESS;
}
//////////////////////////////////////////////////////////////////////////////////////////////
//! \purpose Map VA Rotation flags to appropriate VPHAL Rotation params
//! \params
//! [in] pVpHalSrcSurf
//! [in] rotation_state
//! [out] None
//! \returns VA_STATUS_SUCCESS if call succeeds
/////////////////////////////////////////////////////////////////////////////////////////////
VAStatus
VpUpdateProcRotateState(PVPHAL_SURFACE pVpHalSrcSurf, uint32_t rotation_state)
{
VP_DDI_FUNCTION_ENTER;
DDI_CHK_NULL(pVpHalSrcSurf, "Null pVpHalSrcSurf.", VA_STATUS_ERROR_INVALID_PARAMETER);
switch(rotation_state)
{
case VA_ROTATION_NONE:
pVpHalSrcSurf->Rotation = VPHAL_ROTATION_IDENTITY;
break;
case VA_ROTATION_90:
pVpHalSrcSurf->Rotation = VPHAL_ROTATION_90;
break;
case VA_ROTATION_180:
pVpHalSrcSurf->Rotation = VPHAL_ROTATION_180;
break;
case VA_ROTATION_270:
pVpHalSrcSurf->Rotation = VPHAL_ROTATION_270;
break;
default:
VP_DDI_ASSERTMESSAGE("VpUpdateProcRotateState rotation_state = %d is out of range.", rotation_state);
return VA_STATUS_ERROR_INVALID_PARAMETER;
}
return VA_STATUS_SUCCESS;
}
//////////////////////////////////////////////////////////////////////////////////////////////
//! \purpose Map VA Mirroring flags to appropriate VPHAL Mirroring params
//! \params
//! [in] pVpHalSrcSurf
//! [in] mirror_state
//! [out] None
//! \returns VA_STATUS_SUCCESS if call succeeds
/////////////////////////////////////////////////////////////////////////////////////////////
VAStatus
VpUpdateProcMirrorState(PVPHAL_SURFACE pVpHalSrcSurf, uint32_t mirror_state)
{
VP_DDI_FUNCTION_ENTER;
DDI_CHK_NULL(pVpHalSrcSurf, "Null pVpHalSrcSurf.", VA_STATUS_ERROR_INVALID_PARAMETER);
if(mirror_state > VA_MIRROR_VERTICAL)
{
VP_DDI_ASSERTMESSAGE("VpUpdateProcMirrorState mirror_state = %d is out of range.", mirror_state);
VP_DDI_ASSERTMESSAGE("VpUpdateProcMirrorState reset mirror_state to VA_MIRROR_NONE.");
mirror_state = VA_MIRROR_NONE;
}
// Rotation must be a valid angle
switch(pVpHalSrcSurf->Rotation)
{
case VPHAL_ROTATION_IDENTITY:
if(mirror_state == VA_MIRROR_HORIZONTAL)
{
pVpHalSrcSurf->Rotation = VPHAL_MIRROR_HORIZONTAL;
}
else if(mirror_state == VA_MIRROR_VERTICAL)
{
pVpHalSrcSurf->Rotation = VPHAL_MIRROR_VERTICAL;
}
break;
case VPHAL_ROTATION_90:
if(mirror_state == VA_MIRROR_HORIZONTAL)
{
pVpHalSrcSurf->Rotation = VPHAL_ROTATE_90_MIRROR_HORIZONTAL;
}
else if(mirror_state == VA_MIRROR_VERTICAL)
{
pVpHalSrcSurf->Rotation = VPHAL_ROTATE_90_MIRROR_VERTICAL;
}
break;
case VPHAL_ROTATION_180:
if(mirror_state == VA_MIRROR_HORIZONTAL)
{
pVpHalSrcSurf->Rotation = VPHAL_MIRROR_VERTICAL;
}
else if(mirror_state == VA_MIRROR_VERTICAL)
{
pVpHalSrcSurf->Rotation = VPHAL_MIRROR_HORIZONTAL;
}
break;
case VPHAL_ROTATION_270:
if(mirror_state == VA_MIRROR_HORIZONTAL)
{
pVpHalSrcSurf->Rotation = VPHAL_ROTATE_90_MIRROR_VERTICAL;
}
else if(mirror_state == VA_MIRROR_VERTICAL)
{
pVpHalSrcSurf->Rotation = VPHAL_ROTATE_90_MIRROR_HORIZONTAL;
}
break;
default:
VP_DDI_ASSERTMESSAGE("VpUpdateProcMirrorState Unexpected Invalid Rotation = %d.", pVpHalSrcSurf->Rotation);
return VA_STATUS_ERROR_INVALID_PARAMETER;
}
return VA_STATUS_SUCCESS;
}
//////////////////////////////////////////////////////////////////////////////////////////////
//! \purpose Check whether there is only Procamp with adjusting Brightness
//! \params
//! [in] pVpHalSrcSurf
//! [out] None
//! \returns true if call succeeds
/////////////////////////////////////////////////////////////////////////////////////////////
bool IsProcmpEnable(PVPHAL_SURFACE pVpHalSrcSurf)
{
DDI_CHK_NULL(pVpHalSrcSurf, "Null pVpHalSrcSurf.", VA_STATUS_ERROR_INVALID_PARAMETER);
if ((pVpHalSrcSurf->pProcampParams && pVpHalSrcSurf->pProcampParams->bEnabled) &&
(pVpHalSrcSurf->pProcampParams->fContrast == 1 && pVpHalSrcSurf->pProcampParams->fHue == 0 && pVpHalSrcSurf->pProcampParams->fSaturation == 1) &&
!pVpHalSrcSurf->pBlendingParams && !pVpHalSrcSurf->pLumaKeyParams && (!pVpHalSrcSurf->pIEFParams || !pVpHalSrcSurf->pIEFParams->bEnabled) &&
!pVpHalSrcSurf->pDeinterlaceParams && (!pVpHalSrcSurf->pDenoiseParams || (!pVpHalSrcSurf->pDenoiseParams->bEnableChroma && !pVpHalSrcSurf->pDenoiseParams->bEnableLuma)) &&
(!pVpHalSrcSurf->pColorPipeParams || (!pVpHalSrcSurf->pColorPipeParams->bEnableACE && !pVpHalSrcSurf->pColorPipeParams->bEnableSTE && !pVpHalSrcSurf->pColorPipeParams->bEnableTCC)) &&
!pVpHalSrcSurf->pHDRParams)
{
return true;
}
return false;
}
//////////////////////////////////////////////////////////////////////////////////////////////
//! \purpose Map Chroma Sitting flags to appropriate VPHAL chroma sitting params
//! \params
//! [in] pVpHalSurf
//! [in] chromasiting_state
//! [out] None
//! \returns VA_STATUS_SUCCESS if call succeeds
/////////////////////////////////////////////////////////////////////////////////////////////
VAStatus
VpUpdateProcChromaSittingState(PVPHAL_SURFACE pVpHalSurf, uint8_t chromasiting_state)
{
uint32_t uChromaSitingFlags = 0;
VP_DDI_FUNCTION_ENTER;
DDI_CHK_NULL(pVpHalSurf, "Null pVpHalSurf.", VA_STATUS_ERROR_INVALID_PARAMETER);
// Chroma siting
// The lower 4 bits are still used as chroma-siting flag for output/input_surface_flag
// Set the vertical chroma siting info at bit 1:0
uChromaSitingFlags = chromasiting_state & 0x3;
switch (uChromaSitingFlags)
{
case VA_CHROMA_SITING_VERTICAL_TOP:
pVpHalSurf->ChromaSiting = CHROMA_SITING_VERT_TOP;
break;
case VA_CHROMA_SITING_VERTICAL_CENTER:
pVpHalSurf->ChromaSiting = CHROMA_SITING_VERT_CENTER;
break;
case VA_CHROMA_SITING_VERTICAL_BOTTOM:
pVpHalSurf->ChromaSiting = CHROMA_SITING_VERT_BOTTOM;
break;
default:
pVpHalSurf->ChromaSiting = CHROMA_SITING_NONE;
break;
}
if (pVpHalSurf->ChromaSiting != CHROMA_SITING_NONE)
{
// Set the horizontal chroma siting info at bit 3:2
uChromaSitingFlags = chromasiting_state & 0xc;
switch (uChromaSitingFlags)
{
case VA_CHROMA_SITING_HORIZONTAL_LEFT:
pVpHalSurf->ChromaSiting = pVpHalSurf->ChromaSiting | CHROMA_SITING_HORZ_LEFT;
break;
case VA_CHROMA_SITING_HORIZONTAL_CENTER:
pVpHalSurf->ChromaSiting = pVpHalSurf->ChromaSiting | CHROMA_SITING_HORZ_CENTER;
break;
default:
pVpHalSurf->ChromaSiting = CHROMA_SITING_NONE;
break;
}
}
return VA_STATUS_SUCCESS;
}
//////////////////////////////////////////////////////////////////////////////////////////////
//! \purpose Set the appropriate HDR params according to colour standard, HDR metadata.
//! \params
//! [in] pVpHalSurf : VPHAL Surface
//! [in] pHdrMetadata: HDR metadata
//! [out] None
//! \returns VA_STATUS_SUCCESS if call succeeds
/////////////////////////////////////////////////////////////////////////////////////////////
VAStatus VpUpdateProcHdrState(
const PVPHAL_SURFACE pVpHalSurf,
const VAHdrMetaData* pHdrMetadata)
{
DDI_CHK_NULL(pVpHalSurf, "Null pVpHalSurf.", VA_STATUS_ERROR_INVALID_BUFFER);
// pass HDR metadata
if ((pHdrMetadata != nullptr) && (pHdrMetadata->metadata_size != 0))
{
if (pVpHalSurf->pHDRParams == nullptr)
{
pVpHalSurf->pHDRParams = (PVPHAL_HDR_PARAMS)MOS_AllocAndZeroMemory(sizeof(VPHAL_HDR_PARAMS));
DDI_CHK_NULL(pVpHalSurf->pHDRParams, "VPHAL_HDR_PARAMS MOS_AllocAndZeroMemory failed.", VA_STATUS_ERROR_ALLOCATION_FAILED);
}
// HDR10 Meta Data
if (pHdrMetadata->metadata_type == VAProcHighDynamicRangeMetadataHDR10)
{
VP_DDI_NORMALMESSAGE("VpSetHdrParams HDR10 metadata.");
VAHdrMetaDataHDR10* pHDR10MetaData = (VAHdrMetaDataHDR10*)pHdrMetadata->metadata;
if (pHDR10MetaData)
{
pVpHalSurf->pHDRParams->white_point_x = pHDR10MetaData->white_point_x;
pVpHalSurf->pHDRParams->white_point_y = pHDR10MetaData->white_point_y;
VP_DDI_NORMALMESSAGE("pHDR10MetaData white_point_x %d, white_point_y %d.", pHDR10MetaData->white_point_x, pHDR10MetaData->white_point_y);
pVpHalSurf->pHDRParams->max_display_mastering_luminance = pHDR10MetaData->max_display_mastering_luminance;
pVpHalSurf->pHDRParams->min_display_mastering_luminance = pHDR10MetaData->min_display_mastering_luminance;
VP_DDI_NORMALMESSAGE("pHDR10MetaData max_display_mastering_luminance %d, min_display_mastering_luminance %d.", pHDR10MetaData->max_display_mastering_luminance, pHDR10MetaData->min_display_mastering_luminance);
pVpHalSurf->pHDRParams->MaxCLL = pHDR10MetaData->max_content_light_level;
pVpHalSurf->pHDRParams->MaxFALL = pHDR10MetaData->max_pic_average_light_level;
VP_DDI_NORMALMESSAGE("pHDR10MetaData MaxCLL %d, MaxFALL %d.", pHDR10MetaData->max_content_light_level, pHDR10MetaData->max_pic_average_light_level);
pVpHalSurf->pHDRParams->bAutoMode = false;
pVpHalSurf->pHDRParams->MaxCLL = (pVpHalSurf->pHDRParams->MaxCLL == 0) ? HDR_DEFAULT_MAXCLL : pVpHalSurf->pHDRParams->MaxCLL;
pVpHalSurf->pHDRParams->MaxFALL = (pVpHalSurf->pHDRParams->MaxFALL == 0) ? HDR_DEFAULT_MAXFALL : pVpHalSurf->pHDRParams->MaxFALL;
MOS_SecureMemcpy(pVpHalSurf->pHDRParams->display_primaries_x, 3 * sizeof(uint16_t), pHDR10MetaData->display_primaries_x, 3 * sizeof(uint16_t));
MOS_SecureMemcpy(pVpHalSurf->pHDRParams->display_primaries_y, 3 * sizeof(uint16_t), pHDR10MetaData->display_primaries_y, 3 * sizeof(uint16_t));
switch (pVpHalSurf->GammaType)
{
case VPHAL_GAMMA_SMPTE_ST2084:
pVpHalSurf->pHDRParams->EOTF = VPHAL_HDR_EOTF_SMPTE_ST2084;
break;
case VPHAL_GAMMA_BT1886:
pVpHalSurf->pHDRParams->EOTF = VPHAL_HDR_EOTF_BT1886;
break;
default:
pVpHalSurf->pHDRParams->EOTF = VPHAL_HDR_EOTF_TRADITIONAL_GAMMA_SDR;
break;
}
VP_DDI_NORMALMESSAGE("max_display_mastering_luminance %d.", pVpHalSurf->pHDRParams->max_display_mastering_luminance);
VP_DDI_NORMALMESSAGE("min_display_mastering_luminance %d.", pVpHalSurf->pHDRParams->min_display_mastering_luminance);
VP_DDI_NORMALMESSAGE("GammaType %d.", pVpHalSurf->GammaType);
}
}
}
return VA_STATUS_SUCCESS;
}
//////////////////////////////////////////////////////////////////////////////////////////////
//! \purpose Extract VAProcPipelineParameterBuffer params for target surface and set the appropriate VPHAL params
//! \params
//! [in] pVaDrvCtx : VA Driver context
//! [in] pVpCtx : VP context
//! [in] pPipelineParam : Pipeline parameters from application (VAProcPipelineParameterBuffer)
//! [out] None
//! \returns VA_STATUS_SUCCESS if call succeeds
/////////////////////////////////////////////////////////////////////////////////////////////
VAStatus
VpSetRenderTargetParams(
VADriverContextP pVaDrvCtx,
PDDI_VP_CONTEXT pVpCtx,
VAProcPipelineParameterBuffer* pPipelineParam)
{
PVPHAL_RENDER_PARAMS VpHalRenderParams;
PDDI_MEDIA_CONTEXT pMediaCtx;
PDDI_MEDIA_SURFACE pMediaSrcSurf;
PVPHAL_SURFACE pVpHalTgtSurf;
VP_DDI_FUNCTION_ENTER;
DDI_CHK_NULL(pVaDrvCtx, "Null pVaDrvCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
DDI_CHK_NULL(pVpCtx, "Null pVpCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
DDI_CHK_NULL(pPipelineParam, "Null pPipelineParam.", VA_STATUS_ERROR_INVALID_BUFFER);
pMediaCtx = DdiMedia_GetMediaContext(pVaDrvCtx);
DDI_CHK_NULL(pMediaCtx, "Null pMediaCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
pMediaSrcSurf = DdiMedia_GetSurfaceFromVASurfaceID(pMediaCtx, pPipelineParam->surface);
DDI_CHK_NULL(pMediaSrcSurf, "Null pMediaSrcSurf.", VA_STATUS_ERROR_INVALID_BUFFER);
VpHalRenderParams = pVpCtx->pVpHalRenderParams;
DDI_CHK_NULL(VpHalRenderParams, "Null pVpHalRenderParams.", VA_STATUS_ERROR_INVALID_PARAMETER);
DDI_ASSERT(VpHalRenderParams->uDstCount >= 1);
DDI_CHK_NULL(VpHalRenderParams->pTarget, "Null VpHalRenderParams->pTarget.", VA_STATUS_ERROR_INVALID_BUFFER);
pVpHalTgtSurf = VpHalRenderParams->pTarget[VpHalRenderParams->uDstCount-1];
DDI_CHK_NULL(pVpHalTgtSurf, "Null pVpHalTgtSurf.", VA_STATUS_ERROR_INVALID_BUFFER);
if (pPipelineParam->surface_region != nullptr)
{
pVpHalTgtSurf->rcSrc.left = pPipelineParam->surface_region->x;
pVpHalTgtSurf->rcSrc.top = pPipelineParam->surface_region->y;
pVpHalTgtSurf->rcSrc.right = pPipelineParam->surface_region->x + pPipelineParam->surface_region->width;
pVpHalTgtSurf->rcSrc.bottom = pPipelineParam->surface_region->y + pPipelineParam->surface_region->height;
if (pVpHalTgtSurf->rcSrc.top < 0)
{
pVpHalTgtSurf->rcSrc.top = 0;
}
if (pVpHalTgtSurf->rcSrc.left < 0)
{
pVpHalTgtSurf->rcSrc.left = 0;
}
if (pVpHalTgtSurf->rcSrc.right > pMediaSrcSurf->iWidth)
{
pVpHalTgtSurf->rcSrc.right = pMediaSrcSurf->iWidth;
}
if (pVpHalTgtSurf->rcSrc.bottom > pMediaSrcSurf->iHeight)
{
pVpHalTgtSurf->rcSrc.bottom = pMediaSrcSurf->iHeight;
}
}
// Set dest rect
if (pPipelineParam->output_region != nullptr)
{
pVpHalTgtSurf->rcDst.left = pPipelineParam->output_region->x;
pVpHalTgtSurf->rcDst.top = pPipelineParam->output_region->y;
pVpHalTgtSurf->rcDst.right = pPipelineParam->output_region->x + pPipelineParam->output_region->width;
pVpHalTgtSurf->rcDst.bottom = pPipelineParam->output_region->y + pPipelineParam->output_region->height;
if (pVpHalTgtSurf->rcDst.top < 0)
{
pVpHalTgtSurf->rcDst.top = 0;
}
if (pVpHalTgtSurf->rcDst.left < 0)
{
pVpHalTgtSurf->rcDst.left = 0;
}
if (pVpHalTgtSurf->rcDst.right > pMediaSrcSurf->iWidth)
{
pVpHalTgtSurf->rcDst.right = pMediaSrcSurf->iWidth;
}
if (pVpHalTgtSurf->rcDst.bottom > pMediaSrcSurf->iHeight)
{
pVpHalTgtSurf->rcDst.bottom = pMediaSrcSurf->iHeight;
}
}
if (IsProcmpEnable(pVpHalTgtSurf))
{
// correct the ChromaSitting location if Procamp is enabled.
#if (VA_MAJOR_VERSION < 1)
pPipelineParam->output_surface_flag = VA_CHROMA_SITING_HORIZONTAL_LEFT | VA_CHROMA_SITING_VERTICAL_TOP;
#else
pPipelineParam->output_color_properties.chroma_sample_location = VA_CHROMA_SITING_HORIZONTAL_LEFT | VA_CHROMA_SITING_VERTICAL_TOP;
#endif
}
#if (VA_MAJOR_VERSION < 1)
VpUpdateProcChromaSittingState(pVpHalTgtSurf, (uint8_t)(pPipelineParam->output_surface_flag & 0xff));
#else
VpUpdateProcChromaSittingState(pVpHalTgtSurf, pPipelineParam->output_color_properties.chroma_sample_location);
#endif
return VA_STATUS_SUCCESS;
}
//////////////////////////////////////////////////////////////////////////////////////////////
//! \purpose Set Interpolation Method according to the flag
//! \params
//! [in] PVPHAL_SURFACE : VA Surface
//! [in] uInterpolationflags : Interpolation Flag
//! [out] None
//! \returns VA_STATUS_SUCCESS if call succeeds
/////////////////////////////////////////////////////////////////////////////////////////////
VAStatus
VpSetInterpolationParams(
PVPHAL_SURFACE pSurface,
uint32_t uInterpolationflags)
{
DDI_CHK_NULL(pSurface, "Null pSurface.", VA_STATUS_ERROR_INVALID_SURFACE);
switch (uInterpolationflags)
{
#if VA_CHECK_VERSION(1, 9, 0)
case VA_FILTER_INTERPOLATION_NEAREST_NEIGHBOR:
pSurface->ScalingMode = VPHAL_SCALING_NEAREST;
break;
case VA_FILTER_INTERPOLATION_BILINEAR:
pSurface->ScalingMode = VPHAL_SCALING_BILINEAR;
break;
case VA_FILTER_INTERPOLATION_ADVANCED:
case VA_FILTER_INTERPOLATION_DEFAULT:
#endif
default:
pSurface->ScalingMode = VPHAL_SCALING_AVS;
break;
}
return VA_STATUS_SUCCESS;
}
//////////////////////////////////////////////////////////////////////////////////////////////
//! \purpose Extract VAProcPipelineParameterBuffer params and set the appropriate VPHAL params
//! \params
//! [in] pVaDrvCtx : VA Driver context
//! [in] pVpCtx : VP context
//! [in] pPipelineParam : Pipeline parameters from application (VAProcPipelineParameterBuffer)
//! [out] None
//! \returns VA_STATUS_SUCCESS if call succeeds
/////////////////////////////////////////////////////////////////////////////////////////////
VAStatus
DdiVp_SetProcPipelineParams(
VADriverContextP pVaDrvCtx,
PDDI_VP_CONTEXT pVpCtx,
VAProcPipelineParameterBuffer* pPipelineParam)
{
PVPHAL_RENDER_PARAMS pVpHalRenderParams;
PDDI_MEDIA_CONTEXT pMediaCtx;
PDDI_MEDIA_SURFACE pMediaSrcSurf;
PDDI_MEDIA_BUFFER pFilterBuf;
void *pData;
uint32_t i;
PVPHAL_SURFACE pVpHalSrcSurf;
PVPHAL_SURFACE pVpHalTgtSurf;
uint32_t uSurfIndex;
uint32_t uScalingflags;
uint32_t uInterpolationflags;
uint32_t uChromaSitingFlags;
VAStatus vaStatus;
MOS_STATUS eStatus;
DDI_VP_STATE vpStateFlags;
PMOS_INTERFACE pOsInterface;
VP_DDI_FUNCTION_ENTER;
DDI_CHK_NULL(pVaDrvCtx, "Null pVaDrvCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
// initialize
pMediaCtx = DdiMedia_GetMediaContext(pVaDrvCtx);
DDI_CHK_NULL(pMediaCtx, "Null pMediaCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
pMediaSrcSurf = DdiMedia_GetSurfaceFromVASurfaceID(pMediaCtx, pPipelineParam->surface);
pVpHalRenderParams = pVpCtx->pVpHalRenderParams;
DDI_CHK_NULL(pVpHalRenderParams, "Null pVpHalRenderParams.", VA_STATUS_ERROR_INVALID_PARAMETER);
pFilterBuf = nullptr;
pData = nullptr;
uSurfIndex = 0;
pOsInterface = pVpCtx->pVpHal->GetOsInterface();
uInterpolationflags = 0;
memset(&vpStateFlags, 0, sizeof(vpStateFlags));
DDI_CHK_NULL(pMediaSrcSurf, "Null pMediaSrcSurf.", VA_STATUS_ERROR_INVALID_BUFFER);
DDI_CHK_NULL(pOsInterface, "Null pOsInterface.", VA_STATUS_ERROR_INVALID_BUFFER);
// increment surface count
pVpHalRenderParams->uSrcCount++;
// check if the surface count exceeded maximum VPHAL surfaces
DDI_CHK_CONDITION((pVpHalRenderParams->uSrcCount > VPHAL_MAX_SOURCES),
"Surface count exceeds maximum!", VA_STATUS_ERROR_MAX_NUM_EXCEEDED);
// update surface uSurfIndex
uSurfIndex = pVpHalRenderParams->uSrcCount - 1;
pVpHalSrcSurf = pVpHalRenderParams->pSrc[uSurfIndex];
pVpHalSrcSurf->Format = VpGetFormatFromMediaFormat(pMediaSrcSurf->format);
pVpHalSrcSurf->TileType = VpGetTileTypeFromMediaTileType(pMediaSrcSurf->TileType);
DDI_CHK_CONDITION((Format_Invalid == pVpHalSrcSurf->Format),
"Invalid surface media format!", VA_STATUS_ERROR_INVALID_PARAMETER);
#if (_DEBUG || _RELEASE_INTERNAL)
if (pVpCtx->pCurVpDumpDDIParam != nullptr &&
pVpCtx->pCurVpDumpDDIParam->pPipelineParamBuffers[uSurfIndex] != nullptr)
{
MOS_SecureMemcpy(pVpCtx->pCurVpDumpDDIParam->pPipelineParamBuffers[uSurfIndex], sizeof(VAProcPipelineParameterBuffer), pPipelineParam, sizeof(VAProcPipelineParameterBuffer));
pVpCtx->pCurVpDumpDDIParam->SrcFormat[uSurfIndex] = pVpHalSrcSurf->Format;
}
#endif //(_DEBUG || _RELEASE_INTERNAL)
// Set stream type using pipeline_flags VA_PROC_PIPELINE_FAST flag
// Currently we only support 1 primary surface in VP
if (pPipelineParam->pipeline_flags & VA_PROC_PIPELINE_FAST)
{
pVpHalSrcSurf->SurfType = SURF_IN_SUBSTREAM;
}
else
{
if (pVpCtx->iPriSurfs < VP_MAX_PRIMARY_SURFS)
{
pVpHalSrcSurf->SurfType = SURF_IN_PRIMARY;
pVpCtx->iPriSurfs++;
}
else
{
pVpHalSrcSurf->SurfType = SURF_IN_SUBSTREAM;
}
}
// Set src rect
if (pPipelineParam->surface_region != nullptr)
{
pVpHalSrcSurf->rcSrc.top = pPipelineParam->surface_region->y;
pVpHalSrcSurf->rcSrc.left = pPipelineParam->surface_region->x;
pVpHalSrcSurf->rcSrc.right = pPipelineParam->surface_region->x + pPipelineParam->surface_region->width;
pVpHalSrcSurf->rcSrc.bottom = pPipelineParam->surface_region->y + pPipelineParam->surface_region->height;
if (pVpHalSrcSurf->rcSrc.top < 0)
{
pVpHalSrcSurf->rcSrc.top = 0;
}
if (pVpHalSrcSurf->rcSrc.left < 0)
{
pVpHalSrcSurf->rcSrc.left = 0;
}
if (pVpHalSrcSurf->rcSrc.right > pMediaSrcSurf->iWidth)
{
pVpHalSrcSurf->rcSrc.right = pMediaSrcSurf->iWidth;
}
if (pVpHalSrcSurf->rcSrc.bottom > pMediaSrcSurf->iRealHeight)
{
pVpHalSrcSurf->rcSrc.bottom = pMediaSrcSurf->iRealHeight;
}
}
else
{
// nullptr surface_region implies the whole surface
pVpHalSrcSurf->rcSrc.top = 0;
pVpHalSrcSurf->rcSrc.left = 0;
pVpHalSrcSurf->rcSrc.right = pMediaSrcSurf->iWidth;
pVpHalSrcSurf->rcSrc.bottom = pMediaSrcSurf->iRealHeight;
}
pVpHalTgtSurf = pVpHalRenderParams->pTarget[0];
DDI_CHK_NULL(pVpHalTgtSurf, "Null pVpHalTgtSurf.", VA_STATUS_ERROR_UNKNOWN);
// Set dest rect
if (pPipelineParam->output_region != nullptr)
{
pVpHalSrcSurf->rcDst.top = pPipelineParam->output_region->y;
pVpHalSrcSurf->rcDst.left = pPipelineParam->output_region->x;
pVpHalSrcSurf->rcDst.right = pPipelineParam->output_region->x + pPipelineParam->output_region->width;
pVpHalSrcSurf->rcDst.bottom = pPipelineParam->output_region->y + pPipelineParam->output_region->height;
}
else
{
pVpHalSrcSurf->rcDst.top = 0;
pVpHalSrcSurf->rcDst.left = 0;
pVpHalSrcSurf->rcDst.right = pVpHalTgtSurf->rcDst.right;
pVpHalSrcSurf->rcDst.bottom = pVpHalTgtSurf->rcDst.bottom;
}
if ((pVpHalTgtSurf->rcSrc.right < pVpHalSrcSurf->rcDst.right) ||
(pVpHalTgtSurf->rcSrc.bottom < pVpHalSrcSurf->rcDst.bottom))
{
DDI_CHK_CONDITION(true, "Invalid color fill parameter!", VA_STATUS_ERROR_INVALID_PARAMETER);
}
//set the frame_id
pVpHalSrcSurf->FrameID = pMediaSrcSurf->frame_idx;
//In order to refresh the frame ID in DdiVp_UpdateFilterParamBuffer when run ADI case,
//we need to set the OS resource here.
pVpHalSrcSurf->OsResource.bo = pMediaSrcSurf->bo;
// csc option
//---------------------------------------
// Set color space for src
#if (VA_MAJOR_VERSION < 1)
vaStatus = DdiVp_GetColorSpace(pVpHalSrcSurf, pPipelineParam->surface_color_standard, pPipelineParam->input_surface_flag);
#else
vaStatus = DdiVp_GetColorSpace(pVpHalSrcSurf, pPipelineParam->surface_color_standard, pPipelineParam->input_color_properties);
#endif
DDI_CHK_RET(vaStatus, "Unsupport Color space!");
if(pMediaSrcSurf->format == Media_Format_400P)
{
pVpHalSrcSurf->ColorSpace = CSpace_BT601Gray;
}
// extended gamut? RGB can't have extended gamut flag
pVpHalSrcSurf->ExtendedGamut = false;
// Background Colorfill
// According to libva definition, if alpha in output background color is zero, then colorfill is not needed
if ((pPipelineParam->output_background_color >> 24) != 0)
{
if (pVpHalRenderParams->pColorFillParams == nullptr)
{
pVpHalRenderParams->pColorFillParams = (PVPHAL_COLORFILL_PARAMS)MOS_AllocAndZeroMemory(sizeof(VPHAL_COLORFILL_PARAMS));
}
DDI_CHK_NULL(pVpHalRenderParams->pColorFillParams, "Null pColorFillParams.", VA_STATUS_ERROR_UNKNOWN);
// set background colorfill option
pVpHalRenderParams->pColorFillParams->Color = pPipelineParam->output_background_color;
pVpHalRenderParams->pColorFillParams->bYCbCr = false;
pVpHalRenderParams->pColorFillParams->CSpace = CSpace_sRGB;
}else
{
MOS_FreeMemAndSetNull(pVpHalRenderParams->pColorFillParams);
}
// Set Demo Mode option
if (pVpHalRenderParams->bDisableDemoMode == false)
{
eStatus = VpHal_DdiSetupSplitScreenDemoMode(
0, // No DDI setting on Linux. Set it when Linux DDI supports it
0, // No DDI setting on Linux. Set it when Linux DDI supports it
&pVpHalRenderParams->pSplitScreenDemoModeParams,
&pVpHalRenderParams->bDisableDemoMode,
pOsInterface);
if (MOS_STATUS_SUCCESS != eStatus)
{
VP_DDI_ASSERTMESSAGE("Failed to setup Split-Screen Demo Mode.");
MOS_FreeMemAndSetNull(pVpHalRenderParams->pSplitScreenDemoModeParams);
}
}
// Update fwd and bkward ref frames: Required for Advanced processing - will be supported in the future
pVpHalSrcSurf->uFwdRefCount = pPipelineParam->num_forward_references;
vaStatus = DdiVp_UpdateProcPipelineForwardReferenceFrames(pVpCtx, pVaDrvCtx, pVpHalSrcSurf, pPipelineParam);
DDI_CHK_RET(vaStatus, "Failed to update forward reference frames!");
pVpHalSrcSurf->uBwdRefCount = pPipelineParam->num_backward_references;
vaStatus = DdiVp_UpdateProcPipelineBackwardReferenceFrames(pVpCtx, pVaDrvCtx, pVpHalSrcSurf, pPipelineParam);
DDI_CHK_RET(vaStatus, "Failed to update backward reference frames!");
// Check if filter values changed,if yes, then reset all filters for this surface
// intialize the filter parameter
// Parameters once set in the surface will be keep till video complete
// so the parameter of rendered surface should be intialized every time
if (pVpHalRenderParams->bStereoMode)
{
pVpHalSrcSurf->Rotation = VPHAL_ROTATION_IDENTITY;
}
// Progressive or interlaced - Check filter_flags
// if the deinterlace parameters is not set, manipulate it as a progressive video.
if (pPipelineParam->filter_flags & VA_TOP_FIELD)
{
pVpHalSrcSurf->SampleType = SAMPLE_INTERLEAVED_EVEN_FIRST_TOP_FIELD;
}
else if (pPipelineParam->filter_flags & VA_BOTTOM_FIELD)
{
pVpHalSrcSurf->SampleType = SAMPLE_INTERLEAVED_EVEN_FIRST_BOTTOM_FIELD;
}
else // VA_FRAME_PICTURE
{
pVpHalSrcSurf->SampleType = SAMPLE_PROGRESSIVE;
//if the deinterlace parameters is set, clear it.
if (pVpHalSrcSurf->pDeinterlaceParams != nullptr)
{
MOS_FreeMemAndSetNull(pVpHalSrcSurf->pDeinterlaceParams);
}
}
for (i = 0; i < pPipelineParam->num_filters; i++)
{
VABufferID filter = pPipelineParam->filters[i];
pFilterBuf = DdiMedia_GetBufferFromVABufferID(pMediaCtx, filter);
DDI_CHK_NULL(pFilterBuf, "Null pFilterBuf!", VA_STATUS_ERROR_INVALID_BUFFER);
DDI_CHK_CONDITION((VAProcFilterParameterBufferType != pFilterBuf->uiType),
"Invalid parameter buffer type!", VA_STATUS_ERROR_INVALID_PARAMETER);
// Map Buffer data to virtual addres space
DdiMedia_MapBuffer(pVaDrvCtx, filter, &pData);
VAProcFilterParameterBufferBase* filter_param = (VAProcFilterParameterBufferBase*) pData;
// HSBC can only be applied to the primary layer
if (!((filter_param->type == VAProcFilterColorBalance)
&& pVpHalSrcSurf->SurfType != SURF_IN_PRIMARY))
{
// Pass the filter type
vaStatus = DdiVp_UpdateFilterParamBuffer(pVpCtx, uSurfIndex, filter_param->type, pData, pFilterBuf->uiNumElements, &vpStateFlags);
DDI_CHK_RET(vaStatus, "Failed to update parameter buffer!");
}
}
DdiVp_ClearFilterParamBuffer(pVpCtx, uSurfIndex, vpStateFlags);
// Update the Deinterlace params
//vaStatus = DdiVp_UpdateProcDeinterlaceParams(pVaDrvCtx, pVpHalSrcSurf, pPipelineParam);
//DDI_CHK_RET(vaStatus, "Failed to update vphal advance deinterlace!");
// Use Render to do scaling for resolution larger than 8K
if(MEDIA_IS_WA(&pMediaCtx->WaTable, WaDisableVeboxFor8K))
{
pVpHalRenderParams->bDisableVeboxFor8K = true;
}
// Scaling algorithm
uScalingflags = pPipelineParam->filter_flags & VA_FILTER_SCALING_MASK;
pVpHalSrcSurf->ScalingPreference = VPHAL_SCALING_PREFER_SFC; // default
// Interpolation method
#if VA_CHECK_VERSION(1, 9, 0)
uInterpolationflags = pPipelineParam->filter_flags & VA_FILTER_INTERPOLATION_MASK;
#endif
switch (uScalingflags)
{
case VA_FILTER_SCALING_FAST:
if (pVpHalSrcSurf->SurfType == SURF_IN_PRIMARY)
{
VpSetInterpolationParams(pVpHalSrcSurf, uInterpolationflags);
pVpHalSrcSurf->ScalingPreference = VPHAL_SCALING_PREFER_SFC_FOR_VEBOX;
}
else
{
pVpHalSrcSurf->ScalingMode = VPHAL_SCALING_BILINEAR;
}
break;
case VA_FILTER_SCALING_HQ:
if (pVpHalSrcSurf->SurfType == SURF_IN_PRIMARY)
{
VpSetInterpolationParams(pVpHalSrcSurf, uInterpolationflags);
pVpHalSrcSurf->ScalingPreference = VPHAL_SCALING_PREFER_COMP;
}
else
{
pVpHalSrcSurf->ScalingMode = VPHAL_SCALING_BILINEAR;
}
break;
case VA_FILTER_SCALING_DEFAULT:
case VA_FILTER_SCALING_NL_ANAMORPHIC:
default:
if (pVpHalSrcSurf->SurfType == SURF_IN_PRIMARY)
{
VpSetInterpolationParams(pVpHalSrcSurf, uInterpolationflags);
pVpHalSrcSurf->ScalingPreference = VPHAL_SCALING_PREFER_SFC;
}
else
{
pVpHalSrcSurf->ScalingMode = VPHAL_SCALING_BILINEAR;
}
break;
}
//init interlace scaling flag
pVpHalSrcSurf->bInterlacedScaling = false;
pVpHalSrcSurf->bFieldWeaving = false;
if (pVpHalSrcSurf->pDeinterlaceParams == nullptr)
{
if (pPipelineParam->input_surface_flag & VA_TOP_FIELD_FIRST)
{
if (pPipelineParam->output_surface_flag & VA_TOP_FIELD_FIRST)
{
pVpHalSrcSurf->InterlacedScalingType = ISCALING_INTERLEAVED_TO_INTERLEAVED;
pVpHalSrcSurf->SampleType = SAMPLE_INTERLEAVED_EVEN_FIRST_TOP_FIELD;
pVpHalSrcSurf->bInterlacedScaling = true;
pVpHalSrcSurf->bFieldWeaving = false;
}else if (pPipelineParam->output_surface_flag & VA_TOP_FIELD)
{
pVpHalSrcSurf->InterlacedScalingType = ISCALING_INTERLEAVED_TO_FIELD;
pVpHalSrcSurf->SampleType = SAMPLE_INTERLEAVED_EVEN_FIRST_TOP_FIELD;
pVpHalTgtSurf->SampleType = SAMPLE_SINGLE_TOP_FIELD;
pVpHalSrcSurf->bInterlacedScaling = false;
pVpHalSrcSurf->bFieldWeaving = false;
}else if (pPipelineParam->output_surface_flag & VA_BOTTOM_FIELD)
{
pVpHalSrcSurf->InterlacedScalingType = ISCALING_INTERLEAVED_TO_FIELD;
pVpHalSrcSurf->SampleType = SAMPLE_INTERLEAVED_EVEN_FIRST_BOTTOM_FIELD;
pVpHalTgtSurf->SampleType = SAMPLE_SINGLE_BOTTOM_FIELD;
pVpHalSrcSurf->bInterlacedScaling = false;
pVpHalSrcSurf->bFieldWeaving = false;
}else
{
VP_DDI_ASSERTMESSAGE("output_surface_flag need to be set for interlaced scaling.");
pVpHalSrcSurf->SampleType = SAMPLE_PROGRESSIVE;
pVpHalSrcSurf->InterlacedScalingType = ISCALING_NONE;
pVpHalSrcSurf->bInterlacedScaling = false;
pVpHalSrcSurf->bFieldWeaving = false;
}
}
else if (pPipelineParam->input_surface_flag & VA_BOTTOM_FIELD_FIRST)
{
if (pPipelineParam->output_surface_flag & VA_BOTTOM_FIELD_FIRST)
{
pVpHalSrcSurf->InterlacedScalingType = ISCALING_INTERLEAVED_TO_INTERLEAVED;
pVpHalSrcSurf->SampleType = SAMPLE_INTERLEAVED_ODD_FIRST_BOTTOM_FIELD;
pVpHalSrcSurf->bInterlacedScaling = true;
pVpHalSrcSurf->bFieldWeaving = false;
}else if (pPipelineParam->output_surface_flag & VA_TOP_FIELD)
{
pVpHalSrcSurf->InterlacedScalingType = ISCALING_INTERLEAVED_TO_FIELD;
pVpHalSrcSurf->SampleType = SAMPLE_INTERLEAVED_ODD_FIRST_TOP_FIELD;
pVpHalTgtSurf->SampleType = SAMPLE_SINGLE_TOP_FIELD;
pVpHalSrcSurf->bInterlacedScaling = false;
pVpHalSrcSurf->bFieldWeaving = false;
}else if (pPipelineParam->output_surface_flag & VA_BOTTOM_FIELD)
{
pVpHalSrcSurf->InterlacedScalingType = ISCALING_INTERLEAVED_TO_FIELD;
pVpHalSrcSurf->SampleType = SAMPLE_INTERLEAVED_ODD_FIRST_BOTTOM_FIELD;
pVpHalTgtSurf->SampleType = SAMPLE_SINGLE_BOTTOM_FIELD;
pVpHalSrcSurf->bInterlacedScaling = false;
pVpHalSrcSurf->bFieldWeaving = false;
}else
{
VP_DDI_ASSERTMESSAGE("output_surface_flag need to be set for interlaced scaling.");
pVpHalSrcSurf->SampleType = SAMPLE_PROGRESSIVE;
pVpHalSrcSurf->InterlacedScalingType = ISCALING_NONE;
pVpHalSrcSurf->bInterlacedScaling = false;
pVpHalSrcSurf->bFieldWeaving = false;
}
}else if (pPipelineParam->input_surface_flag & VA_TOP_FIELD)
{
if (pPipelineParam->output_surface_flag & VA_TOP_FIELD_FIRST)
{
pVpHalSrcSurf->InterlacedScalingType = ISCALING_FIELD_TO_INTERLEAVED;
pVpHalSrcSurf->SampleType = SAMPLE_SINGLE_TOP_FIELD;
pVpHalTgtSurf->SampleType = SAMPLE_INTERLEAVED_EVEN_FIRST_TOP_FIELD;
DDI_CHK_NULL(pVpHalSrcSurf->pBwdRef, "No Ref Field!", VA_STATUS_ERROR_UNIMPLEMENTED);
pVpHalSrcSurf->pBwdRef->InterlacedScalingType = ISCALING_FIELD_TO_INTERLEAVED;
pVpHalSrcSurf->pBwdRef->SampleType = SAMPLE_SINGLE_BOTTOM_FIELD;
pVpHalSrcSurf->bInterlacedScaling = false;
pVpHalSrcSurf->bFieldWeaving = true;
}else if(pPipelineParam->output_surface_flag & VA_TOP_FIELD)
{
pVpHalSrcSurf->InterlacedScalingType = ISCALING_FIELD_TO_FIELD;
pVpHalSrcSurf->SampleType = SAMPLE_SINGLE_TOP_FIELD;
pVpHalSrcSurf->bInterlacedScaling = false;
pVpHalSrcSurf->bFieldWeaving = false;
}else
{
pVpHalSrcSurf->SampleType = SAMPLE_PROGRESSIVE;
pVpHalSrcSurf->bInterlacedScaling = false;
pVpHalSrcSurf->bFieldWeaving = false;
}
}else if (pPipelineParam->input_surface_flag & VA_BOTTOM_FIELD)
{
if (pPipelineParam->output_surface_flag & VA_BOTTOM_FIELD_FIRST)
{
pVpHalSrcSurf->InterlacedScalingType = ISCALING_FIELD_TO_INTERLEAVED;
pVpHalSrcSurf->SampleType = SAMPLE_SINGLE_BOTTOM_FIELD;
pVpHalTgtSurf->SampleType = SAMPLE_INTERLEAVED_ODD_FIRST_BOTTOM_FIELD;
DDI_CHK_NULL(pVpHalSrcSurf->pBwdRef, "No Ref Field!", VA_STATUS_ERROR_UNIMPLEMENTED);
pVpHalSrcSurf->pBwdRef->InterlacedScalingType = ISCALING_FIELD_TO_INTERLEAVED;
pVpHalSrcSurf->pBwdRef->SampleType = SAMPLE_SINGLE_TOP_FIELD;
pVpHalSrcSurf->bInterlacedScaling = false;
pVpHalSrcSurf->bFieldWeaving = true;
}else if(pPipelineParam->output_surface_flag & VA_BOTTOM_FIELD)
{
pVpHalSrcSurf->InterlacedScalingType = ISCALING_FIELD_TO_FIELD;
pVpHalSrcSurf->SampleType = SAMPLE_SINGLE_BOTTOM_FIELD;
pVpHalSrcSurf->bInterlacedScaling = false;
pVpHalSrcSurf->bFieldWeaving = false;
}else
{
pVpHalSrcSurf->SampleType = SAMPLE_PROGRESSIVE;
pVpHalSrcSurf->bInterlacedScaling = false;
pVpHalSrcSurf->bFieldWeaving = false;
}
}else
{
pVpHalSrcSurf->SampleType = SAMPLE_PROGRESSIVE;
pVpHalSrcSurf->InterlacedScalingType = ISCALING_NONE;
pVpHalSrcSurf->bInterlacedScaling = false;
pVpHalSrcSurf->bFieldWeaving = false;
}
}
// For legacy interlace scaling
if (pVpHalSrcSurf->pDeinterlaceParams == nullptr && pVpHalSrcSurf->InterlacedScalingType == ISCALING_NONE)
{
if (pPipelineParam->filter_flags & VA_TOP_FIELD)
{
pVpHalSrcSurf->SampleType = SAMPLE_INTERLEAVED_EVEN_FIRST_TOP_FIELD;
pVpHalSrcSurf->ScalingMode = VPHAL_SCALING_AVS;
pVpHalSrcSurf->bInterlacedScaling = true;
pVpHalSrcSurf->InterlacedScalingType = ISCALING_INTERLEAVED_TO_INTERLEAVED;
}
else if (pPipelineParam->filter_flags & VA_BOTTOM_FIELD)
{
pVpHalSrcSurf->SampleType = SAMPLE_INTERLEAVED_ODD_FIRST_BOTTOM_FIELD;
pVpHalSrcSurf->ScalingMode = VPHAL_SCALING_AVS;
pVpHalSrcSurf->bInterlacedScaling = true;
pVpHalSrcSurf->InterlacedScalingType = ISCALING_INTERLEAVED_TO_INTERLEAVED;
}
// Kernel does not support 3-plane interlaced AVS, so for 3-plane interlaced scaling, need to use bilinear.
if (pVpHalSrcSurf->bInterlacedScaling && IS_PL3_FORMAT(pVpHalSrcSurf->Format))
{
pVpHalSrcSurf->ScalingMode = VPHAL_SCALING_BILINEAR;
}
}
// For weave DI
if (pVpHalSrcSurf->pDeinterlaceParams == nullptr)
{
if ((pPipelineParam->filter_flags & 0x00000004) || ((pPipelineParam->filter_flags & VA_TOP_FIELD) && pVpHalSrcSurf->bFieldWeaving))
{
pVpHalSrcSurf->SampleType = SAMPLE_SINGLE_TOP_FIELD;
if (pVpHalSrcSurf->pBwdRef != nullptr)
{
pVpHalSrcSurf->pBwdRef->SampleType = SAMPLE_SINGLE_BOTTOM_FIELD;
}
pVpHalSrcSurf->ScalingMode = VPHAL_SCALING_BILINEAR;
pVpHalSrcSurf->bFieldWeaving = true;
}
if ((pPipelineParam->filter_flags & 0x00000008) || ((pPipelineParam->filter_flags & VA_BOTTOM_FIELD) && pVpHalSrcSurf->bFieldWeaving))
{
pVpHalSrcSurf->SampleType = SAMPLE_SINGLE_BOTTOM_FIELD;
if (pVpHalSrcSurf->pBwdRef != nullptr)
{
pVpHalSrcSurf->pBwdRef->SampleType = SAMPLE_SINGLE_TOP_FIELD;
}
pVpHalSrcSurf->ScalingMode = VPHAL_SCALING_BILINEAR;
pVpHalSrcSurf->bFieldWeaving = true;
}
}
// Rotation
vaStatus = VpUpdateProcRotateState(pVpHalSrcSurf,pPipelineParam->rotation_state);
DDI_CHK_RET(vaStatus, "Failed to update rotate state!");
// Mirror
vaStatus = VpUpdateProcMirrorState(pVpHalSrcSurf,pPipelineParam->mirror_state);
DDI_CHK_RET(vaStatus, "Failed to update mirror state!");
// Alpha blending
// Note: the alpha blending region cannot overlay
vaStatus = DdiVp_SetProcPipelineBlendingParams(pVpCtx, uSurfIndex, pPipelineParam);
DDI_CHK_RET(vaStatus, "Failed to update Alpha Blending parameter!");
if (IsProcmpEnable(pVpHalSrcSurf))
{
// correct the ChromaSitting location if Procamp is enabled.
#if (VA_MAJOR_VERSION < 1)
pPipelineParam->input_surface_flag = VA_CHROMA_SITING_HORIZONTAL_LEFT | VA_CHROMA_SITING_VERTICAL_TOP;
pPipelineParam->output_surface_flag = VA_CHROMA_SITING_HORIZONTAL_LEFT | VA_CHROMA_SITING_VERTICAL_TOP;
#else
pPipelineParam->input_color_properties.chroma_sample_location = VA_CHROMA_SITING_HORIZONTAL_LEFT | VA_CHROMA_SITING_VERTICAL_TOP;
pPipelineParam->output_color_properties.chroma_sample_location = VA_CHROMA_SITING_HORIZONTAL_LEFT | VA_CHROMA_SITING_VERTICAL_TOP;
#endif
}
#if (VA_MAJOR_VERSION < 1)
VpUpdateProcChromaSittingState(pVpHalSrcSurf, (uint8_t)(pPipelineParam->input_surface_flag&0xff));
VpUpdateProcChromaSittingState(pVpHalTgtSurf, (uint8_t)(pPipelineParam->output_surface_flag&0xff));
#else
VpUpdateProcChromaSittingState(pVpHalSrcSurf, pPipelineParam->input_color_properties.chroma_sample_location);
VpUpdateProcChromaSittingState(pVpHalTgtSurf, pPipelineParam->output_color_properties.chroma_sample_location);
#endif
// update OsResource for src surface
pVpHalSrcSurf->OsResource.Format = VpGetFormatFromMediaFormat(pMediaSrcSurf->format);
pVpHalSrcSurf->OsResource.iWidth = pMediaSrcSurf->iWidth;
pVpHalSrcSurf->OsResource.iHeight = pMediaSrcSurf->iHeight;
pVpHalSrcSurf->OsResource.iPitch = pMediaSrcSurf->iPitch;
pVpHalSrcSurf->OsResource.iCount = pMediaSrcSurf->iRefCount;
pVpHalSrcSurf->OsResource.bo = pMediaSrcSurf->bo;
pVpHalSrcSurf->OsResource.TileType = VpGetTileTypeFromMediaTileType(pMediaSrcSurf->TileType);
pVpHalSrcSurf->OsResource.pGmmResInfo = pMediaSrcSurf->pGmmResourceInfo;
Mos_Solo_SetOsResource(pMediaSrcSurf->pGmmResourceInfo, &pVpHalSrcSurf->OsResource);
//Set encryption bit for input surface
//This setting only used for secure VPP test app which do secure VP and provide secure YUV as input
//Since APP cannot set encryption flag, it will set input_surface_flag to ask driver add encryption bit to input surface
if (pOsInterface->osCpInterface->IsHMEnabled() && (pPipelineParam->input_surface_flag & VPHAL_SURFACE_ENCRYPTION_FLAG))
{
pOsInterface->osCpInterface->SetResourceEncryption(&(pVpHalSrcSurf->OsResource), true);
}
// Update the Render Target params - this needs to be done once when Render Target is passed via BeginPicture
vaStatus = DdiVp_UpdateVphalTargetSurfColorSpace(pVaDrvCtx, pVpCtx, pPipelineParam, 0);
DDI_CHK_RET(vaStatus, "Failed to update vphal target surface color space!");
// Update the Render Target HDR params - this needs to be done once when Render Target is passed via BeginPicture
vaStatus = VpUpdateProcHdrState(pVpHalTgtSurf, pPipelineParam->output_hdr_metadata);
DDI_CHK_RET(vaStatus, "Failed to update vphal target surface HDR metadata!");
// Using additional_outputs processing as 1:N case.
for (i = 0; i < pPipelineParam->num_additional_outputs; i++)
{
vaStatus = DdiVp_BeginPictureInt(pVaDrvCtx, pVpCtx, pPipelineParam->additional_outputs[i]);
DDI_CHK_RET(vaStatus, "Failed to update vphal target surface buffers!");
vaStatus = DdiVp_UpdateVphalTargetSurfColorSpace(pVaDrvCtx, pVpCtx, pPipelineParam, i+1);
DDI_CHK_RET(vaStatus, "Failed to update vphal target surface color space!");
}
// add 16aligned UsrPtr mode support
if (pMediaSrcSurf->pSurfDesc && (pMediaSrcSurf->pSurfDesc->uiVaMemType == VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR))
{
pVpHalSrcSurf->b16UsrPtr = VpIs16UsrPtrPitch(pMediaSrcSurf->iPitch, pMediaSrcSurf->format);
}
else
{
pVpHalSrcSurf->b16UsrPtr = false;
}
return VA_STATUS_SUCCESS;
}
//////////////////////////////////////////////////////////////////////////////////////////////
//! \purpose: Get resource informaton from target surface, set OS Resource for VPHAL
//! \[in] pVpCtx : VP context
//! \[in] pboRt : media surface
//! \[in] targetIndex : index of target surface in VpHal RenderParams.
//! \[out] None
//! \returns: Result of operation
//////////////////////////////////////////////////////////////////////////////////////////////
VAStatus VpSetOsResource(
PDDI_VP_CONTEXT pVpCtx,
PDDI_MEDIA_SURFACE pboRt,
uint32_t targetIndex)
{
PMOS_RESOURCE pOsResource;
PVPHAL_RENDER_PARAMS pVpHalRenderParams;
VP_DDI_FUNCTION_ENTER;
DDI_CHK_NULL(pVpCtx, "Null pVpCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
// get vphal render parameters
pVpHalRenderParams = VpGetRenderParams(pVpCtx);
DDI_CHK_NULL(pVpHalRenderParams, "Null pVpHalRenderParams.", VA_STATUS_ERROR_INVALID_PARAMETER);
// set render target os resource information according to target surface
pOsResource = &pVpHalRenderParams->pTarget[targetIndex]->OsResource;
DDI_CHK_NULL(pOsResource, "Null pOsResource.", VA_STATUS_ERROR_INVALID_PARAMETER);
pOsResource->bo = pboRt->bo;
pOsResource->bMapped = pboRt->bMapped;
pOsResource->Format = VpGetFormatFromMediaFormat( pboRt->format );
pOsResource->iWidth = pboRt->iWidth;
pOsResource->iHeight = pboRt->iHeight;
pOsResource->iPitch = pboRt->iPitch;
pOsResource->iCount = pboRt->iRefCount;
pOsResource->TileType = VpGetTileTypeFromMediaTileType(pboRt->TileType);
pOsResource->pGmmResInfo = pboRt->pGmmResourceInfo;
Mos_Solo_SetOsResource(pboRt->pGmmResourceInfo, pOsResource);
return VA_STATUS_SUCCESS;
}
//////////////////////////////////////////////////////////////////////////////////////////////
//! \purpose Helper function for VpAllocateDrvCtxExt to Allocate PDDI_VP_CONTEXT
//! \params
//! [in] pVaDrvCtx : VA Driver context
//! [in] pVpCtx : VP context
//! [out] None
//! \returns VA_STATUS_SUCCESS if call succeeds
/////////////////////////////////////////////////////////////////////////////////////////////
VAStatus DdiVp_InitCtx(VADriverContextP pVaDrvCtx, PDDI_VP_CONTEXT pVpCtx)
{
PERF_UTILITY_AUTO(__FUNCTION__, PERF_VP, PERF_LEVEL_DDI);
PVPHAL_RENDER_PARAMS pVpHalRenderParams = nullptr;
int32_t uSurfIndex;
PDDI_MEDIA_CONTEXT pMediaCtx;
VAStatus vaStatus;
VP_DDI_FUNCTION_ENTER;
DDI_CHK_NULL(pVaDrvCtx, "Null pVaDrvCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
pMediaCtx = DdiMedia_GetMediaContext(pVaDrvCtx);
DDI_CHK_NULL(pMediaCtx, "Null pMediaCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
// initialize VPHAL
DDI_CHK_NULL(pVpCtx, "Null pVpCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
pVpCtx->MosDrvCtx.bufmgr = pMediaCtx->pDrmBufMgr;
pVpCtx->MosDrvCtx.m_gpuContextMgr = pMediaCtx->m_gpuContextMgr;
pVpCtx->MosDrvCtx.m_cmdBufMgr = pMediaCtx->m_cmdBufMgr;
pVpCtx->MosDrvCtx.fd = pMediaCtx->fd;
pVpCtx->MosDrvCtx.iDeviceId = pMediaCtx->iDeviceId;
pVpCtx->MosDrvCtx.SkuTable = pMediaCtx->SkuTable;
pVpCtx->MosDrvCtx.WaTable = pMediaCtx->WaTable;
pVpCtx->MosDrvCtx.gtSystemInfo = *pMediaCtx->pGtSystemInfo;
pVpCtx->MosDrvCtx.platform = pMediaCtx->platform;
pVpCtx->MosDrvCtx.m_auxTableMgr = pMediaCtx->m_auxTableMgr;
pVpCtx->MosDrvCtx.pGmmClientContext = pMediaCtx->pGmmClientContext;
pVpCtx->MosDrvCtx.ppMediaMemDecompState = &pMediaCtx->pMediaMemDecompState;
pVpCtx->MosDrvCtx.pfnMediaMemoryCopy = pMediaCtx->pfnMediaMemoryCopy;
pVpCtx->MosDrvCtx.pfnMediaMemoryCopy2D = pMediaCtx->pfnMediaMemoryCopy2D;
pVpCtx->MosDrvCtx.pfnMemoryDecompress = pMediaCtx->pfnMemoryDecompress;
pVpCtx->MosDrvCtx.ppMediaCopyState = &pMediaCtx->pMediaCopyState;
pVpCtx->MosDrvCtx.m_osDeviceContext = pMediaCtx->m_osDeviceContext;
pVpCtx->MosDrvCtx.m_apoMosEnabled = pMediaCtx->m_apoMosEnabled;
pVpCtx->MosDrvCtx.pPerfData = (PERF_DATA *)MOS_AllocAndZeroMemory(sizeof(PERF_DATA));
if (nullptr == pVpCtx->MosDrvCtx.pPerfData)
{
return VA_STATUS_ERROR_ALLOCATION_FAILED;
}
// initialize DDI level cp interface
pVpCtx->pCpDdiInterface = Create_DdiCpInterface(pVpCtx->MosDrvCtx);
if (nullptr == pVpCtx->pCpDdiInterface)
{
vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
goto FINISH;
}
DDI_CHK_RET(DdiVp_InitVpHal(pVpCtx), "Call DdiVp_InitVpHal failed");
// allocate vphal render param
pVpHalRenderParams = (PVPHAL_RENDER_PARAMS)(MOS_AllocAndZeroMemory(sizeof(VPHAL_RENDER_PARAMS)));
if( nullptr == pVpHalRenderParams)
{
vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
goto FINISH;
}
// initialize vphal render params
for (uSurfIndex = 0; uSurfIndex < VPHAL_MAX_SOURCES; uSurfIndex++)
{
pVpHalRenderParams->pSrc[uSurfIndex] = (PVPHAL_SURFACE)MOS_AllocAndZeroMemory(sizeof(VPHAL_SURFACE));
if( nullptr == pVpHalRenderParams->pSrc[uSurfIndex])
{
vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
goto FINISH;
}
}
for (uSurfIndex = 0; uSurfIndex < VPHAL_MAX_TARGETS; uSurfIndex++)
{
pVpHalRenderParams->pTarget[uSurfIndex] = (PVPHAL_SURFACE)MOS_AllocAndZeroMemory(sizeof(VPHAL_SURFACE));
if( nullptr == pVpHalRenderParams->pTarget[uSurfIndex])
{
vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
goto FINISH;
}
}
// background Colorfill
pVpHalRenderParams->pColorFillParams = (PVPHAL_COLORFILL_PARAMS)MOS_AllocAndZeroMemory(sizeof(VPHAL_COLORFILL_PARAMS));
if( nullptr == pVpHalRenderParams->pColorFillParams)
{
vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
goto FINISH;
}
// reset source surface count
pVpHalRenderParams->uSrcCount = 0;
pVpCtx->MosDrvCtx.wRevision = 0;
pVpCtx->iPriSurfs = 0;
// Add the render param for calculating alpha value.
// Because can not pass the alpha calculate flag from iVP,
// need to hardcode here for both Android and Linux.
pVpHalRenderParams->bCalculatingAlpha = true;
// put the render param in vp context
pVpCtx->pVpHalRenderParams = pVpHalRenderParams;
#if (_DEBUG || _RELEASE_INTERNAL)
vaStatus = VpInitDumpConfig(pVpCtx);
DDI_CHK_RET( vaStatus, "Init Dump Config failed");
#endif //(_DEBUG || _RELEASE_INTERNAL)
return VA_STATUS_SUCCESS;
FINISH:
if(pVpHalRenderParams)
{
for (uSurfIndex = 0; uSurfIndex < VPHAL_MAX_SOURCES; uSurfIndex++)
{
MOS_FreeMemory(pVpHalRenderParams->pSrc[uSurfIndex]);
}
for (uSurfIndex = 0; uSurfIndex < VPHAL_MAX_TARGETS; uSurfIndex++)
{
MOS_FreeMemory(pVpHalRenderParams->pTarget[uSurfIndex]);
}
MOS_FreeMemory(pVpHalRenderParams->pColorFillParams);
MOS_FreeMemory(pVpHalRenderParams);
}
if (pVpCtx->pCpDdiInterface)
{
Delete_DdiCpInterface(pVpCtx->pCpDdiInterface);
pVpCtx->pCpDdiInterface = NULL;
}
#if (_DEBUG || _RELEASE_INTERNAL)
VpDestoryDumpConfig(pVpCtx);
#endif //(_DEBUG || _RELEASE_INTERNAL)
return vaStatus;
}
//////////////////////////////////////////////////////////////////////////////////////////////
//! \purpose Initialize VPHAL State and VPHAL settings per VP context
//! \params
//! [in] pVpCtx : VP context
//! [out] None
//! \returns VA_STATUS_SUCCESS if call succeeds
/////////////////////////////////////////////////////////////////////////////////////////////
VAStatus
DdiVp_InitVpHal(
PDDI_VP_CONTEXT pVpCtx
)
{
PERF_UTILITY_AUTO(__FUNCTION__, PERF_VP, PERF_LEVEL_DDI);
VphalState *pVpHal;
VphalSettings VpHalSettings;
VAStatus vaStatus;
VP_DDI_FUNCTION_ENTER;
DDI_CHK_NULL(pVpCtx, "Null pVpCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
// initialize
vaStatus = VA_STATUS_ERROR_UNKNOWN;
pVpHal = nullptr;
// Create VpHal state
MOS_STATUS eStatus = MOS_STATUS_UNKNOWN;
pVpHal = VphalState::VphalStateFactory( nullptr, &(pVpCtx->MosDrvCtx), &eStatus);
if (pVpHal && MOS_FAILED(eStatus))
{
MOS_Delete(pVpHal);
pVpHal = nullptr;
}
if (!pVpHal)
{
VP_DDI_ASSERTMESSAGE("Failed to create vphal.");
MOS_FreeMemAndSetNull(pVpCtx);
return VA_STATUS_ERROR_ALLOCATION_FAILED;
}
if (nullptr != pVpHal)
{
VpHalSettings.maxPhases = VP_SETTING_MAX_PHASES;
VpHalSettings.mediaStates = VP_SETTING_MEDIA_STATES;
VpHalSettings.sameSampleThreshold = VP_SETTING_SAME_SAMPLE_THRESHOLD;
VpHalSettings.disableDnDi = false;
// Allocate resources (state heaps, resources, KDLL)
if (MOS_FAILED(pVpHal->Allocate(&VpHalSettings)))
{
VP_DDI_ASSERTMESSAGE("Failed to allocate resources for vphal.");
MOS_Delete(pVpHal);
pVpHal = nullptr;
return vaStatus;
}
}
pVpCtx->pVpHal = pVpHal;
return VA_STATUS_SUCCESS;
}
//////////////////////////////////////////////////////////////////////////////////////////////
////! \purpose Set Color Standard Explictly.
////! \params
////! [in] pVpHalSurf : src/target surface
////! [in] colorStandard : VA color standard VAProcColorStandardType
////! [in] colorProperties : input/output surface color properties
////! [out] None
////! \returns appropriate VA_STATUS_SUCCESS if call succeeds
///////////////////////////////////////////////////////////////////////////////////////////////
VAStatus VpSetColorStandardExplictly(PVPHAL_SURFACE pVpHalSurf, VAProcColorStandardType colorStandard, VAProcColorProperties colorProperties)
{
DDI_CHK_NULL(pVpHalSurf, "Null pVpHalSurf.", VA_STATUS_ERROR_INVALID_SURFACE);
DDI_CHK_CONDITION((colorStandard != VAProcColorStandardExplicit), "Not Explict color standard, Exit!", VA_STATUS_ERROR_INVALID_PARAMETER);
if (IS_RGB_FORMAT(pVpHalSurf->Format))
{
switch(colorProperties.colour_primaries)
{
case COLOUR_PRIMARY_BT2020:
pVpHalSurf->ColorSpace = (colorProperties.color_range & VA_SOURCE_RANGE_REDUCED) ? CSpace_BT2020_stRGB : CSpace_BT2020_RGB;
break;
case COLOUR_PRIMARY_BT709:
case COLOUR_PRIMARY_BT601:
pVpHalSurf->ColorSpace = (colorProperties.color_range & VA_SOURCE_RANGE_REDUCED) ? CSpace_stRGB: CSpace_sRGB;
break;
default:
pVpHalSurf->ColorSpace = CSpace_sRGB;
VP_DDI_ASSERTMESSAGE("unknown Color Standard for RGB format.");
break;
}
}
if (IS_YUV_FORMAT(pVpHalSurf->Format) || IS_ALPHA_YUV_FORMAT(pVpHalSurf->Format))
{
switch(colorProperties.colour_primaries)
{
case COLOUR_PRIMARY_BT2020:
pVpHalSurf->ColorSpace = (colorProperties.color_range & VA_SOURCE_RANGE_FULL) ? CSpace_BT2020_FullRange : CSpace_BT2020;
break;
case COLOUR_PRIMARY_BT709:
pVpHalSurf->ColorSpace = (colorProperties.color_range & VA_SOURCE_RANGE_FULL) ? CSpace_BT709_FullRange : CSpace_BT709;
break;
case COLOUR_PRIMARY_BT601:
pVpHalSurf->ColorSpace = (colorProperties.color_range & VA_SOURCE_RANGE_FULL) ? CSpace_BT601_FullRange : CSpace_BT601;
break;
default:
pVpHalSurf->ColorSpace = CSpace_BT601;
VP_DDI_ASSERTMESSAGE("unknown Color Standard for YUV format.");
break;
}
}
switch(colorProperties.transfer_characteristics)
{
case TRANSFER_CHARACTERISTICS_ST2084:
pVpHalSurf->GammaType = VPHAL_GAMMA_SMPTE_ST2084;
break;
default:
pVpHalSurf->GammaType = VPHAL_GAMMA_TRADITIONAL_GAMMA;
break;
}
return VA_STATUS_SUCCESS;
}
//////////////////////////////////////////////////////////////////////////////////////////////
////! \purpose Convert VAProcColorStandardType to VPHAL_CSPACE
////! \params
////! [in] pVpHalSurf : src/target surface
////! [in] colorStandard : VA color standard VAProcColorStandardType
////! [in] flag : input/output surface flag for full/reduced color range
////! [out] None
////! \returns appropriate VPHAL_CSPACE if call succeeds
///////////////////////////////////////////////////////////////////////////////////////////////
#if (VA_MAJOR_VERSION < 1)
VAStatus DdiVp_GetColorSpace(PVPHAL_SURFACE pVpHalSurf, VAProcColorStandardType colorStandard, uint32_t flag)
#else
VAStatus DdiVp_GetColorSpace(PVPHAL_SURFACE pVpHalSurf, VAProcColorStandardType colorStandard, VAProcColorProperties colorProperties)
#endif
{
uint8_t color_range = colorProperties.color_range;
pVpHalSurf->ColorSpace = CSpace_None;
VP_DDI_FUNCTION_ENTER;
// Convert VAProcColorStandardType to VPHAL_CSPACE
if (IS_RGB_FORMAT(pVpHalSurf->Format) || (pVpHalSurf->Format == Format_P8))
{
switch (colorStandard)
{
case VAProcColorStandardBT2020:
#if (VA_MAJOR_VERSION < 1)
if (flag & VA_SOURCE_RANGE_FULL)
#else
if (color_range == VA_SOURCE_RANGE_FULL)
#endif
{
pVpHalSurf->ColorSpace = CSpace_BT2020_RGB;
}
else
{
pVpHalSurf->ColorSpace = CSpace_BT2020_stRGB;
}
break;
case VAProcColorStandardSTRGB:
pVpHalSurf->ColorSpace = CSpace_stRGB;
break;
case VAProcColorStandardExplicit:
VpSetColorStandardExplictly(pVpHalSurf, colorStandard, colorProperties);
break;
case VAProcColorStandardSRGB:
default:
pVpHalSurf->ColorSpace = CSpace_sRGB;
break;
}
}
else
{
// Set colorspace by default to avoid application don't set ColorStandard
if (colorStandard == 0)
{
if ((pVpHalSurf->rcSrc.right - pVpHalSurf->rcSrc.left) <= 1280 && (pVpHalSurf->rcSrc.bottom - pVpHalSurf->rcSrc.top) <= 720)
{
pVpHalSurf->ColorSpace = CSpace_BT601;
}//720p
else if ((pVpHalSurf->rcSrc.right - pVpHalSurf->rcSrc.left) <= 1920 && (pVpHalSurf->rcSrc.bottom - pVpHalSurf->rcSrc.top) <= 1080)
{
pVpHalSurf->ColorSpace = CSpace_BT709;
}//1080p
else
{
if (pVpHalSurf->Format == Format_P010 || pVpHalSurf->Format == Format_P016)
{
pVpHalSurf->ColorSpace = CSpace_BT2020;
}
else
{
pVpHalSurf->ColorSpace = CSpace_BT709;
}
}//4K
}
else
{
switch (colorStandard)
{
case VAProcColorStandardBT709:
#if (VA_MAJOR_VERSION < 1)
if (flag & VA_SOURCE_RANGE_FULL)
#else
if (color_range == VA_SOURCE_RANGE_FULL)
#endif
{
pVpHalSurf->ColorSpace = CSpace_BT709_FullRange;
}
else
{
pVpHalSurf->ColorSpace = CSpace_BT709;
}
break;
case VAProcColorStandardBT601:
#if (VA_MAJOR_VERSION < 1)
if (flag & VA_SOURCE_RANGE_FULL)
#else
if (color_range == VA_SOURCE_RANGE_FULL)
#endif
{
pVpHalSurf->ColorSpace = CSpace_BT601_FullRange;
}
else
{
pVpHalSurf->ColorSpace = CSpace_BT601;
}
break;
case VAProcColorStandardBT2020:
#if (VA_MAJOR_VERSION < 1)
if (flag & VA_SOURCE_RANGE_FULL)
#else
if (color_range == VA_SOURCE_RANGE_FULL)
#endif
{
pVpHalSurf->ColorSpace = CSpace_BT2020_FullRange;
}
else
{
pVpHalSurf->ColorSpace = CSpace_BT2020;
}
break;
case VAProcColorStandardBT470M:
case VAProcColorStandardBT470BG:
case VAProcColorStandardSMPTE170M:
case VAProcColorStandardSMPTE240M:
case VAProcColorStandardGenericFilm:
case VAProcColorStandardXVYCC601:
case VAProcColorStandardXVYCC709:
pVpHalSurf->ColorSpace == CSpace_None;
break;
case VAProcColorStandardExplicit:
VpSetColorStandardExplictly(pVpHalSurf, colorStandard, colorProperties);
break;
default:
pVpHalSurf->ColorSpace == CSpace_BT601;
break;
}
}
}
DDI_CHK_CONDITION((pVpHalSurf->ColorSpace == CSpace_None), "Invalid color standard", VA_STATUS_ERROR_INVALID_PARAMETER);
return VA_STATUS_SUCCESS;
}
//////////////////////////////////////////////////////////////////////////////////////////////
//! \purpose Get ColorSpace from the media format
//! \params
//! [in] format : media format
//! [out] None
//! \returns appropriate VPHAL_CSPACE if call succeeds, CSpace_None otherwise
/////////////////////////////////////////////////////////////////////////////////////////////
VPHAL_CSPACE DdiVp_GetColorSpaceFromMediaFormat(DDI_MEDIA_FORMAT format)
{
MOS_FORMAT mosFormat = VpGetFormatFromMediaFormat(format);
if (IS_RGB_FORMAT(mosFormat))
{
return CSpace_sRGB;
}
else
{
return CSpace_BT601;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//! \purpose Extract Render Target params from VAProcPipelineParameterBuffer and set the appropriate VPHAL params for RT
//! \params
//! [in] pVaDrvCtx : VA Driver context
//! [in] pVpCtx : VP context
//! [in] pPipelineParam : VAProcPipelineParameterBuffer Pipeline paramseter from application
//! [out] None
//! \returns VA_STATUS_SUCCESS if call succeeds
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
VAStatus
DdiVp_UpdateVphalTargetSurfColorSpace(
VADriverContextP pVaDrvCtx,
PDDI_VP_CONTEXT pVpCtx,
VAProcPipelineParameterBuffer* pPipelineParam,
uint32_t targetIndex)
{
PVPHAL_RENDER_PARAMS pVpHalRenderParams;
PVPHAL_SURFACE pVpHalSrcSurf;
PVPHAL_SURFACE pVpHalTgtSurf;
VAStatus vaStatus;
DDI_UNUSED(pVaDrvCtx);
VP_DDI_FUNCTION_ENTER;
DDI_CHK_NULL(pVpCtx, "Null pVpCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
// initialize
pVpHalRenderParams = VpGetRenderParams(pVpCtx);
DDI_CHK_NULL(pVpHalRenderParams, "Null pVpHalRenderParams.", VA_STATUS_ERROR_INVALID_PARAMETER);
pVpHalTgtSurf = pVpHalRenderParams->pTarget[targetIndex];
DDI_CHK_NULL(pVpHalTgtSurf, "Null pVpHalTgtSurf.", VA_STATUS_ERROR_INVALID_SURFACE);
// update target surface color space
#if (VA_MAJOR_VERSION < 1)
vaStatus = DdiVp_GetColorSpace(pVpHalTgtSurf, pPipelineParam->output_color_standard, pPipelineParam->output_surface_flag);
#else
vaStatus = DdiVp_GetColorSpace(pVpHalTgtSurf, pPipelineParam->output_color_standard, pPipelineParam->output_color_properties);
#endif
pVpHalSrcSurf = pVpHalRenderParams->pSrc[0];
// Not support BT601/BT709 -> BT2020 colorspace conversion, if colorspace is not set, will keep it same with input.
if(pVpHalSrcSurf != nullptr &&
pPipelineParam->output_color_standard == 0 &&
IS_COLOR_SPACE_BT2020(pVpHalTgtSurf->ColorSpace) &&
!IS_COLOR_SPACE_BT2020(pVpHalSrcSurf->ColorSpace))
{
pVpHalTgtSurf->ColorSpace = pVpHalSrcSurf->ColorSpace;
}
// extended gamut?
pVpHalRenderParams->pTarget[0]->ExtendedGamut = false;
return vaStatus;
}
//////////////////////////////////////////////////////////////////////////////////////////////
//! \purpose Setup the appropriate filter params for VPHAL input surface based on Filter type
//! \params
//! [in] pVpCtx : VP context
//! [in] uSurfIndex : uSurfIndex to the input surface array
//! [in] FilterType : Filter type
//! [in] pData : Buffer data
//! [in] uElementNum : number of elements in the buffer(FilterParameter)
//! [in] vpStateFlags : filter enable status
//! [out] None
//! \returns VA_STATUS_SUCCESS if call succeeds
//////////////////////////////////////////////////////////////////////////////////////////////
VAStatus
DdiVp_UpdateFilterParamBuffer(
PDDI_VP_CONTEXT pVpCtx,
uint32_t uSurfIndex,
int32_t FilterType,
void *pData,
uint32_t uElementNum,
DDI_VP_STATE* vpStateFlags)
{
VAStatus vaStatus;
VP_DDI_FUNCTION_ENTER;
DDI_CHK_NULL(pVpCtx, "Null pVpCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
vaStatus = VA_STATUS_SUCCESS;
switch (FilterType){
case VAProcFilterDeinterlacing:
vpStateFlags->bDeinterlaceEnable = true;
vaStatus = DdiVp_SetProcFilterDinterlaceParams(
pVpCtx,
uSurfIndex,
(VAProcFilterParameterBufferDeinterlacing*) pData);
break;
case VAProcFilterNoiseReduction:
vpStateFlags->bDenoiseEnable = true;
vaStatus = DdiVp_SetProcFilterDenoiseParams(
pVpCtx,
uSurfIndex,
(VAProcFilterParameterBuffer*) pData);
break;
case VAProcFilterSharpening:
vpStateFlags->bIEFEnable = true;
vaStatus = DdiVp_SetProcFilterSharpnessParams(
pVpCtx,
uSurfIndex,
(VAProcFilterParameterBuffer*) pData);
break;
case VAProcFilterColorBalance:
vpStateFlags->bProcampEnable = true;
vaStatus = DdiVp_SetProcFilterColorBalanceParams(
pVpCtx,
uSurfIndex,
(VAProcFilterParameterBufferColorBalance*) pData,
uElementNum);
break;
case VAProcFilterSkinToneEnhancement:
vaStatus = DdiVp_SetProcFilterSkinToneEnhancementParams(
pVpCtx,
uSurfIndex,
(VAProcFilterParameterBuffer*) pData);
break;
case VAProcFilterTotalColorCorrection:
vaStatus = DdiVp_SetProcFilterTotalColorCorrectionParams(
pVpCtx,
uSurfIndex,
(VAProcFilterParameterBufferTotalColorCorrection*) pData,
uElementNum);
break;
case VAProcFilterHighDynamicRangeToneMapping:
vaStatus = DdiVp_SetProcFilterHdrTmParams(
pVpCtx,
uSurfIndex,
(VAProcFilterParameterBufferHDRToneMapping*) pData);
break;
case VAProcFilterNone:
vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
break;
default:
VP_DDI_ASSERTMESSAGE("VAProcFilterType is unknown.");
vaStatus = VA_STATUS_ERROR_UNSUPPORTED_FILTER;
break;
}// switch (type)
return vaStatus;
}
//////////////////////////////////////////////////////////////////////////////////////////////
//! \purpose clear filter params which is disabled for VPHAL input surface
//! \params
//! [in] pVpCtx : VP context
//! [in] uSurfIndex : uSurfIndex to the input surface array
//! [in] vpStateFlags : filter enable status
//! [out] None
//! \returns VA_STATUS_SUCCESS if call succeeds
//////////////////////////////////////////////////////////////////////////////////////////////
VAStatus DdiVp_ClearFilterParamBuffer(
PDDI_VP_CONTEXT pVpCtx,
uint32_t uSurfIndex,
DDI_VP_STATE vpStateFlags)
{
if(!vpStateFlags.bProcampEnable)
{
MOS_FreeMemAndSetNull(pVpCtx->pVpHalRenderParams->pSrc[uSurfIndex]->pProcampParams);
}
if(!vpStateFlags.bDeinterlaceEnable)
{
MOS_FreeMemAndSetNull(pVpCtx->pVpHalRenderParams->pSrc[uSurfIndex]->pDeinterlaceParams);
}
if(!vpStateFlags.bDenoiseEnable)
{
MOS_FreeMemAndSetNull(pVpCtx->pVpHalRenderParams->pSrc[uSurfIndex]->pDenoiseParams);
}
if(!vpStateFlags.bIEFEnable)
{
if (pVpCtx->pVpHalRenderParams->pSrc[uSurfIndex]->pIEFParams)
{
MOS_FreeMemAndSetNull(pVpCtx->pVpHalRenderParams->pSrc[uSurfIndex]->pIEFParams->pExtParam);
MOS_FreeMemAndSetNull(pVpCtx->pVpHalRenderParams->pSrc[uSurfIndex]->pIEFParams);
}
}
return VA_STATUS_SUCCESS;
}
////////////////////////////////////////////////////////////////////////////////
//! \purpose Set DI filter params for input VPHAL surface
//! \params
//! [in] pVpCtx : VP context
//! [in] uSurfIndex : uSurfIndex to the input surface array
//! [in] pDiParamBuff : Pointer to DI param buffer data
//! [out] None
//! \returns VA_STATUS_SUCCESS if call succeeds
////////////////////////////////////////////////////////////////////////////////
VAStatus
DdiVp_SetProcFilterDinterlaceParams(
PDDI_VP_CONTEXT pVpCtx,
uint32_t uSurfIndex,
VAProcFilterParameterBufferDeinterlacing* pDiParamBuff)
{
PVPHAL_RENDER_PARAMS pVpHalRenderParams;
PVPHAL_SURFACE pTarget;
PVPHAL_SURFACE pSrc;
VPHAL_DI_MODE DIMode;
VP_DDI_FUNCTION_ENTER;
DDI_CHK_NULL(pVpCtx, "Null pVpCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
DDI_CHK_NULL(pDiParamBuff,
"Null pDiParamBuff.",
VA_STATUS_ERROR_INVALID_BUFFER);
// initialize
pVpHalRenderParams = VpGetRenderParams(pVpCtx);
DDI_CHK_NULL(pVpHalRenderParams,
"Null pVpHalRenderParams.",
VA_STATUS_ERROR_INVALID_PARAMETER);
pSrc = pVpHalRenderParams->pSrc[uSurfIndex];
DDI_CHK_NULL(pSrc, "Null pSrc.", VA_STATUS_ERROR_INVALID_SURFACE);
pTarget = pVpHalRenderParams->pTarget[0];
DDI_CHK_NULL(pTarget, "Null pTarget.", VA_STATUS_ERROR_INVALID_SURFACE);
switch (pDiParamBuff->algorithm)
{
case VAProcDeinterlacingBob:
DIMode = DI_MODE_BOB;
break;
case VAProcDeinterlacingMotionAdaptive:
case VAProcDeinterlacingMotionCompensated:
DIMode = DI_MODE_ADI;
break;
case VAProcDeinterlacingWeave:
pSrc->bFieldWeaving = true;;
return VA_STATUS_SUCCESS;
case VAProcDeinterlacingNone:
return VA_STATUS_SUCCESS;
default:
VP_DDI_ASSERTMESSAGE("Deinterlacing type is unsupported.");
return VA_STATUS_ERROR_UNIMPLEMENTED;
}// switch (pDiParamBuff->algorithm)
if (nullptr == pSrc->pDeinterlaceParams)
{
pSrc->pDeinterlaceParams = (PVPHAL_DI_PARAMS)MOS_AllocAndZeroMemory(sizeof(VPHAL_DI_PARAMS));
DDI_CHK_NULL(pSrc->pDeinterlaceParams, "pSrc->pDeinterlaceParams is NULL", VA_STATUS_ERROR_ALLOCATION_FAILED);
}
if (nullptr == pTarget->pDeinterlaceParams)
{
pTarget->pDeinterlaceParams = (PVPHAL_DI_PARAMS)MOS_AllocAndZeroMemory(sizeof(VPHAL_DI_PARAMS));
DDI_CHK_NULL(pTarget->pDeinterlaceParams, "pTarget->pDeinterlaceParams is NULL", VA_STATUS_ERROR_ALLOCATION_FAILED);
}
//application detect scene change and then pass parameter to driver.
if (pDiParamBuff->flags & VA_DEINTERLACING_SCD_ENABLE)
{
DIMode = DI_MODE_BOB;
pSrc->pDeinterlaceParams->bSCDEnable = true;
}
else
{
pSrc->pDeinterlaceParams->bSCDEnable = false;
}
pSrc->pDeinterlaceParams->DIMode = DIMode;
pSrc->pDeinterlaceParams->bSingleField = (pDiParamBuff->flags & VA_DEINTERLACING_ONE_FIELD) ? true : false;
pSrc->pDeinterlaceParams->bEnableFMD = (pDiParamBuff->flags & VA_DEINTERLACING_FMD_ENABLE) ? true : false;
//update sample type
if (pDiParamBuff->flags & VA_DEINTERLACING_BOTTOM_FIELD_FIRST)
{
if (pDiParamBuff->flags & VA_DEINTERLACING_BOTTOM_FIELD)
{
pSrc->SampleType = SAMPLE_INTERLEAVED_ODD_FIRST_BOTTOM_FIELD;
}
else
{
pSrc->SampleType = SAMPLE_INTERLEAVED_ODD_FIRST_TOP_FIELD;
}
}
else
{
if (pDiParamBuff->flags & VA_DEINTERLACING_BOTTOM_FIELD)
{
pSrc->SampleType = SAMPLE_INTERLEAVED_EVEN_FIRST_BOTTOM_FIELD;
}
else
{
pSrc->SampleType = SAMPLE_INTERLEAVED_EVEN_FIRST_TOP_FIELD;
}
}
if (pSrc->pDeinterlaceParams->DIMode == DI_MODE_ADI)
{
//When pBwdRef is not nullptr and uBwdRefCount is nonzero, ADI can use Bwd Ref frame.
//Otherwise, ADI shouldn't use Bwd Ref frame.
if (pSrc->uBwdRefCount && pSrc->pBwdRef != nullptr)
{
pSrc->uBwdRefCount = 1;
//When the bo of the current frame's SRC and reference are same with previous frame's,
//we should set the frame ID same as previous frame's setting.
if ( pVpCtx->FrameIDTracer.pLastSrcSurfBo == pSrc->OsResource.bo &&
pVpCtx->FrameIDTracer.pLastBwdSurfBo == pSrc->pBwdRef->OsResource.bo &&
pVpCtx->FrameIDTracer.uiLastSampleType != pSrc->SampleType)
{
pSrc->FrameID = pVpCtx->FrameIDTracer.uiLastSrcSurfFrameID;
pSrc->pBwdRef->FrameID = pVpCtx->FrameIDTracer.uiLastBwdSurfFrameID;
}
//Otherwise, we should update the values of frame ID and FrameID tracer.
else
{
pSrc->pBwdRef->FrameID = (VP_SETTING_SAME_SAMPLE_THRESHOLD + 1) * pVpCtx->FrameIDTracer.uiFrameIndex;
pSrc->FrameID = pSrc->pBwdRef->FrameID + ( VP_SETTING_SAME_SAMPLE_THRESHOLD + 1);
pVpCtx->FrameIDTracer.pLastSrcSurfBo = pSrc->OsResource.bo;
pVpCtx->FrameIDTracer.pLastBwdSurfBo = pSrc->pBwdRef->OsResource.bo;
pVpCtx->FrameIDTracer.uiLastSrcSurfFrameID = pSrc->FrameID;
pVpCtx->FrameIDTracer.uiLastBwdSurfFrameID = pSrc->pBwdRef->FrameID;
pVpCtx->FrameIDTracer.uiLastSampleType = pSrc->SampleType;
}
}
else
{
//ADI no reference frame driver only care EVEN/ODD
if (pDiParamBuff->flags & VA_DEINTERLACING_BOTTOM_FIELD)
{
pSrc->SampleType = SAMPLE_INTERLEAVED_ODD_FIRST_BOTTOM_FIELD;
}
else
{
pSrc->SampleType = SAMPLE_INTERLEAVED_EVEN_FIRST_TOP_FIELD;
}
}
//int32_t overflow process
pVpCtx->FrameIDTracer.uiFrameIndex = (pVpCtx->FrameIDTracer.uiFrameIndex + 1 == INT_MAX) ? 1 : pVpCtx->FrameIDTracer.uiFrameIndex + 1;
}
return VA_STATUS_SUCCESS;
}
////////////////////////////////////////////////////////////////////////////////
//! \purpose Set DN filter params for VPHAL input surface
//! \params
//! [in] pVpCtx : VP context
//! [in] uSurfIndex : uSurfIndex to the input surface array
//! [in] pDnParamBuff : Pointer to DN param buffer data
//! [out] None
//! \returns VA_STATUS_SUCCESS if call succeeds
////////////////////////////////////////////////////////////////////////////////
VAStatus
DdiVp_SetProcFilterDenoiseParams(
PDDI_VP_CONTEXT pVpCtx,
uint32_t uSurfIndex,
VAProcFilterParameterBuffer* pDnParamBuff)
{
PVPHAL_RENDER_PARAMS pVpHalRenderParams;
PVPHAL_SURFACE pSrc;
VP_DDI_FUNCTION_ENTER;
DDI_CHK_NULL(pVpCtx, "Null pVpCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
// initialize
pVpHalRenderParams = VpGetRenderParams(pVpCtx);
DDI_CHK_NULL(pVpHalRenderParams,
"Null pVpHalRenderParams.",
VA_STATUS_ERROR_INVALID_PARAMETER);
pSrc = pVpHalRenderParams->pSrc[uSurfIndex];
DDI_CHK_NULL(pSrc, "Null pSrc.", VA_STATUS_ERROR_INVALID_SURFACE);
if (nullptr == pSrc->pDenoiseParams)
{
pSrc->pDenoiseParams = (PVPHAL_DENOISE_PARAMS)MOS_AllocAndZeroMemory(sizeof(VPHAL_DENOISE_PARAMS));
}
DDI_CHK_NULL(pSrc->pDenoiseParams, "pDenoiseParams MOS_AllocAndZeroMemory failed.", VA_STATUS_ERROR_ALLOCATION_FAILED);
// denoise caps range is from 0 to 64, out of range parameter is treated as an error
if (pDnParamBuff->value < NOISEREDUCTION_MIN || pDnParamBuff->value > NOISEREDUCTION_MAX)
{
return VA_STATUS_ERROR_INVALID_PARAMETER;
}
pSrc->pDenoiseParams->fDenoiseFactor = pDnParamBuff->value;
// Luma and chroma denoise should be always enabled when noise reduction is needed
pSrc->pDenoiseParams->bEnableLuma = true;
pSrc->pDenoiseParams->bEnableChroma = true;
pSrc->pDenoiseParams->bAutoDetect = false;
pSrc->pDenoiseParams->NoiseLevel = NOISELEVEL_DEFAULT;
return VA_STATUS_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//! \purpose Set Sharpness (Image Enhancement Filter, IEF) filter params for VPHAL input surface
//! \params
//! [in] pVpCtx : VP context
//! [in] uSurfIndex : uSurfIndex to the input surface array
//! [in] pDnParamBuff : Pointer to Sharpness param buffer data
//! [out] None
//! \returns VA_STATUS_SUCCESS if call succeeds
//////////////////////////////////////////////////////////////////////////////////////////////////
VAStatus
DdiVp_SetProcFilterSharpnessParams(
PDDI_VP_CONTEXT pVpCtx,
uint32_t uSurfIndex,
VAProcFilterParameterBuffer* pSharpParamBuff)
{
PVPHAL_RENDER_PARAMS pVpHalRenderParams;
PVPHAL_SURFACE pSrc;
VP_DDI_FUNCTION_ENTER;
DDI_CHK_NULL(pVpCtx, "Null pVpCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
DDI_CHK_NULL(pSharpParamBuff, "Null pSharpParamBuff.", VA_STATUS_ERROR_INVALID_BUFFER);
// initialize
pVpHalRenderParams = VpGetRenderParams(pVpCtx);
DDI_CHK_NULL(pVpHalRenderParams, "Null pVpHalRenderParams.", VA_STATUS_ERROR_INVALID_PARAMETER);
pSrc = pVpHalRenderParams->pSrc[uSurfIndex];
DDI_CHK_NULL(pSrc, "Null pSrc.", VA_STATUS_ERROR_INVALID_SURFACE);
if (nullptr == pSrc->pIEFParams)
{
pSrc->pIEFParams = (PVPHAL_IEF_PARAMS)MOS_AllocAndZeroMemory(sizeof(VPHAL_IEF_PARAMS));
DDI_CHK_NULL(pSrc->pIEFParams, "pIEFParams MOS_AllocAndZeroMemory failed.", VA_STATUS_ERROR_ALLOCATION_FAILED);
}
// out of range parameter is treated as an error
if (pSharpParamBuff->value < EDGEENHANCEMENT_MIN || pSharpParamBuff->value > EDGEENHANCEMENT_MAX)
{
return VA_STATUS_ERROR_INVALID_PARAMETER;
}
// sharpness option
// setting with hard code in mplayer side.
// refer to sharpening section of render_picture_vp() defined in vaapi.c.
// change flag and factor for testing.
VpHal_DdiInitIEFParams(pSrc->pIEFParams);
pSrc->bIEF = true;
pSrc->pIEFParams->bEnabled = true;
pSrc->pIEFParams->fIEFFactor = pSharpParamBuff->value;
return VA_STATUS_SUCCESS;
}
////////////////////////////////////////////////////////////////////////////////
//! \purpose Set Color Balance (procamp) filter params for VPHAL input surface
//! \params
//! [in] pVpCtx : VP context
//! [in] uSurfIndex : uSurfIndex to the input surface array
//! [in] pColorBalanceParamBuff : Pointer to Colorbalance param buffer data
//! [in] uElementNum : number of elements in the Colorbalance param buffer data
//! [out] None
//! \returns VA_STATUS_SUCCESS if call succeeds
////////////////////////////////////////////////////////////////////////////////
VAStatus
DdiVp_SetProcFilterColorBalanceParams(
PDDI_VP_CONTEXT pVpCtx,
uint32_t uSurfIndex,
VAProcFilterParameterBufferColorBalance* pColorBalanceParamBuff,
uint32_t uElementNum)
{
PVPHAL_RENDER_PARAMS pVpHalRenderParams;
PVPHAL_SURFACE pSrc;
uint32_t i;
bool bProcamp;
VP_DDI_FUNCTION_ENTER;
DDI_CHK_NULL(pVpCtx, "Null pVpCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
DDI_CHK_NULL(pColorBalanceParamBuff,
"Null pColorBalanceParamBuff.",
VA_STATUS_ERROR_INVALID_BUFFER);
// initialize
pVpHalRenderParams = VpGetRenderParams(pVpCtx);
DDI_CHK_NULL(pVpHalRenderParams, "Null pVpHalRenderParams.", VA_STATUS_ERROR_INVALID_PARAMETER);
pSrc = pVpHalRenderParams->pSrc[uSurfIndex];
DDI_CHK_NULL(pSrc, "Null pSrc.", VA_STATUS_ERROR_INVALID_SURFACE);
bProcamp = false;
for (i = 0; i < uElementNum; i++)
{
if ((VAProcColorBalanceHue == pColorBalanceParamBuff[i].attrib) ||
(VAProcColorBalanceSaturation == pColorBalanceParamBuff[i].attrib) ||
(VAProcColorBalanceBrightness == pColorBalanceParamBuff[i].attrib) ||
(VAProcColorBalanceContrast == pColorBalanceParamBuff[i].attrib))
{
bProcamp = true;
break;
}
}
if (nullptr == pSrc->pProcampParams &&
true == bProcamp)
{
pSrc->pProcampParams = (PVPHAL_PROCAMP_PARAMS)MOS_AllocAndZeroMemory(sizeof(VPHAL_PROCAMP_PARAMS));
DDI_CHK_NULL(pSrc->pProcampParams, "Source pProcampParams MOS_AllocAndZeroMemory failed.", VA_STATUS_ERROR_ALLOCATION_FAILED);
}
if (nullptr == pVpHalRenderParams->pTarget[0]->pProcampParams)
{
pVpHalRenderParams->pTarget[0]->pProcampParams = (PVPHAL_PROCAMP_PARAMS)MOS_AllocAndZeroMemory(sizeof(VPHAL_PROCAMP_PARAMS));
DDI_CHK_NULL(pVpHalRenderParams->pTarget[0]->pProcampParams, "Target pProcampParams MOS_AllocAndZeroMemory failed.", VA_STATUS_ERROR_ALLOCATION_FAILED);
}
// Needed for ACE
if (nullptr == pSrc->pColorPipeParams &&
SURF_IN_PRIMARY == pSrc->SurfType)
{
pSrc->pColorPipeParams = (PVPHAL_COLORPIPE_PARAMS)MOS_AllocAndZeroMemory(sizeof(VPHAL_COLORPIPE_PARAMS));
DDI_CHK_NULL(pSrc->pColorPipeParams, "pColorPipeParams MOS_AllocAndZeroMemory failed.", VA_STATUS_ERROR_ALLOCATION_FAILED);
}
// set default value
if (nullptr != pSrc->pProcampParams)
{
pSrc->pProcampParams->fHue = PROCAMP_HUE_DEFAULT;
pSrc->pProcampParams->fSaturation = PROCAMP_SATURATION_DEFAULT;
pSrc->pProcampParams->fBrightness = PROCAMP_BRIGHTNESS_DEFAULT;
pSrc->pProcampParams->fContrast = PROCAMP_CONTRAST_DEFAULT;
}
for (i = 0; i < uElementNum; i++)
{
switch (pColorBalanceParamBuff[i].attrib)
{
case VAProcColorBalanceHue:
if (pColorBalanceParamBuff[i].value < PROCAMP_HUE_MIN || pColorBalanceParamBuff[i].value > PROCAMP_HUE_MAX)
{
VP_DDI_ASSERTMESSAGE("%d: Hue is out of bounds.", i);
return VA_STATUS_ERROR_INVALID_PARAMETER;
}
if (true == bProcamp)
{
pSrc->pProcampParams->bEnabled = true;
pSrc->pProcampParams->fHue = pColorBalanceParamBuff[i].value;
}
break;
case VAProcColorBalanceSaturation:
if (pColorBalanceParamBuff[i].value < PROCAMP_SATURATION_MIN || pColorBalanceParamBuff[i].value > PROCAMP_SATURATION_MAX)
{
VP_DDI_ASSERTMESSAGE("%d: Saturation is out of bounds.", i);
return VA_STATUS_ERROR_INVALID_PARAMETER;
}
if (true == bProcamp)
{
pSrc->pProcampParams->bEnabled = true;
pSrc->pProcampParams->fSaturation = pColorBalanceParamBuff[i].value;
}
break;
case VAProcColorBalanceBrightness:
if (pColorBalanceParamBuff[i].value < PROCAMP_BRIGHTNESS_MIN || pColorBalanceParamBuff[i].value > PROCAMP_BRIGHTNESS_MAX)
{
VP_DDI_ASSERTMESSAGE("%d: Brightness is out of bounds.", i);
return VA_STATUS_ERROR_INVALID_PARAMETER;
}
if (true == bProcamp)
{
pSrc->pProcampParams->bEnabled = true;
pSrc->pProcampParams->fBrightness = pColorBalanceParamBuff[i].value;
}
break;
case VAProcColorBalanceContrast:
if (pColorBalanceParamBuff[i].value < PROCAMP_CONTRAST_MIN || pColorBalanceParamBuff[i].value > PROCAMP_CONTRAST_MAX)
{
VP_DDI_ASSERTMESSAGE("%d: Contrast is out of bounds.", i);
return VA_STATUS_ERROR_INVALID_PARAMETER;
}
if (true == bProcamp)
{
pSrc->pProcampParams->bEnabled = true;
pSrc->pProcampParams->fContrast = pColorBalanceParamBuff[i].value;
}
break;
case VAProcColorBalanceAutoContrast:
if (SURF_IN_PRIMARY == pSrc->SurfType)
{
pSrc->pColorPipeParams->bEnableACE = true;
pSrc->pColorPipeParams->dwAceLevel = ACE_LEVEL_DEFAULT;
pSrc->pColorPipeParams->dwAceStrength = ACE_STRENGTH_DEFAULT;
}
break;
case VAProcColorBalanceAutoSaturation:
case VAProcColorBalanceAutoBrightness:
return VA_STATUS_ERROR_UNIMPLEMENTED;
case VAProcColorBalanceNone:
case VAProcColorBalanceCount:
default:
VP_DDI_ASSERTMESSAGE("pColorBalanceParamBuff[%d].attrib is unknown.", i);
return VA_STATUS_ERROR_INVALID_PARAMETER;
}// switch (attrib)
}
return VA_STATUS_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//! \purpose Set Skin Tone Enhancement (STE) filter params for VPHAL input surface
//! \params
//! [in] pVpCtx : VP context
//! [in] uSurfIndex : uSurfIndex to the input surface array
//! [in] pSTEParamBuff : Pointer to Skin Tone Enhancement param buffer data
//! [out] None
//! \returns VA_STATUS_SUCCESS if call succeeds
//////////////////////////////////////////////////////////////////////////////////////////////////
VAStatus
DdiVp_SetProcFilterSkinToneEnhancementParams(
PDDI_VP_CONTEXT pVpCtx,
uint32_t uSurfIndex,
VAProcFilterParameterBuffer* pSTEParamBuff)
{
PVPHAL_RENDER_PARAMS pVpHalRenderParams;
PVPHAL_SURFACE pSrc;
VP_DDI_FUNCTION_ENTER;
DDI_CHK_NULL(pSTEParamBuff, "Null pSTEParamBuff.", VA_STATUS_ERROR_INVALID_BUFFER);
// initialize
pVpHalRenderParams = VpGetRenderParams(pVpCtx);
DDI_CHK_NULL(pVpHalRenderParams, "Null pVpHalRenderParams.", VA_STATUS_ERROR_INVALID_PARAMETER);
pSrc = pVpHalRenderParams->pSrc[uSurfIndex];
DDI_CHK_NULL(pSrc, "Null pSrc.", VA_STATUS_ERROR_INVALID_SURFACE);
if (SURF_IN_PRIMARY == pSrc->SurfType)
{
if (nullptr == pSrc->pColorPipeParams)
{
pSrc->pColorPipeParams = (PVPHAL_COLORPIPE_PARAMS)MOS_AllocAndZeroMemory(sizeof(VPHAL_COLORPIPE_PARAMS));
DDI_CHK_NULL(pSrc->pColorPipeParams, "pColorPipeParams MOS_AllocAndZeroMemory failed.", VA_STATUS_ERROR_ALLOCATION_FAILED);
}
// out of range parameter is treated as an error
if (pSTEParamBuff->value < STE_MIN || pSTEParamBuff->value > STE_MAX)
{
return VA_STATUS_ERROR_INVALID_PARAMETER;
}
pSrc->pColorPipeParams->bEnableSTE = true;
pSrc->pColorPipeParams->SteParams.dwSTEFactor = (uint32_t)pSTEParamBuff->value;
}
return VA_STATUS_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//! \purpose Total Color Correction (TCC) filter params for VPHAL input surface
//! \params
//! [in] pVpCtx : VP context
//! [in] uSurfIndex : uSurfIndex to the input surface array
//! [in] pTCCParamBuff : Pointer to Total Color Correction param buffer data
//! [in] uElementNum : number of elements in the Total Color Correction param buffer data
//! [out] None
//! \returns VA_STATUS_SUCCESS if call succeeds
//////////////////////////////////////////////////////////////////////////////////////////////////
VAStatus
DdiVp_SetProcFilterTotalColorCorrectionParams(
PDDI_VP_CONTEXT pVpCtx,
uint32_t uSurfIndex,
VAProcFilterParameterBufferTotalColorCorrection* pTCCParamBuff,
uint32_t uElementNum)
{
PVPHAL_RENDER_PARAMS pVpHalRenderParams;
PVPHAL_SURFACE pSrc;
uint32_t i;
VP_DDI_FUNCTION_ENTER;
DDI_CHK_NULL(pTCCParamBuff, "Null pTCCParamBuff.", VA_STATUS_ERROR_INVALID_BUFFER);
// initialize
pVpHalRenderParams = VpGetRenderParams(pVpCtx);
DDI_CHK_NULL(pVpHalRenderParams, "Null pVpHalRenderParams.", VA_STATUS_ERROR_INVALID_PARAMETER);
pSrc = pVpHalRenderParams->pSrc[uSurfIndex];
DDI_CHK_NULL(pSrc, "Null pSrc.", VA_STATUS_ERROR_INVALID_SURFACE);
if (SURF_IN_PRIMARY == pSrc->SurfType)
{
if (nullptr == pSrc->pColorPipeParams)
{
pSrc->pColorPipeParams = (PVPHAL_COLORPIPE_PARAMS)MOS_AllocAndZeroMemory(sizeof(VPHAL_COLORPIPE_PARAMS));
DDI_CHK_NULL(pSrc->pColorPipeParams, "pColorPipeParams MOS_AllocAndZeroMemory failed.", VA_STATUS_ERROR_ALLOCATION_FAILED);
}
// set default values
pSrc->pColorPipeParams->TccParams.Red = (uint8_t)TCC_DEFAULT;
pSrc->pColorPipeParams->TccParams.Green = (uint8_t)TCC_DEFAULT;
pSrc->pColorPipeParams->TccParams.Blue = (uint8_t)TCC_DEFAULT;
pSrc->pColorPipeParams->TccParams.Cyan = (uint8_t)TCC_DEFAULT;
pSrc->pColorPipeParams->TccParams.Magenta = (uint8_t)TCC_DEFAULT;
pSrc->pColorPipeParams->TccParams.Yellow = (uint8_t)TCC_DEFAULT;
for (i = 0; i < uElementNum; i++)
{
if (pTCCParamBuff[i].value < TCC_MIN || pTCCParamBuff[i].value > TCC_MAX)
return VA_STATUS_ERROR_INVALID_PARAMETER;
pSrc->pColorPipeParams->bEnableTCC = true;
switch (pTCCParamBuff[i].attrib)