• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "decoder_core.h"
35 #include "error_code.h"
36 #include "memmgr_nal_unit.h"
37 #include "au_parser.h"
38 #include "decode_slice.h"
39 #include "manage_dec_ref.h"
40 #include "expand_pic.h"
41 #include "decoder.h"
42 #include "decode_mb_aux.h"
43 #include "memory_align.h"
44 #include "error_concealment.h"
45 
46 namespace WelsDec {
DecodeFrameConstruction(PWelsDecoderContext pCtx,uint8_t ** ppDst,SBufferInfo * pDstInfo)47 static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {
48   PDqLayer pCurDq = pCtx->pCurDqLayer;
49   PPicture pPic = pCtx->pDec;
50 
51   const int32_t kiWidth = pCurDq->iMbWidth << 4;
52   const int32_t kiHeight = pCurDq->iMbHeight << 4;
53 
54   const int32_t kiTotalNumMbInCurLayer = pCurDq->iMbWidth * pCurDq->iMbHeight;
55   bool bFrameCompleteFlag = true;
56 
57   if (pPic->bNewSeqBegin) {
58     memcpy (& (pCtx->sFrameCrop), & (pCurDq->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.pSps->sFrameCrop),
59             sizeof (SPosOffset)); //confirmed_safe_unsafe_usage
60 #ifdef LONG_TERM_REF
61     pCtx->bParamSetsLostFlag      = false;
62 #else
63     pCtx->bReferenceLostAtT0Flag = false; // need initialize it due new seq, 6/4/2010
64 #endif //LONG_TERM_REF
65     if (pCtx->iTotalNumMbRec == kiTotalNumMbInCurLayer) {
66       pCtx->bPrintFrameErrorTraceFlag = true;
67       WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO,
68                "DecodeFrameConstruction(): will output first frame of new sequence, %d x %d, crop_left:%d, crop_right:%d, crop_top:%d, crop_bottom:%d, ignored error packet:%d.",
69                kiWidth, kiHeight, pCtx->sFrameCrop.iLeftOffset, pCtx->sFrameCrop.iRightOffset, pCtx->sFrameCrop.iTopOffset,
70                pCtx->sFrameCrop.iBottomOffset, pCtx->iIgnoredErrorInfoPacketCount);
71       pCtx->iIgnoredErrorInfoPacketCount = 0;
72     }
73   }
74 
75   const int32_t kiActualWidth = kiWidth - (pCtx->sFrameCrop.iLeftOffset + pCtx->sFrameCrop.iRightOffset) * 2;
76   const int32_t kiActualHeight = kiHeight - (pCtx->sFrameCrop.iTopOffset + pCtx->sFrameCrop.iBottomOffset) * 2;
77 
78 
79   if (pCtx->pParam->eEcActiveIdc == ERROR_CON_DISABLE) {
80     if ((pCtx->pDecoderStatistics->uiWidth != (unsigned int) kiActualWidth)
81         || (pCtx->pDecoderStatistics->uiHeight != (unsigned int) kiActualHeight)) {
82       pCtx->pDecoderStatistics->uiResolutionChangeTimes++;
83       pCtx->pDecoderStatistics->uiWidth = kiActualWidth;
84       pCtx->pDecoderStatistics->uiHeight = kiActualHeight;
85     }
86     UpdateDecStatNoFreezingInfo (pCtx);
87   }
88 
89   if (pCtx->pParam->bParseOnly) { //should exit for parse only to prevent access NULL pDstInfo
90     PAccessUnit pCurAu = pCtx->pAccessUnitList;
91     if (dsErrorFree == pCtx->iErrorCode) { //correct decoding, add to data buffer
92       SParserBsInfo* pParser = pCtx->pParserBsInfo;
93       SNalUnit* pCurNal = NULL;
94       int32_t iTotalNalLen = 0;
95       int32_t iNalLen = 0;
96       int32_t iNum = 0;
97       while (iNum < pParser->iNalNum) {
98         iTotalNalLen += pParser->pNalLenInByte[iNum++];
99       }
100       uint8_t* pDstBuf = pParser->pDstBuff + iTotalNalLen;
101       int32_t iIdx = pCurAu->uiStartPos;
102       int32_t iEndIdx = pCurAu->uiEndPos;
103       uint8_t* pNalBs = NULL;
104       pParser->uiOutBsTimeStamp = (pCurAu->pNalUnitsList [iIdx]) ? pCurAu->pNalUnitsList [iIdx]->uiTimeStamp : 0;
105       //pParser->iNalNum = 0;
106       pParser->iSpsWidthInPixel = (pCtx->pSps->iMbWidth << 4) - ((pCtx->pSps->sFrameCrop.iLeftOffset +
107                                   pCtx->pSps->sFrameCrop.iRightOffset) << 1);
108       pParser->iSpsHeightInPixel = (pCtx->pSps->iMbHeight << 4) - ((pCtx->pSps->sFrameCrop.iTopOffset +
109                                    pCtx->pSps->sFrameCrop.iBottomOffset) << 1);
110 
111       if (pCurAu->pNalUnitsList [iIdx]->sNalHeaderExt.bIdrFlag) { //IDR
112         if (pCtx->bFrameFinish) { //add required sps/pps
113           if (pParser->iNalNum > pCtx->iMaxNalNum - 2) { //2 reserved for sps+pps
114             WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO,
115                      "DecodeFrameConstruction(): current NAL num (%d) plus sps & pps exceeds permitted num (%d). Will expand",
116                      pParser->iNalNum, pCtx->iMaxNalNum);
117             WELS_VERIFY_RETURN_IF (ERR_INFO_OUT_OF_MEMORY, ExpandBsLenBuffer (pCtx, pParser->iNalNum + 2))
118           }
119           bool bSubSps = (NAL_UNIT_CODED_SLICE_EXT == pCurAu->pNalUnitsList [iIdx]->sNalHeaderExt.sNalUnitHeader.eNalUnitType);
120           SSpsBsInfo* pSpsBs = NULL;
121           SPpsBsInfo* pPpsBs = NULL;
122           int32_t iSpsId = pCtx->pSps->iSpsId;
123           int32_t iPpsId = pCtx->pPps->iPpsId;
124           pCtx->bParamSetsLostFlag = false;
125           //find required sps, pps and write into dst buff
126           pSpsBs = bSubSps ? &pCtx->sSubsetSpsBsInfo [iSpsId] : &pCtx->sSpsBsInfo [iSpsId];
127           pPpsBs = &pCtx->sPpsBsInfo [iPpsId];
128           if (pDstBuf - pParser->pDstBuff + pSpsBs->uiSpsBsLen + pPpsBs->uiPpsBsLen >= MAX_ACCESS_UNIT_CAPACITY) {
129             WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR,
130                      "DecodeFrameConstruction(): sps pps size: (%d %d) too large. Failed to parse. \n", pSpsBs->uiSpsBsLen,
131                      pPpsBs->uiPpsBsLen);
132             pCtx->iErrorCode |= dsOutOfMemory;
133             pCtx->pParserBsInfo->iNalNum = 0;
134             return ERR_INFO_OUT_OF_MEMORY;
135           }
136           memcpy (pDstBuf, pSpsBs->pSpsBsBuf, pSpsBs->uiSpsBsLen);
137           pParser->pNalLenInByte [pParser->iNalNum ++] = pSpsBs->uiSpsBsLen;
138           pDstBuf += pSpsBs->uiSpsBsLen;
139           memcpy (pDstBuf, pPpsBs->pPpsBsBuf, pPpsBs->uiPpsBsLen);
140           pParser->pNalLenInByte [pParser->iNalNum ++] = pPpsBs->uiPpsBsLen;
141           pDstBuf += pPpsBs->uiPpsBsLen;
142           pCtx->bFrameFinish = false;
143         }
144       }
145       //then VCL data re-write
146       if (pParser->iNalNum + iEndIdx - iIdx + 1 > pCtx->iMaxNalNum) { //calculate total NAL num
147         WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO,
148                  "DecodeFrameConstruction(): current NAL num (%d) exceeds permitted num (%d). Will expand",
149                  pParser->iNalNum + iEndIdx - iIdx + 1, pCtx->iMaxNalNum);
150         WELS_VERIFY_RETURN_IF (ERR_INFO_OUT_OF_MEMORY, ExpandBsLenBuffer (pCtx, pParser->iNalNum + iEndIdx - iIdx + 1))
151       }
152       while (iIdx <= iEndIdx) {
153         pCurNal = pCurAu->pNalUnitsList [iIdx ++];
154         iNalLen = pCurNal->sNalData.sVclNal.iNalLength;
155         pNalBs = pCurNal->sNalData.sVclNal.pNalPos;
156         pParser->pNalLenInByte [pParser->iNalNum ++] = iNalLen;
157         if (pDstBuf - pParser->pDstBuff + iNalLen >= MAX_ACCESS_UNIT_CAPACITY) {
158           WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR,
159                    "DecodeFrameConstruction(): composed output size (%ld) exceeds (%d). Failed to parse. current data pos %d out of %d:, previously accumulated num: %d, total num: %d, previously accumulated len: %d, current len: %d, current buf pos: %p, header buf pos: %p \n",
160                    (long) (pDstBuf - pParser->pDstBuff + iNalLen), MAX_ACCESS_UNIT_CAPACITY, iIdx, iEndIdx, iNum, pParser->iNalNum,
161                    iTotalNalLen, iNalLen, pDstBuf, pParser->pDstBuff);
162           pCtx->iErrorCode |= dsOutOfMemory;
163           pCtx->pParserBsInfo->iNalNum = 0;
164           return ERR_INFO_OUT_OF_MEMORY;
165         }
166 
167         memcpy (pDstBuf, pNalBs, iNalLen);
168         pDstBuf += iNalLen;
169       }
170       if (pCtx->iTotalNumMbRec == kiTotalNumMbInCurLayer) { //frame complete
171         pCtx->iTotalNumMbRec = 0;
172         pCtx->bFramePending = false;
173         pCtx->bFrameFinish = true; //finish current frame and mark it
174       } else if (pCtx->iTotalNumMbRec != 0) { //frame incomplete
175         pCtx->bFramePending = true;
176         pCtx->pDec->bIsComplete = false;
177         pCtx->bFrameFinish = false; //current frame not finished
178         pCtx->iErrorCode |= dsFramePending;
179         return ERR_INFO_PARSEONLY_PENDING;
180         //pCtx->pParserBsInfo->iNalNum = 0;
181       }
182     } else { //error
183       pCtx->pParserBsInfo->uiOutBsTimeStamp = 0;
184       pCtx->pParserBsInfo->iNalNum = 0;
185       pCtx->pParserBsInfo->iSpsWidthInPixel = 0;
186       pCtx->pParserBsInfo->iSpsHeightInPixel = 0;
187       return ERR_INFO_PARSEONLY_ERROR;
188     }
189     return ERR_NONE;
190   }
191 
192   if (pCtx->iTotalNumMbRec != kiTotalNumMbInCurLayer) {
193     WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
194              "DecodeFrameConstruction(): iTotalNumMbRec:%d, total_num_mb_sps:%d, cur_layer_mb_width:%d, cur_layer_mb_height:%d ",
195              pCtx->iTotalNumMbRec, kiTotalNumMbInCurLayer, pCurDq->iMbWidth, pCurDq->iMbHeight);
196     bFrameCompleteFlag = false; //return later after output buffer is done
197     if (pCtx->bInstantDecFlag) { //no-delay decoding, wait for new slice
198       return ERR_INFO_MB_NUM_INADEQUATE;
199     }
200   } else if (pCurDq->sLayerInfo.sNalHeaderExt.bIdrFlag
201              && (pCtx->iErrorCode == dsErrorFree)) { //complete non-ECed IDR frame done
202     pCtx->pDec->bIsComplete = true;
203     pCtx->bFreezeOutput = false;
204   }
205 
206   pCtx->iTotalNumMbRec = 0;
207 
208   //////output:::normal path
209   pDstInfo->uiOutYuvTimeStamp = pPic->uiTimeStamp;
210   ppDst[0]      = pPic->pData[0];
211   ppDst[1]      = pPic->pData[1];
212   ppDst[2]      = pPic->pData[2];
213 
214   pDstInfo->UsrData.sSystemBuffer.iFormat = videoFormatI420;
215 
216   pDstInfo->UsrData.sSystemBuffer.iWidth = kiActualWidth;
217   pDstInfo->UsrData.sSystemBuffer.iHeight = kiActualHeight;
218   pDstInfo->UsrData.sSystemBuffer.iStride[0] = pPic->iLinesize[0];
219   pDstInfo->UsrData.sSystemBuffer.iStride[1] = pPic->iLinesize[1];
220   ppDst[0] = ppDst[0] + pCtx->sFrameCrop.iTopOffset * 2 * pPic->iLinesize[0] + pCtx->sFrameCrop.iLeftOffset * 2;
221   ppDst[1] = ppDst[1] + pCtx->sFrameCrop.iTopOffset  * pPic->iLinesize[1] + pCtx->sFrameCrop.iLeftOffset;
222   ppDst[2] = ppDst[2] + pCtx->sFrameCrop.iTopOffset  * pPic->iLinesize[1] + pCtx->sFrameCrop.iLeftOffset;
223   for (int i = 0; i < 3; ++i) {
224     pDstInfo->pDst[i] = ppDst[i];
225   }
226   pDstInfo->iBufferStatus = 1;
227   if (GetThreadCount (pCtx) > 1 && pPic->bIsComplete == false) {
228     pPic->bIsComplete = true;
229   }
230   if (GetThreadCount (pCtx) > 1) {
231     uint32_t uiMbHeight = (pCtx->pDec->iHeightInPixel + 15) >> 4;
232     for (uint32_t i = 0; i < uiMbHeight; ++i) {
233       SET_EVENT (&pCtx->pDec->pReadyEvent[i]);
234     }
235   }
236   bool bOutResChange = false;
237   if (GetThreadCount (pCtx) <= 1 || pCtx->pLastThreadCtx == NULL) {
238     bOutResChange = (pCtx->iLastImgWidthInPixel != pDstInfo->UsrData.sSystemBuffer.iWidth)
239                     || (pCtx->iLastImgHeightInPixel != pDstInfo->UsrData.sSystemBuffer.iHeight);
240   } else {
241     if (pCtx->pLastThreadCtx != NULL) {
242       PWelsDecoderThreadCTX pLastThreadCtx = (PWelsDecoderThreadCTX) (pCtx->pLastThreadCtx);
243       bOutResChange = (pLastThreadCtx->pCtx->iLastImgWidthInPixel != pDstInfo->UsrData.sSystemBuffer.iWidth)
244                       || (pLastThreadCtx->pCtx->iLastImgHeightInPixel != pDstInfo->UsrData.sSystemBuffer.iHeight);
245     }
246   }
247   pCtx->iLastImgWidthInPixel = pDstInfo->UsrData.sSystemBuffer.iWidth;
248   pCtx->iLastImgHeightInPixel = pDstInfo->UsrData.sSystemBuffer.iHeight;
249   if (pCtx->pParam->eEcActiveIdc == ERROR_CON_DISABLE) //no buffer output if EC is disabled and frame incomplete
250     pDstInfo->iBufferStatus = (int32_t) (bFrameCompleteFlag
251                                          && pPic->bIsComplete); // When EC disable, ECed picture not output
252   else if ((pCtx->pParam->eEcActiveIdc == ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE
253             || pCtx->pParam->eEcActiveIdc == ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE)
254            && pCtx->iErrorCode && bOutResChange)
255     pCtx->bFreezeOutput = true;
256 
257   if (pDstInfo->iBufferStatus == 0) {
258     if (!bFrameCompleteFlag)
259       pCtx->iErrorCode |= dsBitstreamError;
260     return ERR_INFO_MB_NUM_INADEQUATE;
261   }
262   if (pCtx->bFreezeOutput) {
263     pDstInfo->iBufferStatus = 0;
264     if (pPic->bNewSeqBegin) {
265       WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO,
266                "DecodeFrameConstruction():New sequence detected, but freezed, correct MBs (%d) out of whole MBs (%d).",
267                kiTotalNumMbInCurLayer - pCtx->iMbEcedNum, kiTotalNumMbInCurLayer);
268     }
269   }
270   pCtx->iMbEcedNum = pPic->iMbEcedNum;
271   pCtx->iMbNum = pPic->iMbNum;
272   pCtx->iMbEcedPropNum = pPic->iMbEcedPropNum;
273   if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
274     if (pDstInfo->iBufferStatus && ((pCtx->pDecoderStatistics->uiWidth != (unsigned int) kiActualWidth)
275                                     || (pCtx->pDecoderStatistics->uiHeight != (unsigned int) kiActualHeight))) {
276       pCtx->pDecoderStatistics->uiResolutionChangeTimes++;
277       pCtx->pDecoderStatistics->uiWidth = kiActualWidth;
278       pCtx->pDecoderStatistics->uiHeight = kiActualHeight;
279     }
280     UpdateDecStat (pCtx, pDstInfo->iBufferStatus != 0);
281   }
282   return ERR_NONE;
283 }
284 
CheckSliceNeedReconstruct(uint8_t uiLayerDqId,uint8_t uiTargetDqId)285 inline bool    CheckSliceNeedReconstruct (uint8_t uiLayerDqId, uint8_t uiTargetDqId) {
286   return (uiLayerDqId == uiTargetDqId); // target layer
287 }
288 
GetTargetDqId(uint8_t uiTargetDqId,SDecodingParam * psParam)289 inline uint8_t GetTargetDqId (uint8_t uiTargetDqId,  SDecodingParam* psParam) {
290   uint8_t  uiRequiredDqId = psParam ? psParam->uiTargetDqLayer : (uint8_t)255;
291 
292   return WELS_MIN (uiTargetDqId, uiRequiredDqId);
293 }
294 
295 
HandleReferenceLostL0(PWelsDecoderContext pCtx,PNalUnit pCurNal)296 inline void    HandleReferenceLostL0 (PWelsDecoderContext pCtx, PNalUnit pCurNal) {
297   if (0 == pCurNal->sNalHeaderExt.uiTemporalId) {
298     pCtx->bReferenceLostAtT0Flag = true;
299   }
300   pCtx->iErrorCode |= dsBitstreamError;
301 }
302 
HandleReferenceLost(PWelsDecoderContext pCtx,PNalUnit pCurNal)303 inline void    HandleReferenceLost (PWelsDecoderContext pCtx, PNalUnit pCurNal) {
304   if ((0 == pCurNal->sNalHeaderExt.uiTemporalId) || (1 == pCurNal->sNalHeaderExt.uiTemporalId)) {
305     pCtx->bReferenceLostAtT0Flag = true;
306   }
307   pCtx->iErrorCode |= dsRefLost;
308 }
309 
WelsDecodeConstructSlice(PWelsDecoderContext pCtx,PNalUnit pCurNal)310 inline int32_t  WelsDecodeConstructSlice (PWelsDecoderContext pCtx, PNalUnit pCurNal) {
311   int32_t  iRet = WelsTargetSliceConstruction (pCtx);
312 
313   if (iRet) {
314     HandleReferenceLostL0 (pCtx, pCurNal);
315   }
316 
317   return iRet;
318 }
319 
ParsePredWeightedTable(PBitStringAux pBs,PSliceHeader pSh)320 int32_t ParsePredWeightedTable (PBitStringAux pBs, PSliceHeader pSh) {
321   uint32_t uiCode;
322   int32_t iList = 0;
323   int32_t iCode;
324 
325   WELS_READ_VERIFY (BsGetUe (pBs, &uiCode));
326   WELS_CHECK_SE_BOTH_ERROR_NOLOG (uiCode, 0, 7, "luma_log2_weight_denom",
327                                   GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_LUMA_LOG2_WEIGHT_DENOM));
328   pSh->sPredWeightTable.uiLumaLog2WeightDenom = uiCode;
329   if (pSh->pSps->uiChromaArrayType != 0) {
330     WELS_READ_VERIFY (BsGetUe (pBs, &uiCode));
331     WELS_CHECK_SE_BOTH_ERROR_NOLOG (uiCode, 0, 7, "chroma_log2_weight_denom",
332                                     GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_CHROMA_LOG2_WEIGHT_DENOM));
333     pSh->sPredWeightTable.uiChromaLog2WeightDenom = uiCode;
334   }
335 
336   if ((pSh->sPredWeightTable.uiLumaLog2WeightDenom | pSh->sPredWeightTable.uiChromaLog2WeightDenom) > 7)
337     return ERR_NONE;
338 
339   do {
340 
341     for (int i = 0; i < pSh->uiRefCount[iList]; i++) {
342       //luma
343       WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode));
344       if (!!uiCode) {
345 
346         WELS_READ_VERIFY (BsGetSe (pBs, &iCode));
347         WELS_CHECK_SE_BOTH_ERROR_NOLOG (iCode, -128, 127, "luma_weight",
348                                         GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_LUMA_WEIGHT));
349         pSh->sPredWeightTable.sPredList[iList].iLumaWeight[i] = iCode;
350 
351         WELS_READ_VERIFY (BsGetSe (pBs, &iCode));
352         WELS_CHECK_SE_BOTH_ERROR_NOLOG (iCode, -128, 127, "luma_offset",
353                                         GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_LUMA_OFFSET));
354         pSh->sPredWeightTable.sPredList[iList].iLumaOffset[i] = iCode;
355       } else {
356         pSh->sPredWeightTable.sPredList[iList].iLumaWeight[i] = 1 << (pSh->sPredWeightTable.uiLumaLog2WeightDenom);
357         pSh->sPredWeightTable.sPredList[iList].iLumaOffset[i] = 0;
358 
359       }
360       //chroma
361       if (pSh->pSps->uiChromaArrayType == 0)
362         continue;
363 
364       WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode));
365       if (!!uiCode) {
366         for (int j = 0; j < 2; j++) {
367 
368 
369           WELS_READ_VERIFY (BsGetSe (pBs, &iCode));
370           WELS_CHECK_SE_BOTH_ERROR_NOLOG (iCode, -128, 127, "chroma_weight",
371                                           GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_CHROMA_WEIGHT));
372           pSh->sPredWeightTable.sPredList[iList].iChromaWeight[i][j] = iCode;
373 
374           WELS_READ_VERIFY (BsGetSe (pBs, &iCode));
375           WELS_CHECK_SE_BOTH_ERROR_NOLOG (iCode, -128, 127, "chroma_offset",
376                                           GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_CHROMA_OFFSET));
377           pSh->sPredWeightTable.sPredList[iList].iChromaOffset[i][j] = iCode;
378         }
379       } else {
380         for (int j = 0; j < 2; j++) {
381 
382 
383           pSh->sPredWeightTable.sPredList[iList].iChromaWeight[i][j] = 1 << (pSh->sPredWeightTable.uiChromaLog2WeightDenom);
384           pSh->sPredWeightTable.sPredList[iList].iChromaOffset[i][j] = 0;
385         }
386       }
387 
388     }
389     ++iList;
390     if (pSh->eSliceType != B_SLICE) {
391       break;
392     }
393   } while (iList < LIST_A);//TODO: SUPPORT LIST_A
394   return ERR_NONE;
395 }
396 
CreateImplicitWeightTable(PWelsDecoderContext pCtx)397 void CreateImplicitWeightTable (PWelsDecoderContext pCtx) {
398 
399   PSlice pSlice = &pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer;
400   PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
401   PDqLayer pCurDqLayer = pCtx->pCurDqLayer;
402   if (pCurDqLayer->bUseWeightedBiPredIdc && pSliceHeader->pPps->uiWeightedBipredIdc == 2) {
403     int32_t iPoc = pSliceHeader->iPicOrderCntLsb;
404 
405     //fix Bugzilla 1485229 check if pointers are NULL
406     if (pCtx->sRefPic.pRefList[LIST_0][0] && pCtx->sRefPic.pRefList[LIST_1][0]) {
407       if (pSliceHeader->uiRefCount[0] == 1 && pSliceHeader->uiRefCount[1] == 1
408           && int64_t(pCtx->sRefPic.pRefList[LIST_0][0]->iFramePoc) + int64_t(pCtx->sRefPic.pRefList[LIST_1][0]->iFramePoc) == 2 * int64_t(iPoc)) {
409         pCurDqLayer->bUseWeightedBiPredIdc = false;
410         return;
411       }
412     }
413 
414     pCurDqLayer->pPredWeightTable->uiLumaLog2WeightDenom = 5;
415     pCurDqLayer->pPredWeightTable->uiChromaLog2WeightDenom = 5;
416     for (int32_t iRef0 = 0; iRef0 < pSliceHeader->uiRefCount[0]; iRef0++) {
417       if (pCtx->sRefPic.pRefList[LIST_0][iRef0]) {
418         const int32_t iPoc0 = pCtx->sRefPic.pRefList[LIST_0][iRef0]->iFramePoc;
419         bool bIsLongRef0 = pCtx->sRefPic.pRefList[LIST_0][iRef0]->bIsLongRef;
420         for (int32_t iRef1 = 0; iRef1 < pSliceHeader->uiRefCount[1]; iRef1++) {
421           if (pCtx->sRefPic.pRefList[LIST_1][iRef1]) {
422             const int32_t iPoc1 = pCtx->sRefPic.pRefList[LIST_1][iRef1]->iFramePoc;
423             bool bIsLongRef1 = pCtx->sRefPic.pRefList[LIST_1][iRef1]->bIsLongRef;
424             pCurDqLayer->pPredWeightTable->iImplicitWeight[iRef0][iRef1] = 32;
425             if (!bIsLongRef0 && !bIsLongRef1) {
426               const int32_t iTd = WELS_CLIP3 (iPoc1 - iPoc0, -128, 127);
427               if (iTd) {
428                 int32_t iTb = WELS_CLIP3 (iPoc - iPoc0, -128, 127);
429                 int32_t iTx = (16384 + (WELS_ABS (iTd) >> 1)) / iTd;
430                 int32_t iDistScaleFactor = (iTb * iTx + 32) >> 8;
431                 if (iDistScaleFactor >= -64 && iDistScaleFactor <= 128) {
432                   pCurDqLayer->pPredWeightTable->iImplicitWeight[iRef0][iRef1] = 64 - iDistScaleFactor;
433                 }
434               }
435             }
436           }
437         }
438       }
439     }
440   }
441   return;
442 }
443 
444 /*
445  *  Predeclared function routines ..
446  */
ParseRefPicListReordering(PBitStringAux pBs,PSliceHeader pSh)447 int32_t ParseRefPicListReordering (PBitStringAux pBs, PSliceHeader pSh) {
448   int32_t iList = 0;
449   const EWelsSliceType keSt = pSh->eSliceType;
450   PRefPicListReorderSyn pRefPicListReordering = &pSh->pRefPicListReordering;
451   PSps pSps = pSh->pSps;
452   uint32_t uiCode;
453   if (keSt == I_SLICE || keSt == SI_SLICE)
454     return ERR_NONE;
455 
456   // Common syntaxs for P or B slices: list0, list1 followed if B slices used.
457   do {
458     WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //ref_pic_list_modification_flag_l0
459     pRefPicListReordering->bRefPicListReorderingFlag[iList] = !!uiCode;
460 
461     if (pRefPicListReordering->bRefPicListReorderingFlag[iList]) {
462       int32_t iIdx = 0;
463       do {
464         WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //modification_of_pic_nums_idc
465         const uint32_t kuiIdc = uiCode;
466 
467         //Fixed the referrence list reordering crash issue.(fault kIdc value > 3 case)---
468         if ((iIdx >= MAX_REF_PIC_COUNT) || (kuiIdc > 3)) {
469           return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REF_REORDERING);
470         }
471         pRefPicListReordering->sReorderingSyn[iList][iIdx].uiReorderingOfPicNumsIdc = kuiIdc;
472         if (kuiIdc == 3)
473           break;
474 
475         if (iIdx >= pSh->uiRefCount[iList] || iIdx >= MAX_REF_PIC_COUNT)
476           return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REF_REORDERING);
477 
478         if (kuiIdc == 0 || kuiIdc == 1) {
479           // abs_diff_pic_num_minus1 should be in range 0 to MaxPicNum-1, MaxPicNum is derived as
480           // 2^(4+log2_max_frame_num_minus4)
481           WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //abs_diff_pic_num_minus1
482           WELS_CHECK_SE_UPPER_ERROR_NOLOG (uiCode, (uint32_t) (1 << pSps->uiLog2MaxFrameNum), "abs_diff_pic_num_minus1",
483                                            GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REF_REORDERING));
484           pRefPicListReordering->sReorderingSyn[iList][iIdx].uiAbsDiffPicNumMinus1 = uiCode; // uiAbsDiffPicNumMinus1
485         } else if (kuiIdc == 2) {
486           WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //long_term_pic_num
487           pRefPicListReordering->sReorderingSyn[iList][iIdx].uiLongTermPicNum = uiCode;
488         }
489 
490         ++ iIdx;
491       } while (true);
492     }
493     if (keSt != B_SLICE)
494       break;
495     ++ iList;
496   } while (iList < LIST_A);
497 
498   return ERR_NONE;
499 }
500 
ParseDecRefPicMarking(PWelsDecoderContext pCtx,PBitStringAux pBs,PSliceHeader pSh,PSps pSps,const bool kbIdrFlag)501 int32_t ParseDecRefPicMarking (PWelsDecoderContext pCtx, PBitStringAux pBs, PSliceHeader pSh, PSps pSps,
502                                const bool kbIdrFlag) {
503   PRefPicMarking const kpRefMarking = &pSh->sRefMarking;
504   uint32_t uiCode;
505   if (kbIdrFlag) {
506     WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //no_output_of_prior_pics_flag
507     kpRefMarking->bNoOutputOfPriorPicsFlag = !!uiCode;
508     WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //long_term_reference_flag
509     kpRefMarking->bLongTermRefFlag = !!uiCode;
510   } else {
511     WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //adaptive_ref_pic_marking_mode_flag
512     kpRefMarking->bAdaptiveRefPicMarkingModeFlag = !!uiCode;
513     if (kpRefMarking->bAdaptiveRefPicMarkingModeFlag) {
514       int32_t iIdx = 0;
515       bool bAllowMmco5 = true, bMmco4Exist = false, bMmco5Exist = false, bMmco6Exist = false;
516       do {
517         WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //memory_management_control_operation
518         const uint32_t kuiMmco = uiCode;
519 
520         kpRefMarking->sMmcoRef[iIdx].uiMmcoType = kuiMmco;
521         if (kuiMmco == MMCO_END)
522           break;
523 
524         if (kuiMmco == MMCO_SHORT2UNUSED || kuiMmco == MMCO_SHORT2LONG) {
525           bAllowMmco5 = false;
526           WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //difference_of_pic_nums_minus1
527           kpRefMarking->sMmcoRef[iIdx].iDiffOfPicNum = 1 + uiCode;
528           kpRefMarking->sMmcoRef[iIdx].iShortFrameNum = (pSh->iFrameNum - kpRefMarking->sMmcoRef[iIdx].iDiffOfPicNum) & ((
529                 1 << pSps->uiLog2MaxFrameNum) - 1);
530         } else if (kuiMmco == MMCO_LONG2UNUSED) {
531           bAllowMmco5 = false;
532           WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //long_term_pic_num
533           kpRefMarking->sMmcoRef[iIdx].uiLongTermPicNum = uiCode;
534         }
535         if (kuiMmco == MMCO_SHORT2LONG || kuiMmco == MMCO_LONG) {
536           if (kuiMmco == MMCO_LONG) {
537             WELS_VERIFY_RETURN_IF (-1, bMmco6Exist);
538             bMmco6Exist = true;
539           }
540           WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //long_term_frame_idx
541           kpRefMarking->sMmcoRef[iIdx].iLongTermFrameIdx = uiCode;
542         } else if (kuiMmco == MMCO_SET_MAX_LONG) {
543           WELS_VERIFY_RETURN_IF (-1, bMmco4Exist);
544           bMmco4Exist = true;
545           WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //max_long_term_frame_idx_plus1
546           int32_t iMaxLongTermFrameIdx = -1 + uiCode;
547           if (iMaxLongTermFrameIdx > int32_t (pSps->uiLog2MaxFrameNum)) {
548             //ISO/IEC 14496-10:2009(E) 7.4.3.3 Decoded reference picture marking semantics page 96
549             return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REF_MARKING);
550           }
551           kpRefMarking->sMmcoRef[iIdx].iMaxLongTermFrameIdx = iMaxLongTermFrameIdx;
552         } else if (kuiMmco == MMCO_RESET) {
553           WELS_VERIFY_RETURN_IF (-1, (!bAllowMmco5 || bMmco5Exist));
554           bMmco5Exist = true;
555 
556           pCtx->pLastDecPicInfo->iPrevPicOrderCntLsb = 0;
557           pCtx->pLastDecPicInfo->iPrevPicOrderCntMsb = 0;
558           pSh->iPicOrderCntLsb = 0;
559           if (pCtx->pSliceHeader)
560             pCtx->pSliceHeader->iPicOrderCntLsb = 0;
561         }
562         ++ iIdx;
563 
564       } while (iIdx < MAX_MMCO_COUNT);
565     }
566   }
567 
568   return ERR_NONE;
569 }
570 
FillDefaultSliceHeaderExt(PSliceHeaderExt pShExt,PNalUnitHeaderExt pNalExt)571 bool FillDefaultSliceHeaderExt (PSliceHeaderExt pShExt, PNalUnitHeaderExt pNalExt) {
572   if (pShExt == NULL || pNalExt == NULL)
573     return false;
574 
575   if (pNalExt->iNoInterLayerPredFlag || pNalExt->uiQualityId > 0)
576     pShExt->bBasePredWeightTableFlag = false;
577   else
578     pShExt->bBasePredWeightTableFlag = true;
579   pShExt->uiRefLayerDqId = (uint8_t) - 1;
580   pShExt->uiDisableInterLayerDeblockingFilterIdc        = 0;
581   pShExt->iInterLayerSliceAlphaC0Offset                 = 0;
582   pShExt->iInterLayerSliceBetaOffset                    = 0;
583   pShExt->bConstrainedIntraResamplingFlag               = false;
584   pShExt->uiRefLayerChromaPhaseXPlus1Flag               = 0;
585   pShExt->uiRefLayerChromaPhaseYPlus1                   = 1;
586   //memset(&pShExt->sScaledRefLayer, 0, sizeof(SPosOffset));
587 
588   pShExt->iScaledRefLayerPicWidthInSampleLuma   = pShExt->sSliceHeader.iMbWidth << 4;
589   pShExt->iScaledRefLayerPicHeightInSampleLuma  = pShExt->sSliceHeader.iMbHeight << 4;
590 
591   pShExt->bSliceSkipFlag                = false;
592   pShExt->bAdaptiveBaseModeFlag         = false;
593   pShExt->bDefaultBaseModeFlag          = false;
594   pShExt->bAdaptiveMotionPredFlag       = false;
595   pShExt->bDefaultMotionPredFlag        = false;
596   pShExt->bAdaptiveResidualPredFlag     = false;
597   pShExt->bDefaultResidualPredFlag      = false;
598   pShExt->bTCoeffLevelPredFlag          = false;
599   pShExt->uiScanIdxStart                = 0;
600   pShExt->uiScanIdxEnd                  = 15;
601 
602   return true;
603 }
604 
InitBsBuffer(PWelsDecoderContext pCtx)605 int32_t InitBsBuffer (PWelsDecoderContext pCtx) {
606   if (pCtx == NULL)
607     return ERR_INFO_INVALID_PTR;
608 
609   CMemoryAlign* pMa = pCtx->pMemAlign;
610 
611   pCtx->iMaxBsBufferSizeInByte = MIN_ACCESS_UNIT_CAPACITY * MAX_BUFFERED_NUM;
612   if ((pCtx->sRawData.pHead = static_cast<uint8_t*> (pMa->WelsMallocz (pCtx->iMaxBsBufferSizeInByte,
613                               "pCtx->sRawData.pHead"))) == NULL) {
614     return ERR_INFO_OUT_OF_MEMORY;
615   }
616   pCtx->sRawData.pStartPos = pCtx->sRawData.pCurPos = pCtx->sRawData.pHead;
617   pCtx->sRawData.pEnd = pCtx->sRawData.pHead + pCtx->iMaxBsBufferSizeInByte;
618   if (pCtx->pParam->bParseOnly) {
619     pCtx->pParserBsInfo = static_cast<SParserBsInfo*> (pMa->WelsMallocz (sizeof (SParserBsInfo), "pCtx->pParserBsInfo"));
620     if (pCtx->pParserBsInfo == NULL) {
621       return ERR_INFO_OUT_OF_MEMORY;
622     }
623     memset (pCtx->pParserBsInfo, 0, sizeof (SParserBsInfo));
624     pCtx->pParserBsInfo->pDstBuff = static_cast<uint8_t*> (pMa->WelsMallocz (MAX_ACCESS_UNIT_CAPACITY * sizeof (uint8_t),
625                                     "pCtx->pParserBsInfo->pDstBuff"));
626     if (pCtx->pParserBsInfo->pDstBuff == NULL) {
627       return ERR_INFO_OUT_OF_MEMORY;
628     }
629     memset (pCtx->pParserBsInfo->pDstBuff, 0, MAX_ACCESS_UNIT_CAPACITY * sizeof (uint8_t));
630 
631     if ((pCtx->sSavedData.pHead = static_cast<uint8_t*> (pMa->WelsMallocz (pCtx->iMaxBsBufferSizeInByte,
632                                   "pCtx->sSavedData.pHead"))) == NULL) {
633       return ERR_INFO_OUT_OF_MEMORY;
634     }
635     pCtx->sSavedData.pStartPos = pCtx->sSavedData.pCurPos = pCtx->sSavedData.pHead;
636     pCtx->sSavedData.pEnd = pCtx->sSavedData.pHead + pCtx->iMaxBsBufferSizeInByte;
637 
638     pCtx->iMaxNalNum = MAX_NAL_UNITS_IN_LAYER + 2; //2 reserved for SPS+PPS
639     pCtx->pParserBsInfo->pNalLenInByte = static_cast<int*> (pMa->WelsMallocz (pCtx->iMaxNalNum * sizeof (int),
640                                          "pCtx->pParserBsInfo->pNalLenInByte"));
641     if (pCtx->pParserBsInfo->pNalLenInByte == NULL) {
642       return ERR_INFO_OUT_OF_MEMORY;
643     }
644   }
645   return ERR_NONE;
646 }
647 
ExpandBsBuffer(PWelsDecoderContext pCtx,const int kiSrcLen)648 int32_t ExpandBsBuffer (PWelsDecoderContext pCtx, const int kiSrcLen) {
649   if (pCtx == NULL)
650     return ERR_INFO_INVALID_PTR;
651   int32_t iExpandStepShift = 1;
652   int32_t iNewBuffLen = WELS_MAX ((kiSrcLen * MAX_BUFFERED_NUM), (pCtx->iMaxBsBufferSizeInByte << iExpandStepShift));
653   //allocate new bs buffer
654   CMemoryAlign* pMa = pCtx->pMemAlign;
655 
656   //Realloc sRawData
657   uint8_t* pNewBsBuff = static_cast<uint8_t*> (pMa->WelsMallocz (iNewBuffLen, "pCtx->sRawData.pHead"));
658   if (pNewBsBuff == NULL) {
659     WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "ExpandBsBuffer() Failed for malloc pNewBsBuff (%d)", iNewBuffLen);
660     pCtx->iErrorCode |= dsOutOfMemory;
661     return ERR_INFO_OUT_OF_MEMORY;
662   }
663 
664   //Calculate and set the bs start and end position
665   for (uint32_t i = 0; i <= pCtx->pAccessUnitList->uiActualUnitsNum; i++) {
666     PBitStringAux pSliceBitsRead = &pCtx->pAccessUnitList->pNalUnitsList[i]->sNalData.sVclNal.sSliceBitsRead;
667     pSliceBitsRead->pStartBuf = pSliceBitsRead->pStartBuf - pCtx->sRawData.pHead + pNewBsBuff;
668     pSliceBitsRead->pEndBuf   = pSliceBitsRead->pEndBuf   - pCtx->sRawData.pHead + pNewBsBuff;
669     pSliceBitsRead->pCurBuf   = pSliceBitsRead->pCurBuf   - pCtx->sRawData.pHead + pNewBsBuff;
670   }
671 
672   //Copy current buffer status to new buffer
673   memcpy (pNewBsBuff, pCtx->sRawData.pHead, pCtx->iMaxBsBufferSizeInByte);
674   pCtx->sRawData.pStartPos = pNewBsBuff + (pCtx->sRawData.pStartPos - pCtx->sRawData.pHead);
675   pCtx->sRawData.pCurPos   = pNewBsBuff + (pCtx->sRawData.pCurPos   - pCtx->sRawData.pHead);
676   pCtx->sRawData.pEnd      = pNewBsBuff + iNewBuffLen;
677   pMa->WelsFree (pCtx->sRawData.pHead, "pCtx->sRawData.pHead");
678   pCtx->sRawData.pHead = pNewBsBuff;
679 
680   if (pCtx->pParam->bParseOnly) {
681     //Realloc sSavedData
682     uint8_t* pNewSavedBsBuff = static_cast<uint8_t*> (pMa->WelsMallocz (iNewBuffLen, "pCtx->sSavedData.pHead"));
683     if (pNewSavedBsBuff == NULL) {
684       WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "ExpandBsBuffer() Failed for malloc pNewSavedBsBuff (%d)", iNewBuffLen);
685       pCtx->iErrorCode |= dsOutOfMemory;
686       return ERR_INFO_OUT_OF_MEMORY;
687     }
688 
689     //Copy current buffer status to new buffer
690     memcpy (pNewSavedBsBuff, pCtx->sSavedData.pHead, pCtx->iMaxBsBufferSizeInByte);
691     pCtx->sSavedData.pStartPos = pNewSavedBsBuff + (pCtx->sSavedData.pStartPos - pCtx->sSavedData.pHead);
692     pCtx->sSavedData.pCurPos   = pNewSavedBsBuff + (pCtx->sSavedData.pCurPos   - pCtx->sSavedData.pHead);
693     pCtx->sSavedData.pEnd      = pNewSavedBsBuff + iNewBuffLen;
694     pMa->WelsFree (pCtx->sSavedData.pHead, "pCtx->sSavedData.pHead");
695     pCtx->sSavedData.pHead = pNewSavedBsBuff;
696   }
697 
698   pCtx->iMaxBsBufferSizeInByte = iNewBuffLen;
699   return ERR_NONE;
700 }
701 
ExpandBsLenBuffer(PWelsDecoderContext pCtx,const int kiCurrLen)702 int32_t ExpandBsLenBuffer (PWelsDecoderContext pCtx, const int kiCurrLen) {
703   SParserBsInfo* pParser = pCtx->pParserBsInfo;
704   if (!pParser->pNalLenInByte)
705     return ERR_INFO_INVALID_ACCESS;
706 
707   int iNewLen = kiCurrLen;
708   if (kiCurrLen >= MAX_MB_SIZE + 2) { //exceeds the max MB number of level 5.2
709     WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "Current nal num (%d) exceededs %d.", kiCurrLen, MAX_MB_SIZE);
710     pCtx->iErrorCode |= dsOutOfMemory;
711     return ERR_INFO_OUT_OF_MEMORY;
712   } else {
713     iNewLen = kiCurrLen << 1;
714     iNewLen = WELS_MIN (iNewLen, MAX_MB_SIZE + 2);
715   }
716 
717   CMemoryAlign* pMa = pCtx->pMemAlign;
718   int* pNewLenBuffer = static_cast<int*> (pMa->WelsMallocz (iNewLen * sizeof (int),
719                                           "pCtx->pParserBsInfo->pNalLenInByte"));
720   if (pNewLenBuffer == NULL) {
721     pCtx->iErrorCode |= dsOutOfMemory;
722     return ERR_INFO_OUT_OF_MEMORY;
723   }
724 
725   //copy existing data from old length buffer to new
726   memcpy (pNewLenBuffer, pParser->pNalLenInByte, pCtx->iMaxNalNum * sizeof (int));
727   pMa->WelsFree (pParser->pNalLenInByte, "pCtx->pParserBsInfo->pNalLenInByte");
728   pParser->pNalLenInByte = pNewLenBuffer;
729   pCtx->iMaxNalNum = iNewLen;
730   return ERR_NONE;
731 }
732 
CheckBsBuffer(PWelsDecoderContext pCtx,const int32_t kiSrcLen)733 int32_t CheckBsBuffer (PWelsDecoderContext pCtx, const int32_t kiSrcLen) {
734   if (kiSrcLen > MAX_ACCESS_UNIT_CAPACITY) { //exceeds max allowed data
735     WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "Max AU size exceeded. Allowed size = %d, current size = %d",
736              MAX_ACCESS_UNIT_CAPACITY,
737              kiSrcLen);
738     pCtx->iErrorCode |= dsBitstreamError;
739     return ERR_INFO_INVALID_ACCESS;
740   } else if (kiSrcLen > pCtx->iMaxBsBufferSizeInByte /
741              MAX_BUFFERED_NUM) { //may lead to buffer overwrite, prevent it by expanding buffer
742     if (ExpandBsBuffer (pCtx, kiSrcLen)) {
743       return ERR_INFO_OUT_OF_MEMORY;
744     }
745   }
746 
747   return ERR_NONE;
748 }
749 
750 /*
751  * WelsInitStaticMemory
752  * Memory request for new introduced data
753  * Especially for:
754  * rbsp_au_buffer, cur_dq_layer_ptr and ref_dq_layer_ptr in MB info cache.
755  * return:
756  *  0 - success; otherwise returned error_no defined in error_no.h.
757 */
WelsInitStaticMemory(PWelsDecoderContext pCtx)758 int32_t WelsInitStaticMemory (PWelsDecoderContext pCtx) {
759   if (pCtx == NULL) {
760     return ERR_INFO_INVALID_PTR;
761   }
762 
763   if (MemInitNalList (&pCtx->pAccessUnitList, MAX_NAL_UNIT_NUM_IN_AU, pCtx->pMemAlign) != 0)
764     return ERR_INFO_OUT_OF_MEMORY;
765 
766   if (InitBsBuffer (pCtx) != 0)
767     return ERR_INFO_OUT_OF_MEMORY;
768 
769   pCtx->uiTargetDqId            = (uint8_t) - 1;
770   pCtx->bEndOfStreamFlag        = false;
771 
772   return ERR_NONE;
773 }
774 
775 /*
776  * WelsFreeStaticMemory
777  * Free memory introduced in WelsInitStaticMemory at destruction of decoder.
778  *
779  */
WelsFreeStaticMemory(PWelsDecoderContext pCtx)780 void WelsFreeStaticMemory (PWelsDecoderContext pCtx) {
781   if (pCtx == NULL)
782     return;
783 
784   CMemoryAlign* pMa = pCtx->pMemAlign;
785 
786   MemFreeNalList (&pCtx->pAccessUnitList, pMa);
787 
788   if (pCtx->sRawData.pHead) {
789     pMa->WelsFree (pCtx->sRawData.pHead, "pCtx->sRawData->pHead");
790   }
791   pCtx->sRawData.pHead                = NULL;
792   pCtx->sRawData.pEnd                 = NULL;
793   pCtx->sRawData.pStartPos            = NULL;
794   pCtx->sRawData.pCurPos              = NULL;
795   if (pCtx->pParam->bParseOnly) {
796     if (pCtx->sSavedData.pHead) {
797       pMa->WelsFree (pCtx->sSavedData.pHead, "pCtx->sSavedData->pHead");
798     }
799     pCtx->sSavedData.pHead                = NULL;
800     pCtx->sSavedData.pEnd                 = NULL;
801     pCtx->sSavedData.pStartPos            = NULL;
802     pCtx->sSavedData.pCurPos              = NULL;
803     if (pCtx->pParserBsInfo) {
804       if (pCtx->pParserBsInfo->pNalLenInByte) {
805         pMa->WelsFree (pCtx->pParserBsInfo->pNalLenInByte, "pCtx->pParserBsInfo->pNalLenInByte");
806         pCtx->pParserBsInfo->pNalLenInByte = NULL;
807         pCtx->iMaxNalNum = 0;
808       }
809       if (pCtx->pParserBsInfo->pDstBuff) {
810         pMa->WelsFree (pCtx->pParserBsInfo->pDstBuff, "pCtx->pParserBsInfo->pDstBuff");
811         pCtx->pParserBsInfo->pDstBuff = NULL;
812       }
813       pMa->WelsFree (pCtx->pParserBsInfo, "pCtx->pParserBsInfo");
814       pCtx->pParserBsInfo = NULL;
815     }
816   }
817 
818   if (NULL != pCtx->pParam) {
819     pMa->WelsFree (pCtx->pParam, "pCtx->pParam");
820 
821     pCtx->pParam = NULL;
822   }
823 }
824 /*
825  *  DecodeNalHeaderExt
826  *  Trigger condition: NAL_UNIT_TYPE = NAL_UNIT_PREFIX or NAL_UNIT_CODED_SLICE_EXT
827  *  Parameter:
828  *  pNal:   target NALUnit ptr
829  *  pSrc:   NAL Unit bitstream
830  */
DecodeNalHeaderExt(PNalUnit pNal,uint8_t * pSrc)831 void DecodeNalHeaderExt (PNalUnit pNal, uint8_t* pSrc) {
832   PNalUnitHeaderExt pHeaderExt = &pNal->sNalHeaderExt;
833 
834   uint8_t uiCurByte = *pSrc;
835   pHeaderExt->bIdrFlag              = !! (uiCurByte & 0x40);
836   pHeaderExt->uiPriorityId          = uiCurByte & 0x3F;
837 
838   uiCurByte = * (++pSrc);
839   pHeaderExt->iNoInterLayerPredFlag = uiCurByte >> 7;
840   pHeaderExt->uiDependencyId        = (uiCurByte & 0x70) >> 4;
841   pHeaderExt->uiQualityId           = uiCurByte & 0x0F;
842   uiCurByte = * (++pSrc);
843   pHeaderExt->uiTemporalId          = uiCurByte >> 5;
844   pHeaderExt->bUseRefBasePicFlag    = !! (uiCurByte & 0x10);
845   pHeaderExt->bDiscardableFlag      = !! (uiCurByte & 0x08);
846   pHeaderExt->bOutputFlag           = !! (uiCurByte & 0x04);
847   pHeaderExt->uiReservedThree2Bits  = uiCurByte & 0x03;
848   pHeaderExt->uiLayerDqId           = (pHeaderExt->uiDependencyId << 4) | pHeaderExt->uiQualityId;
849 }
850 
851 
UpdateDecoderStatisticsForActiveParaset(SDecoderStatistics * pDecoderStatistics,PSps pSps,PPps pPps)852 void UpdateDecoderStatisticsForActiveParaset (SDecoderStatistics* pDecoderStatistics,
853     PSps pSps, PPps pPps) {
854   pDecoderStatistics->iCurrentActiveSpsId = pSps->iSpsId;
855 
856   pDecoderStatistics->iCurrentActivePpsId = pPps->iPpsId;
857   pDecoderStatistics->uiProfile = static_cast<unsigned int> (pSps->uiProfileIdc);
858   pDecoderStatistics->uiLevel = pSps->uiLevelIdc;
859 }
860 
861 #define SLICE_HEADER_IDR_PIC_ID_MAX 65535
862 #define SLICE_HEADER_REDUNDANT_PIC_CNT_MAX 127
863 #define SLICE_HEADER_ALPHAC0_BETA_OFFSET_MIN -12
864 #define SLICE_HEADER_ALPHAC0_BETA_OFFSET_MAX 12
865 #define SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MIN -12
866 #define SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MAX 12
867 #define MAX_NUM_REF_IDX_L0_ACTIVE_MINUS1 15
868 #define MAX_NUM_REF_IDX_L1_ACTIVE_MINUS1 15
869 #define SLICE_HEADER_CABAC_INIT_IDC_MAX 2
870 /*
871  *  decode_slice_header_avc
872  *  Parse slice header of bitstream in avc for storing data structure
873  */
ParseSliceHeaderSyntaxs(PWelsDecoderContext pCtx,PBitStringAux pBs,const bool kbExtensionFlag)874 int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, const bool kbExtensionFlag) {
875   PNalUnit const kpCurNal               =
876     pCtx->pAccessUnitList->pNalUnitsList[pCtx->pAccessUnitList->uiAvailUnitsNum -
877                                                                                 1];
878 
879   PNalUnitHeaderExt pNalHeaderExt       = NULL;
880   PSliceHeader pSliceHead               = NULL;
881   PSliceHeaderExt pSliceHeadExt         = NULL;
882   PSubsetSps pSubsetSps                 = NULL;
883   PSps pSps                             = NULL;
884   PPps pPps                             = NULL;
885   EWelsNalUnitType eNalType             = static_cast<EWelsNalUnitType> (0);
886   int32_t iPpsId                        = 0;
887   int32_t iRet                          = ERR_NONE;
888   uint8_t uiSliceType                   = 0;
889   uint8_t uiQualityId                   = BASE_QUALITY_ID;
890   bool  bIdrFlag                        = false;
891   bool  bSgChangeCycleInvolved          = false;        // involved slice group change cycle ?
892   uint32_t uiCode;
893   int32_t iCode;
894   SLogContext* pLogCtx = & (pCtx->sLogCtx);
895 
896   if (kpCurNal == NULL) {
897     return ERR_INFO_OUT_OF_MEMORY;
898   }
899 
900   pNalHeaderExt = &kpCurNal->sNalHeaderExt;
901   pSliceHead    = &kpCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader;
902   eNalType      = pNalHeaderExt->sNalUnitHeader.eNalUnitType;
903 
904   pSliceHeadExt = &kpCurNal->sNalData.sVclNal.sSliceHeaderExt;
905 
906   if (pSliceHeadExt) {
907     SRefBasePicMarking sBaseMarking;
908     const bool kbStoreRefBaseFlag = pSliceHeadExt->bStoreRefBasePicFlag;
909     memcpy (&sBaseMarking, &pSliceHeadExt->sRefBasePicMarking, sizeof (SRefBasePicMarking)); //confirmed_safe_unsafe_usage
910     memset (pSliceHeadExt, 0, sizeof (SSliceHeaderExt));
911     pSliceHeadExt->bStoreRefBasePicFlag = kbStoreRefBaseFlag;
912     memcpy (&pSliceHeadExt->sRefBasePicMarking, &sBaseMarking, sizeof (SRefBasePicMarking)); //confirmed_safe_unsafe_usage
913   }
914 
915   kpCurNal->sNalData.sVclNal.bSliceHeaderExtFlag = kbExtensionFlag;
916 
917   // first_mb_in_slice
918   WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //first_mb_in_slice
919   WELS_CHECK_SE_UPPER_ERROR (uiCode, 36863u, "first_mb_in_slice", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,
920                              ERR_INFO_INVALID_FIRST_MB_IN_SLICE));
921   pSliceHead->iFirstMbInSlice = uiCode;
922 
923   WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //slice_type
924   uiSliceType = uiCode;
925   if (uiSliceType > 9) {
926     WelsLog (pLogCtx, WELS_LOG_WARNING, "slice type too large (%d) at first_mb(%d)", uiSliceType,
927              pSliceHead->iFirstMbInSlice);
928     return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SLICE_TYPE);
929   }
930   if (uiSliceType > 4)
931     uiSliceType -= 5;
932 
933   if ((NAL_UNIT_CODED_SLICE_IDR == eNalType) && (I_SLICE != uiSliceType)) {
934     WelsLog (pLogCtx, WELS_LOG_WARNING, "Invalid slice type(%d) in IDR picture. ", uiSliceType);
935     return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SLICE_TYPE);
936   }
937 
938   if (kbExtensionFlag) {
939     if (uiSliceType > 2) {
940       WelsLog (pLogCtx, WELS_LOG_WARNING, "Invalid slice type(%d).", uiSliceType);
941       return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SLICE_TYPE);
942     }
943   }
944 
945   pSliceHead->eSliceType = static_cast <EWelsSliceType> (uiSliceType);
946 
947   WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //pic_parameter_set_id
948   WELS_CHECK_SE_UPPER_ERROR (uiCode, (MAX_PPS_COUNT - 1), "iPpsId out of range",
949                              GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,
950                                  ERR_INFO_PPS_ID_OVERFLOW));
951   iPpsId = uiCode;
952 
953   //add check PPS available here
954   if (pCtx->sSpsPpsCtx.bPpsAvailFlags[iPpsId] == false) {
955     pCtx->pDecoderStatistics->iPpsReportErrorNum++;
956     if (pCtx->sSpsPpsCtx.iPPSLastInvalidId != iPpsId) {
957       WelsLog (pLogCtx, WELS_LOG_ERROR, "PPS id (%d) is invalid, previous id (%d) error ignored (%d)!", iPpsId,
958                pCtx->sSpsPpsCtx.iPPSLastInvalidId, pCtx->sSpsPpsCtx.iPPSInvalidNum);
959       pCtx->sSpsPpsCtx.iPPSLastInvalidId = iPpsId;
960       pCtx->sSpsPpsCtx.iPPSInvalidNum = 0;
961     } else {
962       pCtx->sSpsPpsCtx.iPPSInvalidNum++;
963     }
964     pCtx->iErrorCode |= dsNoParamSets;
965     return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_PPS_ID);
966   }
967   pCtx->sSpsPpsCtx.iPPSLastInvalidId = -1;
968 
969   pPps    = &pCtx->sSpsPpsCtx.sPpsBuffer[iPpsId];
970 
971   if (pPps->uiNumSliceGroups == 0) {
972     WelsLog (pLogCtx, WELS_LOG_WARNING, "Invalid PPS referenced");
973     pCtx->iErrorCode |= dsNoParamSets;
974     return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_NO_PARAM_SETS);
975   }
976 
977   if (kbExtensionFlag) {
978     pSubsetSps      = &pCtx->sSpsPpsCtx.sSubsetSpsBuffer[pPps->iSpsId];
979     pSps            = &pSubsetSps->sSps;
980     if (pCtx->sSpsPpsCtx.bSubspsAvailFlags[pPps->iSpsId] == false) {
981       pCtx->pDecoderStatistics->iSubSpsReportErrorNum++;
982       if (pCtx->sSpsPpsCtx.iSubSPSLastInvalidId != pPps->iSpsId) {
983         WelsLog (pLogCtx, WELS_LOG_ERROR, "Sub SPS id (%d) is invalid, previous id (%d) error ignored (%d)!", pPps->iSpsId,
984                  pCtx->sSpsPpsCtx.iSubSPSLastInvalidId, pCtx->sSpsPpsCtx.iSubSPSInvalidNum);
985         pCtx->sSpsPpsCtx.iSubSPSLastInvalidId = pPps->iSpsId;
986         pCtx->sSpsPpsCtx.iSubSPSInvalidNum = 0;
987       } else {
988         pCtx->sSpsPpsCtx.iSubSPSInvalidNum++;
989       }
990       pCtx->iErrorCode |= dsNoParamSets;
991       return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SPS_ID);
992     }
993     pCtx->sSpsPpsCtx.iSubSPSLastInvalidId = -1;
994   } else {
995     if (pCtx->sSpsPpsCtx.bSpsAvailFlags[pPps->iSpsId] == false) {
996       pCtx->pDecoderStatistics->iSpsReportErrorNum++;
997       if (pCtx->sSpsPpsCtx.iSPSLastInvalidId != pPps->iSpsId) {
998         WelsLog (pLogCtx, WELS_LOG_ERROR, "SPS id (%d) is invalid, previous id (%d) error ignored (%d)!", pPps->iSpsId,
999                  pCtx->sSpsPpsCtx.iSPSLastInvalidId, pCtx->sSpsPpsCtx.iSPSInvalidNum);
1000         pCtx->sSpsPpsCtx.iSPSLastInvalidId = pPps->iSpsId;
1001         pCtx->sSpsPpsCtx.iSPSInvalidNum = 0;
1002       } else {
1003         pCtx->sSpsPpsCtx.iSPSInvalidNum++;
1004       }
1005       pCtx->iErrorCode |= dsNoParamSets;
1006       return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SPS_ID);
1007     }
1008     pCtx->sSpsPpsCtx.iSPSLastInvalidId = -1;
1009     pSps = &pCtx->sSpsPpsCtx.sSpsBuffer[pPps->iSpsId];
1010   }
1011   pSliceHead->iPpsId = iPpsId;
1012   pSliceHead->iSpsId = pPps->iSpsId;
1013   pSliceHead->pPps   = pPps;
1014   pSliceHead->pSps   = pSps;
1015 
1016   pSliceHeadExt->pSubsetSps = pSubsetSps;
1017 
1018   if (pSps->iNumRefFrames == 0) {
1019     if ((uiSliceType != I_SLICE) && (uiSliceType != SI_SLICE)) {
1020       WelsLog (pLogCtx, WELS_LOG_WARNING, "slice_type (%d) not supported for num_ref_frames = 0.", uiSliceType);
1021       return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SLICE_TYPE);
1022     }
1023   }
1024 
1025   bIdrFlag = (!kbExtensionFlag && eNalType == NAL_UNIT_CODED_SLICE_IDR) || (kbExtensionFlag && pNalHeaderExt->bIdrFlag);
1026   pSliceHead->bIdrFlag = bIdrFlag;
1027 
1028   if (pSps->uiLog2MaxFrameNum == 0) {
1029     WelsLog (pLogCtx, WELS_LOG_WARNING, "non existing SPS referenced");
1030     return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_NO_PARAM_SETS);
1031   }
1032   // check first_mb_in_slice
1033   WELS_CHECK_SE_UPPER_ERROR ((uint32_t) (pSliceHead->iFirstMbInSlice), (pSps->uiTotalMbCount - 1), "first_mb_in_slice",
1034                              GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_FIRST_MB_IN_SLICE));
1035   WELS_READ_VERIFY (BsGetBits (pBs, pSps->uiLog2MaxFrameNum, &uiCode)); //frame_num
1036   pSliceHead->iFrameNum = uiCode;
1037 
1038   pSliceHead->bFieldPicFlag    = false;
1039   pSliceHead->bBottomFiledFlag = false;
1040   if (!pSps->bFrameMbsOnlyFlag) {
1041     WelsLog (pLogCtx, WELS_LOG_WARNING, "ParseSliceHeaderSyntaxs(): frame_mbs_only_flag = %d not supported. ",
1042              pSps->bFrameMbsOnlyFlag);
1043     return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_MBAFF);
1044   }
1045   pSliceHead->iMbWidth  = pSps->iMbWidth;
1046   pSliceHead->iMbHeight = pSps->iMbHeight / (1 + pSliceHead->bFieldPicFlag);
1047 
1048   if (bIdrFlag) {
1049     if (pSliceHead->iFrameNum != 0) {
1050       WelsLog (pLogCtx, WELS_LOG_WARNING,
1051                "ParseSliceHeaderSyntaxs(), invaild frame number: %d due to IDR frame introduced!",
1052                pSliceHead->iFrameNum);
1053       return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_FRAME_NUM);
1054     }
1055     WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //idr_pic_id
1056     // standard 7.4.3 idr_pic_id should be in range 0 to 65535, inclusive.
1057     WELS_CHECK_SE_UPPER_ERROR (uiCode, SLICE_HEADER_IDR_PIC_ID_MAX, "idr_pic_id", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,
1058                                ERR_INFO_INVALID_IDR_PIC_ID));
1059     pSliceHead->uiIdrPicId = uiCode; /* uiIdrPicId */
1060 #ifdef LONG_TERM_REF
1061     pCtx->uiCurIdrPicId = pSliceHead->uiIdrPicId;
1062 #endif
1063   }
1064 
1065   pSliceHead->iDeltaPicOrderCntBottom = 0;
1066   pSliceHead->iDeltaPicOrderCnt[0] =
1067     pSliceHead->iDeltaPicOrderCnt[1] = 0;
1068   if (pSps->uiPocType == 0) {
1069     WELS_READ_VERIFY (BsGetBits (pBs, pSps->iLog2MaxPocLsb, &uiCode)); //pic_order_cnt_lsb
1070     const int32_t iMaxPocLsb = 1 << (pSps->iLog2MaxPocLsb);
1071     pSliceHead->iPicOrderCntLsb = uiCode;
1072     if (pPps->bPicOrderPresentFlag && !pSliceHead->bFieldPicFlag) {
1073       WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //delta_pic_order_cnt_bottom
1074       pSliceHead->iDeltaPicOrderCntBottom = iCode;
1075     }
1076     //Calculate poc if necessary
1077     int32_t pocLsb = pSliceHead->iPicOrderCntLsb;
1078     if (pSliceHead->bIdrFlag || kpCurNal->sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR) {
1079       pCtx->pLastDecPicInfo->iPrevPicOrderCntMsb = 0;
1080       pCtx->pLastDecPicInfo->iPrevPicOrderCntLsb = 0;
1081     }
1082     int32_t pocMsb;
1083     if (pocLsb < pCtx->pLastDecPicInfo->iPrevPicOrderCntLsb
1084         && pCtx->pLastDecPicInfo->iPrevPicOrderCntLsb - pocLsb >= iMaxPocLsb / 2)
1085       pocMsb = pCtx->pLastDecPicInfo->iPrevPicOrderCntMsb + iMaxPocLsb;
1086     else if (pocLsb > pCtx->pLastDecPicInfo->iPrevPicOrderCntLsb
1087              && pocLsb - pCtx->pLastDecPicInfo->iPrevPicOrderCntLsb > iMaxPocLsb / 2)
1088       pocMsb = pCtx->pLastDecPicInfo->iPrevPicOrderCntMsb - iMaxPocLsb;
1089     else
1090       pocMsb = pCtx->pLastDecPicInfo->iPrevPicOrderCntMsb;
1091     pSliceHead->iPicOrderCntLsb = pocMsb + pocLsb;
1092 
1093     if (pPps->bPicOrderPresentFlag && !pSliceHead->bFieldPicFlag) {
1094       pSliceHead->iPicOrderCntLsb += pSliceHead->iDeltaPicOrderCntBottom;
1095     }
1096 
1097     if (kpCurNal->sNalHeaderExt.sNalUnitHeader.uiNalRefIdc != 0) {
1098       pCtx->pLastDecPicInfo->iPrevPicOrderCntLsb = pocLsb;
1099       pCtx->pLastDecPicInfo->iPrevPicOrderCntMsb = pocMsb;
1100     }
1101     //End of Calculating poc
1102   } else if (pSps->uiPocType == 1 && !pSps->bDeltaPicOrderAlwaysZeroFlag) {
1103     WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //delta_pic_order_cnt[ 0 ]
1104     pSliceHead->iDeltaPicOrderCnt[0] = iCode;
1105     if (pPps->bPicOrderPresentFlag && !pSliceHead->bFieldPicFlag) {
1106       WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //delta_pic_order_cnt[ 1 ]
1107       pSliceHead->iDeltaPicOrderCnt[1] = iCode;
1108     }
1109   }
1110   pSliceHead->iRedundantPicCnt = 0;
1111   if (pPps->bRedundantPicCntPresentFlag) {
1112     WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //redundant_pic_cnt
1113     // standard section 7.4.3, redundant_pic_cnt should be in range 0 to 127, inclusive.
1114     WELS_CHECK_SE_UPPER_ERROR (uiCode, SLICE_HEADER_REDUNDANT_PIC_CNT_MAX, "redundant_pic_cnt",
1115                                GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REDUNDANT_PIC_CNT));
1116     pSliceHead->iRedundantPicCnt = uiCode;
1117     if (pSliceHead->iRedundantPicCnt > 0) {
1118       WelsLog (pLogCtx, WELS_LOG_WARNING, "Redundant picture not supported!");
1119       return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REDUNDANT_PIC_CNT);
1120     }
1121   }
1122 
1123   if (B_SLICE == uiSliceType) {
1124     //fix me: it needs to use the this flag somewhere for B-Sclice
1125     WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //direct_spatial_mv_pred_flag
1126     pSliceHead->iDirectSpatialMvPredFlag = uiCode;
1127   }
1128 
1129   //set defaults, might be overriden a few line later
1130   pSliceHead->uiRefCount[0] = pPps->uiNumRefIdxL0Active;
1131   pSliceHead->uiRefCount[1] = pPps->uiNumRefIdxL1Active;
1132 
1133   bool bReadNumRefFlag = (P_SLICE == uiSliceType || B_SLICE == uiSliceType);
1134   if (kbExtensionFlag) {
1135     bReadNumRefFlag &= (BASE_QUALITY_ID == pNalHeaderExt->uiQualityId);
1136   }
1137   if (bReadNumRefFlag) {
1138     WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //num_ref_idx_active_override_flag
1139     pSliceHead->bNumRefIdxActiveOverrideFlag = !!uiCode;
1140     if (pSliceHead->bNumRefIdxActiveOverrideFlag) {
1141       WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //num_ref_idx_l0_active_minus1
1142       WELS_CHECK_SE_UPPER_ERROR (uiCode, MAX_NUM_REF_IDX_L0_ACTIVE_MINUS1, "num_ref_idx_l0_active_minus1",
1143                                  GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_NUM_REF_IDX_L0_ACTIVE_MINUS1));
1144       pSliceHead->uiRefCount[0] = 1 + uiCode;
1145       if (B_SLICE == uiSliceType) {
1146         WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //num_ref_idx_l1_active_minus1
1147         WELS_CHECK_SE_UPPER_ERROR (uiCode, MAX_NUM_REF_IDX_L1_ACTIVE_MINUS1, "num_ref_idx_l1_active_minus1",
1148                                    GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_NUM_REF_IDX_L1_ACTIVE_MINUS1));
1149         pSliceHead->uiRefCount[1] = 1 + uiCode;
1150       }
1151     }
1152   }
1153 
1154   if (pSliceHead->uiRefCount[0] > MAX_REF_PIC_COUNT || pSliceHead->uiRefCount[1] > MAX_REF_PIC_COUNT) {
1155     WelsLog (pLogCtx, WELS_LOG_WARNING, "reference overflow");
1156     return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_REF_COUNT_OVERFLOW);
1157   }
1158 
1159   if (BASE_QUALITY_ID == uiQualityId) {
1160     iRet = ParseRefPicListReordering (pBs, pSliceHead);
1161     if (iRet != ERR_NONE) {
1162       WelsLog (pLogCtx, WELS_LOG_WARNING, "invalid ref pPic list reordering syntaxs!");
1163       return iRet;
1164     }
1165 
1166     if ((pPps->bWeightedPredFlag && uiSliceType == P_SLICE) || (pPps->uiWeightedBipredIdc == 1 && uiSliceType == B_SLICE)) {
1167       iRet = ParsePredWeightedTable (pBs, pSliceHead);
1168       if (iRet != ERR_NONE) {
1169         WelsLog (pLogCtx, WELS_LOG_WARNING, "invalid weighted prediction syntaxs!");
1170         return iRet;
1171       }
1172     }
1173 
1174     if (kbExtensionFlag) {
1175       if (pNalHeaderExt->iNoInterLayerPredFlag || pNalHeaderExt->uiQualityId > 0)
1176         pSliceHeadExt->bBasePredWeightTableFlag = false;
1177       else
1178         pSliceHeadExt->bBasePredWeightTableFlag = true;
1179     }
1180 
1181     if (kpCurNal->sNalHeaderExt.sNalUnitHeader.uiNalRefIdc != 0) {
1182       iRet = ParseDecRefPicMarking (pCtx, pBs, pSliceHead, pSps, bIdrFlag);
1183       if (iRet != ERR_NONE) {
1184         return iRet;
1185       }
1186 
1187       if (kbExtensionFlag && !pSubsetSps->sSpsSvcExt.bSliceHeaderRestrictionFlag) {
1188         WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //store_ref_base_pic_flag
1189         pSliceHeadExt->bStoreRefBasePicFlag = !!uiCode;
1190         if ((pNalHeaderExt->bUseRefBasePicFlag || pSliceHeadExt->bStoreRefBasePicFlag) && !bIdrFlag) {
1191           WelsLog (pLogCtx, WELS_LOG_WARNING,
1192                    "ParseSliceHeaderSyntaxs(): bUseRefBasePicFlag or bStoreRefBasePicFlag = 1 not supported.");
1193           return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_ILP);
1194         }
1195       }
1196     }
1197   }
1198 
1199   if (pPps->bEntropyCodingModeFlag) {
1200     if (pSliceHead->eSliceType != I_SLICE && pSliceHead->eSliceType != SI_SLICE) {
1201       WELS_READ_VERIFY (BsGetUe (pBs, &uiCode));
1202       WELS_CHECK_SE_UPPER_ERROR (uiCode, SLICE_HEADER_CABAC_INIT_IDC_MAX, "cabac_init_idc", ERR_INFO_INVALID_CABAC_INIT_IDC);
1203       pSliceHead->iCabacInitIdc = uiCode;
1204     } else
1205       pSliceHead->iCabacInitIdc = 0;
1206   }
1207 
1208   WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //slice_qp_delta
1209   pSliceHead->iSliceQpDelta     = iCode;
1210   pSliceHead->iSliceQp          = pPps->iPicInitQp + pSliceHead->iSliceQpDelta;
1211   if (pSliceHead->iSliceQp < 0 || pSliceHead->iSliceQp > 51) {
1212     WelsLog (pLogCtx, WELS_LOG_WARNING, "QP %d out of range", pSliceHead->iSliceQp);
1213     return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_QP);
1214   }
1215 
1216   //FIXME qscale / qp ... stuff
1217   if (!kbExtensionFlag) {
1218     if (uiSliceType == SP_SLICE || uiSliceType == SI_SLICE) {
1219       WelsLog (pLogCtx, WELS_LOG_WARNING, "SP/SI not supported");
1220       return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_SPSI);
1221     }
1222   }
1223 
1224   pSliceHead->uiDisableDeblockingFilterIdc = 0;
1225   pSliceHead->iSliceAlphaC0Offset          = 0;
1226   pSliceHead->iSliceBetaOffset             = 0;
1227   if (pPps->bDeblockingFilterControlPresentFlag) {
1228     WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //disable_deblocking_filter_idc
1229     pSliceHead->uiDisableDeblockingFilterIdc = uiCode;
1230     //refer to JVT-X201wcm1.doc G.7.4.3.4--2010.4.20
1231     if (pSliceHead->uiDisableDeblockingFilterIdc > 6) {
1232       WelsLog (pLogCtx, WELS_LOG_WARNING, "disable_deblock_filter_idc (%d) out of range [0, 6]",
1233                pSliceHead->uiDisableDeblockingFilterIdc);
1234       return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_DBLOCKING_IDC);
1235     }
1236     if (pSliceHead->uiDisableDeblockingFilterIdc != 1) {
1237       WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //slice_alpha_c0_offset_div2
1238       pSliceHead->iSliceAlphaC0Offset = iCode * 2;
1239       WELS_CHECK_SE_BOTH_ERROR (pSliceHead->iSliceAlphaC0Offset, SLICE_HEADER_ALPHAC0_BETA_OFFSET_MIN,
1240                                 SLICE_HEADER_ALPHAC0_BETA_OFFSET_MAX, "slice_alpha_c0_offset_div2 * 2", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,
1241                                     ERR_INFO_INVALID_SLICE_ALPHA_C0_OFFSET_DIV2));
1242       WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //slice_beta_offset_div2
1243       pSliceHead->iSliceBetaOffset = iCode * 2;
1244       WELS_CHECK_SE_BOTH_ERROR (pSliceHead->iSliceBetaOffset, SLICE_HEADER_ALPHAC0_BETA_OFFSET_MIN,
1245                                 SLICE_HEADER_ALPHAC0_BETA_OFFSET_MAX, "slice_beta_offset_div2 * 2", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,
1246                                     ERR_INFO_INVALID_SLICE_BETA_OFFSET_DIV2));
1247     }
1248   }
1249 
1250   bSgChangeCycleInvolved = (pPps->uiNumSliceGroups > 1 && pPps->uiSliceGroupMapType >= 3
1251                             && pPps->uiSliceGroupMapType <= 5);
1252   if (kbExtensionFlag && bSgChangeCycleInvolved)
1253     bSgChangeCycleInvolved = (bSgChangeCycleInvolved && (uiQualityId == BASE_QUALITY_ID));
1254   if (bSgChangeCycleInvolved) {
1255     if (pPps->uiSliceGroupChangeRate > 0) {
1256       const int32_t kiNumBits = (int32_t)WELS_CEIL (log (static_cast<double> (1 + pPps->uiPicSizeInMapUnits /
1257                                 pPps->uiSliceGroupChangeRate)));
1258       WELS_READ_VERIFY (BsGetBits (pBs, kiNumBits, &uiCode)); //lice_group_change_cycle
1259       pSliceHead->iSliceGroupChangeCycle = uiCode;
1260     } else
1261       pSliceHead->iSliceGroupChangeCycle = 0;
1262   }
1263 
1264   if (!kbExtensionFlag) {
1265     FillDefaultSliceHeaderExt (pSliceHeadExt, pNalHeaderExt);
1266   } else {
1267     /* Extra syntax elements newly introduced */
1268     pSliceHeadExt->pSubsetSps = pSubsetSps;
1269 
1270     if (!pNalHeaderExt->iNoInterLayerPredFlag && BASE_QUALITY_ID == uiQualityId) {
1271       //the following should be deleted for CODE_CLEAN
1272       WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //ref_layer_dq_id
1273       pSliceHeadExt->uiRefLayerDqId = uiCode;
1274       if (pSubsetSps->sSpsSvcExt.bInterLayerDeblockingFilterCtrlPresentFlag) {
1275         WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //disable_inter_layer_deblocking_filter_idc
1276         pSliceHeadExt->uiDisableInterLayerDeblockingFilterIdc = uiCode;
1277         //refer to JVT-X201wcm1.doc G.7.4.3.4--2010.4.20
1278         if (pSliceHeadExt->uiDisableInterLayerDeblockingFilterIdc > 6) {
1279           WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "disable_inter_layer_deblock_filter_idc (%d) out of range [0, 6]",
1280                    pSliceHeadExt->uiDisableInterLayerDeblockingFilterIdc);
1281           return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_DBLOCKING_IDC);
1282         }
1283         if (pSliceHeadExt->uiDisableInterLayerDeblockingFilterIdc != 1) {
1284           WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //inter_layer_slice_alpha_c0_offset_div2
1285           pSliceHeadExt->iInterLayerSliceAlphaC0Offset = iCode * 2;
1286           WELS_CHECK_SE_BOTH_ERROR (pSliceHeadExt->iInterLayerSliceAlphaC0Offset,
1287                                     SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MIN, SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MAX,
1288                                     "inter_layer_alpha_c0_offset_div2 * 2", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,
1289                                         ERR_INFO_INVALID_SLICE_ALPHA_C0_OFFSET_DIV2));
1290           WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //inter_layer_slice_beta_offset_div2
1291           pSliceHeadExt->iInterLayerSliceBetaOffset = iCode * 2;
1292           WELS_CHECK_SE_BOTH_ERROR (pSliceHeadExt->iInterLayerSliceBetaOffset, SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MIN,
1293                                     SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MAX, "inter_layer_slice_beta_offset_div2 * 2",
1294                                     GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SLICE_BETA_OFFSET_DIV2));
1295         }
1296       }
1297 
1298       pSliceHeadExt->uiRefLayerChromaPhaseXPlus1Flag = pSubsetSps->sSpsSvcExt.uiSeqRefLayerChromaPhaseXPlus1Flag;
1299       pSliceHeadExt->uiRefLayerChromaPhaseYPlus1     = pSubsetSps->sSpsSvcExt.uiSeqRefLayerChromaPhaseYPlus1;
1300 
1301       WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //constrained_intra_resampling_flag
1302       pSliceHeadExt->bConstrainedIntraResamplingFlag = !!uiCode;
1303 
1304       {
1305         SPosOffset pos;
1306         pos.iLeftOffset   = pSubsetSps->sSpsSvcExt.sSeqScaledRefLayer.iLeftOffset;
1307         pos.iTopOffset    = pSubsetSps->sSpsSvcExt.sSeqScaledRefLayer.iTopOffset * (2 - pSps->bFrameMbsOnlyFlag);
1308         pos.iRightOffset  = pSubsetSps->sSpsSvcExt.sSeqScaledRefLayer.iRightOffset;
1309         pos.iBottomOffset = pSubsetSps->sSpsSvcExt.sSeqScaledRefLayer.iBottomOffset * (2 - pSps->bFrameMbsOnlyFlag);
1310         //memcpy(&pSliceHeadExt->sScaledRefLayer, &pos, sizeof(SPosOffset));//confirmed_safe_unsafe_usage
1311         pSliceHeadExt->iScaledRefLayerPicWidthInSampleLuma  = (pSliceHead->iMbWidth << 4) -
1312             (pos.iLeftOffset + pos.iRightOffset);
1313         pSliceHeadExt->iScaledRefLayerPicHeightInSampleLuma = (pSliceHead->iMbHeight << 4) -
1314             (pos.iTopOffset + pos.iBottomOffset) / (1 + pSliceHead->bFieldPicFlag);
1315       }
1316     } else if (uiQualityId > BASE_QUALITY_ID) {
1317       WelsLog (pLogCtx, WELS_LOG_WARNING, "MGS not supported.");
1318       return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_MGS);
1319     } else {
1320       pSliceHeadExt->uiRefLayerDqId = (uint8_t) - 1;
1321     }
1322 
1323     pSliceHeadExt->bSliceSkipFlag            = false;
1324     pSliceHeadExt->bAdaptiveBaseModeFlag     = false;
1325     pSliceHeadExt->bDefaultBaseModeFlag      = false;
1326     pSliceHeadExt->bAdaptiveMotionPredFlag   = false;
1327     pSliceHeadExt->bDefaultMotionPredFlag    = false;
1328     pSliceHeadExt->bAdaptiveResidualPredFlag = false;
1329     pSliceHeadExt->bDefaultResidualPredFlag  = false;
1330     if (pNalHeaderExt->iNoInterLayerPredFlag)
1331       pSliceHeadExt->bTCoeffLevelPredFlag    = false;
1332     else
1333       pSliceHeadExt->bTCoeffLevelPredFlag    = pSubsetSps->sSpsSvcExt.bSeqTCoeffLevelPredFlag;
1334 
1335     if (!pNalHeaderExt->iNoInterLayerPredFlag) {
1336       WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //slice_skip_flag
1337       pSliceHeadExt->bSliceSkipFlag = !!uiCode;
1338       if (pSliceHeadExt->bSliceSkipFlag) {
1339         WelsLog (pLogCtx, WELS_LOG_WARNING, "bSliceSkipFlag == 1 not supported.");
1340         return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_SLICESKIP);
1341       } else {
1342         WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //adaptive_base_mode_flag
1343         pSliceHeadExt->bAdaptiveBaseModeFlag = !!uiCode;
1344         if (!pSliceHeadExt->bAdaptiveBaseModeFlag) {
1345           WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //default_base_mode_flag
1346           pSliceHeadExt->bDefaultBaseModeFlag = !!uiCode;
1347         }
1348         if (!pSliceHeadExt->bDefaultBaseModeFlag) {
1349           WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //adaptive_motion_prediction_flag
1350           pSliceHeadExt->bAdaptiveMotionPredFlag = !!uiCode;
1351           if (!pSliceHeadExt->bAdaptiveMotionPredFlag) {
1352             WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //default_motion_prediction_flag
1353             pSliceHeadExt->bDefaultMotionPredFlag = !!uiCode;
1354           }
1355         }
1356 
1357         WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //adaptive_residual_prediction_flag
1358         pSliceHeadExt->bAdaptiveResidualPredFlag = !!uiCode;
1359         if (!pSliceHeadExt->bAdaptiveResidualPredFlag) {
1360           WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //default_residual_prediction_flag
1361           pSliceHeadExt->bDefaultResidualPredFlag = !!uiCode;
1362         }
1363       }
1364       if (pSubsetSps->sSpsSvcExt.bAdaptiveTCoeffLevelPredFlag) {
1365         WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //tcoeff_level_prediction_flag
1366         pSliceHeadExt->bTCoeffLevelPredFlag = !!uiCode;
1367       }
1368     }
1369 
1370     if (!pSubsetSps->sSpsSvcExt.bSliceHeaderRestrictionFlag) {
1371       WELS_READ_VERIFY (BsGetBits (pBs, 4, &uiCode)); //scan_idx_start
1372       pSliceHeadExt->uiScanIdxStart = uiCode;
1373       WELS_READ_VERIFY (BsGetBits (pBs, 4, &uiCode)); //scan_idx_end
1374       pSliceHeadExt->uiScanIdxEnd = uiCode;
1375       if (pSliceHeadExt->uiScanIdxStart != 0 || pSliceHeadExt->uiScanIdxEnd != 15) {
1376         WelsLog (pLogCtx, WELS_LOG_WARNING, "uiScanIdxStart (%d) != 0 and uiScanIdxEnd (%d) !=15 not supported here",
1377                  pSliceHeadExt->uiScanIdxStart, pSliceHeadExt->uiScanIdxEnd);
1378         return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_MGS);
1379       }
1380     } else {
1381       pSliceHeadExt->uiScanIdxStart = 0;
1382       pSliceHeadExt->uiScanIdxEnd   = 15;
1383     }
1384   }
1385 
1386   return ERR_NONE;
1387 }
1388 
1389 /*
1390  *  Copy relative syntax elements of NALUnitHeaderExt, sRefPicBaseMarking and bStoreRefBasePicFlag in prefix nal unit.
1391  *  pSrc:   mark as decoded prefix NAL
1392  *  ppDst:  succeeded VCL NAL based AVC (I/P Slice)
1393  */
PrefetchNalHeaderExtSyntax(PWelsDecoderContext pCtx,PNalUnit const kppDst,PNalUnit const kpSrc)1394 bool PrefetchNalHeaderExtSyntax (PWelsDecoderContext pCtx, PNalUnit const kppDst, PNalUnit const kpSrc) {
1395   PNalUnitHeaderExt pNalHdrExtD = NULL, pNalHdrExtS = NULL;
1396   PSliceHeaderExt pShExtD = NULL;
1397   PPrefixNalUnit pPrefixS = NULL;
1398   PSps pSps = NULL;
1399   int32_t iIdx = 0;
1400 
1401   if (kppDst == NULL || kpSrc == NULL)
1402     return false;
1403 
1404   pNalHdrExtD   = &kppDst->sNalHeaderExt;
1405   pNalHdrExtS   = &kpSrc->sNalHeaderExt;
1406   pShExtD       = &kppDst->sNalData.sVclNal.sSliceHeaderExt;
1407   pPrefixS      = &kpSrc->sNalData.sPrefixNal;
1408   pSps          = &pCtx->sSpsPpsCtx.sSpsBuffer[pCtx->sSpsPpsCtx.sPpsBuffer[pShExtD->sSliceHeader.iPpsId].iSpsId];
1409 
1410   pNalHdrExtD->uiDependencyId           = pNalHdrExtS->uiDependencyId;
1411   pNalHdrExtD->uiQualityId              = pNalHdrExtS->uiQualityId;
1412   pNalHdrExtD->uiTemporalId             = pNalHdrExtS->uiTemporalId;
1413   pNalHdrExtD->uiPriorityId             = pNalHdrExtS->uiPriorityId;
1414   pNalHdrExtD->bIdrFlag                 = pNalHdrExtS->bIdrFlag;
1415   pNalHdrExtD->iNoInterLayerPredFlag    = pNalHdrExtS->iNoInterLayerPredFlag;
1416   pNalHdrExtD->bDiscardableFlag         = pNalHdrExtS->bDiscardableFlag;
1417   pNalHdrExtD->bOutputFlag              = pNalHdrExtS->bOutputFlag;
1418   pNalHdrExtD->bUseRefBasePicFlag       = pNalHdrExtS->bUseRefBasePicFlag;
1419   pNalHdrExtD->uiLayerDqId              = pNalHdrExtS->uiLayerDqId;
1420 
1421   pShExtD->bStoreRefBasePicFlag         = pPrefixS->bStoreRefBasePicFlag;
1422   memcpy (&pShExtD->sRefBasePicMarking, &pPrefixS->sRefPicBaseMarking,
1423           sizeof (SRefBasePicMarking)); //confirmed_safe_unsafe_usage
1424   if (pShExtD->sRefBasePicMarking.bAdaptiveRefBasePicMarkingModeFlag) {
1425     PRefBasePicMarking pRefBasePicMarking = &pShExtD->sRefBasePicMarking;
1426     iIdx = 0;
1427     do {
1428       if (pRefBasePicMarking->mmco_base[iIdx].uiMmcoType == MMCO_END)
1429         break;
1430       if (pRefBasePicMarking->mmco_base[iIdx].uiMmcoType == MMCO_SHORT2UNUSED)
1431         pRefBasePicMarking->mmco_base[iIdx].iShortFrameNum = (pShExtD->sSliceHeader.iFrameNum -
1432             pRefBasePicMarking->mmco_base[iIdx].uiDiffOfPicNums) & ((1 << pSps->uiLog2MaxFrameNum) - 1);
1433       ++ iIdx;
1434     } while (iIdx < MAX_MMCO_COUNT);
1435   }
1436 
1437   return true;
1438 }
1439 
1440 
1441 
UpdateAccessUnit(PWelsDecoderContext pCtx)1442 int32_t UpdateAccessUnit (PWelsDecoderContext pCtx) {
1443   PAccessUnit pCurAu   = pCtx->pAccessUnitList;
1444   int32_t iIdx         = pCurAu->uiEndPos;
1445 
1446   // Conversed iterator
1447   pCtx->uiTargetDqId = pCurAu->pNalUnitsList[iIdx]->sNalHeaderExt.uiLayerDqId;
1448   pCurAu->uiActualUnitsNum  = iIdx + 1;
1449   pCurAu->bCompletedAuFlag = true;
1450 
1451   // Added for mosaic avoidance, 11/19/2009
1452 #ifdef LONG_TERM_REF
1453   if (pCtx->bParamSetsLostFlag || pCtx->bNewSeqBegin)
1454 #else
1455   if (pCtx->bReferenceLostAtT0Flag || pCtx->bNewSeqBegin)
1456 #endif
1457   {
1458     uint32_t uiActualIdx = 0;
1459     while (uiActualIdx < pCurAu->uiActualUnitsNum) {
1460       PNalUnit nal = pCurAu->pNalUnitsList[uiActualIdx];
1461 
1462       if (nal->sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR || nal->sNalHeaderExt.bIdrFlag) {
1463         break;
1464       }
1465       ++ uiActualIdx;
1466     }
1467     if (uiActualIdx ==
1468         pCurAu->uiActualUnitsNum) { // no found IDR nal within incoming AU, need exit to avoid mosaic issue, 11/19/2009
1469 
1470       pCtx->pDecoderStatistics->uiIDRLostNum++;
1471       if (!pCtx->bParamSetsLostFlag)
1472         WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
1473                  "UpdateAccessUnit():::::Key frame lost.....CAN NOT find IDR from current AU.");
1474       pCtx->iErrorCode |= dsRefLost;
1475       if (pCtx->pParam->eEcActiveIdc == ERROR_CON_DISABLE) {
1476 #ifdef LONG_TERM_REF
1477         pCtx->iErrorCode |= dsNoParamSets;
1478         return dsNoParamSets;
1479 #else
1480         pCtx->iErrorCode |= dsRefLost;
1481         return ERR_INFO_REFERENCE_PIC_LOST;
1482 #endif
1483       }
1484     }
1485   }
1486 
1487   return ERR_NONE;
1488 }
1489 
InitialDqLayersContext(PWelsDecoderContext pCtx,const int32_t kiMaxWidth,const int32_t kiMaxHeight)1490 int32_t InitialDqLayersContext (PWelsDecoderContext pCtx, const int32_t kiMaxWidth, const int32_t kiMaxHeight) {
1491   int32_t i = 0;
1492   WELS_VERIFY_RETURN_IF (ERR_INFO_INVALID_PARAM, (NULL == pCtx || kiMaxWidth <= 0 || kiMaxHeight <= 0))
1493   pCtx->sMb.iMbWidth  = (kiMaxWidth + 15) >> 4;
1494   pCtx->sMb.iMbHeight = (kiMaxHeight + 15) >> 4;
1495 
1496   if (pCtx->bInitialDqLayersMem && kiMaxWidth <= pCtx->iPicWidthReq
1497       && kiMaxHeight <= pCtx->iPicHeightReq) // have same dimension memory, skipped
1498     return ERR_NONE;
1499 
1500   CMemoryAlign* pMa = pCtx->pMemAlign;
1501 
1502   UninitialDqLayersContext (pCtx);
1503 
1504   do {
1505     PDqLayer pDq = (PDqLayer)pMa->WelsMallocz (sizeof (SDqLayer), "PDqLayer");
1506 
1507     if (pDq == NULL)
1508       return ERR_INFO_OUT_OF_MEMORY;
1509 
1510     pCtx->pDqLayersList[i] = pDq; //to keep consistence with in UninitialDqLayersContext()
1511     memset (pDq, 0, sizeof (SDqLayer));
1512 
1513     pCtx->sMb.pMbType[i] = (uint32_t*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (uint32_t),
1514                            "pCtx->sMb.pMbType[]");
1515     pCtx->sMb.pMv[i][LIST_0] = (int16_t (*)[16][2])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
1516                                  int16_t) * MV_A * MB_BLOCK4x4_NUM, "pCtx->sMb.pMv[][]");
1517     pCtx->sMb.pMv[i][LIST_1] = (int16_t (*)[16][2])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
1518                                  int16_t) * MV_A * MB_BLOCK4x4_NUM, "pCtx->sMb.pMv[][]");
1519 
1520     pCtx->sMb.pRefIndex[i][LIST_0] = (int8_t (*)[MB_BLOCK4x4_NUM])pMa->WelsMallocz (pCtx->sMb.iMbWidth *
1521                                      pCtx->sMb.iMbHeight *
1522                                      sizeof (
1523                                        int8_t) * MB_BLOCK4x4_NUM, "pCtx->sMb.pRefIndex[][]");
1524     pCtx->sMb.pRefIndex[i][LIST_1] = (int8_t (*)[MB_BLOCK4x4_NUM])pMa->WelsMallocz (pCtx->sMb.iMbWidth *
1525                                      pCtx->sMb.iMbHeight *
1526                                      sizeof (
1527                                        int8_t) * MB_BLOCK4x4_NUM, "pCtx->sMb.pRefIndex[][]");
1528     pCtx->sMb.pDirect[i] = (int8_t (*)[MB_BLOCK4x4_NUM])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight *
1529                            sizeof (
1530                              int8_t) * MB_BLOCK4x4_NUM, "pCtx->sMb.pDirect[]");
1531     pCtx->sMb.pLumaQp[i] = (int8_t*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
1532                            "pCtx->sMb.pLumaQp[]");
1533     pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[i] = (bool*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight *
1534         sizeof (
1535           bool),
1536         "pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[]");
1537     pCtx->sMb.pTransformSize8x8Flag[i] = (bool*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
1538                                            bool),
1539                                          "pCtx->sMb.pTransformSize8x8Flag[]");
1540     pCtx->sMb.pChromaQp[i] = (int8_t (*)[2])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
1541                                int8_t) * 2,
1542                              "pCtx->sMb.pChromaQp[]");
1543     pCtx->sMb.pMvd[i][LIST_0] = (int16_t (*)[16][2])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
1544                                   int16_t) * MV_A * MB_BLOCK4x4_NUM, "pCtx->sMb.pMvd[][]");
1545     pCtx->sMb.pMvd[i][LIST_1] = (int16_t (*)[16][2])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
1546                                   int16_t) * MV_A * MB_BLOCK4x4_NUM, "pCtx->sMb.pMvd[][]");
1547     pCtx->sMb.pCbfDc[i] = (uint16_t*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (uint16_t),
1548                           "pCtx->sMb.pCbfDc[]");
1549     pCtx->sMb.pNzc[i] = (int8_t (*)[24])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
1550                           int8_t) * 24,
1551                         "pCtx->sMb.pNzc[]");
1552     pCtx->sMb.pNzcRs[i] = (int8_t (*)[24])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
1553                             int8_t) * 24,
1554                           "pCtx->sMb.pNzcRs[]");
1555     pCtx->sMb.pScaledTCoeff[i] = (int16_t (*)[MB_COEFF_LIST_SIZE])pMa->WelsMallocz (pCtx->sMb.iMbWidth *
1556                                  pCtx->sMb.iMbHeight *
1557                                  sizeof (int16_t) * MB_COEFF_LIST_SIZE, "pCtx->sMb.pScaledTCoeff[]");
1558     pCtx->sMb.pIntraPredMode[i] = (int8_t (*)[8])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
1559                                     int8_t) * 8,
1560                                   "pCtx->sMb.pIntraPredMode[]");
1561     pCtx->sMb.pIntra4x4FinalMode[i] = (int8_t (*)[MB_BLOCK4x4_NUM])pMa->WelsMallocz (pCtx->sMb.iMbWidth *
1562                                       pCtx->sMb.iMbHeight *
1563                                       sizeof (int8_t) * MB_BLOCK4x4_NUM, "pCtx->sMb.pIntra4x4FinalMode[]");
1564     pCtx->sMb.pIntraNxNAvailFlag[i] = (uint8_t (*))pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
1565                                         int8_t),
1566                                       "pCtx->sMb.pIntraNxNAvailFlag");
1567     pCtx->sMb.pChromaPredMode[i] = (int8_t*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
1568                                    "pCtx->sMb.pChromaPredMode[]");
1569     pCtx->sMb.pCbp[i] = (int8_t*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
1570                         "pCtx->sMb.pCbp[]");
1571     pCtx->sMb.pSubMbType[i] = (uint32_t (*)[MB_PARTITION_SIZE])pMa->WelsMallocz (pCtx->sMb.iMbWidth *
1572                               pCtx->sMb.iMbHeight *
1573                               sizeof (
1574                                 uint32_t) * MB_PARTITION_SIZE, "pCtx->sMb.pSubMbType[]");
1575     pCtx->sMb.pSliceIdc[i] = (int32_t*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t),
1576                              "pCtx->sMb.pSliceIdc[]"); // using int32_t for slice_idc, 4/21/2010
1577     pCtx->sMb.pResidualPredFlag[i] = (int8_t*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
1578                                        int8_t),
1579                                      "pCtx->sMb.pResidualPredFlag[]");
1580     pCtx->sMb.pInterPredictionDoneFlag[i] = (int8_t*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight *
1581                                             sizeof (
1582                                                 int8_t), "pCtx->sMb.pInterPredictionDoneFlag[]");
1583 
1584     pCtx->sMb.pMbCorrectlyDecodedFlag[i] = (bool*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
1585         bool),
1586                                            "pCtx->sMb.pMbCorrectlyDecodedFlag[]");
1587     pCtx->sMb.pMbRefConcealedFlag[i] = (bool*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
1588                                          bool),
1589                                        "pCtx->pMbRefConcealedFlag[]");
1590 
1591     // check memory block valid due above allocated..
1592     WELS_VERIFY_RETURN_IF (ERR_INFO_OUT_OF_MEMORY,
1593                            ((NULL == pCtx->sMb.pMbType[i]) ||
1594                             (NULL == pCtx->sMb.pMv[i][LIST_0]) ||
1595                             (NULL == pCtx->sMb.pMv[i][LIST_1]) ||
1596                             (NULL == pCtx->sMb.pRefIndex[i][LIST_0]) ||
1597                             (NULL == pCtx->sMb.pRefIndex[i][LIST_1]) ||
1598                             (NULL == pCtx->sMb.pDirect[i]) ||
1599                             (NULL == pCtx->sMb.pLumaQp[i]) ||
1600                             (NULL == pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[i]) ||
1601                             (NULL == pCtx->sMb.pTransformSize8x8Flag[i]) ||
1602                             (NULL == pCtx->sMb.pChromaQp[i]) ||
1603                             (NULL == pCtx->sMb.pMvd[i][LIST_0]) ||
1604                             (NULL == pCtx->sMb.pMvd[i][LIST_1]) ||
1605                             (NULL == pCtx->sMb.pCbfDc[i]) ||
1606                             (NULL == pCtx->sMb.pNzc[i]) ||
1607                             (NULL == pCtx->sMb.pNzcRs[i]) ||
1608                             (NULL == pCtx->sMb.pScaledTCoeff[i]) ||
1609                             (NULL == pCtx->sMb.pIntraPredMode[i]) ||
1610                             (NULL == pCtx->sMb.pIntra4x4FinalMode[i]) ||
1611                             (NULL == pCtx->sMb.pIntraNxNAvailFlag[i]) ||
1612                             (NULL == pCtx->sMb.pChromaPredMode[i]) ||
1613                             (NULL == pCtx->sMb.pCbp[i]) ||
1614                             (NULL == pCtx->sMb.pSubMbType[i]) ||
1615                             (NULL == pCtx->sMb.pSliceIdc[i]) ||
1616                             (NULL == pCtx->sMb.pResidualPredFlag[i]) ||
1617                             (NULL == pCtx->sMb.pInterPredictionDoneFlag[i]) ||
1618                             (NULL == pCtx->sMb.pMbRefConcealedFlag[i]) ||
1619                             (NULL == pCtx->sMb.pMbCorrectlyDecodedFlag[i])
1620                            )
1621                           )
1622 
1623     memset (pCtx->sMb.pSliceIdc[i], 0xff, (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t)));
1624 
1625     ++ i;
1626   } while (i < LAYER_NUM_EXCHANGEABLE);
1627 
1628   pCtx->bInitialDqLayersMem     = true;
1629   pCtx->iPicWidthReq            = kiMaxWidth;
1630   pCtx->iPicHeightReq           = kiMaxHeight;
1631 
1632   return ERR_NONE;
1633 }
1634 
1635 
1636 
UninitialDqLayersContext(PWelsDecoderContext pCtx)1637 void UninitialDqLayersContext (PWelsDecoderContext pCtx) {
1638   int32_t i = 0;
1639   CMemoryAlign* pMa = pCtx->pMemAlign;
1640 
1641   do {
1642     PDqLayer pDq = pCtx->pDqLayersList[i];
1643     if (pDq == NULL) {
1644       ++ i;
1645       continue;
1646     }
1647 
1648     if (pCtx->sMb.pMbType[i]) {
1649       pMa->WelsFree (pCtx->sMb.pMbType[i], "pCtx->sMb.pMbType[]");
1650 
1651       pCtx->sMb.pMbType[i] = NULL;
1652     }
1653 
1654     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
1655       if (pCtx->sMb.pMv[i][listIdx]) {
1656         pMa->WelsFree (pCtx->sMb.pMv[i][listIdx], "pCtx->sMb.pMv[][]");
1657         pCtx->sMb.pMv[i][listIdx] = NULL;
1658       }
1659 
1660       if (pCtx->sMb.pRefIndex[i][listIdx]) {
1661         pMa->WelsFree (pCtx->sMb.pRefIndex[i][listIdx], "pCtx->sMb.pRefIndex[][]");
1662         pCtx->sMb.pRefIndex[i][listIdx] = NULL;
1663       }
1664 
1665       if (pCtx->sMb.pDirect[i]) {
1666         pMa->WelsFree (pCtx->sMb.pDirect[i], "pCtx->sMb.pDirect[]");
1667         pCtx->sMb.pDirect[i] = NULL;
1668       }
1669 
1670       if (pCtx->sMb.pMvd[i][listIdx]) {
1671         pMa->WelsFree (pCtx->sMb.pMvd[i][listIdx], "pCtx->sMb.pMvd[][]");
1672         pCtx->sMb.pMvd[i][listIdx] = NULL;
1673       }
1674     }
1675 
1676     if (pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[i]) {
1677       pMa->WelsFree (pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[i], "pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[]");
1678 
1679       pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[i] = NULL;
1680     }
1681 
1682     if (pCtx->sMb.pTransformSize8x8Flag[i]) {
1683       pMa->WelsFree (pCtx->sMb.pTransformSize8x8Flag[i], "pCtx->sMb.pTransformSize8x8Flag[]");
1684 
1685       pCtx->sMb.pTransformSize8x8Flag[i] = NULL;
1686     }
1687 
1688     if (pCtx->sMb.pLumaQp[i]) {
1689       pMa->WelsFree (pCtx->sMb.pLumaQp[i], "pCtx->sMb.pLumaQp[]");
1690 
1691       pCtx->sMb.pLumaQp[i] = NULL;
1692     }
1693 
1694     if (pCtx->sMb.pChromaQp[i]) {
1695       pMa->WelsFree (pCtx->sMb.pChromaQp[i], "pCtx->sMb.pChromaQp[]");
1696 
1697       pCtx->sMb.pChromaQp[i] = NULL;
1698     }
1699 
1700     if (pCtx->sMb.pCbfDc[i]) {
1701       pMa->WelsFree (pCtx->sMb.pCbfDc[i], "pCtx->sMb.pCbfDc[]");
1702       pCtx->sMb.pCbfDc[i] = NULL;
1703     }
1704 
1705     if (pCtx->sMb.pNzc[i]) {
1706       pMa->WelsFree (pCtx->sMb.pNzc[i], "pCtx->sMb.pNzc[]");
1707 
1708       pCtx->sMb.pNzc[i] = NULL;
1709     }
1710 
1711     if (pCtx->sMb.pNzcRs[i]) {
1712       pMa->WelsFree (pCtx->sMb.pNzcRs[i], "pCtx->sMb.pNzcRs[]");
1713 
1714       pCtx->sMb.pNzcRs[i] = NULL;
1715     }
1716 
1717     if (pCtx->sMb.pScaledTCoeff[i]) {
1718       pMa->WelsFree (pCtx->sMb.pScaledTCoeff[i], "pCtx->sMb.pScaledTCoeff[]");
1719 
1720       pCtx->sMb.pScaledTCoeff[i] = NULL;
1721     }
1722 
1723     if (pCtx->sMb.pIntraPredMode[i]) {
1724       pMa->WelsFree (pCtx->sMb.pIntraPredMode[i], "pCtx->sMb.pIntraPredMode[]");
1725 
1726       pCtx->sMb.pIntraPredMode[i] = NULL;
1727     }
1728 
1729     if (pCtx->sMb.pIntra4x4FinalMode[i]) {
1730       pMa->WelsFree (pCtx->sMb.pIntra4x4FinalMode[i], "pCtx->sMb.pIntra4x4FinalMode[]");
1731 
1732       pCtx->sMb.pIntra4x4FinalMode[i] = NULL;
1733     }
1734 
1735     if (pCtx->sMb.pIntraNxNAvailFlag[i]) {
1736       pMa->WelsFree (pCtx->sMb.pIntraNxNAvailFlag[i], "pCtx->sMb.pIntraNxNAvailFlag");
1737 
1738       pCtx->sMb.pIntraNxNAvailFlag[i] = NULL;
1739     }
1740 
1741     if (pCtx->sMb.pChromaPredMode[i]) {
1742       pMa->WelsFree (pCtx->sMb.pChromaPredMode[i], "pCtx->sMb.pChromaPredMode[]");
1743 
1744       pCtx->sMb.pChromaPredMode[i] = NULL;
1745     }
1746 
1747     if (pCtx->sMb.pCbp[i]) {
1748       pMa->WelsFree (pCtx->sMb.pCbp[i], "pCtx->sMb.pCbp[]");
1749 
1750       pCtx->sMb.pCbp[i] = NULL;
1751     }
1752 
1753     //      if (pCtx->sMb.pMotionPredFlag[i])
1754     //{
1755     //  pMa->WelsFree( pCtx->sMb.pMotionPredFlag[i], "pCtx->sMb.pMotionPredFlag[]" );
1756 
1757     //  pCtx->sMb.pMotionPredFlag[i] = NULL;
1758     //}
1759 
1760     if (pCtx->sMb.pSubMbType[i]) {
1761       pMa->WelsFree (pCtx->sMb.pSubMbType[i], "pCtx->sMb.pSubMbType[]");
1762 
1763       pCtx->sMb.pSubMbType[i] = NULL;
1764     }
1765 
1766     if (pCtx->sMb.pSliceIdc[i]) {
1767       pMa->WelsFree (pCtx->sMb.pSliceIdc[i], "pCtx->sMb.pSliceIdc[]");
1768 
1769       pCtx->sMb.pSliceIdc[i] = NULL;
1770     }
1771 
1772     if (pCtx->sMb.pResidualPredFlag[i]) {
1773       pMa->WelsFree (pCtx->sMb.pResidualPredFlag[i], "pCtx->sMb.pResidualPredFlag[]");
1774 
1775       pCtx->sMb.pResidualPredFlag[i] = NULL;
1776     }
1777 
1778     if (pCtx->sMb.pInterPredictionDoneFlag[i]) {
1779       pMa->WelsFree (pCtx->sMb.pInterPredictionDoneFlag[i], "pCtx->sMb.pInterPredictionDoneFlag[]");
1780 
1781       pCtx->sMb.pInterPredictionDoneFlag[i] = NULL;
1782     }
1783 
1784     if (pCtx->sMb.pMbCorrectlyDecodedFlag[i]) {
1785       pMa->WelsFree (pCtx->sMb.pMbCorrectlyDecodedFlag[i], "pCtx->sMb.pMbCorrectlyDecodedFlag[]");
1786       pCtx->sMb.pMbCorrectlyDecodedFlag[i] = NULL;
1787     }
1788 
1789     if (pCtx->sMb.pMbRefConcealedFlag[i]) {
1790       pMa->WelsFree (pCtx->sMb.pMbRefConcealedFlag[i], "pCtx->sMb.pMbRefConcealedFlag[]");
1791       pCtx->sMb.pMbRefConcealedFlag[i] = NULL;
1792     }
1793     pMa->WelsFree (pDq, "pDq");
1794 
1795     pDq = NULL;
1796     pCtx->pDqLayersList[i] = NULL;
1797 
1798     ++ i;
1799   } while (i < LAYER_NUM_EXCHANGEABLE);
1800 
1801   pCtx->iPicWidthReq            = 0;
1802   pCtx->iPicHeightReq           = 0;
1803   pCtx->bInitialDqLayersMem     = false;
1804 }
1805 
ResetCurrentAccessUnit(PWelsDecoderContext pCtx)1806 void ResetCurrentAccessUnit (PWelsDecoderContext pCtx) {
1807   PAccessUnit pCurAu = pCtx->pAccessUnitList;
1808   pCurAu->uiStartPos            = 0;
1809   pCurAu->uiEndPos              = 0;
1810   pCurAu->bCompletedAuFlag      = false;
1811   if (pCurAu->uiActualUnitsNum > 0) {
1812     uint32_t iIdx = 0;
1813     const uint32_t kuiActualNum = pCurAu->uiActualUnitsNum;
1814     // a more simpler method to do nal units list management prefered here
1815     const uint32_t kuiAvailNum  = pCurAu->uiAvailUnitsNum;
1816     const uint32_t kuiLeftNum   = kuiAvailNum - kuiActualNum;
1817 
1818     // Swapping active nal unit nodes of succeeding AU with leading of list
1819     while (iIdx < kuiLeftNum) {
1820       PNalUnit t = pCurAu->pNalUnitsList[kuiActualNum + iIdx];
1821       pCurAu->pNalUnitsList[kuiActualNum + iIdx] = pCurAu->pNalUnitsList[iIdx];
1822       pCurAu->pNalUnitsList[iIdx] = t;
1823       ++ iIdx;
1824     }
1825     pCurAu->uiActualUnitsNum = pCurAu->uiAvailUnitsNum = kuiLeftNum;
1826   }
1827 }
1828 
1829 /*!
1830  * \brief   Force reset current Acess Unit Nal list in case error parsing/decoding in current AU
1831  * \author
1832  * \history 11/16/2009
1833  */
ForceResetCurrentAccessUnit(PAccessUnit pAu)1834 void ForceResetCurrentAccessUnit (PAccessUnit pAu) {
1835   uint32_t uiSucAuIdx = pAu->uiEndPos + 1;
1836   uint32_t uiCurAuIdx = 0;
1837 
1838   // swap the succeeding AU's nal units to the front
1839   while (uiSucAuIdx < pAu->uiAvailUnitsNum) {
1840     PNalUnit t = pAu->pNalUnitsList[uiSucAuIdx];
1841     pAu->pNalUnitsList[uiSucAuIdx] = pAu->pNalUnitsList[uiCurAuIdx];
1842     pAu->pNalUnitsList[uiCurAuIdx] = t;
1843     ++ uiSucAuIdx;
1844     ++ uiCurAuIdx;
1845   }
1846 
1847   // Update avail/actual units num accordingly for next AU parsing
1848   if (pAu->uiAvailUnitsNum > pAu->uiEndPos)
1849     pAu->uiAvailUnitsNum -= (pAu->uiEndPos + 1);
1850   else
1851     pAu->uiAvailUnitsNum = 0;
1852   pAu->uiActualUnitsNum = 0;
1853   pAu->uiStartPos       = 0;
1854   pAu->uiEndPos         = 0;
1855   pAu->bCompletedAuFlag = false;
1856 }
1857 
1858 //clear current corrupted NAL from pNalUnitsList
ForceClearCurrentNal(PAccessUnit pAu)1859 void ForceClearCurrentNal (PAccessUnit pAu) {
1860   if (pAu->uiAvailUnitsNum > 0)
1861     -- pAu->uiAvailUnitsNum;
1862 }
1863 
ForceResetParaSetStatusAndAUList(PWelsDecoderContext pCtx)1864 void ForceResetParaSetStatusAndAUList (PWelsDecoderContext pCtx) {
1865   pCtx->sSpsPpsCtx.bSpsExistAheadFlag = false;
1866   pCtx->sSpsPpsCtx.bSubspsExistAheadFlag = false;
1867   pCtx->sSpsPpsCtx.bPpsExistAheadFlag = false;
1868 
1869   // Force clear the AU list
1870   pCtx->pAccessUnitList->uiAvailUnitsNum        = 0;
1871   pCtx->pAccessUnitList->uiActualUnitsNum       = 0;
1872   pCtx->pAccessUnitList->uiStartPos             = 0;
1873   pCtx->pAccessUnitList->uiEndPos               = 0;
1874   pCtx->pAccessUnitList->bCompletedAuFlag       = false;
1875 }
1876 
CheckAvailNalUnitsListContinuity(PWelsDecoderContext pCtx,int32_t iStartIdx,int32_t iEndIdx)1877 void CheckAvailNalUnitsListContinuity (PWelsDecoderContext pCtx, int32_t iStartIdx, int32_t iEndIdx) {
1878   PAccessUnit pCurAu = pCtx->pAccessUnitList;
1879 
1880   uint8_t uiLastNuDependencyId, uiLastNuLayerDqId;
1881   uint8_t uiCurNuDependencyId, uiCurNuQualityId, uiCurNuLayerDqId, uiCurNuRefLayerDqId;
1882 
1883   int32_t iCurNalUnitIdx = 0;
1884 
1885   //check the continuity of pNalUnitsList forwards (from pIdxNoInterLayerPred to end_postion)
1886   uiLastNuDependencyId = pCurAu->pNalUnitsList[iStartIdx]->sNalHeaderExt.uiDependencyId;//starting nal unit
1887   uiLastNuLayerDqId   = pCurAu->pNalUnitsList[iStartIdx]->sNalHeaderExt.uiLayerDqId;//starting nal unit
1888   iCurNalUnitIdx = iStartIdx + 1;//current nal unit
1889   while (iCurNalUnitIdx <= iEndIdx) {
1890     uiCurNuDependencyId   = pCurAu->pNalUnitsList[iCurNalUnitIdx]->sNalHeaderExt.uiDependencyId;
1891     uiCurNuQualityId      = pCurAu->pNalUnitsList[iCurNalUnitIdx]->sNalHeaderExt.uiQualityId;
1892     uiCurNuLayerDqId     = pCurAu->pNalUnitsList[iCurNalUnitIdx]->sNalHeaderExt.uiLayerDqId;
1893     uiCurNuRefLayerDqId = pCurAu->pNalUnitsList[iCurNalUnitIdx]->sNalData.sVclNal.sSliceHeaderExt.uiRefLayerDqId;
1894 
1895     if (uiCurNuDependencyId == uiLastNuDependencyId) {
1896       uiLastNuLayerDqId = uiCurNuLayerDqId;
1897       ++ iCurNalUnitIdx;
1898     } else { //uiCurNuDependencyId != uiLastNuDependencyId, new dependency arrive
1899       if (uiCurNuQualityId == 0) {
1900         uiLastNuDependencyId = uiCurNuDependencyId;
1901         if (uiCurNuRefLayerDqId == uiLastNuLayerDqId) {
1902           uiLastNuLayerDqId = uiCurNuLayerDqId;
1903           ++ iCurNalUnitIdx;
1904         } else { //cur_nu_layer_id != next_nu_ref_layer_dq_id, the chain is broken at this point
1905           break;
1906         }
1907       } else { //new dependency arrive, but no base quality layer, so we must stop in this point
1908         break;
1909       }
1910     }
1911   }
1912 
1913   -- iCurNalUnitIdx;
1914   pCurAu->uiEndPos = iCurNalUnitIdx;
1915   pCtx->uiTargetDqId = pCurAu->pNalUnitsList[iCurNalUnitIdx]->sNalHeaderExt.uiLayerDqId;
1916 }
1917 
1918 //main purpose: to support multi-slice and to include all slice which have the same uiDependencyId, uiQualityId and frame_num
1919 //for single slice, pIdxNoInterLayerPred SHOULD NOT be modified
RefineIdxNoInterLayerPred(PAccessUnit pCurAu,int32_t * pIdxNoInterLayerPred)1920 void RefineIdxNoInterLayerPred (PAccessUnit pCurAu, int32_t* pIdxNoInterLayerPred) {
1921   int32_t iLastNalDependId  = pCurAu->pNalUnitsList[*pIdxNoInterLayerPred]->sNalHeaderExt.uiDependencyId;
1922   int32_t iLastNalQualityId = pCurAu->pNalUnitsList[*pIdxNoInterLayerPred]->sNalHeaderExt.uiQualityId;
1923   uint8_t uiLastNalTId       = pCurAu->pNalUnitsList[*pIdxNoInterLayerPred]->sNalHeaderExt.uiTemporalId;
1924   int32_t iLastNalFrameNum  =
1925     pCurAu->pNalUnitsList[*pIdxNoInterLayerPred]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iFrameNum;
1926   int32_t iLastNalPoc        =
1927     pCurAu->pNalUnitsList[*pIdxNoInterLayerPred]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iPicOrderCntLsb;
1928   int32_t iLastNalFirstMb   =
1929     pCurAu->pNalUnitsList[*pIdxNoInterLayerPred]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iFirstMbInSlice;
1930   int32_t iCurNalDependId, iCurNalQualityId, iCurNalTId, iCurNalFrameNum, iCurNalPoc, iCurNalFirstMb, iCurIdx,
1931           iFinalIdxNoInterLayerPred;
1932 
1933   bool  bMultiSliceFind = false;
1934 
1935   iFinalIdxNoInterLayerPred = 0;
1936   iCurIdx = *pIdxNoInterLayerPred - 1;
1937   while (iCurIdx >= 0) {
1938     if (pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.iNoInterLayerPredFlag) {
1939       iCurNalDependId  = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiDependencyId;
1940       iCurNalQualityId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiQualityId;
1941       iCurNalTId       = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiTemporalId;
1942       iCurNalFrameNum  = pCurAu->pNalUnitsList[iCurIdx]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iFrameNum;
1943       iCurNalPoc        = pCurAu->pNalUnitsList[iCurIdx]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iPicOrderCntLsb;
1944       iCurNalFirstMb   = pCurAu->pNalUnitsList[iCurIdx]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iFirstMbInSlice;
1945 
1946       if (iCurNalDependId == iLastNalDependId  &&
1947           iCurNalQualityId == iLastNalQualityId &&
1948           iCurNalTId       == uiLastNalTId       &&
1949           iCurNalFrameNum  == iLastNalFrameNum  &&
1950           iCurNalPoc        == iLastNalPoc        &&
1951           iCurNalFirstMb   != iLastNalFirstMb) {
1952         bMultiSliceFind = true;
1953         iFinalIdxNoInterLayerPred = iCurIdx;
1954         --iCurIdx;
1955         continue;
1956       } else {
1957         break;
1958       }
1959     }
1960     --iCurIdx;
1961   }
1962 
1963   if (bMultiSliceFind && *pIdxNoInterLayerPred != iFinalIdxNoInterLayerPred) {
1964     *pIdxNoInterLayerPred = iFinalIdxNoInterLayerPred;
1965   }
1966 }
1967 
CheckPocOfCurValidNalUnits(PAccessUnit pCurAu,int32_t pIdxNoInterLayerPred)1968 bool CheckPocOfCurValidNalUnits (PAccessUnit pCurAu, int32_t pIdxNoInterLayerPred) {
1969   int32_t iEndIdx    = pCurAu->uiEndPos;
1970   int32_t iCurAuPoc =
1971     pCurAu->pNalUnitsList[pIdxNoInterLayerPred]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iPicOrderCntLsb;
1972   int32_t iTmpPoc, i;
1973   for (i = pIdxNoInterLayerPred + 1; i < iEndIdx; i++) {
1974     iTmpPoc = pCurAu->pNalUnitsList[i]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iPicOrderCntLsb;
1975     if (iTmpPoc != iCurAuPoc) {
1976       return false;
1977     }
1978   }
1979 
1980   return true;
1981 }
1982 
CheckIntegrityNalUnitsList(PWelsDecoderContext pCtx)1983 bool CheckIntegrityNalUnitsList (PWelsDecoderContext pCtx) {
1984   PAccessUnit pCurAu = pCtx->pAccessUnitList;
1985   const int32_t kiEndPos = pCurAu->uiEndPos;
1986   int32_t iIdxNoInterLayerPred = 0;
1987 
1988   if (!pCurAu->bCompletedAuFlag)
1989     return false;
1990 
1991   if (pCtx->bNewSeqBegin) {
1992     pCurAu->uiStartPos = 0;
1993     //step1: search the pNalUnit whose iNoInterLayerPredFlag equal to 1 backwards (from uiEndPos to 0)
1994     iIdxNoInterLayerPred = kiEndPos;
1995     while (iIdxNoInterLayerPred >= 0) {
1996       if (pCurAu->pNalUnitsList[iIdxNoInterLayerPred]->sNalHeaderExt.iNoInterLayerPredFlag) {
1997         break;
1998       }
1999       --iIdxNoInterLayerPred;
2000     }
2001     if (iIdxNoInterLayerPred < 0) {
2002       //can not find the Nal Unit whose no_inter_pred_falg equal to 1, MUST STOP decode
2003       return false;
2004     }
2005 
2006     //step2: support multi-slice, to include all base layer slice
2007     RefineIdxNoInterLayerPred (pCurAu, &iIdxNoInterLayerPred);
2008     pCurAu->uiStartPos = iIdxNoInterLayerPred;
2009     CheckAvailNalUnitsListContinuity (pCtx, iIdxNoInterLayerPred, kiEndPos);
2010 
2011     if (!CheckPocOfCurValidNalUnits (pCurAu, iIdxNoInterLayerPred)) {
2012       return false;
2013     }
2014 
2015     pCtx->iCurSeqIntervalTargetDependId = pCurAu->pNalUnitsList[pCurAu->uiEndPos]->sNalHeaderExt.uiDependencyId;
2016     pCtx->iCurSeqIntervalMaxPicWidth  =
2017       pCurAu->pNalUnitsList[pCurAu->uiEndPos]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iMbWidth << 4;
2018     pCtx->iCurSeqIntervalMaxPicHeight =
2019       pCurAu->pNalUnitsList[pCurAu->uiEndPos]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iMbHeight << 4;
2020   } else { //P_SLICE
2021     //step 1: search uiDependencyId equal to pCtx->cur_seq_interval_target_dependency_id
2022     bool bGetDependId = false;
2023     int32_t iIdxDependId = 0;
2024 
2025     iIdxDependId = kiEndPos;
2026     while (iIdxDependId >= 0) {
2027       if (pCtx->iCurSeqIntervalTargetDependId == pCurAu->pNalUnitsList[iIdxDependId]->sNalHeaderExt.uiDependencyId) {
2028         bGetDependId = true;
2029         break;
2030       } else {
2031         --iIdxDependId;
2032       }
2033     }
2034 
2035     //step 2: switch according to whether or not find the index of pNalUnit whose uiDependencyId equal to iCurSeqIntervalTargetDependId
2036     if (bGetDependId) { //get the index of pNalUnit whose uiDependencyId equal to iCurSeqIntervalTargetDependId
2037       bool bGetNoInterPredFront = false;
2038       //step 2a: search iNoInterLayerPredFlag [0....iIdxDependId]
2039       iIdxNoInterLayerPred = iIdxDependId;
2040       while (iIdxNoInterLayerPred >= 0) {
2041         if (pCurAu->pNalUnitsList[iIdxNoInterLayerPred]->sNalHeaderExt.iNoInterLayerPredFlag) {
2042           bGetNoInterPredFront = true;
2043           break;
2044         }
2045         --iIdxNoInterLayerPred;
2046       }
2047       //step 2b: switch, whether or not find the NAL unit whose no_inter_pred_flag equal to 1 among [0....iIdxDependId]
2048       if (bGetNoInterPredFront) { //YES
2049         RefineIdxNoInterLayerPred (pCurAu, &iIdxNoInterLayerPred);
2050         pCurAu->uiStartPos = iIdxNoInterLayerPred;
2051         CheckAvailNalUnitsListContinuity (pCtx, iIdxNoInterLayerPred, iIdxDependId);
2052 
2053         if (!CheckPocOfCurValidNalUnits (pCurAu, iIdxNoInterLayerPred)) {
2054           return false;
2055         }
2056       } else { //NO, should find the NAL unit whose no_inter_pred_flag equal to 1 among [iIdxDependId....uiEndPos]
2057         iIdxNoInterLayerPred = iIdxDependId;
2058         while (iIdxNoInterLayerPred <= kiEndPos) {
2059           if (pCurAu->pNalUnitsList[iIdxNoInterLayerPred]->sNalHeaderExt.iNoInterLayerPredFlag) {
2060             break;
2061           }
2062           ++iIdxNoInterLayerPred;
2063         }
2064 
2065         if (iIdxNoInterLayerPred > kiEndPos) {
2066           return false; //cann't find the index of pNalUnit whose no_inter_pred_flag = 1
2067         }
2068 
2069         RefineIdxNoInterLayerPred (pCurAu, &iIdxNoInterLayerPred);
2070         pCurAu->uiStartPos = iIdxNoInterLayerPred;
2071         CheckAvailNalUnitsListContinuity (pCtx, iIdxNoInterLayerPred, kiEndPos);
2072 
2073         if (!CheckPocOfCurValidNalUnits (pCurAu, iIdxNoInterLayerPred)) {
2074           return false;
2075         }
2076       }
2077     } else { //without the index of pNalUnit, should process this AU as common case
2078       iIdxNoInterLayerPred = kiEndPos;
2079       while (iIdxNoInterLayerPred >= 0) {
2080         if (pCurAu->pNalUnitsList[iIdxNoInterLayerPred]->sNalHeaderExt.iNoInterLayerPredFlag) {
2081           break;
2082         }
2083         --iIdxNoInterLayerPred;
2084       }
2085       if (iIdxNoInterLayerPred < 0) {
2086         return false; //cann't find the index of pNalUnit whose iNoInterLayerPredFlag = 1
2087       }
2088 
2089       RefineIdxNoInterLayerPred (pCurAu, &iIdxNoInterLayerPred);
2090       pCurAu->uiStartPos = iIdxNoInterLayerPred;
2091       CheckAvailNalUnitsListContinuity (pCtx, iIdxNoInterLayerPred, kiEndPos);
2092 
2093       if (!CheckPocOfCurValidNalUnits (pCurAu, iIdxNoInterLayerPred)) {
2094         return false;
2095       }
2096     }
2097   }
2098 
2099   return true;
2100 }
2101 
CheckOnlyOneLayerInAu(PWelsDecoderContext pCtx)2102 void CheckOnlyOneLayerInAu (PWelsDecoderContext pCtx) {
2103   PAccessUnit pCurAu = pCtx->pAccessUnitList;
2104 
2105   int32_t iEndIdx = pCurAu->uiEndPos;
2106   int32_t iCurIdx = pCurAu->uiStartPos;
2107   uint8_t uiDId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiDependencyId;
2108   uint8_t uiQId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiQualityId;
2109   uint8_t uiTId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiTemporalId;
2110 
2111   uint8_t uiCurDId, uiCurQId, uiCurTId;
2112 
2113   pCtx->bOnlyOneLayerInCurAuFlag = true;
2114 
2115   if (iEndIdx == iCurIdx) { //only one NAL in pNalUnitsList
2116     return;
2117   }
2118 
2119   ++iCurIdx;
2120   while (iCurIdx <= iEndIdx) {
2121     uiCurDId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiDependencyId;
2122     uiCurQId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiQualityId;
2123     uiCurTId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiTemporalId;
2124 
2125     if (uiDId != uiCurDId || uiQId != uiCurQId || uiTId != uiCurTId) {
2126       pCtx->bOnlyOneLayerInCurAuFlag = false;
2127       return;
2128     }
2129 
2130     ++iCurIdx;
2131   }
2132 }
2133 
WelsDecodeAccessUnitStart(PWelsDecoderContext pCtx)2134 int32_t WelsDecodeAccessUnitStart (PWelsDecoderContext pCtx) {
2135   // Roll back NAL units not being belong to current access unit list for proceeded access unit
2136   int32_t iRet = UpdateAccessUnit (pCtx);
2137   if (iRet != ERR_NONE)
2138     return iRet;
2139 
2140   pCtx->pAccessUnitList->uiStartPos = 0;
2141   if (!pCtx->sSpsPpsCtx.bAvcBasedFlag && !CheckIntegrityNalUnitsList (pCtx)) {
2142     pCtx->iErrorCode |= dsBitstreamError;
2143     return dsBitstreamError;
2144   }
2145 
2146   //check current AU has only one layer or not
2147   //If YES, can use deblocking based on AVC
2148   if (!pCtx->sSpsPpsCtx.bAvcBasedFlag) {
2149     CheckOnlyOneLayerInAu (pCtx);
2150   }
2151 
2152   return ERR_NONE;
2153 }
2154 
WelsDecodeAccessUnitEnd(PWelsDecoderContext pCtx)2155 void WelsDecodeAccessUnitEnd (PWelsDecoderContext pCtx) {
2156   //save previous header info
2157   PAccessUnit pCurAu = pCtx->pAccessUnitList;
2158   PNalUnit pCurNal = pCurAu->pNalUnitsList[pCurAu->uiEndPos];
2159   memcpy (&pCtx->pLastDecPicInfo->sLastNalHdrExt, &pCurNal->sNalHeaderExt, sizeof (SNalUnitHeaderExt));
2160   memcpy (&pCtx->pLastDecPicInfo->sLastSliceHeader,
2161           &pCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader, sizeof (SSliceHeader));
2162   // uninitialize context of current access unit and rbsp buffer clean
2163   ResetCurrentAccessUnit (pCtx);
2164 }
2165 
2166 /* CheckNewSeqBeginAndUpdateActiveLayerSps
2167  * return:
2168  * true - the AU to be construct is the start of new sequence; false - not
2169  */
CheckNewSeqBeginAndUpdateActiveLayerSps(PWelsDecoderContext pCtx)2170 static bool CheckNewSeqBeginAndUpdateActiveLayerSps (PWelsDecoderContext pCtx) {
2171   bool bNewSeq = false;
2172   PAccessUnit pCurAu = pCtx->pAccessUnitList;
2173   PSps pTmpLayerSps[MAX_LAYER_NUM];
2174   for (int i = 0; i < MAX_LAYER_NUM; i++) {
2175     pTmpLayerSps[i] = NULL;
2176   }
2177   // track the layer sps for the current au
2178   for (unsigned int i = pCurAu->uiStartPos; i <= pCurAu->uiEndPos; i++) {
2179     uint32_t uiDid = pCurAu->pNalUnitsList[i]->sNalHeaderExt.uiDependencyId;
2180     pTmpLayerSps[uiDid] = pCurAu->pNalUnitsList[i]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pSps;
2181     if ((pCurAu->pNalUnitsList[i]->sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR)
2182         || (pCurAu->pNalUnitsList[i]->sNalHeaderExt.bIdrFlag))
2183       bNewSeq = true;
2184   }
2185   int iMaxActiveLayer = 0, iMaxCurrentLayer = 0;
2186   for (int i = MAX_LAYER_NUM - 1; i >= 0; i--) {
2187     if (pCtx->sSpsPpsCtx.pActiveLayerSps[i] != NULL) {
2188       iMaxActiveLayer = i;
2189       break;
2190     }
2191   }
2192   for (int i = MAX_LAYER_NUM - 1; i >= 0; i--) {
2193     if (pTmpLayerSps[i] != NULL) {
2194       iMaxCurrentLayer = i;
2195       break;
2196     }
2197   }
2198   if ((iMaxCurrentLayer != iMaxActiveLayer)
2199       || (pTmpLayerSps[iMaxCurrentLayer]  != pCtx->sSpsPpsCtx.pActiveLayerSps[iMaxActiveLayer])) {
2200     bNewSeq = true;
2201   }
2202   // fill active sps if the current sps is not null while active layer is null
2203   if (!bNewSeq) {
2204     for (int i = 0; i < MAX_LAYER_NUM; i++) {
2205       if (pCtx->sSpsPpsCtx.pActiveLayerSps[i] == NULL && pTmpLayerSps[i] != NULL) {
2206         pCtx->sSpsPpsCtx.pActiveLayerSps[i] = pTmpLayerSps[i];
2207       }
2208     }
2209   } else {
2210     // UpdateActiveLayerSps if new sequence start
2211     memcpy (&pCtx->sSpsPpsCtx.pActiveLayerSps[0], &pTmpLayerSps[0], MAX_LAYER_NUM * sizeof (PSps));
2212   }
2213   return bNewSeq;
2214 }
2215 
WriteBackActiveParameters(PWelsDecoderContext pCtx)2216 static void WriteBackActiveParameters (PWelsDecoderContext pCtx) {
2217   if (pCtx->sSpsPpsCtx.iOverwriteFlags & OVERWRITE_PPS) {
2218     memcpy (&pCtx->sSpsPpsCtx.sPpsBuffer[pCtx->sSpsPpsCtx.sPpsBuffer[MAX_PPS_COUNT].iPpsId],
2219             &pCtx->sSpsPpsCtx.sPpsBuffer[MAX_PPS_COUNT], sizeof (SPps));
2220   }
2221   if (pCtx->sSpsPpsCtx.iOverwriteFlags & OVERWRITE_SPS) {
2222     memcpy (&pCtx->sSpsPpsCtx.sSpsBuffer[pCtx->sSpsPpsCtx.sSpsBuffer[MAX_SPS_COUNT].iSpsId],
2223             &pCtx->sSpsPpsCtx.sSpsBuffer[MAX_SPS_COUNT], sizeof (SSps));
2224     pCtx->bNewSeqBegin = true;
2225   }
2226   if (pCtx->sSpsPpsCtx.iOverwriteFlags & OVERWRITE_SUBSETSPS) {
2227     memcpy (&pCtx->sSpsPpsCtx.sSubsetSpsBuffer[pCtx->sSpsPpsCtx.sSubsetSpsBuffer[MAX_SPS_COUNT].sSps.iSpsId],
2228             &pCtx->sSpsPpsCtx.sSubsetSpsBuffer[MAX_SPS_COUNT], sizeof (SSubsetSps));
2229     pCtx->bNewSeqBegin = true;
2230   }
2231   pCtx->sSpsPpsCtx.iOverwriteFlags = OVERWRITE_NONE;
2232 }
2233 
2234 /*
2235  * DecodeFinishUpdate
2236  * decoder finish decoding, update active parameter sets and new seq status
2237  *
2238  */
2239 
DecodeFinishUpdate(PWelsDecoderContext pCtx)2240 void DecodeFinishUpdate (PWelsDecoderContext pCtx) {
2241   pCtx->bNewSeqBegin = false;
2242   WriteBackActiveParameters (pCtx);
2243   pCtx->bNewSeqBegin = pCtx->bNewSeqBegin || pCtx->bNextNewSeqBegin;
2244   pCtx->bNextNewSeqBegin = false; // reset it
2245   if (pCtx->bNewSeqBegin)
2246     ResetActiveSPSForEachLayer (pCtx);
2247 }
2248 
2249 /*
2250 * WelsDecodeInitAccessUnitStart
2251 * check and (re)allocate picture buffers on new sequence begin
2252 *  bit_len:    size in bit length of data
2253 *  buf_len:    size in byte length of data
2254 *  coded_au:   mark an Access Unit decoding finished
2255 * return:
2256 *  0 - success; otherwise returned error_no defined in error_no.h
2257 */
WelsDecodeInitAccessUnitStart(PWelsDecoderContext pCtx,SBufferInfo * pDstInfo)2258 int32_t WelsDecodeInitAccessUnitStart (PWelsDecoderContext pCtx, SBufferInfo* pDstInfo) {
2259   int32_t iErr = ERR_NONE;
2260   PAccessUnit pCurAu = pCtx->pAccessUnitList;
2261   pCtx->bAuReadyFlag = false;
2262   pCtx->pLastDecPicInfo->bLastHasMmco5 = false;
2263   bool bTmpNewSeqBegin = CheckNewSeqBeginAndUpdateActiveLayerSps (pCtx);
2264   pCtx->bNewSeqBegin = pCtx->bNewSeqBegin || bTmpNewSeqBegin;
2265   iErr = WelsDecodeAccessUnitStart (pCtx);
2266   GetVclNalTemporalId (pCtx);
2267 
2268   if (ERR_NONE != iErr) {
2269     ForceResetCurrentAccessUnit (pCtx->pAccessUnitList);
2270     if (!pCtx->pParam->bParseOnly)
2271       pDstInfo->iBufferStatus = 0;
2272     pCtx->bNewSeqBegin = pCtx->bNewSeqBegin || pCtx->bNextNewSeqBegin;
2273     pCtx->bNextNewSeqBegin = false; // reset it
2274     if (pCtx->bNewSeqBegin)
2275       ResetActiveSPSForEachLayer (pCtx);
2276     return iErr;
2277   }
2278 
2279   pCtx->pSps = pCurAu->pNalUnitsList[pCurAu->uiStartPos]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pSps;
2280   pCtx->pPps = pCurAu->pNalUnitsList[pCurAu->uiStartPos]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pPps;
2281 
2282   return iErr;
2283 }
2284 
2285 /*
2286 * AllocPicBuffOnNewSeqBegin
2287 * check and (re)allocate picture buffers on new sequence begin
2288 * return:
2289 *  0 - success; otherwise returned error_no defined in error_no.h
2290 */
AllocPicBuffOnNewSeqBegin(PWelsDecoderContext pCtx)2291 int32_t AllocPicBuffOnNewSeqBegin (PWelsDecoderContext pCtx) {
2292   //try to allocate or relocate DPB memory only when new sequence is coming.
2293   if (GetThreadCount (pCtx) <= 1) {
2294     WelsResetRefPic (pCtx); //clear ref pPic when IDR NAL
2295   }
2296   int32_t iErr = SyncPictureResolutionExt (pCtx, pCtx->pSps->iMbWidth, pCtx->pSps->iMbHeight);
2297 
2298   if (ERR_NONE != iErr) {
2299     WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "sync picture resolution ext failed,  the error is %d", iErr);
2300     return iErr;
2301   }
2302 
2303   return iErr;
2304 }
2305 
2306 /*
2307 * InitConstructAccessUnit
2308 * Init before constructing an access unit for given input bitstream, maybe partial NAL Unit, one or more Units are involved to
2309 * joint a collective access unit.
2310 * parameter\
2311 *  SBufferInfo:    Buffer info
2312 * return:
2313 *  0 - success; otherwise returned error_no defined in error_no.h
2314 */
InitConstructAccessUnit(PWelsDecoderContext pCtx,SBufferInfo * pDstInfo)2315 int32_t InitConstructAccessUnit (PWelsDecoderContext pCtx, SBufferInfo* pDstInfo) {
2316   int32_t iErr = ERR_NONE;
2317 
2318   iErr = WelsDecodeInitAccessUnitStart (pCtx, pDstInfo);
2319   if (ERR_NONE != iErr) {
2320     return iErr;
2321   }
2322   if (pCtx->bNewSeqBegin) {
2323     iErr = AllocPicBuffOnNewSeqBegin (pCtx);
2324     if (ERR_NONE != iErr) {
2325       return iErr;
2326     }
2327   }
2328 
2329   return iErr;
2330 }
2331 
2332 /*
2333  * ConstructAccessUnit
2334  * construct an access unit for given input bitstream, maybe partial NAL Unit, one or more Units are involved to
2335  * joint a collective access unit.
2336  * parameter\
2337  *  buf:        bitstream data buffer
2338  *  bit_len:    size in bit length of data
2339  *  buf_len:    size in byte length of data
2340  *  coded_au:   mark an Access Unit decoding finished
2341  * return:
2342  *  0 - success; otherwise returned error_no defined in error_no.h
2343  */
ConstructAccessUnit(PWelsDecoderContext pCtx,uint8_t ** ppDst,SBufferInfo * pDstInfo)2344 int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {
2345   int32_t iErr = ERR_NONE;
2346   if (GetThreadCount (pCtx) <= 1) {
2347     iErr = InitConstructAccessUnit (pCtx, pDstInfo);
2348     if (ERR_NONE != iErr) {
2349       return iErr;
2350     }
2351   }
2352   if (pCtx->pCabacDecEngine == NULL) {
2353     pCtx->pCabacDecEngine = (SWelsCabacDecEngine*)pCtx->pMemAlign->WelsMallocz (sizeof (SWelsCabacDecEngine),
2354                             "pCtx->pCabacDecEngine");
2355     WELS_VERIFY_RETURN_IF (ERR_INFO_OUT_OF_MEMORY, (NULL == pCtx->pCabacDecEngine))
2356   }
2357 
2358   iErr = DecodeCurrentAccessUnit (pCtx, ppDst, pDstInfo);
2359 
2360   WelsDecodeAccessUnitEnd (pCtx);
2361 
2362   if (ERR_NONE != iErr) {
2363     WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "returned error from decoding:[0x%x]", iErr);
2364     return iErr;
2365   }
2366 
2367   return ERR_NONE;
2368 }
2369 
InitDqLayerInfo(PDqLayer pDqLayer,PLayerInfo pLayerInfo,PNalUnit pNalUnit,PPicture pPicDec)2370 static inline void InitDqLayerInfo (PDqLayer pDqLayer, PLayerInfo pLayerInfo, PNalUnit pNalUnit, PPicture pPicDec) {
2371   PNalUnitHeaderExt pNalHdrExt    = &pNalUnit->sNalHeaderExt;
2372   PSliceHeaderExt pShExt          = &pNalUnit->sNalData.sVclNal.sSliceHeaderExt;
2373   PSliceHeader pSh                = &pShExt->sSliceHeader;
2374   const uint8_t kuiQualityId      = pNalHdrExt->uiQualityId;
2375 
2376   memcpy (&pDqLayer->sLayerInfo, pLayerInfo, sizeof (SLayerInfo)); //confirmed_safe_unsafe_usage
2377 
2378   pDqLayer->pDec        = pPicDec;
2379   pDqLayer->iMbWidth    = pSh->iMbWidth;        // MB width of this picture
2380   pDqLayer->iMbHeight   = pSh->iMbHeight;// MB height of this picture
2381 
2382   pDqLayer->iSliceIdcBackup = (pSh->iFirstMbInSlice << 7) | (pNalHdrExt->uiDependencyId << 4) | (pNalHdrExt->uiQualityId);
2383 
2384   /* Common syntax elements across all slices of a DQLayer */
2385   pDqLayer->uiPpsId                                     = pLayerInfo->pPps->iPpsId;
2386   pDqLayer->uiDisableInterLayerDeblockingFilterIdc      = pShExt->uiDisableInterLayerDeblockingFilterIdc;
2387   pDqLayer->iInterLayerSliceAlphaC0Offset               = pShExt->iInterLayerSliceAlphaC0Offset;
2388   pDqLayer->iInterLayerSliceBetaOffset                  = pShExt->iInterLayerSliceBetaOffset;
2389   pDqLayer->iSliceGroupChangeCycle                      = pSh->iSliceGroupChangeCycle;
2390   pDqLayer->bStoreRefBasePicFlag                        = pShExt->bStoreRefBasePicFlag;
2391   pDqLayer->bTCoeffLevelPredFlag                        = pShExt->bTCoeffLevelPredFlag;
2392   pDqLayer->bConstrainedIntraResamplingFlag             = pShExt->bConstrainedIntraResamplingFlag;
2393   pDqLayer->uiRefLayerDqId                              = pShExt->uiRefLayerDqId;
2394   pDqLayer->uiRefLayerChromaPhaseXPlus1Flag             = pShExt->uiRefLayerChromaPhaseXPlus1Flag;
2395   pDqLayer->uiRefLayerChromaPhaseYPlus1                 = pShExt->uiRefLayerChromaPhaseYPlus1;
2396   pDqLayer->bUseWeightPredictionFlag                    = false;
2397   pDqLayer->bUseWeightedBiPredIdc = false;
2398   //memcpy(&pDqLayer->sScaledRefLayer, &pShExt->sScaledRefLayer, sizeof(SPosOffset));//confirmed_safe_unsafe_usage
2399 
2400   if (kuiQualityId == BASE_QUALITY_ID) {
2401     pDqLayer->pRefPicListReordering = &pSh->pRefPicListReordering;
2402     pDqLayer->pRefPicMarking = &pSh->sRefMarking;
2403 
2404     pDqLayer->bUseWeightPredictionFlag = pSh->pPps->bWeightedPredFlag;
2405     pDqLayer->bUseWeightedBiPredIdc = pSh->pPps->uiWeightedBipredIdc != 0;
2406     if (pSh->pPps->bWeightedPredFlag || pSh->pPps->uiWeightedBipredIdc) {
2407       pDqLayer->pPredWeightTable = &pSh->sPredWeightTable;
2408     }
2409     pDqLayer->pRefPicBaseMarking        = &pShExt->sRefBasePicMarking;
2410   }
2411 
2412   pDqLayer->uiLayerDqId                 = pNalHdrExt->uiLayerDqId;      // dq_id of current layer
2413   pDqLayer->bUseRefBasePicFlag          = pNalHdrExt->bUseRefBasePicFlag;
2414 }
2415 
WelsDqLayerDecodeStart(PWelsDecoderContext pCtx,PNalUnit pCurNal,PSps pSps,PPps pPps)2416 void WelsDqLayerDecodeStart (PWelsDecoderContext pCtx, PNalUnit pCurNal, PSps pSps, PPps pPps) {
2417   PSliceHeader pSh = &pCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader;
2418 
2419   pCtx->eSliceType   = pSh->eSliceType;
2420   pCtx->pSliceHeader = pSh;
2421   pCtx->bUsedAsRef   = false;
2422 
2423   pCtx->iFrameNum    = pSh->iFrameNum;
2424   UpdateDecoderStatisticsForActiveParaset (pCtx->pDecoderStatistics, pSps, pPps);
2425 }
2426 
InitRefPicList(PWelsDecoderContext pCtx,const uint8_t kuiNRi,int32_t iPoc)2427 int32_t InitRefPicList (PWelsDecoderContext pCtx, const uint8_t kuiNRi, int32_t iPoc) {
2428   int32_t iRet = ERR_NONE;
2429   if (pCtx->eSliceType == B_SLICE) {
2430     iRet = WelsInitBSliceRefList (pCtx, iPoc);
2431     CreateImplicitWeightTable (pCtx);
2432   } else
2433     iRet = WelsInitRefList (pCtx, iPoc);
2434   if ((pCtx->eSliceType != I_SLICE && pCtx->eSliceType != SI_SLICE)) {
2435 #if 0
2436     if (pCtx->pSps->uiProfileIdc != 66 && pCtx->pPps->bEntropyCodingModeFlag)
2437       iRet = WelsReorderRefList2 (pCtx);
2438     else
2439 #endif
2440       iRet = WelsReorderRefList (pCtx);
2441   }
2442 
2443   return iRet;
2444 }
2445 
InitCurDqLayerData(PWelsDecoderContext pCtx,PDqLayer pCurDq)2446 void InitCurDqLayerData (PWelsDecoderContext pCtx, PDqLayer pCurDq) {
2447   if (NULL != pCtx && NULL != pCurDq) {
2448     pCurDq->pMbType         = pCtx->sMb.pMbType[0];
2449     pCurDq->pSliceIdc       = pCtx->sMb.pSliceIdc[0];
2450     pCurDq->pMv[LIST_0]         = pCtx->sMb.pMv[0][LIST_0];
2451     pCurDq->pMv[LIST_1]         = pCtx->sMb.pMv[0][LIST_1];
2452     pCurDq->pRefIndex[LIST_0]    = pCtx->sMb.pRefIndex[0][LIST_0];
2453     pCurDq->pRefIndex[LIST_1]   = pCtx->sMb.pRefIndex[0][LIST_1];
2454     pCurDq->pDirect             = pCtx->sMb.pDirect[0];
2455     pCurDq->pNoSubMbPartSizeLessThan8x8Flag = pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[0];
2456     pCurDq->pTransformSize8x8Flag = pCtx->sMb.pTransformSize8x8Flag[0];
2457     pCurDq->pLumaQp         = pCtx->sMb.pLumaQp[0];
2458     pCurDq->pChromaQp       = pCtx->sMb.pChromaQp[0];
2459     pCurDq->pMvd[LIST_0]         = pCtx->sMb.pMvd[0][LIST_0];
2460     pCurDq->pMvd[LIST_1]          = pCtx->sMb.pMvd[0][LIST_1];
2461     pCurDq->pCbfDc          = pCtx->sMb.pCbfDc[0];
2462     pCurDq->pNzc            = pCtx->sMb.pNzc[0];
2463     pCurDq->pNzcRs          = pCtx->sMb.pNzcRs[0];
2464     pCurDq->pScaledTCoeff   = pCtx->sMb.pScaledTCoeff[0];
2465     pCurDq->pIntraPredMode  = pCtx->sMb.pIntraPredMode[0];
2466     pCurDq->pIntra4x4FinalMode = pCtx->sMb.pIntra4x4FinalMode[0];
2467     pCurDq->pIntraNxNAvailFlag = pCtx->sMb.pIntraNxNAvailFlag[0];
2468     pCurDq->pChromaPredMode = pCtx->sMb.pChromaPredMode[0];
2469     pCurDq->pCbp            = pCtx->sMb.pCbp[0];
2470     pCurDq->pSubMbType      = pCtx->sMb.pSubMbType[0];
2471     pCurDq->pInterPredictionDoneFlag = pCtx->sMb.pInterPredictionDoneFlag[0];
2472     pCurDq->pResidualPredFlag = pCtx->sMb.pResidualPredFlag[0];
2473     pCurDq->pMbCorrectlyDecodedFlag = pCtx->sMb.pMbCorrectlyDecodedFlag[0];
2474     pCurDq->pMbRefConcealedFlag = pCtx->sMb.pMbRefConcealedFlag[0];
2475   }
2476 }
2477 
2478 /*
2479  * DecodeCurrentAccessUnit
2480  * Decode current access unit when current AU is completed.
2481  */
DecodeCurrentAccessUnit(PWelsDecoderContext pCtx,uint8_t ** ppDst,SBufferInfo * pDstInfo)2482 int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {
2483   PNalUnit pNalCur = pCtx->pNalCur = NULL;
2484   PAccessUnit pCurAu = pCtx->pAccessUnitList;
2485 
2486   int32_t iIdx = pCurAu->uiStartPos;
2487   int32_t iEndIdx = pCurAu->uiEndPos;
2488 
2489   //get current thread ctx
2490   PWelsDecoderThreadCTX pThreadCtx = NULL;
2491   if (pCtx->pThreadCtx != NULL) {
2492     pThreadCtx = (PWelsDecoderThreadCTX)pCtx->pThreadCtx;
2493   }
2494   //get last thread ctx
2495   PWelsDecoderThreadCTX pLastThreadCtx = NULL;
2496   if (pCtx->pLastThreadCtx != NULL) {
2497     pLastThreadCtx = (PWelsDecoderThreadCTX) (pCtx->pLastThreadCtx);
2498     if (pLastThreadCtx->pDec == NULL) {
2499       pLastThreadCtx->pDec = PrefetchLastPicForThread (pCtx->pPicBuff,
2500                              pLastThreadCtx->iPicBuffIdx);
2501     }
2502   }
2503   int32_t iThreadCount = GetThreadCount (pCtx);
2504   int32_t iPpsId = 0;
2505   int32_t iRet = ERR_NONE;
2506 
2507   bool bAllRefComplete = true; // Assume default all ref picutres are complete
2508 
2509   const uint8_t kuiTargetLayerDqId = GetTargetDqId (pCtx->uiTargetDqId, pCtx->pParam);
2510   const uint8_t kuiDependencyIdMax = (kuiTargetLayerDqId & 0x7F) >> 4;
2511   int16_t iLastIdD = -1, iLastIdQ = -1;
2512   int16_t iCurrIdD = 0, iCurrIdQ = 0;
2513   pCtx->uiNalRefIdc = 0;
2514   bool bFreshSliceAvailable =
2515     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
2516 
2517   //update pCurDqLayer at the starting of AU decoding
2518   if (pCtx->bInitialDqLayersMem || pCtx->pCurDqLayer == NULL) {
2519     pCtx->pCurDqLayer = pCtx->pDqLayersList[0];
2520   }
2521 
2522   InitCurDqLayerData (pCtx, pCtx->pCurDqLayer);
2523 
2524   pNalCur = pCurAu->pNalUnitsList[iIdx];
2525   while (iIdx <= iEndIdx) {
2526     PDqLayer dq_cur = pCtx->pCurDqLayer;
2527     SLayerInfo pLayerInfo;
2528     PSliceHeaderExt pShExt = NULL;
2529     PSliceHeader pSh = NULL;
2530     bool isNewFrame = true;
2531     if (iThreadCount > 1) {
2532       isNewFrame = pCtx->pDec == NULL;
2533     }
2534     if (pCtx->pDec == NULL) {
2535       //make call PrefetchPic first before updating reference lists in threaded mode
2536       //this prevents from possible thread-decoding hanging
2537       pCtx->pDec = PrefetchPic (pCtx->pPicBuff);
2538       if (pLastThreadCtx != NULL) {
2539         pLastThreadCtx->pDec->bUsedAsRef = pLastThreadCtx->pCtx->uiNalRefIdc > 0;
2540         if (pLastThreadCtx->pDec->bUsedAsRef) {
2541           for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
2542             uint32_t i = 0;
2543             while (i < MAX_REF_PIC_COUNT && pLastThreadCtx->pCtx->sRefPic.pRefList[listIdx][i]) {
2544               pLastThreadCtx->pDec->pRefPic[listIdx][i] = pLastThreadCtx->pCtx->sRefPic.pRefList[listIdx][i];
2545               ++i;
2546             }
2547           }
2548           pLastThreadCtx->pCtx->sTmpRefPic = pLastThreadCtx->pCtx->sRefPic;
2549           WelsMarkAsRef (pLastThreadCtx->pCtx, pLastThreadCtx->pDec);
2550           pCtx->sRefPic = pLastThreadCtx->pCtx->sTmpRefPic;
2551         } else {
2552           pCtx->sRefPic = pLastThreadCtx->pCtx->sRefPic;
2553         }
2554       }
2555       //WelsResetRefPic needs to be called when a new sequence is encountered
2556       //Otherwise artifacts is observed in decoded yuv in couple of unit tests with multiple-slice frame
2557       if (GetThreadCount (pCtx) > 1 && pCtx->bNewSeqBegin) {
2558         WelsResetRefPic (pCtx);
2559       }
2560       if (pCtx->iTotalNumMbRec != 0)
2561         pCtx->iTotalNumMbRec = 0;
2562 
2563       if (NULL == pCtx->pDec) {
2564         WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR,
2565                  "DecodeCurrentAccessUnit()::::::PrefetchPic ERROR, pSps->iNumRefFrames:%d.",
2566                  pCtx->pSps->iNumRefFrames);
2567         // The error code here need to be separated from the dsOutOfMemory
2568         pCtx->iErrorCode |= dsOutOfMemory;
2569         return ERR_INFO_REF_COUNT_OVERFLOW;
2570       }
2571       if (pThreadCtx != NULL) {
2572         pThreadCtx->pDec = pCtx->pDec;
2573         if (iThreadCount > 1) ++pCtx->pDec->iRefCount;
2574         uint32_t uiMbHeight = (pCtx->pDec->iHeightInPixel + 15) >> 4;
2575         for (uint32_t i = 0; i < uiMbHeight; ++i) {
2576           RESET_EVENT (&pCtx->pDec->pReadyEvent[i]);
2577         }
2578       }
2579       pCtx->pDec->bNewSeqBegin = pCtx->bNewSeqBegin; //set flag for start decoding
2580     } else if (pCtx->iTotalNumMbRec == 0) { //pDec != NULL, already start
2581       pCtx->pDec->bNewSeqBegin = pCtx->bNewSeqBegin; //set flag for start decoding
2582     }
2583     pCtx->pDec->uiTimeStamp = pNalCur->uiTimeStamp;
2584     pCtx->pDec->uiDecodingTimeStamp = pCtx->uiDecodingTimeStamp;
2585     if (pThreadCtx != NULL) {
2586       pThreadCtx->iPicBuffIdx = pCtx->pDec->iPicBuffIdx;
2587       pCtx->pCurDqLayer->pMbCorrectlyDecodedFlag = pCtx->pDec->pMbCorrectlyDecodedFlag;
2588     }
2589 
2590     if (pCtx->iTotalNumMbRec == 0) { //Picture start to decode
2591       for (int32_t i = 0; i < LAYER_NUM_EXCHANGEABLE; ++ i)
2592         memset (pCtx->sMb.pSliceIdc[i], 0xff, (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t)));
2593       memset (pCtx->pCurDqLayer->pMbCorrectlyDecodedFlag, 0, pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight * sizeof (bool));
2594       memset (pCtx->pCurDqLayer->pMbRefConcealedFlag, 0, pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight * sizeof (bool));
2595       memset (pCtx->pDec->pRefPic[LIST_0], 0, sizeof (PPicture) * MAX_DPB_COUNT);
2596       memset (pCtx->pDec->pRefPic[LIST_1], 0, sizeof (PPicture) * MAX_DPB_COUNT);
2597       pCtx->pDec->iMbNum = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
2598       pCtx->pDec->iMbEcedNum = 0;
2599       pCtx->pDec->iMbEcedPropNum = 0;
2600     }
2601     pCtx->bRPLRError = false;
2602     GetI4LumaIChromaAddrTable (pCtx->iDecBlockOffsetArray, pCtx->pDec->iLinesize[0], pCtx->pDec->iLinesize[1]);
2603 
2604     if (pNalCur->sNalHeaderExt.uiLayerDqId > kuiTargetLayerDqId) { // confirmed pNalCur will never be NULL
2605       break; // Per formance it need not to decode the remaining bits any more due to given uiLayerDqId required, 9/2/2009
2606     }
2607 
2608     memset (&pLayerInfo, 0, sizeof (SLayerInfo));
2609 
2610     /*
2611      *  Loop decoding for slices (even FMO and/ multiple slices) within a dq layer
2612      */
2613     while (iIdx <= iEndIdx) {
2614       bool         bReconstructSlice;
2615       iCurrIdQ  = pNalCur->sNalHeaderExt.uiQualityId;
2616       iCurrIdD  = pNalCur->sNalHeaderExt.uiDependencyId;
2617       pSh       = &pNalCur->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader;
2618       pShExt    = &pNalCur->sNalData.sVclNal.sSliceHeaderExt;
2619       pCtx->bRPLRError = false;
2620       bReconstructSlice = CheckSliceNeedReconstruct (pNalCur->sNalHeaderExt.uiLayerDqId, kuiTargetLayerDqId);
2621 
2622       memcpy (&pLayerInfo.sNalHeaderExt, &pNalCur->sNalHeaderExt, sizeof (SNalUnitHeaderExt)); //confirmed_safe_unsafe_usage
2623 
2624       pCtx->pDec->iFrameNum = pSh->iFrameNum;
2625       pCtx->pDec->iFramePoc = pSh->iPicOrderCntLsb; // still can not obtain correct, because current do not support POCtype 2
2626       pCtx->pDec->bIdrFlag = pNalCur->sNalHeaderExt.bIdrFlag;
2627       pCtx->pDec->eSliceType = pSh->eSliceType;
2628 
2629       memcpy (&pLayerInfo.sSliceInLayer.sSliceHeaderExt, pShExt, sizeof (SSliceHeaderExt)); //confirmed_safe_unsafe_usage
2630       pLayerInfo.sSliceInLayer.bSliceHeaderExtFlag      = pNalCur->sNalData.sVclNal.bSliceHeaderExtFlag;
2631       pLayerInfo.sSliceInLayer.eSliceType               = pSh->eSliceType;
2632       pLayerInfo.sSliceInLayer.iLastMbQp                = pSh->iSliceQp;
2633       dq_cur->pBitStringAux = &pNalCur->sNalData.sVclNal.sSliceBitsRead;
2634 
2635       pCtx->uiNalRefIdc = pNalCur->sNalHeaderExt.sNalUnitHeader.uiNalRefIdc;
2636 
2637       iPpsId = pSh->iPpsId;
2638 
2639       pLayerInfo.pPps = pSh->pPps;
2640       pLayerInfo.pSps = pSh->pSps;
2641       pLayerInfo.pSubsetSps = pShExt->pSubsetSps;
2642 
2643       pCtx->pFmo = &pCtx->sFmoList[iPpsId];
2644       iRet = FmoParamUpdate (pCtx->pFmo, pLayerInfo.pSps, pLayerInfo.pPps, &pCtx->iActiveFmoNum, pCtx->pMemAlign);
2645       if (ERR_NONE != iRet) {
2646         if (iRet == ERR_INFO_OUT_OF_MEMORY) {
2647           pCtx->iErrorCode |= dsOutOfMemory;
2648           WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "DecodeCurrentAccessUnit(), Fmo param alloc failed");
2649         } else {
2650           pCtx->iErrorCode |= dsBitstreamError;
2651           WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "DecodeCurrentAccessUnit(), FmoParamUpdate failed, eSliceType: %d.",
2652                    pSh->eSliceType);
2653         }
2654         return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_FMO_INIT_FAIL);
2655       }
2656 
2657       bFreshSliceAvailable = (iCurrIdD != iLastIdD
2658                               || iCurrIdQ != iLastIdQ);        // do not need condition of (first_mb == 0) due multiple slices might be disorder
2659 
2660 
2661       WelsDqLayerDecodeStart (pCtx, pNalCur, pLayerInfo.pSps, pLayerInfo.pPps);
2662 
2663 
2664       if ((iLastIdD < 0) ||  //case 1: first layer
2665           (iLastIdD == iCurrIdD)) { //case 2: same uiDId
2666         InitDqLayerInfo (dq_cur, &pLayerInfo, pNalCur, pCtx->pDec);
2667 
2668         if (!dq_cur->sLayerInfo.pSps->bGapsInFrameNumValueAllowedFlag) {
2669           const bool kbIdrFlag = dq_cur->sLayerInfo.sNalHeaderExt.bIdrFlag
2670                                  || (dq_cur->sLayerInfo.sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR);
2671           // Subclause 8.2.5.2 Decoding process for gaps in frame_num
2672           int32_t iPrevFrameNum = pCtx->pLastDecPicInfo->iPrevFrameNum;
2673           if (pLastThreadCtx != NULL) {
2674             //call GetPrevFrameNum() to get correct iPrevFrameNum to prevent frame gap warning
2675             iPrevFrameNum = pCtx->bNewSeqBegin ? 0 : GetPrevFrameNum (pCtx);
2676           }
2677           if (!kbIdrFlag  &&
2678               pSh->iFrameNum != iPrevFrameNum &&
2679               pSh->iFrameNum != ((iPrevFrameNum + 1) & ((1 << dq_cur->sLayerInfo.pSps->uiLog2MaxFrameNum) -
2680                                  1))) {
2681             WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
2682                      "referencing pictures lost due frame gaps exist, prev_frame_num: %d, curr_frame_num: %d",
2683                      iPrevFrameNum,
2684                      pSh->iFrameNum);
2685 
2686             bAllRefComplete = false;
2687             pCtx->iErrorCode |= dsRefLost;
2688             if (pCtx->pParam->eEcActiveIdc == ERROR_CON_DISABLE) {
2689 #ifdef LONG_TERM_REF
2690               pCtx->bParamSetsLostFlag = true;
2691 #else
2692               pCtx->bReferenceLostAtT0Flag = true;
2693 #endif
2694               return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_REFERENCE_PIC_LOST);
2695             }
2696           }
2697         }
2698 
2699         if (iCurrIdD == kuiDependencyIdMax && iCurrIdQ == BASE_QUALITY_ID && isNewFrame) {
2700           iRet = InitRefPicList (pCtx, pCtx->uiNalRefIdc, pSh->iPicOrderCntLsb);
2701           if (iThreadCount > 1) isNewFrame = false;
2702           if (iRet) {
2703             pCtx->bRPLRError = true;
2704             bAllRefComplete = false; // RPLR error, set ref pictures complete flag false
2705             HandleReferenceLost (pCtx, pNalCur);
2706             WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
2707                      "reference picture introduced by this frame is lost during transmission! uiTId: %d",
2708                      pNalCur->sNalHeaderExt.uiTemporalId);
2709             if (pCtx->pParam->eEcActiveIdc == ERROR_CON_DISABLE) {
2710               if (pCtx->iTotalNumMbRec == 0)
2711                 pCtx->pDec = NULL;
2712               return iRet;
2713             }
2714           }
2715         }
2716         //calculate Colocated mv scaling factor for temporal direct prediction
2717         if (pSh->eSliceType == B_SLICE && !pSh->iDirectSpatialMvPredFlag)
2718           ComputeColocatedTemporalScaling (pCtx);
2719 
2720         if (iThreadCount > 1) {
2721           if (iIdx == 0) {
2722             memset (&pCtx->lastReadyHeightOffset[0][0], -1, LIST_A * MAX_REF_PIC_COUNT * sizeof (int16_t));
2723             SET_EVENT (&pThreadCtx->sSliceDecodeStart);
2724           }
2725           iRet = WelsDecodeAndConstructSlice (pCtx);
2726         } else {
2727           iRet = WelsDecodeSlice (pCtx, bFreshSliceAvailable, pNalCur);
2728         }
2729 
2730         //Output good store_base reconstruction when enhancement quality layer occurred error for MGS key picture case
2731         if (iRet != ERR_NONE) {
2732           WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
2733                    "DecodeCurrentAccessUnit() failed (%d) in frame: %d uiDId: %d uiQId: %d",
2734                    iRet, pSh->iFrameNum, iCurrIdD, iCurrIdQ);
2735           bAllRefComplete = false;
2736           HandleReferenceLostL0 (pCtx, pNalCur);
2737           if (pCtx->pParam->eEcActiveIdc == ERROR_CON_DISABLE) {
2738             if (pCtx->iTotalNumMbRec == 0)
2739               pCtx->pDec = NULL;
2740             return iRet;
2741           }
2742         }
2743 
2744         if (iThreadCount <= 1 && bReconstructSlice) {
2745           if ((iRet = WelsDecodeConstructSlice (pCtx, pNalCur)) != ERR_NONE) {
2746             pCtx->pDec->bIsComplete = false; // reconstruction error, directly set the flag false
2747             return iRet;
2748           }
2749         }
2750         if (bAllRefComplete && pCtx->eSliceType != I_SLICE) {
2751           if (iThreadCount <= 1) {
2752             if (pCtx->sRefPic.uiRefCount[LIST_0] > 0) {
2753               bAllRefComplete &= CheckRefPicturesComplete (pCtx);
2754             } else {
2755               bAllRefComplete = false;
2756             }
2757           }
2758         }
2759       }
2760 #if defined (_DEBUG) &&  !defined (CODEC_FOR_TESTBED)
2761       WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "cur_frame : %d\tiCurrIdD : %d\n ",
2762                dq_cur->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iFrameNum, iCurrIdD);
2763 #endif//#if !CODEC_FOR_TESTBED
2764       iLastIdD = iCurrIdD;
2765       iLastIdQ = iCurrIdQ;
2766 
2767       //pNalUnitsList overflow.
2768       ++ iIdx;
2769       if (iIdx <= iEndIdx) {
2770         pNalCur = pCurAu->pNalUnitsList[iIdx];
2771       } else {
2772         pNalCur = NULL;
2773       }
2774 
2775       if (pNalCur == NULL ||
2776           iLastIdD != pNalCur->sNalHeaderExt.uiDependencyId ||
2777           iLastIdQ != pNalCur->sNalHeaderExt.uiQualityId)
2778         break;
2779     }
2780 
2781     // Set the current dec picture complete flag. The flag will be reset when current picture need do ErrorCon.
2782     pCtx->pDec->bIsComplete = bAllRefComplete;
2783     if (!pCtx->pDec->bIsComplete) {  // Ref pictures ECed, result in ECed
2784       pCtx->iErrorCode |= dsDataErrorConcealed;
2785     }
2786 
2787     // A dq layer decoded here
2788 #if defined (_DEBUG) &&  !defined (CODEC_FOR_TESTBED)
2789 #undef fprintf
2790     WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "POC: #%d, FRAME: #%d, D: %d, Q: %d, T: %d, P: %d, %d\n",
2791              pSh->iPicOrderCntLsb, pSh->iFrameNum, iCurrIdD, iCurrIdQ, dq_cur->sLayerInfo.sNalHeaderExt.uiTemporalId,
2792              dq_cur->sLayerInfo.sNalHeaderExt.uiPriorityId, dq_cur->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iSliceQp);
2793 #endif//#if !CODEC_FOR_TESTBED
2794 
2795     if (dq_cur->uiLayerDqId == kuiTargetLayerDqId) {
2796       if (!pCtx->bInstantDecFlag) {
2797         if (!pCtx->pParam->bParseOnly) {
2798           //Do error concealment here
2799           if ((NeedErrorCon (pCtx)) && (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE)) {
2800             ImplementErrorCon (pCtx);
2801             pCtx->iTotalNumMbRec = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
2802             pCtx->pDec->iSpsId = pCtx->pSps->iSpsId;
2803             pCtx->pDec->iPpsId = pCtx->pPps->iPpsId;
2804           }
2805         }
2806       }
2807 
2808       if (iThreadCount >= 1) {
2809         int32_t  id = pThreadCtx->sThreadInfo.uiThrNum;
2810         for (int32_t i = 0; i < iThreadCount; ++i) {
2811           if (i == id || pThreadCtx[i - id].pCtx->uiDecodingTimeStamp == 0) continue;
2812           if (pThreadCtx[i - id].pCtx->uiDecodingTimeStamp < pCtx->uiDecodingTimeStamp) {
2813             WAIT_EVENT (&pThreadCtx[i - id].sSliceDecodeFinish, WELS_DEC_THREAD_WAIT_INFINITE);
2814           }
2815         }
2816         pCtx->pLastDecPicInfo->uiDecodingTimeStamp = pCtx->uiDecodingTimeStamp;
2817       }
2818       iRet = DecodeFrameConstruction (pCtx, ppDst, pDstInfo);
2819       if (iRet) {
2820         if (iThreadCount > 1) {
2821           SET_EVENT (&pThreadCtx->sSliceDecodeFinish);
2822         }
2823         return iRet;
2824       }
2825 
2826       pCtx->pLastDecPicInfo->pPreviousDecodedPictureInDpb = pCtx->pDec; //store latest decoded picture for EC
2827       pCtx->bUsedAsRef = pCtx->uiNalRefIdc > 0;
2828       if (iThreadCount <= 1) {
2829         if (pCtx->bUsedAsRef) {
2830           for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
2831             uint32_t i = 0;
2832             while (i < MAX_DPB_COUNT && pCtx->sRefPic.pRefList[listIdx][i]) {
2833               pCtx->pDec->pRefPic[listIdx][i] = pCtx->sRefPic.pRefList[listIdx][i];
2834               ++i;
2835             }
2836           }
2837           iRet = WelsMarkAsRef (pCtx);
2838           if (iRet != ERR_NONE) {
2839             if (iRet == ERR_INFO_DUPLICATE_FRAME_NUM)
2840               pCtx->iErrorCode |= dsBitstreamError;
2841             if (pCtx->pParam->eEcActiveIdc == ERROR_CON_DISABLE) {
2842               pCtx->pDec = NULL;
2843               return iRet;
2844             }
2845           }
2846           if (!pCtx->pParam->bParseOnly)
2847             ExpandReferencingPicture (pCtx->pDec->pData, pCtx->pDec->iWidthInPixel, pCtx->pDec->iHeightInPixel,
2848                                       pCtx->pDec->iLinesize,
2849                                       pCtx->sExpandPicFunc.pfExpandLumaPicture, pCtx->sExpandPicFunc.pfExpandChromaPicture);
2850         }
2851       } else if (iThreadCount > 1) {
2852         SET_EVENT (&pThreadCtx->sImageReady);
2853       }
2854       pCtx->pDec = NULL; //after frame decoding, always set to NULL
2855     }
2856 
2857     // need update frame_num due current frame is well decoded
2858     if (pCurAu->pNalUnitsList[pCurAu->uiStartPos]->sNalHeaderExt.sNalUnitHeader.uiNalRefIdc > 0)
2859       pCtx->pLastDecPicInfo->iPrevFrameNum = pSh->iFrameNum;
2860     if (pCtx->pLastDecPicInfo->bLastHasMmco5)
2861       pCtx->pLastDecPicInfo->iPrevFrameNum = 0;
2862     if (iThreadCount > 1) {
2863       int32_t  id = pThreadCtx->sThreadInfo.uiThrNum;
2864       for (int32_t i = 0; i < iThreadCount; ++i) {
2865         if (pThreadCtx[i - id].pCtx != NULL) {
2866           unsigned long long uiTimeStamp = pThreadCtx[i - id].pCtx->uiTimeStamp;
2867           if (uiTimeStamp > 0 && pThreadCtx[i - id].pCtx->sSpsPpsCtx.iSeqId > pCtx->sSpsPpsCtx.iSeqId) {
2868             CopySpsPps (pThreadCtx[i - id].pCtx, pCtx);
2869             if (pCtx->pPicBuff != pThreadCtx[i - id].pCtx->pPicBuff) {
2870               pCtx->pPicBuff = pThreadCtx[i - id].pCtx->pPicBuff;
2871             }
2872             InitialDqLayersContext (pCtx, pCtx->pSps->iMbWidth << 4, pCtx->pSps->iMbHeight << 4);
2873             break;
2874           }
2875         }
2876       }
2877     }
2878     if (iThreadCount > 1) {
2879       SET_EVENT (&pThreadCtx->sSliceDecodeFinish);
2880     }
2881   }
2882   return ERR_NONE;
2883 }
2884 
CheckAndFinishLastPic(PWelsDecoderContext pCtx,uint8_t ** ppDst,SBufferInfo * pDstInfo)2885 bool CheckAndFinishLastPic (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {
2886   PAccessUnit pAu = pCtx->pAccessUnitList;
2887   bool bAuBoundaryFlag = false;
2888   if (IS_VCL_NAL (pCtx->sCurNalHead.eNalUnitType, 1)) { //VCL data, AU list should have data
2889     PNalUnit pCurNal = pAu->pNalUnitsList[pAu->uiEndPos];
2890     bAuBoundaryFlag = (pCtx->iTotalNumMbRec != 0)
2891                       && (CheckAccessUnitBoundaryExt (&pCtx->pLastDecPicInfo->sLastNalHdrExt, &pCurNal->sNalHeaderExt,
2892                           &pCtx->pLastDecPicInfo->sLastSliceHeader,
2893                           &pCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader));
2894   } else { //non VCL
2895     if (pCtx->sCurNalHead.eNalUnitType == NAL_UNIT_AU_DELIMITER) {
2896       bAuBoundaryFlag = true;
2897     } else if (pCtx->sCurNalHead.eNalUnitType == NAL_UNIT_SEI) {
2898       bAuBoundaryFlag = true;
2899     } else if (pCtx->sCurNalHead.eNalUnitType == NAL_UNIT_SPS) {
2900       bAuBoundaryFlag = !! (pCtx->sSpsPpsCtx.iOverwriteFlags & OVERWRITE_SPS);
2901     } else if (pCtx->sCurNalHead.eNalUnitType == NAL_UNIT_SUBSET_SPS) {
2902       bAuBoundaryFlag = !! (pCtx->sSpsPpsCtx.iOverwriteFlags & OVERWRITE_SUBSETSPS);
2903     } else if (pCtx->sCurNalHead.eNalUnitType == NAL_UNIT_PPS) {
2904       bAuBoundaryFlag = !! (pCtx->sSpsPpsCtx.iOverwriteFlags & OVERWRITE_PPS);
2905     }
2906     if (bAuBoundaryFlag && pCtx->pAccessUnitList->uiAvailUnitsNum != 0) { //Construct remaining data first
2907       ConstructAccessUnit (pCtx, ppDst, pDstInfo);
2908     }
2909   }
2910 
2911   //Do Error Concealment here
2912   if (bAuBoundaryFlag && (pCtx->iTotalNumMbRec != 0) && NeedErrorCon (pCtx)) { //AU ready but frame not completely reconed
2913     if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
2914       ImplementErrorCon (pCtx);
2915       pCtx->iTotalNumMbRec = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
2916       pCtx->pDec->iSpsId = pCtx->pSps->iSpsId;
2917       pCtx->pDec->iPpsId = pCtx->pPps->iPpsId;
2918 
2919       DecodeFrameConstruction (pCtx, ppDst, pDstInfo);
2920       pCtx->pLastDecPicInfo->pPreviousDecodedPictureInDpb = pCtx->pDec; //save ECed pic for future use
2921       if (pCtx->pLastDecPicInfo->sLastNalHdrExt.sNalUnitHeader.uiNalRefIdc > 0) {
2922         if (MarkECFrameAsRef (pCtx) == ERR_INFO_INVALID_PTR) {
2923           pCtx->iErrorCode |= dsRefListNullPtrs;
2924           return false;
2925         }
2926       }
2927     } else if (pCtx->pParam->bParseOnly) { //clear parse only internal data status
2928       pCtx->pParserBsInfo->iNalNum = 0;
2929       pCtx->bFrameFinish = true; //clear frame pending status here!
2930     } else {
2931       if (DecodeFrameConstruction (pCtx, ppDst, pDstInfo)) {
2932         if ((pCtx->pLastDecPicInfo->sLastNalHdrExt.sNalUnitHeader.uiNalRefIdc > 0)
2933             && (pCtx->pLastDecPicInfo->sLastNalHdrExt.uiTemporalId == 0))
2934           pCtx->iErrorCode |= dsNoParamSets;
2935         else
2936           pCtx->iErrorCode |= dsBitstreamError;
2937         pCtx->pDec = NULL;
2938         return false;
2939       }
2940     }
2941     pCtx->pDec = NULL;
2942     if (pAu->pNalUnitsList[pAu->uiStartPos]->sNalHeaderExt.sNalUnitHeader.uiNalRefIdc > 0)
2943       pCtx->pLastDecPicInfo->iPrevFrameNum = pCtx->pLastDecPicInfo->sLastSliceHeader.iFrameNum; //save frame_num
2944     if (pCtx->pLastDecPicInfo->bLastHasMmco5)
2945       pCtx->pLastDecPicInfo->iPrevFrameNum = 0;
2946   }
2947   return ERR_NONE;
2948 }
2949 
CheckRefPicturesComplete(PWelsDecoderContext pCtx)2950 bool CheckRefPicturesComplete (PWelsDecoderContext pCtx) {
2951   // Multi Reference, RefIdx may differ
2952   bool bAllRefComplete = true;
2953   int32_t iRealMbIdx = pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iFirstMbInSlice;
2954   for (int32_t iMbIdx = 0; bAllRefComplete
2955        && iMbIdx < pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer.iTotalMbInCurSlice; iMbIdx++) {
2956     switch (pCtx->pCurDqLayer->pDec->pMbType[iRealMbIdx]) {
2957     case MB_TYPE_SKIP:
2958     case MB_TYPE_16x16:
2959       bAllRefComplete &=
2960         pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pDec->pRefIndex[0][iRealMbIdx][0] ]->bIsComplete;
2961       break;
2962 
2963     case MB_TYPE_16x8:
2964       bAllRefComplete &=
2965         pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pDec->pRefIndex[0][iRealMbIdx][0] ]->bIsComplete;
2966       bAllRefComplete &=
2967         pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pDec->pRefIndex[0][iRealMbIdx][8] ]->bIsComplete;
2968       break;
2969 
2970     case MB_TYPE_8x16:
2971       bAllRefComplete &=
2972         pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pDec->pRefIndex[0][iRealMbIdx][0] ]->bIsComplete;
2973       bAllRefComplete &=
2974         pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pDec->pRefIndex[0][iRealMbIdx][2] ]->bIsComplete;
2975       break;
2976 
2977     case MB_TYPE_8x8:
2978     case MB_TYPE_8x8_REF0:
2979       bAllRefComplete &=
2980         pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pDec->pRefIndex[0][iRealMbIdx][0] ]->bIsComplete;
2981       bAllRefComplete &=
2982         pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pDec->pRefIndex[0][iRealMbIdx][2] ]->bIsComplete;
2983       bAllRefComplete &=
2984         pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pDec->pRefIndex[0][iRealMbIdx][8] ]->bIsComplete;
2985       bAllRefComplete &=
2986         pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pDec->pRefIndex[0][iRealMbIdx][10] ]->bIsComplete;
2987       break;
2988 
2989     default:
2990       break;
2991     }
2992     iRealMbIdx = (pCtx->pPps->uiNumSliceGroups > 1) ? FmoNextMb (pCtx->pFmo, iRealMbIdx) :
2993                  (pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iFirstMbInSlice + iMbIdx);
2994     if (iRealMbIdx == -1) //caused by abnormal return of FmoNextMb()
2995       return false;
2996   }
2997 
2998   return bAllRefComplete;
2999 }
3000 } // namespace WelsDec
3001