📄 decodeiff.c
字号:
* 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;
int ret = EOS + 100;
// FILE *f;
// f = fopen("dummy2.txt", "at");
if ( 0 != fseek( fp, box_ath.storedpos, SEEK_SET ) ) return -1;
if ( -1 == readfile( &numPictures, box_fh.numBytesInPictureCountMinusOne+1, 1, fp ) ) return -1;
currPictureInfo.storedpos = ftell( fp );
while ( numPictures-- > 0 && ret != EOS )
ret = decode_one_frame( img, inp, snr );
/* {
rdPictureInfo( fp );
fprintf( f, "picture payload, total %d:\n", currPictureInfo.numPayloads );
i=9;
while (i-- > 0)
{
ret = readSliceIFF( img, inp );
fprintf( f, "picture %d payload nr %d 's payloadsize: %d\n", currPayloadInfo.pictureID, currPayloadInfo.payloadnr, currPayloadInfo.payloadSize);
}
}
fclose( f ); */
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 )
{
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_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 = ftell( fp ); // 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 );
fseek( fp, currPictureInfo.storedpos, SEEK_SET );
num += readfile( &cd, 1, 1, fp );
if ( cd == 0x80 ) currPictureInfo.intraPictureFlag = 1;
else currPictureInfo.intraPictureFlag = 0;
num += readfile( &currPictureInfo.pictureOffset, box_fh.numBytesInPictureOffsetMinusTwo + 2, 1, fp );
num += readfile( &currPictureInfo.pictureDisplayTime, box_fh.numBytesInPictureDisplayTimeMinusOne+1, 1, fp );
num += readfile( &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 );
if ( -1 == readfile( &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:
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
currPictureInfo.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;
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->pictureID = sym.value1;
currSlice->picture_id = img->tr = sym.value1;
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->sliceType = sym.value1;
switch (sym.value1)
{
//! Potential BUG: do we need to distinguish between INTER_IMG_MULT and INTER_IMG?
//! similar with B_IMG_! and B_IMG_MULT
//! also: need to define Slice types for SP images
//! see VCEG-N72r1 for the Slice types, which are mapped here to img->type
case 0:
img->type = currSlice->picture_type = (inp->buf_cycle > 1)?INTER_IMG_MULT:INTER_IMG_1;
break;
case 1:
img->type = currSlice->picture_type = (inp->buf_cycle > 1)?B_IMG_MULT:B_IMG_1;
break;
case 2:
img->type = currSlice->picture_type = (inp->buf_cycle > 1)?SP_IMG_MULT:SP_IMG_1;
break;
case 3:
img->type = currSlice->picture_type = INTRA_IMG;
break;
default:
printf ("Panic: unknown Slice type %d, conceal by loosing slice\n", pp->sliceType);
currSlice->ei_flag = 1;
}
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->firstMBInSliceX = sym.value1;
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->firstMBInSliceY = sym.value1;
buf->frame_bitoffset += sym.len;
bitptr += sym.len;
currSlice->start_mb_nr = pp->firstMBInSliceY * box_ps.pictureWidthInMBs + pp->firstMBInSliceX;
sym.len = GetVLCSymbol( buf->streamBuffer, buf->frame_bitoffset, &sym.inf, buf->bitstream_length );
sym.mapping(sym.len, sym.inf, &(sym.value1), &(sym.value2));
pp->initialQP = MAX_QP - sym.value1;
currSlice->qp = img->qp = pp->initialQP;
buf->frame_bitoffset += sym.len;
bitptr += sym.len;
if ( inp->symbol_mode == CABAC )
{
sym.len = GetVLCSymbol( buf->streamBuffer, buf->frame_bitoffset, &sym.inf, buf->bitstream_length );
sym.mapping(sym.len, sym.inf, &(sym.value1), &(sym.value2));
pp->lastMBnr = sym.value1;
currSlice->last_mb_nr = sym.value1;
buf->frame_bitoffset += sym.len;
bitptr += sym.len;
}
if ( img->type == SP_IMG_1 || img->type == SP_IMG_MULT )
{
sym.len = GetVLCSymbol( buf->streamBuffer, buf->frame_bitoffset, &sym.inf, buf->bitstream_length );
sym.mapping(sym.len, sym.inf, &(sym.value1), &(sym.value2));
img->qpsp = MAX_QP - sym.value1;
buf->frame_bitoffset += sym.len;
bitptr += sym.len;
}
// Multi-Picture Buffering Syntax, Feb 27, 2002
// RPSF: Reference Picture Selection Flags
sym.len = GetVLCSymbol( buf->streamBuffer, buf->frame_bitoffset, &(sym.inf), buf->bitstream_length );
sym.mapping(sym.len, sym.inf, &(sym.value1), &(sym.value2));
buf->frame_bitoffset += sym.len;
bitptr+=sym.len;
// PN: Picture Number
sym.len = GetVLCSymbol( buf->streamBuffer, buf->frame_bitoffset, &(sym.inf), buf->bitstream_length );
sym.mapping(sym.len, sym.inf, &(sym.value1), &(sym.value2));
buf->frame_bitoffset += sym.len;
bitptr+=sym.len;
img->pn=sym.value1;
// RPSL: Reference picture selection layer
sym.len = GetVLCSymbol( buf->streamBuffer, buf->frame_bitoffset, &(sym.inf), buf->bitstream_length );
sym.mapping(sym.len, sym.inf, &(sym.value1), &(sym.value2));
buf->frame_bitoffset += sym.len;
bitptr+=sym.len;
if (sym.value1)
{
// read Reference Picture Selection Layer
// free old buffer content
while (img->currentSlice->rmpni_buffer)
{
tmp_rmpni=img->currentSlice->rmpni_buffer;
img->currentSlice->rmpni_buffer=tmp_rmpni->Next;
free (tmp_rmpni);
}
done=0;
// if P or B frame RMPNI
if ((img->type==INTER_IMG_1)||(img->type==INTER_IMG_MULT)||(img->type==B_IMG_1)||
(img->type==B_IMG_MULT)||(img->type==SP_IMG_1)||(img->type==SP_IMG_MULT))
{
do
{
sym.len = GetVLCSymbol( buf->streamBuffer, buf->frame_bitoffset, &(sym.inf), buf->bitstream_length );
sym.mapping(sym.len, sym.inf, &tmp1, &(sym.value2));
buf->frame_bitoffset += sym.len;
bitptr+=sym.len;
// check for illegal values
if ((tmp1<0)||(tmp1>3))
error ("Invalid RMPNI operation specified",400);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -