• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*!
2  * \copy
3  *     Copyright (c)  2013, Cisco Systems
4  *     All rights reserved.
5  *
6  *     Redistribution and use in source and binary forms, with or without
7  *     modification, are permitted provided that the following conditions
8  *     are met:
9  *
10  *        * Redistributions of source code must retain the above copyright
11  *          notice, this list of conditions and the following disclaimer.
12  *
13  *        * Redistributions in binary form must reproduce the above copyright
14  *          notice, this list of conditions and the following disclaimer in
15  *          the documentation and/or other materials provided with the
16  *          distribution.
17  *
18  *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  *     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  *     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  *     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22  *     COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23  *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24  *     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26  *     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  *     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28  *     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  *     POSSIBILITY OF SUCH DAMAGE.
30  *
31  */
32 
33 #include "WelsFrameWork.h"
34 #include "../denoise/denoise.h"
35 #include "../downsample/downsample.h"
36 #include "../scrolldetection/ScrollDetection.h"
37 #include "../scenechangedetection/SceneChangeDetection.h"
38 #include "../vaacalc/vaacalculation.h"
39 #include "../backgrounddetection/BackgroundDetection.h"
40 #include "../adaptivequantization/AdaptiveQuantization.h"
41 #include "../complexityanalysis/ComplexityAnalysis.h"
42 #include "../imagerotate/imagerotate.h"
43 #include "util.h"
44 
45 /* interface API implement */
46 
WelsCreateVpInterface(void ** ppCtx,int iVersion)47 EResult WelsCreateVpInterface (void** ppCtx, int iVersion) {
48   if (iVersion & 0x8000)
49     return WelsVP::CreateSpecificVpInterface ((IWelsVP**)ppCtx);
50   else if (iVersion & 0x7fff)
51     return WelsVP::CreateSpecificVpInterface ((IWelsVPc**)ppCtx);
52   else
53     return RET_INVALIDPARAM;
54 }
55 
WelsDestroyVpInterface(void * pCtx,int iVersion)56 EResult WelsDestroyVpInterface (void* pCtx, int iVersion) {
57   if (iVersion & 0x8000)
58     return WelsVP::DestroySpecificVpInterface ((IWelsVP*)pCtx);
59   else if (iVersion & 0x7fff)
60     return WelsVP::DestroySpecificVpInterface ((IWelsVPc*)pCtx);
61   else
62     return RET_INVALIDPARAM;
63 }
64 
65 WELSVP_NAMESPACE_BEGIN
66 
67 ///////////////////////////////////////////////////////////////////////
68 
CreateSpecificVpInterface(IWelsVP ** ppCtx)69 EResult CreateSpecificVpInterface (IWelsVP** ppCtx) {
70   EResult  eReturn = RET_FAILED;
71 
72   CVpFrameWork* pFr = new CVpFrameWork (1, eReturn);
73   if (pFr) {
74     *ppCtx  = (IWelsVP*)pFr;
75     eReturn = RET_SUCCESS;
76   }
77 
78   return eReturn;
79 }
80 
DestroySpecificVpInterface(IWelsVP * pCtx)81 EResult DestroySpecificVpInterface (IWelsVP* pCtx) {
82   delete pCtx;
83 
84   return RET_SUCCESS;
85 }
86 
87 ///////////////////////////////////////////////////////////////////////////////
88 
CVpFrameWork(uint32_t uiThreadsNum,EResult & eReturn)89 CVpFrameWork::CVpFrameWork (uint32_t uiThreadsNum, EResult& eReturn) {
90   int32_t iCoreNum = 1;
91   uint32_t uiCPUFlag = WelsCPUFeatureDetect (&iCoreNum);
92 
93   for (int32_t i = 0; i < MAX_STRATEGY_NUM; i++) {
94     m_pStgChain[i] = CreateStrategy (WelsStaticCast (EMethods, i + 1), uiCPUFlag);
95   }
96 
97   WelsMutexInit (&m_mutes);
98 
99   eReturn = RET_SUCCESS;
100 }
101 
~CVpFrameWork()102 CVpFrameWork::~CVpFrameWork() {
103   for (int32_t i = 0; i < MAX_STRATEGY_NUM; i++) {
104     if (m_pStgChain[i]) {
105       Uninit (m_pStgChain[i]->m_eMethod);
106       delete m_pStgChain[i];
107     }
108   }
109 
110   WelsMutexDestroy (&m_mutes);
111 }
112 
Init(int32_t iType,void * pCfg)113 EResult CVpFrameWork::Init (int32_t iType, void* pCfg) {
114   EResult eReturn   = RET_SUCCESS;
115   int32_t iCurIdx    = WelsStaticCast (int32_t, WelsVpGetValidMethod (iType)) - 1;
116 
117   Uninit (iType);
118 
119   WelsMutexLock (&m_mutes);
120 
121   IStrategy* pStrategy = m_pStgChain[iCurIdx];
122   if (pStrategy)
123     eReturn = pStrategy->Init (0, pCfg);
124 
125   WelsMutexUnlock (&m_mutes);
126 
127   return eReturn;
128 }
129 
Uninit(int32_t iType)130 EResult CVpFrameWork::Uninit (int32_t iType) {
131   EResult eReturn        = RET_SUCCESS;
132   int32_t iCurIdx    = WelsStaticCast (int32_t, WelsVpGetValidMethod (iType)) - 1;
133 
134   WelsMutexLock (&m_mutes);
135 
136   IStrategy* pStrategy = m_pStgChain[iCurIdx];
137   if (pStrategy)
138     eReturn = pStrategy->Uninit (0);
139 
140   WelsMutexUnlock (&m_mutes);
141 
142   return eReturn;
143 }
144 
Flush(int32_t iType)145 EResult CVpFrameWork::Flush (int32_t iType) {
146   EResult eReturn        = RET_SUCCESS;
147 
148   return eReturn;
149 }
150 
Process(int32_t iType,SPixMap * pSrcPixMap,SPixMap * pDstPixMap)151 EResult CVpFrameWork::Process (int32_t iType, SPixMap* pSrcPixMap, SPixMap* pDstPixMap) {
152   EResult eReturn        = RET_NOTSUPPORTED;
153   EMethods eMethod    = WelsVpGetValidMethod (iType);
154   int32_t iCurIdx    = WelsStaticCast (int32_t, eMethod) - 1;
155   SPixMap sSrcPic;
156   SPixMap sDstPic;
157   memset (&sSrcPic, 0, sizeof (sSrcPic)); // confirmed_safe_unsafe_usage
158   memset (&sDstPic, 0, sizeof (sDstPic)); // confirmed_safe_unsafe_usage
159 
160   if (pSrcPixMap) sSrcPic = *pSrcPixMap;
161   if (pDstPixMap) sDstPic = *pDstPixMap;
162   if (!CheckValid (eMethod, sSrcPic, sDstPic))
163     return RET_INVALIDPARAM;
164 
165   WelsMutexLock (&m_mutes);
166 
167   IStrategy* pStrategy = m_pStgChain[iCurIdx];
168   if (pStrategy)
169     eReturn = pStrategy->Process (0, &sSrcPic, &sDstPic);
170 
171   WelsMutexUnlock (&m_mutes);
172 
173   return eReturn;
174 }
175 
Get(int32_t iType,void * pParam)176 EResult CVpFrameWork::Get (int32_t iType, void* pParam) {
177   EResult eReturn        = RET_SUCCESS;
178   int32_t iCurIdx    = WelsStaticCast (int32_t, WelsVpGetValidMethod (iType)) - 1;
179 
180   if (!pParam)
181     return RET_INVALIDPARAM;
182 
183   WelsMutexLock (&m_mutes);
184 
185   IStrategy* pStrategy = m_pStgChain[iCurIdx];
186   if (pStrategy)
187     eReturn = pStrategy->Get (0, pParam);
188 
189   WelsMutexUnlock (&m_mutes);
190 
191   return eReturn;
192 }
193 
Set(int32_t iType,void * pParam)194 EResult CVpFrameWork::Set (int32_t iType, void* pParam) {
195   EResult eReturn        = RET_SUCCESS;
196   int32_t iCurIdx    = WelsStaticCast (int32_t, WelsVpGetValidMethod (iType)) - 1;
197 
198   if (!pParam)
199     return RET_INVALIDPARAM;
200 
201   WelsMutexLock (&m_mutes);
202 
203   IStrategy* pStrategy = m_pStgChain[iCurIdx];
204   if (pStrategy)
205     eReturn = pStrategy->Set (0, pParam);
206 
207   WelsMutexUnlock (&m_mutes);
208 
209   return eReturn;
210 }
211 
SpecialFeature(int32_t iType,void * pIn,void * pOut)212 EResult CVpFrameWork::SpecialFeature (int32_t iType, void* pIn, void* pOut) {
213   EResult eReturn        = RET_SUCCESS;
214 
215   return eReturn;
216 }
217 
CheckValid(EMethods eMethod,SPixMap & pSrcPixMap,SPixMap & pDstPixMap)218 bool  CVpFrameWork::CheckValid (EMethods eMethod, SPixMap& pSrcPixMap, SPixMap& pDstPixMap) {
219   bool eReturn = false;
220 
221   if (eMethod == METHOD_NULL)
222     goto exit;
223 
224   if (eMethod != METHOD_COLORSPACE_CONVERT) {
225     if (pSrcPixMap.pPixel[0]) {
226       if (pSrcPixMap.eFormat != VIDEO_FORMAT_I420 && pSrcPixMap.eFormat != VIDEO_FORMAT_YV12)
227         goto exit;
228     }
229     if (pSrcPixMap.pPixel[0] && pDstPixMap.pPixel[0]) {
230       if (pDstPixMap.eFormat != pSrcPixMap.eFormat)
231         goto exit;
232     }
233   }
234 
235   if (pSrcPixMap.pPixel[0]) {
236     if (pSrcPixMap.sRect.iRectWidth <= 0 || pSrcPixMap.sRect.iRectHeight <= 0
237         || pSrcPixMap.sRect.iRectWidth * pSrcPixMap.sRect.iRectHeight > (MAX_MBS_PER_FRAME << 8))
238       goto exit;
239     if (pSrcPixMap.sRect.iRectTop >= pSrcPixMap.sRect.iRectHeight
240         || pSrcPixMap.sRect.iRectLeft >= pSrcPixMap.sRect.iRectWidth || pSrcPixMap.sRect.iRectWidth > pSrcPixMap.iStride[0])
241       goto exit;
242   }
243   if (pDstPixMap.pPixel[0]) {
244     if (pDstPixMap.sRect.iRectWidth <= 0 || pDstPixMap.sRect.iRectHeight <= 0
245         || pDstPixMap.sRect.iRectWidth * pDstPixMap.sRect.iRectHeight > (MAX_MBS_PER_FRAME << 8))
246       goto exit;
247     if (pDstPixMap.sRect.iRectTop >= pDstPixMap.sRect.iRectHeight
248         || pDstPixMap.sRect.iRectLeft >= pDstPixMap.sRect.iRectWidth || pDstPixMap.sRect.iRectWidth > pDstPixMap.iStride[0])
249       goto exit;
250   }
251   eReturn = true;
252 
253 exit:
254   return eReturn;
255 }
256 
CreateStrategy(EMethods m_eMethod,int32_t iCpuFlag)257 IStrategy* CVpFrameWork::CreateStrategy (EMethods m_eMethod, int32_t iCpuFlag) {
258   IStrategy* pStrategy = NULL;
259 
260   switch (m_eMethod) {
261   case METHOD_COLORSPACE_CONVERT:
262     //not support yet
263     break;
264   case METHOD_DENOISE:
265     pStrategy = WelsDynamicCast (IStrategy*, new CDenoiser (iCpuFlag));
266     break;
267   case METHOD_SCROLL_DETECTION:
268     pStrategy = WelsDynamicCast (IStrategy*, new CScrollDetection (iCpuFlag));
269     break;
270   case METHOD_SCENE_CHANGE_DETECTION_VIDEO:
271   case METHOD_SCENE_CHANGE_DETECTION_SCREEN:
272     pStrategy = BuildSceneChangeDetection (m_eMethod, iCpuFlag);
273     break;
274   case METHOD_DOWNSAMPLE:
275     pStrategy = WelsDynamicCast (IStrategy*, new CDownsampling (iCpuFlag));
276     break;
277   case METHOD_VAA_STATISTICS:
278     pStrategy = WelsDynamicCast (IStrategy*, new CVAACalculation (iCpuFlag));
279     break;
280   case METHOD_BACKGROUND_DETECTION:
281     pStrategy = WelsDynamicCast (IStrategy*, new CBackgroundDetection (iCpuFlag));
282     break;
283   case METHOD_ADAPTIVE_QUANT:
284     pStrategy = WelsDynamicCast (IStrategy*, new CAdaptiveQuantization (iCpuFlag));
285     break;
286   case METHOD_COMPLEXITY_ANALYSIS:
287     pStrategy = WelsDynamicCast (IStrategy*, new CComplexityAnalysis (iCpuFlag));
288     break;
289   case METHOD_COMPLEXITY_ANALYSIS_SCREEN:
290     pStrategy = WelsDynamicCast (IStrategy*, new CComplexityAnalysisScreen (iCpuFlag));
291     break;
292   case METHOD_IMAGE_ROTATE:
293     pStrategy = WelsDynamicCast (IStrategy*, new CImageRotating (iCpuFlag));
294     break;
295   default:
296     break;
297   }
298 
299   return pStrategy;
300 }
301 
302 WELSVP_NAMESPACE_END
303