⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dpb.c

📁 This document aims to provide instructions on how to configure the H.264/AVC encoder and decoder usi
💻 C
📖 第 1 页 / 共 2 页
字号:
  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 + -