?? 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, Picture, 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"// 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 Functionsstatic int PutSliceStartCode(Bitstream *s);static int PutPictureStartCode (Bitstream *s);static int PutStartCode (int Type, Bitstream *s, char *ts);// End local Functionsint 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 indicating whether one or more reference frames are// used for P and B frames (hence 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 // 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); // 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); } 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); 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); 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
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -