📄 header.c
字号:
/*
***********************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2001, International Telecommunications Union, Geneva
*
* DISCLAIMER OF WARRANTY
*
* These software programs are available to the user without any
* license fee or royalty on an "as is" basis. The ITU disclaims
* any and all warranties, whether express, implied, or
* statutory, including any implied warranties of merchantability
* or of fitness for a particular purpose. In no event shall the
* contributor or the ITU be liable for any incidental, punitive, or
* consequential damages of any kind whatsoever arising from the
* use of these programs.
*
* This disclaimer of warranty extends to the user of these programs
* and user's customers, employees, agents, transferees, successors,
* and assigns.
*
* The ITU does not represent or warrant that the programs furnished
* hereunder are free of infringement of any third-party patents.
* Commercial implementations of ITU-T Recommendations, including
* shareware, may be subject to royalty fees to patent holders.
* Information regarding the ITU-T patent policy is available from
* the ITU Web site at http://www.itu.int.
*
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE ITU-T PATENT POLICY.
************************************************************************
*/
/*!
*************************************************************************************
* \file header.c
*
* \brief
* H.26L Slice and Sequence headers
*
* \author
* Main contributors (see contributors.h for copyright, address and affiliation details)
* - Stephan Wenger <stewe@cs.tu-berlin.de>
*************************************************************************************
*/
#include <math.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include "elements.h"
#include "header.h"
#include "rtp.h"
#include "mbuffer.h"
// A little trick to avoid those horrible #if TRACE all over the source code
#if TRACE
#define SYMTRACESTRING(s) strncpy(sym->tracestring,s,TRACESTRING_SIZE)
#else
#define SYMTRACESTRING(s) // to nothing
#endif
// local function
static int PutStartCode (int Type, Bitstream *s, char *ts);
/*!
********************************************************************************************
* \brief
* Write a slice header
* \note
* We do not have a picture header. All neccessary information is coded at
* the slice level.
********************************************************************************************
*/
int SliceHeader()
{
int dP_nr = assignSE2partition[input->partition_mode][SE_HEADER];
Bitstream *currStream = ((img->currentSlice)->partArr[dP_nr]).bitstream;
DataPartition *partition = &((img->currentSlice)->partArr[dP_nr]);
SyntaxElement *sym;
int len = 0;
int Quant = img->qp; // Hack. This should be a parameter as soon as Gisle is done
int MBPosition = img->current_mb_nr; // Hack. This should be a paremeter as well.
if ((sym=(SyntaxElement*)calloc(1,sizeof(SyntaxElement)))==NULL) no_mem_exit("SliceHeader:sym");
sym->type = SE_HEADER; // This will be true for all symbols generated here
sym->mapping = n_linfo2; // Mapping rule: Simple code number to len/info
// Write a slice start code
len+=PutStartCode (0, currStream, "\nSlice Header");
// Now, take care of te UVLC coded data structure described in VCEG-M79
sym->value1 = 0; // TRType = 0
SYMTRACESTRING("PH TemporalReferenceType");
len += writeSyntaxElement_UVLC (sym, partition);
sym->value1 = img->tr%256; // TR, variable length
SYMTRACESTRING("PH TemporalReference");
len += writeSyntaxElement_UVLC (sym, partition);
// Size information. If the picture is Intra, then transmit the size in MBs,
// For all other picture type just indicate that it didn't change.
// Note: this is currently the prudent way to do things, because we do not
// have anything similar to Annex P of H.263. However, we should anticipate
// that one day we may want to have an Annex P type functionality. Hence, it is
// unwise to assume that P pictures will never have a size indiciation. So the
// one bit for an "unchanged" inidication is well spent.
if (img->type == INTRA_IMG)
{
// Double check that width and height are divisible by 16
assert (img->width % 16 == 0);
assert (img->height % 16 == 0);
sym->value1 = 1; // SizeType = Width/Height in MBs
SYMTRACESTRING("PH FullSizeInformation");
len += writeSyntaxElement_UVLC (sym, partition);
sym->value1 = img->width / 16;
SYMTRACESTRING("PH FullSize-X");
len += writeSyntaxElement_UVLC (sym, partition);
sym->value1 = img->height / 16;
SYMTRACESTRING("PH FullSize-Y");
len += writeSyntaxElement_UVLC (sym, partition);
} else
{ // Not an intra frame -> write "unchanged"
sym->value1 = 0; // SizeType = Unchanged
SYMTRACESTRING("PHSizeUnchanged");
len += writeSyntaxElement_UVLC (sym, partition);
}
select_picture_type (sym);
SYMTRACESTRING("Hacked Picture Type Symbol");
len+= writeSyntaxElement_UVLC (sym, partition);
// Finally, write Reference Picture ID
// WYK: Oct. 16, 2001. Now I use this for the reference frame ID (non-B frame ID).
// If current frame is a B-frame, it will not change; otherwise it is increased by 1 based
// on refPicID of the previous frame. Thus, the decoder can know how many non-B
// frames are lost, and then can adjust the reference frame buffers correctly.
if (1)
{
sym->value1 = img->refPicID%16; // refPicID, variable length
SYMTRACESTRING("PHRefPicID");
len += writeSyntaxElement_UVLC (sym, partition);
}
// For the GOB address, use straigtforward procedure. Note that this allows slices
// to start at MB addresses up to 2^15 MBs due ot start code emulation problems.
// This should be enough for most practical applications,. but probably not for cinema.
// Has to be discussed. For the MPEG tests this is irrelevant, because there the rule
// will be one silce--one picture.
// Put MB-Adresse
assert (MBPosition < (1<<15));
SYMTRACESTRING("SH FirstMBInSlice");
sym->value1 = MBPosition;
len += writeSyntaxElement_UVLC (sym, partition);
// Put Quant. It's a bit irrationale that we still put the same quant here, but it's
// a good provision for the future. In real-world applications slices typically
// start with Intra information, and Intra MBs will likely use a different quant
// than Inter
// Note: Traditionally, the QP is a bit mask. However, at numerically large QPs
// we usually have high compression and don't want to waste bits, whereas
// at low QPs this is not as much an issue. Hence, the QUANT parameter
// is coded as a UVLC calculated as 31 - QUANT. That is, the UVLC representation
// of 31-QUANT is coded, instead of QUANT.
// Note 3: In addition to the fields in VCEG-M79 there is one additional header field
// with the MV resolution. Currently defined values:
// 0 == 1/4th pel resolution (old default)
// 1 == 1/8th pel resolution
// ... could be enhanced straightforward, it may make sense to define
// 2 == 1/2 pel resolution
// 3 == full pel resolution
SYMTRACESTRING("SH SliceQuant");
sym->value1 = 31 - Quant;
len += writeSyntaxElement_UVLC (sym, partition);
if (img->types==SP_IMG)
{
SYMTRACESTRING("SH SP SliceQuant");
sym->value1 = 31 - img->qpsp;
len += writeSyntaxElement_UVLC (sym, partition);
}
// Put the Motion Vector resolution as per reflector consensus
SYMTRACESTRING("SH MVResolution");
sym->value1 = input->mv_res;
len += writeSyntaxElement_UVLC (sym, partition);
len+=writeERPS(sym, partition);
free(sym);
return len;
}
/*!
********************************************************************************************
* \brief
* writes the ERPS syntax elements
*
* \return
* number of bits used for the ERPS
********************************************************************************************
*/
int writeERPS(SyntaxElement *sym, DataPartition *partition)
{
int len=0;
/* RPSF: Reference Picture Selection Flags */
SYMTRACESTRING("RTP-SH: Reference Picture Selection Flags");
sym->value1 = 0;
len += writeSyntaxElement_UVLC (sym, partition);
/* PN: Picture Number */
SYMTRACESTRING("RTP-SH: Picture Number");
sym->value1 = img->pn;
len += writeSyntaxElement_UVLC (sym, partition);
#ifdef _CHECK_MULTI_BUFFER_1_
/* RPSL: Reference Picture Selection Layer */
SYMTRACESTRING("RTP-SH: Reference Picture Selection Layer");
sym->value1 = 1;
len += writeSyntaxElement_UVLC (sym, partition);
if(img->type!=INTRA_IMG)
{
// let's mix some reference frames
if ((img->pn==5)&&(img->type==INTER_IMG))
{
r = (RMPNIbuffer_t*)calloc (1,sizeof(RMPNIbuffer_t));
r->RMPNI=0;
r->Data=2;
r->Next=NULL;
img->currentSlice->rmpni_buffer=r;
// negative ADPN follows
SYMTRACESTRING("RTP-SH: RMPNI");
sym->value1 = 0;
len += writeSyntaxElement_UVLC (sym, partition);
// ADPN
SYMTRACESTRING("RTP-SH: ADPN");
sym->value1 = 2;
len += writeSyntaxElement_UVLC (sym, partition);
}
// End loop
SYMTRACESTRING("RTP-SH: RMPNI");
sym->value1 = 3;
len += writeSyntaxElement_UVLC (sym, partition);
}
reorder_mref(img);
#else
/* RPSL: Reference Picture Selection Layer */
SYMTRACESTRING("RTP-SH: Reference Picture Selection Layer");
sym->value1 = 0;
len += writeSyntaxElement_UVLC (sym, partition);
#endif
#ifdef _CHECK_MULTI_BUFFER_2_
SYMTRACESTRING("RTP-SH: Reference Picture Bufering Type");
sym->value1 = 1;
len += writeSyntaxElement_UVLC (sym, partition);
// 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
SYMTRACESTRING("RTP-SH: MMCO Specify Max Long Term Index");
// command
sym->value1 = 4;
len += writeSyntaxElement_UVLC (sym, partition);
// size = 2+1 (MLP1)
sym->value1 = 2+1;
len += writeSyntaxElement_UVLC (sym, partition);
img->max_lindex=2;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -