📄 encodeiff.c
字号:
/*!
************************************************************************
* \brief
* Free the memory allocated for Alternate Track Info Box
* \return
* None
************************************************************************
*/
void freeAlternateTrackInfoBox()
{
free(box_ati.info);
}
/*!
************************************************************************
* \brief
* Initiate the Parameter Set Box
* Tian Dong, Feb 10, 2002:
* Only one parameter set, whose ID is set to 0, contained in the output file
* \return
* 0, if success
* -1, otherwise
************************************************************************
*/
int initParameterSetBox()
{
box_ps.type.size = SIZEOF_BOXTYPE + 28; // 26 => 27 => 28, add bufCycle, temporal scalability
box_ps.type.type = BOX_PRMS;
box_ps.parameterSetID = 0;
box_ps.profile = 0;
box_ps.level = 0;
box_ps.version = 0;
box_ps.pictureWidthInMBs = input->img_width / MB_BLOCK_SIZE;
box_ps.pictureHeightInMBs = input->img_height / MB_BLOCK_SIZE;
box_ps.displayRectangleOffsetTop = 0;
box_ps.displayRectangleOffsetLeft = 0;
box_ps.displayRectangleOffsetBottom = 0;
box_ps.displayRectangleOffsetRight = 0;
box_ps.displayMode = 1;
box_ps.displayRectangleOffsetFromWindowTop = 0;
box_ps.displayRectangleOffsetFromWindowLeftBorder = 0;
if ( input->symbol_mode == UVLC ) box_ps.entropyCoding = 0;
else box_ps.entropyCoding = 1;
box_ps.partitioningType = input->partition_mode;
box_ps.intraPredictionType = input->UseConstrainedIntraPred;
box_ps.bufCycle = input->num_reference_frames;
if (input->NumFramesInELSubSeq!=0) box_ps.requiredPictureNumberUpdateBehavior=1;
else box_ps.requiredPictureNumberUpdateBehavior=0;
box_ps.loopFilterParametersFlag = input->LFSendParameters;
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;
unsigned char cd;
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.loopFilterParametersFlag, 1, 1, fp );
num += writefile( &box_ps.entropyCoding, 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 (box_ps.requiredPictureNumberUpdateBehavior==1) cd=0x80;
else cd=0;
num += writefile( &cd, 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, May 30, 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;
if ( box_ps.requiredPictureNumberUpdateBehavior != 0 ) box_ath.numLayers = 2;
else box_ath.numLayers = 0;
assert((box_ath.numLayers <= MAX_LAYER_NUMBER));
if ( initPictureInformationBox() == -1 ) return -1;
if ( initLayerBox() == -1 ) return -1;
return 0;
}
/*!
************************************************************************
* \brief
* Update the data in this Alternate Track Header Box
* Only one PicureInformationBox in ATH, May 30, 2002
* \return
* 0, if success
* -1, if failed
************************************************************************
*/
int updateAlternateTrackHeaderBox()
{
int i;
assert(box_ath.numLayers <= MAX_LAYER_NUMBER );
updatePictureInformationBox();
if ( input->NumFramesInELSubSeq != 0 )
updateLayerBox();
// update the head data
box_ath.type.size = SIZEOF_BOXTYPE + 1 + box_pi.type.size;
for (i=0; i<box_ath.numLayers; i++)
box_ath.type.size += box_layr[i].type.size;
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* destf;
size_t num = 0, ret;
destf = fp;
assert( destf != NULL );
// write the head of Picture Information
num += writefile( &box_ath.type.size, 4, 1, destf );
num += writefile( &box_ath.type.type, 4, 1, destf );
// writefile( &box_ath.type.largesize, 8, 1, destf );
num += writefile( &box_ath.numLayers, 1, 1, destf );
ret = mergePictureInformationBox( destf );
if ( ret == -1 ) return -1;
num += ret;
if ( input->NumFramesInELSubSeq != 0 )
{
ret = mergeLayerBox( destf );
if ( ret == -1 ) return -1;
num += ret;
}
if ( num != box_ath.type.size ) return -1;
return num;
}
/*!
************************************************************************
* \brief
* Free all resource allocated for this Alternate Track Header Box
* \return
* None
************************************************************************
*/
void freeAlternateTrackHeaderBox()
{
freePictureInformationBox();
freeLayerBox();
}
/*!
************************************************************************
* \brief
* Initiate the Picture Information 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 initPictureInformationBox()
{
box_pi.type.size = 0; // to be updated
box_pi.type.type = BOX_PICI;
box_pi.numPictures = 0; // set to 0
box_pi.fpMeta = tmpfile();
if ( box_pi.fpMeta == NULL ) return -1;
currPictureInfo.lastFrameNr = 0; // do this for init of picture info
return 0;
}
/*!
************************************************************************
* \brief
* Update the data in this Picture Information Box
* \return
* 0, if success
* -1, if failed
************************************************************************
*/
int updatePictureInformationBox()
{
int pictureDataSize;
assert( box_pi.fpMeta != NULL );
// update the head data
fseek( box_pi.fpMeta, 0, SEEK_END );
pictureDataSize = ftell( box_pi.fpMeta );
box_pi.type.size = SIZEOF_BOXTYPE + box_fh.numBytesInPictureCountMinusOne+1 + pictureDataSize;
return 0;
}
/*!
************************************************************************
* \brief
* Merge the PictureInformation Data to the output file
* \return
* how many bytes been appended, if success
* -1, if failed
* \param fp
* output file pointer
************************************************************************
*/
size_t mergePictureInformationBox( FILE* fp )
{
FILE* sourcef;
FILE* destf;
unsigned char c;
size_t num = 0;
sourcef = box_pi.fpMeta;
destf = fp;
assert( sourcef != NULL );
assert( destf != NULL );
// write the head of Picture Information
num += writefile( &box_pi.type.size, 4, 1, fp );
num += writefile( &box_pi.type.type, 4, 1, fp );
// writefile( &box_pi.type.largesize, 8, 1, fp );
num += writefile_s( &box_pi.numPictures, sizeof(box_pi.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_pi.type.size ) return num;
return -1;
}
/*!
************************************************************************
* \brief
* Free all resource allocated for this PictureInformation Box
* \return
* None
************************************************************************
*/
void freePictureInformationBox()
{
fclose( box_pi.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 == I_SLICE ) currPictureInfo.intraPictureFlag = TRUE;
else currPictureInfo.intraPictureFlag = FALSE;
if ( img->type == SP_SLICE ) currPictureInfo.syncPictureFlag = TRUE; // ???
else currPictureInfo.syncPictureFlag = FALSE; // ???
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -