• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*!
2  * \copy
3  *     Copyright (c)  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  *      parse_mb_syn_cabac.cpp: cabac parse for syntax elements
32  */
33 #include "parse_mb_syn_cabac.h"
34 #include "decode_slice.h"
35 #include "mv_pred.h"
36 #include "error_code.h"
37 #include <stdio.h>
38 
39 namespace WelsDec {
40 #define IDX_UNUSED -1
41 
42 static const int16_t g_kMaxPos       [] = {IDX_UNUSED, 15, 14, 15, 3, 14, 63, 3, 3, 14, 14};
43 static const int16_t g_kMaxC2       [] = {IDX_UNUSED, 4, 4, 4, 3, 4, 4, 3, 3, 4, 4};
44 static const int16_t g_kBlockCat2CtxOffsetCBF[] = {IDX_UNUSED, 0, 4, 8, 12, 16, 0, 12, 12, 16, 16};
45 static const int16_t g_kBlockCat2CtxOffsetMap [] = {IDX_UNUSED, 0, 15, 29, 44, 47, 0, 44, 44, 47, 47};
46 static const int16_t g_kBlockCat2CtxOffsetLast[] = {IDX_UNUSED, 0, 15, 29, 44, 47, 0, 44, 44, 47, 47};
47 static const int16_t g_kBlockCat2CtxOffsetOne [] = {IDX_UNUSED, 0, 10, 20, 30, 39, 0, 30, 30, 39, 39};
48 static const int16_t g_kBlockCat2CtxOffsetAbs [] = {IDX_UNUSED, 0, 10, 20, 30, 39, 0, 30, 30, 39, 39};
49 
50 const uint8_t g_kTopBlkInsideMb[24] = { //for index with z-order 0~23
51   //  0   1 | 4  5      luma 8*8 block           pNonZeroCount[16+8]
52   0,  0,  1,  1,   //  2   3 | 6  7        0  |  1                  0   1   2   3
53   0,  0,  1,  1,   //---------------      ---------                 4   5   6   7
54   1,  1,  1,  1,   //  8   9 | 12 13       2  |  3                  8   9  10  11
55   1,  1,  1,  1,  // 10  11 | 14 15-----------------------------> 12  13  14  15
56   0,  0,  1,  1,   //----------------    chroma 8*8 block          16  17  18  19
57   0,  0,  1,  1   // 16  17 | 20 21        0    1                 20  21  22  23
58   // 18  19 | 22 23
59 };
60 
61 const uint8_t g_kLeftBlkInsideMb[24] = { //for index with z-order 0~23
62   //  0   1 | 4  5      luma 8*8 block           pNonZeroCount[16+8]
63   0,  1,  0,  1,   //  2   3 | 6  7        0  |  1                  0   1   2   3
64   1,  1,  1,  1,   //---------------      ---------                 4   5   6   7
65   0,  1,  0,  1,   //  8   9 | 12 13       2  |  3                  8   9  10  11
66   1,  1,  1,  1,  // 10  11 | 14 15-----------------------------> 12  13  14  15
67   0,  1,  0,  1,   //----------------    chroma 8*8 block          16  17  18  19
68   0,  1,  0,  1   // 16  17 | 20 21        0    1                 20  21  22  23
69   // 18  19 | 22 23
70 };
71 
DecodeCabacIntraMbType(PWelsDecoderContext pCtx,PWelsNeighAvail pNeighAvail,int ctx_base)72 static uint32_t DecodeCabacIntraMbType (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, int ctx_base) {
73   uint32_t uiCode;
74   uint32_t uiMbType = 0;
75 
76   PWelsCabacDecEngine pCabacDecEngine = pCtx->pCabacDecEngine;
77   PWelsCabacCtx pBinCtx = pCtx->pCabacCtx + ctx_base;
78 
79   WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx, uiCode));
80   if (!uiCode) {
81     return 0; /* I4x4 */
82   }
83 
84   WELS_READ_VERIFY (DecodeTerminateCabac (pCabacDecEngine, uiCode));
85   if (uiCode) {
86     return 25; /* PCM */
87   }
88   uiMbType = 1; /* I16x16 */
89   WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 1, uiCode)); /* cbp_luma != 0 */
90   uiMbType += 12 * uiCode;
91 
92   WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 2, uiCode));
93   if (uiCode) {
94     WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 2, uiCode));
95     uiMbType += 4 + 4 * uiCode;
96   }
97   WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 3, uiCode));
98   uiMbType += 2 * uiCode;
99   WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 3, uiCode));
100   uiMbType += 1 * uiCode;
101   return uiMbType;
102 }
103 
UpdateP16x8RefIdxCabac(PDqLayer pCurDqLayer,int8_t pRefIndex[LIST_A][30],int32_t iPartIdx,const int8_t iRef,const int8_t iListIdx)104 void UpdateP16x8RefIdxCabac (PDqLayer pCurDqLayer, int8_t pRefIndex[LIST_A][30], int32_t iPartIdx, const int8_t iRef,
105                              const int8_t iListIdx) {
106   uint32_t iRef32Bit = (uint32_t) iRef;
107   const int32_t iRef4Bytes = (iRef32Bit << 24) | (iRef32Bit << 16) | (iRef32Bit << 8) | iRef32Bit;
108   int32_t iMbXy = pCurDqLayer->iMbXyIndex;
109   const uint8_t iScan4Idx = g_kuiScan4[iPartIdx];
110   const uint8_t iScan4Idx4 = 4 + iScan4Idx;
111   const uint8_t iCacheIdx = g_kuiCache30ScanIdx[iPartIdx];
112   const uint8_t iCacheIdx6 = 6 + iCacheIdx;
113   //mb
114   ST32 (&pCurDqLayer->pDec->pRefIndex[iListIdx][iMbXy][iScan4Idx ], iRef4Bytes);
115   ST32 (&pCurDqLayer->pDec->pRefIndex[iListIdx][iMbXy][iScan4Idx4], iRef4Bytes);
116   //cache
117   ST32 (&pRefIndex[iListIdx][iCacheIdx ], iRef4Bytes);
118   ST32 (&pRefIndex[iListIdx][iCacheIdx6], iRef4Bytes);
119 }
120 
UpdateP8x16RefIdxCabac(PDqLayer pCurDqLayer,int8_t pRefIndex[LIST_A][30],int32_t iPartIdx,const int8_t iRef,const int8_t iListIdx)121 void UpdateP8x16RefIdxCabac (PDqLayer pCurDqLayer, int8_t pRefIndex[LIST_A][30], int32_t iPartIdx, const int8_t iRef,
122                              const int8_t iListIdx) {
123   uint16_t iRef16Bit = (uint16_t) iRef;
124   const int16_t iRef2Bytes = (iRef16Bit << 8) | iRef16Bit;
125   int32_t i;
126   int32_t iMbXy = pCurDqLayer->iMbXyIndex;
127   for (i = 0; i < 2; i++, iPartIdx += 8) {
128     const uint8_t iScan4Idx = g_kuiScan4[iPartIdx];
129     const uint8_t iCacheIdx = g_kuiCache30ScanIdx[iPartIdx];
130     const uint8_t iScan4Idx4 = 4 + iScan4Idx;
131     const uint8_t iCacheIdx6 = 6 + iCacheIdx;
132     //mb
133     ST16 (&pCurDqLayer->pDec->pRefIndex[iListIdx][iMbXy][iScan4Idx ], iRef2Bytes);
134     ST16 (&pCurDqLayer->pDec->pRefIndex[iListIdx][iMbXy][iScan4Idx4], iRef2Bytes);
135     //cache
136     ST16 (&pRefIndex[iListIdx][iCacheIdx ], iRef2Bytes);
137     ST16 (&pRefIndex[iListIdx][iCacheIdx6], iRef2Bytes);
138   }
139 }
140 
UpdateP8x8RefIdxCabac(PDqLayer pCurDqLayer,int8_t pRefIndex[LIST_A][30],int32_t iPartIdx,const int8_t iRef,const int8_t iListIdx)141 void UpdateP8x8RefIdxCabac (PDqLayer pCurDqLayer, int8_t pRefIndex[LIST_A][30], int32_t iPartIdx, const int8_t iRef,
142                             const int8_t iListIdx) {
143   int32_t iMbXy = pCurDqLayer->iMbXyIndex;
144   const uint8_t iScan4Idx = g_kuiScan4[iPartIdx];
145   pCurDqLayer->pDec->pRefIndex[iListIdx][iMbXy][iScan4Idx] = pCurDqLayer->pDec->pRefIndex[iListIdx][iMbXy][iScan4Idx + 1]
146       =
147         pCurDqLayer->pDec->pRefIndex[iListIdx][iMbXy][iScan4Idx + 4] = pCurDqLayer->pDec->pRefIndex[iListIdx][iMbXy][iScan4Idx +
148             5] = iRef;
149 }
150 
UpdateP8x8DirectCabac(PDqLayer pCurDqLayer,int32_t iPartIdx)151 void UpdateP8x8DirectCabac (PDqLayer pCurDqLayer, int32_t iPartIdx) {
152   int32_t iMbXy = pCurDqLayer->iMbXyIndex;
153   const uint8_t iScan4Idx = g_kuiScan4[iPartIdx];
154   pCurDqLayer->pDirect[iMbXy][iScan4Idx] = pCurDqLayer->pDirect[iMbXy][iScan4Idx + 1] =
155         pCurDqLayer->pDirect[iMbXy][iScan4Idx + 4] = pCurDqLayer->pDirect[iMbXy][iScan4Idx + 5] = 1;
156 }
157 
UpdateP16x16DirectCabac(PDqLayer pCurDqLayer)158 void UpdateP16x16DirectCabac (PDqLayer pCurDqLayer) {
159   int32_t i;
160   int32_t iMbXy = pCurDqLayer->iMbXyIndex;
161   const int16_t direct = (1 << 8) | 1;
162   for (i = 0; i < 16; i += 4) {
163     const uint8_t kuiScan4Idx = g_kuiScan4[i];
164     const uint8_t kuiScan4IdxPlus4 = 4 + kuiScan4Idx;
165     ST16 (&pCurDqLayer->pDirect[iMbXy][kuiScan4Idx], direct);
166     ST16 (&pCurDqLayer->pDirect[iMbXy][kuiScan4IdxPlus4], direct);
167   }
168 }
169 
UpdateP16x16MvdCabac(SDqLayer * pCurDqLayer,int16_t pMvd[2],const int8_t iListIdx)170 void UpdateP16x16MvdCabac (SDqLayer* pCurDqLayer, int16_t pMvd[2], const int8_t iListIdx) {
171   int32_t pMvd32[2];
172   ST32 (&pMvd32[0], LD32 (pMvd));
173   ST32 (&pMvd32[1], LD32 (pMvd));
174   int32_t i;
175   int32_t iMbXy = pCurDqLayer->iMbXyIndex;
176   for (i = 0; i < 16; i += 2) {
177     ST64 (pCurDqLayer->pMvd[iListIdx][iMbXy][i], LD64 (pMvd32));
178   }
179 }
180 
UpdateP16x8MvdCabac(SDqLayer * pCurDqLayer,int16_t pMvdCache[LIST_A][30][MV_A],int32_t iPartIdx,int16_t pMvd[2],const int8_t iListIdx)181 void UpdateP16x8MvdCabac (SDqLayer* pCurDqLayer, int16_t pMvdCache[LIST_A][30][MV_A], int32_t iPartIdx, int16_t pMvd[2],
182                           const int8_t iListIdx) {
183   int32_t pMvd32[2];
184   ST32 (&pMvd32[0], LD32 (pMvd));
185   ST32 (&pMvd32[1], LD32 (pMvd));
186   int32_t i;
187   int32_t iMbXy = pCurDqLayer->iMbXyIndex;
188   for (i = 0; i < 2; i++, iPartIdx += 4) {
189     const uint8_t iScan4Idx = g_kuiScan4[iPartIdx];
190     const uint8_t iScan4Idx4 = 4 + iScan4Idx;
191     const uint8_t iCacheIdx = g_kuiCache30ScanIdx[iPartIdx];
192     const uint8_t iCacheIdx6 = 6 + iCacheIdx;
193     //mb
194     ST64 (pCurDqLayer->pMvd[iListIdx][iMbXy][  iScan4Idx ], LD64 (pMvd32));
195     ST64 (pCurDqLayer->pMvd[iListIdx][iMbXy][  iScan4Idx4], LD64 (pMvd32));
196     //cache
197     ST64 (pMvdCache[iListIdx][  iCacheIdx ], LD64 (pMvd32));
198     ST64 (pMvdCache[iListIdx][  iCacheIdx6], LD64 (pMvd32));
199   }
200 }
201 
UpdateP8x16MvdCabac(SDqLayer * pCurDqLayer,int16_t pMvdCache[LIST_A][30][MV_A],int32_t iPartIdx,int16_t pMvd[2],const int8_t iListIdx)202 void UpdateP8x16MvdCabac (SDqLayer* pCurDqLayer, int16_t pMvdCache[LIST_A][30][MV_A], int32_t iPartIdx, int16_t pMvd[2],
203                           const int8_t iListIdx) {
204   int32_t pMvd32[2];
205   ST32 (&pMvd32[0], LD32 (pMvd));
206   ST32 (&pMvd32[1], LD32 (pMvd));
207   int32_t i;
208   int32_t iMbXy = pCurDqLayer->iMbXyIndex;
209 
210   for (i = 0; i < 2; i++, iPartIdx += 8) {
211     const uint8_t iScan4Idx = g_kuiScan4[iPartIdx];
212     const uint8_t iCacheIdx = g_kuiCache30ScanIdx[iPartIdx];
213     const uint8_t iScan4Idx4 = 4 + iScan4Idx;
214     const uint8_t iCacheIdx6 = 6 + iCacheIdx;
215     //mb
216     ST64 (pCurDqLayer->pMvd[iListIdx][iMbXy][  iScan4Idx ], LD64 (pMvd32));
217     ST64 (pCurDqLayer->pMvd[iListIdx][iMbXy][  iScan4Idx4], LD64 (pMvd32));
218     //cache
219     ST64 (pMvdCache[iListIdx][  iCacheIdx ], LD64 (pMvd32));
220     ST64 (pMvdCache[iListIdx][  iCacheIdx6], LD64 (pMvd32));
221   }
222 }
223 
ParseEndOfSliceCabac(PWelsDecoderContext pCtx,uint32_t & uiBinVal)224 int32_t ParseEndOfSliceCabac (PWelsDecoderContext pCtx, uint32_t& uiBinVal) {
225   uiBinVal = 0;
226   WELS_READ_VERIFY (DecodeTerminateCabac (pCtx->pCabacDecEngine, uiBinVal));
227   return ERR_NONE;
228 }
229 
ParseSkipFlagCabac(PWelsDecoderContext pCtx,PWelsNeighAvail pNeighAvail,uint32_t & uiSkip)230 int32_t ParseSkipFlagCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint32_t& uiSkip) {
231   uiSkip = 0;
232   int32_t iCtxInc = NEW_CTX_OFFSET_SKIP;
233   iCtxInc += (pNeighAvail->iLeftAvail && !IS_SKIP (pNeighAvail->iLeftType)) + (pNeighAvail->iTopAvail
234              && !IS_SKIP (pNeighAvail->iTopType));
235   if (B_SLICE == pCtx->eSliceType)
236     iCtxInc += 13;
237   PWelsCabacCtx pBinCtx = (pCtx->pCabacCtx + iCtxInc);
238   WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pBinCtx, uiSkip));
239   return ERR_NONE;
240 }
241 
242 
ParseMBTypeISliceCabac(PWelsDecoderContext pCtx,PWelsNeighAvail pNeighAvail,uint32_t & uiBinVal)243 int32_t ParseMBTypeISliceCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint32_t& uiBinVal) {
244   uint32_t uiCode;
245   int32_t iIdxA = 0, iIdxB = 0;
246   int32_t iCtxInc;
247   uiBinVal = 0;
248   PWelsCabacDecEngine pCabacDecEngine = pCtx->pCabacDecEngine;
249   PWelsCabacCtx pBinCtx = pCtx->pCabacCtx + NEW_CTX_OFFSET_MB_TYPE_I; //I mode in I slice
250   iIdxA = (pNeighAvail->iLeftAvail) && (pNeighAvail->iLeftType != MB_TYPE_INTRA4x4
251                                         && pNeighAvail->iLeftType != MB_TYPE_INTRA8x8);
252   iIdxB = (pNeighAvail->iTopAvail) && (pNeighAvail->iTopType != MB_TYPE_INTRA4x4
253                                        && pNeighAvail->iTopType != MB_TYPE_INTRA8x8);
254   iCtxInc = iIdxA + iIdxB;
255   WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + iCtxInc, uiCode));
256   uiBinVal = uiCode;
257   if (uiBinVal != 0) {  //I16x16
258     WELS_READ_VERIFY (DecodeTerminateCabac (pCabacDecEngine, uiCode));
259     if (uiCode == 1)
260       uiBinVal = 25; //I_PCM
261     else {
262       WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 3, uiCode));
263       uiBinVal = 1 + uiCode * 12;
264       //decoding of uiCbp:0,1,2
265       WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 4, uiCode));
266       if (uiCode != 0) {
267         WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 5, uiCode));
268         uiBinVal += 4;
269         if (uiCode != 0)
270           uiBinVal += 4;
271       }
272       //decoding of I pred-mode: 0,1,2,3
273       WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 6, uiCode));
274       uiBinVal += (uiCode << 1);
275       WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 7, uiCode));
276       uiBinVal += uiCode;
277     }
278   }
279   //I4x4
280   return ERR_NONE;
281 }
282 
ParseMBTypePSliceCabac(PWelsDecoderContext pCtx,PWelsNeighAvail pNeighAvail,uint32_t & uiMbType)283 int32_t ParseMBTypePSliceCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint32_t& uiMbType) {
284   uint32_t uiCode;
285   uiMbType = 0;
286   PWelsCabacDecEngine pCabacDecEngine = pCtx->pCabacDecEngine;
287 
288   PWelsCabacCtx pBinCtx = pCtx->pCabacCtx + NEW_CTX_OFFSET_SKIP;
289   WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 3, uiCode));
290   if (uiCode) {
291     // Intra MB
292     WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 6, uiCode));
293     if (uiCode) { // Intra 16x16
294       WELS_READ_VERIFY (DecodeTerminateCabac (pCabacDecEngine, uiCode));
295       if (uiCode) {
296         uiMbType = 30;
297         return ERR_NONE;//MB_TYPE_INTRA_PCM;
298       }
299 
300       WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 7, uiCode));
301       uiMbType = 6 + uiCode * 12;
302 
303       //uiCbp: 0,1,2
304       WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 8, uiCode));
305       if (uiCode) {
306         uiMbType += 4;
307         WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 8, uiCode));
308         if (uiCode)
309           uiMbType += 4;
310       }
311 
312       //IPredMode: 0,1,2,3
313       WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 9, uiCode));
314       uiMbType += (uiCode << 1);
315       WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 9, uiCode));
316       uiMbType += uiCode;
317     } else
318       // Intra 4x4
319       uiMbType = 5;
320   } else { // P MB
321     WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 4, uiCode));
322     if (uiCode) { //second bit
323       WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 6, uiCode));
324       if (uiCode)
325         uiMbType = 1;
326       else
327         uiMbType = 2;
328     } else {
329       WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 5, uiCode));
330       if (uiCode)
331         uiMbType = 3;
332       else
333         uiMbType = 0;
334     }
335   }
336   return ERR_NONE;
337 }
338 
ParseMBTypeBSliceCabac(PWelsDecoderContext pCtx,PWelsNeighAvail pNeighAvail,uint32_t & uiMbType)339 int32_t ParseMBTypeBSliceCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint32_t& uiMbType) {
340   uint32_t uiCode;
341   uiMbType = 0;
342   int32_t iIdxA = 0, iIdxB = 0;
343   int32_t iCtxInc;
344 
345   PWelsCabacDecEngine pCabacDecEngine = pCtx->pCabacDecEngine;
346   PWelsCabacCtx pBinCtx = pCtx->pCabacCtx + 27; //B slice
347 
348   iIdxA = (pNeighAvail->iLeftAvail) && !IS_DIRECT (pNeighAvail->iLeftType);
349   iIdxB = (pNeighAvail->iTopAvail) && !IS_DIRECT (pNeighAvail->iTopType);
350 
351   iCtxInc = iIdxA + iIdxB;
352   WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + iCtxInc, uiCode));
353   if (!uiCode)
354     uiMbType = 0; // Bi_Direct
355   else {
356     WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 3, uiCode));
357     if (!uiCode) {
358       WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 5, uiCode));
359       uiMbType = 1 + uiCode; // 16x16 L0L1
360     } else {
361       WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 4, uiCode));
362       uiMbType = uiCode << 3;
363       WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 5, uiCode));
364       uiMbType |= uiCode << 2;
365       WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 5, uiCode));
366       uiMbType |= uiCode << 1;
367       WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 5, uiCode));
368       uiMbType |= uiCode;
369       if (uiMbType < 8) {
370         uiMbType += 3;
371         return ERR_NONE;
372       } else if (uiMbType == 13) {
373         uiMbType = DecodeCabacIntraMbType (pCtx, pNeighAvail, 32) + 23;
374         return ERR_NONE;
375       } else if (uiMbType == 14) {
376         uiMbType = 11; // Bi8x16
377         return ERR_NONE;
378       } else if (uiMbType == 15) {
379         uiMbType = 22; // 8x8
380         return ERR_NONE;
381       }
382       uiMbType <<= 1;
383       WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 5, uiCode));
384       uiMbType |= uiCode;
385       uiMbType -= 4;
386     }
387   }
388   return ERR_NONE;
389 }
390 
ParseTransformSize8x8FlagCabac(PWelsDecoderContext pCtx,PWelsNeighAvail pNeighAvail,bool & bTransformSize8x8Flag)391 int32_t ParseTransformSize8x8FlagCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail,
392                                         bool& bTransformSize8x8Flag) {
393   uint32_t uiCode;
394   int32_t iIdxA, iIdxB;
395   int32_t iCtxInc;
396   PWelsCabacDecEngine pCabacDecEngine = pCtx->pCabacDecEngine;
397   PWelsCabacCtx pBinCtx = pCtx->pCabacCtx + NEW_CTX_OFFSET_TS_8x8_FLAG;
398   iIdxA = (pNeighAvail->iLeftAvail) && (pCtx->pCurDqLayer->pTransformSize8x8Flag[pCtx->pCurDqLayer->iMbXyIndex - 1]);
399   iIdxB = (pNeighAvail->iTopAvail)
400           && (pCtx->pCurDqLayer->pTransformSize8x8Flag[pCtx->pCurDqLayer->iMbXyIndex - pCtx->pCurDqLayer->iMbWidth]);
401   iCtxInc = iIdxA + iIdxB;
402   WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + iCtxInc, uiCode));
403   bTransformSize8x8Flag = !!uiCode;
404 
405   return ERR_NONE;
406 }
407 
ParseSubMBTypeCabac(PWelsDecoderContext pCtx,PWelsNeighAvail pNeighAvail,uint32_t & uiSubMbType)408 int32_t ParseSubMBTypeCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint32_t& uiSubMbType) {
409   uint32_t uiCode;
410   PWelsCabacDecEngine pCabacDecEngine = pCtx->pCabacDecEngine;
411   PWelsCabacCtx pBinCtx = pCtx->pCabacCtx + NEW_CTX_OFFSET_SUBMB_TYPE;
412   WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx, uiCode));
413   if (uiCode)
414     uiSubMbType = 0;
415   else {
416     WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 1, uiCode));
417     if (uiCode) {
418       WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 2, uiCode));
419       uiSubMbType = 3 - uiCode;
420     } else {
421       uiSubMbType = 1;
422     }
423   }
424   return ERR_NONE;
425 }
426 
ParseBSubMBTypeCabac(PWelsDecoderContext pCtx,PWelsNeighAvail pNeighAvail,uint32_t & uiSubMbType)427 int32_t ParseBSubMBTypeCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint32_t& uiSubMbType) {
428   uint32_t uiCode;
429   PWelsCabacDecEngine pCabacDecEngine = pCtx->pCabacDecEngine;
430   PWelsCabacCtx pBinCtx = pCtx->pCabacCtx + NEW_CTX_OFFSET_B_SUBMB_TYPE;
431   WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx, uiCode));
432   if (!uiCode) {
433     uiSubMbType = 0; /* B_Direct_8x8 */
434     return ERR_NONE;
435   }
436   WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 1, uiCode));
437   if (!uiCode) {
438     WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 3, uiCode));
439     uiSubMbType = 1 + uiCode; /* B_L0_8x8, B_L1_8x8 */
440     return ERR_NONE;
441   }
442   uiSubMbType = 3;
443   WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 2, uiCode));
444   if (uiCode) {
445     WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 3, uiCode));
446     if (uiCode) {
447       WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 3, uiCode));
448       uiSubMbType = 11 + uiCode; /* B_L1_4x4, B_Bi_4x4 */
449       return ERR_NONE;
450     }
451     uiSubMbType += 4;
452   }
453   WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 3, uiCode));
454   uiSubMbType += 2 * uiCode;
455   WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 3, uiCode));
456   uiSubMbType += uiCode;
457 
458   return ERR_NONE;
459 }
460 
ParseIntraPredModeLumaCabac(PWelsDecoderContext pCtx,int32_t & iBinVal)461 int32_t ParseIntraPredModeLumaCabac (PWelsDecoderContext pCtx, int32_t& iBinVal) {
462   uint32_t uiCode;
463   iBinVal = 0;
464   WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_IPR, uiCode));
465   if (uiCode == 1)
466     iBinVal = -1;
467   else {
468     WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_IPR + 1, uiCode));
469     iBinVal |= uiCode;
470     WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_IPR + 1, uiCode));
471     iBinVal |= (uiCode << 1);
472     WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_IPR + 1, uiCode));
473     iBinVal |= (uiCode << 2);
474   }
475   return ERR_NONE;
476 }
477 
ParseIntraPredModeChromaCabac(PWelsDecoderContext pCtx,uint8_t uiNeighAvail,int32_t & iBinVal)478 int32_t ParseIntraPredModeChromaCabac (PWelsDecoderContext pCtx, uint8_t uiNeighAvail, int32_t& iBinVal) {
479   uint32_t uiCode;
480   int32_t iIdxA, iIdxB, iCtxInc;
481   int8_t* pChromaPredMode = pCtx->pCurDqLayer->pChromaPredMode;
482   uint32_t* pMbType = pCtx->pCurDqLayer->pDec->pMbType;
483   int32_t iLeftAvail     = uiNeighAvail & 0x04;
484   int32_t iTopAvail      = uiNeighAvail & 0x01;
485 
486   int32_t iMbXy = pCtx->pCurDqLayer->iMbXyIndex;
487   int32_t iMbXyTop = iMbXy - pCtx->pCurDqLayer->iMbWidth;
488   int32_t iMbXyLeft = iMbXy - 1;
489 
490   iBinVal = 0;
491 
492   iIdxB = iTopAvail  && (pChromaPredMode[iMbXyTop] > 0 && pChromaPredMode[iMbXyTop] <= 3)
493           && pMbType[iMbXyTop]  != MB_TYPE_INTRA_PCM;
494   iIdxA = iLeftAvail && (pChromaPredMode[iMbXyLeft] > 0 && pChromaPredMode[iMbXyLeft] <= 3)
495           && pMbType[iMbXyLeft] != MB_TYPE_INTRA_PCM;
496   iCtxInc = iIdxA + iIdxB;
497   WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_CIPR + iCtxInc, uiCode));
498   iBinVal = uiCode;
499   if (iBinVal != 0) {
500     uint32_t iSym;
501     WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_CIPR + 3, iSym));
502     if (iSym == 0) {
503       iBinVal = (iSym + 1);
504       return ERR_NONE;
505     }
506     iSym = 0;
507     do {
508       WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_CIPR + 3, uiCode));
509       ++iSym;
510     } while ((uiCode != 0) && (iSym < 1));
511 
512     if ((uiCode != 0) && (iSym == 1))
513       ++ iSym;
514     iBinVal = (iSym + 1);
515     return ERR_NONE;
516   }
517   return ERR_NONE;
518 }
519 
ParseInterPMotionInfoCabac(PWelsDecoderContext pCtx,PWelsNeighAvail pNeighAvail,uint8_t * pNonZeroCount,int16_t pMotionVector[LIST_A][30][MV_A],int16_t pMvdCache[LIST_A][30][MV_A],int8_t pRefIndex[LIST_A][30])520 int32_t ParseInterPMotionInfoCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroCount,
521                                     int16_t pMotionVector[LIST_A][30][MV_A], int16_t pMvdCache[LIST_A][30][MV_A], int8_t pRefIndex[LIST_A][30]) {
522   PSlice pSlice                 = &pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer;
523   PSliceHeader pSliceHeader     = &pSlice->sSliceHeaderExt.sSliceHeader;
524   PDqLayer pCurDqLayer = pCtx->pCurDqLayer;
525   PPicture* ppRefPic = pCtx->sRefPic.pRefList[LIST_0];
526   int32_t pRefCount[2];
527   int32_t i, j;
528   int32_t iMbXy = pCurDqLayer->iMbXyIndex;
529   int16_t pMv[4] = {0};
530   int16_t pMvd[4] = {0};
531   int8_t iRef[2] = {0};
532   int32_t iPartIdx;
533   int16_t iMinVmv = pSliceHeader->pSps->pSLevelLimits->iMinVmv;
534   int16_t iMaxVmv = pSliceHeader->pSps->pSLevelLimits->iMaxVmv;
535   pRefCount[0] = pSliceHeader->uiRefCount[0];
536   pRefCount[1] = pSliceHeader->uiRefCount[1];
537 
538   bool bIsPending = GetThreadCount (pCtx) > 1;
539 
540   switch (pCurDqLayer->pDec->pMbType[iMbXy]) {
541   case MB_TYPE_16x16: {
542     iPartIdx = 0;
543     WELS_READ_VERIFY (ParseRefIdxCabac (pCtx, pNeighAvail, pNonZeroCount, pRefIndex, 0, LIST_0, iPartIdx, pRefCount[0], 0,
544                                         iRef[0]));
545     if ((iRef[0] < 0) || (iRef[0] >= pRefCount[0]) || (ppRefPic[iRef[0]] == NULL)) { //error ref_idx
546       pCtx->bMbRefConcealed = true;
547       if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
548         iRef[0] = 0;
549         pCtx->iErrorCode |= dsBitstreamError;
550       } else {
551         return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_REF_INDEX);
552       }
553     }
554     pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (ppRefPic[iRef[0]]
555                             && (ppRefPic[iRef[0]]->bIsComplete || bIsPending));
556     PredMv (pMotionVector, pRefIndex, LIST_0, 0, 4, iRef[0], pMv);
557     WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, LIST_0, 0, pMvd[0]));
558     WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, LIST_0, 1, pMvd[1]));
559     pMv[0] += pMvd[0];
560     pMv[1] += pMvd[1];
561     WELS_CHECK_SE_BOTH_WARNING (pMv[1], iMinVmv, iMaxVmv, "vertical mv");
562     UpdateP16x16MotionInfo (pCurDqLayer, LIST_0, iRef[0], pMv);
563     UpdateP16x16MvdCabac (pCurDqLayer, pMvd, LIST_0);
564   }
565   break;
566   case MB_TYPE_16x8:
567     for (i = 0; i < 2; i++) {
568       iPartIdx = i << 3;
569       WELS_READ_VERIFY (ParseRefIdxCabac (pCtx, pNeighAvail, pNonZeroCount, pRefIndex, 0, LIST_0, iPartIdx, pRefCount[0], 0,
570                                           iRef[i]));
571       if ((iRef[i] < 0) || (iRef[i] >= pRefCount[0]) || (ppRefPic[iRef[i]] == NULL)) { //error ref_idx
572         pCtx->bMbRefConcealed = true;
573         if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
574           iRef[i] = 0;
575           pCtx->iErrorCode |= dsBitstreamError;
576         } else {
577           return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_REF_INDEX);
578         }
579       }
580       pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (ppRefPic[iRef[i]]
581                               && (ppRefPic[iRef[i]]->bIsComplete || bIsPending));
582       UpdateP16x8RefIdxCabac (pCurDqLayer, pRefIndex, iPartIdx, iRef[i], LIST_0);
583     }
584     for (i = 0; i < 2; i++) {
585       iPartIdx = i << 3;
586       PredInter16x8Mv (pMotionVector, pRefIndex, LIST_0, iPartIdx, iRef[i], pMv);
587       WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, LIST_0, 0, pMvd[0]));
588       WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, LIST_0, 1, pMvd[1]));
589       pMv[0] += pMvd[0];
590       pMv[1] += pMvd[1];
591       WELS_CHECK_SE_BOTH_WARNING (pMv[1], iMinVmv, iMaxVmv, "vertical mv");
592       UpdateP16x8MotionInfo (pCurDqLayer, pMotionVector, pRefIndex, LIST_0, iPartIdx, iRef[i], pMv);
593       UpdateP16x8MvdCabac (pCurDqLayer, pMvdCache, iPartIdx, pMvd, LIST_0);
594     }
595     break;
596   case MB_TYPE_8x16:
597     for (i = 0; i < 2; i++) {
598       iPartIdx = i << 2;
599       WELS_READ_VERIFY (ParseRefIdxCabac (pCtx, pNeighAvail, pNonZeroCount, pRefIndex, 0, LIST_0, iPartIdx, pRefCount[0], 0,
600                                           iRef[i]));
601       if ((iRef[i] < 0) || (iRef[i] >= pRefCount[0]) || (ppRefPic[iRef[i]] == NULL)) { //error ref_idx
602         pCtx->bMbRefConcealed = true;
603         if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
604           iRef[i] = 0;
605           pCtx->iErrorCode |= dsBitstreamError;
606         } else {
607           return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_REF_INDEX);
608         }
609       }
610       pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (ppRefPic[iRef[i]]
611                               && (ppRefPic[iRef[i]]->bIsComplete || bIsPending));
612       UpdateP8x16RefIdxCabac (pCurDqLayer, pRefIndex, iPartIdx, iRef[i], LIST_0);
613     }
614     for (i = 0; i < 2; i++) {
615       iPartIdx = i << 2;
616       PredInter8x16Mv (pMotionVector, pRefIndex, LIST_0, i << 2, iRef[i], pMv/*&mv[0], &mv[1]*/);
617 
618       WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, LIST_0, 0, pMvd[0]));
619       WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, LIST_0, 1, pMvd[1]));
620       pMv[0] += pMvd[0];
621       pMv[1] += pMvd[1];
622       WELS_CHECK_SE_BOTH_WARNING (pMv[1], iMinVmv, iMaxVmv, "vertical mv");
623       UpdateP8x16MotionInfo (pCurDqLayer, pMotionVector, pRefIndex, LIST_0, iPartIdx, iRef[i], pMv);
624       UpdateP8x16MvdCabac (pCurDqLayer, pMvdCache, iPartIdx, pMvd, LIST_0);
625     }
626     break;
627   case MB_TYPE_8x8:
628   case MB_TYPE_8x8_REF0: {
629     int8_t pRefIdx[4] = {0}, pSubPartCount[4], pPartW[4];
630     uint32_t uiSubMbType;
631     //sub_mb_type, partition
632     for (i = 0; i < 4; i++) {
633       WELS_READ_VERIFY (ParseSubMBTypeCabac (pCtx, pNeighAvail, uiSubMbType));
634       if (uiSubMbType >= 4) { //invalid sub_mb_type
635         return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_SUB_MB_TYPE);
636       }
637       pCurDqLayer->pSubMbType[iMbXy][i] = g_ksInterPSubMbTypeInfo[uiSubMbType].iType;
638       pSubPartCount[i] = g_ksInterPSubMbTypeInfo[uiSubMbType].iPartCount;
639       pPartW[i] = g_ksInterPSubMbTypeInfo[uiSubMbType].iPartWidth;
640 
641       // Need modification when B picture add in, reference to 7.3.5
642       pCurDqLayer->pNoSubMbPartSizeLessThan8x8Flag[iMbXy] &= (uiSubMbType == 0);
643     }
644 
645     for (i = 0; i < 4; i++) {
646       int16_t iIdx8 = i << 2;
647       WELS_READ_VERIFY (ParseRefIdxCabac (pCtx, pNeighAvail, pNonZeroCount, pRefIndex, 0, LIST_0, iIdx8, pRefCount[0], 1,
648                                           pRefIdx[i]));
649       if ((pRefIdx[i] < 0) || (pRefIdx[i] >= pRefCount[0]) || (ppRefPic[pRefIdx[i]] == NULL)) { //error ref_idx
650         pCtx->bMbRefConcealed = true;
651         if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
652           pRefIdx[i] = 0;
653           pCtx->iErrorCode |= dsBitstreamError;
654         } else {
655           return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_REF_INDEX);
656         }
657       }
658       pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (ppRefPic[pRefIdx[i]]
659                               && (ppRefPic[pRefIdx[i]]->bIsComplete || bIsPending));
660       UpdateP8x8RefIdxCabac (pCurDqLayer, pRefIndex, iIdx8, pRefIdx[i], LIST_0);
661     }
662     //mv
663     for (i = 0; i < 4; i++) {
664       int8_t iPartCount = pSubPartCount[i];
665       uiSubMbType = pCurDqLayer->pSubMbType[iMbXy][i];
666       int16_t iPartIdx, iBlockW = pPartW[i];
667       uint8_t iScan4Idx, iCacheIdx;
668       iCacheIdx = g_kuiCache30ScanIdx[i << 2];
669       pRefIndex[0][iCacheIdx ] = pRefIndex[0][iCacheIdx + 1]
670                                  = pRefIndex[0][iCacheIdx + 6] = pRefIndex[0][iCacheIdx + 7] = pRefIdx[i];
671 
672       for (j = 0; j < iPartCount; j++) {
673         iPartIdx = (i << 2) + j * iBlockW;
674         iScan4Idx = g_kuiScan4[iPartIdx];
675         iCacheIdx = g_kuiCache30ScanIdx[iPartIdx];
676         PredMv (pMotionVector, pRefIndex, LIST_0, iPartIdx, iBlockW, pRefIdx[i], pMv);
677         WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, LIST_0, 0, pMvd[0]));
678         WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, LIST_0, 1, pMvd[1]));
679         pMv[0] += pMvd[0];
680         pMv[1] += pMvd[1];
681         WELS_CHECK_SE_BOTH_WARNING (pMv[1], iMinVmv, iMaxVmv, "vertical mv");
682         if (SUB_MB_TYPE_8x8 == uiSubMbType) {
683           ST32 ((pMv + 2), LD32 (pMv));
684           ST32 ((pMvd + 2), LD32 (pMvd));
685           ST64 (pCurDqLayer->pDec->pMv[0][iMbXy][iScan4Idx], LD64 (pMv));
686           ST64 (pCurDqLayer->pDec->pMv[0][iMbXy][iScan4Idx + 4], LD64 (pMv));
687           ST64 (pCurDqLayer->pMvd[0][iMbXy][iScan4Idx], LD64 (pMvd));
688           ST64 (pCurDqLayer->pMvd[0][iMbXy][iScan4Idx + 4], LD64 (pMvd));
689           ST64 (pMotionVector[0][iCacheIdx  ], LD64 (pMv));
690           ST64 (pMotionVector[0][iCacheIdx + 6], LD64 (pMv));
691           ST64 (pMvdCache[0][iCacheIdx  ], LD64 (pMvd));
692           ST64 (pMvdCache[0][iCacheIdx + 6], LD64 (pMvd));
693         } else if (SUB_MB_TYPE_8x4 == uiSubMbType) {
694           ST32 ((pMv + 2), LD32 (pMv));
695           ST32 ((pMvd + 2), LD32 (pMvd));
696           ST64 (pCurDqLayer->pDec->pMv[0][iMbXy][iScan4Idx  ], LD64 (pMv));
697           ST64 (pCurDqLayer->pMvd[0][iMbXy][iScan4Idx  ], LD64 (pMvd));
698           ST64 (pMotionVector[0][iCacheIdx  ], LD64 (pMv));
699           ST64 (pMvdCache[0][iCacheIdx  ], LD64 (pMvd));
700         } else if (SUB_MB_TYPE_4x8 == uiSubMbType) {
701           ST32 (pCurDqLayer->pDec->pMv[0][iMbXy][iScan4Idx  ], LD32 (pMv));
702           ST32 (pCurDqLayer->pDec->pMv[0][iMbXy][iScan4Idx + 4], LD32 (pMv));
703           ST32 (pCurDqLayer->pMvd[0][iMbXy][iScan4Idx  ], LD32 (pMvd));
704           ST32 (pCurDqLayer->pMvd[0][iMbXy][iScan4Idx + 4], LD32 (pMvd));
705           ST32 (pMotionVector[0][iCacheIdx  ], LD32 (pMv));
706           ST32 (pMotionVector[0][iCacheIdx + 6], LD32 (pMv));
707           ST32 (pMvdCache[0][iCacheIdx  ], LD32 (pMvd));
708           ST32 (pMvdCache[0][iCacheIdx + 6], LD32 (pMvd));
709         } else {  //SUB_MB_TYPE_4x4
710           ST32 (pCurDqLayer->pDec->pMv[0][iMbXy][iScan4Idx  ], LD32 (pMv));
711           ST32 (pCurDqLayer->pMvd[0][iMbXy][iScan4Idx  ], LD32 (pMvd));
712           ST32 (pMotionVector[0][iCacheIdx  ], LD32 (pMv));
713           ST32 (pMvdCache[0][iCacheIdx  ], LD32 (pMvd));
714         }
715       }
716     }
717   }
718   break;
719   default:
720     break;
721   }
722   return ERR_NONE;
723 }
724 
ParseInterBMotionInfoCabac(PWelsDecoderContext pCtx,PWelsNeighAvail pNeighAvail,uint8_t * pNonZeroCount,int16_t pMotionVector[LIST_A][30][MV_A],int16_t pMvdCache[LIST_A][30][MV_A],int8_t pRefIndex[LIST_A][30],int8_t pDirect[30])725 int32_t ParseInterBMotionInfoCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroCount,
726                                     int16_t pMotionVector[LIST_A][30][MV_A], int16_t pMvdCache[LIST_A][30][MV_A], int8_t pRefIndex[LIST_A][30],
727                                     int8_t pDirect[30]) {
728   PSlice pSlice = &pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer;
729   PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
730   PDqLayer pCurDqLayer = pCtx->pCurDqLayer;
731   int32_t pRefCount[LIST_A];
732   int32_t iMbXy = pCurDqLayer->iMbXyIndex;
733   int16_t pMv[4] = { 0 };
734   int16_t pMvd[4] = { 0 };
735   int8_t iRef[LIST_A] = { 0 };
736   int32_t iPartIdx;
737   int16_t iMinVmv = pSliceHeader->pSps->pSLevelLimits->iMinVmv;
738   int16_t iMaxVmv = pSliceHeader->pSps->pSLevelLimits->iMaxVmv;
739   pRefCount[0] = pSliceHeader->uiRefCount[0];
740   pRefCount[1] = pSliceHeader->uiRefCount[1];
741 
742   MbType mbType = pCurDqLayer->pDec->pMbType[iMbXy];
743 
744   bool bIsPending = GetThreadCount (pCtx) > 1;
745 
746   if (IS_DIRECT (mbType)) {
747 
748     int16_t pMvDirect[LIST_A][2] = { { 0, 0 }, { 0, 0 } };
749     SubMbType subMbType;
750     if (pSliceHeader->iDirectSpatialMvPredFlag) {
751       //predict direct spatial mv
752       int32_t ret = PredMvBDirectSpatial (pCtx, pMvDirect, iRef, subMbType);
753       if (ret != ERR_NONE) {
754         return ret;
755       }
756     } else {
757       //temporal direct 16x16 mode
758       int32_t ret = PredBDirectTemporal (pCtx, pMvDirect, iRef, subMbType);
759       if (ret != ERR_NONE) {
760         return ret;
761       }
762     }
763   } else if (IS_INTER_16x16 (mbType)) {
764     iPartIdx = 0;
765     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
766       iRef[listIdx] = REF_NOT_IN_LIST;
767       if (IS_DIR (mbType, 0, listIdx)) {
768         WELS_READ_VERIFY (ParseRefIdxCabac (pCtx, pNeighAvail, pNonZeroCount, pRefIndex, pDirect, listIdx, iPartIdx,
769                                             pRefCount[listIdx], 0,
770                                             iRef[listIdx]));
771         if ((iRef[listIdx] < 0) || (iRef[listIdx] >= pRefCount[listIdx])
772             || (pCtx->sRefPic.pRefList[listIdx][iRef[listIdx]] == NULL)) { //error ref_idx
773           pCtx->bMbRefConcealed = true;
774           if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
775             iRef[listIdx] = 0;
776             pCtx->iErrorCode |= dsBitstreamError;
777             RETURN_ERR_IF_NULL(pCtx->sRefPic.pRefList[listIdx][iRef[listIdx]]);
778           } else {
779             return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_REF_INDEX);
780           }
781         }
782         pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (pCtx->sRefPic.pRefList[listIdx][iRef[listIdx]]
783                                 && (pCtx->sRefPic.pRefList[listIdx][iRef[listIdx]]->bIsComplete || bIsPending));
784       }
785     }
786     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
787       if (IS_DIR (mbType, 0, listIdx)) {
788         PredMv (pMotionVector, pRefIndex, listIdx, 0, 4, iRef[listIdx], pMv);
789         WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, listIdx, 0, pMvd[0]));
790         WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, listIdx, 1, pMvd[1]));
791         pMv[0] += pMvd[0];
792         pMv[1] += pMvd[1];
793         WELS_CHECK_SE_BOTH_WARNING (pMv[1], iMinVmv, iMaxVmv, "vertical mv");
794       } else {
795         * (uint32_t*)pMv = * (uint32_t*)pMvd = 0;
796       }
797       UpdateP16x16MotionInfo (pCurDqLayer, listIdx, iRef[listIdx], pMv);
798       UpdateP16x16MvdCabac (pCurDqLayer, pMvd, listIdx);
799     }
800   } else if (IS_INTER_16x8 (mbType)) {
801     int8_t ref_idx_list[LIST_A][2] = { {REF_NOT_IN_LIST, REF_NOT_IN_LIST}, { REF_NOT_IN_LIST, REF_NOT_IN_LIST } };
802     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
803       for (int32_t i = 0; i < 2; ++i) {
804         iPartIdx = i << 3;
805         int8_t ref_idx = REF_NOT_IN_LIST;
806         if (IS_DIR (mbType, i, listIdx)) {
807           WELS_READ_VERIFY (ParseRefIdxCabac (pCtx, pNeighAvail, pNonZeroCount, pRefIndex, pDirect, listIdx, iPartIdx,
808                                               pRefCount[listIdx], 0, ref_idx));
809           if ((ref_idx < 0) || (ref_idx >= pRefCount[listIdx])
810               || (pCtx->sRefPic.pRefList[listIdx][ref_idx] == NULL)) { //error ref_idx
811             pCtx->bMbRefConcealed = true;
812             if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
813               ref_idx = 0;
814               pCtx->iErrorCode |= dsBitstreamError;
815               RETURN_ERR_IF_NULL(pCtx->sRefPic.pRefList[listIdx][ref_idx]);
816             } else {
817               return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_REF_INDEX);
818             }
819           }
820           pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (pCtx->sRefPic.pRefList[listIdx][ref_idx]
821                                   && (pCtx->sRefPic.pRefList[listIdx][ref_idx]->bIsComplete || bIsPending));
822         }
823         UpdateP16x8RefIdxCabac (pCurDqLayer, pRefIndex, iPartIdx, ref_idx, listIdx);
824         ref_idx_list[listIdx][i] = ref_idx;
825       }
826     }
827     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
828       for (int32_t i = 0; i < 2; ++i) {
829         iPartIdx = i << 3;
830         int8_t ref_idx = ref_idx_list[listIdx][i];
831         if (IS_DIR (mbType, i, listIdx)) {
832           PredInter16x8Mv (pMotionVector, pRefIndex, listIdx, iPartIdx, ref_idx, pMv);
833           WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, listIdx, 0, pMvd[0]));
834           WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, listIdx, 1, pMvd[1]));
835           pMv[0] += pMvd[0];
836           pMv[1] += pMvd[1];
837           WELS_CHECK_SE_BOTH_WARNING (pMv[1], iMinVmv, iMaxVmv, "vertical mv");
838         } else {
839           * (uint32_t*)pMv = * (uint32_t*)pMvd = 0;
840         }
841         UpdateP16x8MotionInfo (pCurDqLayer, pMotionVector, pRefIndex, listIdx, iPartIdx, ref_idx, pMv);
842         UpdateP16x8MvdCabac (pCurDqLayer, pMvdCache, iPartIdx, pMvd, listIdx);
843       }
844     }
845   } else if (IS_INTER_8x16 (mbType)) {
846     int8_t ref_idx_list[LIST_A][2] = { { REF_NOT_IN_LIST, REF_NOT_IN_LIST }, { REF_NOT_IN_LIST, REF_NOT_IN_LIST } };
847     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
848       for (int32_t i = 0; i < 2; ++i) {
849         iPartIdx = i << 2;
850         int8_t ref_idx = REF_NOT_IN_LIST;
851         if (IS_DIR (mbType, i, listIdx)) {
852           WELS_READ_VERIFY (ParseRefIdxCabac (pCtx, pNeighAvail, pNonZeroCount, pRefIndex, pDirect, listIdx, iPartIdx,
853                                               pRefCount[listIdx], 0, ref_idx));
854           if ((ref_idx < 0) || (ref_idx >= pRefCount[listIdx])
855               || (pCtx->sRefPic.pRefList[listIdx][ref_idx] == NULL)) { //error ref_idx
856             pCtx->bMbRefConcealed = true;
857             if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
858               ref_idx = 0;
859               pCtx->iErrorCode |= dsBitstreamError;
860               RETURN_ERR_IF_NULL(pCtx->sRefPic.pRefList[listIdx][ref_idx]);
861             } else {
862               return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_REF_INDEX);
863             }
864           }
865           pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (pCtx->sRefPic.pRefList[listIdx][ref_idx]
866                                   && (pCtx->sRefPic.pRefList[listIdx][ref_idx]->bIsComplete || bIsPending));
867         }
868         UpdateP8x16RefIdxCabac (pCurDqLayer, pRefIndex, iPartIdx, ref_idx, listIdx);
869         ref_idx_list[listIdx][i] = ref_idx;
870       }
871     }
872     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
873       for (int32_t i = 0; i < 2; ++i) {
874         iPartIdx = i << 2;
875         int8_t ref_idx = ref_idx_list[listIdx][i];
876         if (IS_DIR (mbType, i, listIdx)) {
877           PredInter8x16Mv (pMotionVector, pRefIndex, listIdx, iPartIdx, ref_idx, pMv);
878           WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, listIdx, 0, pMvd[0]));
879           WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, listIdx, 1, pMvd[1]));
880           pMv[0] += pMvd[0];
881           pMv[1] += pMvd[1];
882           WELS_CHECK_SE_BOTH_WARNING (pMv[1], iMinVmv, iMaxVmv, "vertical mv");
883         } else {
884           * (uint32_t*)pMv = * (uint32_t*)pMvd = 0;
885         }
886         UpdateP8x16MotionInfo (pCurDqLayer, pMotionVector, pRefIndex, listIdx, iPartIdx, ref_idx, pMv);
887         UpdateP8x16MvdCabac (pCurDqLayer, pMvdCache, iPartIdx, pMvd, listIdx);
888       }
889     }
890   } else if (IS_Inter_8x8 (mbType)) {
891     int8_t pSubPartCount[4], pPartW[4];
892     uint32_t uiSubMbType;
893     //sub_mb_type, partition
894     int16_t pMvDirect[LIST_A][2] = { {0, 0}, {0, 0} };
895     if (pCtx->sRefPic.pRefList[LIST_1][0] == NULL) {
896       SLogContext* pLogCtx = & (pCtx->sLogCtx);
897       WelsLog (pLogCtx, WELS_LOG_ERROR, "Colocated Ref Picture for B-Slice is lost, B-Slice decoding cannot be continued!");
898       return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_DATA, ERR_INFO_REFERENCE_PIC_LOST);
899     }
900     bool bIsLongRef = pCtx->sRefPic.pRefList[LIST_1][0]->bIsLongRef;
901     const int32_t ref0Count = WELS_MIN (pSliceHeader->uiRefCount[LIST_0], pCtx->sRefPic.uiRefCount[LIST_0]);
902     bool has_direct_called = false;
903     SubMbType directSubMbType = 0;
904     for (int32_t i = 0; i < 4; i++) {
905       WELS_READ_VERIFY (ParseBSubMBTypeCabac (pCtx, pNeighAvail, uiSubMbType));
906       if (uiSubMbType >= 13) { //invalid sub_mb_type
907         return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_SUB_MB_TYPE);
908       }
909 //      pCurDqLayer->pSubMbType[iMbXy][i] = g_ksInterBSubMbTypeInfo[uiSubMbType].iType;
910       pSubPartCount[i] = g_ksInterBSubMbTypeInfo[uiSubMbType].iPartCount;
911       pPartW[i] = g_ksInterBSubMbTypeInfo[uiSubMbType].iPartWidth;
912 
913       // Need modification when B picture add in, reference to 7.3.5
914       if (pSubPartCount[i] > 1)
915         pCurDqLayer->pNoSubMbPartSizeLessThan8x8Flag[iMbXy] = false;
916 
917       if (IS_DIRECT (g_ksInterBSubMbTypeInfo[uiSubMbType].iType)) {
918         if (!has_direct_called) {
919           if (pSliceHeader->iDirectSpatialMvPredFlag) {
920             int32_t ret = PredMvBDirectSpatial (pCtx, pMvDirect, iRef, directSubMbType);
921             if (ret != ERR_NONE) {
922               return ret;
923             }
924 
925           } else {
926             //temporal direct mode
927             int32_t ret = PredBDirectTemporal (pCtx, pMvDirect, iRef, directSubMbType);
928             if (ret != ERR_NONE) {
929               return ret;
930             }
931           }
932           has_direct_called = true;
933         }
934         pCurDqLayer->pSubMbType[iMbXy][i] = directSubMbType;
935         if (IS_SUB_4x4 (pCurDqLayer->pSubMbType[iMbXy][i])) {
936           pSubPartCount[i] = 4;
937           pPartW[i] = 1;
938         }
939       } else {
940         pCurDqLayer->pSubMbType[iMbXy][i] = g_ksInterBSubMbTypeInfo[uiSubMbType].iType;
941       }
942     }
943     for (int32_t i = 0; i < 4; i++) { //Direct 8x8 Ref and mv
944       int16_t iIdx8 = i << 2;
945       if (IS_DIRECT (pCurDqLayer->pSubMbType[iMbXy][i])) {
946         if (pSliceHeader->iDirectSpatialMvPredFlag) {
947           FillSpatialDirect8x8Mv (pCurDqLayer, iIdx8, pSubPartCount[i], pPartW[i], directSubMbType, bIsLongRef, pMvDirect, iRef,
948                                   pMotionVector, pMvdCache);
949         } else {
950           int16_t (*mvColoc)[2] = pCurDqLayer->iColocMv[LIST_0];
951           iRef[LIST_1] = 0;
952           iRef[LIST_0] = 0;
953           const uint8_t uiColoc4Idx = g_kuiScan4[iIdx8];
954           if (!pCurDqLayer->iColocIntra[uiColoc4Idx]) {
955             iRef[LIST_0] = 0;
956             int8_t colocRefIndexL0 = pCurDqLayer->iColocRefIndex[LIST_0][uiColoc4Idx];
957             if (colocRefIndexL0 >= 0) {
958               iRef[LIST_0] = MapColToList0 (pCtx, colocRefIndexL0, ref0Count);
959             } else {
960               mvColoc = pCurDqLayer->iColocMv[LIST_1];
961             }
962           }
963           Update8x8RefIdx (pCurDqLayer, iIdx8, LIST_0, iRef[LIST_0]);
964           Update8x8RefIdx (pCurDqLayer, iIdx8, LIST_1, iRef[LIST_1]);
965           UpdateP8x8RefCacheIdxCabac (pRefIndex, iIdx8, LIST_0, iRef[LIST_0]);
966           UpdateP8x8RefCacheIdxCabac (pRefIndex, iIdx8, LIST_1, iRef[LIST_1]);
967           FillTemporalDirect8x8Mv (pCurDqLayer, iIdx8, pSubPartCount[i], pPartW[i], directSubMbType, iRef, mvColoc, pMotionVector,
968                                    pMvdCache);
969         }
970       }
971     }
972     //ref no-direct
973     int8_t ref_idx_list[LIST_A][4] = { {REF_NOT_IN_LIST, REF_NOT_IN_LIST}, { REF_NOT_IN_LIST, REF_NOT_IN_LIST } };
974     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
975       for (int32_t i = 0; i < 4; i++) {
976         int16_t iIdx8 = i << 2;
977         int32_t subMbType = pCurDqLayer->pSubMbType[iMbXy][i];
978         int8_t iref = REF_NOT_IN_LIST;
979         if (IS_DIRECT (subMbType)) {
980           if (pSliceHeader->iDirectSpatialMvPredFlag) {
981             Update8x8RefIdx (pCurDqLayer, iIdx8, listIdx, iRef[listIdx]);
982             ref_idx_list[listIdx][i] = iRef[listIdx];
983           }
984           UpdateP8x8DirectCabac (pCurDqLayer, iIdx8);
985         } else {
986           if (IS_DIR (subMbType, 0, listIdx)) {
987             WELS_READ_VERIFY (ParseRefIdxCabac (pCtx, pNeighAvail, pNonZeroCount, pRefIndex, pDirect, listIdx, iIdx8,
988                                                 pRefCount[listIdx], 1,
989                                                 iref));
990             if ((iref < 0) || (iref >= pRefCount[listIdx]) || (pCtx->sRefPic.pRefList[listIdx][iref] == NULL)) { //error ref_idx
991               pCtx->bMbRefConcealed = true;
992               if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
993                 iref = 0;
994                 pCtx->iErrorCode |= dsBitstreamError;
995                 RETURN_ERR_IF_NULL(pCtx->sRefPic.pRefList[listIdx][iref]);
996               } else {
997                 return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_REF_INDEX);
998               }
999             }
1000             pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (pCtx->sRefPic.pRefList[listIdx][iref]
1001                                     && (pCtx->sRefPic.pRefList[listIdx][iref]->bIsComplete || bIsPending));
1002           }
1003           Update8x8RefIdx (pCurDqLayer, iIdx8, listIdx, iref);
1004           ref_idx_list[listIdx][i] = iref;
1005         }
1006       }
1007     }
1008     //mv
1009     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
1010       for (int32_t i = 0; i < 4; i++) {
1011         int16_t iIdx8 = i << 2;
1012 
1013         uint32_t subMbType = pCurDqLayer->pSubMbType[iMbXy][i];
1014         if (IS_DIRECT (subMbType) && !pSliceHeader->iDirectSpatialMvPredFlag)
1015           continue;
1016 
1017         int8_t iref = ref_idx_list[listIdx][i];
1018         UpdateP8x8RefCacheIdxCabac (pRefIndex, iIdx8, listIdx, iref);
1019 
1020         if (IS_DIRECT (subMbType))
1021           continue;
1022 
1023         bool is_dir = IS_DIR (subMbType, 0, listIdx) > 0;
1024         int8_t iPartCount = pSubPartCount[i];
1025         int16_t iBlockW = pPartW[i];
1026         uint8_t iScan4Idx, iCacheIdx;
1027         for (int32_t j = 0; j < iPartCount; j++) {
1028           iPartIdx = (i << 2) + j * iBlockW;
1029           iScan4Idx = g_kuiScan4[iPartIdx];
1030           iCacheIdx = g_kuiCache30ScanIdx[iPartIdx];
1031           if (is_dir) {
1032             PredMv (pMotionVector, pRefIndex, listIdx, iPartIdx, iBlockW, iref, pMv);
1033             WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, listIdx, 0, pMvd[0]));
1034             WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, listIdx, 1, pMvd[1]));
1035             pMv[0] += pMvd[0];
1036             pMv[1] += pMvd[1];
1037             WELS_CHECK_SE_BOTH_WARNING (pMv[1], iMinVmv, iMaxVmv, "vertical mv");
1038           } else {
1039             * (uint32_t*)pMv = * (uint32_t*)pMvd = 0;
1040           }
1041           if (IS_SUB_8x8 (subMbType)) { //MB_TYPE_8x8
1042             ST32 ((pMv + 2), LD32 (pMv));
1043             ST32 ((pMvd + 2), LD32 (pMvd));
1044             ST64 (pCurDqLayer->pDec->pMv[listIdx][iMbXy][iScan4Idx], LD64 (pMv));
1045             ST64 (pCurDqLayer->pDec->pMv[listIdx][iMbXy][iScan4Idx + 4], LD64 (pMv));
1046             ST64 (pCurDqLayer->pMvd[listIdx][iMbXy][iScan4Idx], LD64 (pMvd));
1047             ST64 (pCurDqLayer->pMvd[listIdx][iMbXy][iScan4Idx + 4], LD64 (pMvd));
1048             ST64 (pMotionVector[listIdx][iCacheIdx], LD64 (pMv));
1049             ST64 (pMotionVector[listIdx][iCacheIdx + 6], LD64 (pMv));
1050             ST64 (pMvdCache[listIdx][iCacheIdx], LD64 (pMvd));
1051             ST64 (pMvdCache[listIdx][iCacheIdx + 6], LD64 (pMvd));
1052           } else if (IS_SUB_4x4 (subMbType)) { //MB_TYPE_4x4
1053             ST32 (pCurDqLayer->pDec->pMv[listIdx][iMbXy][iScan4Idx], LD32 (pMv));
1054             ST32 (pCurDqLayer->pMvd[listIdx][iMbXy][iScan4Idx], LD32 (pMvd));
1055             ST32 (pMotionVector[listIdx][iCacheIdx], LD32 (pMv));
1056             ST32 (pMvdCache[listIdx][iCacheIdx], LD32 (pMvd));
1057           } else if (IS_SUB_4x8 (subMbType)) { //MB_TYPE_4x8 5, 7, 9
1058             ST32 (pCurDqLayer->pDec->pMv[listIdx][iMbXy][iScan4Idx], LD32 (pMv));
1059             ST32 (pCurDqLayer->pDec->pMv[listIdx][iMbXy][iScan4Idx + 4], LD32 (pMv));
1060             ST32 (pCurDqLayer->pMvd[listIdx][iMbXy][iScan4Idx], LD32 (pMvd));
1061             ST32 (pCurDqLayer->pMvd[listIdx][iMbXy][iScan4Idx + 4], LD32 (pMvd));
1062             ST32 (pMotionVector[listIdx][iCacheIdx], LD32 (pMv));
1063             ST32 (pMotionVector[listIdx][iCacheIdx + 6], LD32 (pMv));
1064             ST32 (pMvdCache[listIdx][iCacheIdx], LD32 (pMvd));
1065             ST32 (pMvdCache[listIdx][iCacheIdx + 6], LD32 (pMvd));
1066           } else { //MB_TYPE_8x4 4, 6, 8
1067             ST32 ((pMv + 2), LD32 (pMv));
1068             ST32 ((pMvd + 2), LD32 (pMvd));
1069             ST64 (pCurDqLayer->pDec->pMv[listIdx][iMbXy][iScan4Idx], LD64 (pMv));
1070             ST64 (pCurDqLayer->pMvd[listIdx][iMbXy][iScan4Idx], LD64 (pMvd));
1071             ST64 (pMotionVector[listIdx][iCacheIdx], LD64 (pMv));
1072             ST64 (pMvdCache[listIdx][iCacheIdx], LD64 (pMvd));
1073           }
1074         }
1075       }
1076     }
1077   }
1078   return ERR_NONE;
1079 }
1080 
ParseRefIdxCabac(PWelsDecoderContext pCtx,PWelsNeighAvail pNeighAvail,uint8_t * nzc,int8_t ref_idx[LIST_A][30],int8_t direct[30],int32_t iListIdx,int32_t iZOrderIdx,int32_t iActiveRefNum,int32_t b8mode,int8_t & iRefIdxVal)1081 int32_t ParseRefIdxCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint8_t* nzc,
1082                           int8_t ref_idx[LIST_A][30], int8_t direct[30],
1083                           int32_t iListIdx, int32_t iZOrderIdx, int32_t iActiveRefNum, int32_t b8mode, int8_t& iRefIdxVal) {
1084   if (iActiveRefNum == 1) {
1085     iRefIdxVal = 0;
1086     return ERR_NONE;
1087   }
1088   uint32_t uiCode;
1089   int32_t iIdxA = 0, iIdxB = 0;
1090   int32_t iCtxInc = 0;
1091   int8_t* pRefIdxInMB = pCtx->pCurDqLayer->pDec->pRefIndex[iListIdx][pCtx->pCurDqLayer->iMbXyIndex];
1092   int8_t* pDirect = pCtx->pCurDqLayer->pDirect[pCtx->pCurDqLayer->iMbXyIndex];
1093   if (iZOrderIdx == 0) {
1094     iIdxB = (pNeighAvail->iTopAvail && pNeighAvail->iTopType != MB_TYPE_INTRA_PCM
1095              && ref_idx[iListIdx][g_kuiCache30ScanIdx[iZOrderIdx] - 6] > 0);
1096     iIdxA = (pNeighAvail->iLeftAvail && pNeighAvail->iLeftType != MB_TYPE_INTRA_PCM
1097              && ref_idx[iListIdx][g_kuiCache30ScanIdx[iZOrderIdx] - 1] > 0);
1098     if (pCtx->eSliceType == B_SLICE) {
1099       if (iIdxB > 0 && direct[g_kuiCache30ScanIdx[iZOrderIdx] - 6] == 0) {
1100         iCtxInc += 2;
1101       }
1102       if (iIdxA > 0 && direct[g_kuiCache30ScanIdx[iZOrderIdx] - 1] == 0) {
1103         iCtxInc++;
1104       }
1105     }
1106   } else if (iZOrderIdx == 4) {
1107     iIdxB = (pNeighAvail->iTopAvail && pNeighAvail->iTopType != MB_TYPE_INTRA_PCM
1108              && ref_idx[iListIdx][g_kuiCache30ScanIdx[iZOrderIdx] - 6] > 0);
1109     iIdxA = pRefIdxInMB[g_kuiScan4[iZOrderIdx] - 1] > 0;
1110     if (pCtx->eSliceType == B_SLICE) {
1111       if (iIdxB > 0 && direct[g_kuiCache30ScanIdx[iZOrderIdx] - 6] == 0) {
1112         iCtxInc += 2;
1113       }
1114       if (iIdxA > 0 && pDirect[g_kuiScan4[iZOrderIdx] - 1] == 0) {
1115         iCtxInc ++;
1116       }
1117     }
1118   } else if (iZOrderIdx == 8) {
1119 
1120     iIdxB = pRefIdxInMB[g_kuiScan4[iZOrderIdx] - 4] > 0;
1121     iIdxA = (pNeighAvail->iLeftAvail && pNeighAvail->iLeftType != MB_TYPE_INTRA_PCM
1122              && ref_idx[iListIdx][g_kuiCache30ScanIdx[iZOrderIdx] - 1] > 0);
1123     if (pCtx->eSliceType == B_SLICE) {
1124       if (iIdxB > 0 && pDirect[g_kuiScan4[iZOrderIdx] - 4] == 0) {
1125         iCtxInc += 2;
1126       }
1127       if (iIdxA > 0 && direct[g_kuiCache30ScanIdx[iZOrderIdx] - 1] == 0) {
1128         iCtxInc++;
1129       }
1130     }
1131   } else {
1132     iIdxB = pRefIdxInMB[g_kuiScan4[iZOrderIdx] - 4] > 0;
1133     iIdxA = pRefIdxInMB[g_kuiScan4[iZOrderIdx] - 1] > 0;
1134     if (pCtx->eSliceType == B_SLICE) {
1135       if (iIdxB > 0 && pDirect[g_kuiScan4[iZOrderIdx] - 4] == 0) {
1136         iCtxInc += 2;
1137       }
1138       if (iIdxA > 0 && pDirect[g_kuiScan4[iZOrderIdx] - 1] == 0) {
1139         iCtxInc++;
1140       }
1141     }
1142   }
1143   if (pCtx->eSliceType != B_SLICE) {
1144     iCtxInc = iIdxA + (iIdxB << 1);
1145   }
1146 
1147   WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_REF_NO + iCtxInc, uiCode));
1148   if (uiCode) {
1149     WELS_READ_VERIFY (DecodeUnaryBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_REF_NO + 4, 1, uiCode));
1150     ++uiCode;
1151   }
1152   iRefIdxVal = (int8_t) uiCode;
1153   return ERR_NONE;
1154 }
1155 
ParseMvdInfoCabac(PWelsDecoderContext pCtx,PWelsNeighAvail pNeighAvail,int8_t pRefIndex[LIST_A][30],int16_t pMvdCache[LIST_A][30][2],int32_t index,int8_t iListIdx,int8_t iMvComp,int16_t & iMvdVal)1156 int32_t ParseMvdInfoCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, int8_t pRefIndex[LIST_A][30],
1157                            int16_t pMvdCache[LIST_A][30][2], int32_t index, int8_t iListIdx, int8_t iMvComp, int16_t& iMvdVal) {
1158   uint32_t uiCode;
1159   int32_t iIdxA = 0;
1160   //int32_t sym;
1161   PWelsCabacCtx pBinCtx = pCtx->pCabacCtx + NEW_CTX_OFFSET_MVD + iMvComp * CTX_NUM_MVD;
1162   iMvdVal = 0;
1163 
1164   if (pRefIndex[iListIdx][g_kuiCache30ScanIdx[index] - 6] >= 0)
1165     iIdxA = WELS_ABS (pMvdCache[iListIdx][g_kuiCache30ScanIdx[index] - 6][iMvComp]);
1166   if (pRefIndex[iListIdx][g_kuiCache30ScanIdx[index] - 1] >= 0)
1167     iIdxA += WELS_ABS (pMvdCache[iListIdx][g_kuiCache30ScanIdx[index] - 1][iMvComp]);
1168 
1169   int32_t iCtxInc = 0;
1170   if (iIdxA >= 3)
1171     iCtxInc = 1 + (iIdxA > 32);
1172 
1173   WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine,  pBinCtx + iCtxInc, uiCode));
1174   if (uiCode) {
1175     WELS_READ_VERIFY (DecodeUEGMvCabac (pCtx->pCabacDecEngine, pBinCtx + 3, 3, uiCode));
1176     iMvdVal = (int16_t) (uiCode + 1);
1177     WELS_READ_VERIFY (DecodeBypassCabac (pCtx->pCabacDecEngine, uiCode));
1178     if (uiCode) {
1179       iMvdVal = -iMvdVal;
1180     }
1181   } else {
1182     iMvdVal = 0;
1183   }
1184   return ERR_NONE;
1185 }
1186 
ParseCbpInfoCabac(PWelsDecoderContext pCtx,PWelsNeighAvail pNeighAvail,uint32_t & uiCbp)1187 int32_t ParseCbpInfoCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint32_t& uiCbp) {
1188   int32_t iIdxA = 0, iIdxB = 0, pALeftMb[2], pBTopMb[2];
1189   uiCbp = 0;
1190   uint32_t pCbpBit[6];
1191   int32_t iCtxInc;
1192 
1193   //Luma: bit by bit for 4 8x8 blocks in z-order
1194   pBTopMb[0]  = pNeighAvail->iTopAvail  && pNeighAvail->iTopType  != MB_TYPE_INTRA_PCM
1195                 && ((pNeighAvail->iTopCbp  & (1 << 2)) == 0);
1196   pBTopMb[1]  = pNeighAvail->iTopAvail  && pNeighAvail->iTopType  != MB_TYPE_INTRA_PCM
1197                 && ((pNeighAvail->iTopCbp  & (1 << 3)) == 0);
1198   pALeftMb[0] = pNeighAvail->iLeftAvail && pNeighAvail->iLeftType != MB_TYPE_INTRA_PCM
1199                 && ((pNeighAvail->iLeftCbp & (1 << 1)) == 0);
1200   pALeftMb[1] = pNeighAvail->iLeftAvail && pNeighAvail->iLeftType != MB_TYPE_INTRA_PCM
1201                 && ((pNeighAvail->iLeftCbp & (1 << 3)) == 0);
1202 
1203   //left_top 8x8 block
1204   iCtxInc = pALeftMb[0] + (pBTopMb[0] << 1);
1205   WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_CBP + iCtxInc, pCbpBit[0]));
1206   if (pCbpBit[0])
1207     uiCbp += 0x01;
1208 
1209   //right_top 8x8 block
1210   iIdxA = !pCbpBit[0];
1211   iCtxInc = iIdxA + (pBTopMb[1] << 1);
1212   WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_CBP + iCtxInc, pCbpBit[1]));
1213   if (pCbpBit[1])
1214     uiCbp += 0x02;
1215 
1216   //left_bottom 8x8 block
1217   iIdxB = !pCbpBit[0];
1218   iCtxInc = pALeftMb[1] + (iIdxB << 1);
1219   WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_CBP + iCtxInc, pCbpBit[2]));
1220   if (pCbpBit[2])
1221     uiCbp += 0x04;
1222 
1223   //right_bottom 8x8 block
1224   iIdxB = !pCbpBit[1];
1225   iIdxA = !pCbpBit[2];
1226   iCtxInc = iIdxA + (iIdxB << 1);
1227   WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_CBP + iCtxInc, pCbpBit[3]));
1228   if (pCbpBit[3])
1229     uiCbp += 0x08;
1230 
1231   if (pCtx->pSps->uiChromaFormatIdc == 0)//monochroma
1232     return ERR_NONE;
1233 
1234 
1235   //Chroma: bit by bit
1236   iIdxB = pNeighAvail->iTopAvail  && (pNeighAvail->iTopType  == MB_TYPE_INTRA_PCM || (pNeighAvail->iTopCbp  >> 4));
1237   iIdxA = pNeighAvail->iLeftAvail && (pNeighAvail->iLeftType == MB_TYPE_INTRA_PCM || (pNeighAvail->iLeftCbp >> 4));
1238 
1239   //BitIdx = 0
1240   iCtxInc = iIdxA + (iIdxB << 1);
1241   WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_CBP + CTX_NUM_CBP + iCtxInc,
1242                                     pCbpBit[4]));
1243 
1244   //BitIdx = 1
1245   if (pCbpBit[4]) {
1246     iIdxB = pNeighAvail->iTopAvail  && (pNeighAvail->iTopType  == MB_TYPE_INTRA_PCM || (pNeighAvail->iTopCbp  >> 4) == 2);
1247     iIdxA = pNeighAvail->iLeftAvail && (pNeighAvail->iLeftType == MB_TYPE_INTRA_PCM || (pNeighAvail->iLeftCbp >> 4) == 2);
1248     iCtxInc = iIdxA + (iIdxB << 1);
1249     WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine,
1250                                       pCtx->pCabacCtx + NEW_CTX_OFFSET_CBP + 2 * CTX_NUM_CBP + iCtxInc,
1251                                       pCbpBit[5]));
1252     uiCbp += 1 << (4 + pCbpBit[5]);
1253 
1254   }
1255 
1256   return ERR_NONE;
1257 }
1258 
ParseDeltaQpCabac(PWelsDecoderContext pCtx,int32_t & iQpDelta)1259 int32_t ParseDeltaQpCabac (PWelsDecoderContext pCtx, int32_t& iQpDelta) {
1260   uint32_t uiCode;
1261   PSlice pCurrSlice = & (pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer);
1262   iQpDelta = 0;
1263   PWelsCabacCtx pBinCtx = pCtx->pCabacCtx + NEW_CTX_OFFSET_DELTA_QP;
1264   int32_t iCtxInc = (pCurrSlice->iLastDeltaQp != 0);
1265   WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pBinCtx + iCtxInc, uiCode));
1266   if (uiCode != 0) {
1267     WELS_READ_VERIFY (DecodeUnaryBinCabac (pCtx->pCabacDecEngine, pBinCtx + 2, 1, uiCode));
1268     uiCode++;
1269     iQpDelta = (uiCode + 1) >> 1;
1270     if ((uiCode & 1) == 0)
1271       iQpDelta = - iQpDelta;
1272   }
1273   pCurrSlice->iLastDeltaQp = iQpDelta;
1274   return ERR_NONE;
1275 }
1276 
ParseCbfInfoCabac(PWelsNeighAvail pNeighAvail,uint8_t * pNzcCache,int32_t iZIndex,int32_t iResProperty,PWelsDecoderContext pCtx,uint32_t & uiCbfBit)1277 int32_t ParseCbfInfoCabac (PWelsNeighAvail pNeighAvail, uint8_t* pNzcCache, int32_t iZIndex, int32_t iResProperty,
1278                            PWelsDecoderContext pCtx, uint32_t& uiCbfBit) {
1279   int8_t nA, nB/*, zigzag_idx = 0*/;
1280   int32_t iCurrBlkXy = pCtx->pCurDqLayer->iMbXyIndex;
1281   int32_t iTopBlkXy = iCurrBlkXy - pCtx->pCurDqLayer->iMbWidth; //default value: MB neighboring
1282   int32_t iLeftBlkXy = iCurrBlkXy - 1; //default value: MB neighboring
1283   uint16_t* pCbfDc = pCtx->pCurDqLayer->pCbfDc;
1284   uint32_t* pMbType = pCtx->pCurDqLayer->pDec->pMbType;
1285   int32_t iCtxInc;
1286   uiCbfBit = 0;
1287   nA = nB = (int8_t)!!IS_INTRA (pMbType[iCurrBlkXy]);
1288 
1289   if (iResProperty == I16_LUMA_DC || iResProperty == CHROMA_DC_U || iResProperty == CHROMA_DC_V) { //DC
1290     if (pNeighAvail->iTopAvail)
1291       nB = (pMbType[iTopBlkXy] == MB_TYPE_INTRA_PCM) || ((pCbfDc[iTopBlkXy] >> iResProperty) & 1);
1292     if (pNeighAvail->iLeftAvail)
1293       nA = (pMbType[iLeftBlkXy] == MB_TYPE_INTRA_PCM) || ((pCbfDc[iLeftBlkXy] >> iResProperty) & 1);
1294     iCtxInc = nA + (nB << 1);
1295     WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine,
1296                                       pCtx->pCabacCtx + NEW_CTX_OFFSET_CBF + g_kBlockCat2CtxOffsetCBF[iResProperty] + iCtxInc, uiCbfBit));
1297     if (uiCbfBit)
1298       pCbfDc[iCurrBlkXy] |= (1 << iResProperty);
1299   } else { //AC
1300     //for 4x4 blk, make sure blk-idx is correct
1301     if (pNzcCache[g_kCacheNzcScanIdx[iZIndex] - 8] != 0xff) { //top blk available
1302       if (g_kTopBlkInsideMb[iZIndex])
1303         iTopBlkXy = iCurrBlkXy;
1304       nB = pNzcCache[g_kCacheNzcScanIdx[iZIndex] - 8] || pMbType[iTopBlkXy]  == MB_TYPE_INTRA_PCM;
1305     }
1306     if (pNzcCache[g_kCacheNzcScanIdx[iZIndex] - 1] != 0xff) { //left blk available
1307       if (g_kLeftBlkInsideMb[iZIndex])
1308         iLeftBlkXy = iCurrBlkXy;
1309       nA = pNzcCache[g_kCacheNzcScanIdx[iZIndex] - 1] || pMbType[iLeftBlkXy] == MB_TYPE_INTRA_PCM;
1310     }
1311 
1312     iCtxInc = nA + (nB << 1);
1313     WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine,
1314                                       pCtx->pCabacCtx + NEW_CTX_OFFSET_CBF + g_kBlockCat2CtxOffsetCBF[iResProperty] + iCtxInc, uiCbfBit));
1315   }
1316   return ERR_NONE;
1317 }
1318 
ParseSignificantMapCabac(int32_t * pSignificantMap,int32_t iResProperty,PWelsDecoderContext pCtx,uint32_t & uiCoeffNum)1319 int32_t ParseSignificantMapCabac (int32_t* pSignificantMap, int32_t iResProperty, PWelsDecoderContext pCtx,
1320                                   uint32_t& uiCoeffNum) {
1321   uint32_t uiCode;
1322 
1323   PWelsCabacCtx pMapCtx  = pCtx->pCabacCtx + (iResProperty == LUMA_DC_AC_8 ? NEW_CTX_OFFSET_MAP_8x8 : NEW_CTX_OFFSET_MAP)
1324                            + g_kBlockCat2CtxOffsetMap [iResProperty];
1325   PWelsCabacCtx pLastCtx = pCtx->pCabacCtx + (iResProperty == LUMA_DC_AC_8 ? NEW_CTX_OFFSET_LAST_8x8 :
1326                            NEW_CTX_OFFSET_LAST) + g_kBlockCat2CtxOffsetLast[iResProperty];
1327 
1328 
1329   int32_t i;
1330   uiCoeffNum = 0;
1331   int32_t i0 = 0;
1332   int32_t i1 = g_kMaxPos[iResProperty];
1333 
1334   int32_t iCtx;
1335 
1336   for (i = i0; i < i1; ++i) {
1337     iCtx = (iResProperty == LUMA_DC_AC_8 ? g_kuiIdx2CtxSignificantCoeffFlag8x8[i] : i);
1338     //read significant
1339     WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pMapCtx + iCtx, uiCode));
1340     if (uiCode) {
1341       * (pSignificantMap++) = 1;
1342       ++ uiCoeffNum;
1343       //read last significant
1344       iCtx = (iResProperty == LUMA_DC_AC_8 ? g_kuiIdx2CtxLastSignificantCoeffFlag8x8[i] : i);
1345       WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pLastCtx + iCtx, uiCode));
1346       if (uiCode) {
1347         memset (pSignificantMap, 0, (i1 - i) * sizeof (int32_t));
1348         return ERR_NONE;
1349       }
1350     } else
1351       * (pSignificantMap++) = 0;
1352   }
1353 
1354   //deal with last pSignificantMap if no data
1355   //if(i < i1+1)
1356   {
1357     *pSignificantMap = 1;
1358     ++uiCoeffNum;
1359   }
1360 
1361   return ERR_NONE;
1362 }
1363 
ParseSignificantCoeffCabac(int32_t * pSignificant,int32_t iResProperty,PWelsDecoderContext pCtx)1364 int32_t ParseSignificantCoeffCabac (int32_t* pSignificant, int32_t iResProperty, PWelsDecoderContext pCtx) {
1365   uint32_t uiCode;
1366   PWelsCabacCtx pOneCtx = pCtx->pCabacCtx + (iResProperty == LUMA_DC_AC_8 ? NEW_CTX_OFFSET_ONE_8x8 : NEW_CTX_OFFSET_ONE) +
1367                           g_kBlockCat2CtxOffsetOne[iResProperty];
1368   PWelsCabacCtx pAbsCtx = pCtx->pCabacCtx + (iResProperty == LUMA_DC_AC_8 ? NEW_CTX_OFFSET_ABS_8x8 : NEW_CTX_OFFSET_ABS) +
1369                           g_kBlockCat2CtxOffsetAbs[iResProperty];
1370 
1371   const int16_t iMaxType = g_kMaxC2[iResProperty];
1372   int32_t i = g_kMaxPos[iResProperty];
1373   int32_t* pCoff = pSignificant + i;
1374   int32_t c1 = 1;
1375   int32_t c2 = 0;
1376   for (; i >= 0; --i) {
1377     if (*pCoff != 0) {
1378       WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pOneCtx + c1, uiCode));
1379       *pCoff += uiCode;
1380       if (*pCoff == 2) {
1381         WELS_READ_VERIFY (DecodeUEGLevelCabac (pCtx->pCabacDecEngine, pAbsCtx + c2, uiCode));
1382         *pCoff += uiCode;
1383         ++c2;
1384         c2 = WELS_MIN (c2, iMaxType);
1385         c1 = 0;
1386       } else if (c1) {
1387         ++c1;
1388         c1 = WELS_MIN (c1, 4);
1389       }
1390       WELS_READ_VERIFY (DecodeBypassCabac (pCtx->pCabacDecEngine, uiCode));
1391       if (uiCode)
1392         *pCoff = - *pCoff;
1393     }
1394     pCoff--;
1395   }
1396   return ERR_NONE;
1397 }
1398 
ParseResidualBlockCabac8x8(PWelsNeighAvail pNeighAvail,uint8_t * pNonZeroCountCache,SBitStringAux * pBsAux,int32_t iIndex,int32_t iMaxNumCoeff,const uint8_t * pScanTable,int32_t iResProperty,short * sTCoeff,uint8_t uiQp,PWelsDecoderContext pCtx)1399 int32_t ParseResidualBlockCabac8x8 (PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroCountCache, SBitStringAux* pBsAux,
1400                                     int32_t iIndex, int32_t iMaxNumCoeff, const uint8_t* pScanTable, int32_t iResProperty,
1401                                     short* sTCoeff, /*int mb_mode*/ uint8_t uiQp, PWelsDecoderContext pCtx) {
1402   uint32_t uiTotalCoeffNum = 0;
1403   uint32_t uiCbpBit;
1404   int32_t pSignificantMap[64] = {0};
1405 
1406   int32_t iMbResProperty = 0;
1407   GetMbResProperty (&iMbResProperty, &iResProperty, false);
1408   const uint16_t* pDeQuantMul = (pCtx->bUseScalingList) ? pCtx->pDequant_coeff8x8[iMbResProperty - 6][uiQp] :
1409                                 g_kuiDequantCoeff8x8[uiQp];
1410 
1411   uiCbpBit = 1; // for 8x8, MaxNumCoeff == 64 && uiCbpBit == 1
1412   if (uiCbpBit) { //has coeff
1413     WELS_READ_VERIFY (ParseSignificantMapCabac (pSignificantMap, iResProperty, pCtx, uiTotalCoeffNum));
1414     WELS_READ_VERIFY (ParseSignificantCoeffCabac (pSignificantMap, iResProperty, pCtx));
1415   }
1416 
1417   pNonZeroCountCache[g_kCacheNzcScanIdx[iIndex]] =
1418     pNonZeroCountCache[g_kCacheNzcScanIdx[iIndex + 1]] =
1419       pNonZeroCountCache[g_kCacheNzcScanIdx[iIndex + 2]] =
1420         pNonZeroCountCache[g_kCacheNzcScanIdx[iIndex + 3]] = (uint8_t)uiTotalCoeffNum;
1421   if (uiTotalCoeffNum == 0) {
1422     return ERR_NONE;
1423   }
1424   int32_t j = 0, i;
1425   if (iResProperty == LUMA_DC_AC_8) {
1426     do {
1427       if (pSignificantMap[j] != 0) {
1428         i = pScanTable[ j ];
1429         sTCoeff[i] = uiQp >= 36 ? ((pSignificantMap[j] * pDeQuantMul[i]) * (1 << (uiQp / 6 - 6))) : ((
1430                        pSignificantMap[j] * pDeQuantMul[i] + (1 << (5 - uiQp / 6))) >> (6 - uiQp / 6));
1431       }
1432       ++j;
1433     } while (j < 64);
1434   }
1435 
1436   return ERR_NONE;
1437 }
1438 
ParseResidualBlockCabac(PWelsNeighAvail pNeighAvail,uint8_t * pNonZeroCountCache,SBitStringAux * pBsAux,int32_t iIndex,int32_t iMaxNumCoeff,const uint8_t * pScanTable,int32_t iResProperty,short * sTCoeff,uint8_t uiQp,PWelsDecoderContext pCtx)1439 int32_t ParseResidualBlockCabac (PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroCountCache, SBitStringAux* pBsAux,
1440                                  int32_t iIndex, int32_t iMaxNumCoeff,
1441                                  const uint8_t* pScanTable, int32_t iResProperty, short* sTCoeff, /*int mb_mode*/ uint8_t uiQp,
1442                                  PWelsDecoderContext pCtx) {
1443   int32_t iCurNzCacheIdx;
1444   uint32_t uiTotalCoeffNum = 0;
1445   uint32_t uiCbpBit;
1446   int32_t pSignificantMap[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1447 
1448   int32_t iMbResProperty = 0;
1449   GetMbResProperty (&iMbResProperty, &iResProperty, false);
1450   const uint16_t* pDeQuantMul = (pCtx->bUseScalingList) ? pCtx->pDequant_coeff4x4[iMbResProperty][uiQp] :
1451                                 g_kuiDequantCoeff[uiQp];
1452 
1453   WELS_READ_VERIFY (ParseCbfInfoCabac (pNeighAvail, pNonZeroCountCache, iIndex, iResProperty, pCtx, uiCbpBit));
1454   if (uiCbpBit) { //has coeff
1455     WELS_READ_VERIFY (ParseSignificantMapCabac (pSignificantMap, iResProperty, pCtx, uiTotalCoeffNum));
1456     WELS_READ_VERIFY (ParseSignificantCoeffCabac (pSignificantMap, iResProperty, pCtx));
1457   }
1458 
1459   iCurNzCacheIdx = g_kCacheNzcScanIdx[iIndex];
1460   pNonZeroCountCache[iCurNzCacheIdx] = (uint8_t)uiTotalCoeffNum;
1461   if (uiTotalCoeffNum == 0) {
1462     return ERR_NONE;
1463   }
1464   int32_t j = 0;
1465   if (iResProperty == I16_LUMA_DC) {
1466     do {
1467       sTCoeff[pScanTable[j]] = pSignificantMap[j];
1468       ++j;
1469     } while (j < 16);
1470     WelsLumaDcDequantIdct (sTCoeff, uiQp, pCtx);
1471   } else if (iResProperty == CHROMA_DC_U || iResProperty == CHROMA_DC_V) {
1472     do {
1473       sTCoeff[pScanTable[j]] = pSignificantMap[j];
1474       ++j;
1475     } while (j < 4);
1476     //iHadamard2x2
1477     WelsChromaDcIdct (sTCoeff);
1478     //scaling
1479     if (!pCtx->bUseScalingList) {
1480       for (j = 0; j < 4; ++j) {
1481         sTCoeff[pScanTable[j]] = (int16_t) ((int64_t)sTCoeff[pScanTable[j]] * (int64_t)pDeQuantMul[0] >> 1);
1482       }
1483     } else { //with scaling list
1484       for (j = 0; j < 4; ++j) {
1485         sTCoeff[pScanTable[j]] = (int16_t) ((int64_t)sTCoeff[pScanTable[j]] * (int64_t)pDeQuantMul[0] >> 5);
1486       }
1487     }
1488   } else { //luma ac, chroma ac
1489     do {
1490       if (pSignificantMap[j] != 0) {
1491         if (!pCtx->bUseScalingList) {
1492           sTCoeff[pScanTable[j]] = pSignificantMap[j] * pDeQuantMul[pScanTable[j] & 0x07];
1493         } else {
1494           sTCoeff[pScanTable[j]] = (int16_t) (((int64_t)pSignificantMap[j] * (int64_t)pDeQuantMul[pScanTable[j]] + 8) >> 4);
1495         }
1496       }
1497       ++j;
1498     } while (j < 16);
1499   }
1500   return ERR_NONE;
1501 }
1502 
ParseIPCMInfoCabac(PWelsDecoderContext pCtx)1503 int32_t ParseIPCMInfoCabac (PWelsDecoderContext pCtx) {
1504   int32_t i;
1505   PWelsCabacDecEngine pCabacDecEngine = pCtx->pCabacDecEngine;
1506   SBitStringAux* pBsAux = pCtx->pCurDqLayer->pBitStringAux;
1507   SDqLayer* pCurDqLayer = pCtx->pCurDqLayer;
1508   int32_t iDstStrideLuma = pCurDqLayer->pDec->iLinesize[0];
1509   int32_t iDstStrideChroma = pCurDqLayer->pDec->iLinesize[1];
1510   int32_t iMbX = pCurDqLayer->iMbX;
1511   int32_t iMbY = pCurDqLayer->iMbY;
1512   int32_t iMbXy = pCurDqLayer->iMbXyIndex;
1513 
1514   int32_t iMbOffsetLuma = (iMbX + iMbY * iDstStrideLuma) << 4;
1515   int32_t iMbOffsetChroma = (iMbX + iMbY * iDstStrideChroma) << 3;
1516 
1517   uint8_t* pMbDstY = pCtx->pDec->pData[0] + iMbOffsetLuma;
1518   uint8_t* pMbDstU = pCtx->pDec->pData[1] + iMbOffsetChroma;
1519   uint8_t* pMbDstV = pCtx->pDec->pData[2] + iMbOffsetChroma;
1520 
1521   uint8_t* pPtrSrc;
1522 
1523   pCurDqLayer->pDec->pMbType[iMbXy] = MB_TYPE_INTRA_PCM;
1524   RestoreCabacDecEngineToBS (pCabacDecEngine, pBsAux);
1525   intX_t iBytesLeft = pBsAux->pEndBuf - pBsAux->pCurBuf;
1526   if (iBytesLeft < 384) {
1527     return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_CABAC_NO_BS_TO_READ);
1528   }
1529   pPtrSrc = pBsAux->pCurBuf;
1530   if (!pCtx->pParam->bParseOnly) {
1531     for (i = 0; i < 16; i++) {   //luma
1532       memcpy (pMbDstY, pPtrSrc, 16);
1533       pMbDstY += iDstStrideLuma;
1534       pPtrSrc += 16;
1535     }
1536     for (i = 0; i < 8; i++) {   //cb
1537       memcpy (pMbDstU, pPtrSrc, 8);
1538       pMbDstU += iDstStrideChroma;
1539       pPtrSrc += 8;
1540     }
1541     for (i = 0; i < 8; i++) {   //cr
1542       memcpy (pMbDstV, pPtrSrc, 8);
1543       pMbDstV += iDstStrideChroma;
1544       pPtrSrc += 8;
1545     }
1546   }
1547 
1548   pBsAux->pCurBuf += 384;
1549 
1550   pCurDqLayer->pLumaQp[iMbXy] = 0;
1551   pCurDqLayer->pChromaQp[iMbXy][0] = pCurDqLayer->pChromaQp[iMbXy][1] = 0;
1552   memset (pCurDqLayer->pNzc[iMbXy], 16, sizeof (pCurDqLayer->pNzc[iMbXy]));
1553 
1554   //step 4: cabac engine init
1555   WELS_READ_VERIFY (InitReadBits (pBsAux, 1));
1556   WELS_READ_VERIFY (InitCabacDecEngineFromBS (pCabacDecEngine, pBsAux));
1557   return ERR_NONE;
1558 }
UpdateP8x8RefCacheIdxCabac(int8_t pRefIndex[LIST_A][30],const int16_t & iPartIdx,const int32_t & listIdx,const int8_t & iRef)1559 void    UpdateP8x8RefCacheIdxCabac (int8_t pRefIndex[LIST_A][30], const int16_t& iPartIdx,
1560                                     const int32_t& listIdx, const int8_t& iRef) {
1561   const uint8_t uiCacheIdx = g_kuiCache30ScanIdx[iPartIdx];
1562   pRefIndex[listIdx][uiCacheIdx] = pRefIndex[listIdx][uiCacheIdx + 1] = pRefIndex[listIdx][uiCacheIdx + 6] =
1563                                      pRefIndex[listIdx][uiCacheIdx + 7] = iRef;
1564 }
1565 }
1566