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

Unified · Split

codec/decoder/core/src/decoder_core.cpp+2106−0
@@ -0,0 +1,2106 @@
1+/*!
2+ * \copy
3+ * Copyright (c) 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+ * decoder_core.c: Wels decoder framework core implementation
32+ */
33+
34+#include <string.h>
35+#include "codec_def.h"
36+#include "decoder_core.h"
37+#include "typedefs.h"
38+#include "wels_const.h"
39+#include "wels_common_basis.h"
40+#include "codec_app_def.h"
41+#include "decoder_context.h"
42+#include "dec_golomb.h"
43+#include "bit_stream.h"
44+#include "error_code.h"
45+#include "parameter_sets.h"
46+#include "fmo.h"
47+#include "utils.h"
48+#include "memmgr_nal_unit.h"
49+#include "dec_frame.h"
50+#include "au_parser.h"
51+#include "pic_queue.h"
52+#include "ls_defines.h"
53+#include "decode_slice.h"
54+#include "manage_dec_ref.h"
55+#include "expand_pic.h"
56+#include "decoder.h"
57+#include "decode_mb_aux.h"
58+#include "mem_align.h"
59+
60+namespace WelsDec {
61+
62+static inline int32_t DecodeFrameConstruction( PWelsDecoderContext pCtx, uint8_t **ppDst, int32_t *pDstLen, int32_t *pWidth, int32_t *pHeight, SBufferInfo *pDstInfo )
63+{
64+ PDqLayer pCurDq = pCtx->pCurDqLayer;
65+ PPicture pPic = pCtx->pDec;
66+
67+ const int32_t kiWidth = pCurDq->iMbWidth << 4;
68+ const int32_t kiHeight= pCurDq->iMbHeight << 4;
69+
70+ const int32_t kiTotalNumMbInCurLayer = pCurDq->iMbWidth * pCurDq->iMbHeight;
71+
72+ if ( pPic->iTotalNumMbRec != kiTotalNumMbInCurLayer )
73+ {
74+ WelsLog( pCtx, WELS_LOG_WARNING, "DecodeFrameConstruction():::iTotalNumMbRec:%d, total_num_mb_sps:%d, cur_layer_mb_width:%d, cur_layer_mb_height:%d \n",
75+ pPic->iTotalNumMbRec, kiTotalNumMbInCurLayer, pCurDq->iMbWidth, pCurDq->iMbHeight );
76+ return -1;
77+ }
78+#ifdef NO_WAITING_AU
79+ pPic->iTotalNumMbRec = 0;
80+#endif
81+
82+ if ( I_SLICE == pCurDq->sLayerInfo.sSliceInLayer.eSliceType )
83+ {
84+ memcpy( &(pCtx->sFrameCrop), &(pCurDq->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.pSps->sFrameCrop), sizeof(SPosOffset) );//confirmed_safe_unsafe_usage
85+#ifdef LONG_TERM_REF
86+ pCtx->bParamSetsLostFlag = false;
87+#else
88+ pCtx->bReferenceLostAtT0Flag = false; // need initialize it due I_SLICE, 6/4/2010
89+#endif //LONG_TERM_REF
90+ WelsLog( pCtx, WELS_LOG_INFO, "DecodeFrameConstruction()::::output good I frame, %d x %d, crop_left:%d, crop_right:%d, crop_top:%d, crop_bottom:%d.\n",
91+ kiWidth, kiHeight, pCtx->sFrameCrop.iLeftOffset, pCtx->sFrameCrop.iRightOffset, pCtx->sFrameCrop.iTopOffset, pCtx->sFrameCrop.iBottomOffset );
92+ WelsLog( pCtx, WELS_LOG_INFO, "After decoding, set_mode:[%s], eWorkMode:[%s], eBufferProperty:[%s]\n",
93+ DECODER_MODE_NAME(pCtx->iSetMode), DECODER_MODE_NAME(pCtx->iDecoderMode), OUTPUT_PROPERTY_NAME(pDstInfo->eBufferProperty));
94+ }
95+
96+ //////output:::normal path
97+ ppDst[0] = pPic->pData[0];
98+ ppDst[1] = pPic->pData[1];
99+ ppDst[2] = pPic->pData[2];
100+ *pDstLen = pPic->iLinesize[0];
101+ *(pDstLen+1) = pPic->iLinesize[1];
102+ *pWidth = kiWidth;
103+ *pHeight = kiHeight;
104+
105+ pDstInfo->UsrData.sSystemBuffer.iFormat = videoFormatI420;
106+
107+ pDstInfo->UsrData.sSystemBuffer.iWidth = kiWidth - (pCtx->sFrameCrop.iLeftOffset + pCtx->sFrameCrop.iRightOffset)*2;
108+ pDstInfo->UsrData.sSystemBuffer.iHeight = kiHeight - (pCtx->sFrameCrop.iTopOffset + pCtx->sFrameCrop.iBottomOffset)*2;
109+ pDstInfo->UsrData.sSystemBuffer.iStride[0] = pPic->iLinesize[0];
110+ pDstInfo->UsrData.sSystemBuffer.iStride[1] = pPic->iLinesize[1];
111+ ppDst[0] = ppDst[0] + pCtx->sFrameCrop.iTopOffset*2*pPic->iLinesize[0] + pCtx->sFrameCrop.iLeftOffset*2;
112+ ppDst[1] = ppDst[1] + pCtx->sFrameCrop.iTopOffset *pPic->iLinesize[1] + pCtx->sFrameCrop.iLeftOffset;
113+ ppDst[2] = ppDst[2] + pCtx->sFrameCrop.iTopOffset *pPic->iLinesize[1] + pCtx->sFrameCrop.iLeftOffset;
114+ pDstInfo->eBufferProperty = BUFFER_HOST;
115+ pDstInfo->iBufferStatus = 1;
116+
117+ return 0;
118+}
119+
120+inline BOOL_T CheckSliceNeedReconstruct(int16_t iCurDid, int16_t iCurQid, bool_t bStoreRefBasePicFlag,
121+ uint8_t uiDidMax, uint8_t uiLayerDqId, uint8_t uiTargetDqId)
122+{
123+ return ( (iCurDid == uiDidMax) && (iCurQid == BASE_QUALITY_ID) && (bStoreRefBasePicFlag) ) // store base
124+ || (uiLayerDqId == uiTargetDqId); // target layer
125+}
126+
127+inline uint8_t GetTargetDqId(uint8_t uiTargetDqId, SDecodingParam * psParam)
128+{
129+ uint8_t uiRequiredDqId = psParam ? psParam->uiTargetDqLayer : (uint8_t)255;
130+
131+ return WELS_MIN(uiTargetDqId, uiRequiredDqId);
132+}
133+
134+
135+inline void_t HandleReferenceLostL0(PWelsDecoderContext pCtx, PNalUnit pCurNal)
136+{
137+ if( 0 == pCurNal->sNalHeaderExt.uiTemporalId ){
138+ pCtx->bReferenceLostAtT0Flag = true;
139+ }
140+#ifndef LONG_TERM_REF
141+ if( pCtx->bReferenceLostAtT0Flag ){
142+ ResetParameterSetsState(pCtx);
143+ }
144+#endif
145+ pCtx->iErrorCode |= dsBitstreamError;
146+}
147+
148+inline void_t HandleReferenceLost(PWelsDecoderContext pCtx, PNalUnit pCurNal)
149+{
150+ if( (0 == pCurNal->sNalHeaderExt.uiTemporalId) || (1 == pCurNal->sNalHeaderExt.uiTemporalId) ){
151+ pCtx->bReferenceLostAtT0Flag = true;
152+ }
153+#ifndef LONG_TERM_REF
154+ if( pCtx->bReferenceLostAtT0Flag ){
155+ ResetParameterSetsState(pCtx);
156+ }
157+#endif
158+ pCtx->iErrorCode |= dsRefLost;
159+}
160+
161+inline int32_t WelsDecodeConstructSlice(PWelsDecoderContext pCtx, PNalUnit pCurNal)
162+{
163+ int32_t iRet = WelsTargetSliceConstruction(pCtx);
164+
165+ if( iRet ){
166+ HandleReferenceLostL0(pCtx, pCurNal);
167+ }
168+
169+ return iRet;
170+}
171+
172+/*
173+ * Predeclared function routines ..
174+ */
175+int32_t ParseRefPicListReordering ( PBitStringAux pBs, PSliceHeader pSh )
176+{
177+ int32_t iList = 0;
178+ const ESliceType keSt = pSh->eSliceType;
179+ PRefPicListReorderSyn pRefPicListReordering = &pSh->pRefPicListReordering;
180+
181+ if ( keSt == I_SLICE || keSt == SI_SLICE )
182+ return ERR_NONE;
183+
184+ // Common syntaxs for P or B slices: list0, list1 followed if B slices used.
185+ do {
186+ pRefPicListReordering->bRefPicListReorderingFlag[iList] = !!BsGetOneBit( pBs);
187+
188+ if ( pRefPicListReordering->bRefPicListReorderingFlag[iList] ){
189+ int32_t iIdx = 0;
190+ do {
191+ const uint8_t kuiIdc = BsGetUe( pBs );
192+
193+ //Fixed the referrence list reordering crash issue.(fault kIdc value > 3 case)---
194+ if ((iIdx >= MAX_REF_PIC_COUNT )||(kuiIdc > 3))
195+ {
196+ return GENERATE_ERROR_NO(ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REF_REORDERING);
197+ }
198+ pRefPicListReordering->sReorderingSyn[iList][iIdx].uiReorderingOfPicNumsIdc = kuiIdc;
199+ if ( kuiIdc == 3 )
200+ break;
201+
202+ if ( iIdx >= pSh->uiRefCount[iList] || iIdx >= MAX_REF_PIC_COUNT )
203+ return GENERATE_ERROR_NO(ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REF_REORDERING);
204+
205+ if (kuiIdc == 0 || kuiIdc == 1){
206+ pRefPicListReordering->sReorderingSyn[iList][iIdx].uiAbsDiffPicNumMinus1 = BsGetUe( pBs ); // uiAbsDiffPicNumMinus1
207+ }
208+ else if (kuiIdc == 2){
209+ pRefPicListReordering->sReorderingSyn[iList][iIdx].uiLongTermPicNum= BsGetUe( pBs );
210+ }
211+
212+ ++ iIdx;
213+ } while(true);
214+ }
215+ if (keSt != B_SLICE)
216+ break;
217+ ++ iList;
218+ } while(iList < LIST_A);
219+
220+ return ERR_NONE;
221+}
222+
223+int32_t ParseDecRefPicMarking ( PWelsDecoderContext pCtx, PBitStringAux pBs, PSliceHeader pSh, PSps pSps, const bool_t kbIdrFlag)
224+{
225+ PRefPicMarking const kpRefMarking = &pSh->sRefMarking;
226+
227+ if ( kbIdrFlag ){
228+ kpRefMarking->bNoOutputOfPriorPicsFlag = !!BsGetOneBit( pBs );
229+ kpRefMarking->bLongTermRefFlag = !!BsGetOneBit( pBs );
230+ }
231+ else{
232+ kpRefMarking->bAdaptiveRefPicMarkingModeFlag = !!BsGetOneBit( pBs );
233+ if (kpRefMarking->bAdaptiveRefPicMarkingModeFlag){
234+ int32_t iIdx = 0;
235+ do {
236+ const int32_t kiMmco = BsGetUe( pBs );
237+
238+ kpRefMarking->sMmcoRef[iIdx].uiMmcoType = kiMmco;
239+ if (kiMmco == MMCO_END)
240+ break;
241+
242+ if (kiMmco == MMCO_SHORT2UNUSED || kiMmco == MMCO_SHORT2LONG)
243+ {
244+ kpRefMarking->sMmcoRef[iIdx].iDiffOfPicNum = 1 + BsGetUe( pBs );
245+ kpRefMarking->sMmcoRef[iIdx].iShortFrameNum = (pSh->iFrameNum - kpRefMarking->sMmcoRef[iIdx].iDiffOfPicNum) & ((1<<pSps->uiLog2MaxFrameNum)-1);
246+ }
247+ else if (kiMmco == MMCO_LONG2UNUSED)
248+ kpRefMarking->sMmcoRef[iIdx].uiLongTermPicNum = BsGetUe( pBs );
249+
250+ if (kiMmco == MMCO_SHORT2LONG || kiMmco == MMCO_LONG)
251+ {
252+ kpRefMarking->sMmcoRef[iIdx].iLongTermFrameIdx = BsGetUe( pBs );
253+ }
254+ else if (kiMmco == MMCO_SET_MAX_LONG)
255+ kpRefMarking->sMmcoRef[iIdx].iMaxLongTermFrameIdx = -1 + BsGetUe( pBs );
256+ ++ iIdx;
257+
258+ } while(iIdx < MAX_MMCO_COUNT);
259+ }
260+ }
261+
262+ return ERR_NONE;
263+}
264+
265+bool_t FillDefaultSliceHeaderExt ( PSliceHeaderExt pShExt, PNalUnitHeaderExt pNalExt )
266+{
267+ if ( pShExt == NULL || pNalExt == NULL )
268+ return false;
269+
270+ if ( pNalExt->iNoInterLayerPredFlag || pNalExt->uiQualityId > 0 )
271+ pShExt->bBasePredWeightTableFlag = false;
272+ else
273+ pShExt->bBasePredWeightTableFlag = true;
274+ pShExt->uiRefLayerDqId = (uint8_t)-1;
275+ pShExt->uiDisableInterLayerDeblockingFilterIdc = 0;
276+ pShExt->iInterLayerSliceAlphaC0Offset = 0;
277+ pShExt->iInterLayerSliceBetaOffset = 0;
278+ pShExt->bConstrainedIntraResamplingFlag = false;
279+ pShExt->uiRefLayerChromaPhaseXPlus1Flag = 0;
280+ pShExt->uiRefLayerChromaPhaseYPlus1 = 1;
281+ //memset(&pShExt->sScaledRefLayer, 0, sizeof(SPosOffset));
282+
283+ pShExt->iScaledRefLayerPicWidthInSampleLuma = pShExt->sSliceHeader.iMbWidth << 4;
284+ pShExt->iScaledRefLayerPicHeightInSampleLuma = pShExt->sSliceHeader.iMbHeight << 4;
285+
286+ pShExt->bSliceSkipFlag = false;
287+ pShExt->bAdaptiveBaseModeFlag = false;
288+ pShExt->bDefaultBaseModeFlag = false;
289+ pShExt->bAdaptiveMotionPredFlag = false;
290+ pShExt->bDefaultMotionPredFlag = false;
291+ pShExt->bAdaptiveResidualPredFlag = false;
292+ pShExt->bDefaultResidualPredFlag = false;
293+ pShExt->bTCoeffLevelPredFlag = false;
294+ pShExt->uiScanIdxStart = 0;
295+ pShExt->uiScanIdxEnd = 15;
296+
297+ return true;
298+}
299+
300+/*
301+ * WelsInitMemory
302+ * Memory request for new introduced data
303+ * Especially for:
304+ * rbsp_au_buffer, cur_dq_layer_ptr and ref_dq_layer_ptr in MB info cache.
305+ * return:
306+ * 0 - success; otherwise returned error_no defined in error_no.h.
307+*/
308+int32_t WelsInitMemory( PWelsDecoderContext pCtx )
309+{
310+ if (pCtx == NULL){
311+ return ERR_INFO_INVALID_PTR;
312+ }
313+
314+ if ( MemInitNalList( &pCtx->pAccessUnitList, MAX_NAL_UNIT_NUM_IN_AU ) != 0 )
315+ return ERR_INFO_OUT_OF_MEMORY;
316+
317+ if ( ( pCtx->sRawData.pHead = static_cast<uint8_t*> (WelsMalloc( MAX_ACCESS_UINT_CAPACITY, "pCtx->sRawData->pHead" )) ) == NULL )
318+ {
319+ return ERR_INFO_OUT_OF_MEMORY;
320+ }
321+ pCtx->sRawData.pStartPos =
322+ pCtx->sRawData.pCurPos = pCtx->sRawData.pHead;
323+ pCtx->sRawData.pEnd = pCtx->sRawData.pHead + MAX_ACCESS_UINT_CAPACITY;
324+
325+ pCtx->uiTargetDqId = (uint8_t)-1;
326+ pCtx->bEndOfStreamFlag = false;
327+ pCtx->iImgWidthInPixel = 0;
328+ pCtx->iImgHeightInPixel = 0;
329+
330+ return ERR_NONE;
331+}
332+
333+/*
334+ * WelsFreeMemory
335+ * Free memory introduced in WelsInitMemory at destruction of decoder.
336+ *
337+ */
338+void_t WelsFreeMemory( PWelsDecoderContext pCtx )
339+{
340+ if ( pCtx == NULL )
341+ return;
342+
343+ if ( NULL != pCtx->pParam )
344+ {
345+ WelsFree( pCtx->pParam, "pCtx->pParam" );
346+
347+ pCtx->pParam = NULL;
348+ }
349+
350+ MemFreeNalList( &pCtx->pAccessUnitList );
351+
352+ if ( pCtx->sRawData.pHead )
353+ {
354+ WelsFree(pCtx->sRawData.pHead, "pCtx->sRawData->pHead");
355+ }
356+ pCtx->sRawData.pHead = NULL;
357+ pCtx->sRawData.pEnd = NULL;
358+ pCtx->sRawData.pStartPos = NULL;
359+ pCtx->sRawData.pCurPos = NULL;
360+}
361+
362+/*
363+ * DecodeNalHeaderExt
364+ * Trigger condition: NAL_UNIT_TYPE = NAL_UNIT_PREFIX or NAL_UNIT_CODED_SLICE_EXT
365+ * Parameter:
366+ * pNal: target NALUnit ptr
367+ * pSrc: NAL Unit bitstream
368+ */
369+void_t DecodeNalHeaderExt( PNalUnit pNal, uint8_t* pSrc )
370+{
371+ PNalUnitHeaderExt pHeaderExt = &pNal->sNalHeaderExt;
372+
373+ uint8_t uiCurByte = *pSrc;
374+ pHeaderExt->bIdrFlag = !!(uiCurByte & 0x40);
375+ pHeaderExt->uiPriorityId = uiCurByte & 0x3F;
376+
377+ uiCurByte = *(++pSrc);
378+ pHeaderExt->iNoInterLayerPredFlag = uiCurByte >> 7;
379+ pHeaderExt->uiDependencyId = (uiCurByte & 0x70) >> 4;
380+ pHeaderExt->uiQualityId = uiCurByte & 0x0F;
381+ uiCurByte = *(++pSrc);
382+ pHeaderExt->uiTemporalId = uiCurByte >> 5;
383+ pHeaderExt->bUseRefBasePicFlag = !!(uiCurByte & 0x10);
384+ pHeaderExt->bDiscardableFlag = !!(uiCurByte & 0x08);
385+ pHeaderExt->bOutputFlag = !!(uiCurByte & 0x04);
386+ pHeaderExt->uiReservedThree2Bits = uiCurByte & 0x03;
387+ pHeaderExt->uiLayerDqId = (pHeaderExt->uiDependencyId << 4) | pHeaderExt->uiQualityId;
388+}
389+
390+
391+#ifdef MOSAIC_AVOID_BASED_ON_SPS_PPS_ID
392+int32_t CheckPpsId( PWelsDecoderContext pCtx, PPps* ppPps, uint32_t uiPpsId )
393+{
394+ PPps pPpsList = pCtx->sPpsBuffer;
395+ int32_t iPpsNum = pCtx->iPpsTotalNum;
396+ int32_t i = 0;
397+
398+ if ( iPpsNum <= 0 )
399+ {
400+ pCtx->iErrorCode |= dsNoParamSets;
401+
402+ WelsLog( pCtx, WELS_LOG_WARNING, "CheckPpsId():::::PPS list is empty...NO PPS!!!\n" );
403+ return dsNoParamSets;
404+ }
405+
406+ while ( i < iPpsNum )
407+ {
408+ if ( uiPpsId == pPpsList[i].iPpsId )
409+ {
410+ *ppPps = &pPpsList[i];
411+ break;
412+ }
413+ else
414+ {
415+ ++i;
416+ }
417+ }
418+
419+ if ( i == iPpsNum )
420+ {
421+ pCtx->iErrorCode |= dsNoParamSets;
422+
423+ WelsLog( pCtx, WELS_LOG_WARNING, "CheckPpsId()::::::CAN NOT find the matching from the PPS List. iPpsId:%d\n", uiPpsId );
424+ return dsNoParamSets;
425+ }
426+
427+ return 0;
428+}
429+
430+int32_t CheckSpsId( PWelsDecoderContext pCtx, PSubsetSps* ppSubsetSps, PSps* ppSps, int32_t iSpsId, bool_t bExtensionFlag )
431+{
432+ PSps pSpsList = pCtx->sSpsBuffer;
433+ PSubsetSps pSubspsList = pCtx->sSubsetSpsBuffer;
434+
435+ int32_t iSpsNum = pCtx->iSpsTotalNum;
436+ int32_t iSubspsNum = pCtx->iSubspsTotalNum;
437+ int32_t i = 0;
438+
439+ if ( bExtensionFlag )
440+ {
441+ if ( iSubspsNum <= 0 )
442+ {
443+ pCtx->iErrorCode |= dsNoParamSets;
444+
445+ WelsLog( pCtx, WELS_LOG_WARNING, "CheckSpsId()::::SUBSPS list is empty....NO SUBSPS\n" );
446+ return dsNoParamSets;
447+ }
448+ while ( i < iSubspsNum )
449+ {
450+ if ( iSpsId == pSubspsList[i].sSps.iSpsId )
451+ {
452+ *ppSubsetSps = &pSubspsList[i];
453+ *ppSps = &pSubspsList[i].sSps;
454+ break;
455+ }
456+ else
457+ {
458+ ++i;
459+ }
460+ }
461+ if ( i == iSubspsNum )
462+ {
463+ pCtx->iErrorCode |= dsNoParamSets;
464+
465+ WelsLog( pCtx, WELS_LOG_WARNING, "CheckSpsId()::::::CAN NOT find the matching from the SUBSPS List. iSpsId:%d\n", iSpsId );
466+ return dsNoParamSets;
467+ }
468+ }
469+ else
470+ {
471+ if ( iSpsNum <= 0 )
472+ {
473+ pCtx->iErrorCode |= dsNoParamSets;
474+
475+ WelsLog( pCtx, WELS_LOG_WARNING, "CheckSpsId()::::SPS list is empty....NO SPS\n" );
476+ return dsNoParamSets;
477+ }
478+ while ( i < iSpsNum )
479+ {
480+ if ( iSpsId == pSpsList[i].iSpsId )
481+ {
482+ *ppSubsetSps = NULL;
483+ *ppSps = &pSpsList[i];
484+ break;
485+ }
486+ else
487+ {
488+ ++i;
489+ }
490+ }
491+ if ( i == iSpsNum )
492+ {
493+ pCtx->iErrorCode |= dsNoParamSets;
494+
495+ WelsLog( pCtx, WELS_LOG_WARNING, "CheckSpsId()::::::CAN NOT find the matching from the SPS List. iSpsId:%d\n", iSpsId );
496+ return dsNoParamSets;
497+ }
498+ }
499+
500+ return 0;
501+}
502+
503+#endif
504+/*
505+ * decode_slice_header_avc
506+ * Parse slice header of bitstream in avc for storing data structure
507+ */
508+int32_t ParseSliceHeaderSyntaxs ( PWelsDecoderContext pCtx, PBitStringAux pBs, const bool_t kbExtensionFlag )
509+{
510+ PNalUnit const kpCurNal = pCtx->pAccessUnitList->pNalUnitsList[pCtx->pAccessUnitList->uiAvailUnitsNum-1];
511+
512+ PNalUnitHeaderExt pNalHeaderExt = NULL;
513+ PSliceHeader pSliceHead = NULL;
514+ PSliceHeaderExt pSliceHeadExt = NULL;
515+ PSubsetSps pSubsetSps = NULL;
516+ PSps pSps = NULL;
517+ PPps pPps = NULL;
518+ ENalUnitType eNalType = static_cast<ENalUnitType> (0);
519+ int32_t iPpsId = 0;
520+ int32_t iRet = ERR_NONE;
521+ uint8_t uiSliceType = 0;
522+ uint8_t uiQualityId = BASE_QUALITY_ID;
523+ bool_t bIdrFlag = false;
524+ bool_t bSgChangeCycleInvolved = false; // involved slice group change cycle ?
525+
526+ if (kpCurNal == NULL)
527+ {
528+ return ERR_INFO_OUT_OF_MEMORY;
529+ }
530+
531+ pNalHeaderExt = &kpCurNal->sNalHeaderExt;
532+ pSliceHead = &kpCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader;
533+ eNalType = pNalHeaderExt->sNalUnitHeader.eNalUnitType;
534+
535+ pSliceHeadExt = &kpCurNal->sNalData.sVclNal.sSliceHeaderExt;
536+
537+ if ( pSliceHeadExt ){
538+ SRefBasePicMarking sBaseMarking;
539+ const bool_t kbStoreRefBaseFlag = pSliceHeadExt->bStoreRefBasePicFlag;
540+ memcpy(&sBaseMarking, &pSliceHeadExt->sRefBasePicMarking, sizeof(SRefBasePicMarking));//confirmed_safe_unsafe_usage
541+ memset(pSliceHeadExt, 0, sizeof(SSliceHeaderExt));
542+ pSliceHeadExt->bStoreRefBasePicFlag = kbStoreRefBaseFlag;
543+ memcpy(&pSliceHeadExt->sRefBasePicMarking, &sBaseMarking, sizeof(SRefBasePicMarking));//confirmed_safe_unsafe_usage
544+ }
545+
546+ kpCurNal->sNalData.sVclNal.bSliceHeaderExtFlag = kbExtensionFlag;
547+
548+ pSliceHead->iFirstMbInSlice = BsGetUe( pBs );
549+
550+ uiSliceType= BsGetUe( pBs );
551+ if(uiSliceType > 9)
552+ {
553+ WelsLog( pCtx, WELS_LOG_WARNING, "slice type too large (%d) at first_mb(%d)\n", uiSliceType, pSliceHead->iFirstMbInSlice);
554+ return GENERATE_ERROR_NO(ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SLICE_TYPE);
555+ }
556+ if(uiSliceType > 4)
557+ uiSliceType -= 5;
558+
559+ if ( kbExtensionFlag ){
560+ if (uiSliceType > 2){
561+ WelsLog( pCtx, WELS_LOG_WARNING, "Invalid slice type(%d).\n", uiSliceType);
562+ return GENERATE_ERROR_NO(ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SLICE_TYPE);
563+ }
564+ }
565+
566+ pSliceHead->eSliceType = static_cast <ESliceType> (uiSliceType);
567+
568+ iPpsId= BsGetUe( pBs );
569+
570+ if(iPpsId >= MAX_PPS_COUNT){
571+ WelsLog( pCtx, WELS_LOG_WARNING, "iPpsId out of range\n");
572+ return GENERATE_ERROR_NO(ERR_LEVEL_SLICE_HEADER, ERR_INFO_PPS_ID_OVERFLOW);
573+ }
574+
575+#ifdef MOSAIC_AVOID_BASED_ON_SPS_PPS_ID
576+ if ( CheckPpsId( pCtx, &pPps, iPpsId ) )
577+ {
578+ return dsNoParamSets;
579+ }
580+#else
581+ pPps = &pCtx->sPpsBuffer[iPpsId];
582+#endif //MOSAIC_AVOID_BASED_ON_SPS_PPS_ID
583+
584+ if (pPps->uiNumSliceGroups == 0){
585+ WelsLog( pCtx, WELS_LOG_WARNING, "non existing PPS referenced\n");
586+ return GENERATE_ERROR_NO(ERR_LEVEL_SLICE_HEADER, ERR_INFO_NO_PARAM_SETS);
587+ }
588+
589+ if (pPps->iSpsId >= MAX_SPS_COUNT){
590+ WelsLog( pCtx, WELS_LOG_WARNING, "iSpsId out of range\n");
591+ return GENERATE_ERROR_NO(ERR_LEVEL_SLICE_HEADER, ERR_INFO_SPS_ID_OVERFLOW);
592+ }
593+
594+
595+#ifdef MOSAIC_AVOID_BASED_ON_SPS_PPS_ID
596+ if ( CheckSpsId( pCtx, &pSubsetSps, &pSps, pPps->iSpsId, kExtensionFlag ) )
597+ {
598+ return dsNoParamSets;
599+ }
600+#else
601+ if ( kbExtensionFlag )
602+ {
603+ pSubsetSps = &pCtx->sSubsetSpsBuffer[pPps->iSpsId];
604+ pSps = &pSubsetSps->sSps;
605+ }
606+ else
607+ {
608+ pSps = &pCtx->sSpsBuffer[pPps->iSpsId];
609+ }
610+ pCtx->pSps = pSps;
611+#endif //MOSAIC_AVOID_BASED_ON_SPS_PPS_ID
612+ pSliceHead->iPpsId = iPpsId;
613+ pSliceHead->iSpsId = pPps->iSpsId;
614+ pSliceHead->pPps = pPps;
615+ pSliceHead->pSps = pSps;
616+
617+ pSliceHeadExt->pSubsetSps = pSubsetSps;
618+
619+ bIdrFlag = (!kbExtensionFlag && eNalType == NAL_UNIT_CODED_SLICE_IDR) || (kbExtensionFlag && pNalHeaderExt->bIdrFlag);
620+
621+ if(pSps->uiLog2MaxFrameNum == 0){
622+ WelsLog( pCtx, WELS_LOG_WARNING, "non existing SPS referenced\n");
623+ return GENERATE_ERROR_NO(ERR_LEVEL_SLICE_HEADER, ERR_INFO_NO_PARAM_SETS);
624+ }
625+ pSliceHead->iFrameNum = BsGetBits(pBs, pSps->uiLog2MaxFrameNum);
626+
627+ pSliceHead->bFieldPicFlag = false;
628+ pSliceHead->bBottomFiledFlag = false;
629+ if( !pSps->bFrameMbsOnlyFlag ){
630+ WelsLog( pCtx, WELS_LOG_WARNING, "ParseSliceHeaderSyntaxs(): frame_mbs_only_flag = %d not supported. \n", pSps->bFrameMbsOnlyFlag );
631+ return GENERATE_ERROR_NO(ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_MBAFF);
632+ }
633+ pSliceHead->iMbWidth = pSps->iMbWidth;
634+ pSliceHead->iMbHeight = pSps->iMbHeight / (1 + pSliceHead->bFieldPicFlag);
635+
636+ if ( bIdrFlag ){
637+ if ( pSliceHead->iFrameNum != 0 ){
638+ WelsLog( pCtx, WELS_LOG_WARNING, "ParseSliceHeaderSyntaxs(), invaild frame number: %d due to IDR frame introduced!\n", pSliceHead->iFrameNum);
639+ return GENERATE_ERROR_NO(ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_FRAME_NUM);
640+ }
641+ pSliceHead->uiIdrPicId = BsGetUe(pBs); /* uiIdrPicId */
642+#ifdef LONG_TERM_REF
643+ pCtx->uiCurIdrPicId = pSliceHead->uiIdrPicId;
644+#endif
645+ }
646+
647+ pSliceHead->iDeltaPicOrderCntBottom = 0;
648+ pSliceHead->iDeltaPicOrderCnt[0] =
649+ pSliceHead->iDeltaPicOrderCnt[1] = 0;
650+ if(pSps->uiPocType == 0){
651+ pSliceHead->iPicOrderCntLsb = BsGetBits(pBs, pSps->iLog2MaxPocLsb);
652+ if( pPps->bPicOrderPresentFlag && !pSliceHead->bFieldPicFlag ){
653+ pSliceHead->iDeltaPicOrderCntBottom = BsGetSe(pBs);
654+ }
655+ }
656+ else if(pSps->uiPocType == 1 && !pSps->bDeltaPicOrderAlwaysZeroFlag ){
657+ pSliceHead->iDeltaPicOrderCnt[0] = BsGetSe(pBs);
658+ if( pPps->bPicOrderPresentFlag && !pSliceHead->bFieldPicFlag )
659+ pSliceHead->iDeltaPicOrderCnt[1]= BsGetSe(pBs);
660+ }
661+
662+ pSliceHead->iRedundantPicCnt = 0;
663+ if( pPps->bRedundantPicCntPresentFlag ){
664+ pSliceHead->iRedundantPicCnt = BsGetUe(pBs);
665+ }
666+
667+ //set defaults, might be overriden a few line later
668+ pSliceHead->uiRefCount[0] = pPps->uiNumRefIdxL0Active;
669+ pSliceHead->uiRefCount[1] = pPps->uiNumRefIdxL1Active;
670+ if ( kbExtensionFlag ){
671+ uiQualityId = pNalHeaderExt->uiQualityId;
672+ if ( BASE_QUALITY_ID == uiQualityId && (EP_SLICE == uiSliceType || EB_SLICE == uiSliceType) ){
673+ const bool_t kbBipredFlag = (EB_SLICE == uiSliceType);
674+ if ( kbBipredFlag )
675+ {
676+ WelsLog ( pCtx, WELS_LOG_WARNING, "ParseSliceHeaderSyntaxs(): kbBipredFlag = 1 not supported.\n");
677+ return GENERATE_ERROR_NO(ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_BIPRED);
678+ }
679+ pSliceHead->bNumRefIdxActiveOverrideFlag = !!BsGetOneBit(pBs);
680+ if ( pSliceHead->bNumRefIdxActiveOverrideFlag ){
681+ pSliceHead->uiRefCount[0] = 1 + BsGetUe(pBs);
682+ }
683+ }
684+ }
685+ else if(uiSliceType == P_SLICE || uiSliceType == SP_SLICE || uiSliceType == B_SLICE){
686+ const bool_t kbBipredFlag = (B_SLICE == uiSliceType);
687+ if( kbBipredFlag ){
688+ WelsLog ( pCtx, WELS_LOG_WARNING, "ParseSliceHeaderSyntaxs(): kbBipredFlag = 1 not supported.\n");
689+ return GENERATE_ERROR_NO(ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_BIPRED);
690+ }
691+ pSliceHead->bNumRefIdxActiveOverrideFlag = !!BsGetOneBit(pBs);
692+ if( pSliceHead->bNumRefIdxActiveOverrideFlag ){
693+ pSliceHead->uiRefCount[0] = 1 + BsGetUe(pBs);
694+ }
695+ }
696+
697+ if( pSliceHead->uiRefCount[0] > MAX_REF_PIC_COUNT || pSliceHead->uiRefCount[1] > MAX_REF_PIC_COUNT){
698+ WelsLog( pCtx, WELS_LOG_WARNING, "reference overflow\n");
699+ return GENERATE_ERROR_NO(ERR_LEVEL_SLICE_HEADER, ERR_INFO_REF_COUNT_OVERFLOW);
700+ }
701+
702+ if ( BASE_QUALITY_ID == uiQualityId ){
703+ iRet = ParseRefPicListReordering(pBs, pSliceHead);
704+ if (iRet != ERR_NONE){
705+ WelsLog( pCtx, WELS_LOG_WARNING, "invalid ref pPic list reordering syntaxs!\n");
706+ return iRet;
707+ }
708+
709+ if ( kbExtensionFlag ){
710+ if ( pNalHeaderExt->iNoInterLayerPredFlag || pNalHeaderExt->uiQualityId > 0 )
711+ pSliceHeadExt->bBasePredWeightTableFlag = false;
712+ else
713+ pSliceHeadExt->bBasePredWeightTableFlag = true;
714+ }
715+
716+ if( kpCurNal->sNalHeaderExt.sNalUnitHeader.uiNalRefIdc != 0 ){
717+ iRet = ParseDecRefPicMarking(pCtx, pBs, pSliceHead, pSps, bIdrFlag );
718+ if (iRet != ERR_NONE){
719+ return iRet;
720+ }
721+
722+ if ( kbExtensionFlag && !pSubsetSps->sSpsSvcExt.bSliceHeaderRestrictionFlag ){
723+ pSliceHeadExt->bStoreRefBasePicFlag = !!BsGetOneBit(pBs);
724+ if ( (pNalHeaderExt->bUseRefBasePicFlag || pSliceHeadExt->bStoreRefBasePicFlag) && !bIdrFlag ){
725+ WelsLog( pCtx, WELS_LOG_WARNING, "ParseSliceHeaderSyntaxs(): bUseRefBasePicFlag or bStoreRefBasePicFlag = 1 not supported.\n" );
726+ return GENERATE_ERROR_NO(ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_ILP);
727+ }
728+ }
729+ }
730+ }
731+
732+ if ( pPps->bEntropyCodingModeFlag ){
733+ WelsLog( pCtx, WELS_LOG_WARNING, "ParseSliceHeaderSyntaxs(): CABAC in Enhancement layer not supported.\n" );
734+ return GENERATE_ERROR_NO(ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_CABAC_EL);
735+ }
736+
737+ pSliceHead->iSliceQpDelta = BsGetSe(pBs);
738+ pSliceHead->iSliceQp = pPps->iPicInitQp + pSliceHead->iSliceQpDelta;
739+ if( pSliceHead->iSliceQp < 0 || pSliceHead->iSliceQp > 51 ){
740+ WelsLog( pCtx, WELS_LOG_WARNING, "QP %d out of range\n", pSliceHead->iSliceQp);
741+ return GENERATE_ERROR_NO(ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_QP);
742+ }
743+
744+ //FIXME qscale / qp ... stuff
745+ if ( !kbExtensionFlag ){
746+ if( uiSliceType == SP_SLICE || uiSliceType == SI_SLICE )
747+ {
748+ WelsLog( pCtx, WELS_LOG_WARNING, "SP/SI not supported\n");
749+ return GENERATE_ERROR_NO(ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_SPSI);
750+ }
751+ }
752+
753+ pSliceHead->uiDisableDeblockingFilterIdc = 0;
754+ pSliceHead->iSliceAlphaC0Offset = 0;
755+ pSliceHead->iSliceBetaOffset = 0;
756+ if ( pPps->bDeblockingFilterControlPresentFlag ){
757+ pSliceHead->uiDisableDeblockingFilterIdc = BsGetUe(pBs);
758+ //refer to JVT-X201wcm1.doc G.7.4.3.4--2010.4.20
759+ if ( pSliceHead->uiDisableDeblockingFilterIdc > 6 )
760+ {
761+ WelsLog( pCtx, WELS_LOG_WARNING, "disable_deblock_filter_idc (%d) out of range [0, 6]\n", pSliceHead->uiDisableDeblockingFilterIdc );
762+ return ERR_INFO_INVALID_DBLOCKING_IDC;
763+ }
764+ if (pSliceHead->uiDisableDeblockingFilterIdc != 1){
765+ pSliceHead->iSliceAlphaC0Offset = BsGetSe(pBs) << 1; // slice_alpha_c0_offset_div2
766+ pSliceHead->iSliceBetaOffset = BsGetSe(pBs) << 1; // iSliceBetaOffset
767+ }
768+ }
769+
770+ bSgChangeCycleInvolved = (pPps->uiNumSliceGroups > 1 && pPps->uiSliceGroupMapType >= 3 && pPps->uiSliceGroupMapType <= 5);
771+ if ( kbExtensionFlag && bSgChangeCycleInvolved )
772+ bSgChangeCycleInvolved= (bSgChangeCycleInvolved && (uiQualityId == BASE_QUALITY_ID));
773+ if ( bSgChangeCycleInvolved ){
774+ if ( pPps->uiSliceGroupChangeRate > 0 ){
775+ const int32_t kiNumBits = (int32_t)WELS_CEIL(log(static_cast<double>(1 + pPps->uiPicSizeInMapUnits / pPps->uiSliceGroupChangeRate)));
776+ pSliceHead->iSliceGroupChangeCycle = BsGetBits(pBs, kiNumBits); // For FMO extra types
777+ }
778+ else
779+ pSliceHead->iSliceGroupChangeCycle = 0;
780+ }
781+
782+ if ( !kbExtensionFlag ){
783+ FillDefaultSliceHeaderExt ( pSliceHeadExt, pNalHeaderExt );
784+ }
785+ else{
786+ /* Extra syntax elements newly introduced */
787+ pSliceHeadExt->pSubsetSps = pSubsetSps;
788+
789+ if ( !pNalHeaderExt->iNoInterLayerPredFlag && BASE_QUALITY_ID == uiQualityId ){
790+ //the following should be deleted for CODE_CLEAN
791+ pSliceHeadExt->uiRefLayerDqId = BsGetUe(pBs);
792+ if ( pSubsetSps->sSpsSvcExt.bInterLayerDeblockingFilterCtrlPresentFlag )
793+ {
794+ pSliceHeadExt->uiDisableInterLayerDeblockingFilterIdc = BsGetUe(pBs);
795+ //refer to JVT-X201wcm1.doc G.7.4.3.4--2010.4.20
796+ if ( pSliceHeadExt->uiDisableInterLayerDeblockingFilterIdc > 6 )
797+ {
798+ WelsLog( pCtx, WELS_LOG_WARNING, "disable_inter_layer_deblock_filter_idc (%d) out of range [0, 6]\n", pSliceHeadExt->uiDisableInterLayerDeblockingFilterIdc );
799+ return ERR_INFO_INVALID_DBLOCKING_IDC;
800+ }
801+ if ( pSliceHeadExt->uiDisableInterLayerDeblockingFilterIdc != 1 ){
802+ pSliceHeadExt->iInterLayerSliceAlphaC0Offset = BsGetSe(pBs) << 1;
803+ pSliceHeadExt->iInterLayerSliceBetaOffset = BsGetSe(pBs) << 1;
804+ }
805+ }
806+
807+ pSliceHeadExt->uiRefLayerChromaPhaseXPlus1Flag = pSubsetSps->sSpsSvcExt.uiSeqRefLayerChromaPhaseXPlus1Flag;
808+ pSliceHeadExt->uiRefLayerChromaPhaseYPlus1 = pSubsetSps->sSpsSvcExt.uiSeqRefLayerChromaPhaseYPlus1;
809+
810+ pSliceHeadExt->bConstrainedIntraResamplingFlag = !!BsGetOneBit(pBs);
811+
812+ {
813+ SPosOffset pos;
814+ pos.iLeftOffset = pSubsetSps->sSpsSvcExt.sSeqScaledRefLayer.iLeftOffset;
815+ pos.iTopOffset = pSubsetSps->sSpsSvcExt.sSeqScaledRefLayer.iTopOffset * (2 - pSps->bFrameMbsOnlyFlag);
816+ pos.iRightOffset= pSubsetSps->sSpsSvcExt.sSeqScaledRefLayer.iRightOffset;
817+ pos.iBottomOffset=pSubsetSps->sSpsSvcExt.sSeqScaledRefLayer.iBottomOffset * (2 - pSps->bFrameMbsOnlyFlag);
818+ //memcpy(&pSliceHeadExt->sScaledRefLayer, &pos, sizeof(SPosOffset));//confirmed_safe_unsafe_usage
819+ pSliceHeadExt->iScaledRefLayerPicWidthInSampleLuma = (pSliceHead->iMbWidth << 4) - (pos.iLeftOffset+pos.iRightOffset);
820+ pSliceHeadExt->iScaledRefLayerPicHeightInSampleLuma = (pSliceHead->iMbHeight << 4) - (pos.iTopOffset+pos.iBottomOffset) / (1 + pSliceHead->bFieldPicFlag);
821+ }
822+ }
823+ else if (uiQualityId > BASE_QUALITY_ID){
824+ WelsLog( pCtx, WELS_LOG_WARNING, "MGS not supported.\n" );
825+ return GENERATE_ERROR_NO(ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_MGS);
826+ pSliceHeadExt->uiRefLayerDqId = pNalHeaderExt->uiLayerDqId - 1;
827+ }
828+ else{
829+ pSliceHeadExt->uiRefLayerDqId = (uint8_t)-1;
830+ }
831+
832+ pSliceHeadExt->bSliceSkipFlag = false;
833+ pSliceHeadExt->bAdaptiveBaseModeFlag = false;
834+ pSliceHeadExt->bDefaultBaseModeFlag = false;
835+ pSliceHeadExt->bAdaptiveMotionPredFlag = false;
836+ pSliceHeadExt->bDefaultMotionPredFlag = false;
837+ pSliceHeadExt->bAdaptiveResidualPredFlag = false;
838+ pSliceHeadExt->bDefaultResidualPredFlag = false;
839+ if ( pNalHeaderExt->iNoInterLayerPredFlag )
840+ pSliceHeadExt->bTCoeffLevelPredFlag = false;
841+ else
842+ pSliceHeadExt->bTCoeffLevelPredFlag = pSubsetSps->sSpsSvcExt.bSeqTCoeffLevelPredFlag;
843+
844+ if ( !pNalHeaderExt->iNoInterLayerPredFlag ){
845+ pSliceHeadExt->bSliceSkipFlag = !!BsGetOneBit(pBs);
846+ if ( pSliceHeadExt->bSliceSkipFlag ){
847+ pSliceHeadExt->uiNumMbsInSlice = 1 + BsGetUe(pBs);
848+ }
849+ else{
850+ pSliceHeadExt->bAdaptiveBaseModeFlag = !!BsGetOneBit(pBs);
851+ if ( !pSliceHeadExt->bAdaptiveBaseModeFlag ){
852+ pSliceHeadExt->bDefaultBaseModeFlag = !!BsGetOneBit(pBs);
853+ }
854+ if ( !pSliceHeadExt->bDefaultBaseModeFlag ){
855+ pSliceHeadExt->bAdaptiveMotionPredFlag = !!BsGetOneBit(pBs);
856+ if ( !pSliceHeadExt->bAdaptiveMotionPredFlag )
857+ pSliceHeadExt->bDefaultMotionPredFlag = !!BsGetOneBit(pBs);
858+ }
859+
860+ pSliceHeadExt->bAdaptiveResidualPredFlag = !!BsGetOneBit(pBs);
861+ if ( !pSliceHeadExt->bAdaptiveResidualPredFlag ){
862+ pSliceHeadExt->bDefaultResidualPredFlag = !!BsGetOneBit(pBs);
863+ }
864+ }
865+ if ( pSubsetSps->sSpsSvcExt.bAdaptiveTCoeffLevelPredFlag )
866+ pSliceHeadExt->bTCoeffLevelPredFlag = !!BsGetOneBit(pBs);
867+ }
868+
869+ if ( !pSubsetSps->sSpsSvcExt.bSliceHeaderRestrictionFlag )
870+ {
871+ pSliceHeadExt->uiScanIdxStart = BsGetBits(pBs, 4);
872+ pSliceHeadExt->uiScanIdxEnd = BsGetBits(pBs, 4);
873+ if( pSliceHeadExt->uiScanIdxStart != 0 || pSliceHeadExt->uiScanIdxEnd != 15 )
874+ {
875+ WelsLog( pCtx, WELS_LOG_WARNING, "uiScanIdxStart (%d) != 0 and uiScanIdxEnd (%d) !=15 not supported here\n", pSliceHeadExt->uiScanIdxStart, pSliceHeadExt->uiScanIdxEnd );
876+ return GENERATE_ERROR_NO(ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_MGS);
877+ }
878+ }
879+ else{
880+ pSliceHeadExt->uiScanIdxStart = 0;
881+ pSliceHeadExt->uiScanIdxEnd = 15;
882+ }
883+ }
884+
885+ return ERR_NONE;
886+}
887+
888+/*
889+ * Copy relative syntax elements of NALUnitHeaderExt, sRefPicBaseMarking and bStoreRefBasePicFlag in prefix nal unit.
890+ * pSrc: mark as decoded prefix NAL
891+ * ppDst: succeeded VCL NAL based AVC (I/P Slice)
892+ */
893+bool_t PrefetchNalHeaderExtSyntax ( PWelsDecoderContext pCtx, PNalUnit const kppDst, PNalUnit const kpSrc)
894+{
895+ PNalUnitHeaderExt pNalHdrExtD = NULL, pNalHdrExtS = NULL;
896+ PSliceHeaderExt pShExtD = NULL;
897+ PPrefixNalUnit pPrefixS = NULL;
898+ PSps pSps = NULL;
899+ int32_t iIdx = 0;
900+
901+ if ( kppDst == NULL || kpSrc == NULL )
902+ return false;
903+
904+ pNalHdrExtD = &kppDst->sNalHeaderExt;
905+ pNalHdrExtS = &kpSrc->sNalHeaderExt;
906+ pShExtD = &kppDst->sNalData.sVclNal.sSliceHeaderExt;
907+ pPrefixS = &kpSrc->sNalData.sPrefixNal;
908+ pSps = &pCtx->sSpsBuffer[pCtx->sPpsBuffer[pShExtD->sSliceHeader.iPpsId].iSpsId];
909+
910+ pNalHdrExtD->uiDependencyId = pNalHdrExtS->uiDependencyId;
911+ pNalHdrExtD->uiQualityId = pNalHdrExtS->uiQualityId;
912+ pNalHdrExtD->uiTemporalId = pNalHdrExtS->uiTemporalId;
913+ pNalHdrExtD->uiPriorityId = pNalHdrExtS->uiPriorityId;
914+ pNalHdrExtD->bIdrFlag = pNalHdrExtS->bIdrFlag;
915+ pNalHdrExtD->iNoInterLayerPredFlag = pNalHdrExtS->iNoInterLayerPredFlag;
916+ pNalHdrExtD->bDiscardableFlag = pNalHdrExtS->bDiscardableFlag;
917+ pNalHdrExtD->bOutputFlag = pNalHdrExtS->bOutputFlag;
918+ pNalHdrExtD->bUseRefBasePicFlag = pNalHdrExtS->bUseRefBasePicFlag;
919+ pNalHdrExtD->uiLayerDqId = pNalHdrExtS->uiLayerDqId;
920+
921+ pShExtD->bStoreRefBasePicFlag = pPrefixS->bStoreRefBasePicFlag;
922+ memcpy(&pShExtD->sRefBasePicMarking, &pPrefixS->sRefPicBaseMarking, sizeof(SRefBasePicMarking));//confirmed_safe_unsafe_usage
923+ if (pShExtD->sRefBasePicMarking.bAdaptiveRefBasePicMarkingModeFlag){
924+ PRefBasePicMarking pRefBasePicMarking = &pShExtD->sRefBasePicMarking;
925+ iIdx = 0;
926+ do {
927+ if (pRefBasePicMarking->mmco_base[iIdx].uiMmcoType == MMCO_END)
928+ break;
929+ if (pRefBasePicMarking->mmco_base[iIdx].uiMmcoType == MMCO_SHORT2UNUSED)
930+ pRefBasePicMarking->mmco_base[iIdx].iShortFrameNum = (pShExtD->sSliceHeader.iFrameNum-pRefBasePicMarking->mmco_base[iIdx].uiDiffOfPicNums) & ((1<<pSps->uiLog2MaxFrameNum)-1);
931+ ++ iIdx;
932+ } while(iIdx < MAX_MMCO_COUNT);
933+ }
934+
935+ return true;
936+}
937+
938+
939+
940+int32_t UpdateAccessUnit ( PWelsDecoderContext pCtx )
941+{
942+ PAccessUnit pCurAu = pCtx->pAccessUnitList;
943+ int32_t iIdx = pCurAu->uiEndPos;
944+
945+ // Conversed iterator
946+ pCtx->uiTargetDqId = pCurAu->pNalUnitsList[iIdx]->sNalHeaderExt.uiLayerDqId;
947+ pCurAu->uiActualUnitsNum = iIdx + 1;
948+ pCurAu->bCompletedAuFlag = true;
949+
950+ // Added for mosaic avoidance, 11/19/2009
951+#ifdef LONG_TERM_REF
952+ if ( pCtx->bParamSetsLostFlag )
953+#else
954+ if ( pCtx->bReferenceLostAtT0Flag )
955+#endif
956+ {
957+ uint32_t uiActualIdx = 0;
958+ while ( uiActualIdx < pCurAu->uiActualUnitsNum ) {
959+ PNalUnit nal = pCurAu->pNalUnitsList[uiActualIdx];
960+
961+ if ( nal->sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR || nal->sNalHeaderExt.bIdrFlag )
962+ {
963+ break;
964+ }
965+ ++ uiActualIdx;
966+ }
967+ if ( uiActualIdx == pCurAu->uiActualUnitsNum ) // no found IDR nal within incoming AU, need exit to avoid mosaic issue, 11/19/2009
968+ {
969+ WelsLog( pCtx, WELS_LOG_WARNING, "UpdateAccessUnit():::::Key frame lost.....CAN NOT find IDR from current AU.\n" );
970+#ifdef LONG_TERM_REF
971+ pCtx->iErrorCode |= dsNoParamSets;
972+ return dsNoParamSets;
973+#else
974+ pCtx->iErrorCode |= dsRefLost;
975+ return ERR_INFO_REFERENCE_PIC_LOST;
976+#endif
977+ }
978+ }
979+
980+ return ERR_NONE;
981+}
982+
983+int32_t InitialDqLayersContext ( PWelsDecoderContext pCtx, const int32_t kiMaxWidth, const int32_t kiMaxHeight )
984+{
985+ const int32_t kiPicStride = ((kiMaxWidth + 15) & 0xfffff0) + (PADDING_LENGTH<<1);
986+ const int32_t kiPicLines = ((kiMaxHeight + 15) & 0xfffff0);
987+
988+ int32_t i = 0;
989+
990+ WELS_VERIFY_RETURN_IF( ERR_INFO_INVALID_PARAM, ( NULL == pCtx || kiMaxWidth <= 0 || kiMaxHeight <= 0 ) )
991+ pCtx->sMb.iMbWidth = (kiMaxWidth + 15) >> 4;
992+ pCtx->sMb.iMbHeight = (kiMaxHeight + 15) >> 4;
993+
994+ if ( pCtx->bInitialDqLayersMem && kiMaxWidth <= pCtx->iPicWidthReq && kiMaxHeight <= pCtx->iPicHeightReq ) // have same dimension memory, skipped
995+ return ERR_NONE;
996+
997+
998+ UninitialDqLayersContext( pCtx );
999+
1000+ do {
1001+ PDqLayer pDq = (PDqLayer )WelsMalloc(sizeof(SDqLayer), "PDqLayer");
1002+
1003+ int32_t iPlaneIdx = 0;
1004+
1005+ if ( pDq == NULL )
1006+ return ERR_INFO_OUT_OF_MEMORY;
1007+
1008+ memset(pDq, 0, sizeof(SDqLayer));
1009+ if(pCtx->iDecoderMode == SW_MODE)
1010+ {
1011+
1012+ do {
1013+ const int32_t kiHshift = iPlaneIdx ? 1 : 0;
1014+ const int32_t kiVshift = kiHshift;
1015+ const int32_t kiStride = WELS_ALIGN( (kiPicStride >> kiHshift), (16 << (1-kiHshift)) );
1016+ const int32_t kiLine = (kiPicLines + (PADDING_LENGTH<<1)) >> kiVshift;
1017+ const int32_t kiSize = kiStride * kiLine;
1018+
1019+ pCtx->pCsListXchg[i][iPlaneIdx] = (uint8_t *)WelsMalloc( kiSize * sizeof(uint8_t), "pCtx->pCsListXchg[][]" );
1020+
1021+ WELS_VERIFY_RETURN_IF( ERR_INFO_OUT_OF_MEMORY, (NULL == pCtx->pCsListXchg[i][iPlaneIdx]) )
1022+ pCtx->iCsStride[iPlaneIdx] = kiStride;
1023+
1024+
1025+ pCtx->pRsListXchg[i][iPlaneIdx] = (int16_t *)WelsMalloc( kiSize * sizeof(int16_t), "pCtx->pRsListXchg[][]" );
1026+
1027+ WELS_VERIFY_RETURN_IF( ERR_INFO_OUT_OF_MEMORY , (NULL == pCtx->pRsListXchg[i][iPlaneIdx]) )
1028+ pCtx->iRsStride[iPlaneIdx] = kiStride;
1029+
1030+ ++ iPlaneIdx;
1031+ } while(iPlaneIdx < 3);
1032+
1033+
1034+ pCtx->sMb.pMbType[i] = (int8_t *)WelsMalloc( pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight *sizeof(int8_t), "pCtx->sMb.pMbType[]" );
1035+ pCtx->sMb.pMv[i][0] = (int16_t (*)[16][2])WelsMalloc( pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof(int16_t) * MV_A * MB_BLOCK4x4_NUM, "pCtx->sMb.pMv[][]");
1036+ pCtx->sMb.pRefIndex[i][0] = (int8_t (*)[MB_BLOCK4x4_NUM])WelsMalloc( pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof(int8_t) * MB_BLOCK4x4_NUM, "pCtx->sMb.pRefIndex[][]");
1037+ pCtx->sMb.pLumaQp[i] = (int8_t *)WelsMalloc( pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof(int8_t), "pCtx->sMb.pLumaQp[]");
1038+ pCtx->sMb.pChromaQp[i] = (int8_t *)WelsMalloc(pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof(int8_t), "pCtx->sMb.pChromaQp[]");
1039+ pCtx->sMb.pNzc[i] = (int8_t (*)[24])WelsMalloc(pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof(int8_t) * 24, "pCtx->sMb.pNzc[]");
1040+ pCtx->sMb.pNzcRs[i] = (int8_t (*)[24])WelsMalloc(pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof(int8_t) * 24, "pCtx->sMb.pNzcRs[]");
1041+ pCtx->sMb.pScaledTCoeff[i] = (int16_t (*)[MB_COEFF_LIST_SIZE])WelsMalloc(pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof(int16_t) * MB_COEFF_LIST_SIZE, "pCtx->sMb.pScaledTCoeff[]");
1042+ pCtx->sMb.pIntraPredMode[i] = (int8_t (*)[8])WelsMalloc(pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof(int8_t) * 8, "pCtx->sMb.pIntraPredMode[]");
1043+ pCtx->sMb.pIntra4x4FinalMode[i] = (int8_t (*)[MB_BLOCK4x4_NUM])WelsMalloc(pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof(int8_t) * MB_BLOCK4x4_NUM, "pCtx->sMb.pIntra4x4FinalMode[]");
1044+ pCtx->sMb.pChromaPredMode[i] = (int8_t *)WelsMalloc(pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof(int8_t), "pCtx->sMb.pChromaPredMode[]");
1045+ pCtx->sMb.pCbp[i] = (int8_t *)WelsMalloc(pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight *sizeof(int8_t), "pCtx->sMb.pCbp[]");
1046+ pCtx->sMb.pSubMbType[i] = (int8_t (*)[MB_PARTITION_SIZE])WelsMalloc(pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof(int8_t) * MB_PARTITION_SIZE, "pCtx->sMb.pSubMbType[]");
1047+ pCtx->sMb.pSliceIdc[i] = (int32_t *) WelsMalloc(pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof(int32_t), "pCtx->sMb.pSliceIdc[]"); // using int32_t for slice_idc, 4/21/2010
1048+ if ( pCtx->sMb.pSliceIdc[i] != NULL )
1049+ memset(pCtx->sMb.pSliceIdc[i], 0xff, (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof(int32_t)) );
1050+ pCtx->sMb.pResidualPredFlag[i] = (int8_t *) WelsMalloc(pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof(int8_t), "pCtx->sMb.pResidualPredFlag[]");
1051+ //pCtx->sMb.pMotionPredFlag[i] = (uint8_t *) WelsMalloc(pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof(uint8_t), "pCtx->sMb.pMotionPredFlag[]");
1052+ pCtx->sMb.pInterPredictionDoneFlag[i] = (int8_t *) WelsMalloc(pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof(int8_t), "pCtx->sMb.pInterPredictionDoneFlag[]");
1053+
1054+ // check memory block valid due above allocated..
1055+ WELS_VERIFY_RETURN_IF ( ERR_INFO_OUT_OF_MEMORY,
1056+ ( (NULL == pCtx->sMb.pMbType[i]) ||
1057+ (NULL == pCtx->sMb.pMv[i][0]) ||
1058+ (NULL == pCtx->sMb.pRefIndex[i][0]) ||
1059+ (NULL == pCtx->sMb.pLumaQp[i]) ||
1060+ (NULL == pCtx->sMb.pChromaQp[i]) ||
1061+ (NULL == pCtx->sMb.pNzc[i]) ||
1062+ (NULL == pCtx->sMb.pNzcRs[i]) ||
1063+ (NULL == pCtx->sMb.pScaledTCoeff[i]) ||
1064+ (NULL == pCtx->sMb.pIntraPredMode[i]) ||
1065+ (NULL == pCtx->sMb.pIntra4x4FinalMode[i]) ||
1066+ (NULL == pCtx->sMb.pChromaPredMode[i]) ||
1067+ (NULL == pCtx->sMb.pCbp[i]) ||
1068+ (NULL == pCtx->sMb.pSubMbType[i]) ||
1069+ (NULL == pCtx->sMb.pSliceIdc[i]) ||
1070+ (NULL == pCtx->sMb.pResidualPredFlag[i]) ||
1071+ (NULL == pCtx->sMb.pInterPredictionDoneFlag[i])
1072+ )
1073+ )
1074+ } // end of if(pCtx->iDecoderMode == SW_MODE)
1075+
1076+ pCtx->pDqLayersList[i] = pDq;
1077+ ++ i;
1078+ } while( i < LAYER_NUM_EXCHANGEABLE );
1079+
1080+
1081+ pCtx->bInitialDqLayersMem = true;
1082+ pCtx->iPicWidthReq = kiMaxWidth;
1083+ pCtx->iPicHeightReq = kiMaxHeight;
1084+
1085+ return ERR_NONE;
1086+}
1087+
1088+void_t UninitialDqLayersContext ( PWelsDecoderContext pCtx )
1089+{
1090+ int32_t i = 0;
1091+ int32_t j = 0;
1092+
1093+ do {
1094+ PDqLayer pDq = pCtx->pDqLayersList[i];
1095+ if ( pDq == NULL ){
1096+ ++ i;
1097+ continue;
1098+ }
1099+
1100+ if ( pCtx->pCsListXchg[i] ){ // cs picture
1101+ j = 0;
1102+ do {
1103+ if ( NULL != pCtx->pCsListXchg[i][j] )
1104+ {
1105+ WelsFree( pCtx->pCsListXchg[i][j], "pCtx->pCsListXchg[][]" );
1106+
1107+ pCtx->pCsListXchg[i][j] = NULL;
1108+ }
1109+ pCtx->iCsStride[j] = 0;
1110+ ++ j;
1111+ } while( j < 3 );
1112+
1113+ pDq->pCsData[i] = NULL; // for safe
1114+ pDq->iCsStride[i] = 0;
1115+ }
1116+ if ( pCtx->pRsListXchg[i] ){
1117+ j = 0;
1118+ do {
1119+ if ( NULL != pCtx->pRsListXchg[i][j] )
1120+ {
1121+ WelsFree( pCtx->pRsListXchg[i][j], "pCtx->pRsListXchg[][]" );
1122+
1123+ pCtx->pRsListXchg[i][j] = NULL;
1124+ }
1125+ pCtx->iRsStride[j] = 0;
1126+ ++ j;
1127+ } while(j < 3);
1128+ }
1129+
1130+ if (pCtx->sMb.pMbType[i])
1131+ {
1132+ WelsFree( pCtx->sMb.pMbType[i], "pCtx->sMb.pMbType[]");
1133+
1134+ pCtx->sMb.pMbType[i] = NULL;
1135+ }
1136+
1137+ if (pCtx->sMb.pMv[i][0])
1138+ {
1139+ WelsFree( pCtx->sMb.pMv[i][0], "pCtx->sMb.pMv[][]" );
1140+
1141+ pCtx->sMb.pMv[i][0] = NULL;
1142+ }
1143+
1144+ if (pCtx->sMb.pRefIndex[i][0])
1145+ {
1146+ WelsFree( pCtx->sMb.pRefIndex[i][0], "pCtx->sMb.pRefIndex[][]" );
1147+
1148+ pCtx->sMb.pRefIndex[i][0] = NULL;
1149+ }
1150+
1151+ if (pCtx->sMb.pLumaQp[i])
1152+ {
1153+ WelsFree(pCtx->sMb.pLumaQp[i], "pCtx->sMb.pLumaQp[]");
1154+
1155+ pCtx->sMb.pLumaQp[i] = NULL;
1156+ }
1157+
1158+ if (pCtx->sMb.pChromaQp[i])
1159+ {
1160+ WelsFree(pCtx->sMb.pChromaQp[i], "pCtx->sMb.pChromaQp[]");
1161+
1162+ pCtx->sMb.pChromaQp[i] = NULL;
1163+ }
1164+
1165+ if (pCtx->sMb.pNzc[i])
1166+ {
1167+ WelsFree(pCtx->sMb.pNzc[i], "pCtx->sMb.pNzc[]");
1168+
1169+ pCtx->sMb.pNzc[i] = NULL;
1170+ }
1171+
1172+ if (pCtx->sMb.pNzcRs[i])
1173+ {
1174+ WelsFree(pCtx->sMb.pNzcRs[i], "pCtx->sMb.pNzcRs[]");
1175+
1176+ pCtx->sMb.pNzcRs[i] = NULL;
1177+ }
1178+
1179+ if (pCtx->sMb.pScaledTCoeff[i])
1180+ {
1181+ WelsFree(pCtx->sMb.pScaledTCoeff[i], "pCtx->sMb.pScaledTCoeff[]");
1182+
1183+ pCtx->sMb.pScaledTCoeff[i] = NULL;
1184+ }
1185+
1186+ if (pCtx->sMb.pIntraPredMode[i])
1187+ {
1188+ WelsFree(pCtx->sMb.pIntraPredMode[i], "pCtx->sMb.pIntraPredMode[]");
1189+
1190+ pCtx->sMb.pIntraPredMode[i] = NULL;
1191+ }
1192+
1193+ if (pCtx->sMb.pIntra4x4FinalMode[i])
1194+ {
1195+ WelsFree(pCtx->sMb.pIntra4x4FinalMode[i], "pCtx->sMb.pIntra4x4FinalMode[]");
1196+
1197+ pCtx->sMb.pIntra4x4FinalMode[i] = NULL;
1198+ }
1199+
1200+ if (pCtx->sMb.pChromaPredMode[i])
1201+ {
1202+ WelsFree(pCtx->sMb.pChromaPredMode[i], "pCtx->sMb.pChromaPredMode[]");
1203+
1204+ pCtx->sMb.pChromaPredMode[i] = NULL;
1205+ }
1206+
1207+ if (pCtx->sMb.pCbp[i])
1208+ {
1209+ WelsFree( pCtx->sMb.pCbp[i], "pCtx->sMb.pCbp[]" );
1210+
1211+ pCtx->sMb.pCbp[i] = NULL;
1212+ }
1213+
1214+ // if (pCtx->sMb.pMotionPredFlag[i])
1215+ //{
1216+ // WelsFree( pCtx->sMb.pMotionPredFlag[i], "pCtx->sMb.pMotionPredFlag[]" );
1217+
1218+ // pCtx->sMb.pMotionPredFlag[i] = NULL;
1219+ //}
1220+
1221+ if (pCtx->sMb.pSubMbType[i])
1222+ {
1223+ WelsFree(pCtx->sMb.pSubMbType[i], "pCtx->sMb.pSubMbType[]");
1224+
1225+ pCtx->sMb.pSubMbType[i] = NULL;
1226+ }
1227+
1228+ if (pCtx->sMb.pSliceIdc[i])
1229+ {
1230+ WelsFree( pCtx->sMb.pSliceIdc[i], "pCtx->sMb.pSliceIdc[]" );
1231+
1232+ pCtx->sMb.pSliceIdc[i] = NULL;
1233+ }
1234+
1235+ if (pCtx->sMb.pResidualPredFlag[i])
1236+ {
1237+ WelsFree( pCtx->sMb.pResidualPredFlag[i], "pCtx->sMb.pResidualPredFlag[]" );
1238+
1239+ pCtx->sMb.pResidualPredFlag[i] = NULL;
1240+ }
1241+
1242+ if (pCtx->sMb.pInterPredictionDoneFlag[i])
1243+ {
1244+ WelsFree( pCtx->sMb.pInterPredictionDoneFlag[i], "pCtx->sMb.pInterPredictionDoneFlag[]" );
1245+
1246+ pCtx->sMb.pInterPredictionDoneFlag[i] = NULL;
1247+ }
1248+ WelsFree( pDq, "pDq" );
1249+
1250+ pDq = NULL;
1251+ pCtx->pDqLayersList[i] = NULL;
1252+
1253+ ++ i;
1254+ } while( i < LAYER_NUM_EXCHANGEABLE );
1255+
1256+ pCtx->iPicWidthReq = 0;
1257+ pCtx->iPicHeightReq = 0;
1258+ pCtx->bInitialDqLayersMem = false;
1259+}
1260+
1261+void_t ResetCurrentAccessUnit ( PWelsDecoderContext pCtx )
1262+{
1263+ PAccessUnit pCurAu = pCtx->pAccessUnitList;
1264+
1265+ pCurAu->uiEndPos = 0;
1266+ pCurAu->bCompletedAuFlag = false;
1267+ if (pCurAu->uiActualUnitsNum > 0){
1268+ uint32_t iIdx = 0;
1269+ const uint32_t kuiActualNum = pCurAu->uiActualUnitsNum;
1270+ // a more simpler method to do nal units list management prefered here
1271+ const uint32_t kuiAvailNum = pCurAu->uiAvailUnitsNum;
1272+ const uint32_t kuiLeftNum = kuiAvailNum - kuiActualNum;
1273+
1274+ // Swapping active nal unit nodes of succeeding AU with leading of list
1275+ while (iIdx < kuiLeftNum)
1276+ {
1277+ PNalUnit t = pCurAu->pNalUnitsList[kuiActualNum+iIdx];
1278+ pCurAu->pNalUnitsList[kuiActualNum+iIdx] = pCurAu->pNalUnitsList[iIdx];
1279+ pCurAu->pNalUnitsList[iIdx] = t;
1280+ ++ iIdx;
1281+ }
1282+ pCurAu->uiActualUnitsNum = pCurAu->uiAvailUnitsNum = kuiLeftNum;
1283+ }
1284+}
1285+
1286+/*!
1287+ * \brief Force reset current Acess Unit Nal list in case error parsing/decoding in current AU
1288+ * \author
1289+ * \history 11/16/2009
1290+ */
1291+void_t ForceResetCurrentAccessUnit( PAccessUnit pAu )
1292+{
1293+ uint32_t uiSucAuIdx = pAu->uiEndPos + 1;
1294+ uint32_t uiCurAuIdx = 0;
1295+
1296+ // swap the succeeding AU's nal units to the front
1297+ while(uiSucAuIdx < pAu->uiAvailUnitsNum)
1298+ {
1299+ PNalUnit t = pAu->pNalUnitsList[uiSucAuIdx];
1300+ pAu->pNalUnitsList[uiSucAuIdx] = pAu->pNalUnitsList[uiCurAuIdx];
1301+ pAu->pNalUnitsList[uiCurAuIdx] = t;
1302+ ++ uiSucAuIdx;
1303+ ++ uiCurAuIdx;
1304+ }
1305+
1306+ // Update avail/actual units num accordingly for next AU parsing
1307+ if ( pAu->uiAvailUnitsNum > pAu->uiEndPos )
1308+ pAu->uiAvailUnitsNum -= (pAu->uiEndPos+1);
1309+ else
1310+ pAu->uiAvailUnitsNum = 0;
1311+ pAu->uiActualUnitsNum = 0;
1312+ pAu->uiEndPos = 0;
1313+ pAu->bCompletedAuFlag = false;
1314+}
1315+
1316+//clear current corrupted NAL from pNalUnitsList
1317+void_t ForceClearCurrentNal( PAccessUnit pAu )
1318+{
1319+ if (pAu->uiAvailUnitsNum > 0)
1320+ -- pAu->uiAvailUnitsNum;
1321+}
1322+
1323+
1324+void_t CheckAvailNalUnitsListContinuity( PWelsDecoderContext pCtx, int32_t iStartIdx, int32_t iEndIdx )
1325+{
1326+ PAccessUnit pCurAu = pCtx->pAccessUnitList;
1327+
1328+ uint8_t uiLastNuDependencyId, uiLastNuLayerDqId;
1329+ uint8_t uiCurNuDependencyId, uiCurNuQualityId, uiCurNuLayerDqId, uiCurNuRefLayerDqId;
1330+
1331+ int32_t iCurNalUnitIdx = 0;
1332+
1333+ //check the continuity of pNalUnitsList forwards (from pIdxNoInterLayerPred to end_postion)
1334+ uiLastNuDependencyId = pCurAu->pNalUnitsList[iStartIdx]->sNalHeaderExt.uiDependencyId;//starting nal unit
1335+ uiLastNuLayerDqId = pCurAu->pNalUnitsList[iStartIdx]->sNalHeaderExt.uiLayerDqId;//starting nal unit
1336+ iCurNalUnitIdx = iStartIdx + 1;//current nal unit
1337+ while ( iCurNalUnitIdx <= iEndIdx )
1338+ {
1339+ uiCurNuDependencyId = pCurAu->pNalUnitsList[iCurNalUnitIdx]->sNalHeaderExt.uiDependencyId;
1340+ uiCurNuQualityId = pCurAu->pNalUnitsList[iCurNalUnitIdx]->sNalHeaderExt.uiQualityId;
1341+ uiCurNuLayerDqId = pCurAu->pNalUnitsList[iCurNalUnitIdx]->sNalHeaderExt.uiLayerDqId;
1342+ uiCurNuRefLayerDqId = pCurAu->pNalUnitsList[iCurNalUnitIdx]->sNalData.sVclNal.sSliceHeaderExt.uiRefLayerDqId;
1343+
1344+ if ( uiCurNuDependencyId == uiLastNuDependencyId )
1345+ {
1346+ uiLastNuLayerDqId = uiCurNuLayerDqId;
1347+ ++ iCurNalUnitIdx;
1348+ }
1349+ else //uiCurNuDependencyId != uiLastNuDependencyId, new dependency arrive
1350+ {
1351+ if ( uiCurNuQualityId == 0 )
1352+ {
1353+ uiLastNuDependencyId = uiCurNuDependencyId;
1354+ if ( uiCurNuRefLayerDqId == uiLastNuLayerDqId )
1355+ {
1356+ uiLastNuLayerDqId = uiCurNuLayerDqId;
1357+ ++ iCurNalUnitIdx;
1358+ }
1359+ else //cur_nu_layer_id != next_nu_ref_layer_dq_id, the chain is broken at this point
1360+ {
1361+ break;
1362+ }
1363+ }
1364+ else //new dependency arrive, but no base quality layer, so we must stop in this point
1365+ {
1366+ break;
1367+ }
1368+ }
1369+ }
1370+
1371+ -- iCurNalUnitIdx;
1372+ pCurAu->uiEndPos = iCurNalUnitIdx;
1373+ pCtx->uiTargetDqId = pCurAu->pNalUnitsList[iCurNalUnitIdx]->sNalHeaderExt.uiLayerDqId;
1374+}
1375+
1376+//main purpose: to support multi-slice and to include all slice which have the same uiDependencyId, uiQualityId and frame_num
1377+//for single slice, pIdxNoInterLayerPred SHOULD NOT be modified
1378+void_t RefineIdxNoInterLayerPred( PAccessUnit pCurAu, int32_t* pIdxNoInterLayerPred )
1379+{
1380+ int32_t iLastNalDependId = pCurAu->pNalUnitsList[*pIdxNoInterLayerPred]->sNalHeaderExt.uiDependencyId;
1381+ int32_t iLastNalQualityId = pCurAu->pNalUnitsList[*pIdxNoInterLayerPred]->sNalHeaderExt.uiQualityId;
1382+ uint8_t uiLastNalTId = pCurAu->pNalUnitsList[*pIdxNoInterLayerPred]->sNalHeaderExt.uiTemporalId;
1383+ int32_t iLastNalFrameNum = pCurAu->pNalUnitsList[*pIdxNoInterLayerPred]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iFrameNum;
1384+ int32_t iLastNalPoc = pCurAu->pNalUnitsList[*pIdxNoInterLayerPred]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iPicOrderCntLsb;
1385+ int32_t iLastNalFirstMb = pCurAu->pNalUnitsList[*pIdxNoInterLayerPred]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iFirstMbInSlice;
1386+ int32_t iCurNalDependId, iCurNalQualityId, iCurNalTId, iCurNalFrameNum, iCurNalPoc, iCurNalFirstMb, iCurIdx, iFinalIdxNoInterLayerPred;
1387+
1388+ bool_t bMultiSliceFind = false;
1389+
1390+ iFinalIdxNoInterLayerPred = 0;
1391+ iCurIdx = *pIdxNoInterLayerPred - 1;
1392+ while ( iCurIdx >= 0 )
1393+ {
1394+ if ( pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.iNoInterLayerPredFlag )
1395+ {
1396+ iCurNalDependId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiDependencyId;
1397+ iCurNalQualityId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiQualityId;
1398+ iCurNalTId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiTemporalId;
1399+ iCurNalFrameNum = pCurAu->pNalUnitsList[iCurIdx]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iFrameNum;
1400+ iCurNalPoc = pCurAu->pNalUnitsList[iCurIdx]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iPicOrderCntLsb;
1401+ iCurNalFirstMb = pCurAu->pNalUnitsList[iCurIdx]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iFirstMbInSlice;
1402+
1403+ if ( iCurNalDependId == iLastNalDependId &&
1404+ iCurNalQualityId == iLastNalQualityId &&
1405+ iCurNalTId == uiLastNalTId &&
1406+ iCurNalFrameNum == iLastNalFrameNum &&
1407+ iCurNalPoc == iLastNalPoc &&
1408+ iCurNalFirstMb != iLastNalFirstMb )
1409+ {
1410+ bMultiSliceFind = true;
1411+ iFinalIdxNoInterLayerPred = iCurIdx;
1412+ --iCurIdx;
1413+ continue;
1414+ }
1415+ else
1416+ {
1417+ break;
1418+ }
1419+ }
1420+ --iCurIdx;
1421+ }
1422+
1423+ if ( bMultiSliceFind && *pIdxNoInterLayerPred != iFinalIdxNoInterLayerPred )
1424+ {
1425+ *pIdxNoInterLayerPred = iFinalIdxNoInterLayerPred;
1426+ }
1427+}
1428+
1429+bool_t CheckPocOfCurValidNalUnits( PAccessUnit pCurAu, int32_t pIdxNoInterLayerPred )
1430+{
1431+ int32_t iEndIdx = pCurAu->uiEndPos;
1432+ int32_t iCurAuPoc = pCurAu->pNalUnitsList[pIdxNoInterLayerPred]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iPicOrderCntLsb;
1433+ int32_t iTmpPoc, i;
1434+ for ( i = pIdxNoInterLayerPred+1; i < iEndIdx; i++ )
1435+ {
1436+ iTmpPoc = pCurAu->pNalUnitsList[i]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iPicOrderCntLsb;
1437+ if ( iTmpPoc != iCurAuPoc )
1438+ {
1439+ return false;
1440+ }
1441+ }
1442+
1443+ return true;
1444+}
1445+
1446+bool_t CheckIntegrityNalUnitsList( PWelsDecoderContext pCtx )
1447+{
1448+ PAccessUnit pCurAu = pCtx->pAccessUnitList;
1449+ const int32_t kiEndPos = pCurAu->uiEndPos;
1450+ int32_t iIdxNoInterLayerPred = 0;
1451+ int32_t iCurNalUnitIdx = kiEndPos;
1452+
1453+ ESliceType eSliceType = static_cast<ESliceType> (0);//EC 2009.11.12
1454+
1455+ if ( !pCurAu->bCompletedAuFlag )
1456+ return false;
1457+
1458+ eSliceType = pCurAu->pNalUnitsList[iCurNalUnitIdx]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.eSliceType;
1459+
1460+ if ( I_SLICE == eSliceType )
1461+ {
1462+ pCurAu->uiStartPos = 0;
1463+ //step1: search the pNalUnit whose iNoInterLayerPredFlag equal to 1 backwards (from uiEndPos to 0)
1464+ iIdxNoInterLayerPred = kiEndPos;
1465+ while ( iIdxNoInterLayerPred >= 0 )
1466+ {
1467+ if ( pCurAu->pNalUnitsList[iIdxNoInterLayerPred]->sNalHeaderExt.iNoInterLayerPredFlag )
1468+ {
1469+ break;
1470+ }
1471+ --iIdxNoInterLayerPred;
1472+ }
1473+ if ( iIdxNoInterLayerPred < 0 )
1474+ {
1475+ //can not find the Nal Unit whose no_inter_pred_falg equal to 1, MUST STOP decode
1476+ return false;
1477+ }
1478+
1479+ //step2: support multi-slice, to include all base layer slice
1480+ RefineIdxNoInterLayerPred( pCurAu, &iIdxNoInterLayerPred );
1481+ pCurAu->uiStartPos = iIdxNoInterLayerPred;
1482+ CheckAvailNalUnitsListContinuity( pCtx, iIdxNoInterLayerPred, kiEndPos );
1483+
1484+ if ( !CheckPocOfCurValidNalUnits( pCurAu, iIdxNoInterLayerPred ) )
1485+ {
1486+ return false;
1487+ }
1488+
1489+ pCtx->iCurSeqIntervalTargetDependId = pCurAu->pNalUnitsList[pCurAu->uiEndPos]->sNalHeaderExt.uiDependencyId;
1490+ pCtx->iCurSeqIntervalMaxPicWidth = pCurAu->pNalUnitsList[pCurAu->uiEndPos]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iMbWidth << 4;
1491+ pCtx->iCurSeqIntervalMaxPicHeight = pCurAu->pNalUnitsList[pCurAu->uiEndPos]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iMbHeight << 4;
1492+ }
1493+ else //P_SLICE
1494+ {
1495+ //step 1: search uiDependencyId equal to pCtx->cur_seq_interval_target_dependency_id
1496+ bool_t bGetDependId = false;
1497+ int32_t iIdxDependId = 0;
1498+
1499+ iIdxDependId = kiEndPos;
1500+ while ( iIdxDependId >= 0 )
1501+ {
1502+ if ( pCtx->iCurSeqIntervalTargetDependId == pCurAu->pNalUnitsList[iIdxDependId]->sNalHeaderExt.uiDependencyId )
1503+ {
1504+ bGetDependId = true;
1505+ break;
1506+ }
1507+ else
1508+ {
1509+ --iIdxDependId;
1510+ }
1511+ }
1512+
1513+ //step 2: switch according to whether or not find the index of pNalUnit whose uiDependencyId equal to iCurSeqIntervalTargetDependId
1514+ if ( bGetDependId ) //get the index of pNalUnit whose uiDependencyId equal to iCurSeqIntervalTargetDependId
1515+ {
1516+ bool_t bGetNoInterPredFront = false;
1517+ //step 2a: search iNoInterLayerPredFlag [0....iIdxDependId]
1518+ iIdxNoInterLayerPred = iIdxDependId;
1519+ while ( iIdxNoInterLayerPred >= 0 )
1520+ {
1521+ if ( pCurAu->pNalUnitsList[iIdxNoInterLayerPred]->sNalHeaderExt.iNoInterLayerPredFlag )
1522+ {
1523+ bGetNoInterPredFront = true;
1524+ break;
1525+ }
1526+ --iIdxNoInterLayerPred;
1527+ }
1528+ //step 2b: switch, whether or not find the NAL unit whose no_inter_pred_flag equal to 1 among [0....iIdxDependId]
1529+ if ( bGetNoInterPredFront ) //YES
1530+ {
1531+ RefineIdxNoInterLayerPred( pCurAu, &iIdxNoInterLayerPred );
1532+ pCurAu->uiStartPos = iIdxNoInterLayerPred;
1533+ CheckAvailNalUnitsListContinuity( pCtx, iIdxNoInterLayerPred, iIdxDependId );
1534+
1535+ if ( !CheckPocOfCurValidNalUnits( pCurAu, iIdxNoInterLayerPred ) )
1536+ {
1537+ return false;
1538+ }
1539+ }
1540+ else //NO, should find the NAL unit whose no_inter_pred_flag equal to 1 among [iIdxDependId....uiEndPos]
1541+ {
1542+ iIdxNoInterLayerPred = iIdxDependId;
1543+ while ( iIdxNoInterLayerPred <= kiEndPos )
1544+ {
1545+ if ( pCurAu->pNalUnitsList[iIdxNoInterLayerPred]->sNalHeaderExt.iNoInterLayerPredFlag )
1546+ {
1547+ break;
1548+ }
1549+ ++iIdxNoInterLayerPred;
1550+ }
1551+
1552+ if ( iIdxNoInterLayerPred > kiEndPos )
1553+ {
1554+ return false; //cann't find the index of pNalUnit whose no_inter_pred_flag = 1
1555+ }
1556+
1557+ RefineIdxNoInterLayerPred( pCurAu, &iIdxNoInterLayerPred );
1558+ pCurAu->uiStartPos = iIdxNoInterLayerPred;
1559+ CheckAvailNalUnitsListContinuity( pCtx, iIdxNoInterLayerPred, kiEndPos );
1560+
1561+ if ( !CheckPocOfCurValidNalUnits( pCurAu, iIdxNoInterLayerPred ) )
1562+ {
1563+ return false;
1564+ }
1565+ }
1566+ }
1567+ else //without the index of pNalUnit, should process this AU as common case
1568+ {
1569+ iIdxNoInterLayerPred = kiEndPos;
1570+ while (iIdxNoInterLayerPred >= 0)
1571+ {
1572+ if ( pCurAu->pNalUnitsList[iIdxNoInterLayerPred]->sNalHeaderExt.iNoInterLayerPredFlag )
1573+ {
1574+ break;
1575+ }
1576+ --iIdxNoInterLayerPred;
1577+ }
1578+ if (iIdxNoInterLayerPred < 0)
1579+ {
1580+ return false; //cann't find the index of pNalUnit whose iNoInterLayerPredFlag = 1
1581+ }
1582+
1583+ RefineIdxNoInterLayerPred( pCurAu, &iIdxNoInterLayerPred );
1584+ pCurAu->uiStartPos = iIdxNoInterLayerPred;
1585+ CheckAvailNalUnitsListContinuity( pCtx, iIdxNoInterLayerPred, kiEndPos );
1586+
1587+ if ( !CheckPocOfCurValidNalUnits( pCurAu, iIdxNoInterLayerPred ) )
1588+ {
1589+ return false;
1590+ }
1591+ }
1592+ }
1593+
1594+ return true;
1595+}
1596+
1597+void_t CheckOnlyOneLayerInAu( PWelsDecoderContext pCtx )
1598+{
1599+ PAccessUnit pCurAu = pCtx->pAccessUnitList;
1600+
1601+ int32_t iEndIdx = pCurAu->uiEndPos;
1602+ int32_t iCurIdx = pCurAu->uiStartPos;
1603+ uint8_t uiDId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiDependencyId;
1604+ uint8_t uiQId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiQualityId;
1605+ uint8_t uiTId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiTemporalId;
1606+
1607+ uint8_t uiCurDId, uiCurQId, uiCurTId;
1608+
1609+ pCtx->bOnlyOneLayerInCurAuFlag = true;
1610+
1611+ if ( iEndIdx == iCurIdx ) //only one NAL in pNalUnitsList
1612+ {
1613+ return;
1614+ }
1615+
1616+ ++iCurIdx;
1617+ while ( iCurIdx <= iEndIdx )
1618+ {
1619+ uiCurDId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiDependencyId;
1620+ uiCurQId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiQualityId;
1621+ uiCurTId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiTemporalId;
1622+
1623+ if ( uiDId != uiCurDId || uiQId != uiCurQId || uiTId != uiCurTId )
1624+ {
1625+ pCtx->bOnlyOneLayerInCurAuFlag = false;
1626+ return;
1627+ }
1628+
1629+ ++iCurIdx;
1630+ }
1631+}
1632+
1633+int32_t WelsDecodeAccessUnitStart ( PWelsDecoderContext pCtx )
1634+{
1635+ // Roll back NAL units not being belong to current access unit list for proceeded access unit
1636+ int32_t iRet = UpdateAccessUnit ( pCtx );
1637+ if ( iRet != ERR_NONE )
1638+ return iRet;
1639+
1640+ pCtx->pAccessUnitList->uiStartPos = 0;
1641+ if ( !pCtx->bAvcBasedFlag && !CheckIntegrityNalUnitsList( pCtx ) )
1642+ {
1643+ pCtx->iErrorCode |= dsBitstreamError;
1644+ return dsBitstreamError;
1645+ }
1646+
1647+ //check current AU has only one layer or not
1648+ //If YES, can use deblocking based on AVC
1649+ if ( !pCtx->bAvcBasedFlag )
1650+ {
1651+ CheckOnlyOneLayerInAu( pCtx );
1652+ }
1653+
1654+ return ERR_NONE;
1655+}
1656+
1657+void_t WelsDecodeAccessUnitEnd ( PWelsDecoderContext pCtx )
1658+{
1659+ // uninitialize context of current access unit and rbsp buffer clean
1660+ ResetCurrentAccessUnit ( pCtx );
1661+}
1662+
1663+
1664+int32_t CheckBSBound(int32_t iWidth, int32_t iHeight, int32_t sliceNum, int32_t ppsId)
1665+{
1666+ int32_t iRet = 0;
1667+
1668+#if defined(WIN32)
1669+ iRet = ((iWidth == 80) && (iHeight = 45) && (sliceNum < 60));
1670+
1671+#elif defined(MACOS)
1672+ iRet = ((iWidth == 80) && (iHeight = 45) && (ppsId < 57));
1673+
1674+#elif defined(ANDROID)
1675+ iRet = ((iWidth == 40) && (iHeight = 22));
1676+
1677+#endif
1678+
1679+ return iRet;
1680+
1681+}
1682+
1683+
1684+
1685+/*
1686+ * ConstructAccessUnit
1687+ * construct an access unit for given input bitstream, maybe partial NAL Unit, one or more Units are involved to
1688+ * joint a collective access unit.
1689+ * parameter\
1690+ * buf: bitstream data buffer
1691+ * bit_len: size in bit length of data
1692+ * buf_len: size in byte length of data
1693+ * coded_au: mark an Access Unit decoding finished
1694+ * return:
1695+ * 0 - success; otherwise returned error_no defined in error_no.h
1696+ */
1697+int32_t ConstructAccessUnit( PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo *pDstInfo)
1698+{
1699+ int32_t iErr;
1700+ int32_t iWidth;
1701+ int32_t iHeight;
1702+ int32_t iStride[2] = { 0 };
1703+
1704+ PAccessUnit pCurAu = pCtx->pAccessUnitList;
1705+
1706+ pCtx->bAuReadyFlag = false;
1707+ pCtx->bLastHasMmco5 = false;
1708+
1709+ iErr = WelsDecodeAccessUnitStart( pCtx );
1710+ GetVclNalTemporalId( pCtx );
1711+
1712+ if ( ERR_NONE != iErr )
1713+ {
1714+ ForceResetCurrentAccessUnit( pCtx->pAccessUnitList );
1715+ pDstInfo->iBufferStatus = 0;
1716+ return iErr;
1717+ }
1718+
1719+ pCtx->pSps = pCurAu->pNalUnitsList[pCurAu->uiStartPos]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pSps;
1720+ pCtx->pPps = pCurAu->pNalUnitsList[pCurAu->uiStartPos]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pPps;
1721+
1722+ //try to allocate or relocate DPB memory only when IDR arrival.
1723+ if ( NAL_UNIT_CODED_SLICE_IDR == pCurAu->pNalUnitsList[pCurAu->uiStartPos]->sNalHeaderExt.sNalUnitHeader.eNalUnitType ||
1724+ pCurAu->pNalUnitsList[pCurAu->uiStartPos]->sNalHeaderExt.bIdrFlag )
1725+ {
1726+ WelsResetRefPic(pCtx); //clear ref pPic when IDR NAL
1727+ iErr = SyncPictureResolutionExt( pCtx, (pCtx->iMaxWidthInSps+15)>>4, (pCtx->iMaxHeightInSps+15)>>4 );
1728+
1729+ if( ERR_NONE != iErr ){
1730+ WelsLog(pCtx, WELS_LOG_WARNING, "sync picture resolution ext failed, the error is %d", iErr);
1731+ return iErr;
1732+ }
1733+ }
1734+
1735+
1736+ pDstInfo->eBufferProperty = (EBufferProperty)pCtx->iDecoderOutputProperty;
1737+
1738+ iErr = DecodeCurrentAccessUnit( pCtx, ppDst, iStride, &iWidth, &iHeight, pDstInfo );
1739+
1740+ WelsDecodeAccessUnitEnd( pCtx );
1741+
1742+ if ( ERR_NONE != iErr )
1743+ {
1744+ WelsLog( pCtx, WELS_LOG_INFO, "returned error from decoding:[0x%x]\n", iErr);
1745+
1746+ pDstInfo->iBufferStatus = 0;
1747+ return iErr;
1748+ }
1749+
1750+ return 0;
1751+}
1752+
1753+static inline void_t InitDqLayerInfo( PDqLayer pDqLayer, PLayerInfo pLayerInfo, PNalUnit pNalUnit, PPicture pPicDec )
1754+{
1755+ PNalUnitHeaderExt pNalHdrExt = &pNalUnit->sNalHeaderExt;
1756+ PSliceHeaderExt pShExt = &pNalUnit->sNalData.sVclNal.sSliceHeaderExt;
1757+ PSliceHeader pSh = &pShExt->sSliceHeader;
1758+ const uint8_t kuiQualityId = pNalHdrExt->uiQualityId;
1759+
1760+ memcpy(&pDqLayer->sLayerInfo, pLayerInfo, sizeof(SLayerInfo));//confirmed_safe_unsafe_usage
1761+
1762+ pDqLayer->pDec = pPicDec;
1763+ pDqLayer->iMbWidth = pSh->iMbWidth; // MB width of this picture
1764+ pDqLayer->iMbHeight = pSh->iMbHeight;// MB height of this picture
1765+
1766+ pDqLayer->iSliceIdcBackup = (pSh->iFirstMbInSlice << 7) | (pNalHdrExt->uiDependencyId << 4) | (pNalHdrExt->uiQualityId);
1767+
1768+ /* Common syntax elements across all slices of a DQLayer */
1769+ pDqLayer->uiPpsId = pLayerInfo->pPps->iPpsId;
1770+ pDqLayer->uiDisableInterLayerDeblockingFilterIdc = pShExt->uiDisableInterLayerDeblockingFilterIdc;
1771+ pDqLayer->iInterLayerSliceAlphaC0Offset = pShExt->iInterLayerSliceAlphaC0Offset;
1772+ pDqLayer->iInterLayerSliceBetaOffset = pShExt->iInterLayerSliceBetaOffset;
1773+ pDqLayer->iSliceGroupChangeCycle = pSh->iSliceGroupChangeCycle;
1774+ pDqLayer->bStoreRefBasePicFlag = pShExt->bStoreRefBasePicFlag;
1775+ pDqLayer->bTCoeffLevelPredFlag = pShExt->bTCoeffLevelPredFlag;
1776+ pDqLayer->bConstrainedIntraResamplingFlag = pShExt->bConstrainedIntraResamplingFlag;
1777+ pDqLayer->uiRefLayerDqId = pShExt->uiRefLayerDqId;
1778+ pDqLayer->uiRefLayerChromaPhaseXPlus1Flag = pShExt->uiRefLayerChromaPhaseXPlus1Flag;
1779+ pDqLayer->uiRefLayerChromaPhaseYPlus1 = pShExt->uiRefLayerChromaPhaseYPlus1;
1780+ //memcpy(&pDqLayer->sScaledRefLayer, &pShExt->sScaledRefLayer, sizeof(SPosOffset));//confirmed_safe_unsafe_usage
1781+
1782+ if ( kuiQualityId == BASE_QUALITY_ID ){
1783+ pDqLayer->pRefPicListReordering = &pSh->pRefPicListReordering;
1784+ pDqLayer->pRefPicMarking = &pSh->sRefMarking;
1785+ pDqLayer->pRefPicBaseMarking = &pShExt->sRefBasePicMarking;
1786+ }
1787+
1788+ pDqLayer->uiLayerDqId = pNalHdrExt->uiLayerDqId; // dq_id of current layer
1789+ pDqLayer->bUseRefBasePicFlag = pNalHdrExt->bUseRefBasePicFlag;
1790+}
1791+
1792+void_t WelsDqLayerDecodeStart ( PWelsDecoderContext pCtx, PNalUnit pCurNal, PSps pSps, PPps pPps )
1793+{
1794+ SNalUnitHeader *pNalHdr = &pCurNal->sNalHeaderExt.sNalUnitHeader;
1795+ PSliceHeader pSh = &pCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader;
1796+
1797+ pCtx->eSliceType = pSh->eSliceType;
1798+ pCtx->pSliceHeader = pSh;
1799+
1800+ pCtx->iFrameNum = pSh->iFrameNum;
1801+
1802+ if ((pNalHdr->eNalUnitType == NAL_UNIT_CODED_SLICE_IDR ||
1803+ (pCurNal->sNalHeaderExt.uiQualityId == BASE_QUALITY_ID && pCurNal->sNalHeaderExt.bIdrFlag)) &&
1804+ pSh->iFrameNum == 0) //pSh->iFrameNum == 0 this condition can deleted??????
1805+ {
1806+ WelsResetRefPic ( pCtx ); // Reset decoded picture buffer lists due to an IDR frame incomes
1807+ }
1808+}
1809+
1810+int32_t InitRefPicList ( PWelsDecoderContext pCtx, const uint8_t kuiNRi, const bool_t kbFirstSlice, int32_t iPoc)
1811+{
1812+ int32_t iRet = ERR_NONE;
1813+ if( kbFirstSlice)
1814+ iRet = WelsInitRefList( pCtx, iPoc );
1815+ if ( (pCtx->eSliceType!=I_SLICE && pCtx->eSliceType!=SI_SLICE) && kbFirstSlice ){
1816+ iRet = WelsReorderRefList ( pCtx );
1817+ }
1818+
1819+ return iRet;
1820+}
1821+
1822+void_t InitCurDqLayerData( PWelsDecoderContext pCtx, PDqLayer pCurDq )
1823+{
1824+ if ( NULL != pCtx && NULL != pCurDq )
1825+ {
1826+ pCurDq->pCsData[0] = pCtx->pCsListXchg[0][0];
1827+ pCurDq->pCsData[1] = pCtx->pCsListXchg[0][1];
1828+ pCurDq->pCsData[2] = pCtx->pCsListXchg[0][2];
1829+ pCurDq->iCsStride[0] = pCtx->iCsStride[0];
1830+ pCurDq->iCsStride[1] = pCtx->iCsStride[1];
1831+ pCurDq->iCsStride[2] = pCtx->iCsStride[2];
1832+
1833+ pCurDq->pMbType = pCtx->sMb.pMbType[0];
1834+ pCurDq->pSliceIdc = pCtx->sMb.pSliceIdc[0];
1835+ pCurDq->pMv[0] = pCtx->sMb.pMv[0][0];
1836+ pCurDq->pRefIndex[0] = pCtx->sMb.pRefIndex[0][0];
1837+ pCurDq->pLumaQp = pCtx->sMb.pLumaQp[0];
1838+ pCurDq->pChromaQp = pCtx->sMb.pChromaQp[0];
1839+ pCurDq->pNzc = pCtx->sMb.pNzc[0];
1840+ pCurDq->pNzcRs = pCtx->sMb.pNzcRs[0];
1841+ pCurDq->pScaledTCoeff = pCtx->sMb.pScaledTCoeff[0];
1842+ pCurDq->pIntraPredMode = pCtx->sMb.pIntraPredMode[0];
1843+ pCurDq->pIntra4x4FinalMode = pCtx->sMb.pIntra4x4FinalMode[0];
1844+ pCurDq->pChromaPredMode = pCtx->sMb.pChromaPredMode[0];
1845+ pCurDq->pCbp = pCtx->sMb.pCbp[0];
1846+ pCurDq->pSubMbType = pCtx->sMb.pSubMbType[0];
1847+ pCurDq->pInterPredictionDoneFlag = pCtx->sMb.pInterPredictionDoneFlag[0];
1848+ pCurDq->pResidualPredFlag = pCtx->sMb.pResidualPredFlag[0];
1849+ }
1850+}
1851+
1852+// added to reset state of parameter sets to waiting successive incoming IDR, 6/4/2010
1853+// It will be called in case packets lost/ broken and decoded failed at temporal level 0
1854+void_t ResetParameterSetsState( PWelsDecoderContext pCtx )
1855+{
1856+ pCtx->bSpsExistAheadFlag = false;
1857+ pCtx->bSubspsExistAheadFlag = false;
1858+ pCtx->bPpsExistAheadFlag = false;
1859+}
1860+
1861+/*
1862+ * DecodeCurrentAccessUnit
1863+ * Decode current access unit when current AU is completed.
1864+ */
1865+int32_t DecodeCurrentAccessUnit( PWelsDecoderContext pCtx, uint8_t **ppDst, int32_t *pDstLen, int32_t *pWidth, int32_t *pHeight, SBufferInfo *pDstInfo )
1866+{
1867+ int32_t iRefCount[LIST_A];
1868+ PNalUnit pNalCur = NULL;
1869+ PAccessUnit pCurAu = pCtx->pAccessUnitList;
1870+
1871+ int32_t iIdx = pCurAu->uiStartPos;
1872+ int32_t iEndIdx = pCurAu->uiEndPos;
1873+
1874+ int32_t iPpsId = 0;
1875+ int32_t iRet = ERR_NONE;
1876+
1877+ const uint8_t kuiTargetLayerDqId = GetTargetDqId(pCtx->uiTargetDqId, pCtx->pParam);
1878+ const uint8_t kuiDependencyIdMax = (kuiTargetLayerDqId & 0x7F) >> 4;
1879+ int16_t iLastIdD = -1, iLastIdQ = -1;
1880+ int16_t iCurrIdD = 0, iCurrIdQ = 0;
1881+ uint8_t uiNalRefIdc = 0;
1882+ bool_t bFreshSliceAvailable = true; // Another fresh slice comingup for given dq layer, for multiple slices in case of header parts of slices sometimes loss over error-prone channels, 8/14/2008
1883+ PPicture pStoreBasePic = NULL;
1884+
1885+ //update pCurDqLayer at the starting of AU decoding
1886+ if ( pCtx->bInitialDqLayersMem )
1887+ {
1888+ pCtx->pCurDqLayer = pCtx->pDqLayersList[0];
1889+ }
1890+
1891+ InitCurDqLayerData( pCtx, pCtx->pCurDqLayer );
1892+
1893+ pNalCur = pCurAu->pNalUnitsList[iIdx];
1894+ while ( iIdx <= iEndIdx )
1895+ {
1896+ PDqLayer dq_cur = pCtx->pCurDqLayer;
1897+ SLayerInfo pLayerInfo;
1898+ PSliceHeaderExt pShExt = NULL;
1899+ PSliceHeader pSh = NULL;
1900+
1901+ if( pCtx->pDec == NULL ){
1902+ pCtx->pDec = PrefetchPic(pCtx->pPicBuff[0]);
1903+
1904+ if( NULL == pCtx->pDec ){
1905+ WelsLog( pCtx, WELS_LOG_ERROR, "DecodeCurrentAccessUnit()::::::PrefetchPic ERROR, pSps->iNumRefFrames:%d.\n",
1906+ pCtx->pSps->iNumRefFrames );
1907+ pCtx->iErrorCode |= dsOutOfMemory;
1908+ return ERR_INFO_REF_COUNT_OVERFLOW;
1909+ }
1910+ }
1911+
1912+#ifdef NO_WAITING_AU
1913+ //For fixing the nal lossing issue
1914+ if ((pCtx->pDec->iTotalNumMbRec != 0)&&
1915+ (CheckAccessUnitBoundaryExt(&pCtx->sLastNalHdrExt, &pNalCur->sNalHeaderExt, &pCtx->sLastSliceHeader, &pNalCur->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader)))
1916+ {
1917+ pCtx->pDec->iTotalNumMbRec = 0;
1918+ }
1919+#else
1920+ //initialize at the starting of AU.
1921+ pCtx->pDec->iTotalNumMbRec = 0;
1922+#endif
1923+ if(pCtx->pDec->iTotalNumMbRec == 0) //Picture start to decode
1924+ {
1925+ for( int32_t i = 0; i < LAYER_NUM_EXCHANGEABLE; ++ i)
1926+ memset(pCtx->sMb.pSliceIdc[i], 0xff, (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof(int32_t)) );
1927+ }
1928+ GetI4LumaIChromaAddrTable(pCtx->iDecBlockOffsetArray, pCtx->pDec->iLinesize[0], pCtx->pDec->iLinesize[1]);
1929+
1930+ if ( pNalCur->sNalHeaderExt.uiLayerDqId > kuiTargetLayerDqId ) {
1931+ break; // Per formance it need not to decode the remaining bits any more due to given uiLayerDqId required, 9/2/2009
1932+ }
1933+
1934+ memset(&pLayerInfo, 0, sizeof(SLayerInfo));
1935+
1936+ /*
1937+ * Loop decoding for slices (even FMO and/ multiple slices) within a dq layer
1938+ */
1939+ while ( iIdx <= iEndIdx )
1940+ {
1941+ BOOL_T bReconstructSlice;
1942+ iCurrIdQ = pNalCur->sNalHeaderExt.uiQualityId;
1943+ iCurrIdD = pNalCur->sNalHeaderExt.uiDependencyId;
1944+ pSh = &pNalCur->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader;
1945+ pShExt = &pNalCur->sNalData.sVclNal.sSliceHeaderExt;
1946+
1947+ bReconstructSlice = CheckSliceNeedReconstruct(iCurrIdD, iCurrIdQ, pShExt->bStoreRefBasePicFlag,
1948+ kuiDependencyIdMax, pNalCur->sNalHeaderExt.uiLayerDqId, kuiTargetLayerDqId);
1949+
1950+ memcpy(&pLayerInfo.sNalHeaderExt, &pNalCur->sNalHeaderExt, sizeof(SNalUnitHeaderExt));//confirmed_safe_unsafe_usage
1951+
1952+ pCtx->pDec->iFrameNum = pSh->iFrameNum;
1953+
1954+ memcpy(&pLayerInfo.sSliceInLayer.sSliceHeaderExt, pShExt, sizeof(SSliceHeaderExt));//confirmed_safe_unsafe_usage
1955+ pLayerInfo.sSliceInLayer.bSliceHeaderExtFlag = pNalCur->sNalData.sVclNal.bSliceHeaderExtFlag;
1956+ pLayerInfo.sSliceInLayer.eSliceType = pSh->eSliceType;
1957+ pLayerInfo.sSliceInLayer.iLastMbQp = pSh->iSliceQp;
1958+ dq_cur->pBitStringAux = &pNalCur->sNalData.sVclNal.sSliceBitsRead;
1959+
1960+ uiNalRefIdc = pNalCur->sNalHeaderExt.sNalUnitHeader.uiNalRefIdc;
1961+
1962+ iPpsId = pSh->iPpsId;
1963+
1964+ pLayerInfo.pPps = pSh->pPps;
1965+ pLayerInfo.pSps = pSh->pSps;
1966+ pLayerInfo.pSubsetSps = pShExt->pSubsetSps;
1967+
1968+ pCtx->pFmo = &pCtx->sFmoList[iPpsId];
1969+ if ( !FmoParamUpdate( pCtx->pFmo, pLayerInfo.pSps, pLayerInfo.pPps, &pCtx->iActiveFmoNum ) ) {
1970+ pCtx->iErrorCode |= dsBitstreamError;
1971+ WelsLog( pCtx, WELS_LOG_WARNING, "DecodeCurrentAccessUnit(), FmoParamUpdate failed, eSliceType: %d.\n", pSh->eSliceType);
1972+ return GENERATE_ERROR_NO(ERR_LEVEL_SLICE_HEADER, ERR_INFO_FMO_INIT_FAIL);
1973+ }
1974+
1975+ bFreshSliceAvailable = (iCurrIdD != iLastIdD || iCurrIdQ != iLastIdQ); // do not need condition of (first_mb == 0) due multiple slices might be disorder
1976+
1977+ WelsDqLayerDecodeStart ( pCtx, pNalCur, pLayerInfo.pSps, pLayerInfo.pPps );
1978+
1979+ if ( iCurrIdQ == BASE_QUALITY_ID )
1980+ {
1981+ ST64(iRefCount, LD64(pLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.uiRefCount));
1982+ }
1983+
1984+ if ( (iLastIdD < 0) || //case 1: first layer
1985+ ( iLastIdD == iCurrIdD) ) //case 2: same uiDId
1986+ {
1987+ InitDqLayerInfo( dq_cur, &pLayerInfo, pNalCur, pCtx->pDec );
1988+
1989+ if ( !dq_cur->sLayerInfo.pSps->bGapsInFrameNumValueAllowedFlag )
1990+ {
1991+ const bool_t kbIdrFlag = dq_cur->sLayerInfo.sNalHeaderExt.bIdrFlag || (dq_cur->sLayerInfo.sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR);
1992+ // Subclause 8.2.5.2 Decoding process for gaps in frame_num
1993+ if ( !kbIdrFlag &&
1994+ pSh->iFrameNum != pCtx->iPrevFrameNum &&
1995+ pSh->iFrameNum != ((pCtx->iPrevFrameNum+1) & ((1<<dq_cur->sLayerInfo.pSps->uiLog2MaxFrameNum)-1)) )
1996+ {
1997+ WelsLog( pCtx, WELS_LOG_WARNING, "referencing pictures lost due frame gaps exist, prev_frame_num: %d, curr_frame_num: %d\n", pCtx->iPrevFrameNum, pSh->iFrameNum);
1998+
1999+#ifdef LONG_TERM_REF
2000+ pCtx->bParamSetsLostFlag = true;
2001+#else
2002+ pCtx->bReferenceLostAtT0Flag = true;
2003+#endif
2004+ ResetParameterSetsState( pCtx );
2005+
2006+ pCtx->iErrorCode |= dsRefLost;
2007+ return ERR_INFO_REFERENCE_PIC_LOST;
2008+ }
2009+ }
2010+
2011+ if ( iCurrIdD == kuiDependencyIdMax && iCurrIdQ == BASE_QUALITY_ID )
2012+ {
2013+ iRet = InitRefPicList ( pCtx, uiNalRefIdc, bFreshSliceAvailable, pSh->iPicOrderCntLsb);
2014+ if ( iRet )
2015+ {
2016+ HandleReferenceLost(pCtx, pNalCur);
2017+ WelsLog( pCtx, WELS_LOG_WARNING, "reference picture introduced by this frame is lost during transmission! uiTId: %d\n", pNalCur->sNalHeaderExt.uiTemporalId );
2018+ return iRet;
2019+ }
2020+ }
2021+
2022+ iRet = WelsDecodeSlice ( pCtx, bFreshSliceAvailable, pNalCur );
2023+
2024+ //Output good store_base reconstruction when enhancement quality layer occurred error for MGS key picture case
2025+ if ( iRet != ERR_NONE )
2026+ {
2027+ WelsLog( pCtx, WELS_LOG_WARNING, "DecodeCurrentAccessUnit() failed (%d) in frame: %d uiDId: %d uiQId: %d\n",
2028+ iRet, pSh->iFrameNum, iCurrIdD, iCurrIdQ);
2029+ HandleReferenceLostL0(pCtx, pNalCur);
2030+ return iRet;
2031+ }
2032+ if( bReconstructSlice ) {
2033+ if( WelsDecodeConstructSlice(pCtx, pNalCur) ){
2034+ return -1;
2035+ }
2036+ }
2037+ }
2038+#if defined (_DEBUG) && !defined (CODEC_FOR_TESTBED)
2039+ fprintf( stderr, "cur_frame : %d iCurrIdD : %d\n ",
2040+ dq_cur->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iFrameNum, iCurrIdD );
2041+#endif//#if !CODEC_FOR_TESTBED
2042+ iLastIdD = iCurrIdD;
2043+ iLastIdQ = iCurrIdQ;
2044+
2045+ //pNalUnitsList overflow.
2046+ ++ iIdx;
2047+ if (iIdx <= iEndIdx)
2048+ {
2049+ pNalCur = pCurAu->pNalUnitsList[iIdx];
2050+ }
2051+ else
2052+ {
2053+ pNalCur = NULL;
2054+ }
2055+
2056+ if ( pNalCur == NULL ||
2057+ iLastIdD != pNalCur->sNalHeaderExt.uiDependencyId ||
2058+ iLastIdQ != pNalCur->sNalHeaderExt.uiQualityId )
2059+ break;
2060+ }
2061+
2062+ // A dq layer decoded here
2063+#if defined (_DEBUG) && !defined (CODEC_FOR_TESTBED)
2064+#undef fprintf
2065+ fprintf(stderr, "POC: #%d, FRAME: #%d, D: %d, Q: %d, T: %d, P: %d, %d\n",
2066+ pSh->iPicOrderCntLsb, pSh->iFrameNum, iCurrIdD, iCurrIdQ, dq_cur->sLayerInfo.sNalHeaderExt.uiTemporalId, dq_cur->sLayerInfo.sNalHeaderExt.uiPriorityId,dq_cur->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iSliceQp);
2067+#endif//#if !CODEC_FOR_TESTBED
2068+
2069+ if( dq_cur->uiLayerDqId == kuiTargetLayerDqId ){
2070+ if( DecodeFrameConstruction( pCtx, ppDst, pDstLen, pWidth, pHeight, pDstInfo) ){
2071+#ifdef NO_WAITING_AU
2072+ memcpy(&pCtx->sLastNalHdrExt, &pCurAu->pNalUnitsList[iIdx-1]->sNalHeaderExt, sizeof(SNalUnitHeaderExt));
2073+ memcpy(&pCtx->sLastSliceHeader, &pCurAu->pNalUnitsList[iIdx-1]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader, sizeof(SSliceHeader));
2074+ return ERR_NONE;
2075+#else
2076+ pCtx->iErrorCode |= dsBitstreamError;
2077+ return -1;
2078+#endif
2079+
2080+ }
2081+ if( (uiNalRefIdc > 0) && ( iCurrIdQ || (!dq_cur->bStoreRefBasePicFlag) ) ){
2082+ WelsMarkAsRef(pCtx, false);
2083+ ExpandReferencingPicture(pCtx->pDec, pCtx->sExpandPicFunc.pExpandLumaPicture, pCtx->sExpandPicFunc.pExpandChromaPicture);
2084+ pCtx->pDec = NULL;
2085+ }
2086+ }
2087+
2088+ if( (iCurrIdD == kuiDependencyIdMax) && (iCurrIdQ == BASE_QUALITY_ID) && (dq_cur->bStoreRefBasePicFlag) ){
2089+ pStoreBasePic = pCtx->pDec;
2090+
2091+ if( uiNalRefIdc > 0 ){
2092+ WelsMarkAsRef(pCtx, true);
2093+ ExpandReferencingPicture(pCtx->pDec, pCtx->sExpandPicFunc.pExpandLumaPicture, pCtx->sExpandPicFunc.pExpandChromaPicture);
2094+ pCtx->pDec = NULL;
2095+ }
2096+ }
2097+ // need update frame_num due current frame is well decoded
2098+ pCtx->iPrevFrameNum = pSh->iFrameNum;
2099+ if( pCtx->bLastHasMmco5 )
2100+ pCtx->iPrevFrameNum = 0;
2101+ }
2102+
2103+ return ERR_NONE;
2104+}
2105+
2106+} // 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