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

📄 header.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
***********************************************************************
* 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 Functions
static int PutSliceStartCode(Bitstream *s);
static int PutPictureStartCode (Bitstream *s);
static int PutStartCode (int Type, Bitstream *s, char *ts);

// 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 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 + -