📄 dpb.c
字号:
for (i = 0; i < dpbBuf->numShorts - 1; i ++) { for (j = i + 1; j < dpbBuf->numShorts; j ++) { if (refList0[i]->picNum < refList0[j]->picNum) { // exchange refList0[i] and refList0[j] refTmp = refList0[i]; refList0[i] = refList0[j]; refList0[j] = refTmp; } } } if (dpbBuf->numShorts > 0) dpbBuf->idxOldest = (int)(refList0[dpbBuf->numShorts - 1] - dpbBuf->refFrmArr); else dpbBuf->idxOldest = 0; // get pointers to all the frames labeled as long term ref frames for (i = 0; i < dpbBuf->maxNumRefFrms; i++) { refTmp = & dpbBuf->refFrmArr[i]; if (refTmp->forRef && (! refTmp->isShortTerm)) { refList0[numRef ++] = refTmp; dpbBuf->numLongs ++; } } dpbBuf->numLongs = numRef - dpbBuf->numShorts; // order the pointers in ascending order of picNum for long term refs for (i = dpbBuf->numShorts; i < numRef - 1; i ++) { for (j = i + 1; j < numRef; j ++) { if (refList0[i]->picNum > refList0[j]->picNum) { /* exchange refList0[i] and refList0[j] */ refTmp = refList0[i]; refList0[i] = refList0[j]; refList0[j] = refTmp; } } } // set the remaining entries in the pointer array to NULL for (i = numRef; i < dpbBuf->maxNumRefFrms; i++) refList0[i] = 0; // copy the pointers from the normal order for (i = 0; i < dpbBuf->maxNumRefFrms; i ++) { dpbBuf->refPicList0[i] = refList0[i]; }}#if 0/* * dpbRefListReorder * * Parameters: * dpbBuf Decoded/reference picture buffer * * Function: * Generate the new reference order, according to the ordering weights. * The frame will the largest weight should be put in the front of the * pointer array and so on. * The pointer array refPicList0 should contain the normal order. * * Returns: * - * */void dpbRefListReorder(dpbBuf_s *dpbBuf){ int i, j; int numRefFrms; numRefFrms = dpbBuf->numRefFrms; // re-order the pointers according the normal order for (i = 0; i < numRefFrms - 1; i ++) { int minWeight, minIndex; // find the max weight in the remaining entries minWeight = INT_MAX; minIndex = i; for (j = i + 1; j < numRefFrms; j ++) { if (minWeight > dpbBuf->orderWeight[j]) { minIndex = j; minWeight = dpbBuf->orderWeight[j]; } } // exchange with the index with the max weight if (dpbBuf->orderWeight[i] > minWeight) { refFrmBuf_s *pRef; int tmpInt; pRef = dpbBuf->refPicList0[i]; dpbBuf->refPicList0[i] = dpbBuf->refPicList0[minIndex]; dpbBuf->refPicList0[minIndex] = pRef; tmpInt = dpbBuf->orderWeight[i]; dpbBuf->orderWeight[i] = dpbBuf->orderWeight[minIndex]; dpbBuf->orderWeight[minIndex] = tmpInt; } }}#endif/* * markAsUnusedForRef: * * Parameters: * dpbBuf the DPB object * picNumX the picNum of the ref picture * isShort to indicate if ref picture is short or long term * * Function: * mark a ref picture as "unused for ref" * * Returns: * - */static void markAsUnusedForRef(dpbBuf_s *dpbBuf, int picNumX, int isShort){ int i; for (i = 0; i < dpbBuf->maxNumRefFrms; i++) { refFrmBuf_s *pRefFrm; pRefFrm = & dpbBuf->refFrmArr[i]; if (pRefFrm->forRef && pRefFrm->isShortTerm == isShort && pRefFrm->picNum == picNumX) { pRefFrm->forRef = 0; pRefFrm->isShortTerm = -1; } }}/* * markAsUnusedForRef4: * * Parameters: * dpbBuf the DPB object * longTermFrmIdx the given idx threshold * * Function: * mark all the ref picture as "unused for ref", which long term frame * idx is greater than the given idx * * Returns: * - */static void markAsUnusedForRef4(dpbBuf_s *dpbBuf, int longTermFrmIdx){ int i; refFrmBuf_s *pRefFrm; for (i = 0; i < dpbBuf->maxNumRefFrms; i++) { pRefFrm = & dpbBuf->refFrmArr[i]; if (pRefFrm->forRef && pRefFrm->isShortTerm == 0 && pRefFrm->picNum >= longTermFrmIdx) { pRefFrm->forRef = 0; pRefFrm->isShortTerm = -1; } }}/* * markAsLongTermRef: * * Parameters: * dpbBuf the DPB object * picNumX which short-term picture to be marked as a long-term ref pic * longTermFrmIdx the given long-term ref pic index * * Function: * mark a short-term ref pic as a long-term ref pic * * Returns: * - */static void markAsLongTermRef(dpbBuf_s *dpbBuf, int picNumX, int longTermFrmIdx){ int i; refFrmBuf_s *pRefFrm; for (i = 0; i < dpbBuf->maxNumRefFrms; i++) { pRefFrm = & dpbBuf->refFrmArr[i]; if (pRefFrm->forRef == 1 && pRefFrm->isShortTerm == 1 && pRefFrm->picNum == picNumX) { pRefFrm->isShortTerm = 0; pRefFrm->picNum = longTermFrmIdx; return; } }}/* * dpbPicMarkingProcess: * * Parameters: * dpbBuf Decoded picture buffer object * idrFlag to indicate if current picture is an IDR picture or not * * Function: * the reference picture marking process * * Returns: * if success, the pointer to the empty frame buffer is returned * otherwise, 0 */static refFrmBuf_s *dpbPicMarkingProcess(dpbBuf_s *dpbBuf, int idrFlag){ int i; int picNumX; int isShort, longTermFrmIdx; int thisIsShort = 1, thisLongTermFrmIdx = 0; refFrmBuf_s *pRefFrm, *pEmptySlot; MMCO_s *mmcoList; /* Do reference picture marking process, subclause 8.2.5 */ if (idrFlag) { // IDR should not have any MMCO operations dpbBuf->numRefFrms = 0; for (i = 0; i < dpbBuf->maxNumRefFrms; i++) { dpbBuf->refFrmArr[i].isShortTerm = -1; dpbBuf->refFrmArr[i].forRef = 0; } if (dpbBuf->ltrIdr) { thisIsShort = 0; thisLongTermFrmIdx = 0; } } else { mmcoList = dpbBuf->mmcoList; // no MMCO operations if (mmcoList->mmco == 0) { /* 1. sliding window decoded reference picture marking process, -subclause 8.2.5.3 */ if (dpbBuf->numRefFrms == dpbBuf->maxNumRefFrms) { // we know where the oldest short-term ref is if (dpbBuf->numShorts > 0) { dpbBuf->refFrmArr[dpbBuf->idxOldest].forRef = 0; dpbBuf->refFrmArr[dpbBuf->idxOldest].isShortTerm = -1; } } } else { /* 2. MMCO -subclause 8.2.5.4 */ while ( mmcoList ) { switch (mmcoList->mmco) { case 0: // mmco == 0 tells there is no more mmco operations break; case 1: picNumX = dpbBuf->frameNum - mmcoList->diffPicNumMinus1 - 1; isShort = 1; markAsUnusedForRef(dpbBuf, picNumX, isShort); break; case 2: picNumX = mmcoList->longTermPicNum; isShort = 0; markAsUnusedForRef(dpbBuf, picNumX, isShort); break; case 3: picNumX = dpbBuf->frameNum - mmcoList->diffPicNumMinus1 - 1; longTermFrmIdx = mmcoList->longTermFrmIdx; isShort = 0; markAsUnusedForRef(dpbBuf, longTermFrmIdx, isShort); markAsLongTermRef(dpbBuf, picNumX, longTermFrmIdx); break; case 4: markAsUnusedForRef4(dpbBuf, mmcoList->maxLongTermFrmIdxPlus1); break; case 5: for (i = 0; i < dpbBuf->maxNumRefFrms; i++) { if (dpbBuf->refFrmArr[i].forRef == 1) { dpbBuf->refFrmArr[i].isShortTerm = -1; dpbBuf->refFrmArr[i].forRef = 0; } } break; case 6: // to check if the same longTermFrmIdx has been used for (i = 0; i < dpbBuf->maxNumRefFrms; i++) { pRefFrm = & dpbBuf->refFrmArr[i]; if (pRefFrm->forRef && (pRefFrm->isShortTerm == 0) && pRefFrm->frameNum == mmcoList->longTermFrmIdx) { dpbBuf->refFrmArr[i].isShortTerm = -1; dpbBuf->refFrmArr[i].forRef = 0; dpbBuf->numRefFrms--; break; } } thisIsShort = 0; thisLongTermFrmIdx = mmcoList->longTermFrmIdx; break; default: break; } mmcoList = mmcoList->next; } } } /* find the empty frame slot, set its status and return it */ pEmptySlot = 0; for (i = 0; i < dpbBuf->maxNumRefFrms; i++) { pRefFrm = & dpbBuf->refFrmArr[i]; if (pRefFrm->forOutput == 0 && pRefFrm->forRef == 0) { pRefFrm->forRef = 1; pRefFrm->isShortTerm = thisIsShort; if (thisIsShort) pRefFrm->frameNum = dpbBuf->frameNum; else pRefFrm->frameNum = thisLongTermFrmIdx; pEmptySlot = pRefFrm; break; } } if (dpbBuf->numRefFrms < dpbBuf->maxNumRefFrms) dpbBuf->numRefFrms ++; return pEmptySlot;}/* * doBumpingOutput: * the bumping process * Not done in the encoder yet. * The re-ordering of reconstructed is performed by writing a frame * directly to the desired location in the file. */void doBumpingOutput(){}/* * dpbUpdate * * Parameters: * dpbBuf Decoded picture buffer object * recoFrame Reconstructed frame * nalRefIdc Indicate if this is a reference frame * idrFlag Indicate if this is an IDR frame * low_complex_prof3 Low complexity profile 3 * use_search_win Use internal search window * reconstFrm Previous reconstructed frame, use by internal search window * * Function: * Perform update operations after the frame is encoded. * * Returns: * - */void dpbUpdate(dpbBuf_s *dpbBuf, frmBuf_s *recoFrame, int nalRefIdc, int idrFlag, int low_complex_prof3 ){ refFrmBuf_s *refBuf; /* * update reference frame buffer */ if (dpbBuf->maxNumRefFrms > 0) { doBumpingOutput(); if (nalRefIdc > 0) { /* sliding window and /or MMCO operations */ refBuf = dpbPicMarkingProcess(dpbBuf, idrFlag); /* store the reference picture into the DPB */ if (refBuf) { refFrmUpsampleLuma(refBuf, recoFrame->y, low_complex_prof3); refFrmExtendChroma(refBuf, recoFrame->u, recoFrame->v); refFrmStoreChannelDistortion(refBuf, recoFrame->channelDistortion); } } } dpbBuf->codedFrmNum ++;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -