• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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