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

📄 dpb.c

📁 Nokia H.264/AVC Encoder/Decoder Usage Manual
💻 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 <string.h>#include "nccglob.h"#include "globals.h"#include "debug.h"#include "framebuffer.h"#include "dpb.h"/* * * dpbOpen: * * Parameters: * * Function: *      Allocate DPB. * * Returns: *      Pointer to dpb or NULL * */dpb_s *dpbOpen(){  dpb_s *dpb;  dpb = (dpb_s *)nccMalloc(sizeof(dpb_s));  if (dpb != NULL)    memset(dpb, 0, sizeof(dpb_s));  return dpb;}/* * * dpbClose: * * Parameters: *      dpb                   DPB object * * Function: *      Deinitialize DPB. * * Returns: *      - * */void dpbClose(dpb_s *dpb){  int i;  for (i = 0; i < DPB_MAX_SIZE; i++)    frmCloseRef(dpb->buffers[i]);  nccFree(dpb);}/* * * dpbSetSize: * * Parameters: *      dpb                   DPB object *      dpbSize               New DPB size * * Function: *      Set DPB size in frames. * * Returns: *      - * */void dpbSetSize(dpb_s *dpb, int dpbSize){  dpb->size = min(dpbSize, DPB_MAX_SIZE);}/* * * dpbGetNextOutputPic: * * Parameters: *      dpb                   DPB object *      dpbHasIDRorMMCO5      Set upon return if IDR picture or picture with *                            MMCO5 command is found in DPB * * Function: *      Find next frame to output (frame with the lowest POC). *      Search is started from the last active frame in dpb and is *      stopped if all frames have been checked or IDR picture or *      picture with MMCO5 is found. * * Returns: *      Framebuffer with the lowest POC or 0 if DPB is empty * */frmBuf_s *dpbGetNextOutputPic(dpb_s *dpb, int *dpbHasIDRorMMCO5){  frmBuf_s * tmpFrm;  int i;  tmpFrm = 0;  /* Find first output pic in decoding order */  for (i = dpb->fullness-1; i >= 0; i--) {    if (dpb->buffers[i]->forOutput) {      tmpFrm = dpb->buffers[i];      break;    }  }  *dpbHasIDRorMMCO5 = 0;  /* Find picture with lowest poc. Stop search if IDR or MMCO5 is found */  for (; i >= 0; i--) {    if (dpb->buffers[i]->isIDR || dpb->buffers[i]->hasMMCO5) {      *dpbHasIDRorMMCO5 = 1;      break;    }    if (dpb->buffers[i]->forOutput && dpb->buffers[i]->poc < tmpFrm->poc)      tmpFrm = dpb->buffers[i];  }  return tmpFrm;}/* * * dpbStorePicture: * * Parameters: *      dpb                   DPB object *      currPic               Current picture *      outputQueue           Output queue * * Function: *      - Remove unused frames (non-reference, non-output frames) from the DPB. *      - If there is room in the DPB, put picture to DPB. *      - If there is no room in DPB, put pictures to output queue *        until frame is available. * * Returns: *      The number of pictures in output queue or negative value for error. * */int dpbStorePicture(dpb_s *dpb, frmBuf_s *currPic, frmBuf_s *outputQueue[]){  frmBuf_s *tmpRemList[DPB_MAX_SIZE];  frmBuf_s *tmpFrm;  int numFrm, numRemFrm;  int i;  int freeBufferFound;  int numOutput;  int dpbHasIDRorMMCO5;  /*   * Remove unused frames from dpb   */  numFrm = 0;  numRemFrm = 0;  for (i = 0; i < dpb->fullness; i++) {    if (dpb->buffers[i]->refType != FRM_NON_REF_PIC || dpb->buffers[i]->forOutput) {      dpb->buffers[numFrm] = dpb->buffers[i];      numFrm++;    }    else {      /* Put unsused pics to temporary list */      tmpRemList[numRemFrm] = dpb->buffers[i];      numRemFrm++;    }  }  /* Copy unused pics after active pics */  for (i = 0; i < numRemFrm; i++)    dpb->buffers[numFrm+i] = tmpRemList[i];  dpb->fullness = numFrm;  /*   * Try to store current pic to dpb. If there is no room in dpb, we have to   * output some pictures to make room.   */  /* Case 1: if current pic is unused, it won't be stored in dpb */  if (currPic->refType == FRM_NON_REF_PIC && !currPic->forOutput) {    return 0;  }  /* Case 2: if there is space left in dpb, store current pic */  if (dpb->fullness < dpb->size) {    tmpFrm = dpb->buffers[dpb->fullness];   /* Unused frame */    tmpFrm = frmMakeRefFrame(currPic, tmpFrm);    if (tmpFrm == NULL)      return DPB_ERR_MEM_ALLOC;    /* Move frames one position toward end of the list */    for (i = dpb->fullness; i > 0; i--)      dpb->buffers[i] = dpb->buffers[i-1];    /* Always insert new frame to the beginning of the list */    dpb->buffers[0] = tmpFrm;    dpb->fullness++;    if (currPic->refType == FRM_SHORT_TERM_PIC)      dpb->numShortTermPics++;    else if (currPic->refType == FRM_LONG_TERM_PIC)      dpb->numLongTermPics++;    /* Current picture is marked unused */    currPic->forOutput = 0;    currPic->refType   = FRM_NON_REF_PIC;    /* No pictures in ouput queue */    return 0;  }  /* Case 3: output pictures with bumping process until there is space in dpb or  *  current pic is non-reference and has lowest poc */  freeBufferFound = 0;  numOutput       = 0;  while (!freeBufferFound) {    /* Next picture to output is a picture having smallest POC in DPB */    tmpFrm = dpbGetNextOutputPic(dpb, &dpbHasIDRorMMCO5);    /* Current picture is output if it is non-reference picture having */    /* smaller POC than any of the pictures in DPB                     */    if (currPic->refType == FRM_NON_REF_PIC &&        (tmpFrm == 0 || (!dpbHasIDRorMMCO5 && currPic->poc < tmpFrm->poc)))    {      /* Output current picture  */      currPic->forOutput = 0;      outputQueue[numOutput] = currPic;      numOutput++;      freeBufferFound = 1;    }    else {      /* Output picture that we got from DPB */      tmpFrm->forOutput = 0;      outputQueue[numOutput] = tmpFrm;      numOutput++;      if (tmpFrm->refType == FRM_NON_REF_PIC)        freeBufferFound = 1;    }  }  return numOutput;}/* * * dpbUpdatePicNums: * * Parameters: *      dpb                   DPB object *      frameNum              Current picture frame number *      maxFrameNum           Maximum frame number * * Function: *      Compute picture numbers for all pictures in DPB. * * Returns: *      - * */void dpbUpdatePicNums(dpb_s *dpb, int32 frameNum, int32 maxFrameNum){  int i;  frmBuf_s **refPicList;  refPicList = dpb->buffers;  for (i = 0; i < dpb->fullness; i++) {    if (refPicList[i]->refType == FRM_SHORT_TERM_PIC) {      /* Short term pictures */      if (refPicList[i]->frameNum > frameNum)        refPicList[i]->picNum = refPicList[i]->frameNum - maxFrameNum;      else        refPicList[i]->picNum = refPicList[i]->frameNum;    }    else if (refPicList[i]->refType == FRM_LONG_TERM_PIC)      /* Long term pictures */      refPicList[i]->longTermPicNum = refPicList[i]->longTermFrmIdx;  }}/* * * dpbMarkAllPicsAsNonRef: * * Parameters: *      dpb                   DPB object * * Function: *      Mark all picrures as non-reference pictures. * * Returns: *      - * */void dpbMarkAllPicsAsNonRef(dpb_s *dpb){  int i;  /* Mark all pictures as not used for reference */  for (i = 0; i < dpb->fullness; i++)    dpb->buffers[i]->refType = FRM_NON_REF_PIC;  dpb->numShortTermPics = 0;  dpb->numLongTermPics  = 0;}/* * * dpbMarkLowestShortTermPicAsNonRef: * * Parameters: *      dpb                   DPB object * * Function: *      Mark short-term picture having lowest picture number as *      non-reference pictures. * * Returns: *      - * */void dpbMarkLowestShortTermPicAsNonRef(dpb_s *dpb){  int picIdx;  int i;  /* Find short term pic with lowest picNum */  picIdx = -1;  for (i = dpb->fullness-1; i >= 0; i--) {    if (dpb->buffers[i]->refType == FRM_SHORT_TERM_PIC &&        (picIdx < 0 || dpb->buffers[i]->picNum < dpb->buffers[picIdx]->picNum))      picIdx = i;  }  /* Mark short term pic with lowest picNum as not reference picture */  if (picIdx >= 0) {    dpb->buffers[picIdx]->refType = FRM_NON_REF_PIC;    dpb->numShortTermPics--;  }}/* * * dpbMarkShortTermPicAsNonRef: * * Parameters: *      dpb                   DPB object *      picNum                Picture number * * Function: *      Mark short-term picture having picture number picNum as *      non-reference picture. * * Returns: *      DPB_OK or DPB_ERR_PICTURE_NOT_FOUND * */int dpbMarkShortTermPicAsNonRef(dpb_s *dpb, int32 picNum){  int i;  for (i = 0; i < dpb->fullness; i++) {    if (dpb->buffers[i]->refType == FRM_SHORT_TERM_PIC &&        dpb->buffers[i]->picNum == picNum)    {      dpb->buffers[i]->refType = FRM_NON_REF_PIC;      dpb->numShortTermPics--;      return DPB_OK;    }  }  return DPB_ERR_PICTURE_NOT_FOUND;}/* * * dpbMarkLongTermPicAsNonRef: * * Parameters: *      dpb                   DPB object *      longTermPicNum        Long-term picture number * * Function: *      Mark long-term picture having long-term picture number longTermPicNum *      as non-reference picture. * * Returns: *      DPB_OK or DPB_ERR_PICTURE_NOT_FOUND * */int dpbMarkLongTermPicAsNonRef(dpb_s *dpb, int longTermPicNum){  int i;  for (i = 0; i < dpb->fullness; i++) {    if (dpb->buffers[i]->refType == FRM_LONG_TERM_PIC &&        dpb->buffers[i]->longTermPicNum == longTermPicNum)    {      dpb->buffers[i]->refType = FRM_NON_REF_PIC;      dpb->numLongTermPics--;      return DPB_OK;    }  }  return DPB_ERR_PICTURE_NOT_FOUND;}/* * * dpbVerifyLongTermFrmIdx: * * Parameters: *      dpb                   DPB object *      longTermFrmIdx        Long-term frame index * * Function: *      If there is a long-term picture having long term frame index *      longTermFrmIdx, mark that picture as non-reference picture. * * Returns: *      - * */void dpbVerifyLongTermFrmIdx(dpb_s *dpb, int longTermFrmIdx){  int i;  /* Check if longTermFrmIdx is already in use */  for (i = 0; i < dpb->fullness; i++) {    if (dpb->buffers[i]->refType == FRM_LONG_TERM_PIC &&        dpb->buffers[i]->longTermFrmIdx == longTermFrmIdx)    {      dpb->buffers[i]->refType = FRM_NON_REF_PIC;      dpb->numLongTermPics--;      break;    }  }}/* * * dpbMarkShortTermPicAsLongTerm: * * Parameters: *      dpb                   DPB object *      picNum                Picture number *      longTermFrmIdx        Long-term frame index * * Function: *      Mark short-term picture having picture number picNum as long-term *      picture having long-term frame index longTermFrmIdx. * * Returns: *      DPB_OK or DPB_ERR_PICTURE_NOT_FOUND * */int dpbMarkShortTermPicAsLongTerm(dpb_s *dpb, int32 picNum, int longTermFrmIdx){  int i;  /* To avoid duplicate of longTermFrmIdx */  dpbVerifyLongTermFrmIdx(dpb, longTermFrmIdx);  /* Mark pic with picNum as long term and assign longTermFrmIdx to it */  for (i = 0; i < dpb->fullness; i++) {    if (dpb->buffers[i]->refType == FRM_SHORT_TERM_PIC &&        dpb->buffers[i]->picNum == picNum)    {      dpb->buffers[i]->refType = FRM_LONG_TERM_PIC;      dpb->buffers[i]->longTermFrmIdx = longTermFrmIdx;      dpb->numShortTermPics--;      dpb->numLongTermPics++;      return DPB_OK;    }  }  return DPB_ERR_PICTURE_NOT_FOUND;}/* * * dpbSetMaxLongTermFrameIdx: * * Parameters: *      dpb                     DPB object *      maxLongTermFrmIdxPlus1  Maximum long-term frame index plus 1 * * Function: *      Set maximum long-term frame index. All long-term pictures having *      bigger long-term frame index than maxLongTermFrmIdxPlus1-1 are *      marked as non-reference pictures. * * Returns: *      - * */void dpbSetMaxLongTermFrameIdx(dpb_s *dpb, int maxLongTermFrmIdxPlus1){  int i;  for (i = 0; i < dpb->fullness; i++) {    if (dpb->buffers[i]->refType == FRM_LONG_TERM_PIC &&        dpb->buffers[i]->longTermFrmIdx > maxLongTermFrmIdxPlus1-1)    {      dpb->buffers[i]->refType = FRM_NON_REF_PIC;      dpb->numLongTermPics--;    }  }  dpb->maxLongTermFrameIdx = maxLongTermFrmIdxPlus1 - 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -