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

📄 encodeiff.c

📁 h.264/avc 视频编码程序,实现分数像素匹配功能,非原创.
💻 C
📖 第 1 页 / 共 3 页
字号:
    break;
  }
  box_ps.partitioningType = input->partition_mode;
  box_ps.intraPredictionType = input->UseConstrainedIntraPred;
  box_ps.bufCycle = input->no_multpred;
  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;

  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.entropyCoding, 1, 1, fp );
  num += writefile( &box_ps.motionResolution, 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 ( 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, Feb 10, 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;
  box_ath.numPictures = 0;  // set to 0

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

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

/*!
 ************************************************************************
 * \brief
 *      Update the data in this Alternate Track Header
 * \return
 *      0, if success
 *      -1, if failed
 ************************************************************************
 */
int updateAlternateTrackHeaderBox()
{
  int pictureDataSize;
  
  assert( box_ath.fpMeta != NULL );
  // update the head data
  fseek( box_ath.fpMeta, 0, SEEK_END );
  pictureDataSize = ftell( box_ath.fpMeta );
  box_ath.type.size = SIZEOF_BOXTYPE + box_fh.numBytesInPictureCountMinusOne+1 + pictureDataSize;
  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* sourcef;
  FILE* destf;
  unsigned char c;
  size_t num = 0;

  sourcef = box_ath.fpMeta;
  destf = fp;

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

  // write the head of Alternate Track Header Box
  num += writefile( &box_ath.type.size, 4, 1, fp );
  num += writefile( &box_ath.type.type, 4, 1, fp );
//  writefile( &box_ath.type.largesize, 8, 1, fp );

  num += writefile( &box_ath.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_ath.type.size ) return num;
  return -1;
}

/*!
 ************************************************************************
 * \brief
 *      Free all resource allocated for this Alternate Track Header Box
 * \return
 *      None
 ************************************************************************
 */
void freeAlternateTrackHeaderBox()
{
  fclose( box_ath.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 == INTRA_IMG )
    currPictureInfo.intraPictureFlag = 0x80; // if the picture is INTRA
  else
    currPictureInfo.intraPictureFlag = 0x00; // if the picture is not INTRA
  currPictureInfo.pictureOffset = currPictureInfo.currPictureSize;
  currPictureInfo.currPictureSize = 0;  // reset

  // to set the picture display time (relative to the previous coded frame)
  currPictureInfo.pictureDisplayTime = frame_no - prev_frame_no;
  prev_frame_no = frame_no;

  if ( img->type != B_IMG )
    currPictureInfo.lastFrameNr = frame_no;

  currPictureInfo.numPayloads = 0;  // numPayloads must be set to zero here
  currPictureInfo.payloadData = NULL;
  return 0;
}

/*!
 ************************************************************************
 * \brief
 *      The function to write the meta data of the current picture
 * \return
 *      how many bytes been written, if success
 *      -1, if failed
 * \param fp
 *      output file pointer
 ************************************************************************
 */
size_t wrPictureInfo( FILE* fp )
{
  int i;
  INT64 size;
  PayloadInfo* pp;
  size_t num = 0;
//  FILE* f;

//  f = fopen( "dummy1.txt", "at" );
  assert( fp != NULL );

  num += writefile( &currPictureInfo.intraPictureFlag, 1, 1, fp );
  num += writefile( &currPictureInfo.pictureOffset, box_fh.numBytesInPictureOffsetMinusTwo + 2, 1, fp );
  num += writefile( &currPictureInfo.pictureDisplayTime, box_fh.numBytesInPictureDisplayTimeMinusOne + 1, 1, fp );
  num += writefile( &currPictureInfo.numPayloads, box_fh.numBytesInPayloadCountMinusOne + 1, 1, fp );

  if ( num != (unsigned)(1+box_fh.numBytesInPictureOffsetMinusTwo + 2+box_fh.numBytesInPictureDisplayTimeMinusOne + 1+box_fh.numBytesInPayloadCountMinusOne + 1) ) return -1;
//  fprintf( f, "picture %d 's payload, total %d:\n", frame_no, currPictureInfo.numPayloads );

  pp = currPictureInfo.payloadData;
  for ( i = 0; i < currPictureInfo.numPayloads; i++ )
  { 
    assert( pp != NULL );

//    fprintf( f, "payloadsize of %d is: %d\n", i, pp->payloadSize );

    // update and write the payload to file
    if ( -1 == wrPayloadInfo( pp, fp ) ) return -1;

    // then update the parameter in Alternate Track Info Box
    size = pp->payloadSize + pp->headerSize;
    box_ati.info[0].numSDU++;
    box_ati.info[0].sumSDUSize += (long double)size;
    if ( box_ati.info[0].maxSDUSize < size ) box_ati.info[0].maxSDUSize = (unsigned INT16)size;

    pp = pp->next;
  }

//  fclose ( f );
  return 0;
}

/*!
 ************************************************************************
 * \brief
 *      Free all resource allocated for this Picture Info
 * \return
 *      None
 ************************************************************************
 */
void freePictureInfo()
{
  int i;
  PayloadInfo* next;

  for ( i = 0; i < currPictureInfo.numPayloads; i++ )
  {
    assert( currPictureInfo.payloadData != NULL );
    next = currPictureInfo.payloadData->next;
    free( currPictureInfo.payloadData );
    currPictureInfo.payloadData = next;
  }
}

// Functions on payloadInfo

/*!
 ************************************************************************
 * \brief
 *      To new a payload info to save the meta data of a slice
 *      Tian Dong, Feb 10, 2002:
 *      No data partition supported.
 * \return
 *      a pointer to the allocated mem, if success
 *      NULL, if failed
 ************************************************************************
 */
PayloadInfo* newPayloadInfo()
{
  PayloadInfo* pli;

  pli = calloc(1, sizeof(PayloadInfo));
  if ( pli == NULL ) return NULL;

  pli->payloadSize = 0;
  pli->headerSize = box_fh.numBytesInPayloadSizeMinusOne+1 + 1 + 1;
  pli->payloadType = 0;  // single slice
  pli->errorIndication = 0;  // no known error
  pli->reserved = 0;
  pli->parameterSet = 0;
  pli->pictureID = 0;
  pli->sliceID = 0;
  pli->sliceType = 0;
  pli->firstMBInSliceX = 0;
  pli->firstMBInSliceY = 0;
  pli->next = NULL;
  pli->pn = img->pn;
  pli->type = img->type;
  pli->max_lindex = img->max_lindex;
  pli->lindex = img->lindex;

  // set values
  if ( input->partition_mode == PAR_DP_1 )
    pli->payloadType = 0;
  else
    assert(0==1);
  pli->parameterSet = box_ps.parameterSetID;
  pli->pictureID = img->currentSlice->picture_id;
  pli->sliceID = img->current_slice_nr;
  
  // copied from rtp.c, and add pli->sliceType2
  switch (img->type)
  {
    case INTER_IMG:
      if (img->types==SP_IMG)
      {
        pli->sliceType = 2;
        pli->sliceType2 = SP_IMG;
      }
      else
      {
        pli->sliceType = 0;
        pli->sliceType2 = INTER_IMG;
      }
      break;
    case INTRA_IMG:
      pli->sliceType = 3;
      pli->sliceType2 = INTRA_IMG;
      break;
    case B_IMG:
      pli->sliceType = 1;
      pli->sliceType2 = B_IMG;
      break;
    case SP_IMG:
      pli->sliceType = 2;
      pli->sliceType2 = SP_IMG;
      break;
    default:
      printf ("Panic: unknown picture type %d, exit\n", img->type);
      assert (0==1);
  }

  pli->firstMBInSliceX = img->mb_x;
  pli->firstMBInSliceY = img->mb_y;
  pli->initialQP = img->qp;
  pli->qpsp = img->qpsp;

  // begin of ERPS
#ifdef _CHECK_MULTI_BUFFER_1_

  /* RPSL: Reference Picture Selection Layer */
  if(img->type!=INTRA_IMG)
  {
    // let's mix some reference frames
    if ((img->pn==5)&&(img->type==INTER_IMG))
    {
      RMPNIbuffer_t *r;
      r = (RMPNIbuffer_t*)calloc (1,sizeof(RMPNIbuffer_t));
      r->RMPNI=0;
      r->Data=2;
      r->Next=NULL;
      img->currentSlice->rmpni_buffer=r;
    }
  }
  reorder_mref(img);
  
#endif

#ifdef _CHECK_MULTI_BUFFER_2_

  // some code to check operation
  if ((img->pn==3) && (img->type==INTER_IMG))
  {
    // check in this frame as long term picture
//    if (img->max_lindex==0)
    {
      // set long term buffer size = 2
      img->max_lindex=2;
    }

    // assign local long term
    init_long_term_buffer(2,img);
    init_mref(img);
    init_Refbuf(img);

    if (img->current_slice_nr==0)
    {
      assign_long_term_id(3,img->lindex,img);
      img->lindex=(img->lindex+1)%img->max_lindex;
    }
  }

⌨️ 快捷键说明

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