History

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

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

Martin Storsjö committed 8 years ago

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

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

Unified · Split

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