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

📄 header.c

📁 JM 11.0 KTA 2.1 Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:

/*!
*************************************************************************************
* \file header.c
*
* \brief
*    H.264 Slice and Sequence headers
*
* \author
*    Main contributors (see contributors.h for copyright, address and affiliation details)
*      - Stephan Wenger                  <stewe@cs.tu-berlin.de>
*      - Karsten Suehring                <suehring@hhi.de>
*************************************************************************************
*/

#include <math.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>

#include "global.h"

#include "elements.h"
#include "header.h"
#include "rtp.h"
#include "mbuffer.h"
#include "defines.h"
#include "vlc.h"
#include "parset.h"
#ifdef ADAPTIVE_FILTER
#include "adaptive_filter.h"
#endif

#ifdef SWITCHED_FILTERS
#include "switched_filters.h"
#endif  // SWITCHED_FILTERS

// 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) // do nothing
#endif

int * assignSE2partition[2] ;
int assignSE2partition_NoDP[SE_MAX_ELEMENTS] =
{  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int assignSE2partition_DP[SE_MAX_ELEMENTS] =
{  0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 2, 2, 2, 2, 0, 0, 0, 0 } ;

static int ref_pic_list_reordering(Bitstream *bitstream);
static int dec_ref_pic_marking    (Bitstream *bitstream);
static int pred_weight_table      (Bitstream *bitstream);

/*!
********************************************************************************************
* \brief 
*    Write a slice header
*
* \return
*    number of bits used 
********************************************************************************************
*/
int SliceHeader()
{
  int dP_nr = assignSE2partition[input->partition_mode][SE_HEADER];
  Bitstream *bitstream = img->currentSlice->partArr[dP_nr].bitstream;
  Slice* currSlice = img->currentSlice;
  int len = 0;
  unsigned int field_pic_flag = 0, bottom_field_flag = 0;

  int num_bits_slice_group_change_cycle;
  float numtmp;  
#ifdef ADAPTIVE_FILTER
  int i, j, apply_adaptive_filter;
  extern int DiffQFilterCoef[15][SQR_FILTER];        // differences to be transmitted
  extern int POS_EQUATION_NUMBER[15];                // number of different coefficietns for each sub-pel position
  extern int FilterFlag[15];                        // Flags defining if Filter at the particular position calculated
  extern int UseAllSubpelPositions;                  // 1 if FilterFlag for all independent positions is 1
  extern int SubpelPositionsPattern;
  extern int FILTER_SIZE;
  extern int FILTER_OFFSET;
#endif

  if (img->MbaffFrameFlag)
    len  = ue_v("SH: first_mb_in_slice", img->current_mb_nr >> 1,   bitstream);
  else
    len  = ue_v("SH: first_mb_in_slice", img->current_mb_nr,   bitstream);

  len += ue_v("SH: slice_type",        get_picture_type (),   bitstream);

  len += ue_v("SH: pic_parameter_set_id" , active_pps->pic_parameter_set_id ,bitstream);

  len += u_v (log2_max_frame_num_minus4 + 4,"SH: frame_num", img->frame_num, bitstream);

  if (!active_sps->frame_mbs_only_flag)
  {
    // field_pic_flag    u(1)
    field_pic_flag = (img->structure ==TOP_FIELD || img->structure ==BOTTOM_FIELD)?1:0;
    assert( field_pic_flag == img->fld_flag );
    len += u_1("SH: field_pic_flag", field_pic_flag, bitstream);

    if (field_pic_flag)
    {
      //bottom_field_flag     u(1)
      bottom_field_flag = (img->structure == BOTTOM_FIELD)?1:0;
      len += u_1("SH: bottom_field_flag" , bottom_field_flag ,bitstream);
    }
  }

  if (img->currentPicture->idr_flag)
  {
    // idr_pic_id
    len += ue_v ("SH: idr_pic_id", (img->number % 2), bitstream);
  }

  if (img->pic_order_cnt_type == 0)
  {
    if (active_sps->frame_mbs_only_flag)
    {
      img->pic_order_cnt_lsb = (img->toppoc & ~((((unsigned int)(-1)) << (log2_max_pic_order_cnt_lsb_minus4+4))) );
    }
    else
    {
      if (!field_pic_flag || img->structure == TOP_FIELD)
        img->pic_order_cnt_lsb = (img->toppoc & ~((((unsigned int)(-1)) << (log2_max_pic_order_cnt_lsb_minus4+4))) );
      else if ( img->structure == BOTTOM_FIELD )
        img->pic_order_cnt_lsb = (img->bottompoc & ~((((unsigned int)(-1)) << (log2_max_pic_order_cnt_lsb_minus4+4))) );
    }

    len += u_v (log2_max_pic_order_cnt_lsb_minus4+4, "SH: pic_order_cnt_lsb", img->pic_order_cnt_lsb, bitstream);

    if (img->pic_order_present_flag && !field_pic_flag)
    {
      len += se_v ("SH: delta_pic_order_cnt_bottom", img->delta_pic_order_cnt_bottom, bitstream);
    }
  }
  if (img->pic_order_cnt_type == 1 && !img->delta_pic_order_always_zero_flag)
  {
    len += se_v ("SH: delta_pic_order_cnt[0]", img->delta_pic_order_cnt[0], bitstream);

    if (img->pic_order_present_flag && !field_pic_flag)
    {
      len += se_v ("SH: delta_pic_order_cnt[1]", img->delta_pic_order_cnt[1], bitstream);
    }
  }

  if (active_pps->redundant_pic_cnt_present_flag)
  {
    len += ue_v ("SH: redundant_pic_cnt", img->redundant_pic_cnt, bitstream);
  }

  // Direct Mode Type selection for B pictures
  if (img->type==B_SLICE)
  {
    len +=  u_1 ("SH: direct_spatial_mv_pred_flag", img->direct_spatial_mv_pred_flag, bitstream);    
  }

  if ((img->type == P_SLICE) || (img->type == B_SLICE) || (img->type==SP_SLICE))
  {
    int override_flag;
    if ((img->type == P_SLICE) || (img->type==SP_SLICE))
    {
      override_flag = (img->num_ref_idx_l0_active != (active_pps->num_ref_idx_l0_active_minus1 +1)) ? 1 : 0;
    }
    else
    {
      override_flag = ((img->num_ref_idx_l0_active != (active_pps->num_ref_idx_l0_active_minus1 +1)) 
        || (img->num_ref_idx_l1_active != (active_pps->num_ref_idx_l1_active_minus1 +1))) ? 1 : 0;
    }

    len +=  u_1 ("SH: num_ref_idx_active_override_flag", override_flag, bitstream);

    if (override_flag) 
    {
      len += ue_v ("SH: num_ref_idx_l0_active_minus1", img->num_ref_idx_l0_active-1, bitstream);
      if (img->type==B_SLICE)
      {
        len += ue_v ("SH: num_ref_idx_l1_active_minus1", img->num_ref_idx_l1_active-1, bitstream);
      }
    }

  }
  len += ref_pic_list_reordering(bitstream);

  if (((img->type == P_SLICE || img->type == SP_SLICE) && active_pps->weighted_pred_flag) || 
    ((img->type == B_SLICE) && active_pps->weighted_bipred_idc == 1))  
  {
    len += pred_weight_table(bitstream);
  }

  if (img->nal_reference_idc)
    len += dec_ref_pic_marking(bitstream);

  if(input->symbol_mode==CABAC && img->type!=I_SLICE /*&& img->type!=SI_IMG*/)
  {
    len += ue_v("SH: cabac_init_idc", img->model_number, bitstream);
  }

  len += se_v("SH: slice_qp_delta", (currSlice->qp - 26 - active_pps->pic_init_qp_minus26), bitstream);  

  if (img->type==SP_SLICE /*|| img->type==SI_SLICE*/)
  {
    if (img->type==SP_SLICE) // Switch Flag only for SP pictures
    {
      len += u_1 ("SH: sp_for_switch_flag", (si_frame_indicator || sp2_frame_indicator), bitstream);   // 1 for switching SP, 0 for normal SP
    }
    len += se_v ("SH: slice_qs_delta", (img->qpsp - 26), bitstream );
  }

  if (active_pps->deblocking_filter_control_present_flag)
  {
    len += ue_v("SH: disable_deblocking_filter_idc",img->LFDisableIdc, bitstream);  // Turn loop filter on/off on slice basis 

    if (img->LFDisableIdc!=1)
    {
      len += se_v ("SH: slice_alpha_c0_offset_div2", img->LFAlphaC0Offset / 2, bitstream);

      len += se_v ("SH: slice_beta_offset_div2", img->LFBetaOffset / 2, bitstream);
    }
  }
#ifdef ADAPTIVE_QUANTIZATION
  len += u_1 ("SH: slice_fractional_quant_flag", (img->slice_fractional_quant_flag&1), bitstream);
  if(img->slice_fractional_quant_flag)
  {
    len += u_1 ("SH: slice_mqm_signaling_flag", (img->slice_mqm_signaling_flag&1), bitstream);
    if(img->slice_mqm_signaling_flag)
    {
      len+=se_v  ("SH: slice_scaling_model_param0",   (img->slice_modeling_qm_param0-32),    bitstream);
      len+=se_v  ("SH: slice_scaling_model_param1",   (img->slice_modeling_qm_param1-16),    bitstream);
    }
  }
#endif
#ifdef EIGHTH_PEL
  len += ue_v ("SH: motion vector resolution", input->mv_res==1?1:0, bitstream);
#endif
#ifdef ADAPTIVE_FD_SD_CODING
  len += u_1 ("SH: SD coding", img->APEC_in_FD_and_SD==1?1:0, bitstream);
  if (img->APEC_in_FD_and_SD)
  {
    len += u_1 ("SH: Quantizer"                , input->SD_Quantizer==1?1:0, bitstream);
  }
#endif
  if ( active_pps->num_slice_groups_minus1>0 &&
    active_pps->slice_group_map_type>=3 && active_pps->slice_group_map_type<=5)
  {
    numtmp=img->PicHeightInMapUnits*img->PicWidthInMbs/(float)(active_pps->slice_group_change_rate_minus1+1)+1;
    num_bits_slice_group_change_cycle = (int)ceil(log(numtmp)/log(2));

    //! img->slice_group_change_cycle can be changed before calling FmoInit()
    len += u_v (num_bits_slice_group_change_cycle, "SH: slice_group_change_cycle", img->slice_group_change_cycle, bitstream);
  }

  // NOTE: The following syntax element is actually part 
  //        Slice data bitstream A RBSP syntax

  if(input->partition_mode&&!img->currentPicture->idr_flag)
  {
    len += ue_v("DPA: slice_id", img->current_slice_nr, bitstream);
  }
#ifdef ADAPTIVE_FILTER
  if(input->UseAdaptiveFilter == 1 && img->AdaptiveFilterFlag == 1)
  {
#ifndef E_DAIF
    len += u_v(2, "SH: apply_adaptive_filter", input->UseAdaptiveFilter, bitstream);
#else
    len += u_v(3, "SH: apply_adaptive_filter", input->UseAdaptiveFilter, bitstream);
#endif

    len += u_1("SH: use_all_subpel_positions", UseAllSubpelPositions, bitstream);
    if(!UseAllSubpelPositions)
      len += ue_v("SH: positions_pattern", SubpelPositionsPattern, bitstream);

    if(FilterFlag[a_pos])
      for(i= 0; i < POS_EQUATION_NUMBER[a_pos]; i++)
        len += se_v("SH: a_pos", DiffQFilterCoef[a_pos][FILTER_SIZE*FILTER_OFFSET+i], bitstream);
    if(FilterFlag[b_pos])
      for(i= 0; i < POS_EQUATION_NUMBER[b_pos]; i++)
        len += se_v("SH: b_pos", DiffQFilterCoef[b_pos][FILTER_SIZE*FILTER_OFFSET+i], bitstream);
    if(FilterFlag[e_pos])
      for(i = 0; i < FILTER_SIZE; i++)
        for(j = i; j < FILTER_SIZE; j++)
          len += se_v("SH: e_pos", DiffQFilterCoef[e_pos][FILTER_SIZE*i+j], bitstream);
    if(FilterFlag[f_pos])
      for(i = 0; i < FILTER_SIZE; i++)
        for(j = 0; j < FILTER_SIZE/2; j++)
          len += se_v("SH: f_pos", DiffQFilterCoef[f_pos][FILTER_SIZE*i+j], bitstream);
    if(FilterFlag[j_pos])
      for(i = 0; i < FILTER_SIZE/2; i++)
        for(j = i; j < FILTER_SIZE/2; j++)
          len += se_v("SH: j_pos", DiffQFilterCoef[j_pos][FILTER_SIZE*i+j], bitstream);
  }
  else if(input->UseAdaptiveFilter == 2 && img->AdaptiveFilterFlag == 1) //separable aif
  {
#ifndef E_DAIF
    len += u_v(2, "SH: apply_adaptive_filter", input->UseAdaptiveFilter, bitstream);
#else
    len += u_v(3, "SH: apply_adaptive_filter", input->UseAdaptiveFilter, bitstream);
#endif

    len += u_1("SH: use_all_subpel_positions", UseAllSubpelPositions, bitstream);
    if(!UseAllSubpelPositions)
      len += ue_v("SH: positions_pattern", SubpelPositionsPattern, bitstream);

    // a_pos
    if(FilterFlag[a_pos])
      for(i= 0; i < FILTER_SIZE; i++)
        len += se_v("SH: a_pos", DiffQFilterCoef[a_pos][i], bitstream);

    // b_pos        
    if(FilterFlag[b_pos])
      for(i= 0; i < FILTER_SIZE>>1; i++)
        len += se_v("SH: b_pos", DiffQFilterCoef[b_pos][i], bitstream);

    // c_pos             
    if(FilterFlag[c_pos])
    {
      if (FilterFlag[a_pos])
        for(i= 0; i < FILTER_SIZE; i++)
          len += se_v("SH: c_pos", DiffQFilterCoef[c_pos][i] - DiffQFilterCoef[a_pos][FILTER_SIZE-i-1], bitstream);
      else 
        for(i= 0; i < FILTER_SIZE; i++)
          len += se_v("SH: c_pos", DiffQFilterCoef[c_pos][i], bitstream);
    }

    // d_pos             
    if(FilterFlag[d_pos])
      for(i= 0; i < FILTER_SIZE; i++)
        len += se_v("SH: d_pos", DiffQFilterCoef[d_pos][i], bitstream);

    // e_pos             
    if(FilterFlag[e_pos])
    {
      if (FilterFlag[d_pos])
        for(i= 0; i < FILTER_SIZE; i++)
          len += se_v("SH: e_pos", DiffQFilterCoef[e_pos][i] - DiffQFilterCoef[d_pos][i], bitstream);
      else
        for(i= 0; i < FILTER_SIZE; i++)
          len += se_v("SH: e_pos", DiffQFilterCoef[e_pos][i], bitstream);
    }

    // f_pos            
    if(FilterFlag[f_pos])
    {
      if (FilterFlag[e_pos])
        for(i= 0; i < FILTER_SIZE; i++)
          len += se_v("SH: f_pos", DiffQFilterCoef[f_pos][i] - DiffQFilterCoef[e_pos][i], bitstream);
      else
        for(i= 0; i < FILTER_SIZE; i++)
          len += se_v("SH: f_pos", DiffQFilterCoef[f_pos][i], bitstream);
    }

    // g_pos             
    if(FilterFlag[g_pos])
    {
      if (FilterFlag[f_pos])
        for(i= 0; i < FILTER_SIZE; i++)
          len += se_v("SH: g_pos", DiffQFilterCoef[g_pos][i] - DiffQFilterCoef[f_pos][i], bitstream);
      else
        for(i= 0; i < FILTER_SIZE; i++)
          len += se_v("SH: g_pos", DiffQFilterCoef[g_pos][i], bitstream);
    }

    // h_pos             
    if(FilterFlag[h_pos])
      for(i= 0; i < FILTER_SIZE>>1; i++)
        len += se_v("SH: h_pos", DiffQFilterCoef[h_pos][i], bitstream);

⌨️ 快捷键说明

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