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

📄 decodeiff.c

📁 jm61 的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
 */
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
 *      input file pointer
 * \param size
 *      size of the box
 ************************************************************************
 */
int parse_one_segment( struct img_par* img, struct inp_par* inp, struct snr_par *snr, FILE* fp, size_t size )
{
  unsigned long limited, storedpos;

  limited = ftell( fp );
  limited += (size - SIZEOF_BOXTYPE);

  if ( -1 == readfile( &box_s.fileSize, 8, 1, fp ) ) return -1;
  if ( -1 == readfile( &box_s.startTick, 8, 1, fp ) ) return -1;
  if ( -1 == readfile( &box_s.segmentDuration, 8, 1, fp ) ) return -1;
  // storedpos will save the file pointer to point to the current track header
  storedpos = ftell( fp );
  if ( -1 == find_track_meta( fp, limited, &box_ath.storedpos, ThisAlternateTrack ) ) return -1;
  if ( 0 != fseek( fp, storedpos, SEEK_SET ) ) return -1;
  if ( -1 == find_track_media( fp, limited, &box_atm.storedpos, ThisAlternateTrack ) ) return -1;

  if ( -1 == rdOneTrack( img, inp, snr, fp ) ) return -1;

  return 0;
}

/*!
 ************************************************************************
 * \brief
 *      Free all the resources allocated for the segment
 * \return
 *      None
 ************************************************************************
 */
void freeSegmentBox()
{
  freeAlternateTrackHeaderBox();
  freeAlternateTrackMediaBox();
}

/*!
 ************************************************************************
 * \brief
 *      read and decode all the frames in one track of a segment
 * \return
 *      0, if success
 *      -1, otherwise
 * \param img
 *      image pointer
 * \param inp
 *      input parameter pointer
 * \param snr
 *      snr pointer
 * \param fp
 *      input file pointer
 ************************************************************************
 */
int rdOneTrack( struct img_par* img, struct inp_par* inp, struct snr_par *snr, FILE *fp )
{
  unsigned long numPictures, pos;
  unsigned long size, type, boxsize, readsize;
  int ret = EOS + 100;
  int layerno = 0;

  numPictures=0;

  if ( 0 != fseek( fp, box_ath.storedpos, SEEK_SET ) ) return -1; // ath
  if ( -1 == readfile( &boxsize, 4, 1, fp ) ) return -1;
  if ( boxsize == 0 ) return -1;
  if ( -1 == readfile( &type, 4, 1, fp ) ) return -1;
  assert( type == BOX_ATRH );

  if ( -1 == readfile( &box_ath.numLayers, 1, 1, fp ) ) return -1;

  pos = ftell( fp );
  boxsize = boxsize - SIZEOF_BOXTYPE - 1;
  readsize = 0;
  while ( readsize < boxsize )
  {
    if ( 0 != fseek( fp, pos, SEEK_SET ) ) return -1;
    if ( -1 == readfile( &size, 4, 1, fp ) ) return -1;
    if ( size == 0 ) return -1;
    if ( -1 == readfile( &type, 4, 1, fp ) ) return -1;
    
    switch ( type )
    {
    case BOX_PICI:
      if ( -1 == readfile_s( &numPictures, sizeof(unsigned long), box_fh.numBytesInPictureCountMinusOne+1, 1, fp ) ) return -1;
        box_ath.storedpos = ftell( fp );
      while ( numPictures-- > 0 && ret != EOS )
        ret = decode_one_frame( img, inp, snr );
      break;
    case BOX_LAYR:
      rdLayerBox(layerno++, size, fp);
      break;
    default:
      printf("Unknow boxes found in the track!\n");
      exit(0);
      break;
    }
    readsize += size;
    pos += size;
  }
  return 0;
}

/*!
 ************************************************************************
 * \brief
 *      try to find the ATRH box from the input file
 * \return
 *      0, if success
 *      -1, otherwise
 * \param fp
 *      input file pointer
 * \param limited
 *      how far will go to find it
 * \param storedpos
 *      if found, save the position 
 * \param tracknr
 *      which track to find
 ************************************************************************
 */
