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 set_mb_syn_cabac.cpp
33 *
34 * \brief cabac coding engine
35 *
36 * \date 10/11/2014 Created
37 *
38 *************************************************************************************
39 */
40 #include <string.h>
41 #include "typedefs.h"
42 #include "macros.h"
43 #include "set_mb_syn_cabac.h"
44 #include "encoder.h"
45 #include "golomb_common.h"
46
47 namespace {
48
49 const int8_t g_kiClz5Table[32] = {
50 6, 5, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2,
51 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
52 };
53
PropagateCarry(uint8_t * pBufCur,uint8_t * pBufStart)54 void PropagateCarry (uint8_t* pBufCur, uint8_t* pBufStart) {
55 for (; pBufCur > pBufStart; --pBufCur)
56 if (++ * (pBufCur - 1))
57 break;
58 }
59
60 } // anon ns.
61
62 namespace WelsEnc {
63
WelsCabacInit(void * pCtx)64 void WelsCabacInit (void* pCtx) {
65 sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
66 for (int32_t iModel = 0; iModel < 4; iModel++) {
67 for (int32_t iQp = 0; iQp <= WELS_QP_MAX; iQp++)
68 for (int32_t iIdx = 0; iIdx < WELS_CONTEXT_COUNT; iIdx++) {
69 int32_t m = g_kiCabacGlobalContextIdx[iIdx][iModel][0];
70 int32_t n = g_kiCabacGlobalContextIdx[iIdx][iModel][1];
71 int32_t iPreCtxState = WELS_CLIP3 ((((m * iQp) >> 4) + n), 1, 126);
72 uint8_t uiValMps = 0;
73 uint8_t uiStateIdx = 0;
74 if (iPreCtxState <= 63) {
75 uiStateIdx = 63 - iPreCtxState;
76 uiValMps = 0;
77 } else {
78 uiStateIdx = iPreCtxState - 64;
79 uiValMps = 1;
80 }
81 pEncCtx->sWelsCabacContexts[iModel][iQp][iIdx].Set (uiStateIdx, uiValMps);
82 }
83 }
84 }
85
WelsCabacContextInit(void * pCtx,SCabacCtx * pCbCtx,int32_t iModel)86 void WelsCabacContextInit (void* pCtx, SCabacCtx* pCbCtx, int32_t iModel) {
87 sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
88 int32_t iIdx = pEncCtx->eSliceType == WelsCommon::I_SLICE ? 0 : iModel + 1;
89 int32_t iQp = pEncCtx->iGlobalQp;
90 memcpy (pCbCtx->m_sStateCtx, pEncCtx->sWelsCabacContexts[iIdx][iQp],
91 WELS_CONTEXT_COUNT * sizeof (SStateCtx));
92 }
93
WelsCabacEncodeInit(SCabacCtx * pCbCtx,uint8_t * pBuf,uint8_t * pEnd)94 void WelsCabacEncodeInit (SCabacCtx* pCbCtx, uint8_t* pBuf, uint8_t* pEnd) {
95 pCbCtx->m_uiLow = 0;
96 pCbCtx->m_iLowBitCnt = 9;
97 pCbCtx->m_iRenormCnt = 0;
98 pCbCtx->m_uiRange = 510;
99 pCbCtx->m_pBufStart = pBuf;
100 pCbCtx->m_pBufEnd = pEnd;
101 pCbCtx->m_pBufCur = pBuf;
102 }
103
WelsCabacEncodeUpdateLowNontrivial_(SCabacCtx * pCbCtx)104 void WelsCabacEncodeUpdateLowNontrivial_ (SCabacCtx* pCbCtx) {
105 int32_t iLowBitCnt = pCbCtx->m_iLowBitCnt;
106 int32_t iRenormCnt = pCbCtx->m_iRenormCnt;
107 cabac_low_t uiLow = pCbCtx->m_uiLow;
108
109 do {
110 uint8_t* pBufCur = pCbCtx->m_pBufCur;
111 const int32_t kiInc = CABAC_LOW_WIDTH - 1 - iLowBitCnt;
112
113 uiLow <<= kiInc;
114 if (uiLow & cabac_low_t (1) << (CABAC_LOW_WIDTH - 1))
115 PropagateCarry (pBufCur, pCbCtx->m_pBufStart);
116
117 if (CABAC_LOW_WIDTH > 32) {
118 WRITE_BE_32 (pBufCur, (uint32_t) (uiLow >> 31));
119 pBufCur += 4;
120 }
121 *pBufCur++ = (uint8_t) (uiLow >> 23);
122 *pBufCur++ = (uint8_t) (uiLow >> 15);
123 iRenormCnt -= kiInc;
124 iLowBitCnt = 15;
125 uiLow &= (1u << iLowBitCnt) - 1;
126 pCbCtx->m_pBufCur = pBufCur;
127 } while (iLowBitCnt + iRenormCnt > CABAC_LOW_WIDTH - 1);
128
129 pCbCtx->m_iLowBitCnt = iLowBitCnt + iRenormCnt;
130 pCbCtx->m_uiLow = uiLow << iRenormCnt;
131 }
132
WelsCabacEncodeDecisionLps_(SCabacCtx * pCbCtx,int32_t iCtx)133 void WelsCabacEncodeDecisionLps_ (SCabacCtx* pCbCtx, int32_t iCtx) {
134 const int32_t kiState = pCbCtx->m_sStateCtx[iCtx].State();
135 uint32_t uiRange = pCbCtx->m_uiRange;
136 uint32_t uiRangeLps = g_kuiCabacRangeLps[kiState][ (uiRange & 0xff) >> 6];
137 uiRange -= uiRangeLps;
138 pCbCtx->m_sStateCtx[iCtx].Set (g_kuiStateTransTable[kiState][0],
139 pCbCtx->m_sStateCtx[iCtx].Mps() ^ (kiState == 0));
140
141 WelsCabacEncodeUpdateLow_ (pCbCtx);
142 pCbCtx->m_uiLow += uiRange;
143
144 const int32_t kiRenormAmount = g_kiClz5Table[uiRangeLps >> 3];
145 pCbCtx->m_uiRange = uiRangeLps << kiRenormAmount;
146 pCbCtx->m_iRenormCnt = kiRenormAmount;
147 }
148
WelsCabacEncodeTerminate(SCabacCtx * pCbCtx,uint32_t uiBin)149 void WelsCabacEncodeTerminate (SCabacCtx* pCbCtx, uint32_t uiBin) {
150 pCbCtx->m_uiRange -= 2;
151 if (uiBin) {
152 WelsCabacEncodeUpdateLow_ (pCbCtx);
153 pCbCtx->m_uiLow += pCbCtx->m_uiRange;
154
155 const int32_t kiRenormAmount = 7;
156 pCbCtx->m_uiRange = 2 << kiRenormAmount;
157 pCbCtx->m_iRenormCnt = kiRenormAmount;
158
159 WelsCabacEncodeUpdateLow_ (pCbCtx);
160 pCbCtx->m_uiLow |= 0x80;
161 } else {
162 const int32_t kiRenormAmount = pCbCtx->m_uiRange >> 8 ^ 1;
163 pCbCtx->m_uiRange = pCbCtx->m_uiRange << kiRenormAmount;
164 pCbCtx->m_iRenormCnt += kiRenormAmount;
165 }
166 }
WelsCabacEncodeUeBypass(SCabacCtx * pCbCtx,int32_t iExpBits,uint32_t uiVal)167 void WelsCabacEncodeUeBypass (SCabacCtx* pCbCtx, int32_t iExpBits, uint32_t uiVal) {
168 int32_t iSufS = uiVal;
169 int32_t iStopLoop = 0;
170 int32_t k = iExpBits;
171 do {
172 if (iSufS >= (1 << k)) {
173 WelsCabacEncodeBypassOne (pCbCtx, 1);
174 iSufS = iSufS - (1 << k);
175 k++;
176 } else {
177 WelsCabacEncodeBypassOne (pCbCtx, 0);
178 while (k--)
179 WelsCabacEncodeBypassOne (pCbCtx, (iSufS >> k) & 1);
180 iStopLoop = 1;
181 }
182 } while (!iStopLoop);
183 }
184
WelsCabacEncodeFlush(SCabacCtx * pCbCtx)185 void WelsCabacEncodeFlush (SCabacCtx* pCbCtx) {
186 WelsCabacEncodeTerminate (pCbCtx, 1);
187
188 cabac_low_t uiLow = pCbCtx->m_uiLow;
189 int32_t iLowBitCnt = pCbCtx->m_iLowBitCnt;
190 uint8_t* pBufCur = pCbCtx->m_pBufCur;
191
192 uiLow <<= CABAC_LOW_WIDTH - 1 - iLowBitCnt;
193 if (uiLow & cabac_low_t (1) << (CABAC_LOW_WIDTH - 1))
194 PropagateCarry (pBufCur, pCbCtx->m_pBufStart);
195 for (; (iLowBitCnt -= 8) >= 0; uiLow <<= 8)
196 * pBufCur++ = (uint8_t) (uiLow >> (CABAC_LOW_WIDTH - 9));
197
198 pCbCtx->m_pBufCur = pBufCur;
199 }
200
WelsCabacEncodeGetPtr(SCabacCtx * pCbCtx)201 uint8_t* WelsCabacEncodeGetPtr (SCabacCtx* pCbCtx) {
202 return pCbCtx->m_pBufCur;
203 }
204 }
205