📄 decodeiff.c
字号:
currStream->bitstream_length = (int) pp->payloadSize = EBSPtoRBSP( buf, (int) pp->payloadSize, 0);
currStream->bitstream_length = (int) pp->payloadSize = RBSPtoSODB( buf, (int) pp->payloadSize);
currSlice->ei_flag = 0;
currSlice->dp_mode = PAR_DP_1;
currSlice->max_part_nr=1;
read_len = &(currSlice->partArr[0].bitstream->read_len);
*read_len = (int)pp->payloadSize;
if(active_pps->entropy_coding_mode == CABAC)
{
dep = &((currSlice->partArr[0]).de_cabac);
arideco_start_decoding(dep, buf, 0, read_len, img->type);
}
// At this point the slice is ready for decoding.
currSlice->next_header = IFFGetFollowingSliceHeader(img, pp); // no use for the info in nextp, nextsh yet.
return 0;
}
IFFEndOfFile = TRUE;
return -1;
}
/*!
************************************************************************
* \brief
* To check if the last payload in the current picture is read
* \return
* SOP, if TRUE
* SOS, if FALSE, means there are more slices or payloads
* \param img
* image pointer
* \param pp
* corresponding payloadinfo
************************************************************************
*/
int IFFGetFollowingSliceHeader( struct img_par *img, PayloadInfo* pp )
{
if ( currPictureInfo.numPayloads == pp->payloadnr ) // the last payloadinfo is read, set the position of next pic
return SOP;
else // next payloadinfo
return SOS;
}
/*!
************************************************************************
* \brief
* Do nothing
* \return
* None
************************************************************************
*/
void freeAlternateTrackMediaBox()
{
}
/*!
************************************************************************
* \brief
* use parameter set n to set the decoder parameters
* \return
* 0, if success
* -1, otherwise
* \param n
* indicate which parameter set will be used
* \param img
* image pointer
* \param inp
* input parameter pointer
************************************************************************
*/
int IFFUseParameterSet( int n, struct img_par* img, struct inp_par* inp )
{
if ( n == CurrentParameterSet )
return 0;
CurrentParameterSet = n;
img->width = box_ps.pictureWidthInMBs * MB_BLOCK_SIZE;
img->width_cr = box_ps.pictureWidthInMBs * MB_BLOCK_SIZE / 2;
img->height = box_ps.pictureHeightInMBs * MB_BLOCK_SIZE;
img->height_cr = box_ps.pictureHeightInMBs * MB_BLOCK_SIZE / 2;
if ( box_ps.entropyCoding == 0 ) active_pps->entropy_coding_mode = UVLC;
else active_pps->entropy_coding_mode = CABAC;
//! inp->partition_mode = box_ps.partitioningType;
//! inp->UseConstrainedIntraPred = box_ps.intraPredictionType;
inp->buf_cycle = box_ps.bufCycle;
inp->LFParametersFlag = box_ps.loopFilterParametersFlag;
return 0;
}
/*!
************************************************************************
* \brief
* read one slice from the input file
* \return
* EOS, if met with the end of sequence
* SOP, if this is the start of a picture
* SOS, if this is the start of a slice
* \param img
* image pointer
* \param inp
* input parameter pointer
************************************************************************
*/
int readSliceIFF( struct img_par* img, struct inp_par* inp )
{
extern FILE *bits;
if ( IFFEndOfFile )
return EOS;
if ( -1 == rdPayloadInfo(img, inp, &currPayloadInfo, bits) ) return EOS;
if ( -1 == rdOnePayload(img, inp, &currPayloadInfo, bits ) ) return EOS;
if ( BeginOfPictureOrSlice == SOP )
{
BeginOfPictureOrSlice = SOS;
return SOP;
}
return SOS;
}
/*!
************************************************************************
* \brief
* read the data from file, bytes are in big Endian order.
* \return
* how many bytes being read, if success
* -1, otherwise
* \param outf
* output file pointer
************************************************************************
*/
int readfile( void* buf, size_t size, size_t count, FILE* fp )
{
byte* p;
int num = 0;
if (isBigEndian)
p = (byte*)buf;
else
p = (byte*)buf+size-1;
assert( fp != NULL );
assert( buf != NULL );
assert( count == 1 );
while ( size > 0 )
{
if (isBigEndian)
{
if ( fread( p++, 1, 1, fp ) != 1 ) return -1;
}
else
{
if ( fread( p--, 1, 1, fp ) != 1 ) return -1;
}
size--;
num++;
}
return num;
}
/*!
************************************************************************
* \brief
* read the data from file, bytes are in big Endian order.
* to be used if buffers size differs from number of written bytes
* \return
* how many bytes being read, if success
* -1, otherwise
* \param outf
* output file pointer
************************************************************************
*/
int readfile_s( void* buf, size_t bufsize, size_t size, size_t count, FILE* fp )
{
byte* p;
int num = 0;
if (isBigEndian)
p = (byte*)buf+(bufsize-size);
else
p = (byte*)buf+size-1;
assert( fp != NULL );
assert( buf != NULL );
assert( count == 1 );
while ( size > 0 )
{
if (isBigEndian)
{
if ( fread( p++, 1, 1, fp ) != 1 ) return -1;
}
else
{
if ( fread( p--, 1, 1, fp ) != 1 ) return -1;
}
size--;
num++;
}
return num;
}
/*!
************************************************************************
* \brief
* read one box, and then parse it.
* \return
* 0, if success
* -1, otherwise
* \param img
* image pointer
* \param inp
* input parameter pointer
* \param snr
* snr pointer
* \param bits
* input file pointer
************************************************************************
*/
int parse_one_box( struct img_par* img, struct inp_par* inp, struct snr_par* snr, FILE* fp )
{
unsigned int type, size, storedpos;
assert( fp );
storedpos = ftell( fp );
size = -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_JVTH: //<!
if ( -1 == rdFileHeaderBox( fp, size ) ) return -1;
break;
case BOX_CINF: //<!
if ( -1 == rdContentInfoBox( fp, size ) ) return -1;
break;
case BOX_ATIN: //<!
if ( -1 == rdAlternateTrackInfoBox( fp, size ) ) return -1;
break;
case BOX_PRMS: //<!
if ( -1 == rdParameterSetBox( fp, size ) ) return -1;
break;
case BOX_SEGM: //<!
if ( -1 == parse_one_segment( img, inp, snr, fp, size ) ) return -1;
break;
case BOX_ATRH: //<!
case BOX_SWPC: //<!
case BOX_ATRM: //<!
default:
printf( "Unexpected boxs %d at %ld\n", type, ftell( fp ));
return -1;
break;
}
// point to the next box
if ( 0 != fseek( fp, storedpos+size, SEEK_SET ) ) return -1;
return 0;
}
/*!
************************************************************************
* \brief
* Read the first Boxes, and set the initial parameter set according to the input file
* \return
* 0, if success
* -1, otherwise
* \param img
* image pointer
* \param inp
* input parameter pointer
* \param bits
* input file pointer
************************************************************************
*/
int IFFSequenceHeader( struct img_par *img, struct inp_par *inp, FILE *bits )
{
unsigned long size, type;
long storedpos, pos;
assert( bits != NULL );
memset(&currPictureInfo, 0, sizeof(PictureInfo));
memset(&oldPictureInfo, 0, sizeof(PictureInfo));
// read FileTypeBox
if ( -1 == testFileTypeBox( bits ) ) return -1;
size = -1;
if ( -1 == readfile( &size, 4, 1, bits ) ) return -1;
if ( size == 0 ) return -1;
if ( -1 == readfile( &type, 4, 1, bits ) ) return -1;
if ( type != BOX_JVTH ) return -1;
if ( -1 == rdFileHeaderBox( bits, size ) ) return -1;
// now, try to find the parameter set box, which parametersetID is equal to CurrentParameterSet
storedpos = ftell( bits );
if ( 0 != findParameterSetBox( bits, &pos, 0 ) ) return -1;
fseek( bits, pos, SEEK_SET );
if ( -1 == rdParameterSetBox( bits, 0 ) ) return -1;
IFFUseParameterSet( 0, img, inp ); // use parameter set 0
fseek( bits, storedpos, SEEK_SET );
return 0;
}
/*!
************************************************************************
* \brief
* finished, free all resources allocated for interim file format
* \return
* None
* \param img
* image pointer
* \param inp
* input parameter pointer
* \param bits
* input file pointer
************************************************************************
*/
void terminateInterimFile()
{
freeSegmentBox();
freeParameterSetBox();
freeAlternateTrackInfoBox();
freeContentInfoBox();
freeFileHeaderBox();
freeFileTypeBox();
}
int rdLayerBox( int no, unsigned long boxsize, FILE *bits )
{
unsigned long size, type, readsize;
unsigned INT32 avgBitRate, avgFrameRate;
time_t ltime;
FILE *fp = fopen("enhanced_layers.txt", "at");
if ( fp == NULL )
{
printf("Cannot open enhanced_layers.txt for reporting the information in Layer Box.\n");
return -1;
}
if ( no == 0 )
{
time( <ime );
fprintf( fp, "\n\n*****************************************\n");
fprintf( fp, "Reporting the information in Layer Boxes\nGenerated by the JVT decoder\nDate & Time: %s", ctime( <ime ));
fprintf( fp, "*****************************************\n");
}
fprintf(fp, "\nLayer Box %d:\n", no );
if (-1 == readfile( &avgBitRate, 4, 1, bits ) ) return -1;
if (-1 == readfile( &avgFrameRate, 4, 1, bits ) ) return -1;
fprintf(fp, "Average bit-rate is %ld, average frame rate is %ld.\n", avgBitRate, avgFrameRate );
fprintf(fp, "The sub-sequences in this layer:\n");
readsize = 0;
boxsize = boxsize - SIZEOF_BOXTYPE - 8;
while (readsize < boxsize)
{
if ( -1 == readfile( &size, 4, 1, bits ) ) return -1;
if ( size == 0 ) return -1;
if ( -1 == readfile( &type, 4, 1, bits ) ) return -1;
if ( type != BOX_SSEQ ) return -1;
if ( -1 == rdSubSequence(fp, bits) ) return -1;
readsize += size;
}
fclose( fp );
return 0;
}
int rdSubSequence(FILE* fp, FILE* bits)
{
int i;
unsigned INT16 subSequenceIdentifier;
Boolean continuationFromPreviousSegmentFlag=FALSE, continuationToNextSegmentFlag=FALSE;
Boolean startTickAvailableFlag=FALSE;
unsigned INT64 ssStartTick, ssDuration;
unsigned INT32 avgBitRate, avgFrameRate;
unsigned INT16 numReferencedSubSequences;
unsigned INT8 layerNumber;
unsigned INT16 depSubSequenceIdentifier;
unsigned INT16 cd;
if (-1 == readfile( &subSequenceIdentifier, 2, 1, bits ) ) return -1;
fprintf(fp, "\nsubSequenceIdentifier = %d\n", subSequenceIdentifier );
if (-1 == readfile( &cd, 2, 1, bits ) ) return -1;
if ( cd&0x8000 ) continuationFromPreviousSegmentFlag = TRUE;
if ( cd&0x4000 ) continuationToNextSegmentFlag = TRUE;
if ( cd&0x2000 ) startTickAvailableFlag = TRUE;
fprintf(fp, "continuationFromPreviousSegmentFlag = %d\n", continuationFromPreviousSegmentFlag );
fprintf(fp, "continuationToNextSegmentFlag = %d\n", continuationToNextSegmentFlag);
fprintf(fp, "startTickAvailableFlag = %d\n", startTickAvailableFlag);
if (-1 == readfile( &ssStartTick, 8, 1, bits ) ) return -1;
fprintf(fp, "ssStartTick = %lld\n", ssStartTick);
if (-1 == readfile( &ssDuration, 8, 1, bits ) ) return -1;
fprintf(fp, "ssDuration = %lld\n", ssDuration);
if (-1 == readfile( &avgBitRate, 4, 1, bits ) ) return -1;
fprintf(fp, "avgBitRate = %ld\n", avgBitRate);
if (-1 == readfile( &avgFrameRate, 4, 1, bits ) ) return -1;
fprintf(fp, "avgFrameRate = %ld\n", avgFrameRate);
if (-1 == readfile( &numReferencedSubSequences, 2, 1, bits ) ) return -1;
fprintf(fp, "numReferencedSubSequences = %d\n", numReferencedSubSequences);
for (i=0; i<numReferencedSubSequences; i++)
{
if (-1 == readfile( &layerNumber, 1, 1, bits ) ) return -1;
fprintf(fp, "layerNumber = %d\n", layerNumber);
if (-1 == readfile( &depSubSequenceIdentifier, 2, 1, bits ) ) return -1;
fprintf(fp, "depSubSequenceIdentifier= %d\n", depSubSequenceIdentifier);
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -