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    svc_set_mb_syn_cabac.cpp
33  *
34  * \brief   wrtie cabac syntax
35  *
36  * \date    9/28/2014 Created
37  *
38  *************************************************************************************
39  */
40 #include "svc_set_mb_syn.h"
41 #include "set_mb_syn_cabac.h"
42 #include "svc_enc_golomb.h"
43 
44 using namespace WelsEnc;
45 
46 namespace {
47 
48 static const uint16_t uiSignificantCoeffFlagOffset[5] = {0, 15, 29, 44, 47};
49 static const uint16_t uiLastCoeffFlagOffset[5] = {0, 15, 29, 44, 47};
50 static const uint16_t uiCoeffAbsLevelMinus1Offset[5] = {0, 10, 20, 30, 39};
51 static const uint16_t uiCodecBlockFlagOffset[5] = {0, 4, 8, 12, 16};
52 
53 
WelsCabacMbType(SCabacCtx * pCabacCtx,SMB * pCurMb,SMbCache * pMbCache,int32_t iMbWidth,EWelsSliceType eSliceType)54 static void WelsCabacMbType (SCabacCtx* pCabacCtx, SMB* pCurMb, SMbCache* pMbCache, int32_t iMbWidth,
55                              EWelsSliceType eSliceType) {
56 
57   if (eSliceType == I_SLICE) {
58     uint32_t uiNeighborAvail = pCurMb->uiNeighborAvail;
59     SMB* pLeftMb = pCurMb - 1 ;
60     SMB* pTopMb = pCurMb - iMbWidth;
61     int32_t iCtx = 3;
62     if ((uiNeighborAvail & LEFT_MB_POS) && !IS_INTRA4x4 (pLeftMb->uiMbType))
63       iCtx++;
64     if ((uiNeighborAvail & TOP_MB_POS) && !IS_INTRA4x4 (pTopMb->uiMbType))  //TOP MB
65       iCtx++;
66 
67     if (pCurMb->uiMbType == MB_TYPE_INTRA4x4) {
68       WelsCabacEncodeDecision (pCabacCtx, iCtx, 0);
69     } else {
70       int32_t iCbpChroma = pCurMb->uiCbp >> 4;
71       int32_t iCbpLuma   = pCurMb->uiCbp & 15;
72       int32_t iPredMode = g_kiMapModeI16x16[pMbCache->uiLumaI16x16Mode];
73 
74       WelsCabacEncodeDecision (pCabacCtx, iCtx, 1);
75       WelsCabacEncodeTerminate (pCabacCtx, 0);
76       if (iCbpLuma)
77         WelsCabacEncodeDecision (pCabacCtx, 6, 1);
78       else
79         WelsCabacEncodeDecision (pCabacCtx, 6, 0);
80 
81       if (iCbpChroma == 0)
82         WelsCabacEncodeDecision (pCabacCtx, 7, 0);
83       else {
84         WelsCabacEncodeDecision (pCabacCtx, 7, 1);
85         WelsCabacEncodeDecision (pCabacCtx, 8, iCbpChroma >> 1);
86       }
87       WelsCabacEncodeDecision (pCabacCtx, 9, iPredMode >> 1);
88       WelsCabacEncodeDecision (pCabacCtx, 10, iPredMode & 1);
89     }
90   } else if (eSliceType == P_SLICE) {
91     uint32_t uiMbType = pCurMb->uiMbType;
92     if (uiMbType == MB_TYPE_16x16) {
93       WelsCabacEncodeDecision (pCabacCtx, 14, 0);
94       WelsCabacEncodeDecision (pCabacCtx, 15, 0);
95       WelsCabacEncodeDecision (pCabacCtx, 16, 0);
96     } else if ((uiMbType == MB_TYPE_16x8) || (uiMbType == MB_TYPE_8x16)) {
97 
98       WelsCabacEncodeDecision (pCabacCtx, 14, 0);
99       WelsCabacEncodeDecision (pCabacCtx, 15, 1);
100       WelsCabacEncodeDecision (pCabacCtx, 17, pCurMb->uiMbType == MB_TYPE_16x8);
101 
102     } else if ((uiMbType  == MB_TYPE_8x8) || (uiMbType  == MB_TYPE_8x8_REF0)) {
103       WelsCabacEncodeDecision (pCabacCtx, 14, 0);
104       WelsCabacEncodeDecision (pCabacCtx, 15, 0);
105       WelsCabacEncodeDecision (pCabacCtx, 16, 1);
106     } else if (pCurMb->uiMbType == MB_TYPE_INTRA4x4) {
107       WelsCabacEncodeDecision (pCabacCtx, 14, 1);
108       WelsCabacEncodeDecision (pCabacCtx, 17, 0);
109     } else {
110 
111       int32_t iCbpChroma = pCurMb->uiCbp >> 4;
112       int32_t iCbpLuma   = pCurMb->uiCbp & 15;
113       int32_t iPredMode = g_kiMapModeI16x16[pMbCache->uiLumaI16x16Mode];
114       //prefix
115       WelsCabacEncodeDecision (pCabacCtx, 14, 1);
116 
117       //suffix
118       WelsCabacEncodeDecision (pCabacCtx, 17, 1);
119       WelsCabacEncodeTerminate (pCabacCtx, 0);
120       if (iCbpLuma)
121         WelsCabacEncodeDecision (pCabacCtx, 18, 1);
122       else
123         WelsCabacEncodeDecision (pCabacCtx, 18, 0);
124       if (iCbpChroma == 0)
125         WelsCabacEncodeDecision (pCabacCtx, 19, 0);
126       else {
127         WelsCabacEncodeDecision (pCabacCtx, 19, 1);
128         WelsCabacEncodeDecision (pCabacCtx, 19, iCbpChroma >> 1);
129       }
130       WelsCabacEncodeDecision (pCabacCtx, 20, iPredMode >> 1);
131       WelsCabacEncodeDecision (pCabacCtx, 20, iPredMode & 1);
132 
133     }
134   }
135 
136 }
WelsCabacMbIntra4x4PredMode(SCabacCtx * pCabacCtx,SMbCache * pMbCache)137 void WelsCabacMbIntra4x4PredMode (SCabacCtx* pCabacCtx, SMbCache* pMbCache) {
138 
139   for (int32_t iMode = 0; iMode < 16; iMode++) {
140 
141     bool bPredFlag = pMbCache->pPrevIntra4x4PredModeFlag[iMode];
142     int8_t iRemMode  = pMbCache->pRemIntra4x4PredModeFlag[iMode];
143 
144     if (bPredFlag)
145       WelsCabacEncodeDecision (pCabacCtx, 68, 1);
146     else {
147       WelsCabacEncodeDecision (pCabacCtx, 68, 0);
148 
149       WelsCabacEncodeDecision (pCabacCtx, 69, iRemMode & 0x01);
150       WelsCabacEncodeDecision (pCabacCtx, 69, (iRemMode >> 1) & 0x01);
151       WelsCabacEncodeDecision (pCabacCtx, 69, (iRemMode >> 2));
152     }
153   }
154 }
155 
WelsCabacMbIntraChromaPredMode(SCabacCtx * pCabacCtx,SMB * pCurMb,SMbCache * pMbCache,int32_t iMbWidth)156 void WelsCabacMbIntraChromaPredMode (SCabacCtx* pCabacCtx, SMB* pCurMb, SMbCache* pMbCache, int32_t iMbWidth) {
157   uint32_t uiNeighborAvail = pCurMb->uiNeighborAvail;
158   SMB* pLeftMb = pCurMb - 1 ;
159   SMB* pTopMb = pCurMb - iMbWidth;
160 
161   int32_t iPredMode = g_kiMapModeIntraChroma[pMbCache->uiChmaI8x8Mode];
162   int32_t iCtx = 64;
163   if ((uiNeighborAvail & LEFT_MB_POS) && g_kiMapModeIntraChroma[pLeftMb->uiChromPredMode] != 0)
164     iCtx++;
165   if ((uiNeighborAvail & TOP_MB_POS) && g_kiMapModeIntraChroma[pTopMb->uiChromPredMode] != 0)
166     iCtx++;
167 
168   if (iPredMode == 0) {
169     WelsCabacEncodeDecision (pCabacCtx, iCtx, 0);
170   } else if (iPredMode == 1) {
171     WelsCabacEncodeDecision (pCabacCtx, iCtx, 1);
172     WelsCabacEncodeDecision (pCabacCtx, 67, 0);
173   } else if (iPredMode == 2) {
174     WelsCabacEncodeDecision (pCabacCtx, iCtx, 1);
175     WelsCabacEncodeDecision (pCabacCtx, 67, 1);
176     WelsCabacEncodeDecision (pCabacCtx, 67, 0);
177   } else {
178     WelsCabacEncodeDecision (pCabacCtx, iCtx, 1);
179     WelsCabacEncodeDecision (pCabacCtx, 67, 1);
180     WelsCabacEncodeDecision (pCabacCtx, 67, 1);
181   }
182 }
183 
WelsCabacMbCbp(SMB * pCurMb,int32_t iMbWidth,SCabacCtx * pCabacCtx)184 void WelsCabacMbCbp (SMB* pCurMb, int32_t iMbWidth, SCabacCtx* pCabacCtx) {
185   int32_t iCbpBlockLuma[4] = { (pCurMb->uiCbp) & 1, (pCurMb->uiCbp >> 1) & 1, (pCurMb->uiCbp >> 2) & 1, (pCurMb->uiCbp >> 3) & 1};
186   int32_t iCbpChroma = pCurMb->uiCbp >> 4;
187   int32_t iCbpBlockLeft[4] = {0, 0, 0, 0};
188   int32_t iCbpBlockTop[4] = {0, 0, 0, 0};
189   int32_t iCbpLeftChroma  = 0;
190   int32_t iCbpTopChroma = 0;
191   int32_t iCbp = 0;
192   int32_t iCtx = 0;
193   uint32_t uiNeighborAvail = pCurMb->uiNeighborAvail;
194   if (uiNeighborAvail & LEFT_MB_POS) {
195     iCbp = (pCurMb - 1)->uiCbp;
196     iCbpBlockLeft[0] = ! (iCbp & 1);
197     iCbpBlockLeft[1] = ! ((iCbp >> 1) & 1);
198     iCbpBlockLeft[2] = ! ((iCbp >> 2) & 1);
199     iCbpBlockLeft[3] = ! ((iCbp >> 3) & 1);
200     iCbpLeftChroma = iCbp >> 4;
201     if (iCbpLeftChroma)
202       iCtx += 1;
203   }
204   if (uiNeighborAvail & TOP_MB_POS) {
205     iCbp = (pCurMb - iMbWidth)->uiCbp;
206     iCbpBlockTop[0] = ! (iCbp & 1);
207     iCbpBlockTop[1] = ! ((iCbp >> 1) & 1);
208     iCbpBlockTop[2] = ! ((iCbp >> 2) & 1);
209     iCbpBlockTop[3] = ! ((iCbp >> 3) & 1);
210     iCbpTopChroma = iCbp >> 4;
211     if (iCbpTopChroma)
212       iCtx += 2;
213   }
214   WelsCabacEncodeDecision (pCabacCtx, 73 + iCbpBlockLeft[1] + iCbpBlockTop[2] * 2, iCbpBlockLuma[0]);
215   WelsCabacEncodeDecision (pCabacCtx, 73 + !iCbpBlockLuma[0] + iCbpBlockTop[3] * 2, iCbpBlockLuma[1]);
216   WelsCabacEncodeDecision (pCabacCtx, 73 + iCbpBlockLeft[3] + (!iCbpBlockLuma[0]) * 2 , iCbpBlockLuma[2]);
217   WelsCabacEncodeDecision (pCabacCtx, 73 + !iCbpBlockLuma[2] + (!iCbpBlockLuma[1]) * 2, iCbpBlockLuma[3]);
218 
219 
220   //chroma
221   if (iCbpChroma) {
222     WelsCabacEncodeDecision (pCabacCtx, 77 + iCtx, 1);
223     WelsCabacEncodeDecision (pCabacCtx, 81 + (iCbpLeftChroma >> 1) + ((iCbpTopChroma >> 1) * 2), iCbpChroma > 1);
224   } else {
225     WelsCabacEncodeDecision (pCabacCtx, 77 + iCtx, 0);
226   }
227 }
228 
WelsCabacMbDeltaQp(SMB * pCurMb,SCabacCtx * pCabacCtx,bool bFirstMbInSlice)229 void WelsCabacMbDeltaQp (SMB* pCurMb, SCabacCtx* pCabacCtx, bool bFirstMbInSlice) {
230   SMB* pPrevMb = NULL;
231   int32_t iCtx = 0;
232 
233   if (!bFirstMbInSlice) {
234     pPrevMb = pCurMb - 1;
235     pCurMb->iLumaDQp = pCurMb->uiLumaQp - pPrevMb->uiLumaQp;
236 
237     if (IS_SKIP (pPrevMb->uiMbType) || ((pPrevMb->uiMbType != MB_TYPE_INTRA16x16) && (!pPrevMb->uiCbp))
238         || (!pPrevMb->iLumaDQp))
239       iCtx = 0;
240     else
241       iCtx = 1;
242   }
243 
244   if (pCurMb->iLumaDQp) {
245     int32_t iValue = pCurMb->iLumaDQp < 0 ? (-2 * pCurMb->iLumaDQp) : (2 * pCurMb->iLumaDQp - 1);
246     WelsCabacEncodeDecision (pCabacCtx, 60 + iCtx, 1);
247     if (iValue == 1) {
248       WelsCabacEncodeDecision (pCabacCtx, 60 + 2, 0);
249     } else {
250       WelsCabacEncodeDecision (pCabacCtx, 60 + 2, 1);
251       iValue--;
252       while ((--iValue) > 0)
253         WelsCabacEncodeDecision (pCabacCtx, 60 + 3, 1);
254       WelsCabacEncodeDecision (pCabacCtx, 60 + 3, 0);
255     }
256   } else {
257     WelsCabacEncodeDecision (pCabacCtx, 60 + iCtx, 0);
258   }
259 }
260 
WelsMbSkipCabac(SCabacCtx * pCabacCtx,SMB * pCurMb,int32_t iMbWidth,EWelsSliceType eSliceType,int16_t bSkipFlag)261 void WelsMbSkipCabac (SCabacCtx* pCabacCtx, SMB* pCurMb, int32_t iMbWidth, EWelsSliceType eSliceType,
262                       int16_t bSkipFlag) {
263   int32_t iCtx = (eSliceType == P_SLICE) ? 11 : 24;
264   uint32_t uiNeighborAvail = pCurMb->uiNeighborAvail;
265   if (uiNeighborAvail & LEFT_MB_POS) { //LEFT MB
266     if (!IS_SKIP ((pCurMb - 1)->uiMbType))
267       iCtx++;
268   }
269   if (uiNeighborAvail & TOP_MB_POS) { //TOP MB
270     if (!IS_SKIP ((pCurMb - iMbWidth)->uiMbType))
271       iCtx++;
272   }
273   WelsCabacEncodeDecision (pCabacCtx, iCtx, bSkipFlag);
274 
275   if (bSkipFlag) {
276     for (int  i = 0; i < 16; i++) {
277       pCurMb->sMvd[i].iMvX = 0;
278       pCurMb->sMvd[i].iMvY = 0;
279     }
280     pCurMb->uiCbp = pCurMb->iCbpDc  = 0;
281   }
282 }
283 
WelsCabacMbRef(SCabacCtx * pCabacCtx,SMB * pCurMb,SMbCache * pMbCache,int16_t iIdx)284 void WelsCabacMbRef (SCabacCtx* pCabacCtx, SMB* pCurMb, SMbCache* pMbCache, int16_t iIdx) {
285   SMVComponentUnit* pMvComp = &pMbCache->sMvComponents;
286   const int16_t iRefIdxA = pMvComp->iRefIndexCache[iIdx + 6];
287   const int16_t iRefIdxB = pMvComp->iRefIndexCache[iIdx + 1];
288   int16_t iRefIdx  = pMvComp->iRefIndexCache[iIdx + 7];
289   int16_t iCtx  = 0;
290 
291   if ((iRefIdxA > 0) && (!pMbCache->bMbTypeSkip[3]))
292     iCtx++;
293   if ((iRefIdxB > 0) && (!pMbCache->bMbTypeSkip[1]))
294     iCtx += 2;
295 
296   while (iRefIdx > 0) {
297     WelsCabacEncodeDecision (pCabacCtx, 54 + iCtx, 1);
298     iCtx = (iCtx >> 2) + 4;
299     iRefIdx--;
300   }
301   WelsCabacEncodeDecision (pCabacCtx, 54 + iCtx, 0);
302 }
303 
WelsCabacMbMvdLx(SCabacCtx * pCabacCtx,int32_t sMvd,int32_t iCtx,int32_t iPredMvd)304 inline void WelsCabacMbMvdLx (SCabacCtx* pCabacCtx, int32_t sMvd, int32_t iCtx, int32_t iPredMvd) {
305   const int32_t iAbsMvd = WELS_ABS (sMvd);
306   int32_t iCtxInc = 0;
307   int32_t iPrefix = WELS_MIN (iAbsMvd, 9);
308   int32_t i = 0;
309 
310   if (iPredMvd > 32)
311     iCtxInc += 2;
312   else if (iPredMvd > 2)
313     iCtxInc += 1;
314 
315   if (iPrefix) {
316     if (iPrefix < 9) {
317       WelsCabacEncodeDecision (pCabacCtx, iCtx + iCtxInc, 1);
318       iCtxInc = 3;
319       for (i = 0; i < iPrefix - 1; i++) {
320         WelsCabacEncodeDecision (pCabacCtx, iCtx + iCtxInc, 1);
321         if (i < 3)
322           iCtxInc++;
323       }
324       WelsCabacEncodeDecision (pCabacCtx, iCtx + iCtxInc, 0);
325       WelsCabacEncodeBypassOne (pCabacCtx, sMvd < 0);
326     } else {
327       WelsCabacEncodeDecision (pCabacCtx, iCtx + iCtxInc, 1);
328       iCtxInc = 3;
329       for (i = 0; i < (9 - 1); i++) {
330         WelsCabacEncodeDecision (pCabacCtx, iCtx + iCtxInc, 1);
331         if (i < 3)
332           iCtxInc++;
333       }
334       WelsCabacEncodeUeBypass (pCabacCtx, 3, iAbsMvd - 9);
335       WelsCabacEncodeBypassOne (pCabacCtx, sMvd < 0);
336     }
337   } else {
338     WelsCabacEncodeDecision (pCabacCtx, iCtx + iCtxInc, 0);
339   }
340 }
WelsCabacMbMvd(SCabacCtx * pCabacCtx,SMB * pCurMb,uint32_t iMbWidth,SMVUnitXY sCurMv,SMVUnitXY sPredMv,int16_t i4x4ScanIdx)341 SMVUnitXY WelsCabacMbMvd (SCabacCtx* pCabacCtx, SMB* pCurMb, uint32_t iMbWidth,
342                           SMVUnitXY sCurMv, SMVUnitXY sPredMv, int16_t i4x4ScanIdx) {
343   uint32_t iAbsMvd0, iAbsMvd1;
344   uint8_t uiNeighborAvail = pCurMb->uiNeighborAvail;
345   SMVUnitXY sMvd;
346   SMVUnitXY sMvdLeft;
347   SMVUnitXY sMvdTop;
348 
349   sMvdLeft.iMvX = sMvdLeft.iMvY = sMvdTop.iMvX = sMvdTop.iMvY = 0;
350   sMvd.sDeltaMv (sCurMv, sPredMv);
351   if ((i4x4ScanIdx < 4) && (uiNeighborAvail & TOP_MB_POS)) { //top row blocks
352     sMvdTop.sAssignMv ((pCurMb - iMbWidth)->sMvd[i4x4ScanIdx + 12]);
353   } else if (i4x4ScanIdx >= 4) {
354     sMvdTop.sAssignMv (pCurMb->sMvd[i4x4ScanIdx - 4]);
355   }
356   if ((! (i4x4ScanIdx & 0x03)) && (uiNeighborAvail & LEFT_MB_POS)) { //left column blocks
357     sMvdLeft.sAssignMv ((pCurMb - 1)->sMvd[i4x4ScanIdx + 3]);
358   } else if (i4x4ScanIdx & 0x03) {
359     sMvdLeft.sAssignMv (pCurMb->sMvd[i4x4ScanIdx - 1]);
360   }
361 
362   iAbsMvd0 = WELS_ABS (sMvdLeft.iMvX) + WELS_ABS (sMvdTop.iMvX);
363   iAbsMvd1 = WELS_ABS (sMvdLeft.iMvY) + WELS_ABS (sMvdTop.iMvY);
364 
365   WelsCabacMbMvdLx (pCabacCtx, sMvd.iMvX, 40, iAbsMvd0);
366   WelsCabacMbMvdLx (pCabacCtx, sMvd.iMvY, 47, iAbsMvd1);
367   return sMvd;
368 }
WelsCabacSubMbType(SCabacCtx * pCabacCtx,SMB * pCurMb)369 static void WelsCabacSubMbType (SCabacCtx* pCabacCtx, SMB* pCurMb) {
370   for (int32_t i8x8Idx = 0; i8x8Idx < 4; ++i8x8Idx) {
371     uint32_t uiSubMbType = pCurMb->uiSubMbType[i8x8Idx];
372     if (SUB_MB_TYPE_8x8 == uiSubMbType) {
373       WelsCabacEncodeDecision (pCabacCtx, 21, 1);
374       continue;
375     }
376     WelsCabacEncodeDecision (pCabacCtx, 21, 0);
377     if (SUB_MB_TYPE_8x4 == uiSubMbType) {
378       WelsCabacEncodeDecision (pCabacCtx, 22, 0);
379     } else {
380       WelsCabacEncodeDecision (pCabacCtx, 22, 1);
381       WelsCabacEncodeDecision (pCabacCtx, 23, SUB_MB_TYPE_4x8 == uiSubMbType);
382     }
383   } //for
384 }
385 
WelsCabacSubMbMvd(SCabacCtx * pCabacCtx,SMB * pCurMb,SMbCache * pMbCache,const int kiMbWidth)386 static void WelsCabacSubMbMvd (SCabacCtx* pCabacCtx, SMB* pCurMb, SMbCache* pMbCache, const int kiMbWidth) {
387   SMVUnitXY sMvd;
388   int32_t i8x8Idx, i4x4ScanIdx;
389   for (i8x8Idx = 0; i8x8Idx < 4; ++i8x8Idx) {
390     uint32_t uiSubMbType = pCurMb->uiSubMbType[i8x8Idx];
391     if (SUB_MB_TYPE_8x8 == uiSubMbType) {
392       i4x4ScanIdx = g_kuiMbCountScan4Idx[i8x8Idx << 2];
393       sMvd = WelsCabacMbMvd (pCabacCtx, pCurMb, kiMbWidth, pCurMb->sMv[i4x4ScanIdx], pMbCache->sMbMvp[i4x4ScanIdx],
394                              i4x4ScanIdx);
395       pCurMb->sMvd[    i4x4ScanIdx].sAssignMv (sMvd);
396       pCurMb->sMvd[1 + i4x4ScanIdx].sAssignMv (sMvd);
397       pCurMb->sMvd[4 + i4x4ScanIdx].sAssignMv (sMvd);
398       pCurMb->sMvd[5 + i4x4ScanIdx].sAssignMv (sMvd);
399     } else if (SUB_MB_TYPE_4x4 == uiSubMbType) {
400       for (int32_t i4x4Idx = 0; i4x4Idx < 4; ++i4x4Idx) {
401         i4x4ScanIdx = g_kuiMbCountScan4Idx[ (i8x8Idx << 2) + i4x4Idx];
402         sMvd = WelsCabacMbMvd (pCabacCtx, pCurMb, kiMbWidth, pCurMb->sMv[i4x4ScanIdx], pMbCache->sMbMvp[i4x4ScanIdx],
403                                i4x4ScanIdx);
404         pCurMb->sMvd[i4x4ScanIdx].sAssignMv (sMvd);
405       }
406     } else if (SUB_MB_TYPE_8x4 == uiSubMbType) {
407       for (int32_t i8x4Idx = 0; i8x4Idx < 2; ++i8x4Idx) {
408         i4x4ScanIdx = g_kuiMbCountScan4Idx[ (i8x8Idx << 2) + (i8x4Idx << 1)];
409         sMvd = WelsCabacMbMvd (pCabacCtx, pCurMb, kiMbWidth, pCurMb->sMv[i4x4ScanIdx], pMbCache->sMbMvp[i4x4ScanIdx],
410                                i4x4ScanIdx);
411         pCurMb->sMvd[    i4x4ScanIdx].sAssignMv (sMvd);
412         pCurMb->sMvd[1 + i4x4ScanIdx].sAssignMv (sMvd);
413       }
414     } else if (SUB_MB_TYPE_4x8 == uiSubMbType) {
415       for (int32_t i4x8Idx = 0; i4x8Idx < 2; ++i4x8Idx) {
416         i4x4ScanIdx = g_kuiMbCountScan4Idx[ (i8x8Idx << 2) + i4x8Idx];
417         sMvd = WelsCabacMbMvd (pCabacCtx, pCurMb, kiMbWidth, pCurMb->sMv[i4x4ScanIdx], pMbCache->sMbMvp[i4x4ScanIdx],
418                                i4x4ScanIdx);
419         pCurMb->sMvd[    i4x4ScanIdx].sAssignMv (sMvd);
420         pCurMb->sMvd[4 + i4x4ScanIdx].sAssignMv (sMvd);
421       }
422     }
423   }
424 }
425 
WelsGetMbCtxCabac(SMbCache * pMbCache,SMB * pCurMb,uint32_t iMbWidth,ECtxBlockCat eCtxBlockCat,int16_t iIdx)426 int16_t WelsGetMbCtxCabac (SMbCache* pMbCache, SMB* pCurMb, uint32_t iMbWidth, ECtxBlockCat eCtxBlockCat,
427                            int16_t iIdx) {
428   int16_t iNzA = -1, iNzB = -1;
429   int8_t* pNonZeroCoeffCount = pMbCache->iNonZeroCoeffCount;
430   int32_t bIntra = IS_INTRA (pCurMb->uiMbType);
431   int32_t iCtxInc = 0;
432   switch (eCtxBlockCat) {
433   case LUMA_AC:
434   case CHROMA_AC:
435   case LUMA_4x4:
436     iNzA = pNonZeroCoeffCount[iIdx - 1];
437     iNzB = pNonZeroCoeffCount[iIdx - 8];
438     break;
439   case LUMA_DC:
440   case CHROMA_DC:
441     if (pCurMb->uiNeighborAvail & LEFT_MB_POS)
442       iNzA = (pCurMb - 1)->iCbpDc & (1 << iIdx);
443     if (pCurMb->uiNeighborAvail & TOP_MB_POS)
444       iNzB = (pCurMb - iMbWidth)->iCbpDc & (1 << iIdx);
445     break;
446   default:
447     break;
448   }
449   if (((iNzA == -1) && bIntra) || (iNzA > 0))
450     iCtxInc += 1;
451   if (((iNzB == -1) && bIntra) || (iNzB > 0))
452     iCtxInc += 2;
453   return 85 + uiCodecBlockFlagOffset[eCtxBlockCat] + iCtxInc;
454 }
455 
WelsWriteBlockResidualCabac(SMbCache * pMbCache,SMB * pCurMb,uint32_t iMbWidth,SCabacCtx * pCabacCtx,ECtxBlockCat eCtxBlockCat,int16_t iIdx,int16_t iNonZeroCount,int16_t * pBlock,int16_t iEndIdx)456 void  WelsWriteBlockResidualCabac (SMbCache* pMbCache, SMB* pCurMb, uint32_t iMbWidth, SCabacCtx* pCabacCtx,
457                                    ECtxBlockCat eCtxBlockCat, int16_t  iIdx, int16_t iNonZeroCount, int16_t* pBlock, int16_t iEndIdx) {
458   int32_t iCtx = WelsGetMbCtxCabac (pMbCache, pCurMb, iMbWidth, eCtxBlockCat, iIdx);
459   if (iNonZeroCount) {
460     int16_t iLevel[16];
461     const int32_t iCtxSig = 105 + uiSignificantCoeffFlagOffset[eCtxBlockCat];
462     const int32_t iCtxLast = 166 + uiLastCoeffFlagOffset[eCtxBlockCat];
463     const int32_t iCtxLevel = 227 + uiCoeffAbsLevelMinus1Offset[eCtxBlockCat];
464     int32_t iNonZeroIdx = 0;
465     int32_t i = 0;
466 
467     WelsCabacEncodeDecision (pCabacCtx, iCtx, 1);
468     while (1) {
469       if (pBlock[i]) {
470         iLevel[iNonZeroIdx] = pBlock[i];
471 
472         iNonZeroIdx++;
473         WelsCabacEncodeDecision (pCabacCtx, iCtxSig + i, 1);
474         if (iNonZeroIdx != iNonZeroCount)
475           WelsCabacEncodeDecision (pCabacCtx, iCtxLast + i, 0);
476         else {
477           WelsCabacEncodeDecision (pCabacCtx, iCtxLast + i, 1);
478           break;
479         }
480       } else
481         WelsCabacEncodeDecision (pCabacCtx, iCtxSig + i, 0);
482       i++;
483       if (i == iEndIdx) {
484         iLevel[iNonZeroIdx] = pBlock[i];
485         iNonZeroIdx++;
486         break;
487       }
488     }
489 
490     int32_t iNumAbsLevelGt1 = 0;
491     int32_t iCtx1 = iCtxLevel + 1;
492 
493     do {
494       int32_t iPrefix = 0;
495       iNonZeroIdx--;
496       iPrefix = WELS_ABS (iLevel[iNonZeroIdx]) - 1;
497       if (iPrefix) {
498         iPrefix = WELS_MIN (iPrefix, 14);
499         iCtx = WELS_MIN (iCtxLevel + 4, iCtx1);
500         WelsCabacEncodeDecision (pCabacCtx, iCtx, 1);
501         iNumAbsLevelGt1++;
502         iCtx = iCtxLevel + 4 + WELS_MIN (5 - (eCtxBlockCat == CHROMA_DC), iNumAbsLevelGt1);
503         for (i = 1; i < iPrefix; i++)
504           WelsCabacEncodeDecision (pCabacCtx, iCtx, 1);
505         if (WELS_ABS (iLevel[iNonZeroIdx]) < 15)
506           WelsCabacEncodeDecision (pCabacCtx, iCtx, 0);
507         else
508           WelsCabacEncodeUeBypass (pCabacCtx, 0, WELS_ABS (iLevel[iNonZeroIdx]) - 15);
509         iCtx1 = iCtxLevel;
510       } else {
511         iCtx = WELS_MIN (iCtxLevel + 4, iCtx1);
512         WelsCabacEncodeDecision (pCabacCtx, iCtx, 0);
513         iCtx1 += iNumAbsLevelGt1 == 0;
514       }
515       WelsCabacEncodeBypassOne (pCabacCtx, iLevel[iNonZeroIdx] < 0);
516     } while (iNonZeroIdx > 0);
517 
518   } else {
519     WelsCabacEncodeDecision (pCabacCtx, iCtx, 0);
520   }
521 
522 
523 }
WelsCalNonZeroCount2x2Block(int16_t * pBlock)524 int32_t WelsCalNonZeroCount2x2Block (int16_t* pBlock) {
525   return (pBlock[0] != 0)
526          + (pBlock[1] != 0)
527          + (pBlock[2] != 0)
528          + (pBlock[3] != 0);
529 }
WelsWriteMbResidualCabac(SWelsFuncPtrList * pFuncList,SSlice * pSlice,SMbCache * sMbCacheInfo,SMB * pCurMb,SCabacCtx * pCabacCtx,int16_t iMbWidth,uint32_t uiChromaQpIndexOffset)530 int32_t WelsWriteMbResidualCabac (SWelsFuncPtrList* pFuncList, SSlice* pSlice, SMbCache* sMbCacheInfo, SMB* pCurMb,
531                                   SCabacCtx* pCabacCtx,
532                                   int16_t iMbWidth, uint32_t uiChromaQpIndexOffset) {
533 
534   const uint16_t uiMbType = pCurMb->uiMbType;
535   SMbCache* pMbCache = &pSlice->sMbCacheInfo;
536   int16_t i = 0;
537   int8_t* pNonZeroCoeffCount = pMbCache->iNonZeroCoeffCount;
538   SSliceHeaderExt* pSliceHeadExt = &pSlice->sSliceHeaderExt;
539   const int32_t iSliceFirstMbXY = pSliceHeadExt->sSliceHeader.iFirstMbInSlice;
540 
541 
542   pCurMb->iCbpDc = 0;
543   pCurMb->iLumaDQp = 0;
544 
545   if ((pCurMb->uiCbp > 0) || (uiMbType == MB_TYPE_INTRA16x16)) {
546     int32_t iCbpChroma = pCurMb->uiCbp >> 4;
547     int32_t iCbpLuma   = pCurMb->uiCbp & 15;
548 
549     pCurMb->iLumaDQp = pCurMb->uiLumaQp - pSlice->uiLastMbQp;
550     WelsCabacMbDeltaQp (pCurMb, pCabacCtx, (pCurMb->iMbXY == iSliceFirstMbXY));
551     pSlice->uiLastMbQp = pCurMb->uiLumaQp;
552 
553     if (uiMbType == MB_TYPE_INTRA16x16) {
554       //Luma DC
555       int iNonZeroCount = pFuncList->pfGetNoneZeroCount (pMbCache->pDct->iLumaI16x16Dc);
556       WelsWriteBlockResidualCabac (pMbCache, pCurMb, iMbWidth, pCabacCtx, LUMA_DC, 0, iNonZeroCount,
557                                    pMbCache->pDct->iLumaI16x16Dc, 15);
558       if (iNonZeroCount)
559         pCurMb->iCbpDc |= 1;
560       //Luma AC
561 
562       if (iCbpLuma) {
563         for (i = 0; i < 16; i++) {
564           int32_t iIdx = g_kuiCache48CountScan4Idx[i];
565           WelsWriteBlockResidualCabac (pMbCache, pCurMb, iMbWidth, pCabacCtx, LUMA_AC, iIdx,
566                                        pNonZeroCoeffCount[iIdx], pMbCache->pDct->iLumaBlock[i], 14);
567         }
568       }
569     } else {
570       //Luma AC
571       for (i = 0; i < 16; i++) {
572         if (iCbpLuma & (1 << (i >> 2))) {
573           int32_t iIdx = g_kuiCache48CountScan4Idx[i];
574           WelsWriteBlockResidualCabac (pMbCache, pCurMb, iMbWidth, pCabacCtx, LUMA_4x4, iIdx,
575                                        pNonZeroCoeffCount[iIdx], pMbCache->pDct->iLumaBlock[i], 15);
576         }
577 
578       }
579     }
580 
581     if (iCbpChroma) {
582       int32_t iNonZeroCount = 0;
583       //chroma DC
584       iNonZeroCount = WelsCalNonZeroCount2x2Block (pMbCache->pDct->iChromaDc[0]);
585       if (iNonZeroCount)
586         pCurMb->iCbpDc |= 0x2;
587       WelsWriteBlockResidualCabac (pMbCache, pCurMb, iMbWidth, pCabacCtx, CHROMA_DC, 1, iNonZeroCount,
588                                    pMbCache->pDct->iChromaDc[0], 3);
589 
590       iNonZeroCount = WelsCalNonZeroCount2x2Block (pMbCache->pDct->iChromaDc[1]);
591       if (iNonZeroCount)
592         pCurMb->iCbpDc |= 0x4;
593       WelsWriteBlockResidualCabac (pMbCache, pCurMb, iMbWidth, pCabacCtx, CHROMA_DC, 2, iNonZeroCount,
594                                    pMbCache->pDct->iChromaDc[1], 3);
595       if (iCbpChroma & 0x02) {
596         const uint8_t* g_kuiCache48CountScan4Idx_16base = &g_kuiCache48CountScan4Idx[16];
597         //Cb AC
598         for (i = 0; i < 4; i++) {
599           int32_t iIdx = g_kuiCache48CountScan4Idx_16base[i];
600           WelsWriteBlockResidualCabac (pMbCache, pCurMb, iMbWidth, pCabacCtx, CHROMA_AC, iIdx,
601                                        pNonZeroCoeffCount[iIdx], pMbCache->pDct->iChromaBlock[i], 14);
602 
603         }
604 
605         //Cr AC
606 
607         for (i = 0; i < 4; i++) {
608           int32_t iIdx = 24 + g_kuiCache48CountScan4Idx_16base[i];
609           WelsWriteBlockResidualCabac (pMbCache, pCurMb, iMbWidth, pCabacCtx, CHROMA_AC, iIdx,
610                                        pNonZeroCoeffCount[iIdx], pMbCache->pDct->iChromaBlock[4 + i], 14);
611         }
612       }
613     }
614   } else {
615     pCurMb->iLumaDQp = 0;
616     pCurMb->uiLumaQp = pSlice->uiLastMbQp;
617     pCurMb->uiChromaQp = g_kuiChromaQpTable[CLIP3_QP_0_51 (pCurMb->uiLumaQp + uiChromaQpIndexOffset)];
618   }
619   return 0;
620 }
621 
622 } // anon ns.
623 
624 namespace WelsEnc {
625 
WelsInitSliceCabac(sWelsEncCtx * pEncCtx,SSlice * pSlice)626 void WelsInitSliceCabac (sWelsEncCtx* pEncCtx, SSlice* pSlice) {
627   /* alignment needed */
628   SBitStringAux* pBs = pSlice->pSliceBsa;
629   BsAlign (pBs);
630 
631   /* init cabac */
632   WelsCabacContextInit (pEncCtx, &pSlice->sCabacCtx, pSlice->iCabacInitIdc);
633   WelsCabacEncodeInit (&pSlice->sCabacCtx, pBs->pCurBuf, pBs->pEndBuf);
634 }
635 
WelsSpatialWriteMbSynCabac(sWelsEncCtx * pEncCtx,SSlice * pSlice,SMB * pCurMb)636 int32_t WelsSpatialWriteMbSynCabac (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb) {
637   SCabacCtx* pCabacCtx = &pSlice->sCabacCtx;
638   SMbCache* pMbCache = &pSlice->sMbCacheInfo;
639   const uint16_t uiMbType = pCurMb->uiMbType;
640   SSliceHeaderExt* pSliceHeadExt = &pSlice->sSliceHeaderExt;
641   uint32_t uiNumRefIdxL0Active = pSliceHeadExt->sSliceHeader.uiNumRefIdxL0Active - 1;
642   const int32_t iSliceFirstMbXY = pSliceHeadExt->sSliceHeader.iFirstMbInSlice;
643   int16_t i = 0;
644   int16_t iMbWidth = pEncCtx->pCurDqLayer->iMbWidth;
645   uint32_t uiChromaQpIndexOffset = pEncCtx->pCurDqLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset;
646   SMVUnitXY sMvd;
647   int32_t iRet = 0;
648   if (pCurMb->iMbXY > iSliceFirstMbXY)
649     WelsCabacEncodeTerminate (&pSlice->sCabacCtx, 0);
650 
651   if (IS_SKIP (pCurMb->uiMbType)) {
652     pCurMb->uiLumaQp = pSlice->uiLastMbQp;
653     pCurMb->uiChromaQp = g_kuiChromaQpTable[CLIP3_QP_0_51 (pCurMb->uiLumaQp + uiChromaQpIndexOffset)];
654     WelsMbSkipCabac (&pSlice->sCabacCtx, pCurMb, iMbWidth, pEncCtx->eSliceType, 1);
655 
656   } else {
657     //skip flag
658     if (pEncCtx->eSliceType != I_SLICE)
659       WelsMbSkipCabac (&pSlice->sCabacCtx, pCurMb, iMbWidth, pEncCtx->eSliceType, 0);
660 
661     //write mb type
662     WelsCabacMbType (pCabacCtx, pCurMb, pMbCache, iMbWidth, pEncCtx->eSliceType);
663 
664     if (IS_INTRA (uiMbType)) {
665       if (uiMbType == MB_TYPE_INTRA4x4) {
666         WelsCabacMbIntra4x4PredMode (pCabacCtx, pMbCache);
667       }
668       WelsCabacMbIntraChromaPredMode (pCabacCtx, pCurMb, pMbCache, iMbWidth);
669       sMvd.iMvX = sMvd.iMvY = 0;
670       for (i = 0; i < 16; ++i) {
671         pCurMb->sMvd[i].sAssignMv (sMvd);
672       }
673 
674     } else if (uiMbType == MB_TYPE_16x16) {
675 
676       if (uiNumRefIdxL0Active > 0) {
677         WelsCabacMbRef (pCabacCtx, pCurMb, pMbCache, 0);
678       }
679       sMvd = WelsCabacMbMvd (pCabacCtx, pCurMb, iMbWidth, pCurMb->sMv[0], pMbCache->sMbMvp[0], 0);
680 
681       for (i = 0; i < 16; ++i) {
682         pCurMb->sMvd[i].sAssignMv (sMvd);
683       }
684 
685     } else if (uiMbType == MB_TYPE_16x8) {
686       if (uiNumRefIdxL0Active > 0) {
687         WelsCabacMbRef (pCabacCtx, pCurMb, pMbCache, 0);
688         WelsCabacMbRef (pCabacCtx, pCurMb, pMbCache, 12);
689       }
690       sMvd = WelsCabacMbMvd (pCabacCtx, pCurMb, iMbWidth , pCurMb->sMv[0], pMbCache->sMbMvp[0], 0);
691       for (i = 0; i < 8; ++i) {
692         pCurMb->sMvd[i].sAssignMv (sMvd);
693       }
694       sMvd = WelsCabacMbMvd (pCabacCtx, pCurMb, iMbWidth, pCurMb->sMv[8], pMbCache->sMbMvp[1], 8);
695       for (i = 8; i < 16; ++i) {
696         pCurMb->sMvd[i].sAssignMv (sMvd);
697       }
698     } else  if (uiMbType == MB_TYPE_8x16) {
699       if (uiNumRefIdxL0Active > 0) {
700         WelsCabacMbRef (pCabacCtx, pCurMb, pMbCache, 0);
701         WelsCabacMbRef (pCabacCtx, pCurMb, pMbCache, 2);
702       }
703       sMvd = WelsCabacMbMvd (pCabacCtx, pCurMb, iMbWidth, pCurMb->sMv[0], pMbCache->sMbMvp[0], 0);
704       for (i = 0; i < 16; i += 4) {
705         pCurMb->sMvd[i    ].sAssignMv (sMvd);
706         pCurMb->sMvd[i + 1].sAssignMv (sMvd);
707       }
708       sMvd = WelsCabacMbMvd (pCabacCtx, pCurMb, iMbWidth,  pCurMb->sMv[2], pMbCache->sMbMvp[1], 2);
709       for (i = 0; i < 16; i += 4) {
710         pCurMb->sMvd[i + 2].sAssignMv (sMvd);
711         pCurMb->sMvd[i + 3].sAssignMv (sMvd);
712       }
713     } else if ((uiMbType == MB_TYPE_8x8) || (uiMbType == MB_TYPE_8x8_REF0)) {
714       //write sub_mb_type
715       WelsCabacSubMbType (pCabacCtx, pCurMb);
716 
717       if (uiNumRefIdxL0Active > 0) {
718         WelsCabacMbRef (pCabacCtx, pCurMb, pMbCache, 0);
719         WelsCabacMbRef (pCabacCtx, pCurMb, pMbCache, 2);
720         WelsCabacMbRef (pCabacCtx, pCurMb, pMbCache, 12);
721         WelsCabacMbRef (pCabacCtx, pCurMb, pMbCache, 14);
722       }
723       //write sub8x8 mvd
724       WelsCabacSubMbMvd (pCabacCtx, pCurMb, pMbCache, iMbWidth);
725     }
726     if (uiMbType != MB_TYPE_INTRA16x16) {
727       WelsCabacMbCbp (pCurMb, iMbWidth, pCabacCtx);
728     }
729     iRet = WelsWriteMbResidualCabac (pEncCtx->pFuncList, pSlice, pMbCache, pCurMb, pCabacCtx, iMbWidth,
730                                      uiChromaQpIndexOffset);
731   }
732   if (!IS_INTRA (pCurMb->uiMbType))
733     pCurMb->uiChromPredMode = 0;
734 
735   return iRet;
736 }
737 
738 
739 }
740