History

Initial Commit

Ethan Hugg committed 12 years ago

Commit 70e5e621 parent bd509b2308 files · +97095 −-5Browse files

Showing the changes to codec/encoder/core/src/md.cpp (1 of 308 files). Show all

Unified · Split

codec/encoder/core/src/md.cpp+1034−0
@@ -0,0 +1,1034 @@
1/*!
2 * \copy
3 * Copyright (c) 2009-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 * \file md.c
33 *
34 * \brief mode decision
35 *
36 * \date 2009.05.14 Created
37 *
38 *************************************************************************************
39 */
40
41#include <string.h>
42#include "ls_defines.h"
43#include "encoder_context.h"
44#include "svc_enc_slice_segment.h"
45#include "md.h"
46#include "mc.h"
47#include "mv_pred.h"
48#include "cpu_core.h"
49#include "svc_enc_golomb.h"
50#include "sample.h"
51#include "array_stack_align.h"
52
53namespace WelsSVCEnc {
54#define INTRA_VARIANCE_SAD_THRESHOLD 150
55#define INTER_VARIANCE_SAD_THRESHOLD 20
56
57//fill cache of neighbor MB, containing pNonZeroCount, sample_avail, pIntra4x4PredMode
58void FillNeighborCacheIntra(SMbCache* pMbCache, SMB* pCurMb, int32_t iMbWidth)
59{
60 uint32_t uiNeighborAvail = pCurMb->uiNeighborAvail;
61 uint32_t uiNeighborIntra = 0;
62
63 if (uiNeighborAvail & LEFT_MB_POS) //LEFT MB
64 {
65 int8_t* pLeftMbNonZeroCount = pCurMb->pNonZeroCount - MB_LUMA_CHROMA_BLOCK4x4_NUM;
66 pMbCache->iNonZeroCoeffCount[8] = pLeftMbNonZeroCount[ 3];
67 pMbCache->iNonZeroCoeffCount[16] = pLeftMbNonZeroCount[ 7];
68 pMbCache->iNonZeroCoeffCount[24] = pLeftMbNonZeroCount[11];
69 pMbCache->iNonZeroCoeffCount[32] = pLeftMbNonZeroCount[15];
70
71 pMbCache->iNonZeroCoeffCount[ 13] = pLeftMbNonZeroCount[17];
72 pMbCache->iNonZeroCoeffCount[21] = pLeftMbNonZeroCount[21];
73 pMbCache->iNonZeroCoeffCount[37] = pLeftMbNonZeroCount[19];
74 pMbCache->iNonZeroCoeffCount[45] = pLeftMbNonZeroCount[23];
75
76 uiNeighborIntra |= LEFT_MB_POS;
77
78 if ( IS_INTRA4x4((pCurMb-1)->uiMbType ) )
79 {
80 int8_t* pLeftMbIntra4x4PredMode = pCurMb->pIntra4x4PredMode - INTRA_4x4_MODE_NUM;
81 pMbCache->iIntraPredMode[8] = pLeftMbIntra4x4PredMode[4];
82 pMbCache->iIntraPredMode[16] = pLeftMbIntra4x4PredMode[5];
83 pMbCache->iIntraPredMode[24] = pLeftMbIntra4x4PredMode[6];
84 pMbCache->iIntraPredMode[32] = pLeftMbIntra4x4PredMode[3];
85 }
86 else// if ( 0 == constrained_intra_pred_flag || IS_INTRA16x16((pCurMb-1)->uiMbType ))
87 {
88 pMbCache->iIntraPredMode[8] =
89 pMbCache->iIntraPredMode[16] =
90 pMbCache->iIntraPredMode[24] =
91 pMbCache->iIntraPredMode[32] = 2; //DC
92 }
93 }
94 else
95 {
96 pMbCache->iNonZeroCoeffCount[ 8] =
97 pMbCache->iNonZeroCoeffCount[16] =
98 pMbCache->iNonZeroCoeffCount[24] =
99 pMbCache->iNonZeroCoeffCount[32] = -1;//unavailable
100 pMbCache->iNonZeroCoeffCount[13] =
101 pMbCache->iNonZeroCoeffCount[21] =
102 pMbCache->iNonZeroCoeffCount[37] =
103 pMbCache->iNonZeroCoeffCount[45] = -1;//unavailable
104
105 pMbCache->iIntraPredMode[8] =
106 pMbCache->iIntraPredMode[16] =
107 pMbCache->iIntraPredMode[24] =
108 pMbCache->iIntraPredMode[32] = -1;//unavailable
109 }
110
111 if (uiNeighborAvail & TOP_MB_POS)//TOP MB
112 {
113 SMB* pTopMb = pCurMb - iMbWidth;
114 ST32(&pMbCache->iNonZeroCoeffCount[1], LD32(&pTopMb->pNonZeroCount[12]));
115
116 ST16(&pMbCache->iNonZeroCoeffCount[6], LD16(&pTopMb->pNonZeroCount[20]));
117 ST16(&pMbCache->iNonZeroCoeffCount[30], LD16(&pTopMb->pNonZeroCount[22]));
118
119 uiNeighborIntra |= TOP_MB_POS;
120
121 if ( IS_INTRA4x4( pTopMb->uiMbType ) )
122 {
123 ST32(pMbCache->iIntraPredMode+1, LD32(&pTopMb->pIntra4x4PredMode[0]));
124 }
125 else// if ( 0 == constrained_intra_pred_flag || IS_INTRA16x16( pTopMb->uiMbType ))
126 {
127 const uint32_t kuiDc32 = 0x02020202;
128 ST32( pMbCache->iIntraPredMode+1 , kuiDc32 );
129 }
130 }
131 else
132 {
133 const uint32_t kuiUnavail32 = 0xffffffff;
134 ST32( pMbCache->iIntraPredMode+1 , kuiUnavail32 );
135 ST32( &pMbCache->iNonZeroCoeffCount[1], kuiUnavail32 );
136
137 ST16( &pMbCache->iNonZeroCoeffCount[6], 0xffff );
138 ST16( &pMbCache->iNonZeroCoeffCount[30], 0xffff );
139 }
140
141 if (uiNeighborAvail & TOPLEFT_MB_POS)
142 {
143 uiNeighborIntra |= 0x04;
144 }
145
146
147 if (uiNeighborAvail & TOPRIGHT_MB_POS)
148 {
149 uiNeighborIntra |= 0x08;
150 }
151 pMbCache->uiNeighborIntra = uiNeighborIntra;
152}
153//fill cache of neighbor MB, containing motion_vector and uiRefIndex
154void FillNeighborCacheInterWithoutBGD(SMbCache* pMbCache, SMB* pCurMb, int32_t iMbWidth, int8_t *pVaaBgMbFlag)
155{
156 uint32_t uiNeighborAvail = pCurMb->uiNeighborAvail;
157 SMB* pLeftMb = pCurMb -1 ;
158 SMB* pTopMb = pCurMb -iMbWidth;
159 SMB* pLeftTopMb = pCurMb - iMbWidth - 1 ;
160 SMB* iRightTopMb = pCurMb -iMbWidth + 1 ;
161 SMVComponentUnit *pMvComp = &pMbCache->sMvComponents;
162 if( (uiNeighborAvail & LEFT_MB_POS) && IS_SVC_INTER(pLeftMb->uiMbType) )
163 {
164 pMvComp->sMotionVectorCache[ 6] = pLeftMb->sMv[ 3];
165 pMvComp->sMotionVectorCache[12] = pLeftMb->sMv[ 7];
166 pMvComp->sMotionVectorCache[18] = pLeftMb->sMv[11];
167 pMvComp->sMotionVectorCache[24] = pLeftMb->sMv[15];
168 pMvComp->iRefIndexCache[ 6] = pLeftMb->pRefIndex[1];
169 pMvComp->iRefIndexCache[12] = pLeftMb->pRefIndex[1];
170 pMvComp->iRefIndexCache[18] = pLeftMb->pRefIndex[3];
171 pMvComp->iRefIndexCache[24] = pLeftMb->pRefIndex[3];
172 pMbCache->iSadCost[3] = pLeftMb->pSadCost[0];
173
174 if ( pLeftMb->uiMbType == MB_TYPE_SKIP )
175 {
176 pMbCache->bMbTypeSkip[3] = 1;
177 pMbCache->iSadCostSkip[3] = pMbCache->pEncSad[-1];
178 }
179 else
180 {
181 pMbCache->bMbTypeSkip[3] = 0;
182 pMbCache->iSadCostSkip[3] = 0;
183 }
184 }
185 else //avail or non-inter
186 {
187 ST32(&pMvComp->sMotionVectorCache[ 6], 0);
188 ST32(&pMvComp->sMotionVectorCache[12], 0);
189 ST32(&pMvComp->sMotionVectorCache[18], 0);
190 ST32(&pMvComp->sMotionVectorCache[24], 0);
191 pMvComp->iRefIndexCache[ 6] =
192 pMvComp->iRefIndexCache[12] =
193 pMvComp->iRefIndexCache[18] =
194 pMvComp->iRefIndexCache[24] = (uiNeighborAvail & LEFT_MB_POS) ? REF_NOT_IN_LIST : REF_NOT_AVAIL;
195 pMbCache->iSadCost[3] = 0;
196 pMbCache->bMbTypeSkip[3] = 0;
197 pMbCache->iSadCostSkip[3] = 0;
198 }
199
200 if ( (uiNeighborAvail & TOP_MB_POS) && IS_SVC_INTER(pTopMb->uiMbType) ) //TOP MB
201 {
202 ST64(&pMvComp->sMotionVectorCache[1], LD64(&pTopMb->sMv[12]));
203 ST64(&pMvComp->sMotionVectorCache[3], LD64(&pTopMb->sMv[14]));
204 pMvComp->iRefIndexCache[1] = pTopMb->pRefIndex[2];
205 pMvComp->iRefIndexCache[2] = pTopMb->pRefIndex[2];
206 pMvComp->iRefIndexCache[3] = pTopMb->pRefIndex[3];
207 pMvComp->iRefIndexCache[4] = pTopMb->pRefIndex[3];
208 pMbCache->iSadCost[1] = pTopMb->pSadCost[0];
209
210 if ( pTopMb->uiMbType == MB_TYPE_SKIP )
211 {
212 pMbCache->bMbTypeSkip[1] = 1;
213 pMbCache->iSadCostSkip[1] = pMbCache->pEncSad[-iMbWidth];
214 }
215 else
216 {
217 pMbCache->bMbTypeSkip[1] = 0;
218 pMbCache->iSadCostSkip[1] = 0;
219 }
220 }
221 else //unavail
222 {
223 ST64(&pMvComp->sMotionVectorCache[1], 0);
224 ST64(&pMvComp->sMotionVectorCache[3], 0);
225 pMvComp->iRefIndexCache[1] =
226 pMvComp->iRefIndexCache[2] =
227 pMvComp->iRefIndexCache[3] =
228 pMvComp->iRefIndexCache[4] = (uiNeighborAvail & TOP_MB_POS) ? REF_NOT_IN_LIST : REF_NOT_AVAIL;
229 pMbCache->iSadCost[1] = 0;
230
231 pMbCache->bMbTypeSkip[1] = 0;
232 pMbCache->iSadCostSkip[1] = 0;
233 }
234
235 if ( (uiNeighborAvail & TOPLEFT_MB_POS) && IS_SVC_INTER(pLeftTopMb->uiMbType) ) //LEFT_TOP MB
236 {
237 pMvComp->sMotionVectorCache[0] = pLeftTopMb->sMv[15];
238 pMvComp->iRefIndexCache[0] = pLeftTopMb->pRefIndex[3];
239 pMbCache->iSadCost[0] = pLeftTopMb->pSadCost[0];
240
241 if ( pLeftTopMb->uiMbType == MB_TYPE_SKIP )
242 {
243 pMbCache->bMbTypeSkip[0] = 1;
244 pMbCache->iSadCostSkip[0] = pMbCache->pEncSad[-iMbWidth-1];
245 }
246 else
247 {
248 pMbCache->bMbTypeSkip[0] = 0;
249 pMbCache->iSadCostSkip[0] = 0;
250 }
251 }
252 else //unavail
253 {
254 ST32(&pMvComp->sMotionVectorCache[0], 0);
255 pMvComp->iRefIndexCache[0] = (uiNeighborAvail & TOPLEFT_MB_POS) ? REF_NOT_IN_LIST : REF_NOT_AVAIL;
256 pMbCache->iSadCost[0] = 0;
257 pMbCache->bMbTypeSkip[0] = 0;
258 pMbCache->iSadCostSkip[0] = 0;
259 }
260
261 if ((uiNeighborAvail & TOPRIGHT_MB_POS) && IS_SVC_INTER(iRightTopMb->uiMbType) ) //RIGHT_TOP MB
262 {
263 pMvComp->sMotionVectorCache[5] = iRightTopMb->sMv[12];
264 pMvComp->iRefIndexCache[5] = iRightTopMb->pRefIndex[2];
265 pMbCache->iSadCost[2] = iRightTopMb->pSadCost[0];
266
267 if ( iRightTopMb->uiMbType == MB_TYPE_SKIP )
268 {
269 pMbCache->bMbTypeSkip[2] = 1;
270 pMbCache->iSadCostSkip[2] = pMbCache->pEncSad[-iMbWidth+1];
271 }
272 else
273 {
274 pMbCache->bMbTypeSkip[2] = 0;
275 pMbCache->iSadCostSkip[2] = 0;
276 }
277 }
278 else //unavail
279 {
280 ST32(&pMvComp->sMotionVectorCache[5], 0);
281 pMvComp->iRefIndexCache[5] = (uiNeighborAvail & TOPRIGHT_MB_POS) ? REF_NOT_IN_LIST : REF_NOT_AVAIL;
282 pMbCache->iSadCost[2] = 0;
283 pMbCache->bMbTypeSkip[2] = 0;
284 pMbCache->iSadCostSkip[2] = 0;
285 }
286
287 //right-top 4*4 pBlock unavailable
288 ST32(&pMvComp->sMotionVectorCache[ 9], 0);
289 ST32(&pMvComp->sMotionVectorCache[21], 0);
290 ST32(&pMvComp->sMotionVectorCache[11], 0);
291 ST32(&pMvComp->sMotionVectorCache[17], 0);
292 ST32(&pMvComp->sMotionVectorCache[23], 0);
293 pMvComp->iRefIndexCache[ 9] =
294 pMvComp->iRefIndexCache[11] =
295 pMvComp->iRefIndexCache[17] =
296 pMvComp->iRefIndexCache[21] =
297 pMvComp->iRefIndexCache[23] = REF_NOT_AVAIL;
298}
299
300void FillNeighborCacheInterWithBGD(SMbCache* pMbCache, SMB* pCurMb, int32_t iMbWidth, int8_t *pVaaBgMbFlag)
301{
302 uint32_t uiNeighborAvail = pCurMb->uiNeighborAvail;
303 SMB* pLeftMb = pCurMb -1 ;
304 SMB* pTopMb = pCurMb -iMbWidth;
305 SMB* pLeftTopMb = pCurMb - iMbWidth - 1 ;
306 SMB* iRightTopMb = pCurMb -iMbWidth + 1 ;
307 SMVComponentUnit *pMvComp = &pMbCache->sMvComponents;
308
309 if( (uiNeighborAvail & LEFT_MB_POS) && IS_SVC_INTER(pLeftMb->uiMbType) )
310 {
311 pMvComp->sMotionVectorCache[ 6] = pLeftMb->sMv[ 3];
312 pMvComp->sMotionVectorCache[12] = pLeftMb->sMv[ 7];
313 pMvComp->sMotionVectorCache[18] = pLeftMb->sMv[11];
314 pMvComp->sMotionVectorCache[24] = pLeftMb->sMv[15];
315 pMvComp->iRefIndexCache[ 6] = pLeftMb->pRefIndex[1];
316 pMvComp->iRefIndexCache[12] = pLeftMb->pRefIndex[1];
317 pMvComp->iRefIndexCache[18] = pLeftMb->pRefIndex[3];
318 pMvComp->iRefIndexCache[24] = pLeftMb->pRefIndex[3];
319 pMbCache->iSadCost[3] = pLeftMb->pSadCost[0];
320
321 if ( pLeftMb->uiMbType == MB_TYPE_SKIP && pVaaBgMbFlag[-1] == 0)
322 {
323 pMbCache->bMbTypeSkip[3] = 1;
324 pMbCache->iSadCostSkip[3] = pMbCache->pEncSad[-1];
325 }
326 else
327 {
328 pMbCache->bMbTypeSkip[3] = 0;
329 pMbCache->iSadCostSkip[3] = 0;
330 }
331 }
332 else //avail or non-inter
333 {
334 ST32(&pMvComp->sMotionVectorCache[ 6], 0);
335 ST32(&pMvComp->sMotionVectorCache[12], 0);
336 ST32(&pMvComp->sMotionVectorCache[18], 0);
337 ST32(&pMvComp->sMotionVectorCache[24], 0);
338 pMvComp->iRefIndexCache[ 6] =
339 pMvComp->iRefIndexCache[12] =
340 pMvComp->iRefIndexCache[18] =
341 pMvComp->iRefIndexCache[24] = (uiNeighborAvail & LEFT_MB_POS) ? REF_NOT_IN_LIST : REF_NOT_AVAIL;
342 pMbCache->iSadCost[3] = 0;
343 pMbCache->bMbTypeSkip[3] = 0;
344 pMbCache->iSadCostSkip[3] = 0;
345 }
346
347 if ( (uiNeighborAvail & TOP_MB_POS) && IS_SVC_INTER(pTopMb->uiMbType) ) //TOP MB
348 {
349 ST64(&pMvComp->sMotionVectorCache[1], LD64(&pTopMb->sMv[12]));
350 ST64(&pMvComp->sMotionVectorCache[3], LD64(&pTopMb->sMv[14]));
351 pMvComp->iRefIndexCache[1] = pTopMb->pRefIndex[2];
352 pMvComp->iRefIndexCache[2] = pTopMb->pRefIndex[2];
353 pMvComp->iRefIndexCache[3] = pTopMb->pRefIndex[3];
354 pMvComp->iRefIndexCache[4] = pTopMb->pRefIndex[3];
355 pMbCache->iSadCost[1] = pTopMb->pSadCost[0];
356 if ( pTopMb->uiMbType == MB_TYPE_SKIP && pVaaBgMbFlag[-iMbWidth] == 0 )
357 {
358 pMbCache->bMbTypeSkip[1] = 1;
359 pMbCache->iSadCostSkip[1] = pMbCache->pEncSad[-iMbWidth];
360 }
361 else
362 {
363 pMbCache->bMbTypeSkip[1] = 0;
364 pMbCache->iSadCostSkip[1] = 0;
365 }
366 }
367 else //unavail
368 {
369 ST64(&pMvComp->sMotionVectorCache[1], 0);
370 ST64(&pMvComp->sMotionVectorCache[3], 0);
371 pMvComp->iRefIndexCache[1] =
372 pMvComp->iRefIndexCache[2] =
373 pMvComp->iRefIndexCache[3] =
374 pMvComp->iRefIndexCache[4] = (uiNeighborAvail & TOP_MB_POS) ? REF_NOT_IN_LIST : REF_NOT_AVAIL;
375 pMbCache->iSadCost[1] = 0;
376 pMbCache->bMbTypeSkip[1] = 0;
377 pMbCache->iSadCostSkip[1] = 0;
378 }
379
380
381 if ( (uiNeighborAvail & TOPLEFT_MB_POS) && IS_SVC_INTER(pLeftTopMb->uiMbType) ) //LEFT_TOP MB
382 {
383 pMvComp->sMotionVectorCache[0] = pLeftTopMb->sMv[15];
384 pMvComp->iRefIndexCache[0] = pLeftTopMb->pRefIndex[3];
385 pMbCache->iSadCost[0] = pLeftTopMb->pSadCost[0];
386
387 if ( pLeftTopMb->uiMbType == MB_TYPE_SKIP && pVaaBgMbFlag[-iMbWidth-1] == 0 )
388 {
389 pMbCache->bMbTypeSkip[0] = 1;
390 pMbCache->iSadCostSkip[0] = pMbCache->pEncSad[-iMbWidth-1];
391 }
392 else
393 {
394 pMbCache->bMbTypeSkip[0] = 0;
395 pMbCache->iSadCostSkip[0] = 0;
396 }
397 }
398 else //unavail
399 {
400 ST32(&pMvComp->sMotionVectorCache[0], 0);
401 pMvComp->iRefIndexCache[0] = (uiNeighborAvail & TOPLEFT_MB_POS) ? REF_NOT_IN_LIST : REF_NOT_AVAIL;
402 pMbCache->iSadCost[0] = 0;
403 pMbCache->bMbTypeSkip[0] = 0;
404 pMbCache->iSadCostSkip[0] = 0;
405 }
406
407 if ((uiNeighborAvail & TOPRIGHT_MB_POS) && IS_SVC_INTER(iRightTopMb->uiMbType) ) //RIGHT_TOP MB
408 {
409 pMvComp->sMotionVectorCache[5] = iRightTopMb->sMv[12];
410 pMvComp->iRefIndexCache[5] = iRightTopMb->pRefIndex[2];
411 pMbCache->iSadCost[2] = iRightTopMb->pSadCost[0];
412
413 if ( iRightTopMb->uiMbType == MB_TYPE_SKIP && pVaaBgMbFlag[-iMbWidth+1] == 0 )
414 {
415 pMbCache->bMbTypeSkip[2] = 1;
416 pMbCache->iSadCostSkip[2] = pMbCache->pEncSad[-iMbWidth+1];
417 }
418 else
419 {
420 pMbCache->bMbTypeSkip[2] = 0;
421 pMbCache->iSadCostSkip[2] = 0;
422 }
423 }
424 else //unavail
425 {
426 ST32(&pMvComp->sMotionVectorCache[5], 0);
427 pMvComp->iRefIndexCache[5] = (uiNeighborAvail & TOPRIGHT_MB_POS) ? REF_NOT_IN_LIST : REF_NOT_AVAIL;
428 pMbCache->iSadCost[2] = 0;
429 pMbCache->bMbTypeSkip[2] = 0;
430 pMbCache->iSadCostSkip[2] = 0;
431 }
432
433 //right-top 4*4 pBlock unavailable
434 ST32(&pMvComp->sMotionVectorCache[ 9], 0);
435 ST32(&pMvComp->sMotionVectorCache[21], 0);
436 ST32(&pMvComp->sMotionVectorCache[11], 0);
437 ST32(&pMvComp->sMotionVectorCache[17], 0);
438 ST32(&pMvComp->sMotionVectorCache[23], 0);
439 pMvComp->iRefIndexCache[ 9] =
440 pMvComp->iRefIndexCache[11] =
441 pMvComp->iRefIndexCache[17] =
442 pMvComp->iRefIndexCache[21] =
443 pMvComp->iRefIndexCache[23] = REF_NOT_AVAIL;
444}
445
446void InitFillNeighborCacheInterFunc( SWelsFuncPtrList *pFuncList, const int32_t kiFlag )
447{
448 pFuncList->pfFillInterNeighborCache = kiFlag ? FillNeighborCacheInterWithBGD : FillNeighborCacheInterWithoutBGD;
449}
450
451void UpdateMbMv_c( SMVUnitXY *pMvBuffer, const SMVUnitXY ksMv )
452{
453 int32_t k = 0;
454 for (; k < MB_BLOCK4x4_NUM; k += 4)
455 {
456 pMvBuffer[k ] =
457 pMvBuffer[k+1] =
458 pMvBuffer[k+2] =
459 pMvBuffer[k+3] = ksMv;
460 }
461}
462
463
464uint8_t MdInterAnalysisVaaInfo_c( int32_t *pSad8x8 )
465{
466 int32_t iSadBlock[4], iAverageSadBlock[4];
467 int32_t iAverageSad, iVarianceSad;
468
469 iSadBlock[0] = pSad8x8[0];
470 iAverageSad = iSadBlock[0];
471
472 iSadBlock[1] = pSad8x8[1];
473 iAverageSad += iSadBlock[1];
474
475 iSadBlock[2] = pSad8x8[2];
476 iAverageSad += iSadBlock[2];
477
478 iSadBlock[3] = pSad8x8[3];
479 iAverageSad += iSadBlock[3];
480
481 iAverageSad = iAverageSad >> 2;
482
483 iAverageSadBlock[0] = (iSadBlock[0] >> 6) - (iAverageSad >> 6);
484 iVarianceSad = iAverageSadBlock[0] * iAverageSadBlock[0];
485
486 iAverageSadBlock[1] = (iSadBlock[1] >> 6) - (iAverageSad >> 6);
487 iVarianceSad += iAverageSadBlock[1] * iAverageSadBlock[1];
488
489 iAverageSadBlock[2] = (iSadBlock[2] >> 6) - (iAverageSad >> 6);
490 iVarianceSad += iAverageSadBlock[2] * iAverageSadBlock[2];
491
492 iAverageSadBlock[3] = (iSadBlock[3] >> 6) - (iAverageSad >> 6);
493 iVarianceSad += iAverageSadBlock[3] * iAverageSadBlock[3];
494
495 if ( iVarianceSad < INTER_VARIANCE_SAD_THRESHOLD )
496 {
497 return 15;
498 }
499
500 uint8_t uiMbSign = 0;
501 if (iSadBlock[0] > iAverageSad)
502 uiMbSign |= 0x08;
503 if (iSadBlock[1] > iAverageSad)
504 uiMbSign |= 0x04;
505 if (iSadBlock[2] > iAverageSad)
506 uiMbSign |= 0x02;
507 if (iSadBlock[3] > iAverageSad)
508 uiMbSign |= 0x01;
509 return ( uiMbSign );
510}
511
512static inline int32_t AnalysisVaaInfoIntra_c( uint8_t *pDataY, const int32_t kiLineSize )
513{
514 ENFORCE_STACK_ALIGN_1D(uint16_t, uiAvgBlock, 16, 16)
515 uint16_t *pBlock = &uiAvgBlock[0];
516 uint8_t *pEncData = pDataY;
517 const int32_t kiLineSize2 = kiLineSize << 1;
518 const int32_t kiLineSize3 = kiLineSize + kiLineSize2;
519 const int32_t kiLineSize4 = kiLineSize << 2;
520 int32_t i = 0, j = 0, num = 0;
521 int32_t iSumAvg = 0, iSumSqr = 0;
522
523// analysis_vaa_info_intra_core_c( pDataY, iLineSize, pBlock );
524 for ( ; j < 16; j += 4 )
525 {
526 num = 0;
527 for ( i = 0; i < 16; i += 4, num ++ )
528 {
529 pBlock[num] = pEncData[i ] + pEncData[i+1 ] + pEncData[i+2 ] + pEncData[i+3 ];
530 pBlock[num] += pEncData[i+kiLineSize ] + pEncData[i+kiLineSize+1 ] + pEncData[i+kiLineSize+2 ] + pEncData[i+kiLineSize+3 ];
531 pBlock[num] += pEncData[i+kiLineSize2] + pEncData[i+kiLineSize2+1] + pEncData[i+kiLineSize2+2] + pEncData[i+kiLineSize2+3];
532 pBlock[num] += pEncData[i+kiLineSize3] + pEncData[i+kiLineSize3+1] + pEncData[i+kiLineSize3+2] + pEncData[i+kiLineSize3+3];
533 pBlock[num] >>= 4;
534 }
535 pBlock += 4;
536 pEncData += kiLineSize4;
537 }
538
539 pBlock = &uiAvgBlock[0];
540 i = 4;
541 for ( ; i > 0; --i )
542 {
543 iSumAvg += pBlock[0] + pBlock[1] + pBlock[2] + pBlock[3];
544 iSumSqr += pBlock[0] * pBlock[0] + pBlock[1] * pBlock[1] + pBlock[2] * pBlock[2] + pBlock[3] * pBlock[3];
545
546 pBlock += 4;
547 }
548
549
550 return /*variance =*/ (iSumSqr - ((iSumAvg * iSumAvg) >> 4));
551}
552
553// for pfGetVarianceFromIntraVaa function ptr adaptive by CPU features, 6/7/2010
554void InitIntraAnalysisVaaInfo( SWelsFuncPtrList *pFuncList, const uint32_t kuiCpuFlag )
555{
556 pFuncList->pfGetVarianceFromIntraVaa = AnalysisVaaInfoIntra_c;
557 pFuncList->pfGetMbSignFromInterVaa = MdInterAnalysisVaaInfo_c;
558 pFuncList->pfUpdateMbMv = UpdateMbMv_c;
559
560#if defined(X86_ASM)
561 if ( (kuiCpuFlag & WELS_CPU_SSE2) == WELS_CPU_SSE2 )
562 {
563 pFuncList->pfGetVarianceFromIntraVaa = AnalysisVaaInfoIntra_sse2;
564 pFuncList->pfGetMbSignFromInterVaa = MdInterAnalysisVaaInfo_sse2;
565 pFuncList->pfUpdateMbMv = UpdateMbMv_sse2;
566 }
567 if ( (kuiCpuFlag & WELS_CPU_SSSE3) == WELS_CPU_SSSE3 )
568 {
569 pFuncList->pfGetVarianceFromIntraVaa = AnalysisVaaInfoIntra_ssse3;
570 }
571 if ( (kuiCpuFlag & WELS_CPU_SSE41) == WELS_CPU_SSE41 )
572 {
573 pFuncList->pfGetMbSignFromInterVaa = MdInterAnalysisVaaInfo_sse41;
574 }
575#endif//X86_ASM
576}
577
578BOOL_T MdIntraAnalysisVaaInfo( sWelsEncCtx* pEncCtx, uint8_t* pEncMb )
579{
580
581 SDqLayer* pCurDqLayer = pEncCtx->pCurDqLayer;
582 const int32_t kiLineSize = pCurDqLayer->iEncStride[0];
583 const int32_t kiVariance = pEncCtx->pFuncList->pfGetVarianceFromIntraVaa( pEncMb, kiLineSize );
584 return (kiVariance >= INTRA_VARIANCE_SAD_THRESHOLD);
585}
586
587void InitMeRefinePointer(SMeRefinePointer* pMeRefine, SMbCache* pMbCache, int32_t iStride)
588{
589 pMeRefine->pHalfPixH = &pMbCache->pBufferInterPredMe[0] + iStride;
590 pMeRefine->pHalfPixV = &pMbCache->pBufferInterPredMe[640] + iStride;
591
592 pMeRefine->pQuarPixBest= &pMbCache->pBufferInterPredMe[1280] + iStride;
593 pMeRefine->pQuarPixTmp = &pMbCache->pBufferInterPredMe[1920] + iStride;
594}
595typedef struct TagQuarParams
596{
597 int32_t iBestCost;
598 int32_t iBestHalfPix;
599 int32_t iStrideA;
600 int32_t iStrideB;
601 uint8_t * pRef;
602 uint8_t * pSrcB[4];
603 uint8_t * pSrcA[4];
604 int32_t iLms[4];
605 int32_t iBestQuarPix;
606}SQuarRefineParams;
607
608#define SWITCH_BEST_TMP_BUF(prev_best, curr_best){\
609 pParams->iBestCost = iCurCost;\
610 pTmp = prev_best;\
611 prev_best = curr_best;\
612 curr_best = pTmp;\
613}
614#define CALC_COST(me_buf, lm) ( pFunc->sSampleDealingFuncs.pfMeCost[kuiPixel](pEncMb, iStrideEnc, me_buf, ME_REFINE_BUF_STRIDE) + lm )
615
616inline void MeRefineQuarPixel( SWelsFuncPtrList *pFunc, SWelsME* pMe, SMeRefinePointer* pMeRefine, const int32_t kiWidth, const int32_t kiHeight,SQuarRefineParams *pParams, int32_t iStrideEnc )
617{
618 PWelsSampleAveragingFunc *pSampleAvg = pFunc->sMcFuncs.pfSampleAveraging;
619 const int32_t kiAvgIndex = kiWidth >> 4;
620 int32_t iCurCost;
621 uint8_t *pEncMb = pMe->pEncMb;
622 uint8_t *pTmp = NULL;
623 const uint8_t kuiPixel = pMe->uiPixel;
624
625 pSampleAvg[kiAvgIndex](pMeRefine->pQuarPixTmp, ME_REFINE_BUF_STRIDE, pParams->pSrcA[0], ME_REFINE_BUF_STRIDE,pParams->pSrcB[0], pParams->iStrideA, kiHeight);
626
627 iCurCost = CALC_COST(pMeRefine->pQuarPixTmp,pParams->iLms[0]);
628 if (iCurCost < pParams->iBestCost)
629 {
630 pParams->iBestQuarPix = ME_QUAR_PIXEL_TOP;
631 SWITCH_BEST_TMP_BUF(pMeRefine->pQuarPixBest,pMeRefine->pQuarPixTmp);
632 }
633 //=========================(0, 1)=======================//
634 pSampleAvg[kiAvgIndex](pMeRefine->pQuarPixTmp, ME_REFINE_BUF_STRIDE, pParams->pSrcA[1],
635 ME_REFINE_BUF_STRIDE,pParams->pSrcB[1], pParams->iStrideA, kiHeight);
636 iCurCost = CALC_COST(pMeRefine->pQuarPixTmp,pParams->iLms[1]);
637 if (iCurCost < pParams->iBestCost)
638 {
639 pParams->iBestQuarPix = ME_QUAR_PIXEL_BOTTOM;
640 SWITCH_BEST_TMP_BUF(pMeRefine->pQuarPixBest,pMeRefine->pQuarPixTmp);
641 }
642 //==========================(-1, 0)=========================//
643 pSampleAvg[kiAvgIndex](pMeRefine->pQuarPixTmp, ME_REFINE_BUF_STRIDE,pParams->pSrcA[2],
644 ME_REFINE_BUF_STRIDE,pParams->pSrcB[2], pParams->iStrideB, kiHeight);
645 iCurCost = CALC_COST(pMeRefine->pQuarPixTmp,pParams->iLms[2]);
646 if (iCurCost < pParams->iBestCost)
647 {
648 pParams->iBestQuarPix = ME_QUAR_PIXEL_LEFT;
649 SWITCH_BEST_TMP_BUF(pMeRefine->pQuarPixBest,pMeRefine->pQuarPixTmp);
650 }
651 //==========================(1, 0)=========================//
652 pSampleAvg[kiAvgIndex](pMeRefine->pQuarPixTmp, ME_REFINE_BUF_STRIDE,pParams->pSrcA[3],
653 ME_REFINE_BUF_STRIDE, pParams->pSrcB[3], pParams->iStrideB, kiHeight);
654
655 iCurCost = CALC_COST(pMeRefine->pQuarPixTmp,pParams->iLms[3]);
656 if (iCurCost < pParams->iBestCost)
657 {
658 pParams->iBestQuarPix = ME_QUAR_PIXEL_RIGHT;
659 SWITCH_BEST_TMP_BUF(pMeRefine->pQuarPixBest,pMeRefine->pQuarPixTmp);
660 }
661}
662
663void MeRefineFracPixel(sWelsEncCtx* pEncCtx, uint8_t* pMemPredInterMb, SWelsME* pMe,
664 SMeRefinePointer* pMeRefine, int32_t iWidth, int32_t iHeight)
665{
666 SWelsFuncPtrList *pFunc= pEncCtx->pFuncList;
667 int16_t iMvx = pMe->sMv.iMvX;
668 int16_t iMvy = pMe->sMv.iMvY;
669
670 int16_t iHalfMvx = iMvx;
671 int16_t iHalfMvy = iMvy;
672 const int32_t kiStrideEnc = pEncCtx->pCurDqLayer->iEncStride[0];
673 const int32_t kiStrideRef = pEncCtx->pCurDqLayer->pRefPic->iLineSize[0];
674
675 uint8_t* pEncData = pMe->pEncMb;
676 uint8_t* pRef = pMe->pRefMb;//091010
677
678 int32_t iBestQuarPix = ME_NO_BEST_QUAR_PIXEL;
679
680 SQuarRefineParams sParams;
681 static int32_t iMvQuarAddX[10] = {0,0,-1,1,0,0,0,-1,1,0};
682 int32_t *pMvQuarAddY = iMvQuarAddX + 3;
683 uint8_t* pBestPredInter = pRef;
684 int32_t iInterBlk4Stride = ME_REFINE_BUF_STRIDE;
685
686 int32_t iBestCost;
687 int32_t iCurCost;
688 int32_t iBestHalfPix;
689
690 if ((pFunc->sSampleDealingFuncs.pfMeCost == pFunc->sSampleDealingFuncs.pfSampleSatd) && (pFunc->sSampleDealingFuncs.pfMdCost == pFunc->sSampleDealingFuncs.pfSampleSatd))
691 {
692 iBestCost = pMe->uSadPredISatd.uiSatd + COST_MVD(pMe->pMvdCost, iMvx - pMe->sMvp.iMvX, iMvy - pMe->sMvp.iMvY);
693 }
694 else
695 {
696 iBestCost = pFunc->sSampleDealingFuncs.pfMeCost[pMe->uiPixel]( pEncData, kiStrideEnc, pRef, kiStrideRef ) +
697 COST_MVD(pMe->pMvdCost, iMvx - pMe->sMvp.iMvX, iMvy - pMe->sMvp.iMvY);
698 }
699
700 iBestHalfPix = REFINE_ME_NO_BEST_HALF_PIXEL;
701
702 pFunc->sMcFuncs.pfLumaHalfpelVer( pRef-kiStrideRef, kiStrideRef, pMeRefine->pHalfPixV, ME_REFINE_BUF_STRIDE, iWidth, iHeight+1 );
703
704 //step 1: get [iWidth][iHeight+1] half pixel from vertical filter
705 //===========================(0, -2)==============================//
706 iCurCost = pFunc->sSampleDealingFuncs.pfMeCost[pMe->uiPixel](pEncData, kiStrideEnc, pMeRefine->pHalfPixV, ME_REFINE_BUF_STRIDE) +
707 COST_MVD( pMe->pMvdCost, iMvx - pMe->sMvp.iMvX, iMvy - 2 - pMe->sMvp.iMvY );
708 if(iCurCost < iBestCost)
709 {
710 iBestCost = iCurCost;
711 iBestHalfPix = REFINE_ME_HALF_PIXEL_TOP;
712 pBestPredInter = pMeRefine->pHalfPixV;
713 }
714 //===========================(0, 2)==============================//
715 iCurCost = pFunc->sSampleDealingFuncs.pfMeCost[pMe->uiPixel](pEncData, kiStrideEnc, pMeRefine->pHalfPixV+ME_REFINE_BUF_STRIDE, ME_REFINE_BUF_STRIDE) +
716 COST_MVD( pMe->pMvdCost, iMvx - pMe->sMvp.iMvX, iMvy + 2 - pMe->sMvp.iMvY );
717 if(iCurCost < iBestCost)
718 {
719 iBestCost = iCurCost;
720 iBestHalfPix = REFINE_ME_HALF_PIXEL_BOTTOM;
721 pBestPredInter = pMeRefine->pHalfPixV+ME_REFINE_BUF_STRIDE;
722 }
723 pFunc->sMcFuncs.pfLumaHalfpelHor( pRef-1, kiStrideRef, pMeRefine->pHalfPixH, ME_REFINE_BUF_STRIDE, iWidth+1, iHeight );
724 //step 2: get [iWidth][iHeight+1] half pixel from horizon filter
725
726 //===========================(-2, 0)==============================//
727 iCurCost = pFunc->sSampleDealingFuncs.pfMeCost[pMe->uiPixel](pEncData, kiStrideEnc, pMeRefine->pHalfPixH, ME_REFINE_BUF_STRIDE) +
728 COST_MVD( pMe->pMvdCost, iMvx - 2 - pMe->sMvp.iMvX, iMvy - pMe->sMvp.iMvY );
729 if(iCurCost < iBestCost)
730 {
731 iBestCost = iCurCost;
732 iBestHalfPix = REFINE_ME_HALF_PIXEL_LEFT;
733 pBestPredInter = pMeRefine->pHalfPixH;
734 }
735 //===========================(2, 0)===============================//
736 iCurCost = pFunc->sSampleDealingFuncs.pfMeCost[pMe->uiPixel](pEncData, kiStrideEnc, pMeRefine->pHalfPixH+1, ME_REFINE_BUF_STRIDE) +
737 COST_MVD( pMe->pMvdCost, iMvx + 2 - pMe->sMvp.iMvX, iMvy - pMe->sMvp.iMvY );
738 if(iCurCost < iBestCost)
739 {
740 iBestCost = iCurCost;
741 iBestHalfPix = REFINE_ME_HALF_PIXEL_RIGHT;
742 pBestPredInter = pMeRefine->pHalfPixH+1;
743 }
744
745 sParams.iBestCost = iBestCost;
746 sParams.iBestHalfPix = iBestHalfPix;
747 sParams.pRef = pRef;
748 sParams.iBestQuarPix = ME_NO_BEST_QUAR_PIXEL;
749
750 //step 5: if no best half-pixel prediction, try quarter pixel prediction
751 // if yes, must get [X+1][X+1] half-pixel from (2, 2) horizontal and vertical filter
752 if (REFINE_ME_NO_BEST_HALF_PIXEL == iBestHalfPix)
753 {
754 sParams.iStrideA = kiStrideRef;
755 sParams.iStrideB = kiStrideRef;
756 sParams.pSrcA[0] = pMeRefine->pHalfPixV;
757 sParams.pSrcA[1] = pMeRefine->pHalfPixV+ME_REFINE_BUF_STRIDE;
758 sParams.pSrcA[2] = pMeRefine->pHalfPixH;
759 sParams.pSrcA[3] = pMeRefine->pHalfPixH+1;
760
761 sParams.pSrcB[0] = sParams.pSrcB[1] = sParams.pSrcB[2] = sParams.pSrcB[3] = pRef;
762
763 sParams.iLms[0] = COST_MVD( pMe->pMvdCost, iHalfMvx - pMe->sMvp.iMvX, iHalfMvy - 1 - pMe->sMvp.iMvY );
764 sParams.iLms[1] = COST_MVD( pMe->pMvdCost, iHalfMvx - pMe->sMvp.iMvX, iHalfMvy + 1 - pMe->sMvp.iMvY );
765 sParams.iLms[2] = COST_MVD( pMe->pMvdCost, iHalfMvx - 1 - pMe->sMvp.iMvX, iHalfMvy - pMe->sMvp.iMvY );
766 sParams.iLms[3] = COST_MVD( pMe->pMvdCost, iHalfMvx + 1 - pMe->sMvp.iMvX, iHalfMvy - pMe->sMvp.iMvY );
767 }
768 else //must get [X+1][X+1] half-pixel from (2, 2) horizontal and vertical filter
769 {
770 switch(iBestHalfPix)
771 {
772 case REFINE_ME_HALF_PIXEL_LEFT:
773 {
774 pMeRefine->pHalfPixHV = pMeRefine->pHalfPixV;//reuse pBuffer, here only h&hv
775 pFunc->sMcFuncs.pfLumaHalfpelCen( pRef-1-kiStrideRef, kiStrideRef, pMeRefine->pHalfPixHV,ME_REFINE_BUF_STRIDE,iWidth+1, iHeight+1 );
776
777 iHalfMvx -= 2;
778 sParams.iStrideA = ME_REFINE_BUF_STRIDE;
779 sParams.iStrideB = kiStrideRef;
780 sParams.pSrcA[0] = pMeRefine->pHalfPixH;
781 sParams.pSrcA[3] = sParams.pSrcA[2] = sParams.pSrcA[1] = sParams.pSrcA[0];
782 sParams.pSrcB[0] = pMeRefine->pHalfPixHV;
783 sParams.pSrcB[1] = pMeRefine->pHalfPixHV+ME_REFINE_BUF_STRIDE;
784 sParams.pSrcB[2] = pRef - 1;
785 sParams.pSrcB[3] = pRef;
786
787 }break;
788 case REFINE_ME_HALF_PIXEL_RIGHT:
789 {
790 pMeRefine->pHalfPixHV = pMeRefine->pHalfPixV;//reuse pBuffer, here only h&hv
791 pFunc->sMcFuncs.pfLumaHalfpelCen( pRef-1-kiStrideRef, kiStrideRef, pMeRefine->pHalfPixHV,ME_REFINE_BUF_STRIDE,iWidth+1, iHeight+1 );
792 iHalfMvx += 2;
793 sParams.iStrideA = ME_REFINE_BUF_STRIDE;
794 sParams.iStrideB = kiStrideRef;
795 sParams.pSrcA[0] = pMeRefine->pHalfPixH+1;
796 sParams.pSrcA[3] = sParams.pSrcA[2] = sParams.pSrcA[1] = sParams.pSrcA[0];
797 sParams.pSrcB[0] = pMeRefine->pHalfPixHV+1;
798 sParams.pSrcB[1] = pMeRefine->pHalfPixHV+1+ ME_REFINE_BUF_STRIDE;
799 sParams.pSrcB[2] = pRef;
800 sParams.pSrcB[3] = pRef + 1;
801 }break;
802 case REFINE_ME_HALF_PIXEL_TOP:
803 {
804 pMeRefine->pHalfPixHV = pMeRefine->pHalfPixH;//reuse pBuffer, here only v&hv
805 pFunc->sMcFuncs.pfLumaHalfpelCen( pRef-1-kiStrideRef, kiStrideRef, pMeRefine->pHalfPixHV,ME_REFINE_BUF_STRIDE,iWidth+1, iHeight+1 );
806
807 iHalfMvy -= 2;
808 sParams.iStrideA = kiStrideRef;
809 sParams.iStrideB = ME_REFINE_BUF_STRIDE;
810 sParams.pSrcA[0] = pMeRefine->pHalfPixV;
811 sParams.pSrcA[3] = sParams.pSrcA[2] = sParams.pSrcA[1] = sParams.pSrcA[0];
812 sParams.pSrcB[0] = pRef - kiStrideRef;
813 sParams.pSrcB[1] = pRef;
814 sParams.pSrcB[2] = pMeRefine->pHalfPixHV;
815 sParams.pSrcB[3] = pMeRefine->pHalfPixHV+1;
816 }break;
817 case REFINE_ME_HALF_PIXEL_BOTTOM:
818 {
819 pMeRefine->pHalfPixHV = pMeRefine->pHalfPixH;//reuse pBuffer, here only v&hv
820 pFunc->sMcFuncs.pfLumaHalfpelCen( pRef-1-kiStrideRef, kiStrideRef, pMeRefine->pHalfPixHV,ME_REFINE_BUF_STRIDE,iWidth+1, iHeight+1 );
821 iHalfMvy += 2;
822 sParams.iStrideA = kiStrideRef;
823 sParams.iStrideB = ME_REFINE_BUF_STRIDE;
824 sParams.pSrcA[0] = pMeRefine->pHalfPixV + ME_REFINE_BUF_STRIDE;
825 sParams.pSrcA[3] = sParams.pSrcA[2] = sParams.pSrcA[1] = sParams.pSrcA[0];
826 sParams.pSrcB[0] = pRef;
827 sParams.pSrcB[1] = pRef + kiStrideRef;
828 sParams.pSrcB[2] = pMeRefine->pHalfPixHV + ME_REFINE_BUF_STRIDE;
829 sParams.pSrcB[3] = pMeRefine->pHalfPixHV + ME_REFINE_BUF_STRIDE + 1;
830 }break;
831 default:
832 break;
833 }
834 sParams.iLms[0] = COST_MVD( pMe->pMvdCost, iHalfMvx - pMe->sMvp.iMvX, iHalfMvy - 1 - pMe->sMvp.iMvY );
835 sParams.iLms[1] = COST_MVD( pMe->pMvdCost, iHalfMvx - pMe->sMvp.iMvX, iHalfMvy + 1 - pMe->sMvp.iMvY );
836 sParams.iLms[2] = COST_MVD( pMe->pMvdCost, iHalfMvx - 1 - pMe->sMvp.iMvX, iHalfMvy - pMe->sMvp.iMvY );
837 sParams.iLms[3] = COST_MVD( pMe->pMvdCost, iHalfMvx + 1 - pMe->sMvp.iMvX, iHalfMvy - pMe->sMvp.iMvY );
838 }
839 MeRefineQuarPixel(pFunc, pMe, pMeRefine, iWidth, iHeight, &sParams, kiStrideEnc);
840
841 if(iBestCost > sParams.iBestCost)
842 {
843 pBestPredInter = pMeRefine->pQuarPixBest;
844 iBestCost = sParams.iBestCost;
845 }
846 iBestQuarPix = sParams.iBestQuarPix;
847
848 //update final best MV
849 pMe->sMv.iMvX = iHalfMvx + iMvQuarAddX[iBestQuarPix];
850 pMe->sMv.iMvY = iHalfMvy + pMvQuarAddY[iBestQuarPix];
851 pMe->uiSatdCost = iBestCost;
852
853 //No half or quarter pixel best, so do MC with integer pixel MV
854 if ( iBestHalfPix+iBestQuarPix == NO_BEST_FRAC_PIX )
855 {
856 pBestPredInter = pRef;
857 iInterBlk4Stride = kiStrideRef;
858 }
859 if ( MB_WIDTH_LUMA == iWidth && MB_HEIGHT_LUMA == iHeight ) //P16x16
860 {
861 pFunc->pfCopy16x16NotAligned( pMemPredInterMb, MB_WIDTH_LUMA, pBestPredInter, iInterBlk4Stride ); // dst can be align with 16 bytes, but not sure at pSrc, 12/29/2011
862 }
863 else if ( MB_WIDTH_LUMA == iWidth && MB_HEIGHT_CHROMA == iHeight ) //P16x8
864 {
865 pFunc->pfCopy16x8NotAligned( pMemPredInterMb, MB_WIDTH_LUMA, pBestPredInter, iInterBlk4Stride ); // dst can be align with 16 bytes, but not sure at pSrc, 12/29/2011
866 }
867 else if ( MB_WIDTH_CHROMA == iWidth && MB_HEIGHT_LUMA == iHeight ) //P8x16
868 {
869 pFunc->pfCopy8x16Aligned( pMemPredInterMb, MB_WIDTH_LUMA, pBestPredInter, iInterBlk4Stride );
870 }
871 else //P8x8
872 {
873 pFunc->pfCopy8x8Aligned( pMemPredInterMb, MB_WIDTH_LUMA, pBestPredInter, iInterBlk4Stride );
874 }
875}
876
877void InitBlkStrideWithRef(int32_t* pBlkStride, const int32_t kiStrideRef)
878{
879 static const uint8_t kuiStrideX[16] =
880 {
881 0, 4 , 0, 4 ,
882 8, 12, 8, 12,
883 0, 4 , 0, 4 ,
884 8, 12, 8, 12
885 };
886 static const uint8_t kuiStrideY[16] =
887 {
888 0, 0, 4 , 4 ,
889 0, 0, 4 , 4 ,
890 8, 8, 12, 12,
891 8, 8, 12, 12
892 };
893 int32_t i;
894
895 for (i = 0; i < 16; i+=4)
896 {
897 pBlkStride[i ] = kuiStrideX[i ] + kuiStrideY[i ] * kiStrideRef;
898 pBlkStride[i+1] = kuiStrideX[i+1] + kuiStrideY[i+1] * kiStrideRef;
899 pBlkStride[i+2] = kuiStrideX[i+2] + kuiStrideY[i+2] * kiStrideRef;
900 pBlkStride[i+3] = kuiStrideX[i+3] + kuiStrideY[i+3] * kiStrideRef;
901 }
902}
903
904/*
905 * iMvdSz = (648*2+1) or (972*2+1);
906 */
907void MvdCostInit( uint16_t* pMvdCostInter, const int32_t kiMvdSz )
908{
909 const int32_t kiSz = kiMvdSz >> 1;
910 uint16_t *pNegMvd = pMvdCostInter;
911 uint16_t *pPosMvd = pMvdCostInter+kiSz+1;
912 const int32_t *kpQpLambda= &g_kiQpCostTable[0];
913 int32_t i,j;
914
915 for( i = 0; i < 52; ++ i )
916 {
917 const uint16_t kiLambda = kpQpLambda[i];
918 int32_t iNegSe = -kiSz;
919 int32_t iPosSe = 1;
920
921 for (j = 0; j < kiSz; j += 4)
922 {
923 *pNegMvd++ = kiLambda * BsSizeSE(iNegSe++);
924 *pNegMvd++ = kiLambda * BsSizeSE(iNegSe++);
925 *pNegMvd++ = kiLambda * BsSizeSE(iNegSe++);
926 *pNegMvd++ = kiLambda * BsSizeSE(iNegSe++);
927
928 *pPosMvd++ = kiLambda * BsSizeSE(iPosSe++);
929 *pPosMvd++ = kiLambda * BsSizeSE(iPosSe++);
930 *pPosMvd++ = kiLambda * BsSizeSE(iPosSe++);
931 *pPosMvd++ = kiLambda * BsSizeSE(iPosSe++);
932 }
933 *pNegMvd = kiLambda;
934 pNegMvd += kiSz+1;
935 pPosMvd += kiSz+1;
936 }
937}
938
939void PredictSad( int8_t* pRefIndexCache, int32_t* pSadCostCache, int32_t uiRef, int32_t * pSadPred )
940{
941 const int32_t kiRefB = pRefIndexCache[1];//top g_uiCache12_8x8RefIdx[0] - 4
942 int32_t iRefC = pRefIndexCache[5];//top-right g_uiCache12_8x8RefIdx[0] - 2
943 const int32_t kiRefA = pRefIndexCache[6];//left g_uiCache12_8x8RefIdx[0] - 1
944 const int32_t kiSadB = pSadCostCache[1];
945 int32_t iSadC = pSadCostCache[2];
946 const int32_t kiSadA = pSadCostCache[3];
947
948 int32_t iCount;
949
950 if( iRefC == REF_NOT_AVAIL )
951 {
952 iRefC = pRefIndexCache[0];//top-left g_uiCache12_8x8RefIdx[0] - 4 - 1
953 iSadC = pSadCostCache[0];
954 }
955
956 if( kiRefB == REF_NOT_AVAIL && iRefC == REF_NOT_AVAIL && kiRefA != REF_NOT_AVAIL )
957 {
958 * pSadPred = kiSadA;
959 }
960 else
961 {
962 iCount = (uiRef == kiRefA)<<MB_LEFT_BIT;
963 iCount |= (uiRef == kiRefB)<<MB_TOP_BIT;
964 iCount |= (uiRef == iRefC)<<MB_TOPRIGHT_BIT;
965 switch(iCount)
966 {
967 case LEFT_MB_POS:// A
968 *pSadPred = kiSadA;
969 break;
970 case TOP_MB_POS:// B
971 *pSadPred = kiSadB;
972 break;
973 case TOPRIGHT_MB_POS:// C or D
974 *pSadPred = iSadC;
975 break;
976 default:
977 *pSadPred = WELS_MEDIAN( kiSadA, kiSadB, iSadC );
978 break;
979 }
980 }
981
982#define REPLACE_SAD_MULTIPLY(x) ((x) - (x>>3) + (x >>5)) // it's 0.90625, very close with 0.9
983 iCount = (*pSadPred)<<6; // here *64 will not overflow. SAD range 0~ 255*256(max 2^16), int32_t is enough
984 *pSadPred = (REPLACE_SAD_MULTIPLY(iCount) + 32)>>6;
985#undef REPLACE_SAD_MULTIPLY
986}
987
988
989void PredictSadSkip( int8_t* pRefIndexCache, bool_t* pMbSkipCache, int32_t* pSadCostCache, int32_t uiRef, int32_t * iSadPredSkip )
990{
991 const int32_t kiRefB = pRefIndexCache[1];//top g_uiCache12_8x8RefIdx[0] - 4
992 int32_t iRefC = pRefIndexCache[5];//top-right g_uiCache12_8x8RefIdx[0] - 2
993 const int32_t kiRefA = pRefIndexCache[6];//left g_uiCache12_8x8RefIdx[0] - 1
994 const int32_t kiSadB = (pMbSkipCache[1]==1 ? pSadCostCache[1] : 0);
995 int32_t iSadC = (pMbSkipCache[2]==1 ? pSadCostCache[2] : 0);
996 const int32_t kiSadA = (pMbSkipCache[3]==1 ? pSadCostCache[3] : 0);
997 int32_t iRefSkip = pMbSkipCache[2];
998
999 int32_t iCount = 0;
1000
1001 if( iRefC == REF_NOT_AVAIL )
1002 {
1003 iRefC = pRefIndexCache[0];//top-left g_uiCache12_8x8RefIdx[0] - 4 - 1
1004 iSadC = (pMbSkipCache[0]==1 ? pSadCostCache[0] : 0);
1005 iRefSkip = pMbSkipCache[0];
1006 }
1007
1008 if( kiRefB == REF_NOT_AVAIL && iRefC == REF_NOT_AVAIL && kiRefA != REF_NOT_AVAIL )
1009 {
1010 * iSadPredSkip = kiSadA;
1011 }
1012 else
1013 {
1014 iCount = ((uiRef == kiRefA) && (pMbSkipCache[3]==1))<<MB_LEFT_BIT;
1015 iCount |= ((uiRef == kiRefB) && (pMbSkipCache[1]==1))<<MB_TOP_BIT;
1016 iCount |= ((uiRef == iRefC) && (iRefSkip==1))<<MB_TOPRIGHT_BIT;
1017 switch(iCount)
1018 {
1019 case LEFT_MB_POS:// A
1020 *iSadPredSkip = kiSadA;
1021 break;
1022 case TOP_MB_POS:// B
1023 *iSadPredSkip = kiSadB;
1024 break;
1025 case TOPRIGHT_MB_POS:// C or D
1026 *iSadPredSkip = iSadC;
1027 break;
1028 default:
1029 *iSadPredSkip = WELS_MEDIAN( kiSadA, kiSadB, iSadC );
1030 break;
1031 }
1032 }
1033}
1034}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t