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+
53+namespace 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
58+void 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
154+void 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+
300+void 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+
446+void InitFillNeighborCacheInterFunc( SWelsFuncPtrList *pFuncList, const int32_t kiFlag )
447+{
448+ pFuncList->pfFillInterNeighborCache = kiFlag ? FillNeighborCacheInterWithBGD : FillNeighborCacheInterWithoutBGD;
449+}
450+
451+void 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+
464+uint8_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+
512+static 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
554+void 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+
578+BOOL_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+
587+void 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+}
595+typedef 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+
616+inline 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+
663+void 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+
877+void 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+ */
907+void 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+
939+void 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+
989+void 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