📄 encodeiff.c
字号:
unsigned INT16 cd;
unsigned int i;
FILE *fp;
if ( input->NumFramesInELSubSeq == 0 ) return 0;
fp = box_layr[layr].fp;
assert( fp );
if ( box_sseq[layr].numReferenceSubSequences < 0 || box_sseq[layr].numReferenceSubSequences > MAX_DEPENDENT_SUBSEQ )
return -1;
// since we now only deal with the ONE track case, we assert:
assert( box_fh.numAlternateTracks == 1 );
assert( layr >= 0 && layr < box_ath.numLayers );
num += writefile( &box_sseq[layr].type.size, 4, 1, fp );
num += writefile( &box_sseq[layr].type.type, 4, 1, fp );
num += writefile( &box_sseq[layr].subSequenceIdentifier, 2, 1, fp );
if ( box_sseq[layr].continuationFromPreviousSegmentFlag ) cd = 0x8000;
else cd = 0;
if ( box_sseq[layr].continuationToNextSegmentFlag) cd |= 0x4000;
if ( box_sseq[layr].startTickAvailableFlag) cd |= 0x2000;
num += writefile( &cd, 2, 1, fp );
num += writefile( &box_sseq[layr].ssStartTick, 8, 1, fp );
num += writefile( &box_sseq[layr].ssDuration, 8, 1, fp );
num += writefile( &box_sseq[layr].avgBitRate, 4, 1, fp );
num += writefile( &box_sseq[layr].avgFrameRate, 4, 1, fp );
num += writefile( &box_sseq[layr].numReferenceSubSequences, 2, 1, fp );
if ( num != SIZEOF_BOXTYPE+30 ) return -1;
for (i=0; i<box_sseq[layr].numReferenceSubSequences; i++)
{
num2 = writefile( &box_sseq[layr].dependencyData[i].layerNumber, 1, 1, fp );
num2 += writefile( &box_sseq[layr].dependencyData[i].subSequenceIdentifier, 2, 1, fp );
num += num2;
if ( num2 != 3 ) return -1;
}
return num;
}
/*!
************************************************************************
* \brief
* Free the resources allocated for the Sub Sequence Box
* Tian Dong, May 30, 2002:
************************************************************************
*/
void freeSubSequenceBox( int layr )
{
if ( input->NumFramesInELSubSeq == 0 ) return;
}
// 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;
int num = 0;
if (isBigEndian)
p = (byte*)buf;
else
p = (byte*)buf+size-1;
assert( fp != NULL );
assert( buf != NULL );
assert( count == 1 );
while ( size > 0 )
{
if (isBigEndian)
fwrite( p++, 1, 1, fp );
else
fwrite( p--, 1, 1, fp );
size--;
num++;
}
return num;
}
/*!
************************************************************************
* \brief
* write the data to file, bytes are in big Endian order.
* to be used if buffers size differs from number of written bytes
* \return
* how many bytes being written into the file, if success
* -1, otherwise
* \param outf
* output file pointer
************************************************************************
*/
size_t writefile_s( void* buf, size_t bufsize, size_t size, size_t count, FILE* fp )
{
byte* p;
int num = 0;
if (isBigEndian)
p = (byte*)buf+(bufsize-size);
else
p = (byte*)buf+size-1;
assert( fp != NULL );
assert( buf != NULL );
assert( count == 1 );
while ( size > 0 )
{
if (isBigEndian)
fwrite( p++, 1, 1, fp );
else
fwrite( p--, 1, 1, fp );
size--;
num++;
}
return num;
}
/*!
************************************************************************
* \date:
* June 15, 2002
* \brief
* If the first frame in a new sub-sequence is to be encoded,
* this function will do some initialization for the new sub-seq.
************************************************************************
*/
void begin_sub_sequence()
{
if ( input->of_mode == PAR_OF_ANNEXB || input->NumFramesInELSubSeq == 0 ) return;
if ( input->of_mode == PAR_OF_RTP )
{
assert (0==1);
// begin_sub_sequence_rtp();
return;
}
// begin to encode the base layer subseq?
if ( IMG_NUMBER == 0 )
{
// printf("begin to encode the base layer subseq\n");
initSubSequenceBox(0); // init the sub-sequence in the base layer
}
// begin to encode the enhanced layer subseq?
if ( IMG_NUMBER % (input->NumFramesInELSubSeq+1) == 1 )
{
// printf("begin to encode the enhanced layer subseq\n");
initSubSequenceBox(1); // init the sub-sequence in the enhanced layer
add_dependent_subseq(1);
}
}
/*!
************************************************************************
* \date:
* June 15, 2002
* \brief
* If the last frame of current sub-sequence has been encoded,
* this function will do some finalization for the sub-seq.
************************************************************************
*/
void end_sub_sequence()
{
if ( input->of_mode != PAR_OF_ANNEXB || input->NumFramesInELSubSeq == 0 ) return;
if ( input->of_mode == PAR_OF_RTP )
{
assert (0==1);
// end_sub_sequence_rtp();
return;
}
// end of the base layer:
if ( img->number == input->no_frames-1 )
{
// printf("end of encoding the base layer subseq\n");
updateSubSequenceBox(0);
if ( -1 == wrSubSequenceBox(0) )
{
printf("Serious warning: error occurs when trying to write sub sequence box 0.\n");
}
}
// end of the enhanced layer:
if ( ((IMG_NUMBER%(input->NumFramesInELSubSeq+1)==0) && (input->successive_Bframe != 0) && (IMG_NUMBER>0)) || // there are B frames
((IMG_NUMBER%(input->NumFramesInELSubSeq+1)==input->NumFramesInELSubSeq) && (input->successive_Bframe==0)) // there are no B frames
)
{
// printf("end of encoding the enhanced layer subseq\n");
add_dependent_subseq(1);
updateSubSequenceBox(1);
if ( -1 == wrSubSequenceBox(1) )
{
printf("Serious warning: error occurs when trying to write sub sequence box 1.\n");
}
}
}
/*!
************************************************************************
* \date:
* June 15, 2002
* \brief
* Hide some frames in the short term frame buffer
* The number of frames can be used for the forward prediction will
* be set in fb->num_short_used.
************************************************************************
*/
void remap_ref_short_term(PayloadInfo* pp)
{
int i;
RMPNIbuffer_t *r, *t;
int currLayerNo, currSubSeqNo;
int pnp, pnq;
int delta, mdelta;
Boolean need_rmpni = FALSE;
currLayerNo = currPictureInfo.layerNumber;
currSubSeqNo = currPictureInfo.subSequenceIdentifier;
pnp = img->pn;
// check if the remapping is need or not?
for (i=0; i<fb->short_used; i++)
{
if ( fb->picbuf_short[i]->layer_no > currLayerNo ||
(fb->picbuf_short[i]->layer_no == currLayerNo && fb->picbuf_short[i]->sub_seq_no != currSubSeqNo)
)
{
need_rmpni = TRUE;
break;
}
}
if ( !need_rmpni ) return;
fb->num_short_used = 0;
// Tian Dong: we use the reverse order for re-mapping to let the latest frame
// to have the relative index 0. See our implementation accompanying document, section 1.2.5
t = img->currentSlice->rmpni_buffer;
for (i=fb->short_used-1; i>=0; i--)
{
if ( fb->picbuf_short[i]->layer_no < currLayerNo ||
(fb->picbuf_short[i]->layer_no == currLayerNo && fb->picbuf_short[i]->sub_seq_no == currSubSeqNo)
)
{
r = (RMPNIbuffer_t*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -