History

Initial Commit

Ethan Hugg committed 12 years ago

Commit 70e5e621 parent bd509b2308 files · +97095 −-5Browse files

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

Unified · Split

codec/decoder/core/src/decode_slice.cpp+1361−0
@@ -0,0 +1,1361 @@
1+/*!
2+ * \copy
3+ * Copyright (c) 2008-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+ * Abstract
33+ * current slice decoding
34+ *
35+ * History
36+ * 07/10/2008 Created
37+ * 08/09/2013 Modified
38+ *
39+ *****************************************************************************/
40+#include <memory.h>
41+
42+#include "typedefs.h"
43+#include "dec_golomb.h"
44+
45+#include "fmo.h"
46+#include "deblocking.h"
47+#include "utils.h"
48+
49+#include "decode_slice.h"
50+
51+#include "error_code.h"
52+#include "decode_mb_aux.h"
53+#include "parse_mb_syn_cavlc.h"
54+#include "rec_mb.h"
55+#include "mv_pred.h"
56+
57+#include "as264_common.h"
58+#include "cpu_core.h"
59+#include "expand_pic.h"
60+
61+namespace WelsDec {
62+
63+int32_t WelsTargetSliceConstruction( PWelsDecoderContext pCtx )
64+{
65+ int32_t iPreQP = 0;
66+
67+ PDqLayer pCurLayer = pCtx->pCurDqLayer;
68+ PSlice pCurSlice = &pCurLayer->sLayerInfo.sSliceInLayer;
69+ PSliceHeader pSliceHeader = &pCurSlice->sSliceHeaderExt.sSliceHeader;
70+
71+ int32_t iTotalMbTargetLayer = pSliceHeader->pSps->uiTotalMbCount;
72+
73+ int32_t iCurLayerWidth = pCurLayer->iMbWidth << 4;
74+ int32_t iCurLayerHeight = pCurLayer->iMbHeight << 4;
75+
76+ int32_t iNextMbXyIndex = 0;
77+ PFmo pFmo = pCtx->pFmo;
78+
79+ int32_t iTotalNumMb = pCurSlice->iTotalMbInCurSlice;
80+ int32_t iCountNumMb = 0;
81+ PDeblockingFilterMbFunc pDeblockMb;
82+
83+ if ( !pCtx->bAvcBasedFlag && iCurLayerWidth != pCtx->iCurSeqIntervalMaxPicWidth )
84+ {
85+ return -1;
86+ }
87+
88+ iNextMbXyIndex = pSliceHeader->iFirstMbInSlice;
89+ pCurLayer->iMbX = iNextMbXyIndex % pCurLayer->iMbWidth;
90+ pCurLayer->iMbY = iNextMbXyIndex / pCurLayer->iMbWidth;
91+ pCurLayer->iMbXyIndex = iNextMbXyIndex;
92+
93+ if ( 0 == iNextMbXyIndex )
94+ {
95+ pCurLayer->pDec->iSpsId = pSliceHeader->iSpsId;
96+ pCurLayer->pDec->iPpsId = pSliceHeader->iPpsId;
97+
98+ pCurLayer->pDec->uiQualityId = pCurLayer->sLayerInfo.sNalHeaderExt.uiQualityId;
99+ }
100+
101+ do
102+ {
103+ iPreQP = pCurLayer->pLumaQp[pCurLayer->iMbXyIndex];
104+
105+ if ( WelsTargetMbConstruction( pCtx ) )
106+ {
107+ WelsLog( pCtx, WELS_LOG_WARNING, "WelsTargetSliceConstruction():::MB(%d, %d) construction error. pCurSlice_type:%d\n",
108+ pCurLayer->iMbX, pCurLayer->iMbY, pCurSlice->eSliceType );
109+
110+ return -1;
111+ }
112+
113+ ++iCountNumMb;
114+ ++pCurLayer->pDec->iTotalNumMbRec;
115+ if ( iCountNumMb >= iTotalNumMb )
116+ {
117+ break;
118+ }
119+ if ( pCurLayer->pDec->iTotalNumMbRec > iTotalMbTargetLayer )
120+ {
121+ WelsLog( pCtx, WELS_LOG_WARNING, "WelsTargetSliceConstruction():::fdec->iTotalNumMbRec:%d, iTotalMbTargetLayer:%d\n",
122+ pCurLayer->pDec->iTotalNumMbRec, iTotalMbTargetLayer );
123+
124+ return -1;
125+ }
126+
127+ if ( pSliceHeader->pPps->uiNumSliceGroups > 1 )
128+ {
129+ iNextMbXyIndex = FmoNextMb( pFmo, iNextMbXyIndex );
130+ }
131+ else
132+ {
133+ ++iNextMbXyIndex;
134+ }
135+ if ( -1 == iNextMbXyIndex || iNextMbXyIndex >= iTotalMbTargetLayer ) // slice group boundary or end of a frame
136+ {
137+ break;
138+ }
139+ pCurLayer->iMbX = iNextMbXyIndex % pCurLayer->iMbWidth;
140+ pCurLayer->iMbY = iNextMbXyIndex / pCurLayer->iMbWidth;
141+ pCurLayer->iMbXyIndex = iNextMbXyIndex;
142+ } while (1);
143+
144+ pCtx->pDec->iWidthInPixel = iCurLayerWidth;
145+ pCtx->pDec->iHeightInPixel = iCurLayerHeight;
146+
147+ if((pCurSlice->eSliceType != I_SLICE)&&(pCurSlice->eSliceType != P_SLICE))
148+ return 0;
149+
150+ pDeblockMb = WelsDeblockingMb;
151+
152+ if ( 1 == pSliceHeader->uiDisableDeblockingFilterIdc )
153+ {
154+ return 0;//NO_SUPPORTED_FILTER_IDX
155+ }
156+ else
157+ {
158+ WelsDeblockingFilterSlice( pCtx, pDeblockMb );
159+
160+ }
161+ // any other filter_idc not supported here, 7/22/2010
162+
163+ return 0;
164+}
165+
166+int32_t WelsMbInterSampleConstruction( PWelsDecoderContext pCtx, PDqLayer pCurLayer,
167+ uint8_t* pDstY, uint8_t* pDstU, uint8_t* pDstV, int32_t iStrideL, int32_t iStrideC )
168+{
169+ int32_t iMbXy = pCurLayer->iMbXyIndex;
170+ int32_t i, iIndex, iOffset;
171+
172+ WelsChromaDcIdct( pCurLayer->pScaledTCoeff[iMbXy] + 256 ); // 256 = 16*16
173+ WelsChromaDcIdct( pCurLayer->pScaledTCoeff[iMbXy] + 320 ); // 320 = 16*16 + 16*4
174+
175+ for(i=0; i<16; i++) //luma
176+ {
177+ iIndex = g_kuiMbNonZeroCountIdx[i];
178+ if( pCurLayer->pNzc[iMbXy][iIndex] )
179+ {
180+ iOffset = ((iIndex>>2)<<2) * iStrideL + ((iIndex%4)<<2);
181+ pCtx->pIdctResAddPredFunc( pDstY+iOffset, iStrideL, pCurLayer->pScaledTCoeff[iMbXy]+(i<<4) );
182+ }
183+ }
184+
185+ for ( i = 0; i < 4; i++ ) //chroma
186+ {
187+ iIndex = g_kuiMbNonZeroCountIdx[i+16]; //Cb
188+ if ( pCurLayer->pNzc[iMbXy][iIndex] || *(pCurLayer->pScaledTCoeff[iMbXy]+((i+16)<<4)) )
189+ {
190+ iOffset = (((iIndex-16)>>2)<<2) * iStrideC + (((iIndex-16)%4)<<2);
191+ pCtx->pIdctResAddPredFunc( pDstU+iOffset, iStrideC, pCurLayer->pScaledTCoeff[iMbXy]+((i+16)<<4) );
192+ }
193+
194+ iIndex = g_kuiMbNonZeroCountIdx[i+20]; //Cr
195+ if ( pCurLayer->pNzc[iMbXy][iIndex] || *(pCurLayer->pScaledTCoeff[iMbXy]+((i+20)<<4)) )
196+ {
197+ iOffset = (((iIndex-18)>>2)<<2) * iStrideC + (((iIndex-18)%4)<<2);
198+ pCtx->pIdctResAddPredFunc( pDstV+iOffset, iStrideC , pCurLayer->pScaledTCoeff[iMbXy]+((i+20)<<4));
199+ }
200+ }
201+
202+ return 0;
203+}
204+int32_t WelsMbInterConstruction(PWelsDecoderContext pCtx, PDqLayer pCurLayer)
205+{
206+ int32_t iMbX = pCurLayer->iMbX;
207+ int32_t iMbY = pCurLayer->iMbY;
208+ uint8_t *pDstY, *pDstCb, *pDstCr;
209+
210+ int32_t iLumaStride = pCtx->pDec->iLinesize[0];
211+ int32_t iChromaStride = pCtx->pDec->iLinesize[1];
212+
213+ pDstY = pCurLayer->pDec->pData[0] + ((iMbY * iLumaStride + iMbX)<<4);
214+ pDstCb = pCurLayer->pDec->pData[1] + ((iMbY * iChromaStride + iMbX)<<3);
215+ pDstCr = pCurLayer->pDec->pData[2] + ((iMbY * iChromaStride + iMbX)<<3);
216+
217+ GetInterPred(pDstY, pDstCb, pDstCr, pCtx);
218+ WelsMbInterSampleConstruction( pCtx, pCurLayer, pDstY, pDstCb, pDstCr, iLumaStride, iChromaStride );
219+
220+ pCtx->sBlockFunc.pWelsSetNonZeroCountFunc(NULL, pCurLayer->pNzc[pCurLayer->iMbXyIndex]);// set all none-zero nzc to 1; dbk can be opti!
221+ return 0;
222+}
223+
224+void_t WelsLumaDcDequantIdct(int16_t *pBlock, int32_t iQp){
225+ const int32_t kiQMul= g_kuiDequantCoeff[iQp][0];
226+#define STRIDE 16
227+ int32_t i;
228+ int32_t iTemp[16]; //FIXME check if this is a good idea
229+ int16_t* pBlk = pBlock;
230+ static const int32_t kiXOffset[4]={0, STRIDE, STRIDE<<2, 5*STRIDE};
231+ static const int32_t kiYOffset[4]={0, STRIDE<<1, STRIDE<<3, 10*STRIDE};
232+
233+ for(i=0; i<4; i++){
234+ const int32_t kiOffset= kiYOffset[i];
235+ const int32_t kiX1 = kiOffset + kiXOffset[2];
236+ const int32_t kiX2 = STRIDE + kiOffset;
237+ const int32_t kiX3 = kiOffset + kiXOffset[3];
238+ const int32_t kiI4 = i << 2; // 4*i
239+ const int32_t kiZ0= pBlk[kiOffset] + pBlk[kiX1];
240+ const int32_t kiZ1= pBlk[kiOffset] - pBlk[kiX1];
241+ const int32_t kiZ2= pBlk[kiX2] - pBlk[kiX3];
242+ const int32_t kiZ3= pBlk[kiX2] + pBlk[kiX3];
243+
244+ iTemp[kiI4] = kiZ0+kiZ3;
245+ iTemp[1+kiI4]= kiZ1+kiZ2;
246+ iTemp[2+kiI4]= kiZ1-kiZ2;
247+ iTemp[3+kiI4]= kiZ0-kiZ3;
248+ }
249+
250+ for(i=0; i<4; i++){
251+ const int32_t kiOffset= kiXOffset[i];
252+ const int32_t kiI4 = 4 + i;
253+ const int32_t kiZ0= iTemp[i] + iTemp[4+kiI4];
254+ const int32_t kiZ1= iTemp[i] - iTemp[4+kiI4];
255+ const int32_t kiZ2= iTemp[kiI4] - iTemp[8+kiI4];
256+ const int32_t kiZ3= iTemp[kiI4] + iTemp[8+kiI4];
257+
258+ pBlk[kiOffset]= ((kiZ0 + kiZ3)*kiQMul + 2)>>2; //FIXME think about merging this into decode_resdual
259+ pBlk[kiYOffset[1] +kiOffset]= ((kiZ1 + kiZ2)*kiQMul + 2)>>2;
260+ pBlk[kiYOffset[2] +kiOffset]= ((kiZ1 - kiZ2)*kiQMul + 2)>>2;
261+ pBlk[kiYOffset[3] +kiOffset]= ((kiZ0 - kiZ3)*kiQMul + 2)>>2;
262+ }
263+ #undef STRIDE
264+}
265+
266+int32_t WelsMbIntraPredictionConstruction(PWelsDecoderContext pCtx, PDqLayer pCurLayer, bool_t bOutput)
267+{
268+//seems IPCM should not enter this path
269+ int32_t iMbXy = pCurLayer->iMbXyIndex;
270+
271+ FORCE_STACK_ALIGN_1D( int16_t, pTempScaledTCoeff, MB_COEFF_LIST_SIZE, 16 );
272+
273+ memcpy(pTempScaledTCoeff, pCurLayer->pScaledTCoeff[iMbXy], 384*sizeof(pCurLayer->pScaledTCoeff[iMbXy][0]));
274+
275+ WelsFillRecNeededMbInfo(pCtx, bOutput, pCurLayer);
276+
277+ if(IS_INTRA16x16(pCurLayer->pMbType[iMbXy]))
278+ {
279+ int32_t i,j;
280+ // really need?
281+ for(i=0; i<16; i++)
282+ {
283+ j = g_kuiLumaDcZigzagScan[i];
284+ pTempScaledTCoeff[j] = pCurLayer->pScaledTCoeff[iMbXy][j];
285+ }
286+ WelsLumaDcDequantIdct(pTempScaledTCoeff, pCurLayer->pLumaQp[iMbXy]);
287+ RecI16x16Mb(iMbXy, pCtx,pTempScaledTCoeff,pCurLayer);
288+
289+ return 0;
290+ }
291+
292+ if(IS_INTRA4x4(pCurLayer->pMbType[iMbXy]))
293+ RecI4x4Mb(iMbXy, pCtx,pTempScaledTCoeff,pCurLayer);
294+
295+ return 0;
296+}
297+
298+int32_t WelsMbInterPrediction(PWelsDecoderContext pCtx, PDqLayer pCurLayer)
299+{
300+ int32_t iMbX = pCurLayer->iMbX;
301+ int32_t iMbY = pCurLayer->iMbY;
302+ uint8_t *pDstY, *pDstCb, *pDstCr;
303+
304+ int32_t iLumaStride = pCtx->pDec->iLinesize[0];
305+ int32_t iChromaStride = pCtx->pDec->iLinesize[1];
306+
307+ pDstY = pCurLayer->pDec->pData[0] + ((iMbY * iLumaStride + iMbX)<<4);
308+ pDstCb = pCurLayer->pDec->pData[1] + ((iMbY * iChromaStride + iMbX)<<3);
309+ pDstCr = pCurLayer->pDec->pData[2] + ((iMbY * iChromaStride + iMbX)<<3);
310+
311+ GetInterPred(pDstY, pDstCb, pDstCr, pCtx);
312+
313+ return 0;
314+}
315+
316+void_t WelsMbCopy( uint8_t *pDst, int32_t iStrideDst, uint8_t *pSrc, int32_t iStrideSrc,
317+ int32_t iHeight, int32_t iWidth )
318+{
319+ int32_t i;
320+ int32_t iOffsetDst = 0, iOffsetSrc = 0;
321+ for ( i = 0; i < iHeight; i++ )
322+ {
323+ memcpy( pDst+iOffsetDst, pSrc+iOffsetSrc, iWidth );
324+ iOffsetDst += iStrideDst;
325+ iOffsetSrc += iStrideSrc;
326+ }
327+}
328+
329+
330+int32_t WelsTargetMbConstruction(PWelsDecoderContext pCtx)
331+{
332+ PDqLayer pCurLayer = pCtx->pCurDqLayer;
333+ if ( MB_TYPE_INTRA_PCM == pCurLayer->pMbType[pCurLayer->iMbXyIndex] )
334+ {
335+ //copy cs into fdec
336+ int32_t iCsStrideL = pCurLayer->iCsStride[0];
337+ int32_t iCsStrideC = pCurLayer->iCsStride[1];
338+
339+ int32_t iDecStrideL = pCurLayer->pDec->iLinesize[0];
340+ int32_t iDecStrideC = pCurLayer->pDec->iLinesize[1];
341+
342+ int32_t iCsOffsetL = ( pCurLayer->iMbX + pCurLayer->iMbY * iCsStrideL ) << 4;
343+ int32_t iCsOffsetC = ( pCurLayer->iMbX + pCurLayer->iMbY * iCsStrideC ) << 3;
344+
345+ int32_t iDecOffsetL = ( pCurLayer->iMbX + pCurLayer->iMbY * iDecStrideL ) << 4;
346+ int32_t iDecOffsetC = ( pCurLayer->iMbX + pCurLayer->iMbY * iDecStrideC ) << 3;
347+
348+ uint8_t* pSrcY = pCurLayer->pCsData[0] + iCsOffsetL;
349+ uint8_t* pSrcU = pCurLayer->pCsData[1] + iCsOffsetC;
350+ uint8_t* pSrcV = pCurLayer->pCsData[2] + iCsOffsetC;
351+
352+ uint8_t* pDecY = pCurLayer->pDec->pData[0] + iDecOffsetL;
353+ uint8_t* pDecU = pCurLayer->pDec->pData[1] + iDecOffsetC;
354+ uint8_t* pDecV = pCurLayer->pDec->pData[2] + iDecOffsetC;
355+
356+ WelsMbCopy( pDecY, iDecStrideL, pSrcY, iCsStrideL, 16, 16 );
357+ WelsMbCopy( pDecU, iDecStrideC, pSrcU, iCsStrideC, 8, 8 );
358+ WelsMbCopy( pDecV, iDecStrideC, pSrcV, iCsStrideC, 8, 8 );
359+
360+ return 0;
361+ }
362+ else if(IS_INTRA(pCurLayer->pMbType[pCurLayer->iMbXyIndex]))
363+ {
364+ WelsMbIntraPredictionConstruction(pCtx, pCurLayer, 1);
365+ }
366+ else if ( IS_INTER( pCurLayer->pMbType[pCurLayer->iMbXyIndex] ) ) //InterMB
367+ {
368+ if ( 0 == pCurLayer->pCbp[pCurLayer->iMbXyIndex] ) //uiCbp==0 include SKIP
369+ {
370+ WelsMbInterPrediction( pCtx, pCurLayer );
371+ }
372+ else
373+ {
374+ WelsMbInterConstruction( pCtx, pCurLayer );
375+ }
376+ }
377+ else
378+ {
379+ WelsLog( pCtx, WELS_LOG_WARNING, "WelsTargetMbConstruction():::::Unknown MB type: %d\n", pCurLayer->pMbType[pCurLayer->iMbXyIndex] );
380+ return -1;
381+ }
382+
383+ return 0;
384+}
385+
386+void_t WelsChromaDcIdct( int16_t *pBlock )
387+{
388+ int32_t iStride= 32;
389+ int32_t iXStride= 16;
390+ int32_t iStride1 = iXStride + iStride;
391+ int16_t* pBlk = pBlock;
392+ int32_t iA,iB,iC,iD,iE;
393+
394+ iA= pBlk[0];
395+ iB= pBlk[iXStride];
396+ iC= pBlk[iStride];
397+ iD= pBlk[iStride1];
398+
399+ iE = iA-iB;
400+ iA += iB;
401+ iB = iC-iD;
402+ iC += iD;
403+
404+ pBlk[0]= (iA+iC) >> 1;
405+ pBlk[iXStride]= (iE+iB) >> 1;
406+ pBlk[iStride]= (iA-iC) >> 1;
407+ pBlk[iStride1]= (iE-iB) >> 1;
408+}
409+
410+int32_t WelsDecodeSlice(PWelsDecoderContext pCtx, bool_t bFirstSliceInLayer, PNalUnit pNalCur)
411+{
412+ PDqLayer pCurLayer = pCtx->pCurDqLayer;
413+ PFmo pFmo = pCtx->pFmo;
414+ int32_t i, iRet;
415+ int32_t iNextMbXyIndex, iSliceIdc;
416+
417+ PSlice pSlice = &pCurLayer->sLayerInfo.sSliceInLayer;
418+ PSliceHeaderExt pSliceHeaderExt = &pSlice->sSliceHeaderExt;
419+ PSliceHeader pSliceHeader = &pSliceHeaderExt->sSliceHeader;
420+ int32_t iMbX, iMbY;
421+ const int32_t kiCountNumMb = pSliceHeader->pSps->uiTotalMbCount; //need to be correct when fmo or multi slice
422+ PBitStringAux pBs = pCurLayer->pBitStringAux;
423+ int32_t iUsedBits = 0;
424+
425+ PWelsDecMbCavlcFunc pDecMbCavlcFunc;
426+
427+ pSlice->iTotalMbInCurSlice = 0; //initialize at the starting of slice decoding.
428+
429+ if ( P_SLICE == pSliceHeader->eSliceType )
430+ {
431+ pDecMbCavlcFunc = WelsDecodeMbCavlcPSlice;
432+ }
433+ else //I_SLICE
434+ {
435+ pDecMbCavlcFunc = WelsDecodeMbCavlcISlice;
436+ }
437+
438+ if ( pSliceHeader->pPps->bConstainedIntraPredFlag )
439+ {
440+ pCtx->pFillInfoCacheIntra4x4Func = WelsFillCacheConstrain1Intra4x4;
441+ pCtx->pParseIntra4x4ModeFunc = ParseIntra4x4ModeConstrain1;
442+ pCtx->pParseIntra16x16ModeFunc = ParseIntra16x16ModeConstrain1;
443+ }
444+ else
445+ {
446+ pCtx->pFillInfoCacheIntra4x4Func = WelsFillCacheConstrain0Intra4x4;
447+ pCtx->pParseIntra4x4ModeFunc = ParseIntra4x4ModeConstrain0;
448+ pCtx->pParseIntra16x16ModeFunc = ParseIntra16x16ModeConstrain0;
449+ }
450+
451+ pCtx->eSliceType = pSliceHeader->eSliceType;
452+
453+ if (pCurLayer->sLayerInfo.pPps->bEntropyCodingModeFlag == 1)
454+ {
455+ //CABAC encoding is unsupported yet!
456+ return -1;
457+ }
458+
459+ iNextMbXyIndex = pSliceHeader->iFirstMbInSlice;
460+
461+ if ( iNextMbXyIndex >= kiCountNumMb )
462+ {
463+ WelsLog(pCtx, WELS_LOG_ERROR, "WelsDecodeSlice()::iFirstMbInSlice(%d) > pSps->kiTotalMb(%d). ERROR!!! resolution change....\n",
464+ iNextMbXyIndex, kiCountNumMb);
465+ pCtx->iErrorCode |= dsNoParamSets;
466+ return dsNoParamSets;
467+ }
468+
469+ iMbX = iNextMbXyIndex % pCurLayer->iMbWidth;
470+ iMbY = iNextMbXyIndex / pCurLayer->iMbWidth; // error is introduced by multiple slices case, 11/23/2009
471+ pSlice->iMbSkipRun = -1;
472+ iSliceIdc = (pSliceHeader->iFirstMbInSlice<<7)+pCurLayer->uiLayerDqId;
473+
474+ pCurLayer->iMbX = iMbX;
475+ pCurLayer->iMbY = iMbY;
476+ pCurLayer->iMbXyIndex = iNextMbXyIndex;
477+
478+ if(pSliceHeaderExt->bSliceSkipFlag == 1)
479+ {
480+ for(i=0; i<(int32_t)pSliceHeaderExt->uiNumMbsInSlice; i++)
481+ {
482+ pCurLayer->pSliceIdc[iNextMbXyIndex] = iSliceIdc;
483+
484+
485+ pCurLayer->pResidualPredFlag[iNextMbXyIndex] = 1;
486+
487+ if ( pSliceHeaderExt->sSliceHeader.pPps->uiNumSliceGroups > 1 )
488+ {
489+ iNextMbXyIndex = FmoNextMb( pFmo, iNextMbXyIndex );
490+ }
491+ else
492+ {
493+ ++iNextMbXyIndex;
494+ }
495+
496+ iMbX = iNextMbXyIndex%pCurLayer->iMbWidth;
497+ iMbY = iNextMbXyIndex%pCurLayer->iMbHeight;
498+
499+ pCurLayer->iMbX = iMbX;
500+ pCurLayer->iMbY = iMbY;
501+ pCurLayer->iMbXyIndex = iNextMbXyIndex;
502+ }
503+ return 0;
504+ }
505+
506+ do{
507+ pCurLayer->pSliceIdc[iNextMbXyIndex] = iSliceIdc;
508+ iRet = pDecMbCavlcFunc( pCtx, pNalCur );
509+
510+ if (iRet != ERR_NONE){
511+ return iRet;
512+ }
513+
514+ ++pSlice->iTotalMbInCurSlice;
515+
516+ if ( pSliceHeader->pPps->uiNumSliceGroups > 1 )
517+ {
518+ iNextMbXyIndex = FmoNextMb( pFmo, iNextMbXyIndex );
519+ }
520+ else
521+ {
522+ ++iNextMbXyIndex;
523+ }
524+ if ( (-1 == iNextMbXyIndex) || (iNextMbXyIndex >= kiCountNumMb) ) // slice group boundary or end of a frame
525+ {
526+ break;
527+ }
528+
529+ // check whether there is left bits to read next time in case multiple slices
530+ iUsedBits = ((pBs->pCurBuf-pBs->pStartBuf)<<3) - (16-pBs->iLeftBits);
531+ if ( iUsedBits == pBs->iBits && 0 >= pCurLayer->sLayerInfo.sSliceInLayer.iMbSkipRun ) // slice boundary
532+ {
533+ break;
534+ }
535+ if ( iUsedBits > pBs->iBits )//When BS incomplete, as long as find it, SHOULD stop decoding to avoid mosaic or crash.
536+ {
537+ WelsLog( pCtx, WELS_LOG_WARNING, "WelsDecodeSlice()::::pBs incomplete, iUsedBits:%d > pBs->iBits:%d, MUST stop decoding.\n",
538+ iUsedBits, pBs->iBits );
539+ return -1;
540+ }
541+ iMbX = iNextMbXyIndex % pCurLayer->iMbWidth;
542+ iMbY = iNextMbXyIndex / pCurLayer->iMbWidth;
543+ pCurLayer->iMbX = iMbX;
544+ pCurLayer->iMbY = iMbY;
545+ pCurLayer->iMbXyIndex = iNextMbXyIndex;
546+ }while(1);
547+
548+ return ERR_NONE;
549+}
550+
551+int32_t WelsActualDecodeMbCavlcISlice(PWelsDecoderContext pCtx)
552+{
553+ SVlcTable* pVlcTable = &pCtx->sVlcTable;
554+ PDqLayer pCurLayer = pCtx->pCurDqLayer;
555+ PBitStringAux pBs = pCurLayer->pBitStringAux;
556+ PSlice pSlice = &pCurLayer->sLayerInfo.sSliceInLayer;
557+ PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
558+
559+ SNeighAvail sNeighAvail;
560+
561+ int32_t iScanIdxStart = pSlice->sSliceHeaderExt.uiScanIdxStart;
562+ int32_t iScanIdxEnd = pSlice->sSliceHeaderExt.uiScanIdxEnd;
563+
564+ int32_t iMbX = pCurLayer->iMbX;
565+ int32_t iMbY = pCurLayer->iMbY;
566+ int32_t iMbXy = pCurLayer->iMbXyIndex;
567+ int32_t iNMbMode, i;
568+ uint32_t uiMbType = 0, uiCbp = 0, uiCbpL = 0, uiCbpC = 0;
569+
570+ FORCE_STACK_ALIGN_1D( uint8_t, pNonZeroCount, 48, 16 );
571+
572+ pCurLayer->pInterPredictionDoneFlag[iMbXy] = 0;
573+ pCurLayer->pResidualPredFlag[iMbXy] = pSlice->sSliceHeaderExt.bDefaultResidualPredFlag;
574+
575+ uiMbType = BsGetUe(pBs);
576+ if ( uiMbType > 25 )
577+ {
578+ return ERR_INFO_INVALID_MB_TYPE;
579+ }
580+
581+ if ( 25 == uiMbType )
582+ {
583+ int32_t iDecStrideL = pCurLayer->pDec->iLinesize[0];
584+ int32_t iDecStrideC = pCurLayer->pDec->iLinesize[1];
585+
586+ int32_t iOffsetL = ( iMbX + iMbY * iDecStrideL ) << 4;
587+ int32_t iOffsetC = ( iMbX + iMbY * iDecStrideC ) << 3;
588+
589+ uint8_t* pDecY = pCurLayer->pCsData[0] + iOffsetL;
590+ uint8_t* pDecU = pCurLayer->pCsData[1] + iOffsetC;
591+ uint8_t* pDecV = pCurLayer->pCsData[2] + iOffsetC;
592+
593+ uint8_t *pTmpBsBuf;
594+
595+ int32_t i;
596+ int32_t iCopySizeY = ( sizeof( uint8_t ) << 4 );
597+ int32_t iCopySizeUV = ( sizeof( uint8_t ) << 3 );
598+
599+ int32_t iIndex = ((-pBs->iLeftBits)>>3) + 2;
600+
601+ pCurLayer->pMbType[iMbXy] = MB_TYPE_INTRA_PCM;
602+
603+ //step 1: locating bit-stream pointer [must align into integer byte]
604+ pBs->pCurBuf -= iIndex;
605+
606+ //step 2: copy pixel from bit-stream into fdec [reconstruction]
607+ pTmpBsBuf = pBs->pCurBuf;
608+ for ( i = 0; i < 16; i++ ) //luma
609+ {
610+ memcpy( pDecY , pTmpBsBuf, iCopySizeY );
611+ pDecY += iDecStrideL;
612+ pTmpBsBuf += 16;
613+ }
614+ for ( i = 0; i < 8; i++ ) //cb
615+ {
616+ memcpy( pDecU, pTmpBsBuf, iCopySizeUV );
617+ pDecU += iDecStrideC;
618+ pTmpBsBuf += 8;
619+ }
620+ for ( i = 0; i < 8; i++ ) //cr
621+ {
622+ memcpy( pDecV, pTmpBsBuf, iCopySizeUV );
623+ pDecV += iDecStrideC;
624+ pTmpBsBuf += 8;
625+ }
626+
627+ pBs->pCurBuf += 384;
628+ InitReadBits( pBs );
629+
630+ //step 3: update QP and pNonZeroCount
631+ pCurLayer->pLumaQp[iMbXy] = 0;
632+ pCurLayer->pChromaQp[iMbXy] = 0;
633+ memset( pCurLayer->pNzc[iMbXy], 16, sizeof( pCurLayer->pNzc[iMbXy] ) ); //JVT-x201wcm1.doc, page229, 2009.10.23
634+ return 0;
635+ }
636+ else if (0 == uiMbType) //reference to JM
637+ {
638+ FORCE_STACK_ALIGN_1D( int8_t, pIntraPredMode, 48, 16 );
639+ pCurLayer->pMbType[iMbXy] = MB_TYPE_INTRA4x4;
640+ pCtx->pFillInfoCacheIntra4x4Func( &sNeighAvail, pNonZeroCount, pIntraPredMode, pCurLayer );
641+ if ( pCtx->pParseIntra4x4ModeFunc( &sNeighAvail, pIntraPredMode, pBs, pCurLayer ) )
642+ {
643+ return -1;
644+ }
645+
646+ //uiCbp
647+ uiCbp = BsGetUe(pBs);
648+ //G.9.1 Alternative parsing process for coded pBlock pattern
649+ if ( uiCbp > 47 )
650+ return ERR_INFO_INVALID_CBP;
651+
652+ uiCbp = g_kuiIntra4x4CbpTable[uiCbp];
653+
654+ pCurLayer->pCbp[iMbXy] = uiCbp;
655+ uiCbpC = uiCbp >> 4;
656+ uiCbpL = uiCbp & 15;
657+ }
658+ else //I_PCM exclude, we can ignore it
659+ {
660+ pCurLayer->pMbType[iMbXy] = MB_TYPE_INTRA16x16;
661+ pCurLayer->pIntraPredMode[iMbXy][7] = (uiMbType-1) & 3;
662+ pCurLayer->pCbp[iMbXy] = g_kuiI16CbpTable[(uiMbType-1)>>2];
663+ uiCbpC = pCurLayer->pCbp[iMbXy] >> 4;
664+ uiCbpL = pCurLayer->pCbp[iMbXy] & 15;
665+ WelsFillCacheNonZeroCount( &sNeighAvail, pNonZeroCount, pCurLayer );
666+ if ( pCtx->pParseIntra16x16ModeFunc( &sNeighAvail, pBs, pCurLayer ) )
667+ {
668+ return -1;
669+ }
670+ }
671+
672+ iNMbMode = BASE_MB;
673+
674+ memset(pCurLayer->pScaledTCoeff[iMbXy], 0, 384*sizeof(pCurLayer->pScaledTCoeff[iMbXy][0]));
675+ ST32(&pCurLayer->pNzc[iMbXy][0], 0);
676+ ST32(&pCurLayer->pNzc[iMbXy][4], 0);
677+ ST32(&pCurLayer->pNzc[iMbXy][8], 0);
678+ ST32(&pCurLayer->pNzc[iMbXy][12], 0);
679+ ST32(&pCurLayer->pNzc[iMbXy][16], 0);
680+ ST32(&pCurLayer->pNzc[iMbXy][20], 0);
681+
682+ if( pCurLayer->pCbp[iMbXy] == 0 && IS_INTRA4x4(pCurLayer->pMbType[iMbXy]))
683+ {
684+ pCurLayer->pLumaQp[iMbXy] = pSlice->iLastMbQp;
685+ pCurLayer->pChromaQp[iMbXy] = g_kuiChromaQp[WELS_CLIP3(pCurLayer->pLumaQp[iMbXy] +
686+ pSliceHeader->pPps->iChromaQpIndexOffset, 0, 51)];
687+
688+ }
689+
690+ if ( pCurLayer->pCbp[iMbXy] || MB_TYPE_INTRA16x16 == pCurLayer->pMbType[iMbXy] )
691+ {
692+ int32_t iQpDelta, iId8x8, iId4x4;
693+
694+ iQpDelta = BsGetSe(pBs);
695+
696+ if (iQpDelta > 25 || iQpDelta < -26) //out of iQpDelta range
697+ {
698+ return ERR_INFO_INVALID_QP;
699+ }
700+
701+ pCurLayer->pLumaQp[iMbXy] = pSlice->iLastMbQp + iQpDelta; //update iLastMbQp
702+ //refer to JVT-X201wcm1.doc equation(7-35)
703+ if ( (unsigned)(pCurLayer->pLumaQp[iMbXy]) > 51 )
704+ {
705+ if ( pCurLayer->pLumaQp[iMbXy] < 0 )
706+ {
707+ pCurLayer->pLumaQp[iMbXy] += 52;
708+ }
709+ else
710+ {
711+ pCurLayer->pLumaQp[iMbXy] -= 52;
712+ }
713+ }
714+ //QP should be in the range of [0, 51]
715+ if ( pCurLayer->pLumaQp[iMbXy] < 0 || pCurLayer->pLumaQp[iMbXy] > 51 )
716+ {
717+ return ERR_INFO_INVALID_QP;
718+ }
719+ pSlice->iLastMbQp = pCurLayer->pLumaQp[iMbXy];
720+ pCurLayer->pChromaQp[iMbXy] = g_kuiChromaQp[WELS_CLIP3(pSlice->iLastMbQp + pSliceHeader->pPps->iChromaQpIndexOffset, 0, 51)];
721+
722+
723+ BsStartCavlc( pBs );
724+
725+ if ( MB_TYPE_INTRA16x16 == pCurLayer->pMbType[iMbXy] )
726+ {
727+ //step1: Luma DC
728+ if ( WelsResidualBlockCavlc( pVlcTable, pNonZeroCount, pBs, 0, 16,
729+ g_kuiLumaDcZigzagScan, I16_LUMA_DC, pCurLayer->pScaledTCoeff[iMbXy], iNMbMode, pCurLayer->pLumaQp[iMbXy], pCtx) )
730+ {
731+ return -1;//abnormal
732+ }
733+ //step2: Luma AC
734+ if (uiCbpL)
735+ {
736+ for (i = 0; i < 16; i++)
737+ {
738+ if ( WelsResidualBlockCavlc( pVlcTable, pNonZeroCount, pBs, i,
739+ iScanIdxEnd - WELS_MAX(iScanIdxStart, 1) + 1, g_kuiZigzagScan+ WELS_MAX(iScanIdxStart,1),
740+ I16_LUMA_AC, pCurLayer->pScaledTCoeff[iMbXy] + (i<<4), iNMbMode, pCurLayer->pLumaQp[iMbXy], pCtx) )
741+ {
742+ return -1;//abnormal
743+ }
744+ }
745+ ST32(&pCurLayer->pNzc[iMbXy][0], LD32(&pNonZeroCount[1+8*1]));
746+ ST32(&pCurLayer->pNzc[iMbXy][4], LD32(&pNonZeroCount[1+8*2]));
747+ ST32(&pCurLayer->pNzc[iMbXy][8], LD32(&pNonZeroCount[1+8*3]));
748+ ST32(&pCurLayer->pNzc[iMbXy][12], LD32(&pNonZeroCount[1+8*4]));
749+ }
750+ else //pNonZeroCount = 0
751+ {
752+ ST32(&pCurLayer->pNzc[iMbXy][0], 0);
753+ ST32(&pCurLayer->pNzc[iMbXy][4], 0);
754+ ST32(&pCurLayer->pNzc[iMbXy][8], 0);
755+ ST32(&pCurLayer->pNzc[iMbXy][12], 0);
756+ }
757+ }
758+ else //non-MB_TYPE_INTRA16x16
759+ {
760+ for (iId8x8 = 0; iId8x8 < 4; iId8x8++)
761+ {
762+ if (uiCbpL & (1 << iId8x8))
763+ {
764+ int32_t iIndex = (iId8x8 << 2);
765+ for (iId4x4 = 0; iId4x4 < 4; iId4x4++)
766+ {
767+ //Luma (DC and AC decoding together)
768+ if ( WelsResidualBlockCavlc( pVlcTable, pNonZeroCount, pBs, iIndex,
769+ iScanIdxEnd - iScanIdxStart + 1, g_kuiZigzagScan+iScanIdxStart,
770+ LUMA_DC_AC, pCurLayer->pScaledTCoeff[iMbXy] + (iIndex<<4), iNMbMode, pCurLayer->pLumaQp[iMbXy], pCtx) )
771+ {
772+ return -1;//abnormal
773+ }
774+ iIndex++;
775+ }
776+ }
777+ else
778+ {
779+ ST16(&pNonZeroCount[g_kuiCacheNzcScanIdx[(iId8x8<<2)]], 0);
780+ ST16(&pNonZeroCount[g_kuiCacheNzcScanIdx[(iId8x8<<2)+2]], 0);
781+ }
782+ }
783+ ST32(&pCurLayer->pNzc[iMbXy][0], LD32(&pNonZeroCount[1+8*1]));
784+ ST32(&pCurLayer->pNzc[iMbXy][4], LD32(&pNonZeroCount[1+8*2]));
785+ ST32(&pCurLayer->pNzc[iMbXy][8], LD32(&pNonZeroCount[1+8*3]));
786+ ST32(&pCurLayer->pNzc[iMbXy][12], LD32(&pNonZeroCount[1+8*4]));
787+ }
788+
789+ //chroma
790+ //step1: DC
791+ if ( 1 == uiCbpC || 2 == uiCbpC )
792+ {
793+ for (i = 0; i < 2; i++) //Cb Cr
794+ {
795+ if ( WelsResidualBlockCavlc( pVlcTable, pNonZeroCount, pBs,
796+ 16 + (i << 2), 4, g_kuiChromaDcScan, CHROMA_DC, pCurLayer->pScaledTCoeff[iMbXy] + 256 + (i<<6),
797+ iNMbMode, pCurLayer->pChromaQp[iMbXy], pCtx) )
798+ {
799+ return -1;//abnormal
800+ }
801+ }
802+ }
803+
804+ //step2: AC
805+ if (2 == uiCbpC)
806+ {
807+ for (i = 0; i < 2; i++) //Cb Cr
808+ {
809+ int32_t iIndex = 16 + (i<<2);
810+ for (iId4x4 = 0; iId4x4 < 4; iId4x4++)
811+ {
812+ if ( WelsResidualBlockCavlc( pVlcTable, pNonZeroCount, pBs, iIndex,
813+ iScanIdxEnd - WELS_MAX(iScanIdxStart, 1) + 1, g_kuiZigzagScan + WELS_MAX(iScanIdxStart,1),
814+ CHROMA_AC, pCurLayer->pScaledTCoeff[iMbXy]+(iIndex<<4), iNMbMode, pCurLayer->pChromaQp[iMbXy], pCtx) )
815+ {
816+ return -1;//abnormal
817+ }
818+ iIndex++;
819+ }
820+ }
821+ ST16(&pCurLayer->pNzc[iMbXy][16], LD16(&pNonZeroCount[6+8*1]));
822+ ST16(&pCurLayer->pNzc[iMbXy][20], LD16(&pNonZeroCount[6+8*2]));
823+ ST16(&pCurLayer->pNzc[iMbXy][18], LD16(&pNonZeroCount[6+8*4]));
824+ ST16(&pCurLayer->pNzc[iMbXy][22], LD16(&pNonZeroCount[6+8*5]));
825+ }
826+ else
827+ {
828+ ST16(&pCurLayer->pNzc[iMbXy][16], 0);
829+ ST16(&pCurLayer->pNzc[iMbXy][20], 0);
830+ ST16(&pCurLayer->pNzc[iMbXy][18], 0);
831+ ST16(&pCurLayer->pNzc[iMbXy][22], 0);
832+ }
833+ BsEndCavlc( pBs );
834+ }
835+ else
836+ {
837+ ST32(&pCurLayer->pNzc[iMbXy][0], 0);
838+ ST32(&pCurLayer->pNzc[iMbXy][4], 0);
839+ ST32(&pCurLayer->pNzc[iMbXy][8], 0);
840+ ST32(&pCurLayer->pNzc[iMbXy][12], 0);
841+ ST32(&pCurLayer->pNzc[iMbXy][16], 0);
842+ ST32(&pCurLayer->pNzc[iMbXy][20], 0);
843+ }
844+
845+ return 0;
846+}
847+
848+int32_t WelsDecodeMbCavlcISlice(PWelsDecoderContext pCtx, PNalUnit pNalCur)
849+{
850+ PDqLayer pCurLayer = pCtx->pCurDqLayer;
851+ PBitStringAux pBs = pCurLayer->pBitStringAux;
852+ PSliceHeaderExt pSliceHeaderExt = &pCurLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt;
853+ int32_t iBaseModeFlag;
854+ int32_t iRet = 0; //should have the return value to indicate decoding error or not, It's NECESSARY--2010.4.15
855+
856+ if( pSliceHeaderExt->bAdaptiveBaseModeFlag == 1)
857+ {
858+ iBaseModeFlag = BsGetOneBit(pBs);
859+ }
860+ else
861+ {
862+ iBaseModeFlag = pSliceHeaderExt->bDefaultBaseModeFlag;
863+ }
864+ if( !iBaseModeFlag )
865+ {
866+ iRet = WelsActualDecodeMbCavlcISlice( pCtx);
867+ }
868+ else
869+ {
870+ WelsLog( pCtx, WELS_LOG_WARNING, "iBaseModeFlag (%d) != 0, inter-layer prediction not supported.\n", iBaseModeFlag);
871+ return GENERATE_ERROR_NO(ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_ILP);
872+ }
873+ if ( iRet ) //occur error when parsing, MUST STOP decoding
874+ {
875+ return iRet;
876+ }
877+
878+ return 0;
879+}
880+
881+int32_t WelsActualDecodeMbCavlcPSlice(PWelsDecoderContext pCtx)
882+{
883+ SVlcTable* pVlcTable = &pCtx->sVlcTable;
884+ PDqLayer pCurLayer = pCtx->pCurDqLayer;
885+ PBitStringAux pBs = pCurLayer->pBitStringAux;
886+ PSlice pSlice = &pCurLayer->sLayerInfo.sSliceInLayer;
887+ PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
888+
889+ SNeighAvail sNeighAvail;
890+
891+ int32_t iScanIdxStart = pSlice->sSliceHeaderExt.uiScanIdxStart;
892+ int32_t iScanIdxEnd = pSlice->sSliceHeaderExt.uiScanIdxEnd;
893+
894+ int32_t iMbX = pCurLayer->iMbX;
895+ int32_t iMbY = pCurLayer->iMbY;
896+ int32_t iMbXy = pCurLayer->iMbXyIndex;
897+
898+ int32_t iNMbMode, i;
899+ uint32_t uiMbType = 0, uiCbp = 0, uiCbpL = 0, uiCbpC = 0;
900+
901+ FORCE_STACK_ALIGN_1D( uint8_t, pNonZeroCount, 48, 16 );
902+ pCurLayer->pInterPredictionDoneFlag[iMbXy] = 0;//2009.10.23
903+
904+ uiMbType = BsGetUe(pBs);
905+ if (uiMbType < 5) //inter MB type
906+ {
907+ int16_t iMotionVector[LIST_A][30][MV_A];
908+
909+ int8_t iRefIndex[LIST_A][30];
910+ pCurLayer->pMbType[iMbXy] = g_ksInterMbTypeInfo[uiMbType].iType;
911+ WelsFillCacheInter( &sNeighAvail, pNonZeroCount, iMotionVector, iRefIndex, pCurLayer );
912+ if ( ParseInterInfo(pCtx, iMotionVector, iRefIndex, pBs) )
913+ {
914+ return -1;//abnormal
915+ }
916+
917+ if( pSlice->sSliceHeaderExt.bAdaptiveResidualPredFlag ==1 )
918+ {
919+ pCurLayer->pResidualPredFlag[iMbXy] = BsGetOneBit(pBs);
920+ }
921+ else
922+ {
923+ pCurLayer->pResidualPredFlag[iMbXy] = pSlice->sSliceHeaderExt.bDefaultResidualPredFlag;
924+ }
925+
926+ if(pCurLayer->pResidualPredFlag[iMbXy] == 0)
927+ {
928+ iNMbMode = BASE_MB;
929+ pCurLayer->pInterPredictionDoneFlag[iMbXy] = 0;
930+ }
931+ else
932+ {
933+ WelsLog(pCtx, WELS_LOG_WARNING, "residual_pred_flag = 1 not supported.\n");
934+ return -1;
935+ }
936+ }
937+ else //intra MB type
938+ {
939+ uiMbType -= 5;
940+ if ( uiMbType > 25 )
941+ {
942+ return ERR_INFO_INVALID_MB_TYPE;
943+ }
944+
945+ if ( 25 == uiMbType )
946+ {
947+ int32_t iDecStrideL = pCurLayer->pDec->iLinesize[0];
948+ int32_t iDecStrideC = pCurLayer->pDec->iLinesize[1];
949+
950+ int32_t iOffsetL = ( iMbX + iMbY * iDecStrideL ) << 4;
951+ int32_t iOffsetC = ( iMbX + iMbY * iDecStrideC ) << 3;
952+
953+ uint8_t* pDecY = pCurLayer->pCsData[0] + iOffsetL;
954+ uint8_t* pDecU = pCurLayer->pCsData[1] + iOffsetC;
955+ uint8_t* pDecV = pCurLayer->pCsData[2] + iOffsetC;
956+
957+ uint8_t *pTmpBsBuf;
958+
959+ int32_t i;
960+ int32_t iCopySizeY = ( sizeof( uint8_t ) << 4 );
961+ int32_t iCopySizeUV = ( sizeof( uint8_t ) << 3 );
962+
963+ int32_t iIndex = ((-pBs->iLeftBits)>>3) + 2;
964+
965+ pCurLayer->pMbType[iMbXy] = MB_TYPE_INTRA_PCM;
966+
967+ //step 1: locating bit-stream pointer [must align into integer byte]
968+ pBs->pCurBuf -= iIndex;
969+
970+ //step 2: copy pixel from bit-stream into fdec [reconstruction]
971+ pTmpBsBuf = pBs->pCurBuf;
972+ for ( i = 0; i < 16; i++ ) //luma
973+ {
974+ memcpy( pDecY , pTmpBsBuf, iCopySizeY );
975+ pDecY += iDecStrideL;
976+ pTmpBsBuf += 16;
977+ }
978+
979+ for ( i = 0; i < 8; i++ ) //cb
980+ {
981+ memcpy( pDecU, pTmpBsBuf, iCopySizeUV );
982+ pDecU += iDecStrideC;
983+ pTmpBsBuf += 8;
984+ }
985+ for ( i = 0; i < 8; i++ ) //cr
986+ {
987+ memcpy( pDecV, pTmpBsBuf, iCopySizeUV );
988+ pDecV += iDecStrideC;
989+ pTmpBsBuf += 8;
990+ }
991+
992+ pBs->pCurBuf += 384;
993+ InitReadBits( pBs );
994+
995+ //step 3: update QP and pNonZeroCount
996+ pCurLayer->pLumaQp[iMbXy] = 0;
997+ pCurLayer->pChromaQp[iMbXy] = 0;
998+ ST32(&pCurLayer->pNzc[iMbXy][0], 0);
999+ ST32(&pCurLayer->pNzc[iMbXy][4], 0);
1000+ ST32(&pCurLayer->pNzc[iMbXy][8], 0);
1001+ ST32(&pCurLayer->pNzc[iMbXy][12], 0);
1002+ return 0;
1003+ }
1004+ else
1005+ {
1006+ if (0 == uiMbType)
1007+ {
1008+ FORCE_STACK_ALIGN_1D( int8_t, pIntraPredMode, 48, 16 );
1009+ pCurLayer->pMbType[iMbXy] = MB_TYPE_INTRA4x4;
1010+ pCtx->pFillInfoCacheIntra4x4Func( &sNeighAvail, pNonZeroCount, pIntraPredMode, pCurLayer );
1011+ if ( pCtx->pParseIntra4x4ModeFunc( &sNeighAvail, pIntraPredMode, pBs, pCurLayer ) )
1012+ {
1013+ return -1;
1014+ }
1015+ iNMbMode = BASE_MB;
1016+ }
1017+ else //I_PCM exclude, we can ignore it
1018+ {
1019+ pCurLayer->pMbType[iMbXy] = MB_TYPE_INTRA16x16;
1020+ pCurLayer->pIntraPredMode[iMbXy][7] = (uiMbType-1) & 3;
1021+ pCurLayer->pCbp[iMbXy] = g_kuiI16CbpTable[(uiMbType-1)>>2];
1022+ uiCbpC = pCurLayer->pCbp[iMbXy] >> 4;
1023+ uiCbpL = pCurLayer->pCbp[iMbXy] & 15;
1024+ WelsFillCacheNonZeroCount( &sNeighAvail, pNonZeroCount, pCurLayer );
1025+ if ( pCtx->pParseIntra16x16ModeFunc( &sNeighAvail, pBs, pCurLayer ) )
1026+ {
1027+ return -1;
1028+ }
1029+ iNMbMode = BASE_MB;
1030+ }
1031+ }
1032+ }
1033+
1034+ if ( MB_TYPE_INTRA16x16 != pCurLayer->pMbType[iMbXy] )
1035+ {
1036+ uiCbp = BsGetUe(pBs);
1037+ {
1038+ if ( uiCbp > 47 )
1039+ return ERR_INFO_INVALID_CBP;
1040+
1041+ if (MB_TYPE_INTRA4x4 == pCurLayer->pMbType[iMbXy])
1042+ {
1043+ uiCbp = g_kuiIntra4x4CbpTable[uiCbp];
1044+ }
1045+ else //inter
1046+ uiCbp = g_kuiInterCbpTable[uiCbp];
1047+ }
1048+
1049+ pCurLayer->pCbp[iMbXy] = uiCbp;
1050+ uiCbpC = pCurLayer->pCbp[iMbXy] >> 4;
1051+ uiCbpL = pCurLayer->pCbp[iMbXy] & 15;
1052+ }
1053+
1054+ if(iNMbMode == BASE_MB)
1055+ {
1056+ pCtx->sBlockFunc.pWelsBlockZero16x16Func(pCurLayer->pScaledTCoeff[iMbXy], 16);
1057+ pCtx->sBlockFunc.pWelsBlockZero8x8Func(pCurLayer->pScaledTCoeff[iMbXy]+256, 8);
1058+ pCtx->sBlockFunc.pWelsBlockZero8x8Func(pCurLayer->pScaledTCoeff[iMbXy]+256+64, 8);
1059+
1060+ ST32(&pCurLayer->pNzc[iMbXy][0], 0);
1061+ ST32(&pCurLayer->pNzc[iMbXy][4], 0);
1062+ ST32(&pCurLayer->pNzc[iMbXy][8], 0);
1063+ ST32(&pCurLayer->pNzc[iMbXy][12], 0);
1064+ ST32(&pCurLayer->pNzc[iMbXy][20], 0);
1065+ if( pCurLayer->pCbp[iMbXy] == 0 && !IS_INTRA16x16(pCurLayer->pMbType[iMbXy]) && !IS_I_BL(pCurLayer->pMbType[iMbXy]))
1066+ {
1067+ pCurLayer->pLumaQp[iMbXy] = pSlice->iLastMbQp;
1068+ pCurLayer->pChromaQp[iMbXy] = g_kuiChromaQp[WELS_CLIP3(pCurLayer->pLumaQp[iMbXy] + pSliceHeader->pPps->iChromaQpIndexOffset, 0, 51)];
1069+ }
1070+ }
1071+
1072+ if ( pCurLayer->pCbp[iMbXy] || MB_TYPE_INTRA16x16 == pCurLayer->pMbType[iMbXy] )
1073+ {
1074+ int32_t iQpDelta, iId8x8, iId4x4;
1075+
1076+ iQpDelta = BsGetSe(pBs);
1077+
1078+ if (iQpDelta > 25 || iQpDelta < -26) //out of iQpDelta range
1079+ {
1080+ return ERR_INFO_INVALID_QP;
1081+ }
1082+
1083+ pCurLayer->pLumaQp[iMbXy] = pSlice->iLastMbQp + iQpDelta; //update iLastMbQp
1084+ //refer to JVT-X201wcm1.doc equation(7-35)
1085+ if ( (unsigned)(pCurLayer->pLumaQp[iMbXy]) > 51 )
1086+ {
1087+ if ( pCurLayer->pLumaQp[iMbXy] < 0 )
1088+ {
1089+ pCurLayer->pLumaQp[iMbXy] += 52;
1090+ }
1091+ else
1092+ {
1093+ pCurLayer->pLumaQp[iMbXy] -= 52;
1094+ }
1095+ }
1096+ //QP should be in the range of [0, 51]
1097+ if ( pCurLayer->pLumaQp[iMbXy] < 0 || pCurLayer->pLumaQp[iMbXy] > 51 )
1098+ {
1099+ return ERR_INFO_INVALID_QP;
1100+ }
1101+ pSlice->iLastMbQp = pCurLayer->pLumaQp[iMbXy];
1102+ pCurLayer->pChromaQp[iMbXy] = g_kuiChromaQp[WELS_CLIP3(pSlice->iLastMbQp + pSliceHeader->pPps->iChromaQpIndexOffset, 0, 51)];
1103+
1104+ BsStartCavlc( pBs );
1105+
1106+ if ( MB_TYPE_INTRA16x16 == pCurLayer->pMbType[iMbXy] )
1107+ {
1108+ //step1: Luma DC
1109+ if ( WelsResidualBlockCavlc( pVlcTable, pNonZeroCount, pBs, 0, 16, g_kuiLumaDcZigzagScan,
1110+ I16_LUMA_DC, pCurLayer->pScaledTCoeff[iMbXy], iNMbMode, pCurLayer->pLumaQp[iMbXy], pCtx) )
1111+ {
1112+ return -1;//abnormal
1113+ }
1114+ //step2: Luma AC
1115+ if (uiCbpL)
1116+ {
1117+ for (i = 0; i < 16; i++)
1118+ {
1119+ if ( WelsResidualBlockCavlc( pVlcTable, pNonZeroCount,pBs, i,
1120+ iScanIdxEnd - WELS_MAX(iScanIdxStart, 1) + 1, g_kuiZigzagScan + WELS_MAX(iScanIdxStart,1),
1121+ I16_LUMA_AC, pCurLayer->pScaledTCoeff[iMbXy] + (i<<4), iNMbMode, pCurLayer->pLumaQp[iMbXy], pCtx) )
1122+ {
1123+ return -1;//abnormal
1124+ }
1125+ }
1126+ ST32(&pCurLayer->pNzc[iMbXy][0], LD32(&pNonZeroCount[1+8*1]));
1127+ ST32(&pCurLayer->pNzc[iMbXy][4], LD32(&pNonZeroCount[1+8*2]));
1128+ ST32(&pCurLayer->pNzc[iMbXy][8], LD32(&pNonZeroCount[1+8*3]));
1129+ ST32(&pCurLayer->pNzc[iMbXy][12], LD32(&pNonZeroCount[1+8*4]));
1130+ }
1131+ else //pNonZeroCount = 0
1132+ {
1133+ ST32(&pCurLayer->pNzc[iMbXy][0], 0);
1134+ ST32(&pCurLayer->pNzc[iMbXy][4], 0);
1135+ ST32(&pCurLayer->pNzc[iMbXy][8], 0);
1136+ ST32(&pCurLayer->pNzc[iMbXy][12], 0);
1137+ }
1138+ }
1139+ else //non-MB_TYPE_INTRA16x16
1140+ {
1141+ for (iId8x8 = 0; iId8x8 < 4; iId8x8++)
1142+ {
1143+ if (uiCbpL & (1 << iId8x8))
1144+ {
1145+ int32_t iIndex = (iId8x8 << 2);
1146+ for (iId4x4 = 0; iId4x4 < 4; iId4x4++)
1147+ {
1148+ //Luma (DC and AC decoding together)
1149+ if ( WelsResidualBlockCavlc( pVlcTable, pNonZeroCount, pBs, iIndex,
1150+ iScanIdxEnd - iScanIdxStart + 1, g_kuiZigzagScan+iScanIdxStart, LUMA_DC_AC,
1151+ pCurLayer->pScaledTCoeff[iMbXy] + (iIndex<<4), iNMbMode, pCurLayer->pLumaQp[iMbXy], pCtx) )
1152+ {
1153+ return -1;//abnormal
1154+ }
1155+ iIndex++;
1156+ }
1157+ }
1158+ else
1159+ {
1160+ ST16(&pNonZeroCount[g_kuiCacheNzcScanIdx[iId8x8<<2]],0);
1161+ ST16(&pNonZeroCount[g_kuiCacheNzcScanIdx[(iId8x8<<2)+2]],0);
1162+ }
1163+ }
1164+ ST32(&pCurLayer->pNzc[iMbXy][0], LD32(&pNonZeroCount[1+8*1]));
1165+ ST32(&pCurLayer->pNzc[iMbXy][4], LD32(&pNonZeroCount[1+8*2]));
1166+ ST32(&pCurLayer->pNzc[iMbXy][8], LD32(&pNonZeroCount[1+8*3]));
1167+ ST32(&pCurLayer->pNzc[iMbXy][12], LD32(&pNonZeroCount[1+8*4]));
1168+ }
1169+
1170+
1171+ //chroma
1172+ //step1: DC
1173+ if ( 1 == uiCbpC || 2 == uiCbpC )
1174+ {
1175+ for (i = 0; i < 2; i++) //Cb Cr
1176+ {
1177+ if ( WelsResidualBlockCavlc( pVlcTable, pNonZeroCount, pBs,
1178+ 16 + (i << 2), 4, g_kuiChromaDcScan, CHROMA_DC, pCurLayer->pScaledTCoeff[iMbXy] + 256 + (i<<6),
1179+ iNMbMode, pCurLayer->pChromaQp[iMbXy], pCtx) )
1180+ {
1181+ return -1;//abnormal
1182+ }
1183+ }
1184+ }
1185+ else
1186+ {
1187+ }
1188+ //step2: AC
1189+ if (2 == uiCbpC)
1190+ {
1191+ for (i = 0; i < 2; i++) //Cb Cr
1192+ {
1193+ int32_t iIndex= 16 + (i<<2);
1194+ for (iId4x4 = 0; iId4x4 < 4; iId4x4++)
1195+ {
1196+ if ( WelsResidualBlockCavlc( pVlcTable, pNonZeroCount, pBs, iIndex,
1197+ iScanIdxEnd - WELS_MAX(iScanIdxStart, 1) + 1, g_kuiZigzagScan + WELS_MAX(iScanIdxStart,1),
1198+ CHROMA_AC, pCurLayer->pScaledTCoeff[iMbXy]+(iIndex<<4), iNMbMode, pCurLayer->pChromaQp[iMbXy], pCtx) )
1199+ {
1200+ return -1;//abnormal
1201+ }
1202+ iIndex++;
1203+ }
1204+ }
1205+ ST16(&pCurLayer->pNzc[iMbXy][16], LD16(&pNonZeroCount[6+8*1]));
1206+ ST16(&pCurLayer->pNzc[iMbXy][20], LD16(&pNonZeroCount[6+8*2]));
1207+ ST16(&pCurLayer->pNzc[iMbXy][18], LD16(&pNonZeroCount[6+8*4]));
1208+ ST16(&pCurLayer->pNzc[iMbXy][22], LD16(&pNonZeroCount[6+8*5]));
1209+ }
1210+ else
1211+ {
1212+ ST32(&pCurLayer->pNzc[iMbXy][16], 0);
1213+ ST32(&pCurLayer->pNzc[iMbXy][20], 0);
1214+ }
1215+ BsEndCavlc( pBs );
1216+ }
1217+ else
1218+ {
1219+ ST32(&pCurLayer->pNzc[iMbXy][0], 0);
1220+ ST32(&pCurLayer->pNzc[iMbXy][4], 0);
1221+ ST32(&pCurLayer->pNzc[iMbXy][8], 0);
1222+ ST32(&pCurLayer->pNzc[iMbXy][12], 0);
1223+ ST32(&pCurLayer->pNzc[iMbXy][16], 0);
1224+ ST32(&pCurLayer->pNzc[iMbXy][20], 0);
1225+ }
1226+
1227+ return 0;
1228+}
1229+
1230+int32_t WelsDecodeMbCavlcPSlice(PWelsDecoderContext pCtx, PNalUnit pNalCur)
1231+{
1232+ PDqLayer pCurLayer = pCtx->pCurDqLayer;
1233+ PBitStringAux pBs = pCurLayer->pBitStringAux;
1234+ PSlice pSlice = &pCurLayer->sLayerInfo.sSliceInLayer;
1235+ PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
1236+
1237+ int32_t iMbXy = pCurLayer->iMbXyIndex;
1238+ int32_t iBaseModeFlag, i;
1239+ int32_t iRet = 0; //should have the return value to indicate decoding error or not, It's NECESSARY--2010.4.15
1240+
1241+ if (-1 == pSlice->iMbSkipRun)
1242+ {
1243+ pSlice->iMbSkipRun = BsGetUe(pBs);
1244+ if ( -1 == pSlice->iMbSkipRun )
1245+ {
1246+ return -1;
1247+ }
1248+
1249+ }
1250+ if (pSlice->iMbSkipRun--)
1251+ {
1252+ int16_t iMv[2] = {0};
1253+
1254+ pCurLayer->pMbType[iMbXy] = MB_TYPE_SKIP;
1255+ ST32(&pCurLayer->pNzc[iMbXy][0], 0);
1256+ ST32(&pCurLayer->pNzc[iMbXy][4], 0);
1257+ ST32(&pCurLayer->pNzc[iMbXy][8], 0);
1258+ ST32(&pCurLayer->pNzc[iMbXy][12], 0);
1259+ ST32(&pCurLayer->pNzc[iMbXy][16], 0);
1260+ ST32(&pCurLayer->pNzc[iMbXy][20], 0);
1261+
1262+ pCurLayer->pInterPredictionDoneFlag[iMbXy] = 0;
1263+ memset(pCurLayer->pRefIndex[0][iMbXy], 0, sizeof(int8_t) * 16);
1264+
1265+ //predict iMv
1266+ PredPSkipMvFromNeighbor( pCurLayer, iMv );
1267+ for (i = 0; i < 16; i++)
1268+ {
1269+ ST32( pCurLayer->pMv[0][iMbXy][i], *(uint32_t*)iMv );
1270+ }
1271+
1272+ if(!pSlice->sSliceHeaderExt.bDefaultResidualPredFlag)
1273+ {
1274+ memset(pCurLayer->pScaledTCoeff[iMbXy], 0, 384*sizeof(int16_t));
1275+ }
1276+
1277+ //reset rS
1278+ if(!pSlice->sSliceHeaderExt.bDefaultResidualPredFlag ||
1279+ (pNalCur->sNalHeaderExt.uiQualityId==0 && pNalCur->sNalHeaderExt.uiDependencyId==0))
1280+ {
1281+ pCurLayer->pLumaQp[iMbXy] = pSlice->iLastMbQp;
1282+ pCurLayer->pChromaQp[iMbXy] = g_kuiChromaQp[WELS_CLIP3(pCurLayer->pLumaQp[iMbXy] + pSliceHeader->pPps->iChromaQpIndexOffset, 0, 51)];
1283+ }
1284+
1285+ pCurLayer->pCbp[iMbXy] = 0;
1286+
1287+ return 0;
1288+ }
1289+
1290+ if( pSlice->sSliceHeaderExt.bAdaptiveBaseModeFlag == 1)
1291+ {
1292+ iBaseModeFlag = BsGetOneBit(pBs);
1293+ }
1294+ else
1295+ {
1296+ iBaseModeFlag = pSlice->sSliceHeaderExt.bDefaultBaseModeFlag;
1297+ }
1298+ if( !iBaseModeFlag )
1299+ {
1300+ iRet = WelsActualDecodeMbCavlcPSlice( pCtx );
1301+ }
1302+ else
1303+ {
1304+ WelsLog( pCtx, WELS_LOG_WARNING, "iBaseModeFlag (%d) != 0, inter-layer prediction not supported.\n", iBaseModeFlag);
1305+ return GENERATE_ERROR_NO(ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_ILP);
1306+ }
1307+ if ( iRet ) //occur error when parsing, MUST STOP decoding
1308+ {
1309+ return iRet;
1310+ }
1311+
1312+ return 0;
1313+}
1314+
1315+void_t WelsBlockInit(int16_t* pBlock, int32_t iWidth, int32_t iHeight, int32_t iStride, uint8_t uiVal)
1316+{
1317+ int32_t i;
1318+ int16_t* pDst = pBlock;
1319+
1320+ for(i=0; i<iHeight; i++)
1321+ {
1322+ memset(pDst, uiVal, iWidth*sizeof(int16_t));
1323+ pDst += iStride;
1324+ }
1325+}
1326+
1327+void_t WelsBlockFuncInit(SBlockFunc * pFunc, int32_t iCpu)
1328+{
1329+ pFunc->pWelsBlockZero16x16Func = WelsBlockZero16x16_c;
1330+ pFunc->pWelsBlockZero8x8Func = WelsBlockZero8x8_c;
1331+ pFunc->pWelsSetNonZeroCountFunc = SetNonZeroCount_c;
1332+
1333+#ifdef X86_ASM
1334+ if( iCpu & WELS_CPU_SSE2 ){
1335+ pFunc->pWelsBlockZero16x16Func = WelsResBlockZero16x16_sse2;
1336+ pFunc->pWelsBlockZero8x8Func = WelsResBlockZero8x8_sse2;
1337+ }
1338+#endif
1339+}
1340+void_t WelsBlockZero16x16_c(int16_t * pBlock, int32_t iStride)
1341+{
1342+ WelsBlockInit(pBlock,16,16,iStride,0);
1343+}
1344+
1345+void_t WelsBlockZero8x8_c(int16_t * pBlock, int32_t iStride)
1346+{
1347+ WelsBlockInit(pBlock,8,8,iStride,0);
1348+}
1349+
1350+void_t SetNonZeroCount_c(int16_t* pBlock, int8_t* pNonZeroCount)
1351+{
1352+ int32_t i;
1353+ int32_t iIndex;
1354+
1355+ for( i=0;i<24;i++ ){
1356+ iIndex = g_kuiMbNonZeroCountIdx[i];
1357+ pNonZeroCount[iIndex] = !!pNonZeroCount[iIndex];
1358+ }
1359+}
1360+
1361+} // namespace WelsDec

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