📄 decodeiff.c
字号:
if (tmp1!=3)
{
printf ("got RMPNI = %d\n",tmp1);
tmp_rmpni=(RMPNIbuffer_t*)calloc (1,sizeof (RMPNIbuffer_t));
tmp_rmpni->Next=NULL;
tmp_rmpni->RMPNI=tmp1;
// get the additional parameter
sym.len = GetVLCSymbol( buf->streamBuffer, buf->frame_bitoffset, &(sym.inf), buf->bitstream_length );
sym.mapping(sym.len, sym.inf, &(tmp_rmpni->Data), &(sym.value2));
buf->frame_bitoffset += sym.len;
bitptr+=sym.len;
// add RMPNI to list
if (img->currentSlice->rmpni_buffer==NULL)
{
img->currentSlice->rmpni_buffer=tmp_rmpni;
}
else
{
tmp_rmpni2=img->currentSlice->rmpni_buffer;
while (tmp_rmpni2->Next!=NULL)
tmp_rmpni2=tmp_rmpni2->Next;
tmp_rmpni2->Next=tmp_rmpni;
}
} else
{
// free temporary memory (no need to save end loop operation)
done=1;
}
} while (!done);
}
}
// RBPT
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;
// free old buffer content
while (img->mmco_buffer)
{
tmp_mmco=img->mmco_buffer;
img->mmco_buffer=tmp_mmco->Next;
free (tmp_mmco);
}
// read Memory Management Control Operation
if (sym.value1)
{
// read Memory Management Control Operation
do
{
tmp_mmco=(MMCObuffer_t*)calloc (1,sizeof (MMCObuffer_t));
tmp_mmco->Next=NULL;
sym.len = GetVLCSymbol( buf->streamBuffer, buf->frame_bitoffset, &(sym.inf), buf->bitstream_length );
sym.mapping(sym.len, sym.inf, &(tmp_mmco->MMCO), &(sym.value2));
buf->frame_bitoffset += sym.len;
bitptr+=sym.len;
switch (tmp_mmco->MMCO)
{
case 0:
case 5:
break;
case 1:
sym.len = GetVLCSymbol( buf->streamBuffer, buf->frame_bitoffset, &(sym.inf), buf->bitstream_length );
sym.mapping(sym.len, sym.inf, &(tmp_mmco->DPN), &(sym.value2));
buf->frame_bitoffset += sym.len;
bitptr+=sym.len;
break;
case 2:
sym.len = GetVLCSymbol( buf->streamBuffer, buf->frame_bitoffset, &(sym.inf), buf->bitstream_length );
sym.mapping(sym.len, sym.inf, &(tmp_mmco->LPIN), &(sym.value2));
buf->frame_bitoffset += sym.len;
bitptr+=sym.len;
break;
case 3:
sym.len = GetVLCSymbol( buf->streamBuffer, buf->frame_bitoffset, &(sym.inf), buf->bitstream_length );
sym.mapping(sym.len, sym.inf, &(tmp_mmco->DPN), &(sym.value2));
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, &(tmp_mmco->LPIN), &(sym.value2));
buf->frame_bitoffset += sym.len;
bitptr+=sym.len;
break;
case 4:
sym.len = GetVLCSymbol( buf->streamBuffer, buf->frame_bitoffset, &(sym.inf), buf->bitstream_length );
sym.mapping(sym.len, sym.inf, &(tmp_mmco->MLIP1), &(sym.value2));
buf->frame_bitoffset += sym.len;
bitptr+=sym.len;
break;
default:
error ("Invalid MMCO operation specified",400);
break;
}
// add MMCO to list
if (img->mmco_buffer==NULL)
{
img->mmco_buffer=tmp_mmco;
}
else
{
tmp_mmco2=img->mmco_buffer;
while (tmp_mmco2->Next!=NULL) tmp_mmco2=tmp_mmco2->Next;
tmp_mmco2->Next=tmp_mmco;
}
}while (tmp_mmco->MMCO!=0);
}
}
/*!
************************************************************************
* \brief
* read the payload data
* \return
* 0, if success
* -1, otherwise
* \param img
* image pointer
* \param inp
* input parameter pointer
* \param pp
* corresponding payloadinfo
* \param fp
* input file pointer
************************************************************************
*/
int rdOnePayload( struct img_par *img, struct inp_par* inp, PayloadInfo *pp, FILE* fp )
{
int *read_len;
Slice* currSlice = img->currentSlice;
Bitstream* currStream = currSlice->partArr[0].bitstream;
byte* buf = currStream->streamBuffer;
DecodingEnvironmentPtr dep = &((currSlice->partArr[0]).de_cabac);
currStream->frame_bitoffset = 0;
currStream->code_len = 0;
fseek( fp, box_atm.currPayloadOffset, SEEK_SET );
memset( buf, 0, MAX_CODED_FRAME_SIZE );
if ( pp->payloadSize == fread( buf, 1, (unsigned int)pp->payloadSize, fp ) )
{
currStream->bitstream_length = (int)pp->payloadSize;
box_atm.currPayloadOffset += (long)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(inp->symbol_mode == CABAC)
{
dep = &((currSlice->partArr[0]).de_cabac);
arideco_start_decoding(dep, buf, 0, read_len);
}
// 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 ) inp->symbol_mode = UVLC;
else inp->symbol_mode = CABAC;
switch ( box_ps.motionResolution )
{
case 2:
img->mv_res = 0;
break;
case 3:
img->mv_res = 1;
break;
case 0:
img->mv_res = 2;
break;
case 1:
img->mv_res = 3;
break;
default:
assert( 1==0 );
}
inp->partition_mode = box_ps.partitioningType;
inp->UseConstrainedIntraPred = box_ps.intraPredictionType;
inp->buf_cycle = box_ps.bufCycle;
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 = (byte*)buf+size-1;
int num = 0;
assert( fp != NULL );
assert( buf != NULL );
assert( count == 1 );
while ( size > 0 )
{
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 );
// 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();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -