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

📄 header.c

📁 本源码是H.26L标准的Visual C++源代码
💻 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 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 + -