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