📄 encodeiff.c
字号:
}
if (pp->filter_parameters_flag)
{
sym.bitpattern = pp->lf_disable;
sym.len = 1;
writeSyntaxElement2Buf_Fixed(&sym, bitstream);
if (!pp->lf_disable)
{
sym.mapping = se_linfo;
sym.value1 = pp->lf_alpha_c0_offset_div2;
writeSyntaxElement2Buf_UVLC (&sym, bitstream);
sym.value1 = pp->lf_beta_offset_div2;
writeSyntaxElement2Buf_UVLC (&sym, bitstream);
}
}
sym.mapping = ue_linfo;
iff_writeERPS(&sym, pp, bitstream); // Tian: to support ERPS (Annex U), Feb 27, 2002
// Tian Dong: June 10, 2002
// Update: a differential value is conveyed rather than an absolute value.
}
else if ( pp->payloadType == 1 )
{
// write the parameter set
sym.value1 = pp->parameterSet;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
// write picture structure
sym.value1 = pp->pstruct;
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->disposable_flag;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
if ( pp->sliceType2==P_SLICE )
{
sym.value1 = pp->weighted_prediction;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
}
if ( pp->sliceType2==B_SLICE )
{
sym.value1 = pp->weighted_biprediction;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
}
if ( pp->sliceType2==P_SLICE || pp->sliceType2==B_SLICE )
{
sym.value1 = pp->num_ref_pic_active_fwd_minus1;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
}
if ( pp->sliceType2==B_SLICE )
{
sym.value1 = pp->num_ref_pic_active_bwd_minus1;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
}
sym.value1 = pp->firstMBInSliceX;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
sym.value1 = pp->firstMBInSliceY;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
sym.mapping = se_linfo;
sym.value1 = pp->initialQP - (MAX_QP - MIN_QP + 1)/2;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
sym.mapping = ue_linfo;
// 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 picture structure
sym.value1 = pp->pstruct;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
// 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_s( &pp->payloadSize, sizeof(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;
int i;
// 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);
if (pp->numRMPNI)
{
sym->value1 = 1;
len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
// now write the data:
for (i=0; i<pp->numRMPNI; i++)
{
assert( pp->rmpni_RMPNI[i] >= 0 && pp->rmpni_RMPNI[i] <= 3 );
sym->value1 = pp->rmpni_RMPNI[i];
// printf("write RMPNI %d\n", pp->rmpni_RMPNI[i]);
len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
if ( pp->rmpni_RMPNI[i] != 3 )
{
sym->value1 = pp->rmpni_Data[i];
len += writeSyntaxElement2Buf_UVLC(sym, bitstream);
}
}
}
else
{
sym->value1 = 0;
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!=I_SLICE)
{
// let's mix some reference frames
if ((pp->pn==5)&&(pp->type==P_SLICE))
{
// 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==P_SLICE))
{
// 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==P_SLICE))
{
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;
}
/*!
************************************************************************
* \brief
* Initiate the Layer Box
* Tian Dong, May 30, 2002:
* \return
* 0, if success
* -1, otherwise
************************************************************************
*/
int initLayerBox()
{
int i;
if ( input->NumFramesInELSubSeq == 0 ) return 0;
if ( box_ath.numLayers > MAX_LAYER_NUMBER ) return -1;
for (i=0; i<box_ath.numLayers; i++)
{
box_layr[i].type.size = 0; // to be updated
box_layr[i].type.type = BOX_LAYR;
box_layr[i].avgBitRate = 0;
box_layr[i].avgFrameRate = 0;
box_layr[i].fp = tmpfile();
if ( box_layr[i].fp == NULL ) return -1;
}
return 0;
}
/*!
************************************************************************
* \brief
* Update the average bit rate and frame rate in this Layer
* \return
* 0, if success
* -1, if failed
************************************************************************
*/
int updateLayerBox()
{
int i;
int pictureDataSize;
if ( input->NumFramesInELSubSeq == 0 ) return 0;
for (i=0; i<box_ath.numLayers; i++)
{
assert( box_layr[i].fp != NULL );
// update the head data
fseek( box_layr[i].fp, 0, SEEK_END );
pictureDataSize = ftell( box_layr[i].fp );
box_layr[i].type.size = SIZEOF_BOXTYPE + 8 + pictureDataSize;
// replace the following two lines to calculate the average values
box_layr[i].avgBitRate = 0;
box_layr[i].avgFrameRate = 0;
}
return 0;
}
size_t mergeLayerBox( FILE* fp )
{
size_t num = 0, num2 = 0;
int layr;
FILE* sourcef, *destf;
unsigned char c;
if ( input->NumFramesInELSubSeq == 0 ) return 0;
for (layr=0; layr<box_ath.numLayers; layr++)
{
num = 0;
num += writefile( &box_layr[layr].type.size, 4, 1, fp );
num += writefile( &box_layr[layr].type.type, 4, 1, fp );
num += writefile( &box_layr[layr].avgBitRate, 4, 1, fp );
num += writefile( &box_layr[layr].avgFrameRate, 4, 1, fp );
// append the data in box_layr[layr].fp into fp:
sourcef = box_layr[layr].fp;
destf = fp;
fseek( sourcef, 0L, SEEK_SET );
c = fgetc(sourcef);
while ( !feof( sourcef ) )
{
fputc( c, destf );
num++;
c = fgetc(sourcef);
}
if ( num != box_layr[layr].type.size ) return -1;
num2 += num;
}
return num2;
}
void freeLayerBox()
{
int layr;
if ( input->NumFramesInELSubSeq == 0 ) return;
for (layr=0; layr<box_ath.numLayers; layr++)
{
fclose( box_layr[layr].fp );
}
}
/*!
************************************************************************
* \brief
* Initiate the Sub Sequence Box
* Tian Dong, May 30, 2002:
* \return
* 0, if success
* -1, otherwise
************************************************************************
*/
int initSubSequenceBox(int layr)
{
static unsigned INT16 id=0;
if ( input->NumFramesInELSubSeq == 0 ) return 0;
if (layr<0 || layr>box_ath.numLayers) return -1;
box_sseq[layr].type.size = 0; // to be updated
box_sseq[layr].type.type = BOX_SSEQ;
// set the data in current sub-sequence here...
box_sseq[layr].subSequenceIdentifier = id++;
box_sseq[layr].continuationFromPreviousSegmentFlag = FALSE;
box_sseq[layr].continuationToNextSegmentFlag = FALSE;
box_sseq[layr].startTickAvailableFlag = 0;
box_sseq[layr].ssStartTick = 0;
box_sseq[layr].ssDuration = 0;
box_sseq[layr].avgBitRate = 0;
box_sseq[layr].avgFrameRate = 0;
box_sseq[layr].numReferenceSubSequences = 0; // to be updated.
return 0;
}
/*!
************************************************************************
* \brief
* Update the Sub Sequence Box
* Tian Dong, May 30, 2002:
* \return
* number of bytes being written
* -1, if failed
************************************************************************
*/
int updateSubSequenceBox( int layr )
{
if ( input->NumFramesInELSubSeq == 0 ) return 0;
assert( layr >= 0 && layr < box_ath.numLayers );
box_sseq[layr].type.size = SIZEOF_BOXTYPE + 30 + 3*box_sseq[layr].numReferenceSubSequences;
box_sseq[layr].ssDuration = 0;
box_sseq[layr].avgBitRate = 0;
box_sseq[layr].avgFrameRate = 0;
return 0;
}
/*!
************************************************************************
* \brief
* Write the Sub Sequence Box
* Tian Dong, May 30, 2002:
* \input
* layr: the layor number
* fp: the destination file, normally it is box_layr[layr].fp
* \return
* number of bytes being written
* -1, if failed
************************************************************************
*/
size_t wrSubSequenceBox( int layr )
{
size_t num = 0, num2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -