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 parse_mb_syn_cavlc.c
33 *
34 * \brief Interfaces implementation for parsing the syntax of MB
35 *
36 * \date 03/17/2009 Created
37 *
38 *************************************************************************************
39 */
40
41
42 #include "parse_mb_syn_cavlc.h"
43 #include "decode_slice.h"
44 #include "error_code.h"
45 #include "mv_pred.h"
46
47 namespace WelsDec {
48 #define MAX_LEVEL_PREFIX 15
49
50 typedef struct TagReadBitsCache {
51 uint32_t uiCache32Bit;
52 uint8_t uiRemainBits;
53 uint8_t* pBuf;
54 } SReadBitsCache;
55
GetNeighborAvailMbType(PWelsNeighAvail pNeighAvail,PDqLayer pCurDqLayer)56 void GetNeighborAvailMbType (PWelsNeighAvail pNeighAvail, PDqLayer pCurDqLayer) {
57 int32_t iCurSliceIdc, iTopSliceIdc, iLeftTopSliceIdc, iRightTopSliceIdc, iLeftSliceIdc;
58 int32_t iCurXy, iTopXy = 0, iLeftXy = 0, iLeftTopXy = 0, iRightTopXy = 0;
59 int32_t iCurX, iCurY;
60
61 iCurXy = pCurDqLayer->iMbXyIndex;
62 iCurX = pCurDqLayer->iMbX;
63 iCurY = pCurDqLayer->iMbY;
64 iCurSliceIdc = pCurDqLayer->pSliceIdc[iCurXy];
65 if (iCurX != 0) {
66 iLeftXy = iCurXy - 1;
67 iLeftSliceIdc = pCurDqLayer->pSliceIdc[iLeftXy];
68 pNeighAvail->iLeftAvail = (iLeftSliceIdc == iCurSliceIdc);
69 pNeighAvail->iLeftCbp = pNeighAvail->iLeftAvail ? pCurDqLayer->pCbp[iLeftXy] : 0;
70 } else {
71 pNeighAvail->iLeftAvail = 0;
72 pNeighAvail->iLeftTopAvail = 0;
73 pNeighAvail->iLeftCbp = 0;
74 }
75
76 if (iCurY != 0) {
77 iTopXy = iCurXy - pCurDqLayer->iMbWidth;
78 iTopSliceIdc = pCurDqLayer->pSliceIdc[iTopXy];
79 pNeighAvail->iTopAvail = (iTopSliceIdc == iCurSliceIdc);
80 pNeighAvail->iTopCbp = pNeighAvail->iTopAvail ? pCurDqLayer->pCbp[iTopXy] : 0;
81 if (iCurX != 0) {
82 iLeftTopXy = iTopXy - 1;
83 iLeftTopSliceIdc = pCurDqLayer->pSliceIdc[iLeftTopXy];
84 pNeighAvail->iLeftTopAvail = (iLeftTopSliceIdc == iCurSliceIdc);
85 } else {
86 pNeighAvail->iLeftTopAvail = 0;
87 }
88 if (iCurX != (pCurDqLayer->iMbWidth - 1)) {
89 iRightTopXy = iTopXy + 1;
90 iRightTopSliceIdc = pCurDqLayer->pSliceIdc[iRightTopXy];
91 pNeighAvail->iRightTopAvail = (iRightTopSliceIdc == iCurSliceIdc);
92 } else {
93 pNeighAvail->iRightTopAvail = 0;
94 }
95 } else {
96 pNeighAvail->iTopAvail = 0;
97 pNeighAvail->iLeftTopAvail = 0;
98 pNeighAvail->iRightTopAvail = 0;
99 pNeighAvail->iTopCbp = 0;
100 }
101
102 pNeighAvail->iLeftType = (pNeighAvail->iLeftAvail ? pCurDqLayer->pDec->pMbType[iLeftXy] : 0);
103 pNeighAvail->iTopType = (pNeighAvail->iTopAvail ? pCurDqLayer->pDec->pMbType[iTopXy] : 0);
104 pNeighAvail->iLeftTopType = (pNeighAvail->iLeftTopAvail ? pCurDqLayer->pDec->pMbType[iLeftTopXy] : 0);
105 pNeighAvail->iRightTopType = (pNeighAvail->iRightTopAvail ? pCurDqLayer->pDec->pMbType[iRightTopXy] : 0);
106 }
WelsFillCacheNonZeroCount(PWelsNeighAvail pNeighAvail,uint8_t * pNonZeroCount,PDqLayer pCurDqLayer)107 void WelsFillCacheNonZeroCount (PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroCount,
108 PDqLayer pCurDqLayer) { //no matter slice type, intra_pred_constrained_flag
109 int32_t iCurXy = pCurDqLayer->iMbXyIndex;
110 int32_t iTopXy = 0;
111 int32_t iLeftXy = 0;
112 if (pNeighAvail->iTopAvail) {
113 iTopXy = iCurXy - pCurDqLayer->iMbWidth;
114 }
115 if (pNeighAvail->iLeftAvail) {
116 iLeftXy = iCurXy - 1;
117 }
118
119 //stuff non_zero_coeff_count from pNeighAvail(left and top)
120 if (pNeighAvail->iTopAvail) {
121 ST32 (&pNonZeroCount[1], LD32 (&pCurDqLayer->pNzc[iTopXy][12]));
122 pNonZeroCount[0] = pNonZeroCount[5] = pNonZeroCount[29] = 0;
123 ST16 (&pNonZeroCount[6], LD16 (&pCurDqLayer->pNzc[iTopXy][20]));
124 ST16 (&pNonZeroCount[30], LD16 (&pCurDqLayer->pNzc[iTopXy][22]));
125 } else {
126 ST32 (&pNonZeroCount[1], 0xFFFFFFFFU);
127 pNonZeroCount[0] = pNonZeroCount[5] = pNonZeroCount[29] = 0xFF;
128 ST16 (&pNonZeroCount[6], 0xFFFF);
129 ST16 (&pNonZeroCount[30], 0xFFFF);
130 }
131
132 if (pNeighAvail->iLeftAvail) {
133 pNonZeroCount[8 * 1] = pCurDqLayer->pNzc[iLeftXy][3];
134 pNonZeroCount[8 * 2] = pCurDqLayer->pNzc[iLeftXy][7];
135 pNonZeroCount[8 * 3] = pCurDqLayer->pNzc[iLeftXy][11];
136 pNonZeroCount[8 * 4] = pCurDqLayer->pNzc[iLeftXy][15];
137
138 pNonZeroCount[5 + 8 * 1] = pCurDqLayer->pNzc[iLeftXy][17];
139 pNonZeroCount[5 + 8 * 2] = pCurDqLayer->pNzc[iLeftXy][21];
140 pNonZeroCount[5 + 8 * 4] = pCurDqLayer->pNzc[iLeftXy][19];
141 pNonZeroCount[5 + 8 * 5] = pCurDqLayer->pNzc[iLeftXy][23];
142 } else {
143 pNonZeroCount[8 * 1] =
144 pNonZeroCount[8 * 2] =
145 pNonZeroCount[8 * 3] =
146 pNonZeroCount[8 * 4] = -1;//unavailable
147
148 pNonZeroCount[5 + 8 * 1] =
149 pNonZeroCount[5 + 8 * 2] = -1;//unavailable
150
151 pNonZeroCount[5 + 8 * 4] =
152 pNonZeroCount[5 + 8 * 5] = -1;//unavailable
153 }
154 }
WelsFillCacheConstrain1IntraNxN(PWelsNeighAvail pNeighAvail,uint8_t * pNonZeroCount,int8_t * pIntraPredMode,PDqLayer pCurDqLayer)155 void WelsFillCacheConstrain1IntraNxN (PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroCount, int8_t* pIntraPredMode,
156 PDqLayer pCurDqLayer) { //no matter slice type
157 int32_t iCurXy = pCurDqLayer->iMbXyIndex;
158 int32_t iTopXy = 0;
159 int32_t iLeftXy = 0;
160
161 //stuff non_zero_coeff_count from pNeighAvail(left and top)
162 WelsFillCacheNonZeroCount (pNeighAvail, pNonZeroCount, pCurDqLayer);
163
164 if (pNeighAvail->iTopAvail) {
165 iTopXy = iCurXy - pCurDqLayer->iMbWidth;
166 }
167 if (pNeighAvail->iLeftAvail) {
168 iLeftXy = iCurXy - 1;
169 }
170
171 //intraNxN_pred_mode
172 if (pNeighAvail->iTopAvail && IS_INTRANxN (pNeighAvail->iTopType)) { //top
173 ST32 (pIntraPredMode + 1, LD32 (&pCurDqLayer->pIntraPredMode[iTopXy][0]));
174 } else {
175 int32_t iPred;
176 if (IS_INTRA16x16 (pNeighAvail->iTopType) || (MB_TYPE_INTRA_PCM == pNeighAvail->iTopType))
177 iPred = 0x02020202;
178 else
179 iPred = 0xffffffff;
180 ST32 (pIntraPredMode + 1, iPred);
181 }
182
183 if (pNeighAvail->iLeftAvail && IS_INTRANxN (pNeighAvail->iLeftType)) { //left
184 pIntraPredMode[ 0 + 8 ] = pCurDqLayer->pIntraPredMode[iLeftXy][4];
185 pIntraPredMode[ 0 + 8 * 2] = pCurDqLayer->pIntraPredMode[iLeftXy][5];
186 pIntraPredMode[ 0 + 8 * 3] = pCurDqLayer->pIntraPredMode[iLeftXy][6];
187 pIntraPredMode[ 0 + 8 * 4] = pCurDqLayer->pIntraPredMode[iLeftXy][3];
188 } else {
189 int8_t iPred;
190 if (IS_INTRA16x16 (pNeighAvail->iLeftType) || (MB_TYPE_INTRA_PCM == pNeighAvail->iLeftType))
191 iPred = 2;
192 else
193 iPred = -1;
194 pIntraPredMode[ 0 + 8 ] =
195 pIntraPredMode[ 0 + 8 * 2] =
196 pIntraPredMode[ 0 + 8 * 3] =
197 pIntraPredMode[ 0 + 8 * 4] = iPred;
198 }
199 }
200
WelsFillCacheConstrain0IntraNxN(PWelsNeighAvail pNeighAvail,uint8_t * pNonZeroCount,int8_t * pIntraPredMode,PDqLayer pCurDqLayer)201 void WelsFillCacheConstrain0IntraNxN (PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroCount, int8_t* pIntraPredMode,
202 PDqLayer pCurDqLayer) { //no matter slice type
203 int32_t iCurXy = pCurDqLayer->iMbXyIndex;
204 int32_t iTopXy = 0;
205 int32_t iLeftXy = 0;
206
207 //stuff non_zero_coeff_count from pNeighAvail(left and top)
208 WelsFillCacheNonZeroCount (pNeighAvail, pNonZeroCount, pCurDqLayer);
209
210 if (pNeighAvail->iTopAvail) {
211 iTopXy = iCurXy - pCurDqLayer->iMbWidth;
212 }
213 if (pNeighAvail->iLeftAvail) {
214 iLeftXy = iCurXy - 1;
215 }
216
217 //intra4x4_pred_mode
218 if (pNeighAvail->iTopAvail && IS_INTRANxN (pNeighAvail->iTopType)) { //top
219 ST32 (pIntraPredMode + 1, LD32 (&pCurDqLayer->pIntraPredMode[iTopXy][0]));
220 } else {
221 int32_t iPred;
222 if (pNeighAvail->iTopAvail)
223 iPred = 0x02020202;
224 else
225 iPred = 0xffffffff;
226 ST32 (pIntraPredMode + 1, iPred);
227 }
228
229 if (pNeighAvail->iLeftAvail && IS_INTRANxN (pNeighAvail->iLeftType)) { //left
230 pIntraPredMode[ 0 + 8 * 1] = pCurDqLayer->pIntraPredMode[iLeftXy][4];
231 pIntraPredMode[ 0 + 8 * 2] = pCurDqLayer->pIntraPredMode[iLeftXy][5];
232 pIntraPredMode[ 0 + 8 * 3] = pCurDqLayer->pIntraPredMode[iLeftXy][6];
233 pIntraPredMode[ 0 + 8 * 4] = pCurDqLayer->pIntraPredMode[iLeftXy][3];
234 } else {
235 int8_t iPred;
236 if (pNeighAvail->iLeftAvail)
237 iPred = 2;
238 else
239 iPred = -1;
240 pIntraPredMode[ 0 + 8 * 1] =
241 pIntraPredMode[ 0 + 8 * 2] =
242 pIntraPredMode[ 0 + 8 * 3] =
243 pIntraPredMode[ 0 + 8 * 4] = iPred;
244 }
245 }
246
WelsFillCacheInterCabac(PWelsNeighAvail pNeighAvail,uint8_t * pNonZeroCount,int16_t iMvArray[LIST_A][30][MV_A],int16_t iMvdCache[LIST_A][30][MV_A],int8_t iRefIdxArray[LIST_A][30],PDqLayer pCurDqLayer)247 void WelsFillCacheInterCabac (PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroCount, int16_t iMvArray[LIST_A][30][MV_A],
248 int16_t iMvdCache[LIST_A][30][MV_A], int8_t iRefIdxArray[LIST_A][30], PDqLayer pCurDqLayer) {
249 int32_t iCurXy = pCurDqLayer->iMbXyIndex;
250 int32_t iTopXy = 0;
251 int32_t iLeftXy = 0;
252 int32_t iLeftTopXy = 0;
253 int32_t iRightTopXy = 0;
254
255 PSlice pSlice = &pCurDqLayer->sLayerInfo.sSliceInLayer;
256 PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
257 int32_t listCount = 1;
258 if (pSliceHeader->eSliceType == B_SLICE) {
259 listCount = 2;
260 }
261 //stuff non_zero_coeff_count from pNeighAvail(left and top)
262 WelsFillCacheNonZeroCount (pNeighAvail, pNonZeroCount, pCurDqLayer);
263
264 if (pNeighAvail->iTopAvail) {
265 iTopXy = iCurXy - pCurDqLayer->iMbWidth;
266 }
267 if (pNeighAvail->iLeftAvail) {
268 iLeftXy = iCurXy - 1;
269 }
270 if (pNeighAvail->iLeftTopAvail) {
271 iLeftTopXy = iCurXy - 1 - pCurDqLayer->iMbWidth;
272 }
273 if (pNeighAvail->iRightTopAvail) {
274 iRightTopXy = iCurXy + 1 - pCurDqLayer->iMbWidth;
275 }
276
277 for (int32_t listIdx = 0; listIdx < listCount; ++listIdx) {
278 //stuff mv_cache and iRefIdxArray from left and top (inter)
279 if (pNeighAvail->iLeftAvail && IS_INTER (pNeighAvail->iLeftType)) {
280 ST32 (iMvArray[listIdx][6], LD32 (pCurDqLayer->pDec->pMv[listIdx][iLeftXy][3]));
281 ST32 (iMvArray[listIdx][12], LD32 (pCurDqLayer->pDec->pMv[listIdx][iLeftXy][7]));
282 ST32 (iMvArray[listIdx][18], LD32 (pCurDqLayer->pDec->pMv[listIdx][iLeftXy][11]));
283 ST32 (iMvArray[listIdx][24], LD32 (pCurDqLayer->pDec->pMv[listIdx][iLeftXy][15]));
284
285 ST32 (iMvdCache[listIdx][6], LD32 (pCurDqLayer->pMvd[listIdx][iLeftXy][3]));
286 ST32 (iMvdCache[listIdx][12], LD32 (pCurDqLayer->pMvd[listIdx][iLeftXy][7]));
287 ST32 (iMvdCache[listIdx][18], LD32 (pCurDqLayer->pMvd[listIdx][iLeftXy][11]));
288 ST32 (iMvdCache[listIdx][24], LD32 (pCurDqLayer->pMvd[listIdx][iLeftXy][15]));
289
290 iRefIdxArray[listIdx][6] = pCurDqLayer->pDec->pRefIndex[listIdx][iLeftXy][3];
291 iRefIdxArray[listIdx][12] = pCurDqLayer->pDec->pRefIndex[listIdx][iLeftXy][7];
292 iRefIdxArray[listIdx][18] = pCurDqLayer->pDec->pRefIndex[listIdx][iLeftXy][11];
293 iRefIdxArray[listIdx][24] = pCurDqLayer->pDec->pRefIndex[listIdx][iLeftXy][15];
294 } else {
295 ST32 (iMvArray[listIdx][6], 0);
296 ST32 (iMvArray[listIdx][12], 0);
297 ST32 (iMvArray[listIdx][18], 0);
298 ST32 (iMvArray[listIdx][24], 0);
299
300 ST32 (iMvdCache[listIdx][6], 0);
301 ST32 (iMvdCache[listIdx][12], 0);
302 ST32 (iMvdCache[listIdx][18], 0);
303 ST32 (iMvdCache[listIdx][24], 0);
304
305
306 if (0 == pNeighAvail->iLeftAvail) { //not available
307 iRefIdxArray[listIdx][6] =
308 iRefIdxArray[listIdx][12] =
309 iRefIdxArray[listIdx][18] =
310 iRefIdxArray[listIdx][24] = REF_NOT_AVAIL;
311 } else { //available but is intra mb type
312 iRefIdxArray[listIdx][6] =
313 iRefIdxArray[listIdx][12] =
314 iRefIdxArray[listIdx][18] =
315 iRefIdxArray[listIdx][24] = REF_NOT_IN_LIST;
316 }
317 }
318 if (pNeighAvail->iLeftTopAvail && IS_INTER (pNeighAvail->iLeftTopType)) {
319 ST32 (iMvArray[listIdx][0], LD32 (pCurDqLayer->pDec->pMv[listIdx][iLeftTopXy][15]));
320 ST32 (iMvdCache[listIdx][0], LD32 (pCurDqLayer->pMvd[listIdx][iLeftTopXy][15]));
321 iRefIdxArray[listIdx][0] = pCurDqLayer->pDec->pRefIndex[listIdx][iLeftTopXy][15];
322 } else {
323 ST32 (iMvArray[listIdx][0], 0);
324 ST32 (iMvdCache[listIdx][0], 0);
325 if (0 == pNeighAvail->iLeftTopAvail) { //not available
326 iRefIdxArray[listIdx][0] = REF_NOT_AVAIL;
327 } else { //available but is intra mb type
328 iRefIdxArray[listIdx][0] = REF_NOT_IN_LIST;
329 }
330 }
331
332 if (pNeighAvail->iTopAvail && IS_INTER (pNeighAvail->iTopType)) {
333 ST64 (iMvArray[listIdx][1], LD64 (pCurDqLayer->pDec->pMv[listIdx][iTopXy][12]));
334 ST64 (iMvArray[listIdx][3], LD64 (pCurDqLayer->pDec->pMv[listIdx][iTopXy][14]));
335 ST64 (iMvdCache[listIdx][1], LD64 (pCurDqLayer->pMvd[listIdx][iTopXy][12]));
336 ST64 (iMvdCache[listIdx][3], LD64 (pCurDqLayer->pMvd[listIdx][iTopXy][14]));
337 ST32 (&iRefIdxArray[listIdx][1], LD32 (&pCurDqLayer->pDec->pRefIndex[listIdx][iTopXy][12]));
338 } else {
339 ST64 (iMvArray[listIdx][1], 0);
340 ST64 (iMvArray[listIdx][3], 0);
341 ST64 (iMvdCache[listIdx][1], 0);
342 ST64 (iMvdCache[listIdx][3], 0);
343 if (0 == pNeighAvail->iTopAvail) { //not available
344 iRefIdxArray[listIdx][1] =
345 iRefIdxArray[listIdx][2] =
346 iRefIdxArray[listIdx][3] =
347 iRefIdxArray[listIdx][4] = REF_NOT_AVAIL;
348 } else { //available but is intra mb type
349 iRefIdxArray[listIdx][1] =
350 iRefIdxArray[listIdx][2] =
351 iRefIdxArray[listIdx][3] =
352 iRefIdxArray[listIdx][4] = REF_NOT_IN_LIST;
353 }
354 }
355
356 if (pNeighAvail->iRightTopAvail && IS_INTER (pNeighAvail->iRightTopType)) {
357 ST32 (iMvArray[listIdx][5], LD32 (pCurDqLayer->pDec->pMv[listIdx][iRightTopXy][12]));
358 ST32 (iMvdCache[listIdx][5], LD32 (pCurDqLayer->pMvd[listIdx][iRightTopXy][12]));
359 iRefIdxArray[listIdx][5] = pCurDqLayer->pDec->pRefIndex[listIdx][iRightTopXy][12];
360 } else {
361 ST32 (iMvArray[listIdx][5], 0);
362 if (0 == pNeighAvail->iRightTopAvail) { //not available
363 iRefIdxArray[listIdx][5] = REF_NOT_AVAIL;
364 } else { //available but is intra mb type
365 iRefIdxArray[listIdx][5] = REF_NOT_IN_LIST;
366 }
367 }
368
369 //right-top 4*4 block unavailable
370 ST32 (iMvArray[listIdx][9], 0);
371 ST32 (iMvArray[listIdx][21], 0);
372 ST32 (iMvArray[listIdx][11], 0);
373 ST32 (iMvArray[listIdx][17], 0);
374 ST32 (iMvArray[listIdx][23], 0);
375 ST32 (iMvdCache[listIdx][9], 0);
376 ST32 (iMvdCache[listIdx][21], 0);
377 ST32 (iMvdCache[listIdx][11], 0);
378 ST32 (iMvdCache[listIdx][17], 0);
379 ST32 (iMvdCache[listIdx][23], 0);
380 iRefIdxArray[listIdx][9] =
381 iRefIdxArray[listIdx][21] =
382 iRefIdxArray[listIdx][11] =
383 iRefIdxArray[listIdx][17] =
384 iRefIdxArray[listIdx][23] = REF_NOT_AVAIL;
385 }
386 }
387
WelsFillDirectCacheCabac(PWelsNeighAvail pNeighAvail,int8_t iDirect[30],PDqLayer pCurDqLayer)388 void WelsFillDirectCacheCabac (PWelsNeighAvail pNeighAvail, int8_t iDirect[30], PDqLayer pCurDqLayer) {
389
390 int32_t iCurXy = pCurDqLayer->iMbXyIndex;
391 int32_t iTopXy = 0;
392 int32_t iLeftXy = 0;
393 int32_t iLeftTopXy = 0;
394 int32_t iRightTopXy = 0;
395
396 if (pNeighAvail->iTopAvail) {
397 iTopXy = iCurXy - pCurDqLayer->iMbWidth;
398 }
399 if (pNeighAvail->iLeftAvail) {
400 iLeftXy = iCurXy - 1;
401 }
402 if (pNeighAvail->iLeftTopAvail) {
403 iLeftTopXy = iCurXy - 1 - pCurDqLayer->iMbWidth;
404 }
405 if (pNeighAvail->iRightTopAvail) {
406 iRightTopXy = iCurXy + 1 - pCurDqLayer->iMbWidth;
407 }
408 memset (iDirect, 0, 30);
409 if (pNeighAvail->iLeftAvail && IS_INTER (pNeighAvail->iLeftType)) {
410 iDirect[6] = pCurDqLayer->pDirect[iLeftXy][3];
411 iDirect[12] = pCurDqLayer->pDirect[iLeftXy][7];
412 iDirect[18] = pCurDqLayer->pDirect[iLeftXy][11];
413 iDirect[24] = pCurDqLayer->pDirect[iLeftXy][15];
414 }
415 if (pNeighAvail->iLeftTopAvail && IS_INTER (pNeighAvail->iLeftTopType)) {
416 iDirect[0] = pCurDqLayer->pDirect[iLeftTopXy][15];
417 }
418
419 if (pNeighAvail->iTopAvail && IS_INTER (pNeighAvail->iTopType)) {
420 ST32 (&iDirect[1], LD32 (&pCurDqLayer->pDirect[iTopXy][12]));
421 }
422
423 if (pNeighAvail->iRightTopAvail && IS_INTER (pNeighAvail->iRightTopType)) {
424 iDirect[5] = pCurDqLayer->pDirect[iRightTopXy][12];
425 }
426 //right-top 4*4 block unavailable
427 }
428
WelsFillCacheInter(PWelsNeighAvail pNeighAvail,uint8_t * pNonZeroCount,int16_t iMvArray[LIST_A][30][MV_A],int8_t iRefIdxArray[LIST_A][30],PDqLayer pCurDqLayer)429 void WelsFillCacheInter (PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroCount,
430 int16_t iMvArray[LIST_A][30][MV_A], int8_t iRefIdxArray[LIST_A][30], PDqLayer pCurDqLayer) {
431 int32_t iCurXy = pCurDqLayer->iMbXyIndex;
432 int32_t iTopXy = 0;
433 int32_t iLeftXy = 0;
434 int32_t iLeftTopXy = 0;
435 int32_t iRightTopXy = 0;
436
437 PSlice pSlice = &pCurDqLayer->sLayerInfo.sSliceInLayer;
438 PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
439 int32_t listCount = 1;
440 if (pSliceHeader->eSliceType == B_SLICE) {
441 listCount = 2;
442 }
443
444 //stuff non_zero_coeff_count from pNeighAvail(left and top)
445 WelsFillCacheNonZeroCount (pNeighAvail, pNonZeroCount, pCurDqLayer);
446
447 if (pNeighAvail->iTopAvail) {
448 iTopXy = iCurXy - pCurDqLayer->iMbWidth;
449 }
450 if (pNeighAvail->iLeftAvail) {
451 iLeftXy = iCurXy - 1;
452 }
453 if (pNeighAvail->iLeftTopAvail) {
454 iLeftTopXy = iCurXy - 1 - pCurDqLayer->iMbWidth;
455 }
456 if (pNeighAvail->iRightTopAvail) {
457 iRightTopXy = iCurXy + 1 - pCurDqLayer->iMbWidth;
458 }
459
460 for (int32_t listIdx = 0; listIdx < listCount; ++listIdx) {
461 //stuff mv_cache and iRefIdxArray from left and top (inter)
462 if (pNeighAvail->iLeftAvail && IS_INTER (pNeighAvail->iLeftType)) {
463 ST32 (iMvArray[listIdx][6], LD32 (pCurDqLayer->pDec->pMv[listIdx][iLeftXy][3]));
464 ST32 (iMvArray[listIdx][12], LD32 (pCurDqLayer->pDec->pMv[listIdx][iLeftXy][7]));
465 ST32 (iMvArray[listIdx][18], LD32 (pCurDqLayer->pDec->pMv[listIdx][iLeftXy][11]));
466 ST32 (iMvArray[listIdx][24], LD32 (pCurDqLayer->pDec->pMv[listIdx][iLeftXy][15]));
467 iRefIdxArray[listIdx][6] = pCurDqLayer->pDec->pRefIndex[listIdx][iLeftXy][3];
468 iRefIdxArray[listIdx][12] = pCurDqLayer->pDec->pRefIndex[listIdx][iLeftXy][7];
469 iRefIdxArray[listIdx][18] = pCurDqLayer->pDec->pRefIndex[listIdx][iLeftXy][11];
470 iRefIdxArray[listIdx][24] = pCurDqLayer->pDec->pRefIndex[listIdx][iLeftXy][15];
471 } else {
472 ST32 (iMvArray[listIdx][6], 0);
473 ST32 (iMvArray[listIdx][12], 0);
474 ST32 (iMvArray[listIdx][18], 0);
475 ST32 (iMvArray[listIdx][24], 0);
476
477 if (0 == pNeighAvail->iLeftAvail) { //not available
478 iRefIdxArray[listIdx][6] =
479 iRefIdxArray[listIdx][12] =
480 iRefIdxArray[listIdx][18] =
481 iRefIdxArray[listIdx][24] = REF_NOT_AVAIL;
482 } else { //available but is intra mb type
483 iRefIdxArray[listIdx][6] =
484 iRefIdxArray[listIdx][12] =
485 iRefIdxArray[listIdx][18] =
486 iRefIdxArray[listIdx][24] = REF_NOT_IN_LIST;
487 }
488 }
489 if (pNeighAvail->iLeftTopAvail && IS_INTER (pNeighAvail->iLeftTopType)) {
490 ST32 (iMvArray[listIdx][0], LD32 (pCurDqLayer->pDec->pMv[listIdx][iLeftTopXy][15]));
491 iRefIdxArray[listIdx][0] = pCurDqLayer->pDec->pRefIndex[listIdx][iLeftTopXy][15];
492 } else {
493 ST32 (iMvArray[listIdx][0], 0);
494 if (0 == pNeighAvail->iLeftTopAvail) { //not available
495 iRefIdxArray[listIdx][0] = REF_NOT_AVAIL;
496 } else { //available but is intra mb type
497 iRefIdxArray[listIdx][0] = REF_NOT_IN_LIST;
498 }
499 }
500 if (pNeighAvail->iTopAvail && IS_INTER (pNeighAvail->iTopType)) {
501 ST64 (iMvArray[listIdx][1], LD64 (pCurDqLayer->pDec->pMv[listIdx][iTopXy][12]));
502 ST64 (iMvArray[listIdx][3], LD64 (pCurDqLayer->pDec->pMv[listIdx][iTopXy][14]));
503 ST32 (&iRefIdxArray[listIdx][1], LD32 (&pCurDqLayer->pDec->pRefIndex[listIdx][iTopXy][12]));
504 } else {
505 ST64 (iMvArray[listIdx][1], 0);
506 ST64 (iMvArray[listIdx][3], 0);
507 if (0 == pNeighAvail->iTopAvail) { //not available
508 iRefIdxArray[listIdx][1] =
509 iRefIdxArray[listIdx][2] =
510 iRefIdxArray[listIdx][3] =
511 iRefIdxArray[listIdx][4] = REF_NOT_AVAIL;
512 } else { //available but is intra mb type
513 iRefIdxArray[listIdx][1] =
514 iRefIdxArray[listIdx][2] =
515 iRefIdxArray[listIdx][3] =
516 iRefIdxArray[listIdx][4] = REF_NOT_IN_LIST;
517 }
518 }
519 if (pNeighAvail->iRightTopAvail && IS_INTER (pNeighAvail->iRightTopType)) {
520 ST32 (iMvArray[listIdx][5], LD32 (pCurDqLayer->pDec->pMv[listIdx][iRightTopXy][12]));
521 iRefIdxArray[listIdx][5] = pCurDqLayer->pDec->pRefIndex[listIdx][iRightTopXy][12];
522 } else {
523 ST32 (iMvArray[listIdx][5], 0);
524 if (0 == pNeighAvail->iRightTopAvail) { //not available
525 iRefIdxArray[listIdx][5] = REF_NOT_AVAIL;
526 } else { //available but is intra mb type
527 iRefIdxArray[listIdx][5] = REF_NOT_IN_LIST;
528 }
529 }
530 //right-top 4*4 block unavailable
531 ST32 (iMvArray[listIdx][9], 0);
532 ST32 (iMvArray[listIdx][21], 0);
533 ST32 (iMvArray[listIdx][11], 0);
534 ST32 (iMvArray[listIdx][17], 0);
535 ST32 (iMvArray[listIdx][23], 0);
536 iRefIdxArray[listIdx][9] =
537 iRefIdxArray[listIdx][21] =
538 iRefIdxArray[listIdx][11] =
539 iRefIdxArray[listIdx][17] =
540 iRefIdxArray[listIdx][23] = REF_NOT_AVAIL;
541 }
542 }
543
PredIntra4x4Mode(int8_t * pIntraPredMode,int32_t iIdx4)544 int32_t PredIntra4x4Mode (int8_t* pIntraPredMode, int32_t iIdx4) {
545 int8_t iTopMode = pIntraPredMode[g_kuiScan8[iIdx4] - 8];
546 int8_t iLeftMode = pIntraPredMode[g_kuiScan8[iIdx4] - 1];
547 int8_t iBestMode;
548
549 if (-1 == iLeftMode || -1 == iTopMode) {
550 iBestMode = 2;
551 } else {
552 iBestMode = WELS_MIN (iLeftMode, iTopMode);
553 }
554 return iBestMode;
555 }
556
557 #define CHECK_I16_MODE(a, b, c, d) \
558 ((a == g_ksI16PredInfo[a].iPredMode) && \
559 (b >= g_ksI16PredInfo[a].iLeftAvail) && \
560 (c >= g_ksI16PredInfo[a].iTopAvail) && \
561 (d >= g_ksI16PredInfo[a].iLeftTopAvail));
562 #define CHECK_CHROMA_MODE(a, b, c, d) \
563 ((a == g_ksChromaPredInfo[a].iPredMode) && \
564 (b >= g_ksChromaPredInfo[a].iLeftAvail) && \
565 (c >= g_ksChromaPredInfo[a].iTopAvail) && \
566 (d >= g_ksChromaPredInfo[a].iLeftTopAvail));
567 #define CHECK_I4_MODE(a, b, c, d) \
568 ((a == g_ksI4PredInfo[a].iPredMode) && \
569 (b >= g_ksI4PredInfo[a].iLeftAvail) && \
570 (c >= g_ksI4PredInfo[a].iTopAvail) && \
571 (d >= g_ksI4PredInfo[a].iLeftTopAvail));
572
573
CheckIntra16x16PredMode(uint8_t uiSampleAvail,int8_t * pMode)574 int32_t CheckIntra16x16PredMode (uint8_t uiSampleAvail, int8_t* pMode) {
575 int32_t iLeftAvail = uiSampleAvail & 0x04;
576 int32_t bLeftTopAvail = uiSampleAvail & 0x02;
577 int32_t iTopAvail = uiSampleAvail & 0x01;
578
579 if ((*pMode < 0) || (*pMode > MAX_PRED_MODE_ID_I16x16)) {
580 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_I16x16_PRED_MODE);
581 }
582
583 if (I16_PRED_DC == *pMode) {
584 if (iLeftAvail && iTopAvail) {
585 return ERR_NONE;
586 } else if (iLeftAvail) {
587 *pMode = I16_PRED_DC_L;
588 } else if (iTopAvail) {
589 *pMode = I16_PRED_DC_T;
590 } else {
591 *pMode = I16_PRED_DC_128;
592 }
593 } else {
594 bool bModeAvail = CHECK_I16_MODE (*pMode, iLeftAvail, iTopAvail, bLeftTopAvail);
595 if (0 == bModeAvail) {
596 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_I16x16_PRED_MODE);
597 }
598 }
599 return ERR_NONE;
600 }
601
602
CheckIntraChromaPredMode(uint8_t uiSampleAvail,int8_t * pMode)603 int32_t CheckIntraChromaPredMode (uint8_t uiSampleAvail, int8_t* pMode) {
604 int32_t iLeftAvail = uiSampleAvail & 0x04;
605 int32_t bLeftTopAvail = uiSampleAvail & 0x02;
606 int32_t iTopAvail = uiSampleAvail & 0x01;
607
608 if (C_PRED_DC == *pMode) {
609 if (iLeftAvail && iTopAvail) {
610 return ERR_NONE;
611 } else if (iLeftAvail) {
612 *pMode = C_PRED_DC_L;
613 } else if (iTopAvail) {
614 *pMode = C_PRED_DC_T;
615 } else {
616 *pMode = C_PRED_DC_128;
617 }
618 } else {
619 bool bModeAvail = CHECK_CHROMA_MODE (*pMode, iLeftAvail, iTopAvail, bLeftTopAvail);
620 if (0 == bModeAvail) {
621 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_I_CHROMA_PRED_MODE);
622 }
623 }
624 return ERR_NONE;
625 }
626
CheckIntraNxNPredMode(int32_t * pSampleAvail,int8_t * pMode,int32_t iIndex,bool b8x8)627 int32_t CheckIntraNxNPredMode (int32_t* pSampleAvail, int8_t* pMode, int32_t iIndex, bool b8x8) {
628 int8_t iIdx = g_kuiCache30ScanIdx[iIndex];
629
630 int32_t iLeftAvail = pSampleAvail[iIdx - 1];
631 int32_t iTopAvail = pSampleAvail[iIdx - 6];
632 int32_t bLeftTopAvail = pSampleAvail[iIdx - 7];
633 int32_t bRightTopAvail = pSampleAvail[iIdx - (b8x8 ? 4 : 5)]; // Diff with 4x4 Pred
634
635 int8_t iFinalMode;
636
637 if ((*pMode < 0) || (*pMode > MAX_PRED_MODE_ID_I4x4)) {
638 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INVALID_INTRA4X4_MODE);
639 }
640
641 if (I4_PRED_DC == *pMode) {
642 if (iLeftAvail && iTopAvail) {
643 return *pMode;
644 } else if (iLeftAvail) {
645 iFinalMode = I4_PRED_DC_L;
646 } else if (iTopAvail) {
647 iFinalMode = I4_PRED_DC_T;
648 } else {
649 iFinalMode = I4_PRED_DC_128;
650 }
651 } else {
652 bool bModeAvail = CHECK_I4_MODE (*pMode, iLeftAvail, iTopAvail, bLeftTopAvail);
653 if (0 == bModeAvail) {
654 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INVALID_INTRA4X4_MODE);
655 }
656
657 iFinalMode = *pMode;
658
659 //if right-top unavailable, modify mode DDL and VL (padding rightmost pixel of top)
660 if (I4_PRED_DDL == iFinalMode && 0 == bRightTopAvail) {
661 iFinalMode = I4_PRED_DDL_TOP;
662 } else if (I4_PRED_VL == iFinalMode && 0 == bRightTopAvail) {
663 iFinalMode = I4_PRED_VL_TOP;
664 }
665 }
666 return iFinalMode;
667 }
668
BsStartCavlc(PBitStringAux pBs)669 void BsStartCavlc (PBitStringAux pBs) {
670 pBs->iIndex = ((pBs->pCurBuf - pBs->pStartBuf) << 3) - (16 - pBs->iLeftBits);
671 }
BsEndCavlc(PBitStringAux pBs)672 void BsEndCavlc (PBitStringAux pBs) {
673 pBs->pCurBuf = pBs->pStartBuf + (pBs->iIndex >> 3);
674 uint32_t uiCache32Bit = (uint32_t) ((((pBs->pCurBuf[0] << 8) | pBs->pCurBuf[1]) << 16) |
675 (pBs->pCurBuf[2] << 8) | pBs->pCurBuf[3]);
676 pBs->uiCurBits = uiCache32Bit << (pBs->iIndex & 0x07);
677 pBs->pCurBuf += 4;
678 pBs->iLeftBits = -16 + (pBs->iIndex & 0x07);
679 }
680
681
682 // return: used bits
CavlcGetTrailingOnesAndTotalCoeff(uint8_t & uiTotalCoeff,uint8_t & uiTrailingOnes,SReadBitsCache * pBitsCache,SVlcTable * pVlcTable,bool bChromaDc,int8_t nC)683 static int32_t CavlcGetTrailingOnesAndTotalCoeff (uint8_t& uiTotalCoeff, uint8_t& uiTrailingOnes,
684 SReadBitsCache* pBitsCache, SVlcTable* pVlcTable, bool bChromaDc, int8_t nC) {
685 const uint8_t* kpVlcTableMoreBitsCountList[3] = {g_kuiVlcTableMoreBitsCount0, g_kuiVlcTableMoreBitsCount1, g_kuiVlcTableMoreBitsCount2};
686 int32_t iUsedBits = 0;
687 int32_t iIndexVlc, iIndexValue, iNcMapIdx;
688 uint32_t uiCount;
689 uint32_t uiValue;
690
691 if (bChromaDc) {
692 uiValue = pBitsCache->uiCache32Bit >> 24;
693 iIndexVlc = pVlcTable->kpChromaCoeffTokenVlcTable[uiValue][0];
694 uiCount = pVlcTable->kpChromaCoeffTokenVlcTable[uiValue][1];
695 POP_BUFFER (pBitsCache, uiCount);
696 iUsedBits += uiCount;
697 uiTrailingOnes = g_kuiVlcTrailingOneTotalCoeffTable[iIndexVlc][0];
698 uiTotalCoeff = g_kuiVlcTrailingOneTotalCoeffTable[iIndexVlc][1];
699 } else { //luma
700 iNcMapIdx = g_kuiNcMapTable[nC];
701 if (iNcMapIdx <= 2) {
702 uiValue = pBitsCache->uiCache32Bit >> 24;
703 if (uiValue < g_kuiVlcTableNeedMoreBitsThread[iNcMapIdx]) {
704 POP_BUFFER (pBitsCache, 8);
705 iUsedBits += 8;
706 iIndexValue = pBitsCache->uiCache32Bit >> (32 - kpVlcTableMoreBitsCountList[iNcMapIdx][uiValue]);
707 iIndexVlc = pVlcTable->kpCoeffTokenVlcTable[iNcMapIdx + 1][uiValue][iIndexValue][0];
708 uiCount = pVlcTable->kpCoeffTokenVlcTable[iNcMapIdx + 1][uiValue][iIndexValue][1];
709 POP_BUFFER (pBitsCache, uiCount);
710 iUsedBits += uiCount;
711 } else {
712 iIndexVlc = pVlcTable->kpCoeffTokenVlcTable[0][iNcMapIdx][uiValue][0];
713 uiCount = pVlcTable->kpCoeffTokenVlcTable[0][iNcMapIdx][uiValue][1];
714 uiValue = pBitsCache->uiCache32Bit >> (32 - uiCount);
715 POP_BUFFER (pBitsCache, uiCount);
716 iUsedBits += uiCount;
717 }
718 } else {
719 uiValue = pBitsCache->uiCache32Bit >> (32 - 6);
720 POP_BUFFER (pBitsCache, 6);
721 iUsedBits += 6;
722 iIndexVlc = pVlcTable->kpCoeffTokenVlcTable[0][3][uiValue][0]; //differ
723 }
724 uiTrailingOnes = g_kuiVlcTrailingOneTotalCoeffTable[iIndexVlc][0];
725 uiTotalCoeff = g_kuiVlcTrailingOneTotalCoeffTable[iIndexVlc][1];
726 }
727
728 return iUsedBits;
729 }
730
CavlcGetLevelVal(int32_t iLevel[16],SReadBitsCache * pBitsCache,uint8_t uiTotalCoeff,uint8_t uiTrailingOnes)731 static int32_t CavlcGetLevelVal (int32_t iLevel[16], SReadBitsCache* pBitsCache, uint8_t uiTotalCoeff,
732 uint8_t uiTrailingOnes) {
733 int32_t i, iUsedBits = 0;
734 int32_t iSuffixLength, iSuffixLengthSize, iLevelPrefix, iPrefixBits, iLevelCode, iThreshold;
735 for (i = 0; i < uiTrailingOnes; i++) {
736 iLevel[i] = 1 - ((pBitsCache->uiCache32Bit >> (30 - i)) & 0x02);
737 }
738 POP_BUFFER (pBitsCache, uiTrailingOnes);
739 iUsedBits += uiTrailingOnes;
740
741 iSuffixLength = (uiTotalCoeff > 10 && uiTrailingOnes < 3);
742
743 for (; i < uiTotalCoeff; i++) {
744 if (pBitsCache->uiRemainBits <= 16) SHIFT_BUFFER (pBitsCache);
745 WELS_GET_PREFIX_BITS (pBitsCache->uiCache32Bit, iPrefixBits);
746 if (iPrefixBits > MAX_LEVEL_PREFIX + 1) //iPrefixBits includes leading "0"s and first "1", should +1
747 return -1;
748 POP_BUFFER (pBitsCache, iPrefixBits);
749 iUsedBits += iPrefixBits;
750 iLevelPrefix = iPrefixBits - 1;
751
752 iLevelCode = iLevelPrefix << iSuffixLength; //differ
753 iSuffixLengthSize = iSuffixLength;
754
755 if (iLevelPrefix >= 14) {
756 if (14 == iLevelPrefix && 0 == iSuffixLength)
757 iSuffixLengthSize = 4;
758 else if (15 == iLevelPrefix) {
759 iSuffixLengthSize = 12;
760 if (iSuffixLength == 0)
761 iLevelCode += 15;
762 }
763 }
764
765 if (iSuffixLengthSize > 0) {
766 if (pBitsCache->uiRemainBits <= iSuffixLengthSize) SHIFT_BUFFER (pBitsCache);
767 iLevelCode += (pBitsCache->uiCache32Bit >> (32 - iSuffixLengthSize));
768 POP_BUFFER (pBitsCache, iSuffixLengthSize);
769 iUsedBits += iSuffixLengthSize;
770 }
771
772 iLevelCode += ((i == uiTrailingOnes) && (uiTrailingOnes < 3)) << 1;
773 iLevel[i] = ((iLevelCode + 2) >> 1);
774 iLevel[i] -= (iLevel[i] << 1) & (- (iLevelCode & 0x01));
775
776 iSuffixLength += !iSuffixLength;
777 iThreshold = 3 << (iSuffixLength - 1);
778 iSuffixLength += ((iLevel[i] > iThreshold) || (iLevel[i] < -iThreshold)) && (iSuffixLength < 6);
779 }
780
781 return iUsedBits;
782 }
783
CavlcGetTotalZeros(int32_t & iZerosLeft,SReadBitsCache * pBitsCache,uint8_t uiTotalCoeff,SVlcTable * pVlcTable,bool bChromaDc)784 static int32_t CavlcGetTotalZeros (int32_t& iZerosLeft, SReadBitsCache* pBitsCache, uint8_t uiTotalCoeff,
785 SVlcTable* pVlcTable, bool bChromaDc) {
786 int32_t iCount, iUsedBits = 0;
787 const uint8_t* kpBitNumMap;
788 uint32_t uiValue;
789
790 int32_t iTotalZeroVlcIdx;
791 uint8_t uiTableType;
792 //chroma_dc (0 < uiTotalCoeff < 4); others (chroma_ac or luma: 0 < uiTotalCoeff < 16)
793
794 if (bChromaDc) {
795 iTotalZeroVlcIdx = uiTotalCoeff;
796 kpBitNumMap = g_kuiTotalZerosBitNumChromaMap;
797 uiTableType = bChromaDc;
798 } else {
799 iTotalZeroVlcIdx = uiTotalCoeff;
800 kpBitNumMap = g_kuiTotalZerosBitNumMap;
801 uiTableType = 0;
802 }
803
804 iCount = kpBitNumMap[iTotalZeroVlcIdx - 1];
805 if (pBitsCache->uiRemainBits < iCount) SHIFT_BUFFER (
806 pBitsCache); // if uiRemainBits+16 still smaller than iCount?? potential bug
807 uiValue = pBitsCache->uiCache32Bit >> (32 - iCount);
808 iCount = pVlcTable->kpTotalZerosTable[uiTableType][iTotalZeroVlcIdx - 1][uiValue][1];
809 POP_BUFFER (pBitsCache, iCount);
810 iUsedBits += iCount;
811 iZerosLeft = pVlcTable->kpTotalZerosTable[uiTableType][iTotalZeroVlcIdx - 1][uiValue][0];
812
813 return iUsedBits;
814 }
CavlcGetRunBefore(int32_t iRun[16],SReadBitsCache * pBitsCache,uint8_t uiTotalCoeff,SVlcTable * pVlcTable,int32_t iZerosLeft)815 static int32_t CavlcGetRunBefore (int32_t iRun[16], SReadBitsCache* pBitsCache, uint8_t uiTotalCoeff,
816 SVlcTable* pVlcTable, int32_t iZerosLeft) {
817 int32_t i, iUsedBits = 0;
818 uint32_t uiCount, uiValue, iPrefixBits;
819
820 for (i = 0; i < uiTotalCoeff - 1; i++) {
821 if (iZerosLeft > 0) {
822 uiCount = g_kuiZeroLeftBitNumMap[iZerosLeft];
823 if (pBitsCache->uiRemainBits < uiCount) SHIFT_BUFFER (pBitsCache);
824 uiValue = pBitsCache->uiCache32Bit >> (32 - uiCount);
825 if (iZerosLeft < 7) {
826 uiCount = pVlcTable->kpZeroTable[iZerosLeft - 1][uiValue][1];
827 POP_BUFFER (pBitsCache, uiCount);
828 iUsedBits += uiCount;
829 iRun[i] = pVlcTable->kpZeroTable[iZerosLeft - 1][uiValue][0];
830 } else {
831 POP_BUFFER (pBitsCache, uiCount);
832 iUsedBits += uiCount;
833 if (pVlcTable->kpZeroTable[6][uiValue][0] < 7) {
834 iRun[i] = pVlcTable->kpZeroTable[6][uiValue][0];
835 } else {
836 if (pBitsCache->uiRemainBits < 16) SHIFT_BUFFER (pBitsCache);
837 WELS_GET_PREFIX_BITS (pBitsCache->uiCache32Bit, iPrefixBits);
838 iRun[i] = iPrefixBits + 6;
839 if (iRun[i] > iZerosLeft)
840 return -1;
841 POP_BUFFER (pBitsCache, iPrefixBits);
842 iUsedBits += iPrefixBits;
843 }
844 }
845 } else {
846 for (int j = i; j < uiTotalCoeff; j++) {
847 iRun[j] = 0;
848 }
849 return iUsedBits;
850 }
851
852 iZerosLeft -= iRun[i];
853 }
854
855 iRun[uiTotalCoeff - 1] = iZerosLeft;
856
857 return iUsedBits;
858 }
859
WelsResidualBlockCavlc(SVlcTable * pVlcTable,uint8_t * pNonZeroCountCache,PBitStringAux pBs,int32_t iIndex,int32_t iMaxNumCoeff,const uint8_t * kpZigzagTable,int32_t iResidualProperty,int16_t * pTCoeff,uint8_t uiQp,PWelsDecoderContext pCtx)860 int32_t WelsResidualBlockCavlc (SVlcTable* pVlcTable, uint8_t* pNonZeroCountCache, PBitStringAux pBs, int32_t iIndex,
861 int32_t iMaxNumCoeff,
862 const uint8_t* kpZigzagTable, int32_t iResidualProperty, int16_t* pTCoeff, uint8_t uiQp,
863 PWelsDecoderContext pCtx) {
864 int32_t iLevel[16], iZerosLeft, iCoeffNum;
865 int32_t iRun[16];
866 int32_t iCurNonZeroCacheIdx, i;
867
868
869 int32_t iMbResProperty = 0;
870 GetMbResProperty (&iMbResProperty, &iResidualProperty, 1);
871 const uint16_t* kpDequantCoeff = pCtx->bUseScalingList ? pCtx->pDequant_coeff4x4[iMbResProperty][uiQp] :
872 g_kuiDequantCoeff[uiQp];
873
874 int8_t nA, nB, nC;
875 uint8_t uiTotalCoeff, uiTrailingOnes;
876 int32_t iUsedBits = 0;
877 intX_t iCurIdx = pBs->iIndex;
878 uint8_t* pBuf = ((uint8_t*)pBs->pStartBuf) + (iCurIdx >> 3);
879 bool bChromaDc = (CHROMA_DC == iResidualProperty);
880 uint8_t bChroma = (bChromaDc || CHROMA_AC == iResidualProperty);
881 SReadBitsCache sReadBitsCache;
882
883 uint32_t uiCache32Bit = (uint32_t) ((((pBuf[0] << 8) | pBuf[1]) << 16) | (pBuf[2] << 8) | pBuf[3]);
884 sReadBitsCache.uiCache32Bit = uiCache32Bit << (iCurIdx & 0x07);
885 sReadBitsCache.uiRemainBits = 32 - (iCurIdx & 0x07);
886 sReadBitsCache.pBuf = pBuf;
887 //////////////////////////////////////////////////////////////////////////
888
889 if (bChroma) {
890 iCurNonZeroCacheIdx = g_kuiCache48CountScan4Idx[iIndex];
891 nA = pNonZeroCountCache[iCurNonZeroCacheIdx - 1];
892 nB = pNonZeroCountCache[iCurNonZeroCacheIdx - 8];
893 } else { //luma
894 iCurNonZeroCacheIdx = g_kuiCache48CountScan4Idx[iIndex];
895 nA = pNonZeroCountCache[iCurNonZeroCacheIdx - 1];
896 nB = pNonZeroCountCache[iCurNonZeroCacheIdx - 8];
897 }
898
899 WELS_NON_ZERO_COUNT_AVERAGE (nC, nA, nB);
900
901 iUsedBits += CavlcGetTrailingOnesAndTotalCoeff (uiTotalCoeff, uiTrailingOnes, &sReadBitsCache, pVlcTable, bChromaDc,
902 nC);
903
904 if (iResidualProperty != CHROMA_DC && iResidualProperty != I16_LUMA_DC) {
905 pNonZeroCountCache[iCurNonZeroCacheIdx] = uiTotalCoeff;
906 //////////////////////////////////////////////////////////////////////////
907 }
908 if (0 == uiTotalCoeff) {
909 pBs->iIndex += iUsedBits;
910 return ERR_NONE;
911 }
912 if ((uiTrailingOnes > 3) || (uiTotalCoeff > 16)) { /////////////////check uiTrailingOnes and uiTotalCoeff
913 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_CAVLC_INVALID_TOTAL_COEFF_OR_TRAILING_ONES);
914 }
915 if ((i = CavlcGetLevelVal (iLevel, &sReadBitsCache, uiTotalCoeff, uiTrailingOnes)) == -1) {
916 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_CAVLC_INVALID_LEVEL);
917 }
918 iUsedBits += i;
919 if (uiTotalCoeff < iMaxNumCoeff) {
920 iUsedBits += CavlcGetTotalZeros (iZerosLeft, &sReadBitsCache, uiTotalCoeff, pVlcTable, bChromaDc);
921 } else {
922 iZerosLeft = 0;
923 }
924
925 if ((iZerosLeft < 0) || ((iZerosLeft + uiTotalCoeff) > iMaxNumCoeff)) {
926 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_CAVLC_INVALID_ZERO_LEFT);
927 }
928 if ((i = CavlcGetRunBefore (iRun, &sReadBitsCache, uiTotalCoeff, pVlcTable, iZerosLeft)) == -1) {
929 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_CAVLC_INVALID_RUN_BEFORE);
930 }
931 iUsedBits += i;
932 pBs->iIndex += iUsedBits;
933 iCoeffNum = -1;
934
935 if (iResidualProperty == CHROMA_DC) {
936 //chroma dc scaling process, is kpDequantCoeff[0]? LevelScale(qPdc%6,0,0))<<(qPdc/6-6), the transform is done at construction.
937 for (i = uiTotalCoeff - 1; i >= 0; --i) {
938 //FIXME merge into rundecode?
939 int32_t j;
940 iCoeffNum += iRun[i] + 1; //FIXME add 1 earlier ?
941 j = kpZigzagTable[ iCoeffNum ];
942 pTCoeff[j] = iLevel[i];
943 }
944 WelsChromaDcIdct (pTCoeff);
945 //scaling
946 if (!pCtx->bUseScalingList) {
947 for (int j = 0; j < 4; ++j) {
948 pTCoeff[kpZigzagTable[j]] = (pTCoeff[kpZigzagTable[j]] * kpDequantCoeff[0]) >> 1;
949 }
950 } else {
951 for (int j = 0; j < 4; ++j) {
952 pTCoeff[kpZigzagTable[j]] = ((int64_t) pTCoeff[kpZigzagTable[j]] * (int64_t) kpDequantCoeff[0]) >> 5;
953 }
954 }
955 } else if (iResidualProperty == I16_LUMA_DC) { //DC coefficent, only call in Intra_16x16, base_mode_flag = 0
956 for (i = uiTotalCoeff - 1; i >= 0; --i) { //FIXME merge into rundecode?
957 int32_t j;
958 iCoeffNum += iRun[i] + 1; //FIXME add 1 earlier ?
959 j = kpZigzagTable[ iCoeffNum ];
960 pTCoeff[j] = iLevel[i];
961 }
962 WelsLumaDcDequantIdct (pTCoeff, uiQp, pCtx);
963 } else {
964 for (i = uiTotalCoeff - 1; i >= 0; --i) { //FIXME merge into rundecode?
965 int32_t j;
966 iCoeffNum += iRun[i] + 1; //FIXME add 1 earlier ?
967 j = kpZigzagTable[ iCoeffNum ];
968 if (!pCtx->bUseScalingList) {
969 pTCoeff[j] = (iLevel[i] * kpDequantCoeff[j & 0x07]);
970 } else {
971 pTCoeff[j] = (iLevel[i] * kpDequantCoeff[j] + 8) >> 4;
972 }
973 }
974 }
975
976 return ERR_NONE;
977 }
978
WelsResidualBlockCavlc8x8(SVlcTable * pVlcTable,uint8_t * pNonZeroCountCache,PBitStringAux pBs,int32_t iIndex,int32_t iMaxNumCoeff,const uint8_t * kpZigzagTable,int32_t iResidualProperty,int16_t * pTCoeff,int32_t iIdx4x4,uint8_t uiQp,PWelsDecoderContext pCtx)979 int32_t WelsResidualBlockCavlc8x8 (SVlcTable* pVlcTable, uint8_t* pNonZeroCountCache, PBitStringAux pBs, int32_t iIndex,
980 int32_t iMaxNumCoeff, const uint8_t* kpZigzagTable, int32_t iResidualProperty,
981 int16_t* pTCoeff, int32_t iIdx4x4, uint8_t uiQp,
982 PWelsDecoderContext pCtx) {
983 int32_t iLevel[16], iZerosLeft, iCoeffNum;
984 int32_t iRun[16];
985 int32_t iCurNonZeroCacheIdx, i;
986
987 int32_t iMbResProperty = 0;
988 GetMbResProperty (&iMbResProperty, &iResidualProperty, 1);
989
990 const uint16_t* kpDequantCoeff = pCtx->bUseScalingList ? pCtx->pDequant_coeff8x8[iMbResProperty - 6][uiQp] :
991 g_kuiDequantCoeff8x8[uiQp];
992
993 int8_t nA, nB, nC;
994 uint8_t uiTotalCoeff, uiTrailingOnes;
995 int32_t iUsedBits = 0;
996 intX_t iCurIdx = pBs->iIndex;
997 uint8_t* pBuf = ((uint8_t*)pBs->pStartBuf) + (iCurIdx >> 3);
998 bool bChromaDc = (CHROMA_DC == iResidualProperty);
999 uint8_t bChroma = (bChromaDc || CHROMA_AC == iResidualProperty);
1000 SReadBitsCache sReadBitsCache;
1001
1002 uint32_t uiCache32Bit = (uint32_t) ((((pBuf[0] << 8) | pBuf[1]) << 16) | (pBuf[2] << 8) | pBuf[3]);
1003 sReadBitsCache.uiCache32Bit = uiCache32Bit << (iCurIdx & 0x07);
1004 sReadBitsCache.uiRemainBits = 32 - (iCurIdx & 0x07);
1005 sReadBitsCache.pBuf = pBuf;
1006 //////////////////////////////////////////////////////////////////////////
1007
1008 if (bChroma) {
1009 iCurNonZeroCacheIdx = g_kuiCache48CountScan4Idx[iIndex];
1010 nA = pNonZeroCountCache[iCurNonZeroCacheIdx - 1];
1011 nB = pNonZeroCountCache[iCurNonZeroCacheIdx - 8];
1012 } else { //luma
1013 iCurNonZeroCacheIdx = g_kuiCache48CountScan4Idx[iIndex];
1014 nA = pNonZeroCountCache[iCurNonZeroCacheIdx - 1];
1015 nB = pNonZeroCountCache[iCurNonZeroCacheIdx - 8];
1016 }
1017
1018 WELS_NON_ZERO_COUNT_AVERAGE (nC, nA, nB);
1019
1020 iUsedBits += CavlcGetTrailingOnesAndTotalCoeff (uiTotalCoeff, uiTrailingOnes, &sReadBitsCache, pVlcTable, bChromaDc,
1021 nC);
1022
1023 if (iResidualProperty != CHROMA_DC && iResidualProperty != I16_LUMA_DC) {
1024 pNonZeroCountCache[iCurNonZeroCacheIdx] = uiTotalCoeff;
1025 //////////////////////////////////////////////////////////////////////////
1026 }
1027 if (0 == uiTotalCoeff) {
1028 pBs->iIndex += iUsedBits;
1029 return ERR_NONE;
1030 }
1031 if ((uiTrailingOnes > 3) || (uiTotalCoeff > 16)) { /////////////////check uiTrailingOnes and uiTotalCoeff
1032 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_CAVLC_INVALID_TOTAL_COEFF_OR_TRAILING_ONES);
1033 }
1034 if ((i = CavlcGetLevelVal (iLevel, &sReadBitsCache, uiTotalCoeff, uiTrailingOnes)) == -1) {
1035 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_CAVLC_INVALID_LEVEL);
1036 }
1037 iUsedBits += i;
1038 if (uiTotalCoeff < iMaxNumCoeff) {
1039 iUsedBits += CavlcGetTotalZeros (iZerosLeft, &sReadBitsCache, uiTotalCoeff, pVlcTable, bChromaDc);
1040 } else {
1041 iZerosLeft = 0;
1042 }
1043
1044 if ((iZerosLeft < 0) || ((iZerosLeft + uiTotalCoeff) > iMaxNumCoeff)) {
1045 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_CAVLC_INVALID_ZERO_LEFT);
1046 }
1047 if ((i = CavlcGetRunBefore (iRun, &sReadBitsCache, uiTotalCoeff, pVlcTable, iZerosLeft)) == -1) {
1048 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_CAVLC_INVALID_RUN_BEFORE);
1049 }
1050 iUsedBits += i;
1051 pBs->iIndex += iUsedBits;
1052 iCoeffNum = -1;
1053
1054 for (i = uiTotalCoeff - 1; i >= 0; --i) { //FIXME merge into rundecode?
1055 int32_t j;
1056 iCoeffNum += iRun[i] + 1; //FIXME add 1 earlier ?
1057 j = (iCoeffNum << 2) + iIdx4x4;
1058 j = kpZigzagTable[ j ];
1059 pTCoeff[j] = uiQp >= 36 ? ((iLevel[i] * kpDequantCoeff[j]) * (1 << (uiQp / 6 - 6)))
1060 : ((iLevel[i] * kpDequantCoeff[j] + (1 << (5 - uiQp / 6))) >> (6 - uiQp / 6));
1061 }
1062
1063 return ERR_NONE;
1064 }
1065
ParseInterInfo(PWelsDecoderContext pCtx,int16_t iMvArray[LIST_A][30][MV_A],int8_t iRefIdxArray[LIST_A][30],PBitStringAux pBs)1066 int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][MV_A], int8_t iRefIdxArray[LIST_A][30],
1067 PBitStringAux pBs) {
1068 PSlice pSlice = &pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer;
1069 PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
1070 PPicture* ppRefPic = pCtx->sRefPic.pRefList[LIST_0];
1071 int32_t iRefCount[2];
1072 PDqLayer pCurDqLayer = pCtx->pCurDqLayer;
1073 int32_t i, j;
1074 int32_t iMbXy = pCurDqLayer->iMbXyIndex;
1075 int32_t iMotionPredFlag[4];
1076 int16_t iMv[2];
1077 uint32_t uiCode;
1078 int32_t iCode;
1079 int16_t iMinVmv = pSliceHeader->pSps->pSLevelLimits->iMinVmv;
1080 int16_t iMaxVmv = pSliceHeader->pSps->pSLevelLimits->iMaxVmv;
1081 iMotionPredFlag[0] = iMotionPredFlag[1] = iMotionPredFlag[2] = iMotionPredFlag[3] =
1082 pSlice->sSliceHeaderExt.bDefaultMotionPredFlag;
1083 iRefCount[0] = pSliceHeader->uiRefCount[0];
1084 iRefCount[1] = pSliceHeader->uiRefCount[1];
1085
1086 bool bIsPending = GetThreadCount (pCtx) > 1;
1087
1088 switch (pCurDqLayer->pDec->pMbType[iMbXy]) {
1089 case MB_TYPE_16x16: {
1090 int32_t iRefIdx = 0;
1091 if (pSlice->sSliceHeaderExt.bAdaptiveMotionPredFlag) {
1092 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //motion_prediction_flag_l0[ mbPartIdx ]
1093 iMotionPredFlag[0] = uiCode;
1094 }
1095 if (iMotionPredFlag[0] == 0) {
1096 WELS_READ_VERIFY (BsGetTe0 (pBs, iRefCount[0], &uiCode)); //motion_prediction_flag_l1[ mbPartIdx ]
1097 iRefIdx = uiCode;
1098 // Security check: iRefIdx should be in range 0 to num_ref_idx_l0_active_minus1, includsive
1099 // ref to standard section 7.4.5.1. iRefCount[0] is 1 + num_ref_idx_l0_active_minus1.
1100 if ((iRefIdx < 0) || (iRefIdx >= iRefCount[0]) || (ppRefPic[iRefIdx] == NULL)) { //error ref_idx
1101 pCtx->bMbRefConcealed = true;
1102 if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
1103 iRefIdx = 0;
1104 pCtx->iErrorCode |= dsBitstreamError;
1105 } else {
1106 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_REF_INDEX);
1107 }
1108 }
1109 pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (ppRefPic[iRefIdx]
1110 && (ppRefPic[iRefIdx]->bIsComplete || bIsPending));
1111 } else {
1112 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "inter parse: iMotionPredFlag = 1 not supported. ");
1113 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_UNSUPPORTED_ILP);
1114 }
1115 PredMv (iMvArray, iRefIdxArray, LIST_0, 0, 4, iRefIdx, iMv);
1116
1117 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l0[ mbPartIdx ][ 0 ][ compIdx ]
1118 iMv[0] += iCode;
1119 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l1[ mbPartIdx ][ 0 ][ compIdx ]
1120 iMv[1] += iCode;
1121 WELS_CHECK_SE_BOTH_WARNING (iMv[1], iMinVmv, iMaxVmv, "vertical mv");
1122 UpdateP16x16MotionInfo (pCurDqLayer, LIST_0, iRefIdx, iMv);
1123 }
1124 break;
1125 case MB_TYPE_16x8: {
1126 int32_t iRefIdx[2];
1127 for (i = 0; i < 2; i++) {
1128 if (pSlice->sSliceHeaderExt.bAdaptiveMotionPredFlag) {
1129 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //motion_prediction_flag_l0[ mbPartIdx ]
1130 iMotionPredFlag[i] = uiCode;
1131 }
1132 }
1133
1134 for (i = 0; i < 2; i++) {
1135 if (iMotionPredFlag[i]) {
1136 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "inter parse: iMotionPredFlag = 1 not supported. ");
1137 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_UNSUPPORTED_ILP);
1138 }
1139 WELS_READ_VERIFY (BsGetTe0 (pBs, iRefCount[0], &uiCode)); //ref_idx_l0[ mbPartIdx ]
1140 iRefIdx[i] = uiCode;
1141 if ((iRefIdx[i] < 0) || (iRefIdx[i] >= iRefCount[0]) || (ppRefPic[iRefIdx[i]] == NULL)) { //error ref_idx
1142 pCtx->bMbRefConcealed = true;
1143 if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
1144 iRefIdx[i] = 0;
1145 pCtx->iErrorCode |= dsBitstreamError;
1146 } else {
1147 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_REF_INDEX);
1148 }
1149 }
1150 pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (ppRefPic[iRefIdx[i]]
1151 && (ppRefPic[iRefIdx[i]]->bIsComplete || bIsPending));
1152 }
1153 for (i = 0; i < 2; i++) {
1154 PredInter16x8Mv (iMvArray, iRefIdxArray, LIST_0, i << 3, iRefIdx[i], iMv);
1155
1156 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l0[ mbPartIdx ][ 0 ][ compIdx ]
1157 iMv[0] += iCode;
1158 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l1[ mbPartIdx ][ 0 ][ compIdx ]
1159 iMv[1] += iCode;
1160 WELS_CHECK_SE_BOTH_WARNING (iMv[1], iMinVmv, iMaxVmv, "vertical mv");
1161 UpdateP16x8MotionInfo (pCurDqLayer, iMvArray, iRefIdxArray, LIST_0, i << 3, iRefIdx[i], iMv);
1162 }
1163 }
1164 break;
1165 case MB_TYPE_8x16: {
1166 int32_t iRefIdx[2];
1167 for (i = 0; i < 2; i++) {
1168 if (pSlice->sSliceHeaderExt.bAdaptiveMotionPredFlag) {
1169 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //motion_prediction_flag_l0[ mbPartIdx ]
1170 iMotionPredFlag[i] = uiCode;
1171 }
1172 }
1173
1174 for (i = 0; i < 2; i++) {
1175 if (iMotionPredFlag[i] == 0) {
1176 WELS_READ_VERIFY (BsGetTe0 (pBs, iRefCount[0], &uiCode)); //ref_idx_l0[ mbPartIdx ]
1177 iRefIdx[i] = uiCode;
1178 if ((iRefIdx[i] < 0) || (iRefIdx[i] >= iRefCount[0]) || (ppRefPic[iRefIdx[i]] == NULL)) { //error ref_idx
1179 pCtx->bMbRefConcealed = true;
1180 if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
1181 iRefIdx[i] = 0;
1182 pCtx->iErrorCode |= dsBitstreamError;
1183 } else {
1184 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_REF_INDEX);
1185 }
1186 }
1187 pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (ppRefPic[iRefIdx[i]]
1188 && (ppRefPic[iRefIdx[i]]->bIsComplete || bIsPending));
1189 } else {
1190 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "inter parse: iMotionPredFlag = 1 not supported. ");
1191 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_UNSUPPORTED_ILP);
1192 }
1193
1194 }
1195 for (i = 0; i < 2; i++) {
1196 PredInter8x16Mv (iMvArray, iRefIdxArray, LIST_0, i << 2, iRefIdx[i], iMv);
1197
1198 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l0[ mbPartIdx ][ 0 ][ compIdx ]
1199 iMv[0] += iCode;
1200 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l1[ mbPartIdx ][ 0 ][ compIdx ]
1201 iMv[1] += iCode;
1202 WELS_CHECK_SE_BOTH_WARNING (iMv[1], iMinVmv, iMaxVmv, "vertical mv");
1203 UpdateP8x16MotionInfo (pCurDqLayer, iMvArray, iRefIdxArray, LIST_0, i << 2, iRefIdx[i], iMv);
1204 }
1205 }
1206 break;
1207 case MB_TYPE_8x8:
1208 case MB_TYPE_8x8_REF0: {
1209 int32_t iRefIdx[4] = {0}, iSubPartCount[4], iPartWidth[4];
1210 uint32_t uiSubMbType;
1211
1212 if (MB_TYPE_8x8_REF0 == pCurDqLayer->pDec->pMbType[iMbXy]) {
1213 iRefCount[0] =
1214 iRefCount[1] = 1;
1215 }
1216
1217 //uiSubMbType, partition
1218 for (i = 0; i < 4; i++) {
1219 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //sub_mb_type[ mbPartIdx ]
1220 uiSubMbType = uiCode;
1221 if (uiSubMbType >= 4) { //invalid uiSubMbType
1222 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_SUB_MB_TYPE);
1223 }
1224 pCurDqLayer->pSubMbType[iMbXy][i] = g_ksInterPSubMbTypeInfo[uiSubMbType].iType;
1225 iSubPartCount[i] = g_ksInterPSubMbTypeInfo[uiSubMbType].iPartCount;
1226 iPartWidth[i] = g_ksInterPSubMbTypeInfo[uiSubMbType].iPartWidth;
1227
1228 // Need modification when B picture add in, reference to 7.3.5
1229 pCurDqLayer->pNoSubMbPartSizeLessThan8x8Flag[iMbXy] &= (uiSubMbType == 0);
1230 }
1231
1232 if (pSlice->sSliceHeaderExt.bAdaptiveMotionPredFlag) {
1233 for (i = 0; i < 4; i++) {
1234 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //motion_prediction_flag_l0[ mbPartIdx ]
1235 iMotionPredFlag[i] = uiCode;
1236 }
1237 }
1238
1239 //iRefIdxArray
1240 if (MB_TYPE_8x8_REF0 == pCurDqLayer->pDec->pMbType[iMbXy]) {
1241 memset (pCurDqLayer->pDec->pRefIndex[0][iMbXy], 0, 16);
1242 } else {
1243 for (i = 0; i < 4; i++) {
1244 int16_t iIndex8 = i << 2;
1245 uint8_t uiScan4Idx = g_kuiScan4[iIndex8];
1246
1247 if (iMotionPredFlag[i] == 0) {
1248 WELS_READ_VERIFY (BsGetTe0 (pBs, iRefCount[0], &uiCode)); //ref_idx_l0[ mbPartIdx ]
1249 iRefIdx[i] = uiCode;
1250 if ((iRefIdx[i] < 0) || (iRefIdx[i] >= iRefCount[0]) || (ppRefPic[iRefIdx[i]] == NULL)) { //error ref_idx
1251 pCtx->bMbRefConcealed = true;
1252 if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
1253 iRefIdx[i] = 0;
1254 pCtx->iErrorCode |= dsBitstreamError;
1255 } else {
1256 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_REF_INDEX);
1257 }
1258 }
1259 pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (ppRefPic[iRefIdx[i]]
1260 && (ppRefPic[iRefIdx[i]]->bIsComplete || bIsPending));
1261
1262 pCurDqLayer->pDec->pRefIndex[0][iMbXy][uiScan4Idx ] = pCurDqLayer->pDec->pRefIndex[0][iMbXy][uiScan4Idx + 1] =
1263 pCurDqLayer->pDec->pRefIndex[0][iMbXy][uiScan4Idx + 4] = pCurDqLayer->pDec->pRefIndex[0][iMbXy][uiScan4Idx + 5] =
1264 iRefIdx[i];
1265 } else {
1266 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "inter parse: iMotionPredFlag = 1 not supported. ");
1267 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_UNSUPPORTED_ILP);
1268 }
1269 }
1270 }
1271
1272 //gain mv and update mv cache
1273 for (i = 0; i < 4; i++) {
1274 int8_t iPartCount = iSubPartCount[i];
1275 uint32_t uiSubMbType = pCurDqLayer->pSubMbType[iMbXy][i];
1276 int16_t iMv[2], iPartIdx, iBlockWidth = iPartWidth[i], iIdx = i << 2;
1277 uint8_t uiScan4Idx, uiCacheIdx;
1278
1279 uint8_t uiIdx4Cache = g_kuiCache30ScanIdx[iIdx];
1280
1281 iRefIdxArray[0][uiIdx4Cache ] = iRefIdxArray[0][uiIdx4Cache + 1] =
1282 iRefIdxArray[0][uiIdx4Cache + 6] = iRefIdxArray[0][uiIdx4Cache + 7] = iRefIdx[i];
1283
1284 for (j = 0; j < iPartCount; j++) {
1285 iPartIdx = iIdx + j * iBlockWidth;
1286 uiScan4Idx = g_kuiScan4[iPartIdx];
1287 uiCacheIdx = g_kuiCache30ScanIdx[iPartIdx];
1288 PredMv (iMvArray, iRefIdxArray, LIST_0, iPartIdx, iBlockWidth, iRefIdx[i], iMv);
1289
1290 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l0[ mbPartIdx ][ subMbPartIdx ][ compIdx ]
1291 iMv[0] += iCode;
1292 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l1[ mbPartIdx ][ subMbPartIdx ][ compIdx ]
1293 iMv[1] += iCode;
1294 WELS_CHECK_SE_BOTH_WARNING (iMv[1], iMinVmv, iMaxVmv, "vertical mv");
1295 if (SUB_MB_TYPE_8x8 == uiSubMbType) {
1296 ST32 (pCurDqLayer->pDec->pMv[0][iMbXy][uiScan4Idx], LD32 (iMv));
1297 ST32 (pCurDqLayer->pDec->pMv[0][iMbXy][uiScan4Idx + 1], LD32 (iMv));
1298 ST32 (pCurDqLayer->pDec->pMv[0][iMbXy][uiScan4Idx + 4], LD32 (iMv));
1299 ST32 (pCurDqLayer->pDec->pMv[0][iMbXy][uiScan4Idx + 5], LD32 (iMv));
1300 ST32 (iMvArray[0][uiCacheIdx ], LD32 (iMv));
1301 ST32 (iMvArray[0][uiCacheIdx + 1], LD32 (iMv));
1302 ST32 (iMvArray[0][uiCacheIdx + 6], LD32 (iMv));
1303 ST32 (iMvArray[0][uiCacheIdx + 7], LD32 (iMv));
1304 } else if (SUB_MB_TYPE_8x4 == uiSubMbType) {
1305 ST32 (pCurDqLayer->pDec->pMv[0][iMbXy][uiScan4Idx ], LD32 (iMv));
1306 ST32 (pCurDqLayer->pDec->pMv[0][iMbXy][uiScan4Idx + 1], LD32 (iMv));
1307 ST32 (iMvArray[0][uiCacheIdx ], LD32 (iMv));
1308 ST32 (iMvArray[0][uiCacheIdx + 1], LD32 (iMv));
1309 } else if (SUB_MB_TYPE_4x8 == uiSubMbType) {
1310 ST32 (pCurDqLayer->pDec->pMv[0][iMbXy][uiScan4Idx ], LD32 (iMv));
1311 ST32 (pCurDqLayer->pDec->pMv[0][iMbXy][uiScan4Idx + 4], LD32 (iMv));
1312 ST32 (iMvArray[0][uiCacheIdx ], LD32 (iMv));
1313 ST32 (iMvArray[0][uiCacheIdx + 6], LD32 (iMv));
1314 } else { //SUB_MB_TYPE_4x4 == uiSubMbType
1315 ST32 (pCurDqLayer->pDec->pMv[0][iMbXy][uiScan4Idx ], LD32 (iMv));
1316 ST32 (iMvArray[0][uiCacheIdx ], LD32 (iMv));
1317 }
1318 }
1319 }
1320 }
1321 break;
1322 default:
1323 break;
1324 }
1325
1326 return ERR_NONE;
1327 }
ParseInterBInfo(PWelsDecoderContext pCtx,int16_t iMvArray[LIST_A][30][MV_A],int8_t iRefIdxArray[LIST_A][30],PBitStringAux pBs)1328 int32_t ParseInterBInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][MV_A],
1329 int8_t iRefIdxArray[LIST_A][30], PBitStringAux pBs) {
1330 PSlice pSlice = &pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer;
1331 PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
1332 PPicture* ppRefPic[2];
1333 ppRefPic[LIST_0] = pCtx->sRefPic.pRefList[LIST_0];
1334 ppRefPic[LIST_1] = pCtx->sRefPic.pRefList[LIST_1];
1335 int8_t ref_idx_list[LIST_A][4];
1336 int8_t iRef[2] = { 0, 0 };
1337 int32_t iRefCount[2];
1338 PDqLayer pCurDqLayer = pCtx->pCurDqLayer;
1339 int32_t iMbXy = pCurDqLayer->iMbXyIndex;
1340 uint8_t iMotionPredFlag[LIST_A][4];
1341 int16_t iMv[2];
1342 uint32_t uiCode;
1343 int32_t iCode;
1344 int16_t iMinVmv = pSliceHeader->pSps->pSLevelLimits->iMinVmv;
1345 int16_t iMaxVmv = pSliceHeader->pSps->pSLevelLimits->iMaxVmv;
1346 memset (ref_idx_list, -1, LIST_A * 4);
1347 memset (iMotionPredFlag, (pSlice->sSliceHeaderExt.bDefaultMotionPredFlag ? 1 : 0), LIST_A * 4);
1348 iRefCount[0] = pSliceHeader->uiRefCount[0];
1349 iRefCount[1] = pSliceHeader->uiRefCount[1];
1350
1351 bool bIsPending = GetThreadCount (pCtx) > 1;
1352
1353 MbType mbType = pCurDqLayer->pDec->pMbType[iMbXy];
1354 if (IS_DIRECT (mbType)) {
1355
1356 int16_t pMvDirect[LIST_A][2] = { { 0, 0 }, { 0, 0 } };
1357 SubMbType subMbType;
1358 if (pSliceHeader->iDirectSpatialMvPredFlag) {
1359 //predict direct spatial mv
1360 int32_t ret = PredMvBDirectSpatial (pCtx, pMvDirect, iRef, subMbType);
1361 if (ret != ERR_NONE) {
1362 return ret;
1363 }
1364 } else {
1365 //temporal direct 16x16 mode
1366 int32_t ret = PredBDirectTemporal (pCtx, pMvDirect, iRef, subMbType);
1367 if (ret != ERR_NONE) {
1368 return ret;
1369 }
1370 }
1371 } else if (IS_INTER_16x16 (mbType)) {
1372 if (pSlice->sSliceHeaderExt.bAdaptiveMotionPredFlag) {
1373 for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
1374 if (IS_DIR (mbType, 0, listIdx)) {
1375 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //motion_prediction_flag_l0/l1[ mbPartIdx ]
1376 iMotionPredFlag[listIdx][0] = uiCode;
1377 }
1378 }
1379 }
1380 for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
1381 if (IS_DIR (mbType, 0, listIdx)) {
1382 if (iMotionPredFlag[listIdx][0] == 0) {
1383 WELS_READ_VERIFY (BsGetTe0 (pBs, iRefCount[listIdx], &uiCode)); //motion_prediction_flag_l1[ mbPartIdx ]
1384 ref_idx_list[listIdx][0] = uiCode;
1385 // Security check: iRefIdx should be in range 0 to num_ref_idx_l0_active_minus1, includsive
1386 // ref to standard section 7.4.5.1. iRefCount[0] is 1 + num_ref_idx_l0_active_minus1.
1387 if ((ref_idx_list[listIdx][0] < 0) || (ref_idx_list[listIdx][0] >= iRefCount[listIdx])
1388 || (ppRefPic[listIdx][ref_idx_list[listIdx][0]] == NULL)) { //error ref_idx
1389 pCtx->bMbRefConcealed = true;
1390 if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
1391 ref_idx_list[listIdx][0] = 0;
1392 pCtx->iErrorCode |= dsBitstreamError;
1393 RETURN_ERR_IF_NULL(ppRefPic[listIdx][ref_idx_list[listIdx][0]]);
1394 } else {
1395 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_REF_INDEX);
1396 }
1397 }
1398 pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (ppRefPic[listIdx][ref_idx_list[listIdx][0]]
1399 && (ppRefPic[listIdx][ref_idx_list[listIdx][0]]->bIsComplete || bIsPending));
1400 } else {
1401 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "inter parse: iMotionPredFlag = 1 not supported. ");
1402 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_UNSUPPORTED_ILP);
1403 }
1404 }
1405 }
1406 for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
1407 if (IS_DIR (mbType, 0, listIdx)) {
1408 PredMv (iMvArray, iRefIdxArray, listIdx, 0, 4, ref_idx_list[listIdx][0], iMv);
1409 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l0[ mbPartIdx ][ 0 ][ compIdx ]
1410 iMv[0] += iCode;
1411 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l1[ mbPartIdx ][ 0 ][ compIdx ]
1412 iMv[1] += iCode;
1413 WELS_CHECK_SE_BOTH_WARNING (iMv[1], iMinVmv, iMaxVmv, "vertical mv");
1414 } else {
1415 * (uint32_t*)iMv = 0;
1416 }
1417 UpdateP16x16MotionInfo (pCurDqLayer, listIdx, ref_idx_list[listIdx][0], iMv);
1418 }
1419 } else if (IS_INTER_16x8 (mbType)) {
1420 if (pSlice->sSliceHeaderExt.bAdaptiveMotionPredFlag) {
1421 for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
1422 for (int32_t i = 0; i < 2; ++i) {
1423 if (IS_DIR (mbType, i, listIdx)) {
1424 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //motion_prediction_flag_l0/l1[ mbPartIdx ]
1425 iMotionPredFlag[listIdx][i] = uiCode;
1426 }
1427 }
1428 }
1429 }
1430 for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
1431 for (int32_t i = 0; i < 2; ++i) {
1432 if (IS_DIR (mbType, i, listIdx)) {
1433 if (iMotionPredFlag[listIdx][i] == 0) {
1434 WELS_READ_VERIFY (BsGetTe0 (pBs, iRefCount[listIdx], &uiCode)); //motion_prediction_flag_l1[ mbPartIdx ]
1435 int32_t iRefIdx = uiCode;
1436 // Security check: iRefIdx should be in range 0 to num_ref_idx_l0_active_minus1, includsive
1437 // ref to standard section 7.4.5.1. iRefCount[0] is 1 + num_ref_idx_l0_active_minus1.
1438 if ((iRefIdx < 0) || (iRefIdx >= iRefCount[listIdx]) || (ppRefPic[listIdx][iRefIdx] == NULL)) { //error ref_idx
1439 pCtx->bMbRefConcealed = true;
1440 if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
1441 iRefIdx = 0;
1442 pCtx->iErrorCode |= dsBitstreamError;
1443 RETURN_ERR_IF_NULL(ppRefPic[listIdx][iRefIdx]);
1444 } else {
1445 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_REF_INDEX);
1446 }
1447 }
1448 ref_idx_list[listIdx][i] = iRefIdx;
1449 pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (ppRefPic[listIdx][iRefIdx]
1450 && (ppRefPic[listIdx][iRefIdx]->bIsComplete || bIsPending));
1451 } else {
1452 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "inter parse: iMotionPredFlag = 1 not supported. ");
1453 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_UNSUPPORTED_ILP);
1454 }
1455 }
1456 }
1457 }
1458 // Read mvd_L0 then mvd_L1
1459 for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
1460 // Partitions
1461 for (int32_t i = 0; i < 2; i++) {
1462 int iPartIdx = i << 3;
1463 int32_t iRefIdx = ref_idx_list[listIdx][i];
1464 if (IS_DIR (mbType, i, listIdx)) {
1465 PredInter16x8Mv (iMvArray, iRefIdxArray, listIdx, iPartIdx, iRefIdx, iMv);
1466
1467 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l{0,1}[ mbPartIdx ][ listIdx ][x]
1468 iMv[0] += iCode;
1469 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l{0,1}[ mbPartIdx ][ listIdx ][y]
1470 iMv[1] += iCode;
1471
1472 WELS_CHECK_SE_BOTH_WARNING (iMv[1], iMinVmv, iMaxVmv, "vertical mv");
1473 } else {
1474 * (uint32_t*)iMv = 0;
1475 }
1476 UpdateP16x8MotionInfo (pCurDqLayer, iMvArray, iRefIdxArray, listIdx, iPartIdx, iRefIdx, iMv);
1477 }
1478 }
1479 } else if (IS_INTER_8x16 (mbType)) {
1480 if (pSlice->sSliceHeaderExt.bAdaptiveMotionPredFlag) {
1481 for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
1482 for (int32_t i = 0; i < 2; ++i) {
1483 if (IS_DIR (mbType, i, listIdx)) {
1484 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //motion_prediction_flag_l0/l1[ mbPartIdx ]
1485 iMotionPredFlag[listIdx][i] = uiCode;
1486 }
1487 }
1488 }
1489 }
1490 for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
1491 for (int32_t i = 0; i < 2; ++i) {
1492 if (IS_DIR (mbType, i, listIdx)) {
1493 if (iMotionPredFlag[listIdx][i] == 0) {
1494 WELS_READ_VERIFY (BsGetTe0 (pBs, iRefCount[listIdx], &uiCode)); //motion_prediction_flag_l1[ mbPartIdx ]
1495 int32_t iRefIdx = uiCode;
1496 // Security check: iRefIdx should be in range 0 to num_ref_idx_l0_active_minus1, includsive
1497 // ref to standard section 7.4.5.1. iRefCount[0] is 1 + num_ref_idx_l0_active_minus1.
1498 if ((iRefIdx < 0) || (iRefIdx >= iRefCount[listIdx]) || (ppRefPic[listIdx][iRefIdx] == NULL)) { //error ref_idx
1499 pCtx->bMbRefConcealed = true;
1500 if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
1501 iRefIdx = 0;
1502 pCtx->iErrorCode |= dsBitstreamError;
1503 RETURN_ERR_IF_NULL(ppRefPic[listIdx][iRefIdx]);
1504 } else {
1505 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_REF_INDEX);
1506 }
1507 }
1508 ref_idx_list[listIdx][i] = iRefIdx;
1509 pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (ppRefPic[listIdx][iRefIdx]
1510 && (ppRefPic[listIdx][iRefIdx]->bIsComplete || bIsPending));
1511 } else {
1512 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "inter parse: iMotionPredFlag = 1 not supported. ");
1513 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_UNSUPPORTED_ILP);
1514 }
1515 }
1516 }
1517 }
1518 for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
1519 for (int32_t i = 0; i < 2; i++) {
1520 int iPartIdx = i << 2;
1521 int32_t iRefIdx = ref_idx_list[listIdx][i];
1522 if (IS_DIR (mbType, i, listIdx)) {
1523 PredInter8x16Mv (iMvArray, iRefIdxArray, listIdx, iPartIdx, iRefIdx, iMv);
1524
1525 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l0[ mbPartIdx ][ 0 ][ compIdx ]
1526 iMv[0] += iCode;
1527 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l1[ mbPartIdx ][ 0 ][ compIdx ]
1528 iMv[1] += iCode;
1529 WELS_CHECK_SE_BOTH_WARNING (iMv[1], iMinVmv, iMaxVmv, "vertical mv");
1530 } else {
1531 * (uint32_t*)iMv = 0;
1532 }
1533 UpdateP8x16MotionInfo (pCurDqLayer, iMvArray, iRefIdxArray, listIdx, iPartIdx, iRefIdx, iMv);
1534 }
1535 }
1536 } else if (IS_Inter_8x8 (mbType)) {
1537 int8_t pSubPartCount[4], pPartW[4];
1538 uint32_t uiSubMbType;
1539 //sub_mb_type, partition
1540 int16_t pMvDirect[LIST_A][2] = { { 0, 0 }, { 0, 0 } };
1541 if (pCtx->sRefPic.pRefList[LIST_1][0] == NULL) {
1542 SLogContext* pLogCtx = & (pCtx->sLogCtx);
1543 WelsLog (pLogCtx, WELS_LOG_ERROR, "Colocated Ref Picture for B-Slice is lost, B-Slice decoding cannot be continued!");
1544 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_DATA, ERR_INFO_REFERENCE_PIC_LOST);
1545 }
1546 bool bIsLongRef = pCtx->sRefPic.pRefList[LIST_1][0]->bIsLongRef;
1547 const int32_t ref0Count = WELS_MIN (pSliceHeader->uiRefCount[LIST_0], pCtx->sRefPic.uiRefCount[LIST_0]);
1548 bool has_direct_called = false;
1549 SubMbType directSubMbType = 0;
1550
1551 //uiSubMbType, partition
1552 for (int32_t i = 0; i < 4; i++) {
1553 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //sub_mb_type[ mbPartIdx ]
1554 uiSubMbType = uiCode;
1555 if (uiSubMbType >= 13) { //invalid uiSubMbType
1556 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_SUB_MB_TYPE);
1557 }
1558 pSubPartCount[i] = g_ksInterBSubMbTypeInfo[uiSubMbType].iPartCount;
1559 pPartW[i] = g_ksInterBSubMbTypeInfo[uiSubMbType].iPartWidth;
1560
1561 // Need modification when B picture add in, reference to 7.3.5
1562 if (pSubPartCount[i] > 1)
1563 pCurDqLayer->pNoSubMbPartSizeLessThan8x8Flag[iMbXy] = false;
1564
1565 if (IS_DIRECT (g_ksInterBSubMbTypeInfo[uiSubMbType].iType)) {
1566 if (!has_direct_called) {
1567 if (pSliceHeader->iDirectSpatialMvPredFlag) {
1568 int32_t ret = PredMvBDirectSpatial (pCtx, pMvDirect, iRef, directSubMbType);
1569 if (ret != ERR_NONE) {
1570 return ret;
1571 }
1572
1573 } else {
1574 //temporal direct mode
1575 int32_t ret = PredBDirectTemporal (pCtx, pMvDirect, iRef, directSubMbType);
1576 if (ret != ERR_NONE) {
1577 return ret;
1578 }
1579 }
1580 has_direct_called = true;
1581 }
1582 pCurDqLayer->pSubMbType[iMbXy][i] = directSubMbType;
1583 if (IS_SUB_4x4 (pCurDqLayer->pSubMbType[iMbXy][i])) {
1584 pSubPartCount[i] = 4;
1585 pPartW[i] = 1;
1586 }
1587 } else {
1588 pCurDqLayer->pSubMbType[iMbXy][i] = g_ksInterBSubMbTypeInfo[uiSubMbType].iType;
1589 }
1590 }
1591 if (pSlice->sSliceHeaderExt.bAdaptiveMotionPredFlag) {
1592 for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
1593 for (int32_t i = 0; i < 4; i++) {
1594 bool is_dir = IS_DIR (pCurDqLayer->pSubMbType[iMbXy][i], 0, listIdx) > 0;
1595 if (is_dir) {
1596 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //motion_prediction_flag_l0[ mbPartIdx ]
1597 iMotionPredFlag[listIdx][i] = uiCode;
1598 }
1599 }
1600 }
1601 }
1602 for (int32_t i = 0; i < 4; i++) { //Direct 8x8 Ref and mv
1603 int16_t iIdx8 = i << 2;
1604 if (IS_DIRECT (pCurDqLayer->pSubMbType[iMbXy][i])) {
1605 if (pSliceHeader->iDirectSpatialMvPredFlag) {
1606 FillSpatialDirect8x8Mv (pCurDqLayer, iIdx8, pSubPartCount[i], pPartW[i], directSubMbType, bIsLongRef, pMvDirect, iRef,
1607 iMvArray, NULL);
1608 } else {
1609 int16_t (*mvColoc)[2] = pCurDqLayer->iColocMv[LIST_0];
1610 iRef[LIST_1] = 0;
1611 iRef[LIST_0] = 0;
1612 const uint8_t uiColoc4Idx = g_kuiScan4[iIdx8];
1613 if (!pCurDqLayer->iColocIntra[uiColoc4Idx]) {
1614 iRef[LIST_0] = 0;
1615 int8_t colocRefIndexL0 = pCurDqLayer->iColocRefIndex[LIST_0][uiColoc4Idx];
1616 if (colocRefIndexL0 >= 0) {
1617 iRef[LIST_0] = MapColToList0 (pCtx, colocRefIndexL0, ref0Count);
1618 } else {
1619 mvColoc = pCurDqLayer->iColocMv[LIST_1];
1620 }
1621 }
1622 Update8x8RefIdx (pCurDqLayer, iIdx8, LIST_0, iRef[LIST_0]);
1623 Update8x8RefIdx (pCurDqLayer, iIdx8, LIST_1, iRef[LIST_1]);
1624 FillTemporalDirect8x8Mv (pCurDqLayer, iIdx8, pSubPartCount[i], pPartW[i], directSubMbType, iRef, mvColoc, iMvArray,
1625 NULL);
1626 }
1627 }
1628 }
1629 //ref no-direct
1630 for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
1631 for (int32_t i = 0; i < 4; i++) {
1632 int16_t iIdx8 = i << 2;
1633 int32_t subMbType = pCurDqLayer->pSubMbType[iMbXy][i];
1634 int8_t iref = REF_NOT_IN_LIST;
1635 if (IS_DIRECT (subMbType)) {
1636 if (pSliceHeader->iDirectSpatialMvPredFlag) {
1637 Update8x8RefIdx (pCurDqLayer, iIdx8, listIdx, iRef[listIdx]);
1638 ref_idx_list[listIdx][i] = iRef[listIdx];
1639 }
1640 } else {
1641 if (IS_DIR (subMbType, 0, listIdx)) {
1642 if (iMotionPredFlag[listIdx][i] == 0) {
1643 WELS_READ_VERIFY (BsGetTe0 (pBs, iRefCount[listIdx], &uiCode)); //ref_idx_l0[ mbPartIdx ]
1644 iref = uiCode;
1645 if ((iref < 0) || (iref >= iRefCount[listIdx]) || (ppRefPic[listIdx][iref] == NULL)) { //error ref_idx
1646 pCtx->bMbRefConcealed = true;
1647 if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
1648 iref = 0;
1649 pCtx->iErrorCode |= dsBitstreamError;
1650 RETURN_ERR_IF_NULL(ppRefPic[listIdx][iref]);
1651 } else {
1652 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_REF_INDEX);
1653 }
1654 }
1655 pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (ppRefPic[listIdx][iref]
1656 && (ppRefPic[listIdx][iref]->bIsComplete || bIsPending));
1657 } else {
1658 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "inter parse: iMotionPredFlag = 1 not supported. ");
1659 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_UNSUPPORTED_ILP);
1660 }
1661 }
1662 Update8x8RefIdx (pCurDqLayer, iIdx8, listIdx, iref);
1663 ref_idx_list[listIdx][i] = iref;
1664 }
1665 }
1666 }
1667 //mv
1668 for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
1669 for (int32_t i = 0; i < 4; i++) {
1670 int8_t iPartCount = pSubPartCount[i];
1671 int16_t iPartIdx, iBlockW = pPartW[i];
1672 uint8_t uiScan4Idx, uiCacheIdx;
1673
1674 uiCacheIdx = g_kuiCache30ScanIdx[i << 2];
1675
1676 int8_t iref = ref_idx_list[listIdx][i];
1677 iRefIdxArray[listIdx][uiCacheIdx] = iRefIdxArray[listIdx][uiCacheIdx + 1] =
1678 iRefIdxArray[listIdx][uiCacheIdx + 6] = iRefIdxArray[listIdx][uiCacheIdx + 7] = iref;
1679
1680 uint32_t subMbType = pCurDqLayer->pSubMbType[iMbXy][i];
1681 if (IS_DIRECT (subMbType)) {
1682 continue;
1683 }
1684 bool is_dir = IS_DIR (subMbType, 0, listIdx) > 0;
1685 for (int32_t j = 0; j < iPartCount; j++) {
1686 iPartIdx = (i << 2) + j * iBlockW;
1687 uiScan4Idx = g_kuiScan4[iPartIdx];
1688 uiCacheIdx = g_kuiCache30ScanIdx[iPartIdx];
1689 if (is_dir) {
1690 PredMv (iMvArray, iRefIdxArray, listIdx, iPartIdx, iBlockW, iref, iMv);
1691
1692 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l0[ mbPartIdx ][ subMbPartIdx ][ compIdx ]
1693 iMv[0] += iCode;
1694 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mvd_l1[ mbPartIdx ][ subMbPartIdx ][ compIdx ]
1695 iMv[1] += iCode;
1696 WELS_CHECK_SE_BOTH_WARNING (iMv[1], iMinVmv, iMaxVmv, "vertical mv");
1697 } else {
1698 * (uint32_t*)iMv = 0;
1699 }
1700 if (IS_SUB_8x8 (subMbType)) { //MB_TYPE_8x8
1701 ST32 (pCurDqLayer->pDec->pMv[listIdx][iMbXy][uiScan4Idx], LD32 (iMv));
1702 ST32 (pCurDqLayer->pDec->pMv[listIdx][iMbXy][uiScan4Idx + 1], LD32 (iMv));
1703 ST32 (pCurDqLayer->pDec->pMv[listIdx][iMbXy][uiScan4Idx + 4], LD32 (iMv));
1704 ST32 (pCurDqLayer->pDec->pMv[listIdx][iMbXy][uiScan4Idx + 5], LD32 (iMv));
1705 ST32 (iMvArray[listIdx][uiCacheIdx], LD32 (iMv));
1706 ST32 (iMvArray[listIdx][uiCacheIdx + 1], LD32 (iMv));
1707 ST32 (iMvArray[listIdx][uiCacheIdx + 6], LD32 (iMv));
1708 ST32 (iMvArray[listIdx][uiCacheIdx + 7], LD32 (iMv));
1709 } else if (IS_SUB_8x4 (subMbType)) {
1710 ST32 (pCurDqLayer->pDec->pMv[listIdx][iMbXy][uiScan4Idx], LD32 (iMv));
1711 ST32 (pCurDqLayer->pDec->pMv[listIdx][iMbXy][uiScan4Idx + 1], LD32 (iMv));
1712 ST32 (iMvArray[listIdx][uiCacheIdx], LD32 (iMv));
1713 ST32 (iMvArray[listIdx][uiCacheIdx + 1], LD32 (iMv));
1714 } else if (IS_SUB_4x8 (subMbType)) {
1715 ST32 (pCurDqLayer->pDec->pMv[listIdx][iMbXy][uiScan4Idx], LD32 (iMv));
1716 ST32 (pCurDqLayer->pDec->pMv[listIdx][iMbXy][uiScan4Idx + 4], LD32 (iMv));
1717 ST32 (iMvArray[listIdx][uiCacheIdx], LD32 (iMv));
1718 ST32 (iMvArray[listIdx][uiCacheIdx + 6], LD32 (iMv));
1719 } else { //SUB_MB_TYPE_4x4 == uiSubMbType
1720 ST32 (pCurDqLayer->pDec->pMv[listIdx][iMbXy][uiScan4Idx], LD32 (iMv));
1721 ST32 (iMvArray[listIdx][uiCacheIdx], LD32 (iMv));
1722 }
1723 }
1724 }
1725 }
1726 }
1727 return ERR_NONE;
1728 }
1729 } // namespace WelsDec
1730