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/au_parser.cpp (1 of 308 files). Show all

Unified · Split

codec/decoder/core/src/au_parser.cpp+1027−0
@@ -0,0 +1,1027 @@
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 au_parser.c
33+ *
34+ * \brief Interfaces introduced in Access Unit level based parser
35+ *
36+ * \date 03/10/2009 Created
37+ *
38+ *************************************************************************************
39+ */
40+#include <string.h>
41+#include "codec_def.h"
42+#include "ls_defines.h"
43+#include "macros.h"
44+#include "au_parser.h"
45+#include "decoder.h"
46+#include "error_code.h"
47+#include "dec_frame.h"
48+#include "dec_golomb.h"
49+#include "bit_stream.h"
50+#include "utils.h"
51+#include "codec_app_def.h"
52+#include "memmgr_nal_unit.h"
53+#include "decoder_core.h"
54+#include "wels_common_basis.h"
55+#include "decoder_core.h"
56+#include "manage_dec_ref.h"
57+#include "mem_align.h"
58+
59+namespace WelsDec {
60+/*!
61+ *************************************************************************************
62+ * \brief Start Code Prefix (0x 00 00 00 01) detection
63+ *
64+ * \param pBuf bitstream payload buffer
65+ * \param pOffset offset between NAL rbsp and original bitsteam that
66+ * start code prefix is seperated from.
67+ * \param iBufSize count size of buffer
68+ *
69+ * \return RBSP buffer of start code prefix exclusive
70+ *
71+ * \note N/A
72+ *************************************************************************************
73+ */
74+uint8_t* DetectStartCodePrefix( const uint8_t *kpBuf, int32_t *pOffset, int32_t iBufSize )
75+{
76+ uint8_t *pBits = (uint8_t *)kpBuf;
77+
78+ do {
79+ int32_t iIdx = 0;
80+ while( (iIdx<iBufSize) && (!(*pBits)) ){
81+ ++ pBits;
82+ ++ iIdx;
83+ }
84+ if( iIdx >= iBufSize ) break;
85+
86+ ++ iIdx;
87+ ++ pBits;
88+
89+ if( (iIdx>=3) && ((*(pBits-1)) == 0x1) ){
90+ *pOffset = ((uint32_t)pBits) - ((uint32_t)kpBuf);
91+ return pBits;
92+ }
93+
94+ iBufSize -= iIdx;
95+ } while (1);
96+
97+ return NULL;
98+}
99+
100+/*!
101+ *************************************************************************************
102+ * \brief to parse nal unit
103+ *
104+ * \param pCtx decoder context
105+ * \param pNalUnitHeader parsed result of NAL Unit Header to output
106+ * \param pSrcRbsp bitstream buffer to input
107+ * \param iSrcRbspLen length size of bitstream buffer payload
108+ * \param pSrcNal
109+ * \param iSrcNalLen
110+ * \param pConsumedBytes consumed bytes during parsing
111+ *
112+ * \return decoded bytes payload, might be (pSrcRbsp+1) if no escapes
113+ *
114+ * \note N/A
115+ *************************************************************************************
116+ */
117+uint8_t* ParseNalHeader( PWelsDecoderContext pCtx, SNalUnitHeader *pNalUnitHeader, uint8_t *pSrcRbsp, int32_t iSrcRbspLen, uint8_t *pSrcNal, int32_t iSrcNalLen, int32_t* pConsumedBytes )
118+{
119+ PNalUnit pCurNal = NULL;
120+ uint8_t* pNal = pSrcRbsp;
121+ int32_t iNalSize = iSrcRbspLen;
122+ PBitStringAux pBs = NULL;
123+ bool_t bExtensionFlag = false;
124+ int32_t iErr = ERR_NONE;
125+ int32_t iBitSize = 0;
126+
127+ pNalUnitHeader->eNalUnitType = NAL_UNIT_UNSPEC_0;//SHOULD init it. because pCtx->sCurNalHead is common variable.
128+
129+ //remove the consecutive ZERO at the end of current NAL in the reverse order.--2011.6.1
130+ {
131+ int32_t iIndex = iSrcRbspLen - 1;
132+ uint8_t uiBsZero = 0;
133+ while ( iIndex >= 0 )
134+ {
135+ uiBsZero = pSrcRbsp[iIndex];
136+ if ( 0 == uiBsZero )
137+ {
138+ --iNalSize;
139+ --iIndex;
140+ }
141+ else
142+ {
143+ break;
144+ }
145+ }
146+ }
147+
148+ pNalUnitHeader->uiForbiddenZeroBit = (uint8_t)(pNal[0] >> 7); // uiForbiddenZeroBit
149+ if ( pNalUnitHeader->uiForbiddenZeroBit )//2010.4.14
150+ {
151+ return NULL; //uiForbiddenZeroBit should always equal to 0
152+ }
153+
154+ pNalUnitHeader->uiNalRefIdc = (uint8_t)(pNal[0] >> 5); // uiNalRefIdc
155+ pNalUnitHeader->eNalUnitType = (ENalUnitType)(pNal[0] & 0x1f); // eNalUnitType
156+
157+ ++pNal;
158+ --iNalSize;
159+ ++(*pConsumedBytes);
160+
161+#ifdef DEBUG_PARSE_INFO
162+ WelsLog(pCtx, WELS_LOG_INFO, "nal type: %d \n", pNalUnitHeader->eNalUnitType);
163+#endif
164+
165+ if ( !(IS_SEI_NAL(pNalUnitHeader->eNalUnitType) || IS_SPS_NAL(pNalUnitHeader->eNalUnitType) || pCtx->bSpsExistAheadFlag) )
166+ {
167+ WelsLog( pCtx, WELS_LOG_WARNING, "parse_nal(), no exist Sequence Parameter Sets ahead of sequence when try to decode NAL(type:%d).\n", pNalUnitHeader->eNalUnitType);
168+ pCtx->iErrorCode = dsNoParamSets;
169+ return NULL;
170+ }
171+ if ( !(IS_SEI_NAL(pNalUnitHeader->eNalUnitType) || IS_PARAM_SETS_NALS(pNalUnitHeader->eNalUnitType) || pCtx->bPpsExistAheadFlag) )
172+ {
173+ WelsLog( pCtx, WELS_LOG_WARNING, "parse_nal(), no exist Picture Parameter Sets ahead of sequence when try to decode NAL(type:%d).\n", pNalUnitHeader->eNalUnitType);
174+ pCtx->iErrorCode = dsNoParamSets;
175+ return NULL;
176+ }
177+ if ( (IS_VCL_NAL_AVC_BASE(pNalUnitHeader->eNalUnitType) && !(pCtx->bSpsExistAheadFlag || pCtx->bPpsExistAheadFlag)) ||
178+ (IS_NEW_INTRODUCED_NAL(pNalUnitHeader->eNalUnitType) && !(pCtx->bSpsExistAheadFlag || pCtx->bSubspsExistAheadFlag || pCtx->bPpsExistAheadFlag) ) )
179+ {
180+ WelsLog( pCtx, WELS_LOG_WARNING, "ParseNalHeader(), no exist Parameter Sets ahead of sequence when try to decode slice(type:%d).\n", pNalUnitHeader->eNalUnitType);
181+ pCtx->iErrorCode |= dsNoParamSets;
182+ return NULL;
183+ }
184+
185+
186+ switch(pNalUnitHeader->eNalUnitType){
187+ case NAL_UNIT_SEI:
188+
189+ if ( pCtx->pAccessUnitList->uiAvailUnitsNum > 0 )
190+ {
191+ pCtx->pAccessUnitList->uiEndPos = pCtx->pAccessUnitList->uiAvailUnitsNum - 1;
192+ pCtx->bAuReadyFlag = true;
193+ }
194+
195+ break;
196+
197+ case NAL_UNIT_SPS:
198+
199+ if ( pCtx->pAccessUnitList->uiAvailUnitsNum > 0 )
200+ {
201+ pCtx->pAccessUnitList->uiEndPos = pCtx->pAccessUnitList->uiAvailUnitsNum - 1;
202+ pCtx->bAuReadyFlag = true;
203+ }
204+
205+ break;
206+
207+ case NAL_UNIT_PREFIX:
208+ pCurNal = &pCtx->sPrefixNal;
209+
210+ if ( iNalSize < NAL_UNIT_HEADER_EXT_SIZE )
211+ {
212+ return NULL;
213+ }
214+
215+ DecodeNalHeaderExt( pCurNal, pNal );
216+
217+ pNal += NAL_UNIT_HEADER_EXT_SIZE;
218+ iNalSize -= NAL_UNIT_HEADER_EXT_SIZE;
219+ *pConsumedBytes += NAL_UNIT_HEADER_EXT_SIZE;
220+
221+ pCurNal->sNalHeaderExt.sNalUnitHeader.uiForbiddenZeroBit = pNalUnitHeader->uiForbiddenZeroBit;
222+ pCurNal->sNalHeaderExt.sNalUnitHeader.uiNalRefIdc = pNalUnitHeader->uiNalRefIdc;
223+ pCurNal->sNalHeaderExt.sNalUnitHeader.eNalUnitType = pNalUnitHeader->eNalUnitType;
224+
225+ pBs = &pCtx->sBs;
226+
227+ iBitSize = (iNalSize<<3) - BsGetTrailingBits( pNal + iNalSize - 1 ); // convert into bit
228+
229+ InitBits( pBs, pNal, iBitSize);
230+
231+ ParsePrefixNalUnit( pCtx, pBs );
232+
233+ break;
234+ case NAL_UNIT_CODED_SLICE_EXT:
235+ bExtensionFlag = true;
236+ case NAL_UNIT_CODED_SLICE:
237+ case NAL_UNIT_CODED_SLICE_IDR:
238+ {
239+ PAccessUnit pCurAu = NULL;
240+ uint32_t uiAvailNalNum;
241+ pCurNal = MemGetNextNal( &pCtx->pAccessUnitList );
242+ if( NULL == pCurNal )
243+ {
244+ WelsLog( pCtx, WELS_LOG_WARNING, "MemGetNextNal() fail due out of memory.\n");
245+ pCtx->iErrorCode |= dsOutOfMemory;
246+ return NULL;
247+ }
248+
249+ pCurNal->sNalHeaderExt.sNalUnitHeader.uiForbiddenZeroBit = pNalUnitHeader->uiForbiddenZeroBit;
250+ pCurNal->sNalHeaderExt.sNalUnitHeader.uiNalRefIdc = pNalUnitHeader->uiNalRefIdc;
251+ pCurNal->sNalHeaderExt.sNalUnitHeader.eNalUnitType = pNalUnitHeader->eNalUnitType;
252+ pCurAu = pCtx->pAccessUnitList;
253+ uiAvailNalNum = pCurAu->uiAvailUnitsNum;
254+
255+
256+ if( pNalUnitHeader->eNalUnitType == NAL_UNIT_CODED_SLICE_EXT )
257+ {
258+ if ( iNalSize < NAL_UNIT_HEADER_EXT_SIZE )
259+ {
260+ return NULL;
261+ }
262+
263+ DecodeNalHeaderExt( pCurNal, pNal );
264+ if( pCurNal->sNalHeaderExt.uiQualityId != 0 ||
265+ pCurNal->sNalHeaderExt.bUseRefBasePicFlag )
266+ {
267+ if( pCurNal->sNalHeaderExt.uiQualityId != 0 )
268+ WelsLog(pCtx, WELS_LOG_WARNING, "ParseNalHeader():uiQualityId (%d) != 0, MGS not supported!\n", pCurNal->sNalHeaderExt.uiQualityId);
269+ if( pCurNal->sNalHeaderExt.bUseRefBasePicFlag != 0 )
270+ WelsLog(pCtx, WELS_LOG_WARNING, "ParseNalHeader():bUseRefBasePicFlag (%d) != 0, MGS not supported!\n", pCurNal->sNalHeaderExt.bUseRefBasePicFlag);
271+
272+ pCtx->iErrorCode |= dsInvalidArgument;
273+ ForceClearCurrentNal( pCurAu );
274+
275+ if ( uiAvailNalNum > 1 )
276+ {
277+ pCurAu->uiEndPos = uiAvailNalNum - 2;
278+ pCtx->bAuReadyFlag = true;
279+ }
280+ return NULL;
281+ }
282+ pNal += NAL_UNIT_HEADER_EXT_SIZE;
283+ iNalSize -= NAL_UNIT_HEADER_EXT_SIZE;
284+ *pConsumedBytes += NAL_UNIT_HEADER_EXT_SIZE;
285+
286+ }
287+ else
288+ {
289+
290+
291+ if ( NAL_UNIT_PREFIX == pCtx->sPrefixNal.sNalHeaderExt.sNalUnitHeader.eNalUnitType )
292+ {
293+ PrefetchNalHeaderExtSyntax( pCtx, pCurNal, &pCtx->sPrefixNal );
294+ }
295+
296+ pCurNal->sNalHeaderExt.bIdrFlag = ( NAL_UNIT_CODED_SLICE_IDR == pNalUnitHeader->eNalUnitType ) ? true : false; //SHOULD update this flag for AVC if no prefix NAL
297+ pCurNal->sNalHeaderExt.iNoInterLayerPredFlag = 1;
298+ }
299+
300+ pBs = &pCurAu->pNalUnitsList[uiAvailNalNum-1]->sNalData.sVclNal.sSliceBitsRead;
301+ iBitSize = (iNalSize<<3) - BsGetTrailingBits( pNal+ iNalSize - 1 ); // convert into bit
302+ InitBits( pBs, pNal, iBitSize);
303+ iErr = ParseSliceHeaderSyntaxs( pCtx, pBs, bExtensionFlag );
304+ if ( iErr != ERR_NONE )
305+ {
306+ //if current NAL occur error when parsing, should clean it from pNalUnitsList
307+ //otherwise, when Next good NAL decoding, this corrupt NAL is considered as normal NAL and lead to decoder crash
308+ ForceClearCurrentNal( pCurAu );
309+
310+ if ( uiAvailNalNum > 1 )
311+ {
312+ pCurAu->uiEndPos = uiAvailNalNum - 2;
313+ pCtx->bAuReadyFlag = true;
314+
315+
316+ }
317+#ifdef MOSAIC_AVOID_BASED_ON_SPS_PPS_ID
318+ if ( dsNoParamSets & pCtx->iErrorCode )
319+ {
320+ if ( uiAvailNalNum <= 1 ) //no any data to decode and SPS/PPS ID mismatch, SHOULD request IDR
321+ {
322+#ifdef LONG_TERM_REF
323+ pCtx->bParamSetsLostFlag = true;
324+#else
325+ pCtx->bReferenceLostAtT0Flag = true;
326+#endif
327+ ResetParameterSetsState( pCtx );
328+ }
329+ return NULL;
330+ }
331+ else
332+ {
333+ return NULL;
334+ }
335+#else
336+ return NULL;
337+#endif //MOSAIC_AVOID_BASED_ON_SPS_PPS_ID
338+ }
339+
340+ if ( (uiAvailNalNum > 1) &&
341+ CheckAccessUnitBoundary( pCurAu->pNalUnitsList[uiAvailNalNum-1], pCurAu->pNalUnitsList[uiAvailNalNum-2],
342+ pCurAu->pNalUnitsList[uiAvailNalNum-1]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pSps) )
343+ {
344+ pCurAu->uiEndPos = uiAvailNalNum - 2;
345+ pCtx->bAuReadyFlag = true;
346+
347+
348+ }
349+ }
350+ break;
351+ default:
352+ break;
353+ }
354+
355+ return pNal;
356+}
357+
358+
359+bool_t CheckAccessUnitBoundaryExt( PNalUnitHeaderExt pLastNalHdrExt, PNalUnitHeaderExt pCurNalHeaderExt, PSliceHeader pLastSliceHeader, PSliceHeader pCurSliceHeader )
360+{
361+ const PSps kpSps = pCurSliceHeader->pSps;
362+
363+ //Sub-clause 7.1.4.1.1 temporal_id
364+ if (pLastNalHdrExt->uiTemporalId != pCurNalHeaderExt->uiTemporalId) {
365+ return TRUE;
366+ }
367+
368+ // Subclause 7.4.1.2.5
369+ if ( pLastSliceHeader->iRedundantPicCnt < pCurSliceHeader->iRedundantPicCnt )
370+ return FALSE;
371+ else if ( pLastSliceHeader->iRedundantPicCnt > pCurSliceHeader->iRedundantPicCnt )
372+ return TRUE;
373+
374+ // Subclause G7.4.1.2.4
375+ if ( pLastNalHdrExt->uiDependencyId < pCurNalHeaderExt->uiDependencyId )
376+ return FALSE;
377+ else if ( pLastNalHdrExt->uiDependencyId > pCurNalHeaderExt->uiDependencyId )
378+ return TRUE;
379+ if ( pLastNalHdrExt->uiQualityId < pCurNalHeaderExt->uiQualityId )
380+ return FALSE;
381+ else if ( pLastNalHdrExt->uiQualityId > pCurNalHeaderExt->uiQualityId )
382+ return TRUE;
383+
384+ // Subclause 7.4.1.2.4
385+ if ( pLastSliceHeader->iFrameNum != pCurSliceHeader->iFrameNum )
386+ return TRUE;
387+ if ( pLastSliceHeader->iPpsId != pCurSliceHeader->iPpsId )
388+ return TRUE;
389+ if ( pLastSliceHeader->bFieldPicFlag != pCurSliceHeader->bFieldPicFlag )
390+ return TRUE;
391+ if ( pLastSliceHeader->bBottomFiledFlag != pCurSliceHeader->bBottomFiledFlag )
392+ return TRUE;
393+ if ( (pLastNalHdrExt->sNalUnitHeader.uiNalRefIdc != NRI_PRI_LOWEST) != (pCurNalHeaderExt->sNalUnitHeader.uiNalRefIdc != NRI_PRI_LOWEST) )
394+ return TRUE;
395+ if ( pLastNalHdrExt->bIdrFlag != pCurNalHeaderExt->bIdrFlag )
396+ return TRUE;
397+ if ( pCurNalHeaderExt->bIdrFlag ){
398+ if ( pLastSliceHeader->uiIdrPicId != pCurSliceHeader->uiIdrPicId )
399+ return TRUE;
400+ }
401+ if ( kpSps->uiPocType == 0 ){
402+ if ( pLastSliceHeader->iPicOrderCntLsb != pCurSliceHeader->iPicOrderCntLsb )
403+ return TRUE;
404+ if ( pLastSliceHeader->iDeltaPicOrderCntBottom != pCurSliceHeader->iDeltaPicOrderCntBottom )
405+ return TRUE;
406+ }
407+ else if ( kpSps->uiPocType == 1 ){
408+ if ( pLastSliceHeader->iDeltaPicOrderCnt[0] != pCurSliceHeader->iDeltaPicOrderCnt[0] )
409+ return TRUE;
410+ if ( pLastSliceHeader->iDeltaPicOrderCnt[1] != pCurSliceHeader->iDeltaPicOrderCnt[1] )
411+ return TRUE;
412+ }
413+
414+ return FALSE;
415+}
416+
417+
418+bool_t CheckAccessUnitBoundary( const PNalUnit kpCurNal, const PNalUnit kpLastNal, const PSps kpSps )
419+{
420+ const PNalUnitHeaderExt kpLastNalHeaderExt = &kpLastNal->sNalHeaderExt;
421+ const PNalUnitHeaderExt kpCurNalHeaderExt = &kpCurNal->sNalHeaderExt;
422+ const SSliceHeader *kpLastSliceHeader = &kpLastNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader;
423+ const SSliceHeader *kpCurSliceHeader = &kpCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader;
424+
425+ //Sub-clause 7.1.4.1.1 temporal_id
426+ if (kpLastNalHeaderExt->uiTemporalId != kpCurNalHeaderExt->uiTemporalId) {
427+ return TRUE;
428+ }
429+
430+ // Subclause 7.4.1.2.5
431+ if ( kpLastSliceHeader->iRedundantPicCnt < kpCurSliceHeader->iRedundantPicCnt )
432+ return FALSE;
433+ else if ( kpLastSliceHeader->iRedundantPicCnt > kpCurSliceHeader->iRedundantPicCnt )
434+ return TRUE;
435+
436+ // Subclause G7.4.1.2.4
437+ if ( kpLastNalHeaderExt->uiDependencyId < kpCurNalHeaderExt->uiDependencyId )
438+ return FALSE;
439+ else if ( kpLastNalHeaderExt->uiDependencyId > kpCurNalHeaderExt->uiDependencyId )
440+ return TRUE;
441+ if ( kpLastNalHeaderExt->uiQualityId < kpCurNalHeaderExt->uiQualityId )
442+ return FALSE;
443+ else if ( kpLastNalHeaderExt->uiQualityId > kpCurNalHeaderExt->uiQualityId )
444+ return TRUE;
445+
446+ // Subclause 7.4.1.2.4
447+ if ( kpLastSliceHeader->iFrameNum != kpCurSliceHeader->iFrameNum )
448+ return TRUE;
449+ if ( kpLastSliceHeader->iPpsId != kpCurSliceHeader->iPpsId )
450+ return TRUE;
451+ if ( kpLastSliceHeader->bFieldPicFlag != kpCurSliceHeader->bFieldPicFlag )
452+ return TRUE;
453+ if ( kpLastSliceHeader->bBottomFiledFlag != kpCurSliceHeader->bBottomFiledFlag )
454+ return TRUE;
455+ if ( (kpLastNalHeaderExt->sNalUnitHeader.uiNalRefIdc != NRI_PRI_LOWEST) != (kpCurNalHeaderExt->sNalUnitHeader.uiNalRefIdc != NRI_PRI_LOWEST) )
456+ return TRUE;
457+ if ( kpLastNalHeaderExt->bIdrFlag != kpCurNalHeaderExt->bIdrFlag )
458+ return TRUE;
459+ if ( kpCurNalHeaderExt->bIdrFlag ){
460+ if ( kpLastSliceHeader->uiIdrPicId != kpCurSliceHeader->uiIdrPicId )
461+ return TRUE;
462+ }
463+ if ( kpSps->uiPocType == 0 ){
464+ if ( kpLastSliceHeader->iPicOrderCntLsb != kpCurSliceHeader->iPicOrderCntLsb )
465+ return TRUE;
466+ if ( kpLastSliceHeader->iDeltaPicOrderCntBottom != kpCurSliceHeader->iDeltaPicOrderCntBottom )
467+ return TRUE;
468+ }
469+ else if ( kpSps->uiPocType == 1 ){
470+ if ( kpLastSliceHeader->iDeltaPicOrderCnt[0] != kpCurSliceHeader->iDeltaPicOrderCnt[0] )
471+ return TRUE;
472+ if ( kpLastSliceHeader->iDeltaPicOrderCnt[1] != kpCurSliceHeader->iDeltaPicOrderCnt[1] )
473+ return TRUE;
474+ }
475+
476+ return FALSE;
477+}
478+
479+/*!
480+ *************************************************************************************
481+ * \brief to parse NON VCL NAL Units
482+ *
483+ * \param pCtx decoder context
484+ * \param rbsp rbsp buffer of NAL Unit
485+ * \param src_len length of rbsp buffer
486+ *
487+ * \return 0 - successed
488+ * 1 - failed
489+ *
490+ *************************************************************************************
491+ */
492+int32_t ParseNonVclNal( PWelsDecoderContext pCtx, uint8_t *pRbsp, const int32_t kiSrcLen )
493+{
494+ PBitStringAux pBs = NULL;
495+ ENalUnitType eNalType = NAL_UNIT_UNSPEC_0; // make initial value as unspecified
496+ int32_t iPicWidth = 0;
497+ int32_t iPicHeight = 0;
498+ int32_t iBitSize = 0;
499+ int32_t iErr = ERR_NONE;
500+
501+ pBs = &pCtx->sBs; // SBitStringAux instance for non VCL NALs decoding
502+ iBitSize = (kiSrcLen<<3) - BsGetTrailingBits( pRbsp + kiSrcLen - 1 ); // convert into bit
503+ eNalType = pCtx->sCurNalHead.eNalUnitType;
504+
505+ switch( eNalType ) {
506+ case NAL_UNIT_SPS:
507+ case NAL_UNIT_SUBSET_SPS:
508+ if ( iBitSize > 0 )
509+ InitBits( pBs, pRbsp, iBitSize );
510+#ifdef DEBUG_PARSE_INFO
511+ WelsLog(pCtx, WELS_LOG_INFO, "parsing nal: %d \n", eNalType);
512+#endif
513+ iErr = ParseSps( pCtx, pBs, &iPicWidth, &iPicHeight );
514+ if ( ERR_NONE != iErr ) // modified for pSps/pSubsetSps invalid, 12/1/2009
515+ {
516+ pCtx->iErrorCode |= dsNoParamSets;
517+ return iErr;
518+ }
519+
520+ if ( ERR_NONE == iErr )
521+ UpdateMaxPictureResolution( pCtx, iPicWidth, iPicHeight );
522+
523+ break;
524+
525+ case NAL_UNIT_PPS:
526+ if ( iBitSize > 0 )
527+ InitBits( pBs, pRbsp, iBitSize );
528+#ifdef DEBUG_PARSE_INFO
529+ WelsLog(pCtx, WELS_LOG_INFO, "parsing nal: %d \n", eNalType);
530+#endif
531+ iErr = ParsePps( pCtx, &pCtx->sPpsBuffer[0], pBs );
532+ if ( ERR_NONE != iErr ) // modified for pps invalid, 12/1/2009
533+ {
534+ pCtx->iErrorCode |= dsNoParamSets;
535+ return iErr;
536+ }
537+
538+ pCtx->bPpsExistAheadFlag = true;
539+
540+ break;
541+
542+ case NAL_UNIT_SEI:
543+
544+ break;
545+
546+ case NAL_UNIT_PREFIX:
547+ break;
548+ case NAL_UNIT_CODED_SLICE_DPA:
549+ case NAL_UNIT_CODED_SLICE_DPB:
550+ case NAL_UNIT_CODED_SLICE_DPC:
551+
552+ break;
553+
554+ default:
555+ break;
556+ }
557+
558+ return iErr;
559+}
560+
561+void_t ParseRefBasePicMarking ( PBitStringAux pBs, PRefBasePicMarking pRefBasePicMarking )
562+{
563+ const bool_t kbAdaptiveMarkingModeFlag = !!BsGetOneBit( pBs );
564+ pRefBasePicMarking->bAdaptiveRefBasePicMarkingModeFlag = kbAdaptiveMarkingModeFlag;
565+ if ( kbAdaptiveMarkingModeFlag ){
566+ int32_t iIdx = 0;
567+ do {
568+ const uint32_t kuiMmco = BsGetUe( pBs );
569+
570+ pRefBasePicMarking->mmco_base[iIdx].uiMmcoType = kuiMmco;
571+
572+ if (kuiMmco == MMCO_END)
573+ break;
574+
575+ if (kuiMmco == MMCO_SHORT2UNUSED){
576+ pRefBasePicMarking->mmco_base[iIdx].uiDiffOfPicNums = 1 + BsGetUe( pBs );
577+ pRefBasePicMarking->mmco_base[iIdx].iShortFrameNum = 0;
578+ }
579+ else if (kuiMmco == MMCO_LONG2UNUSED){
580+ pRefBasePicMarking->mmco_base[iIdx].uiLongTermPicNum = BsGetUe( pBs );
581+ }
582+ ++ iIdx;
583+ } while(iIdx < MAX_MMCO_COUNT);
584+ }
585+}
586+
587+void_t ParsePrefixNalUnit ( PWelsDecoderContext pCtx, PBitStringAux pBs )
588+{
589+ PNalUnit pCurNal = &pCtx->sPrefixNal;
590+
591+ if ( pCurNal->sNalHeaderExt.sNalUnitHeader.uiNalRefIdc != 0 ){
592+ PNalUnitHeaderExt head_ext = &pCurNal->sNalHeaderExt;
593+ PPrefixNalUnit sPrefixNal = &pCurNal->sNalData.sPrefixNal;
594+ sPrefixNal->bStoreRefBasePicFlag = !!BsGetOneBit( pBs );
595+ if ( (head_ext->bUseRefBasePicFlag || sPrefixNal->bStoreRefBasePicFlag) && !head_ext->bIdrFlag )
596+ {
597+ ParseRefBasePicMarking ( pBs, &sPrefixNal->sRefPicBaseMarking );
598+ }
599+ sPrefixNal->bPrefixNalUnitAdditionalExtFlag = !!BsGetOneBit( pBs );
600+ if ( sPrefixNal->bPrefixNalUnitAdditionalExtFlag ){
601+ sPrefixNal->bPrefixNalUnitExtFlag = !!BsGetOneBit( pBs );
602+ }
603+ }
604+}
605+
606+
607+int32_t DecodeSpsSvcExt( PWelsDecoderContext pCtx, PSubsetSps pSpsExt, PBitStringAux pBs )
608+{
609+ PSpsSvcExt pExt = NULL;
610+ uint8_t uiChromaArrayType = 1;
611+
612+ pExt = &pSpsExt->sSpsSvcExt;
613+
614+ pExt->bInterLayerDeblockingFilterCtrlPresentFlag = !!BsGetOneBit( pBs );
615+ pExt->uiExtendedSpatialScalability = BsGetBits( pBs, 2 );
616+ if ( pExt->uiExtendedSpatialScalability > 2 )
617+ {
618+ WelsLog(pCtx, WELS_LOG_WARNING, "DecodeSpsSvcExt():extended_spatial_scalability (%d) != 0, ESS not supported!\n", pExt->uiExtendedSpatialScalability);
619+ return GENERATE_ERROR_NO(ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_ESS);
620+ }
621+
622+ pExt->uiChromaPhaseXPlus1Flag = 0; // FIXME: Incoherent with JVT X201 standard (= 1), but conformance to JSVM (= 0) implementation.
623+ pExt->uiChromaPhaseYPlus1 = 1;
624+ uiChromaArrayType = pSpsExt->sSps.uiChromaArrayType;
625+
626+ pExt->uiChromaPhaseXPlus1Flag = BsGetOneBit( pBs );
627+ pExt->uiChromaPhaseYPlus1 = BsGetBits( pBs, 2 );
628+
629+ pExt->uiSeqRefLayerChromaPhaseXPlus1Flag = pExt->uiChromaPhaseXPlus1Flag;
630+ pExt->uiSeqRefLayerChromaPhaseYPlus1 = pExt->uiChromaPhaseYPlus1;
631+ memset(&pExt->sSeqScaledRefLayer, 0, sizeof(SPosOffset));
632+
633+ if ( pExt->uiExtendedSpatialScalability == 1 ){
634+ SPosOffset* const kpPos = &pExt->sSeqScaledRefLayer;
635+ pExt->uiSeqRefLayerChromaPhaseXPlus1Flag = BsGetOneBit( pBs );
636+ pExt->uiSeqRefLayerChromaPhaseYPlus1 = BsGetBits( pBs, 2 );
637+
638+ kpPos->iLeftOffset = BsGetSe( pBs );
639+ kpPos->iTopOffset = BsGetSe( pBs );
640+ kpPos->iRightOffset = BsGetSe( pBs );
641+ kpPos->iBottomOffset= BsGetSe( pBs );
642+ }
643+
644+ pExt->bSeqTCoeffLevelPredFlag = !!BsGetOneBit( pBs );
645+ pExt->bAdaptiveTCoeffLevelPredFlag = false;
646+ if ( pExt->bSeqTCoeffLevelPredFlag )
647+ pExt->bAdaptiveTCoeffLevelPredFlag = !!BsGetOneBit( pBs );
648+ pExt->bSliceHeaderRestrictionFlag = !!BsGetOneBit( pBs );
649+
650+
651+
652+ return 0;
653+}
654+
655+/*!
656+ *************************************************************************************
657+ * \brief to parse Sequence Parameter Set (SPS)
658+ *
659+ * \param pCtx Decoder context
660+ * \param pBsAux bitstream reader auxiliary
661+ * \param pPicWidth picture width current Sps represented
662+ * \param pPicHeight picture height current Sps represented
663+ *
664+ * \return 0 - successed
665+ * 1 - failed
666+ *
667+ * \note Call it in case eNalUnitType is SPS.
668+ *************************************************************************************
669+ */
670+
671+
672+int32_t ParseSps( PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t *pPicWidth, int32_t *pPicHeight )
673+{
674+ PBitStringAux pBs = pBsAux;
675+ PSps pSps = NULL;
676+ PSubsetSps pSubsetSps = NULL;
677+ SNalUnitHeader *pNalHead= &pCtx->sCurNalHead;
678+ ProfileIdc uiProfileIdc;
679+ uint8_t uiLevelIdc;
680+ int32_t iSpsId;
681+ bool_t bConstraintSetFlags[6] = { false };
682+ const bool_t kbUseSubsetFlag = IS_SUBSET_SPS_NAL(pNalHead->eNalUnitType);
683+
684+
685+ if ( kbUseSubsetFlag ) // SubsetSps
686+ {
687+ pCtx->bSubspsExistAheadFlag = true;
688+ }
689+ else // Sps
690+ {
691+ pCtx->bSpsExistAheadFlag = true;
692+
693+ // added for EC, 10/28/2009
694+ // for safe
695+ memset( &pCtx->bSpsAvailFlags[0], 0, sizeof(pCtx->bSpsAvailFlags) );
696+ memset( &pCtx->bSubspsAvailFlags[0], 0, sizeof(pCtx->bSubspsAvailFlags) );
697+ memset( &pCtx->bPpsAvailFlags[0], 0, sizeof(pCtx->bPpsAvailFlags) );
698+
699+#ifdef MOSAIC_AVOID_BASED_ON_SPS_PPS_ID
700+ pCtx->iSpsTotalNum = 0;
701+ pCtx->iSubspsTotalNum = 0;
702+ pCtx->iPpsTotalNum = 0;
703+#endif //MOSAIC_AVOID_BASED_ON_SPS_PPS_ID
704+ }
705+
706+ uiProfileIdc = BsGetBits( pBs, 8 );
707+ bConstraintSetFlags[0] = !!BsGetOneBit( pBs ); // constraint_set0_flag
708+ bConstraintSetFlags[1] = !!BsGetOneBit( pBs ); // constraint_set1_flag
709+ bConstraintSetFlags[2] = !!BsGetOneBit( pBs ); // constraint_set2_flag
710+ bConstraintSetFlags[3] = !!BsGetOneBit( pBs ); // constraint_set3_flag
711+ bConstraintSetFlags[4] = !!BsGetOneBit( pBs ); // constraint_set4_flag
712+ bConstraintSetFlags[5] = !!BsGetOneBit( pBs ); // constraint_set5_flag
713+ BsGetBits( pBs, 2 ); // reserved_zero_2bits, equal to 0
714+ uiLevelIdc = BsGetBits( pBs, 8 ); // level_idc
715+
716+ iSpsId = BsGetUe( pBs ); // seq_parameter_set_id
717+
718+
719+ if ( iSpsId >= MAX_SPS_COUNT || iSpsId < 0 ) // Modified to check invalid negative iSpsId, 12/1/2009
720+ {
721+ WelsLog( pCtx, WELS_LOG_WARNING, " iSpsId is out of range! \n");
722+ return GENERATE_ERROR_NO(ERR_LEVEL_PARAM_SETS, ERR_INFO_SPS_ID_OVERFLOW);
723+ }
724+
725+ if ( kbUseSubsetFlag )
726+ {
727+#ifdef MOSAIC_AVOID_BASED_ON_SPS_PPS_ID
728+ pSubsetSps = &pCtx->sSubsetSpsBuffer[pCtx->iSubspsTotalNum];
729+ pCtx->bSubspsAvailFlags[pCtx->iSubspsTotalNum] = true;
730+
731+ pSubsetSps->sSps.iSpsId = iSpsId;
732+ pSps = &pSubsetSps->sSps;
733+ ++pCtx->iSubspsTotalNum;
734+#else
735+ pSubsetSps = &pCtx->sSubsetSpsBuffer[iSpsId];
736+ pSps = &pSubsetSps->sSps;
737+ pCtx->bSubspsAvailFlags[iSpsId] = true; // added for EC, 10/28/2009
738+#endif //MOSAIC_AVOID_BASED_ON_SPS_PPS_ID
739+ }
740+ else
741+ {
742+#ifdef MOSAIC_AVOID_BASED_ON_SPS_PPS_ID
743+ pSps = &pCtx->sSpsBuffer[pCtx->iSpsTotalNum];
744+ pCtx->bSpsAvailFlags[pCtx->iSpsTotalNum] = true;
745+
746+ pSps->iSpsId = iSpsId;
747+ ++pCtx->iSpsTotalNum;
748+#else
749+ pSps = &pCtx->sSpsBuffer[iSpsId];
750+ pCtx->bSpsAvailFlags[iSpsId] = true; // added for EC, 10/28/2009
751+#endif //MOSAIC_AVOID_BASED_ON_SPS_PPS_ID
752+ }
753+
754+ // syntax elements in default
755+ pSps->uiChromaFormatIdc = 1;
756+ pSps->uiBitDepthLuma =
757+ pSps->uiBitDepthChroma = 8;
758+
759+ pSps->uiProfileIdc = uiProfileIdc;
760+ pSps->uiLevelIdc = uiLevelIdc;
761+ pSps->iSpsId = iSpsId;
762+
763+ if ( PRO_SCALABLE_BASELINE == uiProfileIdc || PRO_SCALABLE_HIGH == uiProfileIdc ||
764+ PRO_HIGH == uiProfileIdc || PRO_HIGH10 == uiProfileIdc ||
765+ PRO_HIGH422 == uiProfileIdc || PRO_HIGH444 == uiProfileIdc ||
766+ PRO_CAVLC444 == uiProfileIdc || 44 == uiProfileIdc ){
767+
768+ pSps->uiChromaFormatIdc = BsGetUe( pBs );
769+ if( pSps->uiChromaFormatIdc != 1 )
770+ {
771+ WelsLog( pCtx, WELS_LOG_WARNING, "ParseSps(): chroma_format_idc (%d) = 1 supported.\n", pSps->uiChromaFormatIdc);
772+ return GENERATE_ERROR_NO(ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_NON_BASELINE);
773+ }
774+ pSps->uiChromaArrayType = pSps->uiChromaFormatIdc;
775+ pSps->uiBitDepthLuma = 8 + BsGetUe( pBs );
776+ if( pSps->uiBitDepthLuma != 8 )
777+ {
778+ WelsLog( pCtx, WELS_LOG_WARNING, "ParseSps(): bit_depth_luma (%d) Only 8 bit supported.\n", pSps->uiBitDepthLuma);
779+ return GENERATE_ERROR_NO(ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_NON_BASELINE);
780+ }
781+
782+ pSps->uiBitDepthChroma = 8 + BsGetUe( pBs );
783+ if( pSps->uiBitDepthChroma != 8 )
784+ {
785+ WelsLog( pCtx, WELS_LOG_WARNING, "ParseSps(): bit_depth_chroma (%d). Only 8 bit supported.\n", pSps->uiBitDepthChroma);
786+ return GENERATE_ERROR_NO(ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_NON_BASELINE);
787+ }
788+ pSps->bQpPrimeYZeroTransfBypassFlag = !!BsGetOneBit( pBs );
789+ pSps->bSeqScalingMatrixPresentFlag = !!BsGetOneBit( pBs );
790+
791+ if ( pSps->bSeqScalingMatrixPresentFlag ){ // For high profile, it is not used in current application. FIXME
792+ WelsLog( pCtx, WELS_LOG_WARNING, "ParseSps(): seq_scaling_matrix_present_flag (%d). Feature not supported.\n", pSps->bSeqScalingMatrixPresentFlag);
793+ return GENERATE_ERROR_NO(ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_NON_BASELINE);
794+ }
795+ }
796+
797+ pSps->uiLog2MaxFrameNum = 4 + BsGetUe( pBs ); // log2_max_frame_num_minus4
798+ pSps->uiPocType = BsGetUe( pBs ); // pic_order_cnt_type
799+
800+ if ( 0 == pSps->uiPocType )
801+ {
802+ pSps->iLog2MaxPocLsb = 4 + BsGetUe( pBs ); // log2_max_pic_order_cnt_lsb_minus4
803+
804+ }
805+ else if ( 1 == pSps->uiPocType )
806+ {
807+ int32_t i;
808+ pSps->bDeltaPicOrderAlwaysZeroFlag = !!BsGetOneBit( pBs ); // bDeltaPicOrderAlwaysZeroFlag
809+ pSps->iOffsetForNonRefPic = BsGetSe( pBs ); // iOffsetForNonRefPic
810+ pSps->iOffsetForTopToBottomField = BsGetSe( pBs ); // iOffsetForTopToBottomField
811+ pSps->iNumRefFramesInPocCycle = BsGetUe( pBs ); // num_ref_frames_in_pic_order_cnt_cycle
812+ for( i = 0; i < pSps->iNumRefFramesInPocCycle; i++ )
813+ pSps->iOffsetForRefFrame[ i ] = BsGetSe( pBs ); // iOffsetForRefFrame[ i ]
814+ }
815+ if ( pSps->uiPocType > 2 )
816+ {
817+ WelsLog( pCtx, WELS_LOG_WARNING, " illegal pic_order_cnt_type: %d ! \n", pSps->uiPocType );
818+ return GENERATE_ERROR_NO(ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_POC_TYPE);
819+ }
820+
821+ pSps->iNumRefFrames = BsGetUe( pBs ); // max_num_ref_frames
822+ pSps->bGapsInFrameNumValueAllowedFlag = !!BsGetOneBit( pBs ); // bGapsInFrameNumValueAllowedFlag
823+ pSps->iMbWidth = 1 + BsGetUe( pBs ); // pic_width_in_mbs_minus1
824+ pSps->iMbHeight = 1 + BsGetUe( pBs ); // pic_height_in_map_units_minus1
825+ pSps->uiTotalMbCount = pSps->iMbWidth * pSps->iMbHeight;
826+ pSps->bFrameMbsOnlyFlag = !!BsGetOneBit( pBs ); // frame_mbs_only_flag
827+
828+ if ( !pSps->bFrameMbsOnlyFlag )
829+ {
830+ WelsLog( pCtx, WELS_LOG_WARNING, "ParseSps(): frame_mbs_only_flag (%d) not supported.\n", pSps->bFrameMbsOnlyFlag);
831+ return GENERATE_ERROR_NO(ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_MBAFF);
832+ }
833+ pSps->bDirect8x8InferenceFlag = !!BsGetOneBit( pBs ); // direct_8x8_inference_flag
834+ pSps->bFrameCroppingFlag = !!BsGetOneBit( pBs ); // frame_cropping_flag
835+ if ( pSps->bFrameCroppingFlag )
836+ {
837+ pSps->sFrameCrop.iLeftOffset = BsGetUe( pBs ); // frame_crop_left_offset
838+ pSps->sFrameCrop.iRightOffset = BsGetUe( pBs ); // frame_crop_right_offset
839+ pSps->sFrameCrop.iTopOffset = BsGetUe( pBs ); // frame_crop_top_offset
840+ pSps->sFrameCrop.iBottomOffset = BsGetUe( pBs ); // frame_crop_bottom_offset
841+ }
842+ else
843+ {
844+ pSps->sFrameCrop.iLeftOffset = 0; // frame_crop_left_offset
845+ pSps->sFrameCrop.iRightOffset = 0; // frame_crop_right_offset
846+ pSps->sFrameCrop.iTopOffset = 0; // frame_crop_top_offset
847+ pSps->sFrameCrop.iBottomOffset = 0; // frame_crop_bottom_offset
848+ }
849+ pSps->bVuiParamPresentFlag = !!BsGetOneBit( pBs ); // vui_parameters_present_flag
850+
851+ // Check if SPS SVC extension applicated
852+ if ( kbUseSubsetFlag && ( PRO_SCALABLE_BASELINE == uiProfileIdc || PRO_SCALABLE_HIGH == uiProfileIdc ) )
853+ {
854+ if ( DecodeSpsSvcExt( pCtx, pSubsetSps, pBs ) != ERR_NONE ){
855+ return -1;
856+ }
857+
858+ pSubsetSps->bSvcVuiParamPresentFlag = !!BsGetOneBit( pBs );
859+ if ( pSubsetSps->bSvcVuiParamPresentFlag ){
860+ }
861+ }
862+
863+
864+ if ( PRO_SCALABLE_BASELINE == uiProfileIdc || PRO_SCALABLE_HIGH == uiProfileIdc )
865+ pCtx->bAvcBasedFlag = false;
866+ else
867+ pCtx->bAvcBasedFlag = true; // added for avc base pBs
868+
869+ *pPicWidth = pSps->iMbWidth << 4;
870+ *pPicHeight = pSps->iMbHeight << 4;
871+
872+ return 0;
873+}
874+
875+/*!
876+ *************************************************************************************
877+ * \brief to parse Picture Parameter Set (PPS)
878+ *
879+ * \param pCtx Decoder context
880+ * \param pPpsList pps list
881+ * \param pBsAux bitstream reader auxiliary
882+ *
883+ * \return 0 - successed
884+ * 1 - failed
885+ *
886+ * \note Call it in case eNalUnitType is PPS.
887+ *************************************************************************************
888+ */
889+int32_t ParsePps( PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux )
890+{
891+
892+ PPps pPps = NULL;
893+ uint32_t uiPpsId = 0;
894+ uint32_t iTmp;
895+
896+ uiPpsId = BsGetUe(pBsAux);
897+ if ( uiPpsId >= MAX_PPS_COUNT )
898+ {
899+ return ERR_INFO_PPS_ID_OVERFLOW;
900+ }
901+
902+#ifdef MOSAIC_AVOID_BASED_ON_SPS_PPS_ID
903+ pPps = &pPpsList[pCtx->iPpsTotalNum];
904+#else
905+ pPps = &pPpsList[uiPpsId];
906+#endif //MOSAIC_AVOID_BASED_ON_SPS_PPS_ID
907+
908+
909+ pPps->iPpsId = uiPpsId;
910+ pPps->iSpsId = BsGetUe(pBsAux);
911+
912+ if (pPps->iSpsId >= MAX_SPS_COUNT)
913+ {
914+ return ERR_INFO_SPS_ID_OVERFLOW;
915+ }
916+
917+ pPps->bEntropyCodingModeFlag = !!BsGetOneBit(pBsAux);
918+ pPps->bPicOrderPresentFlag = !!BsGetOneBit(pBsAux);
919+
920+ pPps->uiNumSliceGroups = 1 + BsGetUe(pBsAux);
921+
922+ if (pPps->uiNumSliceGroups > MAX_SLICEGROUP_IDS)
923+ {
924+ return ERR_INFO_INVALID_SLICEGROUP;
925+ }
926+
927+ if (pPps->uiNumSliceGroups > 1)
928+ {
929+ pPps->uiSliceGroupMapType = BsGetUe(pBsAux);
930+ if( pPps->uiSliceGroupMapType > 1)
931+ {
932+ WelsLog( pCtx, WELS_LOG_WARNING, "ParsePps(): slice_group_map_type (%d): support only 0,1.\n", pPps->uiSliceGroupMapType);
933+ return GENERATE_ERROR_NO(ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_FMOTYPE);
934+ }
935+
936+ switch(pPps->uiSliceGroupMapType)
937+ {
938+ case 0:
939+ for (iTmp = 0; iTmp < pPps->uiNumSliceGroups; iTmp++)
940+ {
941+ pPps->uiRunLength[iTmp] = 1 + BsGetUe(pBsAux);
942+ }
943+ break;
944+ default:
945+ break;
946+ }
947+ }
948+
949+ pPps->uiNumRefIdxL0Active = 1 + BsGetUe(pBsAux);
950+ pPps->uiNumRefIdxL1Active = 1 + BsGetUe(pBsAux);
951+
952+ if (pPps->uiNumRefIdxL0Active > MAX_REF_PIC_COUNT ||
953+ pPps->uiNumRefIdxL1Active > MAX_REF_PIC_COUNT)
954+ {
955+ return ERR_INFO_REF_COUNT_OVERFLOW;
956+ }
957+
958+ pPps->bWeightedPredFlag = !!BsGetOneBit(pBsAux);
959+ pPps->uiWeightedBipredIdc = BsGetBits(pBsAux, 2);
960+ if( pPps->bWeightedPredFlag || pPps->uiWeightedBipredIdc != 0 )
961+ {
962+ WelsLog( pCtx, WELS_LOG_WARNING, "ParsePps(): weighted_pred_flag (%d) weighted_bipred_idc (%d) neither supported.\n", pPps->bWeightedPredFlag, pPps->uiWeightedBipredIdc);
963+ return GENERATE_ERROR_NO(ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_WP);
964+ }
965+
966+ pPps->iPicInitQp = 26 + BsGetSe(pBsAux);
967+ pPps->iPicInitQs = 26 + BsGetSe(pBsAux);
968+
969+ pPps->iChromaQpIndexOffset = BsGetSe(pBsAux);
970+ pPps->bDeblockingFilterControlPresentFlag = !!BsGetOneBit(pBsAux);
971+ pPps->bConstainedIntraPredFlag = !!BsGetOneBit(pBsAux);
972+ pPps->bRedundantPicCntPresentFlag = !!BsGetOneBit(pBsAux);
973+
974+
975+#ifdef MOSAIC_AVOID_BASED_ON_SPS_PPS_ID
976+ pCtx->bPpsAvailFlags[pCtx->iPpsTotalNum] = true;
977+ ++pCtx->iPpsTotalNum;
978+#else
979+ pCtx->bPpsAvailFlags[uiPpsId] = true; // added for EC, 10/28/2009
980+#endif //MOSAIC_AVOID_BASED_ON_SPS_PPS_ID
981+
982+ return ERR_NONE;
983+}
984+
985+/*!
986+ *************************************************************************************
987+ * \brief to parse SEI message payload
988+ *
989+ * \param pSei sei message to be parsed output
990+ * \param pBsAux bitstream reader auxiliary
991+ *
992+ * \return 0 - successed
993+ * 1 - failed
994+ *
995+ * \note Call it in case eNalUnitType is NAL_UNIT_SEI.
996+ *************************************************************************************
997+ */
998+int32_t ParseSei( void_t *pSei, PBitStringAux pBsAux ) // reserved Sei_Msg type
999+{
1000+
1001+
1002+ return ERR_NONE;
1003+}
1004+
1005+/*!
1006+ *************************************************************************************
1007+ * \brief reset fmo list due to got Sps now
1008+ *
1009+ * \param pCtx decoder context
1010+ *
1011+ * \return count number of fmo context units are reset
1012+ *************************************************************************************
1013+ */
1014+int32_t ResetFmoList( PWelsDecoderContext pCtx )
1015+{
1016+ int32_t iCountNum = 0;
1017+ if ( NULL != pCtx )
1018+ {
1019+ // Fixed memory leak due to PPS_ID might not be continuous sometimes, 1/5/2010
1020+ UninitFmoList( &pCtx->sFmoList[0], MAX_PPS_COUNT, pCtx->iActiveFmoNum );
1021+ iCountNum = pCtx->iActiveFmoNum;
1022+ pCtx->iActiveFmoNum = 0;
1023+ }
1024+ return iCountNum;
1025+}
1026+
1027+} // 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