⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 header.c

📁 Mobile IP VCEG的信道模拟程序
💻 C
📖 第 1 页 / 共 2 页
字号:
// *************************************************************************************
// *************************************************************************************
// header.c	 H.26L Slice, Picture, and Sequence headers
//
// 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 <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "defines.h"

#include "global.h"
#include "header.h"
#include "elements.h"


// A little trick to avoid those horrible #if TRACE all over the source code
#if TRACE
#define SYMTRACESTRING(s) strcpy(sym.tracestring,s)
#else
#define SYMTRACESTRING(s)	/* to nothing */
#endif

// Local Functions
static int PutSliceStartCode(Bitstream *s);
static int PutPictureStartCode (Bitstream *s);
static int PutStartCode (int Type, Bitstream *s, char *ts);
// static void select_picture_type (SyntaxElement *symbol);

// End local Functions


int PictureHeader() {

// StW: PictureTypeSymbol is the Symbol used to encode the picture type.  
// This is one of the dirtiest hacks if have seen so far from people who 
// usually know what they are doing :-)
// img->type has one of three possible values (I, P, B), the picture type as coded
// distiguishes further by nidicating whether one or more reference frames are
// used for P and B frames 9hence 5 values).  See decoder/defines.h
// The mapping is performed in image.c select_picture_type()

	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;

	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

	// A bit of checking, for debug purposes only, will not be in code later
	assert(img->current_mb_nr == 0);

	// Ok.  We are sure we want to code a Picture Header.  So, first: Put PSC
	len+=PutPictureStartCode (currStream);

	// 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
	// taht 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);

	// Now always put TR 
	// Finally, write Reference Picture ID (same as TR here).  
	sym.value1 = img->tr%256;					// TR, variable length
	SYMTRACESTRING("PHRefPicID");
	len += writeSyntaxElement_UVLC (&sym, partition);

	return len;
}


int SliceHeader(int UseStartCode) {
	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.

	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

	// Note 1.	Current implementation: Slice start code is similar to pictrure start code
	//          (info is 1 for slice and 0 for picture start code).  Slice Start code is not 
	//			present except when generating an UVLC file.  Start codes are typical NAL
	//			functionality, and hence NALs will take care the issue in the future.
	// Note 2:	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

	if (UseStartCode) {
		// Input mode 0, File Format, and not Picture Start (first slice in picture)
		// This is the only case where a slice start code makes sense
		//
		// Putting a Slice Start Code is the same like the picture start code.  It's
		// n ot as straightforward as one thinks,  See remarks above.
		len += PutSliceStartCode(currStream);
	};

	// Now we have coded the Pciture header when appropriate, and the slice header when
	// appropriate.  Follow with the content of the slice header: GOB address of the slice
	// start and (initial) QP.  For the QP see remarks above.  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

	SYMTRACESTRING("SH SliceQuant");
	sym.value1 = 31 - Quant;
	len += writeSyntaxElement_UVLC (&sym, partition);
// printf ("Wrote SliceQuant len %d info %d, value %d\n", sym.len, sym.inf, sym.value1);

	// Put the Motion Vector resolution as per reflector consensus

	SYMTRACESTRING("SH MVResolution");
	sym.value1 = input->mv_res;
	len += writeSyntaxElement_UVLC (&sym, partition);
// printf ("Write MVResolution len %d info %d, value %d\n", sym.len, sym.inf, sym.value1);
		
	return len;
}


int SequenceHeader (FILE *outf) {
  //int LenInBytes = 0;
	int HeaderInfo;					// Binary coded Headerinfo to be written in file
	int ProfileLevelVersionHash;

	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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -