📄 decodeiff.c
字号:
*/
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 + -