int find_track_meta( FILE *fp, unsigned long limited, unsigned long* storedpos, int tracknr )
{
  int nr = -1;
  unsigned long size, type, pos;

  *storedpos = 0;

  assert( fp != NULL );
  assert( tracknr < box_fh.numAlternateTracks );

  pos = 0;
  while ( tracknr > nr && pos < limited && pos != (unsigned long)-1 )
  {
    pos = (unsigned)ftell(fp);
    if ( -1 == readfile( &size, 4, 1, fp ) ) return -1;     // in 32 bits mode
    if ( -1 == readfile( &type, 4, 1, fp ) ) return -1;
    if ( type == BOX_ATRH ) nr++;
    if ( tracknr > nr )
    { if ( 0 != fseek( fp, size - SIZEOF_BOXTYPE, SEEK_CUR ) ) return -1; }
  }

  if ( tracknr != nr ) return -1;     // have not found the track needed

  *storedpos = pos;           // save the file pointer to the track header
  return 0;
}

/*!
 ************************************************************************
 * \brief
 *      try to find the ATRM box from the input file
 * \return
 *      0, if success
 *      -1, otherwise
 * \param fp
 *      input file pointer
 * \param limited
 *      how far will go to find it
 * \param storedpos
 *      if found, save the position 
 * \param tracknr
 *      which track to find
 ************************************************************************
 */
int find_track_media( FILE *fp, unsigned long limited, unsigned long* storedpos, int tracknr )
{
  int nr = -1;
  unsigned long size, type, pos;

  *storedpos = 0;

  assert( fp != NULL );
  assert( tracknr < box_fh.numAlternateTracks );

  pos = 0;
  while ( tracknr > nr && pos < limited && pos != (unsigned long)-1 )
  {
    if ( -1 == readfile( &size, 4, 1, fp ) ) return -1;     // in 32 bits mode
    if ( -1 == readfile( &type, 4, 1, fp ) ) return -1;
    pos = (unsigned)ftell(fp);
    if ( type == BOX_ATRM ) nr++;
    if ( tracknr > nr )
    { if ( 0 != fseek( fp, size - SIZEOF_BOXTYPE, SEEK_CUR ) ) return -1; }
  }

  if ( tracknr != nr ) return -1;     // have not found the track needed

  *storedpos = ftell( fp );           // save the file pointer to the track header
  box_atm.currPictureOffset = *storedpos;   // maintain the media data pointer
  box_atm.currPayloadOffset = *storedpos;
  return 0;
}

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

/*!
 ************************************************************************
 * \brief
 *      Read the picture info before it is decoded
 * \return
 *      0, if success
 *      -1, otherwise
 * \param fp
 *      input file pointer
 ************************************************************************
 */
int rdPictureInfo( FILE* fp )
{
  byte cd;
  size_t num = 0;
  
  assert( fp != NULL );

  memcpy( &oldPictureInfo, &currPictureInfo, sizeof(PictureInfo) );

  fseek( fp, box_ath.storedpos, SEEK_SET );

  num += readfile( &cd, 1, 1, fp );
  if ( (cd&0x80) != 0 ) currPictureInfo.intraPictureFlag = TRUE;
  else currPictureInfo.intraPictureFlag = FALSE;
  if ( (cd&0x40) != 0 ) currPictureInfo.syncPictureFlag = TRUE;
  else currPictureInfo.syncPictureFlag = FALSE;

  currPictureInfo.pictureOffset=0;
  currPictureInfo.pictureDisplayTime=0;
  currPictureInfo.numPayloads=0;

  num += readfile_s( &currPictureInfo.pictureOffset, sizeof(currPictureInfo.pictureOffset), box_fh.numBytesInPictureOffsetMinusTwo + 2, 1, fp );
  num += readfile_s( &currPictureInfo.pictureDisplayTime, sizeof(currPictureInfo.pictureDisplayTime), box_fh.numBytesInPictureDisplayTimeMinusOne+1, 1, fp );

  if (box_ath.numLayers != 0)
  {
    if ( -1 == readfile( &currPictureInfo.layerNumber, 1, 1, fp ) ) return -1;
    if ( -1 == readfile( &currPictureInfo.subSequenceIdentifier, 2, 1, fp ) ) return -1;
    if ( currPictureInfo.syncPictureFlag )
    {
      if ( -1 == readfile( &currPictureInfo.originLayerNumber, 1, 1, fp ) ) return -1;
      if ( -1 == readfile( &currPictureInfo.originSubSequenceIdentifier, 2, 1, fp ) ) return -1;
    }
  }

  num += readfile_s( &currPictureInfo.numPayloads, sizeof(currPictureInfo.numPayloads), box_fh.numBytesInPayloadCountMinusOne+1, 1, fp );

  if ( num != (unsigned)(1+box_fh.numBytesInPictureOffsetMinusTwo + 2 +
    box_fh.numBytesInPictureDisplayTimeMinusOne+1 +
    box_fh.numBytesInPayloadCountMinusOne+1) ) 
    return -1;

  currPayloadInfo.storedpos = ftell( fp );  // update the pointer, it will be increased when read one payload info
  currPayloadInfo.payloadnr = 0;
  BeginOfPictureOrSlice = SOP;
  return 0;
}

/*!
 ************************************************************************
 * \brief
 *      read the payloadinfo data and set the decoder parameter
 * \return
 *      0, if success
 *      -1, otherwise
 * \param img
 *      image pointer
 * \param inp
 *      input parameter pointer
 * \param pp
 *      read the data to pp
 * \param fp
 *      input file pointer
 ************************************************************************
 */
int rdPayloadInfo( struct img_par *img, struct inp_par* inp, PayloadInfo* pp, FILE *fp )
{
  byte cd;

  assert( fp != NULL );

  fseek( fp, pp->storedpos, SEEK_SET );

  pp->payloadSize=0;
  if ( -1 == readfile_s( &pp->payloadSize, sizeof (pp->payloadSize), box_fh.numBytesInPayloadSizeMinusOne+1, 1, fp ) ) return -1;
  if ( -1 == readfile( &pp->headerSize, 1, 1, fp ) ) return -1;
  if ( -1 == readfile( &cd, 1, 1, fp ) ) return -1;
  pp->payloadType = (cd >> 4);
  pp->errorIndication = ((cd&0x0F) >> 3);
  pp->reserved = (cd & 0x07);

  switch ( pp->payloadType )
  {
  case 0:
  case PAYLOAD_TYPE_IDERP:
    pp->buffer.bitstream_length = pp->headerSize - (box_fh.numBytesInPayloadSizeMinusOne+1 + 2);
    pp->buffer.streamBuffer = alloca( pp->buffer.bitstream_length );
    assert( pp->buffer.streamBuffer != NULL );
    if ( fread( pp->buffer.streamBuffer, 1, pp->buffer.bitstream_length, fp ) != (unsigned)pp->buffer.bitstream_length )
      return -1;
    pp->buffer.frame_bitoffset = 0;
    decomposeSliceHeader( img, inp, pp );
    break;
  default:
    // not supported now.
    assert( 0 == 1 );
    break;
  }

  pp->payloadnr++;
  if ( currPictureInfo.numPayloads == pp->payloadnr ) // the last payloadinfo is read, set the position of next pic
    box_ath.storedpos = ftell( fp );
  else // next payloadinfo 
    pp->storedpos = ftell( fp );

  return 0;
}

/*!
 ************************************************************************
 * \brief
 *      set the decoder parameter according to a payloadinfo
 * \return
 *      None
 * \param img
 *      image pointer
 * \param inp
 *      input parameter pointer
 * \param pp
 *      read the data to pp
 ************************************************************************
 */
void decomposeSliceHeader( struct img_par *img, struct inp_par* inp, PayloadInfo* pp )
{
  SyntaxElement sym;
  Bitstream* buf;
  Slice *currSlice = img->currentSlice;
  int bitptr = 0;
  int tmp1;
  RMPNIbuffer_t *tmp_rmpni,*tmp_rmpni2;
  MMCObuffer_t *tmp_mmco,*tmp_mmco2;
  int done;
  static int last_imgtr_frm=0,modulo_ctr_frm=0,last_imgtr_fld=0,modulo_ctr_fld=0;
  static int last_imgtr_frm_b=0,modulo_ctr_frm_b=0,last_imgtr_fld_b=0,modulo_ctr_fld_b=0;

  buf = &(pp->buffer);

  sym.type = SE_HEADER;       // This will be true for all symbols generated here
  sym.mapping = linfo;        // Mapping rule: Simple code number to len/info
  
  sym.len = GetVLCSymbol( buf->streamBuffer, buf->frame_bitoffset, &sym.inf, buf->bitstream_length );
  sym.mapping(sym.len, sym.inf, &(sym.value1), &(sym.value2));
  pp->parameterSet = sym.value1;
  IFFUseParameterSet( pp->parameterSet, img, inp );
  buf->frame_bitoffset += sym.len;
  bitptr += sym.len;

  sym.len = GetVLCSymbol( buf->streamBuffer, buf->frame_bitoffset, &sym.inf, buf->bitstream_length );
  sym.mapping(sym.len, sym.inf, &(sym.value1), &(sym.value2));
  pp->structure = sym.value1;
  currSlice->structure = img->structure = sym.value1;
  buf->frame_bitoffset += sym.len;

⌨️ 快捷键说明

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