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