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/manage_dec_ref.cpp (1 of 55 files). Show all

Unified · Split

codec/decoder/core/src/manage_dec_ref.cpp+773−630
@@ -1,630 +1,773 @@
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);
60−static int32_t MarkAsLongTerm (PRefPic pRefPic, int32_t iFrameNum, int32_t iLongTermFrameIdx);
61−#ifdef LONG_TERM_REF
62−int32_t GetLTRFrameIndex (PRefPic pRefPic, int32_t iAncLTRFrameNum);
63−#endif
64−static int32_t RemainOneBufferInDpbForEC (PWelsDecoderContext pCtx);
65−
66−static void SetUnRef (PPicture pRef) {
67− if (NULL != pRef) {
68− pRef->bUsedAsRef = false;
69− pRef->bIsLongRef = false;
70− pRef->iFrameNum = -1;
71− //pRef->iFramePoc = 0;
72− pRef->iLongTermFrameIdx = -1;
73− pRef->uiQualityId = -1;
74− pRef->uiTemporalId = -1;
75− pRef->uiSpatialId = -1;
76− pRef->iSpsId = -1;
77− pRef->bIsComplete = false;
78− }
79−}
80−
81−//reset pRefList when
82−// 1.sps arrived that is new sequence starting
83−// 2.IDR NAL i.e. 1st layer in IDR AU
84−
85−void WelsResetRefPic (PWelsDecoderContext pCtx) {
86− int32_t i = 0;
87− PRefPic pRefPic = &pCtx->sRefPic;
88− pCtx->sRefPic.uiLongRefCount[LIST_0] = pCtx->sRefPic.uiShortRefCount[LIST_0] = 0;
89−
90− pRefPic->uiRefCount[LIST_0] = 0;
91−
92− for (i = 0; i < MAX_DPB_COUNT; i++) {
93− if (pRefPic->pShortRefList[LIST_0][i] != NULL) {
94− SetUnRef (pRefPic->pShortRefList[LIST_0][i]);
95− pRefPic->pShortRefList[LIST_0][i] = NULL;
96− }
97− }
98− pRefPic->uiShortRefCount[LIST_0] = 0;
99−
100− for (i = 0; i < MAX_DPB_COUNT; i++) {
101− if (pRefPic->pLongRefList[LIST_0][i] != NULL) {
102− SetUnRef (pRefPic->pLongRefList[LIST_0][i]);
103− pRefPic->pLongRefList[LIST_0][i] = NULL;
104− }
105− }
106− pRefPic->uiLongRefCount[LIST_0] = 0;
107−}
108−
109−/**
110− * fills the pRefPic.pRefList.
111− */
112−int32_t WelsInitRefList (PWelsDecoderContext pCtx, int32_t iPoc) {
113− int32_t i, iCount = 0;
114−
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[0]);
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−
160− PPicture* ppShoreRefList = pCtx->sRefPic.pShortRefList[LIST_0];
161− PPicture* ppLongRefList = pCtx->sRefPic.pLongRefList[LIST_0];
162− memset (pCtx->sRefPic.pRefList[LIST_0], 0, MAX_DPB_COUNT * sizeof (PPicture));
163− //short
164− for (i = 0; i < pCtx->sRefPic.uiShortRefCount[LIST_0]; ++i) {
165− pCtx->sRefPic.pRefList[LIST_0][iCount++ ] = ppShoreRefList[i];
166− }
167−
168− //long
169− for (i = 0; i < pCtx->sRefPic.uiLongRefCount[LIST_0] ; ++i) {
170− pCtx->sRefPic.pRefList[LIST_0][iCount++ ] = ppLongRefList[i];
171− }
172− pCtx->sRefPic.uiRefCount[LIST_0] = iCount;
173−
174− return ERR_NONE;
175−}
176−
177−int32_t WelsReorderRefList (PWelsDecoderContext pCtx) {
178− PRefPicListReorderSyn pRefPicListReorderSyn = pCtx->pCurDqLayer->pRefPicListReordering;
179− PNalUnitHeaderExt pNalHeaderExt = &pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt;
180− PSliceHeader pSliceHeader = &pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader;
181− PPicture pPic = NULL;
182− PPicture* ppRefList = pCtx->sRefPic.pRefList[LIST_0];
183− int32_t iMaxRefIdx = pCtx->pSps->iNumRefFrames;
184− int32_t iRefCount = pCtx->sRefPic.uiRefCount[LIST_0];
185− int32_t iPredFrameNum = pSliceHeader->iFrameNum;
186− int32_t iMaxPicNum = 1 << pSliceHeader->pSps->uiLog2MaxFrameNum;
187− int32_t iAbsDiffPicNum = -1;
188− int32_t iReorderingIndex = 0;
189− int32_t i = 0;
190−
191− if (pCtx->eSliceType == I_SLICE || pCtx->eSliceType == SI_SLICE) {
192− return ERR_NONE;
193− }
194−
195− if (iRefCount <= 0) {
196− pCtx->iErrorCode = dsNoParamSets; //No any reference for decoding, SHOULD request IDR
197− return ERR_INFO_REFERENCE_PIC_LOST;
198− }
199−
200− if (pRefPicListReorderSyn->bRefPicListReorderingFlag[LIST_0]) {
201− while ((iReorderingIndex < iMaxRefIdx)
202− && (pRefPicListReorderSyn->sReorderingSyn[LIST_0][iReorderingIndex].uiReorderingOfPicNumsIdc != 3)) {
203− uint16_t uiReorderingOfPicNumsIdc =
204− pRefPicListReorderSyn->sReorderingSyn[LIST_0][iReorderingIndex].uiReorderingOfPicNumsIdc;
205− if (uiReorderingOfPicNumsIdc < 2) {
206− iAbsDiffPicNum = pRefPicListReorderSyn->sReorderingSyn[LIST_0][iReorderingIndex].uiAbsDiffPicNumMinus1 + 1;
207−
208− if (uiReorderingOfPicNumsIdc == 0) {
209− iPredFrameNum -= iAbsDiffPicNum;
210− } else {
211− iPredFrameNum += iAbsDiffPicNum;
212− }
213− iPredFrameNum &= iMaxPicNum - 1;
214−
215− for (i = iMaxRefIdx - 1; i >= 0; i--) {
216− if (ppRefList[i] != NULL && ppRefList[i]->iFrameNum == iPredFrameNum && !ppRefList[i]->bIsLongRef) {
217− if ((pNalHeaderExt->uiQualityId == ppRefList[i]->uiQualityId)
218− && (pSliceHeader->iSpsId != ppRefList[i]->iSpsId)) { //check;
219− WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "WelsReorderRefList()::::BASE LAYER::::iSpsId:%d, ref_sps_id:%d",
220− pSliceHeader->iSpsId, ppRefList[i]->iSpsId);
221− pCtx->iErrorCode = dsNoParamSets; //cross-IDR reference frame selection, SHOULD request IDR.--
222− return ERR_INFO_REFERENCE_PIC_LOST;
223− } else {
224− break;
225− }
226− }
227− }
228−
229− } else if (uiReorderingOfPicNumsIdc == 2) {
230− for (i = iMaxRefIdx - 1; i >= 0; i--) {
231− if (ppRefList[i] != NULL && ppRefList[i]->bIsLongRef
232− && ppRefList[i]->iLongTermFrameIdx ==
233− pRefPicListReorderSyn->sReorderingSyn[LIST_0][iReorderingIndex].uiLongTermPicNum) {
234− if ((pNalHeaderExt->uiQualityId == ppRefList[i]->uiQualityId)
235− && (pSliceHeader->iSpsId != ppRefList[i]->iSpsId)) { //check;
236− WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "WelsReorderRefList()::::BASE LAYER::::iSpsId:%d, ref_sps_id:%d",
237− pSliceHeader->iSpsId, ppRefList[i]->iSpsId);
238− pCtx->iErrorCode = dsNoParamSets; //cross-IDR reference frame selection, SHOULD request IDR.--
239− return ERR_INFO_REFERENCE_PIC_LOST;
240− } else {
241− break;
242− }
243− }
244− }
245− }
246− if (i < 0) {
247− return ERR_INFO_REFERENCE_PIC_LOST;
248− }
249− pPic = ppRefList[i];
250− if (i > iReorderingIndex) {
251− memmove (&ppRefList[1 + iReorderingIndex], &ppRefList[iReorderingIndex],
252− (i - iReorderingIndex)*sizeof (PPicture)); //confirmed_safe_unsafe_usage
253− } else if (i < iReorderingIndex) {
254− memmove (&ppRefList[1 + iReorderingIndex], &ppRefList[iReorderingIndex],
255− (iMaxRefIdx - iReorderingIndex)*sizeof (PPicture));
256− }
257− ppRefList[iReorderingIndex] = pPic;
258− iReorderingIndex++;
259− }
260− }
261− return ERR_NONE;
262−}
263−
264−int32_t WelsMarkAsRef (PWelsDecoderContext pCtx) {
265− PRefPic pRefPic = &pCtx->sRefPic;
266− PRefPicMarking pRefPicMarking = pCtx->pCurDqLayer->pRefPicMarking;
267− PAccessUnit pCurAU = pCtx->pAccessUnitList;
268− bool bIsIDRAU = false;
269− uint32_t j;
270−
271− int32_t iRet = ERR_NONE;
272−
273− pCtx->pDec->uiQualityId = pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.uiQualityId;
274− pCtx->pDec->uiTemporalId = pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.uiTemporalId;
275− pCtx->pDec->iSpsId = pCtx->pSps->iSpsId;
276− pCtx->pDec->iPpsId = pCtx->pPps->iPpsId;
277−
278− for (j = pCurAU->uiStartPos; j <= pCurAU->uiEndPos; j++) {
279− if (pCurAU->pNalUnitsList[j]->sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR
280− || pCurAU->pNalUnitsList[j]->sNalHeaderExt.bIdrFlag) {
281− bIsIDRAU = true;
282− break;
283− }
284− }
285− if (bIsIDRAU) {
286− if (pRefPicMarking->bLongTermRefFlag) {
287− pCtx->sRefPic.iMaxLongTermFrameIdx = 0;
288− AddLongTermToList (pRefPic, pCtx->pDec, 0);
289− } else {
290− pCtx->sRefPic.iMaxLongTermFrameIdx = -1;
291− }
292− } else {
293− if (pRefPicMarking->bAdaptiveRefPicMarkingModeFlag) {
294− iRet = MMCO (pCtx, pRefPicMarking);
295− if (iRet != ERR_NONE) {
296− if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
297− iRet = RemainOneBufferInDpbForEC (pCtx);
298− WELS_VERIFY_RETURN_IF (iRet, iRet);
299− } else {
300− return iRet;
301− }
302− }
303−
304− if (pCtx->bLastHasMmco5) {
305− pCtx->pDec->iFrameNum = 0;
306− pCtx->pDec->iFramePoc = 0;
307− }
308−
309− } else {
310− iRet = SlidingWindow (pCtx);
311− if (iRet != ERR_NONE) {
312− if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
313− iRet = RemainOneBufferInDpbForEC (pCtx);
314− WELS_VERIFY_RETURN_IF (iRet, iRet);
315− } else {
316− return iRet;
317− }
318− }
319− }
320− }
321−
322− if (!pCtx->pDec->bIsLongRef) {
323− if (pRefPic->uiLongRefCount[LIST_0] + pRefPic->uiShortRefCount[LIST_0] >= WELS_MAX (1, pCtx->pSps->iNumRefFrames)) {
324− if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
325− iRet = RemainOneBufferInDpbForEC (pCtx);
326− WELS_VERIFY_RETURN_IF (iRet, iRet);
327− } else {
328− return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW;
329− }
330− }
331− iRet = AddShortTermToList (pRefPic, pCtx->pDec);
332− }
333−
334− return iRet;
335−}
336−
337−static int32_t MMCO (PWelsDecoderContext pCtx, PRefPicMarking pRefPicMarking) {
338− PSps pSps = pCtx->pCurDqLayer->sLayerInfo.pSps;
339− int32_t i = 0;
340− int32_t iRet = ERR_NONE;
341− for (i = 0; i < MAX_MMCO_COUNT && pRefPicMarking->sMmcoRef[i].uiMmcoType != MMCO_END; i++) {
342− uint32_t uiMmcoType = pRefPicMarking->sMmcoRef[i].uiMmcoType;
343− int32_t iShortFrameNum = (pCtx->iFrameNum - pRefPicMarking->sMmcoRef[i].iDiffOfPicNum) & ((
344− 1 << pSps->uiLog2MaxFrameNum) - 1);
345− uint32_t uiLongTermPicNum = pRefPicMarking->sMmcoRef[i].uiLongTermPicNum;
346− int32_t iLongTermFrameIdx = pRefPicMarking->sMmcoRef[i].iLongTermFrameIdx;
347− int32_t iMaxLongTermFrameIdx = pRefPicMarking->sMmcoRef[i].iMaxLongTermFrameIdx;
348− if (uiMmcoType > MMCO_LONG) {
349− return ERR_INFO_INVALID_MMCO_OPCODE_BASE;
350− }
351− iRet = MMCOProcess (pCtx, uiMmcoType, iShortFrameNum, uiLongTermPicNum, iLongTermFrameIdx, iMaxLongTermFrameIdx);
352− if (iRet != ERR_NONE) {
353− return iRet;
354− }
355− }
356− if (i == MAX_MMCO_COUNT) { //although Rec does not handle this condition, we here prohibit too many MMCO op
357− return ERR_INFO_INVALID_MMCO_NUM;
358− }
359−
360− return ERR_NONE;
361−}
362−static int32_t MMCOProcess (PWelsDecoderContext pCtx, uint32_t uiMmcoType,
363− int32_t iShortFrameNum, uint32_t uiLongTermPicNum , int32_t iLongTermFrameIdx, int32_t iMaxLongTermFrameIdx) {
364− PRefPic pRefPic = &pCtx->sRefPic;
365− PPicture pPic = NULL;
366− int32_t i = 0;
367− int32_t iRet = ERR_NONE;
368−
369− switch (uiMmcoType) {
370− case MMCO_SHORT2UNUSED:
371− pPic = WelsDelShortFromListSetUnref (pRefPic, iShortFrameNum);
372− if (pPic == NULL) {
373− WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "MMCO_SHORT2UNUSED: delete an empty entry from short term list");
374− }
375− break;
376− case MMCO_LONG2UNUSED:
377− pPic = WelsDelLongFromListSetUnref (pRefPic, uiLongTermPicNum);
378− if (pPic == NULL) {
379− WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "MMCO_LONG2UNUSED: delete an empty entry from long term list");
380− }
381− break;
382− case MMCO_SHORT2LONG:
383− if (iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx) {
384− return ERR_INFO_INVALID_MMCO_LONG_TERM_IDX_EXCEED_MAX;
385− }
386− pPic = WelsDelShortFromList (pRefPic, iShortFrameNum);
387− if (pPic == NULL) {
388− WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "MMCO_LONG2LONG: delete an empty entry from short term list");
389− break;
390− }
391− WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx);
392−#ifdef LONG_TERM_REF
393− pCtx->bCurAuContainLtrMarkSeFlag = true;
394− pCtx->iFrameNumOfAuMarkedLtr = iShortFrameNum;
395− WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "ex_mark_avc():::MMCO_SHORT2LONG:::LTR marking....iFrameNum: %d",
396− pCtx->iFrameNumOfAuMarkedLtr);
397−#endif
398−
399− MarkAsLongTerm (pRefPic, iShortFrameNum, iLongTermFrameIdx);
400− break;
401− case MMCO_SET_MAX_LONG:
402− pRefPic->iMaxLongTermFrameIdx = iMaxLongTermFrameIdx;
403− for (i = 0 ; i < pRefPic->uiLongRefCount[LIST_0]; i++) {
404− if (pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx) {
405− WelsDelLongFromListSetUnref (pRefPic, pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx);
406− }
407− }
408− break;
409− case MMCO_RESET:
410− WelsResetRefPic (pCtx);
411− pCtx->bLastHasMmco5 = true;
412− break;
413− case MMCO_LONG:
414− if (iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx) {
415− return ERR_INFO_INVALID_MMCO_LONG_TERM_IDX_EXCEED_MAX;
416− }
417− WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx);
418− if (pRefPic->uiLongRefCount[LIST_0] + pRefPic->uiShortRefCount[LIST_0] >= WELS_MAX (1, pCtx->pSps->iNumRefFrames)) {
419− return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW;
420− }
421−#ifdef LONG_TERM_REF
422− pCtx->bCurAuContainLtrMarkSeFlag = true;
423− pCtx->iFrameNumOfAuMarkedLtr = pCtx->iFrameNum;
424− WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "ex_mark_avc():::MMCO_LONG:::LTR marking....iFrameNum: %d",
425− pCtx->iFrameNum);
426−#endif
427− iRet = AddLongTermToList (pRefPic, pCtx->pDec, iLongTermFrameIdx);
428− break;
429− default :
430− break;
431− }
432−
433− return iRet;
434−}
435−
436−static int32_t SlidingWindow (PWelsDecoderContext pCtx) {
437− PRefPic pRefPic = &pCtx->sRefPic;
438− PPicture pPic = NULL;
439− int32_t i = 0;
440−
441− if (pCtx->sRefPic.uiShortRefCount[LIST_0] + pCtx->sRefPic.uiLongRefCount[LIST_0] >= pCtx->pSps->iNumRefFrames) {
442− if (pCtx->sRefPic.uiShortRefCount[LIST_0] == 0) {
443− WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "No reference picture in short term list when sliding window");
444− return ERR_INFO_INVALID_MMCO_REF_NUM_NOT_ENOUGH;
445− }
446− for (i = pRefPic->uiShortRefCount[LIST_0] - 1; i >= 0; i--) {
447− pPic = WelsDelShortFromList (pRefPic, pRefPic->pShortRefList[LIST_0][i]->iFrameNum);
448− if (pPic) {
449− SetUnRef (pPic);
450− break;
451− } else {
452− return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW;
453− }
454− }
455− }
456− return ERR_NONE;
457−}
458−
459−static PPicture WelsDelShortFromList (PRefPic pRefPic, int32_t iFrameNum) {
460− int32_t i = 0;
461− int32_t iMoveSize = 0;
462− PPicture pPic = NULL;
463−
464− for (i = 0; i < pRefPic->uiShortRefCount[LIST_0]; i++) {
465− if (pRefPic->pShortRefList[LIST_0][i]->iFrameNum == iFrameNum) {
466− iMoveSize = pRefPic->uiShortRefCount[LIST_0] - i - 1;
467− pRefPic->pShortRefList[LIST_0][i]->bUsedAsRef = false;
468− pPic = pRefPic->pShortRefList[LIST_0][i];
469− pRefPic->pShortRefList[LIST_0][i] = NULL;
470− if (iMoveSize > 0) {
471− memmove (&pRefPic->pShortRefList[LIST_0][i], &pRefPic->pShortRefList[LIST_0][i + 1],
472− iMoveSize * sizeof (PPicture)); //confirmed_safe_unsafe_usage
473− }
474− pRefPic->uiShortRefCount[LIST_0]--;
475− pRefPic->pShortRefList[LIST_0][pRefPic->uiShortRefCount[LIST_0]] = NULL;
476− break;
477− }
478− }
479−
480− return pPic;
481−}
482−
483−static PPicture WelsDelShortFromListSetUnref (PRefPic pRefPic, int32_t iFrameNum) {
484− PPicture pPic = WelsDelShortFromList (pRefPic, iFrameNum);
485− if (pPic) {
486− SetUnRef (pPic);
487− }
488− return pPic;
489−}
490−
491−static PPicture WelsDelLongFromList (PRefPic pRefPic, uint32_t uiLongTermFrameIdx) {
492− PPicture pPic = NULL;
493− int32_t i = 0;
494− for (i = 0; i < pRefPic->uiLongRefCount[LIST_0]; i++) {
495− pPic = pRefPic->pLongRefList[LIST_0][i];
496− if (pPic->iLongTermFrameIdx == (int32_t)uiLongTermFrameIdx) {
497− int32_t iMoveSize = pRefPic->uiLongRefCount[LIST_0] - i - 1;
498− pPic->bUsedAsRef = false;
499− pPic->bIsLongRef = false;
500− if (iMoveSize > 0) {
501− memmove (&pRefPic->pLongRefList[LIST_0][i], &pRefPic->pLongRefList[LIST_0][i + 1],
502− iMoveSize * sizeof (PPicture)); //confirmed_safe_unsafe_usage
503− }
504− pRefPic->uiLongRefCount[LIST_0]--;
505− pRefPic->pLongRefList[LIST_0][pRefPic->uiLongRefCount[LIST_0]] = NULL;
506− return pPic;
507− }
508− }
509− return NULL;
510−}
511−
512−static PPicture WelsDelLongFromListSetUnref (PRefPic pRefPic, uint32_t uiLongTermFrameIdx) {
513− PPicture pPic = WelsDelLongFromList (pRefPic, uiLongTermFrameIdx);
514− if (pPic) {
515− SetUnRef (pPic);
516− }
517− return pPic;
518−}
519−
520−static int32_t AddShortTermToList (PRefPic pRefPic, PPicture pPic) {
521− pPic->bUsedAsRef = true;
522− pPic->bIsLongRef = false;
523− pPic->iLongTermFrameIdx = -1;
524− if (pRefPic->uiShortRefCount[LIST_0] > 0) {
525− // Check the duplicate frame_num in short ref list
526− for (int32_t iPos = 0; iPos < pRefPic->uiShortRefCount[LIST_0]; iPos++) {
527− if (pPic->iFrameNum == pRefPic->pShortRefList[LIST_0][iPos]->iFrameNum) {
528− // Replace the previous ref pic with the new one with the same frame_num
529− pRefPic->pShortRefList[LIST_0][iPos] = pPic;
530− return ERR_INFO_DUPLICATE_FRAME_NUM;
531− }
532− }
533−
534− memmove (&pRefPic->pShortRefList[LIST_0][1], &pRefPic->pShortRefList[LIST_0][0],
535− pRefPic->uiShortRefCount[LIST_0]*sizeof (PPicture));//confirmed_safe_unsafe_usage
536− }
537− pRefPic->pShortRefList[LIST_0][0] = pPic;
538− pRefPic->uiShortRefCount[LIST_0]++;
539− return ERR_NONE;
540−}
541−
542−static int32_t AddLongTermToList (PRefPic pRefPic, PPicture pPic, int32_t iLongTermFrameIdx) {
543− int32_t i = 0;
544−
545− pPic->bUsedAsRef = true;
546− pPic->bIsLongRef = true;
547− pPic->iLongTermFrameIdx = iLongTermFrameIdx;
548− if (pRefPic->uiLongRefCount[LIST_0] == 0) {
549− pRefPic->pLongRefList[LIST_0][pRefPic->uiLongRefCount[LIST_0]] = pPic;
550− } else {
551− for (i = 0; i < pRefPic->uiLongRefCount[LIST_0]; i++) {
552− if (pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx > pPic->iLongTermFrameIdx) {
553− break;
554− }
555− }
556− memmove (&pRefPic->pLongRefList[LIST_0][i + 1], &pRefPic->pLongRefList[LIST_0][i],
557− (pRefPic->uiLongRefCount[LIST_0] - i)*sizeof (PPicture)); //confirmed_safe_unsafe_usage
558− pRefPic->pLongRefList[LIST_0][i] = pPic;
559− }
560−
561− pRefPic->uiLongRefCount[LIST_0]++;
562− return ERR_NONE;
563−}
564−
565−static int32_t MarkAsLongTerm (PRefPic pRefPic, int32_t iFrameNum, int32_t iLongTermFrameIdx) {
566− PPicture pPic = NULL;
567− int32_t i = 0;
568− int32_t iRet = ERR_NONE;
569− WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx);
570−
571− for (i = 0; i < pRefPic->uiRefCount[LIST_0]; i++) {
572− pPic = pRefPic->pRefList[LIST_0][i];
573− if (pPic->iFrameNum == iFrameNum && !pPic->bIsLongRef) {
574− iRet = AddLongTermToList (pRefPic, pPic, iLongTermFrameIdx);
575− break;
576− }
577− }
578−
579− return iRet;
580−}
581−
582−#ifdef LONG_TERM_REF
583−int32_t GetLTRFrameIndex (PRefPic pRefPic, int32_t iAncLTRFrameNum) {
584− int32_t iLTRFrameIndex = -1;
585− PPicture pPic;
586− for (int i = 0; i < pRefPic->uiLongRefCount[0]; ++i) {
587− pPic = pRefPic->pLongRefList[LIST_0][i];
588− if (pPic->iFrameNum == iAncLTRFrameNum) {
589− return (pPic->iLongTermFrameIdx);
590− }
591− }
592− return iLTRFrameIndex;
593−}
594−#endif
595−
596−static int32_t RemainOneBufferInDpbForEC (PWelsDecoderContext pCtx) {
597− int32_t iRet = ERR_NONE;
598− PRefPic pRefPic = &pCtx->sRefPic;
599− if (pRefPic->uiShortRefCount[0] + pRefPic->uiLongRefCount[0] < pCtx->pSps->iNumRefFrames)
600− return iRet;
601−
602− if (pRefPic->uiShortRefCount[0] > 0) {
603− iRet = SlidingWindow (pCtx);
604− } else { //all LTR, remove the smallest long_term_frame_idx
605− int32_t iLongTermFrameIdx = 0;
606− int32_t iMaxLongTermFrameIdx = pRefPic->iMaxLongTermFrameIdx;
607−#ifdef LONG_TERM_REF
608− int32_t iCurrLTRFrameIdx = GetLTRFrameIndex (pRefPic, pCtx->iFrameNumOfAuMarkedLtr);
609−#endif
610− while ((pRefPic->uiLongRefCount[0] >= pCtx->pSps->iNumRefFrames) && (iLongTermFrameIdx <= iMaxLongTermFrameIdx)) {
611−#ifdef LONG_TERM_REF
612− if (iLongTermFrameIdx == iCurrLTRFrameIdx) {
613− iLongTermFrameIdx++;
614− continue;
615− }
616−#endif
617− WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx);
618− iLongTermFrameIdx++;
619− }
620− }
621− if (pRefPic->uiShortRefCount[0] + pRefPic->uiLongRefCount[0] >=
622− pCtx->pSps->iNumRefFrames) { //fail to remain one empty buffer in DPB
623− WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "RemainOneBufferInDpbForEC(): empty one DPB failed for EC!");
624− iRet = ERR_INFO_REF_COUNT_OVERFLOW;
625− }
626−
627− return iRet;
628−}
629−
630−} // 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);
60+static int32_t MarkAsLongTerm (PRefPic pRefPic, int32_t iFrameNum, int32_t iLongTermFrameIdx);
61+static int32_t WelsCheckAndRecoverForFutureDecoding (PWelsDecoderContext pCtx);
62+#ifdef LONG_TERM_REF
63+int32_t GetLTRFrameIndex (PRefPic pRefPic, int32_t iAncLTRFrameNum);
64+#endif
65+static int32_t RemainOneBufferInDpbForEC (PWelsDecoderContext pCtx);
66+
67+static void SetUnRef (PPicture pRef) {
68+ if (NULL != pRef) {
69+ pRef->bUsedAsRef = false;
70+ pRef->bIsLongRef = false;
71+ pRef->iFrameNum = -1;
72+ //pRef->iFramePoc = 0;
73+ pRef->iLongTermFrameIdx = -1;
74+ pRef->uiQualityId = -1;
75+ pRef->uiTemporalId = -1;
76+ pRef->uiSpatialId = -1;
77+ pRef->iSpsId = -1;
78+ pRef->bIsComplete = false;
79+ }
80+}
81+
82+//reset pRefList when
83+// 1.sps arrived that is new sequence starting
84+// 2.IDR NAL i.e. 1st layer in IDR AU
85+
86+void WelsResetRefPic (PWelsDecoderContext pCtx) {
87+ int32_t i = 0;
88+ PRefPic pRefPic = &pCtx->sRefPic;
89+ pCtx->sRefPic.uiLongRefCount[LIST_0] = pCtx->sRefPic.uiShortRefCount[LIST_0] = 0;
90+
91+ pRefPic->uiRefCount[LIST_0] = 0;
92+ pRefPic->uiRefCount[LIST_1] = 0;
93+
94+ for (i = 0; i < MAX_DPB_COUNT; i++) {
95+ if (pRefPic->pShortRefList[LIST_0][i] != NULL) {
96+ SetUnRef (pRefPic->pShortRefList[LIST_0][i]);
97+ pRefPic->pShortRefList[LIST_0][i] = NULL;
98+ }
99+ }
100+ pRefPic->uiShortRefCount[LIST_0] = 0;
101+
102+ for (i = 0; i < MAX_DPB_COUNT; i++) {
103+ if (pRefPic->pLongRefList[LIST_0][i] != NULL) {
104+ SetUnRef (pRefPic->pLongRefList[LIST_0][i]);
105+ pRefPic->pLongRefList[LIST_0][i] = NULL;
106+ }
107+ }
108+ pRefPic->uiLongRefCount[LIST_0] = 0;
109+}
110+
111+static int32_t WelsCheckAndRecoverForFutureDecoding (PWelsDecoderContext pCtx) {
112+ if ((pCtx->sRefPic.uiShortRefCount[LIST_0] + pCtx->sRefPic.uiLongRefCount[LIST_0] <= 0) && (pCtx->eSliceType != I_SLICE
113+ && pCtx->eSliceType != SI_SLICE)) {
114+ if (pCtx->pParam->eEcActiveIdc !=
115+ ERROR_CON_DISABLE) { //IDR lost!, recover it for future decoding with data all set to 0
116+ PPicture pRef = PrefetchPic (pCtx->pPicBuff);
117+ if (pRef != NULL) {
118+ // IDR lost, set new
119+ pRef->bIsComplete = false; // Set complete flag to false for lost IDR ref picture
120+ pRef->iSpsId = pCtx->pSps->iSpsId;
121+ pRef->iPpsId = pCtx->pPps->iPpsId;
122+ pCtx->iErrorCode |= dsDataErrorConcealed;
123+ bool bCopyPrevious = ((ERROR_CON_FRAME_COPY_CROSS_IDR == pCtx->pParam->eEcActiveIdc)
124+ || (ERROR_CON_SLICE_COPY_CROSS_IDR == pCtx->pParam->eEcActiveIdc)
125+ || (ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE == pCtx->pParam->eEcActiveIdc)
126+ || (ERROR_CON_SLICE_MV_COPY_CROSS_IDR == pCtx->pParam->eEcActiveIdc)
127+ || (ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE == pCtx->pParam->eEcActiveIdc))
128+ && (NULL != pCtx->pPreviousDecodedPictureInDpb);
129+ bCopyPrevious = bCopyPrevious && (pRef->iWidthInPixel == pCtx->pPreviousDecodedPictureInDpb->iWidthInPixel)
130+ && (pRef->iHeightInPixel == pCtx->pPreviousDecodedPictureInDpb->iHeightInPixel);
131+
132+ if (!bCopyPrevious) {
133+ memset (pRef->pData[0], 128, pRef->iLinesize[0] * pRef->iHeightInPixel);
134+ memset (pRef->pData[1], 128, pRef->iLinesize[1] * pRef->iHeightInPixel / 2);
135+ memset (pRef->pData[2], 128, pRef->iLinesize[2] * pRef->iHeightInPixel / 2);
136+ } else if (pRef == pCtx->pPreviousDecodedPictureInDpb) {
137+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "WelsInitRefList()::EC memcpy overlap.");
138+ } else {
139+ memcpy (pRef->pData[0], pCtx->pPreviousDecodedPictureInDpb->pData[0], pRef->iLinesize[0] * pRef->iHeightInPixel);
140+ memcpy (pRef->pData[1], pCtx->pPreviousDecodedPictureInDpb->pData[1], pRef->iLinesize[1] * pRef->iHeightInPixel / 2);
141+ memcpy (pRef->pData[2], pCtx->pPreviousDecodedPictureInDpb->pData[2], pRef->iLinesize[2] * pRef->iHeightInPixel / 2);
142+ }
143+ pRef->iFrameNum = 0;
144+ pRef->iFramePoc = 0;
145+ pRef->uiTemporalId = pRef->uiQualityId = 0;
146+ ExpandReferencingPicture (pRef->pData, pRef->iWidthInPixel, pRef->iHeightInPixel, pRef->iLinesize,
147+ pCtx->sExpandPicFunc.pfExpandLumaPicture, pCtx->sExpandPicFunc.pfExpandChromaPicture);
148+ AddShortTermToList (&pCtx->sRefPic, pRef);
149+ } else {
150+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "WelsInitRefList()::PrefetchPic for EC errors.");
151+ pCtx->iErrorCode |= dsOutOfMemory;
152+ return ERR_INFO_REF_COUNT_OVERFLOW;
153+ }
154+ }
155+ }
156+ return ERR_NONE;
157+}
158+
159+/**
160+* fills the pRefPic.pRefList LIST_0 and LIST_0 for B-Slice.
161+*/
162+int32_t WelsInitBSliceRefList (PWelsDecoderContext pCtx, int32_t iPoc) {
163+
164+ int32_t err = WelsCheckAndRecoverForFutureDecoding (pCtx);
165+ if (err != ERR_NONE) return err;
166+
167+ PPicture* ppShoreRefList = pCtx->sRefPic.pShortRefList[LIST_0];
168+ PPicture* ppLongRefList = pCtx->sRefPic.pLongRefList[LIST_0];
169+ memset (pCtx->sRefPic.pRefList[LIST_0], 0, MAX_DPB_COUNT * sizeof (PPicture));
170+ memset (pCtx->sRefPic.pRefList[LIST_1], 0, MAX_DPB_COUNT * sizeof (PPicture));
171+ int32_t iLSCurrPocCount = 0;
172+ int32_t iLTCurrPocCount = 0;
173+ PPicture pLSCurrPocList0[MAX_DPB_COUNT];
174+ PPicture pLTCurrPocList0[MAX_DPB_COUNT];
175+ for (int32_t i = 0; i < pCtx->sRefPic.uiShortRefCount[LIST_0]; ++i) {
176+ if (ppShoreRefList[i]->iFramePoc < iPoc) {
177+ pLSCurrPocList0[iLSCurrPocCount++] = ppShoreRefList[i];
178+ }
179+ }
180+ for (int32_t i = pCtx->sRefPic.uiShortRefCount[LIST_0] - 1; i >= 0; --i) {
181+ if (ppShoreRefList[i]->iFramePoc > iPoc) {
182+ pLTCurrPocList0[iLTCurrPocCount++] = ppShoreRefList[i];
183+ }
184+ }
185+ if (pCtx->sRefPic.uiLongRefCount[LIST_0] > 1) {
186+ //long sorts in increasing order
187+ PPicture pTemp;
188+ for (int32_t i = 0; i < pCtx->sRefPic.uiLongRefCount[LIST_0]; ++i) {
189+ for (int32_t j = i + 1; j < pCtx->sRefPic.uiLongRefCount[LIST_0]; ++j) {
190+ if (ppLongRefList[j]->iFramePoc < ppLongRefList[i]->iFramePoc) {
191+ pTemp = ppLongRefList[i];
192+ ppLongRefList[i] = ppLongRefList[j];
193+ ppLongRefList[j] = pTemp;
194+ }
195+ }
196+ }
197+ }
198+ int32_t iCurrPocCount = iLSCurrPocCount + iLTCurrPocCount;
199+ int32_t iCount = 0;
200+ //LIST_0
201+ //short
202+ //It may need to sort LIST_0 and LIST_1 so that they will have the right default orders.
203+ for (int32_t i = 0; i < iLSCurrPocCount; ++i) {
204+ pCtx->sRefPic.pRefList[LIST_0][iCount++] = pLSCurrPocList0[i];
205+ }
206+ if (iLSCurrPocCount > 1) {
207+ //LIST_0 short sorts in decreasing order
208+ PPicture pTemp;
209+ for (int32_t i = 0; i < iLSCurrPocCount; ++i) {
210+ for (int32_t j = i + 1; j < iLSCurrPocCount; ++j) {
211+ if (pCtx->sRefPic.pRefList[LIST_0][j]->iFramePoc > pCtx->sRefPic.pRefList[LIST_0][i]->iFramePoc) {
212+ pTemp = pCtx->sRefPic.pRefList[LIST_0][i];
213+ pCtx->sRefPic.pRefList[LIST_0][i] = pCtx->sRefPic.pRefList[LIST_0][j];
214+ pCtx->sRefPic.pRefList[LIST_0][j] = pTemp;
215+ }
216+ }
217+ }
218+ }
219+ for (int32_t i = 0; i < iLTCurrPocCount; ++i) {
220+ pCtx->sRefPic.pRefList[LIST_0][iCount++] = pLTCurrPocList0[i];
221+ }
222+ if (iLTCurrPocCount > 1) {
223+ //LIST_0 short sorts in increasing order
224+ PPicture pTemp;
225+ for (int32_t i = iLSCurrPocCount; i < iCurrPocCount; ++i) {
226+ for (int32_t j = i + 1; j < iCurrPocCount; ++j) {
227+ if (pCtx->sRefPic.pRefList[LIST_0][j]->iFramePoc < pCtx->sRefPic.pRefList[LIST_0][i]->iFramePoc) {
228+ pTemp = pCtx->sRefPic.pRefList[LIST_0][i];
229+ pCtx->sRefPic.pRefList[LIST_0][i] = pCtx->sRefPic.pRefList[LIST_0][j];
230+ pCtx->sRefPic.pRefList[LIST_0][j] = pTemp;
231+ }
232+ }
233+ }
234+ }
235+ //long
236+ for (int32_t i = 0; i < pCtx->sRefPic.uiLongRefCount[LIST_0]; ++i) {
237+ pCtx->sRefPic.pRefList[LIST_0][iCount++] = ppLongRefList[i];
238+ }
239+ pCtx->sRefPic.uiRefCount[LIST_0] = iCount;
240+
241+ iCount = 0;
242+ //LIST_1
243+ //short
244+ for (int32_t i = 0; i < iLTCurrPocCount; ++i) {
245+ pCtx->sRefPic.pRefList[LIST_1][iCount++] = pLTCurrPocList0[i];
246+ }
247+ if (iLTCurrPocCount > 1) {
248+ //LIST_1 short sorts in increasing order
249+ PPicture pTemp;
250+ for (int32_t i = 0; i < iLTCurrPocCount; ++i) {
251+ for (int32_t j = i + 1; j < iLTCurrPocCount; ++j) {
252+ if (pCtx->sRefPic.pRefList[LIST_1][j]->iFramePoc < pCtx->sRefPic.pRefList[LIST_1][i]->iFramePoc) {
253+ pTemp = pCtx->sRefPic.pRefList[LIST_1][i];
254+ pCtx->sRefPic.pRefList[LIST_1][i] = pCtx->sRefPic.pRefList[LIST_1][j];
255+ pCtx->sRefPic.pRefList[LIST_1][j] = pTemp;
256+ }
257+ }
258+ }
259+ }
260+ for (int32_t i = 0; i < iLSCurrPocCount; ++i) {
261+ pCtx->sRefPic.pRefList[LIST_1][iCount++] = pLSCurrPocList0[i];
262+ }
263+ if (iLSCurrPocCount > 1) {
264+ //LIST_1 short sorts in decreasing order
265+ PPicture pTemp;
266+ for (int32_t i = iLTCurrPocCount; i < iCurrPocCount; ++i) {
267+ for (int32_t j = i + 1; j < iCurrPocCount; ++j) {
268+ if (pCtx->sRefPic.pRefList[LIST_1][j]->iFramePoc > pCtx->sRefPic.pRefList[LIST_1][i]->iFramePoc) {
269+ pTemp = pCtx->sRefPic.pRefList[LIST_1][i];
270+ pCtx->sRefPic.pRefList[LIST_1][i] = pCtx->sRefPic.pRefList[LIST_1][j];
271+ pCtx->sRefPic.pRefList[LIST_1][j] = pTemp;
272+ }
273+ }
274+ }
275+ }
276+ //long
277+ for (int32_t i = 0; i < pCtx->sRefPic.uiLongRefCount[LIST_0]; ++i) {
278+ pCtx->sRefPic.pRefList[LIST_1][iCount++] = ppLongRefList[i];
279+ }
280+ pCtx->sRefPic.uiRefCount[LIST_1] = iCount;
281+ return ERR_NONE;
282+}
283+
284+/**
285+ * fills the pRefPic.pRefList.
286+ */
287+int32_t WelsInitRefList (PWelsDecoderContext pCtx, int32_t iPoc) {
288+
289+ int32_t err = WelsCheckAndRecoverForFutureDecoding (pCtx);
290+ if (err != ERR_NONE) return err;
291+
292+ PPicture* ppShoreRefList = pCtx->sRefPic.pShortRefList[LIST_0];
293+ PPicture* ppLongRefList = pCtx->sRefPic.pLongRefList[LIST_0];
294+ memset (pCtx->sRefPic.pRefList[LIST_0], 0, MAX_DPB_COUNT * sizeof (PPicture));
295+
296+ int32_t i, iCount = 0;
297+ //short
298+ for (i = 0; i < pCtx->sRefPic.uiShortRefCount[LIST_0]; ++i) {
299+ pCtx->sRefPic.pRefList[LIST_0][iCount++ ] = ppShoreRefList[i];
300+ }
301+
302+ //long
303+ for (i = 0; i < pCtx->sRefPic.uiLongRefCount[LIST_0] ; ++i) {
304+ pCtx->sRefPic.pRefList[LIST_0][iCount++ ] = ppLongRefList[i];
305+ }
306+ pCtx->sRefPic.uiRefCount[LIST_0] = iCount;
307+
308+ return ERR_NONE;
309+}
310+
311+int32_t WelsReorderRefList (PWelsDecoderContext pCtx) {
312+
313+ if (pCtx->eSliceType == I_SLICE || pCtx->eSliceType == SI_SLICE) {
314+ return ERR_NONE;
315+ }
316+
317+ PRefPicListReorderSyn pRefPicListReorderSyn = pCtx->pCurDqLayer->pRefPicListReordering;
318+ PNalUnitHeaderExt pNalHeaderExt = &pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt;
319+ PSliceHeader pSliceHeader = &pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader;
320+ int32_t ListCount = 1;
321+ if (pCtx->eSliceType == B_SLICE) ListCount = 2;
322+// PPicture* ppShoreRefList = pCtx->sRefPic.pShortRefList[LIST_0];
323+// int32_t iShortRefCount = pCtx->sRefPic.uiShortRefCount[LIST_0];
324+// PPicture* ppLongRefList = pCtx->sRefPic.pLongRefList[LIST_0];
325+// int32_t iLongRefCount = pCtx->sRefPic.uiLongRefCount[LIST_0];
326+ for (int32_t listIdx = 0; listIdx < ListCount; ++listIdx) {
327+ PPicture pPic = NULL;
328+ PPicture* ppRefList = pCtx->sRefPic.pRefList[listIdx];
329+ int32_t iMaxRefIdx = pCtx->pSps->iNumRefFrames;
330+ int32_t iRefCount = pCtx->sRefPic.uiRefCount[listIdx];
331+ int32_t iPredFrameNum = pSliceHeader->iFrameNum;
332+ int32_t iMaxPicNum = 1 << pSliceHeader->pSps->uiLog2MaxFrameNum;
333+ int32_t iAbsDiffPicNum = -1;
334+ int32_t iReorderingIndex = 0;
335+ int32_t i = 0;
336+
337+ if (iRefCount <= 0) {
338+ pCtx->iErrorCode = dsNoParamSets; //No any reference for decoding, SHOULD request IDR
339+ return ERR_INFO_REFERENCE_PIC_LOST;
340+ }
341+
342+ if (pRefPicListReorderSyn->bRefPicListReorderingFlag[listIdx]) {
343+ while ((iReorderingIndex < iMaxRefIdx)
344+ && (pRefPicListReorderSyn->sReorderingSyn[listIdx][iReorderingIndex].uiReorderingOfPicNumsIdc != 3)) {
345+ uint16_t uiReorderingOfPicNumsIdc =
346+ pRefPicListReorderSyn->sReorderingSyn[listIdx][iReorderingIndex].uiReorderingOfPicNumsIdc;
347+ if (uiReorderingOfPicNumsIdc < 2) {
348+ iAbsDiffPicNum = pRefPicListReorderSyn->sReorderingSyn[listIdx][iReorderingIndex].uiAbsDiffPicNumMinus1 + 1;
349+
350+ if (uiReorderingOfPicNumsIdc == 0) {
351+ iPredFrameNum -= iAbsDiffPicNum;
352+ } else {
353+ iPredFrameNum += iAbsDiffPicNum;
354+ }
355+ iPredFrameNum &= iMaxPicNum - 1;
356+
357+ for (i = iMaxRefIdx - 1; i >= 0; i--) {
358+ if (ppRefList[i] != NULL && ppRefList[i]->iFrameNum == iPredFrameNum && !ppRefList[i]->bIsLongRef) {
359+ if ((pNalHeaderExt->uiQualityId == ppRefList[i]->uiQualityId)
360+ && (pSliceHeader->iSpsId != ppRefList[i]->iSpsId)) { //check;
361+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "WelsReorderRefList()::::BASE LAYER::::iSpsId:%d, ref_sps_id:%d",
362+ pSliceHeader->iSpsId, ppRefList[i]->iSpsId);
363+ pCtx->iErrorCode = dsNoParamSets; //cross-IDR reference frame selection, SHOULD request IDR.--
364+ return ERR_INFO_REFERENCE_PIC_LOST;
365+ } else {
366+ break;
367+ }
368+ }
369+ }
370+
371+ } else if (uiReorderingOfPicNumsIdc == 2) {
372+ for (i = iMaxRefIdx - 1; i >= 0; i--) {
373+ if (ppRefList[i] != NULL && ppRefList[i]->bIsLongRef
374+ && ppRefList[i]->iLongTermFrameIdx ==
375+ pRefPicListReorderSyn->sReorderingSyn[listIdx][iReorderingIndex].uiLongTermPicNum) {
376+ if ((pNalHeaderExt->uiQualityId == ppRefList[i]->uiQualityId)
377+ && (pSliceHeader->iSpsId != ppRefList[i]->iSpsId)) { //check;
378+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "WelsReorderRefList()::::BASE LAYER::::iSpsId:%d, ref_sps_id:%d",
379+ pSliceHeader->iSpsId, ppRefList[i]->iSpsId);
380+ pCtx->iErrorCode = dsNoParamSets; //cross-IDR reference frame selection, SHOULD request IDR.--
381+ return ERR_INFO_REFERENCE_PIC_LOST;
382+ } else {
383+ break;
384+ }
385+ }
386+ }
387+ }
388+ if (i < 0) {
389+ return ERR_INFO_REFERENCE_PIC_LOST;
390+ }
391+ pPic = ppRefList[i];
392+ if (i > iReorderingIndex) {
393+ memmove (&ppRefList[1 + iReorderingIndex], &ppRefList[iReorderingIndex],
394+ (i - iReorderingIndex) * sizeof (PPicture)); //confirmed_safe_unsafe_usage
395+ } else if (i < iReorderingIndex) {
396+ memmove (&ppRefList[1 + iReorderingIndex], &ppRefList[iReorderingIndex],
397+ (iMaxRefIdx - iReorderingIndex) * sizeof (PPicture));
398+ }
399+ ppRefList[iReorderingIndex] = pPic;
400+ iReorderingIndex++;
401+ }
402+ }
403+ }
404+ return ERR_NONE;
405+}
406+
407+int32_t WelsMarkAsRef (PWelsDecoderContext pCtx) {
408+ PRefPic pRefPic = &pCtx->sRefPic;
409+ PRefPicMarking pRefPicMarking = pCtx->pCurDqLayer->pRefPicMarking;
410+ PAccessUnit pCurAU = pCtx->pAccessUnitList;
411+ bool bIsIDRAU = false;
412+ uint32_t j;
413+
414+ int32_t iRet = ERR_NONE;
415+
416+ pCtx->pDec->uiQualityId = pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.uiQualityId;
417+ pCtx->pDec->uiTemporalId = pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.uiTemporalId;
418+ pCtx->pDec->iSpsId = pCtx->pSps->iSpsId;
419+ pCtx->pDec->iPpsId = pCtx->pPps->iPpsId;
420+
421+ for (j = pCurAU->uiStartPos; j <= pCurAU->uiEndPos; j++) {
422+ if (pCurAU->pNalUnitsList[j]->sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR
423+ || pCurAU->pNalUnitsList[j]->sNalHeaderExt.bIdrFlag) {
424+ bIsIDRAU = true;
425+ break;
426+ }
427+ }
428+ if (bIsIDRAU) {
429+ if (pRefPicMarking->bLongTermRefFlag) {
430+ pCtx->sRefPic.iMaxLongTermFrameIdx = 0;
431+ AddLongTermToList (pRefPic, pCtx->pDec, 0);
432+ } else {
433+ pCtx->sRefPic.iMaxLongTermFrameIdx = -1;
434+ }
435+ } else {
436+ if (pRefPicMarking->bAdaptiveRefPicMarkingModeFlag) {
437+ iRet = MMCO (pCtx, pRefPicMarking);
438+ if (iRet != ERR_NONE) {
439+ if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
440+ iRet = RemainOneBufferInDpbForEC (pCtx);
441+ WELS_VERIFY_RETURN_IF (iRet, iRet);
442+ } else {
443+ return iRet;
444+ }
445+ }
446+
447+ if (pCtx->bLastHasMmco5) {
448+ pCtx->pDec->iFrameNum = 0;
449+ pCtx->pDec->iFramePoc = 0;
450+ }
451+
452+ } else {
453+ iRet = SlidingWindow (pCtx);
454+ if (iRet != ERR_NONE) {
455+ if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
456+ iRet = RemainOneBufferInDpbForEC (pCtx);
457+ WELS_VERIFY_RETURN_IF (iRet, iRet);
458+ } else {
459+ return iRet;
460+ }
461+ }
462+ }
463+ }
464+
465+ if (!pCtx->pDec->bIsLongRef) {
466+ if (pRefPic->uiLongRefCount[LIST_0] + pRefPic->uiShortRefCount[LIST_0] >= WELS_MAX (1, pCtx->pSps->iNumRefFrames)) {
467+ if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
468+ iRet = RemainOneBufferInDpbForEC (pCtx);
469+ WELS_VERIFY_RETURN_IF (iRet, iRet);
470+ } else {
471+ return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW;
472+ }
473+ }
474+ iRet = AddShortTermToList (pRefPic, pCtx->pDec);
475+ }
476+
477+ return iRet;
478+}
479+
480+static int32_t MMCO (PWelsDecoderContext pCtx, PRefPicMarking pRefPicMarking) {
481+ PSps pSps = pCtx->pCurDqLayer->sLayerInfo.pSps;
482+ int32_t i = 0;
483+ int32_t iRet = ERR_NONE;
484+ for (i = 0; i < MAX_MMCO_COUNT && pRefPicMarking->sMmcoRef[i].uiMmcoType != MMCO_END; i++) {
485+ uint32_t uiMmcoType = pRefPicMarking->sMmcoRef[i].uiMmcoType;
486+ int32_t iShortFrameNum = (pCtx->iFrameNum - pRefPicMarking->sMmcoRef[i].iDiffOfPicNum) & ((
487+ 1 << pSps->uiLog2MaxFrameNum) - 1);
488+ uint32_t uiLongTermPicNum = pRefPicMarking->sMmcoRef[i].uiLongTermPicNum;
489+ int32_t iLongTermFrameIdx = pRefPicMarking->sMmcoRef[i].iLongTermFrameIdx;
490+ int32_t iMaxLongTermFrameIdx = pRefPicMarking->sMmcoRef[i].iMaxLongTermFrameIdx;
491+ if (uiMmcoType > MMCO_LONG) {
492+ return ERR_INFO_INVALID_MMCO_OPCODE_BASE;
493+ }
494+ iRet = MMCOProcess (pCtx, uiMmcoType, iShortFrameNum, uiLongTermPicNum, iLongTermFrameIdx, iMaxLongTermFrameIdx);
495+ if (iRet != ERR_NONE) {
496+ return iRet;
497+ }
498+ }
499+ if (i == MAX_MMCO_COUNT) { //although Rec does not handle this condition, we here prohibit too many MMCO op
500+ return ERR_INFO_INVALID_MMCO_NUM;
501+ }
502+
503+ return ERR_NONE;
504+}
505+static int32_t MMCOProcess (PWelsDecoderContext pCtx, uint32_t uiMmcoType,
506+ int32_t iShortFrameNum, uint32_t uiLongTermPicNum, int32_t iLongTermFrameIdx, int32_t iMaxLongTermFrameIdx) {
507+ PRefPic pRefPic = &pCtx->sRefPic;
508+ PPicture pPic = NULL;
509+ int32_t i = 0;
510+ int32_t iRet = ERR_NONE;
511+
512+ switch (uiMmcoType) {
513+ case MMCO_SHORT2UNUSED:
514+ pPic = WelsDelShortFromListSetUnref (pRefPic, iShortFrameNum);
515+ if (pPic == NULL) {
516+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "MMCO_SHORT2UNUSED: delete an empty entry from short term list");
517+ }
518+ break;
519+ case MMCO_LONG2UNUSED:
520+ pPic = WelsDelLongFromListSetUnref (pRefPic, uiLongTermPicNum);
521+ if (pPic == NULL) {
522+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "MMCO_LONG2UNUSED: delete an empty entry from long term list");
523+ }
524+ break;
525+ case MMCO_SHORT2LONG:
526+ if (iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx) {
527+ return ERR_INFO_INVALID_MMCO_LONG_TERM_IDX_EXCEED_MAX;
528+ }
529+ pPic = WelsDelShortFromList (pRefPic, iShortFrameNum);
530+ if (pPic == NULL) {
531+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "MMCO_LONG2LONG: delete an empty entry from short term list");
532+ break;
533+ }
534+ WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx);
535+#ifdef LONG_TERM_REF
536+ pCtx->bCurAuContainLtrMarkSeFlag = true;
537+ pCtx->iFrameNumOfAuMarkedLtr = iShortFrameNum;
538+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "ex_mark_avc():::MMCO_SHORT2LONG:::LTR marking....iFrameNum: %d",
539+ pCtx->iFrameNumOfAuMarkedLtr);
540+#endif
541+
542+ MarkAsLongTerm (pRefPic, iShortFrameNum, iLongTermFrameIdx);
543+ break;
544+ case MMCO_SET_MAX_LONG:
545+ pRefPic->iMaxLongTermFrameIdx = iMaxLongTermFrameIdx;
546+ for (i = 0 ; i < pRefPic->uiLongRefCount[LIST_0]; i++) {
547+ if (pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx) {
548+ WelsDelLongFromListSetUnref (pRefPic, pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx);
549+ }
550+ }
551+ break;
552+ case MMCO_RESET:
553+ WelsResetRefPic (pCtx);
554+ pCtx->bLastHasMmco5 = true;
555+ break;
556+ case MMCO_LONG:
557+ if (iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx) {
558+ return ERR_INFO_INVALID_MMCO_LONG_TERM_IDX_EXCEED_MAX;
559+ }
560+ WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx);
561+ if (pRefPic->uiLongRefCount[LIST_0] + pRefPic->uiShortRefCount[LIST_0] >= WELS_MAX (1, pCtx->pSps->iNumRefFrames)) {
562+ return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW;
563+ }
564+#ifdef LONG_TERM_REF
565+ pCtx->bCurAuContainLtrMarkSeFlag = true;
566+ pCtx->iFrameNumOfAuMarkedLtr = pCtx->iFrameNum;
567+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "ex_mark_avc():::MMCO_LONG:::LTR marking....iFrameNum: %d",
568+ pCtx->iFrameNum);
569+#endif
570+ iRet = AddLongTermToList (pRefPic, pCtx->pDec, iLongTermFrameIdx);
571+ break;
572+ default :
573+ break;
574+ }
575+
576+ return iRet;
577+}
578+
579+static int32_t SlidingWindow (PWelsDecoderContext pCtx) {
580+ PRefPic pRefPic = &pCtx->sRefPic;
581+ PPicture pPic = NULL;
582+ int32_t i = 0;
583+
584+ if (pCtx->sRefPic.uiShortRefCount[LIST_0] + pCtx->sRefPic.uiLongRefCount[LIST_0] >= pCtx->pSps->iNumRefFrames) {
585+ if (pCtx->sRefPic.uiShortRefCount[LIST_0] == 0) {
586+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "No reference picture in short term list when sliding window");
587+ return ERR_INFO_INVALID_MMCO_REF_NUM_NOT_ENOUGH;
588+ }
589+ for (i = pRefPic->uiShortRefCount[LIST_0] - 1; i >= 0; i--) {
590+ pPic = WelsDelShortFromList (pRefPic, pRefPic->pShortRefList[LIST_0][i]->iFrameNum);
591+ if (pPic) {
592+ SetUnRef (pPic);
593+ break;
594+ } else {
595+ return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW;
596+ }
597+ }
598+ }
599+ return ERR_NONE;
600+}
601+
602+static PPicture WelsDelShortFromList (PRefPic pRefPic, int32_t iFrameNum) {
603+ int32_t i = 0;
604+ int32_t iMoveSize = 0;
605+ PPicture pPic = NULL;
606+
607+ for (i = 0; i < pRefPic->uiShortRefCount[LIST_0]; i++) {
608+ if (pRefPic->pShortRefList[LIST_0][i]->iFrameNum == iFrameNum) {
609+ iMoveSize = pRefPic->uiShortRefCount[LIST_0] - i - 1;
610+ pRefPic->pShortRefList[LIST_0][i]->bUsedAsRef = false;
611+ pPic = pRefPic->pShortRefList[LIST_0][i];
612+ pRefPic->pShortRefList[LIST_0][i] = NULL;
613+ if (iMoveSize > 0) {
614+ memmove (&pRefPic->pShortRefList[LIST_0][i], &pRefPic->pShortRefList[LIST_0][i + 1],
615+ iMoveSize * sizeof (PPicture)); //confirmed_safe_unsafe_usage
616+ }
617+ pRefPic->uiShortRefCount[LIST_0]--;
618+ pRefPic->pShortRefList[LIST_0][pRefPic->uiShortRefCount[LIST_0]] = NULL;
619+ break;
620+ }
621+ }
622+
623+ return pPic;
624+}
625+
626+static PPicture WelsDelShortFromListSetUnref (PRefPic pRefPic, int32_t iFrameNum) {
627+ PPicture pPic = WelsDelShortFromList (pRefPic, iFrameNum);
628+ if (pPic) {
629+ SetUnRef (pPic);
630+ }
631+ return pPic;
632+}
633+
634+static PPicture WelsDelLongFromList (PRefPic pRefPic, uint32_t uiLongTermFrameIdx) {
635+ PPicture pPic = NULL;
636+ int32_t i = 0;
637+ for (i = 0; i < pRefPic->uiLongRefCount[LIST_0]; i++) {
638+ pPic = pRefPic->pLongRefList[LIST_0][i];
639+ if (pPic->iLongTermFrameIdx == (int32_t)uiLongTermFrameIdx) {
640+ int32_t iMoveSize = pRefPic->uiLongRefCount[LIST_0] - i - 1;
641+ pPic->bUsedAsRef = false;
642+ pPic->bIsLongRef = false;
643+ if (iMoveSize > 0) {
644+ memmove (&pRefPic->pLongRefList[LIST_0][i], &pRefPic->pLongRefList[LIST_0][i + 1],
645+ iMoveSize * sizeof (PPicture)); //confirmed_safe_unsafe_usage
646+ }
647+ pRefPic->uiLongRefCount[LIST_0]--;
648+ pRefPic->pLongRefList[LIST_0][pRefPic->uiLongRefCount[LIST_0]] = NULL;
649+ return pPic;
650+ }
651+ }
652+ return NULL;
653+}
654+
655+static PPicture WelsDelLongFromListSetUnref (PRefPic pRefPic, uint32_t uiLongTermFrameIdx) {
656+ PPicture pPic = WelsDelLongFromList (pRefPic, uiLongTermFrameIdx);
657+ if (pPic) {
658+ SetUnRef (pPic);
659+ }
660+ return pPic;
661+}
662+
663+static int32_t AddShortTermToList (PRefPic pRefPic, PPicture pPic) {
664+ pPic->bUsedAsRef = true;
665+ pPic->bIsLongRef = false;
666+ pPic->iLongTermFrameIdx = -1;
667+ if (pRefPic->uiShortRefCount[LIST_0] > 0) {
668+ // Check the duplicate frame_num in short ref list
669+ for (int32_t iPos = 0; iPos < pRefPic->uiShortRefCount[LIST_0]; iPos++) {
670+ if (pPic->iFrameNum == pRefPic->pShortRefList[LIST_0][iPos]->iFrameNum) {
671+ // Replace the previous ref pic with the new one with the same frame_num
672+ pRefPic->pShortRefList[LIST_0][iPos] = pPic;
673+ return ERR_INFO_DUPLICATE_FRAME_NUM;
674+ }
675+ }
676+
677+ memmove (&pRefPic->pShortRefList[LIST_0][1], &pRefPic->pShortRefList[LIST_0][0],
678+ pRefPic->uiShortRefCount[LIST_0]*sizeof (PPicture));//confirmed_safe_unsafe_usage
679+ }
680+ pRefPic->pShortRefList[LIST_0][0] = pPic;
681+ pRefPic->uiShortRefCount[LIST_0]++;
682+ return ERR_NONE;
683+}
684+
685+static int32_t AddLongTermToList (PRefPic pRefPic, PPicture pPic, int32_t iLongTermFrameIdx) {
686+ int32_t i = 0;
687+
688+ pPic->bUsedAsRef = true;
689+ pPic->bIsLongRef = true;
690+ pPic->iLongTermFrameIdx = iLongTermFrameIdx;
691+ if (pRefPic->uiLongRefCount[LIST_0] == 0) {
692+ pRefPic->pLongRefList[LIST_0][pRefPic->uiLongRefCount[LIST_0]] = pPic;
693+ } else {
694+ for (i = 0; i < pRefPic->uiLongRefCount[LIST_0]; i++) {
695+ if (pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx > pPic->iLongTermFrameIdx) {
696+ break;
697+ }
698+ }
699+ memmove (&pRefPic->pLongRefList[LIST_0][i + 1], &pRefPic->pLongRefList[LIST_0][i],
700+ (pRefPic->uiLongRefCount[LIST_0] - i)*sizeof (PPicture)); //confirmed_safe_unsafe_usage
701+ pRefPic->pLongRefList[LIST_0][i] = pPic;
702+ }
703+
704+ pRefPic->uiLongRefCount[LIST_0]++;
705+ return ERR_NONE;
706+}
707+
708+static int32_t MarkAsLongTerm (PRefPic pRefPic, int32_t iFrameNum, int32_t iLongTermFrameIdx) {
709+ PPicture pPic = NULL;
710+ int32_t i = 0;
711+ int32_t iRet = ERR_NONE;
712+ WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx);
713+
714+ for (i = 0; i < pRefPic->uiRefCount[LIST_0]; i++) {
715+ pPic = pRefPic->pRefList[LIST_0][i];
716+ if (pPic->iFrameNum == iFrameNum && !pPic->bIsLongRef) {
717+ iRet = AddLongTermToList (pRefPic, pPic, iLongTermFrameIdx);
718+ break;
719+ }
720+ }
721+
722+ return iRet;
723+}
724+
725+#ifdef LONG_TERM_REF
726+int32_t GetLTRFrameIndex (PRefPic pRefPic, int32_t iAncLTRFrameNum) {
727+ int32_t iLTRFrameIndex = -1;
728+ PPicture pPic;
729+ for (int i = 0; i < pRefPic->uiLongRefCount[0]; ++i) {
730+ pPic = pRefPic->pLongRefList[LIST_0][i];
731+ if (pPic->iFrameNum == iAncLTRFrameNum) {
732+ return (pPic->iLongTermFrameIdx);
733+ }
734+ }
735+ return iLTRFrameIndex;
736+}
737+#endif
738+
739+static int32_t RemainOneBufferInDpbForEC (PWelsDecoderContext pCtx) {
740+ int32_t iRet = ERR_NONE;
741+ PRefPic pRefPic = &pCtx->sRefPic;
742+ if (pRefPic->uiShortRefCount[0] + pRefPic->uiLongRefCount[0] < pCtx->pSps->iNumRefFrames)
743+ return iRet;
744+
745+ if (pRefPic->uiShortRefCount[0] > 0) {
746+ iRet = SlidingWindow (pCtx);
747+ } else { //all LTR, remove the smallest long_term_frame_idx
748+ int32_t iLongTermFrameIdx = 0;
749+ int32_t iMaxLongTermFrameIdx = pRefPic->iMaxLongTermFrameIdx;
750+#ifdef LONG_TERM_REF
751+ int32_t iCurrLTRFrameIdx = GetLTRFrameIndex (pRefPic, pCtx->iFrameNumOfAuMarkedLtr);
752+#endif
753+ while ((pRefPic->uiLongRefCount[0] >= pCtx->pSps->iNumRefFrames) && (iLongTermFrameIdx <= iMaxLongTermFrameIdx)) {
754+#ifdef LONG_TERM_REF
755+ if (iLongTermFrameIdx == iCurrLTRFrameIdx) {
756+ iLongTermFrameIdx++;
757+ continue;
758+ }
759+#endif
760+ WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx);
761+ iLongTermFrameIdx++;
762+ }
763+ }
764+ if (pRefPic->uiShortRefCount[0] + pRefPic->uiLongRefCount[0] >=
765+ pCtx->pSps->iNumRefFrames) { //fail to remain one empty buffer in DPB
766+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "RemainOneBufferInDpbForEC(): empty one DPB failed for EC!");
767+ iRet = ERR_INFO_REF_COUNT_OVERFLOW;
768+ }
769+
770+ return iRet;
771+}
772+
773+} // 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