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

📄 encodeiff.c

📁 h.264/avc 视频编码程序,实现分数像素匹配功能,非原创.
💻 C
📖 第 1 页 / 共 3 页
字号:
#endif 
  // end of ERPS

  return pli;
}

/*!
 ************************************************************************
 * \brief
 *      Add a payload info to the Payloadinfo List, which head is stored in PictureInfo
 *      Tian Dong, Feb 10, 2002:
 *      No data partition supported.
 * \return
 *      1, if success
 *      0, if failed
 * \param pi
 *      The PayloadInfo will be added to the list
 ************************************************************************
 */
int addOnePayloadInfo(PayloadInfo* pi)
{
  PayloadInfo* p;
  PayloadInfo* last;

  last = p = currPictureInfo.payloadData;

  assert( pi != NULL );

  while ( p )
  {
    last = p;
    p = p->next;
  }

  if (last == NULL)
    currPictureInfo.payloadData = pi;  // this is the first payloadInfo
  else
    last->next = pi;  // add the payloadInfo to the end of the payloadInfo list

  currPictureInfo.numPayloads++;
  
  return 1;
}

/*!
 ************************************************************************
 * \brief
 *      The function to write one payloadinfo to file
 * \return
 *      how many bytes been written, if success
 *      -1, if failed
 * \param pp
 *      PayloadInfo pointer
 * \param fp
 *      output file pointer
 ************************************************************************
 */
size_t wrPayloadInfo( PayloadInfo* pp, FILE *fp )
{
  byte cd; 
  Bitstream* bitstream; // used as a MEM buffer of slice header
  SyntaxElement sym;
  size_t num = 0, bytes_written;

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

  // Initialize the bitsteam:
  bitstream = alloca(sizeof(Bitstream));
  assert( bitstream != NULL );
  bitstream->streamBuffer = alloca(BUFSIZE_FOR_PAYLOADINFO);
  memset( bitstream->streamBuffer, 0, BUFSIZE_FOR_PAYLOADINFO);
  
  bitstream->bits_to_go  = 8;
  bitstream->byte_pos    = 0;
  bitstream->byte_buf    = 0;
  
  // First write the element to the MEM bitstream buffer
  sym.type = SE_HEADER;       // This will be true for all symbols generated here
  sym.mapping = n_linfo2;       // Mapping rule: Simple code number to len/info
  if ( pp->payloadType == 0 )
  {
    // write the parameter set
    sym.value1 = pp->parameterSet;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    // write slice header;
    sym.value1 = pp->pictureID;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    sym.value1 = pp->sliceType;
//    select_picture_type (&sym);
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    sym.value1 = pp->firstMBInSliceX;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    sym.value1 = pp->firstMBInSliceY;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    sym.value1 = MAX_QP - pp->initialQP;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    if ( input->symbol_mode == CABAC )
    {
      sym.value1 = pp->lastMBnr;
      writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    }
    if ( pp->sliceType2 == SP_IMG )
    {
      sym.value1 = MAX_QP - pp->qpsp;
      writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    }

    iff_writeERPS(&sym, pp, bitstream);       // Tian: to support ERPS (Annex U), Feb 27, 2002
  }
  else if ( pp->payloadType == 1 )
  {
    // write the parameter set
    sym.value1 = pp->parameterSet;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    // write slice header;
    sym.value1 = pp->pictureID;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    sym.value1 = pp->sliceType;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    sym.value1 = pp->firstMBInSliceX;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    sym.value1 = pp->firstMBInSliceY;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    sym.value1 = MAX_QP - pp->initialQP;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    // write the slice id
    sym.value1 = pp->sliceID;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);

    iff_writeERPS(&sym, pp, bitstream);       // Tian: to support ERPS (Annex U), Feb 27, 2002
  }
  else if ( pp->payloadType == 2 || pp->payloadType == 3 )
  {
    // write pictureID
    sym.value1 = pp->pictureID;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);
    // write sliceID
    sym.value1 = pp->sliceID;
    writeSyntaxElement2Buf_UVLC(&sym, bitstream);

    iff_writeERPS(&sym, pp, bitstream);       // Tian: to support ERPS (Annex U), Feb 27, 2002
  }
  else if ( pp->payloadType == 5 )
  {
    // no additional codewords
  }

  // finishing the MEM buffer
  if (bitstream->bits_to_go < 8)
  { // trailing bits to process
    bitstream->byte_buf <<= bitstream->bits_to_go;
    bitstream->streamBuffer[bitstream->byte_pos++]=bitstream->byte_buf;
    bitstream->bits_to_go = 8;
  }

  bytes_written = bitstream->byte_pos;

  // update & write headerSize
  num += writefile( &pp->payloadSize, box_fh.numBytesInPayloadSizeMinusOne+1, 1, fp );
  pp->headerSize += bytes_written;
  num += writefile( &pp->headerSize, 1, 1, fp );
  cd = (pp->payloadType << 4) | (pp->errorIndication << 3) | (pp->reserved);
  num += writefile( &cd, 1, 1, fp );
  if ( num != (unsigned)(box_fh.numBytesInPayloadSizeMinusOne+1+2) ) return -1;

  // Then write the bitstream to FILE
  if ( bytes_written != fwrite (bitstream->streamBuffer, 1, bytes_written, fp) ) return -1;
  return num+bytes_written;
}

