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

📄 encodeiff.c

📁 比较老的264解码器baseline实现
💻 C
📖 第 1 页 / 共 5 页
字号:

/*!
 ************************************************************************
 * \brief
 *      Free the memory allocated for Alternate Track Info Box
 * \return
 *      None
 ************************************************************************
 */
void freeAlternateTrackInfoBox()
{
  free(box_ati.info);
}

/*!
 ************************************************************************
 * \brief
 *      Initiate the Parameter Set Box
 *      Tian Dong, Feb 10, 2002:
 *      Only one parameter set, whose ID is set to 0, contained in the output file
 * \return
 *      0, if success
 *      -1, otherwise
 ************************************************************************
 */
int initParameterSetBox()
{
  box_ps.type.size = SIZEOF_BOXTYPE + 28;     // 26 => 27 => 28, add bufCycle, temporal scalability
  box_ps.type.type = BOX_PRMS;

  box_ps.parameterSetID = 0;
  box_ps.profile = 0;
  box_ps.level = 0;
  box_ps.version = 0;
  box_ps.pictureWidthInMBs = input->img_width / MB_BLOCK_SIZE;  
  box_ps.pictureHeightInMBs = input->img_height / MB_BLOCK_SIZE;
  box_ps.displayRectangleOffsetTop = 0;
  box_ps.displayRectangleOffsetLeft = 0;
  box_ps.displayRectangleOffsetBottom = 0;
  box_ps.displayRectangleOffsetRight = 0;
  box_ps.displayMode = 1;
  box_ps.displayRectangleOffsetFromWindowTop = 0;
  box_ps.displayRectangleOffsetFromWindowLeftBorder = 0;
  if ( input->symbol_mode == UVLC ) box_ps.entropyCoding = 0;
  else box_ps.entropyCoding = 1;
  box_ps.partitioningType = input->partition_mode;
  box_ps.intraPredictionType = input->UseConstrainedIntraPred;
  box_ps.bufCycle = input->num_reference_frames;
  if (input->NumFramesInELSubSeq!=0) box_ps.requiredPictureNumberUpdateBehavior=1;
  else box_ps.requiredPictureNumberUpdateBehavior=0;
  box_ps.loopFilterParametersFlag = input->LFSendParameters;
  return 0;
}

/*!
 ************************************************************************
 * \brief
 *      The function to write the Parameter Set Box to output file
 * \return
 *      how many bytes been written, if success
 *      -1, if failed
 * \param fp
 *      output file pointer
 ************************************************************************
 */
size_t wrParameterSetBox( FILE* fp )
{
  size_t num = 0;
  unsigned char cd;

  assert( fp != NULL );
  num += writefile( &box_ps.type.size, 4, 1, fp );
  num += writefile( &box_ps.type.type, 4, 1, fp );

  num += writefile( &box_ps.parameterSetID, 2, 1, fp );
  num += writefile( &box_ps.profile, 1, 1, fp );
  num += writefile( &box_ps.level, 1, 1, fp );
  num += writefile( &box_ps.version, 1, 1, fp );
  num += writefile( &box_ps.pictureWidthInMBs, 2, 1, fp );
  num += writefile( &box_ps.pictureHeightInMBs, 2, 1, fp );
  num += writefile( &box_ps.displayRectangleOffsetTop, 2, 1, fp );
  num += writefile( &box_ps.displayRectangleOffsetLeft, 2, 1, fp );
  num += writefile( &box_ps.displayRectangleOffsetBottom, 2, 1, fp );
  num += writefile( &box_ps.displayRectangleOffsetRight, 2, 1, fp );
  num += writefile( &box_ps.displayMode, 1, 1, fp );
  num += writefile( &box_ps.displayRectangleOffsetFromWindowTop, 2, 1, fp );
  num += writefile( &box_ps.displayRectangleOffsetFromWindowLeftBorder, 2, 1, fp );
  num += writefile( &box_ps.loopFilterParametersFlag, 1, 1, fp );
  num += writefile( &box_ps.entropyCoding, 1, 1, fp );
  num += writefile( &box_ps.partitioningType, 1, 1, fp );
  num += writefile( &box_ps.intraPredictionType, 1, 1, fp );
  num += writefile( &box_ps.bufCycle, 1, 1, fp );
  if (box_ps.requiredPictureNumberUpdateBehavior==1) cd=0x80;
  else cd=0;
  num += writefile( &cd, 1, 1, fp );

  if ( num == box_ps.type.size ) return num;
  return -1;
}

/*!
 ************************************************************************
 * \brief
 *      Do nothing
 * \return
 *      None
 ************************************************************************
 */
void freeParameterSetBox()
{
}

// Functions on SegmentBox
/*!
 ************************************************************************
 * \brief
 *      Initiate the Segment Box and all sub-Boxes in it.
 *      Tian Dong, Feb 10, 2002:
 *      Only one Segment Box in the output file
 * \return
 *      0, if success
 *      -1, otherwise
 ************************************************************************
 */
int initSegmentBox()
{
  box_s.type.size = 0;  // to be updated
  box_s.type.type = BOX_SEGM;
  
  box_s.fileSize = 0; // to be updated
  box_s.startTick = 0;
  box_s.firstFrameNr = box_s.lastFrameNr;
  box_s.lastFrameNr = 0;  // serve as the duration of the segment.
  box_s.segmentDuration = 0; // to be updated

  // since we now only deal with the ONE track case, we assert:
  assert( box_fh.numAlternateTracks == 1 );

  if ( -1 == initAlternateTrackHeaderBox() ) return -1;
  if ( -1 == initSwitchPictureBox() ) return -1;
  if ( -1 == initAlternateTrackMediaBox() ) return -1;

  return 0;
}

/*!
 ************************************************************************
 * \brief
 *      Update the data in Segment Box
 * \return
 *      None
 ************************************************************************
 */
void updateSegmentBox()
{
  box_s.type.size = SIZEOF_BOXTYPE + 24 + box_ath.type.size + box_atm.type.size;
  box_s.fileSize = box_s.type.size;
  box_s.segmentDuration = box_s.lastFrameNr - box_s.firstFrameNr + 1;
}

/*!
 ************************************************************************
 * \brief
 *      The function to write the Segment Box to output file
 * \return
 *      how many bytes been written, if success
 *      -1, if failed
 * \param fp
 *      output file pointer
 ************************************************************************
 */
size_t wrSegmentBox( FILE *fp )
{
  size_t num = 0;
  assert( fp );

  // since we now only deal with the ONE track case, we assert:
  assert( box_fh.numAlternateTracks == 1 );

  num += writefile( &box_s.type.size, 4, 1, fp );
  num += writefile( &box_s.type.type, 4, 1, fp );
  num += writefile( &box_s.fileSize, 8, 1, fp );
  num += writefile( &box_s.startTick, 8, 1, fp );
  num += writefile( &box_s.segmentDuration, 8, 1, fp );

  num += mergeAlternateTrackHeaderBox( fp );
  num += mergeAlternateTrackMediaBox( fp );

  if ( num == box_s.type.size ) return num;
  return 0;
}

/*!
 ************************************************************************
 * \brief
 *      Free all resource allocated for this segment
 * \return
 *      None
 ************************************************************************
 */
void freeSegmentBox()
{
  freeAlternateTrackHeaderBox();
  freeAlternateTrackMediaBox();
}

// Functions on AlternateTrackHeaderBox
/*!
 ************************************************************************
 * \brief
 *      Initiate the Alternate Track Header Box & some data in picture info.
 *      Tian Dong, May 30, 2002:
 *      Only one Alternate Track Header Box in the output file.
 * \return
 *      0, if success
 *      -1, otherwise
 ************************************************************************
 */
int initAlternateTrackHeaderBox()
{
  box_ath.type.size = 0;  // to be updated
  box_ath.type.type = BOX_ATRH;
  
  if ( box_ps.requiredPictureNumberUpdateBehavior != 0 ) box_ath.numLayers = 2;
  else box_ath.numLayers = 0;

  assert((box_ath.numLayers <= MAX_LAYER_NUMBER));

  if ( initPictureInformationBox() == -1 ) return -1;
  if ( initLayerBox() == -1 ) return -1;
  return 0;
}

/*!
 ************************************************************************
 * \brief
 *      Update the data in this Alternate Track Header Box
 *      Only one PicureInformationBox in ATH, May 30, 2002
 * \return
 *      0, if success
 *      -1, if failed
 ************************************************************************
 */
int updateAlternateTrackHeaderBox()
{
  int i;
  assert(box_ath.numLayers <= MAX_LAYER_NUMBER );

  updatePictureInformationBox();
  if ( input->NumFramesInELSubSeq != 0 )
    updateLayerBox();

  // update the head data
  box_ath.type.size = SIZEOF_BOXTYPE + 1 + box_pi.type.size;
  for (i=0; i<box_ath.numLayers; i++)
    box_ath.type.size += box_layr[i].type.size;
  return 0;
}

/*!
 ************************************************************************
 * \brief
 *      Merge the Alternate Track Header Data to the output file
 * \return
 *      how many bytes been appended, if success
 *      -1, if failed
 * \param fp
 *      output file pointer
 ************************************************************************
 */
size_t mergeAlternateTrackHeaderBox( FILE* fp )
{
  FILE* destf;
  size_t num = 0, ret;

  destf = fp;
  assert( destf != NULL );

  // write the head of Picture Information
  num += writefile( &box_ath.type.size, 4, 1, destf );
  num += writefile( &box_ath.type.type, 4, 1, destf );
//  writefile( &box_ath.type.largesize, 8, 1, destf );

  num += writefile( &box_ath.numLayers, 1, 1, destf );
  
  ret = mergePictureInformationBox( destf );
  if ( ret == -1 ) return -1;
  num += ret;

  if ( input->NumFramesInELSubSeq != 0 ) 
  {
    ret = mergeLayerBox( destf );
    if ( ret == -1 ) return -1;
    num += ret;
  }

  if ( num != box_ath.type.size ) return -1;
  return num;
}

/*!
 ************************************************************************
 * \brief
 *      Free all resource allocated for this Alternate Track Header Box
 * \return
 *      None
 ************************************************************************
 */
void freeAlternateTrackHeaderBox()
{
  freePictureInformationBox();
  freeLayerBox();
}

/*!
 ************************************************************************
 * \brief
 *      Initiate the Picture Information Box & some data in picture info.
 *      Tian Dong, Feb 10, 2002:
 *      Only one Alternate Track Header Box in the output file.
 * \return
 *      0, if success
 *      -1, otherwise
 ************************************************************************
 */
int initPictureInformationBox()
{
  box_pi.type.size = 0;  // to be updated
  box_pi.type.type = BOX_PICI;
  box_pi.numPictures = 0;  // set to 0

  box_pi.fpMeta = tmpfile();
  if ( box_pi.fpMeta == NULL ) return -1;

  currPictureInfo.lastFrameNr = 0;    // do this for init of picture info
  return 0;
}

/*!
 ************************************************************************
 * \brief
 *      Update the data in this Picture Information Box
 * \return
 *      0, if success
 *      -1, if failed
 ************************************************************************
 */
int updatePictureInformationBox()
{
  int pictureDataSize;
  
  assert( box_pi.fpMeta != NULL );
  // update the head data
  fseek( box_pi.fpMeta, 0, SEEK_END );
  pictureDataSize = ftell( box_pi.fpMeta );
  box_pi.type.size = SIZEOF_BOXTYPE + box_fh.numBytesInPictureCountMinusOne+1 + pictureDataSize;
  return 0;
}

/*!
 ************************************************************************
 * \brief
 *      Merge the PictureInformation Data to the output file
 * \return
 *      how many bytes been appended, if success
 *      -1, if failed
 * \param fp
 *      output file pointer
 ************************************************************************
 */
size_t mergePictureInformationBox( FILE* fp )
{
  FILE* sourcef;
  FILE* destf;
  unsigned char c;
  size_t num = 0;

  sourcef = box_pi.fpMeta;
  destf = fp;

  assert( sourcef != NULL );
  assert( destf != NULL );

  // write the head of Picture Information
  num += writefile( &box_pi.type.size, 4, 1, fp );
  num += writefile( &box_pi.type.type, 4, 1, fp );
//  writefile( &box_pi.type.largesize, 8, 1, fp );

  num += writefile_s( &box_pi.numPictures, sizeof(box_pi.numPictures), box_fh.numBytesInPictureCountMinusOne+1, 1, destf );
  
  // append the data in box_ath.fpMeta into fp:
  fseek( sourcef, 0L, SEEK_SET );
  
  c = fgetc(sourcef);
  while ( !feof( sourcef ) )
  {
    fputc( c, destf );
    num++;
    c = fgetc(sourcef);
  }

  if ( num == box_pi.type.size ) return num;
  return -1;
}

/*!
 ************************************************************************
 * \brief
 *      Free all resource allocated for this PictureInformation Box
 * \return
 *      None
 ************************************************************************
 */
void freePictureInformationBox()
{
  fclose( box_pi.fpMeta );
}

// Functions on PictureInfo
/*!
 ************************************************************************
 * \brief
 *      Initiate the picture info, before one frame is encoded
 * \return
 *      0, if success
 *      -1, otherwise
 ************************************************************************
 */
int initPictureInfo()
{
  static int prev_frame_no = 0;

  if ( img->type == I_SLICE ) currPictureInfo.intraPictureFlag = TRUE;
  else currPictureInfo.intraPictureFlag = FALSE;
  if ( img->type == SP_SLICE ) currPictureInfo.syncPictureFlag = TRUE; // ???
  else currPictureInfo.syncPictureFlag = FALSE; // ???

⌨️ 快捷键说明

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