History

convert windows file line break to unix format

Guangwei committed 8 years ago

Commit 3efd69a1 parent 0d713264 files · +6361 −6361Browse files

Showing the changes to codec/decoder/core/src/decoder_core.cpp (1 of 4 files). Show all

Unified · Split

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

555 more lines aren’t shown here.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t