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

📄 encodeiff.c

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

/*!
 ************************************************************************
 *  \file
 *     encodeiff.c
 *  \brief
 *     Implementation of the interim file format, as defined
 *     in Appendix III of WD-1 (JVT-A003r1).
 *
 *     Instructions for a new release of the Joint Model:
 *     1. Remember to update WORKING_DRAFT_MAJOR_NO and WORKING_DRAFT_MINOR_NO
 *        in defines.h appropriately
 *     2. Remember to modify the decoder as well
 *
 *     Instructions for modifications to the interim file format:
 *     1. Update INTERIM_FILE_MAJOR_NO and INTERIM_FILE_MINOR_NO
 *        in defines.h appropriately. It is up to the implementor
 *        to decide, which modification deserves an update in the major
 *        version number.
 *     2. If you modify one of the box types that are of constant size,
 *        such as the Parameter Set Box, update the hard-coded size of 
 *        the box appropriately.
 *
 *     Feb 10, 2002:
 *     Until now, the box header only permits the compact size (32 bits mode),
 *     and the Data Partition mode is not supported. One segment per file
 *     is created.
 *      
 *  \author
 *      - Dong Tian                             <tian@cs.tut.fi>
 *      - Miska M. Hannuksela                   <miska.hannuksela@nokia.com>
 *
 ************************************************************************
 */

 /*!
 ************************************************************************
 *  Tian Dong (Last Updated in June 15, 2002)
 *  \flowchart of how the output module works:
 *  main()
 *  {
 *    start_sequence()
 *    {
 *      SequenceHeader(out)
 *      {
 *        initInterimFile()
 *      }
 *    }
 *    initSegmentBox()
 *    {
 *      ......
 *      initAlternateTrackHeaderBox()
 *      {
 *         initPictureInformationBox()
 *         initLayerBox()
 *      }
 *      initSwitchPictureBox();
 *      initAlternateTrackMediaBox();
 *    }
 *    loop over pictures in the same segment
 *    {
 *      encode_one_frame()
 *      {
 *        init_frame()
 *        update header of AlternateTrackHeaderBox 
 *        initPictureInfo 
 *        while (end_of_frame == FALSE) // loop over slices
 *        {
 *          encode_one_slice(&sym)
 *          {
 *            start_slice()
 *            {
 *              newPayloadInfo
 *              addOnePayloadInfo
 *            }
 *            loop over MB encoding // write the MBData to mem buffer
 *            terminate_slice()  file handle
 *            {
 *              updating the payloadInfo
 *              writing media data to the tmp file
 *            }
 *          }
 *        }
 *        wrPictureInfo // write pictureInfo & all payloadInfos to a temporary file
 *        {
 *          write the pictureInfo header to file
 *          loop to write every payloadInfo to file
 *          {
 *            wrPayloadInfo
 *            update info about SDU in AlternateTrackInfo Box
 *          }
 *        }
 *        freePictureInfo
 *      }
 *    }
 *    updateAlternateTrackHeaderBox();
 *    updateAlternateTrackMediaBox();
 *    updateSegmentBox();
 *    terminate_sequence()
 *    {
 *      TerminateInterimFile( outf )
 *      {
 *        wrFileTypeBox( outf );
 *        wrFileHeaderBox( outf );
 *        wrContentInfoBox( outf );
 *        wrAlternateTrackInfoBox( outf );
 *        wrParameterSetBox( outf );
 *        wrSegmentBox( outf );
 *        freeAll
 *      }
 *    }
 *  }
 ************************************************************************
 */

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <memory.h>
#include <malloc.h>
#include "global.h"
#include "mbuffer.h"
#include "encodeiff.h"
#include "rtp.h"

FileTypeBox box_ft;
FileHeaderBox box_fh;
ContentInfoBox box_ci;
AlternateTrackInfoBox box_ati;
ParameterSetBox box_ps;
SegmentBox box_s;
AlternateTrackHeaderBox box_ath;
PictureInformationBox box_pi;
PayloadInfo* pCurrPayloadInfo;
PictureInfo currPictureInfo;
LayerBox box_layr[MAX_LAYER_NUMBER];
SubSequenceBox box_sseq[MAX_LAYER_NUMBER];
AlternateTrackMediaBox box_atm;
SwitchPictureBox box_sp;

int isBigEndian=0;

/*!
 ************************************************************************
 * \brief
 *      checks if the System is big- or little-endian
 * \return
 *      0, little-endian
 *      1, big-endian
 ************************************************************************
 */
int testEndian()
{
  short s;
  byte *p;

  p=(byte*)&s;

  s=1;

  return (*p==0);
}

/*!
 ************************************************************************
 * \brief
 *      Initiate the File Type Box. 
 * \return
 *      0, if success
 *      -1, otherwise
 ************************************************************************
 */
int initFileTypeBox()
{
  box_ft.type.size = SIZEOF_BOXTYPE + 12;
  box_ft.type.type = BOX_FTYP;

  memcpy( box_ft.majorBrand, "jvt ", 4 );
  box_ft.jmMajorVersion = WORKING_DRAFT_MAJOR_NO;
  box_ft.jmMinorVersion = WORKING_DRAFT_MINOR_NO;
  
  box_ft.numCompatibleBrands = 1;
  box_ft.compatibleBrands = calloc( box_ft.numCompatibleBrands*4, 1 );
  if ( box_ft.compatibleBrands == NULL ) return -1;
  memcpy( box_ft.compatibleBrands, "jvt ", 4 );

  return 0;
}

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

  // to write the structure to file
  num += writefile( &box_ft.type.size, 4, 1, fp );
  num += writefile( &box_ft.type.type, 4, 1, fp );
  num += writefile( box_ft.majorBrand, 4, 1, fp );
  num += writefile( &box_ft.jmMajorVersion, 2, 1, fp );
  num += writefile( &box_ft.jmMinorVersion, 2, 1, fp );
  ret = fwrite( box_ft.compatibleBrands, 4, box_ft.numCompatibleBrands, fp );
  num += (ret * 4);

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

/*!
 ************************************************************************
 * \brief
 *      Free the memory allocated for File Type Box
 * \return
 *      None
 ************************************************************************
 */
void freeFileTypeBox()
{
  free( box_ft.compatibleBrands );
}

/*!
 ************************************************************************
 * \brief
 *      Initiate the File Header Box
 * \return
 *      0, if success
 *      -1, otherwise
 ************************************************************************
 */
int initFileHeaderBox( )
{
  // to write the file header
  box_fh.type.size = SIZEOF_BOXTYPE + 27;
  box_fh.type.type = BOX_JVTH;

  box_fh.majorVersion = INTERIM_FILE_MAJOR_NO;
  box_fh.minorVersion = INTERIM_FILE_MINOR_NO;
  box_fh.timescale = 30000;
  box_fh.numUnitsInTick = 1001;
  box_fh.duration = 0; // to be updated at the end of coding
  box_fh.pixAspectRatioX = 1;
  box_fh.pixAspectRatioY = 1;
  box_fh.maxPicId = input->PicIdModulus - 1;
  box_fh.numAlternateTracks = 1;
  box_fh.numBytesInPayloadCountMinusOne = 1;
  box_fh.numBytesInPictureOffsetMinusTwo = 1;
  box_fh.numBytesInPictureDisplayTimeMinusOne = 1;
  box_fh.numBytesInPictureCountMinusOne = 1;
  box_fh.numBytesInPayloadSizeMinusOne = 1;
  return 0;
}

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

  box_fh.duration = box_ati.info[0].last_frame + 1;     // update

  num += writefile( &box_fh.type.size, 4, 1, fp );
  num += writefile( &box_fh.type.type, 4, 1, fp );
  num += writefile( &box_fh.majorVersion, 1, 1, fp );
  num += writefile( &box_fh.minorVersion, 1, 1, fp );
  num += writefile( &box_fh.timescale, 4, 1, fp );
  num += writefile( &box_fh.numUnitsInTick, 4, 1, fp );
  num += writefile( &box_fh.duration, 8, 1, fp );
  num += writefile( &box_fh.pixAspectRatioX, 2, 1, fp );
  num += writefile( &box_fh.pixAspectRatioY, 2, 1, fp );
  num += writefile( &box_fh.maxPicId, 2, 1, fp );
  num += writefile( &box_fh.numAlternateTracks, 1, 1, fp );

  cd = 0;
  cd = (box_fh.numBytesInPayloadCountMinusOne << 6) |
    (box_fh.numBytesInPictureOffsetMinusTwo << 4) |
    (box_fh.numBytesInPictureDisplayTimeMinusOne << 2) |
    (box_fh.numBytesInPictureCountMinusOne << 0);
  num += writefile( &cd, 1, 1, fp );

  cd = 0 +
    (box_fh.numBytesInPayloadSizeMinusOne << 6);
  num += writefile( &cd, 1, 1, fp );

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

/*!
 ************************************************************************
 * \brief
 *      Free the memory allocated for File Type Box
 *      Do nothing
 * \return
 *      None
 ************************************************************************
 */
void freeFileHeaderBox()
{
}

/*!
 ************************************************************************
 * \brief
 *      Initiate the Content Info Box
 *      Tian Dong, Feb 10, 2002:
 *      Do nothing, The Box is skipped in current implementation.
 * \return
 *      0, if success
 *      -1, otherwise
 ************************************************************************
 */
int initContentInfoBox()
{
  return 0;
}

/*!
 ************************************************************************
 * \brief
 *      The function to write the Content Info Box to output file
 * \return
 *      how many bytes been written, if success
 *      -1, if failed
 * \param fp
 *      output file pointer
 ************************************************************************
 */
size_t wrContentInfoBox( FILE* fp )
{
  return 0;
} 

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

// Functions on AlternateTrackInfoBox
/*!
 ************************************************************************
 * \brief
 *      Initiate the Alternate Track Info Box
 *      Tian Dong, Feb 10, 2002:
 *      Only one track media contained in the output file
 * \return
 *      0, if success
 *      -1, otherwise
 ************************************************************************
 */
int initAlternateTrackInfoBox()
{
  assert(box_fh.numAlternateTracks == 1);   // Only one track media contained in the output file

  box_ati.type.size = SIZEOF_BOXTYPE + 12 * box_fh.numAlternateTracks;
  box_ati.type.type = BOX_ATIN;

  box_ati.info = calloc( sizeof(AlternateTrackInfo), box_fh.numAlternateTracks );
  if ( box_ati.info == NULL ) return -1;

  box_ati.info[0].displayWindowWidth = input->img_width;
  box_ati.info[0].displayWindowHeight = input->img_height;
  box_ati.info[0].maxSDUSize = 0; // to be updated
  box_ati.info[0].avgSDUSize = 0; // to be updated
  box_ati.info[0].avgBitRate = 0; // to be updated

  box_ati.info[0].numSDU = 0;
  box_ati.info[0].sumSDUSize = 0;
  box_ati.info[0].last_frame = 0;
  return 0;
}

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

  assert( fp != NULL );

  // update avgSDUSize
  if ( box_ati.info[0].numSDU != 0 )
    box_ati.info[0].avgSDUSize = (unsigned INT16)(box_ati.info[0].sumSDUSize / box_ati.info[0].numSDU);
  t = (float)(box_ati.info[0].last_frame + 1) * (float)box_fh.numUnitsInTick / (float)box_fh.timescale;
  box_ati.info[0].avgBitRate = (INT32) (box_ati.info[0].sumSDUSize / t );

  // write them to the file
  num += writefile( &box_ati.type.size, 4, 1, fp );
  num += writefile( &box_ati.type.type, 4, 1, fp );

  num += writefile( &box_ati.info[0].displayWindowWidth, 2, 1, fp );
  num += writefile( &box_ati.info[0].displayWindowHeight, 2, 1, fp );
  num += writefile( &box_ati.info[0].maxSDUSize, 2, 1, fp );
  num += writefile( &box_ati.info[0].avgSDUSize, 2, 1, fp );
  num += writefile( &box_ati.info[0].avgBitRate, 4, 1, fp );

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

⌨️ 快捷键说明

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