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/*!1/*!
2 * \copy2 * \copy
3 * Copyright (c) 2008-2013, Cisco Systems3 * Copyright (c) 2008-2013, Cisco Systems
4 * All rights reserved.4 * All rights reserved.
5 *5 *
6 * Redistribution and use in source and binary forms, with or without6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions7 * modification, are permitted provided that the following conditions
8 * are met:8 * are met:
9 *9 *
10 * * Redistributions of source code must retain the above copyright10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.11 * notice, this list of conditions and the following disclaimer.
12 *12 *
13 * * Redistributions in binary form must reproduce the above copyright13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the15 * the documentation and/or other materials provided with the
16 * distribution.16 * distribution.
17 *17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,22 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.29 * POSSIBILITY OF SUCH DAMAGE.
30 *30 *
31 *31 *
32 * manage_dec_ref.cpp32 * manage_dec_ref.cpp
33 *33 *
34 * Abstract34 * Abstract
35 * Implementation for managing reference picture35 * Implementation for managing reference picture
36 *36 *
37 * History37 * History
38 * 07/21/2008 Created38 * 07/21/2008 Created
39 *39 *
40 *****************************************************************************/40 *****************************************************************************/
41 41
42#include "manage_dec_ref.h"42#include "manage_dec_ref.h"
43#include "error_concealment.h"43#include "error_concealment.h"
44#include "error_code.h"44#include "error_code.h"
45 45
46namespace WelsDec {46namespace WelsDec {
47 47
48static PPicture WelsDelShortFromList (PRefPic pRefPic, int32_t iFrameNum);48static PPicture WelsDelShortFromList (PRefPic pRefPic, int32_t iFrameNum);
49static PPicture WelsDelLongFromList (PRefPic pRefPic, uint32_t uiLongTermFrameIdx);49static PPicture WelsDelLongFromList (PRefPic pRefPic, uint32_t uiLongTermFrameIdx);
50static PPicture WelsDelShortFromListSetUnref (PRefPic pRefPic, int32_t iFrameNum);50static PPicture WelsDelShortFromListSetUnref (PRefPic pRefPic, int32_t iFrameNum);
51static PPicture WelsDelLongFromListSetUnref (PRefPic pRefPic, uint32_t uiLongTermFrameIdx);51static PPicture WelsDelLongFromListSetUnref (PRefPic pRefPic, uint32_t uiLongTermFrameIdx);
52 52
53static int32_t MMCO (PWelsDecoderContext pCtx, PRefPicMarking pRefPicMarking);53static int32_t MMCO (PWelsDecoderContext pCtx, PRefPicMarking pRefPicMarking);
54static int32_t MMCOProcess (PWelsDecoderContext pCtx, uint32_t uiMmcoType,54static int32_t MMCOProcess (PWelsDecoderContext pCtx, uint32_t uiMmcoType,
55 int32_t iShortFrameNum, uint32_t uiLongTermPicNum, int32_t iLongTermFrameIdx, int32_t iMaxLongTermFrameIdx);55 int32_t iShortFrameNum, uint32_t uiLongTermPicNum, int32_t iLongTermFrameIdx, int32_t iMaxLongTermFrameIdx);
56static int32_t SlidingWindow (PWelsDecoderContext pCtx);56static int32_t SlidingWindow (PWelsDecoderContext pCtx);
57 57
58static int32_t AddShortTermToList (PRefPic pRefPic, PPicture pPic);58static int32_t AddShortTermToList (PRefPic pRefPic, PPicture pPic);
59static int32_t AddLongTermToList (PRefPic pRefPic, PPicture pPic, int32_t iLongTermFrameIdx);59static int32_t AddLongTermToList (PRefPic pRefPic, PPicture pPic, int32_t iLongTermFrameIdx);
60static int32_t MarkAsLongTerm (PRefPic pRefPic, int32_t iFrameNum, int32_t iLongTermFrameIdx);60static int32_t MarkAsLongTerm (PRefPic pRefPic, int32_t iFrameNum, int32_t iLongTermFrameIdx);
61#ifdef LONG_TERM_REF61static int32_t WelsCheckAndRecoverForFutureDecoding (PWelsDecoderContext pCtx);
62int32_t GetLTRFrameIndex (PRefPic pRefPic, int32_t iAncLTRFrameNum);62#ifdef LONG_TERM_REF
63#endif63int32_t GetLTRFrameIndex (PRefPic pRefPic, int32_t iAncLTRFrameNum);
64static int32_t RemainOneBufferInDpbForEC (PWelsDecoderContext pCtx);64#endif
65 65static int32_t RemainOneBufferInDpbForEC (PWelsDecoderContext pCtx);
66static void SetUnRef (PPicture pRef) {66
67 if (NULL != pRef) {67static void SetUnRef (PPicture pRef) {
68 pRef->bUsedAsRef = false;68 if (NULL != pRef) {
69 pRef->bIsLongRef = false;69 pRef->bUsedAsRef = false;
70 pRef->iFrameNum = -1;70 pRef->bIsLongRef = false;
71 //pRef->iFramePoc = 0;71 pRef->iFrameNum = -1;
72 pRef->iLongTermFrameIdx = -1;72 //pRef->iFramePoc = 0;
73 pRef->uiQualityId = -1;73 pRef->iLongTermFrameIdx = -1;
74 pRef->uiTemporalId = -1;74 pRef->uiQualityId = -1;
75 pRef->uiSpatialId = -1;75 pRef->uiTemporalId = -1;
76 pRef->iSpsId = -1;76 pRef->uiSpatialId = -1;
77 pRef->bIsComplete = false;77 pRef->iSpsId = -1;
78 }78 pRef->bIsComplete = false;
79}79 }
80 80}
81//reset pRefList when81
82// 1.sps arrived that is new sequence starting82//reset pRefList when
83// 2.IDR NAL i.e. 1st layer in IDR AU83// 1.sps arrived that is new sequence starting
84 84// 2.IDR NAL i.e. 1st layer in IDR AU
85void WelsResetRefPic (PWelsDecoderContext pCtx) {85
86 int32_t i = 0;86void WelsResetRefPic (PWelsDecoderContext pCtx) {
87 PRefPic pRefPic = &pCtx->sRefPic;87 int32_t i = 0;
88 pCtx->sRefPic.uiLongRefCount[LIST_0] = pCtx->sRefPic.uiShortRefCount[LIST_0] = 0;88 PRefPic pRefPic = &pCtx->sRefPic;
89 89 pCtx->sRefPic.uiLongRefCount[LIST_0] = pCtx->sRefPic.uiShortRefCount[LIST_0] = 0;
90 pRefPic->uiRefCount[LIST_0] = 0;90
91 91 pRefPic->uiRefCount[LIST_0] = 0;
92 for (i = 0; i < MAX_DPB_COUNT; i++) {92 pRefPic->uiRefCount[LIST_1] = 0;
93 if (pRefPic->pShortRefList[LIST_0][i] != NULL) {93
94 SetUnRef (pRefPic->pShortRefList[LIST_0][i]);94 for (i = 0; i < MAX_DPB_COUNT; i++) {
95 pRefPic->pShortRefList[LIST_0][i] = NULL;95 if (pRefPic->pShortRefList[LIST_0][i] != NULL) {
96 }96 SetUnRef (pRefPic->pShortRefList[LIST_0][i]);
97 }97 pRefPic->pShortRefList[LIST_0][i] = NULL;
98 pRefPic->uiShortRefCount[LIST_0] = 0;98 }
99 99 }
100 for (i = 0; i < MAX_DPB_COUNT; i++) {100 pRefPic->uiShortRefCount[LIST_0] = 0;
101 if (pRefPic->pLongRefList[LIST_0][i] != NULL) {101
102 SetUnRef (pRefPic->pLongRefList[LIST_0][i]);102 for (i = 0; i < MAX_DPB_COUNT; i++) {
103 pRefPic->pLongRefList[LIST_0][i] = NULL;103 if (pRefPic->pLongRefList[LIST_0][i] != NULL) {
104 }104 SetUnRef (pRefPic->pLongRefList[LIST_0][i]);
105 }105 pRefPic->pLongRefList[LIST_0][i] = NULL;
106 pRefPic->uiLongRefCount[LIST_0] = 0;106 }
107}107 }
108 108 pRefPic->uiLongRefCount[LIST_0] = 0;
109/**109}
110 * fills the pRefPic.pRefList.110
111 */111static int32_t WelsCheckAndRecoverForFutureDecoding (PWelsDecoderContext pCtx) {
112int32_t WelsInitRefList (PWelsDecoderContext pCtx, int32_t iPoc) {112 if ((pCtx->sRefPic.uiShortRefCount[LIST_0] + pCtx->sRefPic.uiLongRefCount[LIST_0] <= 0) && (pCtx->eSliceType != I_SLICE
113 int32_t i, iCount = 0;113 && pCtx->eSliceType != SI_SLICE)) {
114 114 if (pCtx->pParam->eEcActiveIdc !=
115 if ((pCtx->sRefPic.uiShortRefCount[LIST_0] + pCtx->sRefPic.uiLongRefCount[LIST_0] <= 0) && (pCtx->eSliceType != I_SLICE115 ERROR_CON_DISABLE) { //IDR lost!, recover it for future decoding with data all set to 0
116 && pCtx->eSliceType != SI_SLICE)) {116 PPicture pRef = PrefetchPic (pCtx->pPicBuff);
117 if (pCtx->pParam->eEcActiveIdc !=117 if (pRef != NULL) {
118 ERROR_CON_DISABLE) { //IDR lost!, recover it for future decoding with data all set to 0118 // IDR lost, set new
119 PPicture pRef = PrefetchPic (pCtx->pPicBuff[0]);119 pRef->bIsComplete = false; // Set complete flag to false for lost IDR ref picture
120 if (pRef != NULL) {120 pRef->iSpsId = pCtx->pSps->iSpsId;
121 // IDR lost, set new121 pRef->iPpsId = pCtx->pPps->iPpsId;
122 pRef->bIsComplete = false; // Set complete flag to false for lost IDR ref picture122 pCtx->iErrorCode |= dsDataErrorConcealed;
123 pRef->iSpsId = pCtx->pSps->iSpsId;123 bool bCopyPrevious = ((ERROR_CON_FRAME_COPY_CROSS_IDR == pCtx->pParam->eEcActiveIdc)
124 pRef->iPpsId = pCtx->pPps->iPpsId;124 || (ERROR_CON_SLICE_COPY_CROSS_IDR == pCtx->pParam->eEcActiveIdc)
125 pCtx->iErrorCode |= dsDataErrorConcealed;125 || (ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE == pCtx->pParam->eEcActiveIdc)
126 bool bCopyPrevious = ((ERROR_CON_FRAME_COPY_CROSS_IDR == pCtx->pParam->eEcActiveIdc)126 || (ERROR_CON_SLICE_MV_COPY_CROSS_IDR == pCtx->pParam->eEcActiveIdc)
127 || (ERROR_CON_SLICE_COPY_CROSS_IDR == pCtx->pParam->eEcActiveIdc)127 || (ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE == pCtx->pParam->eEcActiveIdc))
128 || (ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE == pCtx->pParam->eEcActiveIdc)128 && (NULL != pCtx->pPreviousDecodedPictureInDpb);
129 || (ERROR_CON_SLICE_MV_COPY_CROSS_IDR == pCtx->pParam->eEcActiveIdc)129 bCopyPrevious = bCopyPrevious && (pRef->iWidthInPixel == pCtx->pPreviousDecodedPictureInDpb->iWidthInPixel)
130 || (ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE == pCtx->pParam->eEcActiveIdc))130 && (pRef->iHeightInPixel == pCtx->pPreviousDecodedPictureInDpb->iHeightInPixel);
131 && (NULL != pCtx->pPreviousDecodedPictureInDpb);131
132 bCopyPrevious = bCopyPrevious && (pRef->iWidthInPixel == pCtx->pPreviousDecodedPictureInDpb->iWidthInPixel)132 if (!bCopyPrevious) {
133 && (pRef->iHeightInPixel == pCtx->pPreviousDecodedPictureInDpb->iHeightInPixel);133 memset (pRef->pData[0], 128, pRef->iLinesize[0] * pRef->iHeightInPixel);
134 134 memset (pRef->pData[1], 128, pRef->iLinesize[1] * pRef->iHeightInPixel / 2);
135 if (!bCopyPrevious) {135 memset (pRef->pData[2], 128, pRef->iLinesize[2] * pRef->iHeightInPixel / 2);
136 memset (pRef->pData[0], 128, pRef->iLinesize[0] * pRef->iHeightInPixel);136 } else if (pRef == pCtx->pPreviousDecodedPictureInDpb) {
137 memset (pRef->pData[1], 128, pRef->iLinesize[1] * pRef->iHeightInPixel / 2);137 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "WelsInitRefList()::EC memcpy overlap.");
138 memset (pRef->pData[2], 128, pRef->iLinesize[2] * pRef->iHeightInPixel / 2);138 } else {
139 } else if (pRef == pCtx->pPreviousDecodedPictureInDpb) {139 memcpy (pRef->pData[0], pCtx->pPreviousDecodedPictureInDpb->pData[0], pRef->iLinesize[0] * pRef->iHeightInPixel);
140 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "WelsInitRefList()::EC memcpy overlap.");140 memcpy (pRef->pData[1], pCtx->pPreviousDecodedPictureInDpb->pData[1], pRef->iLinesize[1] * pRef->iHeightInPixel / 2);
141 } else {141 memcpy (pRef->pData[2], pCtx->pPreviousDecodedPictureInDpb->pData[2], pRef->iLinesize[2] * pRef->iHeightInPixel / 2);
142 memcpy (pRef->pData[0], pCtx->pPreviousDecodedPictureInDpb->pData[0], pRef->iLinesize[0] * pRef->iHeightInPixel);142 }
143 memcpy (pRef->pData[1], pCtx->pPreviousDecodedPictureInDpb->pData[1], pRef->iLinesize[1] * pRef->iHeightInPixel / 2);143 pRef->iFrameNum = 0;
144 memcpy (pRef->pData[2], pCtx->pPreviousDecodedPictureInDpb->pData[2], pRef->iLinesize[2] * pRef->iHeightInPixel / 2);144 pRef->iFramePoc = 0;
145 }145 pRef->uiTemporalId = pRef->uiQualityId = 0;
146 pRef->iFrameNum = 0;146 ExpandReferencingPicture (pRef->pData, pRef->iWidthInPixel, pRef->iHeightInPixel, pRef->iLinesize,
147 pRef->iFramePoc = 0;147 pCtx->sExpandPicFunc.pfExpandLumaPicture, pCtx->sExpandPicFunc.pfExpandChromaPicture);
148 pRef->uiTemporalId = pRef->uiQualityId = 0;148 AddShortTermToList (&pCtx->sRefPic, pRef);
149 ExpandReferencingPicture (pRef->pData, pRef->iWidthInPixel, pRef->iHeightInPixel, pRef->iLinesize,149 } else {
150 pCtx->sExpandPicFunc.pfExpandLumaPicture, pCtx->sExpandPicFunc.pfExpandChromaPicture);150 WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "WelsInitRefList()::PrefetchPic for EC errors.");
151 AddShortTermToList (&pCtx->sRefPic, pRef);151 pCtx->iErrorCode |= dsOutOfMemory;
152 } else {152 return ERR_INFO_REF_COUNT_OVERFLOW;
153 WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "WelsInitRefList()::PrefetchPic for EC errors.");153 }
154 pCtx->iErrorCode |= dsOutOfMemory;154 }
155 return ERR_INFO_REF_COUNT_OVERFLOW;155 }
156 }156 return ERR_NONE;
157 }157}
158 }158
159 159/**
160 PPicture* ppShoreRefList = pCtx->sRefPic.pShortRefList[LIST_0];160* fills the pRefPic.pRefList LIST_0 and LIST_0 for B-Slice.
161 PPicture* ppLongRefList = pCtx->sRefPic.pLongRefList[LIST_0];161*/
162 memset (pCtx->sRefPic.pRefList[LIST_0], 0, MAX_DPB_COUNT * sizeof (PPicture));162int32_t WelsInitBSliceRefList (PWelsDecoderContext pCtx, int32_t iPoc) {
163 //short163
164 for (i = 0; i < pCtx->sRefPic.uiShortRefCount[LIST_0]; ++i) {164 int32_t err = WelsCheckAndRecoverForFutureDecoding (pCtx);
165 pCtx->sRefPic.pRefList[LIST_0][iCount++ ] = ppShoreRefList[i];165 if (err != ERR_NONE) return err;
166 }166
167 167 PPicture* ppShoreRefList = pCtx->sRefPic.pShortRefList[LIST_0];
168 //long168 PPicture* ppLongRefList = pCtx->sRefPic.pLongRefList[LIST_0];
169 for (i = 0; i < pCtx->sRefPic.uiLongRefCount[LIST_0] ; ++i) {169 memset (pCtx->sRefPic.pRefList[LIST_0], 0, MAX_DPB_COUNT * sizeof (PPicture));
170 pCtx->sRefPic.pRefList[LIST_0][iCount++ ] = ppLongRefList[i];170 memset (pCtx->sRefPic.pRefList[LIST_1], 0, MAX_DPB_COUNT * sizeof (PPicture));
171 }171 int32_t iLSCurrPocCount = 0;
172 pCtx->sRefPic.uiRefCount[LIST_0] = iCount;172 int32_t iLTCurrPocCount = 0;
173 173 PPicture pLSCurrPocList0[MAX_DPB_COUNT];
174 return ERR_NONE;174 PPicture pLTCurrPocList0[MAX_DPB_COUNT];
175}175 for (int32_t i = 0; i < pCtx->sRefPic.uiShortRefCount[LIST_0]; ++i) {
176 176 if (ppShoreRefList[i]->iFramePoc < iPoc) {
177int32_t WelsReorderRefList (PWelsDecoderContext pCtx) {177 pLSCurrPocList0[iLSCurrPocCount++] = ppShoreRefList[i];
178 PRefPicListReorderSyn pRefPicListReorderSyn = pCtx->pCurDqLayer->pRefPicListReordering;178 }
179 PNalUnitHeaderExt pNalHeaderExt = &pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt;179 }
180 PSliceHeader pSliceHeader = &pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader;180 for (int32_t i = pCtx->sRefPic.uiShortRefCount[LIST_0] - 1; i >= 0; --i) {
181 PPicture pPic = NULL;181 if (ppShoreRefList[i]->iFramePoc > iPoc) {
182 PPicture* ppRefList = pCtx->sRefPic.pRefList[LIST_0];182 pLTCurrPocList0[iLTCurrPocCount++] = ppShoreRefList[i];
183 int32_t iMaxRefIdx = pCtx->pSps->iNumRefFrames;183 }
184 int32_t iRefCount = pCtx->sRefPic.uiRefCount[LIST_0];184 }
185 int32_t iPredFrameNum = pSliceHeader->iFrameNum;185 if (pCtx->sRefPic.uiLongRefCount[LIST_0] > 1) {
186 int32_t iMaxPicNum = 1 << pSliceHeader->pSps->uiLog2MaxFrameNum;186 //long sorts in increasing order
187 int32_t iAbsDiffPicNum = -1;187 PPicture pTemp;
188 int32_t iReorderingIndex = 0;188 for (int32_t i = 0; i < pCtx->sRefPic.uiLongRefCount[LIST_0]; ++i) {
189 int32_t i = 0;189 for (int32_t j = i + 1; j < pCtx->sRefPic.uiLongRefCount[LIST_0]; ++j) {
190 190 if (ppLongRefList[j]->iFramePoc < ppLongRefList[i]->iFramePoc) {
191 if (pCtx->eSliceType == I_SLICE || pCtx->eSliceType == SI_SLICE) {191 pTemp = ppLongRefList[i];
192 return ERR_NONE;192 ppLongRefList[i] = ppLongRefList[j];
193 }193 ppLongRefList[j] = pTemp;
194 194 }
195 if (iRefCount <= 0) {195 }
196 pCtx->iErrorCode = dsNoParamSets; //No any reference for decoding, SHOULD request IDR196 }
197 return ERR_INFO_REFERENCE_PIC_LOST;197 }
198 }198 int32_t iCurrPocCount = iLSCurrPocCount + iLTCurrPocCount;
199 199 int32_t iCount = 0;
200 if (pRefPicListReorderSyn->bRefPicListReorderingFlag[LIST_0]) {200 //LIST_0
201 while ((iReorderingIndex < iMaxRefIdx)201 //short
202 && (pRefPicListReorderSyn->sReorderingSyn[LIST_0][iReorderingIndex].uiReorderingOfPicNumsIdc != 3)) {202 //It may need to sort LIST_0 and LIST_1 so that they will have the right default orders.
203 uint16_t uiReorderingOfPicNumsIdc =203 for (int32_t i = 0; i < iLSCurrPocCount; ++i) {
204 pRefPicListReorderSyn->sReorderingSyn[LIST_0][iReorderingIndex].uiReorderingOfPicNumsIdc;204 pCtx->sRefPic.pRefList[LIST_0][iCount++] = pLSCurrPocList0[i];
205 if (uiReorderingOfPicNumsIdc < 2) {205 }
206 iAbsDiffPicNum = pRefPicListReorderSyn->sReorderingSyn[LIST_0][iReorderingIndex].uiAbsDiffPicNumMinus1 + 1;206 if (iLSCurrPocCount > 1) {
207 207 //LIST_0 short sorts in decreasing order
208 if (uiReorderingOfPicNumsIdc == 0) {208 PPicture pTemp;
209 iPredFrameNum -= iAbsDiffPicNum;209 for (int32_t i = 0; i < iLSCurrPocCount; ++i) {
210 } else {210 for (int32_t j = i + 1; j < iLSCurrPocCount; ++j) {
211 iPredFrameNum += iAbsDiffPicNum;211 if (pCtx->sRefPic.pRefList[LIST_0][j]->iFramePoc > pCtx->sRefPic.pRefList[LIST_0][i]->iFramePoc) {
212 }212 pTemp = pCtx->sRefPic.pRefList[LIST_0][i];
213 iPredFrameNum &= iMaxPicNum - 1;213 pCtx->sRefPic.pRefList[LIST_0][i] = pCtx->sRefPic.pRefList[LIST_0][j];
214 214 pCtx->sRefPic.pRefList[LIST_0][j] = pTemp;
215 for (i = iMaxRefIdx - 1; i >= 0; i--) {215 }
216 if (ppRefList[i] != NULL && ppRefList[i]->iFrameNum == iPredFrameNum && !ppRefList[i]->bIsLongRef) {216 }
217 if ((pNalHeaderExt->uiQualityId == ppRefList[i]->uiQualityId)217 }
218 && (pSliceHeader->iSpsId != ppRefList[i]->iSpsId)) { //check;218 }
219 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "WelsReorderRefList()::::BASE LAYER::::iSpsId:%d, ref_sps_id:%d",219 for (int32_t i = 0; i < iLTCurrPocCount; ++i) {
220 pSliceHeader->iSpsId, ppRefList[i]->iSpsId);220 pCtx->sRefPic.pRefList[LIST_0][iCount++] = pLTCurrPocList0[i];
221 pCtx->iErrorCode = dsNoParamSets; //cross-IDR reference frame selection, SHOULD request IDR.--221 }
222 return ERR_INFO_REFERENCE_PIC_LOST;222 if (iLTCurrPocCount > 1) {
223 } else {223 //LIST_0 short sorts in increasing order
224 break;224 PPicture pTemp;
225 }225 for (int32_t i = iLSCurrPocCount; i < iCurrPocCount; ++i) {
226 }226 for (int32_t j = i + 1; j < iCurrPocCount; ++j) {
227 }227 if (pCtx->sRefPic.pRefList[LIST_0][j]->iFramePoc < pCtx->sRefPic.pRefList[LIST_0][i]->iFramePoc) {
228 228 pTemp = pCtx->sRefPic.pRefList[LIST_0][i];
229 } else if (uiReorderingOfPicNumsIdc == 2) {229 pCtx->sRefPic.pRefList[LIST_0][i] = pCtx->sRefPic.pRefList[LIST_0][j];
230 for (i = iMaxRefIdx - 1; i >= 0; i--) {230 pCtx->sRefPic.pRefList[LIST_0][j] = pTemp;
231 if (ppRefList[i] != NULL && ppRefList[i]->bIsLongRef231 }
232 && ppRefList[i]->iLongTermFrameIdx ==232 }
233 pRefPicListReorderSyn->sReorderingSyn[LIST_0][iReorderingIndex].uiLongTermPicNum) {233 }
234 if ((pNalHeaderExt->uiQualityId == ppRefList[i]->uiQualityId)234 }
235 && (pSliceHeader->iSpsId != ppRefList[i]->iSpsId)) { //check;235 //long
236 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "WelsReorderRefList()::::BASE LAYER::::iSpsId:%d, ref_sps_id:%d",236 for (int32_t i = 0; i < pCtx->sRefPic.uiLongRefCount[LIST_0]; ++i) {
237 pSliceHeader->iSpsId, ppRefList[i]->iSpsId);237 pCtx->sRefPic.pRefList[LIST_0][iCount++] = ppLongRefList[i];
238 pCtx->iErrorCode = dsNoParamSets; //cross-IDR reference frame selection, SHOULD request IDR.--238 }
239 return ERR_INFO_REFERENCE_PIC_LOST;239 pCtx->sRefPic.uiRefCount[LIST_0] = iCount;
240 } else {240
241 break;241 iCount = 0;
242 }242 //LIST_1
243 }243 //short
244 }244 for (int32_t i = 0; i < iLTCurrPocCount; ++i) {
245 }245 pCtx->sRefPic.pRefList[LIST_1][iCount++] = pLTCurrPocList0[i];
246 if (i < 0) {246 }
247 return ERR_INFO_REFERENCE_PIC_LOST;247 if (iLTCurrPocCount > 1) {
248 }248 //LIST_1 short sorts in increasing order
249 pPic = ppRefList[i];249 PPicture pTemp;
250 if (i > iReorderingIndex) {250 for (int32_t i = 0; i < iLTCurrPocCount; ++i) {
251 memmove (&ppRefList[1 + iReorderingIndex], &ppRefList[iReorderingIndex],251 for (int32_t j = i + 1; j < iLTCurrPocCount; ++j) {
252 (i - iReorderingIndex)*sizeof (PPicture)); //confirmed_safe_unsafe_usage252 if (pCtx->sRefPic.pRefList[LIST_1][j]->iFramePoc < pCtx->sRefPic.pRefList[LIST_1][i]->iFramePoc) {
253 } else if (i < iReorderingIndex) {253 pTemp = pCtx->sRefPic.pRefList[LIST_1][i];
254 memmove (&ppRefList[1 + iReorderingIndex], &ppRefList[iReorderingIndex],254 pCtx->sRefPic.pRefList[LIST_1][i] = pCtx->sRefPic.pRefList[LIST_1][j];
255 (iMaxRefIdx - iReorderingIndex)*sizeof (PPicture));255 pCtx->sRefPic.pRefList[LIST_1][j] = pTemp;
256 }256 }
257 ppRefList[iReorderingIndex] = pPic;257 }
258 iReorderingIndex++;258 }
259 }259 }
260 }260 for (int32_t i = 0; i < iLSCurrPocCount; ++i) {
261 return ERR_NONE;261 pCtx->sRefPic.pRefList[LIST_1][iCount++] = pLSCurrPocList0[i];
262}262 }
263 263 if (iLSCurrPocCount > 1) {
264int32_t WelsMarkAsRef (PWelsDecoderContext pCtx) {264 //LIST_1 short sorts in decreasing order
265 PRefPic pRefPic = &pCtx->sRefPic;265 PPicture pTemp;
266 PRefPicMarking pRefPicMarking = pCtx->pCurDqLayer->pRefPicMarking;266 for (int32_t i = iLTCurrPocCount; i < iCurrPocCount; ++i) {
267 PAccessUnit pCurAU = pCtx->pAccessUnitList;267 for (int32_t j = i + 1; j < iCurrPocCount; ++j) {
268 bool bIsIDRAU = false;268 if (pCtx->sRefPic.pRefList[LIST_1][j]->iFramePoc > pCtx->sRefPic.pRefList[LIST_1][i]->iFramePoc) {
269 uint32_t j;269 pTemp = pCtx->sRefPic.pRefList[LIST_1][i];
270 270 pCtx->sRefPic.pRefList[LIST_1][i] = pCtx->sRefPic.pRefList[LIST_1][j];
271 int32_t iRet = ERR_NONE;271 pCtx->sRefPic.pRefList[LIST_1][j] = pTemp;
272 272 }
273 pCtx->pDec->uiQualityId = pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.uiQualityId;273 }
274 pCtx->pDec->uiTemporalId = pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.uiTemporalId;274 }
275 pCtx->pDec->iSpsId = pCtx->pSps->iSpsId;275 }
276 pCtx->pDec->iPpsId = pCtx->pPps->iPpsId;276 //long
277 277 for (int32_t i = 0; i < pCtx->sRefPic.uiLongRefCount[LIST_0]; ++i) {
278 for (j = pCurAU->uiStartPos; j <= pCurAU->uiEndPos; j++) {278 pCtx->sRefPic.pRefList[LIST_1][iCount++] = ppLongRefList[i];
279 if (pCurAU->pNalUnitsList[j]->sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR279 }
280 || pCurAU->pNalUnitsList[j]->sNalHeaderExt.bIdrFlag) {280 pCtx->sRefPic.uiRefCount[LIST_1] = iCount;
281 bIsIDRAU = true;281 return ERR_NONE;
282 break;282}
283 }283
284 }284/**
285 if (bIsIDRAU) {285 * fills the pRefPic.pRefList.
286 if (pRefPicMarking->bLongTermRefFlag) {286 */
287 pCtx->sRefPic.iMaxLongTermFrameIdx = 0;287int32_t WelsInitRefList (PWelsDecoderContext pCtx, int32_t iPoc) {
288 AddLongTermToList (pRefPic, pCtx->pDec, 0);288
289 } else {289 int32_t err = WelsCheckAndRecoverForFutureDecoding (pCtx);
290 pCtx->sRefPic.iMaxLongTermFrameIdx = -1;290 if (err != ERR_NONE) return err;
291 }291
292 } else {292 PPicture* ppShoreRefList = pCtx->sRefPic.pShortRefList[LIST_0];
293 if (pRefPicMarking->bAdaptiveRefPicMarkingModeFlag) {293 PPicture* ppLongRefList = pCtx->sRefPic.pLongRefList[LIST_0];
294 iRet = MMCO (pCtx, pRefPicMarking);294 memset (pCtx->sRefPic.pRefList[LIST_0], 0, MAX_DPB_COUNT * sizeof (PPicture));
295 if (iRet != ERR_NONE) {295
296 if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {296 int32_t i, iCount = 0;
297 iRet = RemainOneBufferInDpbForEC (pCtx);297 //short
298 WELS_VERIFY_RETURN_IF (iRet, iRet);298 for (i = 0; i < pCtx->sRefPic.uiShortRefCount[LIST_0]; ++i) {
299 } else {299 pCtx->sRefPic.pRefList[LIST_0][iCount++ ] = ppShoreRefList[i];
300 return iRet;300 }
301 }301
302 }302 //long
303 303 for (i = 0; i < pCtx->sRefPic.uiLongRefCount[LIST_0] ; ++i) {
304 if (pCtx->bLastHasMmco5) {304 pCtx->sRefPic.pRefList[LIST_0][iCount++ ] = ppLongRefList[i];
305 pCtx->pDec->iFrameNum = 0;305 }
306 pCtx->pDec->iFramePoc = 0;306 pCtx->sRefPic.uiRefCount[LIST_0] = iCount;
307 }307
308 308 return ERR_NONE;
309 } else {309}
310 iRet = SlidingWindow (pCtx);310
311 if (iRet != ERR_NONE) {311int32_t WelsReorderRefList (PWelsDecoderContext pCtx) {
312 if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {312
313 iRet = RemainOneBufferInDpbForEC (pCtx);313 if (pCtx->eSliceType == I_SLICE || pCtx->eSliceType == SI_SLICE) {
314 WELS_VERIFY_RETURN_IF (iRet, iRet);314 return ERR_NONE;
315 } else {315 }
316 return iRet;316
317 }317 PRefPicListReorderSyn pRefPicListReorderSyn = pCtx->pCurDqLayer->pRefPicListReordering;
318 }318 PNalUnitHeaderExt pNalHeaderExt = &pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt;
319 }319 PSliceHeader pSliceHeader = &pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader;
320 }320 int32_t ListCount = 1;
321 321 if (pCtx->eSliceType == B_SLICE) ListCount = 2;
322 if (!pCtx->pDec->bIsLongRef) {322// PPicture* ppShoreRefList = pCtx->sRefPic.pShortRefList[LIST_0];
323 if (pRefPic->uiLongRefCount[LIST_0] + pRefPic->uiShortRefCount[LIST_0] >= WELS_MAX (1, pCtx->pSps->iNumRefFrames)) {323// int32_t iShortRefCount = pCtx->sRefPic.uiShortRefCount[LIST_0];
324 if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {324// PPicture* ppLongRefList = pCtx->sRefPic.pLongRefList[LIST_0];
325 iRet = RemainOneBufferInDpbForEC (pCtx);325// int32_t iLongRefCount = pCtx->sRefPic.uiLongRefCount[LIST_0];
326 WELS_VERIFY_RETURN_IF (iRet, iRet);326 for (int32_t listIdx = 0; listIdx < ListCount; ++listIdx) {
327 } else {327 PPicture pPic = NULL;
328 return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW;328 PPicture* ppRefList = pCtx->sRefPic.pRefList[listIdx];
329 }329 int32_t iMaxRefIdx = pCtx->pSps->iNumRefFrames;
330 }330 int32_t iRefCount = pCtx->sRefPic.uiRefCount[listIdx];
331 iRet = AddShortTermToList (pRefPic, pCtx->pDec);331 int32_t iPredFrameNum = pSliceHeader->iFrameNum;
332 }332 int32_t iMaxPicNum = 1 << pSliceHeader->pSps->uiLog2MaxFrameNum;
333 333 int32_t iAbsDiffPicNum = -1;
334 return iRet;334 int32_t iReorderingIndex = 0;
335}335 int32_t i = 0;
336 336
337static int32_t MMCO (PWelsDecoderContext pCtx, PRefPicMarking pRefPicMarking) {337 if (iRefCount <= 0) {
338 PSps pSps = pCtx->pCurDqLayer->sLayerInfo.pSps;338 pCtx->iErrorCode = dsNoParamSets; //No any reference for decoding, SHOULD request IDR
339 int32_t i = 0;339 return ERR_INFO_REFERENCE_PIC_LOST;
340 int32_t iRet = ERR_NONE;340 }
341 for (i = 0; i < MAX_MMCO_COUNT && pRefPicMarking->sMmcoRef[i].uiMmcoType != MMCO_END; i++) {341
342 uint32_t uiMmcoType = pRefPicMarking->sMmcoRef[i].uiMmcoType;342 if (pRefPicListReorderSyn->bRefPicListReorderingFlag[listIdx]) {
343 int32_t iShortFrameNum = (pCtx->iFrameNum - pRefPicMarking->sMmcoRef[i].iDiffOfPicNum) & ((343 while ((iReorderingIndex < iMaxRefIdx)
344 1 << pSps->uiLog2MaxFrameNum) - 1);344 && (pRefPicListReorderSyn->sReorderingSyn[listIdx][iReorderingIndex].uiReorderingOfPicNumsIdc != 3)) {
345 uint32_t uiLongTermPicNum = pRefPicMarking->sMmcoRef[i].uiLongTermPicNum;345 uint16_t uiReorderingOfPicNumsIdc =
346 int32_t iLongTermFrameIdx = pRefPicMarking->sMmcoRef[i].iLongTermFrameIdx;346 pRefPicListReorderSyn->sReorderingSyn[listIdx][iReorderingIndex].uiReorderingOfPicNumsIdc;
347 int32_t iMaxLongTermFrameIdx = pRefPicMarking->sMmcoRef[i].iMaxLongTermFrameIdx;347 if (uiReorderingOfPicNumsIdc < 2) {
348 if (uiMmcoType > MMCO_LONG) {348 iAbsDiffPicNum = pRefPicListReorderSyn->sReorderingSyn[listIdx][iReorderingIndex].uiAbsDiffPicNumMinus1 + 1;
349 return ERR_INFO_INVALID_MMCO_OPCODE_BASE;349
350 }350 if (uiReorderingOfPicNumsIdc == 0) {
351 iRet = MMCOProcess (pCtx, uiMmcoType, iShortFrameNum, uiLongTermPicNum, iLongTermFrameIdx, iMaxLongTermFrameIdx);351 iPredFrameNum -= iAbsDiffPicNum;
352 if (iRet != ERR_NONE) {352 } else {
353 return iRet;353 iPredFrameNum += iAbsDiffPicNum;
354 }354 }
355 }355 iPredFrameNum &= iMaxPicNum - 1;
356 if (i == MAX_MMCO_COUNT) { //although Rec does not handle this condition, we here prohibit too many MMCO op356
357 return ERR_INFO_INVALID_MMCO_NUM;357 for (i = iMaxRefIdx - 1; i >= 0; i--) {
358 }358 if (ppRefList[i] != NULL && ppRefList[i]->iFrameNum == iPredFrameNum && !ppRefList[i]->bIsLongRef) {
359 359 if ((pNalHeaderExt->uiQualityId == ppRefList[i]->uiQualityId)
360 return ERR_NONE;360 && (pSliceHeader->iSpsId != ppRefList[i]->iSpsId)) { //check;
361}361 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "WelsReorderRefList()::::BASE LAYER::::iSpsId:%d, ref_sps_id:%d",
362static int32_t MMCOProcess (PWelsDecoderContext pCtx, uint32_t uiMmcoType,362 pSliceHeader->iSpsId, ppRefList[i]->iSpsId);
363 int32_t iShortFrameNum, uint32_t uiLongTermPicNum , int32_t iLongTermFrameIdx, int32_t iMaxLongTermFrameIdx) {363 pCtx->iErrorCode = dsNoParamSets; //cross-IDR reference frame selection, SHOULD request IDR.--
364 PRefPic pRefPic = &pCtx->sRefPic;364 return ERR_INFO_REFERENCE_PIC_LOST;
365 PPicture pPic = NULL;365 } else {
366 int32_t i = 0;366 break;
367 int32_t iRet = ERR_NONE;367 }
368 368 }
369 switch (uiMmcoType) {369 }
370 case MMCO_SHORT2UNUSED:370
371 pPic = WelsDelShortFromListSetUnref (pRefPic, iShortFrameNum);371 } else if (uiReorderingOfPicNumsIdc == 2) {
372 if (pPic == NULL) {372 for (i = iMaxRefIdx - 1; i >= 0; i--) {
373 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "MMCO_SHORT2UNUSED: delete an empty entry from short term list");373 if (ppRefList[i] != NULL && ppRefList[i]->bIsLongRef
374 }374 && ppRefList[i]->iLongTermFrameIdx ==
375 break;375 pRefPicListReorderSyn->sReorderingSyn[listIdx][iReorderingIndex].uiLongTermPicNum) {
376 case MMCO_LONG2UNUSED:376 if ((pNalHeaderExt->uiQualityId == ppRefList[i]->uiQualityId)
377 pPic = WelsDelLongFromListSetUnref (pRefPic, uiLongTermPicNum);377 && (pSliceHeader->iSpsId != ppRefList[i]->iSpsId)) { //check;
378 if (pPic == NULL) {378 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "WelsReorderRefList()::::BASE LAYER::::iSpsId:%d, ref_sps_id:%d",
379 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "MMCO_LONG2UNUSED: delete an empty entry from long term list");379 pSliceHeader->iSpsId, ppRefList[i]->iSpsId);
380 }380 pCtx->iErrorCode = dsNoParamSets; //cross-IDR reference frame selection, SHOULD request IDR.--
381 break;381 return ERR_INFO_REFERENCE_PIC_LOST;
382 case MMCO_SHORT2LONG:382 } else {
383 if (iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx) {383 break;
384 return ERR_INFO_INVALID_MMCO_LONG_TERM_IDX_EXCEED_MAX;384 }
385 }385 }
386 pPic = WelsDelShortFromList (pRefPic, iShortFrameNum);386 }
387 if (pPic == NULL) {387 }
388 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "MMCO_LONG2LONG: delete an empty entry from short term list");388 if (i < 0) {
389 break;389 return ERR_INFO_REFERENCE_PIC_LOST;
390 }390 }
391 WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx);391 pPic = ppRefList[i];
392#ifdef LONG_TERM_REF392 if (i > iReorderingIndex) {
393 pCtx->bCurAuContainLtrMarkSeFlag = true;393 memmove (&ppRefList[1 + iReorderingIndex], &ppRefList[iReorderingIndex],
394 pCtx->iFrameNumOfAuMarkedLtr = iShortFrameNum;394 (i - iReorderingIndex) * sizeof (PPicture)); //confirmed_safe_unsafe_usage
395 WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "ex_mark_avc():::MMCO_SHORT2LONG:::LTR marking....iFrameNum: %d",395 } else if (i < iReorderingIndex) {
396 pCtx->iFrameNumOfAuMarkedLtr);396 memmove (&ppRefList[1 + iReorderingIndex], &ppRefList[iReorderingIndex],
397#endif397 (iMaxRefIdx - iReorderingIndex) * sizeof (PPicture));
398 398 }
399 MarkAsLongTerm (pRefPic, iShortFrameNum, iLongTermFrameIdx);399 ppRefList[iReorderingIndex] = pPic;
400 break;400 iReorderingIndex++;
401 case MMCO_SET_MAX_LONG:401 }
402 pRefPic->iMaxLongTermFrameIdx = iMaxLongTermFrameIdx;402 }
403 for (i = 0 ; i < pRefPic->uiLongRefCount[LIST_0]; i++) {403 }
404 if (pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx) {404 return ERR_NONE;
405 WelsDelLongFromListSetUnref (pRefPic, pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx);405}
406 }406
407 }407int32_t WelsMarkAsRef (PWelsDecoderContext pCtx) {
408 break;408 PRefPic pRefPic = &pCtx->sRefPic;
409 case MMCO_RESET:409 PRefPicMarking pRefPicMarking = pCtx->pCurDqLayer->pRefPicMarking;
410 WelsResetRefPic (pCtx);410 PAccessUnit pCurAU = pCtx->pAccessUnitList;
411 pCtx->bLastHasMmco5 = true;411 bool bIsIDRAU = false;
412 break;412 uint32_t j;
413 case MMCO_LONG:413
414 if (iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx) {414 int32_t iRet = ERR_NONE;
415 return ERR_INFO_INVALID_MMCO_LONG_TERM_IDX_EXCEED_MAX;415
416 }416 pCtx->pDec->uiQualityId = pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.uiQualityId;
417 WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx);417 pCtx->pDec->uiTemporalId = pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.uiTemporalId;
418 if (pRefPic->uiLongRefCount[LIST_0] + pRefPic->uiShortRefCount[LIST_0] >= WELS_MAX (1, pCtx->pSps->iNumRefFrames)) {418 pCtx->pDec->iSpsId = pCtx->pSps->iSpsId;
419 return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW;419 pCtx->pDec->iPpsId = pCtx->pPps->iPpsId;
420 }420
421#ifdef LONG_TERM_REF421 for (j = pCurAU->uiStartPos; j <= pCurAU->uiEndPos; j++) {
422 pCtx->bCurAuContainLtrMarkSeFlag = true;422 if (pCurAU->pNalUnitsList[j]->sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR
423 pCtx->iFrameNumOfAuMarkedLtr = pCtx->iFrameNum;423 || pCurAU->pNalUnitsList[j]->sNalHeaderExt.bIdrFlag) {
424 WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "ex_mark_avc():::MMCO_LONG:::LTR marking....iFrameNum: %d",424 bIsIDRAU = true;
425 pCtx->iFrameNum);425 break;
426#endif426 }
427 iRet = AddLongTermToList (pRefPic, pCtx->pDec, iLongTermFrameIdx);427 }
428 break;428 if (bIsIDRAU) {
429 default :429 if (pRefPicMarking->bLongTermRefFlag) {
430 break;430 pCtx->sRefPic.iMaxLongTermFrameIdx = 0;
431 }431 AddLongTermToList (pRefPic, pCtx->pDec, 0);
432 432 } else {
433 return iRet;433 pCtx->sRefPic.iMaxLongTermFrameIdx = -1;
434}434 }
435 435 } else {
436static int32_t SlidingWindow (PWelsDecoderContext pCtx) {436 if (pRefPicMarking->bAdaptiveRefPicMarkingModeFlag) {
437 PRefPic pRefPic = &pCtx->sRefPic;437 iRet = MMCO (pCtx, pRefPicMarking);
438 PPicture pPic = NULL;438 if (iRet != ERR_NONE) {
439 int32_t i = 0;439 if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
440 440 iRet = RemainOneBufferInDpbForEC (pCtx);
441 if (pCtx->sRefPic.uiShortRefCount[LIST_0] + pCtx->sRefPic.uiLongRefCount[LIST_0] >= pCtx->pSps->iNumRefFrames) {441 WELS_VERIFY_RETURN_IF (iRet, iRet);
442 if (pCtx->sRefPic.uiShortRefCount[LIST_0] == 0) {442 } else {
443 WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "No reference picture in short term list when sliding window");443 return iRet;
444 return ERR_INFO_INVALID_MMCO_REF_NUM_NOT_ENOUGH;444 }
445 }445 }
446 for (i = pRefPic->uiShortRefCount[LIST_0] - 1; i >= 0; i--) {446
447 pPic = WelsDelShortFromList (pRefPic, pRefPic->pShortRefList[LIST_0][i]->iFrameNum);447 if (pCtx->bLastHasMmco5) {
448 if (pPic) {448 pCtx->pDec->iFrameNum = 0;
449 SetUnRef (pPic);449 pCtx->pDec->iFramePoc = 0;
450 break;450 }
451 } else {451
452 return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW;452 } else {
453 }453 iRet = SlidingWindow (pCtx);
454 }454 if (iRet != ERR_NONE) {
455 }455 if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
456 return ERR_NONE;456 iRet = RemainOneBufferInDpbForEC (pCtx);
457}457 WELS_VERIFY_RETURN_IF (iRet, iRet);
458 458 } else {
459static PPicture WelsDelShortFromList (PRefPic pRefPic, int32_t iFrameNum) {459 return iRet;
460 int32_t i = 0;460 }
461 int32_t iMoveSize = 0;461 }
462 PPicture pPic = NULL;462 }
463 463 }
464 for (i = 0; i < pRefPic->uiShortRefCount[LIST_0]; i++) {464
465 if (pRefPic->pShortRefList[LIST_0][i]->iFrameNum == iFrameNum) {465 if (!pCtx->pDec->bIsLongRef) {
466 iMoveSize = pRefPic->uiShortRefCount[LIST_0] - i - 1;466 if (pRefPic->uiLongRefCount[LIST_0] + pRefPic->uiShortRefCount[LIST_0] >= WELS_MAX (1, pCtx->pSps->iNumRefFrames)) {
467 pRefPic->pShortRefList[LIST_0][i]->bUsedAsRef = false;467 if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
468 pPic = pRefPic->pShortRefList[LIST_0][i];468 iRet = RemainOneBufferInDpbForEC (pCtx);
469 pRefPic->pShortRefList[LIST_0][i] = NULL;469 WELS_VERIFY_RETURN_IF (iRet, iRet);
470 if (iMoveSize > 0) {470 } else {
471 memmove (&pRefPic->pShortRefList[LIST_0][i], &pRefPic->pShortRefList[LIST_0][i + 1],471 return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW;
472 iMoveSize * sizeof (PPicture)); //confirmed_safe_unsafe_usage472 }
473 }473 }
474 pRefPic->uiShortRefCount[LIST_0]--;474 iRet = AddShortTermToList (pRefPic, pCtx->pDec);
475 pRefPic->pShortRefList[LIST_0][pRefPic->uiShortRefCount[LIST_0]] = NULL;475 }
476 break;476
477 }477 return iRet;
478 }478}
479 479
480 return pPic;480static int32_t MMCO (PWelsDecoderContext pCtx, PRefPicMarking pRefPicMarking) {
481}481 PSps pSps = pCtx->pCurDqLayer->sLayerInfo.pSps;
482 482 int32_t i = 0;
483static PPicture WelsDelShortFromListSetUnref (PRefPic pRefPic, int32_t iFrameNum) {483 int32_t iRet = ERR_NONE;
484 PPicture pPic = WelsDelShortFromList (pRefPic, iFrameNum);484 for (i = 0; i < MAX_MMCO_COUNT && pRefPicMarking->sMmcoRef[i].uiMmcoType != MMCO_END; i++) {
485 if (pPic) {485 uint32_t uiMmcoType = pRefPicMarking->sMmcoRef[i].uiMmcoType;
486 SetUnRef (pPic);486 int32_t iShortFrameNum = (pCtx->iFrameNum - pRefPicMarking->sMmcoRef[i].iDiffOfPicNum) & ((
487 }487 1 << pSps->uiLog2MaxFrameNum) - 1);
488 return pPic;488 uint32_t uiLongTermPicNum = pRefPicMarking->sMmcoRef[i].uiLongTermPicNum;
489}489 int32_t iLongTermFrameIdx = pRefPicMarking->sMmcoRef[i].iLongTermFrameIdx;
490 490 int32_t iMaxLongTermFrameIdx = pRefPicMarking->sMmcoRef[i].iMaxLongTermFrameIdx;
491static PPicture WelsDelLongFromList (PRefPic pRefPic, uint32_t uiLongTermFrameIdx) {491 if (uiMmcoType > MMCO_LONG) {
492 PPicture pPic = NULL;492 return ERR_INFO_INVALID_MMCO_OPCODE_BASE;
493 int32_t i = 0;493 }
494 for (i = 0; i < pRefPic->uiLongRefCount[LIST_0]; i++) {494 iRet = MMCOProcess (pCtx, uiMmcoType, iShortFrameNum, uiLongTermPicNum, iLongTermFrameIdx, iMaxLongTermFrameIdx);
495 pPic = pRefPic->pLongRefList[LIST_0][i];495 if (iRet != ERR_NONE) {
496 if (pPic->iLongTermFrameIdx == (int32_t)uiLongTermFrameIdx) {496 return iRet;
497 int32_t iMoveSize = pRefPic->uiLongRefCount[LIST_0] - i - 1;497 }
498 pPic->bUsedAsRef = false;498 }
499 pPic->bIsLongRef = false;499 if (i == MAX_MMCO_COUNT) { //although Rec does not handle this condition, we here prohibit too many MMCO op
500 if (iMoveSize > 0) {500 return ERR_INFO_INVALID_MMCO_NUM;
501 memmove (&pRefPic->pLongRefList[LIST_0][i], &pRefPic->pLongRefList[LIST_0][i + 1],501 }
502 iMoveSize * sizeof (PPicture)); //confirmed_safe_unsafe_usage502
503 }503 return ERR_NONE;
504 pRefPic->uiLongRefCount[LIST_0]--;504}
505 pRefPic->pLongRefList[LIST_0][pRefPic->uiLongRefCount[LIST_0]] = NULL;505static int32_t MMCOProcess (PWelsDecoderContext pCtx, uint32_t uiMmcoType,
506 return pPic;506 int32_t iShortFrameNum, uint32_t uiLongTermPicNum, int32_t iLongTermFrameIdx, int32_t iMaxLongTermFrameIdx) {
507 }507 PRefPic pRefPic = &pCtx->sRefPic;
508 }508 PPicture pPic = NULL;
509 return NULL;509 int32_t i = 0;
510}510 int32_t iRet = ERR_NONE;
511 511
512static PPicture WelsDelLongFromListSetUnref (PRefPic pRefPic, uint32_t uiLongTermFrameIdx) {512 switch (uiMmcoType) {
513 PPicture pPic = WelsDelLongFromList (pRefPic, uiLongTermFrameIdx);513 case MMCO_SHORT2UNUSED:
514 if (pPic) {514 pPic = WelsDelShortFromListSetUnref (pRefPic, iShortFrameNum);
515 SetUnRef (pPic);515 if (pPic == NULL) {
516 }516 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "MMCO_SHORT2UNUSED: delete an empty entry from short term list");
517 return pPic;517 }
518}518 break;
519 519 case MMCO_LONG2UNUSED:
520static int32_t AddShortTermToList (PRefPic pRefPic, PPicture pPic) {520 pPic = WelsDelLongFromListSetUnref (pRefPic, uiLongTermPicNum);
521 pPic->bUsedAsRef = true;521 if (pPic == NULL) {
522 pPic->bIsLongRef = false;522 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "MMCO_LONG2UNUSED: delete an empty entry from long term list");
523 pPic->iLongTermFrameIdx = -1;523 }
524 if (pRefPic->uiShortRefCount[LIST_0] > 0) {524 break;
525 // Check the duplicate frame_num in short ref list525 case MMCO_SHORT2LONG:
526 for (int32_t iPos = 0; iPos < pRefPic->uiShortRefCount[LIST_0]; iPos++) {526 if (iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx) {
527 if (pPic->iFrameNum == pRefPic->pShortRefList[LIST_0][iPos]->iFrameNum) {527 return ERR_INFO_INVALID_MMCO_LONG_TERM_IDX_EXCEED_MAX;
528 // Replace the previous ref pic with the new one with the same frame_num528 }
529 pRefPic->pShortRefList[LIST_0][iPos] = pPic;529 pPic = WelsDelShortFromList (pRefPic, iShortFrameNum);
530 return ERR_INFO_DUPLICATE_FRAME_NUM;530 if (pPic == NULL) {
531 }531 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "MMCO_LONG2LONG: delete an empty entry from short term list");
532 }532 break;
533 533 }
534 memmove (&pRefPic->pShortRefList[LIST_0][1], &pRefPic->pShortRefList[LIST_0][0],534 WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx);
535 pRefPic->uiShortRefCount[LIST_0]*sizeof (PPicture));//confirmed_safe_unsafe_usage535#ifdef LONG_TERM_REF
536 }536 pCtx->bCurAuContainLtrMarkSeFlag = true;
537 pRefPic->pShortRefList[LIST_0][0] = pPic;537 pCtx->iFrameNumOfAuMarkedLtr = iShortFrameNum;
538 pRefPic->uiShortRefCount[LIST_0]++;538 WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "ex_mark_avc():::MMCO_SHORT2LONG:::LTR marking....iFrameNum: %d",
539 return ERR_NONE;539 pCtx->iFrameNumOfAuMarkedLtr);
540}540#endif
541 541
542static int32_t AddLongTermToList (PRefPic pRefPic, PPicture pPic, int32_t iLongTermFrameIdx) {542 MarkAsLongTerm (pRefPic, iShortFrameNum, iLongTermFrameIdx);
543 int32_t i = 0;543 break;
544 544 case MMCO_SET_MAX_LONG:
545 pPic->bUsedAsRef = true;545 pRefPic->iMaxLongTermFrameIdx = iMaxLongTermFrameIdx;
546 pPic->bIsLongRef = true;546 for (i = 0 ; i < pRefPic->uiLongRefCount[LIST_0]; i++) {
547 pPic->iLongTermFrameIdx = iLongTermFrameIdx;547 if (pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx) {
548 if (pRefPic->uiLongRefCount[LIST_0] == 0) {548 WelsDelLongFromListSetUnref (pRefPic, pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx);
549 pRefPic->pLongRefList[LIST_0][pRefPic->uiLongRefCount[LIST_0]] = pPic;549 }
550 } else {550 }
551 for (i = 0; i < pRefPic->uiLongRefCount[LIST_0]; i++) {551 break;
552 if (pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx > pPic->iLongTermFrameIdx) {552 case MMCO_RESET:
553 break;553 WelsResetRefPic (pCtx);
554 }554 pCtx->bLastHasMmco5 = true;
555 }555 break;
556 memmove (&pRefPic->pLongRefList[LIST_0][i + 1], &pRefPic->pLongRefList[LIST_0][i],556 case MMCO_LONG:
557 (pRefPic->uiLongRefCount[LIST_0] - i)*sizeof (PPicture)); //confirmed_safe_unsafe_usage557 if (iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx) {
558 pRefPic->pLongRefList[LIST_0][i] = pPic;558 return ERR_INFO_INVALID_MMCO_LONG_TERM_IDX_EXCEED_MAX;
559 }559 }
560 560 WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx);
561 pRefPic->uiLongRefCount[LIST_0]++;561 if (pRefPic->uiLongRefCount[LIST_0] + pRefPic->uiShortRefCount[LIST_0] >= WELS_MAX (1, pCtx->pSps->iNumRefFrames)) {
562 return ERR_NONE;562 return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW;
563}563 }
564 564#ifdef LONG_TERM_REF
565static int32_t MarkAsLongTerm (PRefPic pRefPic, int32_t iFrameNum, int32_t iLongTermFrameIdx) {565 pCtx->bCurAuContainLtrMarkSeFlag = true;
566 PPicture pPic = NULL;566 pCtx->iFrameNumOfAuMarkedLtr = pCtx->iFrameNum;
567 int32_t i = 0;567 WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "ex_mark_avc():::MMCO_LONG:::LTR marking....iFrameNum: %d",
568 int32_t iRet = ERR_NONE;568 pCtx->iFrameNum);
569 WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx);569#endif
570 570 iRet = AddLongTermToList (pRefPic, pCtx->pDec, iLongTermFrameIdx);
571 for (i = 0; i < pRefPic->uiRefCount[LIST_0]; i++) {571 break;
572 pPic = pRefPic->pRefList[LIST_0][i];572 default :
573 if (pPic->iFrameNum == iFrameNum && !pPic->bIsLongRef) {573 break;
574 iRet = AddLongTermToList (pRefPic, pPic, iLongTermFrameIdx);574 }
575 break;575
576 }576 return iRet;
577 }577}
578 578
579 return iRet;579static int32_t SlidingWindow (PWelsDecoderContext pCtx) {
580}580 PRefPic pRefPic = &pCtx->sRefPic;
581 581 PPicture pPic = NULL;
582#ifdef LONG_TERM_REF582 int32_t i = 0;
583int32_t GetLTRFrameIndex (PRefPic pRefPic, int32_t iAncLTRFrameNum) {583
584 int32_t iLTRFrameIndex = -1;584 if (pCtx->sRefPic.uiShortRefCount[LIST_0] + pCtx->sRefPic.uiLongRefCount[LIST_0] >= pCtx->pSps->iNumRefFrames) {
585 PPicture pPic;585 if (pCtx->sRefPic.uiShortRefCount[LIST_0] == 0) {
586 for (int i = 0; i < pRefPic->uiLongRefCount[0]; ++i) {586 WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "No reference picture in short term list when sliding window");
587 pPic = pRefPic->pLongRefList[LIST_0][i];587 return ERR_INFO_INVALID_MMCO_REF_NUM_NOT_ENOUGH;
588 if (pPic->iFrameNum == iAncLTRFrameNum) {588 }
589 return (pPic->iLongTermFrameIdx);589 for (i = pRefPic->uiShortRefCount[LIST_0] - 1; i >= 0; i--) {
590 }590 pPic = WelsDelShortFromList (pRefPic, pRefPic->pShortRefList[LIST_0][i]->iFrameNum);
591 }591 if (pPic) {
592 return iLTRFrameIndex;592 SetUnRef (pPic);
593}593 break;
594#endif594 } else {
595 595 return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW;
596static int32_t RemainOneBufferInDpbForEC (PWelsDecoderContext pCtx) {596 }
597 int32_t iRet = ERR_NONE;597 }
598 PRefPic pRefPic = &pCtx->sRefPic;598 }
599 if (pRefPic->uiShortRefCount[0] + pRefPic->uiLongRefCount[0] < pCtx->pSps->iNumRefFrames)599 return ERR_NONE;
600 return iRet;600}
601 601
602 if (pRefPic->uiShortRefCount[0] > 0) {602static PPicture WelsDelShortFromList (PRefPic pRefPic, int32_t iFrameNum) {
603 iRet = SlidingWindow (pCtx);603 int32_t i = 0;
604 } else { //all LTR, remove the smallest long_term_frame_idx604 int32_t iMoveSize = 0;
605 int32_t iLongTermFrameIdx = 0;605 PPicture pPic = NULL;
606 int32_t iMaxLongTermFrameIdx = pRefPic->iMaxLongTermFrameIdx;606
607#ifdef LONG_TERM_REF607 for (i = 0; i < pRefPic->uiShortRefCount[LIST_0]; i++) {
608 int32_t iCurrLTRFrameIdx = GetLTRFrameIndex (pRefPic, pCtx->iFrameNumOfAuMarkedLtr);608 if (pRefPic->pShortRefList[LIST_0][i]->iFrameNum == iFrameNum) {
609#endif609 iMoveSize = pRefPic->uiShortRefCount[LIST_0] - i - 1;
610 while ((pRefPic->uiLongRefCount[0] >= pCtx->pSps->iNumRefFrames) && (iLongTermFrameIdx <= iMaxLongTermFrameIdx)) {610 pRefPic->pShortRefList[LIST_0][i]->bUsedAsRef = false;
611#ifdef LONG_TERM_REF611 pPic = pRefPic->pShortRefList[LIST_0][i];
612 if (iLongTermFrameIdx == iCurrLTRFrameIdx) {612 pRefPic->pShortRefList[LIST_0][i] = NULL;
613 iLongTermFrameIdx++;613 if (iMoveSize > 0) {
614 continue;614 memmove (&pRefPic->pShortRefList[LIST_0][i], &pRefPic->pShortRefList[LIST_0][i + 1],
615 }615 iMoveSize * sizeof (PPicture)); //confirmed_safe_unsafe_usage
616#endif616 }
617 WelsDelLongFromListSetUnref (pRefPic, iLongTermFrameIdx);617 pRefPic->uiShortRefCount[LIST_0]--;
618 iLongTermFrameIdx++;618 pRefPic->pShortRefList[LIST_0][pRefPic->uiShortRefCount[LIST_0]] = NULL;
619 }619 break;
620 }620 }
621 if (pRefPic->uiShortRefCount[0] + pRefPic->uiLongRefCount[0] >=621 }
622 pCtx->pSps->iNumRefFrames) { //fail to remain one empty buffer in DPB622
623 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "RemainOneBufferInDpbForEC(): empty one DPB failed for EC!");623 return pPic;
624 iRet = ERR_INFO_REF_COUNT_OVERFLOW;624}
625 }625
626 626static PPicture WelsDelShortFromListSetUnref (PRefPic pRefPic, int32_t iFrameNum) {
627 return iRet;627 PPicture pPic = WelsDelShortFromList (pRefPic, iFrameNum);
628}628 if (pPic) {
629 629 SetUnRef (pPic);
630} // namespace WelsDec630 }
631 return pPic;
632}
633
634static 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
655static 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
663static 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
685static 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
708static 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
726int32_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
739static 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