ref: cf92e8d6208af51fb55ed61554b135585ed33c1b
dir: /processing/src/common/WelsFrameWork.cpp/
/*!
* \copy
* Copyright (c) 2013, Cisco Systems
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "WelsFrameWork.h"
#include "cpu.h"
#include "../denoise/denoise.h"
#include "../downsample/downsample.h"
#include "../scenechangedetection/SceneChangeDetection.h"
#include "../vaacalc/vaacalculation.h"
#include "../backgounddetection/BackgroundDetection.h"
#include "../adaptivequantization/AdaptiveQuantization.h"
#include "../complexityanalysis/ComplexityAnalysis.h"
#include "../imagerotate/imagerotate.h"
/* interface API implement */
EResult WELSAPI CreateVpInterface (void **ppCtx, int iVersion)
{
if (iVersion & 0x8000)
return nsWelsVP::CreateSpecificVpInterface((IWelsVP **)ppCtx);
else if (iVersion & 0x7fff)
return nsWelsVP::CreateSpecificVpInterface((IWelsVPc **)ppCtx);
else
return RET_INVALIDPARAM;
}
EResult WELSAPI DestroyVpInterface (void *pCtx, int iVersion)
{
if (iVersion & 0x8000)
return nsWelsVP::DestroySpecificVpInterface((IWelsVP *)pCtx);
else if (iVersion & 0x7fff)
return nsWelsVP::DestroySpecificVpInterface((IWelsVPc *)pCtx);
else
return RET_INVALIDPARAM;
}
WELSVP_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////
EResult CreateSpecificVpInterface(IWelsVP **ppCtx)
{
EResult eReturn = RET_FAILED;
CVpFrameWork *pFr = new CVpFrameWork(1, eReturn);
if (pFr)
{
*ppCtx = (IWelsVP *)pFr;
eReturn = RET_SUCCESS;
}
return eReturn;
}
EResult DestroySpecificVpInterface (IWelsVP *pCtx)
{
_SafeDelete(pCtx);
return RET_SUCCESS;
}
///////////////////////////////////////////////////////////////////////////////
CVpFrameWork::CVpFrameWork(uint32_t uiThreadsNum, EResult &eReturn)
{
int32_t iCoreNum = 1;
#ifndef X86_ASM
uint32_t uiCPUFlag = 0;
#else
uint32_t uiCPUFlag = WelsCPUFeatureDetect(&iCoreNum);
#endif
for (int32_t i = 0; i < MAX_STRATEGY_NUM; i++)
{
IStrategy *pStrategy = m_pStgChain[i];
pStrategy = CreateStrategy(WelsStaticCast(EMethods, i + 1), uiCPUFlag);
m_pStgChain[i] = pStrategy;
}
WelsMutexInit(&m_mutes);
eReturn = RET_SUCCESS;
}
CVpFrameWork::~CVpFrameWork()
{
for (int32_t i = 0; i < MAX_STRATEGY_NUM; i++)
{
if (m_pStgChain[i])
{
Uninit(m_pStgChain[i]->m_eMethod);
_SafeDelete(m_pStgChain[i]);
}
}
WelsMutexDestroy(&m_mutes);
}
EResult CVpFrameWork::Init(int32_t iType, void *pCfg)
{
EResult eReturn = RET_SUCCESS;
int32_t iCurIdx = WelsStaticCast(int32_t, WelsVpGetValidMethod(iType)) - 1;
Uninit(iType);
WelsMutexLock(&m_mutes);
IStrategy *pStrategy = m_pStgChain[iCurIdx];
if (pStrategy)
eReturn = pStrategy->Init(0, pCfg);
WelsMutexUnlock(&m_mutes);
return eReturn;
}
EResult CVpFrameWork::Uninit(int32_t iType)
{
EResult eReturn = RET_SUCCESS;
int32_t iCurIdx = WelsStaticCast(int32_t, WelsVpGetValidMethod(iType)) - 1;
WelsMutexLock(&m_mutes);
IStrategy *pStrategy = m_pStgChain[iCurIdx];
if (pStrategy)
eReturn = pStrategy->Uninit(0);
WelsMutexUnlock(&m_mutes);
return eReturn;
}
EResult CVpFrameWork::Flush(int32_t iType)
{
EResult eReturn = RET_SUCCESS;
return eReturn;
}
EResult CVpFrameWork::Process(int32_t iType, SPixMap *pSrcPixMap, SPixMap *pDstPixMap)
{
EResult eReturn = RET_NOTSUPPORTED;
EMethods eMethod = WelsVpGetValidMethod(iType);
int32_t iCurIdx = WelsStaticCast(int32_t, eMethod) - 1;
SPixMap sSrcPic;
SPixMap sDstPic;
memset(&sSrcPic, 0, sizeof(sSrcPic));// confirmed_safe_unsafe_usage
memset(&sDstPic, 0, sizeof(sDstPic));// confirmed_safe_unsafe_usage
if (pSrcPixMap) sSrcPic = *pSrcPixMap;
if (pDstPixMap) sDstPic = *pDstPixMap;
if (!CheckValid(eMethod, sSrcPic, sDstPic))
return RET_INVALIDPARAM;
WelsMutexLock(&m_mutes);
IStrategy *pStrategy = m_pStgChain[iCurIdx];
if (pStrategy)
eReturn = pStrategy->Process(0, &sSrcPic, &sDstPic);
WelsMutexUnlock(&m_mutes);
return eReturn;
}
EResult CVpFrameWork::Get(int32_t iType, void *pParam)
{
EResult eReturn = RET_SUCCESS;
int32_t iCurIdx = WelsStaticCast(int32_t, WelsVpGetValidMethod(iType)) - 1;
if (!pParam)
return RET_INVALIDPARAM;
WelsMutexLock(&m_mutes);
IStrategy *pStrategy = m_pStgChain[iCurIdx];
if (pStrategy)
eReturn = pStrategy->Get(0, pParam);
WelsMutexUnlock(&m_mutes);
return eReturn;
}
EResult CVpFrameWork::Set(int32_t iType, void *pParam)
{
EResult eReturn = RET_SUCCESS;
int32_t iCurIdx = WelsStaticCast(int32_t, WelsVpGetValidMethod(iType)) - 1;
if (!pParam)
return RET_INVALIDPARAM;
WelsMutexLock(&m_mutes);
IStrategy *pStrategy = m_pStgChain[iCurIdx];
if (pStrategy)
eReturn = pStrategy->Set(0, pParam);
WelsMutexUnlock(&m_mutes);
return eReturn;
}
EResult CVpFrameWork::SpecialFeature(int32_t iType, void *pIn, void *pOut)
{
EResult eReturn = RET_SUCCESS;
return eReturn;
}
bool_t CVpFrameWork::CheckValid(EMethods eMethod, SPixMap &pSrcPixMap, SPixMap &pDstPixMap)
{
bool_t eReturn = FALSE;
if (eMethod == METHOD_NULL)
goto exit;
if (eMethod != METHOD_COLORSPACE_CONVERT)
{
if (pSrcPixMap.pPixel[0])
{
if (pSrcPixMap.eFormat != VIDEO_FORMAT_I420 && pSrcPixMap.eFormat != VIDEO_FORMAT_YV12)
goto exit;
}
if (pSrcPixMap.pPixel[0] && pDstPixMap.pPixel[0])
{
if (pDstPixMap.eFormat != pSrcPixMap.eFormat)
goto exit;
}
}
if (pSrcPixMap.pPixel[0])
{
if (pSrcPixMap.sRect.iRectWidth <= 0 || pSrcPixMap.sRect.iRectWidth > MAX_WIDTH || pSrcPixMap.sRect.iRectHeight <= 0 || pSrcPixMap.sRect.iRectHeight > MAX_HEIGHT)
goto exit;
if (pSrcPixMap.sRect.iRectTop >= pSrcPixMap.sRect.iRectHeight || pSrcPixMap.sRect.iRectLeft >= pSrcPixMap.sRect.iRectWidth || pSrcPixMap.sRect.iRectWidth > pSrcPixMap.iStride[0])
goto exit;
}
if (pDstPixMap.pPixel[0])
{
if (pDstPixMap.sRect.iRectWidth <= 0 || pDstPixMap.sRect.iRectWidth > MAX_WIDTH || pDstPixMap.sRect.iRectHeight <= 0 || pDstPixMap.sRect.iRectHeight > MAX_HEIGHT)
goto exit;
if (pDstPixMap.sRect.iRectTop >= pDstPixMap.sRect.iRectHeight || pDstPixMap.sRect.iRectLeft >= pDstPixMap.sRect.iRectWidth || pDstPixMap.sRect.iRectWidth > pDstPixMap.iStride[0])
goto exit;
}
eReturn = TRUE;
exit:
return eReturn;
}
IStrategy* CVpFrameWork::CreateStrategy(EMethods m_eMethod, int32_t iCpuFlag)
{
IStrategy *pStrategy = NULL;
switch (m_eMethod)
{
case METHOD_COLORSPACE_CONVERT:
//not support yet
break;
case METHOD_DENOISE:
pStrategy = WelsDynamicCast(IStrategy *, new CDenoiser(iCpuFlag));
break;
case METHOD_SCENE_CHANGE_DETECTION:
pStrategy = WelsDynamicCast(IStrategy *, new CSceneChangeDetection(iCpuFlag));
break;
case METHOD_DOWNSAMPLE:
pStrategy = WelsDynamicCast(IStrategy *, new CDownsampling(iCpuFlag));
break;
case METHOD_VAA_STATISTICS:
pStrategy = WelsDynamicCast(IStrategy *, new CVAACalculation(iCpuFlag));
break;
case METHOD_BACKGROUND_DETECTION:
pStrategy = WelsDynamicCast(IStrategy *, new CBackgroundDetection(iCpuFlag));
break;
case METHOD_ADAPTIVE_QUANT:
pStrategy = WelsDynamicCast(IStrategy *, new CAdaptiveQuantization(iCpuFlag));
break;
case METHOD_COMPLEXITY_ANALYSIS:
pStrategy = WelsDynamicCast(IStrategy *, new CComplexityAnalysis(iCpuFlag));
break;
case METHOD_IMAGE_ROTATE:
pStrategy = WelsDynamicCast(IStrategy *, new CImageRotating(iCpuFlag));
break;
default:
break;
}
return pStrategy;
}
WELSVP_NAMESPACE_END