📄 encodeiff.c
字号:
#endif
// end of ERPS
return pli;
}
/*!
************************************************************************
* \brief
* Add a payload info to the Payloadinfo List, which head is stored in PictureInfo
* Tian Dong, Feb 10, 2002:
* No data partition supported.
* \return
* 1, if success
* 0, if failed
* \param pi
* The PayloadInfo will be added to the list
************************************************************************
*/
int addOnePayloadInfo(PayloadInfo* pi)
{
PayloadInfo* p;
PayloadInfo* last;
last = p = currPictureInfo.payloadData;
assert( pi != NULL );
while ( p )
{
last = p;
p = p->next;
}
if (last == NULL)
currPictureInfo.payloadData = pi; // this is the first payloadInfo
else
last->next = pi; // add the payloadInfo to the end of the payloadInfo list
currPictureInfo.numPayloads++;
return 1;
}
/*!
************************************************************************
* \brief
* The function to write one payloadinfo to file
* \return
* how many bytes been written, if success
* -1, if failed
* \param pp
* PayloadInfo pointer
* \param fp
* output file pointer
************************************************************************
*/
size_t wrPayloadInfo( PayloadInfo* pp, FILE *fp )
{
byte cd;
Bitstream* bitstream; // used as a MEM buffer of slice header
SyntaxElement sym;
size_t num = 0, bytes_written;
assert( pp != NULL );
assert( fp != NULL );
// Initialize the bitsteam:
bitstream = alloca(sizeof(Bitstream));
assert( bitstream != NULL );
bitstream->streamBuffer = alloca(BUFSIZE_FOR_PAYLOADINFO);
memset( bitstream->streamBuffer, 0, BUFSIZE_FOR_PAYLOADINFO);
bitstream->bits_to_go = 8;
bitstream->byte_pos = 0;
bitstream->byte_buf = 0;
// First write the element to the MEM bitstream buffer
sym.type = SE_HEADER; // This will be true for all symbols generated here
sym.mapping = n_linfo2; // Mapping rule: Simple code number to len/info
if ( pp->payloadType == 0 )
{
// write the parameter set
sym.value1 = pp->parameterSet;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
// write slice header;
sym.value1 = pp->pictureID;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
sym.value1 = pp->sliceType;
// select_picture_type (&sym);
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
sym.value1 = pp->firstMBInSliceX;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
sym.value1 = pp->firstMBInSliceY;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
sym.value1 = MAX_QP - pp->initialQP;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
if ( input->symbol_mode == CABAC )
{
sym.value1 = pp->lastMBnr;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
}
if ( pp->sliceType2 == SP_IMG )
{
sym.value1 = MAX_QP - pp->qpsp;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
}
iff_writeERPS(&sym, pp, bitstream); // Tian: to support ERPS (Annex U), Feb 27, 2002
}
else if ( pp->payloadType == 1 )
{
// write the parameter set
sym.value1 = pp->parameterSet;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
// write slice header;
sym.value1 = pp->pictureID;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
sym.value1 = pp->sliceType;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
sym.value1 = pp->firstMBInSliceX;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
sym.value1 = pp->firstMBInSliceY;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
sym.value1 = MAX_QP - pp->initialQP;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
// write the slice id
sym.value1 = pp->sliceID;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
iff_writeERPS(&sym, pp, bitstream); // Tian: to support ERPS (Annex U), Feb 27, 2002
}
else if ( pp->payloadType == 2 || pp->payloadType == 3 )
{
// write pictureID
sym.value1 = pp->pictureID;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
// write sliceID
sym.value1 = pp->sliceID;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
iff_writeERPS(&sym, pp, bitstream); // Tian: to support ERPS (Annex U), Feb 27, 2002
}
else if ( pp->payloadType == 5 )
{
// no additional codewords
}
// finishing the MEM buffer
if (bitstream->bits_to_go < 8)
{ // trailing bits to process
bitstream->byte_buf <<= bitstream->bits_to_go;
bitstream->streamBuffer[bitstream->byte_pos++]=bitstream->byte_buf;
bitstream->bits_to_go = 8;
}
bytes_written = bitstream->byte_pos;
// update & write headerSize
num += writefile( &pp->payloadSize, box_fh.numBytesInPayloadSizeMinusOne+1, 1, fp );
pp->headerSize += bytes_written;
num += writefile( &pp->headerSize, 1, 1, fp );
cd = (pp->payloadType << 4) | (pp->errorIndication << 3) | (pp->reserved);
num += writefile( &cd, 1, 1, fp );
if ( num != (unsigned)(box_fh.numBytesInPayloadSizeMinusOne+1+2) ) return -1;
// Then write the bitstream to FILE
if ( bytes_written != fwrite (bitstream->streamBuffer, 1, bytes_written, fp) ) return -1;
return num+bytes_written;
}
/*!
************************************************************************
* \brief
* writes the ERPS syntax elements to a bitstream
* imitate write_ERPS(), and change the function calls:
* from:
* len += writeSyntaxElement_UVLC (sym, partition);
* to:
* len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
* \return
* how many bytes been written, if success
* -1, if failed
* \param bitstream
* destination: where the code to be written
************************************************************************
*/
size_t iff_writeERPS(SyntaxElement *sym, PayloadInfo* pp, Bitstream* bitstream)
{
size_t len=0;
// RPSF: Reference Picture Selection Flags
sym->value1 = 0;
len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
// PN: Picture Number
sym->value1 = pp->pn;
len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
#ifdef _CHECK_MULTI_BUFFER_1_
// RPSL: Reference Picture Selection Layer
sym->value1 = 1;
len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
if(pp->type!=INTRA_IMG)
{
// let's mix some reference frames
if ((pp->pn==5)&&(pp->type==INTER_IMG))
{
// negative ADPN follows
// RMPNI
sym->value1 = 0;
len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
// ADPN
sym->value1 = 2;
len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
}
// RMPNI
sym->value1 = 3;
len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
}
#else
// RPSL: Reference Picture Selection Layer
sym->value1 = 0;
len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
#endif
#ifdef _CHECK_MULTI_BUFFER_2_
// Reference Picture Bufering Type
sym->value1 = 1;
len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
// some code to check operation
if ((pp->pn==3) && (pp->type==INTER_IMG))
{
// set long term buffer size = 2
// MMCO Specify Max Long Term Index
// command
sym->value1 = 4;
len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
// size = 2+1 (MLP1)
sym->value1 = 2+1;
len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
// assign a long term index to actual frame
// MMCO Assign Long Term Index to a Picture
// command
sym->value1 = 3;
len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
// DPN=0 for actual frame
sym->value1 = 0;
len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
//long term ID
sym->value1 = pp->lindex;
len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
}
if ((pp->pn==4) && (pp->type==INTER_IMG))
{
if (pp->max_lindex>0)
{
// delete long term picture again
// MMCO Mark a Long-Term Picture as Unused
// command
sym->value1 = 2;
len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
// MMCO LPIN
// command
sym->value1 = (pp->max_lindex+pp->lindex-1)%pp->max_lindex;
len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
}
}
// end MMCO loop
// end loop
sym->value1 = 0;
len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
#else
// RPBT: Reference Picture Bufering Type
sym->value1 = 0;
len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
#endif
return len;
}
// Functions on SwitchPictureBox
/*!
************************************************************************
* \brief
* Initiate the Switch Picture Box. Do nothing
* Tian Dong, Feb 10, 2002
* The switch picture box is skipped in the output file
* \return
* 0, if success
* -1, otherwise
************************************************************************
*/
int initSwitchPictureBox()
{
return 0;
}
// Functions on AlternateMediaBox
/*!
************************************************************************
* \brief
* Initiate the Alternate Track Media Box & some data in picture info.
* Tian Dong, Feb 10, 2002:
* Only one Alternate Track Media Box in the output file.
* \return
* 0, if success
* -1, otherwise
************************************************************************
*/
int initAlternateTrackMediaBox()
{
box_atm.type.size = 0; // to be updated
box_atm.type.type = BOX_ATRM;
box_atm.fpMedia = tmpfile();
assert( box_atm.fpMedia != NULL );
// to maintain a picture pointer to point to the beginning
// of the latest picture, relative to the beginning of the ATMC.
currPictureInfo.currPictureSize = SIZEOF_BOXTYPE; // the first time to set its value. in 64 bits mode
return 0;
}
/*!
************************************************************************
* \brief
* Update the data in this Alternate Track Media
* \return
* 0, if success
* -1, if failed
************************************************************************
*/
int updateAlternateTrackMediaBox()
{
int mediaDataSize;
assert( box_atm.fpMedia != NULL );
fseek( box_atm.fpMedia, 0, SEEK_END );
mediaDataSize = ftell( box_atm.fpMedia );
box_atm.type.size = SIZEOF_BOXTYPE + mediaDataSize;
return 0;
}
/*!
************************************************************************
* \brief
* Merge the Alternate Track Media Data to the output file
* \return
* how many bytes been appended, if success
* -1, if failed
* \param fp
* output file pointer
************************************************************************
*/
int mergeAlternateTrackMediaBox( FILE* fp )
{
FILE* sourcef;
FILE* destf;
unsigned char c;
size_t num = 0;
sourcef = box_atm.fpMedia;
destf = fp;
assert( sourcef != NULL );
assert( destf != NULL );
// write the head
num += writefile( &box_atm.type.size, 4, 1, fp );
num += writefile( &box_atm.type.type, 4, 1, fp );
if ( num != 8 ) return -1;
// append the data in box_ath.fpMeta into fp:
fseek( sourcef, 0L, SEEK_SET );
c = fgetc(sourcef);
while ( !feof( sourcef ) )
{
fputc( c, destf );
num++;
c = fgetc(sourcef);
}
return num;
}
/*!
************************************************************************
* \brief
* Free all resource allocated for this Alternate Track Media Box
* \return
* None
************************************************************************
*/
void freeAlternateTrackMediaBox()
{
fclose( box_atm.fpMedia );
}
/*!
************************************************************************
* \brief
* The init function for Interim File Format
* \return
* 0, if success
* -1, otherwise
************************************************************************
*/
int initInterimFile()
{
box_s.lastFrameNr = 0;
if ( -1 == initFileTypeBox() ) return -1;
if ( -1 == initFileHeaderBox() ) return -1;
if ( -1 == initContentInfoBox() ) return -1;
if ( -1 == initAlternateTrackInfoBox() ) return -1;
if ( -1 == initParameterSetBox() ) return -1;
return 0;
}
/*!
************************************************************************
* \brief
* The close function for Interim File Format
* \return
* how many bytes being written into the file, if success
* -1, otherwise
* \param outf
* output file pointer
************************************************************************
*/
size_t terminateInterimFile(FILE* outf)
{
size_t num = 0, len;
assert( outf != NULL );
if ( (len = wrFileTypeBox( outf )) == -1 ) return -1;
num += len;
if ( (len = wrFileHeaderBox( outf )) == -1 ) return -1;
num += len;
if ( (len = wrContentInfoBox( outf )) == -1 ) return -1;
num += len;
if ( (len = wrAlternateTrackInfoBox( outf )) == -1 ) return -1;
num += len;
if ( (len = wrParameterSetBox( outf )) == -1 ) return -1;
num += len;
if ( (len = wrSegmentBox( outf )) == -1 ) return -1;
num += len;
freeSegmentBox();
freeParameterSetBox();
freeAlternateTrackInfoBox();
freeContentInfoBox();
freeFileHeaderBox();
freeFileTypeBox();
return num;
}
/*!
************************************************************************
* \brief
* write the data to file, bytes are in big Endian order.
* \return
* how many bytes being written into the file, if success
* -1, otherwise
* \param outf
* output file pointer
************************************************************************
*/
size_t writefile( 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 )
{
fwrite( p--, 1, 1, fp );
size--;
num++;
}
return num;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -