📄 header.c
字号:
// assign a long term index to actual frame
SYMTRACESTRING("RTP-SH: MMCO Assign Long Term Index to a Picture");
// command
sym->value1 = 3;
len += writeSyntaxElement_UVLC (sym, partition);
// DPN=0 for actual frame
sym->value1 = 0;
len += writeSyntaxElement_UVLC (sym, partition);
//long term ID
sym->value1 = img->lindex;
len += writeSyntaxElement_UVLC (sym, partition);
// assign local long term
init_long_term_buffer(2,img);
init_mref(img);
init_Refbuf(img);
assign_long_term_id(3,img->lindex,img);
img->lindex=(img->lindex+1)%img->max_lindex;
}
if ((img->pn==4) && (img->type==INTER_IMG))
{
if (img->max_lindex>0)
{
// delete long term picture again
SYMTRACESTRING("RTP-SH: MMCO Mark a Long-Term Picture as Unused");
// command
sym->value1 = 2;
len += writeSyntaxElement_UVLC (sym, partition);
SYMTRACESTRING("RTP-SH: MMCO LPIN");
// command
sym->value1 = (img->max_lindex+img->lindex-1)%img->max_lindex;
len += writeSyntaxElement_UVLC (sym, partition);
}
}
// end MMCO loop
SYMTRACESTRING("RTP-SH: end loop");
sym->value1 = 0;
len += writeSyntaxElement_UVLC (sym, partition);
#else
/* RPBT: Reference Picture Bufering Type */
SYMTRACESTRING("RTP-SH: Reference Picture Bufering Type");
sym->value1 = 0;
len += writeSyntaxElement_UVLC (sym, partition);
#endif
return len;
}
int SequenceHeader (FILE *outf)
{
int LenInBytes = 0;
int HeaderInfo; // Binary coded Headerinfo to be written in file
int ProfileLevelVersionHash;
// Handle the RTP case
if (input->of_mode == PAR_OF_RTP)
{
if ((LenInBytes = RTPSequenceHeader (outf)) < 0)
{
snprintf (errortext, ET_SIZE, "SequenceHeaqder(): Problems writing the RTP Parameter Packet");
error (errortext, 600);
return -1;
}
else
return LenInBytes*8;
}
// Non RTP-type file formats follow
switch (input->SequenceHeaderType)
{
case 0:
// No SequenceHeader, do nothing
return 0;
case 1:
// A binary mini Sequence header. Fixed length 32 bits. Defined as follows
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | 0 | 1 | 2 | 3 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | TR Modulus | PicIDModulus |OfMode |part |S|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
// S is symbol_mode (UVLC = 0, CABAC = 1), the other are as in the input file
assert (input->TRModulus < 4096);
assert (sizeof (int) == 4);
assert (input->PicIdModulus <4096);
assert (input->of_mode <16);
assert (input->partition_mode <8);
assert (input->symbol_mode < 2);
ProfileLevelVersionHash = input->of_mode<<0 | input->partition_mode<<4 | input->symbol_mode<<7;
HeaderInfo = input->TRModulus | input->PicIdModulus<<12 | ProfileLevelVersionHash<<24;
if (1 != fwrite (&HeaderInfo, 4, 1, outf))
{
snprintf (errortext, ET_SIZE, "Error while writing Mini Sequence Header");
error(errortext, 500);
}
#if TRACE
fprintf(p_trace, "Binary Mini Sequence Header 0x%x\n\n", HeaderInfo);
#endif
return 32;
case 2:
// An ASCII representation of many input file parameters, useful for debug purposes
//
//
assert ("To be hacked");
return -1;
case 3:
// An UVLC coded representatioj of the Sequence Header. To be hacked.
// Note that all UVLC initialization has already taken place, so just use
// write_synyaxelement() to put the sequence header symbols. Has to be double
// checked whether this is true for cabac as well. Do we need a new context
// for that? Anyway:
//
assert ("to be hacked");
return -1;
default:
snprintf (errortext, ET_SIZE, "Unspported Sequence Header Type (should not happen since checked in input module, exiting");
error (errortext, 600);
return -1;
}
}
/********************************************************************************************
********************************************************************************************
*
* Local Support Functions
*
********************************************************************************************
********************************************************************************************/
/*!
********************************************************************************************
* \brief Puts a Start Code into the Bitstream
* ts is a TraceString
*
* \return
* number of bits used for the PSC.
*
* \note
* See PutPictureStartCode()
********************************************************************************************
*/
static int PutStartCode (int Type, Bitstream *s, char *ts)
{
SyntaxElement sym;
// Putting the Start Codes is a bit tricky, because we cannot use writesyntaxelement()
// directly. Problem is that we want a codeword of len == 31 with an info of 0 or 1.
// There is no simple mapping() rule to express this. Of course, one could calculate
// what info would have to be for such a case. But I guess it's cleaner to use
// the len/info interface directly.
sym.len = LEN_STARTCODE;
sym.inf = Type;
sym.type = SE_HEADER;
#if TRACE
strncpy(sym.tracestring, ts, TRACESTRING_SIZE);
#endif
symbol2uvlc(&sym); // generates the bit pattern
writeUVLC2buffer(&sym, s); // and puts it out to the buffer
#if TRACE
trace2out(&sym);
#endif
return LEN_STARTCODE;
}
// StW Note: This function is a hack. It would be cleaner if the encoder maintains
// the picture type in the given format. Note further that I have yet to understand
// why the encoder needs to know whether a picture is predicted from one or more
// reference pictures.
/*!
************************************************************************
* \brief
* Selects picture type and codes it to symbol
************************************************************************
*/
void select_picture_type(SyntaxElement *symbol)
{
int multpred;
#ifdef _ADDITIONAL_REFERENCE_FRAME_
if (input->no_multpred <= 1 && input->add_ref_frame == 0)
#else
if (input->no_multpred <= 1)
#endif
multpred=FALSE;
else
multpred=TRUE; // multiple reference frames in motion search
if (img->type == INTRA_IMG)
{
symbol->len=3;
symbol->inf=1;
symbol->value1 = 2;
}
else if((img->type == INTER_IMG) && (multpred == FALSE) ) // inter single reference frame
{
symbol->len=1;
symbol->inf=0;
symbol->value1 = 0;
}
else if((img->type == INTER_IMG) && (multpred == TRUE)) // inter multiple reference frames
{
symbol->len=3;
symbol->inf=0;
symbol->value1 = 1;
}
else if((img->type == B_IMG) && (multpred == FALSE))
{
symbol->len=5;
symbol->inf=0;
symbol->value1 = 3;
}
else if((img->type == B_IMG) && (multpred == TRUE))
{
symbol->len=5;
symbol->inf=1;
symbol->value1 = 4;
}
else
{
error("Picture Type not supported!",1);
}
if((img->types == SP_IMG ) && (multpred == FALSE))
{
symbol->len=5;
symbol->inf=0;
symbol->value1 = 5;
}
else if((img->types == SP_IMG) && (multpred == TRUE))
{
symbol->len=5;
symbol->inf=0;
symbol->value1 = 6;
}
#if TRACE
snprintf(symbol->tracestring, TRACESTRING_SIZE, "Image type = %3d ", img->type);
#endif
symbol->type = SE_PTYPE;
}
/*!
************************************************************************
* \brief
* Writes the number of MBs of this slice
************************************************************************
*/
void LastMBInSlice()
{
int dP_nr = assignSE2partition[input->partition_mode][SE_HEADER];
DataPartition *partition = &((img->currentSlice)->partArr[dP_nr]);
SyntaxElement *sym;
int d_MB_Nr;
if ((sym=(SyntaxElement*)calloc(1,sizeof(SyntaxElement)))==NULL) no_mem_exit("LastMBInSlice:sym");
d_MB_Nr = img->current_mb_nr-img->currentSlice->start_mb_nr;
if (d_MB_Nr == img->total_number_mb)
d_MB_Nr = 0;
sym->type = SE_HEADER;
sym->mapping = n_linfo2; // Mapping rule: Simple code number to len/info
// Put MB-Adresse
assert (d_MB_Nr < (1<<15));
SYMTRACESTRING("SH Numbers of MB in Slice");
sym->value1 = d_MB_Nr;
writeSyntaxElement_UVLC (sym, partition);
free (sym);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -