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

📄 decodeiff.c

📁 jm61 的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
***********************************************************************
* 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 <stdlib.h>
#include <time.h>

#include "global.h"
#include "decodeiff.h"
#include "mbuffer.h"
#include "vlc.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 currPayloadInfo;
PictureInfo currPictureInfo, oldPictureInfo;
LayerBox box_layr[MAX_LAYER_NUMBER];
SubSequenceBox box_sseq[MAX_LAYER_NUMBER];
AlternateTrackMediaBox box_atm;
SwitchPictureBox box_sp;

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.

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
 *      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 )
{
  unsigned char cd;
  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.loopFilterParametersFlag, 1, 1, fp ) ) return -1;
  if ( -1 == readfile( &box_ps.entropyCoding, 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;

  if ( -1 == readfile( &cd, 1, 1, fp ) ) return -1;
  if ( cd == 0x80 ) box_ps.requiredPictureNumberUpdateBehavior= TRUE;
  else box_ps.requiredPictureNumberUpdateBehavior = FALSE;

  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
 ************************************************************************

⌨️ 快捷键说明

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