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