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

📄 slice.c

📁 Nokia H.264/AVC Encoder/Decoder Usage Manual
💻 C
📖 第 1 页 / 共 2 页
字号:
        }        else if (reordering_of_pic_nums_idc == 2) {          /* longTermPicNum be in the range of 0 to num_ref_frames, inclusive. */          if ((retCode = ue_v(bitbuf, &slice->reorderCmdList[i].long_term_pic_num, numRefFrames)) < 0)            return retCode;        }        i++;      } while (reordering_of_pic_nums_idc != 3 && i < MAX_NUM_OF_REORDER_CMDS);    }  }  return SLICE_OK;}/* * getDecRefPicMarkingCmds: * * Parameters: *     slice               Slice object *     bitbuf              Bitbuffer object *     numRefFrames        Number of reference frames in used * * Function: *     Parse and store the MMCO commands * * Return: *     The number of bits being parsed */static int getDecRefPicMarkingCmds(slice_s *slice, unsigned int numRefFrames,                                   bitbuffer_s *bitbuf){  int i;  unsigned int mmco;  int retCode;  /* MMCO commands can exist only in slice header of a reference picture */  if (slice->nalRefIdc != 0) {    if (slice->isIDR) {      if ((retCode = u_n(bitbuf, 1, &slice->no_output_of_prior_pics_flag)) < 0)        return retCode;      if ((retCode = u_n(bitbuf, 1, &slice->long_term_reference_flag)) < 0)        return retCode;    }    else {      if ((retCode = u_n(bitbuf, 1, &slice->adaptive_ref_pic_marking_mode_flag)) < 0)        return retCode;      if (slice->adaptive_ref_pic_marking_mode_flag) {        i = 0;        do {          /* Get MMCO command */          if ((retCode = ue_v(bitbuf, &mmco, 6)) < 0)            return retCode;          slice->mmcoCmdList[i].memory_management_control_operation = mmco;          /* Get command parameter (if any) */          if (mmco == 1 || mmco == 3) {            if ((retCode = ue_v(bitbuf, &slice->mmcoCmdList[i].difference_of_pic_nums_minus1, 65535)) < 0)              return retCode;          }          if (mmco == 2) {            if ((retCode = ue_v(bitbuf, &slice->mmcoCmdList[i].long_term_pic_num, numRefFrames)) < 0)              return retCode;          }          if (mmco == 3 || mmco == 6) {            if ((retCode = ue_v(bitbuf, &slice->mmcoCmdList[i].long_term_frame_idx, numRefFrames)) < 0)              return retCode;          }          if (mmco == 4) {            if ((retCode = ue_v(bitbuf, &slice->mmcoCmdList[i].max_long_term_frame_idx_plus1, numRefFrames)) < 0)              return retCode;          }          if (mmco == 5) {            slice->picHasMMCO5 = 1;          }          i++;        } while (mmco != 0 && i < MAX_NUM_OF_MMCO_OPS);      }    }  }  else    slice->adaptive_ref_pic_marking_mode_flag = 0;  return NCC_OK;}/* * sliceInitRefPicList: * * Parameters: *     dpb                  DPB buffer *     refPicList           Reference picture list (output) *     numRefPicActive      Number of active reference frames * * Fucntion: *     Initialize reference picture list. * * Return: *     SLICE_OK for no error and negative value for error. */int sliceInitRefPicList(dpb_s *dpb, frmBuf_s *refPicList[],                        int numRefPicActive){  int numRef, numShort;  frmBuf_s *refTmp;  int i, j;  /*   * Select the reference pictures from the DPB   */  j = 0;  /* Put short term pictures first in the list */  for (i = 0; i < dpb->fullness; i++) {    if (dpb->buffers[i]->refType == FRM_SHORT_TERM_PIC)       refPicList[j++] = dpb->buffers[i];  }  numShort = j;  /* Put long term pictures after the short term pictures */  for (i = 0; i < dpb->fullness; i++) {    if (dpb->buffers[i]->refType == FRM_LONG_TERM_PIC)       refPicList[j++] = dpb->buffers[i];  }  numRef = j;  /* numLong = numRef - numShort; */  if (numRef < numRefPicActive)    return SLICE_ERR_ILLEGAL_VALUE;  /*   * Initialisation process for reference picture lists   */  /* Sort short term pictures in the order of descending picNum */  for (i = 0; i < numShort; i++) {    for (j = i+1; j < numShort; j++) {      if (refPicList[i]->picNum < refPicList[j]->picNum) {        /* exchange refPicList[i] and refPicList[j] */        refTmp = refPicList[i];        refPicList[i] = refPicList[j];        refPicList[j] = refTmp;      }    }  }  /* Sort long term pictures in the order of ascending longTermPicNum */  for (i = numShort; i < numRef; i++) {    for (j = i+1; j < numRef; j++) {      if (refPicList[i]->longTermPicNum > refPicList[j]->longTermPicNum) {        /* exchange refPicList[i] and refPicList[j] */        refTmp = refPicList[i];        refPicList[i] = refPicList[j];        refPicList[j] = refTmp;      }    }  }  return SLICE_OK;}/* * refPicListReordering: * * Parameters: *     slice                Current slice object *     dpb                  DPB buffer *     refPicList           Reference picture list (modified by this function) *     numRefPicActive      Number of active reference frames *     reorderCmdList       Reordering command list * * Fucntion: *     Reorder the reference picture list for current slice * * Return: *     SLICE_OK for no error and negative value for error */static int refPicListReordering(slice_s *slice, dpb_s *dpb,                                frmBuf_s *refPicList[], int numRefPicActive,                                sliceRefPicListReorderCmd_s reorderCmdList[]){  int i;  int reordering_of_pic_nums_idc, longTermPicNum;  int32 absDiffPicNum;  int refIdx;  int32 currPicNum, picNumPred, picNumNoWrap;  int32 maxPicNum, picNum;  int cmdNum;  int cIdx, nIdx;  /*   * 3. Reordering process for reference picture list   */  maxPicNum = slice->maxFrameNum;   /* for frame coding only */  currPicNum = slice->frame_num;  picNumPred = currPicNum;  refIdx = 0;  cmdNum = 0;  do {    reordering_of_pic_nums_idc = reorderCmdList[cmdNum].reordering_of_pic_nums_idc;    if (reordering_of_pic_nums_idc == 0 || reordering_of_pic_nums_idc == 1) {      /*       * reorder short-term ref pic  -subclause 8.2.4.3.1       */      absDiffPicNum = reorderCmdList[cmdNum].abs_diff_pic_num_minus1 + 1;      /* Derive picNumNoWrap */      if (reordering_of_pic_nums_idc == 0) {        if (picNumPred - absDiffPicNum < 0)          picNumNoWrap = picNumPred - absDiffPicNum + maxPicNum;        else          picNumNoWrap = picNumPred - absDiffPicNum;      }      else { /* reordering_of_pic_nums_idc == 1 */        if (picNumPred + absDiffPicNum >= maxPicNum)           picNumNoWrap = picNumPred + absDiffPicNum - maxPicNum;        else          picNumNoWrap = picNumPred + absDiffPicNum;      }      /* Derive picNum */      if (picNumNoWrap > currPicNum)        picNum = picNumNoWrap - maxPicNum;      else        picNum = picNumNoWrap;      /* Find short term picture with picture number picNum */      for (i = 0; i < dpb->fullness; i++) {        if (!dpb->buffers[i]->nonExisting &&            dpb->buffers[i]->refType == FRM_SHORT_TERM_PIC &&            dpb->buffers[i]->picNum == picNum)          break;      }      /* If picNum was not found */      if (i == dpb->fullness) {        deb1f(stderr, "The short term ref pic(%d) is not found!\n", picNum);        return SLICE_ERR_ILLEGAL_VALUE;      }      /* Shift remaining pictures later in the list */      for (cIdx = numRefPicActive; cIdx > refIdx; cIdx--)        refPicList[cIdx] = refPicList[cIdx - 1];      /* Place picture with number picNum into the index position refIdx */      refPicList[refIdx++] = dpb->buffers[i];      /* Remove duplicate of the inserted picture */      nIdx = refIdx;      for (cIdx = refIdx; cIdx <= numRefPicActive; cIdx++)        if (refPicList[cIdx]->refType == FRM_LONG_TERM_PIC || refPicList[cIdx]->picNum != picNum)          refPicList[nIdx++] = refPicList[cIdx];      picNumPred = picNumNoWrap;    }    else if (reordering_of_pic_nums_idc == 2) {      /*       * reorder long-term ref pic  -subclause 8.2.4.3.2       */      /* Get long-term picture number */      longTermPicNum = reorderCmdList[cmdNum].long_term_pic_num;      /* Find long-term picture with picture number longTermPicNum */      for (i = 0; i < dpb->fullness; i++)        if (dpb->buffers[i]->refType == FRM_LONG_TERM_PIC &&            dpb->buffers[i]->longTermPicNum == longTermPicNum)          break;      if (i == dpb->fullness) {        // something wrong !        deb1f(stderr, "The long term ref pic(%d) is not found!\n", longTermPicNum);        return SLICE_ERR_ILLEGAL_VALUE;      }      /* Shift remaining pictures later in the list */      for (cIdx = numRefPicActive; cIdx > refIdx; cIdx--)        refPicList[cIdx] = refPicList[cIdx - 1];      /* Place picture with number longTermPicNum into the index position refIdx */      refPicList[refIdx++] = dpb->buffers[i];      /* Remove duplicate of the inserted picture */      nIdx = refIdx;      for (cIdx = refIdx; cIdx <= numRefPicActive; cIdx++)        if (refPicList[cIdx]->refType == FRM_SHORT_TERM_PIC ||            refPicList[cIdx]->longTermPicNum != longTermPicNum)        {          refPicList[nIdx++] = refPicList[cIdx];        }    }    cmdNum++;  } while (reordering_of_pic_nums_idc != 3 && cmdNum < MAX_NUM_OF_REORDER_CMDS);  refPicList[numRefPicActive] = 0;  return SLICE_OK;}/* * * sliceDecodeMacroblocks: * * Parameters: *      slice                 Slice object *      recoBuf               Current frame buffer *      dpb                   Decoded picture buffer *      pEc                   Error concealment *      pps                   Picture PS *      mdData                Macroblock buffer *      sliceID               Slice ID (=sliceNum*16+sliceGroupNum) *      bitbuf                Bitbuffer object * * Function: *      Decode one slice * * Returns: *      SLICE_OK:             Success *      <0:                   Fail */int sliceDecodeMacroblocks(slice_s *slice, frmBuf_s *recoBuf, dpb_s *dpb,#ifdef ERROR_CONCEALMENT                           errorConcealment_s *pEc,#endif                           pic_parameter_set_s *pps,                           mbAttributes_s *mbData, int sliceID,                           bitbuffer_s *bitbuf){  frmBuf_s *refPicList0[DPB_MAX_SIZE+1];  macroblock_s mb;  int numRefFrames;  int mbIdxY;  int mbIdxX;  int mbksPerLine;  int mbksPerCol;  int picSizeInMbs;  int currMbAddr;  int sliceGroupNum;  void *stream;  int retCode;  /* Choose number of reference frames and build reference picture list */  numRefFrames = 0;  if (!IS_SLICE_I(slice->slice_type)) {    if (slice->num_ref_idx_active_override_flag)      numRefFrames = slice->num_ref_idx_l0_active_minus1 + 1;    else      numRefFrames = pps->num_ref_idx_l0_active_minus1 + 1;    retCode = sliceInitRefPicList(dpb, refPicList0, numRefFrames);    if (retCode < 0)      return retCode;    if (slice->ref_pic_list_reordering_flag0) {      retCode = refPicListReordering(slice, dpb, refPicList0, numRefFrames, slice->reorderCmdList);      if (retCode < 0)        return retCode;    }  }  mbksPerLine = recoBuf->width/MBK_SIZE;  mbksPerCol  = recoBuf->height/MBK_SIZE;  picSizeInMbs = mbksPerLine*mbksPerCol;  currMbAddr = slice->first_mb_in_slice;  sliceGroupNum = sliceID & 0xF;  mbIdxY = currMbAddr / mbksPerLine;  mbIdxX = currMbAddr - mbIdxY*mbksPerLine;  mbkSetInitialQP(&mb, slice->qp, pps->chroma_qp_index_offset);  stream = bitbuf;  /* Loop until all macroblocks in current slice have been decoded */  do {    /* Store slice ID for current macroblock */    mbData->sliceMap[currMbAddr] = sliceID;    /* Store loopfilter mode */    mbData->filterModeTab[currMbAddr] = (int8) slice->disable_deblocking_filter_idc;    mbData->alphaOffset[currMbAddr]   = (int8) (slice->slice_alpha_c0_offset_div2*2);    mbData->betaOffset[currMbAddr]    = (int8) (slice->slice_beta_offset_div2*2);    retCode = mbkDecode(&mb, recoBuf, refPicList0, numRefFrames,                        mbData, recoBuf->width, recoBuf->height,                        slice->slice_type, pps->constrained_intra_pred_flag,                        pps->chroma_qp_index_offset, mbIdxX, mbIdxY, stream);    if (retCode < 0)      return SLICE_ERROR;#ifdef ERROR_CONCEALMENT    ercDecodeMb(pEc, mbIdxX, mbIdxY);#endif    /* If end of slice data has been reached and there are no */    /* skipped macroblocks left, stop decoding slice.         */    if (!bibMoreRbspData(bitbuf) && mb.numSkipped <= 0)      break;    /* Find next mb address in the current slice group */    do {      /* Next mb address */      currMbAddr++;      /* If end of frame was reached, stop search */      if (currMbAddr == picSizeInMbs)        break;      /* Update mb location */      mbIdxX++;      if (mbIdxX == mbksPerLine) {        mbIdxX = 0;        mbIdxY++;      }    } while ((mbData->sliceMap[currMbAddr] & 0xF) != sliceGroupNum);    /* If end of frame was reached, stop decoding slice */  } while (currMbAddr < picSizeInMbs);  return SLICE_OK;}

⌨️ 快捷键说明

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