static void slice_header(struct h265_private *p) { int i; p->slice.first_slice_segment_in_pic_flag = get_u(p->regs, 1); if (p->nal_unit_type >= 16 && p->nal_unit_type <= 23) p->slice.no_output_of_prior_pics_flag = get_u(p->regs, 1); p->slice.slice_pic_parameter_set_id = get_ue(p->regs); if (!p->slice.first_slice_segment_in_pic_flag) { if (p->info->dependent_slice_segments_enabled_flag) p->slice.dependent_slice_segment_flag = get_u(p->regs, 1); p->slice.slice_segment_address = get_u(p->regs, ceil_log2(PicSizeInCtbsY)); } if (!p->slice.dependent_slice_segment_flag) { p->slice.pic_output_flag = 1; p->slice.num_ref_idx_l0_active_minus1 = p->info->num_ref_idx_l0_default_active_minus1; p->slice.num_ref_idx_l1_active_minus1 = p->info->num_ref_idx_l1_default_active_minus1; p->slice.collocated_from_l0_flag = 1; p->slice.slice_deblocking_filter_disabled_flag = p->info->pps_deblocking_filter_disabled_flag; p->slice.slice_beta_offset_div2 = p->info->pps_beta_offset_div2; p->slice.slice_tc_offset_div2 = p->info->pps_tc_offset_div2; p->slice.slice_loop_filter_across_slices_enabled_flag = p->info->pps_loop_filter_across_slices_enabled_flag; skip_bits(p->regs, p->info->num_extra_slice_header_bits); p->slice.slice_type = get_ue(p->regs); if (p->info->output_flag_present_flag) p->slice.pic_output_flag = get_u(p->regs, 1); if (p->info->separate_colour_plane_flag == 1) p->slice.colour_plane_id = get_u(p->regs, 2); if (p->nal_unit_type != 19 && p->nal_unit_type != 20) { p->slice.slice_pic_order_cnt_lsb = get_u(p->regs, p->info->log2_max_pic_order_cnt_lsb_minus4 + 4); p->slice.short_term_ref_pic_set_sps_flag = get_u(p->regs, 1); skip_bits(p->regs, p->info->NumShortTermPictureSliceHeaderBits); if (p->info->long_term_ref_pics_present_flag) skip_bits(p->regs, p->info->NumLongTermPictureSliceHeaderBits); if (p->info->sps_temporal_mvp_enabled_flag) p->slice.slice_temporal_mvp_enabled_flag = get_u(p->regs, 1); } if (p->info->sample_adaptive_offset_enabled_flag) { p->slice.slice_sao_luma_flag = get_u(p->regs, 1); p->slice.slice_sao_chroma_flag = get_u(p->regs, 1); } if (p->slice.slice_type == SLICE_P || p->slice.slice_type == SLICE_B) { p->slice.num_ref_idx_active_override_flag = get_u(p->regs, 1); if (p->slice.num_ref_idx_active_override_flag) { p->slice.num_ref_idx_l0_active_minus1 = get_ue(p->regs); if (p->slice.slice_type == SLICE_B) p->slice.num_ref_idx_l1_active_minus1 = get_ue(p->regs); } if (p->info->lists_modification_present_flag && p->info->NumPocTotalCurr > 1) ref_pic_lists_modification(p); if (p->slice.slice_type == SLICE_B) p->slice.mvd_l1_zero_flag = get_u(p->regs, 1); if (p->info->cabac_init_present_flag) p->slice.cabac_init_flag = get_u(p->regs, 1); if (p->slice.slice_temporal_mvp_enabled_flag) { if (p->slice.slice_type == SLICE_B) p->slice.collocated_from_l0_flag = get_u(p->regs, 1); if ((p->slice.collocated_from_l0_flag && p->slice.num_ref_idx_l0_active_minus1 > 0) || (!p->slice.collocated_from_l0_flag && p->slice.num_ref_idx_l1_active_minus1 > 0)) p->slice.collocated_ref_idx = get_ue(p->regs); } if ((p->info->weighted_pred_flag && p->slice.slice_type == SLICE_P) || (p->info->weighted_bipred_flag && p->slice.slice_type == SLICE_B)) pred_weight_table(p); p->slice.five_minus_max_num_merge_cand = get_ue(p->regs); } p->slice.slice_qp_delta = get_se(p->regs); if (p->info->pps_slice_chroma_qp_offsets_present_flag) { p->slice.slice_cb_qp_offset = get_se(p->regs); p->slice.slice_cr_qp_offset = get_se(p->regs); } if (p->info->deblocking_filter_override_enabled_flag) p->slice.deblocking_filter_override_flag = get_u(p->regs, 1); if (p->slice.deblocking_filter_override_flag) { p->slice.slice_deblocking_filter_disabled_flag = get_u(p->regs, 1); if (!p->slice.slice_deblocking_filter_disabled_flag) { p->slice.slice_beta_offset_div2 = get_se(p->regs); p->slice.slice_tc_offset_div2 = get_se(p->regs); } } if (p->info->pps_loop_filter_across_slices_enabled_flag && (p->slice.slice_sao_luma_flag || p->slice.slice_sao_chroma_flag || !p->slice.slice_deblocking_filter_disabled_flag)) p->slice.slice_loop_filter_across_slices_enabled_flag = get_u(p->regs, 1); } if (p->info->tiles_enabled_flag || p->info->entropy_coding_sync_enabled_flag) { p->slice.num_entry_point_offsets = get_ue(p->regs); if (p->slice.num_entry_point_offsets > 0) { p->slice.offset_len_minus1 = get_ue(p->regs); for (i = 0; i < p->slice.num_entry_point_offsets; i++) p->slice.entry_point_offset_minus1[i] = get_u(p->regs, p->slice.offset_len_minus1 + 1); } } if (p->info->slice_segment_header_extension_present_flag) skip_bits(p->regs, get_ue(p->regs) * 8); }
/*! ************************************************************************ * \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) { VideoParameters *p_Vid = currSlice->p_Vid; InputParameters *p_Inp = currSlice->p_Inp; seq_parameter_set_rbsp_t *active_sps = p_Vid->active_sps; byte dP_nr = assignSE2partition[currSlice->dp_mode][SE_HEADER]; DataPartition *partition = &(currSlice->partArr[dP_nr]); Bitstream *currStream = partition->bitstream; int val, len; currSlice->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(currSlice->idr_flag) //if (p_Vid->idr_flag) { p_Vid->pre_frame_num = currSlice->frame_num; // picture error concealment p_Vid->last_ref_pic_poc = 0; assert(currSlice->frame_num == 0); } if (active_sps->frame_mbs_only_flag) { p_Vid->structure = FRAME; currSlice->field_pic_flag=0; } else { // field_pic_flag u(1) currSlice->field_pic_flag = u_1("SH: field_pic_flag", currStream); if (currSlice->field_pic_flag) { // bottom_field_flag u(1) currSlice->bottom_field_flag = (byte) u_1("SH: bottom_field_flag", currStream); p_Vid->structure = currSlice->bottom_field_flag ? BOTTOM_FIELD : TOP_FIELD; } else { p_Vid->structure = FRAME; currSlice->bottom_field_flag = FALSE; } } currSlice->structure = (PictureStructure) p_Vid->structure; currSlice->mb_aff_frame_flag = (active_sps->mb_adaptive_frame_field_flag && (currSlice->field_pic_flag==0)); //currSlice->mb_aff_frame_flag = p_Vid->mb_aff_frame_flag; if (p_Vid->structure == FRAME ) assert (currSlice->field_pic_flag == 0); if (p_Vid->structure == TOP_FIELD ) assert (currSlice->field_pic_flag == 1 && (currSlice->bottom_field_flag == FALSE)); if (p_Vid->structure == BOTTOM_FIELD) assert (currSlice->field_pic_flag == 1 && (currSlice->bottom_field_flag == TRUE )); if (currSlice->idr_flag) { currSlice->idr_pic_id = ue_v("SH: idr_pic_id", currStream); } if (active_sps->pic_order_cnt_type == 0) { currSlice->pic_order_cnt_lsb = u_v(active_sps->log2_max_pic_order_cnt_lsb_minus4 + 4, "SH: pic_order_cnt_lsb", currStream); if( p_Vid->active_pps->bottom_field_pic_order_in_frame_present_flag == 1 && !currSlice->field_pic_flag ) currSlice->delta_pic_order_cnt_bottom = se_v("SH: delta_pic_order_cnt_bottom", currStream); else currSlice->delta_pic_order_cnt_bottom = 0; } if( active_sps->pic_order_cnt_type == 1) { if ( !active_sps->delta_pic_order_always_zero_flag ) { currSlice->delta_pic_order_cnt[ 0 ] = se_v("SH: delta_pic_order_cnt[0]", currStream); if( p_Vid->active_pps->bottom_field_pic_order_in_frame_present_flag == 1 && !currSlice->field_pic_flag ) currSlice->delta_pic_order_cnt[ 1 ] = se_v("SH: delta_pic_order_cnt[1]", currStream); else currSlice->delta_pic_order_cnt[ 1 ] = 0; // set to zero if not in stream } else { currSlice->delta_pic_order_cnt[ 0 ] = 0; currSlice->delta_pic_order_cnt[ 1 ] = 0; } } //! redundant_pic_cnt is missing here if (p_Vid->active_pps->redundant_pic_cnt_present_flag) { currSlice->redundant_pic_cnt = ue_v ("SH: redundant_pic_cnt", currStream); } if(currSlice->slice_type == B_SLICE) { currSlice->direct_spatial_mv_pred_flag = u_1 ("SH: direct_spatial_mv_pred_flag", currStream); } currSlice->num_ref_idx_active[LIST_0] = p_Vid->active_pps->num_ref_idx_l0_active_minus1 + 1; currSlice->num_ref_idx_active[LIST_1] = p_Vid->active_pps->num_ref_idx_l1_active_minus1 + 1; if(p_Vid->type==P_SLICE || p_Vid->type == SP_SLICE || p_Vid->type==B_SLICE) { val = u_1 ("SH: num_ref_idx_override_flag", currStream); if (val) { currSlice->num_ref_idx_active[LIST_0] = 1 + ue_v ("SH: num_ref_idx_l0_active_minus1", currStream); if(p_Vid->type==B_SLICE) { currSlice->num_ref_idx_active[LIST_1] = 1 + ue_v ("SH: num_ref_idx_l1_active_minus1", currStream); } } } if (currSlice->slice_type!=B_SLICE) { currSlice->num_ref_idx_active[LIST_1] = 0; } #if (MVC_EXTENSION_ENABLE) if (currSlice->svc_extension_flag == 0 || currSlice->svc_extension_flag == 1) ref_pic_list_mvc_modification(currSlice); else ref_pic_list_reordering(currSlice); #else ref_pic_list_reordering(currSlice); #endif currSlice->weighted_pred_flag = (unsigned short) ((currSlice->slice_type == P_SLICE || currSlice->slice_type == SP_SLICE) ? p_Vid->active_pps->weighted_pred_flag : (currSlice->slice_type == B_SLICE && p_Vid->active_pps->weighted_bipred_idc == 1)); currSlice->weighted_bipred_idc = (unsigned short) (currSlice->slice_type == B_SLICE && p_Vid->active_pps->weighted_bipred_idc > 0); if ((p_Vid->active_pps->weighted_pred_flag&&(p_Vid->type==P_SLICE|| p_Vid->type == SP_SLICE))|| (p_Vid->active_pps->weighted_bipred_idc==1 && (p_Vid->type==B_SLICE))) { pred_weight_table(currSlice); } if (currSlice->nal_reference_idc) dec_ref_pic_marking(p_Vid, currStream, currSlice); if (p_Vid->active_pps->entropy_coding_mode_flag && p_Vid->type!=I_SLICE && p_Vid->type!=SI_SLICE) { currSlice->model_number = ue_v("SH: cabac_init_idc", currStream); } else { currSlice->model_number = 0; } currSlice->slice_qp_delta = val = se_v("SH: slice_qp_delta", currStream); //currSlice->qp = p_Vid->qp = 26 + p_Vid->active_pps->pic_init_qp_minus26 + val; currSlice->qp = 26 + p_Vid->active_pps->pic_init_qp_minus26 + val; if ((currSlice->qp < -p_Vid->bitdepth_luma_qp_scale) || (currSlice->qp > 51)) error ("slice_qp_delta makes slice_qp_y out of range", 500); if(p_Vid->type==SP_SLICE || p_Vid->type == SI_SLICE) { if(p_Vid->type==SP_SLICE) { currSlice->sp_switch = u_1 ("SH: sp_for_switch_flag", currStream); } currSlice->slice_qs_delta = val = se_v("SH: slice_qs_delta", currStream); currSlice->qs = 26 + p_Vid->active_pps->pic_init_qs_minus26 + val; if ((currSlice->qs < 0) || (currSlice->qs > 51)) error ("slice_qs_delta makes slice_qs_y out of range", 500); } if ( !HI_INTRA_ONLY_PROFILE || (HI_INTRA_ONLY_PROFILE && (p_Inp->intra_profile_deblocking == 1) )) //then read flags and parameters from bistream { if (p_Vid->active_pps->deblocking_filter_control_present_flag) { currSlice->DFDisableIdc = (short) ue_v ("SH: disable_deblocking_filter_idc", currStream); if (currSlice->DFDisableIdc!=1) { currSlice->DFAlphaC0Offset = (short) (2 * se_v("SH: slice_alpha_c0_offset_div2", currStream)); currSlice->DFBetaOffset = (short) (2 * se_v("SH: slice_beta_offset_div2", currStream)); } else { currSlice->DFAlphaC0Offset = currSlice->DFBetaOffset = 0; } } else { currSlice->DFDisableIdc = currSlice->DFAlphaC0Offset = currSlice->DFBetaOffset = 0; } } else //By default the Loop Filter is Off { //444_TEMP_NOTE: change made below. 08/07/07 //still need to parse the SEs (read flags and parameters from bistream) but will ignore if (p_Vid->active_pps->deblocking_filter_control_present_flag) { currSlice->DFDisableIdc = (short) ue_v ("SH: disable_deblocking_filter_idc", currStream); if (currSlice->DFDisableIdc!=1) { currSlice->DFAlphaC0Offset = (short) (2 * se_v("SH: slice_alpha_c0_offset_div2", currStream)); currSlice->DFBetaOffset = (short) (2 * se_v("SH: slice_beta_offset_div2", currStream)); } }//444_TEMP_NOTE. the end of change. 08/07/07 //Ignore the SEs, by default the Loop Filter is Off currSlice->DFDisableIdc =1; currSlice->DFAlphaC0Offset = currSlice->DFBetaOffset = 0; } if (p_Vid->active_pps->num_slice_groups_minus1>0 && p_Vid->active_pps->slice_group_map_type>=3 && p_Vid->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)/ (p_Vid->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))% (p_Vid->active_pps->slice_group_change_rate_minus1+1)) len +=1; len = CeilLog2(len+1); currSlice->slice_group_change_cycle = u_v (len, "SH: slice_group_change_cycle", currStream); } p_Vid->PicHeightInMbs = p_Vid->FrameHeightInMbs / ( 1 + currSlice->field_pic_flag ); p_Vid->PicSizeInMbs = p_Vid->PicWidthInMbs * p_Vid->PicHeightInMbs; p_Vid->FrameSizeInMbs = p_Vid->PicWidthInMbs * p_Vid->FrameHeightInMbs; return p_Dec->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) { VideoParameters *p_Vid = currSlice->p_Vid; InputParameters *p_Inp = currSlice->p_Inp; seq_parameter_set_rbsp_t *active_sps = p_Vid->active_sps; byte dP_nr = assignSE2partition[currSlice->dp_mode][SE_HEADER]; DataPartition *partition = &(currSlice->partArr[dP_nr]); Bitstream *currStream = partition->bitstream; int val, len; currSlice->frame_num = read_u_v (active_sps->log2_max_frame_num_minus4 + 4, "SH: frame_num", currStream, &p_Dec->UsedBits); /* Tian Dong: frame_num gap processing, if found */ if(currSlice->idr_flag) //if (p_Vid->idr_flag) { p_Vid->pre_frame_num = currSlice->frame_num; // picture error concealment p_Vid->last_ref_pic_poc = 0; assert(currSlice->frame_num == 0); } if (active_sps->frame_mbs_only_flag) { p_Vid->structure = FRAME; currSlice->field_pic_flag=0; } else { // field_pic_flag u(1) currSlice->field_pic_flag = read_u_1("SH: field_pic_flag", currStream, &p_Dec->UsedBits); if (currSlice->field_pic_flag) { // bottom_field_flag u(1) currSlice->bottom_field_flag = (byte) read_u_1("SH: bottom_field_flag", currStream, &p_Dec->UsedBits); p_Vid->structure = currSlice->bottom_field_flag ? BOTTOM_FIELD : TOP_FIELD; } else { p_Vid->structure = FRAME; currSlice->bottom_field_flag = FALSE; } } currSlice->structure = (PictureStructure) p_Vid->structure; currSlice->mb_aff_frame_flag = (active_sps->mb_adaptive_frame_field_flag && (currSlice->field_pic_flag==0)); //currSlice->mb_aff_frame_flag = p_Vid->mb_aff_frame_flag; if (currSlice->structure == FRAME ) assert (currSlice->field_pic_flag == 0); if (currSlice->structure == TOP_FIELD ) assert (currSlice->field_pic_flag == 1 && (currSlice->bottom_field_flag == FALSE)); if (currSlice->structure == BOTTOM_FIELD) assert (currSlice->field_pic_flag == 1 && (currSlice->bottom_field_flag == TRUE )); if (currSlice->idr_flag) { currSlice->idr_pic_id = read_ue_v("SH: idr_pic_id", currStream, &p_Dec->UsedBits); } #if (MVC_EXTENSION_ENABLE) else if ( currSlice->svc_extension_flag == 0 && currSlice->NaluHeaderMVCExt.non_idr_flag == 0 ) { currSlice->idr_pic_id = read_ue_v("SH: idr_pic_id", currStream, &p_Dec->UsedBits); } #endif if (active_sps->pic_order_cnt_type == 0) { currSlice->pic_order_cnt_lsb = read_u_v(active_sps->log2_max_pic_order_cnt_lsb_minus4 + 4, "SH: pic_order_cnt_lsb", currStream, &p_Dec->UsedBits); if( p_Vid->active_pps->bottom_field_pic_order_in_frame_present_flag == 1 && !currSlice->field_pic_flag ) currSlice->delta_pic_order_cnt_bottom = read_se_v("SH: delta_pic_order_cnt_bottom", currStream, &p_Dec->UsedBits); else currSlice->delta_pic_order_cnt_bottom = 0; } if( active_sps->pic_order_cnt_type == 1 ) { if ( !active_sps->delta_pic_order_always_zero_flag ) { currSlice->delta_pic_order_cnt[ 0 ] = read_se_v("SH: delta_pic_order_cnt[0]", currStream, &p_Dec->UsedBits); if( p_Vid->active_pps->bottom_field_pic_order_in_frame_present_flag == 1 && !currSlice->field_pic_flag ) currSlice->delta_pic_order_cnt[ 1 ] = read_se_v("SH: delta_pic_order_cnt[1]", currStream, &p_Dec->UsedBits); else currSlice->delta_pic_order_cnt[ 1 ] = 0; // set to zero if not in stream } else { currSlice->delta_pic_order_cnt[ 0 ] = 0; currSlice->delta_pic_order_cnt[ 1 ] = 0; } } //! redundant_pic_cnt is missing here if (p_Vid->active_pps->redundant_pic_cnt_present_flag) { currSlice->redundant_pic_cnt = read_ue_v ("SH: redundant_pic_cnt", currStream, &p_Dec->UsedBits); } if(currSlice->slice_type == B_SLICE) { currSlice->direct_spatial_mv_pred_flag = read_u_1 ("SH: direct_spatial_mv_pred_flag", currStream, &p_Dec->UsedBits); } currSlice->num_ref_idx_active[LIST_0] = p_Vid->active_pps->num_ref_idx_l0_default_active_minus1 + 1; currSlice->num_ref_idx_active[LIST_1] = p_Vid->active_pps->num_ref_idx_l1_default_active_minus1 + 1; if(currSlice->slice_type == P_SLICE || currSlice->slice_type == SP_SLICE || currSlice->slice_type == B_SLICE) { val = read_u_1 ("SH: num_ref_idx_override_flag", currStream, &p_Dec->UsedBits); if (val) { currSlice->num_ref_idx_active[LIST_0] = 1 + read_ue_v ("SH: num_ref_idx_l0_active_minus1", currStream, &p_Dec->UsedBits); if(currSlice->slice_type == B_SLICE) { currSlice->num_ref_idx_active[LIST_1] = 1 + read_ue_v ("SH: num_ref_idx_l1_active_minus1", currStream, &p_Dec->UsedBits); } } } if (currSlice->slice_type!=B_SLICE) { currSlice->num_ref_idx_active[LIST_1] = 0; } #if (MVC_EXTENSION_ENABLE) if (currSlice->svc_extension_flag == 0 || currSlice->svc_extension_flag == 1) ref_pic_list_mvc_modification(currSlice); else ref_pic_list_reordering(currSlice); #else ref_pic_list_reordering(currSlice); #endif currSlice->weighted_pred_flag = (unsigned short) ((currSlice->slice_type == P_SLICE || currSlice->slice_type == SP_SLICE) ? p_Vid->active_pps->weighted_pred_flag : (currSlice->slice_type == B_SLICE && p_Vid->active_pps->weighted_bipred_idc == 1)); currSlice->weighted_bipred_idc = (unsigned short) (currSlice->slice_type == B_SLICE && p_Vid->active_pps->weighted_bipred_idc > 0); if ((p_Vid->active_pps->weighted_pred_flag&&(currSlice->slice_type == P_SLICE|| currSlice->slice_type == SP_SLICE))|| (p_Vid->active_pps->weighted_bipred_idc==1 && (currSlice->slice_type == B_SLICE))) { pred_weight_table(currSlice); } if (currSlice->nal_reference_idc) dec_ref_pic_marking(p_Vid, currStream, currSlice); if (p_Vid->active_pps->entropy_coding_mode_flag && currSlice->slice_type != I_SLICE && currSlice->slice_type != SI_SLICE) { currSlice->model_number = read_ue_v("SH: cabac_init_idc", currStream, &p_Dec->UsedBits); } else { currSlice->model_number = 0; } currSlice->slice_qp_delta = val = read_se_v("SH: slice_qp_delta", currStream, &p_Dec->UsedBits); //currSlice->qp = p_Vid->qp = 26 + p_Vid->active_pps->pic_init_qp_minus26 + val; currSlice->qp = 26 + p_Vid->active_pps->pic_init_qp_minus26 + val; if ((currSlice->qp < -p_Vid->bitdepth_luma_qp_scale) || (currSlice->qp > 51)) error ("slice_qp_delta makes slice_qp_y out of range", 500); if(currSlice->slice_type == SP_SLICE || currSlice->slice_type == SI_SLICE) { if(currSlice->slice_type==SP_SLICE) { currSlice->sp_switch = read_u_1 ("SH: sp_for_switch_flag", currStream, &p_Dec->UsedBits); } currSlice->slice_qs_delta = val = read_se_v("SH: slice_qs_delta", currStream, &p_Dec->UsedBits); currSlice->qs = 26 + p_Vid->active_pps->pic_init_qs_minus26 + val; if ((currSlice->qs < 0) || (currSlice->qs > 51)) error ("slice_qs_delta makes slice_qs_y out of range", 500); } #if DPF_PARAM_DISP printf("deblocking_filter_control_present_flag:%d\n", p_Vid->active_pps->deblocking_filter_control_present_flag); #endif if (p_Vid->active_pps->deblocking_filter_control_present_flag) { currSlice->DFDisableIdc = (short) read_ue_v ("SH: disable_deblocking_filter_idc", currStream, &p_Dec->UsedBits); if (currSlice->DFDisableIdc!=1) { currSlice->DFAlphaC0Offset = (short) (2 * read_se_v("SH: slice_alpha_c0_offset_div2", currStream, &p_Dec->UsedBits)); currSlice->DFBetaOffset = (short) (2 * read_se_v("SH: slice_beta_offset_div2", currStream, &p_Dec->UsedBits)); } else { currSlice->DFAlphaC0Offset = currSlice->DFBetaOffset = 0; } } else { currSlice->DFDisableIdc = currSlice->DFAlphaC0Offset = currSlice->DFBetaOffset = 0; } #if DPF_PARAM_DISP printf("Slice:%d, DFParameters:(%d,%d,%d)\n\n", currSlice->current_slice_nr, currSlice->DFDisableIdc, currSlice->DFAlphaC0Offset, currSlice->DFBetaOffset); #endif // The conformance point for intra profiles is without deblocking, but decoders are still recommended to filter the output. // We allow in the decoder config to skip the loop filtering. This is achieved by modifying the parameters here. if ( is_HI_intra_only_profile(active_sps->profile_idc, active_sps->constrained_set3_flag) && (p_Inp->intra_profile_deblocking == 0) ) { currSlice->DFDisableIdc =1; currSlice->DFAlphaC0Offset = currSlice->DFBetaOffset = 0; } if (p_Vid->active_pps->num_slice_groups_minus1>0 && p_Vid->active_pps->slice_group_map_type>=3 && p_Vid->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)/ (p_Vid->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))% (p_Vid->active_pps->slice_group_change_rate_minus1+1)) len +=1; len = CeilLog2(len+1); currSlice->slice_group_change_cycle = read_u_v (len, "SH: slice_group_change_cycle", currStream, &p_Dec->UsedBits); } p_Vid->PicHeightInMbs = p_Vid->FrameHeightInMbs / ( 1 + currSlice->field_pic_flag ); p_Vid->PicSizeInMbs = p_Vid->PicWidthInMbs * p_Vid->PicHeightInMbs; p_Vid->FrameSizeInMbs = p_Vid->PicWidthInMbs * p_Vid->FrameHeightInMbs; return p_Dec->UsedBits; }
/*********************************************************************** *\brief Header_parsing * - Code not related to baseline removed. * * "Muhammad Tahir Awan" <*****@*****.**>, * "Umair Razzak" <*****@*****.**> **************************** * Changes till 21-11-2005 *********************************************************************** */ int RestOfSliceHeader_baseline( h264_decoder* dec_params ) { Slice *currSlice = dec_params->img->currentSlice; //int dP_nr = assignSE2partition[PAR_DP_1][SE_HEADER]; //int dP_nr = 0; DataPartition *partition = &(currSlice->partArr[0]); Bitstream *currStream = partition->bitstream; int val, len; // reading frame number (7.3.3) dec_params->img->frame_num = u_v (dec_params->active_sps->log2_max_frame_num_minus4 + 4, "SH: frame_num", currStream,dec_params); /* Tian Dong: frame_num gap processing, if found */ if (dec_params->img->idr_flag) { dec_params->img->pre_frame_num = dec_params->img->frame_num; assert(dec_params->img->frame_num == 0); } //{ // dec_params->img->structure = FRAME; //} //currSlice->structure = FRAME; //assert (dec_params->img->field_pic_flag == 0); if (dec_params->img->idr_flag) { dec_params->img->idr_pic_id = ue_v("SH: idr_pic_id", currStream,dec_params); } if (dec_params->active_sps->pic_order_cnt_type == 0) { dec_params->img->pic_order_cnt_lsb = u_v(dec_params->active_sps->log2_max_pic_order_cnt_lsb_minus4 + 4, "SH: pic_order_cnt_lsb", currStream,dec_params); if( dec_params->active_pps->pic_order_present_flag == 1) dec_params->img->delta_pic_order_cnt_bottom = se_v("SH: delta_pic_order_cnt_bottom", currStream,dec_params); else dec_params->img->delta_pic_order_cnt_bottom = 0; } if( dec_params->active_sps->pic_order_cnt_type == 1 && !dec_params->active_sps->delta_pic_order_always_zero_flag ) { dec_params->img->delta_pic_order_cnt[ 0 ] = se_v("SH: delta_pic_order_cnt[0]", currStream,dec_params); if( dec_params->active_pps->pic_order_present_flag == 1 ) dec_params->img->delta_pic_order_cnt[ 1 ] = se_v("SH: delta_pic_order_cnt[1]", currStream,dec_params); }else { if (dec_params->active_sps->pic_order_cnt_type == 1) { dec_params->img->delta_pic_order_cnt[ 0 ] = 0; dec_params->img->delta_pic_order_cnt[ 1 ] = 0; } } //! redundant_pic_cnt is missing here if (dec_params->active_pps->redundant_pic_cnt_present_flag) { //dec_params->img->redundant_pic_cnt = ue_v ("SH: redundant_pic_cnt", currStream,dec_params); } if(dec_params->img->type==B_SLICE) { dec_params->img->direct_spatial_mv_pred_flag = u_1 ("SH: direct_spatial_mv_pred_flag", currStream,dec_params); } dec_params->img->num_ref_idx_l0_active = dec_params->active_pps->num_ref_idx_l0_active_minus1 + 1; dec_params->img->num_ref_idx_l1_active = dec_params->active_pps->num_ref_idx_l1_active_minus1 + 1; if(dec_params->img->type==P_SLICE || dec_params->img->type==B_SLICE)// added by Faisal Abdullah for B frames { val = u_1 ("SH: num_ref_idx_override_flag", currStream,dec_params); if (val) { dec_params->img->num_ref_idx_l0_active = 1 + ue_v ("SH: num_ref_idx_l0_active_minus1", currStream,dec_params); if(dec_params->img->type==B_SLICE) { dec_params->img->num_ref_idx_l1_active = 1 + ue_v ("SH: num_ref_idx_l1_active_minus1", currStream,dec_params); } } } if (dec_params->img->type!=B_SLICE) { dec_params->img->num_ref_idx_l1_active = 0; } ref_pic_list_reordering( dec_params ); // for weighted prediction in B and P frames dec_params->img->apply_weights = ((dec_params->active_pps->weighted_pred_flag && (currSlice->picture_type == P_SLICE ) ) || ((dec_params->active_pps->weighted_bipred_idc > 0 ) && (currSlice->picture_type == B_SLICE))); /*dec_params->img->apply_weights = ((dec_params->active_pps->weighted_pred_flag && (currSlice->picture_type == P_SLICE ) ) || ((dec_params->active_pps->weighted_bipred_idc == 1 ) && (currSlice->picture_type == B_SLICE)));*/ dec_params->img->apply_weights_bi = 0; dec_params->img->apply_weights_luma = 0; dec_params->img->apply_weights_chr = 0; if ((dec_params->active_pps->weighted_pred_flag&&(dec_params->img->type==P_SLICE))|| (dec_params->active_pps->weighted_bipred_idc==1 && (dec_params->img->type==B_SLICE))) { pred_weight_table(dec_params); } dec_params->img->apply_weights_bi = (dec_params->active_pps->weighted_bipred_idc==2 && (dec_params->img->type==B_SLICE)); if (dec_params->img->nal_reference_idc) dec_ref_pic_marking(currStream,dec_params); //__CABAC__ if (dec_params->active_pps->entropy_coding_mode_flag && dec_params->img->type!=I_SLICE && dec_params->img->type!=SI_SLICE) { dec_params->img->model_number = ue_v("SH: cabac_init_idc", currStream, dec_params); } else { dec_params->img->model_number = 0; } //__CABAC__ val = se_v("SH: slice_qp_delta", currStream,dec_params); //currSlice->qp = dec_params->img->qp = 26 + dec_params->active_pps->pic_init_qp_minus26 + val; dec_params->img->qp = 26 + dec_params->active_pps->pic_init_qp_minus26 + val; //currSlice->slice_qp_delta = val; if (dec_params->active_pps->deblocking_filter_control_present_flag) { currSlice->LFDisableIdc = ue_v ("SH: disable_deblocking_filter_idc", currStream,dec_params); if (currSlice->LFDisableIdc!=1) { currSlice->LFAlphaC0Offset = 2 * se_v("SH: slice_alpha_c0_offset_div2", currStream,dec_params); currSlice->LFBetaOffset = 2 * se_v("SH: slice_beta_offset_div2", currStream,dec_params); } else { currSlice->LFAlphaC0Offset = currSlice->LFBetaOffset = 0; } } else { currSlice->LFDisableIdc = currSlice->LFAlphaC0Offset = currSlice->LFBetaOffset = 0; } if (dec_params->active_pps->num_slice_groups_minus1>0 && dec_params->active_pps->slice_group_map_type>=3 && dec_params->active_pps->slice_group_map_type<=5) { len = (dec_params->active_sps->pic_height_in_map_units_minus1+1)*(dec_params->active_sps->pic_width_in_mbs_minus1+1)/ (dec_params->active_pps->slice_group_change_rate_minus1+1); if (((dec_params->active_sps->pic_height_in_map_units_minus1+1)*(dec_params->active_sps->pic_width_in_mbs_minus1+1))% (dec_params->active_pps->slice_group_change_rate_minus1+1)) len +=1; len = CeilLog2(len+1); dec_params->img->slice_group_change_cycle = u_v (len, "SH: slice_group_change_cycle", currStream,dec_params); } dec_params->img->FrameSizeInMbs = dec_params->img->FrameWidthInMbs * dec_params->img->FrameHeightInMbs; return dec_params->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); /* 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 = 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; 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 (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; } 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; return UsedBits; }