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 | ||