void nalu_parse_slice_header()

in ftl_app/nalu.c [89:386]


void nalu_parse_slice_header(struct bitstream_elmt_t *bs, struct nalu_t* nalu, struct slice_header_t *slice)
{
	struct sequence_params_set_t *sps;
	struct picture_params_set_t *pps;
	int slice_skip_flag = 0;
	int i;

	memset(slice, 0, sizeof(struct slice_header_t));

	slice->first_mb_in_slice = bitstream_ue(bs);
	slice->slice_type = bitstream_ue(bs) % 5;
	slice->pic_parameter_set_id = bitstream_ue(bs);

	pps = find_pps(slice->pic_parameter_set_id);
	sps = find_sps(nalu->nal_unit_type, pps->seq_parameter_set_id);

	slice->frame_num = bitstream_u(bs, sps->log2_max_frame_num_minus4 + 4);
#if 0
	slice->field_pic_flag = 0;

	if( !sps->frame_mbs_only_flag ) 
	{
		slice->field_pic_flag = bitstream_u(bs, 1);

		if( slice->field_pic_flag )
		{
			slice->bottom_field_flag = bitstream_u(bs, 1);
		}
	}

	if( nalu->nal_unit_type  ==  NALU_TYPE_IDR_SLICE || (nalu->nal_unit_type == 20 && nalu->idr_flag)) 
	{
		slice->idr_pic_id = bitstream_ue(bs);
	}

	if( sps->pic_order_cnt_type  ==  0 ) 
	{
		slice->pic_order_cnt_lsb = bitstream_u(bs, sps->log2_max_pic_order_cnt_lsb_minus4 + 4);

		if( pps->pic_order_present_flag &&  !slice->field_pic_flag )
		{
			slice->delta_pic_order_cnt_bottom = bitstream_se(bs);
		}
	}

	if( sps->pic_order_cnt_type == 1 && !sps->delta_pic_order_always_zero_flag ) 
	{
		slice->delta_pic_order_cnt[0] = bitstream_se(bs);

		if( pps->pic_order_present_flag  &&  !slice->field_pic_flag )
		{
			slice->delta_pic_order_cnt[1] = bitstream_se(bs);
		}
	}

	if( pps->redundant_pic_cnt_present_flag )
	{
		slice->redundant_pic_cnt = bitstream_ue(bs);
	}

	if( slice->slice_type  ==  SLICE_TYPE_B )
	{
		slice->direct_spatial_mv_pred_flag = bitstream_u(bs, 1);
	}

	if( slice->slice_type == SLICE_TYPE_P || slice->slice_type == SLICE_TYPE_SP || slice->slice_type == SLICE_TYPE_B ) 
	{
		slice->num_ref_idx_active_override_flag = bitstream_u(bs, 1);

		if( slice->num_ref_idx_active_override_flag ) 
		{
			slice->num_ref_idx_l0_active_minus1 = bitstream_ue(bs);

			if( slice->slice_type  ==  SLICE_TYPE_B )
			{
				slice->num_ref_idx_l1_active_minus1 = bitstream_ue(bs);
			}
		}
	}

	/*7.3.3.1 -- Reference picture list reordering */
	if( slice->slice_type != SLICE_TYPE_I  &&  slice->slice_type != SLICE_TYPE_SI ) 
	{ 
		slice->ref_pic_reorder.ref_pic_list_reordering_flag_l0 = bitstream_u(bs, 1);

		if( slice->ref_pic_reorder.ref_pic_list_reordering_flag_l0 )
		{
			i = -1;
			
			do {
				i++;

				slice->ref_pic_reorder.list0[i].reordering_of_pic_nums_idc = bitstream_ue(bs);

				if(		slice->ref_pic_reorder.list0[i].reordering_of_pic_nums_idc == 0 
					||	slice->ref_pic_reorder.list0[i].reordering_of_pic_nums_idc == 1)
				{
					slice->ref_pic_reorder.list0[i].abs_diff_pic_num_minus1 = bitstream_ue(bs);
				}
				else if(slice->ref_pic_reorder.list0[i].reordering_of_pic_nums_idc == 2)
				{
					slice->ref_pic_reorder.list0[i].long_term_pic_num = bitstream_ue(bs);
				}
			} while( slice->ref_pic_reorder.list0[i].reordering_of_pic_nums_idc  !=  3 );
		}
	}

	if( slice->slice_type == SLICE_TYPE_B ) 
	{
		slice->ref_pic_reorder.ref_pic_list_reordering_flag_l1 = bitstream_u(bs, 1);

		if( slice->ref_pic_reorder.ref_pic_list_reordering_flag_l1 )
		{
			i = -1;
			
			do {
				i++;

				slice->ref_pic_reorder.list1[i].reordering_of_pic_nums_idc = bitstream_ue(bs);

				if(		slice->ref_pic_reorder.list1[i].reordering_of_pic_nums_idc == 0 
					||	slice->ref_pic_reorder.list1[i].reordering_of_pic_nums_idc == 1)
				{
					slice->ref_pic_reorder.list1[i].abs_diff_pic_num_minus1 = bitstream_ue(bs);
				}
				else if(slice->ref_pic_reorder.list1[i].reordering_of_pic_nums_idc == 2)
				{
					slice->ref_pic_reorder.list1[i].long_term_pic_num = bitstream_ue(bs);
				}
			} while( slice->ref_pic_reorder.list1[i].reordering_of_pic_nums_idc  !=  3 );
		}
	}
	

	if(		( pps->weighted_pred_flag  &&  ( slice->slice_type == SLICE_TYPE_P  ||  slice->slice_type == SLICE_TYPE_SP ) )  
		||	( pps->weighted_bipred_idc  ==  1  &&  slice->slice_type  ==  SLICE_TYPE_B ) 
      )
	{
		//pred_weight_table( )
		//printf("Weighted Table not supported\n");
	}

	if( nalu->nal_ref_idc != 0 )
	{
		/*7.3.3.3	Decoded reference picture marking*/
		if( nalu->nal_unit_type  ==  NALU_TYPE_IDR_SLICE || (nalu->nal_unit_type == 20 && nalu->idr_flag))  
		{
			slice->ref_pic_marking.no_output_of_prior_pics_flag = bitstream_u(bs, 1);
			slice->ref_pic_marking.long_term_reference_flag = bitstream_u(bs, 1);
		} 
		else 
		{
			slice->ref_pic_marking.adaptive_ref_pic_marking_mode_flag = bitstream_u(bs, 1);

			if( slice->ref_pic_marking.adaptive_ref_pic_marking_mode_flag )
			{
				slice->ref_pic_marking.difference_of_pic_nums_minus1 = -1;
				slice->ref_pic_marking.long_term_pic_num = -1;
				slice->ref_pic_marking.long_term_frame_idx = -1;
				slice->ref_pic_marking.max_long_term_frame_idx_plus1 = -1;

				i = -1;

				memset(slice->ref_pic_marking.memory_management_control_operation, 0, sizeof(slice->ref_pic_marking.memory_management_control_operation));

				do {
					i++;

					slice->ref_pic_marking.memory_management_control_operation[i] = bitstream_ue(bs);

					if(		slice->ref_pic_marking.memory_management_control_operation[i] == 1 
						||	slice->ref_pic_marking.memory_management_control_operation[i] == 3 )
					{
						slice->ref_pic_marking.difference_of_pic_nums_minus1 = bitstream_ue(bs);
					}

					if(slice->ref_pic_marking.memory_management_control_operation[i] == 2 )
					{
						slice->ref_pic_marking.long_term_pic_num = bitstream_ue(bs);
					}

			 		if( slice->ref_pic_marking.memory_management_control_operation[i] == 3 ||
						slice->ref_pic_marking.memory_management_control_operation[i] == 6)
					{
						slice->ref_pic_marking.long_term_frame_idx = bitstream_ue(bs);
					}

					if( slice->ref_pic_marking.memory_management_control_operation[i] == 4)
					{
						slice->ref_pic_marking.max_long_term_frame_idx_plus1 = bitstream_ue(bs);
					}

				} while( slice->ref_pic_marking.memory_management_control_operation[i] != 0 );
			}
		}

#ifdef READ_SVC
		if( sps->profile_idc == 83 || sps->profile_idc == 86 )
		{
			if(!sps->sps_svc.slice_header_restriction_flag)
			{
				slice->store_ref_base_pic_flag = bitstream_u(bs, 1);		

				if ( ( nalu->use_ref_base_pic_flag || slice->store_ref_base_pic_flag ) && !nalu->idr_flag )
				{
					int i = -1;

					//dec_ref_base_pic_marking( )
					slice->ref_base_pic_marking.adaptive_ref_base_pic_marking_mode_flag = bitstream_u(bs, 1);

					if( slice->ref_base_pic_marking.adaptive_ref_base_pic_marking_mode_flag )
					{
						do 
						{
							i++;

							slice->ref_base_pic_marking.memory_management_base_control_operation[i] = bitstream_ue(bs);

							if( slice->ref_base_pic_marking.memory_management_base_control_operation[i] == 1 )
							{
								slice->ref_base_pic_marking.difference_of_base_pic_nums_minus1 = bitstream_ue(bs);
							}
							
							if( slice->ref_base_pic_marking.memory_management_base_control_operation[i] == 2 )
							{
								slice->ref_base_pic_marking.long_term_base_pic_num = bitstream_ue(bs);
							}
						} while( slice->ref_base_pic_marking.memory_management_base_control_operation[i] != 0 );
					}
				}
			}
		}
#endif
	}

	if( pps->entropy_coding_mode_flag  &&  slice->slice_type  !=  SLICE_TYPE_I  &&  slice->slice_type  !=  SLICE_TYPE_SI )
	{
		slice->cabac_init_idc = bitstream_ue(bs);
	}

	slice->slice_qp_delta = bitstream_se(bs);

	if( slice->slice_type  ==  SLICE_TYPE_SP  ||  slice->slice_type  ==  SLICE_TYPE_SI ) 
	{
		if( slice->slice_type  ==  SLICE_TYPE_SP )
		{
			slice->sp_for_switch_flag = bitstream_u(bs, 1);
		}

		slice->slice_qs_delta = bitstream_se(bs);
	}

	if( pps->deblocking_filter_control_present_flag ) 
	{
		slice->disable_deblocking_filter_idc = bitstream_ue(bs);

		if( slice->disable_deblocking_filter_idc  !=  1 ) 
		{
			slice->slice_alpha_c0_offset_div2 = bitstream_se(bs);
			slice->slice_beta_offset_div2 = bitstream_se(bs);
		}
	}

	if(		pps->num_slice_groups_minus1 > 0  
		&&	pps->slice_group_map_type >= 3  
		&&  pps->slice_group_map_type <= 5)
	{

		int bits=0;
		int pic_size, change_rate;
		unsigned int value;

		pic_size = pps->pic_size_in_map_units_minus1 + 1;
		change_rate = pps->slice_group_change_rate_minus1 + 1;

		value = pic_size / change_rate + 1; 

		while(value != 0)
		{
			bits++;
			value >>= 1;
		}

		slice->slice_group_change_cycle = bitstream_u(bs, bits);
	}

#ifdef READ_SVC
 	if( sps->profile_idc == 83 || sps->profile_idc == 86 )
	{
		if(!sps->sps_svc.slice_header_restriction_flag && !slice_skip_flag)
		{
			slice->scan_idx_start = read_u(bs, 4);
			slice->scan_idx_end = read_u(bs, 4);
		}
	}
#endif
#endif
}