📄 header.c
字号:
/*!
*************************************************************************************
* \file header.c
*
* \brief
* H.264 Slice headers
*
*************************************************************************************
*/
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include "global.h"
#include "elements.h"
#include "defines.h"
#include "fmo.h"
#include "vlc.h"
#include "mbuffer.h"
#include "header.h"
#include "ctx_tables.h"
#ifdef ADAPTIVE_FILTER
#include "adaptive_filter.h"
#endif
#ifdef ADAPTIVE_QUANTIZATION
#include "adaptive_quantization.h"
#endif
extern StorablePicture *dec_picture;
#if TRACE
#define SYMTRACESTRING(s) strncpy(sym.tracestring,s,TRACESTRING_SIZE)
#else
#define SYMTRACESTRING(s) // to nothing
#endif
extern int UsedBits;
static void ref_pic_list_reordering();
static void pred_weight_table();
/*!
************************************************************************
* \brief
* calculate Ceil(Log2(uiVal))
************************************************************************
*/
unsigned CeilLog2( unsigned uiVal)
{
unsigned uiTmp = uiVal-1;
unsigned uiRet = 0;
while( uiTmp != 0 )
{
uiTmp >>= 1;
uiRet++;
}
return uiRet;
}
/*!
************************************************************************
* \brief
* read the first part of the header (only the pic_parameter_set_id)
* \return
* Length of the first part of the slice header (in bits)
************************************************************************
*/
int FirstPartOfSliceHeader()
{
Slice *currSlice = img->currentSlice;
int dP_nr = assignSE2partition[currSlice->dp_mode][SE_HEADER];
DataPartition *partition = &(currSlice->partArr[dP_nr]);
Bitstream *currStream = partition->bitstream;
int tmp;
UsedBits= partition->bitstream->frame_bitoffset; // was hardcoded to 31 for previous start-code. This is better.
// Get first_mb_in_slice
currSlice->start_mb_nr = ue_v ("SH: first_mb_in_slice", currStream);
tmp = ue_v ("SH: slice_type", currStream);
if (tmp>4) tmp -=5;
img->type = currSlice->picture_type = (SliceType) tmp;
currSlice->pic_parameter_set_id = ue_v ("SH: pic_parameter_set_id", currStream);
return UsedBits;
}
/*!
************************************************************************
* \brief
* read the scond part of the header (without the pic_parameter_set_id
* \return
* Length of the second part of the Slice header in bits
************************************************************************
*/
int RestOfSliceHeader()
{
Slice *currSlice = img->currentSlice;
int dP_nr = assignSE2partition[currSlice->dp_mode][SE_HEADER];
DataPartition *partition = &(currSlice->partArr[dP_nr]);
Bitstream *currStream = partition->bitstream;
int val, len;
#ifdef ADAPTIVE_FILTER
int sub_pos, i, j;
extern int FILTER_SIZE;
extern int FILTER_OFFSET;
extern int UseAllSubpelPositions;
extern int SubpelPositionsPattern;
extern int DiffQFilterCoef[15][SQR_FILTER]; // differences to be received
extern int FilterFlag[15];
extern int POS_EQUATION_NUMBER[15];
#endif
img->frame_num = u_v (active_sps->log2_max_frame_num_minus4 + 4, "SH: frame_num", currStream);
/* Tian Dong: frame_num gap processing, if found */
if (img->idr_flag)
{
img->pre_frame_num = img->frame_num;
// picture error concealment
img->last_ref_pic_poc = 0;
assert(img->frame_num == 0);
}
if (active_sps->frame_mbs_only_flag)
{
img->structure = FRAME;
img->field_pic_flag=0;
}
else
{
// field_pic_flag u(1)
img->field_pic_flag = u_1("SH: field_pic_flag", currStream);
if (img->field_pic_flag)
{
// bottom_field_flag u(1)
img->bottom_field_flag = u_1("SH: bottom_field_flag", currStream);
img->structure = img->bottom_field_flag ? BOTTOM_FIELD : TOP_FIELD;
}
else
{
img->structure = FRAME;
img->bottom_field_flag=0;
}
}
currSlice->structure = (PictureStructure)img->structure;
img->MbaffFrameFlag=(active_sps->mb_adaptive_frame_field_flag && (img->field_pic_flag==0));
if (img->structure == FRAME ) assert (img->field_pic_flag == 0);
if (img->structure == TOP_FIELD ) assert (img->field_pic_flag == 1 && img->bottom_field_flag == 0);
if (img->structure == BOTTOM_FIELD) assert (img->field_pic_flag == 1 && img->bottom_field_flag == 1);
if (img->idr_flag)
{
img->idr_pic_id = ue_v("SH: idr_pic_id", currStream);
}
if (active_sps->pic_order_cnt_type == 0)
{
img->pic_order_cnt_lsb = u_v(active_sps->log2_max_pic_order_cnt_lsb_minus4 + 4, "SH: pic_order_cnt_lsb", currStream);
if( active_pps->pic_order_present_flag == 1 && !img->field_pic_flag )
img->delta_pic_order_cnt_bottom = se_v("SH: delta_pic_order_cnt_bottom", currStream);
else
img->delta_pic_order_cnt_bottom = 0;
}
if( active_sps->pic_order_cnt_type == 1 && !active_sps->delta_pic_order_always_zero_flag )
{
img->delta_pic_order_cnt[ 0 ] = se_v("SH: delta_pic_order_cnt[0]", currStream);
if( active_pps->pic_order_present_flag == 1 && !img->field_pic_flag )
img->delta_pic_order_cnt[ 1 ] = se_v("SH: delta_pic_order_cnt[1]", currStream);
}else
{
if (active_sps->pic_order_cnt_type == 1)
{
img->delta_pic_order_cnt[ 0 ] = 0;
img->delta_pic_order_cnt[ 1 ] = 0;
}
}
//! redundant_pic_cnt is missing here
if (active_pps->redundant_pic_cnt_present_flag)
{
img->redundant_pic_cnt = ue_v ("SH: redundant_pic_cnt", currStream);
}
if(img->type==B_SLICE)
{
img->direct_spatial_mv_pred_flag = u_1 ("SH: direct_spatial_mv_pred_flag", currStream);
}
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;
if(img->type==P_SLICE || img->type == SP_SLICE || img->type==B_SLICE)
{
val = u_1 ("SH: num_ref_idx_override_flag", currStream);
if (val)
{
img->num_ref_idx_l0_active = 1 + ue_v ("SH: num_ref_idx_l0_active_minus1", currStream);
if(img->type==B_SLICE)
{
img->num_ref_idx_l1_active = 1 + ue_v ("SH: num_ref_idx_l1_active_minus1", currStream);
}
}
}
if (img->type!=B_SLICE)
{
img->num_ref_idx_l1_active = 0;
}
ref_pic_list_reordering();
img->apply_weights = ((active_pps->weighted_pred_flag && (currSlice->picture_type == P_SLICE || currSlice->picture_type == SP_SLICE) )
|| ((active_pps->weighted_bipred_idc > 0 ) && (currSlice->picture_type == B_SLICE)));
if ((active_pps->weighted_pred_flag&&(img->type==P_SLICE|| img->type == SP_SLICE))||
(active_pps->weighted_bipred_idc==1 && (img->type==B_SLICE)))
{
pred_weight_table();
}
if (img->nal_reference_idc)
dec_ref_pic_marking(currStream);
if (active_pps->entropy_coding_mode_flag && img->type!=I_SLICE && img->type!=SI_SLICE)
{
img->model_number = ue_v("SH: cabac_init_idc", currStream);
}
else
{
img->model_number = 0;
}
val = se_v("SH: slice_qp_delta", currStream);
currSlice->qp = img->qp = 26 + active_pps->pic_init_qp_minus26 + val;
if ((img->qp < -img->bitdepth_luma_qp_scale) || (img->qp > 51))
error ("slice_qp_delta makes slice_qp_y out of range", 500);
currSlice->slice_qp_delta = val;
if(img->type==SP_SLICE || img->type == SI_SLICE)
{
if(img->type==SP_SLICE)
{
img->sp_switch = u_1 ("SH: sp_for_switch_flag", currStream);
}
val = se_v("SH: slice_qs_delta", currStream);
img->qpsp = 26 + active_pps->pic_init_qs_minus26 + val;
if ((img->qpsp < 0) || (img->qpsp > 51))
error ("slice_qs_delta makes slice_qs_y out of range", 500);
}
if (active_pps->deblocking_filter_control_present_flag)
{
currSlice->LFDisableIdc = ue_v ("SH: disable_deblocking_filter_idc", currStream);
if (currSlice->LFDisableIdc!=1)
{
currSlice->LFAlphaC0Offset = 2 * se_v("SH: slice_alpha_c0_offset_div2", currStream);
currSlice->LFBetaOffset = 2 * se_v("SH: slice_beta_offset_div2", currStream);
}
else
{
currSlice->LFAlphaC0Offset = currSlice->LFBetaOffset = 0;
}
}
else
{
currSlice->LFDisableIdc = currSlice->LFAlphaC0Offset = currSlice->LFBetaOffset = 0;
}
#ifdef ADAPTIVE_QUANTIZATION
img->slice_fractional_quant_flag = u_1 ("SH: slice_fractional_quant_flag", currStream);
if(img->slice_fractional_quant_flag)
{
img->slice_mqm_signaling_flag = u_1 ("SH: slice_mqm_signaling_flag", currStream);
if(img->slice_mqm_signaling_flag)
{
img->slice_modeling_qm_param0 = se_v ("SH: slice_modeling_qm_param0", currStream) + 32;
img->slice_modeling_qm_param1 = se_v ("SH: slice_modeling_qm_param1", currStream) + 16;
}
else
{
img->slice_modeling_qm_param0 = 32;
img->slice_modeling_qm_param1 = 16;
}
SetAutoScalingListDataForMQM(img->slice_modeling_qm_param0, img->slice_modeling_qm_param1);
CreateModelingMatrixForIAQMS();
}
#endif
#ifdef EIGHTH_PEL
// 1/8-pel motion vector resolution (munderl)
img->mv_res = ue_v( "SH: motion vector resolution" , currStream);
#endif
#ifdef ADAPTIVE_FD_SD_CODING
img->Allow_SD_Coding = u_1( "SH: SD coding" , currStream);
if (img->Allow_SD_Coding)
{
img->SD_Quantizer = u_1( "SH: Quantizer" , currStream);
}
#endif
if (active_pps->num_slice_groups_minus1>0 && active_pps->slice_group_map_type>=3 &&
active_pps->slice_group_map_type<=5)
{
len = (active_sps->pic_height_in_map_units_minus1+1)*(active_sps->pic_width_in_mbs_minus1+1)/
(active_pps->slice_group_change_rate_minus1+1);
if (((active_sps->pic_height_in_map_units_minus1+1)*(active_sps->pic_width_in_mbs_minus1+1))%
(active_pps->slice_group_change_rate_minus1+1))
len +=1;
len = CeilLog2(len+1);
img->slice_group_change_cycle = u_v (len, "SH: slice_group_change_cycle", currStream);
}
img->PicHeightInMbs = img->FrameHeightInMbs / ( 1 + img->field_pic_flag );
img->PicSizeInMbs = img->PicWidthInMbs * img->PicHeightInMbs;
img->FrameSizeInMbs = img->PicWidthInMbs * img->FrameHeightInMbs;
#ifdef ADAPTIVE_FILTER
ResetAdaptiveFilter();
if(UseAdaptiveFilterForCurrentFrame())
{
#ifdef E_DAIF
img->AdaptiveFilterFlag = u_v(3,"apply_adaptive_filter", currStream);
#else
img->AdaptiveFilterFlag = u_v(2,"apply_adaptive_filter", currStream);
#endif
if(img->AdaptiveFilterFlag == FILTER_TYPE_2D_NS) // 2D aif
{
UseAllSubpelPositions = u_1("use_all_subpel_positions", currStream);
if(UseAllSubpelPositions)
{
for(sub_pos=a_pos; sub_pos <= o_pos; sub_pos++)
FilterFlag[sub_pos] = 1;
SubpelPositionsPattern = (FilterFlag[j_pos]<<4) + (FilterFlag[f_pos]<<3) + (FilterFlag[e_pos]<<2) +
(FilterFlag[b_pos]<<1) + FilterFlag[a_pos];
}
else
{
SubpelPositionsPattern = ue_v("positions_pattern", currStream);
FilterFlag[a_pos] =
FilterFlag[c_pos] =
FilterFlag[d_pos] =
FilterFlag[l_pos] = SubpelPositionsPattern & 1;
FilterFlag[b_pos] =
FilterFlag[h_pos] = (SubpelPositionsPattern >> 1) & 1;
FilterFlag[e_pos] =
FilterFlag[g_pos] =
FilterFlag[m_pos] =
FilterFlag[o_pos] = (SubpelPositionsPattern >> 2) & 1;
FilterFlag[f_pos] =
FilterFlag[i_pos] =
FilterFlag[k_pos] =
FilterFlag[n_pos] = (SubpelPositionsPattern >> 3) & 1;
FilterFlag[j_pos] = (SubpelPositionsPattern >> 4) & 1;
}
if(FilterFlag[a_pos])
for(i= 0; i < POS_EQUATION_NUMBER[a_pos]; i++)
DiffQFilterCoef[a_pos][FILTER_SIZE*FILTER_OFFSET+i] = se_v("a_pos", currStream);
if(FilterFlag[b_pos])
for(i= 0; i < POS_EQUATION_NUMBER[b_pos]; i++)
DiffQFilterCoef[b_pos][FILTER_SIZE*FILTER_OFFSET+i] = se_v("b_pos", currStream);
if(FilterFlag[e_pos])
for(i = 0; i < FILTER_SIZE; i++)
for(j = i; j < FILTER_SIZE; j++)
DiffQFilterCoef[e_pos][FILTER_SIZE*i+j] = se_v("e_pos", currStream);
if(FilterFlag[f_pos])
for(i = 0; i < FILTER_SIZE; i++)
for(j = 0; j < FILTER_SIZE/2; j++)
DiffQFilterCoef[f_pos][FILTER_SIZE*i+j] = se_v("f_pos", currStream);
if(FilterFlag[j_pos])
for(i = 0; i < FILTER_SIZE/2; i++)
for(j = i; j < FILTER_SIZE/2; j++)
DiffQFilterCoef[j_pos][FILTER_SIZE*i+j] = se_v("j_pos", currStream);
for(sub_pos = a_pos; sub_pos <= o_pos; sub_pos++)
ExtendFilterCoefficientsInt(sub_pos, DiffQFilterCoef);
}
else if (img->AdaptiveFilterFlag == FILTER_TYPE_2D_S) // separable aif
{
UseAllSubpelPositions = u_1("use_all_subpel_positions", currStream);
if(UseAllSubpelPositions)
{
for(sub_pos=a_pos; sub_pos <= o_pos; sub_pos++)
FilterFlag[sub_pos] = 1;
SubpelPositionsPattern = 2047;
}
else
{
SubpelPositionsPattern = ue_v ("positions_pattern", currStream);
FilterFlag[a_pos] = SubpelPositionsPattern & 1;
FilterFlag[b_pos] = (SubpelPositionsPattern >> 1) & 1;
FilterFlag[c_pos] = (SubpelPositionsPattern >> 2) & 1;
FilterFlag[d_pos] = (SubpelPositionsPattern >> 3) & 1;
FilterFlag[e_pos] = (SubpelPositionsPattern >> 4) & 1;
FilterFlag[f_pos] = (SubpelPositionsPattern >> 5) & 1;
FilterFlag[g_pos] = (SubpelPositionsPattern >> 6) & 1;
FilterFlag[h_pos] = (SubpelPositionsPattern >> 7) & 1;
FilterFlag[i_pos] = (SubpelPositionsPattern >> 8) & 1;
FilterFlag[j_pos] = (SubpelPositionsPattern >> 9) & 1;
FilterFlag[k_pos] = (SubpelPositionsPattern >> 10) & 1;
FilterFlag[l_pos] = FilterFlag[d_pos];
FilterFlag[m_pos] = FilterFlag[e_pos];
FilterFlag[n_pos] = FilterFlag[f_pos];
FilterFlag[o_pos] = FilterFlag[g_pos];
}
// a_pos
if(FilterFlag[a_pos])
for(i= 0; i < FILTER_SIZE; i++)
DiffQFilterCoef[a_pos][i] = se_v("a_pos", currStream);
// b_pos
if(FilterFlag[b_pos])
{
for(i= 0; i < FILTER_SIZE >> 1; i++)
DiffQFilterCoef[b_pos][i] = se_v("b_pos", currStream);
DiffQFilterCoef[b_pos][3] = DiffQFilterCoef[b_pos][2];
DiffQFilterCoef[b_pos][4] = DiffQFilterCoef[b_pos][1];
DiffQFilterCoef[b_pos][5] = DiffQFilterCoef[b_pos][0];
}
// c_pos
if(FilterFlag[c_pos])
{
if (FilterFlag[a_pos])
for(i= 0; i < FILTER_SIZE; i++)
DiffQFilterCoef[c_pos][i] = se_v("c_pos", currStream) + DiffQFilterCoef[a_pos][FILTER_SIZE-i-1];
else
for(i= 0; i < FILTER_SIZE; i++)
DiffQFilterCoef[c_pos][i] = se_v("c_pos", currStream);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -