Showing the changes to codec/decoder/core/src/manage_dec_ref.cpp (1 of 308 files). Show all
Unified · Split
| @@ -0,0 +1,575 @@ | ||
| 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_ref_pic.cpp | |
| 33 | + * | |
| 34 | + * Abstract | |
| 35 | + * Implementation for managing reference picture | |
| 36 | + * | |
| 37 | + * History | |
| 38 | + * 07/21/2008 Created | |
| 39 | + * | |
| 40 | + *****************************************************************************/ | |
| 41 | +#include <string.h> | |
| 42 | + | |
| 43 | +#include "manage_dec_ref.h" | |
| 44 | +#include "error_code.h" | |
| 45 | +#include "utils.h" | |
| 46 | +#include "as264_common.h" // for LTR macro can be delete later | |
| 47 | + | |
| 48 | +namespace WelsDec { | |
| 49 | + | |
| 50 | +static void_t SetUnRef(PPicture pRef) | |
| 51 | +{ | |
| 52 | + if( NULL != pRef) | |
| 53 | + { | |
| 54 | + pRef->bUsedAsRef = false; | |
| 55 | + pRef->bIsLongRef = false; | |
| 56 | + pRef->iFrameNum = -1; | |
| 57 | + pRef->iFramePoc = 0; | |
| 58 | + pRef->iLongTermFrameIdx = -1; | |
| 59 | + pRef->bRefBaseFlag = 0; | |
| 60 | + pRef->uiQualityId = -1; | |
| 61 | + pRef->uiTemporalId = -1; | |
| 62 | + pRef->uiSpatialId = -1; | |
| 63 | + pRef->iSpsId = -1; | |
| 64 | + } | |
| 65 | +} | |
| 66 | + | |
| 67 | +//reset pRefList when | |
| 68 | +// 1.sps arrived that is new sequence starting | |
| 69 | +// 2.IDR NAL i.e. 1st layer in IDR AU | |
| 70 | + | |
| 71 | +void_t WelsResetRefPic(PWelsDecoderContext pCtx) | |
| 72 | +{ | |
| 73 | + int32_t i = 0; | |
| 74 | + PRefPic pRefPic = &pCtx->sRefPic; | |
| 75 | + pCtx->sRefPic.uiLongRefCount[0] = pCtx->sRefPic.uiShortRefCount[0] = 0; | |
| 76 | + | |
| 77 | + pRefPic->uiRefCount[LIST_0] = 0; | |
| 78 | + | |
| 79 | + for(i=0; i < MAX_SHORT_REF_COUNT; i++) { | |
| 80 | + if ( pRefPic->pShortRefList[LIST_0][i] != NULL){ | |
| 81 | + SetUnRef(pRefPic->pShortRefList[LIST_0][i]); | |
| 82 | + pRefPic->pShortRefList[LIST_0][i] = NULL; | |
| 83 | + } | |
| 84 | + } | |
| 85 | + pRefPic->uiShortRefCount[LIST_0] = 0; | |
| 86 | + | |
| 87 | + for(i=0; i < MAX_LONG_REF_COUNT; i++){ | |
| 88 | + if (pRefPic->pLongRefList[LIST_0][i] != NULL) { | |
| 89 | + SetUnRef(pRefPic->pLongRefList[LIST_0][i]); | |
| 90 | + pRefPic->pLongRefList[LIST_0][i] = NULL; | |
| 91 | + } | |
| 92 | + } | |
| 93 | + pRefPic->uiLongRefCount[LIST_0] = 0; | |
| 94 | +} | |
| 95 | + | |
| 96 | +/** | |
| 97 | + * fills the pRefPic.pRefList. | |
| 98 | + */ | |
| 99 | +int32_t WelsInitRefList(PWelsDecoderContext pCtx, int32_t iPoc) | |
| 100 | +{ | |
| 101 | + int32_t i,j, iCount=0; | |
| 102 | + const bool_t kbUseRefBasePicFlag = pCtx->pCurDqLayer->bUseRefBasePicFlag; | |
| 103 | + PPicture* ppShoreRefList = pCtx->sRefPic.pShortRefList[LIST_0]; | |
| 104 | + PPicture* ppLongRefList = pCtx->sRefPic.pLongRefList[LIST_0]; | |
| 105 | + memset(pCtx->sRefPic.pRefList[LIST_0],0,MAX_REF_PIC_COUNT*sizeof(PPicture)); | |
| 106 | + //short | |
| 107 | + for(i=0; i<pCtx->sRefPic.uiShortRefCount[LIST_0]; ++i){ | |
| 108 | + if( kbUseRefBasePicFlag == ppShoreRefList[i]->bRefBaseFlag ) { | |
| 109 | + pCtx->sRefPic.pRefList[LIST_0][iCount++ ]= ppShoreRefList[i]; | |
| 110 | + }else{ | |
| 111 | + for ( j = 0;j<pCtx->sRefPic.uiShortRefCount[LIST_0];++j) | |
| 112 | + { | |
| 113 | + if (ppShoreRefList[j]->iFrameNum == ppShoreRefList[i]->iFrameNum && ppShoreRefList[j]->bRefBaseFlag == kbUseRefBasePicFlag) | |
| 114 | + { | |
| 115 | + break; | |
| 116 | + } | |
| 117 | + } | |
| 118 | + if (j == pCtx->sRefPic.uiShortRefCount[LIST_0]) | |
| 119 | + { | |
| 120 | + pCtx->sRefPic.pRefList[LIST_0][iCount++] = ppShoreRefList[i]; | |
| 121 | + } | |
| 122 | + } | |
| 123 | + } | |
| 124 | + | |
| 125 | + //long | |
| 126 | + j = 0; | |
| 127 | + for(i=0; i< pCtx->sRefPic.uiLongRefCount[LIST_0] ; ++i){ | |
| 128 | + if(kbUseRefBasePicFlag == ppLongRefList[i]->bRefBaseFlag){ | |
| 129 | + pCtx->sRefPic.pRefList[LIST_0][iCount++ ]= ppLongRefList[i]; | |
| 130 | + }else{ | |
| 131 | + for ( j = 0;j<pCtx->sRefPic.uiLongRefCount[LIST_0];++j) | |
| 132 | + { | |
| 133 | + if (ppLongRefList[j]->iLongTermFrameIdx == ppLongRefList[i]->iLongTermFrameIdx && ppLongRefList[j]->bRefBaseFlag == kbUseRefBasePicFlag) | |
| 134 | + { | |
| 135 | + break; | |
| 136 | + } | |
| 137 | + } | |
| 138 | + if (j == pCtx->sRefPic.uiLongRefCount[LIST_0]) | |
| 139 | + { | |
| 140 | + pCtx->sRefPic.pRefList[LIST_0][iCount++] = ppLongRefList[i]; | |
| 141 | + } | |
| 142 | + } | |
| 143 | + } | |
| 144 | + pCtx->sRefPic.uiRefCount[LIST_0] = iCount; | |
| 145 | + | |
| 146 | + return ERR_NONE; | |
| 147 | +} | |
| 148 | + | |
| 149 | +int32_t WelsReorderRefList(PWelsDecoderContext pCtx) | |
| 150 | +{ | |
| 151 | + PRefPicListReorderSyn pRefPicListReorderSyn = pCtx->pCurDqLayer->pRefPicListReordering; | |
| 152 | + PNalUnitHeaderExt pNalHeaderExt = &pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt; | |
| 153 | + PSliceHeader pSliceHeader = &pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader; | |
| 154 | + PPicture pPic = NULL; | |
| 155 | + PPicture* ppRefList = pCtx->sRefPic.pRefList[LIST_0]; | |
| 156 | + int32_t iRefCount = pCtx->sRefPic.uiRefCount[LIST_0]; | |
| 157 | + int32_t iPredFrameNum = pSliceHeader->iFrameNum; | |
| 158 | + int32_t iMaxPicNum = 1<<pSliceHeader->pSps->uiLog2MaxFrameNum; | |
| 159 | + int32_t iAbsDiffPicNum = -1; | |
| 160 | + int32_t iReorderingIndex = 0; | |
| 161 | + int32_t i = 0; | |
| 162 | + | |
| 163 | + if(pCtx->eSliceType == I_SLICE || pCtx->eSliceType == SI_SLICE) { | |
| 164 | + return ERR_NONE; | |
| 165 | + } | |
| 166 | + | |
| 167 | + if ( iRefCount <= 0 ) | |
| 168 | + { | |
| 169 | + pCtx->iErrorCode = dsNoParamSets; //No any reference for decoding, SHOULD request IDR | |
| 170 | + return ERR_INFO_REFERENCE_PIC_LOST; | |
| 171 | + } | |
| 172 | + | |
| 173 | + if (pRefPicListReorderSyn->bRefPicListReorderingFlag[LIST_0]){ | |
| 174 | + while (pRefPicListReorderSyn->sReorderingSyn[LIST_0][iReorderingIndex].uiReorderingOfPicNumsIdc != 3) | |
| 175 | + { | |
| 176 | + uint16_t uiReorderingOfPicNumsIdc = pRefPicListReorderSyn->sReorderingSyn[LIST_0][iReorderingIndex].uiReorderingOfPicNumsIdc; | |
| 177 | + if (uiReorderingOfPicNumsIdc <2){ | |
| 178 | + iAbsDiffPicNum = pRefPicListReorderSyn->sReorderingSyn[LIST_0][iReorderingIndex].uiAbsDiffPicNumMinus1 + 1; | |
| 179 | + | |
| 180 | + if (uiReorderingOfPicNumsIdc == 0){ | |
| 181 | + iPredFrameNum -= iAbsDiffPicNum; | |
| 182 | + }else{ | |
| 183 | + iPredFrameNum += iAbsDiffPicNum; | |
| 184 | + } | |
| 185 | + iPredFrameNum &= iMaxPicNum-1; | |
| 186 | + | |
| 187 | + for( i= iRefCount-1; i>=iReorderingIndex; i--){ | |
| 188 | + if (ppRefList[i]->iFrameNum == iPredFrameNum && !ppRefList[i]->bIsLongRef) | |
| 189 | + { | |
| 190 | + if( ( pNalHeaderExt->uiQualityId == ppRefList[i]->uiQualityId ) && ( pSliceHeader->iSpsId != ppRefList[i]->iSpsId ) )//check; | |
| 191 | + { | |
| 192 | + WelsLog( pCtx, WELS_LOG_WARNING, "WelsReorderRefList()::::BASE LAYER::::iSpsId:%d, ref_sps_id:%d\n",pSliceHeader->iSpsId, ppRefList[i]->iSpsId ); | |
| 193 | + pCtx->iErrorCode = dsNoParamSets; //cross-IDR reference frame selection, SHOULD request IDR.-- | |
| 194 | + return ERR_INFO_REFERENCE_PIC_LOST; | |
| 195 | + }else{ | |
| 196 | + break; | |
| 197 | + } | |
| 198 | + } | |
| 199 | + } | |
| 200 | + | |
| 201 | + }else if (uiReorderingOfPicNumsIdc == 2){ | |
| 202 | + for( i = iRefCount -1; i>=iReorderingIndex; i--){ | |
| 203 | + if( ppRefList[i]->bIsLongRef && ppRefList[i]->iLongTermFrameIdx == pRefPicListReorderSyn->sReorderingSyn[LIST_0][iReorderingIndex].uiLongTermPicNum ) | |
| 204 | + { | |
| 205 | + if ( ( pNalHeaderExt->uiQualityId == ppRefList[i]->uiQualityId ) && ( pSliceHeader->iSpsId != ppRefList[i]->iSpsId ) )//check; | |
| 206 | + { | |
| 207 | + WelsLog( pCtx, WELS_LOG_WARNING, "WelsReorderRefList()::::BASE LAYER::::iSpsId:%d, ref_sps_id:%d\n",pSliceHeader->iSpsId, ppRefList[i]->iSpsId ); | |
| 208 | + pCtx->iErrorCode = dsNoParamSets; //cross-IDR reference frame selection, SHOULD request IDR.-- | |
| 209 | + return ERR_INFO_REFERENCE_PIC_LOST; | |
| 210 | + }else{ | |
| 211 | + break; | |
| 212 | + } | |
| 213 | + } | |
| 214 | + } | |
| 215 | + } | |
| 216 | + if (i < 0) { | |
| 217 | + return ERR_INFO_REFERENCE_PIC_LOST; | |
| 218 | + } | |
| 219 | + pPic = ppRefList[i]; | |
| 220 | + memmove(&ppRefList[1+iReorderingIndex], &ppRefList[iReorderingIndex], (i-iReorderingIndex)*sizeof(PPicture));//confirmed_safe_unsafe_usage | |
| 221 | + ppRefList[iReorderingIndex]= pPic; | |
| 222 | + iReorderingIndex++; | |
| 223 | + } | |
| 224 | + } | |
| 225 | + return ERR_NONE; | |
| 226 | +} | |
| 227 | + | |
| 228 | +int32_t WelsMarkAsRef(PWelsDecoderContext pCtx, const bool_t kbRefBaseMarkingFlag) | |
| 229 | +{ | |
| 230 | + PRefPic pRefPic = &pCtx->sRefPic; | |
| 231 | + PRefPicMarking pRefPicMarking = pCtx->pCurDqLayer->pRefPicMarking; | |
| 232 | + PRefBasePicMarking pRefPicBaseMarking =pCtx->pCurDqLayer->pRefPicBaseMarking; | |
| 233 | + PAccessUnit pCurAU = pCtx->pAccessUnitList; | |
| 234 | + bool_t bIsIDRAU = FALSE; | |
| 235 | + uint32_t j; | |
| 236 | + | |
| 237 | + int32_t iRet = ERR_NONE; | |
| 238 | + if(pCtx->pCurDqLayer->bStoreRefBasePicFlag && (pCtx->pSps->iNumRefFrames<2)){ | |
| 239 | + return ERR_INFO_INVALID_MMCO_REF_NUM_NOT_ENOUGH; | |
| 240 | + } | |
| 241 | + | |
| 242 | + pCtx->pDec->bUsedAsRef = TRUE; | |
| 243 | + pCtx->pDec->uiQualityId = pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.uiQualityId; | |
| 244 | + pCtx->pDec->uiTemporalId = pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.uiTemporalId; | |
| 245 | + pCtx->pDec->bRefBaseFlag = kbRefBaseMarkingFlag; | |
| 246 | + | |
| 247 | + for( j = pCurAU->uiStartPos; j <= pCurAU->uiEndPos; j++ ) { | |
| 248 | + if (pCurAU->pNalUnitsList[j]->sNalHeaderExt.sNalUnitHeader.eNalUnitType== NAL_UNIT_CODED_SLICE_IDR|| pCurAU->pNalUnitsList[j]->sNalHeaderExt.bIdrFlag) { | |
| 249 | + bIsIDRAU = TRUE; | |
| 250 | + break; | |
| 251 | + } | |
| 252 | + } | |
| 253 | + if(bIsIDRAU){ | |
| 254 | + if (pRefPicMarking->bLongTermRefFlag){ | |
| 255 | + pCtx->sRefPic.iMaxLongTermFrameIdx = 0; | |
| 256 | + AddLongTermToList(pRefPic,pCtx->pDec,0); | |
| 257 | + }else{ | |
| 258 | + pCtx->sRefPic.iMaxLongTermFrameIdx = -1; | |
| 259 | + } | |
| 260 | + }else{ | |
| 261 | + if (pRefPicBaseMarking->bAdaptiveRefBasePicMarkingModeFlag){ | |
| 262 | + iRet = MMCOBase(pCtx,pRefPicBaseMarking); | |
| 263 | + } | |
| 264 | + | |
| 265 | + if (iRet != ERR_NONE){ | |
| 266 | + return iRet; | |
| 267 | + } | |
| 268 | + | |
| 269 | + if (pRefPicMarking->bAdaptiveRefPicMarkingModeFlag){ | |
| 270 | + iRet = MMCO(pCtx,pRefPicMarking); | |
| 271 | + if( pCtx->bLastHasMmco5 ) | |
| 272 | + { | |
| 273 | + pCtx->pDec->iFrameNum = 0; | |
| 274 | + pCtx->pDec->iFramePoc = 0; | |
| 275 | + } | |
| 276 | + if (pRefPic->uiLongRefCount[LIST_0]+pRefPic->uiShortRefCount[LIST_0] > pCtx->pSps->iNumRefFrames){ | |
| 277 | + return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW; | |
| 278 | + } | |
| 279 | + }else{ | |
| 280 | + iRet = SlidingWindow(pCtx); | |
| 281 | + } | |
| 282 | + } | |
| 283 | + | |
| 284 | + if (!pCtx->pDec->bIsLongRef){ | |
| 285 | + AddShortTermToList(pRefPic,pCtx->pDec); | |
| 286 | + } | |
| 287 | + | |
| 288 | + return iRet; | |
| 289 | +} | |
| 290 | + | |
| 291 | +static int32_t MMCOBase(PWelsDecoderContext pCtx,PRefBasePicMarking pRefPicBaseMarking) | |
| 292 | +{ | |
| 293 | + PSps pSps = pCtx->pCurDqLayer->sLayerInfo.pSps; | |
| 294 | + int32_t i = 0; | |
| 295 | + int32_t iRet = ERR_NONE; | |
| 296 | + | |
| 297 | + for ( i = 0 ; pRefPicBaseMarking->mmco_base[i].uiMmcoType != MMCO_END; i++){ | |
| 298 | + uint32_t uiMmcoType = pRefPicBaseMarking->mmco_base[i].uiMmcoType; | |
| 299 | + int32_t iShortFrameNum = (pCtx->iFrameNum - pRefPicBaseMarking->mmco_base[i].uiDiffOfPicNums) &((1<<pSps->uiLog2MaxFrameNum)-1); | |
| 300 | + uint32_t uiLongTermPicNum = pRefPicBaseMarking->mmco_base[i].uiLongTermPicNum; | |
| 301 | + if ( uiMmcoType > MMCO_LONG2UNUSED) { | |
| 302 | + return ERR_INFO_INVALID_MMCO_OPCODE_BASE; | |
| 303 | + } | |
| 304 | + iRet = MMCOProcess(pCtx,uiMmcoType,TRUE,iShortFrameNum,uiLongTermPicNum,0,0); | |
| 305 | + | |
| 306 | + if (iRet != ERR_NONE){ | |
| 307 | + return iRet; | |
| 308 | + } | |
| 309 | + } | |
| 310 | + | |
| 311 | + return ERR_NONE; | |
| 312 | +} | |
| 313 | + | |
| 314 | +static int32_t MMCO(PWelsDecoderContext pCtx,PRefPicMarking pRefPicMarking) | |
| 315 | +{ | |
| 316 | + PSps pSps = pCtx->pCurDqLayer->sLayerInfo.pSps; | |
| 317 | + int32_t i = 0; | |
| 318 | + int32_t iRet = ERR_NONE; | |
| 319 | + for ( i = 0; pRefPicMarking->sMmcoRef[i].uiMmcoType != MMCO_END; i++){ | |
| 320 | + uint32_t uiMmcoType = pRefPicMarking->sMmcoRef[i].uiMmcoType; | |
| 321 | + int32_t iShortFrameNum = (pCtx->iFrameNum - pRefPicMarking->sMmcoRef[i].iDiffOfPicNum) & ((1<<pSps->uiLog2MaxFrameNum)-1); | |
| 322 | + uint32_t uiLongTermPicNum = pRefPicMarking->sMmcoRef[i].uiLongTermPicNum; | |
| 323 | + int32_t iLongTermFrameIdx = pRefPicMarking->sMmcoRef[i].iLongTermFrameIdx; | |
| 324 | + int32_t iMaxLongTermFrameIdx = pRefPicMarking->sMmcoRef[i].iMaxLongTermFrameIdx; | |
| 325 | + if ( uiMmcoType > MMCO_LONG) { | |
| 326 | + return ERR_INFO_INVALID_MMCO_OPCODE_BASE; | |
| 327 | + } | |
| 328 | + iRet = MMCOProcess(pCtx,uiMmcoType,FALSE,iShortFrameNum,uiLongTermPicNum,iLongTermFrameIdx,iMaxLongTermFrameIdx); | |
| 329 | + if (iRet != ERR_NONE){ | |
| 330 | + return iRet; | |
| 331 | + } | |
| 332 | + } | |
| 333 | + | |
| 334 | + return ERR_NONE; | |
| 335 | +} | |
| 336 | +static int32_t MMCOProcess( PWelsDecoderContext pCtx,uint32_t uiMmcoType,bool_t bRefBasePic, | |
| 337 | + int32_t iShortFrameNum,uint32_t uiLongTermPicNum ,int32_t iLongTermFrameIdx,int32_t iMaxLongTermFrameIdx ) | |
| 338 | +{ | |
| 339 | + PRefPic pRefPic = &pCtx->sRefPic; | |
| 340 | + PPicture pPic = NULL; | |
| 341 | + int32_t i = 0; | |
| 342 | + int32_t iRet = ERR_NONE; | |
| 343 | + | |
| 344 | + switch (uiMmcoType) | |
| 345 | + { | |
| 346 | + case MMCO_SHORT2UNUSED: | |
| 347 | + pPic = WelsDelShortFromListSetUnref(pRefPic,iShortFrameNum,(ERemoveFlag) bRefBasePic); | |
| 348 | + break; | |
| 349 | + case MMCO_LONG2UNUSED: | |
| 350 | + pPic = WelsDelLongFromListSetUnref(pRefPic,uiLongTermPicNum,(ERemoveFlag) bRefBasePic); | |
| 351 | + break; | |
| 352 | + case MMCO_SHORT2LONG: | |
| 353 | + if(iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx){ | |
| 354 | + return ERR_INFO_INVALID_MMCO_LONG_TERM_IDX_EXCEED_MAX; | |
| 355 | + } | |
| 356 | + pPic = WelsDelShortFromList(pRefPic,iShortFrameNum,REMOVE_TARGET); | |
| 357 | + WelsDelLongFromListSetUnref(pRefPic,iLongTermFrameIdx,REMOVE_TARGET); | |
| 358 | + | |
| 359 | + WelsDelShortFromList(pRefPic,iShortFrameNum,REMOVE_BASE); | |
| 360 | + WelsDelLongFromListSetUnref(pRefPic,iLongTermFrameIdx,REMOVE_BASE); | |
| 361 | +#ifdef LONG_TERM_REF | |
| 362 | + pCtx->bCurAuContainLtrMarkSeFlag = true; | |
| 363 | + pCtx->iFrameNumOfAuMarkedLtr = iShortFrameNum; | |
| 364 | + WelsLog( pCtx, WELS_LOG_INFO, "ex_mark_avc():::MMCO_SHORT2LONG:::LTR marking....iFrameNum: %d\n", pCtx->iFrameNumOfAuMarkedLtr ); | |
| 365 | +#endif | |
| 366 | + | |
| 367 | + MarkAsLongTerm(pRefPic,iShortFrameNum,iLongTermFrameIdx); | |
| 368 | + break; | |
| 369 | + case MMCO_SET_MAX_LONG: | |
| 370 | + pRefPic->iMaxLongTermFrameIdx = iMaxLongTermFrameIdx; | |
| 371 | + for (i = 0 ;i <pRefPic->uiLongRefCount[LIST_0];i++) { | |
| 372 | + if (pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx) { | |
| 373 | + WelsDelLongFromListSetUnref(pRefPic,pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx,REMOVE_BASE_FIRST); | |
| 374 | + } | |
| 375 | + } | |
| 376 | + break; | |
| 377 | + case MMCO_RESET: | |
| 378 | + WelsResetRefPic(pCtx); | |
| 379 | + pCtx->bLastHasMmco5 = true; | |
| 380 | + break; | |
| 381 | + case MMCO_LONG: | |
| 382 | + if(iLongTermFrameIdx > pRefPic->iMaxLongTermFrameIdx){ | |
| 383 | + return ERR_INFO_INVALID_MMCO_LONG_TERM_IDX_EXCEED_MAX; | |
| 384 | + } | |
| 385 | +#ifdef LONG_TERM_REF | |
| 386 | + pCtx->bCurAuContainLtrMarkSeFlag = true; | |
| 387 | + pCtx->iFrameNumOfAuMarkedLtr = pCtx->iFrameNum; | |
| 388 | + WelsLog( pCtx, WELS_LOG_INFO, "ex_mark_avc():::MMCO_LONG:::LTR marking....iFrameNum: %d\n", pCtx->iFrameNum ); | |
| 389 | +#endif | |
| 390 | + WelsDelLongFromListSetUnref(pRefPic,iLongTermFrameIdx,REMOVE_TARGET); | |
| 391 | + WelsDelLongFromListSetUnref(pRefPic,iLongTermFrameIdx,REMOVE_BASE); | |
| 392 | + iRet = AddLongTermToList(pRefPic,pCtx->pDec,iLongTermFrameIdx); | |
| 393 | + break; | |
| 394 | + default : | |
| 395 | + break; | |
| 396 | + } | |
| 397 | + | |
| 398 | + return iRet; | |
| 399 | +} | |
| 400 | + | |
| 401 | +static int32_t SlidingWindow( PWelsDecoderContext pCtx ) | |
| 402 | +{ | |
| 403 | + PRefPic pRefPic = &pCtx->sRefPic; | |
| 404 | + PPicture pPic = NULL; | |
| 405 | + int32_t i = 0; | |
| 406 | + | |
| 407 | + if (pCtx->sRefPic.uiShortRefCount[LIST_0] +pCtx->sRefPic.uiLongRefCount[LIST_0] >= pCtx->pSps->iNumRefFrames){ | |
| 408 | + for ( i = pRefPic->uiShortRefCount[LIST_0] -1;i>=0;i--){ | |
| 409 | + pPic = WelsDelShortFromList(pRefPic,pRefPic->pShortRefList[LIST_0][i]->iFrameNum,REMOVE_BASE_FIRST); | |
| 410 | + if (pPic){ | |
| 411 | + SetUnRef(pPic); | |
| 412 | + break; | |
| 413 | + }else{ | |
| 414 | + return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW; | |
| 415 | + } | |
| 416 | + } | |
| 417 | + } | |
| 418 | + return ERR_NONE; | |
| 419 | +} | |
| 420 | + | |
| 421 | +static PPicture WelsDelShortFromList(PRefPic pRefPic, int32_t iFrameNum, ERemoveFlag eRemoveFlag) | |
| 422 | +{ | |
| 423 | + int32_t i = 0; | |
| 424 | + int32_t iMoveSize = 0; | |
| 425 | + PPicture pPic = NULL; | |
| 426 | + | |
| 427 | + for(i=0; i<pRefPic->uiShortRefCount[LIST_0]; i++){ | |
| 428 | + if( pRefPic->pShortRefList[LIST_0][i]->iFrameNum == iFrameNum) | |
| 429 | + { | |
| 430 | + if( ( eRemoveFlag == REMOVE_TARGET && !pRefPic->pShortRefList[LIST_0][i]->bRefBaseFlag ) | |
| 431 | + ||( eRemoveFlag == REMOVE_BASE && pRefPic->pShortRefList[LIST_0][i]->bRefBaseFlag) | |
| 432 | + ||(eRemoveFlag == REMOVE_BASE_FIRST ) ) | |
| 433 | + { | |
| 434 | + iMoveSize = pRefPic->uiShortRefCount[LIST_0] - i - 1; | |
| 435 | + pRefPic->pShortRefList[LIST_0][i]->bUsedAsRef = false; | |
| 436 | + pPic = pRefPic->pShortRefList[LIST_0][i]; | |
| 437 | + pRefPic->pShortRefList[LIST_0][i]= NULL; | |
| 438 | + if (iMoveSize > 0){ | |
| 439 | + memmove(&pRefPic->pShortRefList[LIST_0][i], &pRefPic->pShortRefList[LIST_0][i+1], iMoveSize * sizeof(PPicture));//confirmed_safe_unsafe_usage | |
| 440 | + } | |
| 441 | + pRefPic->uiShortRefCount[LIST_0]--; | |
| 442 | + pRefPic->pShortRefList[LIST_0][pRefPic->uiShortRefCount[0]] = NULL; | |
| 443 | + break; | |
| 444 | + } | |
| 445 | + } | |
| 446 | + } | |
| 447 | + | |
| 448 | + return pPic; | |
| 449 | +} | |
| 450 | + | |
| 451 | +static PPicture WelsDelShortFromListSetUnref(PRefPic pRefPic, int32_t iFrameNum, ERemoveFlag eRemoveFlag) | |
| 452 | +{ | |
| 453 | + PPicture pPic = WelsDelShortFromList(pRefPic,iFrameNum,eRemoveFlag); | |
| 454 | + if (pPic){ | |
| 455 | + SetUnRef(pPic); | |
| 456 | + } | |
| 457 | + return pPic; | |
| 458 | +} | |
| 459 | + | |
| 460 | +static PPicture WelsDelLongFromList(PRefPic pRefPic, uint32_t uiLongTermFrameIdx, ERemoveFlag eRemoveFlag) | |
| 461 | +{ | |
| 462 | + PPicture pPic = NULL; | |
| 463 | + int32_t i = 0; | |
| 464 | + for ( i = 0;i<pRefPic->uiLongRefCount[LIST_0];i++) | |
| 465 | + { | |
| 466 | + pPic = pRefPic->pLongRefList[LIST_0][i]; | |
| 467 | + if ( pPic->iLongTermFrameIdx == (int32_t)uiLongTermFrameIdx) | |
| 468 | + { | |
| 469 | + if( ((eRemoveFlag == REMOVE_TARGET) && !(pPic->bRefBaseFlag)) || ((eRemoveFlag == REMOVE_BASE) && pPic->bRefBaseFlag) ) | |
| 470 | + { | |
| 471 | + int32_t iMoveSize = pRefPic->uiLongRefCount[LIST_0] - i - 1; | |
| 472 | + pPic->bUsedAsRef = FALSE; | |
| 473 | + pPic->bIsLongRef = FALSE; | |
| 474 | + if (iMoveSize > 0){ | |
| 475 | + memmove(&pRefPic->pLongRefList[LIST_0][i], &pRefPic->pLongRefList[LIST_0][i+1], iMoveSize * sizeof(PPicture));//confirmed_safe_unsafe_usage | |
| 476 | + } | |
| 477 | + pRefPic->uiLongRefCount[LIST_0]--; | |
| 478 | + pRefPic->pLongRefList[LIST_0][pRefPic->uiLongRefCount[LIST_0]] = NULL; | |
| 479 | + return pPic; | |
| 480 | + } | |
| 481 | + } | |
| 482 | + } | |
| 483 | + return NULL; | |
| 484 | +} | |
| 485 | + | |
| 486 | +static PPicture WelsDelLongFromListSetUnref(PRefPic pRefPic, uint32_t uiLongTermFrameIdx, ERemoveFlag eRemoveFlag) | |
| 487 | +{ | |
| 488 | + PPicture pPic = WelsDelLongFromList(pRefPic,uiLongTermFrameIdx,eRemoveFlag); | |
| 489 | + if (pPic){ | |
| 490 | + SetUnRef(pPic); | |
| 491 | + } | |
| 492 | + return pPic; | |
| 493 | +} | |
| 494 | + | |
| 495 | +static int32_t AddShortTermToList(PRefPic pRefPic,PPicture pPic) | |
| 496 | +{ | |
| 497 | + pPic->bUsedAsRef = TRUE; | |
| 498 | + pPic->bIsLongRef = FALSE; | |
| 499 | + pPic->iLongTermFrameIdx = -1; | |
| 500 | + if (pRefPic->uiShortRefCount[LIST_0]>0) { | |
| 501 | + memmove(&pRefPic->pShortRefList[LIST_0][1],&pRefPic->pShortRefList[LIST_0][0],pRefPic->uiShortRefCount[LIST_0]*sizeof(PPicture));//confirmed_safe_unsafe_usage | |
| 502 | + } | |
| 503 | + pRefPic->pShortRefList[LIST_0][0] = pPic; | |
| 504 | + pRefPic->uiShortRefCount[LIST_0]++; | |
| 505 | + return ERR_NONE; | |
| 506 | +} | |
| 507 | + | |
| 508 | +static int32_t AddLongTermToList(PRefPic pRefPic,PPicture pPic, int32_t iLongTermFrameIdx) | |
| 509 | +{ | |
| 510 | + int32_t i = 0; | |
| 511 | + | |
| 512 | + pPic->bUsedAsRef = TRUE; | |
| 513 | + pPic->bIsLongRef = TRUE; | |
| 514 | + pPic->iLongTermFrameIdx = iLongTermFrameIdx; | |
| 515 | + if (pRefPic->uiLongRefCount[LIST_0] == 0){ | |
| 516 | + pRefPic->pLongRefList[LIST_0][pRefPic->uiLongRefCount[LIST_0]] = pPic; | |
| 517 | + }else if (pRefPic->uiLongRefCount[LIST_0] >0){ | |
| 518 | + for ( i = 0; i<pRefPic->uiLongRefCount[LIST_0];i++){ | |
| 519 | + if (pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx > pPic->iLongTermFrameIdx) { | |
| 520 | + break; | |
| 521 | + } | |
| 522 | + } | |
| 523 | + memmove(&pRefPic->pLongRefList[LIST_0][i+1],&pRefPic->pLongRefList[LIST_0][i],(pRefPic->uiLongRefCount[LIST_0]-i)*sizeof(PPicture));//confirmed_safe_unsafe_usage | |
| 524 | + pRefPic->pLongRefList[LIST_0][i] = pPic; | |
| 525 | + }else{ | |
| 526 | + return ERR_INFO_REF_COUNT_OVERFLOW; | |
| 527 | + } | |
| 528 | + | |
| 529 | + | |
| 530 | + pRefPic->uiLongRefCount[LIST_0]++; | |
| 531 | + return ERR_NONE; | |
| 532 | +} | |
| 533 | + | |
| 534 | +static int32_t AssignLongTermIdx(PRefPic pRefPic,int32_t iFrameNum,int32_t iLongTermFrameIdx ) | |
| 535 | +{ | |
| 536 | + PPicture pPic = NULL; | |
| 537 | + int32_t iRet = ERR_NONE; | |
| 538 | + WelsDelLongFromListSetUnref(pRefPic,iLongTermFrameIdx,REMOVE_TARGET); | |
| 539 | + WelsDelLongFromListSetUnref(pRefPic,iLongTermFrameIdx,REMOVE_BASE); | |
| 540 | + | |
| 541 | + pPic = WelsDelShortFromList(pRefPic,iFrameNum,REMOVE_TARGET); | |
| 542 | + if (pPic){ | |
| 543 | + iRet = AddLongTermToList(pRefPic,pPic,iLongTermFrameIdx); | |
| 544 | + }else{ | |
| 545 | + return ERR_INFO_INVALID_REF_MARKING; | |
| 546 | + } | |
| 547 | + | |
| 548 | + pPic = NULL; | |
| 549 | + pPic = WelsDelShortFromList(pRefPic,iFrameNum,REMOVE_BASE); | |
| 550 | + if (pPic){ | |
| 551 | + iRet = AddLongTermToList(pRefPic,pPic,iLongTermFrameIdx); | |
| 552 | + } | |
| 553 | + | |
| 554 | + return iRet; | |
| 555 | +} | |
| 556 | + | |
| 557 | +static int32_t MarkAsLongTerm( PRefPic pRefPic,int32_t iFrameNum, int32_t iLongTermFrameIdx ) | |
| 558 | +{ | |
| 559 | + PPicture pPic = NULL; | |
| 560 | + int32_t i = 0; | |
| 561 | + int32_t iRet = ERR_NONE; | |
| 562 | + WelsDelLongFromListSetUnref(pRefPic,iLongTermFrameIdx,REMOVE_TARGET); | |
| 563 | + WelsDelLongFromListSetUnref(pRefPic,iLongTermFrameIdx,REMOVE_BASE); | |
| 564 | + | |
| 565 | + for (i = 0; i<pRefPic->uiRefCount[LIST_0];i++) { | |
| 566 | + pPic = pRefPic->pRefList[LIST_0][i]; | |
| 567 | + if ( pPic->iFrameNum == iFrameNum && !pPic->bIsLongRef){ | |
| 568 | + iRet = AddLongTermToList(pRefPic,pPic,iLongTermFrameIdx); | |
| 569 | + } | |
| 570 | + } | |
| 571 | + | |
| 572 | + return iRet; | |
| 573 | +} | |
| 574 | + | |
| 575 | +} // namespace WelsDec | |