History

B-frame decoding support for Main and High Profile with two test cases.

xiaotianshi2 committed 8 years ago

Commit 657d2171 parent e3e838355 files · +17936 −13825Browse files

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

Unified · Split

codec/decoder/core/src/decoder_core.cpp+2772−2639
@@ -1,2639 +1,2772 @@
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 315 if ((pSh->sPredWeightTable.uiLumaLog2WeightDenom | pSh->sPredWeightTable.uiChromaLog2WeightDenom) > 7)
316 do {316 return ERR_NONE;
317 317
318 for (int i = 0; i < pSh->uiRefCount[iList]; i++) {318 do {
319 //luma319
320 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode));320 for (int i = 0; i < pSh->uiRefCount[iList]; i++) {
321 if (!!uiCode) {321 //luma
322 322 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode));
323 WELS_READ_VERIFY (BsGetSe (pBs, &iCode));323 if (!!uiCode) {
324 WELS_CHECK_SE_BOTH_ERROR_NOLOG (iCode, -128, 127, "luma_weight",324
325 GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_LUMA_WEIGHT));325 WELS_READ_VERIFY (BsGetSe (pBs, &iCode));
326 pSh->sPredWeightTable.sPredList[iList].iLumaWeight[i] = iCode;326 WELS_CHECK_SE_BOTH_ERROR_NOLOG (iCode, -128, 127, "luma_weight",
327 327 GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_LUMA_WEIGHT));
328 WELS_READ_VERIFY (BsGetSe (pBs, &iCode));328 pSh->sPredWeightTable.sPredList[iList].iLumaWeight[i] = iCode;
329 WELS_CHECK_SE_BOTH_ERROR_NOLOG (iCode, -128, 127, "luma_offset",329
330 GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_LUMA_OFFSET));330 WELS_READ_VERIFY (BsGetSe (pBs, &iCode));
331 pSh->sPredWeightTable.sPredList[iList].iLumaOffset[i] = iCode;331 WELS_CHECK_SE_BOTH_ERROR_NOLOG (iCode, -128, 127, "luma_offset",
332 } else {332 GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_LUMA_OFFSET));
333 pSh->sPredWeightTable.sPredList[iList].iLumaWeight[i] = 1 << (pSh->sPredWeightTable.uiLumaLog2WeightDenom);333 pSh->sPredWeightTable.sPredList[iList].iLumaOffset[i] = iCode;
334 pSh->sPredWeightTable.sPredList[iList].iLumaOffset[i] = 0;334 } else {
335 335 pSh->sPredWeightTable.sPredList[iList].iLumaWeight[i] = 1 << (pSh->sPredWeightTable.uiLumaLog2WeightDenom);
336 }336 pSh->sPredWeightTable.sPredList[iList].iLumaOffset[i] = 0;
337 //chroma337
338 if (pSh->pSps->uiChromaArrayType == 0)338 }
339 continue;339 //chroma
340 340 if (pSh->pSps->uiChromaArrayType == 0)
341 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode));341 continue;
342 if (!!uiCode) {342
343 for (int j = 0; j < 2; j++) {343 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode));
344 344 if (!!uiCode) {
345 345 for (int j = 0; j < 2; j++) {
346 WELS_READ_VERIFY (BsGetSe (pBs, &iCode));346
347 WELS_CHECK_SE_BOTH_ERROR_NOLOG (iCode, -128, 127, "chroma_weight",347
348 GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_CHROMA_WEIGHT));348 WELS_READ_VERIFY (BsGetSe (pBs, &iCode));
349 pSh->sPredWeightTable.sPredList[iList].iChromaWeight[i][j] = iCode;349 WELS_CHECK_SE_BOTH_ERROR_NOLOG (iCode, -128, 127, "chroma_weight",
350 350 GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_CHROMA_WEIGHT));
351 WELS_READ_VERIFY (BsGetSe (pBs, &iCode));351 pSh->sPredWeightTable.sPredList[iList].iChromaWeight[i][j] = iCode;
352 WELS_CHECK_SE_BOTH_ERROR_NOLOG (iCode, -128, 127, "chroma_offset",352
353 GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_CHROMA_OFFSET));353 WELS_READ_VERIFY (BsGetSe (pBs, &iCode));
354 pSh->sPredWeightTable.sPredList[iList].iChromaOffset[i][j] = iCode;354 WELS_CHECK_SE_BOTH_ERROR_NOLOG (iCode, -128, 127, "chroma_offset",
355 }355 GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_CHROMA_OFFSET));
356 } else {356 pSh->sPredWeightTable.sPredList[iList].iChromaOffset[i][j] = iCode;
357 for (int j = 0; j < 2; j++) {357 }
358 358 } else {
359 359 for (int j = 0; j < 2; j++) {
360 pSh->sPredWeightTable.sPredList[iList].iChromaWeight[i][j] = 1 << (pSh->sPredWeightTable.uiChromaLog2WeightDenom);360
361 pSh->sPredWeightTable.sPredList[iList].iChromaOffset[i][j] = 0;361
362 }362 pSh->sPredWeightTable.sPredList[iList].iChromaWeight[i][j] = 1 << (pSh->sPredWeightTable.uiChromaLog2WeightDenom);
363 }363 pSh->sPredWeightTable.sPredList[iList].iChromaOffset[i][j] = 0;
364 364 }
365 }365 }
366 ++iList;366
367 } while (iList < LIST_1);//TODO: SUPPORT LIST_A367 }
368 return ERR_NONE;368 ++iList;
369}369 if (pSh->eSliceType != B_SLICE) {
370 370 break;
371/*371 }
372 * Predeclared function routines ..372 } while (iList < LIST_A);//TODO: SUPPORT LIST_A
373 */373 return ERR_NONE;
374int32_t ParseRefPicListReordering (PBitStringAux pBs, PSliceHeader pSh) {374}
375 int32_t iList = 0;375
376 const EWelsSliceType keSt = pSh->eSliceType;376void CreateImplicitWeightTable (PWelsDecoderContext pCtx) {
377 PRefPicListReorderSyn pRefPicListReordering = &pSh->pRefPicListReordering;377
378 PSps pSps = pSh->pSps;378 PSlice pSlice = &pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer;
379 uint32_t uiCode;379 PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
380 if (keSt == I_SLICE || keSt == SI_SLICE)380 PDqLayer pCurDqLayer = pCtx->pCurDqLayer;
381 return ERR_NONE;381 if (pCurDqLayer->bUseWeightedBiPredIdc && pSliceHeader->pPps->uiWeightedBipredIdc == 2) {
382 382 int32_t iPoc = pSliceHeader->iPicOrderCntLsb;
383 // Common syntaxs for P or B slices: list0, list1 followed if B slices used.383
384 do {384 if (pSliceHeader->uiRefCount[0] == 1 && pSliceHeader->uiRefCount[1] == 1
385 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //ref_pic_list_modification_flag_l0385 && pCtx->sRefPic.pRefList[LIST_0][0]->iFramePoc + pCtx->sRefPic.pRefList[LIST_1][0]->iFramePoc == 2 * iPoc) {
386 pRefPicListReordering->bRefPicListReorderingFlag[iList] = !!uiCode;386 pCurDqLayer->bUseWeightedBiPredIdc = false;
387 387 return;
388 if (pRefPicListReordering->bRefPicListReorderingFlag[iList]) {388 }
389 int32_t iIdx = 0;389
390 do {390 pCurDqLayer->pPredWeightTable->uiLumaLog2WeightDenom = 5;
391 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //modification_of_pic_nums_idc391 pCurDqLayer->pPredWeightTable->uiChromaLog2WeightDenom = 5;
392 const uint32_t kuiIdc = uiCode;392 for (int32_t iRef0 = 0; iRef0 < pSliceHeader->uiRefCount[0]; iRef0++) {
393 393 if (pCtx->sRefPic.pRefList[LIST_0][iRef0]) {
394 //Fixed the referrence list reordering crash issue.(fault kIdc value > 3 case)---394 const int32_t iPoc0 = pCtx->sRefPic.pRefList[LIST_0][iRef0]->iFramePoc;
395 if ((iIdx >= MAX_REF_PIC_COUNT) || (kuiIdc > 3)) {395 bool bIsLongRef0 = pCtx->sRefPic.pRefList[LIST_0][iRef0]->bIsLongRef;
396 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REF_REORDERING);396 for (int32_t iRef1 = 0; iRef1 < pSliceHeader->uiRefCount[1]; iRef1++) {
397 }397 if (pCtx->sRefPic.pRefList[LIST_1][iRef1]) {
398 pRefPicListReordering->sReorderingSyn[iList][iIdx].uiReorderingOfPicNumsIdc = kuiIdc;398 const int32_t iPoc1 = pCtx->sRefPic.pRefList[LIST_1][iRef1]->iFramePoc;
399 if (kuiIdc == 3)399 bool bIsLongRef1 = pCtx->sRefPic.pRefList[LIST_1][iRef1]->bIsLongRef;
400 break;400 pCurDqLayer->pPredWeightTable->iImplicitWeight[iRef0][iRef1] = 32;
401 401 if (!bIsLongRef0 && !bIsLongRef1) {
402 if (iIdx >= pSh->uiRefCount[iList] || iIdx >= MAX_REF_PIC_COUNT)402 const int32_t iTd = WELS_CLIP3 (iPoc1 - iPoc0, -128, 127);
403 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REF_REORDERING);403 if (iTd) {
404 404 int32_t iTb = WELS_CLIP3 (iPoc - iPoc0, -128, 127);
405 if (kuiIdc == 0 || kuiIdc == 1) {405 int32_t iTx = (16384 + (WELS_ABS (iTd) >> 1)) / iTd;
406 // abs_diff_pic_num_minus1 should be in range 0 to MaxPicNum-1, MaxPicNum is derived as406 int32_t iDistScaleFactor = (iTb * iTx + 32) >> 8;
407 // 2^(4+log2_max_frame_num_minus4)407 if (iDistScaleFactor >= -64 && iDistScaleFactor <= 128) {
408 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //abs_diff_pic_num_minus1408 pCurDqLayer->pPredWeightTable->iImplicitWeight[iRef0][iRef1] = 64 - iDistScaleFactor;
409 WELS_CHECK_SE_UPPER_ERROR_NOLOG (uiCode, (uint32_t) (1 << pSps->uiLog2MaxFrameNum), "abs_diff_pic_num_minus1",409 }
410 GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REF_REORDERING));410 }
411 pRefPicListReordering->sReorderingSyn[iList][iIdx].uiAbsDiffPicNumMinus1 = uiCode; // uiAbsDiffPicNumMinus1411 }
412 } else if (kuiIdc == 2) {412 }
413 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //long_term_pic_num413 }
414 pRefPicListReordering->sReorderingSyn[iList][iIdx].uiLongTermPicNum = uiCode;414 }
415 }415 }
416 416 }
417 ++ iIdx;417 return;
418 } while (true);418}
419 }419
420 if (keSt != B_SLICE)420/*
421 break;421 * Predeclared function routines ..
422 ++ iList;422 */
423 } while (iList < LIST_A);423int32_t ParseRefPicListReordering (PBitStringAux pBs, PSliceHeader pSh) {
424 424 int32_t iList = 0;
425 return ERR_NONE;425 const EWelsSliceType keSt = pSh->eSliceType;
426}426 PRefPicListReorderSyn pRefPicListReordering = &pSh->pRefPicListReordering;
427 427 PSps pSps = pSh->pSps;
428int32_t ParseDecRefPicMarking (PWelsDecoderContext pCtx, PBitStringAux pBs, PSliceHeader pSh, PSps pSps,428 uint32_t uiCode;
429 const bool kbIdrFlag) {429 if (keSt == I_SLICE || keSt == SI_SLICE)
430 PRefPicMarking const kpRefMarking = &pSh->sRefMarking;430 return ERR_NONE;
431 uint32_t uiCode;431
432 if (kbIdrFlag) {432 // Common syntaxs for P or B slices: list0, list1 followed if B slices used.
433 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //no_output_of_prior_pics_flag433 do {
434 kpRefMarking->bNoOutputOfPriorPicsFlag = !!uiCode;434 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //ref_pic_list_modification_flag_l0
435 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //long_term_reference_flag435 pRefPicListReordering->bRefPicListReorderingFlag[iList] = !!uiCode;
436 kpRefMarking->bLongTermRefFlag = !!uiCode;436
437 } else {437 if (pRefPicListReordering->bRefPicListReorderingFlag[iList]) {
438 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //adaptive_ref_pic_marking_mode_flag438 int32_t iIdx = 0;
439 kpRefMarking->bAdaptiveRefPicMarkingModeFlag = !!uiCode;439 do {
440 if (kpRefMarking->bAdaptiveRefPicMarkingModeFlag) {440 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //modification_of_pic_nums_idc
441 int32_t iIdx = 0;441 const uint32_t kuiIdc = uiCode;
442 bool bAllowMmco5 = true, bMmco4Exist = false, bMmco5Exist = false, bMmco6Exist = false;442
443 do {443 //Fixed the referrence list reordering crash issue.(fault kIdc value > 3 case)---
444 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //memory_management_control_operation444 if ((iIdx >= MAX_REF_PIC_COUNT) || (kuiIdc > 3)) {
445 const uint32_t kuiMmco = uiCode;445 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REF_REORDERING);
446 446 }
447 kpRefMarking->sMmcoRef[iIdx].uiMmcoType = kuiMmco;447 pRefPicListReordering->sReorderingSyn[iList][iIdx].uiReorderingOfPicNumsIdc = kuiIdc;
448 if (kuiMmco == MMCO_END)448 if (kuiIdc == 3)
449 break;449 break;
450 450
451 if (kuiMmco == MMCO_SHORT2UNUSED || kuiMmco == MMCO_SHORT2LONG) {451 if (iIdx >= pSh->uiRefCount[iList] || iIdx >= MAX_REF_PIC_COUNT)
452 bAllowMmco5 = false;452 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REF_REORDERING);
453 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //difference_of_pic_nums_minus1453
454 kpRefMarking->sMmcoRef[iIdx].iDiffOfPicNum = 1 + uiCode;454 if (kuiIdc == 0 || kuiIdc == 1) {
455 kpRefMarking->sMmcoRef[iIdx].iShortFrameNum = (pSh->iFrameNum - kpRefMarking->sMmcoRef[iIdx].iDiffOfPicNum) & ((455 // abs_diff_pic_num_minus1 should be in range 0 to MaxPicNum-1, MaxPicNum is derived as
456 1 << pSps->uiLog2MaxFrameNum) - 1);456 // 2^(4+log2_max_frame_num_minus4)
457 } else if (kuiMmco == MMCO_LONG2UNUSED) {457 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //abs_diff_pic_num_minus1
458 bAllowMmco5 = false;458 WELS_CHECK_SE_UPPER_ERROR_NOLOG (uiCode, (uint32_t) (1 << pSps->uiLog2MaxFrameNum), "abs_diff_pic_num_minus1",
459 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //long_term_pic_num459 GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REF_REORDERING));
460 kpRefMarking->sMmcoRef[iIdx].uiLongTermPicNum = uiCode;460 pRefPicListReordering->sReorderingSyn[iList][iIdx].uiAbsDiffPicNumMinus1 = uiCode; // uiAbsDiffPicNumMinus1
461 }461 } else if (kuiIdc == 2) {
462 if (kuiMmco == MMCO_SHORT2LONG || kuiMmco == MMCO_LONG) {462 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //long_term_pic_num
463 if (kuiMmco == MMCO_LONG) {463 pRefPicListReordering->sReorderingSyn[iList][iIdx].uiLongTermPicNum = uiCode;
464 WELS_VERIFY_RETURN_IF (-1, bMmco6Exist);464 }
465 bMmco6Exist = true;465
466 }466 ++ iIdx;
467 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //long_term_frame_idx467 } while (true);
468 kpRefMarking->sMmcoRef[iIdx].iLongTermFrameIdx = uiCode;468 }
469 } else if (kuiMmco == MMCO_SET_MAX_LONG) {469 if (keSt != B_SLICE)
470 WELS_VERIFY_RETURN_IF (-1, bMmco4Exist);470 break;
471 bMmco4Exist = true;471 ++ iList;
472 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //max_long_term_frame_idx_plus1472 } while (iList < LIST_A);
473 kpRefMarking->sMmcoRef[iIdx].iMaxLongTermFrameIdx = -1 + uiCode;473
474 } else if (kuiMmco == MMCO_RESET) {474 return ERR_NONE;
475 WELS_VERIFY_RETURN_IF (-1, (!bAllowMmco5 || bMmco5Exist));475}
476 bMmco5Exist = true;476
477 }477int32_t ParseDecRefPicMarking (PWelsDecoderContext pCtx, PBitStringAux pBs, PSliceHeader pSh, PSps pSps,
478 ++ iIdx;478 const bool kbIdrFlag) {
479 479 PRefPicMarking const kpRefMarking = &pSh->sRefMarking;
480 } while (iIdx < MAX_MMCO_COUNT);480 uint32_t uiCode;
481 }481 if (kbIdrFlag) {
482 }482 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //no_output_of_prior_pics_flag
483 483 kpRefMarking->bNoOutputOfPriorPicsFlag = !!uiCode;
484 return ERR_NONE;484 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //long_term_reference_flag
485}485 kpRefMarking->bLongTermRefFlag = !!uiCode;
486 486 } else {
487bool FillDefaultSliceHeaderExt (PSliceHeaderExt pShExt, PNalUnitHeaderExt pNalExt) {487 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //adaptive_ref_pic_marking_mode_flag
488 if (pShExt == NULL || pNalExt == NULL)488 kpRefMarking->bAdaptiveRefPicMarkingModeFlag = !!uiCode;
489 return false;489 if (kpRefMarking->bAdaptiveRefPicMarkingModeFlag) {
490 490 int32_t iIdx = 0;
491 if (pNalExt->iNoInterLayerPredFlag || pNalExt->uiQualityId > 0)491 bool bAllowMmco5 = true, bMmco4Exist = false, bMmco5Exist = false, bMmco6Exist = false;
492 pShExt->bBasePredWeightTableFlag = false;492 do {
493 else493 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //memory_management_control_operation
494 pShExt->bBasePredWeightTableFlag = true;494 const uint32_t kuiMmco = uiCode;
495 pShExt->uiRefLayerDqId = (uint8_t) - 1;495
496 pShExt->uiDisableInterLayerDeblockingFilterIdc = 0;496 kpRefMarking->sMmcoRef[iIdx].uiMmcoType = kuiMmco;
497 pShExt->iInterLayerSliceAlphaC0Offset = 0;497 if (kuiMmco == MMCO_END)
498 pShExt->iInterLayerSliceBetaOffset = 0;498 break;
499 pShExt->bConstrainedIntraResamplingFlag = false;499
500 pShExt->uiRefLayerChromaPhaseXPlus1Flag = 0;500 if (kuiMmco == MMCO_SHORT2UNUSED || kuiMmco == MMCO_SHORT2LONG) {
501 pShExt->uiRefLayerChromaPhaseYPlus1 = 1;501 bAllowMmco5 = false;
502 //memset(&pShExt->sScaledRefLayer, 0, sizeof(SPosOffset));502 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //difference_of_pic_nums_minus1
503 503 kpRefMarking->sMmcoRef[iIdx].iDiffOfPicNum = 1 + uiCode;
504 pShExt->iScaledRefLayerPicWidthInSampleLuma = pShExt->sSliceHeader.iMbWidth << 4;504 kpRefMarking->sMmcoRef[iIdx].iShortFrameNum = (pSh->iFrameNum - kpRefMarking->sMmcoRef[iIdx].iDiffOfPicNum) & ((
505 pShExt->iScaledRefLayerPicHeightInSampleLuma = pShExt->sSliceHeader.iMbHeight << 4;505 1 << pSps->uiLog2MaxFrameNum) - 1);
506 506 } else if (kuiMmco == MMCO_LONG2UNUSED) {
507 pShExt->bSliceSkipFlag = false;507 bAllowMmco5 = false;
508 pShExt->bAdaptiveBaseModeFlag = false;508 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //long_term_pic_num
509 pShExt->bDefaultBaseModeFlag = false;509 kpRefMarking->sMmcoRef[iIdx].uiLongTermPicNum = uiCode;
510 pShExt->bAdaptiveMotionPredFlag = false;510 }
511 pShExt->bDefaultMotionPredFlag = false;511 if (kuiMmco == MMCO_SHORT2LONG || kuiMmco == MMCO_LONG) {
512 pShExt->bAdaptiveResidualPredFlag = false;512 if (kuiMmco == MMCO_LONG) {
513 pShExt->bDefaultResidualPredFlag = false;513 WELS_VERIFY_RETURN_IF (-1, bMmco6Exist);
514 pShExt->bTCoeffLevelPredFlag = false;514 bMmco6Exist = true;
515 pShExt->uiScanIdxStart = 0;515 }
516 pShExt->uiScanIdxEnd = 15;516 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //long_term_frame_idx
517 517 kpRefMarking->sMmcoRef[iIdx].iLongTermFrameIdx = uiCode;
518 return true;518 } else if (kuiMmco == MMCO_SET_MAX_LONG) {
519}519 WELS_VERIFY_RETURN_IF (-1, bMmco4Exist);
520 520 bMmco4Exist = true;
521int32_t InitBsBuffer (PWelsDecoderContext pCtx) {521 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //max_long_term_frame_idx_plus1
522 if (pCtx == NULL)522 kpRefMarking->sMmcoRef[iIdx].iMaxLongTermFrameIdx = -1 + uiCode;
523 return ERR_INFO_INVALID_PTR;523 } else if (kuiMmco == MMCO_RESET) {
524 524 WELS_VERIFY_RETURN_IF (-1, (!bAllowMmco5 || bMmco5Exist));
525 CMemoryAlign* pMa = pCtx->pMemAlign;525 bMmco5Exist = true;
526 526
527 pCtx->iMaxBsBufferSizeInByte = MIN_ACCESS_UNIT_CAPACITY * MAX_BUFFERED_NUM;527 pCtx->iPrevPicOrderCntLsb = 0;
528 if ((pCtx->sRawData.pHead = static_cast<uint8_t*> (pMa->WelsMallocz (pCtx->iMaxBsBufferSizeInByte,528 pCtx->iPrevPicOrderCntMsb = 0;
529 "pCtx->sRawData.pHead"))) == NULL) {529 pCtx->pSliceHeader->iPicOrderCntLsb = 0;
530 return ERR_INFO_OUT_OF_MEMORY;530 }
531 }531 ++ iIdx;
532 pCtx->sRawData.pStartPos = pCtx->sRawData.pCurPos = pCtx->sRawData.pHead;532
533 pCtx->sRawData.pEnd = pCtx->sRawData.pHead + pCtx->iMaxBsBufferSizeInByte;533 } while (iIdx < MAX_MMCO_COUNT);
534 if (pCtx->pParam->bParseOnly) {534 }
535 pCtx->pParserBsInfo = static_cast<SParserBsInfo*> (pMa->WelsMallocz (sizeof (SParserBsInfo), "pCtx->pParserBsInfo"));535 }
536 if (pCtx->pParserBsInfo == NULL) {536
537 return ERR_INFO_OUT_OF_MEMORY;537 return ERR_NONE;
538 }538}
539 memset (pCtx->pParserBsInfo, 0, sizeof (SParserBsInfo));539
540 pCtx->pParserBsInfo->pDstBuff = static_cast<uint8_t*> (pMa->WelsMallocz (MAX_ACCESS_UNIT_CAPACITY * sizeof (uint8_t),540bool FillDefaultSliceHeaderExt (PSliceHeaderExt pShExt, PNalUnitHeaderExt pNalExt) {
541 "pCtx->pParserBsInfo->pDstBuff"));541 if (pShExt == NULL || pNalExt == NULL)
542 if (pCtx->pParserBsInfo->pDstBuff == NULL) {542 return false;
543 return ERR_INFO_OUT_OF_MEMORY;543
544 }544 if (pNalExt->iNoInterLayerPredFlag || pNalExt->uiQualityId > 0)
545 memset (pCtx->pParserBsInfo->pDstBuff, 0, MAX_ACCESS_UNIT_CAPACITY * sizeof (uint8_t));545 pShExt->bBasePredWeightTableFlag = false;
546 546 else
547 if ((pCtx->sSavedData.pHead = static_cast<uint8_t*> (pMa->WelsMallocz (pCtx->iMaxBsBufferSizeInByte,547 pShExt->bBasePredWeightTableFlag = true;
548 "pCtx->sSavedData.pHead"))) == NULL) {548 pShExt->uiRefLayerDqId = (uint8_t) - 1;
549 return ERR_INFO_OUT_OF_MEMORY;549 pShExt->uiDisableInterLayerDeblockingFilterIdc = 0;
550 }550 pShExt->iInterLayerSliceAlphaC0Offset = 0;
551 pCtx->sSavedData.pStartPos = pCtx->sSavedData.pCurPos = pCtx->sSavedData.pHead;551 pShExt->iInterLayerSliceBetaOffset = 0;
552 pCtx->sSavedData.pEnd = pCtx->sSavedData.pHead + pCtx->iMaxBsBufferSizeInByte;552 pShExt->bConstrainedIntraResamplingFlag = false;
553 553 pShExt->uiRefLayerChromaPhaseXPlus1Flag = 0;
554 pCtx->iMaxNalNum = MAX_NAL_UNITS_IN_LAYER + 2; //2 reserved for SPS+PPS554 pShExt->uiRefLayerChromaPhaseYPlus1 = 1;
555 pCtx->pParserBsInfo->pNalLenInByte = static_cast<int*> (pMa->WelsMallocz (pCtx->iMaxNalNum * sizeof (int),555 //memset(&pShExt->sScaledRefLayer, 0, sizeof(SPosOffset));
556 "pCtx->pParserBsInfo->pNalLenInByte"));556
557 if (pCtx->pParserBsInfo->pNalLenInByte == NULL) {557 pShExt->iScaledRefLayerPicWidthInSampleLuma = pShExt->sSliceHeader.iMbWidth << 4;
558 return ERR_INFO_OUT_OF_MEMORY;558 pShExt->iScaledRefLayerPicHeightInSampleLuma = pShExt->sSliceHeader.iMbHeight << 4;
559 }559
560 }560 pShExt->bSliceSkipFlag = false;
561 return ERR_NONE;561 pShExt->bAdaptiveBaseModeFlag = false;
562}562 pShExt->bDefaultBaseModeFlag = false;
563 563 pShExt->bAdaptiveMotionPredFlag = false;
564int32_t ExpandBsBuffer (PWelsDecoderContext pCtx, const int32_t kiSrcLen) {564 pShExt->bDefaultMotionPredFlag = false;
565 if (pCtx == NULL)565 pShExt->bAdaptiveResidualPredFlag = false;
566 return ERR_INFO_INVALID_PTR;566 pShExt->bDefaultResidualPredFlag = false;
567 int32_t iExpandStepShift = 1;567 pShExt->bTCoeffLevelPredFlag = false;
568 int32_t iNewBuffLen = WELS_MAX ((kiSrcLen * MAX_BUFFERED_NUM), (pCtx->iMaxBsBufferSizeInByte << iExpandStepShift));568 pShExt->uiScanIdxStart = 0;
569 //allocate new bs buffer569 pShExt->uiScanIdxEnd = 15;
570 CMemoryAlign* pMa = pCtx->pMemAlign;570
571 571 return true;
572 //Realloc sRawData572}
573 uint8_t* pNewBsBuff = static_cast<uint8_t*> (pMa->WelsMallocz (iNewBuffLen, "pCtx->sRawData.pHead"));573
574 if (pNewBsBuff == NULL) {574int32_t InitBsBuffer (PWelsDecoderContext pCtx) {
575 WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "ExpandBsBuffer() Failed for malloc pNewBsBuff (%d)", iNewBuffLen);575 if (pCtx == NULL)
576 pCtx->iErrorCode |= dsOutOfMemory;576 return ERR_INFO_INVALID_PTR;
577 return ERR_INFO_OUT_OF_MEMORY;577
578 }578 CMemoryAlign* pMa = pCtx->pMemAlign;
579 579
580 //Calculate and set the bs start and end position580 pCtx->iMaxBsBufferSizeInByte = MIN_ACCESS_UNIT_CAPACITY * MAX_BUFFERED_NUM;
581 for (uint32_t i = 0; i <= pCtx->pAccessUnitList->uiActualUnitsNum; i++) {581 if ((pCtx->sRawData.pHead = static_cast<uint8_t*> (pMa->WelsMallocz (pCtx->iMaxBsBufferSizeInByte,
582 PBitStringAux pSliceBitsRead = &pCtx->pAccessUnitList->pNalUnitsList[i]->sNalData.sVclNal.sSliceBitsRead;582 "pCtx->sRawData.pHead"))) == NULL) {
583 pSliceBitsRead->pStartBuf = pSliceBitsRead->pStartBuf - pCtx->sRawData.pHead + pNewBsBuff;583 return ERR_INFO_OUT_OF_MEMORY;
584 pSliceBitsRead->pEndBuf = pSliceBitsRead->pEndBuf - pCtx->sRawData.pHead + pNewBsBuff;584 }
585 pSliceBitsRead->pCurBuf = pSliceBitsRead->pCurBuf - pCtx->sRawData.pHead + pNewBsBuff;585 pCtx->sRawData.pStartPos = pCtx->sRawData.pCurPos = pCtx->sRawData.pHead;
586 }586 pCtx->sRawData.pEnd = pCtx->sRawData.pHead + pCtx->iMaxBsBufferSizeInByte;
587 587 if (pCtx->pParam->bParseOnly) {
588 //Copy current buffer status to new buffer588 pCtx->pParserBsInfo = static_cast<SParserBsInfo*> (pMa->WelsMallocz (sizeof (SParserBsInfo), "pCtx->pParserBsInfo"));
589 memcpy (pNewBsBuff, pCtx->sRawData.pHead, pCtx->iMaxBsBufferSizeInByte);589 if (pCtx->pParserBsInfo == NULL) {
590 pCtx->sRawData.pStartPos = pNewBsBuff + (pCtx->sRawData.pStartPos - pCtx->sRawData.pHead);590 return ERR_INFO_OUT_OF_MEMORY;
591 pCtx->sRawData.pCurPos = pNewBsBuff + (pCtx->sRawData.pCurPos - pCtx->sRawData.pHead);591 }
592 pCtx->sRawData.pEnd = pNewBsBuff + iNewBuffLen;592 memset (pCtx->pParserBsInfo, 0, sizeof (SParserBsInfo));
593 pMa->WelsFree (pCtx->sRawData.pHead, "pCtx->sRawData.pHead");593 pCtx->pParserBsInfo->pDstBuff = static_cast<uint8_t*> (pMa->WelsMallocz (MAX_ACCESS_UNIT_CAPACITY * sizeof (uint8_t),
594 pCtx->sRawData.pHead = pNewBsBuff;594 "pCtx->pParserBsInfo->pDstBuff"));
595 595 if (pCtx->pParserBsInfo->pDstBuff == NULL) {
596 if (pCtx->pParam->bParseOnly) {596 return ERR_INFO_OUT_OF_MEMORY;
597 //Realloc sSavedData597 }
598 uint8_t* pNewSavedBsBuff = static_cast<uint8_t*> (pMa->WelsMallocz (iNewBuffLen, "pCtx->sSavedData.pHead"));598 memset (pCtx->pParserBsInfo->pDstBuff, 0, MAX_ACCESS_UNIT_CAPACITY * sizeof (uint8_t));
599 if (pNewSavedBsBuff == NULL) {599
600 WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "ExpandBsBuffer() Failed for malloc pNewSavedBsBuff (%d)", iNewBuffLen);600 if ((pCtx->sSavedData.pHead = static_cast<uint8_t*> (pMa->WelsMallocz (pCtx->iMaxBsBufferSizeInByte,
601 pCtx->iErrorCode |= dsOutOfMemory;601 "pCtx->sSavedData.pHead"))) == NULL) {
602 return ERR_INFO_OUT_OF_MEMORY;602 return ERR_INFO_OUT_OF_MEMORY;
603 }603 }
604 604 pCtx->sSavedData.pStartPos = pCtx->sSavedData.pCurPos = pCtx->sSavedData.pHead;
605 //Copy current buffer status to new buffer605 pCtx->sSavedData.pEnd = pCtx->sSavedData.pHead + pCtx->iMaxBsBufferSizeInByte;
606 memcpy (pNewSavedBsBuff, pCtx->sSavedData.pHead, pCtx->iMaxBsBufferSizeInByte);606
607 pCtx->sSavedData.pStartPos = pNewSavedBsBuff + (pCtx->sSavedData.pStartPos - pCtx->sSavedData.pHead);607 pCtx->iMaxNalNum = MAX_NAL_UNITS_IN_LAYER + 2; //2 reserved for SPS+PPS
608 pCtx->sSavedData.pCurPos = pNewSavedBsBuff + (pCtx->sSavedData.pCurPos - pCtx->sSavedData.pHead);608 pCtx->pParserBsInfo->pNalLenInByte = static_cast<int*> (pMa->WelsMallocz (pCtx->iMaxNalNum * sizeof (int),
609 pCtx->sSavedData.pEnd = pNewSavedBsBuff + iNewBuffLen;609 "pCtx->pParserBsInfo->pNalLenInByte"));
610 pMa->WelsFree (pCtx->sSavedData.pHead, "pCtx->sSavedData.pHead");610 if (pCtx->pParserBsInfo->pNalLenInByte == NULL) {
611 pCtx->sSavedData.pHead = pNewSavedBsBuff;611 return ERR_INFO_OUT_OF_MEMORY;
612 }612 }
613 613 }
614 pCtx->iMaxBsBufferSizeInByte = iNewBuffLen;614 return ERR_NONE;
615 return ERR_NONE;615}
616}616
617 617int32_t ExpandBsBuffer (PWelsDecoderContext pCtx, const int kiSrcLen) {
618int32_t ExpandBsLenBuffer (PWelsDecoderContext pCtx, const int32_t kiCurrLen) {618 if (pCtx == NULL)
619 SParserBsInfo* pParser = pCtx->pParserBsInfo;619 return ERR_INFO_INVALID_PTR;
620 if (!pParser->pNalLenInByte)620 int32_t iExpandStepShift = 1;
621 return ERR_INFO_INVALID_ACCESS;621 int32_t iNewBuffLen = WELS_MAX ((kiSrcLen * MAX_BUFFERED_NUM), (pCtx->iMaxBsBufferSizeInByte << iExpandStepShift));
622 622 //allocate new bs buffer
623 int iNewLen = kiCurrLen;623 CMemoryAlign* pMa = pCtx->pMemAlign;
624 if (kiCurrLen >= MAX_MB_SIZE + 2) { //exceeds the max MB number of level 5.2624
625 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "Current nal num (%d) exceededs %d.", kiCurrLen, MAX_MB_SIZE);625 //Realloc sRawData
626 pCtx->iErrorCode |= dsOutOfMemory;626 uint8_t* pNewBsBuff = static_cast<uint8_t*> (pMa->WelsMallocz (iNewBuffLen, "pCtx->sRawData.pHead"));
627 return ERR_INFO_OUT_OF_MEMORY;627 if (pNewBsBuff == NULL) {
628 } else {628 WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "ExpandBsBuffer() Failed for malloc pNewBsBuff (%d)", iNewBuffLen);
629 iNewLen = kiCurrLen << 1;629 pCtx->iErrorCode |= dsOutOfMemory;
630 iNewLen = WELS_MIN (iNewLen, MAX_MB_SIZE + 2);630 return ERR_INFO_OUT_OF_MEMORY;
631 }631 }
632 632
633 CMemoryAlign* pMa = pCtx->pMemAlign;633 //Calculate and set the bs start and end position
634 int* pNewLenBuffer = static_cast<int*> (pMa->WelsMallocz (iNewLen * sizeof (int),634 for (uint32_t i = 0; i <= pCtx->pAccessUnitList->uiActualUnitsNum; i++) {
635 "pCtx->pParserBsInfo->pNalLenInByte"));635 PBitStringAux pSliceBitsRead = &pCtx->pAccessUnitList->pNalUnitsList[i]->sNalData.sVclNal.sSliceBitsRead;
636 if (pNewLenBuffer == NULL) {636 pSliceBitsRead->pStartBuf = pSliceBitsRead->pStartBuf - pCtx->sRawData.pHead + pNewBsBuff;
637 pCtx->iErrorCode |= dsOutOfMemory;637 pSliceBitsRead->pEndBuf = pSliceBitsRead->pEndBuf - pCtx->sRawData.pHead + pNewBsBuff;
638 return ERR_INFO_OUT_OF_MEMORY;638 pSliceBitsRead->pCurBuf = pSliceBitsRead->pCurBuf - pCtx->sRawData.pHead + pNewBsBuff;
639 }639 }
640 640
641 //copy existing data from old length buffer to new641 //Copy current buffer status to new buffer
642 memcpy (pNewLenBuffer, pParser->pNalLenInByte, pCtx->iMaxNalNum * sizeof (int));642 memcpy (pNewBsBuff, pCtx->sRawData.pHead, pCtx->iMaxBsBufferSizeInByte);
643 pMa->WelsFree (pParser->pNalLenInByte, "pCtx->pParserBsInfo->pNalLenInByte");643 pCtx->sRawData.pStartPos = pNewBsBuff + (pCtx->sRawData.pStartPos - pCtx->sRawData.pHead);
644 pParser->pNalLenInByte = pNewLenBuffer;644 pCtx->sRawData.pCurPos = pNewBsBuff + (pCtx->sRawData.pCurPos - pCtx->sRawData.pHead);
645 pCtx->iMaxNalNum = iNewLen;645 pCtx->sRawData.pEnd = pNewBsBuff + iNewBuffLen;
646 return ERR_NONE;646 pMa->WelsFree (pCtx->sRawData.pHead, "pCtx->sRawData.pHead");
647}647 pCtx->sRawData.pHead = pNewBsBuff;
648 648
649int32_t CheckBsBuffer (PWelsDecoderContext pCtx, const int32_t kiSrcLen) {649 if (pCtx->pParam->bParseOnly) {
650 if (kiSrcLen > MAX_ACCESS_UNIT_CAPACITY) { //exceeds max allowed data650 //Realloc sSavedData
651 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "Max AU size exceeded. Allowed size = %d, current size = %d",651 uint8_t* pNewSavedBsBuff = static_cast<uint8_t*> (pMa->WelsMallocz (iNewBuffLen, "pCtx->sSavedData.pHead"));
652 MAX_ACCESS_UNIT_CAPACITY,652 if (pNewSavedBsBuff == NULL) {
653 kiSrcLen);653 WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "ExpandBsBuffer() Failed for malloc pNewSavedBsBuff (%d)", iNewBuffLen);
654 pCtx->iErrorCode |= dsBitstreamError;654 pCtx->iErrorCode |= dsOutOfMemory;
655 return ERR_INFO_INVALID_ACCESS;655 return ERR_INFO_OUT_OF_MEMORY;
656 } else if (kiSrcLen > pCtx->iMaxBsBufferSizeInByte /656 }
657 MAX_BUFFERED_NUM) { //may lead to buffer overwrite, prevent it by expanding buffer657
658 if (ExpandBsBuffer (pCtx, kiSrcLen)) {658 //Copy current buffer status to new buffer
659 return ERR_INFO_OUT_OF_MEMORY;659 memcpy (pNewSavedBsBuff, pCtx->sSavedData.pHead, pCtx->iMaxBsBufferSizeInByte);
660 }660 pCtx->sSavedData.pStartPos = pNewSavedBsBuff + (pCtx->sSavedData.pStartPos - pCtx->sSavedData.pHead);
661 }661 pCtx->sSavedData.pCurPos = pNewSavedBsBuff + (pCtx->sSavedData.pCurPos - pCtx->sSavedData.pHead);
662 662 pCtx->sSavedData.pEnd = pNewSavedBsBuff + iNewBuffLen;
663 return ERR_NONE;663 pMa->WelsFree (pCtx->sSavedData.pHead, "pCtx->sSavedData.pHead");
664}664 pCtx->sSavedData.pHead = pNewSavedBsBuff;
665 665 }
666/*666
667 * WelsInitStaticMemory667 pCtx->iMaxBsBufferSizeInByte = iNewBuffLen;
668 * Memory request for new introduced data668 return ERR_NONE;
669 * Especially for:669}
670 * rbsp_au_buffer, cur_dq_layer_ptr and ref_dq_layer_ptr in MB info cache.670
671 * return:671int32_t ExpandBsLenBuffer (PWelsDecoderContext pCtx, const int kiCurrLen) {
672 * 0 - success; otherwise returned error_no defined in error_no.h.672 SParserBsInfo* pParser = pCtx->pParserBsInfo;
673*/673 if (!pParser->pNalLenInByte)
674int32_t WelsInitStaticMemory (PWelsDecoderContext pCtx) {674 return ERR_INFO_INVALID_ACCESS;
675 if (pCtx == NULL) {675
676 return ERR_INFO_INVALID_PTR;676 int iNewLen = kiCurrLen;
677 }677 if (kiCurrLen >= MAX_MB_SIZE + 2) { //exceeds the max MB number of level 5.2
678 678 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "Current nal num (%d) exceededs %d.", kiCurrLen, MAX_MB_SIZE);
679 if (MemInitNalList (&pCtx->pAccessUnitList, MAX_NAL_UNIT_NUM_IN_AU, pCtx->pMemAlign) != 0)679 pCtx->iErrorCode |= dsOutOfMemory;
680 return ERR_INFO_OUT_OF_MEMORY;680 return ERR_INFO_OUT_OF_MEMORY;
681 681 } else {
682 if (InitBsBuffer (pCtx) != 0)682 iNewLen = kiCurrLen << 1;
683 return ERR_INFO_OUT_OF_MEMORY;683 iNewLen = WELS_MIN (iNewLen, MAX_MB_SIZE + 2);
684 684 }
685 pCtx->uiTargetDqId = (uint8_t) - 1;685
686 pCtx->bEndOfStreamFlag = false;686 CMemoryAlign* pMa = pCtx->pMemAlign;
687 687 int* pNewLenBuffer = static_cast<int*> (pMa->WelsMallocz (iNewLen * sizeof (int),
688 return ERR_NONE;688 "pCtx->pParserBsInfo->pNalLenInByte"));
689}689 if (pNewLenBuffer == NULL) {
690 690 pCtx->iErrorCode |= dsOutOfMemory;
691/*691 return ERR_INFO_OUT_OF_MEMORY;
692 * WelsFreeStaticMemory692 }
693 * Free memory introduced in WelsInitStaticMemory at destruction of decoder.693
694 *694 //copy existing data from old length buffer to new
695 */695 memcpy (pNewLenBuffer, pParser->pNalLenInByte, pCtx->iMaxNalNum * sizeof (int));
696void WelsFreeStaticMemory (PWelsDecoderContext pCtx) {696 pMa->WelsFree (pParser->pNalLenInByte, "pCtx->pParserBsInfo->pNalLenInByte");
697 if (pCtx == NULL)697 pParser->pNalLenInByte = pNewLenBuffer;
698 return;698 pCtx->iMaxNalNum = iNewLen;
699 699 return ERR_NONE;
700 CMemoryAlign* pMa = pCtx->pMemAlign;700}
701 701
702 MemFreeNalList (&pCtx->pAccessUnitList, pMa);702int32_t CheckBsBuffer (PWelsDecoderContext pCtx, const int32_t kiSrcLen) {
703 703 if (kiSrcLen > MAX_ACCESS_UNIT_CAPACITY) { //exceeds max allowed data
704 if (pCtx->sRawData.pHead) {704 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "Max AU size exceeded. Allowed size = %d, current size = %d",
705 pMa->WelsFree (pCtx->sRawData.pHead, "pCtx->sRawData->pHead");705 MAX_ACCESS_UNIT_CAPACITY,
706 }706 kiSrcLen);
707 pCtx->sRawData.pHead = NULL;707 pCtx->iErrorCode |= dsBitstreamError;
708 pCtx->sRawData.pEnd = NULL;708 return ERR_INFO_INVALID_ACCESS;
709 pCtx->sRawData.pStartPos = NULL;709 } else if (kiSrcLen > pCtx->iMaxBsBufferSizeInByte /
710 pCtx->sRawData.pCurPos = NULL;710 MAX_BUFFERED_NUM) { //may lead to buffer overwrite, prevent it by expanding buffer
711 if (pCtx->pParam->bParseOnly) {711 if (ExpandBsBuffer (pCtx, kiSrcLen)) {
712 if (pCtx->sSavedData.pHead) {712 return ERR_INFO_OUT_OF_MEMORY;
713 pMa->WelsFree (pCtx->sSavedData.pHead, "pCtx->sSavedData->pHead");713 }
714 }714 }
715 pCtx->sSavedData.pHead = NULL;715
716 pCtx->sSavedData.pEnd = NULL;716 return ERR_NONE;
717 pCtx->sSavedData.pStartPos = NULL;717}
718 pCtx->sSavedData.pCurPos = NULL;718
719 if (pCtx->pParserBsInfo) {719/*
720 if (pCtx->pParserBsInfo->pNalLenInByte) {720 * WelsInitStaticMemory
721 pMa->WelsFree (pCtx->pParserBsInfo->pNalLenInByte, "pCtx->pParserBsInfo->pNalLenInByte");721 * Memory request for new introduced data
722 pCtx->pParserBsInfo->pNalLenInByte = NULL;722 * Especially for:
723 pCtx->iMaxNalNum = 0;723 * rbsp_au_buffer, cur_dq_layer_ptr and ref_dq_layer_ptr in MB info cache.
724 }724 * return:
725 if (pCtx->pParserBsInfo->pDstBuff) {725 * 0 - success; otherwise returned error_no defined in error_no.h.
726 pMa->WelsFree (pCtx->pParserBsInfo->pDstBuff, "pCtx->pParserBsInfo->pDstBuff");726*/
727 pCtx->pParserBsInfo->pDstBuff = NULL;727int32_t WelsInitStaticMemory (PWelsDecoderContext pCtx) {
728 }728 if (pCtx == NULL) {
729 pMa->WelsFree (pCtx->pParserBsInfo, "pCtx->pParserBsInfo");729 return ERR_INFO_INVALID_PTR;
730 pCtx->pParserBsInfo = NULL;730 }
731 }731
732 }732 if (MemInitNalList (&pCtx->pAccessUnitList, MAX_NAL_UNIT_NUM_IN_AU, pCtx->pMemAlign) != 0)
733 733 return ERR_INFO_OUT_OF_MEMORY;
734 if (NULL != pCtx->pParam) {734
735 pMa->WelsFree (pCtx->pParam, "pCtx->pParam");735 if (InitBsBuffer (pCtx) != 0)
736 736 return ERR_INFO_OUT_OF_MEMORY;
737 pCtx->pParam = NULL;737
738 }738 pCtx->uiTargetDqId = (uint8_t) - 1;
739}739 pCtx->bEndOfStreamFlag = false;
740/*740
741 * DecodeNalHeaderExt741 return ERR_NONE;
742 * Trigger condition: NAL_UNIT_TYPE = NAL_UNIT_PREFIX or NAL_UNIT_CODED_SLICE_EXT742}
743 * Parameter:743
744 * pNal: target NALUnit ptr744/*
745 * pSrc: NAL Unit bitstream745 * WelsFreeStaticMemory
746 */746 * Free memory introduced in WelsInitStaticMemory at destruction of decoder.
747void DecodeNalHeaderExt (PNalUnit pNal, uint8_t* pSrc) {747 *
748 PNalUnitHeaderExt pHeaderExt = &pNal->sNalHeaderExt;748 */
749 749void WelsFreeStaticMemory (PWelsDecoderContext pCtx) {
750 uint8_t uiCurByte = *pSrc;750 if (pCtx == NULL)
751 pHeaderExt->bIdrFlag = !! (uiCurByte & 0x40);751 return;
752 pHeaderExt->uiPriorityId = uiCurByte & 0x3F;752
753 753 CMemoryAlign* pMa = pCtx->pMemAlign;
754 uiCurByte = * (++pSrc);754
755 pHeaderExt->iNoInterLayerPredFlag = uiCurByte >> 7;755 MemFreeNalList (&pCtx->pAccessUnitList, pMa);
756 pHeaderExt->uiDependencyId = (uiCurByte & 0x70) >> 4;756
757 pHeaderExt->uiQualityId = uiCurByte & 0x0F;757 if (pCtx->sRawData.pHead) {
758 uiCurByte = * (++pSrc);758 pMa->WelsFree (pCtx->sRawData.pHead, "pCtx->sRawData->pHead");
759 pHeaderExt->uiTemporalId = uiCurByte >> 5;759 }
760 pHeaderExt->bUseRefBasePicFlag = !! (uiCurByte & 0x10);760 pCtx->sRawData.pHead = NULL;
761 pHeaderExt->bDiscardableFlag = !! (uiCurByte & 0x08);761 pCtx->sRawData.pEnd = NULL;
762 pHeaderExt->bOutputFlag = !! (uiCurByte & 0x04);762 pCtx->sRawData.pStartPos = NULL;
763 pHeaderExt->uiReservedThree2Bits = uiCurByte & 0x03;763 pCtx->sRawData.pCurPos = NULL;
764 pHeaderExt->uiLayerDqId = (pHeaderExt->uiDependencyId << 4) | pHeaderExt->uiQualityId;764 if (pCtx->pParam->bParseOnly) {
765}765 if (pCtx->sSavedData.pHead) {
766 766 pMa->WelsFree (pCtx->sSavedData.pHead, "pCtx->sSavedData->pHead");
767 767 }
768void UpdateDecoderStatisticsForActiveParaset (SDecoderStatistics* pDecoderStatistics,768 pCtx->sSavedData.pHead = NULL;
769 PSps pSps, PPps pPps) {769 pCtx->sSavedData.pEnd = NULL;
770 pDecoderStatistics->iCurrentActiveSpsId = pSps->iSpsId;770 pCtx->sSavedData.pStartPos = NULL;
771 771 pCtx->sSavedData.pCurPos = NULL;
772 pDecoderStatistics->iCurrentActivePpsId = pPps->iPpsId;772 if (pCtx->pParserBsInfo) {
773 pDecoderStatistics->uiProfile = static_cast<unsigned int> (pSps->uiProfileIdc);773 if (pCtx->pParserBsInfo->pNalLenInByte) {
774 pDecoderStatistics->uiLevel = pSps->uiLevelIdc;774 pMa->WelsFree (pCtx->pParserBsInfo->pNalLenInByte, "pCtx->pParserBsInfo->pNalLenInByte");
775}775 pCtx->pParserBsInfo->pNalLenInByte = NULL;
776 776 pCtx->iMaxNalNum = 0;
777#define SLICE_HEADER_IDR_PIC_ID_MAX 65535777 }
778#define SLICE_HEADER_REDUNDANT_PIC_CNT_MAX 127778 if (pCtx->pParserBsInfo->pDstBuff) {
779#define SLICE_HEADER_ALPHAC0_BETA_OFFSET_MIN -12779 pMa->WelsFree (pCtx->pParserBsInfo->pDstBuff, "pCtx->pParserBsInfo->pDstBuff");
780#define SLICE_HEADER_ALPHAC0_BETA_OFFSET_MAX 12780 pCtx->pParserBsInfo->pDstBuff = NULL;
781#define SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MIN -12781 }
782#define SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MAX 12782 pMa->WelsFree (pCtx->pParserBsInfo, "pCtx->pParserBsInfo");
783#define MAX_NUM_REF_IDX_L0_ACTIVE_MINUS1 15783 pCtx->pParserBsInfo = NULL;
784#define SLICE_HEADER_CABAC_INIT_IDC_MAX 2784 }
785/*785 }
786 * decode_slice_header_avc786
787 * Parse slice header of bitstream in avc for storing data structure787 if (NULL != pCtx->pParam) {
788 */788 pMa->WelsFree (pCtx->pParam, "pCtx->pParam");
789int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, const bool kbExtensionFlag) {789
790 PNalUnit const kpCurNal = pCtx->pAccessUnitList->pNalUnitsList[pCtx->pAccessUnitList->uiAvailUnitsNum -790 pCtx->pParam = NULL;
791 1];791 }
792 792}
793 PNalUnitHeaderExt pNalHeaderExt = NULL;793/*
794 PSliceHeader pSliceHead = NULL;794 * DecodeNalHeaderExt
795 PSliceHeaderExt pSliceHeadExt = NULL;795 * Trigger condition: NAL_UNIT_TYPE = NAL_UNIT_PREFIX or NAL_UNIT_CODED_SLICE_EXT
796 PSubsetSps pSubsetSps = NULL;796 * Parameter:
797 PSps pSps = NULL;797 * pNal: target NALUnit ptr
798 PPps pPps = NULL;798 * pSrc: NAL Unit bitstream
799 EWelsNalUnitType eNalType = static_cast<EWelsNalUnitType> (0);799 */
800 int32_t iPpsId = 0;800void DecodeNalHeaderExt (PNalUnit pNal, uint8_t* pSrc) {
801 int32_t iRet = ERR_NONE;801 PNalUnitHeaderExt pHeaderExt = &pNal->sNalHeaderExt;
802 uint8_t uiSliceType = 0;802
803 uint8_t uiQualityId = BASE_QUALITY_ID;803 uint8_t uiCurByte = *pSrc;
804 bool bIdrFlag = false;804 pHeaderExt->bIdrFlag = !! (uiCurByte & 0x40);
805 bool bSgChangeCycleInvolved = false; // involved slice group change cycle ?805 pHeaderExt->uiPriorityId = uiCurByte & 0x3F;
806 uint32_t uiCode;806
807 int32_t iCode;807 uiCurByte = * (++pSrc);
808 SLogContext* pLogCtx = & (pCtx->sLogCtx);808 pHeaderExt->iNoInterLayerPredFlag = uiCurByte >> 7;
809 809 pHeaderExt->uiDependencyId = (uiCurByte & 0x70) >> 4;
810 if (kpCurNal == NULL) {810 pHeaderExt->uiQualityId = uiCurByte & 0x0F;
811 return ERR_INFO_OUT_OF_MEMORY;811 uiCurByte = * (++pSrc);
812 }812 pHeaderExt->uiTemporalId = uiCurByte >> 5;
813 813 pHeaderExt->bUseRefBasePicFlag = !! (uiCurByte & 0x10);
814 pNalHeaderExt = &kpCurNal->sNalHeaderExt;814 pHeaderExt->bDiscardableFlag = !! (uiCurByte & 0x08);
815 pSliceHead = &kpCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader;815 pHeaderExt->bOutputFlag = !! (uiCurByte & 0x04);
816 eNalType = pNalHeaderExt->sNalUnitHeader.eNalUnitType;816 pHeaderExt->uiReservedThree2Bits = uiCurByte & 0x03;
817 817 pHeaderExt->uiLayerDqId = (pHeaderExt->uiDependencyId << 4) | pHeaderExt->uiQualityId;
818 pSliceHeadExt = &kpCurNal->sNalData.sVclNal.sSliceHeaderExt;818}
819 819
820 if (pSliceHeadExt) {820
821 SRefBasePicMarking sBaseMarking;821void UpdateDecoderStatisticsForActiveParaset (SDecoderStatistics* pDecoderStatistics,
822 const bool kbStoreRefBaseFlag = pSliceHeadExt->bStoreRefBasePicFlag;822 PSps pSps, PPps pPps) {
823 memcpy (&sBaseMarking, &pSliceHeadExt->sRefBasePicMarking, sizeof (SRefBasePicMarking)); //confirmed_safe_unsafe_usage823 pDecoderStatistics->iCurrentActiveSpsId = pSps->iSpsId;
824 memset (pSliceHeadExt, 0, sizeof (SSliceHeaderExt));824
825 pSliceHeadExt->bStoreRefBasePicFlag = kbStoreRefBaseFlag;825 pDecoderStatistics->iCurrentActivePpsId = pPps->iPpsId;
826 memcpy (&pSliceHeadExt->sRefBasePicMarking, &sBaseMarking, sizeof (SRefBasePicMarking)); //confirmed_safe_unsafe_usage826 pDecoderStatistics->uiProfile = static_cast<unsigned int> (pSps->uiProfileIdc);
827 }827 pDecoderStatistics->uiLevel = pSps->uiLevelIdc;
828 828}
829 kpCurNal->sNalData.sVclNal.bSliceHeaderExtFlag = kbExtensionFlag;829
830 830#define SLICE_HEADER_IDR_PIC_ID_MAX 65535
831 // first_mb_in_slice831#define SLICE_HEADER_REDUNDANT_PIC_CNT_MAX 127
832 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //first_mb_in_slice832#define SLICE_HEADER_ALPHAC0_BETA_OFFSET_MIN -12
833 WELS_CHECK_SE_UPPER_ERROR (uiCode, 36863u, "first_mb_in_slice", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,833#define SLICE_HEADER_ALPHAC0_BETA_OFFSET_MAX 12
834 ERR_INFO_INVALID_FIRST_MB_IN_SLICE));834#define SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MIN -12
835 pSliceHead->iFirstMbInSlice = uiCode;835#define SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MAX 12
836 836#define MAX_NUM_REF_IDX_L0_ACTIVE_MINUS1 15
837 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //slice_type837#define MAX_NUM_REF_IDX_L1_ACTIVE_MINUS1 15
838 uiSliceType = uiCode;838#define SLICE_HEADER_CABAC_INIT_IDC_MAX 2
839 if (uiSliceType > 9) {839/*
840 WelsLog (pLogCtx, WELS_LOG_WARNING, "slice type too large (%d) at first_mb(%d)", uiSliceType,840 * decode_slice_header_avc
841 pSliceHead->iFirstMbInSlice);841 * Parse slice header of bitstream in avc for storing data structure
842 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SLICE_TYPE);842 */
843 }843int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, const bool kbExtensionFlag) {
844 if (uiSliceType > 4)844 PNalUnit const kpCurNal = pCtx->pAccessUnitList->pNalUnitsList[pCtx->pAccessUnitList->uiAvailUnitsNum -
845 uiSliceType -= 5;845 1];
846 846
847 if (B_SLICE == uiSliceType) {847 PNalUnitHeaderExt pNalHeaderExt = NULL;
848 WelsLog (pLogCtx, WELS_LOG_WARNING, "ParseSliceHeaderSyntaxs(): B slice not supported.");848 PSliceHeader pSliceHead = NULL;
849 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_BIPRED);849 PSliceHeaderExt pSliceHeadExt = NULL;
850 }850 PSubsetSps pSubsetSps = NULL;
851 if ((NAL_UNIT_CODED_SLICE_IDR == eNalType) && (I_SLICE != uiSliceType)) {851 PSps pSps = NULL;
852 WelsLog (pLogCtx, WELS_LOG_WARNING, "Invalid slice type(%d) in IDR picture. ", uiSliceType);852 PPps pPps = NULL;
853 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SLICE_TYPE);853 EWelsNalUnitType eNalType = static_cast<EWelsNalUnitType> (0);
854 }854 int32_t iPpsId = 0;
855 855 int32_t iRet = ERR_NONE;
856 if (kbExtensionFlag) {856 uint8_t uiSliceType = 0;
857 if (uiSliceType > 2) {857 uint8_t uiQualityId = BASE_QUALITY_ID;
858 WelsLog (pLogCtx, WELS_LOG_WARNING, "Invalid slice type(%d).", uiSliceType);858 bool bIdrFlag = false;
859 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SLICE_TYPE);859 bool bSgChangeCycleInvolved = false; // involved slice group change cycle ?
860 }860 uint32_t uiCode;
861 }861 int32_t iCode;
862 862 SLogContext* pLogCtx = & (pCtx->sLogCtx);
863 pSliceHead->eSliceType = static_cast <EWelsSliceType> (uiSliceType);863
864 864 if (kpCurNal == NULL) {
865 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //pic_parameter_set_id865 return ERR_INFO_OUT_OF_MEMORY;
866 WELS_CHECK_SE_UPPER_ERROR (uiCode, (MAX_PPS_COUNT - 1), "iPpsId out of range",866 }
867 GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,867
868 ERR_INFO_PPS_ID_OVERFLOW));868 pNalHeaderExt = &kpCurNal->sNalHeaderExt;
869 iPpsId = uiCode;869 pSliceHead = &kpCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader;
870 870 eNalType = pNalHeaderExt->sNalUnitHeader.eNalUnitType;
871 //add check PPS available here871
872 if (pCtx->bPpsAvailFlags[iPpsId] == false) {872 pSliceHeadExt = &kpCurNal->sNalData.sVclNal.sSliceHeaderExt;
873 pCtx->sDecoderStatistics.iPpsReportErrorNum++;873
874 if (pCtx->iPPSLastInvalidId != iPpsId) {874 if (pSliceHeadExt) {
875 WelsLog (pLogCtx, WELS_LOG_ERROR, "PPS id (%d) is invalid, previous id (%d) error ignored (%d)!", iPpsId,875 SRefBasePicMarking sBaseMarking;
876 pCtx->iPPSLastInvalidId, pCtx->iPPSInvalidNum);876 const bool kbStoreRefBaseFlag = pSliceHeadExt->bStoreRefBasePicFlag;
877 pCtx->iPPSLastInvalidId = iPpsId;877 memcpy (&sBaseMarking, &pSliceHeadExt->sRefBasePicMarking, sizeof (SRefBasePicMarking)); //confirmed_safe_unsafe_usage
878 pCtx->iPPSInvalidNum = 0;878 memset (pSliceHeadExt, 0, sizeof (SSliceHeaderExt));
879 } else {879 pSliceHeadExt->bStoreRefBasePicFlag = kbStoreRefBaseFlag;
880 pCtx->iPPSInvalidNum++;880 memcpy (&pSliceHeadExt->sRefBasePicMarking, &sBaseMarking, sizeof (SRefBasePicMarking)); //confirmed_safe_unsafe_usage
881 }881 }
882 pCtx->iErrorCode |= dsNoParamSets;882
883 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_PPS_ID);883 kpCurNal->sNalData.sVclNal.bSliceHeaderExtFlag = kbExtensionFlag;
884 }884
885 pCtx->iPPSLastInvalidId = -1;885 // first_mb_in_slice
886 886 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //first_mb_in_slice
887 pPps = &pCtx->sPpsBuffer[iPpsId];887 WELS_CHECK_SE_UPPER_ERROR (uiCode, 36863u, "first_mb_in_slice", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,
888 888 ERR_INFO_INVALID_FIRST_MB_IN_SLICE));
889 if (pPps->uiNumSliceGroups == 0) {889 pSliceHead->iFirstMbInSlice = uiCode;
890 WelsLog (pLogCtx, WELS_LOG_WARNING, "Invalid PPS referenced");890
891 pCtx->iErrorCode |= dsNoParamSets;891 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //slice_type
892 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_NO_PARAM_SETS);892 uiSliceType = uiCode;
893 }893 if (uiSliceType > 9) {
894 894 WelsLog (pLogCtx, WELS_LOG_WARNING, "slice type too large (%d) at first_mb(%d)", uiSliceType,
895 if (kbExtensionFlag) {895 pSliceHead->iFirstMbInSlice);
896 pSubsetSps = &pCtx->sSubsetSpsBuffer[pPps->iSpsId];896 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SLICE_TYPE);
897 pSps = &pSubsetSps->sSps;897 }
898 if (pCtx->bSubspsAvailFlags[pPps->iSpsId] == false) {898 if (uiSliceType > 4)
899 pCtx->sDecoderStatistics.iSubSpsReportErrorNum++;899 uiSliceType -= 5;
900 if (pCtx->iSubSPSLastInvalidId != pPps->iSpsId) {900
901 WelsLog (pLogCtx, WELS_LOG_ERROR, "Sub SPS id (%d) is invalid, previous id (%d) error ignored (%d)!", pPps->iSpsId,901 if ((NAL_UNIT_CODED_SLICE_IDR == eNalType) && (I_SLICE != uiSliceType)) {
902 pCtx->iSubSPSLastInvalidId, pCtx->iSubSPSInvalidNum);902 WelsLog (pLogCtx, WELS_LOG_WARNING, "Invalid slice type(%d) in IDR picture. ", uiSliceType);
903 pCtx->iSubSPSLastInvalidId = pPps->iSpsId;903 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SLICE_TYPE);
904 pCtx->iSubSPSInvalidNum = 0;904 }
905 } else {905
906 pCtx->iSubSPSInvalidNum++;906 if (kbExtensionFlag) {
907 }907 if (uiSliceType > 2) {
908 pCtx->iErrorCode |= dsNoParamSets;908 WelsLog (pLogCtx, WELS_LOG_WARNING, "Invalid slice type(%d).", uiSliceType);
909 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SPS_ID);909 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SLICE_TYPE);
910 }910 }
911 pCtx->iSubSPSLastInvalidId = -1;911 }
912 } else {912
913 if (pCtx->bSpsAvailFlags[pPps->iSpsId] == false) {913 pSliceHead->eSliceType = static_cast <EWelsSliceType> (uiSliceType);
914 pCtx->sDecoderStatistics.iSpsReportErrorNum++;914
915 if (pCtx->iSPSLastInvalidId != pPps->iSpsId) {915 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //pic_parameter_set_id
916 WelsLog (pLogCtx, WELS_LOG_ERROR, "SPS id (%d) is invalid, previous id (%d) error ignored (%d)!", pPps->iSpsId,916 WELS_CHECK_SE_UPPER_ERROR (uiCode, (MAX_PPS_COUNT - 1), "iPpsId out of range",
917 pCtx->iSPSLastInvalidId, pCtx->iSPSInvalidNum);917 GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,
918 pCtx->iSPSLastInvalidId = pPps->iSpsId;918 ERR_INFO_PPS_ID_OVERFLOW));
919 pCtx->iSPSInvalidNum = 0;919 iPpsId = uiCode;
920 } else {920
921 pCtx->iSPSInvalidNum++;921 //add check PPS available here
922 }922 if (pCtx->bPpsAvailFlags[iPpsId] == false) {
923 pCtx->iErrorCode |= dsNoParamSets;923 pCtx->sDecoderStatistics.iPpsReportErrorNum++;
924 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SPS_ID);924 if (pCtx->iPPSLastInvalidId != iPpsId) {
925 }925 WelsLog (pLogCtx, WELS_LOG_ERROR, "PPS id (%d) is invalid, previous id (%d) error ignored (%d)!", iPpsId,
926 pCtx->iSPSLastInvalidId = -1;926 pCtx->iPPSLastInvalidId, pCtx->iPPSInvalidNum);
927 pSps = &pCtx->sSpsBuffer[pPps->iSpsId];927 pCtx->iPPSLastInvalidId = iPpsId;
928 }928 pCtx->iPPSInvalidNum = 0;
929 pSliceHead->iPpsId = iPpsId;929 } else {
930 pSliceHead->iSpsId = pPps->iSpsId;930 pCtx->iPPSInvalidNum++;
931 pSliceHead->pPps = pPps;931 }
932 pSliceHead->pSps = pSps;932 pCtx->iErrorCode |= dsNoParamSets;
933 933 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_PPS_ID);
934 pSliceHeadExt->pSubsetSps = pSubsetSps;934 }
935 935 pCtx->iPPSLastInvalidId = -1;
936 if (pSps->iNumRefFrames == 0) {936
937 if ((uiSliceType != I_SLICE) && (uiSliceType != SI_SLICE)) {937 pPps = &pCtx->sPpsBuffer[iPpsId];
938 WelsLog (pLogCtx, WELS_LOG_WARNING, "slice_type (%d) not supported for num_ref_frames = 0.", uiSliceType);938
939 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SLICE_TYPE);939 if (pPps->uiNumSliceGroups == 0) {
940 }940 WelsLog (pLogCtx, WELS_LOG_WARNING, "Invalid PPS referenced");
941 }941 pCtx->iErrorCode |= dsNoParamSets;
942 942 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_NO_PARAM_SETS);
943 bIdrFlag = (!kbExtensionFlag && eNalType == NAL_UNIT_CODED_SLICE_IDR) || (kbExtensionFlag && pNalHeaderExt->bIdrFlag);943 }
944 pSliceHead->bIdrFlag = bIdrFlag;944
945 945 if (kbExtensionFlag) {
946 if (pSps->uiLog2MaxFrameNum == 0) {946 pSubsetSps = &pCtx->sSubsetSpsBuffer[pPps->iSpsId];
947 WelsLog (pLogCtx, WELS_LOG_WARNING, "non existing SPS referenced");947 pSps = &pSubsetSps->sSps;
948 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_NO_PARAM_SETS);948 if (pCtx->bSubspsAvailFlags[pPps->iSpsId] == false) {
949 }949 pCtx->sDecoderStatistics.iSubSpsReportErrorNum++;
950 // check first_mb_in_slice950 if (pCtx->iSubSPSLastInvalidId != pPps->iSpsId) {
951 WELS_CHECK_SE_UPPER_ERROR ((uint32_t) (pSliceHead->iFirstMbInSlice), (pSps->uiTotalMbCount - 1), "first_mb_in_slice",951 WelsLog (pLogCtx, WELS_LOG_ERROR, "Sub SPS id (%d) is invalid, previous id (%d) error ignored (%d)!", pPps->iSpsId,
952 GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_FIRST_MB_IN_SLICE));952 pCtx->iSubSPSLastInvalidId, pCtx->iSubSPSInvalidNum);
953 WELS_READ_VERIFY (BsGetBits (pBs, pSps->uiLog2MaxFrameNum, &uiCode)); //frame_num953 pCtx->iSubSPSLastInvalidId = pPps->iSpsId;
954 pSliceHead->iFrameNum = uiCode;954 pCtx->iSubSPSInvalidNum = 0;
955 955 } else {
956 pSliceHead->bFieldPicFlag = false;956 pCtx->iSubSPSInvalidNum++;
957 pSliceHead->bBottomFiledFlag = false;957 }
958 if (!pSps->bFrameMbsOnlyFlag) {958 pCtx->iErrorCode |= dsNoParamSets;
959 WelsLog (pLogCtx, WELS_LOG_WARNING, "ParseSliceHeaderSyntaxs(): frame_mbs_only_flag = %d not supported. ",959 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SPS_ID);
960 pSps->bFrameMbsOnlyFlag);960 }
961 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_MBAFF);961 pCtx->iSubSPSLastInvalidId = -1;
962 }962 } else {
963 pSliceHead->iMbWidth = pSps->iMbWidth;963 if (pCtx->bSpsAvailFlags[pPps->iSpsId] == false) {
964 pSliceHead->iMbHeight = pSps->iMbHeight / (1 + pSliceHead->bFieldPicFlag);964 pCtx->sDecoderStatistics.iSpsReportErrorNum++;
965 965 if (pCtx->iSPSLastInvalidId != pPps->iSpsId) {
966 if (bIdrFlag) {966 WelsLog (pLogCtx, WELS_LOG_ERROR, "SPS id (%d) is invalid, previous id (%d) error ignored (%d)!", pPps->iSpsId,
967 if (pSliceHead->iFrameNum != 0) {967 pCtx->iSPSLastInvalidId, pCtx->iSPSInvalidNum);
968 WelsLog (pLogCtx, WELS_LOG_WARNING,968 pCtx->iSPSLastInvalidId = pPps->iSpsId;
969 "ParseSliceHeaderSyntaxs(), invaild frame number: %d due to IDR frame introduced!",969 pCtx->iSPSInvalidNum = 0;
970 pSliceHead->iFrameNum);970 } else {
971 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_FRAME_NUM);971 pCtx->iSPSInvalidNum++;
972 }972 }
973 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //idr_pic_id973 pCtx->iErrorCode |= dsNoParamSets;
974 // standard 7.4.3 idr_pic_id should be in range 0 to 65535, inclusive.974 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SPS_ID);
975 WELS_CHECK_SE_UPPER_ERROR (uiCode, SLICE_HEADER_IDR_PIC_ID_MAX, "idr_pic_id", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,975 }
976 ERR_INFO_INVALID_IDR_PIC_ID));976 pCtx->iSPSLastInvalidId = -1;
977 pSliceHead->uiIdrPicId = uiCode; /* uiIdrPicId */977 pSps = &pCtx->sSpsBuffer[pPps->iSpsId];
978#ifdef LONG_TERM_REF978 }
979 pCtx->uiCurIdrPicId = pSliceHead->uiIdrPicId;979 pSliceHead->iPpsId = iPpsId;
980#endif980 pSliceHead->iSpsId = pPps->iSpsId;
981 }981 pSliceHead->pPps = pPps;
982 982 pSliceHead->pSps = pSps;
983 pSliceHead->iDeltaPicOrderCntBottom = 0;983
984 pSliceHead->iDeltaPicOrderCnt[0] =984 pSliceHeadExt->pSubsetSps = pSubsetSps;
985 pSliceHead->iDeltaPicOrderCnt[1] = 0;985
986 if (pSps->uiPocType == 0) {986 if (pSps->iNumRefFrames == 0) {
987 WELS_READ_VERIFY (BsGetBits (pBs, pSps->iLog2MaxPocLsb, &uiCode)); //pic_order_cnt_lsb987 if ((uiSliceType != I_SLICE) && (uiSliceType != SI_SLICE)) {
988 pSliceHead->iPicOrderCntLsb = uiCode;988 WelsLog (pLogCtx, WELS_LOG_WARNING, "slice_type (%d) not supported for num_ref_frames = 0.", uiSliceType);
989 if (pPps->bPicOrderPresentFlag && !pSliceHead->bFieldPicFlag) {989 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SLICE_TYPE);
990 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //delta_pic_order_cnt_bottom990 }
991 pSliceHead->iDeltaPicOrderCntBottom = iCode;991 }
992 }992
993 } else if (pSps->uiPocType == 1 && !pSps->bDeltaPicOrderAlwaysZeroFlag) {993 bIdrFlag = (!kbExtensionFlag && eNalType == NAL_UNIT_CODED_SLICE_IDR) || (kbExtensionFlag && pNalHeaderExt->bIdrFlag);
994 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //delta_pic_order_cnt[ 0 ]994 pSliceHead->bIdrFlag = bIdrFlag;
995 pSliceHead->iDeltaPicOrderCnt[0] = iCode;995
996 if (pPps->bPicOrderPresentFlag && !pSliceHead->bFieldPicFlag) {996 if (pSps->uiLog2MaxFrameNum == 0) {
997 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //delta_pic_order_cnt[ 1 ]997 WelsLog (pLogCtx, WELS_LOG_WARNING, "non existing SPS referenced");
998 pSliceHead->iDeltaPicOrderCnt[1] = iCode;998 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_NO_PARAM_SETS);
999 }999 }
1000 }1000 // check first_mb_in_slice
1001 1001 WELS_CHECK_SE_UPPER_ERROR ((uint32_t) (pSliceHead->iFirstMbInSlice), (pSps->uiTotalMbCount - 1), "first_mb_in_slice",
1002 pSliceHead->iRedundantPicCnt = 0;1002 GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_FIRST_MB_IN_SLICE));
1003 if (pPps->bRedundantPicCntPresentFlag) {1003 WELS_READ_VERIFY (BsGetBits (pBs, pSps->uiLog2MaxFrameNum, &uiCode)); //frame_num
1004 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //redundant_pic_cnt1004 pSliceHead->iFrameNum = uiCode;
1005 // standard section 7.4.3, redundant_pic_cnt should be in range 0 to 127, inclusive.1005
1006 WELS_CHECK_SE_UPPER_ERROR (uiCode, SLICE_HEADER_REDUNDANT_PIC_CNT_MAX, "redundant_pic_cnt",1006 pSliceHead->bFieldPicFlag = false;
1007 GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REDUNDANT_PIC_CNT));1007 pSliceHead->bBottomFiledFlag = false;
1008 pSliceHead->iRedundantPicCnt = uiCode;1008 if (!pSps->bFrameMbsOnlyFlag) {
1009 if (pSliceHead->iRedundantPicCnt > 0) {1009 WelsLog (pLogCtx, WELS_LOG_WARNING, "ParseSliceHeaderSyntaxs(): frame_mbs_only_flag = %d not supported. ",
1010 WelsLog (pLogCtx, WELS_LOG_WARNING, "Redundant picture not supported!");1010 pSps->bFrameMbsOnlyFlag);
1011 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REDUNDANT_PIC_CNT);1011 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_MBAFF);
1012 }1012 }
1013 }1013 pSliceHead->iMbWidth = pSps->iMbWidth;
1014 1014 pSliceHead->iMbHeight = pSps->iMbHeight / (1 + pSliceHead->bFieldPicFlag);
1015 //set defaults, might be overriden a few line later1015
1016 pSliceHead->uiRefCount[0] = pPps->uiNumRefIdxL0Active;1016 if (bIdrFlag) {
1017 pSliceHead->uiRefCount[1] = pPps->uiNumRefIdxL1Active;1017 if (pSliceHead->iFrameNum != 0) {
1018 1018 WelsLog (pLogCtx, WELS_LOG_WARNING,
1019 bool bReadNumRefFlag = (P_SLICE == uiSliceType);1019 "ParseSliceHeaderSyntaxs(), invaild frame number: %d due to IDR frame introduced!",
1020 if (kbExtensionFlag) {1020 pSliceHead->iFrameNum);
1021 bReadNumRefFlag &= (BASE_QUALITY_ID == pNalHeaderExt->uiQualityId);1021 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_FRAME_NUM);
1022 }1022 }
1023 if (bReadNumRefFlag) {1023 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //idr_pic_id
1024 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //num_ref_idx_active_override_flag1024 // standard 7.4.3 idr_pic_id should be in range 0 to 65535, inclusive.
1025 pSliceHead->bNumRefIdxActiveOverrideFlag = !!uiCode;1025 WELS_CHECK_SE_UPPER_ERROR (uiCode, SLICE_HEADER_IDR_PIC_ID_MAX, "idr_pic_id", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,
1026 if (pSliceHead->bNumRefIdxActiveOverrideFlag) {1026 ERR_INFO_INVALID_IDR_PIC_ID));
1027 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //num_ref_idx_l0_active_minus11027 pSliceHead->uiIdrPicId = uiCode; /* uiIdrPicId */
1028 WELS_CHECK_SE_UPPER_ERROR (uiCode, MAX_NUM_REF_IDX_L0_ACTIVE_MINUS1, "num_ref_idx_l0_active_minus1",1028#ifdef LONG_TERM_REF
1029 GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_NUM_REF_IDX_L0_ACTIVE_MINUS1));1029 pCtx->uiCurIdrPicId = pSliceHead->uiIdrPicId;
1030 pSliceHead->uiRefCount[0] = 1 + uiCode;1030#endif
1031 }1031 }
1032 }1032
1033 1033 pSliceHead->iDeltaPicOrderCntBottom = 0;
1034 if (pSliceHead->uiRefCount[0] > MAX_REF_PIC_COUNT || pSliceHead->uiRefCount[1] > MAX_REF_PIC_COUNT) {1034 pSliceHead->iDeltaPicOrderCnt[0] =
1035 WelsLog (pLogCtx, WELS_LOG_WARNING, "reference overflow");1035 pSliceHead->iDeltaPicOrderCnt[1] = 0;
1036 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_REF_COUNT_OVERFLOW);1036 if (pSps->uiPocType == 0) {
1037 }1037 WELS_READ_VERIFY (BsGetBits (pBs, pSps->iLog2MaxPocLsb, &uiCode)); //pic_order_cnt_lsb
1038 1038 const int32_t iMaxPocLsb = 1 << (pSps->iLog2MaxPocLsb);
1039 if (BASE_QUALITY_ID == uiQualityId) {1039 pSliceHead->iPicOrderCntLsb = uiCode;
1040 iRet = ParseRefPicListReordering (pBs, pSliceHead);1040 if (pPps->bPicOrderPresentFlag && !pSliceHead->bFieldPicFlag) {
1041 if (iRet != ERR_NONE) {1041 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //delta_pic_order_cnt_bottom
1042 WelsLog (pLogCtx, WELS_LOG_WARNING, "invalid ref pPic list reordering syntaxs!");1042 pSliceHead->iDeltaPicOrderCntBottom = iCode;
1043 return iRet;1043 }
1044 }1044 //Calculate poc if necessary
1045 1045 int32_t pocLsb = pSliceHead->iPicOrderCntLsb;
1046 if (pPps->bWeightedPredFlag && (uiSliceType == P_SLICE)) {1046 if (pSliceHead->bIdrFlag || kpCurNal->sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR) {
1047 iRet = ParsePredWeightedTable (pBs, pSliceHead);1047 pCtx->iPrevPicOrderCntMsb = 0;
1048 if (iRet != ERR_NONE) {1048 pCtx->iPrevPicOrderCntLsb = 0;
1049 WelsLog (pLogCtx, WELS_LOG_WARNING, "invalid weighted prediction syntaxs!");1049 }
1050 return iRet;1050 int32_t pocMsb;
1051 }1051 if (pocLsb < pCtx->iPrevPicOrderCntLsb && pCtx->iPrevPicOrderCntLsb - pocLsb >= iMaxPocLsb / 2)
1052 }1052 pocMsb = pCtx->iPrevPicOrderCntMsb + iMaxPocLsb;
1053 1053 else if (pocLsb > pCtx->iPrevPicOrderCntLsb && pocLsb - pCtx->iPrevPicOrderCntLsb > iMaxPocLsb / 2)
1054 if (kbExtensionFlag) {1054 pocMsb = pCtx->iPrevPicOrderCntMsb - iMaxPocLsb;
1055 if (pNalHeaderExt->iNoInterLayerPredFlag || pNalHeaderExt->uiQualityId > 0)1055 else
1056 pSliceHeadExt->bBasePredWeightTableFlag = false;1056 pocMsb = pCtx->iPrevPicOrderCntMsb;
1057 else1057 pSliceHead->iPicOrderCntLsb = pocMsb + pocLsb;
1058 pSliceHeadExt->bBasePredWeightTableFlag = true;1058
1059 }1059 if (pPps->bPicOrderPresentFlag && !pSliceHead->bFieldPicFlag) {
1060 1060 pSliceHead->iPicOrderCntLsb += pSliceHead->iDeltaPicOrderCntBottom;
1061 if (kpCurNal->sNalHeaderExt.sNalUnitHeader.uiNalRefIdc != 0) {1061 }
1062 iRet = ParseDecRefPicMarking (pCtx, pBs, pSliceHead, pSps, bIdrFlag);1062
1063 if (iRet != ERR_NONE) {1063 if (kpCurNal->sNalHeaderExt.sNalUnitHeader.uiNalRefIdc != 0) {
1064 return iRet;1064 pCtx->iPrevPicOrderCntLsb = pocLsb;
1065 }1065 pCtx->iPrevPicOrderCntMsb = pocMsb;
1066 1066 }
1067 if (kbExtensionFlag && !pSubsetSps->sSpsSvcExt.bSliceHeaderRestrictionFlag) {1067 //End of Calculating poc
1068 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //store_ref_base_pic_flag1068 } else if (pSps->uiPocType == 1 && !pSps->bDeltaPicOrderAlwaysZeroFlag) {
1069 pSliceHeadExt->bStoreRefBasePicFlag = !!uiCode;1069 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //delta_pic_order_cnt[ 0 ]
1070 if ((pNalHeaderExt->bUseRefBasePicFlag || pSliceHeadExt->bStoreRefBasePicFlag) && !bIdrFlag) {1070 pSliceHead->iDeltaPicOrderCnt[0] = iCode;
1071 WelsLog (pLogCtx, WELS_LOG_WARNING,1071 if (pPps->bPicOrderPresentFlag && !pSliceHead->bFieldPicFlag) {
1072 "ParseSliceHeaderSyntaxs(): bUseRefBasePicFlag or bStoreRefBasePicFlag = 1 not supported.");1072 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //delta_pic_order_cnt[ 1 ]
1073 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_ILP);1073 pSliceHead->iDeltaPicOrderCnt[1] = iCode;
1074 }1074 }
1075 }1075 }
1076 }1076 pSliceHead->iRedundantPicCnt = 0;
1077 }1077 if (pPps->bRedundantPicCntPresentFlag) {
1078 1078 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //redundant_pic_cnt
1079 if (pPps->bEntropyCodingModeFlag) {1079 // standard section 7.4.3, redundant_pic_cnt should be in range 0 to 127, inclusive.
1080 if (pSliceHead->eSliceType != I_SLICE && pSliceHead->eSliceType != SI_SLICE) {1080 WELS_CHECK_SE_UPPER_ERROR (uiCode, SLICE_HEADER_REDUNDANT_PIC_CNT_MAX, "redundant_pic_cnt",
1081 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode));1081 GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REDUNDANT_PIC_CNT));
1082 WELS_CHECK_SE_UPPER_ERROR (uiCode, SLICE_HEADER_CABAC_INIT_IDC_MAX, "cabac_init_idc", ERR_INFO_INVALID_CABAC_INIT_IDC);1082 pSliceHead->iRedundantPicCnt = uiCode;
1083 pSliceHead->iCabacInitIdc = uiCode;1083 if (pSliceHead->iRedundantPicCnt > 0) {
1084 } else1084 WelsLog (pLogCtx, WELS_LOG_WARNING, "Redundant picture not supported!");
1085 pSliceHead->iCabacInitIdc = 0;1085 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_REDUNDANT_PIC_CNT);
1086 }1086 }
1087 1087 }
1088 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //slice_qp_delta1088
1089 pSliceHead->iSliceQpDelta = iCode;1089 if (B_SLICE == uiSliceType) {
1090 pSliceHead->iSliceQp = pPps->iPicInitQp + pSliceHead->iSliceQpDelta;1090 //fix me: it needs to use the this flag somewhere for B-Sclice
1091 if (pSliceHead->iSliceQp < 0 || pSliceHead->iSliceQp > 51) {1091 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //direct_spatial_mv_pred_flag
1092 WelsLog (pLogCtx, WELS_LOG_WARNING, "QP %d out of range", pSliceHead->iSliceQp);1092 pSliceHead->iDirectSpatialMvPredFlag = uiCode;
1093 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_QP);1093 }
1094 }1094
1095 1095 //set defaults, might be overriden a few line later
1096 //FIXME qscale / qp ... stuff1096 pSliceHead->uiRefCount[0] = pPps->uiNumRefIdxL0Active;
1097 if (!kbExtensionFlag) {1097 pSliceHead->uiRefCount[1] = pPps->uiNumRefIdxL1Active;
1098 if (uiSliceType == SP_SLICE || uiSliceType == SI_SLICE) {1098
1099 WelsLog (pLogCtx, WELS_LOG_WARNING, "SP/SI not supported");1099 bool bReadNumRefFlag = (P_SLICE == uiSliceType || B_SLICE == uiSliceType);
1100 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_SPSI);1100 if (kbExtensionFlag) {
1101 }1101 bReadNumRefFlag &= (BASE_QUALITY_ID == pNalHeaderExt->uiQualityId);
1102 }1102 }
1103 1103 if (bReadNumRefFlag) {
1104 pSliceHead->uiDisableDeblockingFilterIdc = 0;1104 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //num_ref_idx_active_override_flag
1105 pSliceHead->iSliceAlphaC0Offset = 0;1105 pSliceHead->bNumRefIdxActiveOverrideFlag = !!uiCode;
1106 pSliceHead->iSliceBetaOffset = 0;1106 if (pSliceHead->bNumRefIdxActiveOverrideFlag) {
1107 if (pPps->bDeblockingFilterControlPresentFlag) {1107 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //num_ref_idx_l0_active_minus1
1108 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //disable_deblocking_filter_idc1108 WELS_CHECK_SE_UPPER_ERROR (uiCode, MAX_NUM_REF_IDX_L0_ACTIVE_MINUS1, "num_ref_idx_l0_active_minus1",
1109 pSliceHead->uiDisableDeblockingFilterIdc = uiCode;1109 GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_NUM_REF_IDX_L0_ACTIVE_MINUS1));
1110 //refer to JVT-X201wcm1.doc G.7.4.3.4--2010.4.201110 pSliceHead->uiRefCount[0] = 1 + uiCode;
1111 if (pSliceHead->uiDisableDeblockingFilterIdc > 6) {1111 if (B_SLICE == uiSliceType) {
1112 WelsLog (pLogCtx, WELS_LOG_WARNING, "disable_deblock_filter_idc (%d) out of range [0, 6]",1112 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //num_ref_idx_l1_active_minus1
1113 pSliceHead->uiDisableDeblockingFilterIdc);1113 WELS_CHECK_SE_UPPER_ERROR (uiCode, MAX_NUM_REF_IDX_L1_ACTIVE_MINUS1, "num_ref_idx_l1_active_minus1",
1114 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_DBLOCKING_IDC);1114 GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_NUM_REF_IDX_L1_ACTIVE_MINUS1));
1115 }1115 pSliceHead->uiRefCount[1] = 1 + uiCode;
1116 if (pSliceHead->uiDisableDeblockingFilterIdc != 1) {1116 }
1117 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //slice_alpha_c0_offset_div21117 }
1118 pSliceHead->iSliceAlphaC0Offset = iCode * 2;1118 }
1119 WELS_CHECK_SE_BOTH_ERROR (pSliceHead->iSliceAlphaC0Offset, SLICE_HEADER_ALPHAC0_BETA_OFFSET_MIN,1119
1120 SLICE_HEADER_ALPHAC0_BETA_OFFSET_MAX, "slice_alpha_c0_offset_div2 * 2", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,1120 if (pSliceHead->uiRefCount[0] > MAX_REF_PIC_COUNT || pSliceHead->uiRefCount[1] > MAX_REF_PIC_COUNT) {
1121 ERR_INFO_INVALID_SLICE_ALPHA_C0_OFFSET_DIV2));1121 WelsLog (pLogCtx, WELS_LOG_WARNING, "reference overflow");
1122 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //slice_beta_offset_div21122 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_REF_COUNT_OVERFLOW);
1123 pSliceHead->iSliceBetaOffset = iCode * 2;1123 }
1124 WELS_CHECK_SE_BOTH_ERROR (pSliceHead->iSliceBetaOffset, SLICE_HEADER_ALPHAC0_BETA_OFFSET_MIN,1124
1125 SLICE_HEADER_ALPHAC0_BETA_OFFSET_MAX, "slice_beta_offset_div2 * 2", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,1125 if (BASE_QUALITY_ID == uiQualityId) {
1126 ERR_INFO_INVALID_SLICE_BETA_OFFSET_DIV2));1126 iRet = ParseRefPicListReordering (pBs, pSliceHead);
1127 }1127 if (iRet != ERR_NONE) {
1128 }1128 WelsLog (pLogCtx, WELS_LOG_WARNING, "invalid ref pPic list reordering syntaxs!");
1129 1129 return iRet;
1130 bSgChangeCycleInvolved = (pPps->uiNumSliceGroups > 1 && pPps->uiSliceGroupMapType >= 31130 }
1131 && pPps->uiSliceGroupMapType <= 5);1131
1132 if (kbExtensionFlag && bSgChangeCycleInvolved)1132 if ((pPps->bWeightedPredFlag && uiSliceType == P_SLICE) || (pPps->uiWeightedBipredIdc == 1 && uiSliceType == B_SLICE)) {
1133 bSgChangeCycleInvolved = (bSgChangeCycleInvolved && (uiQualityId == BASE_QUALITY_ID));1133 iRet = ParsePredWeightedTable (pBs, pSliceHead);
1134 if (bSgChangeCycleInvolved) {1134 if (iRet != ERR_NONE) {
1135 if (pPps->uiSliceGroupChangeRate > 0) {1135 WelsLog (pLogCtx, WELS_LOG_WARNING, "invalid weighted prediction syntaxs!");
1136 const int32_t kiNumBits = (int32_t)WELS_CEIL (log (static_cast<double> (1 + pPps->uiPicSizeInMapUnits /1136 return iRet;
1137 pPps->uiSliceGroupChangeRate)));1137 }
1138 WELS_READ_VERIFY (BsGetBits (pBs, kiNumBits, &uiCode)); //lice_group_change_cycle1138 }
1139 pSliceHead->iSliceGroupChangeCycle = uiCode;1139
1140 } else1140 if (kbExtensionFlag) {
1141 pSliceHead->iSliceGroupChangeCycle = 0;1141 if (pNalHeaderExt->iNoInterLayerPredFlag || pNalHeaderExt->uiQualityId > 0)
1142 }1142 pSliceHeadExt->bBasePredWeightTableFlag = false;
1143 1143 else
1144 if (!kbExtensionFlag) {1144 pSliceHeadExt->bBasePredWeightTableFlag = true;
1145 FillDefaultSliceHeaderExt (pSliceHeadExt, pNalHeaderExt);1145 }
1146 } else {1146
1147 /* Extra syntax elements newly introduced */1147 if (kpCurNal->sNalHeaderExt.sNalUnitHeader.uiNalRefIdc != 0) {
1148 pSliceHeadExt->pSubsetSps = pSubsetSps;1148 iRet = ParseDecRefPicMarking (pCtx, pBs, pSliceHead, pSps, bIdrFlag);
1149 1149 if (iRet != ERR_NONE) {
1150 if (!pNalHeaderExt->iNoInterLayerPredFlag && BASE_QUALITY_ID == uiQualityId) {1150 return iRet;
1151 //the following should be deleted for CODE_CLEAN1151 }
1152 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //ref_layer_dq_id1152
1153 pSliceHeadExt->uiRefLayerDqId = uiCode;1153 if (kbExtensionFlag && !pSubsetSps->sSpsSvcExt.bSliceHeaderRestrictionFlag) {
1154 if (pSubsetSps->sSpsSvcExt.bInterLayerDeblockingFilterCtrlPresentFlag) {1154 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //store_ref_base_pic_flag
1155 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //disable_inter_layer_deblocking_filter_idc1155 pSliceHeadExt->bStoreRefBasePicFlag = !!uiCode;
1156 pSliceHeadExt->uiDisableInterLayerDeblockingFilterIdc = uiCode;1156 if ((pNalHeaderExt->bUseRefBasePicFlag || pSliceHeadExt->bStoreRefBasePicFlag) && !bIdrFlag) {
1157 //refer to JVT-X201wcm1.doc G.7.4.3.4--2010.4.201157 WelsLog (pLogCtx, WELS_LOG_WARNING,
1158 if (pSliceHeadExt->uiDisableInterLayerDeblockingFilterIdc > 6) {1158 "ParseSliceHeaderSyntaxs(): bUseRefBasePicFlag or bStoreRefBasePicFlag = 1 not supported.");
1159 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "disable_inter_layer_deblock_filter_idc (%d) out of range [0, 6]",1159 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_ILP);
1160 pSliceHeadExt->uiDisableInterLayerDeblockingFilterIdc);1160 }
1161 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_DBLOCKING_IDC);1161 }
1162 }1162 }
1163 if (pSliceHeadExt->uiDisableInterLayerDeblockingFilterIdc != 1) {1163 }
1164 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //inter_layer_slice_alpha_c0_offset_div21164
1165 pSliceHeadExt->iInterLayerSliceAlphaC0Offset = iCode * 2;1165 if (pPps->bEntropyCodingModeFlag) {
1166 WELS_CHECK_SE_BOTH_ERROR (pSliceHeadExt->iInterLayerSliceAlphaC0Offset,1166 if (pSliceHead->eSliceType != I_SLICE && pSliceHead->eSliceType != SI_SLICE) {
1167 SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MIN, SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MAX,1167 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode));
1168 "inter_layer_alpha_c0_offset_div2 * 2", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,1168 WELS_CHECK_SE_UPPER_ERROR (uiCode, SLICE_HEADER_CABAC_INIT_IDC_MAX, "cabac_init_idc", ERR_INFO_INVALID_CABAC_INIT_IDC);
1169 ERR_INFO_INVALID_SLICE_ALPHA_C0_OFFSET_DIV2));1169 pSliceHead->iCabacInitIdc = uiCode;
1170 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //inter_layer_slice_beta_offset_div21170 } else
1171 pSliceHeadExt->iInterLayerSliceBetaOffset = iCode * 2;1171 pSliceHead->iCabacInitIdc = 0;
1172 WELS_CHECK_SE_BOTH_ERROR (pSliceHeadExt->iInterLayerSliceBetaOffset, SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MIN,1172 }
1173 SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MAX, "inter_layer_slice_beta_offset_div2 * 2",1173
1174 GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SLICE_BETA_OFFSET_DIV2));1174 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //slice_qp_delta
1175 }1175 pSliceHead->iSliceQpDelta = iCode;
1176 }1176 pSliceHead->iSliceQp = pPps->iPicInitQp + pSliceHead->iSliceQpDelta;
1177 1177 if (pSliceHead->iSliceQp < 0 || pSliceHead->iSliceQp > 51) {
1178 pSliceHeadExt->uiRefLayerChromaPhaseXPlus1Flag = pSubsetSps->sSpsSvcExt.uiSeqRefLayerChromaPhaseXPlus1Flag;1178 WelsLog (pLogCtx, WELS_LOG_WARNING, "QP %d out of range", pSliceHead->iSliceQp);
1179 pSliceHeadExt->uiRefLayerChromaPhaseYPlus1 = pSubsetSps->sSpsSvcExt.uiSeqRefLayerChromaPhaseYPlus1;1179 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_QP);
1180 1180 }
1181 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //constrained_intra_resampling_flag1181
1182 pSliceHeadExt->bConstrainedIntraResamplingFlag = !!uiCode;1182 //FIXME qscale / qp ... stuff
1183 1183 if (!kbExtensionFlag) {
1184 {1184 if (uiSliceType == SP_SLICE || uiSliceType == SI_SLICE) {
1185 SPosOffset pos;1185 WelsLog (pLogCtx, WELS_LOG_WARNING, "SP/SI not supported");
1186 pos.iLeftOffset = pSubsetSps->sSpsSvcExt.sSeqScaledRefLayer.iLeftOffset;1186 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_SPSI);
1187 pos.iTopOffset = pSubsetSps->sSpsSvcExt.sSeqScaledRefLayer.iTopOffset * (2 - pSps->bFrameMbsOnlyFlag);1187 }
1188 pos.iRightOffset = pSubsetSps->sSpsSvcExt.sSeqScaledRefLayer.iRightOffset;1188 }
1189 pos.iBottomOffset = pSubsetSps->sSpsSvcExt.sSeqScaledRefLayer.iBottomOffset * (2 - pSps->bFrameMbsOnlyFlag);1189
1190 //memcpy(&pSliceHeadExt->sScaledRefLayer, &pos, sizeof(SPosOffset));//confirmed_safe_unsafe_usage1190 pSliceHead->uiDisableDeblockingFilterIdc = 0;
1191 pSliceHeadExt->iScaledRefLayerPicWidthInSampleLuma = (pSliceHead->iMbWidth << 4) -1191 pSliceHead->iSliceAlphaC0Offset = 0;
1192 (pos.iLeftOffset + pos.iRightOffset);1192 pSliceHead->iSliceBetaOffset = 0;
1193 pSliceHeadExt->iScaledRefLayerPicHeightInSampleLuma = (pSliceHead->iMbHeight << 4) -1193 if (pPps->bDeblockingFilterControlPresentFlag) {
1194 (pos.iTopOffset + pos.iBottomOffset) / (1 + pSliceHead->bFieldPicFlag);1194 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //disable_deblocking_filter_idc
1195 }1195 pSliceHead->uiDisableDeblockingFilterIdc = uiCode;
1196 } else if (uiQualityId > BASE_QUALITY_ID) {1196 //refer to JVT-X201wcm1.doc G.7.4.3.4--2010.4.20
1197 WelsLog (pLogCtx, WELS_LOG_WARNING, "MGS not supported.");1197 if (pSliceHead->uiDisableDeblockingFilterIdc > 6) {
1198 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_MGS);1198 WelsLog (pLogCtx, WELS_LOG_WARNING, "disable_deblock_filter_idc (%d) out of range [0, 6]",
1199 } else {1199 pSliceHead->uiDisableDeblockingFilterIdc);
1200 pSliceHeadExt->uiRefLayerDqId = (uint8_t) - 1;1200 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_DBLOCKING_IDC);
1201 }1201 }
1202 1202 if (pSliceHead->uiDisableDeblockingFilterIdc != 1) {
1203 pSliceHeadExt->bSliceSkipFlag = false;1203 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //slice_alpha_c0_offset_div2
1204 pSliceHeadExt->bAdaptiveBaseModeFlag = false;1204 pSliceHead->iSliceAlphaC0Offset = iCode * 2;
1205 pSliceHeadExt->bDefaultBaseModeFlag = false;1205 WELS_CHECK_SE_BOTH_ERROR (pSliceHead->iSliceAlphaC0Offset, SLICE_HEADER_ALPHAC0_BETA_OFFSET_MIN,
1206 pSliceHeadExt->bAdaptiveMotionPredFlag = false;1206 SLICE_HEADER_ALPHAC0_BETA_OFFSET_MAX, "slice_alpha_c0_offset_div2 * 2", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,
1207 pSliceHeadExt->bDefaultMotionPredFlag = false;1207 ERR_INFO_INVALID_SLICE_ALPHA_C0_OFFSET_DIV2));
1208 pSliceHeadExt->bAdaptiveResidualPredFlag = false;1208 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //slice_beta_offset_div2
1209 pSliceHeadExt->bDefaultResidualPredFlag = false;1209 pSliceHead->iSliceBetaOffset = iCode * 2;
1210 if (pNalHeaderExt->iNoInterLayerPredFlag)1210 WELS_CHECK_SE_BOTH_ERROR (pSliceHead->iSliceBetaOffset, SLICE_HEADER_ALPHAC0_BETA_OFFSET_MIN,
1211 pSliceHeadExt->bTCoeffLevelPredFlag = false;1211 SLICE_HEADER_ALPHAC0_BETA_OFFSET_MAX, "slice_beta_offset_div2 * 2", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,
1212 else1212 ERR_INFO_INVALID_SLICE_BETA_OFFSET_DIV2));
1213 pSliceHeadExt->bTCoeffLevelPredFlag = pSubsetSps->sSpsSvcExt.bSeqTCoeffLevelPredFlag;1213 }
1214 1214 }
1215 if (!pNalHeaderExt->iNoInterLayerPredFlag) {1215
1216 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //slice_skip_flag1216 bSgChangeCycleInvolved = (pPps->uiNumSliceGroups > 1 && pPps->uiSliceGroupMapType >= 3
1217 pSliceHeadExt->bSliceSkipFlag = !!uiCode;1217 && pPps->uiSliceGroupMapType <= 5);
1218 if (pSliceHeadExt->bSliceSkipFlag) {1218 if (kbExtensionFlag && bSgChangeCycleInvolved)
1219 WelsLog (pLogCtx, WELS_LOG_WARNING, "bSliceSkipFlag == 1 not supported.");1219 bSgChangeCycleInvolved = (bSgChangeCycleInvolved && (uiQualityId == BASE_QUALITY_ID));
1220 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_SLICESKIP);1220 if (bSgChangeCycleInvolved) {
1221 } else {1221 if (pPps->uiSliceGroupChangeRate > 0) {
1222 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //adaptive_base_mode_flag1222 const int32_t kiNumBits = (int32_t)WELS_CEIL (log (static_cast<double> (1 + pPps->uiPicSizeInMapUnits /
1223 pSliceHeadExt->bAdaptiveBaseModeFlag = !!uiCode;1223 pPps->uiSliceGroupChangeRate)));
1224 if (!pSliceHeadExt->bAdaptiveBaseModeFlag) {1224 WELS_READ_VERIFY (BsGetBits (pBs, kiNumBits, &uiCode)); //lice_group_change_cycle
1225 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //default_base_mode_flag1225 pSliceHead->iSliceGroupChangeCycle = uiCode;
1226 pSliceHeadExt->bDefaultBaseModeFlag = !!uiCode;1226 } else
1227 }1227 pSliceHead->iSliceGroupChangeCycle = 0;
1228 if (!pSliceHeadExt->bDefaultBaseModeFlag) {1228 }
1229 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //adaptive_motion_prediction_flag1229
1230 pSliceHeadExt->bAdaptiveMotionPredFlag = !!uiCode;1230 if (!kbExtensionFlag) {
1231 if (!pSliceHeadExt->bAdaptiveMotionPredFlag) {1231 FillDefaultSliceHeaderExt (pSliceHeadExt, pNalHeaderExt);
1232 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //default_motion_prediction_flag1232 } else {
1233 pSliceHeadExt->bDefaultMotionPredFlag = !!uiCode;1233 /* Extra syntax elements newly introduced */
1234 }1234 pSliceHeadExt->pSubsetSps = pSubsetSps;
1235 }1235
1236 1236 if (!pNalHeaderExt->iNoInterLayerPredFlag && BASE_QUALITY_ID == uiQualityId) {
1237 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //adaptive_residual_prediction_flag1237 //the following should be deleted for CODE_CLEAN
1238 pSliceHeadExt->bAdaptiveResidualPredFlag = !!uiCode;1238 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //ref_layer_dq_id
1239 if (!pSliceHeadExt->bAdaptiveResidualPredFlag) {1239 pSliceHeadExt->uiRefLayerDqId = uiCode;
1240 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //default_residual_prediction_flag1240 if (pSubsetSps->sSpsSvcExt.bInterLayerDeblockingFilterCtrlPresentFlag) {
1241 pSliceHeadExt->bDefaultResidualPredFlag = !!uiCode;1241 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //disable_inter_layer_deblocking_filter_idc
1242 }1242 pSliceHeadExt->uiDisableInterLayerDeblockingFilterIdc = uiCode;
1243 }1243 //refer to JVT-X201wcm1.doc G.7.4.3.4--2010.4.20
1244 if (pSubsetSps->sSpsSvcExt.bAdaptiveTCoeffLevelPredFlag) {1244 if (pSliceHeadExt->uiDisableInterLayerDeblockingFilterIdc > 6) {
1245 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //tcoeff_level_prediction_flag1245 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "disable_inter_layer_deblock_filter_idc (%d) out of range [0, 6]",
1246 pSliceHeadExt->bTCoeffLevelPredFlag = !!uiCode;1246 pSliceHeadExt->uiDisableInterLayerDeblockingFilterIdc);
1247 }1247 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_DBLOCKING_IDC);
1248 }1248 }
1249 1249 if (pSliceHeadExt->uiDisableInterLayerDeblockingFilterIdc != 1) {
1250 if (!pSubsetSps->sSpsSvcExt.bSliceHeaderRestrictionFlag) {1250 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //inter_layer_slice_alpha_c0_offset_div2
1251 WELS_READ_VERIFY (BsGetBits (pBs, 4, &uiCode)); //scan_idx_start1251 pSliceHeadExt->iInterLayerSliceAlphaC0Offset = iCode * 2;
1252 pSliceHeadExt->uiScanIdxStart = uiCode;1252 WELS_CHECK_SE_BOTH_ERROR (pSliceHeadExt->iInterLayerSliceAlphaC0Offset,
1253 WELS_READ_VERIFY (BsGetBits (pBs, 4, &uiCode)); //scan_idx_end1253 SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MIN, SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MAX,
1254 pSliceHeadExt->uiScanIdxEnd = uiCode;1254 "inter_layer_alpha_c0_offset_div2 * 2", GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER,
1255 if (pSliceHeadExt->uiScanIdxStart != 0 || pSliceHeadExt->uiScanIdxEnd != 15) {1255 ERR_INFO_INVALID_SLICE_ALPHA_C0_OFFSET_DIV2));
1256 WelsLog (pLogCtx, WELS_LOG_WARNING, "uiScanIdxStart (%d) != 0 and uiScanIdxEnd (%d) !=15 not supported here",1256 WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //inter_layer_slice_beta_offset_div2
1257 pSliceHeadExt->uiScanIdxStart, pSliceHeadExt->uiScanIdxEnd);1257 pSliceHeadExt->iInterLayerSliceBetaOffset = iCode * 2;
1258 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_MGS);1258 WELS_CHECK_SE_BOTH_ERROR (pSliceHeadExt->iInterLayerSliceBetaOffset, SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MIN,
1259 }1259 SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MAX, "inter_layer_slice_beta_offset_div2 * 2",
1260 } else {1260 GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SLICE_BETA_OFFSET_DIV2));
1261 pSliceHeadExt->uiScanIdxStart = 0;1261 }
1262 pSliceHeadExt->uiScanIdxEnd = 15;1262 }
1263 }1263
1264 }1264 pSliceHeadExt->uiRefLayerChromaPhaseXPlus1Flag = pSubsetSps->sSpsSvcExt.uiSeqRefLayerChromaPhaseXPlus1Flag;
1265 1265 pSliceHeadExt->uiRefLayerChromaPhaseYPlus1 = pSubsetSps->sSpsSvcExt.uiSeqRefLayerChromaPhaseYPlus1;
1266 return ERR_NONE;1266
1267}1267 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //constrained_intra_resampling_flag
1268 1268 pSliceHeadExt->bConstrainedIntraResamplingFlag = !!uiCode;
1269/*1269
1270 * Copy relative syntax elements of NALUnitHeaderExt, sRefPicBaseMarking and bStoreRefBasePicFlag in prefix nal unit.1270 {
1271 * pSrc: mark as decoded prefix NAL1271 SPosOffset pos;
1272 * ppDst: succeeded VCL NAL based AVC (I/P Slice)1272 pos.iLeftOffset = pSubsetSps->sSpsSvcExt.sSeqScaledRefLayer.iLeftOffset;
1273 */1273 pos.iTopOffset = pSubsetSps->sSpsSvcExt.sSeqScaledRefLayer.iTopOffset * (2 - pSps->bFrameMbsOnlyFlag);
1274bool PrefetchNalHeaderExtSyntax (PWelsDecoderContext pCtx, PNalUnit const kppDst, PNalUnit const kpSrc) {1274 pos.iRightOffset = pSubsetSps->sSpsSvcExt.sSeqScaledRefLayer.iRightOffset;
1275 PNalUnitHeaderExt pNalHdrExtD = NULL, pNalHdrExtS = NULL;1275 pos.iBottomOffset = pSubsetSps->sSpsSvcExt.sSeqScaledRefLayer.iBottomOffset * (2 - pSps->bFrameMbsOnlyFlag);
1276 PSliceHeaderExt pShExtD = NULL;1276 //memcpy(&pSliceHeadExt->sScaledRefLayer, &pos, sizeof(SPosOffset));//confirmed_safe_unsafe_usage
1277 PPrefixNalUnit pPrefixS = NULL;1277 pSliceHeadExt->iScaledRefLayerPicWidthInSampleLuma = (pSliceHead->iMbWidth << 4) -
1278 PSps pSps = NULL;1278 (pos.iLeftOffset + pos.iRightOffset);
1279 int32_t iIdx = 0;1279 pSliceHeadExt->iScaledRefLayerPicHeightInSampleLuma = (pSliceHead->iMbHeight << 4) -
1280 1280 (pos.iTopOffset + pos.iBottomOffset) / (1 + pSliceHead->bFieldPicFlag);
1281 if (kppDst == NULL || kpSrc == NULL)1281 }
1282 return false;1282 } else if (uiQualityId > BASE_QUALITY_ID) {
1283 1283 WelsLog (pLogCtx, WELS_LOG_WARNING, "MGS not supported.");
1284 pNalHdrExtD = &kppDst->sNalHeaderExt;1284 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_MGS);
1285 pNalHdrExtS = &kpSrc->sNalHeaderExt;1285 } else {
1286 pShExtD = &kppDst->sNalData.sVclNal.sSliceHeaderExt;1286 pSliceHeadExt->uiRefLayerDqId = (uint8_t) - 1;
1287 pPrefixS = &kpSrc->sNalData.sPrefixNal;1287 }
1288 pSps = &pCtx->sSpsBuffer[pCtx->sPpsBuffer[pShExtD->sSliceHeader.iPpsId].iSpsId];1288
1289 1289 pSliceHeadExt->bSliceSkipFlag = false;
1290 pNalHdrExtD->uiDependencyId = pNalHdrExtS->uiDependencyId;1290 pSliceHeadExt->bAdaptiveBaseModeFlag = false;
1291 pNalHdrExtD->uiQualityId = pNalHdrExtS->uiQualityId;1291 pSliceHeadExt->bDefaultBaseModeFlag = false;
1292 pNalHdrExtD->uiTemporalId = pNalHdrExtS->uiTemporalId;1292 pSliceHeadExt->bAdaptiveMotionPredFlag = false;
1293 pNalHdrExtD->uiPriorityId = pNalHdrExtS->uiPriorityId;1293 pSliceHeadExt->bDefaultMotionPredFlag = false;
1294 pNalHdrExtD->bIdrFlag = pNalHdrExtS->bIdrFlag;1294 pSliceHeadExt->bAdaptiveResidualPredFlag = false;
1295 pNalHdrExtD->iNoInterLayerPredFlag = pNalHdrExtS->iNoInterLayerPredFlag;1295 pSliceHeadExt->bDefaultResidualPredFlag = false;
1296 pNalHdrExtD->bDiscardableFlag = pNalHdrExtS->bDiscardableFlag;1296 if (pNalHeaderExt->iNoInterLayerPredFlag)
1297 pNalHdrExtD->bOutputFlag = pNalHdrExtS->bOutputFlag;1297 pSliceHeadExt->bTCoeffLevelPredFlag = false;
1298 pNalHdrExtD->bUseRefBasePicFlag = pNalHdrExtS->bUseRefBasePicFlag;1298 else
1299 pNalHdrExtD->uiLayerDqId = pNalHdrExtS->uiLayerDqId;1299 pSliceHeadExt->bTCoeffLevelPredFlag = pSubsetSps->sSpsSvcExt.bSeqTCoeffLevelPredFlag;
1300 1300
1301 pShExtD->bStoreRefBasePicFlag = pPrefixS->bStoreRefBasePicFlag;1301 if (!pNalHeaderExt->iNoInterLayerPredFlag) {
1302 memcpy (&pShExtD->sRefBasePicMarking, &pPrefixS->sRefPicBaseMarking,1302 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //slice_skip_flag
1303 sizeof (SRefBasePicMarking)); //confirmed_safe_unsafe_usage1303 pSliceHeadExt->bSliceSkipFlag = !!uiCode;
1304 if (pShExtD->sRefBasePicMarking.bAdaptiveRefBasePicMarkingModeFlag) {1304 if (pSliceHeadExt->bSliceSkipFlag) {
1305 PRefBasePicMarking pRefBasePicMarking = &pShExtD->sRefBasePicMarking;1305 WelsLog (pLogCtx, WELS_LOG_WARNING, "bSliceSkipFlag == 1 not supported.");
1306 iIdx = 0;1306 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_SLICESKIP);
1307 do {1307 } else {
1308 if (pRefBasePicMarking->mmco_base[iIdx].uiMmcoType == MMCO_END)1308 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //adaptive_base_mode_flag
1309 break;1309 pSliceHeadExt->bAdaptiveBaseModeFlag = !!uiCode;
1310 if (pRefBasePicMarking->mmco_base[iIdx].uiMmcoType == MMCO_SHORT2UNUSED)1310 if (!pSliceHeadExt->bAdaptiveBaseModeFlag) {
1311 pRefBasePicMarking->mmco_base[iIdx].iShortFrameNum = (pShExtD->sSliceHeader.iFrameNum -1311 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //default_base_mode_flag
1312 pRefBasePicMarking->mmco_base[iIdx].uiDiffOfPicNums) & ((1 << pSps->uiLog2MaxFrameNum) - 1);1312 pSliceHeadExt->bDefaultBaseModeFlag = !!uiCode;
1313 ++ iIdx;1313 }
1314 } while (iIdx < MAX_MMCO_COUNT);1314 if (!pSliceHeadExt->bDefaultBaseModeFlag) {
1315 }1315 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //adaptive_motion_prediction_flag
1316 1316 pSliceHeadExt->bAdaptiveMotionPredFlag = !!uiCode;
1317 return true;1317 if (!pSliceHeadExt->bAdaptiveMotionPredFlag) {
1318}1318 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //default_motion_prediction_flag
1319 1319 pSliceHeadExt->bDefaultMotionPredFlag = !!uiCode;
1320 1320 }
1321 1321 }
1322int32_t UpdateAccessUnit (PWelsDecoderContext pCtx) {1322
1323 PAccessUnit pCurAu = pCtx->pAccessUnitList;1323 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //adaptive_residual_prediction_flag
1324 int32_t iIdx = pCurAu->uiEndPos;1324 pSliceHeadExt->bAdaptiveResidualPredFlag = !!uiCode;
1325 1325 if (!pSliceHeadExt->bAdaptiveResidualPredFlag) {
1326 // Conversed iterator1326 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //default_residual_prediction_flag
1327 pCtx->uiTargetDqId = pCurAu->pNalUnitsList[iIdx]->sNalHeaderExt.uiLayerDqId;1327 pSliceHeadExt->bDefaultResidualPredFlag = !!uiCode;
1328 pCurAu->uiActualUnitsNum = iIdx + 1;1328 }
1329 pCurAu->bCompletedAuFlag = true;1329 }
1330 1330 if (pSubsetSps->sSpsSvcExt.bAdaptiveTCoeffLevelPredFlag) {
1331 // Added for mosaic avoidance, 11/19/20091331 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //tcoeff_level_prediction_flag
1332#ifdef LONG_TERM_REF1332 pSliceHeadExt->bTCoeffLevelPredFlag = !!uiCode;
1333 if (pCtx->bParamSetsLostFlag || pCtx->bNewSeqBegin)1333 }
1334#else1334 }
1335 if (pCtx->bReferenceLostAtT0Flag || pCtx->bNewSeqBegin)1335
1336#endif1336 if (!pSubsetSps->sSpsSvcExt.bSliceHeaderRestrictionFlag) {
1337 {1337 WELS_READ_VERIFY (BsGetBits (pBs, 4, &uiCode)); //scan_idx_start
1338 uint32_t uiActualIdx = 0;1338 pSliceHeadExt->uiScanIdxStart = uiCode;
1339 while (uiActualIdx < pCurAu->uiActualUnitsNum) {1339 WELS_READ_VERIFY (BsGetBits (pBs, 4, &uiCode)); //scan_idx_end
1340 PNalUnit nal = pCurAu->pNalUnitsList[uiActualIdx];1340 pSliceHeadExt->uiScanIdxEnd = uiCode;
1341 1341 if (pSliceHeadExt->uiScanIdxStart != 0 || pSliceHeadExt->uiScanIdxEnd != 15) {
1342 if (nal->sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR || nal->sNalHeaderExt.bIdrFlag) {1342 WelsLog (pLogCtx, WELS_LOG_WARNING, "uiScanIdxStart (%d) != 0 and uiScanIdxEnd (%d) !=15 not supported here",
1343 break;1343 pSliceHeadExt->uiScanIdxStart, pSliceHeadExt->uiScanIdxEnd);
1344 }1344 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_MGS);
1345 ++ uiActualIdx;1345 }
1346 }1346 } else {
1347 if (uiActualIdx ==1347 pSliceHeadExt->uiScanIdxStart = 0;
1348 pCurAu->uiActualUnitsNum) { // no found IDR nal within incoming AU, need exit to avoid mosaic issue, 11/19/20091348 pSliceHeadExt->uiScanIdxEnd = 15;
1349 1349 }
1350 pCtx->sDecoderStatistics.uiIDRLostNum++;1350 }
1351 if (!pCtx->bParamSetsLostFlag)1351
1352 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,1352 return ERR_NONE;
1353 "UpdateAccessUnit():::::Key frame lost.....CAN NOT find IDR from current AU.");1353}
1354 pCtx->iErrorCode |= dsRefLost;1354
1355 if (pCtx->pParam->eEcActiveIdc == ERROR_CON_DISABLE) {1355/*
1356#ifdef LONG_TERM_REF1356 * Copy relative syntax elements of NALUnitHeaderExt, sRefPicBaseMarking and bStoreRefBasePicFlag in prefix nal unit.
1357 pCtx->iErrorCode |= dsNoParamSets;1357 * pSrc: mark as decoded prefix NAL
1358 return dsNoParamSets;1358 * ppDst: succeeded VCL NAL based AVC (I/P Slice)
1359#else1359 */
1360 pCtx->iErrorCode |= dsRefLost;1360bool PrefetchNalHeaderExtSyntax (PWelsDecoderContext pCtx, PNalUnit const kppDst, PNalUnit const kpSrc) {
1361 return ERR_INFO_REFERENCE_PIC_LOST;1361 PNalUnitHeaderExt pNalHdrExtD = NULL, pNalHdrExtS = NULL;
1362#endif1362 PSliceHeaderExt pShExtD = NULL;
1363 }1363 PPrefixNalUnit pPrefixS = NULL;
1364 }1364 PSps pSps = NULL;
1365 }1365 int32_t iIdx = 0;
1366 1366
1367 return ERR_NONE;1367 if (kppDst == NULL || kpSrc == NULL)
1368}1368 return false;
1369 1369
1370int32_t InitialDqLayersContext (PWelsDecoderContext pCtx, const int32_t kiMaxWidth, const int32_t kiMaxHeight) {1370 pNalHdrExtD = &kppDst->sNalHeaderExt;
1371 int32_t i = 0;1371 pNalHdrExtS = &kpSrc->sNalHeaderExt;
1372 1372 pShExtD = &kppDst->sNalData.sVclNal.sSliceHeaderExt;
1373 WELS_VERIFY_RETURN_IF (ERR_INFO_INVALID_PARAM, (NULL == pCtx || kiMaxWidth <= 0 || kiMaxHeight <= 0))1373 pPrefixS = &kpSrc->sNalData.sPrefixNal;
1374 pCtx->sMb.iMbWidth = (kiMaxWidth + 15) >> 4;1374 pSps = &pCtx->sSpsBuffer[pCtx->sPpsBuffer[pShExtD->sSliceHeader.iPpsId].iSpsId];
1375 pCtx->sMb.iMbHeight = (kiMaxHeight + 15) >> 4;1375
1376 1376 pNalHdrExtD->uiDependencyId = pNalHdrExtS->uiDependencyId;
1377 if (pCtx->bInitialDqLayersMem && kiMaxWidth <= pCtx->iPicWidthReq1377 pNalHdrExtD->uiQualityId = pNalHdrExtS->uiQualityId;
1378 && kiMaxHeight <= pCtx->iPicHeightReq) // have same dimension memory, skipped1378 pNalHdrExtD->uiTemporalId = pNalHdrExtS->uiTemporalId;
1379 return ERR_NONE;1379 pNalHdrExtD->uiPriorityId = pNalHdrExtS->uiPriorityId;
1380 1380 pNalHdrExtD->bIdrFlag = pNalHdrExtS->bIdrFlag;
1381 CMemoryAlign* pMa = pCtx->pMemAlign;1381 pNalHdrExtD->iNoInterLayerPredFlag = pNalHdrExtS->iNoInterLayerPredFlag;
1382 1382 pNalHdrExtD->bDiscardableFlag = pNalHdrExtS->bDiscardableFlag;
1383 UninitialDqLayersContext (pCtx);1383 pNalHdrExtD->bOutputFlag = pNalHdrExtS->bOutputFlag;
1384 1384 pNalHdrExtD->bUseRefBasePicFlag = pNalHdrExtS->bUseRefBasePicFlag;
1385 do {1385 pNalHdrExtD->uiLayerDqId = pNalHdrExtS->uiLayerDqId;
1386 PDqLayer pDq = (PDqLayer)pMa->WelsMallocz (sizeof (SDqLayer), "PDqLayer");1386
1387 1387 pShExtD->bStoreRefBasePicFlag = pPrefixS->bStoreRefBasePicFlag;
1388 if (pDq == NULL)1388 memcpy (&pShExtD->sRefBasePicMarking, &pPrefixS->sRefPicBaseMarking,
1389 return ERR_INFO_OUT_OF_MEMORY;1389 sizeof (SRefBasePicMarking)); //confirmed_safe_unsafe_usage
1390 1390 if (pShExtD->sRefBasePicMarking.bAdaptiveRefBasePicMarkingModeFlag) {
1391 pCtx->pDqLayersList[i] = pDq; //to keep consistence with in UninitialDqLayersContext()1391 PRefBasePicMarking pRefBasePicMarking = &pShExtD->sRefBasePicMarking;
1392 memset (pDq, 0, sizeof (SDqLayer));1392 iIdx = 0;
1393 1393 do {
1394 pCtx->sMb.pMbType[i] = (int16_t*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int16_t),1394 if (pRefBasePicMarking->mmco_base[iIdx].uiMmcoType == MMCO_END)
1395 "pCtx->sMb.pMbType[]");1395 break;
1396 pCtx->sMb.pMv[i][0] = (int16_t (*)[16][2])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (1396 if (pRefBasePicMarking->mmco_base[iIdx].uiMmcoType == MMCO_SHORT2UNUSED)
1397 int16_t) * MV_A * MB_BLOCK4x4_NUM, "pCtx->sMb.pMv[][]");1397 pRefBasePicMarking->mmco_base[iIdx].iShortFrameNum = (pShExtD->sSliceHeader.iFrameNum -
1398 pCtx->sMb.pRefIndex[i][0] = (int8_t (*)[MB_BLOCK4x4_NUM])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight *1398 pRefBasePicMarking->mmco_base[iIdx].uiDiffOfPicNums) & ((1 << pSps->uiLog2MaxFrameNum) - 1);
1399 sizeof (1399 ++ iIdx;
1400 int8_t) * MB_BLOCK4x4_NUM, "pCtx->sMb.pRefIndex[][]");1400 } while (iIdx < MAX_MMCO_COUNT);
1401 pCtx->sMb.pLumaQp[i] = (int8_t*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),1401 }
1402 "pCtx->sMb.pLumaQp[]");1402
1403 pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[i] = (bool*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight *1403 return true;
1404 sizeof (1404}
1405 bool),1405
1406 "pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[]");1406
1407 pCtx->sMb.pTransformSize8x8Flag[i] = (bool*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (bool),1407
1408 "pCtx->sMb.pTransformSize8x8Flag[]");1408int32_t UpdateAccessUnit (PWelsDecoderContext pCtx) {
1409 pCtx->sMb.pChromaQp[i] = (int8_t (*)[2])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (1409 PAccessUnit pCurAu = pCtx->pAccessUnitList;
1410 int8_t) * 2,1410 int32_t iIdx = pCurAu->uiEndPos;
1411 "pCtx->sMb.pChromaQp[]");1411
1412 pCtx->sMb.pMvd[i][0] = (int16_t (*)[16][2])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (1412 // Conversed iterator
1413 int16_t) * MV_A * MB_BLOCK4x4_NUM, "pCtx->sMb.pMvd[][]");1413 pCtx->uiTargetDqId = pCurAu->pNalUnitsList[iIdx]->sNalHeaderExt.uiLayerDqId;
1414 pCtx->sMb.pCbfDc[i] = (uint16_t*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (uint16_t),1414 pCurAu->uiActualUnitsNum = iIdx + 1;
1415 "pCtx->sMb.pCbfDc[]");1415 pCurAu->bCompletedAuFlag = true;
1416 pCtx->sMb.pNzc[i] = (int8_t (*)[24])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t) * 24,1416
1417 "pCtx->sMb.pNzc[]");1417 // Added for mosaic avoidance, 11/19/2009
1418 pCtx->sMb.pNzcRs[i] = (int8_t (*)[24])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t) * 24,1418#ifdef LONG_TERM_REF
1419 "pCtx->sMb.pNzcRs[]");1419 if (pCtx->bParamSetsLostFlag || pCtx->bNewSeqBegin)
1420 pCtx->sMb.pScaledTCoeff[i] = (int16_t (*)[MB_COEFF_LIST_SIZE])pMa->WelsMallocz (pCtx->sMb.iMbWidth *1420#else
1421 pCtx->sMb.iMbHeight *1421 if (pCtx->bReferenceLostAtT0Flag || pCtx->bNewSeqBegin)
1422 sizeof (int16_t) * MB_COEFF_LIST_SIZE, "pCtx->sMb.pScaledTCoeff[]");1422#endif
1423 pCtx->sMb.pIntraPredMode[i] = (int8_t (*)[8])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (1423 {
1424 int8_t) * 8,1424 uint32_t uiActualIdx = 0;
1425 "pCtx->sMb.pIntraPredMode[]");1425 while (uiActualIdx < pCurAu->uiActualUnitsNum) {
1426 pCtx->sMb.pIntra4x4FinalMode[i] = (int8_t (*)[MB_BLOCK4x4_NUM])pMa->WelsMallocz (pCtx->sMb.iMbWidth *1426 PNalUnit nal = pCurAu->pNalUnitsList[uiActualIdx];
1427 pCtx->sMb.iMbHeight *1427
1428 sizeof (int8_t) * MB_BLOCK4x4_NUM, "pCtx->sMb.pIntra4x4FinalMode[]");1428 if (nal->sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR || nal->sNalHeaderExt.bIdrFlag) {
1429 pCtx->sMb.pIntraNxNAvailFlag[i] = (uint8_t (*))pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (1429 break;
1430 int8_t),1430 }
1431 "pCtx->sMb.pIntraNxNAvailFlag");1431 ++ uiActualIdx;
1432 pCtx->sMb.pChromaPredMode[i] = (int8_t*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),1432 }
1433 "pCtx->sMb.pChromaPredMode[]");1433 if (uiActualIdx ==
1434 pCtx->sMb.pCbp[i] = (int8_t*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),1434 pCurAu->uiActualUnitsNum) { // no found IDR nal within incoming AU, need exit to avoid mosaic issue, 11/19/2009
1435 "pCtx->sMb.pCbp[]");1435
1436 pCtx->sMb.pSubMbType[i] = (int8_t (*)[MB_PARTITION_SIZE])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight *1436 pCtx->sDecoderStatistics.uiIDRLostNum++;
1437 sizeof (1437 if (!pCtx->bParamSetsLostFlag)
1438 int8_t) * MB_PARTITION_SIZE, "pCtx->sMb.pSubMbType[]");1438 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
1439 pCtx->sMb.pSliceIdc[i] = (int32_t*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t),1439 "UpdateAccessUnit():::::Key frame lost.....CAN NOT find IDR from current AU.");
1440 "pCtx->sMb.pSliceIdc[]"); // using int32_t for slice_idc, 4/21/20101440 pCtx->iErrorCode |= dsRefLost;
1441 pCtx->sMb.pResidualPredFlag[i] = (int8_t*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),1441 if (pCtx->pParam->eEcActiveIdc == ERROR_CON_DISABLE) {
1442 "pCtx->sMb.pResidualPredFlag[]");1442#ifdef LONG_TERM_REF
1443 pCtx->sMb.pInterPredictionDoneFlag[i] = (int8_t*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (1443 pCtx->iErrorCode |= dsNoParamSets;
1444 int8_t), "pCtx->sMb.pInterPredictionDoneFlag[]");1444 return dsNoParamSets;
1445 1445#else
1446 pCtx->sMb.pMbCorrectlyDecodedFlag[i] = (bool*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (1446 pCtx->iErrorCode |= dsRefLost;
1447 bool),1447 return ERR_INFO_REFERENCE_PIC_LOST;
1448 "pCtx->sMb.pMbCorrectlyDecodedFlag[]");1448#endif
1449 pCtx->sMb.pMbRefConcealedFlag[i] = (bool*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (bool),1449 }
1450 "pCtx->pMbRefConcealedFlag[]");1450 }
1451 1451 }
1452 // check memory block valid due above allocated..1452
1453 WELS_VERIFY_RETURN_IF (ERR_INFO_OUT_OF_MEMORY,1453 return ERR_NONE;
1454 ((NULL == pCtx->sMb.pMbType[i]) ||1454}
1455 (NULL == pCtx->sMb.pMv[i][0]) ||1455
1456 (NULL == pCtx->sMb.pRefIndex[i][0]) ||1456int32_t InitialDqLayersContext (PWelsDecoderContext pCtx, const int32_t kiMaxWidth, const int32_t kiMaxHeight) {
1457 (NULL == pCtx->sMb.pLumaQp[i]) ||1457 int32_t i = 0;
1458 (NULL == pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[i]) ||1458
1459 (NULL == pCtx->sMb.pTransformSize8x8Flag[i]) ||1459 WELS_VERIFY_RETURN_IF (ERR_INFO_INVALID_PARAM, (NULL == pCtx || kiMaxWidth <= 0 || kiMaxHeight <= 0))
1460 (NULL == pCtx->sMb.pChromaQp[i]) ||1460 pCtx->sMb.iMbWidth = (kiMaxWidth + 15) >> 4;
1461 (NULL == pCtx->sMb.pMvd[i][0]) ||1461 pCtx->sMb.iMbHeight = (kiMaxHeight + 15) >> 4;
1462 (NULL == pCtx->sMb.pCbfDc[i]) ||1462
1463 (NULL == pCtx->sMb.pNzc[i]) ||1463 if (pCtx->bInitialDqLayersMem && kiMaxWidth <= pCtx->iPicWidthReq
1464 (NULL == pCtx->sMb.pNzcRs[i]) ||1464 && kiMaxHeight <= pCtx->iPicHeightReq) // have same dimension memory, skipped
1465 (NULL == pCtx->sMb.pScaledTCoeff[i]) ||1465 return ERR_NONE;
1466 (NULL == pCtx->sMb.pIntraPredMode[i]) ||1466
1467 (NULL == pCtx->sMb.pIntra4x4FinalMode[i]) ||1467 CMemoryAlign* pMa = pCtx->pMemAlign;
1468 (NULL == pCtx->sMb.pIntraNxNAvailFlag[i]) ||1468
1469 (NULL == pCtx->sMb.pChromaPredMode[i]) ||1469 UninitialDqLayersContext (pCtx);
1470 (NULL == pCtx->sMb.pCbp[i]) ||1470
1471 (NULL == pCtx->sMb.pSubMbType[i]) ||1471 do {
1472 (NULL == pCtx->sMb.pSliceIdc[i]) ||1472 PDqLayer pDq = (PDqLayer)pMa->WelsMallocz (sizeof (SDqLayer), "PDqLayer");
1473 (NULL == pCtx->sMb.pResidualPredFlag[i]) ||1473
1474 (NULL == pCtx->sMb.pInterPredictionDoneFlag[i]) ||1474 if (pDq == NULL)
1475 (NULL == pCtx->sMb.pMbRefConcealedFlag[i]) ||1475 return ERR_INFO_OUT_OF_MEMORY;
1476 (NULL == pCtx->sMb.pMbCorrectlyDecodedFlag[i])1476
1477 )1477 pCtx->pDqLayersList[i] = pDq; //to keep consistence with in UninitialDqLayersContext()
1478 )1478 memset (pDq, 0, sizeof (SDqLayer));
1479 1479
1480 memset (pCtx->sMb.pSliceIdc[i], 0xff, (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t)));1480 pCtx->sMb.pMbType[i] = (uint32_t*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (uint32_t),
1481 1481 "pCtx->sMb.pMbType[]");
1482 ++ i;1482 pCtx->sMb.pMv[i][LIST_0] = (int16_t (*)[16][2])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
1483 } while (i < LAYER_NUM_EXCHANGEABLE);1483 int16_t) * MV_A * MB_BLOCK4x4_NUM, "pCtx->sMb.pMv[][]");
1484 1484 pCtx->sMb.pMv[i][LIST_1] = (int16_t (*)[16][2])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
1485 pCtx->bInitialDqLayersMem = true;1485 int16_t) * MV_A * MB_BLOCK4x4_NUM, "pCtx->sMb.pMv[][]");
1486 pCtx->iPicWidthReq = kiMaxWidth;1486
1487 pCtx->iPicHeightReq = kiMaxHeight;1487 pCtx->sMb.pRefIndex[i][LIST_0] = (int8_t (*)[MB_BLOCK4x4_NUM])pMa->WelsMallocz (pCtx->sMb.iMbWidth *
1488 1488 pCtx->sMb.iMbHeight *
1489 return ERR_NONE;1489 sizeof (
1490}1490 int8_t) * MB_BLOCK4x4_NUM, "pCtx->sMb.pRefIndex[][]");
1491 1491 pCtx->sMb.pRefIndex[i][LIST_1] = (int8_t (*)[MB_BLOCK4x4_NUM])pMa->WelsMallocz (pCtx->sMb.iMbWidth *
1492void UninitialDqLayersContext (PWelsDecoderContext pCtx) {1492 pCtx->sMb.iMbHeight *
1493 int32_t i = 0;1493 sizeof (
1494 CMemoryAlign* pMa = pCtx->pMemAlign;1494 int8_t) * MB_BLOCK4x4_NUM, "pCtx->sMb.pRefIndex[][]");
1495 1495 pCtx->sMb.pDirect[i] = (int8_t (*)[MB_BLOCK4x4_NUM])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight *
1496 do {1496 sizeof (
1497 PDqLayer pDq = pCtx->pDqLayersList[i];1497 int8_t) * MB_BLOCK4x4_NUM, "pCtx->sMb.pDirect[]");
1498 if (pDq == NULL) {1498 pCtx->sMb.pLumaQp[i] = (int8_t*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
1499 ++ i;1499 "pCtx->sMb.pLumaQp[]");
1500 continue;1500 pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[i] = (bool*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight *
1501 }1501 sizeof (
1502 1502 bool),
1503 if (pCtx->sMb.pMbType[i]) {1503 "pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[]");
1504 pMa->WelsFree (pCtx->sMb.pMbType[i], "pCtx->sMb.pMbType[]");1504 pCtx->sMb.pTransformSize8x8Flag[i] = (bool*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (bool),
1505 1505 "pCtx->sMb.pTransformSize8x8Flag[]");
1506 pCtx->sMb.pMbType[i] = NULL;1506 pCtx->sMb.pChromaQp[i] = (int8_t (*)[2])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
1507 }1507 int8_t) * 2,
1508 1508 "pCtx->sMb.pChromaQp[]");
1509 if (pCtx->sMb.pMv[i][0]) {1509 pCtx->sMb.pMvd[i][LIST_0] = (int16_t (*)[16][2])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
1510 pMa->WelsFree (pCtx->sMb.pMv[i][0], "pCtx->sMb.pMv[][]");1510 int16_t) * MV_A * MB_BLOCK4x4_NUM, "pCtx->sMb.pMvd[][]");
1511 1511 pCtx->sMb.pMvd[i][LIST_1] = (int16_t (*)[16][2])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
1512 pCtx->sMb.pMv[i][0] = NULL;1512 int16_t) * MV_A * MB_BLOCK4x4_NUM, "pCtx->sMb.pMvd[][]");
1513 }1513 pCtx->sMb.pCbfDc[i] = (uint16_t*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (uint16_t),
1514 1514 "pCtx->sMb.pCbfDc[]");
1515 if (pCtx->sMb.pRefIndex[i][0]) {1515 pCtx->sMb.pNzc[i] = (int8_t (*)[24])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t) * 24,
1516 pMa->WelsFree (pCtx->sMb.pRefIndex[i][0], "pCtx->sMb.pRefIndex[][]");1516 "pCtx->sMb.pNzc[]");
1517 1517 pCtx->sMb.pNzcRs[i] = (int8_t (*)[24])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t) * 24,
1518 pCtx->sMb.pRefIndex[i][0] = NULL;1518 "pCtx->sMb.pNzcRs[]");
1519 }1519 pCtx->sMb.pScaledTCoeff[i] = (int16_t (*)[MB_COEFF_LIST_SIZE])pMa->WelsMallocz (pCtx->sMb.iMbWidth *
1520 1520 pCtx->sMb.iMbHeight *
1521 if (pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[i]) {1521 sizeof (int16_t) * MB_COEFF_LIST_SIZE, "pCtx->sMb.pScaledTCoeff[]");
1522 pMa->WelsFree (pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[i], "pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[]");1522 pCtx->sMb.pIntraPredMode[i] = (int8_t (*)[8])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
1523 1523 int8_t) * 8,
1524 pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[i] = NULL;1524 "pCtx->sMb.pIntraPredMode[]");
1525 }1525 pCtx->sMb.pIntra4x4FinalMode[i] = (int8_t (*)[MB_BLOCK4x4_NUM])pMa->WelsMallocz (pCtx->sMb.iMbWidth *
1526 1526 pCtx->sMb.iMbHeight *
1527 if (pCtx->sMb.pTransformSize8x8Flag[i]) {1527 sizeof (int8_t) * MB_BLOCK4x4_NUM, "pCtx->sMb.pIntra4x4FinalMode[]");
1528 pMa->WelsFree (pCtx->sMb.pTransformSize8x8Flag[i], "pCtx->sMb.pTransformSize8x8Flag[]");1528 pCtx->sMb.pIntraNxNAvailFlag[i] = (uint8_t (*))pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
1529 1529 int8_t),
1530 pCtx->sMb.pTransformSize8x8Flag[i] = NULL;1530 "pCtx->sMb.pIntraNxNAvailFlag");
1531 }1531 pCtx->sMb.pChromaPredMode[i] = (int8_t*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
1532 1532 "pCtx->sMb.pChromaPredMode[]");
1533 if (pCtx->sMb.pLumaQp[i]) {1533 pCtx->sMb.pCbp[i] = (int8_t*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
1534 pMa->WelsFree (pCtx->sMb.pLumaQp[i], "pCtx->sMb.pLumaQp[]");1534 "pCtx->sMb.pCbp[]");
1535 1535 pCtx->sMb.pSubMbType[i] = (uint32_t (*)[MB_PARTITION_SIZE])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight *
1536 pCtx->sMb.pLumaQp[i] = NULL;1536 sizeof (
1537 }1537 uint32_t) * MB_PARTITION_SIZE, "pCtx->sMb.pSubMbType[]");
1538 1538 pCtx->sMb.pSliceIdc[i] = (int32_t*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t),
1539 if (pCtx->sMb.pChromaQp[i]) {1539 "pCtx->sMb.pSliceIdc[]"); // using int32_t for slice_idc, 4/21/2010
1540 pMa->WelsFree (pCtx->sMb.pChromaQp[i], "pCtx->sMb.pChromaQp[]");1540 pCtx->sMb.pResidualPredFlag[i] = (int8_t*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
1541 1541 "pCtx->sMb.pResidualPredFlag[]");
1542 pCtx->sMb.pChromaQp[i] = NULL;1542 pCtx->sMb.pInterPredictionDoneFlag[i] = (int8_t*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
1543 }1543 int8_t), "pCtx->sMb.pInterPredictionDoneFlag[]");
1544 1544
1545 if (pCtx->sMb.pMvd[i][0]) {1545 pCtx->sMb.pMbCorrectlyDecodedFlag[i] = (bool*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
1546 pMa->WelsFree (pCtx->sMb.pMvd[i][0], "pCtx->sMb.pMvd[][]");1546 bool),
1547 pCtx->sMb.pMvd[i][0] = NULL;1547 "pCtx->sMb.pMbCorrectlyDecodedFlag[]");
1548 }1548 pCtx->sMb.pMbRefConcealedFlag[i] = (bool*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (bool),
1549 1549 "pCtx->pMbRefConcealedFlag[]");
1550 if (pCtx->sMb.pCbfDc[i]) {1550
1551 pMa->WelsFree (pCtx->sMb.pCbfDc[i], "pCtx->sMb.pCbfDc[]");1551 // check memory block valid due above allocated..
1552 pCtx->sMb.pCbfDc[i] = NULL;1552 WELS_VERIFY_RETURN_IF (ERR_INFO_OUT_OF_MEMORY,
1553 }1553 ((NULL == pCtx->sMb.pMbType[i]) ||
1554 1554 (NULL == pCtx->sMb.pMv[i][LIST_0]) ||
1555 if (pCtx->sMb.pNzc[i]) {1555 (NULL == pCtx->sMb.pMv[i][LIST_1]) ||
1556 pMa->WelsFree (pCtx->sMb.pNzc[i], "pCtx->sMb.pNzc[]");1556 (NULL == pCtx->sMb.pRefIndex[i][LIST_0]) ||
1557 1557 (NULL == pCtx->sMb.pRefIndex[i][LIST_1]) ||
1558 pCtx->sMb.pNzc[i] = NULL;1558 (NULL == pCtx->sMb.pDirect[i]) ||
1559 }1559 (NULL == pCtx->sMb.pLumaQp[i]) ||
1560 1560 (NULL == pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[i]) ||
1561 if (pCtx->sMb.pNzcRs[i]) {1561 (NULL == pCtx->sMb.pTransformSize8x8Flag[i]) ||
1562 pMa->WelsFree (pCtx->sMb.pNzcRs[i], "pCtx->sMb.pNzcRs[]");1562 (NULL == pCtx->sMb.pChromaQp[i]) ||
1563 1563 (NULL == pCtx->sMb.pMvd[i][LIST_0]) ||
1564 pCtx->sMb.pNzcRs[i] = NULL;1564 (NULL == pCtx->sMb.pMvd[i][LIST_1]) ||
1565 }1565 (NULL == pCtx->sMb.pCbfDc[i]) ||
1566 1566 (NULL == pCtx->sMb.pNzc[i]) ||
1567 if (pCtx->sMb.pScaledTCoeff[i]) {1567 (NULL == pCtx->sMb.pNzcRs[i]) ||
1568 pMa->WelsFree (pCtx->sMb.pScaledTCoeff[i], "pCtx->sMb.pScaledTCoeff[]");1568 (NULL == pCtx->sMb.pScaledTCoeff[i]) ||
1569 1569 (NULL == pCtx->sMb.pIntraPredMode[i]) ||
1570 pCtx->sMb.pScaledTCoeff[i] = NULL;1570 (NULL == pCtx->sMb.pIntra4x4FinalMode[i]) ||
1571 }1571 (NULL == pCtx->sMb.pIntraNxNAvailFlag[i]) ||
1572 1572 (NULL == pCtx->sMb.pChromaPredMode[i]) ||
1573 if (pCtx->sMb.pIntraPredMode[i]) {1573 (NULL == pCtx->sMb.pCbp[i]) ||
1574 pMa->WelsFree (pCtx->sMb.pIntraPredMode[i], "pCtx->sMb.pIntraPredMode[]");1574 (NULL == pCtx->sMb.pSubMbType[i]) ||
1575 1575 (NULL == pCtx->sMb.pSliceIdc[i]) ||
1576 pCtx->sMb.pIntraPredMode[i] = NULL;1576 (NULL == pCtx->sMb.pResidualPredFlag[i]) ||
1577 }1577 (NULL == pCtx->sMb.pInterPredictionDoneFlag[i]) ||
1578 1578 (NULL == pCtx->sMb.pMbRefConcealedFlag[i]) ||
1579 if (pCtx->sMb.pIntra4x4FinalMode[i]) {1579 (NULL == pCtx->sMb.pMbCorrectlyDecodedFlag[i])
1580 pMa->WelsFree (pCtx->sMb.pIntra4x4FinalMode[i], "pCtx->sMb.pIntra4x4FinalMode[]");1580 )
1581 1581 )
1582 pCtx->sMb.pIntra4x4FinalMode[i] = NULL;1582
1583 }1583 memset (pCtx->sMb.pSliceIdc[i], 0xff, (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t)));
1584 1584
1585 if (pCtx->sMb.pIntraNxNAvailFlag[i]) {1585 ++ i;
1586 pMa->WelsFree (pCtx->sMb.pIntraNxNAvailFlag[i], "pCtx->sMb.pIntraNxNAvailFlag");1586 } while (i < LAYER_NUM_EXCHANGEABLE);
1587 1587
1588 pCtx->sMb.pIntraNxNAvailFlag[i] = NULL;1588 pCtx->bInitialDqLayersMem = true;
1589 }1589 pCtx->iPicWidthReq = kiMaxWidth;
1590 1590 pCtx->iPicHeightReq = kiMaxHeight;
1591 if (pCtx->sMb.pChromaPredMode[i]) {1591
1592 pMa->WelsFree (pCtx->sMb.pChromaPredMode[i], "pCtx->sMb.pChromaPredMode[]");1592 return ERR_NONE;
1593 1593}
1594 pCtx->sMb.pChromaPredMode[i] = NULL;1594
1595 }1595void UninitialDqLayersContext (PWelsDecoderContext pCtx) {
1596 1596 int32_t i = 0;
1597 if (pCtx->sMb.pCbp[i]) {1597 CMemoryAlign* pMa = pCtx->pMemAlign;
1598 pMa->WelsFree (pCtx->sMb.pCbp[i], "pCtx->sMb.pCbp[]");1598
1599 1599 do {
1600 pCtx->sMb.pCbp[i] = NULL;1600 PDqLayer pDq = pCtx->pDqLayersList[i];
1601 }1601 if (pDq == NULL) {
1602 1602 ++ i;
1603 // if (pCtx->sMb.pMotionPredFlag[i])1603 continue;
1604 //{1604 }
1605 // pMa->WelsFree( pCtx->sMb.pMotionPredFlag[i], "pCtx->sMb.pMotionPredFlag[]" );1605
1606 1606 if (pCtx->sMb.pMbType[i]) {
1607 // pCtx->sMb.pMotionPredFlag[i] = NULL;1607 pMa->WelsFree (pCtx->sMb.pMbType[i], "pCtx->sMb.pMbType[]");
1608 //}1608
1609 1609 pCtx->sMb.pMbType[i] = NULL;
1610 if (pCtx->sMb.pSubMbType[i]) {1610 }
1611 pMa->WelsFree (pCtx->sMb.pSubMbType[i], "pCtx->sMb.pSubMbType[]");1611
1612 1612 for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
1613 pCtx->sMb.pSubMbType[i] = NULL;1613 if (pCtx->sMb.pMv[i][listIdx]) {
1614 }1614 pMa->WelsFree (pCtx->sMb.pMv[i][listIdx], "pCtx->sMb.pMv[][]");
1615 1615 pCtx->sMb.pMv[i][listIdx] = NULL;
1616 if (pCtx->sMb.pSliceIdc[i]) {1616 }
1617 pMa->WelsFree (pCtx->sMb.pSliceIdc[i], "pCtx->sMb.pSliceIdc[]");1617
1618 1618 if (pCtx->sMb.pRefIndex[i][listIdx]) {
1619 pCtx->sMb.pSliceIdc[i] = NULL;1619 pMa->WelsFree (pCtx->sMb.pRefIndex[i][listIdx], "pCtx->sMb.pRefIndex[][]");
1620 }1620 pCtx->sMb.pRefIndex[i][listIdx] = NULL;
1621 1621 }
1622 if (pCtx->sMb.pResidualPredFlag[i]) {1622
1623 pMa->WelsFree (pCtx->sMb.pResidualPredFlag[i], "pCtx->sMb.pResidualPredFlag[]");1623 if (pCtx->sMb.pDirect[i]) {
1624 1624 pMa->WelsFree (pCtx->sMb.pDirect[i], "pCtx->sMb.pDirect[]");
1625 pCtx->sMb.pResidualPredFlag[i] = NULL;1625 pCtx->sMb.pDirect[i] = NULL;
1626 }1626 }
1627 1627
1628 if (pCtx->sMb.pInterPredictionDoneFlag[i]) {1628 if (pCtx->sMb.pMvd[i][listIdx]) {
1629 pMa->WelsFree (pCtx->sMb.pInterPredictionDoneFlag[i], "pCtx->sMb.pInterPredictionDoneFlag[]");1629 pMa->WelsFree (pCtx->sMb.pMvd[i][listIdx], "pCtx->sMb.pMvd[][]");
1630 1630 pCtx->sMb.pMvd[i][listIdx] = NULL;
1631 pCtx->sMb.pInterPredictionDoneFlag[i] = NULL;1631 }
1632 }1632 }
1633 1633
1634 if (pCtx->sMb.pMbCorrectlyDecodedFlag[i]) {1634 if (pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[i]) {
1635 pMa->WelsFree (pCtx->sMb.pMbCorrectlyDecodedFlag[i], "pCtx->sMb.pMbCorrectlyDecodedFlag[]");1635 pMa->WelsFree (pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[i], "pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[]");
1636 pCtx->sMb.pMbCorrectlyDecodedFlag[i] = NULL;1636
1637 }1637 pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[i] = NULL;
1638 1638 }
1639 if (pCtx->sMb.pMbRefConcealedFlag[i]) {1639
1640 pMa->WelsFree (pCtx->sMb.pMbRefConcealedFlag[i], "pCtx->sMb.pMbRefConcealedFlag[]");1640 if (pCtx->sMb.pTransformSize8x8Flag[i]) {
1641 pCtx->sMb.pMbRefConcealedFlag[i] = NULL;1641 pMa->WelsFree (pCtx->sMb.pTransformSize8x8Flag[i], "pCtx->sMb.pTransformSize8x8Flag[]");
1642 }1642
1643 pMa->WelsFree (pDq, "pDq");1643 pCtx->sMb.pTransformSize8x8Flag[i] = NULL;
1644 1644 }
1645 pDq = NULL;1645
1646 pCtx->pDqLayersList[i] = NULL;1646 if (pCtx->sMb.pLumaQp[i]) {
1647 1647 pMa->WelsFree (pCtx->sMb.pLumaQp[i], "pCtx->sMb.pLumaQp[]");
1648 ++ i;1648
1649 } while (i < LAYER_NUM_EXCHANGEABLE);1649 pCtx->sMb.pLumaQp[i] = NULL;
1650 1650 }
1651 pCtx->iPicWidthReq = 0;1651
1652 pCtx->iPicHeightReq = 0;1652 if (pCtx->sMb.pChromaQp[i]) {
1653 pCtx->bInitialDqLayersMem = false;1653 pMa->WelsFree (pCtx->sMb.pChromaQp[i], "pCtx->sMb.pChromaQp[]");
1654}1654
1655 1655 pCtx->sMb.pChromaQp[i] = NULL;
1656void ResetCurrentAccessUnit (PWelsDecoderContext pCtx) {1656 }
1657 PAccessUnit pCurAu = pCtx->pAccessUnitList;1657
1658 pCurAu->uiStartPos = 0;1658 if (pCtx->sMb.pCbfDc[i]) {
1659 pCurAu->uiEndPos = 0;1659 pMa->WelsFree (pCtx->sMb.pCbfDc[i], "pCtx->sMb.pCbfDc[]");
1660 pCurAu->bCompletedAuFlag = false;1660 pCtx->sMb.pCbfDc[i] = NULL;
1661 if (pCurAu->uiActualUnitsNum > 0) {1661 }
1662 uint32_t iIdx = 0;1662
1663 const uint32_t kuiActualNum = pCurAu->uiActualUnitsNum;1663 if (pCtx->sMb.pNzc[i]) {
1664 // a more simpler method to do nal units list management prefered here1664 pMa->WelsFree (pCtx->sMb.pNzc[i], "pCtx->sMb.pNzc[]");
1665 const uint32_t kuiAvailNum = pCurAu->uiAvailUnitsNum;1665
1666 const uint32_t kuiLeftNum = kuiAvailNum - kuiActualNum;1666 pCtx->sMb.pNzc[i] = NULL;
1667 1667 }
1668 // Swapping active nal unit nodes of succeeding AU with leading of list1668
1669 while (iIdx < kuiLeftNum) {1669 if (pCtx->sMb.pNzcRs[i]) {
1670 PNalUnit t = pCurAu->pNalUnitsList[kuiActualNum + iIdx];1670 pMa->WelsFree (pCtx->sMb.pNzcRs[i], "pCtx->sMb.pNzcRs[]");
1671 pCurAu->pNalUnitsList[kuiActualNum + iIdx] = pCurAu->pNalUnitsList[iIdx];1671
1672 pCurAu->pNalUnitsList[iIdx] = t;1672 pCtx->sMb.pNzcRs[i] = NULL;
1673 ++ iIdx;1673 }
1674 }1674
1675 pCurAu->uiActualUnitsNum = pCurAu->uiAvailUnitsNum = kuiLeftNum;1675 if (pCtx->sMb.pScaledTCoeff[i]) {
1676 }1676 pMa->WelsFree (pCtx->sMb.pScaledTCoeff[i], "pCtx->sMb.pScaledTCoeff[]");
1677}1677
1678 1678 pCtx->sMb.pScaledTCoeff[i] = NULL;
1679/*!1679 }
1680 * \brief Force reset current Acess Unit Nal list in case error parsing/decoding in current AU1680
1681 * \author1681 if (pCtx->sMb.pIntraPredMode[i]) {
1682 * \history 11/16/20091682 pMa->WelsFree (pCtx->sMb.pIntraPredMode[i], "pCtx->sMb.pIntraPredMode[]");
1683 */1683
1684void ForceResetCurrentAccessUnit (PAccessUnit pAu) {1684 pCtx->sMb.pIntraPredMode[i] = NULL;
1685 uint32_t uiSucAuIdx = pAu->uiEndPos + 1;1685 }
1686 uint32_t uiCurAuIdx = 0;1686
1687 1687 if (pCtx->sMb.pIntra4x4FinalMode[i]) {
1688 // swap the succeeding AU's nal units to the front1688 pMa->WelsFree (pCtx->sMb.pIntra4x4FinalMode[i], "pCtx->sMb.pIntra4x4FinalMode[]");
1689 while (uiSucAuIdx < pAu->uiAvailUnitsNum) {1689
1690 PNalUnit t = pAu->pNalUnitsList[uiSucAuIdx];1690 pCtx->sMb.pIntra4x4FinalMode[i] = NULL;
1691 pAu->pNalUnitsList[uiSucAuIdx] = pAu->pNalUnitsList[uiCurAuIdx];1691 }
1692 pAu->pNalUnitsList[uiCurAuIdx] = t;1692
1693 ++ uiSucAuIdx;1693 if (pCtx->sMb.pIntraNxNAvailFlag[i]) {
1694 ++ uiCurAuIdx;1694 pMa->WelsFree (pCtx->sMb.pIntraNxNAvailFlag[i], "pCtx->sMb.pIntraNxNAvailFlag");
1695 }1695
1696 1696 pCtx->sMb.pIntraNxNAvailFlag[i] = NULL;
1697 // Update avail/actual units num accordingly for next AU parsing1697 }
1698 if (pAu->uiAvailUnitsNum > pAu->uiEndPos)1698
1699 pAu->uiAvailUnitsNum -= (pAu->uiEndPos + 1);1699 if (pCtx->sMb.pChromaPredMode[i]) {
1700 else1700 pMa->WelsFree (pCtx->sMb.pChromaPredMode[i], "pCtx->sMb.pChromaPredMode[]");
1701 pAu->uiAvailUnitsNum = 0;1701
1702 pAu->uiActualUnitsNum = 0;1702 pCtx->sMb.pChromaPredMode[i] = NULL;
1703 pAu->uiStartPos = 0;1703 }
1704 pAu->uiEndPos = 0;1704
1705 pAu->bCompletedAuFlag = false;1705 if (pCtx->sMb.pCbp[i]) {
1706}1706 pMa->WelsFree (pCtx->sMb.pCbp[i], "pCtx->sMb.pCbp[]");
1707 1707
1708//clear current corrupted NAL from pNalUnitsList1708 pCtx->sMb.pCbp[i] = NULL;
1709void ForceClearCurrentNal (PAccessUnit pAu) {1709 }
1710 if (pAu->uiAvailUnitsNum > 0)1710
1711 -- pAu->uiAvailUnitsNum;1711 // if (pCtx->sMb.pMotionPredFlag[i])
1712}1712 //{
1713 1713 // pMa->WelsFree( pCtx->sMb.pMotionPredFlag[i], "pCtx->sMb.pMotionPredFlag[]" );
1714void ForceResetParaSetStatusAndAUList (PWelsDecoderContext pCtx) {1714
1715 pCtx->bSpsExistAheadFlag = false;1715 // pCtx->sMb.pMotionPredFlag[i] = NULL;
1716 pCtx->bSubspsExistAheadFlag = false;1716 //}
1717 pCtx->bPpsExistAheadFlag = false;1717
1718 1718 if (pCtx->sMb.pSubMbType[i]) {
1719 // Force clear the AU list1719 pMa->WelsFree (pCtx->sMb.pSubMbType[i], "pCtx->sMb.pSubMbType[]");
1720 pCtx->pAccessUnitList->uiAvailUnitsNum = 0;1720
1721 pCtx->pAccessUnitList->uiActualUnitsNum = 0;1721 pCtx->sMb.pSubMbType[i] = NULL;
1722 pCtx->pAccessUnitList->uiStartPos = 0;1722 }
1723 pCtx->pAccessUnitList->uiEndPos = 0;1723
1724 pCtx->pAccessUnitList->bCompletedAuFlag = false;1724 if (pCtx->sMb.pSliceIdc[i]) {
1725}1725 pMa->WelsFree (pCtx->sMb.pSliceIdc[i], "pCtx->sMb.pSliceIdc[]");
1726 1726
1727void CheckAvailNalUnitsListContinuity (PWelsDecoderContext pCtx, int32_t iStartIdx, int32_t iEndIdx) {1727 pCtx->sMb.pSliceIdc[i] = NULL;
1728 PAccessUnit pCurAu = pCtx->pAccessUnitList;1728 }
1729 1729
1730 uint8_t uiLastNuDependencyId, uiLastNuLayerDqId;1730 if (pCtx->sMb.pResidualPredFlag[i]) {
1731 uint8_t uiCurNuDependencyId, uiCurNuQualityId, uiCurNuLayerDqId, uiCurNuRefLayerDqId;1731 pMa->WelsFree (pCtx->sMb.pResidualPredFlag[i], "pCtx->sMb.pResidualPredFlag[]");
1732 1732
1733 int32_t iCurNalUnitIdx = 0;1733 pCtx->sMb.pResidualPredFlag[i] = NULL;
1734 1734 }
1735 //check the continuity of pNalUnitsList forwards (from pIdxNoInterLayerPred to end_postion)1735
1736 uiLastNuDependencyId = pCurAu->pNalUnitsList[iStartIdx]->sNalHeaderExt.uiDependencyId;//starting nal unit1736 if (pCtx->sMb.pInterPredictionDoneFlag[i]) {
1737 uiLastNuLayerDqId = pCurAu->pNalUnitsList[iStartIdx]->sNalHeaderExt.uiLayerDqId;//starting nal unit1737 pMa->WelsFree (pCtx->sMb.pInterPredictionDoneFlag[i], "pCtx->sMb.pInterPredictionDoneFlag[]");
1738 iCurNalUnitIdx = iStartIdx + 1;//current nal unit1738
1739 while (iCurNalUnitIdx <= iEndIdx) {1739 pCtx->sMb.pInterPredictionDoneFlag[i] = NULL;
1740 uiCurNuDependencyId = pCurAu->pNalUnitsList[iCurNalUnitIdx]->sNalHeaderExt.uiDependencyId;1740 }
1741 uiCurNuQualityId = pCurAu->pNalUnitsList[iCurNalUnitIdx]->sNalHeaderExt.uiQualityId;1741
1742 uiCurNuLayerDqId = pCurAu->pNalUnitsList[iCurNalUnitIdx]->sNalHeaderExt.uiLayerDqId;1742 if (pCtx->sMb.pMbCorrectlyDecodedFlag[i]) {
1743 uiCurNuRefLayerDqId = pCurAu->pNalUnitsList[iCurNalUnitIdx]->sNalData.sVclNal.sSliceHeaderExt.uiRefLayerDqId;1743 pMa->WelsFree (pCtx->sMb.pMbCorrectlyDecodedFlag[i], "pCtx->sMb.pMbCorrectlyDecodedFlag[]");
1744 1744 pCtx->sMb.pMbCorrectlyDecodedFlag[i] = NULL;
1745 if (uiCurNuDependencyId == uiLastNuDependencyId) {1745 }
1746 uiLastNuLayerDqId = uiCurNuLayerDqId;1746
1747 ++ iCurNalUnitIdx;1747 if (pCtx->sMb.pMbRefConcealedFlag[i]) {
1748 } else { //uiCurNuDependencyId != uiLastNuDependencyId, new dependency arrive1748 pMa->WelsFree (pCtx->sMb.pMbRefConcealedFlag[i], "pCtx->sMb.pMbRefConcealedFlag[]");
1749 if (uiCurNuQualityId == 0) {1749 pCtx->sMb.pMbRefConcealedFlag[i] = NULL;
1750 uiLastNuDependencyId = uiCurNuDependencyId;1750 }
1751 if (uiCurNuRefLayerDqId == uiLastNuLayerDqId) {1751 pMa->WelsFree (pDq, "pDq");
1752 uiLastNuLayerDqId = uiCurNuLayerDqId;1752
1753 ++ iCurNalUnitIdx;1753 pDq = NULL;
1754 } else { //cur_nu_layer_id != next_nu_ref_layer_dq_id, the chain is broken at this point1754 pCtx->pDqLayersList[i] = NULL;
1755 break;1755
1756 }1756 ++ i;
1757 } else { //new dependency arrive, but no base quality layer, so we must stop in this point1757 } while (i < LAYER_NUM_EXCHANGEABLE);
1758 break;1758
1759 }1759 pCtx->iPicWidthReq = 0;
1760 }1760 pCtx->iPicHeightReq = 0;
1761 }1761 pCtx->bInitialDqLayersMem = false;
1762 1762}
1763 -- iCurNalUnitIdx;1763
1764 pCurAu->uiEndPos = iCurNalUnitIdx;1764void ResetCurrentAccessUnit (PWelsDecoderContext pCtx) {
1765 pCtx->uiTargetDqId = pCurAu->pNalUnitsList[iCurNalUnitIdx]->sNalHeaderExt.uiLayerDqId;1765 PAccessUnit pCurAu = pCtx->pAccessUnitList;
1766}1766 pCurAu->uiStartPos = 0;
1767 1767 pCurAu->uiEndPos = 0;
1768//main purpose: to support multi-slice and to include all slice which have the same uiDependencyId, uiQualityId and frame_num1768 pCurAu->bCompletedAuFlag = false;
1769//for single slice, pIdxNoInterLayerPred SHOULD NOT be modified1769 if (pCurAu->uiActualUnitsNum > 0) {
1770void RefineIdxNoInterLayerPred (PAccessUnit pCurAu, int32_t* pIdxNoInterLayerPred) {1770 uint32_t iIdx = 0;
1771 int32_t iLastNalDependId = pCurAu->pNalUnitsList[*pIdxNoInterLayerPred]->sNalHeaderExt.uiDependencyId;1771 const uint32_t kuiActualNum = pCurAu->uiActualUnitsNum;
1772 int32_t iLastNalQualityId = pCurAu->pNalUnitsList[*pIdxNoInterLayerPred]->sNalHeaderExt.uiQualityId;1772 // a more simpler method to do nal units list management prefered here
1773 uint8_t uiLastNalTId = pCurAu->pNalUnitsList[*pIdxNoInterLayerPred]->sNalHeaderExt.uiTemporalId;1773 const uint32_t kuiAvailNum = pCurAu->uiAvailUnitsNum;
1774 int32_t iLastNalFrameNum =1774 const uint32_t kuiLeftNum = kuiAvailNum - kuiActualNum;
1775 pCurAu->pNalUnitsList[*pIdxNoInterLayerPred]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iFrameNum;1775
1776 int32_t iLastNalPoc =1776 // Swapping active nal unit nodes of succeeding AU with leading of list
1777 pCurAu->pNalUnitsList[*pIdxNoInterLayerPred]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iPicOrderCntLsb;1777 while (iIdx < kuiLeftNum) {
1778 int32_t iLastNalFirstMb =1778 PNalUnit t = pCurAu->pNalUnitsList[kuiActualNum + iIdx];
1779 pCurAu->pNalUnitsList[*pIdxNoInterLayerPred]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iFirstMbInSlice;1779 pCurAu->pNalUnitsList[kuiActualNum + iIdx] = pCurAu->pNalUnitsList[iIdx];
1780 int32_t iCurNalDependId, iCurNalQualityId, iCurNalTId, iCurNalFrameNum, iCurNalPoc, iCurNalFirstMb, iCurIdx,1780 pCurAu->pNalUnitsList[iIdx] = t;
1781 iFinalIdxNoInterLayerPred;1781 ++ iIdx;
1782 1782 }
1783 bool bMultiSliceFind = false;1783 pCurAu->uiActualUnitsNum = pCurAu->uiAvailUnitsNum = kuiLeftNum;
1784 1784 }
1785 iFinalIdxNoInterLayerPred = 0;1785}
1786 iCurIdx = *pIdxNoInterLayerPred - 1;1786
1787 while (iCurIdx >= 0) {1787/*!
1788 if (pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.iNoInterLayerPredFlag) {1788 * \brief Force reset current Acess Unit Nal list in case error parsing/decoding in current AU
1789 iCurNalDependId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiDependencyId;1789 * \author
1790 iCurNalQualityId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiQualityId;1790 * \history 11/16/2009
1791 iCurNalTId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiTemporalId;1791 */
1792 iCurNalFrameNum = pCurAu->pNalUnitsList[iCurIdx]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iFrameNum;1792void ForceResetCurrentAccessUnit (PAccessUnit pAu) {
1793 iCurNalPoc = pCurAu->pNalUnitsList[iCurIdx]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iPicOrderCntLsb;1793 uint32_t uiSucAuIdx = pAu->uiEndPos + 1;
1794 iCurNalFirstMb = pCurAu->pNalUnitsList[iCurIdx]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iFirstMbInSlice;1794 uint32_t uiCurAuIdx = 0;
1795 1795
1796 if (iCurNalDependId == iLastNalDependId &&1796 // swap the succeeding AU's nal units to the front
1797 iCurNalQualityId == iLastNalQualityId &&1797 while (uiSucAuIdx < pAu->uiAvailUnitsNum) {
1798 iCurNalTId == uiLastNalTId &&1798 PNalUnit t = pAu->pNalUnitsList[uiSucAuIdx];
1799 iCurNalFrameNum == iLastNalFrameNum &&1799 pAu->pNalUnitsList[uiSucAuIdx] = pAu->pNalUnitsList[uiCurAuIdx];
1800 iCurNalPoc == iLastNalPoc &&1800 pAu->pNalUnitsList[uiCurAuIdx] = t;
1801 iCurNalFirstMb != iLastNalFirstMb) {1801 ++ uiSucAuIdx;
1802 bMultiSliceFind = true;1802 ++ uiCurAuIdx;
1803 iFinalIdxNoInterLayerPred = iCurIdx;1803 }
1804 --iCurIdx;1804
1805 continue;1805 // Update avail/actual units num accordingly for next AU parsing
1806 } else {1806 if (pAu->uiAvailUnitsNum > pAu->uiEndPos)
1807 break;1807 pAu->uiAvailUnitsNum -= (pAu->uiEndPos + 1);
1808 }1808 else
1809 }1809 pAu->uiAvailUnitsNum = 0;
1810 --iCurIdx;1810 pAu->uiActualUnitsNum = 0;
1811 }1811 pAu->uiStartPos = 0;
1812 1812 pAu->uiEndPos = 0;
1813 if (bMultiSliceFind && *pIdxNoInterLayerPred != iFinalIdxNoInterLayerPred) {1813 pAu->bCompletedAuFlag = false;
1814 *pIdxNoInterLayerPred = iFinalIdxNoInterLayerPred;1814}
1815 }1815
1816}1816//clear current corrupted NAL from pNalUnitsList
1817 1817void ForceClearCurrentNal (PAccessUnit pAu) {
1818bool CheckPocOfCurValidNalUnits (PAccessUnit pCurAu, int32_t pIdxNoInterLayerPred) {1818 if (pAu->uiAvailUnitsNum > 0)
1819 int32_t iEndIdx = pCurAu->uiEndPos;1819 -- pAu->uiAvailUnitsNum;
1820 int32_t iCurAuPoc =1820}
1821 pCurAu->pNalUnitsList[pIdxNoInterLayerPred]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iPicOrderCntLsb;1821
1822 int32_t iTmpPoc, i;1822void ForceResetParaSetStatusAndAUList (PWelsDecoderContext pCtx) {
1823 for (i = pIdxNoInterLayerPred + 1; i < iEndIdx; i++) {1823 pCtx->bSpsExistAheadFlag = false;
1824 iTmpPoc = pCurAu->pNalUnitsList[i]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iPicOrderCntLsb;1824 pCtx->bSubspsExistAheadFlag = false;
1825 if (iTmpPoc != iCurAuPoc) {1825 pCtx->bPpsExistAheadFlag = false;
1826 return false;1826
1827 }1827 // Force clear the AU list
1828 }1828 pCtx->pAccessUnitList->uiAvailUnitsNum = 0;
1829 1829 pCtx->pAccessUnitList->uiActualUnitsNum = 0;
1830 return true;1830 pCtx->pAccessUnitList->uiStartPos = 0;
1831}1831 pCtx->pAccessUnitList->uiEndPos = 0;
1832 1832 pCtx->pAccessUnitList->bCompletedAuFlag = false;
1833bool CheckIntegrityNalUnitsList (PWelsDecoderContext pCtx) {1833}
1834 PAccessUnit pCurAu = pCtx->pAccessUnitList;1834
1835 const int32_t kiEndPos = pCurAu->uiEndPos;1835void CheckAvailNalUnitsListContinuity (PWelsDecoderContext pCtx, int32_t iStartIdx, int32_t iEndIdx) {
1836 int32_t iIdxNoInterLayerPred = 0;1836 PAccessUnit pCurAu = pCtx->pAccessUnitList;
1837 1837
1838 if (!pCurAu->bCompletedAuFlag)1838 uint8_t uiLastNuDependencyId, uiLastNuLayerDqId;
1839 return false;1839 uint8_t uiCurNuDependencyId, uiCurNuQualityId, uiCurNuLayerDqId, uiCurNuRefLayerDqId;
1840 1840
1841 if (pCtx->bNewSeqBegin) {1841 int32_t iCurNalUnitIdx = 0;
1842 pCurAu->uiStartPos = 0;1842
1843 //step1: search the pNalUnit whose iNoInterLayerPredFlag equal to 1 backwards (from uiEndPos to 0)1843 //check the continuity of pNalUnitsList forwards (from pIdxNoInterLayerPred to end_postion)
1844 iIdxNoInterLayerPred = kiEndPos;1844 uiLastNuDependencyId = pCurAu->pNalUnitsList[iStartIdx]->sNalHeaderExt.uiDependencyId;//starting nal unit
1845 while (iIdxNoInterLayerPred >= 0) {1845 uiLastNuLayerDqId = pCurAu->pNalUnitsList[iStartIdx]->sNalHeaderExt.uiLayerDqId;//starting nal unit
1846 if (pCurAu->pNalUnitsList[iIdxNoInterLayerPred]->sNalHeaderExt.iNoInterLayerPredFlag) {1846 iCurNalUnitIdx = iStartIdx + 1;//current nal unit
1847 break;1847 while (iCurNalUnitIdx <= iEndIdx) {
1848 }1848 uiCurNuDependencyId = pCurAu->pNalUnitsList[iCurNalUnitIdx]->sNalHeaderExt.uiDependencyId;
1849 --iIdxNoInterLayerPred;1849 uiCurNuQualityId = pCurAu->pNalUnitsList[iCurNalUnitIdx]->sNalHeaderExt.uiQualityId;
1850 }1850 uiCurNuLayerDqId = pCurAu->pNalUnitsList[iCurNalUnitIdx]->sNalHeaderExt.uiLayerDqId;
1851 if (iIdxNoInterLayerPred < 0) {1851 uiCurNuRefLayerDqId = pCurAu->pNalUnitsList[iCurNalUnitIdx]->sNalData.sVclNal.sSliceHeaderExt.uiRefLayerDqId;
1852 //can not find the Nal Unit whose no_inter_pred_falg equal to 1, MUST STOP decode1852
1853 return false;1853 if (uiCurNuDependencyId == uiLastNuDependencyId) {
1854 }1854 uiLastNuLayerDqId = uiCurNuLayerDqId;
1855 1855 ++ iCurNalUnitIdx;
1856 //step2: support multi-slice, to include all base layer slice1856 } else { //uiCurNuDependencyId != uiLastNuDependencyId, new dependency arrive
1857 RefineIdxNoInterLayerPred (pCurAu, &iIdxNoInterLayerPred);1857 if (uiCurNuQualityId == 0) {
1858 pCurAu->uiStartPos = iIdxNoInterLayerPred;1858 uiLastNuDependencyId = uiCurNuDependencyId;
1859 CheckAvailNalUnitsListContinuity (pCtx, iIdxNoInterLayerPred, kiEndPos);1859 if (uiCurNuRefLayerDqId == uiLastNuLayerDqId) {
1860 1860 uiLastNuLayerDqId = uiCurNuLayerDqId;
1861 if (!CheckPocOfCurValidNalUnits (pCurAu, iIdxNoInterLayerPred)) {1861 ++ iCurNalUnitIdx;
1862 return false;1862 } else { //cur_nu_layer_id != next_nu_ref_layer_dq_id, the chain is broken at this point
1863 }1863 break;
1864 1864 }
1865 pCtx->iCurSeqIntervalTargetDependId = pCurAu->pNalUnitsList[pCurAu->uiEndPos]->sNalHeaderExt.uiDependencyId;1865 } else { //new dependency arrive, but no base quality layer, so we must stop in this point
1866 pCtx->iCurSeqIntervalMaxPicWidth =1866 break;
1867 pCurAu->pNalUnitsList[pCurAu->uiEndPos]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iMbWidth << 4;1867 }
1868 pCtx->iCurSeqIntervalMaxPicHeight =1868 }
1869 pCurAu->pNalUnitsList[pCurAu->uiEndPos]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iMbHeight << 4;1869 }
1870 } else { //P_SLICE1870
1871 //step 1: search uiDependencyId equal to pCtx->cur_seq_interval_target_dependency_id1871 -- iCurNalUnitIdx;
1872 bool bGetDependId = false;1872 pCurAu->uiEndPos = iCurNalUnitIdx;
1873 int32_t iIdxDependId = 0;1873 pCtx->uiTargetDqId = pCurAu->pNalUnitsList[iCurNalUnitIdx]->sNalHeaderExt.uiLayerDqId;
1874 1874}
1875 iIdxDependId = kiEndPos;1875
1876 while (iIdxDependId >= 0) {1876//main purpose: to support multi-slice and to include all slice which have the same uiDependencyId, uiQualityId and frame_num
1877 if (pCtx->iCurSeqIntervalTargetDependId == pCurAu->pNalUnitsList[iIdxDependId]->sNalHeaderExt.uiDependencyId) {1877//for single slice, pIdxNoInterLayerPred SHOULD NOT be modified
1878 bGetDependId = true;1878void RefineIdxNoInterLayerPred (PAccessUnit pCurAu, int32_t* pIdxNoInterLayerPred) {
1879 break;1879 int32_t iLastNalDependId = pCurAu->pNalUnitsList[*pIdxNoInterLayerPred]->sNalHeaderExt.uiDependencyId;
1880 } else {1880 int32_t iLastNalQualityId = pCurAu->pNalUnitsList[*pIdxNoInterLayerPred]->sNalHeaderExt.uiQualityId;
1881 --iIdxDependId;1881 uint8_t uiLastNalTId = pCurAu->pNalUnitsList[*pIdxNoInterLayerPred]->sNalHeaderExt.uiTemporalId;
1882 }1882 int32_t iLastNalFrameNum =
1883 }1883 pCurAu->pNalUnitsList[*pIdxNoInterLayerPred]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iFrameNum;
1884 1884 int32_t iLastNalPoc =
1885 //step 2: switch according to whether or not find the index of pNalUnit whose uiDependencyId equal to iCurSeqIntervalTargetDependId1885 pCurAu->pNalUnitsList[*pIdxNoInterLayerPred]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iPicOrderCntLsb;
1886 if (bGetDependId) { //get the index of pNalUnit whose uiDependencyId equal to iCurSeqIntervalTargetDependId1886 int32_t iLastNalFirstMb =
1887 bool bGetNoInterPredFront = false;1887 pCurAu->pNalUnitsList[*pIdxNoInterLayerPred]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iFirstMbInSlice;
1888 //step 2a: search iNoInterLayerPredFlag [0....iIdxDependId]1888 int32_t iCurNalDependId, iCurNalQualityId, iCurNalTId, iCurNalFrameNum, iCurNalPoc, iCurNalFirstMb, iCurIdx,
1889 iIdxNoInterLayerPred = iIdxDependId;1889 iFinalIdxNoInterLayerPred;
1890 while (iIdxNoInterLayerPred >= 0) {1890
1891 if (pCurAu->pNalUnitsList[iIdxNoInterLayerPred]->sNalHeaderExt.iNoInterLayerPredFlag) {1891 bool bMultiSliceFind = false;
1892 bGetNoInterPredFront = true;1892
1893 break;1893 iFinalIdxNoInterLayerPred = 0;
1894 }1894 iCurIdx = *pIdxNoInterLayerPred - 1;
1895 --iIdxNoInterLayerPred;1895 while (iCurIdx >= 0) {
1896 }1896 if (pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.iNoInterLayerPredFlag) {
1897 //step 2b: switch, whether or not find the NAL unit whose no_inter_pred_flag equal to 1 among [0....iIdxDependId]1897 iCurNalDependId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiDependencyId;
1898 if (bGetNoInterPredFront) { //YES1898 iCurNalQualityId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiQualityId;
1899 RefineIdxNoInterLayerPred (pCurAu, &iIdxNoInterLayerPred);1899 iCurNalTId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiTemporalId;
1900 pCurAu->uiStartPos = iIdxNoInterLayerPred;1900 iCurNalFrameNum = pCurAu->pNalUnitsList[iCurIdx]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iFrameNum;
1901 CheckAvailNalUnitsListContinuity (pCtx, iIdxNoInterLayerPred, iIdxDependId);1901 iCurNalPoc = pCurAu->pNalUnitsList[iCurIdx]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iPicOrderCntLsb;
1902 1902 iCurNalFirstMb = pCurAu->pNalUnitsList[iCurIdx]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iFirstMbInSlice;
1903 if (!CheckPocOfCurValidNalUnits (pCurAu, iIdxNoInterLayerPred)) {1903
1904 return false;1904 if (iCurNalDependId == iLastNalDependId &&
1905 }1905 iCurNalQualityId == iLastNalQualityId &&
1906 } else { //NO, should find the NAL unit whose no_inter_pred_flag equal to 1 among [iIdxDependId....uiEndPos]1906 iCurNalTId == uiLastNalTId &&
1907 iIdxNoInterLayerPred = iIdxDependId;1907 iCurNalFrameNum == iLastNalFrameNum &&
1908 while (iIdxNoInterLayerPred <= kiEndPos) {1908 iCurNalPoc == iLastNalPoc &&
1909 if (pCurAu->pNalUnitsList[iIdxNoInterLayerPred]->sNalHeaderExt.iNoInterLayerPredFlag) {1909 iCurNalFirstMb != iLastNalFirstMb) {
1910 break;1910 bMultiSliceFind = true;
1911 }1911 iFinalIdxNoInterLayerPred = iCurIdx;
1912 ++iIdxNoInterLayerPred;1912 --iCurIdx;
1913 }1913 continue;
1914 1914 } else {
1915 if (iIdxNoInterLayerPred > kiEndPos) {1915 break;
1916 return false; //cann't find the index of pNalUnit whose no_inter_pred_flag = 11916 }
1917 }1917 }
1918 1918 --iCurIdx;
1919 RefineIdxNoInterLayerPred (pCurAu, &iIdxNoInterLayerPred);1919 }
1920 pCurAu->uiStartPos = iIdxNoInterLayerPred;1920
1921 CheckAvailNalUnitsListContinuity (pCtx, iIdxNoInterLayerPred, kiEndPos);1921 if (bMultiSliceFind && *pIdxNoInterLayerPred != iFinalIdxNoInterLayerPred) {
1922 1922 *pIdxNoInterLayerPred = iFinalIdxNoInterLayerPred;
1923 if (!CheckPocOfCurValidNalUnits (pCurAu, iIdxNoInterLayerPred)) {1923 }
1924 return false;1924}
1925 }1925
1926 }1926bool CheckPocOfCurValidNalUnits (PAccessUnit pCurAu, int32_t pIdxNoInterLayerPred) {
1927 } else { //without the index of pNalUnit, should process this AU as common case1927 int32_t iEndIdx = pCurAu->uiEndPos;
1928 iIdxNoInterLayerPred = kiEndPos;1928 int32_t iCurAuPoc =
1929 while (iIdxNoInterLayerPred >= 0) {1929 pCurAu->pNalUnitsList[pIdxNoInterLayerPred]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iPicOrderCntLsb;
1930 if (pCurAu->pNalUnitsList[iIdxNoInterLayerPred]->sNalHeaderExt.iNoInterLayerPredFlag) {1930 int32_t iTmpPoc, i;
1931 break;1931 for (i = pIdxNoInterLayerPred + 1; i < iEndIdx; i++) {
1932 }1932 iTmpPoc = pCurAu->pNalUnitsList[i]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iPicOrderCntLsb;
1933 --iIdxNoInterLayerPred;1933 if (iTmpPoc != iCurAuPoc) {
1934 }1934 return false;
1935 if (iIdxNoInterLayerPred < 0) {1935 }
1936 return false; //cann't find the index of pNalUnit whose iNoInterLayerPredFlag = 11936 }
1937 }1937
1938 1938 return true;
1939 RefineIdxNoInterLayerPred (pCurAu, &iIdxNoInterLayerPred);1939}
1940 pCurAu->uiStartPos = iIdxNoInterLayerPred;1940
1941 CheckAvailNalUnitsListContinuity (pCtx, iIdxNoInterLayerPred, kiEndPos);1941bool CheckIntegrityNalUnitsList (PWelsDecoderContext pCtx) {
1942 1942 PAccessUnit pCurAu = pCtx->pAccessUnitList;
1943 if (!CheckPocOfCurValidNalUnits (pCurAu, iIdxNoInterLayerPred)) {1943 const int32_t kiEndPos = pCurAu->uiEndPos;
1944 return false;1944 int32_t iIdxNoInterLayerPred = 0;
1945 }1945
1946 }1946 if (!pCurAu->bCompletedAuFlag)
1947 }1947 return false;
1948 1948
1949 return true;1949 if (pCtx->bNewSeqBegin) {
1950}1950 pCurAu->uiStartPos = 0;
1951 1951 //step1: search the pNalUnit whose iNoInterLayerPredFlag equal to 1 backwards (from uiEndPos to 0)
1952void CheckOnlyOneLayerInAu (PWelsDecoderContext pCtx) {1952 iIdxNoInterLayerPred = kiEndPos;
1953 PAccessUnit pCurAu = pCtx->pAccessUnitList;1953 while (iIdxNoInterLayerPred >= 0) {
1954 1954 if (pCurAu->pNalUnitsList[iIdxNoInterLayerPred]->sNalHeaderExt.iNoInterLayerPredFlag) {
1955 int32_t iEndIdx = pCurAu->uiEndPos;1955 break;
1956 int32_t iCurIdx = pCurAu->uiStartPos;1956 }
1957 uint8_t uiDId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiDependencyId;1957 --iIdxNoInterLayerPred;
1958 uint8_t uiQId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiQualityId;1958 }
1959 uint8_t uiTId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiTemporalId;1959 if (iIdxNoInterLayerPred < 0) {
1960 1960 //can not find the Nal Unit whose no_inter_pred_falg equal to 1, MUST STOP decode
1961 uint8_t uiCurDId, uiCurQId, uiCurTId;1961 return false;
1962 1962 }
1963 pCtx->bOnlyOneLayerInCurAuFlag = true;1963
1964 1964 //step2: support multi-slice, to include all base layer slice
1965 if (iEndIdx == iCurIdx) { //only one NAL in pNalUnitsList1965 RefineIdxNoInterLayerPred (pCurAu, &iIdxNoInterLayerPred);
1966 return;1966 pCurAu->uiStartPos = iIdxNoInterLayerPred;
1967 }1967 CheckAvailNalUnitsListContinuity (pCtx, iIdxNoInterLayerPred, kiEndPos);
1968 1968
1969 ++iCurIdx;1969 if (!CheckPocOfCurValidNalUnits (pCurAu, iIdxNoInterLayerPred)) {
1970 while (iCurIdx <= iEndIdx) {1970 return false;
1971 uiCurDId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiDependencyId;1971 }
1972 uiCurQId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiQualityId;1972
1973 uiCurTId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiTemporalId;1973 pCtx->iCurSeqIntervalTargetDependId = pCurAu->pNalUnitsList[pCurAu->uiEndPos]->sNalHeaderExt.uiDependencyId;
1974 1974 pCtx->iCurSeqIntervalMaxPicWidth =
1975 if (uiDId != uiCurDId || uiQId != uiCurQId || uiTId != uiCurTId) {1975 pCurAu->pNalUnitsList[pCurAu->uiEndPos]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iMbWidth << 4;
1976 pCtx->bOnlyOneLayerInCurAuFlag = false;1976 pCtx->iCurSeqIntervalMaxPicHeight =
1977 return;1977 pCurAu->pNalUnitsList[pCurAu->uiEndPos]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.iMbHeight << 4;
1978 }1978 } else { //P_SLICE
1979 1979 //step 1: search uiDependencyId equal to pCtx->cur_seq_interval_target_dependency_id
1980 ++iCurIdx;1980 bool bGetDependId = false;
1981 }1981 int32_t iIdxDependId = 0;
1982}1982
1983 1983 iIdxDependId = kiEndPos;
1984int32_t WelsDecodeAccessUnitStart (PWelsDecoderContext pCtx) {1984 while (iIdxDependId >= 0) {
1985 // Roll back NAL units not being belong to current access unit list for proceeded access unit1985 if (pCtx->iCurSeqIntervalTargetDependId == pCurAu->pNalUnitsList[iIdxDependId]->sNalHeaderExt.uiDependencyId) {
1986 int32_t iRet = UpdateAccessUnit (pCtx);1986 bGetDependId = true;
1987 if (iRet != ERR_NONE)1987 break;
1988 return iRet;1988 } else {
1989 1989 --iIdxDependId;
1990 pCtx->pAccessUnitList->uiStartPos = 0;1990 }
1991 if (!pCtx->bAvcBasedFlag && !CheckIntegrityNalUnitsList (pCtx)) {1991 }
1992 pCtx->iErrorCode |= dsBitstreamError;1992
1993 return dsBitstreamError;1993 //step 2: switch according to whether or not find the index of pNalUnit whose uiDependencyId equal to iCurSeqIntervalTargetDependId
1994 }1994 if (bGetDependId) { //get the index of pNalUnit whose uiDependencyId equal to iCurSeqIntervalTargetDependId
1995 1995 bool bGetNoInterPredFront = false;
1996 //check current AU has only one layer or not1996 //step 2a: search iNoInterLayerPredFlag [0....iIdxDependId]
1997 //If YES, can use deblocking based on AVC1997 iIdxNoInterLayerPred = iIdxDependId;
1998 if (!pCtx->bAvcBasedFlag) {1998 while (iIdxNoInterLayerPred >= 0) {
1999 CheckOnlyOneLayerInAu (pCtx);1999 if (pCurAu->pNalUnitsList[iIdxNoInterLayerPred]->sNalHeaderExt.iNoInterLayerPredFlag) {
2000 }2000 bGetNoInterPredFront = true;
2001 2001 break;
2002 return ERR_NONE;2002 }
2003}2003 --iIdxNoInterLayerPred;
2004 2004 }
2005void WelsDecodeAccessUnitEnd (PWelsDecoderContext pCtx) {2005 //step 2b: switch, whether or not find the NAL unit whose no_inter_pred_flag equal to 1 among [0....iIdxDependId]
2006 //save previous header info2006 if (bGetNoInterPredFront) { //YES
2007 PAccessUnit pCurAu = pCtx->pAccessUnitList;2007 RefineIdxNoInterLayerPred (pCurAu, &iIdxNoInterLayerPred);
2008 PNalUnit pCurNal = pCurAu->pNalUnitsList[pCurAu->uiEndPos];2008 pCurAu->uiStartPos = iIdxNoInterLayerPred;
2009 memcpy (&pCtx->sLastNalHdrExt, &pCurNal->sNalHeaderExt, sizeof (SNalUnitHeaderExt));2009 CheckAvailNalUnitsListContinuity (pCtx, iIdxNoInterLayerPred, iIdxDependId);
2010 memcpy (&pCtx->sLastSliceHeader,2010
2011 &pCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader, sizeof (SSliceHeader));2011 if (!CheckPocOfCurValidNalUnits (pCurAu, iIdxNoInterLayerPred)) {
2012 // uninitialize context of current access unit and rbsp buffer clean2012 return false;
2013 ResetCurrentAccessUnit (pCtx);2013 }
2014}2014 } else { //NO, should find the NAL unit whose no_inter_pred_flag equal to 1 among [iIdxDependId....uiEndPos]
2015 2015 iIdxNoInterLayerPred = iIdxDependId;
2016/* CheckNewSeqBeginAndUpdateActiveLayerSps2016 while (iIdxNoInterLayerPred <= kiEndPos) {
2017 * return:2017 if (pCurAu->pNalUnitsList[iIdxNoInterLayerPred]->sNalHeaderExt.iNoInterLayerPredFlag) {
2018 * true - the AU to be construct is the start of new sequence; false - not2018 break;
2019 */2019 }
2020static bool CheckNewSeqBeginAndUpdateActiveLayerSps (PWelsDecoderContext pCtx) {2020 ++iIdxNoInterLayerPred;
2021 bool bNewSeq = false;2021 }
2022 PAccessUnit pCurAu = pCtx->pAccessUnitList;2022
2023 PSps pTmpLayerSps[MAX_LAYER_NUM];2023 if (iIdxNoInterLayerPred > kiEndPos) {
2024 for (int i = 0; i < MAX_LAYER_NUM; i++) {2024 return false; //cann't find the index of pNalUnit whose no_inter_pred_flag = 1
2025 pTmpLayerSps[i] = NULL;2025 }
2026 }2026
2027 // track the layer sps for the current au2027 RefineIdxNoInterLayerPred (pCurAu, &iIdxNoInterLayerPred);
2028 for (unsigned int i = pCurAu->uiStartPos; i <= pCurAu->uiEndPos; i++) {2028 pCurAu->uiStartPos = iIdxNoInterLayerPred;
2029 uint32_t uiDid = pCurAu->pNalUnitsList[i]->sNalHeaderExt.uiDependencyId;2029 CheckAvailNalUnitsListContinuity (pCtx, iIdxNoInterLayerPred, kiEndPos);
2030 pTmpLayerSps[uiDid] = pCurAu->pNalUnitsList[i]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pSps;2030
2031 if ((pCurAu->pNalUnitsList[i]->sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR)2031 if (!CheckPocOfCurValidNalUnits (pCurAu, iIdxNoInterLayerPred)) {
2032 || (pCurAu->pNalUnitsList[i]->sNalHeaderExt.bIdrFlag))2032 return false;
2033 bNewSeq = true;2033 }
2034 }2034 }
2035 int iMaxActiveLayer = 0, iMaxCurrentLayer = 0;2035 } else { //without the index of pNalUnit, should process this AU as common case
2036 for (int i = MAX_LAYER_NUM - 1; i >= 0; i--) {2036 iIdxNoInterLayerPred = kiEndPos;
2037 if (pCtx->pActiveLayerSps[i] != NULL) {2037 while (iIdxNoInterLayerPred >= 0) {
2038 iMaxActiveLayer = i;2038 if (pCurAu->pNalUnitsList[iIdxNoInterLayerPred]->sNalHeaderExt.iNoInterLayerPredFlag) {
2039 break;2039 break;
2040 }2040 }
2041 }2041 --iIdxNoInterLayerPred;
2042 for (int i = MAX_LAYER_NUM - 1; i >= 0; i--) {2042 }
2043 if (pTmpLayerSps[i] != NULL) {2043 if (iIdxNoInterLayerPred < 0) {
2044 iMaxCurrentLayer = i;2044 return false; //cann't find the index of pNalUnit whose iNoInterLayerPredFlag = 1
2045 break;2045 }
2046 }2046
2047 }2047 RefineIdxNoInterLayerPred (pCurAu, &iIdxNoInterLayerPred);
2048 if ((iMaxCurrentLayer != iMaxActiveLayer)2048 pCurAu->uiStartPos = iIdxNoInterLayerPred;
2049 || (pTmpLayerSps[iMaxCurrentLayer] != pCtx->pActiveLayerSps[iMaxActiveLayer])) {2049 CheckAvailNalUnitsListContinuity (pCtx, iIdxNoInterLayerPred, kiEndPos);
2050 bNewSeq = true;2050
2051 }2051 if (!CheckPocOfCurValidNalUnits (pCurAu, iIdxNoInterLayerPred)) {
2052 // fill active sps if the current sps is not null while active layer is null2052 return false;
2053 if (!bNewSeq) {2053 }
2054 for (int i = 0; i < MAX_LAYER_NUM; i++) {2054 }
2055 if (pCtx->pActiveLayerSps[i] == NULL && pTmpLayerSps[i] != NULL) {2055 }
2056 pCtx->pActiveLayerSps[i] = pTmpLayerSps[i];2056
2057 }2057 return true;
2058 }2058}
2059 } else {2059
2060 // UpdateActiveLayerSps if new sequence start2060void CheckOnlyOneLayerInAu (PWelsDecoderContext pCtx) {
2061 memcpy (&pCtx->pActiveLayerSps[0], &pTmpLayerSps[0], MAX_LAYER_NUM * sizeof (PSps));2061 PAccessUnit pCurAu = pCtx->pAccessUnitList;
2062 }2062
2063 return bNewSeq;2063 int32_t iEndIdx = pCurAu->uiEndPos;
2064}2064 int32_t iCurIdx = pCurAu->uiStartPos;
2065 2065 uint8_t uiDId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiDependencyId;
2066static void WriteBackActiveParameters (PWelsDecoderContext pCtx) {2066 uint8_t uiQId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiQualityId;
2067 if (pCtx->iOverwriteFlags & OVERWRITE_PPS) {2067 uint8_t uiTId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiTemporalId;
2068 memcpy (&pCtx->sPpsBuffer[pCtx->sPpsBuffer[MAX_PPS_COUNT].iPpsId], &pCtx->sPpsBuffer[MAX_PPS_COUNT], sizeof (SPps));2068
2069 }2069 uint8_t uiCurDId, uiCurQId, uiCurTId;
2070 if (pCtx->iOverwriteFlags & OVERWRITE_SPS) {2070
2071 memcpy (&pCtx->sSpsBuffer[pCtx->sSpsBuffer[MAX_SPS_COUNT].iSpsId], &pCtx->sSpsBuffer[MAX_SPS_COUNT], sizeof (SSps));2071 pCtx->bOnlyOneLayerInCurAuFlag = true;
2072 pCtx->bNewSeqBegin = true;2072
2073 }2073 if (iEndIdx == iCurIdx) { //only one NAL in pNalUnitsList
2074 if (pCtx->iOverwriteFlags & OVERWRITE_SUBSETSPS) {2074 return;
2075 memcpy (&pCtx->sSubsetSpsBuffer[pCtx->sSubsetSpsBuffer[MAX_SPS_COUNT].sSps.iSpsId],2075 }
2076 &pCtx->sSubsetSpsBuffer[MAX_SPS_COUNT], sizeof (SSubsetSps));2076
2077 pCtx->bNewSeqBegin = true;2077 ++iCurIdx;
2078 }2078 while (iCurIdx <= iEndIdx) {
2079 pCtx->iOverwriteFlags = OVERWRITE_NONE;2079 uiCurDId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiDependencyId;
2080}2080 uiCurQId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiQualityId;
2081 2081 uiCurTId = pCurAu->pNalUnitsList[iCurIdx]->sNalHeaderExt.uiTemporalId;
2082/*2082
2083 * DecodeFinishUpdate2083 if (uiDId != uiCurDId || uiQId != uiCurQId || uiTId != uiCurTId) {
2084 * decoder finish decoding, update active parameter sets and new seq status2084 pCtx->bOnlyOneLayerInCurAuFlag = false;
2085 *2085 return;
2086 */2086 }
2087 2087
2088void DecodeFinishUpdate (PWelsDecoderContext pCtx) {2088 ++iCurIdx;
2089 pCtx->bNewSeqBegin = false;2089 }
2090 WriteBackActiveParameters (pCtx);2090}
2091 pCtx->bNewSeqBegin = pCtx->bNewSeqBegin || pCtx->bNextNewSeqBegin;2091
2092 pCtx->bNextNewSeqBegin = false; // reset it2092int32_t WelsDecodeAccessUnitStart (PWelsDecoderContext pCtx) {
2093 if (pCtx->bNewSeqBegin)2093 // Roll back NAL units not being belong to current access unit list for proceeded access unit
2094 ResetActiveSPSForEachLayer (pCtx);2094 int32_t iRet = UpdateAccessUnit (pCtx);
2095}2095 if (iRet != ERR_NONE)
2096 2096 return iRet;
2097/*2097
2098 * ConstructAccessUnit2098 pCtx->pAccessUnitList->uiStartPos = 0;
2099 * construct an access unit for given input bitstream, maybe partial NAL Unit, one or more Units are involved to2099 if (!pCtx->bAvcBasedFlag && !CheckIntegrityNalUnitsList (pCtx)) {
2100 * joint a collective access unit.2100 pCtx->iErrorCode |= dsBitstreamError;
2101 * parameter\2101 return dsBitstreamError;
2102 * buf: bitstream data buffer2102 }
2103 * bit_len: size in bit length of data2103
2104 * buf_len: size in byte length of data2104 //check current AU has only one layer or not
2105 * coded_au: mark an Access Unit decoding finished2105 //If YES, can use deblocking based on AVC
2106 * return:2106 if (!pCtx->bAvcBasedFlag) {
2107 * 0 - success; otherwise returned error_no defined in error_no.h2107 CheckOnlyOneLayerInAu (pCtx);
2108 */2108 }
2109int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {2109
2110 int32_t iErr;2110 return ERR_NONE;
2111 PAccessUnit pCurAu = pCtx->pAccessUnitList;2111}
2112 pCtx->bAuReadyFlag = false;2112
2113 pCtx->bLastHasMmco5 = false;2113void WelsDecodeAccessUnitEnd (PWelsDecoderContext pCtx) {
2114 bool bTmpNewSeqBegin = CheckNewSeqBeginAndUpdateActiveLayerSps (pCtx);2114 //save previous header info
2115 pCtx->bNewSeqBegin = pCtx->bNewSeqBegin || bTmpNewSeqBegin;2115 PAccessUnit pCurAu = pCtx->pAccessUnitList;
2116 iErr = WelsDecodeAccessUnitStart (pCtx);2116 PNalUnit pCurNal = pCurAu->pNalUnitsList[pCurAu->uiEndPos];
2117 GetVclNalTemporalId (pCtx);2117 memcpy (&pCtx->sLastNalHdrExt, &pCurNal->sNalHeaderExt, sizeof (SNalUnitHeaderExt));
2118 2118 memcpy (&pCtx->sLastSliceHeader,
2119 if (ERR_NONE != iErr) {2119 &pCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader, sizeof (SSliceHeader));
2120 ForceResetCurrentAccessUnit (pCtx->pAccessUnitList);2120 // uninitialize context of current access unit and rbsp buffer clean
2121 if (!pCtx->pParam->bParseOnly)2121 ResetCurrentAccessUnit (pCtx);
2122 pDstInfo->iBufferStatus = 0;2122}
2123 pCtx->bNewSeqBegin = pCtx->bNewSeqBegin || pCtx->bNextNewSeqBegin;2123
2124 pCtx->bNextNewSeqBegin = false; // reset it2124/* CheckNewSeqBeginAndUpdateActiveLayerSps
2125 if (pCtx->bNewSeqBegin)2125 * return:
2126 ResetActiveSPSForEachLayer (pCtx);2126 * true - the AU to be construct is the start of new sequence; false - not
2127 return iErr;2127 */
2128 }2128static bool CheckNewSeqBeginAndUpdateActiveLayerSps (PWelsDecoderContext pCtx) {
2129 2129 bool bNewSeq = false;
2130 pCtx->pSps = pCurAu->pNalUnitsList[pCurAu->uiStartPos]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pSps;2130 PAccessUnit pCurAu = pCtx->pAccessUnitList;
2131 pCtx->pPps = pCurAu->pNalUnitsList[pCurAu->uiStartPos]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pPps;2131 PSps pTmpLayerSps[MAX_LAYER_NUM];
2132 2132 for (int i = 0; i < MAX_LAYER_NUM; i++) {
2133 //try to allocate or relocate DPB memory only when new sequence is coming.2133 pTmpLayerSps[i] = NULL;
2134 if (pCtx->bNewSeqBegin) {2134 }
2135 WelsResetRefPic (pCtx); //clear ref pPic when IDR NAL2135 // track the layer sps for the current au
2136 iErr = SyncPictureResolutionExt (pCtx, pCtx->pSps->iMbWidth, pCtx->pSps->iMbHeight);2136 for (unsigned int i = pCurAu->uiStartPos; i <= pCurAu->uiEndPos; i++) {
2137 2137 uint32_t uiDid = pCurAu->pNalUnitsList[i]->sNalHeaderExt.uiDependencyId;
2138 if (ERR_NONE != iErr) {2138 pTmpLayerSps[uiDid] = pCurAu->pNalUnitsList[i]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pSps;
2139 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "sync picture resolution ext failed, the error is %d", iErr);2139 if ((pCurAu->pNalUnitsList[i]->sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR)
2140 return iErr;2140 || (pCurAu->pNalUnitsList[i]->sNalHeaderExt.bIdrFlag))
2141 }2141 bNewSeq = true;
2142 }2142 }
2143 2143 int iMaxActiveLayer = 0, iMaxCurrentLayer = 0;
2144 iErr = DecodeCurrentAccessUnit (pCtx, ppDst, pDstInfo);2144 for (int i = MAX_LAYER_NUM - 1; i >= 0; i--) {
2145 2145 if (pCtx->pActiveLayerSps[i] != NULL) {
2146 WelsDecodeAccessUnitEnd (pCtx);2146 iMaxActiveLayer = i;
2147 2147 break;
2148 if (ERR_NONE != iErr) {2148 }
2149 WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "returned error from decoding:[0x%x]", iErr);2149 }
2150 return iErr;2150 for (int i = MAX_LAYER_NUM - 1; i >= 0; i--) {
2151 }2151 if (pTmpLayerSps[i] != NULL) {
2152 2152 iMaxCurrentLayer = i;
2153 return ERR_NONE;2153 break;
2154}2154 }
2155 2155 }
2156static inline void InitDqLayerInfo (PDqLayer pDqLayer, PLayerInfo pLayerInfo, PNalUnit pNalUnit, PPicture pPicDec) {2156 if ((iMaxCurrentLayer != iMaxActiveLayer)
2157 PNalUnitHeaderExt pNalHdrExt = &pNalUnit->sNalHeaderExt;2157 || (pTmpLayerSps[iMaxCurrentLayer] != pCtx->pActiveLayerSps[iMaxActiveLayer])) {
2158 PSliceHeaderExt pShExt = &pNalUnit->sNalData.sVclNal.sSliceHeaderExt;2158 bNewSeq = true;
2159 PSliceHeader pSh = &pShExt->sSliceHeader;2159 }
2160 const uint8_t kuiQualityId = pNalHdrExt->uiQualityId;2160 // fill active sps if the current sps is not null while active layer is null
2161 2161 if (!bNewSeq) {
2162 memcpy (&pDqLayer->sLayerInfo, pLayerInfo, sizeof (SLayerInfo)); //confirmed_safe_unsafe_usage2162 for (int i = 0; i < MAX_LAYER_NUM; i++) {
2163 2163 if (pCtx->pActiveLayerSps[i] == NULL && pTmpLayerSps[i] != NULL) {
2164 pDqLayer->pDec = pPicDec;2164 pCtx->pActiveLayerSps[i] = pTmpLayerSps[i];
2165 pDqLayer->iMbWidth = pSh->iMbWidth; // MB width of this picture2165 }
2166 pDqLayer->iMbHeight = pSh->iMbHeight;// MB height of this picture2166 }
2167 2167 } else {
2168 pDqLayer->iSliceIdcBackup = (pSh->iFirstMbInSlice << 7) | (pNalHdrExt->uiDependencyId << 4) | (pNalHdrExt->uiQualityId);2168 // UpdateActiveLayerSps if new sequence start
2169 2169 memcpy (&pCtx->pActiveLayerSps[0], &pTmpLayerSps[0], MAX_LAYER_NUM * sizeof (PSps));
2170 /* Common syntax elements across all slices of a DQLayer */2170 }
2171 pDqLayer->uiPpsId = pLayerInfo->pPps->iPpsId;2171 return bNewSeq;
2172 pDqLayer->uiDisableInterLayerDeblockingFilterIdc = pShExt->uiDisableInterLayerDeblockingFilterIdc;2172}
2173 pDqLayer->iInterLayerSliceAlphaC0Offset = pShExt->iInterLayerSliceAlphaC0Offset;2173
2174 pDqLayer->iInterLayerSliceBetaOffset = pShExt->iInterLayerSliceBetaOffset;2174static void WriteBackActiveParameters (PWelsDecoderContext pCtx) {
2175 pDqLayer->iSliceGroupChangeCycle = pSh->iSliceGroupChangeCycle;2175 if (pCtx->iOverwriteFlags & OVERWRITE_PPS) {
2176 pDqLayer->bStoreRefBasePicFlag = pShExt->bStoreRefBasePicFlag;2176 memcpy (&pCtx->sPpsBuffer[pCtx->sPpsBuffer[MAX_PPS_COUNT].iPpsId], &pCtx->sPpsBuffer[MAX_PPS_COUNT], sizeof (SPps));
2177 pDqLayer->bTCoeffLevelPredFlag = pShExt->bTCoeffLevelPredFlag;2177 }
2178 pDqLayer->bConstrainedIntraResamplingFlag = pShExt->bConstrainedIntraResamplingFlag;2178 if (pCtx->iOverwriteFlags & OVERWRITE_SPS) {
2179 pDqLayer->uiRefLayerDqId = pShExt->uiRefLayerDqId;2179 memcpy (&pCtx->sSpsBuffer[pCtx->sSpsBuffer[MAX_SPS_COUNT].iSpsId], &pCtx->sSpsBuffer[MAX_SPS_COUNT], sizeof (SSps));
2180 pDqLayer->uiRefLayerChromaPhaseXPlus1Flag = pShExt->uiRefLayerChromaPhaseXPlus1Flag;2180 pCtx->bNewSeqBegin = true;
2181 pDqLayer->uiRefLayerChromaPhaseYPlus1 = pShExt->uiRefLayerChromaPhaseYPlus1;2181 }
2182 //memcpy(&pDqLayer->sScaledRefLayer, &pShExt->sScaledRefLayer, sizeof(SPosOffset));//confirmed_safe_unsafe_usage2182 if (pCtx->iOverwriteFlags & OVERWRITE_SUBSETSPS) {
2183 2183 memcpy (&pCtx->sSubsetSpsBuffer[pCtx->sSubsetSpsBuffer[MAX_SPS_COUNT].sSps.iSpsId],
2184 if (kuiQualityId == BASE_QUALITY_ID) {2184 &pCtx->sSubsetSpsBuffer[MAX_SPS_COUNT], sizeof (SSubsetSps));
2185 pDqLayer->pRefPicListReordering = &pSh->pRefPicListReordering;2185 pCtx->bNewSeqBegin = true;
2186 pDqLayer->pRefPicMarking = &pSh->sRefMarking;2186 }
2187 2187 pCtx->iOverwriteFlags = OVERWRITE_NONE;
2188 if (pSh->pPps->bWeightedPredFlag) {2188}
2189 pDqLayer->bUseWeightPredictionFlag = true;2189
2190 pDqLayer->pPredWeightTable = &pSh->sPredWeightTable;2190/*
2191 2191 * DecodeFinishUpdate
2192 } else2192 * decoder finish decoding, update active parameter sets and new seq status
2193 pDqLayer->bUseWeightPredictionFlag = false;2193 *
2194 2194 */
2195 pDqLayer->pRefPicBaseMarking = &pShExt->sRefBasePicMarking;2195
2196 }2196void DecodeFinishUpdate (PWelsDecoderContext pCtx) {
2197 2197 pCtx->bNewSeqBegin = false;
2198 pDqLayer->uiLayerDqId = pNalHdrExt->uiLayerDqId; // dq_id of current layer2198 WriteBackActiveParameters (pCtx);
2199 pDqLayer->bUseRefBasePicFlag = pNalHdrExt->bUseRefBasePicFlag;2199 pCtx->bNewSeqBegin = pCtx->bNewSeqBegin || pCtx->bNextNewSeqBegin;
2200}2200 pCtx->bNextNewSeqBegin = false; // reset it
2201 2201 if (pCtx->bNewSeqBegin)
2202void WelsDqLayerDecodeStart (PWelsDecoderContext pCtx, PNalUnit pCurNal, PSps pSps, PPps pPps) {2202 ResetActiveSPSForEachLayer (pCtx);
2203 PSliceHeader pSh = &pCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader;2203}
2204 2204
2205 pCtx->eSliceType = pSh->eSliceType;2205/*
2206 pCtx->pSliceHeader = pSh;2206 * ConstructAccessUnit
2207 2207 * construct an access unit for given input bitstream, maybe partial NAL Unit, one or more Units are involved to
2208 pCtx->iFrameNum = pSh->iFrameNum;2208 * joint a collective access unit.
2209 2209 * parameter\
2210 UpdateDecoderStatisticsForActiveParaset (& (pCtx->sDecoderStatistics),2210 * buf: bitstream data buffer
2211 pSps, pPps);2211 * bit_len: size in bit length of data
2212}2212 * buf_len: size in byte length of data
2213 2213 * coded_au: mark an Access Unit decoding finished
2214int32_t InitRefPicList (PWelsDecoderContext pCtx, const uint8_t kuiNRi, int32_t iPoc) {2214 * return:
2215 int32_t iRet = ERR_NONE;2215 * 0 - success; otherwise returned error_no defined in error_no.h
2216 iRet = WelsInitRefList (pCtx, iPoc);2216 */
2217 if ((pCtx->eSliceType != I_SLICE && pCtx->eSliceType != SI_SLICE)) {2217int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {
2218 iRet = WelsReorderRefList (pCtx);2218 int32_t iErr;
2219 }2219 PAccessUnit pCurAu = pCtx->pAccessUnitList;
2220 2220 pCtx->bAuReadyFlag = false;
2221 return iRet;2221 pCtx->bLastHasMmco5 = false;
2222}2222 bool bTmpNewSeqBegin = CheckNewSeqBeginAndUpdateActiveLayerSps (pCtx);
2223 2223 pCtx->bNewSeqBegin = pCtx->bNewSeqBegin || bTmpNewSeqBegin;
2224void InitCurDqLayerData (PWelsDecoderContext pCtx, PDqLayer pCurDq) {2224 iErr = WelsDecodeAccessUnitStart (pCtx);
2225 if (NULL != pCtx && NULL != pCurDq) {2225 GetVclNalTemporalId (pCtx);
2226 pCurDq->pMbType = pCtx->sMb.pMbType[0];2226
2227 pCurDq->pSliceIdc = pCtx->sMb.pSliceIdc[0];2227 if (ERR_NONE != iErr) {
2228 pCurDq->pMv[0] = pCtx->sMb.pMv[0][0];2228 ForceResetCurrentAccessUnit (pCtx->pAccessUnitList);
2229 pCurDq->pRefIndex[0] = pCtx->sMb.pRefIndex[0][0];2229 if (!pCtx->pParam->bParseOnly)
2230 pCurDq->pNoSubMbPartSizeLessThan8x8Flag = pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[0];2230 pDstInfo->iBufferStatus = 0;
2231 pCurDq->pTransformSize8x8Flag = pCtx->sMb.pTransformSize8x8Flag[0];2231 pCtx->bNewSeqBegin = pCtx->bNewSeqBegin || pCtx->bNextNewSeqBegin;
2232 pCurDq->pLumaQp = pCtx->sMb.pLumaQp[0];2232 pCtx->bNextNewSeqBegin = false; // reset it
2233 pCurDq->pChromaQp = pCtx->sMb.pChromaQp[0];2233 if (pCtx->bNewSeqBegin)
2234 pCurDq->pMvd[0] = pCtx->sMb.pMvd[0][0];2234 ResetActiveSPSForEachLayer (pCtx);
2235 pCurDq->pCbfDc = pCtx->sMb.pCbfDc[0];2235 return iErr;
2236 pCurDq->pNzc = pCtx->sMb.pNzc[0];2236 }
2237 pCurDq->pNzcRs = pCtx->sMb.pNzcRs[0];2237
2238 pCurDq->pScaledTCoeff = pCtx->sMb.pScaledTCoeff[0];2238 pCtx->pSps = pCurAu->pNalUnitsList[pCurAu->uiStartPos]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pSps;
2239 pCurDq->pIntraPredMode = pCtx->sMb.pIntraPredMode[0];2239 pCtx->pPps = pCurAu->pNalUnitsList[pCurAu->uiStartPos]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pPps;
2240 pCurDq->pIntra4x4FinalMode = pCtx->sMb.pIntra4x4FinalMode[0];2240
2241 pCurDq->pIntraNxNAvailFlag = pCtx->sMb.pIntraNxNAvailFlag[0];2241 //try to allocate or relocate DPB memory only when new sequence is coming.
2242 pCurDq->pChromaPredMode = pCtx->sMb.pChromaPredMode[0];2242 if (pCtx->bNewSeqBegin) {
2243 pCurDq->pCbp = pCtx->sMb.pCbp[0];2243 WelsResetRefPic (pCtx); //clear ref pPic when IDR NAL
2244 pCurDq->pSubMbType = pCtx->sMb.pSubMbType[0];2244 iErr = SyncPictureResolutionExt (pCtx, pCtx->pSps->iMbWidth, pCtx->pSps->iMbHeight);
2245 pCurDq->pInterPredictionDoneFlag = pCtx->sMb.pInterPredictionDoneFlag[0];2245
2246 pCurDq->pResidualPredFlag = pCtx->sMb.pResidualPredFlag[0];2246 if (ERR_NONE != iErr) {
2247 pCurDq->pMbCorrectlyDecodedFlag = pCtx->sMb.pMbCorrectlyDecodedFlag[0];2247 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "sync picture resolution ext failed, the error is %d", iErr);
2248 pCurDq->pMbRefConcealedFlag = pCtx->sMb.pMbRefConcealedFlag[0];2248 return iErr;
2249 }2249 }
2250}2250 }
2251 2251
2252/*2252 iErr = DecodeCurrentAccessUnit (pCtx, ppDst, pDstInfo);
2253 * DecodeCurrentAccessUnit2253
2254 * Decode current access unit when current AU is completed.2254 WelsDecodeAccessUnitEnd (pCtx);
2255 */2255
2256int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {2256 if (ERR_NONE != iErr) {
2257 int32_t iRefCount[LIST_A];2257 WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "returned error from decoding:[0x%x]", iErr);
2258 PNalUnit pNalCur = NULL;2258 return iErr;
2259 PAccessUnit pCurAu = pCtx->pAccessUnitList;2259 }
2260 2260
2261 int32_t iIdx = pCurAu->uiStartPos;2261 return ERR_NONE;
2262 int32_t iEndIdx = pCurAu->uiEndPos;2262}
2263 2263
2264 int32_t iPpsId = 0;2264static inline void InitDqLayerInfo (PDqLayer pDqLayer, PLayerInfo pLayerInfo, PNalUnit pNalUnit, PPicture pPicDec) {
2265 int32_t iRet = ERR_NONE;2265 PNalUnitHeaderExt pNalHdrExt = &pNalUnit->sNalHeaderExt;
2266 2266 PSliceHeaderExt pShExt = &pNalUnit->sNalData.sVclNal.sSliceHeaderExt;
2267 bool bAllRefComplete = true; // Assume default all ref picutres are complete2267 PSliceHeader pSh = &pShExt->sSliceHeader;
2268 2268 const uint8_t kuiQualityId = pNalHdrExt->uiQualityId;
2269 const uint8_t kuiTargetLayerDqId = GetTargetDqId (pCtx->uiTargetDqId, pCtx->pParam);2269
2270 const uint8_t kuiDependencyIdMax = (kuiTargetLayerDqId & 0x7F) >> 4;2270 memcpy (&pDqLayer->sLayerInfo, pLayerInfo, sizeof (SLayerInfo)); //confirmed_safe_unsafe_usage
2271 int16_t iLastIdD = -1, iLastIdQ = -1;2271
2272 int16_t iCurrIdD = 0, iCurrIdQ = 0;2272 pDqLayer->pDec = pPicDec;
2273 uint8_t uiNalRefIdc = 0;2273 pDqLayer->iMbWidth = pSh->iMbWidth; // MB width of this picture
2274 bool bFreshSliceAvailable =2274 pDqLayer->iMbHeight = pSh->iMbHeight;// MB height of this picture
2275 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/20082275
2276 2276 pDqLayer->iSliceIdcBackup = (pSh->iFirstMbInSlice << 7) | (pNalHdrExt->uiDependencyId << 4) | (pNalHdrExt->uiQualityId);
2277 //update pCurDqLayer at the starting of AU decoding2277
2278 if (pCtx->bInitialDqLayersMem) {2278 /* Common syntax elements across all slices of a DQLayer */
2279 pCtx->pCurDqLayer = pCtx->pDqLayersList[0];2279 pDqLayer->uiPpsId = pLayerInfo->pPps->iPpsId;
2280 }2280 pDqLayer->uiDisableInterLayerDeblockingFilterIdc = pShExt->uiDisableInterLayerDeblockingFilterIdc;
2281 2281 pDqLayer->iInterLayerSliceAlphaC0Offset = pShExt->iInterLayerSliceAlphaC0Offset;
2282 InitCurDqLayerData (pCtx, pCtx->pCurDqLayer);2282 pDqLayer->iInterLayerSliceBetaOffset = pShExt->iInterLayerSliceBetaOffset;
2283 2283 pDqLayer->iSliceGroupChangeCycle = pSh->iSliceGroupChangeCycle;
2284 pNalCur = pCurAu->pNalUnitsList[iIdx];2284 pDqLayer->bStoreRefBasePicFlag = pShExt->bStoreRefBasePicFlag;
2285 while (iIdx <= iEndIdx) {2285 pDqLayer->bTCoeffLevelPredFlag = pShExt->bTCoeffLevelPredFlag;
2286 PDqLayer dq_cur = pCtx->pCurDqLayer;2286 pDqLayer->bConstrainedIntraResamplingFlag = pShExt->bConstrainedIntraResamplingFlag;
2287 SLayerInfo pLayerInfo;2287 pDqLayer->uiRefLayerDqId = pShExt->uiRefLayerDqId;
2288 PSliceHeaderExt pShExt = NULL;2288 pDqLayer->uiRefLayerChromaPhaseXPlus1Flag = pShExt->uiRefLayerChromaPhaseXPlus1Flag;
2289 PSliceHeader pSh = NULL;2289 pDqLayer->uiRefLayerChromaPhaseYPlus1 = pShExt->uiRefLayerChromaPhaseYPlus1;
2290 2290 pDqLayer->bUseWeightPredictionFlag = false;
2291 if (pCtx->pDec == NULL) {2291 pDqLayer->bUseWeightedBiPredIdc = false;
2292 pCtx->pDec = PrefetchPic (pCtx->pPicBuff[0]);2292 //memcpy(&pDqLayer->sScaledRefLayer, &pShExt->sScaledRefLayer, sizeof(SPosOffset));//confirmed_safe_unsafe_usage
2293 if (pCtx->iTotalNumMbRec != 0)2293
2294 pCtx->iTotalNumMbRec = 0;2294 if (kuiQualityId == BASE_QUALITY_ID) {
2295 2295 pDqLayer->pRefPicListReordering = &pSh->pRefPicListReordering;
2296 if (NULL == pCtx->pDec) {2296 pDqLayer->pRefPicMarking = &pSh->sRefMarking;
2297 WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR,2297
2298 "DecodeCurrentAccessUnit()::::::PrefetchPic ERROR, pSps->iNumRefFrames:%d.",2298 pDqLayer->bUseWeightPredictionFlag = pSh->pPps->bWeightedPredFlag;
2299 pCtx->pSps->iNumRefFrames);2299 pDqLayer->bUseWeightedBiPredIdc = pSh->pPps->uiWeightedBipredIdc != 0;
2300 // The error code here need to be separated from the dsOutOfMemory2300 if (pSh->pPps->bWeightedPredFlag || pSh->pPps->uiWeightedBipredIdc) {
2301 pCtx->iErrorCode |= dsOutOfMemory;2301 pDqLayer->pPredWeightTable = &pSh->sPredWeightTable;
2302 return ERR_INFO_REF_COUNT_OVERFLOW;2302 }
2303 }2303 pDqLayer->pRefPicBaseMarking = &pShExt->sRefBasePicMarking;
2304 pCtx->pDec->bNewSeqBegin = pCtx->bNewSeqBegin; //set flag for start decoding2304 }
2305 } else if (pCtx->iTotalNumMbRec == 0) { //pDec != NULL, already start2305
2306 pCtx->pDec->bNewSeqBegin = pCtx->bNewSeqBegin; //set flag for start decoding2306 pDqLayer->uiLayerDqId = pNalHdrExt->uiLayerDqId; // dq_id of current layer
2307 }2307 pDqLayer->bUseRefBasePicFlag = pNalHdrExt->bUseRefBasePicFlag;
2308 pCtx->pDec->uiTimeStamp = pNalCur->uiTimeStamp;2308}
2309 2309
2310 if (pCtx->iTotalNumMbRec == 0) { //Picture start to decode2310void WelsDqLayerDecodeStart (PWelsDecoderContext pCtx, PNalUnit pCurNal, PSps pSps, PPps pPps) {
2311 for (int32_t i = 0; i < LAYER_NUM_EXCHANGEABLE; ++ i)2311 PSliceHeader pSh = &pCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader;
2312 memset (pCtx->sMb.pSliceIdc[i], 0xff, (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t)));2312
2313 memset (pCtx->pCurDqLayer->pMbCorrectlyDecodedFlag, 0, pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight * sizeof (bool));2313 pCtx->eSliceType = pSh->eSliceType;
2314 memset (pCtx->pCurDqLayer->pMbRefConcealedFlag, 0, pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight * sizeof (bool));2314 pCtx->pSliceHeader = pSh;
2315 pCtx->pDec->iMbNum = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;2315 pCtx->bUsedAsRef = false;
2316 pCtx->pDec->iMbEcedNum = 0;2316
2317 pCtx->pDec->iMbEcedPropNum = 0;2317 pCtx->iFrameNum = pSh->iFrameNum;
2318 }2318 UpdateDecoderStatisticsForActiveParaset (& (pCtx->sDecoderStatistics),
2319 pCtx->bRPLRError = false;2319 pSps, pPps);
2320 GetI4LumaIChromaAddrTable (pCtx->iDecBlockOffsetArray, pCtx->pDec->iLinesize[0], pCtx->pDec->iLinesize[1]);2320}
2321 2321
2322 if (pNalCur->sNalHeaderExt.uiLayerDqId > kuiTargetLayerDqId) { // confirmed pNalCur will never be NULL2322int32_t InitRefPicList (PWelsDecoderContext pCtx, const uint8_t kuiNRi, int32_t iPoc) {
2323 break; // Per formance it need not to decode the remaining bits any more due to given uiLayerDqId required, 9/2/20092323 int32_t iRet = ERR_NONE;
2324 }2324 if (pCtx->eSliceType == B_SLICE) {
2325 2325 iRet = WelsInitBSliceRefList (pCtx, iPoc);
2326 memset (&pLayerInfo, 0, sizeof (SLayerInfo));2326 CreateImplicitWeightTable (pCtx);
2327 2327 } else
2328 /*2328 iRet = WelsInitRefList (pCtx, iPoc);
2329 * Loop decoding for slices (even FMO and/ multiple slices) within a dq layer2329 if ((pCtx->eSliceType != I_SLICE && pCtx->eSliceType != SI_SLICE)) {
2330 */2330 iRet = WelsReorderRefList (pCtx);
2331 while (iIdx <= iEndIdx) {2331 }
2332 bool bReconstructSlice;2332
2333 iCurrIdQ = pNalCur->sNalHeaderExt.uiQualityId;2333 return iRet;
2334 iCurrIdD = pNalCur->sNalHeaderExt.uiDependencyId;2334}
2335 pSh = &pNalCur->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader;2335
2336 pShExt = &pNalCur->sNalData.sVclNal.sSliceHeaderExt;2336void InitCurDqLayerData (PWelsDecoderContext pCtx, PDqLayer pCurDq) {
2337 pCtx->bRPLRError = false;2337 if (NULL != pCtx && NULL != pCurDq) {
2338 bReconstructSlice = CheckSliceNeedReconstruct (pNalCur->sNalHeaderExt.uiLayerDqId, kuiTargetLayerDqId);2338 pCurDq->pMbType = pCtx->sMb.pMbType[0];
2339 2339 pCurDq->pSliceIdc = pCtx->sMb.pSliceIdc[0];
2340 memcpy (&pLayerInfo.sNalHeaderExt, &pNalCur->sNalHeaderExt, sizeof (SNalUnitHeaderExt)); //confirmed_safe_unsafe_usage2340 pCurDq->pMv[LIST_0] = pCtx->sMb.pMv[0][LIST_0];
2341 2341 pCurDq->pMv[LIST_1] = pCtx->sMb.pMv[0][LIST_1];
2342 pCtx->pDec->iFrameNum = pSh->iFrameNum;2342 pCurDq->pRefIndex[LIST_0] = pCtx->sMb.pRefIndex[0][LIST_0];
2343 pCtx->pDec->iFramePoc = pSh->iPicOrderCntLsb; // still can not obtain correct, because current do not support POCtype 22343 pCurDq->pRefIndex[LIST_1] = pCtx->sMb.pRefIndex[0][LIST_1];
2344 pCtx->pDec->bIdrFlag = pNalCur->sNalHeaderExt.bIdrFlag;2344 pCurDq->pDirect = pCtx->sMb.pDirect[0];
2345 2345 pCurDq->pNoSubMbPartSizeLessThan8x8Flag = pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[0];
2346 memcpy (&pLayerInfo.sSliceInLayer.sSliceHeaderExt, pShExt, sizeof (SSliceHeaderExt)); //confirmed_safe_unsafe_usage2346 pCurDq->pTransformSize8x8Flag = pCtx->sMb.pTransformSize8x8Flag[0];
2347 pLayerInfo.sSliceInLayer.bSliceHeaderExtFlag = pNalCur->sNalData.sVclNal.bSliceHeaderExtFlag;2347 pCurDq->pLumaQp = pCtx->sMb.pLumaQp[0];
2348 pLayerInfo.sSliceInLayer.eSliceType = pSh->eSliceType;2348 pCurDq->pChromaQp = pCtx->sMb.pChromaQp[0];
2349 pLayerInfo.sSliceInLayer.iLastMbQp = pSh->iSliceQp;2349 pCurDq->pMvd[LIST_0] = pCtx->sMb.pMvd[0][LIST_0];
2350 dq_cur->pBitStringAux = &pNalCur->sNalData.sVclNal.sSliceBitsRead;2350 pCurDq->pMvd[LIST_1] = pCtx->sMb.pMvd[0][LIST_1];
2351 2351 pCurDq->pCbfDc = pCtx->sMb.pCbfDc[0];
2352 uiNalRefIdc = pNalCur->sNalHeaderExt.sNalUnitHeader.uiNalRefIdc;2352 pCurDq->pNzc = pCtx->sMb.pNzc[0];
2353 2353 pCurDq->pNzcRs = pCtx->sMb.pNzcRs[0];
2354 iPpsId = pSh->iPpsId;2354 pCurDq->pScaledTCoeff = pCtx->sMb.pScaledTCoeff[0];
2355 2355 pCurDq->pIntraPredMode = pCtx->sMb.pIntraPredMode[0];
2356 pLayerInfo.pPps = pSh->pPps;2356 pCurDq->pIntra4x4FinalMode = pCtx->sMb.pIntra4x4FinalMode[0];
2357 pLayerInfo.pSps = pSh->pSps;2357 pCurDq->pIntraNxNAvailFlag = pCtx->sMb.pIntraNxNAvailFlag[0];
2358 pLayerInfo.pSubsetSps = pShExt->pSubsetSps;2358 pCurDq->pChromaPredMode = pCtx->sMb.pChromaPredMode[0];
2359 2359 pCurDq->pCbp = pCtx->sMb.pCbp[0];
2360 pCtx->pFmo = &pCtx->sFmoList[iPpsId];2360 pCurDq->pSubMbType = pCtx->sMb.pSubMbType[0];
2361 iRet = FmoParamUpdate (pCtx->pFmo, pLayerInfo.pSps, pLayerInfo.pPps, &pCtx->iActiveFmoNum, pCtx->pMemAlign);
2362 if (ERR_NONE != iRet) {
2363 if (iRet == ERR_INFO_OUT_OF_MEMORY) {
2364 pCtx->iErrorCode |= dsOutOfMemory;
2365 WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "DecodeCurrentAccessUnit(), Fmo param alloc failed");
2366 } else {
2367 pCtx->iErrorCode |= dsBitstreamError;
2368 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "DecodeCurrentAccessUnit(), FmoParamUpdate failed, eSliceType: %d.",
2369 pSh->eSliceType);
2370 }
2371 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_FMO_INIT_FAIL);
2372 }
2373
2374 bFreshSliceAvailable = (iCurrIdD != iLastIdD
2375 || iCurrIdQ != iLastIdQ); // do not need condition of (first_mb == 0) due multiple slices might be disorder
2376
2377 WelsDqLayerDecodeStart (pCtx, pNalCur, pLayerInfo.pSps, pLayerInfo.pPps);
2378
2379 if (iCurrIdQ == BASE_QUALITY_ID) {
2380 ST64 (iRefCount, LD64 (pLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.uiRefCount));
2381 }
2382
2383 if ((iLastIdD < 0) || //case 1: first layer
2384 (iLastIdD == iCurrIdD)) { //case 2: same uiDId
2385 InitDqLayerInfo (dq_cur, &pLayerInfo, pNalCur, pCtx->pDec);
2386
2387 if (!dq_cur->sLayerInfo.pSps->bGapsInFrameNumValueAllowedFlag) {
2388 const bool kbIdrFlag = dq_cur->sLayerInfo.sNalHeaderExt.bIdrFlag
2389 || (dq_cur->sLayerInfo.sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR);
2390 // Subclause 8.2.5.2 Decoding process for gaps in frame_num
2391 if (!kbIdrFlag &&
2392 pSh->iFrameNum != pCtx->iPrevFrameNum &&
2393 pSh->iFrameNum != ((pCtx->iPrevFrameNum + 1) & ((1 << dq_cur->sLayerInfo.pSps->uiLog2MaxFrameNum) - 1))) {
2394 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
2395 "referencing pictures lost due frame gaps exist, prev_frame_num: %d, curr_frame_num: %d", pCtx->iPrevFrameNum,
2396 pSh->iFrameNum);
2397
2398 bAllRefComplete = false;
2399 pCtx->iErrorCode |= dsRefLost;
2400 if (pCtx->pParam->eEcActiveIdc == ERROR_CON_DISABLE) {
2401#ifdef LONG_TERM_REF
2402 pCtx->bParamSetsLostFlag = true;
2403#else
2404 pCtx->bReferenceLostAtT0Flag = true;
2405#endif
2406 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_REFERENCE_PIC_LOST);
2407 }
2408 }
2409 }
2410
2411 if (iCurrIdD == kuiDependencyIdMax && iCurrIdQ == BASE_QUALITY_ID) {
2412 iRet = InitRefPicList (pCtx, uiNalRefIdc, pSh->iPicOrderCntLsb);
2413 if (iRet) {
2414 pCtx->bRPLRError = true;
2415 bAllRefComplete = false; // RPLR error, set ref pictures complete flag false
2416 HandleReferenceLost (pCtx, pNalCur);
2417 WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
2418 "reference picture introduced by this frame is lost during transmission! uiTId: %d",
2419 pNalCur->sNalHeaderExt.uiTemporalId);
2420 if (pCtx->pParam->eEcActiveIdc == ERROR_CON_DISABLE) {
2421 if (pCtx->iTotalNumMbRec == 0)
2422 pCtx->pDec = NULL;
2423 return iRet;
2424 }
2425 }
2426 }
2427
2428 iRet = WelsDecodeSlice (pCtx, bFreshSliceAvailable, pNalCur);
2429
2430 //Output good store_base reconstruction when enhancement quality layer occurred error for MGS key picture case
2431 if (iRet != ERR_NONE) {
2432 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
2433 "DecodeCurrentAccessUnit() failed (%d) in frame: %d uiDId: %d uiQId: %d",
2434 iRet, pSh->iFrameNum, iCurrIdD, iCurrIdQ);
2435 bAllRefComplete = false;
2436 HandleReferenceLostL0 (pCtx, pNalCur);
2437 if (pCtx->pParam->eEcActiveIdc == ERROR_CON_DISABLE) {
2438 if (pCtx->iTotalNumMbRec == 0)
2439 pCtx->pDec = NULL;
2440 return iRet;
2441 }
2442 }
2443
2444 if (bReconstructSlice) {
2445 if ((iRet = WelsDecodeConstructSlice (pCtx, pNalCur)) != ERR_NONE) {
2446 pCtx->pDec->bIsComplete = false; // reconstruction error, directly set the flag false
2447 return iRet;
2448 }
2449 }
2450 if (bAllRefComplete && pCtx->eSliceType != I_SLICE) {
2451 if (pCtx->sRefPic.uiRefCount[LIST_0] > 0) {
2452 bAllRefComplete &= CheckRefPicturesComplete (pCtx);
2453 } else {
2454 bAllRefComplete = false;
2455 }
2456 }
2457 }
2458#if defined (_DEBUG) && !defined (CODEC_FOR_TESTBED)
2459 WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "cur_frame : %d\tiCurrIdD : %d\n ",
2460 dq_cur->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iFrameNum, iCurrIdD);
2461#endif//#if !CODEC_FOR_TESTBED
2462 iLastIdD = iCurrIdD;
2463 iLastIdQ = iCurrIdQ;
2464
2465 //pNalUnitsList overflow.
2466 ++ iIdx;
2467 if (iIdx <= iEndIdx) {
2468 pNalCur = pCurAu->pNalUnitsList[iIdx];
2469 } else {
2470 pNalCur = NULL;
2471 }
2472
2473 if (pNalCur == NULL ||
2474 iLastIdD != pNalCur->sNalHeaderExt.uiDependencyId ||
2475 iLastIdQ != pNalCur->sNalHeaderExt.uiQualityId)
2476 break;
2477 }
2478
2479 // Set the current dec picture complete flag. The flag will be reset when current picture need do ErrorCon.
2480 pCtx->pDec->bIsComplete = bAllRefComplete;
2481 if (!pCtx->pDec->bIsComplete) { // Ref pictures ECed, result in ECed
2482 pCtx->iErrorCode |= dsDataErrorConcealed;
2483 }
2484
2485 // A dq layer decoded here
2486#if defined (_DEBUG) && !defined (CODEC_FOR_TESTBED)
2487#undef fprintf
2488 WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "POC: #%d, FRAME: #%d, D: %d, Q: %d, T: %d, P: %d, %d\n",
2489 pSh->iPicOrderCntLsb, pSh->iFrameNum, iCurrIdD, iCurrIdQ, dq_cur->sLayerInfo.sNalHeaderExt.uiTemporalId,
2490 dq_cur->sLayerInfo.sNalHeaderExt.uiPriorityId, dq_cur->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iSliceQp);
2491#endif//#if !CODEC_FOR_TESTBED
2492
2493 if (dq_cur->uiLayerDqId == kuiTargetLayerDqId) {
2494 if (!pCtx->bInstantDecFlag) {
2495 if (!pCtx->pParam->bParseOnly) {
2496 //Do error concealment here
2497 if ((NeedErrorCon (pCtx)) && (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE)) {
2498 ImplementErrorCon (pCtx);
2499 pCtx->iTotalNumMbRec = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
2500 pCtx->pDec->iSpsId = pCtx->pSps->iSpsId;
2501 pCtx->pDec->iPpsId = pCtx->pPps->iPpsId;
2502 }
2503 }
2504 }
2505
2506 iRet = DecodeFrameConstruction (pCtx, ppDst, pDstInfo);
2507 if (iRet)
2508 return iRet;
2509
2510 pCtx->pPreviousDecodedPictureInDpb = pCtx->pDec; //store latest decoded picture for EC
2511 if (uiNalRefIdc > 0) {
2512 iRet = WelsMarkAsRef (pCtx);
2513 if (iRet != ERR_NONE) {
2514 if (iRet == ERR_INFO_DUPLICATE_FRAME_NUM)
2515 pCtx->iErrorCode |= dsBitstreamError;
2516 if (pCtx->pParam->eEcActiveIdc == ERROR_CON_DISABLE) {
2517 pCtx->pDec = NULL;
2518 return iRet;
2519 }
2520 }
2521 if (!pCtx->pParam->bParseOnly)
2522 ExpandReferencingPicture (pCtx->pDec->pData, pCtx->pDec->iWidthInPixel, pCtx->pDec->iHeightInPixel,
2523 pCtx->pDec->iLinesize,
2524 pCtx->sExpandPicFunc.pfExpandLumaPicture, pCtx->sExpandPicFunc.pfExpandChromaPicture);
2525 }
2526 pCtx->pDec = NULL; //after frame decoding, always set to NULL
2527 }
2528
2529 // need update frame_num due current frame is well decoded
2530 if (pCurAu->pNalUnitsList[pCurAu->uiStartPos]->sNalHeaderExt.sNalUnitHeader.uiNalRefIdc > 0)
2531 pCtx->iPrevFrameNum = pSh->iFrameNum;
2532 if (pCtx->bLastHasMmco5)
2533 pCtx->iPrevFrameNum = 0;
2534 }
2535
2536 return ERR_NONE;
2537}
2538
2539bool CheckAndFinishLastPic (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {
2540 PAccessUnit pAu = pCtx->pAccessUnitList;
2541 bool bAuBoundaryFlag = false;
2542 if (IS_VCL_NAL (pCtx->sCurNalHead.eNalUnitType, 1)) { //VCL data, AU list should have data
2543 PNalUnit pCurNal = pAu->pNalUnitsList[pAu->uiEndPos];
2544 bAuBoundaryFlag = (pCtx->iTotalNumMbRec != 0)
2545 && (CheckAccessUnitBoundaryExt (&pCtx->sLastNalHdrExt, &pCurNal->sNalHeaderExt, &pCtx->sLastSliceHeader,
2546 &pCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader));
2547 } else { //non VCL
2548 if (pCtx->sCurNalHead.eNalUnitType == NAL_UNIT_AU_DELIMITER) {
2549 bAuBoundaryFlag = true;
2550 } else if (pCtx->sCurNalHead.eNalUnitType == NAL_UNIT_SEI) {
2551 bAuBoundaryFlag = true;
2552 } else if (pCtx->sCurNalHead.eNalUnitType == NAL_UNIT_SPS) {
2553 bAuBoundaryFlag = !! (pCtx->iOverwriteFlags & OVERWRITE_SPS);
2554 } else if (pCtx->sCurNalHead.eNalUnitType == NAL_UNIT_SUBSET_SPS) {
2555 bAuBoundaryFlag = !! (pCtx->iOverwriteFlags & OVERWRITE_SUBSETSPS);
2556 } else if (pCtx->sCurNalHead.eNalUnitType == NAL_UNIT_PPS) {
2557 bAuBoundaryFlag = !! (pCtx->iOverwriteFlags & OVERWRITE_PPS);
2558 }
2559 if (bAuBoundaryFlag && pCtx->pAccessUnitList->uiAvailUnitsNum != 0) { //Construct remaining data first
2560 ConstructAccessUnit (pCtx, ppDst, pDstInfo);
2561 }
2562 }
2563
2564 //Do Error Concealment here
2565 if (bAuBoundaryFlag && (pCtx->iTotalNumMbRec != 0) && NeedErrorCon (pCtx)) { //AU ready but frame not completely reconed
2566 if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
2567 ImplementErrorCon (pCtx);
2568 pCtx->iTotalNumMbRec = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
2569 pCtx->pDec->iSpsId = pCtx->pSps->iSpsId;
2570 pCtx->pDec->iPpsId = pCtx->pPps->iPpsId;
2571
2572 DecodeFrameConstruction (pCtx, ppDst, pDstInfo);
2573 pCtx->pPreviousDecodedPictureInDpb = pCtx->pDec; //save ECed pic for future use
2574 if (pCtx->sLastNalHdrExt.sNalUnitHeader.uiNalRefIdc > 0) {
2575 MarkECFrameAsRef (pCtx);
2576 }
2577 } else if (pCtx->pParam->bParseOnly) { //clear parse only internal data status
2578 pCtx->pParserBsInfo->iNalNum = 0;
2579 pCtx->bFrameFinish = true; //clear frame pending status here!
2580 } else {
2581 if (DecodeFrameConstruction (pCtx, ppDst, pDstInfo)) {
2582 if ((pCtx->sLastNalHdrExt.sNalUnitHeader.uiNalRefIdc > 0) && (pCtx->sLastNalHdrExt.uiTemporalId == 0))
2583 pCtx->iErrorCode |= dsNoParamSets;
2584 else
2585 pCtx->iErrorCode |= dsBitstreamError;
2586 pCtx->pDec = NULL;
2587 return false;
2588 }
2589 }
2590 pCtx->pDec = NULL;
2591 if (pAu->pNalUnitsList[pAu->uiStartPos]->sNalHeaderExt.sNalUnitHeader.uiNalRefIdc > 0)
2592 pCtx->iPrevFrameNum = pCtx->sLastSliceHeader.iFrameNum; //save frame_num
2593 if (pCtx->bLastHasMmco5)
2594 pCtx->iPrevFrameNum = 0;
2595 }
2596 return ERR_NONE;
2597}
2598
2599bool CheckRefPicturesComplete (PWelsDecoderContext pCtx) {
2600 // Multi Reference, RefIdx may differ
2601 bool bAllRefComplete = true;
2602 int32_t iRealMbIdx = pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iFirstMbInSlice;
2603 for (int32_t iMbIdx = 0; bAllRefComplete
2604 && iMbIdx < pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer.iTotalMbInCurSlice; iMbIdx++) {
2605 switch (pCtx->pCurDqLayer->pMbType[iRealMbIdx]) {
2606 case MB_TYPE_SKIP:
2607 case MB_TYPE_16x16:
2608 bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][0] ]->bIsComplete;
2609 break;
2610
2611 case MB_TYPE_16x8:
2612 bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][0] ]->bIsComplete;
2613 bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][8] ]->bIsComplete;
2614 break;
2615
2616 case MB_TYPE_8x16:
2617 bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][0] ]->bIsComplete;
2618 bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][2] ]->bIsComplete;
2619 break;
2620
2621 case MB_TYPE_8x8:
2622 case MB_TYPE_8x8_REF0:
2623 bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][0] ]->bIsComplete;
2624 bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][2] ]->bIsComplete;
2625 bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][8] ]->bIsComplete;
2626 bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][10] ]->bIsComplete;
2627 break;
2628
2629 default:
2630 break;
2631 }
2632 iRealMbIdx = (pCtx->pPps->uiNumSliceGroups > 1) ? FmoNextMb (pCtx->pFmo, iRealMbIdx) :
2633 (pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iFirstMbInSlice + iMbIdx);
2634 if (iRealMbIdx == -1) //caused by abnormal return of FmoNextMb()
2635 return false;
2636 }
2637 return bAllRefComplete;
2638}
2639} // namespace WelsDec

412 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