• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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