📄 encodeiff.c
字号:
break;
}
box_ps.partitioningType = input->partition_mode;
box_ps.intraPredictionType = input->UseConstrainedIntraPred;
box_ps.bufCycle = input->no_multpred;
return 0;
}
/*!
************************************************************************
* \brief
* The function to write the Parameter Set Box to output file
* \return
* how many bytes been written, if success
* -1, if failed
* \param fp
* output file pointer
************************************************************************
*/
size_t wrParameterSetBox( FILE* fp )
{
size_t num = 0;
assert( fp != NULL );
num += writefile( &box_ps.type.size, 4, 1, fp );
num += writefile( &box_ps.type.type, 4, 1, fp );
num += writefile( &box_ps.parameterSetID, 2, 1, fp );
num += writefile( &box_ps.profile, 1, 1, fp );
num += writefile( &box_ps.level, 1, 1, fp );
num += writefile( &box_ps.version, 1, 1, fp );
num += writefile( &box_ps.pictureWidthInMBs, 2, 1, fp );
num += writefile( &box_ps.pictureHeightInMBs, 2, 1, fp );
num += writefile( &box_ps.displayRectangleOffsetTop, 2, 1, fp );
num += writefile( &box_ps.displayRectangleOffsetLeft, 2, 1, fp );
num += writefile( &box_ps.displayRectangleOffsetBottom, 2, 1, fp );
num += writefile( &box_ps.displayRectangleOffsetRight, 2, 1, fp );
num += writefile( &box_ps.displayMode, 1, 1, fp );
num += writefile( &box_ps.displayRectangleOffsetFromWindowTop, 2, 1, fp );
num += writefile( &box_ps.displayRectangleOffsetFromWindowLeftBorder, 2, 1, fp );
num += writefile( &box_ps.entropyCoding, 1, 1, fp );
num += writefile( &box_ps.motionResolution, 1, 1, fp );
num += writefile( &box_ps.partitioningType, 1, 1, fp );
num += writefile( &box_ps.intraPredictionType, 1, 1, fp );
num += writefile( &box_ps.bufCycle, 1, 1, fp );
if ( num == box_ps.type.size ) return num;
return -1;
}
/*!
************************************************************************
* \brief
* Do nothing
* \return
* None
************************************************************************
*/
void freeParameterSetBox()
{
}
// Functions on SegmentBox
/*!
************************************************************************
* \brief
* Initiate the Segment Box and all sub-Boxes in it.
* Tian Dong, Feb 10, 2002:
* Only one Segment Box in the output file
* \return
* 0, if success
* -1, otherwise
************************************************************************
*/
int initSegmentBox()
{
box_s.type.size = 0; // to be updated
box_s.type.type = BOX_SEGM;
box_s.fileSize = 0; // to be updated
box_s.startTick = 0;
box_s.firstFrameNr = box_s.lastFrameNr;
box_s.lastFrameNr = 0; // serve as the duration of the segment.
box_s.segmentDuration = 0; // to be updated
// since we now only deal with the ONE track case, we assert:
assert( box_fh.numAlternateTracks == 1 );
if ( -1 == initAlternateTrackHeaderBox() ) return -1;
if ( -1 == initSwitchPictureBox() ) return -1;
if ( -1 == initAlternateTrackMediaBox() ) return -1;
return 0;
}
/*!
************************************************************************
* \brief
* Update the data in Segment Box
* \return
* None
************************************************************************
*/
void updateSegmentBox()
{
box_s.type.size = SIZEOF_BOXTYPE + 24 + box_ath.type.size + box_atm.type.size;
box_s.fileSize = box_s.type.size;
box_s.segmentDuration = box_s.lastFrameNr - box_s.firstFrameNr + 1;
}
/*!
************************************************************************
* \brief
* The function to write the Segment Box to output file
* \return
* how many bytes been written, if success
* -1, if failed
* \param fp
* output file pointer
************************************************************************
*/
size_t wrSegmentBox( FILE *fp )
{
size_t num = 0;
assert( fp );
// since we now only deal with the ONE track case, we assert:
assert( box_fh.numAlternateTracks == 1 );
num += writefile( &box_s.type.size, 4, 1, fp );
num += writefile( &box_s.type.type, 4, 1, fp );
num += writefile( &box_s.fileSize, 8, 1, fp );
num += writefile( &box_s.startTick, 8, 1, fp );
num += writefile( &box_s.segmentDuration, 8, 1, fp );
num += mergeAlternateTrackHeaderBox( fp );
num += mergeAlternateTrackMediaBox( fp );
if ( num == box_s.type.size ) return num;
return 0;
}
/*!
************************************************************************
* \brief
* Free all resource allocated for this segment
* \return
* None
************************************************************************
*/
void freeSegmentBox()
{
freeAlternateTrackHeaderBox();
freeAlternateTrackMediaBox();
}
// Functions on AlternateTrackHeaderBox
/*!
************************************************************************
* \brief
* Initiate the Alternate Track Header Box & some data in picture info.
* Tian Dong, Feb 10, 2002:
* Only one Alternate Track Header Box in the output file.
* \return
* 0, if success
* -1, otherwise
************************************************************************
*/
int initAlternateTrackHeaderBox()
{
box_ath.type.size = 0; // to be updated
box_ath.type.type = BOX_ATRH;
box_ath.numPictures = 0; // set to 0
box_ath.fpMeta = tmpfile();
if ( box_ath.fpMeta == NULL ) return -1;
currPictureInfo.lastFrameNr = 0; // do this for init of picture info
return 0;
}
/*!
************************************************************************
* \brief
* Update the data in this Alternate Track Header
* \return
* 0, if success
* -1, if failed
************************************************************************
*/
int updateAlternateTrackHeaderBox()
{
int pictureDataSize;
assert( box_ath.fpMeta != NULL );
// update the head data
fseek( box_ath.fpMeta, 0, SEEK_END );
pictureDataSize = ftell( box_ath.fpMeta );
box_ath.type.size = SIZEOF_BOXTYPE + box_fh.numBytesInPictureCountMinusOne+1 + pictureDataSize;
return 0;
}
/*!
************************************************************************
* \brief
* Merge the Alternate Track Header Data to the output file
* \return
* how many bytes been appended, if success
* -1, if failed
* \param fp
* output file pointer
************************************************************************
*/
size_t mergeAlternateTrackHeaderBox( FILE* fp )
{
FILE* sourcef;
FILE* destf;
unsigned char c;
size_t num = 0;
sourcef = box_ath.fpMeta;
destf = fp;
assert( sourcef != NULL );
assert( destf != NULL );
// write the head of Alternate Track Header Box
num += writefile( &box_ath.type.size, 4, 1, fp );
num += writefile( &box_ath.type.type, 4, 1, fp );
// writefile( &box_ath.type.largesize, 8, 1, fp );
num += writefile( &box_ath.numPictures, box_fh.numBytesInPictureCountMinusOne+1, 1, destf );
// 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);
}
if ( num == box_ath.type.size ) return num;
return -1;
}
/*!
************************************************************************
* \brief
* Free all resource allocated for this Alternate Track Header Box
* \return
* None
************************************************************************
*/
void freeAlternateTrackHeaderBox()
{
fclose( box_ath.fpMeta );
}
// Functions on PictureInfo
/*!
************************************************************************
* \brief
* Initiate the picture info, before one frame is encoded
* \return
* 0, if success
* -1, otherwise
************************************************************************
*/
int initPictureInfo()
{
static int prev_frame_no = 0;
if ( img->type == INTRA_IMG )
currPictureInfo.intraPictureFlag = 0x80; // if the picture is INTRA
else
currPictureInfo.intraPictureFlag = 0x00; // if the picture is not INTRA
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_IMG )
currPictureInfo.lastFrameNr = frame_no;
currPictureInfo.numPayloads = 0; // numPayloads must be set to zero here
currPictureInfo.payloadData = NULL;
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;
size_t num = 0;
// FILE* f;
// f = fopen( "dummy1.txt", "at" );
assert( fp != NULL );
num += writefile( &currPictureInfo.intraPictureFlag, 1, 1, fp );
num += writefile( &currPictureInfo.pictureOffset, box_fh.numBytesInPictureOffsetMinusTwo + 2, 1, fp );
num += writefile( &currPictureInfo.pictureDisplayTime, box_fh.numBytesInPictureDisplayTimeMinusOne + 1, 1, fp );
num += writefile( &currPictureInfo.numPayloads, box_fh.numBytesInPayloadCountMinusOne + 1, 1, fp );
if ( num != (unsigned)(1+box_fh.numBytesInPictureOffsetMinusTwo + 2+box_fh.numBytesInPictureDisplayTimeMinusOne + 1+box_fh.numBytesInPayloadCountMinusOne + 1) ) return -1;
// fprintf( f, "picture %d 's payload, total %d:\n", frame_no, currPictureInfo.numPayloads );
pp = currPictureInfo.payloadData;
for ( i = 0; i < currPictureInfo.numPayloads; i++ )
{
assert( pp != NULL );
// fprintf( f, "payloadsize of %d is: %d\n", i, pp->payloadSize );
// 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;
}
// fclose ( f );
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->next = NULL;
pli->pn = img->pn;
pli->type = img->type;
pli->max_lindex = img->max_lindex;
pli->lindex = img->lindex;
// set values
if ( input->partition_mode == PAR_DP_1 )
pli->payloadType = 0;
else
assert(0==1);
pli->parameterSet = box_ps.parameterSetID;
pli->pictureID = img->currentSlice->picture_id;
pli->sliceID = img->current_slice_nr;
// copied from rtp.c, and add pli->sliceType2
switch (img->type)
{
case INTER_IMG:
if (img->types==SP_IMG)
{
pli->sliceType = 2;
pli->sliceType2 = SP_IMG;
}
else
{
pli->sliceType = 0;
pli->sliceType2 = INTER_IMG;
}
break;
case INTRA_IMG:
pli->sliceType = 3;
pli->sliceType2 = INTRA_IMG;
break;
case B_IMG:
pli->sliceType = 1;
pli->sliceType2 = B_IMG;
break;
case SP_IMG:
pli->sliceType = 2;
pli->sliceType2 = SP_IMG;
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;
// begin of ERPS
#ifdef _CHECK_MULTI_BUFFER_1_
/* RPSL: Reference Picture Selection Layer */
if(img->type!=INTRA_IMG)
{
// let's mix some reference frames
if ((img->pn==5)&&(img->type==INTER_IMG))
{
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_
// some code to check operation
if ((img->pn==3) && (img->type==INTER_IMG))
{
// 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(img);
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;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -