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

📄 encodeiff.c

📁 比较老的264解码器baseline实现
💻 C
📖 第 1 页 / 共 5 页
字号:
  unsigned INT16 cd;
  unsigned int i;
  FILE *fp;

  if ( input->NumFramesInELSubSeq == 0 ) return 0;
  fp = box_layr[layr].fp;
  assert( fp );
  if ( box_sseq[layr].numReferenceSubSequences < 0 || box_sseq[layr].numReferenceSubSequences > MAX_DEPENDENT_SUBSEQ )
    return -1;

  // since we now only deal with the ONE track case, we assert:
  assert( box_fh.numAlternateTracks == 1 );
  assert( layr >= 0 && layr < box_ath.numLayers );

  num += writefile( &box_sseq[layr].type.size, 4, 1, fp );
  num += writefile( &box_sseq[layr].type.type, 4, 1, fp );
  num += writefile( &box_sseq[layr].subSequenceIdentifier, 2, 1, fp );

  if ( box_sseq[layr].continuationFromPreviousSegmentFlag ) cd = 0x8000;
  else cd = 0;
  if ( box_sseq[layr].continuationToNextSegmentFlag) cd |= 0x4000;
  if ( box_sseq[layr].startTickAvailableFlag) cd |= 0x2000;
  num += writefile( &cd, 2, 1, fp );

  num += writefile( &box_sseq[layr].ssStartTick, 8, 1, fp );
  num += writefile( &box_sseq[layr].ssDuration, 8, 1, fp );
  num += writefile( &box_sseq[layr].avgBitRate, 4, 1, fp );
  num += writefile( &box_sseq[layr].avgFrameRate, 4, 1, fp );
  num += writefile( &box_sseq[layr].numReferenceSubSequences, 2, 1, fp );
  
  if ( num != SIZEOF_BOXTYPE+30 ) return -1;

  for (i=0; i<box_sseq[layr].numReferenceSubSequences; i++)
  {
    num2 = writefile( &box_sseq[layr].dependencyData[i].layerNumber, 1, 1, fp );
    num2 += writefile( &box_sseq[layr].dependencyData[i].subSequenceIdentifier, 2, 1, fp );
    num += num2;
    if ( num2 != 3 ) return -1;
  }

  return num;
}

/*!
 ************************************************************************
 * \brief
 *      Free the resources allocated for the Sub Sequence Box
 *      Tian Dong, May 30, 2002:
 ************************************************************************
 */
void freeSubSequenceBox( int layr )
{
  if ( input->NumFramesInELSubSeq == 0 ) return;
}

// Functions on SwitchPictureBox
/*!
 ************************************************************************
 * \brief
 *      Initiate the Switch Picture Box. Do nothing
 *      Tian Dong, Feb 10, 2002
 *      The switch picture box is skipped in the output file
 * \return
 *      0, if success
 *      -1, otherwise
 ************************************************************************
 */
int initSwitchPictureBox()
{
  return 0;
}

// Functions on AlternateMediaBox
/*!
 ************************************************************************
 * \brief
 *      Initiate the Alternate Track Media Box & some data in picture info.
 *      Tian Dong, Feb 10, 2002:
 *      Only one Alternate Track Media Box in the output file.
 * \return
 *      0, if success
 *      -1, otherwise
 ************************************************************************
 */
int initAlternateTrackMediaBox()
{
  box_atm.type.size = 0;    // to be updated
  box_atm.type.type = BOX_ATRM;

  box_atm.fpMedia = tmpfile();
  assert( box_atm.fpMedia != NULL );

  // to maintain a picture pointer to point to the beginning 
  // of the latest picture, relative to the beginning of the ATMC.
  currPictureInfo.currPictureSize = SIZEOF_BOXTYPE;  // the first time to set its value. in 64 bits mode
  return 0;
}

/*!
 ************************************************************************
 * \brief
 *      Update the data in this Alternate Track Media
 * \return
 *      0, if success
 *      -1, if failed
 ************************************************************************
 */