/*!
 ************************************************************************
 * \brief
 *      writes the ERPS syntax elements to a bitstream
 *      imitate write_ERPS(), and change the function calls:
 *    from:
 *      len += writeSyntaxElement_UVLC (sym, partition);
 *    to:
 *      len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
 * \return
 *      how many bytes been written, if success
 *      -1, if failed
 * \param bitstream
 *      destination: where the code to be written
 ************************************************************************
 */
size_t iff_writeERPS(SyntaxElement *sym, PayloadInfo* pp, Bitstream* bitstream)
{
  size_t len=0;

  // RPSF: Reference Picture Selection Flags
  sym->value1 = 0;
  len += writeSyntaxElement2Buf_UVLC(sym, bitstream);

  // PN: Picture Number
  sym->value1 = pp->pn;
  len += writeSyntaxElement2Buf_UVLC(sym, bitstream);

#ifdef _CHECK_MULTI_BUFFER_1_

  // RPSL: Reference Picture Selection Layer
  sym->value1 = 1;
  len += writeSyntaxElement2Buf_UVLC(sym, bitstream);

  if(pp->type!=INTRA_IMG)
  {
    // let's mix some reference frames
    if ((pp->pn==5)&&(pp->type==INTER_IMG))
    {
      // negative ADPN follows
      // RMPNI
      sym->value1 = 0;
      len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
      // ADPN
      sym->value1 = 2;
      len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
    }
    // RMPNI
    sym->value1 = 3;
    len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
  }
  
#else
  // RPSL: Reference Picture Selection Layer
  sym->value1 = 0;
  len += writeSyntaxElement2Buf_UVLC(sym, bitstream);

#endif

#ifdef _CHECK_MULTI_BUFFER_2_

  // Reference Picture Bufering Type
  sym->value1 = 1;
  len += writeSyntaxElement2Buf_UVLC(sym, bitstream);

  // some code to check operation
  if ((pp->pn==3) && (pp->type==INTER_IMG))
  {
    // set long term buffer size = 2
    // MMCO Specify Max Long Term Index
    // command
    sym->value1 = 4;
    len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
    // size = 2+1 (MLP1)
    sym->value1 = 2+1;
    len += writeSyntaxElement2Buf_UVLC(sym, bitstream);

    // assign a long term index to actual frame
    // MMCO Assign Long Term Index to a Picture
    // command
    sym->value1 = 3;
    len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
    // DPN=0 for actual frame 
    sym->value1 = 0;
    len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
    //long term ID
    sym->value1 = pp->lindex;
    len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
  } 
  if ((pp->pn==4) && (pp->type==INTER_IMG))
  {
     if (pp->max_lindex>0)
     {
      // delete long term picture again
      // MMCO Mark a Long-Term Picture as Unused
      // command
      sym->value1 = 2;
      len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
      // MMCO LPIN
      // command
      sym->value1 = (pp->max_lindex+pp->lindex-1)%pp->max_lindex;
      len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
    }
  } 

  // end MMCO loop
  // end loop
  sym->value1 = 0;
  len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
#else
    // RPBT: Reference Picture Bufering Type
    sym->value1 = 0;
    len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
#endif 

  return len;
}

// 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 = (byte*)buf+size-1;
  int num = 0;

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

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

⌨️ 快捷键说明

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