📄 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"
extern StorablePicture *dec_picture;
#if TRACE
#define SYMTRACESTRING(s) strncpy(sym.tracestring,s,TRACESTRING_SIZE)
#else
#define SYMTRACESTRING(s) // do 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;
}
unsigned CeilLog2_sf( 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);
//fprintf(img->fpinfo, "SH: first_mb_in_slice (%3d)\n", currSlice->start_mb_nr);
tmp = ue_v ("SH: slice_type", currStream);
//fprintf(img->fpinfo, "SH: slice_type (%3d)\n", tmp);
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);
//fprintf(img->fpinfo, "SH: pic_parameter_set_id (%3d)\n", currSlice->pic_parameter_set_id);
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;
img->frame_num = u_v (active_sps->log2_max_frame_num_minus4 + 4, "SH: frame_num", currStream);
//fprintf(img->fpinfo, "SH: frame_num (%3d)\n", img->frame_num);
/* 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);
//fprintf(img->fpinfo, "SH: field_pic_flag (%3d)\n", img->field_pic_flag);
if (img->field_pic_flag)
{
// bottom_field_flag u(1)
img->bottom_field_flag = u_1("SH: bottom_field_flag", currStream);
//fprintf(img->fpinfo, "SH: bottom_field_flag (%3d)\n", img->bottom_field_flag);
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);
//fprintf(img->fpinfo, "SH: idr_pic_id (%3d)\n", img->idr_pic_id);
}
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);
//fprintf(img->fpinfo, "SH: pic_order_cnt_lsb (%3d)\n", img->pic_order_cnt_lsb);
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);
//fprintf(img->fpinfo, "SH: delta_pic_order_cnt_bottom (%3d)\n", img->delta_pic_order_cnt_bottom);
}
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);
//fprintf(img->fpinfo, "SH: delta_pic_order_cnt[0] (%3d)\n", img->delta_pic_order_cnt[ 0 ]);
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);
//fprintf(img->fpinfo, "SH: delta_pic_order_cnt[1] (%3d)\n", img->delta_pic_order_cnt[ 1 ]);
}
}
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);
//fprintf(img->fpinfo, "SH: redundant_pic_cnt (%3d)\n", img->redundant_pic_cnt);
}
if(img->type==B_SLICE)
{
img->direct_spatial_mv_pred_flag = u_1 ("SH: direct_spatial_mv_pred_flag", currStream);
//fprintf(img->fpinfo, "SH: direct_spatial_mv_pred_flag (%3d)\n", img->direct_spatial_mv_pred_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;
if(img->type==P_SLICE || img->type == SP_SLICE || img->type==B_SLICE)
{
val = u_1 ("SH: num_ref_idx_override_flag", currStream);
//fprintf(img->fpinfo, "SH: num_ref_idx_override_flag (%3d)\n", val);
if (val)
{
img->num_ref_idx_l0_active = 1 + ue_v ("SH: num_ref_idx_l0_active_minus1", currStream);
//fprintf(img->fpinfo, "SH: num_ref_idx_l0_active_minus1 (%3d)\n", img->num_ref_idx_l0_active - 1);
if(img->type==B_SLICE)
{
img->num_ref_idx_l1_active = 1 + ue_v ("SH: num_ref_idx_l1_active_minus1", currStream);
//fprintf(img->fpinfo, "SH: num_ref_idx_l1_active_minus1 (%3d)\n", img->num_ref_idx_l1_active - 1);
}
}
}
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);
//fprintf(img->fpinfo, "SH: cabac_init_idc (%3d)\n", img->model_number);
}
else
{
img->model_number = 0;
}
val = se_v("SH: slice_qp_delta", currStream);
//fprintf(img->fpinfo, "SH: slice_qp_delta (%3d)\n", val);
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);
//fprintf(img->fpinfo, "SH: sp_for_switch_flag (%3d)\n", img->sp_switch);
}
val = se_v("SH: slice_qs_delta", currStream);
//fprintf(img->fpinfo, "SH: slice_qs_delta (%3d)\n", val);
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);
//fprintf(img->fpinfo, "SH: disable_deblocking_filter_idc (%3d)\n", currSlice->LFDisableIdc);
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);
//fprintf(img->fpinfo, "SH: slice_alpha_c0_offset_div2 (%3d)\n", currSlice->LFAlphaC0Offset);
//fprintf(img->fpinfo, "SH: slice_beta_offset_div2 (%3d)\n", currSlice->LFBetaOffset);
}
else
{
currSlice->LFAlphaC0Offset = currSlice->LFBetaOffset = 0;
}
}
else
{
currSlice->LFDisableIdc = currSlice->LFAlphaC0Offset = currSlice->LFBetaOffset = 0;
}
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);
//fprintf(img->fpinfo, "SH: slice_group_change_cycle (%3d)\n", img->slice_group_change_cycle);
}
img->PicHeightInMbs = img->FrameHeightInMbs / ( 1 + img->field_pic_flag );
img->PicSizeInMbs = img->PicWidthInMbs * img->PicHeightInMbs;
img->FrameSizeInMbs = img->PicWidthInMbs * img->FrameHeightInMbs;
return UsedBits;
}
/*!
************************************************************************
* \brief
* read the reference picture reordering information
************************************************************************
*/
static void ref_pic_list_reordering()
{
Slice *currSlice = img->currentSlice;
int dP_nr = assignSE2partition[currSlice->dp_mode][SE_HEADER];
DataPartition *partition = &(currSlice->partArr[dP_nr]);
Bitstream *currStream = partition->bitstream;
int i, val;
alloc_ref_pic_list_reordering_buffer(currSlice);
if (img->type!=I_SLICE && img->type!=SI_SLICE)
{
val = currSlice->ref_pic_list_reordering_flag_l0 = u_1 ("SH: ref_pic_list_reordering_flag_l0", currStream);
if (val)
{
i=0;
do
{
val = currSlice->reordering_of_pic_nums_idc_l0[i] = ue_v("SH: reordering_of_pic_nums_idc_l0", currStream);
if (val==0 || val==1)
{
currSlice->abs_diff_pic_num_minus1_l0[i] = ue_v("SH: abs_diff_pic_num_minus1_l0", currStream);
}
else
{
if (val==2)
{
currSlice->long_term_pic_idx_l0[i] = ue_v("SH: long_term_pic_idx_l0", currStream);
}
}
i++;
// assert (i>img->num_ref_idx_l0_active);
} while (val != 3);
}
}
if (img->type==B_SLICE)
{
val = currSlice->ref_pic_list_reordering_flag_l1 = u_1 ("SH: ref_pic_list_reordering_flag_l1", currStream);
if (val)
{
i=0;
do
{
val = currSlice->reordering_of_pic_nums_idc_l1[i] = ue_v("SH: reordering_of_pic_nums_idc_l1", currStream);
if (val==0 || val==1)
{
currSlice->abs_diff_pic_num_minus1_l1[i] = ue_v("SH: abs_diff_pic_num_minus1_l1", currStream);
}
else
{
if (val==2)
{
currSlice->long_term_pic_idx_l1[i] = ue_v("SH: long_term_pic_idx_l1", currStream);
}
}
i++;
// assert (i>img->num_ref_idx_l1_active);
} while (val != 3);
}
}
// set reference index of redundant slices.
if(img->redundant_pic_cnt)
{
redundant_slice_ref_idx = currSlice->abs_diff_pic_num_minus1_l0[0] + 1;
}
}
/*!
************************************************************************
* \brief
* read the weighted prediction tables
************************************************************************
*/
static void pred_weight_table()
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -