History

add decoder cabac support and add UT

dong zhang committed 12 years ago

Commit cf857451 parent c7b505132 files · +2615 −470Browse files

Showing the changes to codec/decoder/core/src/cabac_decoder.cpp (1 of 32 files). Show all

Unified · Split

codec/decoder/core/src/cabac_decoder.cpp+330−0
@@ -0,0 +1,330 @@
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+
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
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
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+
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
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 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+
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+
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+
214+int32_t DecodeTerminateCabac (PWelsCabacDecEngine pDecEngine, uint32_t& uiBinVal) {
215+ int32_t iErrorInfo = ERR_NONE;
216+ uint64_t uiRange = pDecEngine->uiRange - 2;
217+ int64_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+
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+
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);
277+
278+ while (iCount--) {
279+ WELS_READ_VERIFY (DecodeBypassCabac (pDecEngine, uiCode));
280+ if (uiCode == 1) {
281+ iSymTmp2 |= (1 << iCount);
282+ }
283+ }
284+ uiSymVal = (uint32_t) (iSymTmp + iSymTmp2);
285+ return ERR_NONE;
286+}
287+
288+uint32_t DecodeUEGLevelCabac (PWelsCabacDecEngine pDecEngine, PWelsCabacCtx pBinCtx, uint32_t& uiCode) {
289+ uiCode = 0;
290+ WELS_READ_VERIFY (DecodeBinCabac (pDecEngine, pBinCtx, uiCode));
291+ if (uiCode == 0)
292+ return ERR_NONE;
293+ else {
294+ uint32_t uiTmp, uiCount = 1;
295+ uiCode = 0;
296+ do {
297+ WELS_READ_VERIFY (DecodeBinCabac (pDecEngine, pBinCtx, uiTmp));
298+ ++uiCode;
299+ ++uiCount;
300+ } while (uiTmp != 0 && uiCount != 13);
301+
302+ if (uiTmp != 0) {
303+ WELS_READ_VERIFY (DecodeExpBypassCabac (pDecEngine, 0, uiTmp));
304+ uiCode += uiTmp + 1;
305+ }
306+ return ERR_NONE;
307+ }
308+ return ERR_NONE;
309+}
310+
311+int32_t DecodeUEGMvCabac (PWelsCabacDecEngine pDecEngine, PWelsCabacCtx pBinCtx, uint32_t iMaxBin, uint32_t& uiCode) {
312+ WELS_READ_VERIFY (DecodeBinCabac (pDecEngine, pBinCtx + g_kMvdBinPos2Ctx[0], uiCode));
313+ if (uiCode == 0)
314+ return ERR_NONE;
315+ else {
316+ uint32_t uiTmp, uiCount = 1;
317+ uiCode = 0;
318+ do {
319+ WELS_READ_VERIFY (DecodeBinCabac (pDecEngine, pBinCtx + g_kMvdBinPos2Ctx[uiCount++], uiTmp));
320+ uiCode++;
321+ } while (uiTmp != 0 && uiCount != 8);
322+
323+ if (uiTmp != 0) {
324+ WELS_READ_VERIFY (DecodeExpBypassCabac (pDecEngine, 3, uiTmp));
325+ uiCode += (uiTmp + 1);
326+ }
327+ return ERR_NONE;
328+ }
329+}
330+}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t