ref: 99faf1ec4a47c5362a6bde552d6097166e2fda16
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