History

B-frame decoding support for Main and High Profile with two test cases.

xiaotianshi2 committed 8 years ago

Commit 657d2171 parent e3e838355 files · +17936 −13825Browse files

Showing the changes to codec/decoder/core/src/mv_pred.cpp (1 of 55 files). Show all

Unified · Split

codec/decoder/core/src/mv_pred.cpp+728−135
@@ -41,8 +41,120 @@ · 40 unmodified lines
4141 #include "mv_pred.h"
4242 #include "ls_defines.h"
4343 #include "mb_cache.h"
44+#include "parse_mb_syn_cabac.h"
4445
4546 namespace WelsDec {
47+
48+static inline void SetRectBlock (void* vp, int32_t w, const int32_t h, int32_t stride, const uint32_t val,
49+ const int32_t size) {
50+ uint8_t* p = (uint8_t*)vp;
51+ w *= size;
52+ if (w == 1 && h == 4) {
53+ * (uint8_t*) (p + 0 * stride) =
54+ * (uint8_t*) (p + 1 * stride) =
55+ * (uint8_t*) (p + 2 * stride) =
56+ * (uint8_t*) (p + 3 * stride) = (uint8_t)val;
57+ } else if (w == 2 && h == 2) {
58+ * (uint16_t*) (p + 0 * stride) =
59+ * (uint16_t*) (p + 1 * stride) = size == 4 ? (uint16_t)val : (uint16_t) (val * 0x0101U);
60+ } else if (w == 2 && h == 4) {
61+ * (uint16_t*) (p + 0 * stride) =
62+ * (uint16_t*) (p + 1 * stride) =
63+ * (uint16_t*) (p + 2 * stride) =
64+ * (uint16_t*) (p + 3 * stride) = size == 4 ? (uint16_t)val : (uint16_t) (val * 0x0101U);
65+ } else if (w == 4 && h == 2) {
66+ * (uint32_t*) (p + 0 * stride) =
67+ * (uint32_t*) (p + 1 * stride) = size == 4 ? val : (uint32_t) (val * 0x01010101UL);
68+ } else if (w == 4 && h == 4) {
69+ * (uint32_t*) (p + 0 * stride) =
70+ * (uint32_t*) (p + 1 * stride) =
71+ * (uint32_t*) (p + 2 * stride) =
72+ * (uint32_t*) (p + 3 * stride) = size == 4 ? val : (uint32_t) (val * 0x01010101UL);
73+ } else if (w == 8 && h == 1) {
74+ * (uint32_t*) (p + 0 * stride) =
75+ * (uint32_t*) (p + 0 * stride + 4) = size == 4 ? val : (uint32_t) (val * 0x01010101UL);
76+ } else if (w == 8 && h == 2) {
77+ * (uint32_t*) (p + 0 * stride) =
78+ * (uint32_t*) (p + 0 * stride + 4) =
79+ * (uint32_t*) (p + 1 * stride) =
80+ * (uint32_t*) (p + 1 * stride + 4) = size == 4 ? val : (uint32_t) (val * 0x01010101UL);
81+ } else if (w == 8 && h == 4) {
82+ * (uint32_t*) (p + 0 * stride) =
83+ * (uint32_t*) (p + 0 * stride + 4) =
84+ * (uint32_t*) (p + 1 * stride) =
85+ * (uint32_t*) (p + 1 * stride + 4) =
86+ * (uint32_t*) (p + 2 * stride) =
87+ * (uint32_t*) (p + 2 * stride + 4) =
88+ * (uint32_t*) (p + 3 * stride) =
89+ * (uint32_t*) (p + 3 * stride + 4) = size == 4 ? val : (uint32_t) (val * 0x01010101UL);
90+ } else if (w == 16 && h == 2) {
91+ * (uint32_t*) (p + 0 * stride + 0) =
92+ * (uint32_t*) (p + 0 * stride + 4) =
93+ * (uint32_t*) (p + 0 * stride + 8) =
94+ * (uint32_t*) (p + 0 * stride + 12) =
95+ * (uint32_t*) (p + 1 * stride + 0) =
96+ * (uint32_t*) (p + 1 * stride + 4) =
97+ * (uint32_t*) (p + 1 * stride + 8) =
98+ * (uint32_t*) (p + 1 * stride + 12) = size == 4 ? val : (uint32_t) (val * 0x01010101UL);
99+ } else if (w == 16 && h == 3) {
100+ * (uint32_t*) (p + 0 * stride + 0) =
101+ * (uint32_t*) (p + 0 * stride + 4) =
102+ * (uint32_t*) (p + 0 * stride + 8) =
103+ * (uint32_t*) (p + 0 * stride + 12) =
104+ * (uint32_t*) (p + 1 * stride + 0) =
105+ * (uint32_t*) (p + 1 * stride + 4) =
106+ * (uint32_t*) (p + 1 * stride + 8) =
107+ * (uint32_t*) (p + 1 * stride + 12) =
108+ * (uint32_t*) (p + 2 * stride + 0) =
109+ * (uint32_t*) (p + 2 * stride + 4) =
110+ * (uint32_t*) (p + 2 * stride + 8) =
111+ * (uint32_t*) (p + 2 * stride + 12) = size == 4 ? val : (uint32_t) (val * 0x01010101UL);
112+ } else if (w == 16 && h == 4) {
113+ * (uint32_t*) (p + 0 * stride + 0) =
114+ * (uint32_t*) (p + 0 * stride + 4) =
115+ * (uint32_t*) (p + 0 * stride + 8) =
116+ * (uint32_t*) (p + 0 * stride + 12) =
117+ * (uint32_t*) (p + 1 * stride + 0) =
118+ * (uint32_t*) (p + 1 * stride + 4) =
119+ * (uint32_t*) (p + 1 * stride + 8) =
120+ * (uint32_t*) (p + 1 * stride + 12) =
121+ * (uint32_t*) (p + 2 * stride + 0) =
122+ * (uint32_t*) (p + 2 * stride + 4) =
123+ * (uint32_t*) (p + 2 * stride + 8) =
124+ * (uint32_t*) (p + 2 * stride + 12) =
125+ * (uint32_t*) (p + 3 * stride + 0) =
126+ * (uint32_t*) (p + 3 * stride + 4) =
127+ * (uint32_t*) (p + 3 * stride + 8) =
128+ * (uint32_t*) (p + 3 * stride + 12) = size == 4 ? val : (uint32_t) (val * 0x01010101UL);
129+ }
130+}
131+void CopyRectBlock4Cols (void* vdst, void* vsrc, const int32_t stride_dst, const int32_t stride_src, int32_t w,
132+ const int32_t size) {
133+ uint8_t* dst = (uint8_t*)vdst;
134+ uint8_t* src = (uint8_t*)vsrc;
135+ w *= size;
136+ if (w == 1) {
137+ dst[stride_dst * 0] = src[stride_src * 0];
138+ dst[stride_dst * 1] = src[stride_src * 1];
139+ dst[stride_dst * 2] = src[stride_src * 2];
140+ dst[stride_dst * 3] = src[stride_src * 3];
141+ } else if (w == 2) {
142+ * (uint16_t*) (&dst[stride_dst * 0]) = * (uint16_t*) (&src[stride_src * 0]);
143+ * (uint16_t*) (&dst[stride_dst * 1]) = * (uint16_t*) (&src[stride_src * 1]);
144+ * (uint16_t*) (&dst[stride_dst * 2]) = * (uint16_t*) (&src[stride_src * 2]);
145+ * (uint16_t*) (&dst[stride_dst * 3]) = * (uint16_t*) (&src[stride_src * 3]);
146+ } else if (w == 4) {
147+ * (uint32_t*) (&dst[stride_dst * 0]) = * (uint32_t*) (&src[stride_src * 0]);
148+ * (uint32_t*) (&dst[stride_dst * 1]) = * (uint32_t*) (&src[stride_src * 1]);
149+ * (uint32_t*) (&dst[stride_dst * 2]) = * (uint32_t*) (&src[stride_src * 2]);
150+ * (uint32_t*) (&dst[stride_dst * 3]) = * (uint32_t*) (&src[stride_src * 3]);
151+ } else if (w == 16) {
152+ memcpy (&dst[stride_dst * 0], &src[stride_src * 0], 16);
153+ memcpy (&dst[stride_dst * 1], &src[stride_src * 1], 16);
154+ memcpy (&dst[stride_dst * 2], &src[stride_src * 2], 16);
155+ memcpy (&dst[stride_dst * 3], &src[stride_src * 3], 16);
156+ }
157+}
46158 void PredPSkipMvFromNeighbor (PDqLayer pCurLayer, int16_t iMvp[2]) {
47159 bool bTopAvail, bLeftTopAvail, bRightTopAvail, bLeftAvail;
48160
@@ -52,15 +164,237 @@ void PredPSkipMvFromNeighbor (PDqLayer pCurLayer, int16_t iMvp[2]) { · 3 unmodified lines
52164
53165 int8_t iLeftRef;
54166 int8_t iTopRef;
55− int8_t iRightTopRef;
56− int8_t iLeftTopRef;
57− int8_t iDiagonalRef;
58− int8_t iMatchRef;
59− int16_t iMvA[2], iMvB[2], iMvC[2], iMvD[2];
167+ int8_t iRightTopRef;
168+ int8_t iLeftTopRef;
169+ int8_t iDiagonalRef;
170+ int8_t iMatchRef;
171+ int16_t iMvA[2], iMvB[2], iMvC[2], iMvD[2];
172+
173+ iCurXy = pCurLayer->iMbXyIndex;
174+ iCurX = pCurLayer->iMbX;
175+ iCurY = pCurLayer->iMbY;
176+ iCurSliceIdc = pCurLayer->pSliceIdc[iCurXy];
177+
178+ if (iCurX != 0) {
179+ iLeftXy = iCurXy - 1;
180+ iLeftSliceIdc = pCurLayer->pSliceIdc[iLeftXy];
181+ bLeftAvail = (iLeftSliceIdc == iCurSliceIdc);
182+ } else {
183+ bLeftAvail = 0;
184+ bLeftTopAvail = 0;
185+ }
186+
187+ if (iCurY != 0) {
188+ iTopXy = iCurXy - pCurLayer->iMbWidth;
189+ iTopSliceIdc = pCurLayer->pSliceIdc[iTopXy];
190+ bTopAvail = (iTopSliceIdc == iCurSliceIdc);
191+ if (iCurX != 0) {
192+ iLeftTopXy = iTopXy - 1;
193+ iLeftTopSliceIdc = pCurLayer->pSliceIdc[iLeftTopXy];
194+ bLeftTopAvail = (iLeftTopSliceIdc == iCurSliceIdc);
195+ } else {
196+ bLeftTopAvail = 0;
197+ }
198+ if (iCurX != (pCurLayer->iMbWidth - 1)) {
199+ iRightTopXy = iTopXy + 1;
200+ iRightTopSliceIdc = pCurLayer->pSliceIdc[iRightTopXy];
201+ bRightTopAvail = (iRightTopSliceIdc == iCurSliceIdc);
202+ } else {
203+ bRightTopAvail = 0;
204+ }
205+ } else {
206+ bTopAvail = 0;
207+ bLeftTopAvail = 0;
208+ bRightTopAvail = 0;
209+ }
210+
211+ iLeftType = ((iCurX != 0 && bLeftAvail) ? pCurLayer->pMbType[iLeftXy] : 0);
212+ iTopType = ((iCurY != 0 && bTopAvail) ? pCurLayer->pMbType[iTopXy] : 0);
213+ iLeftTopType = ((iCurX != 0 && iCurY != 0 && bLeftTopAvail)
214+ ? pCurLayer->pMbType[iLeftTopXy] : 0);
215+ iRightTopType = ((iCurX != pCurLayer->iMbWidth - 1 && iCurY != 0 && bRightTopAvail)
216+ ? pCurLayer->pMbType[iRightTopXy] : 0);
217+
218+ /*get neb mv&iRefIdxArray*/
219+ /*left*/
220+ if (bLeftAvail && IS_INTER (iLeftType)) {
221+ ST32 (iMvA, LD32 (pCurLayer->pMv[0][iLeftXy][3]));
222+ iLeftRef = pCurLayer->pRefIndex[0][iLeftXy][3];
223+ } else {
224+ ST32 (iMvA, 0);
225+ if (0 == bLeftAvail) { //not available
226+ iLeftRef = REF_NOT_AVAIL;
227+ } else { //available but is intra mb type
228+ iLeftRef = REF_NOT_IN_LIST;
229+ }
230+ }
231+ if (REF_NOT_AVAIL == iLeftRef ||
232+ (0 == iLeftRef && 0 == * (int32_t*)iMvA)) {
233+ ST32 (iMvp, 0);
234+ return;
235+ }
236+
237+ /*top*/
238+ if (bTopAvail && IS_INTER (iTopType)) {
239+ ST32 (iMvB, LD32 (pCurLayer->pMv[0][iTopXy][12]));
240+ iTopRef = pCurLayer->pRefIndex[0][iTopXy][12];
241+ } else {
242+ ST32 (iMvB, 0);
243+ if (0 == bTopAvail) { //not available
244+ iTopRef = REF_NOT_AVAIL;
245+ } else { //available but is intra mb type
246+ iTopRef = REF_NOT_IN_LIST;
247+ }
248+ }
249+ if (REF_NOT_AVAIL == iTopRef ||
250+ (0 == iTopRef && 0 == * (int32_t*)iMvB)) {
251+ ST32 (iMvp, 0);
252+ return;
253+ }
254+
255+ /*right_top*/
256+ if (bRightTopAvail && IS_INTER (iRightTopType)) {
257+ ST32 (iMvC, LD32 (pCurLayer->pMv[0][iRightTopXy][12]));
258+ iRightTopRef = pCurLayer->pRefIndex[0][iRightTopXy][12];
259+ } else {
260+ ST32 (iMvC, 0);
261+ if (0 == bRightTopAvail) { //not available
262+ iRightTopRef = REF_NOT_AVAIL;
263+ } else { //available but is intra mb type
264+ iRightTopRef = REF_NOT_IN_LIST;
265+ }
266+ }
267+
268+ /*left_top*/
269+ if (bLeftTopAvail && IS_INTER (iLeftTopType)) {
270+ ST32 (iMvD, LD32 (pCurLayer->pMv[0][iLeftTopXy][15]));
271+ iLeftTopRef = pCurLayer->pRefIndex[0][iLeftTopXy][15];
272+ } else {
273+ ST32 (iMvD, 0);
274+ if (0 == bLeftTopAvail) { //not available
275+ iLeftTopRef = REF_NOT_AVAIL;
276+ } else { //available but is intra mb type
277+ iLeftTopRef = REF_NOT_IN_LIST;
278+ }
279+ }
280+
281+ iDiagonalRef = iRightTopRef;
282+ if (REF_NOT_AVAIL == iDiagonalRef) {
283+ iDiagonalRef = iLeftTopRef;
284+ * (int32_t*)iMvC = * (int32_t*)iMvD;
285+ }
286+
287+ if (REF_NOT_AVAIL == iTopRef && REF_NOT_AVAIL == iDiagonalRef && iLeftRef >= REF_NOT_IN_LIST) {
288+ ST32 (iMvp, LD32 (iMvA));
289+ return;
290+ }
291+
292+ iMatchRef = (0 == iLeftRef) + (0 == iTopRef) + (0 == iDiagonalRef);
293+ if (1 == iMatchRef) {
294+ if (0 == iLeftRef) {
295+ ST32 (iMvp, LD32 (iMvA));
296+ } else if (0 == iTopRef) {
297+ ST32 (iMvp, LD32 (iMvB));
298+ } else {
299+ ST32 (iMvp, LD32 (iMvC));
300+ }
301+ } else {
302+ iMvp[0] = WelsMedian (iMvA[0], iMvB[0], iMvC[0]);
303+ iMvp[1] = WelsMedian (iMvA[1], iMvB[1], iMvC[1]);
304+ }
305+}
306+
307+int32_t GetColocatedMb (PWelsDecoderContext pCtx, MbType& mbType, SubMbType& subMbType) {
308+ PDqLayer pCurLayer = pCtx->pCurDqLayer;
309+ int32_t iMbXy = pCurLayer->iMbXyIndex;
310+
311+ uint32_t is8x8 = IS_Inter_8x8 (pCurLayer->pMbType[iMbXy]);
312+ mbType = pCurLayer->pMbType[iMbXy];
313+
314+ PPicture colocPic = pCtx->sRefPic.pRefList[LIST_1][0];
315+
316+ MbType coloc_mbType = colocPic->pMbType[iMbXy];
317+
318+ if (IS_Inter_8x8 (coloc_mbType) && !pCtx->pSps->bDirect8x8InferenceFlag) {
319+ subMbType = SUB_MB_TYPE_4x4 | MB_TYPE_P0L0 | MB_TYPE_P0L1 | MB_TYPE_DIRECT;
320+ mbType |= MB_TYPE_8x8 | MB_TYPE_L0 | MB_TYPE_L1;
321+ } else if (!is8x8 && (IS_INTER_16x16 (coloc_mbType) || IS_INTRA (coloc_mbType)/* || IS_SKIP(coloc_mbType)*/)) {
322+ subMbType = SUB_MB_TYPE_8x8 | MB_TYPE_P0L0 | MB_TYPE_P0L1 | MB_TYPE_DIRECT;
323+ mbType |= MB_TYPE_16x16 | MB_TYPE_L0 | MB_TYPE_L1;
324+ } else {
325+ subMbType = SUB_MB_TYPE_8x8 | MB_TYPE_P0L0 | MB_TYPE_P0L1 | MB_TYPE_DIRECT;
326+ mbType |= MB_TYPE_8x8 | MB_TYPE_L0 | MB_TYPE_L1;
327+ }
328+
329+ if (IS_INTRA (coloc_mbType)) {
330+ SetRectBlock (pCurLayer->iColocIntra, 4, 4, 4 * sizeof (int8_t), 1, sizeof (int8_t));
331+ return 1;
332+ }
333+ SetRectBlock (pCurLayer->iColocIntra, 4, 4, 4 * sizeof (int8_t), 0, sizeof (int8_t));
334+
335+ if (IS_INTER_16x16 (mbType)) {
336+ int16_t iMVZero[2] = { 0 };
337+ int16_t* pMv = IS_TYPE_L1 (coloc_mbType) ? colocPic->pMv[LIST_1][iMbXy][0] : iMVZero;
338+ ST32 (pCurLayer->iColocMv[LIST_0][0], LD32 (colocPic->pMv[LIST_0][iMbXy][0]));
339+ ST32 (pCurLayer->iColocMv[LIST_1][0], LD32 (pMv));
340+ pCurLayer->iColocRefIndex[LIST_0][0] = colocPic->pRefIndex[LIST_0][iMbXy][0];
341+ pCurLayer->iColocRefIndex[LIST_1][0] = IS_TYPE_L1 (coloc_mbType) ? colocPic->pRefIndex[LIST_1][iMbXy][0] :
342+ REF_NOT_IN_LIST;
343+ } else {
344+ if (!pCtx->pSps->bDirect8x8InferenceFlag) {
345+ CopyRectBlock4Cols (pCurLayer->iColocMv[LIST_0], colocPic->pMv[LIST_0][iMbXy], 16, 16, 4, 4);
346+ CopyRectBlock4Cols (pCurLayer->iColocRefIndex[LIST_0], colocPic->pRefIndex[LIST_0][iMbXy], 4, 4, 4, 1);
347+ if (IS_TYPE_L1 (coloc_mbType)) {
348+ CopyRectBlock4Cols (pCurLayer->iColocMv[LIST_1], colocPic->pMv[LIST_1][iMbXy], 16, 16, 4, 4);
349+ CopyRectBlock4Cols (pCurLayer->iColocRefIndex[LIST_1], colocPic->pRefIndex[LIST_1][iMbXy], 4, 4, 4, 1);
350+ } else { // only forward prediction
351+ SetRectBlock (pCurLayer->iColocRefIndex[LIST_1], 4, 4, 4, (uint8_t)REF_NOT_IN_LIST, 1);
352+ }
353+ } else {
354+ for (int32_t listIdx = 0; listIdx < 1 + !! (coloc_mbType & MB_TYPE_L1); listIdx++) {
355+ SetRectBlock (pCurLayer->iColocMv[listIdx][0], 2, 2, 16, LD32 (colocPic->pMv[listIdx][iMbXy][0]), 4);
356+ SetRectBlock (pCurLayer->iColocMv[listIdx][2], 2, 2, 16, LD32 (colocPic->pMv[listIdx][iMbXy][3]), 4);
357+ SetRectBlock (pCurLayer->iColocMv[listIdx][8], 2, 2, 16, LD32 (colocPic->pMv[listIdx][iMbXy][12]), 4);
358+ SetRectBlock (pCurLayer->iColocMv[listIdx][10], 2, 2, 16, LD32 (colocPic->pMv[listIdx][iMbXy][15]), 4);
359+
360+ SetRectBlock (&pCurLayer->iColocRefIndex[listIdx][0], 2, 2, 4, colocPic->pRefIndex[listIdx][iMbXy][0], 1);
361+ SetRectBlock (&pCurLayer->iColocRefIndex[listIdx][2], 2, 2, 4, colocPic->pRefIndex[listIdx][iMbXy][3], 1);
362+ SetRectBlock (&pCurLayer->iColocRefIndex[listIdx][8], 2, 2, 4, colocPic->pRefIndex[listIdx][iMbXy][12], 1);
363+ SetRectBlock (&pCurLayer->iColocRefIndex[listIdx][10], 2, 2, 4, colocPic->pRefIndex[listIdx][iMbXy][15], 1);
364+ }
365+ if (! (coloc_mbType & MB_TYPE_L1)) // only forward prediction
366+ SetRectBlock (&pCurLayer->iColocRefIndex[1][0], 4, 4, 4, (uint8_t)REF_NOT_IN_LIST, 1);
367+ }
368+ }
369+ return 1;
370+}
371+
372+SubMbType PredMvBDirectSpatial (PWelsDecoderContext pCtx, int16_t iMvp[LIST_A][2], int8_t ref[LIST_A]) {
373+
374+ PDqLayer pCurLayer = pCtx->pCurDqLayer;
375+ int32_t iMbXy = pCurLayer->iMbXyIndex;
376+ bool bSkipOrDirect = (IS_SKIP (pCurLayer->pMbType[iMbXy]) | IS_DIRECT (pCurLayer->pMbType[iMbXy])) > 0;
377+
378+ MbType mbType;
379+ SubMbType subMbType;
380+ GetColocatedMb (pCtx, mbType, subMbType);
381+
382+ bool bTopAvail, bLeftTopAvail, bRightTopAvail, bLeftAvail;
383+ int32_t iLeftTopType, iRightTopType, iTopType, iLeftType;
384+ int32_t iCurSliceIdc, iTopSliceIdc, iLeftTopSliceIdc, iRightTopSliceIdc, iLeftSliceIdc;
385+ int32_t iCurX, iCurY, iCurXy, iLeftXy = 0, iTopXy = 0, iLeftTopXy = 0, iRightTopXy = 0;
386+
387+ int8_t iLeftRef[LIST_A];
388+ int8_t iTopRef[LIST_A];
389+ int8_t iRightTopRef[LIST_A];
390+ int8_t iLeftTopRef[LIST_A];
391+ int8_t iDiagonalRef[LIST_A];
392+ int16_t iMvA[LIST_A][2], iMvB[LIST_A][2], iMvC[LIST_A][2], iMvD[LIST_A][2];
60393
61394 iCurXy = pCurLayer->iMbXyIndex;
62− iCurX = pCurLayer->iMbX;
63− iCurY = pCurLayer->iMbY;
395+
396+ iCurX = pCurLayer->iMbX;
397+ iCurY = pCurLayer->iMbY;
64398 iCurSliceIdc = pCurLayer->pSliceIdc[iCurXy];
65399
66400 if (iCurX != 0) {
@@ -79,7 +413,7 @@ void PredPSkipMvFromNeighbor (PDqLayer pCurLayer, int16_t iMvp[2]) { · 12 unmodified lines
79413 if (iCurX != 0) {
80414 iLeftTopXy = iTopXy - 1;
81415 iLeftTopSliceIdc = pCurLayer->pSliceIdc[iLeftTopXy];
82− bLeftTopAvail = (iLeftTopSliceIdc == iCurSliceIdc);
416+ bLeftTopAvail = (iLeftTopSliceIdc == iCurSliceIdc);
83417 } else {
84418 bLeftTopAvail = 0;
85419 }
@@ -104,107 +438,330 @@ void PredPSkipMvFromNeighbor (PDqLayer pCurLayer, int16_t iMvp[2]) { · 18 unmodified lines
104438 ? pCurLayer->pMbType[iRightTopXy] : 0);
105439
106440 /*get neb mv&iRefIdxArray*/
107− /*left*/
108− if (bLeftAvail && IS_INTER (iLeftType)) {
109− ST32 (iMvA, LD32 (pCurLayer->pMv[0][iLeftXy][3]));
110− iLeftRef = pCurLayer->pRefIndex[0][iLeftXy][3];
111− } else {
112− ST32 (iMvA, 0);
113− if (0 == bLeftAvail) { //not available
114− iLeftRef = REF_NOT_AVAIL;
115− } else { //available but is intra mb type
116− iLeftRef = REF_NOT_IN_LIST;
441+ for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
442+
443+ /*left*/
444+ if (bLeftAvail && IS_INTER (iLeftType)) {
445+ ST32 (iMvA[listIdx], LD32 (pCurLayer->pMv[listIdx][iLeftXy][3]));
446+ iLeftRef[listIdx] = pCurLayer->pRefIndex[listIdx][iLeftXy][3];
447+ } else {
448+ ST32 (iMvA[listIdx], 0);
449+ if (0 == bLeftAvail) { //not available
450+ iLeftRef[listIdx] = REF_NOT_AVAIL;
451+ } else { //available but is intra mb type
452+ iLeftRef[listIdx] = REF_NOT_IN_LIST;
453+ }
117454 }
118− }
119− if (REF_NOT_AVAIL == iLeftRef ||
120− (0 == iLeftRef && 0 == * (int32_t*)iMvA)) {
121− ST32 (iMvp, 0);
122− return;
123− }
124455
125− /*top*/
126− if (bTopAvail && IS_INTER (iTopType)) {
127− ST32 (iMvB, LD32 (pCurLayer->pMv[0][iTopXy][12]));
128− iTopRef = pCurLayer->pRefIndex[0][iTopXy][12];
129− } else {
130− ST32 (iMvB, 0);
131− if (0 == bTopAvail) { //not available
132− iTopRef = REF_NOT_AVAIL;
133− } else { //available but is intra mb type
134− iTopRef = REF_NOT_IN_LIST;
456+ /*top*/
457+ if (bTopAvail && IS_INTER (iTopType)) {
458+ ST32 (iMvB[listIdx], LD32 (pCurLayer->pMv[listIdx][iTopXy][12]));
459+ iTopRef[listIdx] = pCurLayer->pRefIndex[listIdx][iTopXy][12];
460+ } else {
461+ ST32 (iMvB[listIdx], 0);
462+ if (0 == bTopAvail) { //not available
463+ iTopRef[listIdx] = REF_NOT_AVAIL;
464+ } else { //available but is intra mb type
465+ iTopRef[listIdx] = REF_NOT_IN_LIST;
466+ }
135467 }
136− }
137− if (REF_NOT_AVAIL == iTopRef ||
138− (0 == iTopRef && 0 == * (int32_t*)iMvB)) {
139− ST32 (iMvp, 0);
140− return;
141− }
142468
143− /*right_top*/
144− if (bRightTopAvail && IS_INTER (iRightTopType)) {
145− ST32 (iMvC, LD32 (pCurLayer->pMv[0][iRightTopXy][12]));
146− iRightTopRef = pCurLayer->pRefIndex[0][iRightTopXy][12];
147− } else {
148− ST32 (iMvC, 0);
149− if (0 == bRightTopAvail) { //not available
150− iRightTopRef = REF_NOT_AVAIL;
151− } else { //available but is intra mb type
152− iRightTopRef = REF_NOT_IN_LIST;
469+ /*right_top*/
470+ if (bRightTopAvail && IS_INTER (iRightTopType)) {
471+ ST32 (iMvC[listIdx], LD32 (pCurLayer->pMv[listIdx][iRightTopXy][12]));
472+ iRightTopRef[listIdx] = pCurLayer->pRefIndex[listIdx][iRightTopXy][12];
473+ } else {
474+ ST32 (iMvC[listIdx], 0);
475+ if (0 == bRightTopAvail) { //not available
476+ iRightTopRef[listIdx] = REF_NOT_AVAIL;
477+ } else { //available but is intra mb type
478+ iRightTopRef[listIdx] = REF_NOT_IN_LIST;
479+ }
480+ }
481+ /*left_top*/
482+ if (bLeftTopAvail && IS_INTER (iLeftTopType)) {
483+ ST32 (iMvD[listIdx], LD32 (pCurLayer->pMv[listIdx][iLeftTopXy][15]));
484+ iLeftTopRef[listIdx] = pCurLayer->pRefIndex[listIdx][iLeftTopXy][15];
485+ } else {
486+ ST32 (iMvD[listIdx], 0);
487+ if (0 == bLeftTopAvail) { //not available
488+ iLeftTopRef[listIdx] = REF_NOT_AVAIL;
489+ } else { //available but is intra mb type
490+ iLeftTopRef[listIdx] = REF_NOT_IN_LIST;
491+ }
153492 }
154− }
155493
156− /*left_top*/
157− if (bLeftTopAvail && IS_INTER (iLeftTopType)) {
158− ST32 (iMvD, LD32 (pCurLayer->pMv[0][iLeftTopXy][15]));
159− iLeftTopRef = pCurLayer->pRefIndex[0][iLeftTopXy][15];
160− } else {
161− ST32 (iMvD, 0);
162− if (0 == bLeftTopAvail) { //not available
163− iLeftTopRef = REF_NOT_AVAIL;
164− } else { //available but is intra mb type
165− iLeftTopRef = REF_NOT_IN_LIST;
494+ iDiagonalRef[listIdx] = iRightTopRef[listIdx];
495+ if (REF_NOT_AVAIL == iDiagonalRef[listIdx]) {
496+ iDiagonalRef[listIdx] = iLeftTopRef[listIdx];
497+ * (int32_t*)iMvC[listIdx] = * (int32_t*)iMvD[listIdx];
166498 }
167− }
168499
169− iDiagonalRef = iRightTopRef;
170− if (REF_NOT_AVAIL == iDiagonalRef) {
171− iDiagonalRef = iLeftTopRef;
172− * (int32_t*)iMvC = * (int32_t*)iMvD;
500+ int8_t ref_temp = WELS_MIN_POSITIVE (iTopRef[listIdx], iDiagonalRef[listIdx]);
501+ ref[listIdx] = WELS_MIN_POSITIVE (iLeftRef[listIdx], ref_temp);
502+ if (ref[listIdx] >= 0) {
503+
504+ uint32_t match_count = (iLeftRef[listIdx] == ref[listIdx]) + (iTopRef[listIdx] == ref[listIdx]) +
505+ (iDiagonalRef[listIdx] == ref[listIdx]);
506+ if (match_count == 1) {
507+ if (iLeftRef[listIdx] == ref[listIdx]) {
508+ ST32 (iMvp[listIdx], LD32 (iMvA[listIdx]));
509+ } else if (iTopRef[listIdx] == ref[listIdx]) {
510+ ST32 (iMvp[listIdx], LD32 (iMvB[listIdx]));
511+ } else {
512+ ST32 (iMvp[listIdx], LD32 (iMvC[listIdx]));
513+ }
514+ } else {
515+ iMvp[listIdx][0] = WelsMedian (iMvA[listIdx][0], iMvB[listIdx][0], iMvC[listIdx][0]);
516+ iMvp[listIdx][1] = WelsMedian (iMvA[listIdx][1], iMvB[listIdx][1], iMvC[listIdx][1]);
517+ }
518+ } else {
519+ iMvp[listIdx][0] = 0;
520+ iMvp[listIdx][1] = 0;
521+ ref[listIdx] = REF_NOT_IN_LIST;
522+ }
173523 }
174−
175− if (REF_NOT_AVAIL == iTopRef && REF_NOT_AVAIL == iDiagonalRef && iLeftRef >= REF_NOT_IN_LIST) {
176− ST32 (iMvp, LD32 (iMvA));
177− return;
524+ if (ref[LIST_0] <= REF_NOT_IN_LIST && ref[LIST_1] <= REF_NOT_IN_LIST) {
525+ ref[LIST_0] = ref[LIST_1] = 0;
526+ } else if (ref[LIST_1] < 0) {
527+ mbType &= ~MB_TYPE_L1;
528+ subMbType &= ~MB_TYPE_L1;
529+ } else if (ref[LIST_0] < 0) {
530+ mbType &= ~MB_TYPE_L0;
531+ subMbType &= ~MB_TYPE_L0;
532+ }
533+ pCurLayer->pMbType[iMbXy] = mbType;
534+
535+ int16_t pMvd[4] = { 0 };
536+
537+ bool bIsLongRef = pCtx->sRefPic.pRefList[LIST_1][0]->bIsLongRef;
538+
539+ if (IS_INTER_16x16 (mbType)) {
540+ if ((* (int32_t*)iMvp[LIST_0] | * (int32_t*)iMvp[LIST_1])) {
541+ if (0 == pCurLayer->iColocIntra[0] && !bIsLongRef
542+ && ((pCurLayer->iColocRefIndex[LIST_0][0] == 0 && (unsigned) (pCurLayer->iColocMv[LIST_0][0][0] + 1) <= 2
543+ && (unsigned) (pCurLayer->iColocMv[LIST_0][0][1] + 1) <= 2)
544+ || (pCurLayer->iColocRefIndex[LIST_0][0] < 0 && pCurLayer->iColocRefIndex[LIST_1][0] == 0
545+ && (unsigned) (pCurLayer->iColocMv[LIST_1][0][0] + 1) <= 2
546+ && (unsigned) (pCurLayer->iColocMv[LIST_1][0][1] + 1) <= 2))) {
547+ if (0 >= ref[0]) * (uint32_t*)iMvp[LIST_0] = 0;
548+ if (0 >= ref[1]) * (uint32_t*)iMvp[LIST_1] = 0;
549+ }
550+ }
551+ UpdateP16x16DirectCabac (pCurLayer);
552+ for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
553+ UpdateP16x16MotionInfo (pCurLayer, listIdx, ref[listIdx], iMvp[listIdx]);
554+ UpdateP16x16MvdCabac (pCurLayer, pMvd, listIdx);
555+ }
556+ } else {
557+ if (bSkipOrDirect) {
558+ int8_t pSubPartCount[4], pPartW[4];
559+ for (int32_t i = 0; i < 4; i++) { //Direct 8x8 Ref and mv
560+ int16_t iIdx8 = i << 2;
561+ pCurLayer->pSubMbType[iMbXy][i] = subMbType;
562+ int8_t pRefIndex[LIST_A][30];
563+ UpdateP8x8RefIdxCabac (pCurLayer, pRefIndex, iIdx8, ref[LIST_0], LIST_0);
564+ UpdateP8x8RefIdxCabac (pCurLayer, pRefIndex, iIdx8, ref[LIST_1], LIST_1);
565+ UpdateP8x8DirectCabac (pCurLayer, iIdx8);
566+
567+ pSubPartCount[i] = g_ksInterBSubMbTypeInfo[0].iPartCount;
568+ pPartW[i] = g_ksInterBSubMbTypeInfo[0].iPartWidth;
569+
570+ if (IS_SUB_4x4 (subMbType)) {
571+ pSubPartCount[i] = 4;
572+ pPartW[i] = 1;
573+ }
574+
575+ int8_t iPartCount = pSubPartCount[i];
576+ int16_t iPartIdx, iBlockW = pPartW[i];
577+
578+ for (int32_t j = 0; j < iPartCount; j++) {
579+ iPartIdx = iIdx8 + j * iBlockW;
580+ uint8_t iScan4Idx = g_kuiScan4[iPartIdx];
581+ uint8_t iColocIdx = g_kuiScan4[iPartIdx];
582+ //uint8_t iCacheIdx = g_kuiCache30ScanIdx[iPartIdx];
583+
584+ int16_t pMV[4] = { 0 };
585+ if (IS_SUB_8x8 (subMbType)) {
586+ * (uint32_t*)pMV = * (uint32_t*)iMvp[LIST_0];
587+ ST32 ((pMV + 2), LD32 (pMV));
588+ ST64 (pCurLayer->pMv[LIST_0][iMbXy][iScan4Idx], LD64 (pMV));
589+ ST64 (pCurLayer->pMv[LIST_0][iMbXy][iScan4Idx + 4], LD64 (pMV));
590+ ST64 (pCurLayer->pMvd[LIST_0][iMbXy][iScan4Idx], 0);
591+ ST64 (pCurLayer->pMvd[LIST_0][iMbXy][iScan4Idx + 4], 0);
592+ * (uint32_t*)pMV = * (uint32_t*)iMvp[LIST_1];
593+ ST32 ((pMV + 2), LD32 (pMV));
594+ ST64 (pCurLayer->pMv[LIST_1][iMbXy][iScan4Idx], LD64 (pMV));
595+ ST64 (pCurLayer->pMv[LIST_1][iMbXy][iScan4Idx + 4], LD64 (pMV));
596+ ST64 (pCurLayer->pMvd[LIST_1][iMbXy][iScan4Idx], 0);
597+ ST64 (pCurLayer->pMvd[LIST_1][iMbXy][iScan4Idx + 4], 0);
598+ } else { //SUB_4x4
599+ * (uint32_t*)pMV = * (uint32_t*)iMvp[LIST_0];
600+ ST32 (pCurLayer->pMv[LIST_0][iMbXy][iScan4Idx], LD32 (pMV));
601+ ST32 (pCurLayer->pMvd[LIST_0][iMbXy][iScan4Idx], 0);
602+ * (uint32_t*)pMV = * (uint32_t*)iMvp[LIST_1];
603+ ST32 (pCurLayer->pMv[LIST_1][iMbXy][iScan4Idx], LD32 (pMV));
604+ ST32 (pCurLayer->pMvd[LIST_1][iMbXy][iScan4Idx], 0);
605+ }
606+ if ((* (int32_t*)iMvp[LIST_0] | * (int32_t*)iMvp[LIST_1])) {
607+ uint32_t uiColZeroFlag = (0 == pCurLayer->iColocIntra[iColocIdx]) && !bIsLongRef &&
608+ (pCurLayer->iColocRefIndex[LIST_0][iColocIdx] == 0 || (pCurLayer->iColocRefIndex[LIST_0][iColocIdx] < 0
609+ && pCurLayer->iColocRefIndex[LIST_1][iColocIdx] == 0));
610+ const int16_t (*mvColoc)[2] = 0 == pCurLayer->iColocRefIndex[LIST_0][iColocIdx] ? pCurLayer->iColocMv[LIST_0] :
611+ pCurLayer->iColocMv[LIST_1];
612+ const int16_t* mv = mvColoc[iColocIdx];
613+ if (IS_SUB_8x8 (subMbType)) {
614+ if (uiColZeroFlag && ((unsigned) (mv[0] + 1) <= 2 && (unsigned) (mv[1] + 1) <= 2)) {
615+ if (ref[LIST_0] == 0) {
616+ ST64 (pCurLayer->pMv[LIST_0][iMbXy][iScan4Idx], 0);
617+ ST64 (pCurLayer->pMv[LIST_0][iMbXy][iScan4Idx + 4], 0);
618+ ST64 (pCurLayer->pMvd[LIST_0][iMbXy][iScan4Idx], 0);
619+ ST64 (pCurLayer->pMvd[LIST_0][iMbXy][iScan4Idx + 4], 0);
620+ }
621+
622+ if (ref[LIST_1] == 0) {
623+ ST64 (pCurLayer->pMv[LIST_1][iMbXy][iScan4Idx], 0);
624+ ST64 (pCurLayer->pMv[LIST_1][iMbXy][iScan4Idx + 4], 0);
625+ ST64 (pCurLayer->pMvd[LIST_1][iMbXy][iScan4Idx], 0);
626+ ST64 (pCurLayer->pMvd[LIST_1][iMbXy][iScan4Idx + 4], 0);
627+ }
628+ }
629+ } else {
630+ if (uiColZeroFlag && ((unsigned) (mv[0] + 1) <= 2 && (unsigned) (mv[1] + 1) <= 2)) {
631+ if (ref[LIST_0] == 0) {
632+ ST32 (pCurLayer->pMv[LIST_0][iMbXy][iScan4Idx], 0);
633+ ST32 (pCurLayer->pMvd[LIST_0][iMbXy][iScan4Idx], 0);
634+ }
635+ if (ref[LIST_1] == 0) {
636+ ST32 (pCurLayer->pMv[LIST_1][iMbXy][iScan4Idx], 0);
637+ ST32 (pCurLayer->pMvd[LIST_1][iMbXy][iScan4Idx], 0);
638+ }
639+ }
640+ }
641+ }
642+ }
643+ }
644+ }
178645 }
646+ return subMbType;
647+}
179648
180− iMatchRef = (0 == iLeftRef) + (0 == iTopRef) + (0 == iDiagonalRef);
181− if (1 == iMatchRef) {
182− if (0 == iLeftRef) {
183− ST32 (iMvp, LD32 (iMvA));
184− } else if (0 == iTopRef) {
185− ST32 (iMvp, LD32 (iMvB));
649+void PredBDirectTemporal (PWelsDecoderContext pCtx, int16_t iMvp[LIST_A][2], int8_t ref[LIST_A]) {
650+ PDqLayer pCurLayer = pCtx->pCurDqLayer;
651+ int32_t iMbXy = pCurLayer->iMbXyIndex;
652+ bool bSkipOrDirect = (IS_SKIP (pCurLayer->pMbType[iMbXy]) | IS_DIRECT (pCurLayer->pMbType[iMbXy])) > 0;
653+ MbType mbType;
654+ SubMbType subMbType;
655+ GetColocatedMb (pCtx, mbType, subMbType);
656+ PSlice pSlice = &pCurLayer->sLayerInfo.sSliceInLayer;
657+ if (IS_INTER_16x16 (mbType)) {
658+ ref[LIST_0] = 0;
659+ ref[LIST_1] = 0;
660+ UpdateP16x16RefIdx (pCurLayer, LIST_1, ref[LIST_1]);
661+ ST64 (iMvp, 0);
662+ if (pCurLayer->iColocIntra[0]) {
663+ UpdateP16x16MotionOnly (pCurLayer, LIST_0, iMvp[LIST_0]);
664+ UpdateP16x16MotionOnly (pCurLayer, LIST_1, iMvp[LIST_1]);
665+ UpdateP16x16RefIdx (pCurLayer, LIST_0, ref[LIST_0]);
186666 } else {
187− ST32 (iMvp, LD32 (iMvC));
667+ ref[LIST_0] = pCurLayer->iColocRefIndex[LIST_0][0];
668+ const int16_t (*mvColoc)[2] = 0 == ref[LIST_0] ? pCurLayer->iColocMv[LIST_0] : pCurLayer->iColocMv[LIST_1];
669+ const int16_t* mv = mvColoc[0];
670+ UpdateP16x16RefIdx (pCurLayer, LIST_0, ref[LIST_0]);
671+
672+ iMvp[LIST_0][0] = (pSlice->iMvScale[LIST_0][ref[LIST_0]] * mv[0] + 128) >> 8;
673+ iMvp[LIST_0][1] = (pSlice->iMvScale[LIST_0][ref[LIST_0]] * mv[1] + 128) >> 8;
674+ UpdateP16x16MotionOnly (pCurLayer, LIST_0, iMvp[LIST_0]);
675+ iMvp[LIST_1][0] = iMvp[LIST_0][0] - mv[0];
676+ iMvp[LIST_1][1] = iMvp[LIST_0][1] - mv[1];
677+ UpdateP16x16MotionOnly (pCurLayer, LIST_1, iMvp[LIST_1]);
188678 }
189679 } else {
190− iMvp[0] = WelsMedian (iMvA[0], iMvB[0], iMvC[0]);
191− iMvp[1] = WelsMedian (iMvA[1], iMvB[1], iMvC[1]);
680+ if (bSkipOrDirect) {
681+ int8_t pSubPartCount[4], pPartW[4];
682+ for (int32_t i = 0; i < 4; i++) {
683+ int16_t iIdx8 = i << 2;
684+ pCurLayer->pSubMbType[iMbXy][i] = subMbType;
685+
686+ ref[LIST_1] = 0;
687+ if (pCurLayer->iColocIntra[g_kuiScan4[iIdx8]]) {
688+ ref[LIST_0] = 0;
689+ } else {
690+ if (pCurLayer->iColocRefIndex[LIST_0][iIdx8] >= 0) {
691+ ref[LIST_0] = pCurLayer->iColocRefIndex[LIST_0][iIdx8];
692+ } else {
693+ ref[LIST_0] = pCurLayer->iColocRefIndex[LIST_1][iIdx8];
694+ }
695+ }
696+ int8_t pRefIndex[LIST_A][30];
697+ UpdateP8x8RefIdxCabac (pCurLayer, pRefIndex, iIdx8, ref[LIST_0], LIST_0);
698+ UpdateP8x8RefIdxCabac (pCurLayer, pRefIndex, iIdx8, ref[LIST_1], LIST_1);
699+ UpdateP8x8DirectCabac (pCurLayer, iIdx8);
700+
701+ pSubPartCount[i] = g_ksInterBSubMbTypeInfo[0].iPartCount;
702+ pPartW[i] = g_ksInterBSubMbTypeInfo[0].iPartWidth;
703+
704+ if (IS_SUB_4x4 (subMbType)) {
705+ pSubPartCount[i] = 4;
706+ pPartW[i] = 1;
707+ }
708+
709+ int8_t iPartCount = pSubPartCount[i];
710+ int16_t iPartIdx, iBlockW = pPartW[i];
711+ for (int32_t j = 0; j < iPartCount; j++) {
712+ iPartIdx = iIdx8 + j * iBlockW;
713+ uint8_t iScan4Idx = g_kuiScan4[iPartIdx];
714+ uint8_t iColocIdx = g_kuiScan4[iPartIdx];
715+
716+ int16_t (*mvColoc)[2] = pCurLayer->iColocMv[LIST_0];
717+ int16_t* mv = mvColoc[iColocIdx];
718+
719+ int16_t pMV[4] = { 0 };
720+ if (IS_SUB_8x8 (subMbType)) {
721+ iMvp[LIST_0][0] = (pSlice->iMvScale[LIST_0][ref[LIST_0]] * mv[0] + 128) >> 8;
722+ iMvp[LIST_0][1] = (pSlice->iMvScale[LIST_0][ref[LIST_0]] * mv[1] + 128) >> 8;
723+ ST32 (pMV, LD32 (iMvp[LIST_0]));
724+ ST32 ((pMV + 2), LD32 (iMvp[LIST_0]));
725+ ST64 (pCurLayer->pMv[LIST_0][iMbXy][iScan4Idx], LD64 (pMV));
726+ ST64 (pCurLayer->pMv[LIST_0][iMbXy][iScan4Idx + 4], LD64 (pMV));
727+ ST64 (pCurLayer->pMvd[LIST_0][iMbXy][iScan4Idx], 0);
728+ ST64 (pCurLayer->pMvd[LIST_0][iMbXy][iScan4Idx + 4], 0);
729+ iMvp[LIST_1][0] -= iMvp[LIST_0][0] - mv[0];
730+ iMvp[LIST_1][1] -= iMvp[LIST_0][0] - mv[1];
731+ ST32 (pMV, LD32 (iMvp[LIST_1]));
732+ ST32 ((pMV + 2), LD32 (iMvp[LIST_1]));
733+ ST64 (pCurLayer->pMv[LIST_1][iMbXy][iScan4Idx], LD64 (pMV));
734+ ST64 (pCurLayer->pMv[LIST_1][iMbXy][iScan4Idx + 4], LD64 (pMV));
735+ ST64 (pCurLayer->pMvd[LIST_1][iMbXy][iScan4Idx], 0);
736+ ST64 (pCurLayer->pMvd[LIST_1][iMbXy][iScan4Idx + 4], 0);
737+ } else { //SUB_4x4
738+ iMvp[LIST_0][0] = (pSlice->iMvScale[LIST_0][ref[LIST_0]] * mv[0] + 128) >> 8;
739+ iMvp[LIST_0][1] = (pSlice->iMvScale[LIST_0][ref[LIST_0]] * mv[1] + 128) >> 8;
740+ ST32 (pCurLayer->pMv[LIST_0][iMbXy][iScan4Idx], LD32 (iMvp[LIST_0]));
741+ ST32 (pCurLayer->pMvd[LIST_0][iMbXy][iScan4Idx], 0);
742+ iMvp[LIST_1][0] -= iMvp[LIST_0][0] - mv[0];
743+ iMvp[LIST_1][1] -= iMvp[LIST_0][0] - mv[1];
744+ ST32 (pCurLayer->pMv[LIST_1][iMbXy][iScan4Idx], LD32 (iMvp[LIST_1]));
745+ ST32 (pCurLayer->pMvd[LIST_1][iMbXy][iScan4Idx], 0);
746+ }
747+ }
748+ }
749+ }
192750 }
193751 }
194752
195−
196753 //basic iMVs prediction unit for iMVs partition width (4, 2, 1)
197754 void PredMv (int16_t iMotionVector[LIST_A][30][MV_A], int8_t iRefIndex[LIST_A][30],
198− int32_t iPartIdx, int32_t iPartWidth, int8_t iRef, int16_t iMVP[2]) {
755+ int32_t listIdx, int32_t iPartIdx, int32_t iPartWidth, int8_t iRef, int16_t iMVP[2]) {
199756 const uint8_t kuiLeftIdx = g_kuiCache30ScanIdx[iPartIdx] - 1;
200757 const uint8_t kuiTopIdx = g_kuiCache30ScanIdx[iPartIdx] - 6;
201758 const uint8_t kuiRightTopIdx = kuiTopIdx + iPartWidth;
202759 const uint8_t kuiLeftTopIdx = kuiTopIdx - 1;
203760
204− const int8_t kiLeftRef = iRefIndex[0][kuiLeftIdx];
205− const int8_t kiTopRef = iRefIndex[0][ kuiTopIdx];
206− const int8_t kiRightTopRef = iRefIndex[0][kuiRightTopIdx];
207− const int8_t kiLeftTopRef = iRefIndex[0][ kuiLeftTopIdx];
761+ const int8_t kiLeftRef = iRefIndex[listIdx][kuiLeftIdx];
762+ const int8_t kiTopRef = iRefIndex[listIdx][ kuiTopIdx];
763+ const int8_t kiRightTopRef = iRefIndex[listIdx][kuiRightTopIdx];
764+ const int8_t kiLeftTopRef = iRefIndex[listIdx][ kuiLeftTopIdx];
208765 int8_t iDiagonalRef = kiRightTopRef;
209766
210767 int8_t iMatchRef = 0;
@@ -212,13 +769,13 @@ void PredMv (int16_t iMotionVector[LIST_A][30][MV_A], int8_t iRefIndex[LIST_A][3 · 1 unmodified line
212769
213770 int16_t iAMV[2], iBMV[2], iCMV[2];
214771
215− ST32 (iAMV, LD32 (iMotionVector[0][ kuiLeftIdx]));
216− ST32 (iBMV, LD32 (iMotionVector[0][ kuiTopIdx]));
217− ST32 (iCMV, LD32 (iMotionVector[0][kuiRightTopIdx]));
772+ ST32 (iAMV, LD32 (iMotionVector[listIdx][ kuiLeftIdx]));
773+ ST32 (iBMV, LD32 (iMotionVector[listIdx][ kuiTopIdx]));
774+ ST32 (iCMV, LD32 (iMotionVector[listIdx][kuiRightTopIdx]));
218775
219776 if (REF_NOT_AVAIL == iDiagonalRef) {
220777 iDiagonalRef = kiLeftTopRef;
221− ST32 (iCMV, LD32 (iMotionVector[0][kuiLeftTopIdx]));
778+ ST32 (iCMV, LD32 (iMotionVector[listIdx][kuiLeftTopIdx]));
222779 }
223780
224781 iMatchRef = (iRef == kiLeftRef) + (iRef == kiTopRef) + (iRef == iDiagonalRef);
@@ -242,50 +799,50 @@ void PredMv (int16_t iMotionVector[LIST_A][30][MV_A], int8_t iRefIndex[LIST_A][3 · 17 unmodified lines
242799 }
243800 }
244801 void PredInter8x16Mv (int16_t iMotionVector[LIST_A][30][MV_A], int8_t iRefIndex[LIST_A][30],
245− int32_t iPartIdx, int8_t iRef, int16_t iMVP[2]) {
802+ int32_t listIdx, int32_t iPartIdx, int8_t iRef, int16_t iMVP[2]) {
246803 if (0 == iPartIdx) {
247− const int8_t kiLeftRef = iRefIndex[0][6];
804+ const int8_t kiLeftRef = iRefIndex[listIdx][6];
248805 if (iRef == kiLeftRef) {
249− ST32 (iMVP, LD32 (&iMotionVector[0][6][0]));
806+ ST32 (iMVP, LD32 (&iMotionVector[listIdx][6][0]));
250807 return;
251808 }
252809 } else { // 1 == iPartIdx
253− int8_t iDiagonalRef = iRefIndex[0][5]; //top-right
810+ int8_t iDiagonalRef = iRefIndex[listIdx][5]; //top-right
254811 int8_t index = 5;
255812 if (REF_NOT_AVAIL == iDiagonalRef) {
256− iDiagonalRef = iRefIndex[0][2]; //top-left for 8*8 block(index 1)
813+ iDiagonalRef = iRefIndex[listIdx][2]; //top-left for 8*8 block(index 1)
257814 index = 2;
258815 }
259816 if (iRef == iDiagonalRef) {
260− ST32 (iMVP, LD32 (&iMotionVector[0][index][0]));
817+ ST32 (iMVP, LD32 (&iMotionVector[listIdx][index][0]));
261818 return;
262819 }
263820 }
264821
265− PredMv (iMotionVector, iRefIndex, iPartIdx, 2, iRef, iMVP);
822+ PredMv (iMotionVector, iRefIndex, listIdx, iPartIdx, 2, iRef, iMVP);
266823 }
267824 void PredInter16x8Mv (int16_t iMotionVector[LIST_A][30][MV_A], int8_t iRefIndex[LIST_A][30],
268− int32_t iPartIdx, int8_t iRef, int16_t iMVP[2]) {
825+ int32_t listIdx, int32_t iPartIdx, int8_t iRef, int16_t iMVP[2]) {
269826 if (0 == iPartIdx) {
270− const int8_t kiTopRef = iRefIndex[0][1];
827+ const int8_t kiTopRef = iRefIndex[listIdx][1];
271828 if (iRef == kiTopRef) {
272− ST32 (iMVP, LD32 (&iMotionVector[0][1][0]));
829+ ST32 (iMVP, LD32 (&iMotionVector[listIdx][1][0]));
273830 return;
274831 }
275832 } else { // 8 == iPartIdx
276− const int8_t kiLeftRef = iRefIndex[0][18];
833+ const int8_t kiLeftRef = iRefIndex[listIdx][18];
277834 if (iRef == kiLeftRef) {
278− ST32 (iMVP, LD32 (&iMotionVector[0][18][0]));
835+ ST32 (iMVP, LD32 (&iMotionVector[listIdx][18][0]));
279836 return;
280837 }
281838 }
282839
283− PredMv (iMotionVector, iRefIndex, iPartIdx, 4, iRef, iMVP);
840+ PredMv (iMotionVector, iRefIndex, listIdx, iPartIdx, 4, iRef, iMVP);
284841 }
285842
286843 //update iMVs and iRefIndex cache for current MB, only for P_16*16 (SKIP inclusive)
287844 /* can be further optimized */
288−void UpdateP16x16MotionInfo (PDqLayer pCurDqLayer, int8_t iRef, int16_t iMVs[2]) {
845+void UpdateP16x16MotionInfo (PDqLayer pCurDqLayer, int32_t listIdx, int8_t iRef, int16_t iMVs[2]) {
289846 const int16_t kiRef2 = (iRef << 8) | iRef;
290847 const int32_t kiMV32 = LD32 (iMVs);
291848 int32_t i;
@@ -296,13 +853,49 @@ void UpdateP16x16MotionInfo (PDqLayer pCurDqLayer, int8_t iRef, int16_t iMVs[2]) · 4 unmodified lines
296853 const uint8_t kuiScan4Idx = g_kuiScan4[i];
297854 const uint8_t kuiScan4IdxPlus4 = 4 + kuiScan4Idx;
298855
299− ST16 (&pCurDqLayer->pRefIndex[0][iMbXy][kuiScan4Idx ], kiRef2);
300− ST16 (&pCurDqLayer->pRefIndex[0][iMbXy][kuiScan4IdxPlus4], kiRef2);
856+ ST16 (&pCurDqLayer->pRefIndex[listIdx][iMbXy][kuiScan4Idx ], kiRef2);
857+ ST16 (&pCurDqLayer->pRefIndex[listIdx][iMbXy][kuiScan4IdxPlus4], kiRef2);
858+
859+ ST32 (pCurDqLayer->pMv[listIdx][iMbXy][ kuiScan4Idx ], kiMV32);
860+ ST32 (pCurDqLayer->pMv[listIdx][iMbXy][1 + kuiScan4Idx ], kiMV32);
861+ ST32 (pCurDqLayer->pMv[listIdx][iMbXy][ kuiScan4IdxPlus4], kiMV32);
862+ ST32 (pCurDqLayer->pMv[listIdx][iMbXy][1 + kuiScan4IdxPlus4], kiMV32);
863+ }
864+}
865+
866+//update iRefIndex cache for current MB, only for P_16*16 (SKIP inclusive)
867+/* can be further optimized */
868+void UpdateP16x16RefIdx (PDqLayer pCurDqLayer, int32_t listIdx, int8_t iRef) {
869+ const int16_t kiRef2 = (iRef << 8) | iRef;
870+ int32_t i;
871+ int32_t iMbXy = pCurDqLayer->iMbXyIndex;
872+
873+ for (i = 0; i < 16; i += 4) {
874+ //mb
875+ const uint8_t kuiScan4Idx = g_kuiScan4[i];
876+ const uint8_t kuiScan4IdxPlus4 = 4 + kuiScan4Idx;
877+
878+ ST16 (&pCurDqLayer->pRefIndex[listIdx][iMbXy][kuiScan4Idx], kiRef2);
879+ ST16 (&pCurDqLayer->pRefIndex[listIdx][iMbXy][kuiScan4IdxPlus4], kiRef2);
880+ }
881+}
882+
883+//update iMVs only cache for current MB, only for P_16*16 (SKIP inclusive)
884+/* can be further optimized */
885+void UpdateP16x16MotionOnly (PDqLayer pCurDqLayer, int32_t listIdx, int16_t iMVs[2]) {
886+ const int32_t kiMV32 = LD32 (iMVs);
887+ int32_t i;
888+ int32_t iMbXy = pCurDqLayer->iMbXyIndex;
889+
890+ for (i = 0; i < 16; i += 4) {
891+ //mb
892+ const uint8_t kuiScan4Idx = g_kuiScan4[i];
893+ const uint8_t kuiScan4IdxPlus4 = 4 + kuiScan4Idx;
301894
302− ST32 (pCurDqLayer->pMv[0][iMbXy][ kuiScan4Idx ], kiMV32);
303− ST32 (pCurDqLayer->pMv[0][iMbXy][1 + kuiScan4Idx ], kiMV32);
304− ST32 (pCurDqLayer->pMv[0][iMbXy][ kuiScan4IdxPlus4], kiMV32);
305− ST32 (pCurDqLayer->pMv[0][iMbXy][1 + kuiScan4IdxPlus4], kiMV32);
895+ ST32 (pCurDqLayer->pMv[listIdx][iMbXy][kuiScan4Idx], kiMV32);
896+ ST32 (pCurDqLayer->pMv[listIdx][iMbXy][1 + kuiScan4Idx], kiMV32);
897+ ST32 (pCurDqLayer->pMv[listIdx][iMbXy][kuiScan4IdxPlus4], kiMV32);
898+ ST32 (pCurDqLayer->pMv[listIdx][iMbXy][1 + kuiScan4IdxPlus4], kiMV32);
306899 }
307900 }
308901
@@ -310,7 +903,7 @@ void UpdateP16x16MotionInfo (PDqLayer pCurDqLayer, int8_t iRef, int16_t iMVs[2]) · 1 unmodified line
310903 /*need further optimization, mb_cache not work */
311904 void UpdateP16x8MotionInfo (PDqLayer pCurDqLayer, int16_t iMotionVector[LIST_A][30][MV_A],
312905 int8_t iRefIndex[LIST_A][30],
313− int32_t iPartIdx, int8_t iRef, int16_t iMVs[2]) {
906+ int32_t listIdx, int32_t iPartIdx, int8_t iRef, int16_t iMVs[2]) {
314907 const int16_t kiRef2 = (iRef << 8) | iRef;
315908 const int32_t kiMV32 = LD32 (iMVs);
316909 int32_t i;
@@ -322,25 +915,25 @@ void UpdateP16x8MotionInfo (PDqLayer pCurDqLayer, int16_t iMotionVector[LIST_A][ · 5 unmodified lines
322915 const uint8_t kuiCacheIdxPlus6 = 6 + kuiCacheIdx;
323916
324917 //mb
325− ST16 (&pCurDqLayer->pRefIndex[0][iMbXy][kuiScan4Idx ], kiRef2);
326− ST16 (&pCurDqLayer->pRefIndex[0][iMbXy][kuiScan4IdxPlus4], kiRef2);
327− ST32 (pCurDqLayer->pMv[0][iMbXy][ kuiScan4Idx ], kiMV32);
328− ST32 (pCurDqLayer->pMv[0][iMbXy][1 + kuiScan4Idx ], kiMV32);
329− ST32 (pCurDqLayer->pMv[0][iMbXy][ kuiScan4IdxPlus4], kiMV32);
330− ST32 (pCurDqLayer->pMv[0][iMbXy][1 + kuiScan4IdxPlus4], kiMV32);
918+ ST16 (&pCurDqLayer->pRefIndex[listIdx][iMbXy][kuiScan4Idx ], kiRef2);
919+ ST16 (&pCurDqLayer->pRefIndex[listIdx][iMbXy][kuiScan4IdxPlus4], kiRef2);
920+ ST32 (pCurDqLayer->pMv[listIdx][iMbXy][ kuiScan4Idx ], kiMV32);
921+ ST32 (pCurDqLayer->pMv[listIdx][iMbXy][1 + kuiScan4Idx ], kiMV32);
922+ ST32 (pCurDqLayer->pMv[listIdx][iMbXy][ kuiScan4IdxPlus4], kiMV32);
923+ ST32 (pCurDqLayer->pMv[listIdx][iMbXy][1 + kuiScan4IdxPlus4], kiMV32);
331924 //cache
332− ST16 (&iRefIndex[0][kuiCacheIdx ], kiRef2);
333− ST16 (&iRefIndex[0][kuiCacheIdxPlus6], kiRef2);
334− ST32 (iMotionVector[0][ kuiCacheIdx ], kiMV32);
335− ST32 (iMotionVector[0][1 + kuiCacheIdx ], kiMV32);
336− ST32 (iMotionVector[0][ kuiCacheIdxPlus6], kiMV32);
337− ST32 (iMotionVector[0][1 + kuiCacheIdxPlus6], kiMV32);
925+ ST16 (&iRefIndex[listIdx][kuiCacheIdx ], kiRef2);
926+ ST16 (&iRefIndex[listIdx][kuiCacheIdxPlus6], kiRef2);
927+ ST32 (iMotionVector[listIdx][ kuiCacheIdx ], kiMV32);
928+ ST32 (iMotionVector[listIdx][1 + kuiCacheIdx ], kiMV32);
929+ ST32 (iMotionVector[listIdx][ kuiCacheIdxPlus6], kiMV32);
930+ ST32 (iMotionVector[listIdx][1 + kuiCacheIdxPlus6], kiMV32);
338931 }
339932 }
340933 //update iRefIndex and iMVs of both Mb and Mb_cache, only for P8x16
341934 void UpdateP8x16MotionInfo (PDqLayer pCurDqLayer, int16_t iMotionVector[LIST_A][30][MV_A],
342935 int8_t iRefIndex[LIST_A][30],
343− int32_t iPartIdx, int8_t iRef, int16_t iMVs[2]) {
936+ int32_t listIdx, int32_t iPartIdx, int8_t iRef, int16_t iMVs[2]) {
344937 const int16_t kiRef2 = (iRef << 8) | iRef;
345938 const int32_t kiMV32 = LD32 (iMVs);
346939 int32_t i;
@@ -353,19 +946,19 @@ void UpdateP8x16MotionInfo (PDqLayer pCurDqLayer, int16_t iMotionVector[LIST_A][ · 6 unmodified lines
353946 const uint8_t kuiCacheIdxPlus6 = 6 + kuiCacheIdx;
354947
355948 //mb
356− ST16 (&pCurDqLayer->pRefIndex[0][iMbXy][kuiScan4Idx ], kiRef2);
357− ST16 (&pCurDqLayer->pRefIndex[0][iMbXy][kuiScan4IdxPlus4], kiRef2);
358− ST32 (pCurDqLayer->pMv[0][iMbXy][ kuiScan4Idx ], kiMV32);
359− ST32 (pCurDqLayer->pMv[0][iMbXy][1 + kuiScan4Idx ], kiMV32);
360− ST32 (pCurDqLayer->pMv[0][iMbXy][ kuiScan4IdxPlus4], kiMV32);
361− ST32 (pCurDqLayer->pMv[0][iMbXy][1 + kuiScan4IdxPlus4], kiMV32);
949+ ST16 (&pCurDqLayer->pRefIndex[listIdx][iMbXy][kuiScan4Idx ], kiRef2);
950+ ST16 (&pCurDqLayer->pRefIndex[listIdx][iMbXy][kuiScan4IdxPlus4], kiRef2);
951+ ST32 (pCurDqLayer->pMv[listIdx][iMbXy][ kuiScan4Idx ], kiMV32);
952+ ST32 (pCurDqLayer->pMv[listIdx][iMbXy][1 + kuiScan4Idx ], kiMV32);
953+ ST32 (pCurDqLayer->pMv[listIdx][iMbXy][ kuiScan4IdxPlus4], kiMV32);
954+ ST32 (pCurDqLayer->pMv[listIdx][iMbXy][1 + kuiScan4IdxPlus4], kiMV32);
362955 //cache
363− ST16 (&iRefIndex[0][kuiCacheIdx ], kiRef2);
364− ST16 (&iRefIndex[0][kuiCacheIdxPlus6], kiRef2);
365− ST32 (iMotionVector[0][ kuiCacheIdx ], kiMV32);
366− ST32 (iMotionVector[0][1 + kuiCacheIdx ], kiMV32);
367− ST32 (iMotionVector[0][ kuiCacheIdxPlus6], kiMV32);
368− ST32 (iMotionVector[0][1 + kuiCacheIdxPlus6], kiMV32);
956+ ST16 (&iRefIndex[listIdx][kuiCacheIdx ], kiRef2);
957+ ST16 (&iRefIndex[listIdx][kuiCacheIdxPlus6], kiRef2);
958+ ST32 (iMotionVector[listIdx][ kuiCacheIdx ], kiMV32);
959+ ST32 (iMotionVector[listIdx][1 + kuiCacheIdx ], kiMV32);
960+ ST32 (iMotionVector[listIdx][ kuiCacheIdxPlus6], kiMV32);
961+ ST32 (iMotionVector[listIdx][1 + kuiCacheIdxPlus6], kiMV32);
369962 }
370963 }
371964

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