int updateAlternateTrackMediaBox()
{
  int mediaDataSize;

  assert( box_atm.fpMedia != NULL );
  fseek( box_atm.fpMedia, 0, SEEK_END );
  mediaDataSize = ftell( box_atm.fpMedia );
  box_atm.type.size = SIZEOF_BOXTYPE + mediaDataSize;
  return 0;
}

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

  sourcef = box_atm.fpMedia;
  destf = fp;

  assert( sourcef != NULL );
  assert( destf != NULL );
  
  // write the head
  num += writefile( &box_atm.type.size, 4, 1, fp );
  num += writefile( &box_atm.type.type, 4, 1, fp );
  if ( num != 8 ) return -1;

  // 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);
  }
  return num;
}

/*!
 ************************************************************************
 * \brief
 *      Free all resource allocated for this Alternate Track Media Box
 * \return
 *      None
 ************************************************************************
 */
void freeAlternateTrackMediaBox()
{
  fclose( box_atm.fpMedia );
}

/*!
 ************************************************************************
 * \brief
 *      The init function for Interim File Format
 * \return
 *      0, if success
 *      -1, otherwise
 ************************************************************************
 */
int initInterimFile()
{
  box_s.lastFrameNr = 0;
  if ( -1 == initFileTypeBox() ) return -1;
  if ( -1 == initFileHeaderBox() ) return -1;
  if ( -1 == initContentInfoBox() ) return -1;
  if ( -1 == initAlternateTrackInfoBox() ) return -1;
  if ( -1 == initParameterSetBox() ) return -1;
  return 0;
}

/*!
 ************************************************************************
 * \brief
 *      The close function for Interim File Format
 * \return
 *      how many bytes being written into the file, if success
 *      -1, otherwise
 * \param outf
 *      output file pointer
 ************************************************************************
 */
size_t terminateInterimFile(FILE* outf)
{
  size_t num = 0, len;

  assert( outf != NULL );

  if ( (len = wrFileTypeBox( outf )) == -1 ) return -1;
  num += len;
  if ( (len = wrFileHeaderBox( outf )) == -1 ) return -1;
  num += len;
  if ( (len = wrContentInfoBox( outf )) == -1 ) return -1;
  num += len;
  if ( (len = wrAlternateTrackInfoBox( outf )) == -1 ) return -1;
  num += len;
  if ( (len = wrParameterSetBox( outf )) == -1 ) return -1;
  num += len;
  if ( (len = wrSegmentBox( outf )) == -1 ) return -1;
  num += len;

  freeSegmentBox();
  freeParameterSetBox();
  freeAlternateTrackInfoBox();
  freeContentInfoBox();
  freeFileHeaderBox();
  freeFileTypeBox();

  return num;
}

/*!
 ************************************************************************
 * \brief
 *      write the data to file, bytes are in big Endian order.
 * \return
 *      how many bytes being written into the file, if success
 *      -1, otherwise
 * \param outf
 *      output file pointer
 ************************************************************************
 */
size_t writefile( void* buf, size_t size, size_t count, FILE* fp )
{
  byte* p;
  int num = 0;

  if (isBigEndian)
    p = (byte*)buf;
  else
    p = (byte*)buf+size-1;


  assert( fp != NULL );
  assert( buf != NULL );
  assert( count == 1 );

  while ( size > 0 )
  {
    if (isBigEndian)
      fwrite( p++, 1, 1, fp );
    else
      fwrite( p--, 1, 1, fp );
    size--;
    num++;
  }
  return num;
}

/*!
 ************************************************************************
 * \brief
 *      write the data to file, bytes are in big Endian order.
 *      to be used if buffers size differs from number of written bytes
 * \return
 *      how many bytes being written into the file, if success
 *      -1, otherwise
 * \param outf
 *      output file pointer
 ************************************************************************
 */
size_t writefile_s( void* buf, size_t bufsize, size_t size, size_t count, FILE* fp )
{
  byte* p;
  int num = 0;

  if (isBigEndian)
    p = (byte*)buf+(bufsize-size);
  else
    p = (byte*)buf+size-1;


  assert( fp != NULL );
  assert( buf != NULL );
  assert( count == 1 );

  while ( size > 0 )
  {
    if (isBigEndian)
      fwrite( p++, 1, 1, fp );
    else
      fwrite( p--, 1, 1, fp );
    size--;
    num++;
  }
  return num;
}

/*!
 ************************************************************************
 * \date:
 *      June 15, 2002
 * \brief
 *      If the first frame in a new sub-sequence is to be encoded,
 *        this function will do some initialization for the new sub-seq.
 ************************************************************************
 */
