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
60namespace WelsDec {
61
62static 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
120inline 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
127inline 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
135inline 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
148inline 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
161inline 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 */
175int32_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
223int32_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
265bool_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*/
308int32_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 */
338void_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 */
369void_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
392int32_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
430int32_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 */
508int32_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 */
893bool_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
940int32_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
983int32_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
1088void_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
1261void_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 */
1291void_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
1317void_t ForceClearCurrentNal( PAccessUnit pAu )
1318{
1319 if (pAu->uiAvailUnitsNum > 0)
1320 -- pAu->uiAvailUnitsNum;
1321}
1322
1323
1324void_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
1378void_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
1429bool_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
1446bool_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
1597void_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
1633int32_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
1657void_t WelsDecodeAccessUnitEnd ( PWelsDecoderContext pCtx )
1658{
1659 // uninitialize context of current access unit and rbsp buffer clean
1660 ResetCurrentAccessUnit ( pCtx );
1661}
1662
1663
1664int32_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 */
1697int32_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
1753static 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
1792void_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
1810int32_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
1822void_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
1854void_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 */
1865int32_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