• 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  *      cabac_decoder.cpp:      deals with cabac state transition and related functions
32  */
33 #include "cabac_decoder.h"
34 namespace WelsDec {
35 static const int16_t g_kMvdBinPos2Ctx [8] = {0, 1, 2, 3, 3, 3, 3, 3};
36 
WelsCabacGlobalInit(PWelsDecoderContext pCtx)37 void WelsCabacGlobalInit (PWelsDecoderContext pCtx) {
38   for (int32_t iModel = 0; iModel < 4; iModel++) {
39     for (int32_t iQp = 0; iQp <= WELS_QP_MAX; iQp++)
40       for (int32_t iIdx = 0; iIdx < WELS_CONTEXT_COUNT; iIdx++) {
41         int32_t m               = g_kiCabacGlobalContextIdx[iIdx][iModel][0];
42         int32_t n               = g_kiCabacGlobalContextIdx[iIdx][iModel][1];
43         int32_t iPreCtxState    = WELS_CLIP3 ((((m * iQp) >> 4) + n), 1, 126);
44         uint8_t uiValMps         = 0;
45         uint8_t uiStateIdx       = 0;
46         if (iPreCtxState <= 63) {
47           uiStateIdx = 63 - iPreCtxState;
48           uiValMps = 0;
49         } else {
50           uiStateIdx = iPreCtxState - 64;
51           uiValMps = 1;
52         }
53         pCtx->sWelsCabacContexts[iModel][iQp][iIdx].uiState = uiStateIdx;
54         pCtx->sWelsCabacContexts[iModel][iQp][iIdx].uiMPS = uiValMps;
55       }
56   }
57   pCtx->bCabacInited = true;
58 }
59 
60 // ------------------- 1. context initialization
WelsCabacContextInit(PWelsDecoderContext pCtx,uint8_t eSliceType,int32_t iCabacInitIdc,int32_t iQp)61 void WelsCabacContextInit (PWelsDecoderContext  pCtx, uint8_t eSliceType, int32_t iCabacInitIdc, int32_t iQp) {
62   int32_t iIdx =  pCtx->eSliceType == WelsCommon::I_SLICE ? 0 : iCabacInitIdc + 1;
63   if (!pCtx->bCabacInited) {
64     WelsCabacGlobalInit (pCtx);
65   }
66   memcpy (pCtx->pCabacCtx, pCtx->sWelsCabacContexts[iIdx][iQp],
67           WELS_CONTEXT_COUNT * sizeof (SWelsCabacCtx));
68 }
69 
70 // ------------------- 2. decoding Engine initialization
InitCabacDecEngineFromBS(PWelsCabacDecEngine pDecEngine,PBitStringAux pBsAux)71 int32_t InitCabacDecEngineFromBS (PWelsCabacDecEngine pDecEngine, PBitStringAux pBsAux) {
72   int32_t iRemainingBits = - pBsAux->iLeftBits; //pBsAux->iLeftBits < 0
73   int32_t iRemainingBytes = (iRemainingBits >> 3) + 2; //+2: indicating the pre-read 2 bytes
74   uint8_t* pCurr;
75 
76   pCurr = pBsAux->pCurBuf - iRemainingBytes;
77   if (pCurr >= (pBsAux->pEndBuf - 1)) {
78     return ERR_INFO_INVALID_ACCESS;
79   }
80   pDecEngine->uiOffset = ((pCurr[0] << 16) | (pCurr[1] << 8) | pCurr[2]);
81   pDecEngine->uiOffset <<= 16;
82   pDecEngine->uiOffset |= (pCurr[3] << 8) | pCurr[4];
83   pDecEngine->iBitsLeft = 31;
84   pDecEngine->pBuffCurr = pCurr + 5;
85 
86   pDecEngine->uiRange = WELS_CABAC_HALF;
87   pDecEngine->pBuffStart = pBsAux->pStartBuf;
88   pDecEngine->pBuffEnd = pBsAux->pEndBuf;
89   pBsAux->iLeftBits = 0;
90   return ERR_NONE;
91 }
92 
RestoreCabacDecEngineToBS(PWelsCabacDecEngine pDecEngine,PBitStringAux pBsAux)93 void RestoreCabacDecEngineToBS (PWelsCabacDecEngine pDecEngine, PBitStringAux pBsAux) {
94   //CABAC decoding finished, changing to SBitStringAux
95   pDecEngine->pBuffCurr -= (pDecEngine->iBitsLeft >> 3);
96   pDecEngine->iBitsLeft = 0;     //pcm_alignment_zero_bit in CABAC
97   pBsAux->iLeftBits = 0;
98   pBsAux->pStartBuf = pDecEngine->pBuffStart;
99   pBsAux->pCurBuf = pDecEngine->pBuffCurr;
100   pBsAux->uiCurBits = 0;
101   pBsAux->iIndex = 0;
102 }
103 
104 // ------------------- 3. actual decoding
Read32BitsCabac(PWelsCabacDecEngine pDecEngine,uint32_t & uiValue,int32_t & iNumBitsRead)105 int32_t Read32BitsCabac (PWelsCabacDecEngine pDecEngine, uint32_t& uiValue, int32_t& iNumBitsRead) {
106   intX_t iLeftBytes = pDecEngine->pBuffEnd - pDecEngine->pBuffCurr;
107   iNumBitsRead = 0;
108   uiValue = 0;
109   if (iLeftBytes <= 0) {
110     return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_CABAC_NO_BS_TO_READ);
111   }
112   switch (iLeftBytes) {
113   case 3:
114     uiValue = ((pDecEngine->pBuffCurr[0]) << 16 | (pDecEngine->pBuffCurr[1]) << 8 | (pDecEngine->pBuffCurr[2]));
115     pDecEngine->pBuffCurr += 3;
116     iNumBitsRead = 24;
117     break;
118   case 2:
119     uiValue = ((pDecEngine->pBuffCurr[0]) << 8 | (pDecEngine->pBuffCurr[1]));
120     pDecEngine->pBuffCurr += 2;
121     iNumBitsRead = 16;
122     break;
123   case 1:
124     uiValue = pDecEngine->pBuffCurr[0];
125     pDecEngine->pBuffCurr += 1;
126     iNumBitsRead = 8;
127     break;
128   default:
129     uiValue = ((pDecEngine->pBuffCurr[0] << 24) | (pDecEngine->pBuffCurr[1]) << 16 | (pDecEngine->pBuffCurr[2]) << 8 |
130                (pDecEngine->pBuffCurr[3]));
131     pDecEngine->pBuffCurr += 4;
132     iNumBitsRead = 32;
133     break;
134   }
135   return ERR_NONE;
136 }
137 
DecodeBinCabac(PWelsCabacDecEngine pDecEngine,PWelsCabacCtx pBinCtx,uint32_t & uiBinVal)138 int32_t DecodeBinCabac (PWelsCabacDecEngine pDecEngine, PWelsCabacCtx pBinCtx, uint32_t& uiBinVal) {
139   int32_t iErrorInfo = ERR_NONE;
140   uint32_t uiState = pBinCtx->uiState;
141   uiBinVal = pBinCtx->uiMPS;
142   uint64_t uiOffset = pDecEngine->uiOffset;
143   uint64_t uiRange = pDecEngine->uiRange;
144 
145   int32_t iRenorm = 1;
146   uint32_t uiRangeLPS = g_kuiCabacRangeLps[uiState][ (uiRange >> 6) & 0x03];
147   uiRange -= uiRangeLPS;
148   if (uiOffset >= (uiRange << pDecEngine->iBitsLeft)) { //LPS
149     uiOffset -= (uiRange << pDecEngine->iBitsLeft);
150     uiBinVal ^= 0x0001;
151     if (!uiState)
152       pBinCtx->uiMPS ^= 0x01;
153     pBinCtx->uiState = g_kuiStateTransTable[uiState][0];
154     iRenorm = g_kRenormTable256[uiRangeLPS];
155     uiRange = (uiRangeLPS << iRenorm);
156   } else {  //MPS
157     pBinCtx->uiState = g_kuiStateTransTable[uiState][1];
158     if (uiRange >= WELS_CABAC_QUARTER) {
159       pDecEngine->uiRange = uiRange;
160       return ERR_NONE;
161     } else {
162       uiRange <<= 1;
163     }
164   }
165   //Renorm
166   pDecEngine->uiRange = uiRange;
167   pDecEngine->iBitsLeft -= iRenorm;
168   if (pDecEngine->iBitsLeft > 0) {
169     pDecEngine->uiOffset = uiOffset;
170     return ERR_NONE;
171   }
172   uint32_t uiVal = 0;
173   int32_t iNumBitsRead = 0;
174   iErrorInfo = Read32BitsCabac (pDecEngine, uiVal, iNumBitsRead);
175   pDecEngine->uiOffset = (uiOffset << iNumBitsRead) | uiVal;
176   pDecEngine->iBitsLeft += iNumBitsRead;
177   if (iErrorInfo && pDecEngine->iBitsLeft < 0) {
178     return iErrorInfo;
179   }
180   return ERR_NONE;
181 }
182 
DecodeBypassCabac(PWelsCabacDecEngine pDecEngine,uint32_t & uiBinVal)183 int32_t DecodeBypassCabac (PWelsCabacDecEngine pDecEngine, uint32_t& uiBinVal) {
184   int32_t iErrorInfo = ERR_NONE;
185   int32_t iBitsLeft = pDecEngine->iBitsLeft;
186   uint64_t uiOffset = pDecEngine->uiOffset;
187   uint64_t uiRangeValue;
188 
189 
190   if (iBitsLeft <= 0) {
191     uint32_t uiVal = 0;
192     int32_t iNumBitsRead = 0;
193     iErrorInfo = Read32BitsCabac (pDecEngine, uiVal, iNumBitsRead);
194     uiOffset = (uiOffset << iNumBitsRead) | uiVal;
195     iBitsLeft = iNumBitsRead;
196     if (iErrorInfo && iBitsLeft == 0) {
197       return iErrorInfo;
198     }
199   }
200   iBitsLeft--;
201   uiRangeValue = (pDecEngine->uiRange << iBitsLeft);
202   if (uiOffset >= uiRangeValue) {
203     pDecEngine->iBitsLeft = iBitsLeft;
204     pDecEngine->uiOffset = uiOffset - uiRangeValue;
205     uiBinVal = 1;
206     return ERR_NONE;
207   }
208   pDecEngine->iBitsLeft = iBitsLeft;
209   pDecEngine->uiOffset = uiOffset;
210   uiBinVal = 0;
211   return ERR_NONE;
212 }
213 
DecodeTerminateCabac(PWelsCabacDecEngine pDecEngine,uint32_t & uiBinVal)214 int32_t DecodeTerminateCabac (PWelsCabacDecEngine pDecEngine, uint32_t& uiBinVal) {
215   int32_t iErrorInfo = ERR_NONE;
216   uint64_t uiRange = pDecEngine->uiRange - 2;
217   uint64_t uiOffset = pDecEngine->uiOffset;
218 
219   if (uiOffset >= (uiRange << pDecEngine->iBitsLeft)) {
220     uiBinVal = 1;
221   } else {
222     uiBinVal = 0;
223     // Renorm
224     if (uiRange < WELS_CABAC_QUARTER) {
225       int32_t iRenorm = g_kRenormTable256[uiRange];
226       pDecEngine->uiRange = (uiRange << iRenorm);
227       pDecEngine->iBitsLeft -= iRenorm;
228       if (pDecEngine->iBitsLeft < 0) {
229         uint32_t uiVal = 0;
230         int32_t iNumBitsRead = 0;
231         iErrorInfo = Read32BitsCabac (pDecEngine, uiVal, iNumBitsRead);
232         pDecEngine->uiOffset = (pDecEngine->uiOffset << iNumBitsRead) | uiVal;
233         pDecEngine->iBitsLeft += iNumBitsRead;
234       }
235       if (iErrorInfo && pDecEngine->iBitsLeft < 0) {
236         return iErrorInfo;
237       }
238       return ERR_NONE;
239     } else {
240       pDecEngine->uiRange = uiRange;
241       return ERR_NONE;
242     }
243   }
244   return ERR_NONE;
245 }
246 
DecodeUnaryBinCabac(PWelsCabacDecEngine pDecEngine,PWelsCabacCtx pBinCtx,int32_t iCtxOffset,uint32_t & uiSymVal)247 int32_t DecodeUnaryBinCabac (PWelsCabacDecEngine pDecEngine, PWelsCabacCtx pBinCtx, int32_t iCtxOffset,
248                              uint32_t& uiSymVal) {
249   uiSymVal = 0;
250   WELS_READ_VERIFY (DecodeBinCabac (pDecEngine, pBinCtx, uiSymVal));
251   if (uiSymVal == 0) {
252     return ERR_NONE;
253   } else {
254     uint32_t uiCode;
255     pBinCtx += iCtxOffset;
256     uiSymVal = 0;
257     do {
258       WELS_READ_VERIFY (DecodeBinCabac (pDecEngine, pBinCtx, uiCode));
259       ++uiSymVal;
260     } while (uiCode != 0);
261     return ERR_NONE;
262   }
263 }
264 
DecodeExpBypassCabac(PWelsCabacDecEngine pDecEngine,int32_t iCount,uint32_t & uiSymVal)265 int32_t DecodeExpBypassCabac (PWelsCabacDecEngine pDecEngine, int32_t iCount, uint32_t& uiSymVal) {
266   uint32_t uiCode;
267   int32_t iSymTmp = 0;
268   int32_t iSymTmp2 = 0;
269   uiSymVal = 0;
270   do {
271     WELS_READ_VERIFY (DecodeBypassCabac (pDecEngine, uiCode));
272     if (uiCode == 1) {
273       iSymTmp += (1 << iCount);
274       ++iCount;
275     }
276   } while (uiCode != 0 && iCount != 16);
277   if (iCount == 16) {
278     return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_CABAC_UNEXPECTED_VALUE);
279   }
280 
281   while (iCount--) {
282     WELS_READ_VERIFY (DecodeBypassCabac (pDecEngine, uiCode));
283     if (uiCode == 1) {
284       iSymTmp2 |= (1 << iCount);
285     }
286   }
287   uiSymVal = (uint32_t) (iSymTmp + iSymTmp2);
288   return ERR_NONE;
289 }
290 
DecodeUEGLevelCabac(PWelsCabacDecEngine pDecEngine,PWelsCabacCtx pBinCtx,uint32_t & uiCode)291 uint32_t DecodeUEGLevelCabac (PWelsCabacDecEngine pDecEngine, PWelsCabacCtx pBinCtx, uint32_t& uiCode) {
292   uiCode = 0;
293   WELS_READ_VERIFY (DecodeBinCabac (pDecEngine, pBinCtx, uiCode));
294   if (uiCode == 0)
295     return ERR_NONE;
296   else {
297     uint32_t uiTmp, uiCount = 1;
298     uiCode = 0;
299     do {
300       WELS_READ_VERIFY (DecodeBinCabac (pDecEngine, pBinCtx, uiTmp));
301       ++uiCode;
302       ++uiCount;
303     } while (uiTmp != 0 && uiCount != 13);
304 
305     if (uiTmp != 0) {
306       WELS_READ_VERIFY (DecodeExpBypassCabac (pDecEngine, 0, uiTmp));
307       uiCode += uiTmp + 1;
308     }
309     return ERR_NONE;
310   }
311   return ERR_NONE;
312 }
313 
DecodeUEGMvCabac(PWelsCabacDecEngine pDecEngine,PWelsCabacCtx pBinCtx,uint32_t iMaxBin,uint32_t & uiCode)314 int32_t DecodeUEGMvCabac (PWelsCabacDecEngine pDecEngine, PWelsCabacCtx pBinCtx, uint32_t iMaxBin,  uint32_t& uiCode) {
315   WELS_READ_VERIFY (DecodeBinCabac (pDecEngine, pBinCtx + g_kMvdBinPos2Ctx[0], uiCode));
316   if (uiCode == 0)
317     return ERR_NONE;
318   else {
319     uint32_t uiTmp, uiCount = 1;
320     uiCode = 0;
321     do {
322       WELS_READ_VERIFY (DecodeBinCabac (pDecEngine, pBinCtx + g_kMvdBinPos2Ctx[uiCount++], uiTmp));
323       uiCode++;
324     } while (uiTmp != 0 && uiCount != 8);
325 
326     if (uiTmp != 0) {
327       WELS_READ_VERIFY (DecodeExpBypassCabac (pDecEngine, 3, uiTmp));
328       uiCode += (uiTmp + 1);
329     }
330     return ERR_NONE;
331   }
332 }
333 }
334