History

Pretty printed the C++ code with astyle

Ethan Hugg committed 12 years ago

Commit ff6b6691 parent 063709c225 files · +48457 −51954Browse files

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

Unified · Split

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