ref: 4227bead55e29c15efcf9b9e80db5240f4cf8b28
dir: /codec/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 "../denoise/denoise.h" #include "../downsample/downsample.h" #include "../scrolldetection/ScrollDetection.h" #include "../scenechangedetection/SceneChangeDetection.h" #include "../vaacalc/vaacalculation.h" #include "../backgrounddetection/BackgroundDetection.h" #include "../adaptivequantization/AdaptiveQuantization.h" #include "../complexityanalysis/ComplexityAnalysis.h" #include "../imagerotate/imagerotate.h" #include "util.h" /* interface API implement */ EResult WelsCreateVpInterface (void** ppCtx, int iVersion) { if (iVersion & 0x8000) return WelsVP::CreateSpecificVpInterface ((IWelsVP**)ppCtx); else if (iVersion & 0x7fff) return WelsVP::CreateSpecificVpInterface ((IWelsVPc**)ppCtx); else return RET_INVALIDPARAM; } EResult WelsDestroyVpInterface (void* pCtx, int iVersion) { if (iVersion & 0x8000) return WelsVP::DestroySpecificVpInterface ((IWelsVP*)pCtx); else if (iVersion & 0x7fff) return WelsVP::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) { delete pCtx; return RET_SUCCESS; } /////////////////////////////////////////////////////////////////////////////// CVpFrameWork::CVpFrameWork (uint32_t uiThreadsNum, EResult& eReturn) { int32_t iCoreNum = 1; uint32_t uiCPUFlag = WelsCPUFeatureDetect (&iCoreNum); for (int32_t i = 0; i < MAX_STRATEGY_NUM; i++) { m_pStgChain[i] = CreateStrategy (WelsStaticCast (EMethods, i + 1), uiCPUFlag); } 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); delete 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 CVpFrameWork::CheckValid (EMethods eMethod, SPixMap& pSrcPixMap, SPixMap& pDstPixMap) { bool 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.iRectHeight <= 0 || pSrcPixMap.sRect.iRectWidth * pSrcPixMap.sRect.iRectHeight > (MAX_MBS_PER_FRAME << 8)) 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.iRectHeight <= 0 || pDstPixMap.sRect.iRectWidth * pDstPixMap.sRect.iRectHeight > (MAX_MBS_PER_FRAME << 8)) 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_SCROLL_DETECTION: pStrategy = WelsDynamicCast (IStrategy*, new CScrollDetection (iCpuFlag)); break; case METHOD_SCENE_CHANGE_DETECTION_VIDEO: case METHOD_SCENE_CHANGE_DETECTION_SCREEN: pStrategy = BuildSceneChangeDetection (m_eMethod, 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_COMPLEXITY_ANALYSIS_SCREEN: pStrategy = WelsDynamicCast (IStrategy*, new CComplexityAnalysisScreen (iCpuFlag)); break; case METHOD_IMAGE_ROTATE: pStrategy = WelsDynamicCast (IStrategy*, new CImageRotating (iCpuFlag)); break; default: break; } return pStrategy; } WELSVP_NAMESPACE_END