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