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
61namespace WelsDec {
62
63int32_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
166int32_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}
204int32_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
224void_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
266int32_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
298int32_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
316void_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
330int32_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
386void_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
410int32_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
551int32_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
848int32_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
881int32_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
1230int32_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
1315void_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
1327void_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}
1340void_t WelsBlockZero16x16_c(int16_t * pBlock, int32_t iStride)
1341{
1342 WelsBlockInit(pBlock,16,16,iStride,0);
1343}
1344
1345void_t WelsBlockZero8x8_c(int16_t * pBlock, int32_t iStride)
1346{
1347 WelsBlockInit(pBlock,8,8,iStride,0);
1348}
1349
1350void_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