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
59namespace 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 */
74uint8_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 */
117uint8_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
359bool_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
418bool_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 */
492int32_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
561void_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
587void_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
607int32_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
672int32_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 */
889int32_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 */
998int32_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 */
1014int32_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