void begin_sub_sequence()
{
  if ( input->of_mode == PAR_OF_ANNEXB || input->NumFramesInELSubSeq == 0 ) return;
  if ( input->of_mode == PAR_OF_RTP ) 
  { 
    assert (0==1);
//    begin_sub_sequence_rtp();
    return;
  }

  // begin to encode the base layer subseq?
  if ( IMG_NUMBER == 0 )
  {
//    printf("begin to encode the base layer subseq\n");
    initSubSequenceBox(0);  // init the sub-sequence in the base layer
  }
  // begin to encode the enhanced layer subseq?
  if ( IMG_NUMBER % (input->NumFramesInELSubSeq+1) == 1 )
  {
//    printf("begin to encode the enhanced layer subseq\n");
    initSubSequenceBox(1);  // init the sub-sequence in the enhanced layer
    add_dependent_subseq(1);
  }
}

/*!
 ************************************************************************
 * \date:
 *      June 15, 2002
 * \brief
 *      If the last frame of current sub-sequence has been encoded,
 *        this function will do some finalization for the sub-seq.
 ************************************************************************
 */
void end_sub_sequence()
{
  if ( input->of_mode != PAR_OF_ANNEXB || input->NumFramesInELSubSeq == 0 ) return;
  if ( input->of_mode == PAR_OF_RTP ) 
  {
    assert (0==1);
//    end_sub_sequence_rtp();
    return;
  }

  // end of the base layer:
  if ( img->number == input->no_frames-1 )
  {
//    printf("end of encoding the base layer subseq\n");
    updateSubSequenceBox(0);
    if ( -1 == wrSubSequenceBox(0) )
    {
      printf("Serious warning: error occurs when trying to write sub sequence box 0.\n");
    }
  }
  // end of the enhanced layer:
  if ( ((IMG_NUMBER%(input->NumFramesInELSubSeq+1)==0) && (input->successive_Bframe != 0) && (IMG_NUMBER>0)) || // there are B frames
    ((IMG_NUMBER%(input->NumFramesInELSubSeq+1)==input->NumFramesInELSubSeq) && (input->successive_Bframe==0))   // there are no B frames
    )
  {
//    printf("end of encoding the enhanced layer subseq\n");
    add_dependent_subseq(1);
    updateSubSequenceBox(1);
    if ( -1 == wrSubSequenceBox(1) )
    {
      printf("Serious warning: error occurs when trying to write sub sequence box 1.\n");
    }
  }
}


/*!
 ************************************************************************
 * \date:
 *      June 15, 2002
 * \brief
 *    Hide some frames in the short term frame buffer
 *      The number of frames can be used for the forward prediction will
 *      be set in fb->num_short_used.
 ************************************************************************
 */
void remap_ref_short_term(PayloadInfo* pp)
{
  int i;
  RMPNIbuffer_t *r, *t;
  int currLayerNo, currSubSeqNo;
  int pnp, pnq;
  int delta, mdelta;
  Boolean need_rmpni = FALSE;

  currLayerNo = currPictureInfo.layerNumber;
  currSubSeqNo = currPictureInfo.subSequenceIdentifier;
  pnp = img->pn;

  // check if the remapping is need or not?
  for (i=0; i<fb->short_used; i++)
  {
    if ( fb->picbuf_short[i]->layer_no > currLayerNo ||
      (fb->picbuf_short[i]->layer_no == currLayerNo && fb->picbuf_short[i]->sub_seq_no != currSubSeqNo)
      )
    {
      need_rmpni = TRUE;
      break;
    }
  }

  if ( !need_rmpni ) return;

  fb->num_short_used = 0;

  // Tian Dong: we use the reverse order for re-mapping to let the latest frame
  // to have the relative index 0. See our implementation accompanying document, section 1.2.5
  t = img->currentSlice->rmpni_buffer;
  for (i=fb->short_used-1; i>=0; i--)
  {
    if ( fb->picbuf_short[i]->layer_no < currLayerNo ||
      (fb->picbuf_short[i]->layer_no == currLayerNo && fb->picbuf_short[i]->sub_seq_no == currSubSeqNo)
      )
    {
      r = (RMPNIbuffer_t*

⌨️ 快捷键说明

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