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

📄 sequence.c

📁 Nokia H.264/AVC Encoder/Decoder Usage Manual
💻 C
📖 第 1 页 / 共 4 页
字号:
    seq->prevPocLsb      = slice->pic_order_cnt_lsb;    seq->prevPocMsb      = seq->pocMsb;  }#ifdef ERROR_CONCEALMENT  numBlks = currPic->width*currPic->height/(BLK_SIZE*BLK_SIZE);  /* clear the flags for error concealment! */  for (blkIdx = 0; blkIdx < numBlks; blkIdx++) {    seq->mbData->motVecTable[blkIdx].x = 0;    seq->mbData->motVecTable[blkIdx].y = 0;    seq->mbData->refIdxTable[blkIdx]   = -1;  }#endif  return numOutput;}/* * * generateNonExistingFrames: * * Parameters: *      seq                   Sequence object * * Function: *      Generate non-existing frame for each unused frame number between *      two closest existing frames in decoding order. Generated frames *      are stored to dpb in finishCurrentPic function. * * Returns: *       0 : no frames were output *      >0 : the number of frames output *      <0 : error */static int generateNonExistingFrames(sequence_s *seq){  slice_s *slice;  frmBuf_s *currPic;  int32 nextFrameNum;  int numOutput;  slice   = seq->currSlice;  currPic = seq->recoBuf;  slice->picHasMMCO5                        = 0;  slice->isIDR                              = 0;  slice->adaptive_ref_pic_marking_mode_flag = 0;  slice->nalType                            = NAL_TYPE_CODED_SLICE;  slice->nalRefIdc                          = 1;  currPic->forOutput   = 0;  currPic->nonExisting = 1;  do {    slice->frame_num = seq->unusedShortTermFrameNum;    dpbUpdatePicNums(seq->dpb, slice->frame_num, slice->maxFrameNum);    numOutput = finishCurrentPic(seq);    nextFrameNum = (seq->unusedShortTermFrameNum + 1) % seq->nextSlice->maxFrameNum;    if (nextFrameNum == (int)seq->nextSlice->frame_num)      seq->unusedShortTermFrameNum = -1;    else      seq->unusedShortTermFrameNum = nextFrameNum;  } while (numOutput == 0 && seq->unusedShortTermFrameNum >= 0);  return numOutput;}/* * * initializeCurrentPicture: * * Parameters: *      seq                   Sequence object *      sps                   Active sequence parameter set *      pps                   Active picture parameter set *      width                 Picture width *      height                Picture height * * Function: *      Current frame and dpb are initialized according to active *      parameter sets. * * Returns: *      SEQ_OK for no error, negative value for error */static int initializeCurrentPicture(sequence_s *seq, seq_parameter_set_s *sps,                                    pic_parameter_set_s *pps,                                    int width, int height){  frmBuf_s *currPic;  slice_s *slice;  int i;#ifdef CHECK_MV_RANGE  if (sps->level_idc <= 10)    maxVerticalMvRange = 64;  else if (sps->level_idc <= 20)    maxVerticalMvRange = 128;  else if (sps->level_idc <= 30)    maxVerticalMvRange = 256;  else    maxVerticalMvRange = 512;#endif  currPic = seq->recoBuf;  slice   = seq->currSlice;  if (slice->isIDR) {    /*     * (Re)initialize frame buffer for current picture if picture size has changed     */    if (!currPic || width != currPic->width || height != currPic->height) {      frmClose(currPic, seq->mbData);      if ((currPic = frmOpen(&seq->mbData, width, height)) == NULL)        return SEQ_ERR_MEM;      seq->recoBuf = currPic;#ifdef ERROR_CONCEALMENT      /* (Re)initialize the error concealment procedure if picture size has changed */      ercClose(seq->errConcealment);      if ((seq->errConcealment = ercOpen(width/MBK_SIZE, height/MBK_SIZE)) == NULL)        return SEQ_ERR_MEM;#endif    }  }  for (i = 0; i < MAX_SLICE_GROUP_NUM; i++)    seq->sliceNums[i] = 0;  /* Build slice group map */  buildSliceGroups(seq, slice, sps, pps);  /* By default picture will be output */  currPic->forOutput   = 1;  currPic->nonExisting = 0;  currPic->isIDR       = slice->isIDR;  if (sps->frame_cropping_flag) {    currPic->cropLeftOff   = sps->frame_crop_left_offset;    currPic->cropRightOff  = sps->frame_crop_right_offset;    currPic->cropTopOff    = sps->frame_crop_top_offset;    currPic->cropBottomOff = sps->frame_crop_bottom_offset;  }  else {    currPic->cropLeftOff   = 0;    currPic->cropRightOff  = 0;    currPic->cropTopOff    = 0;    currPic->cropBottomOff = 0;  }  if (sps->vui_parameters_present_flag &&      sps->vui_parameters.timing_info_present_flag &&      sps->vui_parameters.num_units_in_tick != 0)    currPic->frameRate = (float)(0.5 * (float)sps->vui_parameters.time_scale/(float)sps->vui_parameters.num_units_in_tick);  else    currPic->frameRate = 0.0;  /* Get poc for current picture */  currPic->poc = decodePictureOrderCount(seq, slice, sps);  /* Set chroma qp index offset */  currPic->chromaQpIndexOffset = pps->chroma_qp_index_offset;#ifdef ERROR_CONCEALMENT  /* By default, this is not a scene cut picture */  currPic->sceneCut = 0;#endif  return SEQ_OK;}#ifdef ERROR_CONCEALMENT/* * * setSceneCutFlag: * * Parameters: *      seq                   Sequence object * * Function: *      Tell if current picture is a scene cut picture or not. * * Returns: *      - */static void setSceneCutFlag(sequence_s *seq){  seq->errConcealment->hasSceneInfo = seq->hasSceneInfo;  /* Scene info messages are available, and there is newly decoded scene info SEI */  if (seq->hasSceneInfo && seq->sceneInfoDecoded) {    seq->sceneInfoDecoded = 0;    if (seq->prevSceneInfo->sceneId != seq->currSceneInfo->sceneId ||        seq->prevSceneInfo->sceneTransitionType != seq->currSceneInfo->sceneTransitionType )      seq->recoBuf->sceneCut = 1;  }}#endif/* * * decodeSliceData: * * Parameters: *      seq                   Sequence object * * Function: *      Decode slice data of the current slice. Before decoding slice data, *      current frame and dpb are initialized according to active *      parameter sets. * * Returns: *      SEQ_OK for no error, negative value for error */static int decodeSliceData(sequence_s *seq){  slice_s *slice;  pic_parameter_set_s *pps;  seq_parameter_set_s *sps;  int width, height;  const level_s *level;  int dpbSize;  int sliceGroupNum, sliceID;  int retCode;  /* New slice becomes current slice */  slice = seq->nextSlice;  seq->nextSlice = seq->currSlice;  seq->currSlice = slice;  /* Get current parameter sets */  pps = seq->ppsList[slice->pic_parameter_set_id];  sps = seq->spsList[pps->seq_parameter_set_id];  /* Get picture size */  width  = (sps->pic_width_in_mbs_minus1+1)*16;  height = (sps->pic_height_in_map_units_minus1+1)*16;  /* If this is the first slice of a picture, initialize picture */  if (seq->isFirstSliceOfSeq || seq->isPicBoundary) {    if (slice->isIDR) {      /*       * Set dpb according to level       */      level = getLevel(sps->level_idc);      dpbSize = level->maxDPB/((int32)width*height*3/2);      if (sps->vui_parameters_present_flag && sps->vui_parameters.bitstream_restriction_flag)        dpbSize = min((unsigned)dpbSize, sps->vui_parameters.max_dec_frame_buffering);      dpbSetSize(seq->dpb, dpbSize);      seq->dpb->maxNumRefFrames = sps->num_ref_frames;    }    retCode = initializeCurrentPicture(seq, sps, pps, width, height);    if (retCode < 0)      return retCode;#ifdef ERROR_CONCEALMENT    /* Reset error concealment */    ercClear(seq->errConcealment);    /* Set the scene cut flag if scene info SEIs are available */    setSceneCutFlag(seq);    if (seq->isFirstSliceOfSeq)      seq->errConcealment->isFirstPicOfSeq = 1;    else      seq->errConcealment->isFirstPicOfSeq = 0;    seq->errConcealment->alg = seq->ecAlg;#endif  }  /* Compute picture numbers for all reference frames */  if (!slice->isIDR)    dpbUpdatePicNums(seq->dpb, slice->frame_num, slice->maxFrameNum);  /* Get slice group number if there are more than 1 slice groups */  if (pps->num_slice_groups_minus1 == 0)    sliceGroupNum = 0;  else    sliceGroupNum = seq->mbData->sliceMap[slice->first_mb_in_slice] & 0xF;  /* Increment slice number for current slice group (slice numbers start from 1) */  seq->sliceNums[sliceGroupNum]++;  /* sliceID for current slice */  sliceID       = seq->sliceNums[sliceGroupNum]*16 | sliceGroupNum;  /*   * Go decode slice data   */  retCode = sliceDecodeMacroblocks(slice, seq->recoBuf, seq->dpb,#ifdef ERROR_CONCEALMENT                                   seq->errConcealment,#endif                                   pps, seq->mbData, sliceID, seq->bitbuf);  /* Update sequence variables */  seq->isFirstSliceOfSeq        = 0;  seq->isPicBoundary            = 0;  seq->isSliceDataDecodePending = 0;  if (retCode < 0)    return SEQ_ERROR;  else    return SEQ_OK;}#ifdef ERROR_CONCEALMENT/* * * concealFrames: * * Parameters: *      seq                   Sequence object * * Function: *      Try to recover an entirely lost picture. Compared to partly *      corrupted picture, additional tasks have to be done to set *      proper flags for the lost pictures. * * Returns: *       0 : no frames were output *      >0 : the number of frames output *      <0 : error * */static int concealFrames(sequence_s *seq){  slice_s *slice;  frmBuf_s *currPic;  int nextFrameNum;  int numOutput;  pic_parameter_set_s *pps;  ercClear(seq->errConcealment);  slice   = seq->currSlice;  currPic = seq->recoBuf;  slice->picHasMMCO5                        = 0;  slice->isIDR                              = 0;  slice->adaptive_ref_pic_marking_mode_flag = 0;  slice->nalType                            = NAL_TYPE_CODED_SLICE;  slice->nalRefIdc                          = 1;  /*    * Set the currPic->forOutput to 0 for the time being. The wholly lost pictures will not    * be outputted by the video decoder.   */  currPic->forOutput   = 0;  currPic->nonExisting = 1;  pps = seq->ppsList[slice->pic_parameter_set_id];  do {    slice->frame_num = seq->unusedShortTermFrameNum;    deb1f(stderr, "Concealing frame num: %d\n", slice->frame_num);    currPic->poc = 0;    dpbUpdatePicNums(seq->dpb, slice->frame_num, slice->maxFrameNum);    ercConcealWholePic(seq->errConcealment, seq->recoBuf, seq->mbData, seq->dpb);    numOutput = finishCurrentPic(seq);    nextFrameNum = (seq->unusedShortTermFrameNum + 1) % seq->nextSlice->maxFrameNum;    if (nextFrameNum == (int)seq->nextSlice->frame_num)      seq->unusedShortTermFrameNum = -1;    else      seq->unusedShortTermFrameNum = nextFrameNum;  } while (numOutput == 0 && seq->unusedShortTermFrameNum >= 0);  return numOutput;}#endif/* * * decodeSlice: * * Parameters: *      seq                   Sequence object *      nalType               Type of nal unit *      nalRefIdc             Nal unit reference indicator * * Function: *      Start decoding slice. Decode slice header and also *      decode slice data if picture boundary is not detected. If  *      picture boundary is detected, current picture is finished and an *      attempt is made to store it in the dpb. Possible gap *      in frame numbers is detected and handled (by generating *      non-existing frames). * * Returns: *      SEQ_OK for ok, negative value for error */static int decodeSlice(sequence_s *seq, int nalType, int nalRefIdc){  slice_s *slice;  int32 nextFrameNum;  int numOutput;  int retCode;#ifndef DECODE_ACCESS_UNITS  pic_parameter_set_s *pps;#endif  slice = seq->nextSlice;  slice->nalType   = nalType;  slice->nalRefIdc = nalRefIdc;  slice->isIDR     = (nalType == NAL_TYPE_CODED_SLICE_IDR);  retCode = sliceGetHeader(slice, seq->spsList, seq->ppsList,                           seq->bitbuf);  if (retCode < 0)    return SEQ_ERROR;  /* Check if next slice belongs to next picture */  if (seq->isFirstSliceOfSeq)    seq->isPicBoundary = 0;  else    seq->isPicBoundary = isPicBoundary(seq);  if (!seq->isPicBoundary) {    /* There is no picture boundary -> Decode new slice */    return decodeSliceData(seq);  }  else {    /* Picture boundary reached. */#ifndef DECODE_ACCESS_UNITS    pps = seq->ppsList[slice->pic_parameter_set_id];#ifdef ERROR_CONCEALMENT    ercCheckAndConceal(seq->errConcealment, seq->recoBuf, seq->mbData, seq->dpb, pps);#endif    /* Finish decoding of current picture */    numOutput = finishCurrentPic(seq);    /* numOutput is the number of pictures in output queue */    /* If numOutput < 0, error occured */    if (numOutput < 0)      return numOutput;#else    numOutput = 0;#endif    /* Compute expected next frame number */    nextFrameNum = (seq->prevRefFrameNum + 1) % slice->maxFrameNum;    /* Check if there is a gap in frame numbers */    if (!slice->isIDR &&        (int)slice->frame_num != seq->prevRefFrameNum &&        (int)slice->frame_num != nextFrameNum)    {#ifdef ERROR_CONCEALMENT      /* Check if gaps in frame numbers are allowed */      if (!seq->spsList[seq->ppsList[slice->pic_parameter_set_id]->seq_parameter_set_id]->gaps_in_frame_num_value_allowed_flag)      {        /*         * Start concealing the lost pictures         */        deb1f(stderr, "Lost before frame num: %d\n", slice->frame_num);

⌨️ 快捷键说明

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