History

Restore unix newlines after "Merge pull request #2991 from xiaotianshi2/master"

Some newlines were fixed in "Merge pull request #2997 from GuangweiWang/fix-issue-external", but lots were still left behind.

Martin Storsjö committed 8 years ago

Commit 1fb2f7d1 parent d43bfc114 files · +9238 −9238Browse files

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

Unified · Split

codec/decoder/core/src/manage_dec_ref.cpp+897−897
@@ -1,897 +1,897 @@
1−/*!
2− * \copy
3− * Copyright (c) 2008-2013, Cisco Systems
4− * All rights reserved.
5− *
6− * Redistribution and use in source and binary forms, with or without
7− * modification, are permitted provided that the following conditions
8− * are met:
9− *
10− * * Redistributions of source code must retain the above copyright
11− * notice, this list of conditions and the following disclaimer.
12− *
13− * * Redistributions in binary form must reproduce the above copyright
14− * notice, this list of conditions and the following disclaimer in
15− * the documentation and/or other materials provided with the
16− * distribution.
17− *
18− * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19− * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20− * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21− * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22− * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23− * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24− * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25− * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26− * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27− * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28− * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29− * POSSIBILITY OF SUCH DAMAGE.
30− *
31− *
32− * manage_dec_ref.cpp
33− *
34− * Abstract
35− * Implementation for managing reference picture
36− *
37− * History
38− * 07/21/2008 Created
39− *
40− *****************************************************************************/
41−
42−#include "manage_dec_ref.h"
43−#include "error_concealment.h"
44−#include "error_code.h"
45−
46−namespace WelsDec {
47−
48−static PPicture WelsDelShortFromList (PRefPic pRefPic, int32_t iFrameNum);
49−static PPicture WelsDelLongFromList (PRefPic pRefPic, uint32_t uiLongTermFrameIdx);
50−static PPicture WelsDelShortFromListSetUnref (PRefPic pRefPic, int32_t iFrameNum);
51−static PPicture WelsDelLongFromListSetUnref (PRefPic pRefPic, uint32_t uiLongTermFrameIdx);
52−
53−static int32_t MMCO (PWelsDecoderContext pCtx, PRefPicMarking pRefPicMarking);
54−static int32_t MMCOProcess (PWelsDecoderContext pCtx, uint32_t uiMmcoType,
55− int32_t iShortFrameNum, uint32_t uiLongTermPicNum, int32_t iLongTermFrameIdx, int32_t iMaxLongTermFrameIdx);
56−static int32_t SlidingWindow (PWelsDecoderContext pCtx);
57−
58−static int32_t AddShortTermToList (PRefPic pRefPic, PPicture pPic);
59−static int32_t AddLongTermToList (PRefPic pRefPic, PPicture pPic, int32_t iLongTermFrameIdx, uint32_t uiLongTermPicNum);
60−static int32_t MarkAsLongTerm (PRefPic pRefPic, int32_t iFrameNum, int32_t iLongTermFrameIdx,
61− uint32_t uiLongTermPicNum);
62−static int32_t WelsCheckAndRecoverForFutureDecoding (PWelsDecoderContext pCtx);
63−#ifdef LONG_TERM_REF
64−int32_t GetLTRFrameIndex (PRefPic pRefPic, int32_t iAncLTRFrameNum);
65−#endif
66−static int32_t RemainOneBufferInDpbForEC (PWelsDecoderContext pCtx);
67−
68−static void SetUnRef (PPicture pRef) {
69− if (NULL != pRef) {
70− pRef->bUsedAsRef = false;
71− pRef->bIsLongRef = false;
72− pRef->iFrameNum = -1;
73− pRef->iFrameWrapNum = -1;
74− //pRef->iFramePoc = 0;
75− pRef->iLongTermFrameIdx = -1;
76− pRef->uiLongTermPicNum = 0;
77− pRef->uiQualityId = -1;
78− pRef->uiTemporalId = -1;
79− pRef->uiSpatialId = -1;
80− pRef->iSpsId = -1;
81− pRef->bIsComplete = false;
82− }
83−}
84−
85−//reset pRefList when
86−// 1.sps arrived that is new sequence starting
87−// 2.IDR NAL i.e. 1st layer in IDR AU
88−
89−void WelsResetRefPic (PWelsDecoderContext pCtx) {
90− int32_t i = 0;
91− PRefPic pRefPic = &pCtx->sRefPic;
92− pCtx->sRefPic.uiLongRefCount[LIST_0] = pCtx->sRefPic.uiShortRefCount[LIST_0] = 0;
93−
94− pRefPic->uiRefCount[LIST_0] = 0;
95− pRefPic->uiRefCount[LIST_1] = 0;
96−
97− for (i = 0; i < MAX_DPB_COUNT; i++) {
98− if (pRefPic->pShortRefList[LIST_0][i] != NULL) {
99− SetUnRef (pRefPic->pShortRefList[LIST_0][i]);
100− pRefPic->pShortRefList[LIST_0][i] = NULL;
101− }
102− }
103− pRefPic->uiShortRefCount[LIST_0] = 0;
104−
105− for (i = 0; i < MAX_DPB_COUNT; i++) {
106− if (pRefPic->pLongRefList[LIST_0][i] != NULL) {
107− SetUnRef (pRefPic->pLongRefList[LIST_0][i]);
108− pRefPic->pLongRefList[LIST_0][i] = NULL;
109− }
110− }
111− pRefPic->uiLongRefCount[LIST_0] = 0;
112−}
113−
114−static int32_t WelsCheckAndRecoverForFutureDecoding (PWelsDecoderContext pCtx) {
115− if ((pCtx->sRefPic.uiShortRefCount[LIST_0] + pCtx->sRefPic.uiLongRefCount[LIST_0] <= 0) && (pCtx->eSliceType != I_SLICE
116− && pCtx->eSliceType != SI_SLICE)) {
117− if (pCtx->pParam->eEcActiveIdc !=
118− ERROR_CON_DISABLE) { //IDR lost!, recover it for future decoding with data all set to 0
119− PPicture pRef = PrefetchPic (pCtx->pPicBuff);
120− if (pRef != NULL) {
121− // IDR lost, set new
122− pRef->bIsComplete = false; // Set complete flag to false for lost IDR ref picture
123− pRef->iSpsId = pCtx->pSps->iSpsId;
124− pRef->iPpsId = pCtx->pPps->iPpsId;
125− pCtx->iErrorCode |= dsDataErrorConcealed;
126− bool bCopyPrevious = ((ERROR_CON_FRAME_COPY_CROSS_IDR == pCtx->pParam->eEcActiveIdc)
127− || (ERROR_CON_SLICE_COPY_CROSS_IDR == pCtx->pParam->eEcActiveIdc)
128− || (ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE == pCtx->pParam->eEcActiveIdc)
129− || (ERROR_CON_SLICE_MV_COPY_CROSS_IDR == pCtx->pParam->eEcActiveIdc)
130− || (ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE == pCtx->pParam->eEcActiveIdc))
131− && (NULL != pCtx->pPreviousDecodedPictureInDpb);
132− bCopyPrevious = bCopyPrevious && (pRef->iWidthInPixel == pCtx->pPreviousDecodedPictureInDpb->iWidthInPixel)
133− && (pRef->iHeightInPixel == pCtx->pPreviousDecodedPictureInDpb->iHeightInPixel);
134−
135− if (!bCopyPrevious) {
136− memset (pRef->pData[0], 128, pRef->iLinesize[0] * pRef->iHeightInPixel);
137− memset (pRef->pData[1], 128, pRef->iLinesize[1] * pRef->iHeightInPixel / 2);
138− memset (pRef->pData[2], 128, pRef->iLinesize[2] * pRef->iHeightInPixel / 2);
139− } else if (pRef == pCtx->pPreviousDecodedPictureInDpb) {
140− WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "WelsInitRefList()::EC memcpy overlap.");
141− } else {
142− memcpy (pRef->pData[0], pCtx->pPreviousDecodedPictureInDpb->pData[0], pRef->iLinesize[0] * pRef->iHeightInPixel);
143− memcpy (pRef->pData[1], pCtx->pPreviousDecodedPictureInDpb->pData[1], pRef->iLinesize[1] * pRef->iHeightInPixel / 2);
144− memcpy (pRef->pData[2], pCtx->pPreviousDecodedPictureInDpb->pData[2], pRef->iLinesize[2] * pRef->iHeightInPixel / 2);
145− }
146− pRef->iFrameNum = 0;
147− pRef->iFramePoc = 0;
148− pRef->uiTemporalId = pRef->uiQualityId = 0;
149− ExpandReferencingPicture (pRef->pData, pRef->iWidthInPixel, pRef->iHeightInPixel, pRef->iLinesize,
150− pCtx->sExpandPicFunc.pfExpandLumaPicture, pCtx->sExpandPicFunc.pfExpandChromaPicture);
151− AddShortTermToList (&pCtx->sRefPic, pRef);
152− } else {
153− WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "WelsInitRefList()::PrefetchPic for EC errors.");
154− pCtx->iErrorCode |= dsOutOfMemory;
155− return ERR_INFO_REF_COUNT_OVERFLOW;
156− }
157− }
158− }
159− return ERR_NONE;
160−}
161−
162−static void WrapShortRefPicNum (PWelsDecoderContext pCtx) {
163− int32_t i;
164− PSliceHeader pSliceHeader = &pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader;
165− int32_t iMaxPicNum = 1 << pSliceHeader->pSps->uiLog2MaxFrameNum;
166− PPicture* ppShoreRefList = pCtx->sRefPic.pShortRefList[LIST_0];
167− int32_t iShortRefCount = pCtx->sRefPic.uiShortRefCount[LIST_0];
168− //wrap pic num
169− for (i = 0; i < iShortRefCount; i++) {
170− if (ppShoreRefList[i]) {
171− if (ppShoreRefList[i]->iFrameNum > pSliceHeader->iFrameNum)
172− ppShoreRefList[i]->iFrameWrapNum = ppShoreRefList[i]->iFrameNum - iMaxPicNum;
173− else
174− ppShoreRefList[i]->iFrameWrapNum = ppShoreRefList[i]->iFrameNum;
175− }
176− }
177−}
178−
179−/**
180−* fills the pRefPic.pRefList LIST_0 and LIST_0 for B-Slice.
181−*/
182−int32_t WelsInitBSliceRefList (PWelsDecoderContext pCtx, int32_t iPoc) {
183−
184− int32_t err = WelsCheckAndRecoverForFutureDecoding (pCtx);
185− if (err != ERR_NONE) return err;
186−
187− WrapShortRefPicNum (pCtx);
188−
189− PPicture* ppShoreRefList = pCtx->sRefPic.pShortRefList[LIST_0];
190− PPicture* ppLongRefList = pCtx->sRefPic.pLongRefList[LIST_0];
191− memset (pCtx->sRefPic.pRefList[LIST_0], 0, MAX_DPB_COUNT * sizeof (PPicture));
192− memset (pCtx->sRefPic.pRefList[LIST_1], 0, MAX_DPB_COUNT * sizeof (PPicture));
193− int32_t iLSCurrPocCount = 0;
194− int32_t iLTCurrPocCount = 0;
195− PPicture pLSCurrPocList0[MAX_DPB_COUNT];
196− PPicture pLTCurrPocList0[MAX_DPB_COUNT];
197− for (int32_t i = 0; i < pCtx->sRefPic.uiShortRefCount[LIST_0]; ++i) {
198− if (ppShoreRefList[i]->iFramePoc < iPoc) {
199− pLSCurrPocList0[iLSCurrPocCount++] = ppShoreRefList[i];
200− }
201− }
202− for (int32_t i = pCtx->sRefPic.uiShortRefCount[LIST_0] - 1; i >= 0; --i) {
203− if (ppShoreRefList[i]->iFramePoc > iPoc) {
204− pLTCurrPocList0[iLTCurrPocCount++] = ppShoreRefList[i];
205− }
206− }
207− if (pCtx->sRefPic.uiLongRefCount[LIST_0] > 1) {
208− //long sorts in increasing order
209− PPicture pTemp;
210− for (int32_t i = 0; i < pCtx->sRefPic.uiLongRefCount[LIST_0]; ++i) {
211− for (int32_t j = i + 1; j < pCtx->sRefPic.uiLongRefCount[LIST_0]; ++j) {
212− if (ppLongRefList[j]->iFramePoc < ppLongRefList[i]->iFramePoc) {
213− pTemp = ppLongRefList[i];
214− ppLongRefList[i] = ppLongRefList[j];
215− ppLongRefList[j] = pTemp;
216− }
217− }
218− }
219− }
220− int32_t iCurrPocCount = iLSCurrPocCount + iLTCurrPocCount;
221− int32_t iCount = 0;
222− //LIST_0
223− //short
224− //It may need to sort LIST_0 and LIST_1 so that they will have the right default orders.
225− for (int32_t i = 0; i < iLSCurrPocCount; ++i) {
226− pCtx->sRefPic.pRefList[LIST_0][iCount++] = pLSCurrPocList0[i];
227− }
228− if (iLSCurrPocCount > 1) {
229− //LIST_0 short sorts in decreasing order
230− PPicture pTemp;
231− for (int32_t i = 0; i < iLSCurrPocCount; ++i) {
232− for (int32_t j = i + 1; j < iLSCurrPocCount; ++j) {
233− if (pCtx->sRefPic.pRefList[LIST_0][j]->iFramePoc > pCtx->sRefPic.pRefList[LIST_0][i]->iFramePoc) {
234− pTemp = pCtx->sRefPic.pRefList[LIST_0][i];
235− pCtx->sRefPic.pRefList[LIST_0][i] = pCtx->sRefPic.pRefList[LIST_0][j];
236− pCtx->sRefPic.pRefList[LIST_0][j] = pTemp;
237− }
238− }
239− }
240− }
241− for (int32_t i = 0; i < iLTCurrPocCount; ++i) {
242− pCtx->sRefPic.pRefList[LIST_0][iCount++] = pLTCurrPocList0[i];
243− }
244− if (iLTCurrPocCount > 1) {
245− //LIST_0 short sorts in increasing order
246− PPicture pTemp;
247− for (int32_t i = iLSCurrPocCount; i < iCurrPocCount; ++i) {
248− for (int32_t j = i + 1; j < iCurrPocCount; ++j) {
249− if (pCtx->sRefPic.pRefList[LIST_0][j]->iFramePoc < pCtx->sRefPic.pRefList[LIST_0][i]->iFramePoc) {
250− pTemp = pCtx->sRefPic.pRefList[LIST_0][i];
251− pCtx->sRefPic.pRefList[LIST_0][i] = pCtx->sRefPic.pRefList[LIST_0][j];
252− pCtx->sRefPic.pRefList[LIST_0][j] = pTemp;
253− }
254− }
255− }
256− }
257− //long
258− for (int32_t i = 0; i < pCtx->sRefPic.uiLongRefCount[LIST_0]; ++i) {
259− pCtx->sRefPic.pRefList[LIST_0][iCount++] = ppLongRefList[i];
260− }
261− pCtx->sRefPic.uiRefCount[LIST_0] = iCount;
262−
263− iCount = 0;
264− //LIST_1
265− //short
266− for (int32_t i = 0; i < iLTCurrPocCount; ++i) {
267− pCtx->sRefPic.pRefList[LIST_1][iCount++] = pLTCurrPocList0[i];
268− }
269− if (iLTCurrPocCount > 1) {
270− //LIST_1 short sorts in increasing order
271− PPicture pTemp;
272− for (int32_t i = 0; i < iLTCurrPocCount; ++i) {
273− for (int32_t j = i + 1; j < iLTCurrPocCount; ++j) {
274− if (pCtx->sRefPic.pRefList[LIST_1][j]->iFramePoc < pCtx->sRefPic.pRefList[LIST_1][i]->iFramePoc) {
275− pTemp = pCtx->sRefPic.pRefList[LIST_1][i];
276− pCtx->sRefPic.pRefList[LIST_1][i] = pCtx->sRefPic.pRefList[LIST_1][j];
277− pCtx->sRefPic.pRefList[LIST_1][j] = pTemp;
278− }
279− }
280− }
281− }
282− for (int32_t i = 0; i < iLSCurrPocCount; ++i) {
283− pCtx->sRefPic.pRefList[LIST_1][iCount++] = pLSCurrPocList0[i];
284− }
285− if (iLSCurrPocCount > 1) {
286− //LIST_1 short sorts in decreasing order
287− PPicture pTemp;
288− for (int32_t i = iLTCurrPocCount; i < iCurrPocCount; ++i) {
289− for (int32_t j = i + 1; j < iCurrPocCount; ++j) {
290− if (pCtx->sRefPic.pRefList[LIST_1][j]->iFramePoc > pCtx->sRefPic.pRefList[LIST_1][i]->iFramePoc) {
291− pTemp = pCtx->sRefPic.pRefList[LIST_1][i];
292− pCtx->sRefPic.pRefList[LIST_1][i] = pCtx->sRefPic.pRefList[LIST_1][j];
293− pCtx->sRefPic.pRefList[LIST_1][j] = pTemp;
294− }
295− }
296− }
297− }
298− //long
299− for (int32_t i = 0; i < pCtx->sRefPic.uiLongRefCount[LIST_0]; ++i) {
300− pCtx->sRefPic.pRefList[LIST_1][iCount++] = ppLongRefList[i];
301− }
302− pCtx->sRefPic.uiRefCount[LIST_1] = iCount;
303− return ERR_NONE;
304−}
305−
306−/**
307− * fills the pRefPic.pRefList.
308− */
309−int32_t WelsInitRefList (PWelsDecoderContext pCtx, int32_t iPoc) {
310−
311− int32_t err = WelsCheckAndRecoverForFutureDecoding (pCtx);
312− if (err != ERR_NONE) return err;
313−
314− WrapShortRefPicNum (pCtx);
315−
316− PPicture* ppShoreRefList = pCtx->sRefPic.pShortRefList[LIST_0];
317− PPicture* ppLongRefList = pCtx->sRefPic.pLongRefList[LIST_0];
318− memset (pCtx->sRefPic.pRefList[LIST_0], 0, MAX_DPB_COUNT * sizeof (PPicture));
319−
320− int32_t i, iCount = 0;
321− //short
322− for (i = 0; i < pCtx->sRefPic.uiShortRefCount[LIST_0]; ++i) {
323− pCtx->sRefPic.pRefList[LIST_0][iCount++ ] = ppShoreRefList[i];
324− }
325−
326− //long
327− for (i = 0; i < pCtx->sRefPic.uiLongRefCount[LIST_0] ; ++i) {
328− pCtx->sRefPic.pRefList[LIST_0][iCount++ ] = ppLongRefList[i];
329− }
330− pCtx->sRefPic.uiRefCount[LIST_0] = iCount;
331−
332− return ERR_NONE;
333−}
334−
335−int32_t WelsReorderRefList (PWelsDecoderContext pCtx) {
336−
337− if (pCtx->eSliceType == I_SLICE || pCtx->eSliceType == SI_SLICE) {
338− return ERR_NONE;
339− }
340−
341− PRefPicListReorderSyn pRefPicListReorderSyn = pCtx->pCurDqLayer->pRefPicListReordering;
342− PNalUnitHeaderExt pNalHeaderExt = &pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt;
343− PSliceHeader pSliceHeader = &pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader;
344− int32_t ListCount = 1;
345− if (pCtx->eSliceType == B_SLICE) ListCount = 2;
346− for (int32_t listIdx = 0; listIdx < ListCount; ++listIdx) {
347− PPicture pPic = NULL;
348− PPicture* ppRefList = pCtx->sRefPic.pRefList[listIdx];
349− int32_t iMaxRefIdx = pCtx->pSps->iNumRefFrames;
350− int32_t iRefCount = pCtx->sRefPic.uiRefCount[listIdx];
351− int32_t iPredFrameNum = pSliceHeader->iFrameNum;
352− int32_t iMaxPicNum = 1 << pSliceHeader->pSps->uiLog2MaxFrameNum;
353− int32_t iAbsDiffPicNum = -1;
354− int32_t iReorderingIndex = 0;
355− int32_t i = 0;
356−
357− if (iRefCount <= 0) {
358− pCtx->iErrorCode = dsNoParamSets; //No any reference for decoding, SHOULD request IDR
359− return ERR_INFO_REFERENCE_PIC_LOST;
360− }
361−
362− if (pRefPicListReorderSyn->bRefPicListReorderingFlag[listIdx]) {
363− while ((iReorderingIndex < iMaxRefIdx)
364− && (pRefPicListReorderSyn->sReorderingSyn[listIdx][iReorderingIndex].uiReorderingOfPicNumsIdc != 3)) {
365− uint16_t uiReorderingOfPicNumsIdc =
366− pRefPicListReorderSyn->sReorderingSyn[listIdx][iReorderingIndex].uiReorderingOfPicNumsIdc;
367− if (uiReorderingOfPicNumsIdc < 2) {
368− iAbsDiffPicNum = pRefPicListReorderSyn->sReorderingSyn[listIdx][iReorderingIndex].uiAbsDiffPicNumMinus1 + 1;
369−
370− if (uiReorderingOfPicNumsIdc == 0) {
371− iPredFrameNum -= iAbsDiffPicNum;
372− } else {
373− iPredFrameNum += iAbsDiffPicNum;
374− }
375− iPredFrameNum &= iMaxPicNum - 1;
376−
377− for (i = iMaxRefIdx - 1; i >= 0; i--) {
378− if (ppRefList[i] != NULL && ppRefList[i]->iFrameNum == iPredFrameNum && !ppRefList[i]->bIsLongRef) {
379− if ((pNalHeaderExt->uiQualityId == ppRefList[i]->uiQualityId)
380− && (pSliceHeader->iSpsId != ppRefList[i]->iSpsId)) { //check;
381− WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "WelsReorderRefList()::::BASE LAYER::::iSpsId:%d, ref_sps_id:%d",
382− pSliceHeader->iSpsId, ppRefList[i]->iSpsId);
383− pCtx->iErrorCode = dsNoParamSets; //cross-IDR reference frame selection, SHOULD request IDR.--
384− return ERR_INFO_REFERENCE_PIC_LOST;
385− } else {
386− break;
387− }
388− }
389− }
390−
391− } else if (uiReorderingOfPicNumsIdc == 2) {
392− for (i = iMaxRefIdx - 1; i >= 0; i--) {
393− if (ppRefList[i] != NULL && ppRefList[i]->bIsLongRef
394− && ppRefList[i]->iLongTermFrameIdx ==
395− pRefPicListReorderSyn->sReorderingSyn[listIdx][iReorderingIndex].uiLongTermPicNum) {
396− if ((pNalHeaderExt->uiQualityId == ppRefList[i]->uiQualityId)
397− && (pSliceHeader->iSpsId != ppRefList[i]->iSpsId)) { //check;
398− WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "WelsReorderRefList()::::BASE LAYER::::iSpsId:%d, ref_sps_id:%d",
399− pSliceHeader->iSpsId, ppRefList[i]->iSpsId);
400− pCtx->iErrorCode = dsNoParamSets; //cross-IDR reference frame selection, SHOULD request IDR.--
401− return ERR_INFO_REFERENCE_PIC_LOST;
402− } else {
403− break;
404− }
405− }
406− }
407− }
408− if (i < 0) {
409− return ERR_INFO_REFERENCE_PIC_LOST;
410− }
411− pPic = ppRefList[i];
412− if (i > iReorderingIndex) {
413− memmove (&ppRefList[1 + iReorderingIndex], &ppRefList[iReorderingIndex],
414− (i - iReorderingIndex) * sizeof (PPicture)); //confirmed_safe_unsafe_usage
415− } else if (i < iReorderingIndex) {
416− memmove (&ppRefList[1 + iReorderingIndex], &ppRefList[iReorderingIndex],
417− (iMaxRefIdx - iReorderingIndex) * sizeof (PPicture));
418− }
419− ppRefList[iReorderingIndex] = pPic;
420− iReorderingIndex++;
421− }
422− }
423− }
424− return ERR_NONE;
425−}
426−
427−//WelsReorderRefList2 is the test code
428−int32_t WelsReorderRefList2 (PWelsDecoderContext pCtx) {
429−
430− if (pCtx->eSliceType == I_SLICE || pCtx->eSliceType == SI_SLICE) {
431− return ERR_NONE;
432− }
433−
434− PRefPicListReorderSyn pRefPicListReorderSyn = pCtx->pCurDqLayer->pRefPicListReordering;
435− PSliceHeader pSliceHeader = &pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader;
436−
437− PPicture* ppShoreRefList = pCtx->sRefPic.pShortRefList[LIST_0];
438− int32_t iShortRefCount = pCtx->sRefPic.uiShortRefCount[LIST_0];
439− PPicture* ppLongRefList = pCtx->sRefPic.pLongRefList[LIST_0];
440− int32_t iLongRefCount = pCtx->sRefPic.uiLongRefCount[LIST_0];
441− int32_t i = 0;
442− int32_t j = 0;
443− int32_t k = 0;
444− int32_t iMaxRefIdx = pCtx->pSps->iNumRefFrames;
445− const int32_t iCurFrameNum = pSliceHeader->iFrameNum;
446− const int32_t iMaxPicNum = 1 << pSliceHeader->pSps->uiLog2MaxFrameNum;
447− int32_t iListCount = 1;
448− if (pCtx->eSliceType == B_SLICE) iListCount = 2;
449− for (int32_t listIdx = 0; listIdx < iListCount; ++listIdx) {
450− PPicture* ppRefList = pCtx->sRefPic.pRefList[listIdx];
451− int32_t iCount = 0;
452− int32_t iRefCount = pSliceHeader->uiRefCount[listIdx];
453− int32_t iAbsDiffPicNum = -1;
454−
455− if (pRefPicListReorderSyn->bRefPicListReorderingFlag[listIdx]) {
456− int32_t iPredFrameNum = iCurFrameNum;
457− for (i = 0; pRefPicListReorderSyn->sReorderingSyn[listIdx][i].uiReorderingOfPicNumsIdc != 3; i++) {
458− if (iCount >= iMaxRefIdx)
459− break;
460−
461− for (j = iRefCount; j > iCount; j--)
462− ppRefList[j] = ppRefList[j - 1];
463−
464− uint16_t uiReorderingOfPicNumsIdc =
465− pRefPicListReorderSyn->sReorderingSyn[listIdx][i].uiReorderingOfPicNumsIdc;
466−
467− if (uiReorderingOfPicNumsIdc < 2) { // reorder short references
468− iAbsDiffPicNum = (int32_t) (pRefPicListReorderSyn->sReorderingSyn[listIdx][i].uiAbsDiffPicNumMinus1 + 1);
469− if (uiReorderingOfPicNumsIdc == 0) {
470− if (iPredFrameNum - iAbsDiffPicNum < 0)
471− iPredFrameNum -= (iAbsDiffPicNum - iMaxPicNum);
472− else
473− iPredFrameNum -= iAbsDiffPicNum;
474− } else {
475− if (iPredFrameNum + iAbsDiffPicNum >= iMaxPicNum)
476− iPredFrameNum += (iAbsDiffPicNum - iMaxPicNum);
477− else
478− iPredFrameNum += iAbsDiffPicNum;
479− }
480−
481− if (iPredFrameNum > iCurFrameNum) {
482− iPredFrameNum -= iMaxPicNum;
483− }
484−
485− for (j = 0; j < iShortRefCount; j++) {
486− if (ppShoreRefList[j]) {
487− if (ppShoreRefList[j]->iFrameWrapNum == iPredFrameNum) {
488− ppRefList[iCount++] = ppShoreRefList[j];
489− break;
490− }
491− }
492− }
493− k = iCount;
494− for (j = k; j <= iRefCount; j++) {
495− if (ppRefList[j] != NULL) {
496− if (ppRefList[j]->bIsLongRef || ppRefList[j]->iFrameWrapNum != iPredFrameNum)
497− ppRefList[k++] = ppRefList[j];
498− }
499− }
500− } else { // reorder long term references uiReorderingOfPicNumsIdc == 2
501− iPredFrameNum = pRefPicListReorderSyn->sReorderingSyn[listIdx][i].uiLongTermPicNum;
502− for (j = 0; j < iLongRefCount; j++) {
503− if (ppLongRefList[j] != NULL) {
504− if (ppLongRefList[j]->uiLongTermPicNum == (uint32_t)iPredFrameNum) {
505− ppRefList[iCount++] = ppLongRefList[j];
506− break;
507− }
508− }
509− }
510− k = iCount;
511− for (j = k; j <= iRefCount; j++) {
512− if (ppRefList[j] != NULL) {
513− if (!ppRefList[j]->bIsLongRef || ppLongRefList[j]->uiLongTermPicNum != (uint32_t)iPredFrameNum)
514− ppRefList[k++] = ppRefList[j];
515− }
516− }
517− }
518− }
519− }
520−
521− for (i = WELS_MAX (1, WELS_MAX (iCount, pCtx->sRefPic.uiRefCount[listIdx])); i < iRefCount; i++)
522− ppRefList[i] = ppRefList[i - 1];
523− pCtx->sRefPic.uiRefCount[listIdx] = (uint8_t)WELS_MIN (WELS_MAX (iCount, pCtx->sRefPic.uiRefCount[listIdx]), iRefCount);
524− }
525− return ERR_NONE;
526−}
527−
528−int32_t WelsMarkAsRef (PWelsDecoderContext pCtx) {
529− PRefPic pRefPic = &pCtx->sRefPic;
530− PRefPicMarking pRefPicMarking = pCtx->pCurDqLayer->pRefPicMarking;
531− PAccessUnit pCurAU = pCtx->pAccessUnitList;
532− bool bIsIDRAU = false;
533− uint32_t j;
534−
535− int32_t iRet = ERR_NONE;
536−
537− pCtx->pDec->uiQualityId = pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.uiQualityId;
538− pCtx->pDec->uiTemporalId = pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.uiTemporalId;
539− pCtx->pDec->iSpsId = pCtx->pSps->iSpsId;
540− pCtx->pDec->iPpsId = pCtx->pPps->iPpsId;
541−
542− for (j = pCurAU->uiStartPos; j <= pCurAU->uiEndPos; j++) {
543− if (pCurAU->pNalUnitsList[j]->sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR
544− || pCurAU->pNalUnitsList[j]->sNalHeaderExt.bIdrFlag) {
545− bIsIDRAU = true;
546− break;
547− }
548− }
549− if (bIsIDRAU) {
550− if (pRefPicMarking->bLongTermRefFlag) {
551− pCtx->sRefPic.iMaxLongTermFrameIdx = 0;
552− AddLongTermToList (pRefPic, pCtx->pDec, 0, 0);
553− } else {
554− pCtx->sRefPic.iMaxLongTermFrameIdx = -1;
555− }
556− } else {
557− if (pRefPicMarking->bAdaptiveRefPicMarkingModeFlag) {
558− iRet = MMCO (pCtx, pRefPicMarking);
559− if (iRet != ERR_NONE) {
560− if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
561− iRet = RemainOneBufferInDpbForEC (pCtx);
562− WELS_VERIFY_RETURN_IF (iRet, iRet);
563− } else {
564− return iRet;
565− }
566− }
567−
568− if (pCtx->bLastHasMmco5) {
569− pCtx->pDec->iFrameNum = 0;
570− pCtx->pDec->iFramePoc = 0;
571− }
572−
573− } else {
574− iRet = SlidingWindow (pCtx);
575− if (iRet != ERR_NONE) {
576− if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
577− iRet = RemainOneBufferInDpbForEC (pCtx);
578− WELS_VERIFY_RETURN_IF (iRet, iRet);
579− } else {
580− return iRet;
581− }
582− }
583− }
584− }
585−
586− if (!pCtx->pDec->bIsLongRef) {
587− if (pRefPic->uiLongRefCount[LIST_0] + pRefPic->uiShortRefCount[LIST_0] >= WELS_MAX (1, pCtx->pSps->iNumRefFrames)) {
588− if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
589− iRet = RemainOneBufferInDpbForEC (pCtx);
590− WELS_VERIFY_RETURN_IF (iRet, iRet);
591− } else {
592− return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW;
593− }
594− }
595− iRet = AddShortTermToList (pRefPic, pCtx->pDec);
596− }
597−
598− return iRet;
599−}
600−
601−static int32_t MMCO (PWelsDecoderContext pCtx, PRefPicMarking pRefPicMarking) {
602− PSps pSps = pCtx->pCurDqLayer->sLayerInfo.pSps;
603− int32_t i = 0;
604− int32_t iRet = ERR_NONE;
605− for (i = 0; i < MAX_MMCO_COUNT && pRefPicMarking->sMmcoRef[i].uiMmcoType != MMCO_END; i++) {
606− uint32_t uiMmcoType = pRefPicMarking->sMmcoRef[i].uiMmcoType;
607− int32_t iShortFrameNum = (pCtx->iFrameNum - pRefPicMarking->sMmcoRef[i].iDiffOfPicNum) & ((
608− 1 << pSps->uiLog2MaxFrameNum) - 1);
609− uint32_t uiLongTermPicNum = pRefPicMarking->sMmcoRef[i].uiLongTermPicNum;
610− int32_t iLongTermFrameIdx = pRefPicMarking->sMmcoRef[i].iLongTermFrameIdx;
611− int32_t iMaxLongTermFrameIdx = pRefPicMarking->sMmcoRef[i].iMaxLongTermFrameIdx;
612− if (uiMmcoType > MMCO_LONG) {
613− return ERR_INFO_INVALID_MMCO_OPCODE_BASE;
614− }
615− iRet = MMCOProcess (pCtx, uiMmcoType, iShortFrameNum, uiLongTermPicNum, iLongTermFrameIdx, iMaxLongTermFrameIdx);
616− if (iRet != ERR_NONE) {
617− return iRet;
618− }
619− }
620− if (i == MAX_MMCO_COUNT) { //although Rec does not handle this condition, we here prohibit too many MMCO op
621− return ERR_INFO_INVALID_MMCO_NUM;
622− }
623−
624− return ERR_NONE;
625−}
626−static int32_t MMCOProcess (PWelsDecoderContext pCtx, uint32_t uiMmcoType,
627− int32_t iShortFrameNum, uint32_t uiLongTermPicNum, int32_t iLongTermFrameIdx, int32_t iMaxLongTermFrameIdx) {
628− PRefPic pRefPic = &pCtx->sRefPic;
629− PPicture pPic = NULL;
630− int32_t i = 0;
631− int32_t iRet = ERR_NONE;
632−
633− switch (uiMmcoType) {
634− case MMCO_SHORT2UNUSED:
635− pPic = WelsDelShortFromListSetUnref (pRefPic, iShortFrameNum);
636− if (pPic == NULL) {
637− WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "MMCO_SHORT2UNUSED: delete an empty entry from short term list");
638− }
639− break;
640− case MMCO_LONG2UNUSED:
641− pPic = WelsDelLongFromListSetUnref (pRefPic, uiLongTermPicNum);
642− if (pPic == NULL) {
643− WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "MMCO_LONG2UNUSED: delete an empty entry from long term list");
644− }
645− break;
646− case MMCO_SHORT2LONG:
647− if (iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx) {
648− return ERR_INFO_INVALID_MMCO_LONG_TERM_IDX_EXCEED_MAX;
649− }
650− pPic = WelsDelShortFromList (pRefPic, iShortFrameNum);
651− if (pPic == NULL) {
652− WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "MMCO_LONG2LONG: delete an empty entry from short term list");
653− break;
654− }
655− WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx);
656−#ifdef LONG_TERM_REF
657− pCtx->bCurAuContainLtrMarkSeFlag = true;
658− pCtx->iFrameNumOfAuMarkedLtr = iShortFrameNum;
659− WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "ex_mark_avc():::MMCO_SHORT2LONG:::LTR marking....iFrameNum: %d",
660− pCtx->iFrameNumOfAuMarkedLtr);
661−#endif
662−
663− MarkAsLongTerm (pRefPic, iShortFrameNum, iLongTermFrameIdx, uiLongTermPicNum);
664− break;
665− case MMCO_SET_MAX_LONG:
666− pRefPic->iMaxLongTermFrameIdx = iMaxLongTermFrameIdx;
667− for (i = 0 ; i < pRefPic->uiLongRefCount[LIST_0]; i++) {
668− if (pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx) {
669− WelsDelLongFromListSetUnref (pRefPic, pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx);
670− }
671− }
672− break;
673− case MMCO_RESET:
674− WelsResetRefPic (pCtx);
675− pCtx->bLastHasMmco5 = true;
676− break;
677− case MMCO_LONG:
678− if (iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx) {
679− return ERR_INFO_INVALID_MMCO_LONG_TERM_IDX_EXCEED_MAX;
680− }
681− WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx);
682− if (pRefPic->uiLongRefCount[LIST_0] + pRefPic->uiShortRefCount[LIST_0] >= WELS_MAX (1, pCtx->pSps->iNumRefFrames)) {
683− return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW;
684− }
685−#ifdef LONG_TERM_REF
686− pCtx->bCurAuContainLtrMarkSeFlag = true;
687− pCtx->iFrameNumOfAuMarkedLtr = pCtx->iFrameNum;
688− WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "ex_mark_avc():::MMCO_LONG:::LTR marking....iFrameNum: %d",
689− pCtx->iFrameNum);
690−#endif
691− iRet = AddLongTermToList (pRefPic, pCtx->pDec, iLongTermFrameIdx, uiLongTermPicNum);
692− break;
693− default :
694− break;
695− }
696−
697− return iRet;
698−}
699−
700−static int32_t SlidingWindow (PWelsDecoderContext pCtx) {
701− PRefPic pRefPic = &pCtx->sRefPic;
702− PPicture pPic = NULL;
703− int32_t i = 0;
704−
705− if (pCtx->sRefPic.uiShortRefCount[LIST_0] + pCtx->sRefPic.uiLongRefCount[LIST_0] >= pCtx->pSps->iNumRefFrames) {
706− if (pCtx->sRefPic.uiShortRefCount[LIST_0] == 0) {
707− WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "No reference picture in short term list when sliding window");
708− return ERR_INFO_INVALID_MMCO_REF_NUM_NOT_ENOUGH;
709− }
710− for (i = pRefPic->uiShortRefCount[LIST_0] - 1; i >= 0; i--) {
711− pPic = WelsDelShortFromList (pRefPic, pRefPic->pShortRefList[LIST_0][i]->iFrameNum);
712− if (pPic) {
713− SetUnRef (pPic);
714− break;
715− } else {
716− return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW;
717− }
718− }
719− }
720− return ERR_NONE;
721−}
722−
723−static PPicture WelsDelShortFromList (PRefPic pRefPic, int32_t iFrameNum) {
724− int32_t i = 0;
725− int32_t iMoveSize = 0;
726− PPicture pPic = NULL;
727−
728− for (i = 0; i < pRefPic->uiShortRefCount[LIST_0]; i++) {
729− if (pRefPic->pShortRefList[LIST_0][i]->iFrameNum == iFrameNum) {
730− iMoveSize = pRefPic->uiShortRefCount[LIST_0] - i - 1;
731− pRefPic->pShortRefList[LIST_0][i]->bUsedAsRef = false;
732− pPic = pRefPic->pShortRefList[LIST_0][i];
733− pRefPic->pShortRefList[LIST_0][i] = NULL;
734− if (iMoveSize > 0) {
735− memmove (&pRefPic->pShortRefList[LIST_0][i], &pRefPic->pShortRefList[LIST_0][i + 1],
736− iMoveSize * sizeof (PPicture)); //confirmed_safe_unsafe_usage
737− }
738− pRefPic->uiShortRefCount[LIST_0]--;
739− pRefPic->pShortRefList[LIST_0][pRefPic->uiShortRefCount[LIST_0]] = NULL;
740− break;
741− }
742− }
743−
744− return pPic;
745−}
746−
747−static PPicture WelsDelShortFromListSetUnref (PRefPic pRefPic, int32_t iFrameNum) {
748− PPicture pPic = WelsDelShortFromList (pRefPic, iFrameNum);
749− if (pPic) {
750− SetUnRef (pPic);
751− }
752− return pPic;
753−}
754−
755−static PPicture WelsDelLongFromList (PRefPic pRefPic, uint32_t uiLongTermFrameIdx) {
756− PPicture pPic = NULL;
757− int32_t i = 0;
758− for (i = 0; i < pRefPic->uiLongRefCount[LIST_0]; i++) {
759− pPic = pRefPic->pLongRefList[LIST_0][i];
760− if (pPic->iLongTermFrameIdx == (int32_t)uiLongTermFrameIdx) {
761− int32_t iMoveSize = pRefPic->uiLongRefCount[LIST_0] - i - 1;
762− pPic->bUsedAsRef = false;
763− pPic->bIsLongRef = false;
764− if (iMoveSize > 0) {
765− memmove (&pRefPic->pLongRefList[LIST_0][i], &pRefPic->pLongRefList[LIST_0][i + 1],
766− iMoveSize * sizeof (PPicture)); //confirmed_safe_unsafe_usage
767− }
768− pRefPic->uiLongRefCount[LIST_0]--;
769− pRefPic->pLongRefList[LIST_0][pRefPic->uiLongRefCount[LIST_0]] = NULL;
770− return pPic;
771− }
772− }
773− return NULL;
774−}
775−
776−static PPicture WelsDelLongFromListSetUnref (PRefPic pRefPic, uint32_t uiLongTermFrameIdx) {
777− PPicture pPic = WelsDelLongFromList (pRefPic, uiLongTermFrameIdx);
778− if (pPic) {
779− SetUnRef (pPic);
780− }
781− return pPic;
782−}
783−
784−static int32_t AddShortTermToList (PRefPic pRefPic, PPicture pPic) {
785− pPic->bUsedAsRef = true;
786− pPic->bIsLongRef = false;
787− pPic->iLongTermFrameIdx = -1;
788− if (pRefPic->uiShortRefCount[LIST_0] > 0) {
789− // Check the duplicate frame_num in short ref list
790− for (int32_t iPos = 0; iPos < pRefPic->uiShortRefCount[LIST_0]; iPos++) {
791− if (pPic->iFrameNum == pRefPic->pShortRefList[LIST_0][iPos]->iFrameNum) {
792− // Replace the previous ref pic with the new one with the same frame_num
793− pRefPic->pShortRefList[LIST_0][iPos] = pPic;
794− return ERR_INFO_DUPLICATE_FRAME_NUM;
795− }
796− }
797−
798− memmove (&pRefPic->pShortRefList[LIST_0][1], &pRefPic->pShortRefList[LIST_0][0],
799− pRefPic->uiShortRefCount[LIST_0]*sizeof (PPicture));//confirmed_safe_unsafe_usage
800− }
801− pRefPic->pShortRefList[LIST_0][0] = pPic;
802− pRefPic->uiShortRefCount[LIST_0]++;
803− return ERR_NONE;
804−}
805−
806−static int32_t AddLongTermToList (PRefPic pRefPic, PPicture pPic, int32_t iLongTermFrameIdx,
807− uint32_t uiLongTermPicNum) {
808− int32_t i = 0;
809−
810− pPic->bUsedAsRef = true;
811− pPic->bIsLongRef = true;
812− pPic->iLongTermFrameIdx = iLongTermFrameIdx;
813− pPic->uiLongTermPicNum = uiLongTermPicNum;
814− if (pRefPic->uiLongRefCount[LIST_0] == 0) {
815− pRefPic->pLongRefList[LIST_0][pRefPic->uiLongRefCount[LIST_0]] = pPic;
816− } else {
817− for (i = 0; i < pRefPic->uiLongRefCount[LIST_0]; i++) {
818− if (pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx > pPic->iLongTermFrameIdx) {
819− break;
820− }
821− }
822− memmove (&pRefPic->pLongRefList[LIST_0][i + 1], &pRefPic->pLongRefList[LIST_0][i],
823− (pRefPic->uiLongRefCount[LIST_0] - i)*sizeof (PPicture)); //confirmed_safe_unsafe_usage
824− pRefPic->pLongRefList[LIST_0][i] = pPic;
825− }
826−
827− pRefPic->uiLongRefCount[LIST_0]++;
828− return ERR_NONE;
829−}
830−
831−static int32_t MarkAsLongTerm (PRefPic pRefPic, int32_t iFrameNum, int32_t iLongTermFrameIdx,
832− uint32_t uiLongTermPicNum) {
833− PPicture pPic = NULL;
834− int32_t i = 0;
835− int32_t iRet = ERR_NONE;
836− WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx);
837−
838− for (i = 0; i < pRefPic->uiRefCount[LIST_0]; i++) {
839− pPic = pRefPic->pRefList[LIST_0][i];
840− if (pPic->iFrameNum == iFrameNum && !pPic->bIsLongRef) {
841− iRet = AddLongTermToList (pRefPic, pPic, iLongTermFrameIdx, uiLongTermPicNum);
842− break;
843− }
844− }
845−
846− return iRet;
847−}
848−
849−#ifdef LONG_TERM_REF
850−int32_t GetLTRFrameIndex (PRefPic pRefPic, int32_t iAncLTRFrameNum) {
851− int32_t iLTRFrameIndex = -1;
852− PPicture pPic;
853− for (int i = 0; i < pRefPic->uiLongRefCount[0]; ++i) {
854− pPic = pRefPic->pLongRefList[LIST_0][i];
855− if (pPic->iFrameNum == iAncLTRFrameNum) {
856− return (pPic->iLongTermFrameIdx);
857− }
858− }
859− return iLTRFrameIndex;
860−}
861−#endif
862−
863−static int32_t RemainOneBufferInDpbForEC (PWelsDecoderContext pCtx) {
864− int32_t iRet = ERR_NONE;
865− PRefPic pRefPic = &pCtx->sRefPic;
866− if (pRefPic->uiShortRefCount[0] + pRefPic->uiLongRefCount[0] < pCtx->pSps->iNumRefFrames)
867− return iRet;
868−
869− if (pRefPic->uiShortRefCount[0] > 0) {
870− iRet = SlidingWindow (pCtx);
871− } else { //all LTR, remove the smallest long_term_frame_idx
872− int32_t iLongTermFrameIdx = 0;
873− int32_t iMaxLongTermFrameIdx = pRefPic->iMaxLongTermFrameIdx;
874−#ifdef LONG_TERM_REF
875− int32_t iCurrLTRFrameIdx = GetLTRFrameIndex (pRefPic, pCtx->iFrameNumOfAuMarkedLtr);
876−#endif
877− while ((pRefPic->uiLongRefCount[0] >= pCtx->pSps->iNumRefFrames) && (iLongTermFrameIdx <= iMaxLongTermFrameIdx)) {
878−#ifdef LONG_TERM_REF
879− if (iLongTermFrameIdx == iCurrLTRFrameIdx) {
880− iLongTermFrameIdx++;
881− continue;
882− }
883−#endif
884− WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx);
885− iLongTermFrameIdx++;
886− }
887− }
888− if (pRefPic->uiShortRefCount[0] + pRefPic->uiLongRefCount[0] >=
889− pCtx->pSps->iNumRefFrames) { //fail to remain one empty buffer in DPB
890− WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "RemainOneBufferInDpbForEC(): empty one DPB failed for EC!");
891− iRet = ERR_INFO_REF_COUNT_OVERFLOW;
892− }
893−
894− return iRet;
895−}
896−
897−} // namespace WelsDec
1+/*!
2+ * \copy
3+ * Copyright (c) 2008-2013, Cisco Systems
4+ * All rights reserved.
5+ *
6+ * Redistribution and use in source and binary forms, with or without
7+ * modification, are permitted provided that the following conditions
8+ * are met:
9+ *
10+ * * Redistributions of source code must retain the above copyright
11+ * notice, this list of conditions and the following disclaimer.
12+ *
13+ * * Redistributions in binary form must reproduce the above copyright
14+ * notice, this list of conditions and the following disclaimer in
15+ * the documentation and/or other materials provided with the
16+ * distribution.
17+ *
18+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29+ * POSSIBILITY OF SUCH DAMAGE.
30+ *
31+ *
32+ * manage_dec_ref.cpp
33+ *
34+ * Abstract
35+ * Implementation for managing reference picture
36+ *
37+ * History
38+ * 07/21/2008 Created
39+ *
40+ *****************************************************************************/
41+
42+#include "manage_dec_ref.h"
43+#include "error_concealment.h"
44+#include "error_code.h"
45+
46+namespace WelsDec {
47+
48+static PPicture WelsDelShortFromList (PRefPic pRefPic, int32_t iFrameNum);
49+static PPicture WelsDelLongFromList (PRefPic pRefPic, uint32_t uiLongTermFrameIdx);
50+static PPicture WelsDelShortFromListSetUnref (PRefPic pRefPic, int32_t iFrameNum);
51+static PPicture WelsDelLongFromListSetUnref (PRefPic pRefPic, uint32_t uiLongTermFrameIdx);
52+
53+static int32_t MMCO (PWelsDecoderContext pCtx, PRefPicMarking pRefPicMarking);
54+static int32_t MMCOProcess (PWelsDecoderContext pCtx, uint32_t uiMmcoType,
55+ int32_t iShortFrameNum, uint32_t uiLongTermPicNum, int32_t iLongTermFrameIdx, int32_t iMaxLongTermFrameIdx);
56+static int32_t SlidingWindow (PWelsDecoderContext pCtx);
57+
58+static int32_t AddShortTermToList (PRefPic pRefPic, PPicture pPic);
59+static int32_t AddLongTermToList (PRefPic pRefPic, PPicture pPic, int32_t iLongTermFrameIdx, uint32_t uiLongTermPicNum);
60+static int32_t MarkAsLongTerm (PRefPic pRefPic, int32_t iFrameNum, int32_t iLongTermFrameIdx,
61+ uint32_t uiLongTermPicNum);
62+static int32_t WelsCheckAndRecoverForFutureDecoding (PWelsDecoderContext pCtx);
63+#ifdef LONG_TERM_REF
64+int32_t GetLTRFrameIndex (PRefPic pRefPic, int32_t iAncLTRFrameNum);
65+#endif
66+static int32_t RemainOneBufferInDpbForEC (PWelsDecoderContext pCtx);
67+
68+static void SetUnRef (PPicture pRef) {
69+ if (NULL != pRef) {
70+ pRef->bUsedAsRef = false;
71+ pRef->bIsLongRef = false;
72+ pRef->iFrameNum = -1;
73+ pRef->iFrameWrapNum = -1;
74+ //pRef->iFramePoc = 0;
75+ pRef->iLongTermFrameIdx = -1;
76+ pRef->uiLongTermPicNum = 0;
77+ pRef->uiQualityId = -1;
78+ pRef->uiTemporalId = -1;
79+ pRef->uiSpatialId = -1;
80+ pRef->iSpsId = -1;
81+ pRef->bIsComplete = false;
82+ }
83+}
84+
85+//reset pRefList when
86+// 1.sps arrived that is new sequence starting
87+// 2.IDR NAL i.e. 1st layer in IDR AU
88+
89+void WelsResetRefPic (PWelsDecoderContext pCtx) {
90+ int32_t i = 0;
91+ PRefPic pRefPic = &pCtx->sRefPic;
92+ pCtx->sRefPic.uiLongRefCount[LIST_0] = pCtx->sRefPic.uiShortRefCount[LIST_0] = 0;
93+
94+ pRefPic->uiRefCount[LIST_0] = 0;
95+ pRefPic->uiRefCount[LIST_1] = 0;
96+
97+ for (i = 0; i < MAX_DPB_COUNT; i++) {
98+ if (pRefPic->pShortRefList[LIST_0][i] != NULL) {
99+ SetUnRef (pRefPic->pShortRefList[LIST_0][i]);
100+ pRefPic->pShortRefList[LIST_0][i] = NULL;
101+ }
102+ }
103+ pRefPic->uiShortRefCount[LIST_0] = 0;
104+
105+ for (i = 0; i < MAX_DPB_COUNT; i++) {
106+ if (pRefPic->pLongRefList[LIST_0][i] != NULL) {
107+ SetUnRef (pRefPic->pLongRefList[LIST_0][i]);
108+ pRefPic->pLongRefList[LIST_0][i] = NULL;
109+ }
110+ }
111+ pRefPic->uiLongRefCount[LIST_0] = 0;
112+}
113+
114+static int32_t WelsCheckAndRecoverForFutureDecoding (PWelsDecoderContext pCtx) {
115+ if ((pCtx->sRefPic.uiShortRefCount[LIST_0] + pCtx->sRefPic.uiLongRefCount[LIST_0] <= 0) && (pCtx->eSliceType != I_SLICE
116+ && pCtx->eSliceType != SI_SLICE)) {
117+ if (pCtx->pParam->eEcActiveIdc !=
118+ ERROR_CON_DISABLE) { //IDR lost!, recover it for future decoding with data all set to 0
119+ PPicture pRef = PrefetchPic (pCtx->pPicBuff);
120+ if (pRef != NULL) {
121+ // IDR lost, set new
122+ pRef->bIsComplete = false; // Set complete flag to false for lost IDR ref picture
123+ pRef->iSpsId = pCtx->pSps->iSpsId;
124+ pRef->iPpsId = pCtx->pPps->iPpsId;
125+ pCtx->iErrorCode |= dsDataErrorConcealed;
126+ bool bCopyPrevious = ((ERROR_CON_FRAME_COPY_CROSS_IDR == pCtx->pParam->eEcActiveIdc)
127+ || (ERROR_CON_SLICE_COPY_CROSS_IDR == pCtx->pParam->eEcActiveIdc)
128+ || (ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE == pCtx->pParam->eEcActiveIdc)
129+ || (ERROR_CON_SLICE_MV_COPY_CROSS_IDR == pCtx->pParam->eEcActiveIdc)
130+ || (ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE == pCtx->pParam->eEcActiveIdc))
131+ && (NULL != pCtx->pPreviousDecodedPictureInDpb);
132+ bCopyPrevious = bCopyPrevious && (pRef->iWidthInPixel == pCtx->pPreviousDecodedPictureInDpb->iWidthInPixel)
133+ && (pRef->iHeightInPixel == pCtx->pPreviousDecodedPictureInDpb->iHeightInPixel);
134+
135+ if (!bCopyPrevious) {
136+ memset (pRef->pData[0], 128, pRef->iLinesize[0] * pRef->iHeightInPixel);
137+ memset (pRef->pData[1], 128, pRef->iLinesize[1] * pRef->iHeightInPixel / 2);
138+ memset (pRef->pData[2], 128, pRef->iLinesize[2] * pRef->iHeightInPixel / 2);
139+ } else if (pRef == pCtx->pPreviousDecodedPictureInDpb) {
140+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "WelsInitRefList()::EC memcpy overlap.");
141+ } else {
142+ memcpy (pRef->pData[0], pCtx->pPreviousDecodedPictureInDpb->pData[0], pRef->iLinesize[0] * pRef->iHeightInPixel);
143+ memcpy (pRef->pData[1], pCtx->pPreviousDecodedPictureInDpb->pData[1], pRef->iLinesize[1] * pRef->iHeightInPixel / 2);
144+ memcpy (pRef->pData[2], pCtx->pPreviousDecodedPictureInDpb->pData[2], pRef->iLinesize[2] * pRef->iHeightInPixel / 2);
145+ }
146+ pRef->iFrameNum = 0;
147+ pRef->iFramePoc = 0;
148+ pRef->uiTemporalId = pRef->uiQualityId = 0;
149+ ExpandReferencingPicture (pRef->pData, pRef->iWidthInPixel, pRef->iHeightInPixel, pRef->iLinesize,
150+ pCtx->sExpandPicFunc.pfExpandLumaPicture, pCtx->sExpandPicFunc.pfExpandChromaPicture);
151+ AddShortTermToList (&pCtx->sRefPic, pRef);
152+ } else {
153+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "WelsInitRefList()::PrefetchPic for EC errors.");
154+ pCtx->iErrorCode |= dsOutOfMemory;
155+ return ERR_INFO_REF_COUNT_OVERFLOW;
156+ }
157+ }
158+ }
159+ return ERR_NONE;
160+}
161+
162+static void WrapShortRefPicNum (PWelsDecoderContext pCtx) {
163+ int32_t i;
164+ PSliceHeader pSliceHeader = &pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader;
165+ int32_t iMaxPicNum = 1 << pSliceHeader->pSps->uiLog2MaxFrameNum;
166+ PPicture* ppShoreRefList = pCtx->sRefPic.pShortRefList[LIST_0];
167+ int32_t iShortRefCount = pCtx->sRefPic.uiShortRefCount[LIST_0];
168+ //wrap pic num
169+ for (i = 0; i < iShortRefCount; i++) {
170+ if (ppShoreRefList[i]) {
171+ if (ppShoreRefList[i]->iFrameNum > pSliceHeader->iFrameNum)
172+ ppShoreRefList[i]->iFrameWrapNum = ppShoreRefList[i]->iFrameNum - iMaxPicNum;
173+ else
174+ ppShoreRefList[i]->iFrameWrapNum = ppShoreRefList[i]->iFrameNum;
175+ }
176+ }
177+}
178+
179+/**
180+* fills the pRefPic.pRefList LIST_0 and LIST_0 for B-Slice.
181+*/
182+int32_t WelsInitBSliceRefList (PWelsDecoderContext pCtx, int32_t iPoc) {
183+
184+ int32_t err = WelsCheckAndRecoverForFutureDecoding (pCtx);
185+ if (err != ERR_NONE) return err;
186+
187+ WrapShortRefPicNum (pCtx);
188+
189+ PPicture* ppShoreRefList = pCtx->sRefPic.pShortRefList[LIST_0];
190+ PPicture* ppLongRefList = pCtx->sRefPic.pLongRefList[LIST_0];
191+ memset (pCtx->sRefPic.pRefList[LIST_0], 0, MAX_DPB_COUNT * sizeof (PPicture));
192+ memset (pCtx->sRefPic.pRefList[LIST_1], 0, MAX_DPB_COUNT * sizeof (PPicture));
193+ int32_t iLSCurrPocCount = 0;
194+ int32_t iLTCurrPocCount = 0;
195+ PPicture pLSCurrPocList0[MAX_DPB_COUNT];
196+ PPicture pLTCurrPocList0[MAX_DPB_COUNT];
197+ for (int32_t i = 0; i < pCtx->sRefPic.uiShortRefCount[LIST_0]; ++i) {
198+ if (ppShoreRefList[i]->iFramePoc < iPoc) {
199+ pLSCurrPocList0[iLSCurrPocCount++] = ppShoreRefList[i];
200+ }
201+ }
202+ for (int32_t i = pCtx->sRefPic.uiShortRefCount[LIST_0] - 1; i >= 0; --i) {
203+ if (ppShoreRefList[i]->iFramePoc > iPoc) {
204+ pLTCurrPocList0[iLTCurrPocCount++] = ppShoreRefList[i];
205+ }
206+ }
207+ if (pCtx->sRefPic.uiLongRefCount[LIST_0] > 1) {
208+ //long sorts in increasing order
209+ PPicture pTemp;
210+ for (int32_t i = 0; i < pCtx->sRefPic.uiLongRefCount[LIST_0]; ++i) {
211+ for (int32_t j = i + 1; j < pCtx->sRefPic.uiLongRefCount[LIST_0]; ++j) {
212+ if (ppLongRefList[j]->iFramePoc < ppLongRefList[i]->iFramePoc) {
213+ pTemp = ppLongRefList[i];
214+ ppLongRefList[i] = ppLongRefList[j];
215+ ppLongRefList[j] = pTemp;
216+ }
217+ }
218+ }
219+ }
220+ int32_t iCurrPocCount = iLSCurrPocCount + iLTCurrPocCount;
221+ int32_t iCount = 0;
222+ //LIST_0
223+ //short
224+ //It may need to sort LIST_0 and LIST_1 so that they will have the right default orders.
225+ for (int32_t i = 0; i < iLSCurrPocCount; ++i) {
226+ pCtx->sRefPic.pRefList[LIST_0][iCount++] = pLSCurrPocList0[i];
227+ }
228+ if (iLSCurrPocCount > 1) {
229+ //LIST_0 short sorts in decreasing order
230+ PPicture pTemp;
231+ for (int32_t i = 0; i < iLSCurrPocCount; ++i) {
232+ for (int32_t j = i + 1; j < iLSCurrPocCount; ++j) {
233+ if (pCtx->sRefPic.pRefList[LIST_0][j]->iFramePoc > pCtx->sRefPic.pRefList[LIST_0][i]->iFramePoc) {
234+ pTemp = pCtx->sRefPic.pRefList[LIST_0][i];
235+ pCtx->sRefPic.pRefList[LIST_0][i] = pCtx->sRefPic.pRefList[LIST_0][j];
236+ pCtx->sRefPic.pRefList[LIST_0][j] = pTemp;
237+ }
238+ }
239+ }
240+ }
241+ for (int32_t i = 0; i < iLTCurrPocCount; ++i) {
242+ pCtx->sRefPic.pRefList[LIST_0][iCount++] = pLTCurrPocList0[i];
243+ }
244+ if (iLTCurrPocCount > 1) {
245+ //LIST_0 short sorts in increasing order
246+ PPicture pTemp;
247+ for (int32_t i = iLSCurrPocCount; i < iCurrPocCount; ++i) {
248+ for (int32_t j = i + 1; j < iCurrPocCount; ++j) {
249+ if (pCtx->sRefPic.pRefList[LIST_0][j]->iFramePoc < pCtx->sRefPic.pRefList[LIST_0][i]->iFramePoc) {
250+ pTemp = pCtx->sRefPic.pRefList[LIST_0][i];
251+ pCtx->sRefPic.pRefList[LIST_0][i] = pCtx->sRefPic.pRefList[LIST_0][j];
252+ pCtx->sRefPic.pRefList[LIST_0][j] = pTemp;
253+ }
254+ }
255+ }
256+ }
257+ //long
258+ for (int32_t i = 0; i < pCtx->sRefPic.uiLongRefCount[LIST_0]; ++i) {
259+ pCtx->sRefPic.pRefList[LIST_0][iCount++] = ppLongRefList[i];
260+ }
261+ pCtx->sRefPic.uiRefCount[LIST_0] = iCount;
262+
263+ iCount = 0;
264+ //LIST_1
265+ //short
266+ for (int32_t i = 0; i < iLTCurrPocCount; ++i) {
267+ pCtx->sRefPic.pRefList[LIST_1][iCount++] = pLTCurrPocList0[i];
268+ }
269+ if (iLTCurrPocCount > 1) {
270+ //LIST_1 short sorts in increasing order
271+ PPicture pTemp;
272+ for (int32_t i = 0; i < iLTCurrPocCount; ++i) {
273+ for (int32_t j = i + 1; j < iLTCurrPocCount; ++j) {
274+ if (pCtx->sRefPic.pRefList[LIST_1][j]->iFramePoc < pCtx->sRefPic.pRefList[LIST_1][i]->iFramePoc) {
275+ pTemp = pCtx->sRefPic.pRefList[LIST_1][i];
276+ pCtx->sRefPic.pRefList[LIST_1][i] = pCtx->sRefPic.pRefList[LIST_1][j];
277+ pCtx->sRefPic.pRefList[LIST_1][j] = pTemp;
278+ }
279+ }
280+ }
281+ }
282+ for (int32_t i = 0; i < iLSCurrPocCount; ++i) {
283+ pCtx->sRefPic.pRefList[LIST_1][iCount++] = pLSCurrPocList0[i];
284+ }
285+ if (iLSCurrPocCount > 1) {
286+ //LIST_1 short sorts in decreasing order
287+ PPicture pTemp;
288+ for (int32_t i = iLTCurrPocCount; i < iCurrPocCount; ++i) {
289+ for (int32_t j = i + 1; j < iCurrPocCount; ++j) {
290+ if (pCtx->sRefPic.pRefList[LIST_1][j]->iFramePoc > pCtx->sRefPic.pRefList[LIST_1][i]->iFramePoc) {
291+ pTemp = pCtx->sRefPic.pRefList[LIST_1][i];
292+ pCtx->sRefPic.pRefList[LIST_1][i] = pCtx->sRefPic.pRefList[LIST_1][j];
293+ pCtx->sRefPic.pRefList[LIST_1][j] = pTemp;
294+ }
295+ }
296+ }
297+ }
298+ //long
299+ for (int32_t i = 0; i < pCtx->sRefPic.uiLongRefCount[LIST_0]; ++i) {
300+ pCtx->sRefPic.pRefList[LIST_1][iCount++] = ppLongRefList[i];
301+ }
302+ pCtx->sRefPic.uiRefCount[LIST_1] = iCount;
303+ return ERR_NONE;
304+}
305+
306+/**
307+ * fills the pRefPic.pRefList.
308+ */
309+int32_t WelsInitRefList (PWelsDecoderContext pCtx, int32_t iPoc) {
310+
311+ int32_t err = WelsCheckAndRecoverForFutureDecoding (pCtx);
312+ if (err != ERR_NONE) return err;
313+
314+ WrapShortRefPicNum (pCtx);
315+
316+ PPicture* ppShoreRefList = pCtx->sRefPic.pShortRefList[LIST_0];
317+ PPicture* ppLongRefList = pCtx->sRefPic.pLongRefList[LIST_0];
318+ memset (pCtx->sRefPic.pRefList[LIST_0], 0, MAX_DPB_COUNT * sizeof (PPicture));
319+
320+ int32_t i, iCount = 0;
321+ //short
322+ for (i = 0; i < pCtx->sRefPic.uiShortRefCount[LIST_0]; ++i) {
323+ pCtx->sRefPic.pRefList[LIST_0][iCount++ ] = ppShoreRefList[i];
324+ }
325+
326+ //long
327+ for (i = 0; i < pCtx->sRefPic.uiLongRefCount[LIST_0] ; ++i) {
328+ pCtx->sRefPic.pRefList[LIST_0][iCount++ ] = ppLongRefList[i];
329+ }
330+ pCtx->sRefPic.uiRefCount[LIST_0] = iCount;
331+
332+ return ERR_NONE;
333+}
334+
335+int32_t WelsReorderRefList (PWelsDecoderContext pCtx) {
336+
337+ if (pCtx->eSliceType == I_SLICE || pCtx->eSliceType == SI_SLICE) {
338+ return ERR_NONE;
339+ }
340+
341+ PRefPicListReorderSyn pRefPicListReorderSyn = pCtx->pCurDqLayer->pRefPicListReordering;
342+ PNalUnitHeaderExt pNalHeaderExt = &pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt;
343+ PSliceHeader pSliceHeader = &pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader;
344+ int32_t ListCount = 1;
345+ if (pCtx->eSliceType == B_SLICE) ListCount = 2;
346+ for (int32_t listIdx = 0; listIdx < ListCount; ++listIdx) {
347+ PPicture pPic = NULL;
348+ PPicture* ppRefList = pCtx->sRefPic.pRefList[listIdx];
349+ int32_t iMaxRefIdx = pCtx->pSps->iNumRefFrames;
350+ int32_t iRefCount = pCtx->sRefPic.uiRefCount[listIdx];
351+ int32_t iPredFrameNum = pSliceHeader->iFrameNum;
352+ int32_t iMaxPicNum = 1 << pSliceHeader->pSps->uiLog2MaxFrameNum;
353+ int32_t iAbsDiffPicNum = -1;
354+ int32_t iReorderingIndex = 0;
355+ int32_t i = 0;
356+
357+ if (iRefCount <= 0) {
358+ pCtx->iErrorCode = dsNoParamSets; //No any reference for decoding, SHOULD request IDR
359+ return ERR_INFO_REFERENCE_PIC_LOST;
360+ }
361+
362+ if (pRefPicListReorderSyn->bRefPicListReorderingFlag[listIdx]) {
363+ while ((iReorderingIndex < iMaxRefIdx)
364+ && (pRefPicListReorderSyn->sReorderingSyn[listIdx][iReorderingIndex].uiReorderingOfPicNumsIdc != 3)) {
365+ uint16_t uiReorderingOfPicNumsIdc =
366+ pRefPicListReorderSyn->sReorderingSyn[listIdx][iReorderingIndex].uiReorderingOfPicNumsIdc;
367+ if (uiReorderingOfPicNumsIdc < 2) {
368+ iAbsDiffPicNum = pRefPicListReorderSyn->sReorderingSyn[listIdx][iReorderingIndex].uiAbsDiffPicNumMinus1 + 1;
369+
370+ if (uiReorderingOfPicNumsIdc == 0) {
371+ iPredFrameNum -= iAbsDiffPicNum;
372+ } else {
373+ iPredFrameNum += iAbsDiffPicNum;
374+ }
375+ iPredFrameNum &= iMaxPicNum - 1;
376+
377+ for (i = iMaxRefIdx - 1; i >= 0; i--) {
378+ if (ppRefList[i] != NULL && ppRefList[i]->iFrameNum == iPredFrameNum && !ppRefList[i]->bIsLongRef) {
379+ if ((pNalHeaderExt->uiQualityId == ppRefList[i]->uiQualityId)
380+ && (pSliceHeader->iSpsId != ppRefList[i]->iSpsId)) { //check;
381+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "WelsReorderRefList()::::BASE LAYER::::iSpsId:%d, ref_sps_id:%d",
382+ pSliceHeader->iSpsId, ppRefList[i]->iSpsId);
383+ pCtx->iErrorCode = dsNoParamSets; //cross-IDR reference frame selection, SHOULD request IDR.--
384+ return ERR_INFO_REFERENCE_PIC_LOST;
385+ } else {
386+ break;
387+ }
388+ }
389+ }
390+
391+ } else if (uiReorderingOfPicNumsIdc == 2) {
392+ for (i = iMaxRefIdx - 1; i >= 0; i--) {
393+ if (ppRefList[i] != NULL && ppRefList[i]->bIsLongRef
394+ && ppRefList[i]->iLongTermFrameIdx ==
395+ pRefPicListReorderSyn->sReorderingSyn[listIdx][iReorderingIndex].uiLongTermPicNum) {
396+ if ((pNalHeaderExt->uiQualityId == ppRefList[i]->uiQualityId)
397+ && (pSliceHeader->iSpsId != ppRefList[i]->iSpsId)) { //check;
398+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "WelsReorderRefList()::::BASE LAYER::::iSpsId:%d, ref_sps_id:%d",
399+ pSliceHeader->iSpsId, ppRefList[i]->iSpsId);
400+ pCtx->iErrorCode = dsNoParamSets; //cross-IDR reference frame selection, SHOULD request IDR.--
401+ return ERR_INFO_REFERENCE_PIC_LOST;
402+ } else {
403+ break;
404+ }
405+ }
406+ }
407+ }
408+ if (i < 0) {
409+ return ERR_INFO_REFERENCE_PIC_LOST;
410+ }
411+ pPic = ppRefList[i];
412+ if (i > iReorderingIndex) {
413+ memmove (&ppRefList[1 + iReorderingIndex], &ppRefList[iReorderingIndex],
414+ (i - iReorderingIndex) * sizeof (PPicture)); //confirmed_safe_unsafe_usage
415+ } else if (i < iReorderingIndex) {
416+ memmove (&ppRefList[1 + iReorderingIndex], &ppRefList[iReorderingIndex],
417+ (iMaxRefIdx - iReorderingIndex) * sizeof (PPicture));
418+ }
419+ ppRefList[iReorderingIndex] = pPic;
420+ iReorderingIndex++;
421+ }
422+ }
423+ }
424+ return ERR_NONE;
425+}
426+
427+//WelsReorderRefList2 is the test code
428+int32_t WelsReorderRefList2 (PWelsDecoderContext pCtx) {
429+
430+ if (pCtx->eSliceType == I_SLICE || pCtx->eSliceType == SI_SLICE) {
431+ return ERR_NONE;
432+ }
433+
434+ PRefPicListReorderSyn pRefPicListReorderSyn = pCtx->pCurDqLayer->pRefPicListReordering;
435+ PSliceHeader pSliceHeader = &pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader;
436+
437+ PPicture* ppShoreRefList = pCtx->sRefPic.pShortRefList[LIST_0];
438+ int32_t iShortRefCount = pCtx->sRefPic.uiShortRefCount[LIST_0];
439+ PPicture* ppLongRefList = pCtx->sRefPic.pLongRefList[LIST_0];
440+ int32_t iLongRefCount = pCtx->sRefPic.uiLongRefCount[LIST_0];
441+ int32_t i = 0;
442+ int32_t j = 0;
443+ int32_t k = 0;
444+ int32_t iMaxRefIdx = pCtx->pSps->iNumRefFrames;
445+ const int32_t iCurFrameNum = pSliceHeader->iFrameNum;
446+ const int32_t iMaxPicNum = 1 << pSliceHeader->pSps->uiLog2MaxFrameNum;
447+ int32_t iListCount = 1;
448+ if (pCtx->eSliceType == B_SLICE) iListCount = 2;
449+ for (int32_t listIdx = 0; listIdx < iListCount; ++listIdx) {
450+ PPicture* ppRefList = pCtx->sRefPic.pRefList[listIdx];
451+ int32_t iCount = 0;
452+ int32_t iRefCount = pSliceHeader->uiRefCount[listIdx];
453+ int32_t iAbsDiffPicNum = -1;
454+
455+ if (pRefPicListReorderSyn->bRefPicListReorderingFlag[listIdx]) {
456+ int32_t iPredFrameNum = iCurFrameNum;
457+ for (i = 0; pRefPicListReorderSyn->sReorderingSyn[listIdx][i].uiReorderingOfPicNumsIdc != 3; i++) {
458+ if (iCount >= iMaxRefIdx)
459+ break;
460+
461+ for (j = iRefCount; j > iCount; j--)
462+ ppRefList[j] = ppRefList[j - 1];
463+
464+ uint16_t uiReorderingOfPicNumsIdc =
465+ pRefPicListReorderSyn->sReorderingSyn[listIdx][i].uiReorderingOfPicNumsIdc;
466+
467+ if (uiReorderingOfPicNumsIdc < 2) { // reorder short references
468+ iAbsDiffPicNum = (int32_t) (pRefPicListReorderSyn->sReorderingSyn[listIdx][i].uiAbsDiffPicNumMinus1 + 1);
469+ if (uiReorderingOfPicNumsIdc == 0) {
470+ if (iPredFrameNum - iAbsDiffPicNum < 0)
471+ iPredFrameNum -= (iAbsDiffPicNum - iMaxPicNum);
472+ else
473+ iPredFrameNum -= iAbsDiffPicNum;
474+ } else {
475+ if (iPredFrameNum + iAbsDiffPicNum >= iMaxPicNum)
476+ iPredFrameNum += (iAbsDiffPicNum - iMaxPicNum);
477+ else
478+ iPredFrameNum += iAbsDiffPicNum;
479+ }
480+
481+ if (iPredFrameNum > iCurFrameNum) {
482+ iPredFrameNum -= iMaxPicNum;
483+ }
484+
485+ for (j = 0; j < iShortRefCount; j++) {
486+ if (ppShoreRefList[j]) {
487+ if (ppShoreRefList[j]->iFrameWrapNum == iPredFrameNum) {
488+ ppRefList[iCount++] = ppShoreRefList[j];
489+ break;
490+ }
491+ }
492+ }
493+ k = iCount;
494+ for (j = k; j <= iRefCount; j++) {
495+ if (ppRefList[j] != NULL) {
496+ if (ppRefList[j]->bIsLongRef || ppRefList[j]->iFrameWrapNum != iPredFrameNum)
497+ ppRefList[k++] = ppRefList[j];
498+ }
499+ }
500+ } else { // reorder long term references uiReorderingOfPicNumsIdc == 2
501+ iPredFrameNum = pRefPicListReorderSyn->sReorderingSyn[listIdx][i].uiLongTermPicNum;
502+ for (j = 0; j < iLongRefCount; j++) {
503+ if (ppLongRefList[j] != NULL) {
504+ if (ppLongRefList[j]->uiLongTermPicNum == (uint32_t)iPredFrameNum) {
505+ ppRefList[iCount++] = ppLongRefList[j];
506+ break;
507+ }
508+ }
509+ }
510+ k = iCount;
511+ for (j = k; j <= iRefCount; j++) {
512+ if (ppRefList[j] != NULL) {
513+ if (!ppRefList[j]->bIsLongRef || ppLongRefList[j]->uiLongTermPicNum != (uint32_t)iPredFrameNum)
514+ ppRefList[k++] = ppRefList[j];
515+ }
516+ }
517+ }
518+ }
519+ }
520+
521+ for (i = WELS_MAX (1, WELS_MAX (iCount, pCtx->sRefPic.uiRefCount[listIdx])); i < iRefCount; i++)
522+ ppRefList[i] = ppRefList[i - 1];
523+ pCtx->sRefPic.uiRefCount[listIdx] = (uint8_t)WELS_MIN (WELS_MAX (iCount, pCtx->sRefPic.uiRefCount[listIdx]), iRefCount);
524+ }
525+ return ERR_NONE;
526+}
527+
528+int32_t WelsMarkAsRef (PWelsDecoderContext pCtx) {
529+ PRefPic pRefPic = &pCtx->sRefPic;
530+ PRefPicMarking pRefPicMarking = pCtx->pCurDqLayer->pRefPicMarking;
531+ PAccessUnit pCurAU = pCtx->pAccessUnitList;
532+ bool bIsIDRAU = false;
533+ uint32_t j;
534+
535+ int32_t iRet = ERR_NONE;
536+
537+ pCtx->pDec->uiQualityId = pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.uiQualityId;
538+ pCtx->pDec->uiTemporalId = pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.uiTemporalId;
539+ pCtx->pDec->iSpsId = pCtx->pSps->iSpsId;
540+ pCtx->pDec->iPpsId = pCtx->pPps->iPpsId;
541+
542+ for (j = pCurAU->uiStartPos; j <= pCurAU->uiEndPos; j++) {
543+ if (pCurAU->pNalUnitsList[j]->sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR
544+ || pCurAU->pNalUnitsList[j]->sNalHeaderExt.bIdrFlag) {
545+ bIsIDRAU = true;
546+ break;
547+ }
548+ }
549+ if (bIsIDRAU) {
550+ if (pRefPicMarking->bLongTermRefFlag) {
551+ pCtx->sRefPic.iMaxLongTermFrameIdx = 0;
552+ AddLongTermToList (pRefPic, pCtx->pDec, 0, 0);
553+ } else {
554+ pCtx->sRefPic.iMaxLongTermFrameIdx = -1;
555+ }
556+ } else {
557+ if (pRefPicMarking->bAdaptiveRefPicMarkingModeFlag) {
558+ iRet = MMCO (pCtx, pRefPicMarking);
559+ if (iRet != ERR_NONE) {
560+ if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
561+ iRet = RemainOneBufferInDpbForEC (pCtx);
562+ WELS_VERIFY_RETURN_IF (iRet, iRet);
563+ } else {
564+ return iRet;
565+ }
566+ }
567+
568+ if (pCtx->bLastHasMmco5) {
569+ pCtx->pDec->iFrameNum = 0;
570+ pCtx->pDec->iFramePoc = 0;
571+ }
572+
573+ } else {
574+ iRet = SlidingWindow (pCtx);
575+ if (iRet != ERR_NONE) {
576+ if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
577+ iRet = RemainOneBufferInDpbForEC (pCtx);
578+ WELS_VERIFY_RETURN_IF (iRet, iRet);
579+ } else {
580+ return iRet;
581+ }
582+ }
583+ }
584+ }
585+
586+ if (!pCtx->pDec->bIsLongRef) {
587+ if (pRefPic->uiLongRefCount[LIST_0] + pRefPic->uiShortRefCount[LIST_0] >= WELS_MAX (1, pCtx->pSps->iNumRefFrames)) {
588+ if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
589+ iRet = RemainOneBufferInDpbForEC (pCtx);
590+ WELS_VERIFY_RETURN_IF (iRet, iRet);
591+ } else {
592+ return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW;
593+ }
594+ }
595+ iRet = AddShortTermToList (pRefPic, pCtx->pDec);
596+ }
597+
598+ return iRet;
599+}
600+
601+static int32_t MMCO (PWelsDecoderContext pCtx, PRefPicMarking pRefPicMarking) {
602+ PSps pSps = pCtx->pCurDqLayer->sLayerInfo.pSps;
603+ int32_t i = 0;
604+ int32_t iRet = ERR_NONE;
605+ for (i = 0; i < MAX_MMCO_COUNT && pRefPicMarking->sMmcoRef[i].uiMmcoType != MMCO_END; i++) {
606+ uint32_t uiMmcoType = pRefPicMarking->sMmcoRef[i].uiMmcoType;
607+ int32_t iShortFrameNum = (pCtx->iFrameNum - pRefPicMarking->sMmcoRef[i].iDiffOfPicNum) & ((
608+ 1 << pSps->uiLog2MaxFrameNum) - 1);
609+ uint32_t uiLongTermPicNum = pRefPicMarking->sMmcoRef[i].uiLongTermPicNum;
610+ int32_t iLongTermFrameIdx = pRefPicMarking->sMmcoRef[i].iLongTermFrameIdx;
611+ int32_t iMaxLongTermFrameIdx = pRefPicMarking->sMmcoRef[i].iMaxLongTermFrameIdx;
612+ if (uiMmcoType > MMCO_LONG) {
613+ return ERR_INFO_INVALID_MMCO_OPCODE_BASE;
614+ }
615+ iRet = MMCOProcess (pCtx, uiMmcoType, iShortFrameNum, uiLongTermPicNum, iLongTermFrameIdx, iMaxLongTermFrameIdx);
616+ if (iRet != ERR_NONE) {
617+ return iRet;
618+ }
619+ }
620+ if (i == MAX_MMCO_COUNT) { //although Rec does not handle this condition, we here prohibit too many MMCO op
621+ return ERR_INFO_INVALID_MMCO_NUM;
622+ }
623+
624+ return ERR_NONE;
625+}
626+static int32_t MMCOProcess (PWelsDecoderContext pCtx, uint32_t uiMmcoType,
627+ int32_t iShortFrameNum, uint32_t uiLongTermPicNum, int32_t iLongTermFrameIdx, int32_t iMaxLongTermFrameIdx) {
628+ PRefPic pRefPic = &pCtx->sRefPic;
629+ PPicture pPic = NULL;
630+ int32_t i = 0;
631+ int32_t iRet = ERR_NONE;
632+
633+ switch (uiMmcoType) {
634+ case MMCO_SHORT2UNUSED:
635+ pPic = WelsDelShortFromListSetUnref (pRefPic, iShortFrameNum);
636+ if (pPic == NULL) {
637+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "MMCO_SHORT2UNUSED: delete an empty entry from short term list");
638+ }
639+ break;
640+ case MMCO_LONG2UNUSED:
641+ pPic = WelsDelLongFromListSetUnref (pRefPic, uiLongTermPicNum);
642+ if (pPic == NULL) {
643+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "MMCO_LONG2UNUSED: delete an empty entry from long term list");
644+ }
645+ break;
646+ case MMCO_SHORT2LONG:
647+ if (iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx) {
648+ return ERR_INFO_INVALID_MMCO_LONG_TERM_IDX_EXCEED_MAX;
649+ }
650+ pPic = WelsDelShortFromList (pRefPic, iShortFrameNum);
651+ if (pPic == NULL) {
652+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "MMCO_LONG2LONG: delete an empty entry from short term list");
653+ break;
654+ }
655+ WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx);
656+#ifdef LONG_TERM_REF
657+ pCtx->bCurAuContainLtrMarkSeFlag = true;
658+ pCtx->iFrameNumOfAuMarkedLtr = iShortFrameNum;
659+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "ex_mark_avc():::MMCO_SHORT2LONG:::LTR marking....iFrameNum: %d",
660+ pCtx->iFrameNumOfAuMarkedLtr);
661+#endif
662+
663+ MarkAsLongTerm (pRefPic, iShortFrameNum, iLongTermFrameIdx, uiLongTermPicNum);
664+ break;
665+ case MMCO_SET_MAX_LONG:
666+ pRefPic->iMaxLongTermFrameIdx = iMaxLongTermFrameIdx;
667+ for (i = 0 ; i < pRefPic->uiLongRefCount[LIST_0]; i++) {
668+ if (pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx) {
669+ WelsDelLongFromListSetUnref (pRefPic, pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx);
670+ }
671+ }
672+ break;
673+ case MMCO_RESET:
674+ WelsResetRefPic (pCtx);
675+ pCtx->bLastHasMmco5 = true;
676+ break;
677+ case MMCO_LONG:
678+ if (iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx) {
679+ return ERR_INFO_INVALID_MMCO_LONG_TERM_IDX_EXCEED_MAX;
680+ }
681+ WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx);
682+ if (pRefPic->uiLongRefCount[LIST_0] + pRefPic->uiShortRefCount[LIST_0] >= WELS_MAX (1, pCtx->pSps->iNumRefFrames)) {
683+ return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW;
684+ }
685+#ifdef LONG_TERM_REF
686+ pCtx->bCurAuContainLtrMarkSeFlag = true;
687+ pCtx->iFrameNumOfAuMarkedLtr = pCtx->iFrameNum;
688+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "ex_mark_avc():::MMCO_LONG:::LTR marking....iFrameNum: %d",
689+ pCtx->iFrameNum);
690+#endif
691+ iRet = AddLongTermToList (pRefPic, pCtx->pDec, iLongTermFrameIdx, uiLongTermPicNum);
692+ break;
693+ default :
694+ break;
695+ }
696+
697+ return iRet;
698+}
699+
700+static int32_t SlidingWindow (PWelsDecoderContext pCtx) {
701+ PRefPic pRefPic = &pCtx->sRefPic;
702+ PPicture pPic = NULL;
703+ int32_t i = 0;
704+
705+ if (pCtx->sRefPic.uiShortRefCount[LIST_0] + pCtx->sRefPic.uiLongRefCount[LIST_0] >= pCtx->pSps->iNumRefFrames) {
706+ if (pCtx->sRefPic.uiShortRefCount[LIST_0] == 0) {
707+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "No reference picture in short term list when sliding window");
708+ return ERR_INFO_INVALID_MMCO_REF_NUM_NOT_ENOUGH;
709+ }
710+ for (i = pRefPic->uiShortRefCount[LIST_0] - 1; i >= 0; i--) {
711+ pPic = WelsDelShortFromList (pRefPic, pRefPic->pShortRefList[LIST_0][i]->iFrameNum);
712+ if (pPic) {
713+ SetUnRef (pPic);
714+ break;
715+ } else {
716+ return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW;
717+ }
718+ }
719+ }
720+ return ERR_NONE;
721+}
722+
723+static PPicture WelsDelShortFromList (PRefPic pRefPic, int32_t iFrameNum) {
724+ int32_t i = 0;
725+ int32_t iMoveSize = 0;
726+ PPicture pPic = NULL;
727+
728+ for (i = 0; i < pRefPic->uiShortRefCount[LIST_0]; i++) {
729+ if (pRefPic->pShortRefList[LIST_0][i]->iFrameNum == iFrameNum) {
730+ iMoveSize = pRefPic->uiShortRefCount[LIST_0] - i - 1;
731+ pRefPic->pShortRefList[LIST_0][i]->bUsedAsRef = false;
732+ pPic = pRefPic->pShortRefList[LIST_0][i];
733+ pRefPic->pShortRefList[LIST_0][i] = NULL;
734+ if (iMoveSize > 0) {
735+ memmove (&pRefPic->pShortRefList[LIST_0][i], &pRefPic->pShortRefList[LIST_0][i + 1],
736+ iMoveSize * sizeof (PPicture)); //confirmed_safe_unsafe_usage
737+ }
738+ pRefPic->uiShortRefCount[LIST_0]--;
739+ pRefPic->pShortRefList[LIST_0][pRefPic->uiShortRefCount[LIST_0]] = NULL;
740+ break;
741+ }
742+ }
743+
744+ return pPic;
745+}
746+
747+static PPicture WelsDelShortFromListSetUnref (PRefPic pRefPic, int32_t iFrameNum) {
748+ PPicture pPic = WelsDelShortFromList (pRefPic, iFrameNum);
749+ if (pPic) {
750+ SetUnRef (pPic);
751+ }
752+ return pPic;
753+}
754+
755+static PPicture WelsDelLongFromList (PRefPic pRefPic, uint32_t uiLongTermFrameIdx) {
756+ PPicture pPic = NULL;
757+ int32_t i = 0;
758+ for (i = 0; i < pRefPic->uiLongRefCount[LIST_0]; i++) {
759+ pPic = pRefPic->pLongRefList[LIST_0][i];
760+ if (pPic->iLongTermFrameIdx == (int32_t)uiLongTermFrameIdx) {
761+ int32_t iMoveSize = pRefPic->uiLongRefCount[LIST_0] - i - 1;
762+ pPic->bUsedAsRef = false;
763+ pPic->bIsLongRef = false;
764+ if (iMoveSize > 0) {
765+ memmove (&pRefPic->pLongRefList[LIST_0][i], &pRefPic->pLongRefList[LIST_0][i + 1],
766+ iMoveSize * sizeof (PPicture)); //confirmed_safe_unsafe_usage
767+ }
768+ pRefPic->uiLongRefCount[LIST_0]--;
769+ pRefPic->pLongRefList[LIST_0][pRefPic->uiLongRefCount[LIST_0]] = NULL;
770+ return pPic;
771+ }
772+ }
773+ return NULL;
774+}
775+
776+static PPicture WelsDelLongFromListSetUnref (PRefPic pRefPic, uint32_t uiLongTermFrameIdx) {
777+ PPicture pPic = WelsDelLongFromList (pRefPic, uiLongTermFrameIdx);
778+ if (pPic) {
779+ SetUnRef (pPic);
780+ }
781+ return pPic;
782+}
783+
784+static int32_t AddShortTermToList (PRefPic pRefPic, PPicture pPic) {
785+ pPic->bUsedAsRef = true;
786+ pPic->bIsLongRef = false;
787+ pPic->iLongTermFrameIdx = -1;
788+ if (pRefPic->uiShortRefCount[LIST_0] > 0) {
789+ // Check the duplicate frame_num in short ref list
790+ for (int32_t iPos = 0; iPos < pRefPic->uiShortRefCount[LIST_0]; iPos++) {
791+ if (pPic->iFrameNum == pRefPic->pShortRefList[LIST_0][iPos]->iFrameNum) {
792+ // Replace the previous ref pic with the new one with the same frame_num
793+ pRefPic->pShortRefList[LIST_0][iPos] = pPic;
794+ return ERR_INFO_DUPLICATE_FRAME_NUM;
795+ }
796+ }
797+
798+ memmove (&pRefPic->pShortRefList[LIST_0][1], &pRefPic->pShortRefList[LIST_0][0],
799+ pRefPic->uiShortRefCount[LIST_0]*sizeof (PPicture));//confirmed_safe_unsafe_usage
800+ }
801+ pRefPic->pShortRefList[LIST_0][0] = pPic;
802+ pRefPic->uiShortRefCount[LIST_0]++;
803+ return ERR_NONE;
804+}
805+
806+static int32_t AddLongTermToList (PRefPic pRefPic, PPicture pPic, int32_t iLongTermFrameIdx,
807+ uint32_t uiLongTermPicNum) {
808+ int32_t i = 0;
809+
810+ pPic->bUsedAsRef = true;
811+ pPic->bIsLongRef = true;
812+ pPic->iLongTermFrameIdx = iLongTermFrameIdx;
813+ pPic->uiLongTermPicNum = uiLongTermPicNum;
814+ if (pRefPic->uiLongRefCount[LIST_0] == 0) {
815+ pRefPic->pLongRefList[LIST_0][pRefPic->uiLongRefCount[LIST_0]] = pPic;
816+ } else {
817+ for (i = 0; i < pRefPic->uiLongRefCount[LIST_0]; i++) {
818+ if (pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx > pPic->iLongTermFrameIdx) {
819+ break;
820+ }
821+ }
822+ memmove (&pRefPic->pLongRefList[LIST_0][i + 1], &pRefPic->pLongRefList[LIST_0][i],
823+ (pRefPic->uiLongRefCount[LIST_0] - i)*sizeof (PPicture)); //confirmed_safe_unsafe_usage
824+ pRefPic->pLongRefList[LIST_0][i] = pPic;
825+ }
826+
827+ pRefPic->uiLongRefCount[LIST_0]++;
828+ return ERR_NONE;
829+}
830+
831+static int32_t MarkAsLongTerm (PRefPic pRefPic, int32_t iFrameNum, int32_t iLongTermFrameIdx,
832+ uint32_t uiLongTermPicNum) {
833+ PPicture pPic = NULL;
834+ int32_t i = 0;
835+ int32_t iRet = ERR_NONE;
836+ WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx);
837+
838+ for (i = 0; i < pRefPic->uiRefCount[LIST_0]; i++) {
839+ pPic = pRefPic->pRefList[LIST_0][i];
840+ if (pPic->iFrameNum == iFrameNum && !pPic->bIsLongRef) {
841+ iRet = AddLongTermToList (pRefPic, pPic, iLongTermFrameIdx, uiLongTermPicNum);
842+ break;
843+ }
844+ }
845+
846+ return iRet;
847+}
848+
849+#ifdef LONG_TERM_REF
850+int32_t GetLTRFrameIndex (PRefPic pRefPic, int32_t iAncLTRFrameNum) {
851+ int32_t iLTRFrameIndex = -1;
852+ PPicture pPic;
853+ for (int i = 0; i < pRefPic->uiLongRefCount[0]; ++i) {
854+ pPic = pRefPic->pLongRefList[LIST_0][i];
855+ if (pPic->iFrameNum == iAncLTRFrameNum) {
856+ return (pPic->iLongTermFrameIdx);
857+ }
858+ }
859+ return iLTRFrameIndex;
860+}
861+#endif
862+
863+static int32_t RemainOneBufferInDpbForEC (PWelsDecoderContext pCtx) {
864+ int32_t iRet = ERR_NONE;
865+ PRefPic pRefPic = &pCtx->sRefPic;
866+ if (pRefPic->uiShortRefCount[0] + pRefPic->uiLongRefCount[0] < pCtx->pSps->iNumRefFrames)
867+ return iRet;
868+
869+ if (pRefPic->uiShortRefCount[0] > 0) {
870+ iRet = SlidingWindow (pCtx);
871+ } else { //all LTR, remove the smallest long_term_frame_idx
872+ int32_t iLongTermFrameIdx = 0;
873+ int32_t iMaxLongTermFrameIdx = pRefPic->iMaxLongTermFrameIdx;
874+#ifdef LONG_TERM_REF
875+ int32_t iCurrLTRFrameIdx = GetLTRFrameIndex (pRefPic, pCtx->iFrameNumOfAuMarkedLtr);
876+#endif
877+ while ((pRefPic->uiLongRefCount[0] >= pCtx->pSps->iNumRefFrames) && (iLongTermFrameIdx <= iMaxLongTermFrameIdx)) {
878+#ifdef LONG_TERM_REF
879+ if (iLongTermFrameIdx == iCurrLTRFrameIdx) {
880+ iLongTermFrameIdx++;
881+ continue;
882+ }
883+#endif
884+ WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx);
885+ iLongTermFrameIdx++;
886+ }
887+ }
888+ if (pRefPic->uiShortRefCount[0] + pRefPic->uiLongRefCount[0] >=
889+ pCtx->pSps->iNumRefFrames) { //fail to remain one empty buffer in DPB
890+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "RemainOneBufferInDpbForEC(): empty one DPB failed for EC!");
891+ iRet = ERR_INFO_REF_COUNT_OVERFLOW;
892+ }
893+
894+ return iRet;
895+}
896+
897+} // namespace WelsDec

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

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

Repository code

Go to file
t