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
41#include "mv_pred.h"41#include "mv_pred.h"
42#include "ls_defines.h"42#include "ls_defines.h"
43#include "mb_cache.h"43#include "mb_cache.h"
44#include "parse_mb_syn_cabac.h"
44 45
45namespace WelsDec {46namespace WelsDec {
47
48static 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}
131void 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}
46void PredPSkipMvFromNeighbor (PDqLayer pCurLayer, int16_t iMvp[2]) {158void PredPSkipMvFromNeighbor (PDqLayer pCurLayer, int16_t iMvp[2]) {
47 bool bTopAvail, bLeftTopAvail, bRightTopAvail, bLeftAvail;159 bool bTopAvail, bLeftTopAvail, bRightTopAvail, bLeftAvail;
48 160
@@ -52,15 +164,237 @@ void PredPSkipMvFromNeighbor (PDqLayer pCurLayer, int16_t iMvp[2]) { · 3 unmodified lines
52 164
53 int8_t iLeftRef;165 int8_t iLeftRef;
54 int8_t iTopRef;166 int8_t iTopRef;
55 int8_t iRightTopRef;167 int8_t iRightTopRef;
56 int8_t iLeftTopRef;168 int8_t iLeftTopRef;
57 int8_t iDiagonalRef;169 int8_t iDiagonalRef;
58 int8_t iMatchRef;170 int8_t iMatchRef;
59 int16_t iMvA[2], iMvB[2], iMvC[2], iMvD[2];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
307int32_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
372SubMbType 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];
60 393
61 iCurXy = pCurLayer->iMbXyIndex;394 iCurXy = pCurLayer->iMbXyIndex;
62 iCurX = pCurLayer->iMbX;395
63 iCurY = pCurLayer->iMbY;396 iCurX = pCurLayer->iMbX;
397 iCurY = pCurLayer->iMbY;
64 iCurSliceIdc = pCurLayer->pSliceIdc[iCurXy];398 iCurSliceIdc = pCurLayer->pSliceIdc[iCurXy];
65 399
66 if (iCurX != 0) {400 if (iCurX != 0) {
@@ -79,7 +413,7 @@ void PredPSkipMvFromNeighbor (PDqLayer pCurLayer, int16_t iMvp[2]) { · 12 unmodified lines
79 if (iCurX != 0) {413 if (iCurX != 0) {
80 iLeftTopXy = iTopXy - 1;414 iLeftTopXy = iTopXy - 1;
81 iLeftTopSliceIdc = pCurLayer->pSliceIdc[iLeftTopXy];415 iLeftTopSliceIdc = pCurLayer->pSliceIdc[iLeftTopXy];
82 bLeftTopAvail = (iLeftTopSliceIdc == iCurSliceIdc);416 bLeftTopAvail = (iLeftTopSliceIdc == iCurSliceIdc);
83 } else {417 } else {
84 bLeftTopAvail = 0;418 bLeftTopAvail = 0;
85 }419 }
@@ -104,107 +438,330 @@ void PredPSkipMvFromNeighbor (PDqLayer pCurLayer, int16_t iMvp[2]) { · 18 unmodified lines
104 ? pCurLayer->pMbType[iRightTopXy] : 0);438 ? pCurLayer->pMbType[iRightTopXy] : 0);
105 439
106 /*get neb mv&iRefIdxArray*/440 /*get neb mv&iRefIdxArray*/
107 /*left*/441 for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
108 if (bLeftAvail && IS_INTER (iLeftType)) {442
109 ST32 (iMvA, LD32 (pCurLayer->pMv[0][iLeftXy][3]));443 /*left*/
110 iLeftRef = pCurLayer->pRefIndex[0][iLeftXy][3];444 if (bLeftAvail && IS_INTER (iLeftType)) {
111 } else {445 ST32 (iMvA[listIdx], LD32 (pCurLayer->pMv[listIdx][iLeftXy][3]));
112 ST32 (iMvA, 0);446 iLeftRef[listIdx] = pCurLayer->pRefIndex[listIdx][iLeftXy][3];
113 if (0 == bLeftAvail) { //not available447 } else {
114 iLeftRef = REF_NOT_AVAIL;448 ST32 (iMvA[listIdx], 0);
115 } else { //available but is intra mb type449 if (0 == bLeftAvail) { //not available
116 iLeftRef = REF_NOT_IN_LIST;450 iLeftRef[listIdx] = REF_NOT_AVAIL;
451 } else { //available but is intra mb type
452 iLeftRef[listIdx] = REF_NOT_IN_LIST;
453 }
117 }454 }
118 }
119 if (REF_NOT_AVAIL == iLeftRef ||
120 (0 == iLeftRef && 0 == * (int32_t*)iMvA)) {
121 ST32 (iMvp, 0);
122 return;
123 }
124 455
125 /*top*/456 /*top*/
126 if (bTopAvail && IS_INTER (iTopType)) {457 if (bTopAvail && IS_INTER (iTopType)) {
127 ST32 (iMvB, LD32 (pCurLayer->pMv[0][iTopXy][12]));458 ST32 (iMvB[listIdx], LD32 (pCurLayer->pMv[listIdx][iTopXy][12]));
128 iTopRef = pCurLayer->pRefIndex[0][iTopXy][12];459 iTopRef[listIdx] = pCurLayer->pRefIndex[listIdx][iTopXy][12];
129 } else {460 } else {
130 ST32 (iMvB, 0);461 ST32 (iMvB[listIdx], 0);
131 if (0 == bTopAvail) { //not available462 if (0 == bTopAvail) { //not available
132 iTopRef = REF_NOT_AVAIL;463 iTopRef[listIdx] = REF_NOT_AVAIL;
133 } else { //available but is intra mb type464 } else { //available but is intra mb type
134 iTopRef = REF_NOT_IN_LIST;465 iTopRef[listIdx] = REF_NOT_IN_LIST;
466 }
135 }467 }
136 }
137 if (REF_NOT_AVAIL == iTopRef ||
138 (0 == iTopRef && 0 == * (int32_t*)iMvB)) {
139 ST32 (iMvp, 0);
140 return;
141 }
142 468
143 /*right_top*/469 /*right_top*/
144 if (bRightTopAvail && IS_INTER (iRightTopType)) {470 if (bRightTopAvail && IS_INTER (iRightTopType)) {
145 ST32 (iMvC, LD32 (pCurLayer->pMv[0][iRightTopXy][12]));471 ST32 (iMvC[listIdx], LD32 (pCurLayer->pMv[listIdx][iRightTopXy][12]));
146 iRightTopRef = pCurLayer->pRefIndex[0][iRightTopXy][12];472 iRightTopRef[listIdx] = pCurLayer->pRefIndex[listIdx][iRightTopXy][12];
147 } else {473 } else {
148 ST32 (iMvC, 0);474 ST32 (iMvC[listIdx], 0);
149 if (0 == bRightTopAvail) { //not available475 if (0 == bRightTopAvail) { //not available
150 iRightTopRef = REF_NOT_AVAIL;476 iRightTopRef[listIdx] = REF_NOT_AVAIL;
151 } else { //available but is intra mb type477 } else { //available but is intra mb type
152 iRightTopRef = REF_NOT_IN_LIST;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 }
153 }492 }
154 }
155 493
156 /*left_top*/494 iDiagonalRef[listIdx] = iRightTopRef[listIdx];
157 if (bLeftTopAvail && IS_INTER (iLeftTopType)) {495 if (REF_NOT_AVAIL == iDiagonalRef[listIdx]) {
158 ST32 (iMvD, LD32 (pCurLayer->pMv[0][iLeftTopXy][15]));496 iDiagonalRef[listIdx] = iLeftTopRef[listIdx];
159 iLeftTopRef = pCurLayer->pRefIndex[0][iLeftTopXy][15];497 * (int32_t*)iMvC[listIdx] = * (int32_t*)iMvD[listIdx];
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;
166 }498 }
167 }
168 499
169 iDiagonalRef = iRightTopRef;500 int8_t ref_temp = WELS_MIN_POSITIVE (iTopRef[listIdx], iDiagonalRef[listIdx]);
170 if (REF_NOT_AVAIL == iDiagonalRef) {501 ref[listIdx] = WELS_MIN_POSITIVE (iLeftRef[listIdx], ref_temp);
171 iDiagonalRef = iLeftTopRef;502 if (ref[listIdx] >= 0) {
172 * (int32_t*)iMvC = * (int32_t*)iMvD;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 }
173 }523 }
174 524 if (ref[LIST_0] <= REF_NOT_IN_LIST && ref[LIST_1] <= REF_NOT_IN_LIST) {
175 if (REF_NOT_AVAIL == iTopRef && REF_NOT_AVAIL == iDiagonalRef && iLeftRef >= REF_NOT_IN_LIST) {525 ref[LIST_0] = ref[LIST_1] = 0;
176 ST32 (iMvp, LD32 (iMvA));526 } else if (ref[LIST_1] < 0) {
177 return;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 }
178 }645 }
646 return subMbType;
647}
179 648
180 iMatchRef = (0 == iLeftRef) + (0 == iTopRef) + (0 == iDiagonalRef);649void PredBDirectTemporal (PWelsDecoderContext pCtx, int16_t iMvp[LIST_A][2], int8_t ref[LIST_A]) {
181 if (1 == iMatchRef) {650 PDqLayer pCurLayer = pCtx->pCurDqLayer;
182 if (0 == iLeftRef) {651 int32_t iMbXy = pCurLayer->iMbXyIndex;
183 ST32 (iMvp, LD32 (iMvA));652 bool bSkipOrDirect = (IS_SKIP (pCurLayer->pMbType[iMbXy]) | IS_DIRECT (pCurLayer->pMbType[iMbXy])) > 0;
184 } else if (0 == iTopRef) {653 MbType mbType;
185 ST32 (iMvp, LD32 (iMvB));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]);
186 } else {666 } 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]);
188 }678 }
189 } else {679 } else {
190 iMvp[0] = WelsMedian (iMvA[0], iMvB[0], iMvC[0]);680 if (bSkipOrDirect) {
191 iMvp[1] = WelsMedian (iMvA[1], iMvB[1], iMvC[1]);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 }
192 }750 }
193}751}
194 752
195
196//basic iMVs prediction unit for iMVs partition width (4, 2, 1)753//basic iMVs prediction unit for iMVs partition width (4, 2, 1)
197void PredMv (int16_t iMotionVector[LIST_A][30][MV_A], int8_t iRefIndex[LIST_A][30],754void 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]) {
199 const uint8_t kuiLeftIdx = g_kuiCache30ScanIdx[iPartIdx] - 1;756 const uint8_t kuiLeftIdx = g_kuiCache30ScanIdx[iPartIdx] - 1;
200 const uint8_t kuiTopIdx = g_kuiCache30ScanIdx[iPartIdx] - 6;757 const uint8_t kuiTopIdx = g_kuiCache30ScanIdx[iPartIdx] - 6;
201 const uint8_t kuiRightTopIdx = kuiTopIdx + iPartWidth;758 const uint8_t kuiRightTopIdx = kuiTopIdx + iPartWidth;
202 const uint8_t kuiLeftTopIdx = kuiTopIdx - 1;759 const uint8_t kuiLeftTopIdx = kuiTopIdx - 1;
203 760
204 const int8_t kiLeftRef = iRefIndex[0][kuiLeftIdx];761 const int8_t kiLeftRef = iRefIndex[listIdx][kuiLeftIdx];
205 const int8_t kiTopRef = iRefIndex[0][ kuiTopIdx];762 const int8_t kiTopRef = iRefIndex[listIdx][ kuiTopIdx];
206 const int8_t kiRightTopRef = iRefIndex[0][kuiRightTopIdx];763 const int8_t kiRightTopRef = iRefIndex[listIdx][kuiRightTopIdx];
207 const int8_t kiLeftTopRef = iRefIndex[0][ kuiLeftTopIdx];764 const int8_t kiLeftTopRef = iRefIndex[listIdx][ kuiLeftTopIdx];
208 int8_t iDiagonalRef = kiRightTopRef;765 int8_t iDiagonalRef = kiRightTopRef;
209 766
210 int8_t iMatchRef = 0;767 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
212 769
213 int16_t iAMV[2], iBMV[2], iCMV[2];770 int16_t iAMV[2], iBMV[2], iCMV[2];
214 771
215 ST32 (iAMV, LD32 (iMotionVector[0][ kuiLeftIdx]));772 ST32 (iAMV, LD32 (iMotionVector[listIdx][ kuiLeftIdx]));
216 ST32 (iBMV, LD32 (iMotionVector[0][ kuiTopIdx]));773 ST32 (iBMV, LD32 (iMotionVector[listIdx][ kuiTopIdx]));
217 ST32 (iCMV, LD32 (iMotionVector[0][kuiRightTopIdx]));774 ST32 (iCMV, LD32 (iMotionVector[listIdx][kuiRightTopIdx]));
218 775
219 if (REF_NOT_AVAIL == iDiagonalRef) {776 if (REF_NOT_AVAIL == iDiagonalRef) {
220 iDiagonalRef = kiLeftTopRef;777 iDiagonalRef = kiLeftTopRef;
221 ST32 (iCMV, LD32 (iMotionVector[0][kuiLeftTopIdx]));778 ST32 (iCMV, LD32 (iMotionVector[listIdx][kuiLeftTopIdx]));
222 }779 }
223 780
224 iMatchRef = (iRef == kiLeftRef) + (iRef == kiTopRef) + (iRef == iDiagonalRef);781 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
242 }799 }
243}800}
244void PredInter8x16Mv (int16_t iMotionVector[LIST_A][30][MV_A], int8_t iRefIndex[LIST_A][30],801void 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]) {
246 if (0 == iPartIdx) {803 if (0 == iPartIdx) {
247 const int8_t kiLeftRef = iRefIndex[0][6];804 const int8_t kiLeftRef = iRefIndex[listIdx][6];
248 if (iRef == kiLeftRef) {805 if (iRef == kiLeftRef) {
249 ST32 (iMVP, LD32 (&iMotionVector[0][6][0]));806 ST32 (iMVP, LD32 (&iMotionVector[listIdx][6][0]));
250 return;807 return;
251 }808 }
252 } else { // 1 == iPartIdx809 } else { // 1 == iPartIdx
253 int8_t iDiagonalRef = iRefIndex[0][5]; //top-right810 int8_t iDiagonalRef = iRefIndex[listIdx][5]; //top-right
254 int8_t index = 5;811 int8_t index = 5;
255 if (REF_NOT_AVAIL == iDiagonalRef) {812 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)
257 index = 2;814 index = 2;
258 }815 }
259 if (iRef == iDiagonalRef) {816 if (iRef == iDiagonalRef) {
260 ST32 (iMVP, LD32 (&iMotionVector[0][index][0]));817 ST32 (iMVP, LD32 (&iMotionVector[listIdx][index][0]));
261 return;818 return;
262 }819 }
263 }820 }
264 821
265 PredMv (iMotionVector, iRefIndex, iPartIdx, 2, iRef, iMVP);822 PredMv (iMotionVector, iRefIndex, listIdx, iPartIdx, 2, iRef, iMVP);
266}823}
267void PredInter16x8Mv (int16_t iMotionVector[LIST_A][30][MV_A], int8_t iRefIndex[LIST_A][30],824void 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]) {
269 if (0 == iPartIdx) {826 if (0 == iPartIdx) {
270 const int8_t kiTopRef = iRefIndex[0][1];827 const int8_t kiTopRef = iRefIndex[listIdx][1];
271 if (iRef == kiTopRef) {828 if (iRef == kiTopRef) {
272 ST32 (iMVP, LD32 (&iMotionVector[0][1][0]));829 ST32 (iMVP, LD32 (&iMotionVector[listIdx][1][0]));
273 return;830 return;
274 }831 }
275 } else { // 8 == iPartIdx832 } else { // 8 == iPartIdx
276 const int8_t kiLeftRef = iRefIndex[0][18];833 const int8_t kiLeftRef = iRefIndex[listIdx][18];
277 if (iRef == kiLeftRef) {834 if (iRef == kiLeftRef) {
278 ST32 (iMVP, LD32 (&iMotionVector[0][18][0]));835 ST32 (iMVP, LD32 (&iMotionVector[listIdx][18][0]));
279 return;836 return;
280 }837 }
281 }838 }
282 839
283 PredMv (iMotionVector, iRefIndex, iPartIdx, 4, iRef, iMVP);840 PredMv (iMotionVector, iRefIndex, listIdx, iPartIdx, 4, iRef, iMVP);
284}841}
285 842
286//update iMVs and iRefIndex cache for current MB, only for P_16*16 (SKIP inclusive)843//update iMVs and iRefIndex cache for current MB, only for P_16*16 (SKIP inclusive)
287/* can be further optimized */844/* can be further optimized */
288void UpdateP16x16MotionInfo (PDqLayer pCurDqLayer, int8_t iRef, int16_t iMVs[2]) {845void UpdateP16x16MotionInfo (PDqLayer pCurDqLayer, int32_t listIdx, int8_t iRef, int16_t iMVs[2]) {
289 const int16_t kiRef2 = (iRef << 8) | iRef;846 const int16_t kiRef2 = (iRef << 8) | iRef;
290 const int32_t kiMV32 = LD32 (iMVs);847 const int32_t kiMV32 = LD32 (iMVs);
291 int32_t i;848 int32_t i;
@@ -296,13 +853,49 @@ void UpdateP16x16MotionInfo (PDqLayer pCurDqLayer, int8_t iRef, int16_t iMVs[2]) · 4 unmodified lines
296 const uint8_t kuiScan4Idx = g_kuiScan4[i];853 const uint8_t kuiScan4Idx = g_kuiScan4[i];
297 const uint8_t kuiScan4IdxPlus4 = 4 + kuiScan4Idx;854 const uint8_t kuiScan4IdxPlus4 = 4 + kuiScan4Idx;
298 855
299 ST16 (&pCurDqLayer->pRefIndex[0][iMbXy][kuiScan4Idx ], kiRef2);856 ST16 (&pCurDqLayer->pRefIndex[listIdx][iMbXy][kuiScan4Idx ], kiRef2);
300 ST16 (&pCurDqLayer->pRefIndex[0][iMbXy][kuiScan4IdxPlus4], 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 */
868void 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 */
885void 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;
301 894
302 ST32 (pCurDqLayer->pMv[0][iMbXy][ kuiScan4Idx ], kiMV32);895 ST32 (pCurDqLayer->pMv[listIdx][iMbXy][kuiScan4Idx], kiMV32);
303 ST32 (pCurDqLayer->pMv[0][iMbXy][1 + kuiScan4Idx ], kiMV32);896 ST32 (pCurDqLayer->pMv[listIdx][iMbXy][1 + kuiScan4Idx], kiMV32);
304 ST32 (pCurDqLayer->pMv[0][iMbXy][ kuiScan4IdxPlus4], kiMV32);897 ST32 (pCurDqLayer->pMv[listIdx][iMbXy][kuiScan4IdxPlus4], kiMV32);
305 ST32 (pCurDqLayer->pMv[0][iMbXy][1 + kuiScan4IdxPlus4], kiMV32);898 ST32 (pCurDqLayer->pMv[listIdx][iMbXy][1 + kuiScan4IdxPlus4], kiMV32);
306 }899 }
307}900}
308 901
@@ -310,7 +903,7 @@ void UpdateP16x16MotionInfo (PDqLayer pCurDqLayer, int8_t iRef, int16_t iMVs[2]) · 1 unmodified line
310/*need further optimization, mb_cache not work */903/*need further optimization, mb_cache not work */
311void UpdateP16x8MotionInfo (PDqLayer pCurDqLayer, int16_t iMotionVector[LIST_A][30][MV_A],904void UpdateP16x8MotionInfo (PDqLayer pCurDqLayer, int16_t iMotionVector[LIST_A][30][MV_A],
312 int8_t iRefIndex[LIST_A][30],905 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]) {
314 const int16_t kiRef2 = (iRef << 8) | iRef;907 const int16_t kiRef2 = (iRef << 8) | iRef;
315 const int32_t kiMV32 = LD32 (iMVs);908 const int32_t kiMV32 = LD32 (iMVs);
316 int32_t i;909 int32_t i;
@@ -322,25 +915,25 @@ void UpdateP16x8MotionInfo (PDqLayer pCurDqLayer, int16_t iMotionVector[LIST_A][ · 5 unmodified lines
322 const uint8_t kuiCacheIdxPlus6 = 6 + kuiCacheIdx;915 const uint8_t kuiCacheIdxPlus6 = 6 + kuiCacheIdx;
323 916
324 //mb917 //mb
325 ST16 (&pCurDqLayer->pRefIndex[0][iMbXy][kuiScan4Idx ], kiRef2);918 ST16 (&pCurDqLayer->pRefIndex[listIdx][iMbXy][kuiScan4Idx ], kiRef2);
326 ST16 (&pCurDqLayer->pRefIndex[0][iMbXy][kuiScan4IdxPlus4], kiRef2);919 ST16 (&pCurDqLayer->pRefIndex[listIdx][iMbXy][kuiScan4IdxPlus4], kiRef2);
327 ST32 (pCurDqLayer->pMv[0][iMbXy][ kuiScan4Idx ], kiMV32);920 ST32 (pCurDqLayer->pMv[listIdx][iMbXy][ kuiScan4Idx ], kiMV32);
328 ST32 (pCurDqLayer->pMv[0][iMbXy][1 + kuiScan4Idx ], kiMV32);921 ST32 (pCurDqLayer->pMv[listIdx][iMbXy][1 + kuiScan4Idx ], kiMV32);
329 ST32 (pCurDqLayer->pMv[0][iMbXy][ kuiScan4IdxPlus4], kiMV32);922 ST32 (pCurDqLayer->pMv[listIdx][iMbXy][ kuiScan4IdxPlus4], kiMV32);
330 ST32 (pCurDqLayer->pMv[0][iMbXy][1 + kuiScan4IdxPlus4], kiMV32);923 ST32 (pCurDqLayer->pMv[listIdx][iMbXy][1 + kuiScan4IdxPlus4], kiMV32);
331 //cache924 //cache
332 ST16 (&iRefIndex[0][kuiCacheIdx ], kiRef2);925 ST16 (&iRefIndex[listIdx][kuiCacheIdx ], kiRef2);
333 ST16 (&iRefIndex[0][kuiCacheIdxPlus6], kiRef2);926 ST16 (&iRefIndex[listIdx][kuiCacheIdxPlus6], kiRef2);
334 ST32 (iMotionVector[0][ kuiCacheIdx ], kiMV32);927 ST32 (iMotionVector[listIdx][ kuiCacheIdx ], kiMV32);
335 ST32 (iMotionVector[0][1 + kuiCacheIdx ], kiMV32);928 ST32 (iMotionVector[listIdx][1 + kuiCacheIdx ], kiMV32);
336 ST32 (iMotionVector[0][ kuiCacheIdxPlus6], kiMV32);929 ST32 (iMotionVector[listIdx][ kuiCacheIdxPlus6], kiMV32);
337 ST32 (iMotionVector[0][1 + kuiCacheIdxPlus6], kiMV32);930 ST32 (iMotionVector[listIdx][1 + kuiCacheIdxPlus6], kiMV32);
338 }931 }
339}932}
340//update iRefIndex and iMVs of both Mb and Mb_cache, only for P8x16933//update iRefIndex and iMVs of both Mb and Mb_cache, only for P8x16
341void UpdateP8x16MotionInfo (PDqLayer pCurDqLayer, int16_t iMotionVector[LIST_A][30][MV_A],934void UpdateP8x16MotionInfo (PDqLayer pCurDqLayer, int16_t iMotionVector[LIST_A][30][MV_A],
342 int8_t iRefIndex[LIST_A][30],935 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]) {
344 const int16_t kiRef2 = (iRef << 8) | iRef;937 const int16_t kiRef2 = (iRef << 8) | iRef;
345 const int32_t kiMV32 = LD32 (iMVs);938 const int32_t kiMV32 = LD32 (iMVs);
346 int32_t i;939 int32_t i;
@@ -353,19 +946,19 @@ void UpdateP8x16MotionInfo (PDqLayer pCurDqLayer, int16_t iMotionVector[LIST_A][ · 6 unmodified lines
353 const uint8_t kuiCacheIdxPlus6 = 6 + kuiCacheIdx;946 const uint8_t kuiCacheIdxPlus6 = 6 + kuiCacheIdx;
354 947
355 //mb948 //mb
356 ST16 (&pCurDqLayer->pRefIndex[0][iMbXy][kuiScan4Idx ], kiRef2);949 ST16 (&pCurDqLayer->pRefIndex[listIdx][iMbXy][kuiScan4Idx ], kiRef2);
357 ST16 (&pCurDqLayer->pRefIndex[0][iMbXy][kuiScan4IdxPlus4], kiRef2);950 ST16 (&pCurDqLayer->pRefIndex[listIdx][iMbXy][kuiScan4IdxPlus4], kiRef2);
358 ST32 (pCurDqLayer->pMv[0][iMbXy][ kuiScan4Idx ], kiMV32);951 ST32 (pCurDqLayer->pMv[listIdx][iMbXy][ kuiScan4Idx ], kiMV32);
359 ST32 (pCurDqLayer->pMv[0][iMbXy][1 + kuiScan4Idx ], kiMV32);952 ST32 (pCurDqLayer->pMv[listIdx][iMbXy][1 + kuiScan4Idx ], kiMV32);
360 ST32 (pCurDqLayer->pMv[0][iMbXy][ kuiScan4IdxPlus4], kiMV32);953 ST32 (pCurDqLayer->pMv[listIdx][iMbXy][ kuiScan4IdxPlus4], kiMV32);
361 ST32 (pCurDqLayer->pMv[0][iMbXy][1 + kuiScan4IdxPlus4], kiMV32);954 ST32 (pCurDqLayer->pMv[listIdx][iMbXy][1 + kuiScan4IdxPlus4], kiMV32);
362 //cache955 //cache
363 ST16 (&iRefIndex[0][kuiCacheIdx ], kiRef2);956 ST16 (&iRefIndex[listIdx][kuiCacheIdx ], kiRef2);
364 ST16 (&iRefIndex[0][kuiCacheIdxPlus6], kiRef2);957 ST16 (&iRefIndex[listIdx][kuiCacheIdxPlus6], kiRef2);
365 ST32 (iMotionVector[0][ kuiCacheIdx ], kiMV32);958 ST32 (iMotionVector[listIdx][ kuiCacheIdx ], kiMV32);
366 ST32 (iMotionVector[0][1 + kuiCacheIdx ], kiMV32);959 ST32 (iMotionVector[listIdx][1 + kuiCacheIdx ], kiMV32);
367 ST32 (iMotionVector[0][ kuiCacheIdxPlus6], kiMV32);960 ST32 (iMotionVector[listIdx][ kuiCacheIdxPlus6], kiMV32);
368 ST32 (iMotionVector[0][1 + kuiCacheIdxPlus6], kiMV32);961 ST32 (iMotionVector[listIdx][1 + kuiCacheIdxPlus6], kiMV32);
369 }962 }
370}963}
371 964

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