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 "ComplexityAnalysis.h"
34 #include "cpu.h"
35 #include "macros.h"
36 #include "intra_pred_common.h"
37 #include "sad_common.h"
38
39 WELSVP_NAMESPACE_BEGIN
40
41 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
42
CComplexityAnalysis(int32_t iCpuFlag)43 CComplexityAnalysis::CComplexityAnalysis (int32_t iCpuFlag) {
44 m_eMethod = METHOD_COMPLEXITY_ANALYSIS;
45 m_pfGomSad = NULL;
46 WelsMemset (&m_sComplexityAnalysisParam, 0, sizeof (m_sComplexityAnalysisParam));
47 }
48
~CComplexityAnalysis()49 CComplexityAnalysis::~CComplexityAnalysis() {
50 }
51
Process(int32_t iType,SPixMap * pSrcPixMap,SPixMap * pRefPixMap)52 EResult CComplexityAnalysis::Process (int32_t iType, SPixMap* pSrcPixMap, SPixMap* pRefPixMap) {
53 EResult eReturn = RET_SUCCESS;
54
55 switch (m_sComplexityAnalysisParam.iComplexityAnalysisMode) {
56 case FRAME_SAD:
57 AnalyzeFrameComplexityViaSad (pSrcPixMap, pRefPixMap);
58 break;
59 case GOM_SAD:
60 AnalyzeGomComplexityViaSad (pSrcPixMap, pRefPixMap);
61 break;
62 case GOM_VAR:
63 AnalyzeGomComplexityViaVar (pSrcPixMap, pRefPixMap);
64 break;
65 default:
66 eReturn = RET_INVALIDPARAM;
67 break;
68 }
69
70 return eReturn;
71 }
72
73
Set(int32_t iType,void * pParam)74 EResult CComplexityAnalysis::Set (int32_t iType, void* pParam) {
75 if (pParam == NULL) {
76 return RET_INVALIDPARAM;
77 }
78
79 m_sComplexityAnalysisParam = * (SComplexityAnalysisParam*)pParam;
80
81 return RET_SUCCESS;
82 }
83
Get(int32_t iType,void * pParam)84 EResult CComplexityAnalysis::Get (int32_t iType, void* pParam) {
85 if (pParam == NULL) {
86 return RET_INVALIDPARAM;
87 }
88
89 SComplexityAnalysisParam* sComplexityAnalysisParam = (SComplexityAnalysisParam*)pParam;
90
91 sComplexityAnalysisParam->iFrameComplexity = m_sComplexityAnalysisParam.iFrameComplexity;
92
93 return RET_SUCCESS;
94 }
95
96
97 ///////////////////////////////////////////////////////////////////////////////////////////////
AnalyzeFrameComplexityViaSad(SPixMap * pSrcPixMap,SPixMap * pRefPixMap)98 void CComplexityAnalysis::AnalyzeFrameComplexityViaSad (SPixMap* pSrcPixMap, SPixMap* pRefPixMap) {
99 SVAACalcResult* pVaaCalcResults = NULL;
100 pVaaCalcResults = m_sComplexityAnalysisParam.pCalcResult;
101
102 m_sComplexityAnalysisParam.iFrameComplexity = pVaaCalcResults->iFrameSad;
103
104 if (m_sComplexityAnalysisParam.iCalcBgd) { //BGD control
105 m_sComplexityAnalysisParam.iFrameComplexity = GetFrameSadExcludeBackground (pSrcPixMap, pRefPixMap);
106 }
107 }
108
GetFrameSadExcludeBackground(SPixMap * pSrcPixMap,SPixMap * pRefPixMap)109 int32_t CComplexityAnalysis::GetFrameSadExcludeBackground (SPixMap* pSrcPixMap, SPixMap* pRefPixMap) {
110 int32_t iWidth = pSrcPixMap->sRect.iRectWidth;
111 int32_t iHeight = pSrcPixMap->sRect.iRectHeight;
112 int32_t iMbWidth = iWidth >> 4;
113 int32_t iMbHeight = iHeight >> 4;
114 int32_t iMbNum = iMbWidth * iMbHeight;
115
116 int32_t iMbNumInGom = m_sComplexityAnalysisParam.iMbNumInGom;
117 int32_t iGomMbNum = (iMbNum + iMbNumInGom - 1) / iMbNumInGom;
118 int32_t iGomMbStartIndex = 0, iGomMbEndIndex = 0;
119
120 uint8_t* pBackgroundMbFlag = (uint8_t*)m_sComplexityAnalysisParam.pBackgroundMbFlag;
121 uint32_t* uiRefMbType = (uint32_t*)m_sComplexityAnalysisParam.uiRefMbType;
122 SVAACalcResult* pVaaCalcResults = m_sComplexityAnalysisParam.pCalcResult;
123 int32_t* pGomForegroundBlockNum = m_sComplexityAnalysisParam.pGomForegroundBlockNum;
124
125 uint32_t uiFrameSad = 0;
126 for (int32_t j = 0; j < iGomMbNum; j ++) {
127 iGomMbStartIndex = j * iMbNumInGom;
128 iGomMbEndIndex = WELS_MIN ((j + 1) * iMbNumInGom, iMbNum);
129
130 for (int32_t i = iGomMbStartIndex; i < iGomMbEndIndex; i ++) {
131 if (pBackgroundMbFlag[i] == 0 || IS_INTRA (uiRefMbType[i])) {
132 pGomForegroundBlockNum[j]++;
133 uiFrameSad += pVaaCalcResults->pSad8x8[i][0];
134 uiFrameSad += pVaaCalcResults->pSad8x8[i][1];
135 uiFrameSad += pVaaCalcResults->pSad8x8[i][2];
136 uiFrameSad += pVaaCalcResults->pSad8x8[i][3];
137 }
138 }
139 }
140
141 return (uiFrameSad);
142 }
143
144
InitGomSadFunc(PGOMSadFunc & pfGomSad,uint8_t iCalcBgd)145 void InitGomSadFunc (PGOMSadFunc& pfGomSad, uint8_t iCalcBgd) {
146 pfGomSad = GomSampleSad;
147
148 if (iCalcBgd) {
149 pfGomSad = GomSampleSadExceptBackground;
150 }
151 }
152
GomSampleSad(uint32_t * pGomSad,int32_t * pGomForegroundBlockNum,int32_t * pSad8x8,uint8_t pBackgroundMbFlag)153 void GomSampleSad (uint32_t* pGomSad, int32_t* pGomForegroundBlockNum, int32_t* pSad8x8, uint8_t pBackgroundMbFlag) {
154 (*pGomForegroundBlockNum) ++;
155 *pGomSad += pSad8x8[0];
156 *pGomSad += pSad8x8[1];
157 *pGomSad += pSad8x8[2];
158 *pGomSad += pSad8x8[3];
159 }
160
GomSampleSadExceptBackground(uint32_t * pGomSad,int32_t * pGomForegroundBlockNum,int32_t * pSad8x8,uint8_t pBackgroundMbFlag)161 void GomSampleSadExceptBackground (uint32_t* pGomSad, int32_t* pGomForegroundBlockNum, int32_t* pSad8x8,
162 uint8_t pBackgroundMbFlag) {
163 if (pBackgroundMbFlag == 0) {
164 (*pGomForegroundBlockNum) ++;
165 *pGomSad += pSad8x8[0];
166 *pGomSad += pSad8x8[1];
167 *pGomSad += pSad8x8[2];
168 *pGomSad += pSad8x8[3];
169 }
170 }
171
AnalyzeGomComplexityViaSad(SPixMap * pSrcPixMap,SPixMap * pRefPixMap)172 void CComplexityAnalysis::AnalyzeGomComplexityViaSad (SPixMap* pSrcPixMap, SPixMap* pRefPixMap) {
173 int32_t iWidth = pSrcPixMap->sRect.iRectWidth;
174 int32_t iHeight = pSrcPixMap->sRect.iRectHeight;
175 int32_t iMbWidth = iWidth >> 4;
176 int32_t iMbHeight = iHeight >> 4;
177 int32_t iMbNum = iMbWidth * iMbHeight;
178
179 int32_t iMbNumInGom = m_sComplexityAnalysisParam.iMbNumInGom;
180 int32_t iGomMbNum = (iMbNum + iMbNumInGom - 1) / iMbNumInGom;
181
182 int32_t iGomMbStartIndex = 0, iGomMbEndIndex = 0, iGomMbRowNum = 0;
183 int32_t iMbStartIndex = 0, iMbEndIndex = 0;
184
185 uint8_t* pBackgroundMbFlag = (uint8_t*)m_sComplexityAnalysisParam.pBackgroundMbFlag;
186 uint32_t* uiRefMbType = (uint32_t*)m_sComplexityAnalysisParam.uiRefMbType;
187 SVAACalcResult* pVaaCalcResults = m_sComplexityAnalysisParam.pCalcResult;
188 int32_t* pGomForegroundBlockNum = (int32_t*)m_sComplexityAnalysisParam.pGomForegroundBlockNum;
189 int32_t* pGomComplexity = (int32_t*)m_sComplexityAnalysisParam.pGomComplexity;
190
191 uint32_t uiGomSad = 0, uiFrameSad = 0;
192 InitGomSadFunc (m_pfGomSad, m_sComplexityAnalysisParam.iCalcBgd);
193
194 for (int32_t j = 0; j < iGomMbNum; j ++) {
195 uiGomSad = 0;
196
197 iGomMbStartIndex = j * iMbNumInGom;
198 iGomMbEndIndex = WELS_MIN ((j + 1) * iMbNumInGom, iMbNum);
199 iGomMbRowNum = (iGomMbEndIndex + iMbWidth - 1) / iMbWidth - iGomMbStartIndex / iMbWidth;
200
201 iMbStartIndex = iGomMbStartIndex;
202 iMbEndIndex = WELS_MIN ((iMbStartIndex / iMbWidth + 1) * iMbWidth, iGomMbEndIndex);
203
204 do {
205 for (int32_t i = iMbStartIndex; i < iMbEndIndex; i ++) {
206 m_pfGomSad (&uiGomSad, pGomForegroundBlockNum + j, pVaaCalcResults->pSad8x8[i], pBackgroundMbFlag[i]
207 && !IS_INTRA (uiRefMbType[i]));
208 }
209
210 iMbStartIndex = iMbEndIndex;
211 iMbEndIndex = WELS_MIN (iMbEndIndex + iMbWidth , iGomMbEndIndex);
212
213 } while (--iGomMbRowNum);
214 pGomComplexity[j] = uiGomSad;
215 uiFrameSad += pGomComplexity[j];
216 }
217 m_sComplexityAnalysisParam.iFrameComplexity = uiFrameSad;
218 }
219
220
AnalyzeGomComplexityViaVar(SPixMap * pSrcPixMap,SPixMap * pRefPixMap)221 void CComplexityAnalysis::AnalyzeGomComplexityViaVar (SPixMap* pSrcPixMap, SPixMap* pRefPixMap) {
222 int32_t iWidth = pSrcPixMap->sRect.iRectWidth;
223 int32_t iHeight = pSrcPixMap->sRect.iRectHeight;
224 int32_t iMbWidth = iWidth >> 4;
225 int32_t iMbHeight = iHeight >> 4;
226 int32_t iMbNum = iMbWidth * iMbHeight;
227
228 int32_t iMbNumInGom = m_sComplexityAnalysisParam.iMbNumInGom;
229 int32_t iGomMbNum = (iMbNum + iMbNumInGom - 1) / iMbNumInGom;
230 int32_t iGomSampleNum = 0;
231
232 int32_t iGomMbStartIndex = 0, iGomMbEndIndex = 0, iGomMbRowNum = 0;
233 int32_t iMbStartIndex = 0, iMbEndIndex = 0;
234
235 SVAACalcResult* pVaaCalcResults = m_sComplexityAnalysisParam.pCalcResult;
236 int32_t* pGomComplexity = (int32_t*)m_sComplexityAnalysisParam.pGomComplexity;
237 uint32_t uiFrameSad = 0;
238
239 uint32_t uiSampleSum = 0, uiSquareSum = 0;
240
241 for (int32_t j = 0; j < iGomMbNum; j ++) {
242 uiSampleSum = 0;
243 uiSquareSum = 0;
244
245 iGomMbStartIndex = j * iMbNumInGom;
246 iGomMbEndIndex = WELS_MIN ((j + 1) * iMbNumInGom, iMbNum);
247 iGomMbRowNum = (iGomMbEndIndex + iMbWidth - 1) / iMbWidth - iGomMbStartIndex / iMbWidth;
248
249 iMbStartIndex = iGomMbStartIndex;
250 iMbEndIndex = WELS_MIN ((iMbStartIndex / iMbWidth + 1) * iMbWidth, iGomMbEndIndex);
251
252 iGomSampleNum = (iMbEndIndex - iMbStartIndex) * MB_WIDTH_LUMA * MB_WIDTH_LUMA;
253
254 do {
255 for (int32_t i = iMbStartIndex; i < iMbEndIndex; i ++) {
256 uiSampleSum += pVaaCalcResults->pSum16x16[i];
257 uiSquareSum += pVaaCalcResults->pSumOfSquare16x16[i];
258 }
259
260 iMbStartIndex = iMbEndIndex;
261 iMbEndIndex = WELS_MIN (iMbEndIndex + iMbWidth, iGomMbEndIndex);
262
263 } while (--iGomMbRowNum);
264
265 pGomComplexity[j] = uiSquareSum - (uiSampleSum * uiSampleSum / iGomSampleNum);
266 uiFrameSad += pGomComplexity[j];
267 }
268 m_sComplexityAnalysisParam.iFrameComplexity = uiFrameSad;
269 }
270
271
CComplexityAnalysisScreen(int32_t iCpuFlag)272 CComplexityAnalysisScreen::CComplexityAnalysisScreen (int32_t iCpuFlag) {
273 m_eMethod = METHOD_COMPLEXITY_ANALYSIS_SCREEN;
274 WelsMemset (&m_ComplexityAnalysisParam, 0, sizeof (m_ComplexityAnalysisParam));
275
276 m_pSadFunc = WelsSampleSad16x16_c;
277 m_pIntraFunc[0] = WelsI16x16LumaPredV_c;
278 m_pIntraFunc[1] = WelsI16x16LumaPredH_c;
279 #ifdef X86_ASM
280 if (iCpuFlag & WELS_CPU_SSE2) {
281 m_pSadFunc = WelsSampleSad16x16_sse2;
282 m_pIntraFunc[0] = WelsI16x16LumaPredV_sse2;
283 m_pIntraFunc[1] = WelsI16x16LumaPredH_sse2;
284
285 }
286 #endif
287
288 #if defined (HAVE_NEON)
289 if (iCpuFlag & WELS_CPU_NEON) {
290 m_pSadFunc = WelsSampleSad16x16_neon;
291 m_pIntraFunc[0] = WelsI16x16LumaPredV_neon;
292 m_pIntraFunc[1] = WelsI16x16LumaPredH_neon;
293
294 }
295 #endif
296
297 #if defined (HAVE_NEON_AARCH64)
298 if (iCpuFlag & WELS_CPU_NEON) {
299 m_pSadFunc = WelsSampleSad16x16_AArch64_neon;
300 m_pIntraFunc[0] = WelsI16x16LumaPredV_AArch64_neon;
301 m_pIntraFunc[1] = WelsI16x16LumaPredH_AArch64_neon;
302 }
303 #endif
304
305 #if defined (HAVE_LASX)
306 if (iCpuFlag & WELS_CPU_LASX) {
307 m_pSadFunc = WelsSampleSad16x16_lasx;
308 }
309 #endif
310
311 }
312
~CComplexityAnalysisScreen()313 CComplexityAnalysisScreen::~CComplexityAnalysisScreen() {
314 }
315
Process(int32_t nType,SPixMap * pSrc,SPixMap * pRef)316 EResult CComplexityAnalysisScreen::Process (int32_t nType, SPixMap* pSrc, SPixMap* pRef) {
317 bool bScrollFlag = m_ComplexityAnalysisParam.sScrollResult.bScrollDetectFlag;
318 int32_t iIdrFlag = m_ComplexityAnalysisParam.iIdrFlag;
319 int32_t iScrollMvX = m_ComplexityAnalysisParam.sScrollResult.iScrollMvX;
320 int32_t iScrollMvY = m_ComplexityAnalysisParam.sScrollResult.iScrollMvY;
321
322 if (m_ComplexityAnalysisParam.iMbRowInGom <= 0)
323 return RET_INVALIDPARAM;
324 if (!iIdrFlag && pRef == NULL)
325 return RET_INVALIDPARAM;
326
327 if (iIdrFlag || pRef == NULL) {
328 GomComplexityAnalysisIntra (pSrc);
329 } else if (!bScrollFlag || ((iScrollMvX == 0) && (iScrollMvY == 0))) {
330 GomComplexityAnalysisInter (pSrc, pRef, 0);
331 } else {
332 GomComplexityAnalysisInter (pSrc, pRef, 1);
333 }
334
335 return RET_SUCCESS;
336 }
337
338
Set(int32_t nType,void * pParam)339 EResult CComplexityAnalysisScreen::Set (int32_t nType, void* pParam) {
340 if (pParam == NULL)
341 return RET_INVALIDPARAM;
342
343 m_ComplexityAnalysisParam = * (SComplexityAnalysisScreenParam*)pParam;
344
345 return RET_SUCCESS;
346 }
347
Get(int32_t nType,void * pParam)348 EResult CComplexityAnalysisScreen::Get (int32_t nType, void* pParam) {
349 if (pParam == NULL)
350 return RET_INVALIDPARAM;
351
352 * (SComplexityAnalysisScreenParam*)pParam = m_ComplexityAnalysisParam;
353
354 return RET_SUCCESS;
355 }
356
GomComplexityAnalysisIntra(SPixMap * pSrc)357 void CComplexityAnalysisScreen::GomComplexityAnalysisIntra (SPixMap* pSrc) {
358 int32_t iWidth = pSrc->sRect.iRectWidth;
359 int32_t iHeight = pSrc->sRect.iRectHeight;
360 int32_t iBlockWidth = iWidth >> 4;
361 int32_t iBlockHeight = iHeight >> 4;
362
363 int32_t iBlockSadH, iBlockSadV, iGomSad = 0;
364 int32_t iIdx = 0;
365
366 uint8_t* pPtrY = NULL;
367 int32_t iStrideY = 0;
368 int32_t iRowStrideY = 0;
369
370 uint8_t* pTmpCur = NULL;
371
372 ENFORCE_STACK_ALIGN_1D (uint8_t, iMemPredMb, 256, 16)
373
374 pPtrY = (uint8_t*)pSrc->pPixel[0];
375
376 iStrideY = pSrc->iStride[0];
377 iRowStrideY = iStrideY << 4;
378
379 m_ComplexityAnalysisParam.iFrameComplexity = 0;
380
381 for (int32_t j = 0; j < iBlockHeight; j ++) {
382 pTmpCur = pPtrY;
383
384 for (int32_t i = 0; i < iBlockWidth; i++) {
385 iBlockSadH = iBlockSadV = 0x7fffffff; // INT_MAX
386 if (j > 0) {
387 m_pIntraFunc[0] (iMemPredMb, pTmpCur, iStrideY);
388 iBlockSadH = m_pSadFunc (pTmpCur, iStrideY, iMemPredMb, 16);
389 }
390 if (i > 0) {
391 m_pIntraFunc[1] (iMemPredMb, pTmpCur, iStrideY);
392 iBlockSadV = m_pSadFunc (pTmpCur, iStrideY, iMemPredMb, 16);
393 }
394 if (i || j)
395 iGomSad += WELS_MIN (iBlockSadH, iBlockSadV);
396
397 pTmpCur += 16;
398
399 if (i == iBlockWidth - 1 && ((j + 1) % m_ComplexityAnalysisParam.iMbRowInGom == 0 || j == iBlockHeight - 1)) {
400 m_ComplexityAnalysisParam.pGomComplexity[iIdx] = iGomSad;
401 m_ComplexityAnalysisParam.iFrameComplexity += iGomSad;
402 iIdx++;
403 iGomSad = 0;
404 }
405 }
406
407 pPtrY += iRowStrideY;
408 }
409 m_ComplexityAnalysisParam.iGomNumInFrame = iIdx;
410 }
411
412
GomComplexityAnalysisInter(SPixMap * pSrc,SPixMap * pRef,bool bScrollFlag)413 void CComplexityAnalysisScreen::GomComplexityAnalysisInter (SPixMap* pSrc, SPixMap* pRef, bool bScrollFlag) {
414 int32_t iWidth = pSrc->sRect.iRectWidth;
415 int32_t iHeight = pSrc->sRect.iRectHeight;
416 int32_t iBlockWidth = iWidth >> 4;
417 int32_t iBlockHeight = iHeight >> 4;
418
419 int32_t iInterSad, iScrollSad, iBlockSadH, iBlockSadV, iGomSad = 0;
420 int32_t iIdx = 0;
421
422 int32_t iScrollMvX = m_ComplexityAnalysisParam.sScrollResult.iScrollMvX;
423 int32_t iScrollMvY = m_ComplexityAnalysisParam.sScrollResult.iScrollMvY;
424
425 uint8_t* pPtrX = NULL, *pPtrY = NULL;
426 int32_t iStrideX = 0, iStrideY = 0;
427 int32_t iRowStrideX = 0, iRowStrideY = 0;
428
429 uint8_t* pTmpRef = NULL, *pTmpCur = NULL, *pTmpRefScroll = NULL;
430
431 ENFORCE_STACK_ALIGN_1D (uint8_t, iMemPredMb, 256, 16)
432
433 pPtrX = (uint8_t*)pRef->pPixel[0];
434 pPtrY = (uint8_t*)pSrc->pPixel[0];
435
436 iStrideX = pRef->iStride[0];
437 iStrideY = pSrc->iStride[0];
438
439 iRowStrideX = pRef->iStride[0] << 4;
440 iRowStrideY = pSrc->iStride[0] << 4;
441
442 m_ComplexityAnalysisParam.iFrameComplexity = 0;
443
444 for (int32_t j = 0; j < iBlockHeight; j ++) {
445 pTmpRef = pPtrX;
446 pTmpCur = pPtrY;
447
448 for (int32_t i = 0; i < iBlockWidth; i++) {
449 int32_t iBlockPointX = i << 4;
450 int32_t iBlockPointY = j << 4;
451
452 iInterSad = m_pSadFunc (pTmpCur, iStrideY, pTmpRef, iStrideX);
453 if (bScrollFlag) {
454 if ((iInterSad != 0) &&
455 (iBlockPointX + iScrollMvX >= 0) && (iBlockPointX + iScrollMvX <= iWidth - 8) &&
456 (iBlockPointY + iScrollMvY >= 0) && (iBlockPointY + iScrollMvY <= iHeight - 8)) {
457 pTmpRefScroll = pTmpRef - iScrollMvY * iStrideX + iScrollMvX;
458 iScrollSad = m_pSadFunc (pTmpCur, iStrideY, pTmpRefScroll, iStrideX);
459
460 if (iScrollSad < iInterSad) {
461 iInterSad = iScrollSad;
462 }
463 }
464
465 }
466
467 iBlockSadH = iBlockSadV = 0x7fffffff; // INT_MAX
468
469 if (j > 0) {
470 m_pIntraFunc[0] (iMemPredMb, pTmpCur, iStrideY);
471 iBlockSadH = m_pSadFunc (pTmpCur, iStrideY, iMemPredMb, 16);
472 }
473 if (i > 0) {
474 m_pIntraFunc[1] (iMemPredMb, pTmpCur, iStrideY);
475 iBlockSadV = m_pSadFunc (pTmpCur, iStrideY, iMemPredMb, 16);
476 }
477
478 iGomSad += WELS_MIN (WELS_MIN (iBlockSadH, iBlockSadV), iInterSad);
479
480 if (i == iBlockWidth - 1 && ((j + 1) % m_ComplexityAnalysisParam.iMbRowInGom == 0 || j == iBlockHeight - 1)) {
481 m_ComplexityAnalysisParam.pGomComplexity[iIdx] = iGomSad;
482 m_ComplexityAnalysisParam.iFrameComplexity += iGomSad;
483 iIdx++;
484 iGomSad = 0;
485 }
486
487 pTmpRef += 16;
488 pTmpCur += 16;
489 }
490 pPtrX += iRowStrideX;
491 pPtrY += iRowStrideY;
492 }
493 m_ComplexityAnalysisParam.iGomNumInFrame = iIdx;
494 }
495
496 WELSVP_NAMESPACE_END
497