📄 encodeiff.c
字号:
currPictureInfo.pictureOffset = currPictureInfo.currPictureSize;
currPictureInfo.currPictureSize = 0; // reset
// to set the picture display time (relative to the previous coded frame)
currPictureInfo.pictureDisplayTime = frame_no - prev_frame_no;
prev_frame_no = frame_no;
if ( img->type != B_SLICE )
currPictureInfo.lastFrameNr = frame_no;
currPictureInfo.numPayloads = 0; // numPayloads must be set to zero here
currPictureInfo.payloadData = NULL;
// the follow values may be updated.
currPictureInfo.layerNumber = 0;
currPictureInfo.subSequenceIdentifier = 0;
currPictureInfo.originLayerNumber = 0;
currPictureInfo.originSubSequenceIdentifier = 0;
if ( input->NumFramesInELSubSeq != 0 )
{
if (IMG_NUMBER%(input->NumFramesInELSubSeq+1)==0 && img->type!=B_SLICE)
currPictureInfo.layerNumber = 0;
else
{
currPictureInfo.layerNumber = 1;
}
currPictureInfo.subSequenceIdentifier = box_sseq[currPictureInfo.layerNumber].subSequenceIdentifier;
if (img->type!=B_SLICE)
{
currPictureInfo.refFromLayerNumber = currPictureInfo.layerNumber;
currPictureInfo.refFromSubSequenceIdentifier = currPictureInfo.subSequenceIdentifier;
}
}
return 0;
}
/*!
************************************************************************
* \brief
* The function to write the meta data of the current picture
* \return
* how many bytes been written, if success
* -1, if failed
* \param fp
* output file pointer
************************************************************************
*/
size_t wrPictureInfo( FILE* fp )
{
int i;
INT64 size;
PayloadInfo* pp;
unsigned char cd;
size_t num = 0;
assert( fp != NULL );
if ( currPictureInfo.intraPictureFlag == TRUE ) cd = 0x80;
else cd = 0x00;
if ( currPictureInfo.syncPictureFlag == TRUE ) cd |= 0x40;
num += writefile( &cd, 1, 1, fp );
num += writefile_s( &currPictureInfo.pictureOffset, sizeof(currPictureInfo.pictureOffset), box_fh.numBytesInPictureOffsetMinusTwo + 2, 1, fp );
num += writefile_s( &currPictureInfo.pictureDisplayTime, sizeof(currPictureInfo.pictureDisplayTime), box_fh.numBytesInPictureDisplayTimeMinusOne + 1, 1, fp );
if ( box_ath.numLayers )
{
if ( -1 == writefile( &currPictureInfo.layerNumber, 1, 1, fp ) ) return -1;
if ( -1 == writefile( &currPictureInfo.subSequenceIdentifier, 2, 1, fp ) ) return -1;
if ( currPictureInfo.syncPictureFlag )
{
if ( -1 == writefile( &currPictureInfo.originLayerNumber, 1, 1, fp ) ) return -1;
if ( -1 == writefile( &currPictureInfo.originSubSequenceIdentifier, 2, 1, fp ) ) return -1;
}
}
num += writefile_s( &currPictureInfo.numPayloads, sizeof(currPictureInfo.numPayloads), box_fh.numBytesInPayloadCountMinusOne + 1, 1, fp );
// check if the operations to write file are successful.
if ( num != (unsigned)(1+box_fh.numBytesInPictureOffsetMinusTwo + 2+box_fh.numBytesInPictureDisplayTimeMinusOne + 1+box_fh.numBytesInPayloadCountMinusOne + 1) ) return -1;
pp = currPictureInfo.payloadData;
for ( i = 0; i < currPictureInfo.numPayloads; i++ )
{
assert( pp != NULL );
// update and write the payload to file
if ( -1 == wrPayloadInfo( pp, fp ) ) return -1;
// then update the parameter in Alternate Track Info Box
size = pp->payloadSize + pp->headerSize;
box_ati.info[0].numSDU++;
box_ati.info[0].sumSDUSize += (long double)size;
if ( box_ati.info[0].maxSDUSize < size ) box_ati.info[0].maxSDUSize = (unsigned INT16)size;
pp = pp->next;
}
return 0;
}
/*!
************************************************************************
* \brief
* Free all resource allocated for this Picture Info
* \return
* None
************************************************************************
*/
void freePictureInfo()
{
int i;
PayloadInfo* next;
for ( i = 0; i < currPictureInfo.numPayloads; i++ )
{
assert( currPictureInfo.payloadData != NULL );
next = currPictureInfo.payloadData->next;
free( currPictureInfo.payloadData );
currPictureInfo.payloadData = next;
}
}
// Functions on payloadInfo
/*!
************************************************************************
* \brief
* To new a payload info to save the meta data of a slice
* Tian Dong, Feb 10, 2002:
* No data partition supported.
* \return
* a pointer to the allocated mem, if success
* NULL, if failed
************************************************************************
*/
PayloadInfo* newPayloadInfo()
{
PayloadInfo* pli;
pli = calloc(1, sizeof(PayloadInfo));
if ( pli == NULL ) return NULL;
pli->payloadSize = 0;
pli->headerSize = box_fh.numBytesInPayloadSizeMinusOne+1 + 1 + 1;
pli->payloadType = 0; // single slice
pli->errorIndication = 0; // no known error
pli->reserved = 0;
pli->parameterSet = 0;
pli->pictureID = 0;
pli->sliceID = 0;
pli->sliceType = 0;
pli->firstMBInSliceX = 0;
pli->firstMBInSliceY = 0;
pli->directType=input->direct_type;
pli->spSwitchFlag = 0; // Flag for SP picture. 1 for switching SP, 0 for normal SP
pli->next = NULL;
pli->pn = img->pn;
pli->type = img->type;
pli->max_lindex = img->max_lindex;
pli->lindex = img->lindex;
// pli->disposable_flag = img->disposable_flag;
pli->weighted_prediction = input->WeightedPrediction;
pli->weighted_biprediction = input->WeightedBiprediction;
pli->num_ref_pic_active_fwd_minus1 = img->num_ref_pic_active_fwd_minus1;
pli->num_ref_pic_active_bwd_minus1 = img->num_ref_pic_active_bwd_minus1;
// set values
assert ( input->partition_mode == PAR_DP_1 );
// Tian Dong: JVT-C083. June 15, 2002
// Calculating payload type, the conditions may be updated when more
// coding options are supported later.
if ( FirstFrameIn2ndIGOP == img->number )
pli->payloadType = PAYLOAD_TYPE_IDERP;
pli->parameterSet = box_ps.parameterSetID;
pli->pictureID = img->currentSlice->picture_id;
pli->sliceID = img->current_slice_nr;
pli->pstruct = img->pstruct;
// copied from rtp.c, and add pli->sliceType2
switch (img->type)
{
case P_SLICE:
if (img->types==SP_SLICE)
{
pli->sliceType = 2;
pli->sliceType2 = SP_SLICE;
}
else
{
pli->sliceType = 0;
pli->sliceType2 = P_SLICE;
}
break;
case I_SLICE:
pli->sliceType = 3;
pli->sliceType2 = I_SLICE;
break;
case B_SLICE:
case BS_IMG:
pli->sliceType = 1;
pli->sliceType2 = B_SLICE;
break;
case SP_SLICE:
pli->sliceType = 2;
pli->sliceType2 = SP_SLICE;
break;
default:
printf ("Panic: unknown picture type %d, exit\n", img->type);
assert (0==1);
}
pli->firstMBInSliceX = img->mb_x;
pli->firstMBInSliceY = img->mb_y;
pli->initialQP = img->qp;
pli->qpsp = img->qpsp;
pli->filter_parameters_flag = input->LFSendParameters;
pli->lf_disable = input->LFDisableIdc;
pli->lf_alpha_c0_offset_div2 = input->LFAlphaC0Offset >> 1;
pli->lf_beta_offset_div2 = input->LFBetaOffset >> 1;
// Tian: begin of ERPS
pli->numRMPNI = 0;
if ( img->type != I_SLICE )
{
// do the possible remapping
remap_ref_short_term(pli);
}
// begin of ERPS
#ifdef _CHECK_MULTI_BUFFER_1_
// Tian Dong: It is suggested to delete the lines
// for test purpose. June 7, 2002
printf("_CHECK_MULTI_BUFFER_1_ cannot be defined!\n");
exit(0);
/* RPSL: Reference Picture Selection Layer */
if(img->type!=I_SLICE)
{
// let's mix some reference frames
if ((img->pn==5)&&(img->type==P_SLICE))
{
RMPNIbuffer_t *r;
r = (RMPNIbuffer_t*)calloc (1,sizeof(RMPNIbuffer_t));
r->RMPNI=0;
r->Data=2;
r->Next=NULL;
img->currentSlice->rmpni_buffer=r;
}
}
reorder_mref(img);
#endif
#ifdef _CHECK_MULTI_BUFFER_2_
// Tian Dong: It is suggested to delete such check coding lines
// for test purpose. June 7, 2002
assert(0);
// some code to check operation
if ((img->pn==3) && (img->type==P_SLICE))
{
// check in this frame as long term picture
// if (img->max_lindex==0)
{
// set long term buffer size = 2
img->max_lindex=2;
}
// assign local long term
init_long_term_buffer(2,img);
init_mref();
init_Refbuf(img);
if (img->current_slice_nr==0)
{
assign_long_term_id(3,img->lindex,img);
img->lindex=(img->lindex+1)%img->max_lindex;
}
}
#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;
int start_mb_nr;
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 = ue_linfo; // Mapping rule: Simple code number to len/info
if ( pp->payloadType == 0 || pp->payloadType == PAYLOAD_TYPE_IDERP )
{
// 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 )
{
// weighted_bipred_explicit_flag
sym.value1 = (pp->weighted_biprediction == 1) ? 1:0;
writeSyntaxElement2Buf_UVLC(&sym, bitstream);
// weighted_bipred_implicit_flag
sym.value1 = (pp->weighted_biprediction == 2) ? 1:0;
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);
start_mb_nr = (img->width/16)*pp->firstMBInSliceY+pp->firstMBInSliceX;
if (pp->sliceType2==B_SLICE)
{
sym.bitpattern = pp->directType;
sym.len = 1;
writeSyntaxElement2Buf_Fixed(&sym, bitstream);
}
sym.mapping = se_linfo;
sym.value1 = pp->initialQP - (MAX_QP - MIN_QP +1)/2;
writeSyntaxElement2Buf_UVLC (&sym, bitstream);
if ( pp->sliceType2 == SP_SLICE)
{
if ( pp->sliceType2 == SP_SLICE) // Needs some definition for SI Images. Currently code seems not to support them,
{
sym.bitpattern = pp->spSwitchFlag;
sym.len = 1;
writeSyntaxElement2Buf_Fixed(&sym, bitstream);
}
sym.value1 = pp->qpsp - (MAX_QP - MIN_QP +1)/2;
writeSyntaxElement2Buf_UVLC (&sym, bitstream);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -