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

📄 decodeiff.c

📁 h.264/avc 视频编码程序,实现分数像素匹配功能,非原创.
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
***********************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2001, International Telecommunications Union, Geneva
*
* DISCLAIMER OF WARRANTY
*
* These software programs are available to the user without any
* license fee or royalty on an "as is" basis. The ITU disclaims
* any and all warranties, whether express, implied, or
* statutory, including any implied warranties of merchantability
* or of fitness for a particular purpose.  In no event shall the
* contributor or the ITU be liable for any incidental, punitive, or
* consequential damages of any kind whatsoever arising from the
* use of these programs.
*
* This disclaimer of warranty extends to the user of these programs
* and user's customers, employees, agents, transferees, successors,
* and assigns.
*
* The ITU does not represent or warrant that the programs furnished
* hereunder are free of infringement of any third-party patents.
* Commercial implementations of ITU-T Recommendations, including
* shareware, may be subject to royalty fees to patent holders.
* Information regarding the ITU-T patent policy is available from
* the ITU Web site at http://www.itu.int.
*
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE ITU-T PATENT POLICY.
************************************************************************
*/

/*!
 ************************************************************************
 *  \file
 *     decodeiff.c
 *  \brief
 *     Impelentation of the interim file format 
 *     as defined in Appendix III of WD-1 (JVT-A003).
 *
 *     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 encoder 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.
 *
 *     The box header only permits compact size (32 bits mode)
 *     data partition is not supported.
 *     The source code supports multiple segments per file, but
 *     the feature has not been tested.
 *      
 *  \author
 *      - Dong Tian                              <tian@cs.tut.fi>
 *      - Miska M. Hannuksela                    <miska.hannuksela@nokia.com>
 ************************************************************************
 */

/*!
 ************************************************************************
 *  \flowchart
 * main()
 * {
 *   init
 *   IFFSequenceHeader(); // Read the first Boxes, and set the initial parameter set 
 *                        // according to the input file
 *   if ( inp->of_mode == PAR_OF_IFF )
 *     while ( parse_one_box() != -1 );
 *   else
 *     while (decode_one_frame() != EOS);
 * }
 * 
 * parse_one_box()
 * {
 *   call different funcitons according to the box type
 *   switch( box type )
 *   {
 *     ......
 *     case segment:
 *       parse_one_segment
 *       {
 *         while ( decode_one_frame() );
 *       }
 *     break;
 *     ......
 *   }
 * }
 ************************************************************************
 */

#include <stdio.h>
#include <assert.h>
#include <memory.h>
#include <malloc.h>
#include "global.h"
#include "decodeiff.h"

FileTypeBox box_ft;
FileHeaderBox box_fh;
ContentInfoBox box_ci;
AlternateTrackInfoBox box_ati;
ParameterSetBox box_ps;
SegmentBox box_s;
AlternateTrackHeaderBox box_ath;
PayloadInfo currPayloadInfo;
PictureInfo currPictureInfo;
AlternateTrackMediaBox box_atm;
SwitchPictureBox box_sp;

extern int CurrentParameterSet=-1;  // Tian Dong: must not be set to 0 here.
static int BeginOfPictureOrSlice; // SOP or SOS
int IFFEndOfFile = FALSE;
int ThisAlternateTrack = 0;   // indicate which track in the file will be decoded.

/*!
 ************************************************************************
 * \brief
 *      Test the file if it is in Interim File Format by reading FileTypeBox
 * \return
 *      0, if it is in Interim File Format
 *      -1, otherwise
  * \param fp
 *      input file pointer
************************************************************************
 */
int testFileTypeBox(FILE* fp)
{
  int left;
  int size, x;

  assert( fp != NULL );

  box_ft.compatibleBrands = NULL;

  x = readfile( &box_ft.type.size, 4, 1, fp );
  if ( -1 == x ) return -1;
  x = readfile( &box_ft.type.type, 4, 1, fp );
  if ( -1 == x ) return -1;
  size = box_ft.type.size;
  if ( box_ft.type.type != BOX_FTYP ) return -1;

  if ( box_ft.type.size > 0 )
  {
    x = readfile( box_ft.majorBrand, 4, 1, fp );
    if ( -1 == x ) return -1;
    x = readfile( &box_ft.jmMajorVersion, 2, 1, fp );
    if ( -1 == x ) return -1;
    x = readfile( &box_ft.jmMinorVersion, 2, 1, fp );
    if ( -1 == x ) return -1;

    if ( box_ft.jmMajorVersion != WORKING_DRAFT_MAJOR_NO ||
      box_ft.jmMinorVersion != WORKING_DRAFT_MINOR_NO)    
    {
      printf( "Error: The working draft version is not supported.\n" );
      return -1;
    }

    left = (int)size - SIZEOF_BOXTYPE - 8;
    box_ft.compatibleBrands = calloc( 1, left );
    box_ft.numCompatibleBrands = left / 4;
    x = fread( box_ft.compatibleBrands, 1, left, fp );
    if ( left != x ) return -1;
  }
  return 0;
}

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

/*!
 ************************************************************************
 * \brief
 *      Read the File Header Box
 * \return
 *      0, if success
 *      -1, otherwise
 * \param fp
 *      input file pointer
 * \param size
 *      size of the box
 ************************************************************************
 */
int rdFileHeaderBox( FILE* fp, size_t size )
{
  byte cd;
  int x;
  assert( fp != NULL );

  x = readfile(&box_fh.majorVersion, 1, 1, fp);
  if ( -1 == x ) return -1;
  x = readfile(&box_fh.minorVersion, 1, 1, fp);
  if ( -1 == x ) return -1;

  if ( 
    box_fh.majorVersion != INTERIM_FILE_MAJOR_NO ||
    box_fh.minorVersion != INTERIM_FILE_MINOR_NO )
  {
    printf( "Error: The interim file format version is not supported.\n" );
    return -1;
  }

  x = readfile(&box_fh.timescale, 4, 1, fp);
  if ( -1 == x ) return -1;
  x = readfile(&box_fh.numUnitsInTick, 4, 1, fp);
  if ( -1 == x ) return -1;
  x = readfile(&box_fh.duration, 8, 1, fp);
  if ( -1 == x ) return -1;
  x = readfile(&box_fh.pixAspectRatioX, 2, 1, fp);
  if ( -1 == x ) return -1;
  x = readfile(&box_fh.pixAspectRatioY, 2, 1, fp);
  if ( -1 == x ) return -1;
  x = readfile(&box_fh.maxPicId, 2, 1, fp);
  if ( -1 == x ) return -1;
  x = readfile(&box_fh.numAlternateTracks, 1, 1, fp);
  if ( -1 == x ) return -1;
  x = readfile(&cd, 1, 1, fp);
  if ( -1 == x ) return -1;
  box_fh.numBytesInPayloadCountMinusOne = (cd >> 6);
  box_fh.numBytesInPictureOffsetMinusTwo = ((cd & 0x3F) >> 4);
  box_fh.numBytesInPictureDisplayTimeMinusOne = ((cd & 0x0f) >> 2);
  box_fh.numBytesInPictureCountMinusOne = (cd & 0x03);
  x = readfile(&cd, 1, 1, fp);
  if ( -1 == x ) return -1;
  box_fh.numBytesInPayloadSizeMinusOne = (cd >> 6);

  return 0;
}

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

/*!
 ************************************************************************
 * \brief
 *      Tian Dong, Feb 10, 2002:
 *      Just move the file pointer forward to skip the content info box
 * \return
 *      0, if success
 *      -1, otherwise
 * \param fp
 *      input file pointer
 * \param size
 *      size of the box
 ************************************************************************
 */
int rdContentInfoBox( FILE* fp, size_t size )
{
  // do nothing
  if ( 0 != fseek( fp, size - SIZEOF_BOXTYPE, SEEK_CUR ) ) return -1;
  return 0;
}

/*!
 ************************************************************************
 * \brief
 *      Free the memory allocated for Content Info Box
 *      Do nothing
 * \return
 *      None
 ************************************************************************
 */
void freeContentInfoBox()
{
}

/*!
 ************************************************************************
 * \brief
 *      Read the Alterate Track Info Box
 *      Tian Dong, Feb 10, 2002:
 *      Only one track in the input file
 * \return
 *      0, if success
 *      -1, otherwise
 * \param fp
 *      input file pointer
 * \param size
 *      size of the box
 ************************************************************************
 */
int rdAlternateTrackInfoBox( FILE* fp, unsigned long size )
{
  assert( fp != NULL );
  assert( box_fh.numAlternateTracks == 1 );
  box_ati.info = NULL;
  box_ati.info = calloc( box_fh.numAlternateTracks, sizeof(AlternateTrackInfo) );
  if ( box_ati.info == NULL ) return -1;
  if ( -1 == readfile( &box_ati.info[0].displayWindowWidth, 2, 1, fp ) ) return -1;
  if ( -1 == readfile( &box_ati.info[0].displayWindowHeight, 2, 1, fp ) ) return -1;
  if ( -1 == readfile( &box_ati.info[0].maxSDUSize, 2, 1, fp ) ) return -1;
  if ( -1 == readfile( &box_ati.info[0].avgSDUSize, 2, 1, fp ) ) return -1;
  if ( -1 == readfile( &box_ati.info[0].avgBitRate, 4, 1, fp ) ) return -1;

  return 0;
}

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

/*!
 ************************************************************************
 * \brief
 *      Read the ParameterSet Box
 *      Tian Dong, Feb 10, 2002:
 *      Only one Parameter Set Box in the input file
 * \return
 *      0, if success
 *      -1, otherwise
 * \param fp
 *      input file pointer
 * \param size
 *      size of the box
 ************************************************************************
 */
int rdParameterSetBox( FILE* fp, unsigned long size )
{
  assert( fp );

  if ( -1 == readfile( &box_ps.parameterSetID, 2, 1, fp ) ) return -1;
  if ( -1 == readfile( &box_ps.profile, 1, 1, fp ) ) return -1;
  if ( -1 == readfile( &box_ps.level, 1, 1, fp ) ) return -1;
  if ( -1 == readfile( &box_ps.version, 1, 1, fp ) ) return -1;
  if ( -1 == readfile( &box_ps.pictureWidthInMBs, 2, 1, fp ) ) return -1;
  if ( -1 == readfile( &box_ps.pictureHeightInMBs, 2, 1, fp ) ) return -1;
  if ( -1 == readfile( &box_ps.displayRectangleOffsetTop, 2, 1, fp ) ) return -1;
  if ( -1 == readfile( &box_ps.displayRectangleOffsetLeft, 2, 1, fp ) ) return -1;
  if ( -1 == readfile( &box_ps.displayRectangleOffsetBottom, 2, 1, fp ) ) return -1;
  if ( -1 == readfile( &box_ps.displayRectangleOffsetRight, 2, 1, fp ) ) return -1;
  if ( -1 == readfile( &box_ps.displayMode, 1, 1, fp ) ) return -1;
  if ( -1 == readfile( &box_ps.displayRectangleOffsetFromWindowTop, 2, 1, fp ) ) return -1;
  if ( -1 == readfile( &box_ps.displayRectangleOffsetFromWindowLeftBorder, 2, 1, fp ) ) return -1;
  if ( -1 == readfile( &box_ps.entropyCoding, 1, 1, fp ) ) return -1;
  if ( -1 == readfile( &box_ps.motionResolution, 1, 1, fp ) ) return -1;
  if ( -1 == readfile( &box_ps.partitioningType, 1, 1, fp ) ) return -1;
  if ( -1 == readfile( &box_ps.intraPredictionType, 1, 1, fp ) ) return -1;
  if ( -1 == readfile( &box_ps.bufCycle, 1, 1, fp ) ) return -1;

  return 0;
}

/*!
 ************************************************************************
 * \brief
 *      From the current position, find the parameter set which id is given.
 *      The file pointer must point to the beginning of a box.
 * \return
 *      0, if success
 *      -1, otherwise
 * \param fp
 *      input file pointer
 * \param pos
 *      used to store the parameter set box's position
 * \param pid
 *      give the id of the wanted parameter set
 ************************************************************************
 */
int findParameterSetBox( FILE* fp, long *pos, int pid )
{
  int id, size, type;

  assert( fp );
  while( !feof( fp ) )
  {
    if ( readfile( &size, 4, 1, fp ) == -1 ) return -1;
    if ( readfile( &type, 4, 1, fp ) == -1 ) return -1;
    if ( type == BOX_PRMS )
    {
      if ( readfile( &id, 4, 1, fp ) == -1 ) return -1;
      if ( id == pid ) 
      {
        *pos = ftell( fp ) - 4;
        return 0;   // succeed
      }
      if ( 0 != fseek( fp, size-12, SEEK_CUR ) ) return -1;
    }
    else
    {
      if ( 0 != fseek( fp, size-8, SEEK_CUR ) ) return -1;
    }
  }
  return -1;
}

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

/*!
 ************************************************************************
 * \brief
 *      parse one segment
 *      Tian Dong, Feb 10, 2002:
 *      Only one Parameter Set Box in the input file
 * \return
 *      0, if success
 *      -1, otherwise
 * \param img
 *      image pointer
 * \param inp
 *      input parameter pointer
 * \param snr
 *      snr pointer
 * \param fp

⌨️ 快捷键说明

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