📄 dpb.c
字号:
/*COPYRIGHT, LICENSE AND WARRANTY INFORMATIONThis software module has been originally developed by Nokia Corporation. Provided that a person, entity or a company willing to use the Software (hereinafter Licensee) comply with all the terms and conditions of this Statement and subject to the limitations set forth in this Statement Nokia grants to such Licensee a non-exclusive, sub-licensable, worldwide, limited license under copyrights owned by Nokia to use the Software for the sole purpose of creating, manufacturing, selling, marketing, or distributing (including the right to make modifications to the Software) a fully compliant decoder implementation (hereinafter "Decoder") of ITU-T Recommendation H.264 / ISO/IEC International Standard 14496-10 and an encoder implementation producing output that is decodable with the Decoder.Nokia retains the ownership of copyrights to the Software. There is no patent nor other intellectual property right of Nokia licensed under this Statement (except the copyright license above). Licensee hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if patent licenses are required, it is their responsibility to acquire the license before utilizing the Software.The license by Nokia is subject to that the Licensee grants to Nokia the non-exclusive, worldwide, royalty-free, perpetual and irrevocable covenant that the Licensee(s) shall not bring a suit before any court or administrative agency or otherwise assert a claim for infringement under the Licensee intellectual property rights that, but for a license, would be infringed by the Software against (a) Nokia or Nokia's Affiliate; or (b) other recipient of a license and covenant not to sue with respect to the Software from Nokia; or (c) contractor, customer or distributor of a party listed above in a or b, which suit or claim is related to the Software or use thereof.The Licensee(s) further agrees to grant a reciprocal license to Nokia (as granted by Nokia to the Licensee(s) on the modifications made by Licensee(s) to the Software. THE SOFTWARE IS PROVIDED "AS IS" AND THE ORIGINAL DEVELOPER DISCLAIMS ANY AND ALL WARRANTIES WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. THOSE INTENDING TO USE THE SOFTWARE ARE EXPRESSLY ADVISED THAT ITS USE MAY INFRINGE EXISTING PATENTS AND BE SUBJECT TO ROYALTY PAYMENTS TO PATENT OWNERS. ANYONE USING THE SOFTWARE ON THE BASIS OF THIS LICENSE AGREES TO OBTAIN THE NECESSARY PERMISSIONS FROM ANY AND ALL APPLICABLE PATENT OWNERS FOR SUCH USE.IN NO EVENT SHALL THE ORIGINAL DEVELOPER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.This copyright, license and warranty information notice must be retained in all copies and derivative works of the Software or substantial portions thereof.*/#include <assert.h>#include <string.h>#include <stdio.h>#include <limits.h>#include "nccglob.h"#include "debug.h"#include "RefFrame.h"#include "dpb.h"#include "frame.h"/* * dpbInitialize: * * Parameters: * dpbBuf Decoded picture buffer object * pEncPar Encoding parameter * * Function: * Initialize the decoded picture buffer. This buffer also manages the * reference frame pointers. * * Returns: * - */void dpbInitialize(dpbBuf_s *dpbBuf, encParams_s *pEncPar){ int i; dpbBuf->frameNum = 0; dpbBuf->prevRefFrameNum = 0; dpbBuf->maxFrameNum = 1 << (pEncPar->log2_max_frame_num_minus4 + 4); dpbBuf->maxNumRefFrms = pEncPar->maxNumRefFrms; dpbBuf->numRefFrms = 0; dpbBuf->actualNumRefFrms = 0; dpbBuf->numShorts = 0; dpbBuf->numLongs = 0; dpbBuf->idxOldest = 0; dpbBuf->prevPicHasMMCO5 = 0; dpbBuf->frameNumOffset = 0; dpbBuf->prevFrameNumOffset = 0; dpbBuf->ltrIdr = 0; // only support P frame, so # of frame buffers needed is equal // to the maximal # of reference frames if (dpbBuf->maxNumRefFrms > 0) { dpbBuf->refFrmArr = (refFrmBuf_s *) nccMalloc(dpbBuf->maxNumRefFrms * sizeof(refFrmBuf_s)); dpbBuf->refPicList0 = (refFrmBuf_s **) nccMalloc(dpbBuf->maxNumRefFrms * sizeof(refFrmBuf_s *)); dpbBuf->refPicListNormalOrder = (refFrmBuf_s **) nccMalloc(dpbBuf->maxNumRefFrms * sizeof(refFrmBuf_s *)); dpbBuf->reorderCmds = (reorderCommand_s *) nccMalloc((dpbBuf->maxNumRefFrms) * sizeof(reorderCommand_s)); if (dpbBuf->refFrmArr != 0) { for (i = 0; i < dpbBuf->maxNumRefFrms; i++) refFrmOpen(& dpbBuf->refFrmArr[i], pEncPar); } } // mmcoList always has at least one entry dpbBuf->mmcoList = (MMCO_s *) nccMalloc(sizeof(MMCO_s)); dpbBuf->mmcoList->mmco = 0; dpbBuf->mmcoList->next = 0;}/* * freeMMCOList * * Parameters: * mmcoList mmcoList object * * Function: * free the memory of a MMCO list * * Returns: * - */static void freeMMCOList(MMCO_s *mmcoList){ MMCO_s *next = mmcoList; while (next) { next = mmcoList->next; nccFree(mmcoList); mmcoList = next; }}/* * dpbRelease: * * Parameters: * dpbBuf Decoded picture buffer object * low_complex_prof3 Low complexity prof 3 * use_search_win Use internal search window * * Function: * Release all the internal buffers within dbpBuf. * * Returns: * - */void dpbRelease(dpbBuf_s *dpbBuf, int low_complex_prof3){ int i; // release the reference frame buffers if (dpbBuf->refFrmArr != 0) { for (i = 0; i < dpbBuf->maxNumRefFrms; i++) refFrmClose(& dpbBuf->refFrmArr[i], low_complex_prof3); nccFree(dpbBuf->refFrmArr); dpbBuf->refFrmArr = 0; } // release other buffers within dpbBuf object if (dpbBuf->refPicList0 != 0) { nccFree(dpbBuf->refPicList0); dpbBuf->refPicList0 = 0; } if (dpbBuf->refPicListNormalOrder != 0) { nccFree(dpbBuf->refPicListNormalOrder); dpbBuf->refPicListNormalOrder = 0; } if (dpbBuf->reorderCmds != 0) { nccFree(dpbBuf->reorderCmds); dpbBuf->reorderCmds = 0; } if (dpbBuf->mmcoList != 0) { freeMMCOList(dpbBuf->mmcoList); dpbBuf->mmcoList = 0; }}/* * dpbCreateMmcoEntry: * * Parameters: * mmcoEntry new mmco entry * operation mmco operation index, 0 to 6, * parameter mmco operation parameter * * Function: * Create a new MMCO entry. Buffer will be allocated if the buffer is * not available. * * Returns: * - */static void dpbCreateMmcoEntry(MMCO_s **mmcoEntry, int operation, int parameter){ if (*mmcoEntry == 0) { // create a new entry *mmcoEntry = (MMCO_s *) nccMalloc(sizeof(MMCO_s)); if (*mmcoEntry) (*mmcoEntry)->next = 0; } // in case the allocation failed if (*mmcoEntry != 0) { (*mmcoEntry)->mmco = operation; // only support mmco 6 for the time being if (operation == 6) (*mmcoEntry)->longTermFrmIdx = parameter; }}/* * dbpBeforeEncodeFrame: * * Parameters: * dpbBuf Decoded picture buffer object * nalRefIdc Indicate if the frame will be used as ref frame * idrFlag IDR frame flag * ltrCandidate This frame will be set as a long term ref frame * * Function: * Perform frameNum update and prepare MMCO list before the frame is * encoded. * * Returns: * - */void dbpBeforeEncodeFrame(dpbBuf_s *dpbBuf, int nalRefIdc, int idrFlag, int ltrCandidate){ if (idrFlag) { dpbBuf->frameNum = 0; dpbBuf->prevRefFrameNum = 0; } else { dpbBuf->frameNum = (dpbBuf->prevRefFrameNum + 1) % dpbBuf->maxFrameNum; if (nalRefIdc) dpbBuf->prevRefFrameNum = dpbBuf->frameNum; } dpbBuf->prevPicHasMMCO5 = dpbBuf->picHasMMCO5; dpbBuf->prevFrameNumOffset = dpbBuf->frameNumOffset; dpbBuf->mmcoList->mmco = 0; dpbBuf->ltrIdr = 0; if (ltrCandidate) { if (idrFlag) // handled differently dpbBuf->ltrIdr = 1; else { // this is so far the only MMCO operation we support // handled as MMCO operation dpbCreateMmcoEntry(& dpbBuf->mmcoList, 6, 0); dpbCreateMmcoEntry(& dpbBuf->mmcoList->next, 0, 0); // terminating condition } }}/* * dpbGetReorderCommands: * * Parameters: * dpbBuf Decoded picture buffer object * * Function: * Get the re-ordering command based on the comparison between the * pointers normal order and re-order pointers. * * Returns: * - */int dpbGetReorderCommands(dpbBuf_s *dpbBuf){ int numCmds; refFrmBuf_s **normal, **reorder; // find the last frame that is reordered normal = dpbBuf->refPicListNormalOrder; reorder = dpbBuf->refPicList0; numCmds = dpbBuf->numRefFrms - 1; while (numCmds >= 0) { if ((normal[numCmds] != reorder[numCmds])) break; numCmds --; } numCmds ++; if (numCmds > 0) { int i, diff; int picNumL0Pred, maxPicNum; picNumL0Pred = dpbBuf->frameNum; maxPicNum = dpbBuf->maxFrameNum; for (i = 0; i < numCmds; i ++) { diff = reorder[i]->picNum - picNumL0Pred; if (diff < 0) { dpbBuf->reorderCmds[i].idc = 0; dpbBuf->reorderCmds[i].absDiffPicNumMinus1 = - diff - 1; if (reorder[i]->picNum < 0) picNumL0Pred = reorder[i]->picNum + maxPicNum; else picNumL0Pred = reorder[i]->picNum; } else { dpbBuf->reorderCmds[i].idc = 1; dpbBuf->reorderCmds[i].absDiffPicNumMinus1 = diff - 1; if (reorder[i]->picNum >= maxPicNum) picNumL0Pred = reorder[i]->picNum - maxPicNum; else picNumL0Pred = reorder[i]->picNum; } } } return numCmds;}/* * dpbRefListNormalOrder * * Parameters: * dpbBuf Decoded/reference picture buffer * * Function: * Generate the pointers to the reference frames in the normal order * according to the reference picture numbers. * The normal order for the reference frame pointers: * Short-term ref frame pointers in descending order of picture number, * Followed by long-term reference frame pointers in ascending order. * * Returns: * - * */void dpbRefListNormalOrder(dpbBuf_s *dpbBuf){ int i, j; int numRef; refFrmBuf_s *refTmp; refFrmBuf_s **refList0; refList0 = dpbBuf->refPicListNormalOrder; // get pointers to all the frames labeled as short term ref frames numRef = 0; for (i = 0; i < dpbBuf->maxNumRefFrms; i++) { refTmp = & dpbBuf->refFrmArr[i]; if (refTmp->forRef && refTmp->isShortTerm) { refList0[numRef ++] = refTmp; // Assign the picture numbers that are easier to use refTmp->picNum = refTmp->frameNum; if (refTmp->picNum > dpbBuf->frameNum) refTmp->picNum -= dpbBuf->maxFrameNum; } } dpbBuf->numShorts = numRef; // order the pointers in descending order of picNum for short term refs
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -