#include #include #include #include "bs.h" #include "h265_stream.h" #include "h265_sei.h" FILE* h265_dbgfile = NULL; #define printf(...) fprintf((h265_dbgfile == NULL ? stdout : h265_dbgfile), __VA_ARGS__) /** Create a new H265 stream object. Allocates all structures contained within it. @return the stream object */ h265_stream_t* h265_new() { h265_stream_t* h = (h265_stream_t*)calloc(1, sizeof(h265_stream_t)); h->nal = (h265_nal_t*)calloc(1, sizeof(h265_nal_t)); // initialize tables for ( int i = 0; i < 16; i++ ) { h->vps_table[i] = (h265_vps_t*)calloc(1, sizeof(h265_vps_t)); } for ( int i = 0; i < 32; i++ ) { h->sps_table[i] = (h265_sps_t*)calloc(1, sizeof(h265_sps_t)); } for ( int i = 0; i < 256; i++ ) { h->pps_table[i] = (h265_pps_t*)calloc(1, sizeof(h265_pps_t)); } h->vps = h->vps_table[0]; h->sps = h->sps_table[0]; h->pps = h->pps_table[0]; h->aud = (h265_aud_t*)calloc(1, sizeof(h265_aud_t)); h->num_seis = 0; h->seis = NULL; h->sei = NULL; //This is a TEMP pointer at whats in h->seis... h->sh = (h265_slice_header_t*)calloc(1, sizeof(h265_slice_header_t)); h->info = (videoinfo_t*)calloc(1, sizeof(videoinfo_t)); h->info->type = 1; return h; } /** Free an existing H265 stream object. Frees all contained structures. @param[in,out] h the stream object */ void h265_free(h265_stream_t* h) { free(h->nal); for ( int i = 0; i < 16; i++ ) { if (h->vps_table[i]!=NULL) free( h->vps_table[i] ); } for ( int i = 0; i < 32; i++ ) { if (h->sps_table[i]!=NULL) free( h->sps_table[i] ); } for ( int i = 0; i < 256; i++ ) { if (h->pps_table[i]!=NULL) free( h->pps_table[i] ); } if (h->aud != NULL) { free(h->aud); } if(h->seis != NULL) { for( int i = 0; i < h->num_seis; i++ ) { h265_sei_t* sei = h->seis[i]; h265_sei_free(sei); } free(h->seis); } free(h->sh); free(h->info); free(h); } /** Read a NAL unit from a byte buffer. The buffer must start exactly at the beginning of the nal (after the start prefix). The NAL is read into h->nal and into other fields within h depending on its type (check h->nal->nal_unit_type after reading). @param[in,out] h the stream object @param[in] buf the buffer @param[in] size the size of the buffer @return the length of data actually read, or -1 on error */ //7.3.1 NAL unit syntax int h265_read_nal_unit(h265_stream_t* h, uint8_t* buf, int size) { h265_nal_t* nal = h->nal; bs_t* b = bs_new(buf, size); // nal header nal->forbidden_zero_bit = bs_read_f(b,1); nal->nal_unit_type = bs_read_u(b,6); nal->nuh_layer_id = bs_read_u(b,6); nal->nuh_temporal_id_plus1 = bs_read_u(b,3); nal->parsed = NULL; nal->sizeof_parsed = 0; bs_free(b); int nal_size = size; int rbsp_size = size; uint8_t* rbsp_buf = (uint8_t*)malloc(rbsp_size); int rc = nal_to_rbsp(2, buf, &nal_size, rbsp_buf, &rbsp_size); if (rc < 0) { free(rbsp_buf); return -1; } // handle conversion error b = bs_new(rbsp_buf, rbsp_size); // nal data switch ( nal->nal_unit_type ) { case NAL_UNIT_VPS: h265_read_vps_rbsp(h,b); break; case NAL_UNIT_SPS: h265_read_sps_rbsp(h, b); nal->parsed = h->sps; nal->sizeof_parsed = sizeof(h265_sps_t); break; case NAL_UNIT_PPS: h265_read_pps_rbsp(h, b); nal->parsed = h->pps; nal->sizeof_parsed = sizeof(h265_pps_t); break; case NAL_UNIT_PREFIX_SEI: h265_read_sei_rbsp(h, b); nal->parsed = h->sei; nal->sizeof_parsed = sizeof(h265_sei_t); break; case NAL_UNIT_SUFFIX_SEI: h265_read_sei_rbsp(h, b); nal->parsed = h->sei; nal->sizeof_parsed = sizeof(h265_sei_t); break; case NAL_UNIT_AUD: h265_read_aud_rbsp(h, b); nal->parsed = h->aud; nal->sizeof_parsed = sizeof(h265_aud_t); break; case NAL_UNIT_EOS: h265_read_end_of_seq_rbsp(h, b); break; case NAL_UNIT_EOB: h265_read_end_of_stream_rbsp(h, b); break; case NAL_UNIT_CODED_SLICE_TRAIL_N: case NAL_UNIT_CODED_SLICE_TRAIL_R: case NAL_UNIT_CODED_SLICE_TSA_N: case NAL_UNIT_CODED_SLICE_TSA_R: case NAL_UNIT_CODED_SLICE_STSA_N: case NAL_UNIT_CODED_SLICE_STSA_R: case NAL_UNIT_CODED_SLICE_RADL_N: case NAL_UNIT_CODED_SLICE_RADL_R: case NAL_UNIT_CODED_SLICE_RASL_N: case NAL_UNIT_CODED_SLICE_RASL_R: case NAL_UNIT_CODED_SLICE_BLA_W_LP: case NAL_UNIT_CODED_SLICE_BLA_W_RADL: case NAL_UNIT_CODED_SLICE_BLA_N_LP: case NAL_UNIT_CODED_SLICE_IDR_W_RADL: case NAL_UNIT_CODED_SLICE_IDR_N_LP: case NAL_UNIT_CODED_SLICE_CRA: h265_read_slice_layer_rbsp(h, b); nal->parsed = h->sh; nal->sizeof_parsed = sizeof(h265_slice_header_t); break; case NAL_UNIT_RESERVED_VCL_N10: case NAL_UNIT_RESERVED_VCL_R11: case NAL_UNIT_RESERVED_VCL_N12: case NAL_UNIT_RESERVED_VCL_R13: case NAL_UNIT_RESERVED_VCL_N14: case NAL_UNIT_RESERVED_VCL_R15: case NAL_UNIT_RESERVED_IRAP_VCL22: case NAL_UNIT_RESERVED_IRAP_VCL23: case NAL_UNIT_RESERVED_VCL24: case NAL_UNIT_RESERVED_VCL25: case NAL_UNIT_RESERVED_VCL26: case NAL_UNIT_RESERVED_VCL27: case NAL_UNIT_RESERVED_VCL28: case NAL_UNIT_RESERVED_VCL29: case NAL_UNIT_RESERVED_VCL30: case NAL_UNIT_RESERVED_VCL31: printf ("Note: found reserved VCL NAL unit.\n"); nal->parsed = NULL; nal->sizeof_parsed = 0; break; case NAL_UNIT_RESERVED_NVCL41: case NAL_UNIT_RESERVED_NVCL42: case NAL_UNIT_RESERVED_NVCL43: case NAL_UNIT_RESERVED_NVCL44: case NAL_UNIT_RESERVED_NVCL45: case NAL_UNIT_RESERVED_NVCL46: case NAL_UNIT_RESERVED_NVCL47: printf ("Note: found reserved NAL unit.\n"); nal->parsed = NULL; nal->sizeof_parsed = 0; break; case NAL_UNIT_UNSPECIFIED_48: case NAL_UNIT_UNSPECIFIED_49: case NAL_UNIT_UNSPECIFIED_50: case NAL_UNIT_UNSPECIFIED_51: case NAL_UNIT_UNSPECIFIED_52: case NAL_UNIT_UNSPECIFIED_53: case NAL_UNIT_UNSPECIFIED_54: case NAL_UNIT_UNSPECIFIED_55: case NAL_UNIT_UNSPECIFIED_56: case NAL_UNIT_UNSPECIFIED_57: case NAL_UNIT_UNSPECIFIED_58: case NAL_UNIT_UNSPECIFIED_59: case NAL_UNIT_UNSPECIFIED_60: case NAL_UNIT_UNSPECIFIED_61: case NAL_UNIT_UNSPECIFIED_62: case NAL_UNIT_UNSPECIFIED_63: printf ("Note: found unspecified NAL unit.\n"); nal->parsed = NULL; nal->sizeof_parsed = 0; break; default: // here comes the reserved/unspecified/ignored stuff nal->parsed = NULL; nal->sizeof_parsed = 0; return 0; } if (bs_overrun(b)) { bs_free(b); free(rbsp_buf); return -1; } bs_free(b); free(rbsp_buf); return nal_size; } void h265_read_ptl(profile_tier_level_t* ptl, bs_t* b, int profilePresentFlag, int max_sub_layers_minus1) { int i = 0; if (profilePresentFlag) { ptl->general_profile_space = bs_read_u(b, 2); ptl->general_tier_flag = bs_read_u1(b); ptl->general_profile_idc = bs_read_u(b, 5); for (i = 0; i < 32; i++) { ptl->general_profile_compatibility_flag[i] = bs_read_u1(b); } ptl->general_progressive_source_flag = bs_read_u1(b); ptl->general_interlaced_source_flag = bs_read_u1(b); ptl->general_non_packed_constraint_flag = bs_read_u1(b); ptl->general_frame_only_constraint_flag = bs_read_u1(b); if (ptl->general_profile_idc==4 || ptl->general_profile_compatibility_flag[4] || ptl->general_profile_idc==5 || ptl->general_profile_compatibility_flag[5] || ptl->general_profile_idc==6 || ptl->general_profile_compatibility_flag[6] || ptl->general_profile_idc==7 || ptl->general_profile_compatibility_flag[7]) { ptl->general_max_12bit_constraint_flag = bs_read_u1(b); ptl->general_max_10bit_constraint_flag = bs_read_u1(b); ptl->general_max_8bit_constraint_flag = bs_read_u1(b); ptl->general_max_422chroma_constraint_flag = bs_read_u1(b); ptl->general_max_420chroma_constraint_flag = bs_read_u1(b); ptl->general_max_monochrome_constraint_flag = bs_read_u1(b); ptl->general_intra_constraint_flag = bs_read_u1(b); ptl->general_one_picture_only_constraint_flag = bs_read_u1(b); ptl->general_lower_bit_rate_constraint_flag = bs_read_u1(b); uint64_t tmp1 = bs_read_u(b, 32); uint64_t tmp2 = bs_read_u(b, 2); ptl->general_reserved_zero_34bits = tmp1+tmp2; } else { uint64_t tmp1 = bs_read_u(b, 32); uint64_t tmp2 = bs_read_u(b, 11); ptl->general_reserved_zero_43bits = tmp1+tmp2; } if ((ptl->general_profile_idc>=1 && ptl->general_profile_idc<=5) || ptl->general_profile_compatibility_flag[1] || ptl->general_profile_compatibility_flag[2] || ptl->general_profile_compatibility_flag[3] || ptl->general_profile_compatibility_flag[4] || ptl->general_profile_compatibility_flag[5]) { ptl->general_inbld_flag = bs_read_u1(b); } else { ptl->general_reserved_zero_bit = bs_read_u1(b); } } ptl->general_level_idc = bs_read_u8(b); ptl->sub_layer_profile_present_flag.resize(max_sub_layers_minus1); ptl->sub_layer_level_present_flag.resize(max_sub_layers_minus1); for (i = 0; i < max_sub_layers_minus1; i++) { ptl->sub_layer_profile_present_flag[i] = bs_read_u1(b); ptl->sub_layer_level_present_flag[i] = bs_read_u1(b); } if (max_sub_layers_minus1 > 0) { for (i = max_sub_layers_minus1; i < 8; i++) { ptl->reserved_zero_2bits[i] = bs_read_u(b, 2); } } ptl->sub_layer_profile_space.resize(max_sub_layers_minus1); ptl->sub_layer_tier_flag.resize(max_sub_layers_minus1); ptl->sub_layer_profile_idc.resize(max_sub_layers_minus1); ptl->sub_layer_profile_compatibility_flag.resize(max_sub_layers_minus1); for (int j = 0; j < max_sub_layers_minus1; j++) { ptl->sub_layer_profile_compatibility_flag[j].resize(32); } ptl->sub_layer_progressive_source_flag.resize(max_sub_layers_minus1); ptl->sub_layer_interlaced_source_flag.resize(max_sub_layers_minus1); ptl->sub_layer_non_packed_constraint_flag.resize(max_sub_layers_minus1); ptl->sub_layer_frame_only_constraint_flag.resize(max_sub_layers_minus1); ptl->sub_layer_max_12bit_constraint_flag.resize(max_sub_layers_minus1); ptl->sub_layer_max_10bit_constraint_flag.resize(max_sub_layers_minus1); ptl->sub_layer_max_8bit_constraint_flag.resize(max_sub_layers_minus1); ptl->sub_layer_max_422chroma_constraint_flag.resize(max_sub_layers_minus1); ptl->sub_layer_max_420chroma_constraint_flag.resize(max_sub_layers_minus1); ptl->sub_layer_max_monochrome_constraint_flag.resize(max_sub_layers_minus1); ptl->sub_layer_intra_constraint_flag.resize(max_sub_layers_minus1); ptl->sub_layer_one_picture_only_constraint_flag.resize(max_sub_layers_minus1); ptl->sub_layer_lower_bit_rate_constraint_flag.resize(max_sub_layers_minus1); ptl->sub_layer_reserved_zero_34bits.resize(max_sub_layers_minus1); ptl->sub_layer_reserved_zero_43bits.resize(max_sub_layers_minus1); ptl->sub_layer_inbld_flag.resize(max_sub_layers_minus1); ptl->sub_layer_reserved_zero_bit.resize(max_sub_layers_minus1); ptl->sub_layer_level_idc.resize(max_sub_layers_minus1); for (i = 0; i < max_sub_layers_minus1; i++) { if (ptl->sub_layer_profile_present_flag[i]) { ptl->sub_layer_profile_space[i] = bs_read_u(b, 2); ptl->sub_layer_tier_flag[i] = bs_read_u1(b); ptl->sub_layer_profile_idc[i] = bs_read_u(b, 5); for (int j = 0; j < 32; j++) { ptl->sub_layer_profile_compatibility_flag[i][j] = bs_read_u1(b); } ptl->sub_layer_progressive_source_flag[i] = bs_read_u1(b); ptl->sub_layer_interlaced_source_flag[i] = bs_read_u1(b); ptl->sub_layer_non_packed_constraint_flag[i] = bs_read_u1(b); ptl->sub_layer_frame_only_constraint_flag[i] = bs_read_u1(b); if (ptl->sub_layer_profile_idc[i]==4 || ptl->sub_layer_profile_compatibility_flag[i][4] || ptl->sub_layer_profile_idc[i]==5 || ptl->sub_layer_profile_compatibility_flag[i][5] || ptl->sub_layer_profile_idc[i]==6 || ptl->sub_layer_profile_compatibility_flag[i][6] || ptl->sub_layer_profile_idc[i]==7 || ptl->sub_layer_profile_compatibility_flag[i][7]) { ptl->sub_layer_max_12bit_constraint_flag[i] = bs_read_u1(b); ptl->sub_layer_max_10bit_constraint_flag[i] = bs_read_u1(b); ptl->sub_layer_max_8bit_constraint_flag[i] = bs_read_u1(b); ptl->sub_layer_max_422chroma_constraint_flag[i] = bs_read_u1(b); ptl->sub_layer_max_420chroma_constraint_flag[i] = bs_read_u1(b); ptl->sub_layer_max_monochrome_constraint_flag[i] = bs_read_u1(b); ptl->sub_layer_intra_constraint_flag[i] = bs_read_u1(b); ptl->sub_layer_one_picture_only_constraint_flag[i] = bs_read_u1(b); ptl->sub_layer_lower_bit_rate_constraint_flag[i] = bs_read_u1(b); uint64_t tmp1 = bs_read_u(b, 32); uint64_t tmp2 = bs_read_u(b, 2); ptl->sub_layer_reserved_zero_34bits[i] = tmp1+tmp2; } else { uint64_t tmp1 = bs_read_u(b, 32); uint64_t tmp2 = bs_read_u(b, 12); ptl->sub_layer_reserved_zero_43bits[i] = tmp1+tmp2; } // to check if ((ptl->sub_layer_profile_idc[i]>=1 && ptl->sub_layer_profile_idc[i]<=5) || ptl->sub_layer_profile_compatibility_flag[i][1] || ptl->sub_layer_profile_compatibility_flag[i][2] || ptl->sub_layer_profile_compatibility_flag[i][3] || ptl->sub_layer_profile_compatibility_flag[i][4] || ptl->sub_layer_profile_compatibility_flag[i][5]) { ptl->sub_layer_inbld_flag[i] = bs_read_u1(b); } else { ptl->sub_layer_reserved_zero_bit[i] = bs_read_u1(b); } } if (ptl->sub_layer_level_present_flag[i]) { ptl->sub_layer_level_idc[i] = bs_read_u8(b); } } } // E.2.3 Sub-layer HRD parameters syntax // E.3.3 The variable CpbCnt is set equal to cpb_cnt_minus1[ subLayerId ]. void h265_read_sub_layer_hrd_parameters(sub_layer_hrd_parameters_t* subhrd, bs_t* b, int sub_pic_hrd_params_present_flag, int CpbCnt) { subhrd->bit_rate_value_minus1.resize(CpbCnt+1); subhrd->cpb_size_value_minus1.resize(CpbCnt+1); subhrd->cpb_size_du_value_minus1.resize(CpbCnt+1); subhrd->bit_rate_du_value_minus1.resize(CpbCnt+1); subhrd->cbr_flag.resize(CpbCnt+1); for (int i = 0; i <= CpbCnt; i++) { subhrd->bit_rate_value_minus1[i] = bs_read_ue(b); subhrd->cpb_size_value_minus1[i] = bs_read_ue(b); if (sub_pic_hrd_params_present_flag) { subhrd->cpb_size_du_value_minus1[i] = bs_read_ue(b); subhrd->bit_rate_du_value_minus1[i] = bs_read_ue(b); } subhrd->cbr_flag[i] = bs_read_u1(b); } } // E.2.2 HRD parameters syntax void h265_read_hrd_parameters(hrd_parameters_t* hrd, bs_t* b, int commonInfPresentFlag, int maxNumSubLayersMinus1) { if(commonInfPresentFlag) { hrd->nal_hrd_parameters_present_flag = bs_read_u1(b); hrd->vcl_hrd_parameters_present_flag = bs_read_u1(b); if (hrd->nal_hrd_parameters_present_flag || hrd->vcl_hrd_parameters_present_flag) { hrd->sub_pic_hrd_params_present_flag = bs_read_u1(b); if (hrd->sub_pic_hrd_params_present_flag) { hrd->tick_divisor_minus2 = bs_read_u8(b); hrd->du_cpb_removal_delay_increment_length_minus1 = bs_read_u(b, 5); hrd->sub_pic_cpb_params_in_pic_timing_sei_flag = bs_read_u1(b); hrd->dpb_output_delay_du_length_minus1 = bs_read_u(b, 5); } hrd->bit_rate_scale = bs_read_u(b, 4); hrd->cpb_size_scale = bs_read_u(b, 4); if (hrd->sub_pic_hrd_params_present_flag) { hrd->cpb_size_du_scale = bs_read_u(b, 4); } hrd->initial_cpb_removal_delay_length_minus1 = bs_read_u(b, 5); hrd->au_cpb_removal_delay_length_minus1 = bs_read_u(b, 5); hrd->dpb_output_delay_length_minus1 = bs_read_u(b, 5); } } hrd->fixed_pic_rate_general_flag.resize(maxNumSubLayersMinus1+1); hrd->fixed_pic_rate_within_cvs_flag.resize(maxNumSubLayersMinus1+1); hrd->elemental_duration_in_tc_minus1.resize(maxNumSubLayersMinus1+1); hrd->low_delay_hrd_flag.resize(maxNumSubLayersMinus1+1); hrd->cpb_cnt_minus1.resize(maxNumSubLayersMinus1+1); for (int i = 0; i <= maxNumSubLayersMinus1; i++) { hrd->fixed_pic_rate_general_flag[i] = bs_read_u1(b); if (!hrd->fixed_pic_rate_general_flag[i]) { hrd->fixed_pic_rate_within_cvs_flag[i] = bs_read_u1(b); } if (hrd->fixed_pic_rate_within_cvs_flag[i]) { hrd->elemental_duration_in_tc_minus1[i] = bs_read_ue(b); } else { hrd->low_delay_hrd_flag[i] = bs_read_u1(b); } if (!hrd->low_delay_hrd_flag[i]) { hrd->cpb_cnt_minus1[i] = bs_read_u1(b); } if(hrd->nal_hrd_parameters_present_flag) { h265_read_sub_layer_hrd_parameters(&(hrd->sub_layer_hrd_parameters), b, hrd->sub_pic_hrd_params_present_flag, hrd->cpb_cnt_minus1[i]); } if(hrd->vcl_hrd_parameters_present_flag) { h265_read_sub_layer_hrd_parameters(&(hrd->sub_layer_hrd_parameters_v), b, hrd->sub_pic_hrd_params_present_flag, hrd->cpb_cnt_minus1[i]); } } } // E.2.1 VUI parameters syntax void h265_read_vui_parameters(vui_parameters_t* vui, bs_t* b, int maxNumSubLayersMinus1) { vui->aspect_ratio_info_present_flag = bs_read_u1(b); if (vui->aspect_ratio_info_present_flag) { vui->aspect_ratio_idc = bs_read_u8(b); if (vui->aspect_ratio_idc == H265_SAR_Extended) { vui->sar_width = bs_read_u(b, 16); vui->sar_height = bs_read_u(b, 16); } } vui->overscan_info_present_flag = bs_read_u1(b); if (vui->overscan_info_present_flag) { vui->overscan_appropriate_flag = bs_read_u1(b); } vui->video_signal_type_present_flag = bs_read_u1(b); if (vui->video_signal_type_present_flag) { vui->video_format = bs_read_u(b, 3); vui->video_full_range_flag = bs_read_u1(b); vui->colour_description_present_flag = bs_read_u1(b); if (vui->colour_description_present_flag) { vui->colour_primaries = bs_read_u8(b); vui->transfer_characteristics = bs_read_u8(b); vui->matrix_coeffs = bs_read_u8(b); } } vui->chroma_loc_info_present_flag = bs_read_u1(b); if (vui->chroma_loc_info_present_flag) { vui->chroma_sample_loc_type_top_field = bs_read_ue(b); vui->chroma_sample_loc_type_bottom_field = bs_read_ue(b); } vui->neutral_chroma_indication_flag = bs_read_u1(b); vui->field_seq_flag = bs_read_u1(b); vui->frame_field_info_present_flag = bs_read_u1(b); vui->default_display_window_flag = bs_read_u1(b); if (vui->default_display_window_flag) { vui->def_disp_win_left_offset = bs_read_ue(b); vui->def_disp_win_right_offset = bs_read_ue(b); vui->def_disp_win_top_offset = bs_read_ue(b); vui->def_disp_win_bottom_offset = bs_read_ue(b); } vui->vui_timing_info_present_flag = bs_read_u1(b); if (vui->vui_timing_info_present_flag) { vui->vui_num_units_in_tick = bs_read_u(b, 32); vui->vui_time_scale = bs_read_u(b, 32); vui->vui_poc_proportional_to_timing_flag = bs_read_u1(b); if (vui->vui_poc_proportional_to_timing_flag) { vui->vui_num_ticks_poc_diff_one_minus1 = bs_read_ue(b); } vui->vui_hrd_parameters_present_flag = bs_read_u1(b); if (vui->vui_hrd_parameters_present_flag) { h265_read_hrd_parameters(&vui->hrd_parameters, b, 1, maxNumSubLayersMinus1); } } vui->bitstream_restriction_flag = bs_read_u1(b); if (vui->bitstream_restriction_flag) { vui->tiles_fixed_structure_flag = bs_read_u1(b); vui->motion_vectors_over_pic_boundaries_flag = bs_read_u1(b); vui->restricted_ref_pic_lists_flag = bs_read_u1(b); vui->min_spatial_segmentation_idc = bs_read_ue(b); vui->max_bytes_per_pic_denom = bs_read_ue(b); vui->max_bits_per_min_cu_denom = bs_read_ue(b); vui->log2_max_mv_length_horizontal = bs_read_ue(b); vui->log2_max_mv_length_vertical = bs_read_ue(b); } } // 7.3.4 Scaling list data syntax void h265_read_scaling_list(scaling_list_data_t* sld, bs_t* b) { for(int sizeId = 0; sizeId < 4; sizeId++) { for(int matrixId = 0; matrixId < 6; matrixId += ( sizeId == 3 ) ? 3 : 1) { sld->scaling_list_pred_mode_flag[sizeId][matrixId] = bs_read_u1(b); if (!sld->scaling_list_pred_mode_flag[sizeId][matrixId]) { sld->scaling_list_pred_matrix_id_delta[sizeId][matrixId] = bs_read_ue(b); } else { int nextCoef = 8; int coefNum = min(64, (1 << (4 + (sizeId << 1)))); sld->coefNum = coefNum; // tmp store if (sizeId > 1) { sld->scaling_list_dc_coef_minus8[sizeId - 2][matrixId] = bs_read_se(b); nextCoef = sld->scaling_list_dc_coef_minus8[sizeId - 2][matrixId] + 8; } for (int i = 0; i < sld->coefNum; i++) { int scaling_list_delta_coef = bs_read_se(b); nextCoef = (nextCoef + scaling_list_delta_coef + 256) % 256; sld->ScalingList[sizeId][matrixId][i] = nextCoef; } } } } } // st_ref_pic_set // 7.3.7 Short-term reference picture set syntax void h265_read_short_term_ref_pic_set(bs_t* b, h265_sps_t* sps, st_ref_pic_set_t*st, referencePictureSets_t* rps, int stRpsIdx) { st->inter_ref_pic_set_prediction_flag = 0; if (stRpsIdx != 0) { st->inter_ref_pic_set_prediction_flag = bs_read_u1(b); } if (st->inter_ref_pic_set_prediction_flag) { st->delta_idx_minus1 = 0; if (stRpsIdx == sps->m_RPSList.size()) { st->delta_idx_minus1 = bs_read_ue(b); } int rIdx = stRpsIdx - 1 - st->delta_idx_minus1; referencePictureSets_t* rpsRef = &sps->m_RPSList[rIdx]; st->delta_rps_sign = bs_read_u1(b); st->abs_delta_rps_minus1 = bs_read_ue(b); int deltaRPS = (1 - 2 * st->delta_rps_sign) * (st->abs_delta_rps_minus1 + 1); // delta_RPS st->used_by_curr_pic_flag.resize(rpsRef->m_numberOfPictures+1); st->use_delta_flag.resize(rpsRef->m_numberOfPictures+1); for (int j = 0; j <= rpsRef->m_numberOfPictures; j++) { st->used_by_curr_pic_flag[j] = bs_read_u1(b); int refIdc = st->used_by_curr_pic_flag[j]; if (!st->used_by_curr_pic_flag[j]) { st->use_delta_flag[j] = bs_read_u1(b); refIdc = st->use_delta_flag[j] << 1; //second bit is "1" if refIdc is 2, "0" if refIdc = 0. } // todo furture if (refIdc == 1 || refIdc == 2) { } } } else { st->num_negative_pics = bs_read_ue(b); st->num_positive_pics = bs_read_ue(b); rps->m_numberOfNegativePictures = st->num_negative_pics; rps->m_numberOfPositivePictures = st->num_positive_pics; // to check... st->delta_poc_s0_minus1.resize(st->num_negative_pics); st->used_by_curr_pic_s0_flag.resize(st->num_negative_pics); for (int i = 0; i < st->num_negative_pics; i++) { st->delta_poc_s0_minus1[i] = bs_read_ue(b); st->used_by_curr_pic_s0_flag[i] = bs_read_u1(b); rps->m_used[i] = st->used_by_curr_pic_s0_flag[i]; } st->delta_poc_s1_minus1.resize(st->num_positive_pics); st->used_by_curr_pic_s1_flag.resize(st->num_positive_pics); for (int i = 0; i < st->num_positive_pics; i++) { st->delta_poc_s1_minus1[i] = bs_read_ue(b); st->used_by_curr_pic_s1_flag[i] = bs_read_u1(b); rps->m_used[i + st->num_negative_pics] = st->used_by_curr_pic_s1_flag[i]; } rps->m_numberOfPictures = rps->m_numberOfNegativePictures + rps->m_numberOfPositivePictures; } } static int getNumRpsCurrTempList(h265_slice_header_t *hrd) { int numRpsCurrTempList = 0; if (hrd->slice_type == H265_SH_SLICE_TYPE_I) { return 0; } if (hrd->m_pRPS == NULL) return 0; // tmp... // todo error for (int i = 0; i < hrd->m_pRPS->m_numberOfNegativePictures + hrd->m_pRPS->m_numberOfPositivePictures + hrd->m_pRPS->m_numberOfLongtermPictures; i++) { if (hrd->m_pRPS->m_used[i]) { numRpsCurrTempList++; } } return numRpsCurrTempList; } // ref_pic_lists_modification // 7.3.6.2 Reference picture list modification syntax void h265_read_ref_pic_lists_modification(bs_t* b, h265_slice_header_t* hrd) { hrd->ref_pic_lists_modification.ref_pic_list_modification_flag_l0 = bs_read_u1(b); if (hrd->ref_pic_lists_modification.ref_pic_list_modification_flag_l0) { int numRpsCurrTempList0 = getNumRpsCurrTempList(hrd); if (numRpsCurrTempList0 > 1) { int length = 1; numRpsCurrTempList0--; while (numRpsCurrTempList0 >>= 1) { length++; } for (int i = 0; i <= hrd->num_ref_idx_l0_active_minus1; i++) // ×¢ÒâÓеȺţ¬Òª×¢Òâ±ß½ç { hrd->ref_pic_lists_modification.list_entry_l0[i] = bs_read_u(b, length); } } else { for (int i = 0; i <= hrd->num_ref_idx_l0_active_minus1; i ++) { hrd->ref_pic_lists_modification.list_entry_l0[i] = 0; } } } if (hrd->slice_type == H265_SH_SLICE_TYPE_B) { hrd->ref_pic_lists_modification.ref_pic_list_modification_flag_l1 = bs_read_u1(b); if (hrd->ref_pic_lists_modification.ref_pic_list_modification_flag_l1) { int numRpsCurrTempList1 = getNumRpsCurrTempList(hrd); if (numRpsCurrTempList1 > 1) { int length = 1; numRpsCurrTempList1--; while (numRpsCurrTempList1 >>= 1) { length++; } for (int i = 0; i <= hrd->num_ref_idx_l1_active_minus1; i++) // ×¢ÒâÓеȺţ¬Òª×¢Òâ±ß½ç { hrd->ref_pic_lists_modification.list_entry_l1[i] = bs_read_u(b, length); } } else { for (int i = 0; i <= hrd->num_ref_idx_l1_active_minus1; i ++) { hrd->ref_pic_lists_modification.list_entry_l1[i] = 0; } } } } } // 7.3.6.3 Weighted prediction parameters syntax void h265_read_pred_weight_table(h265_stream_t* h, bs_t* b) { pred_weight_table_t* pwt = &h->sh->pred_weight_table; int l0_size = h->sh->num_ref_idx_l0_active_minus1+1; int l1_size = h->sh->num_ref_idx_l1_active_minus1+1; pwt->luma_weight_l0_flag.resize(l0_size); pwt->chroma_weight_l0_flag.resize(l0_size); pwt->delta_luma_weight_l0.resize(l0_size); pwt->luma_offset_l0.resize(l0_size); pwt->delta_chroma_weight_l0.resize(l0_size); pwt->delta_chroma_offset_l0.resize(l0_size); for (int j = 0; j < l0_size; j++) { pwt->delta_chroma_weight_l0[j].resize(2); pwt->delta_chroma_offset_l0[j].resize(2); } pwt->luma_weight_l1_flag.resize(l1_size); pwt->chroma_weight_l1_flag.resize(l1_size); pwt->delta_luma_weight_l1.resize(l1_size); pwt->luma_offset_l1.resize(l1_size); pwt->delta_chroma_weight_l1.resize(l1_size); pwt->delta_chroma_offset_l1.resize(l1_size); for (int j = 0; j < l1_size; j++) { pwt->delta_chroma_weight_l1[j].resize(2); pwt->delta_chroma_offset_l1[j].resize(2); } pwt->luma_log2_weight_denom = bs_read_ue(b); if (h->sps->chroma_format_idc != 0) { pwt->delta_chroma_log2_weight_denom = bs_read_se(b); } for (int i = 0; i <= h->sh->num_ref_idx_l0_active_minus1; i++) { pwt->luma_weight_l0_flag[i] = bs_read_u1(b); } if (h->sps->chroma_format_idc != 0) { for (int i = 0; i <= h->sh->num_ref_idx_l0_active_minus1; i++) { pwt->chroma_weight_l0_flag[i] = bs_read_u1(b); } } for (int i = 0; i <= h->sh->num_ref_idx_l0_active_minus1; i++) { if (pwt->luma_weight_l0_flag[i]) { pwt->delta_luma_weight_l0[i] = bs_read_se(b); pwt->luma_offset_l0[i] = bs_read_se(b); } if (pwt->chroma_weight_l0_flag[i]) { for (int j = 0; j < 2; j++) { pwt->delta_chroma_weight_l0[i][j] = bs_read_se(b); pwt->delta_chroma_offset_l0[i][j] = bs_read_se(b); } } } if (h->sh->slice_type == H265_SH_SLICE_TYPE_B) { for (int i = 0; i <= h->sh->num_ref_idx_l1_active_minus1; i++) { pwt->luma_weight_l1_flag[i] = bs_read_u1(b); } if (h->sps->chroma_format_idc != 0) { for (int i = 0; i <= h->sh->num_ref_idx_l1_active_minus1; i++) { pwt->chroma_weight_l1_flag[i] = bs_read_u1(b); } } for (int i = 0; i <= h->sh->num_ref_idx_l1_active_minus1; i++) { if (pwt->luma_weight_l1_flag[i]) { pwt->delta_luma_weight_l1[i] = bs_read_se(b); pwt->luma_offset_l1[i] = bs_read_se(b); } if (pwt->chroma_weight_l1_flag[i]) { for (int j = 0; j < 2; j++) { pwt->delta_chroma_weight_l1[i][j] = bs_read_se(b); pwt->delta_chroma_offset_l1[i][j] = bs_read_se(b); } } } } } void h265_read_vps_rbsp(h265_stream_t* h, bs_t* b) { int i = 0; int j = 0; int vps_video_parameter_set_id = bs_read_u(b, 4); // Ñ¡ÔñÕýÈ·µÄsps±í h->vps = h->vps_table[vps_video_parameter_set_id]; h265_vps_t* vps = h->vps; memset(vps, 0, sizeof(h265_vps_t)); vps->vps_video_parameter_set_id = vps_video_parameter_set_id; vps->vps_base_layer_internal_flag = bs_read_u1(b); vps->vps_base_layer_available_flag = bs_read_u1(b); vps->vps_max_layers_minus1 = bs_read_u(b, 6); vps->vps_max_sub_layers_minus1 = bs_read_u(b, 3); vps->vps_temporal_id_nesting_flag = bs_read_u1(b); vps->vps_reserved_0xffff_16bits = bs_read_u(b, 16); // profile tier level... h265_read_ptl(&vps->ptl, b, 1, vps->vps_max_sub_layers_minus1); h->info->profile_idc = vps->ptl.general_profile_idc; h->info->level_idc = vps->ptl.general_level_idc; h->info->tier_idc = vps->ptl.general_tier_flag; vps->vps_sub_layer_ordering_info_present_flag = bs_read_u1(b); for (i = (vps->vps_sub_layer_ordering_info_present_flag ? 0 : vps->vps_max_sub_layers_minus1); i <= vps->vps_max_sub_layers_minus1; i++ ) { vps->vps_max_dec_pic_buffering_minus1[i] = bs_read_ue(b); vps->vps_max_num_reorder_pics[i] = bs_read_ue(b); vps->vps_max_latency_increase_plus1[i] = bs_read_ue(b); } vps->vps_max_layer_id = bs_read_u(b, 6); vps->vps_num_layer_sets_minus1 = bs_read_ue(b); vps->layer_id_included_flag.resize(vps->vps_num_layer_sets_minus1+1); for (unsigned int k = 0; k < vps->layer_id_included_flag.size(); k++) { vps->layer_id_included_flag[k].resize(vps->vps_max_layer_id); } for (i = 1; i <= vps->vps_num_layer_sets_minus1; i++) { vps->layer_id_included_flag[i].resize(vps->vps_num_layer_sets_minus1+1); } for (i = 1; i <= vps->vps_num_layer_sets_minus1; i++) { for (j = 0; j <= vps->vps_max_layer_id; j++) { vps->layer_id_included_flag[i][j] = bs_read_u1(b); } } vps->vps_timing_info_present_flag = bs_read_u1(b); if (vps->vps_timing_info_present_flag) { vps->vps_num_units_in_tick = bs_read_u(b, 32); vps->vps_time_scale = bs_read_u(b, 32); vps->vps_poc_proportional_to_timing_flag = bs_read_u1(b); if (vps->vps_poc_proportional_to_timing_flag) { vps->vps_num_ticks_poc_diff_one_minus1 = bs_read_ue(b); } vps->vps_num_hrd_parameters = bs_read_ue(b); vps->hrd_layer_set_idx.resize(vps->vps_num_hrd_parameters); vps->cprms_present_flag.resize(vps->vps_num_hrd_parameters); vps->hrd_layer_set_idx.resize(vps->vps_num_hrd_parameters); vps->cprms_present_flag.resize(vps->vps_num_hrd_parameters); for (i = 0; i < vps->vps_num_hrd_parameters; i++) { vps->hrd_layer_set_idx[i] = bs_read_ue(b); if (i > 0) { vps->cprms_present_flag[i] = bs_read_u1(b); } // hrd_parameters() h265_read_hrd_parameters(&(vps->hrd_parameters), b, vps->cprms_present_flag[i], vps->vps_max_sub_layers_minus1); } } vps->vps_extension_flag = bs_read_u1(b); if (vps->vps_extension_flag) { while (h265_more_rbsp_trailing_data(b)) { int sps_extension_data_flag = bs_read_u1(b); } } h265_read_rbsp_trailing_bits(b); } //7.3.2.1 Sequence parameter set RBSP syntax void h265_read_sps_rbsp(h265_stream_t* h, bs_t* b) { // NOTE ²»ÄÜÖ±½Ó¸³Öµ¸øsps£¬ÒòΪ»¹Î´ÖªÊÇÄÄÒ»¸ösps¡£ int sps_video_parameter_set_id = 0; int sps_max_sub_layers_minus1 = 0; int sps_temporal_id_nesting_flag = 0; int sps_seq_parameter_set_id = 0; profile_tier_level_t profile_tier_level; sps_video_parameter_set_id = bs_read_u(b, 4); sps_max_sub_layers_minus1 = bs_read_u(b, 3); sps_temporal_id_nesting_flag = bs_read_u1(b); // profile tier level... memset(&profile_tier_level, '\0', sizeof(profile_tier_level_t)); h265_read_ptl(&profile_tier_level, b, 1, sps_max_sub_layers_minus1); sps_seq_parameter_set_id = bs_read_ue(b); // Ñ¡ÔñÕýÈ·µÄsps±í h->sps = h->sps_table[sps_seq_parameter_set_id]; h265_sps_t* sps = h->sps; memset(sps, 0, sizeof(h265_sps_t)); sps->sps_video_parameter_set_id = sps_video_parameter_set_id; sps->sps_max_sub_layers_minus1 = sps_max_sub_layers_minus1; sps->sps_temporal_id_nesting_flag = sps_temporal_id_nesting_flag; memcpy(&(sps->ptl), &profile_tier_level, sizeof(profile_tier_level_t)); // ptl sps->sps_seq_parameter_set_id = sps_seq_parameter_set_id; sps->chroma_format_idc = bs_read_ue(b); h->info->chroma_format_idc = sps->chroma_format_idc; if (sps->chroma_format_idc == 3) { sps->separate_colour_plane_flag = bs_read_u1(b); } sps->pic_width_in_luma_samples = bs_read_ue(b); sps->pic_height_in_luma_samples = bs_read_ue(b); h->info->width = sps->pic_width_in_luma_samples; h->info->height = sps->pic_height_in_luma_samples; sps->conformance_window_flag = bs_read_u1(b); if (sps->conformance_window_flag) { sps->conf_win_left_offset = bs_read_ue(b); sps->conf_win_right_offset = bs_read_ue(b); sps->conf_win_top_offset = bs_read_ue(b); sps->conf_win_bottom_offset = bs_read_ue(b); // calc width & height again... h->info->crop_left = sps->conf_win_left_offset; h->info->crop_right = sps->conf_win_right_offset; h->info->crop_top = sps->conf_win_top_offset; h->info->crop_bottom = sps->conf_win_bottom_offset; // ¸ù¾ÝTable6-1¼°7.4.3.2.1ÖØÐ¼ÆËã¿í¡¢¸ß // ×¢Ò⣺ÊÖ²áÀï¼Ó1£¬Êµ¼ÊÉϲ»Óà // ²Î¿¼£ºhttps://github.com/mbunkus/mkvtoolnix/issues/1152 int sub_width_c = ((1 == sps->chroma_format_idc) || (2 == sps->chroma_format_idc)) && (0 == sps->separate_colour_plane_flag) ? 2 : 1; int sub_height_c = (1 == sps->chroma_format_idc) && (0 == sps->separate_colour_plane_flag) ? 2 : 1; h->info->width -= (sub_width_c*sps->conf_win_right_offset + sub_width_c*sps->conf_win_left_offset); h->info->height -= (sub_height_c*sps->conf_win_bottom_offset + sub_height_c*sps->conf_win_top_offset); } sps->bit_depth_luma_minus8 = bs_read_ue(b); sps->bit_depth_chroma_minus8 = bs_read_ue(b); // bit depth h->info->bit_depth_luma = sps->bit_depth_luma_minus8 + 8; h->info->bit_depth_chroma = sps->bit_depth_chroma_minus8 + 8; sps->log2_max_pic_order_cnt_lsb_minus4 = bs_read_ue(b); sps->sps_sub_layer_ordering_info_present_flag = bs_read_u1(b); for (int i = (sps->sps_sub_layer_ordering_info_present_flag ? 0 : sps->sps_max_sub_layers_minus1); i <= sps->sps_max_sub_layers_minus1; i++ ) { sps->sps_max_dec_pic_buffering_minus1[i] = bs_read_ue(b); sps->sps_max_num_reorder_pics[i] = bs_read_ue(b); sps->sps_max_latency_increase_plus1[i] = bs_read_ue(b); } sps->log2_min_luma_coding_block_size_minus3 = bs_read_ue(b); sps->log2_diff_max_min_luma_coding_block_size = bs_read_ue(b); sps->log2_min_luma_transform_block_size_minus2 = bs_read_ue(b); sps->log2_diff_max_min_luma_transform_block_size = bs_read_ue(b); sps->max_transform_hierarchy_depth_inter = bs_read_ue(b); sps->max_transform_hierarchy_depth_intra = bs_read_ue(b); sps->scaling_list_enabled_flag = bs_read_u1(b); if (sps->scaling_list_enabled_flag) { sps->sps_scaling_list_data_present_flag = bs_read_u1(b); if (sps->sps_scaling_list_data_present_flag) { // scaling_list_data() h265_read_scaling_list(&(sps->scaling_list_data), b); } } sps->amp_enabled_flag = bs_read_u1(b); sps->sample_adaptive_offset_enabled_flag = bs_read_u1(b); sps->pcm_enabled_flag = bs_read_u1(b); if (sps->pcm_enabled_flag) { sps->pcm_sample_bit_depth_luma_minus1 = bs_read_u(b, 4); sps->pcm_sample_bit_depth_chroma_minus1 = bs_read_u(b, 4); sps->log2_min_pcm_luma_coding_block_size_minus3 = bs_read_ue(b); sps->log2_diff_max_min_pcm_luma_coding_block_size = bs_read_ue(b); sps->pcm_loop_filter_disabled_flag = bs_read_u1(b); } sps->num_short_term_ref_pic_sets = bs_read_ue(b); // ¸ù¾Ýnum_short_term_ref_pic_sets´´½¨Êý×é sps->st_ref_pic_set.resize(sps->num_short_term_ref_pic_sets); sps->m_RPSList.resize(sps->num_short_term_ref_pic_sets); // È·¶¨Ò»¹²ÓжàÉÙ¸öRPSÁбí referencePictureSets_t* rps = NULL; st_ref_pic_set_t* st = NULL; for (int i = 0; i < sps->num_short_term_ref_pic_sets; i++) { st = &sps->st_ref_pic_set[i]; rps = &sps->m_RPSList[i]; h265_read_short_term_ref_pic_set(b, sps, st, rps, i); } sps->long_term_ref_pics_present_flag = bs_read_u1(b); if (sps->long_term_ref_pics_present_flag) { sps->num_long_term_ref_pics_sps = bs_read_ue(b); sps->lt_ref_pic_poc_lsb_sps.resize(sps->num_long_term_ref_pics_sps); sps->used_by_curr_pic_lt_sps_flag.resize(sps->num_long_term_ref_pics_sps); for (int i = 0; i < sps->num_long_term_ref_pics_sps; i++) { sps->lt_ref_pic_poc_lsb_sps_bytes = sps->log2_max_pic_order_cnt_lsb_minus4 + 4; sps->lt_ref_pic_poc_lsb_sps[i] = bs_read_u(b, sps->log2_max_pic_order_cnt_lsb_minus4 + 4); // u(v) sps->used_by_curr_pic_lt_sps_flag[i] = bs_read_u1(b); } } sps->sps_temporal_mvp_enabled_flag = bs_read_u1(b); sps->strong_intra_smoothing_enabled_flag = bs_read_u1(b); sps->vui_parameters_present_flag = bs_read_u1(b); if (sps->vui_parameters_present_flag) { h265_read_vui_parameters(&(sps->vui), b, sps->sps_max_sub_layers_minus1); // calc fps if (sps->vui.vui_num_units_in_tick != 0) h->info->max_framerate = (float)(sps->vui.vui_time_scale) / (float)(sps->vui.vui_num_units_in_tick); } sps->sps_extension_present_flag = bs_read_u1(b); if (sps->sps_extension_present_flag) { sps->sps_range_extension_flag = bs_read_u1(b); sps->sps_multilayer_extension_flag = bs_read_u1(b); sps->sps_3d_extension_flag = bs_read_u1(b); sps->sps_extension_5bits = bs_read_u(b, 5); } if (sps->sps_range_extension_flag) { sps->sps_range_extension.transform_skip_rotation_enabled_flag = bs_read_u1(b); sps->sps_range_extension.transform_skip_context_enabled_flag = bs_read_u1(b); sps->sps_range_extension.implicit_rdpcm_enabled_flag = bs_read_u1(b); sps->sps_range_extension.explicit_rdpcm_enabled_flag = bs_read_u1(b); sps->sps_range_extension.extended_precision_processing_flag = bs_read_u1(b); sps->sps_range_extension.intra_smoothing_disabled_flag = bs_read_u1(b); sps->sps_range_extension.high_precision_offsets_enabled_flag = bs_read_u1(b); sps->sps_range_extension.persistent_rice_adaptation_enabled_flag = bs_read_u1(b); sps->sps_range_extension.cabac_bypass_alignment_enabled_flag = bs_read_u1(b); } if (sps->sps_multilayer_extension_flag) { // sps_multilayer_extension() sps->inter_view_mv_vert_constraint_flag = bs_read_u1(b); } if (sps->sps_3d_extension_flag) { // todo sps_3d_extension( ) } if (sps->sps_extension_5bits) { while (h265_more_rbsp_trailing_data(b)) { int sps_extension_data_flag = bs_read_u1(b); } } h265_read_rbsp_trailing_bits(b); } //7.3.2.2 Picture parameter set RBSP syntax void h265_read_pps_rbsp(h265_stream_t* h, bs_t* b) { int pps_pic_parameter_set_id = bs_read_ue(b); // get id h265_pps_t* pps = h->pps = h->pps_table[pps_pic_parameter_set_id] ; memset(pps, 0, sizeof(h265_pps_t)); pps->pps_pic_parameter_set_id = pps_pic_parameter_set_id; pps->pps_seq_parameter_set_id = bs_read_ue(b); pps->dependent_slice_segments_enabled_flag = bs_read_u1(b); pps->output_flag_present_flag = bs_read_u1(b); pps->num_extra_slice_header_bits = bs_read_u(b, 3); pps->sign_data_hiding_enabled_flag = bs_read_u1(b); pps->cabac_init_present_flag = bs_read_u1(b); pps->num_ref_idx_l0_default_active_minus1 = bs_read_ue(b); pps->num_ref_idx_l1_default_active_minus1 = bs_read_ue(b); pps->init_qp_minus26 = bs_read_se(b); pps->constrained_intra_pred_flag = bs_read_u1(b); pps->transform_skip_enabled_flag = bs_read_u1(b); pps->cu_qp_delta_enabled_flag = bs_read_u1(b); if (pps->cu_qp_delta_enabled_flag) { pps->diff_cu_qp_delta_depth = bs_read_ue(b); } pps->pps_cb_qp_offset = bs_read_se(b); pps->pps_cr_qp_offset = bs_read_se(b); pps->pps_slice_chroma_qp_offsets_present_flag = bs_read_u1(b); pps->weighted_pred_flag = bs_read_u1(b); pps->weighted_bipred_flag = bs_read_u1(b); pps->transquant_bypass_enabled_flag = bs_read_u1(b); pps->tiles_enabled_flag = bs_read_u1(b); pps->entropy_coding_sync_enabled_flag = bs_read_u1(b); h->info->encoding_type = pps->entropy_coding_sync_enabled_flag; if (pps->tiles_enabled_flag) { pps->num_tile_columns_minus1 = bs_read_ue(b); pps->num_tile_rows_minus1 = bs_read_ue(b); pps->uniform_spacing_flag = bs_read_u1(b); if (!pps->uniform_spacing_flag) { pps->column_width_minus1.resize(pps->num_tile_columns_minus1); pps->row_height_minus1.resize(pps->num_tile_rows_minus1); for (int i = 0; i < pps->num_tile_columns_minus1; i++) { pps->column_width_minus1[i] = bs_read_ue(b); } for (int i = 0; i < pps->num_tile_rows_minus1; i++) { pps->row_height_minus1[i] = bs_read_ue(b); } } pps->loop_filter_across_tiles_enabled_flag = bs_read_u1(b); } pps->pps_loop_filter_across_slices_enabled_flag = bs_read_u1(b); pps->deblocking_filter_control_present_flag = bs_read_u1(b); if (pps->deblocking_filter_control_present_flag) { pps->deblocking_filter_override_enabled_flag = bs_read_u1(b); pps->pps_deblocking_filter_disabled_flag = bs_read_u1(b); if (pps->pps_deblocking_filter_disabled_flag) { pps->pps_beta_offset_div2 = bs_read_se(b); pps->pps_tc_offset_div2 = bs_read_se(b); } } pps->pps_scaling_list_data_present_flag = bs_read_u1(b); if (pps->pps_scaling_list_data_present_flag) { // scaling_list_data() h265_read_scaling_list(&(pps->scaling_list_data), b); } pps->lists_modification_present_flag = bs_read_u1(b); pps->log2_parallel_merge_level_minus2 = bs_read_ue(b); pps->slice_segment_header_extension_present_flag = bs_read_u1(b); pps->pps_extension_present_flag = bs_read_u1(b); if (pps->pps_extension_present_flag) { pps->pps_range_extension_flag = bs_read_u1(b); pps->pps_multilayer_extension_flag = bs_read_u1(b); pps->pps_3d_extension_flag = bs_read_u1(b); pps->pps_extension_5bits = bs_read_u(b, 5); } if (pps->pps_range_extension_flag) { if (pps->transform_skip_enabled_flag) { pps->pps_range_extension.log2_max_transform_skip_block_size_minus2 = bs_read_ue(b); } pps->pps_range_extension.cross_component_prediction_enabled_flag = bs_read_u1(b); pps->pps_range_extension.chroma_qp_offset_list_enabled_flag = bs_read_u1(b); if (pps->pps_range_extension.chroma_qp_offset_list_enabled_flag) { pps->pps_range_extension.diff_cu_chroma_qp_offset_depth = bs_read_ue(b); pps->pps_range_extension.chroma_qp_offset_list_len_minus1 = bs_read_ue(b); pps->pps_range_extension.cb_qp_offset_list.resize(pps->pps_range_extension.chroma_qp_offset_list_len_minus1); pps->pps_range_extension.cr_qp_offset_list.resize(pps->pps_range_extension.chroma_qp_offset_list_len_minus1); for (int i = 0; i < pps->pps_range_extension.chroma_qp_offset_list_len_minus1; i++) { pps->pps_range_extension.cb_qp_offset_list[i] = bs_read_se(b); pps->pps_range_extension.cr_qp_offset_list[i] = bs_read_se(b); } } pps->pps_range_extension.log2_sao_offset_scale_luma = bs_read_ue(b); pps->pps_range_extension.log2_sao_offset_scale_chroma = bs_read_ue(b); } if (pps->pps_multilayer_extension_flag) { // todo sps_multilayer_extension( ) } if (pps->pps_3d_extension_flag) { // todo sps_3d_extension( ) } if (pps->pps_extension_5bits) { while (h265_more_rbsp_trailing_data(b)) { int pps_extension_data_flag = bs_read_u1(b); } } h265_read_rbsp_trailing_bits(b); } //7.3.6.1 General slice segment header syntax void h265_read_slice_header(h265_stream_t* h, bs_t* b) { h265_slice_header_t* hrd = h->sh; h265_sps_t* sps = NULL; h265_pps_t* pps = NULL; int nal_unit_type = h->nal->nal_unit_type; int read_slice_type = hrd->read_slice_type; memset(hrd, 0, sizeof(h265_slice_header_t)); hrd->first_slice_segment_in_pic_flag = bs_read_u1(b); if (nal_unit_type >= NAL_UNIT_CODED_SLICE_BLA_W_LP && nal_unit_type <= NAL_UNIT_RESERVED_IRAP_VCL23) { hrd->no_output_of_prior_pics_flag = bs_read_u1(b); } hrd->slice_pic_parameter_set_id = bs_read_ue(b); pps = h->pps = h->pps_table[hrd->slice_pic_parameter_set_id]; sps = h->sps = h->sps_table[pps->pps_seq_parameter_set_id]; hrd->dependent_slice_segment_flag = 0; if (!hrd->first_slice_segment_in_pic_flag) { if (pps->dependent_slice_segments_enabled_flag) { hrd->dependent_slice_segment_flag = bs_read_u1(b); } int maxCUWidth = 1<<(sps->log2_min_luma_coding_block_size_minus3+3 + sps->log2_diff_max_min_luma_coding_block_size); int maxCUHeight = maxCUWidth;// to check int numCTUs = ((sps->pic_width_in_luma_samples+maxCUWidth-1)/maxCUWidth)*((sps->pic_height_in_luma_samples+maxCUHeight-1)/maxCUHeight);; int bitsSliceSegmentAddress = 0; while(numCTUs>(1<slice_segment_address_bytes = bitsSliceSegmentAddress; hrd->slice_segment_address = bs_read_u(b, bitsSliceSegmentAddress); // u(v) } if (!hrd->dependent_slice_segment_flag) { hrd->slice_reserved_flag.resize(pps->num_extra_slice_header_bits); for (int i = 0; i < pps->num_extra_slice_header_bits; i++) { hrd->slice_reserved_flag[i] = bs_read_u1(b); } hrd->slice_type = bs_read_ue(b); // we need slice type only if (read_slice_type) return; if (pps->output_flag_present_flag) { hrd->pic_output_flag = bs_read_u1(b); } if (sps->separate_colour_plane_flag == 1) { hrd->colour_plane_id = bs_read_u(b, 2); } // IDR if (nal_unit_type == NAL_UNIT_CODED_SLICE_IDR_W_RADL || nal_unit_type == NAL_UNIT_CODED_SLICE_IDR_N_LP) { referencePictureSets_t* rps = &hrd->m_localRPS; memset(rps, '\0', sizeof(referencePictureSets_t)); rps->m_numberOfPictures = 0; rps->m_numberOfNegativePictures = 0; rps->m_numberOfPositivePictures = 0; hrd->m_pRPS = rps; } //if (nal_unit_type != NAL_UNIT_CODED_SLICE_IDR_W_RADL && nal_unit_type != NAL_UNIT_CODED_SLICE_IDR_N_LP) else { hrd->slice_pic_order_cnt_lsb_bytes = sps->log2_max_pic_order_cnt_lsb_minus4 + 4; hrd->slice_pic_order_cnt_lsb = bs_read_u(b, hrd->slice_pic_order_cnt_lsb_bytes); // poc v(u) hrd->short_term_ref_pic_set_sps_flag = bs_read_u1(b); if (!hrd->short_term_ref_pic_set_sps_flag) { referencePictureSets_t* rps = &hrd->m_localRPS; hrd->m_pRPS = &hrd->m_localRPS; // error here // st_ref_pic_set(num_short_term_ref_pic_sets) h265_read_short_term_ref_pic_set(b, sps, &hrd->st_ref_pic_set, rps, sps->num_short_term_ref_pic_sets); } // sps->num_short_term_ref_pic_setʵ¼ÊµÈÓÚssps->m_RPSList.size() ÏÂͬ else if (sps->num_short_term_ref_pic_sets > 1) { uint32_t numBits = 0; while ((1 << numBits) < sps->num_short_term_ref_pic_sets) { numBits++; } if (numBits) { hrd->short_term_ref_pic_set_idx_bytes = numBits; hrd->short_term_ref_pic_set_idx = bs_read_u(b, numBits); } else { hrd->short_term_ref_pic_set_idx = 0; } } if (sps->long_term_ref_pics_present_flag) { if (sps->num_long_term_ref_pics_sps > 0) { hrd->num_long_term_sps = bs_read_ue(b); } uint32_t numLtrpInSPS = 0; while (sps->num_long_term_ref_pics_sps > (1 << numLtrpInSPS)) { numLtrpInSPS++; } hrd->num_long_term_pics = bs_read_ue(b); int cnt = hrd->num_long_term_sps + hrd->num_long_term_pics; hrd->lt_idx_sps.resize(cnt); hrd->poc_lsb_lt.resize(cnt); hrd->used_by_curr_pic_lt_flag.resize(cnt); hrd->delta_poc_msb_present_flag.resize(cnt); hrd->delta_poc_msb_cycle_lt.resize(cnt); for (int i = 0; i < cnt; i++) { if (i < hrd->num_long_term_sps) { //if (sps->num_long_term_ref_pics_sps > 1) // to confirm... if (numLtrpInSPS > 0) { hrd->lt_idx_sps[i] = bs_read_u(b, numLtrpInSPS); // u(v) } } else { hrd->poc_lsb_lt[i] = bs_read_u(b, sps->log2_max_pic_order_cnt_lsb_minus4+4); hrd->used_by_curr_pic_lt_flag[i] = bs_read_u1(b); } hrd->delta_poc_msb_present_flag[i] = bs_read_u1(b); if(hrd->delta_poc_msb_present_flag[i]) { hrd->delta_poc_msb_cycle_lt[i] = bs_read_ue(b); } } } if(sps->sps_temporal_mvp_enabled_flag) { hrd->slice_temporal_mvp_enabled_flag = bs_read_u1(b); } } if(sps->sample_adaptive_offset_enabled_flag) { hrd->slice_sao_luma_flag = bs_read_u1(b); bool ChromaArrayType = (sps->chroma_format_idc != CHROMA_400); if (ChromaArrayType != 0) { hrd->slice_sao_chroma_flag = bs_read_u1(b); } } if (hrd->slice_type == H265_SH_SLICE_TYPE_P || hrd->slice_type == H265_SH_SLICE_TYPE_B) { hrd->num_ref_idx_active_override_flag = bs_read_u1(b); if (hrd->num_ref_idx_active_override_flag) { hrd->num_ref_idx_l0_active_minus1 = bs_read_ue(b); if (hrd->slice_type == H265_SH_SLICE_TYPE_B) { hrd->num_ref_idx_l1_active_minus1 = bs_read_ue(b); } } // to confirm... int tmp = 0; int NumPicTotalCurr = getNumRpsCurrTempList(hrd); if(pps->lists_modification_present_flag && NumPicTotalCurr > 1) { h265_read_ref_pic_lists_modification(b, hrd); } if (hrd->slice_type == H265_SH_SLICE_TYPE_B) { hrd->mvd_l1_zero_flag = bs_read_u1(b); } if (pps->cabac_init_present_flag) { hrd->cabac_init_flag = bs_read_u1(b); } if (hrd->slice_temporal_mvp_enabled_flag) { if (hrd->slice_type == H265_SH_SLICE_TYPE_B) { hrd->collocated_from_l0_flag = bs_read_u1(b); } if ((hrd->collocated_from_l0_flag && hrd->num_ref_idx_l0_active_minus1 > 0) || (!hrd->collocated_from_l0_flag && hrd->num_ref_idx_l1_active_minus1 > 0)) { hrd->collocated_ref_idx = bs_read_ue(b); } } if ((pps->weighted_pred_flag && hrd->slice_type == H265_SH_SLICE_TYPE_P) || (pps->weighted_bipred_flag && hrd->slice_type == H265_SH_SLICE_TYPE_B)) { h265_read_pred_weight_table(h, b); } hrd->five_minus_max_num_merge_cand = bs_read_ue(b); } // end of slice_type P || B hrd->slice_qp_delta = bs_read_se(b); if (pps->pps_slice_chroma_qp_offsets_present_flag) { hrd->slice_cb_qp_offset = bs_read_se(b); hrd->slice_cr_qp_offset = bs_read_se(b); } if (pps->pps_range_extension.chroma_qp_offset_list_enabled_flag) { hrd->cu_chroma_qp_offset_enabled_flag = bs_read_u1(b); } if (pps->deblocking_filter_override_enabled_flag) { hrd->deblocking_filter_override_flag = bs_read_u1(b); } if (hrd->deblocking_filter_override_flag) { hrd->slice_deblocking_filter_disabled_flag = bs_read_u1(b); if (!hrd->slice_deblocking_filter_disabled_flag) { hrd->slice_beta_offset_div2 = bs_read_se(b); hrd->slice_tc_offset_div2 = bs_read_se(b); } } if (pps-> pps_loop_filter_across_slices_enabled_flag && (hrd->slice_sao_luma_flag || hrd->slice_sao_chroma_flag || !hrd->slice_deblocking_filter_disabled_flag)) { hrd->slice_loop_filter_across_slices_enabled_flag = bs_read_u1(b); } } // end of dependent_slice_segment_flag if (pps->tiles_enabled_flag || pps->entropy_coding_sync_enabled_flag) { hrd->num_entry_point_offsets = bs_read_ue(b); if (hrd->num_entry_point_offsets > 0) { hrd->offset_len_minus1 = bs_read_ue(b); hrd->entry_point_offset_minus1_bytes = hrd->offset_len_minus1+1; hrd->entry_point_offset_minus1.resize(hrd->num_entry_point_offsets); // error for (int i = 0; i < hrd->num_entry_point_offsets; i++) { // to confirm // entry_point_offset_minus1Ϊu(u),³¤¶ÈÔÚoffset_len_minus1µÄÖµ¼ÓÉÏ1£¬¼ûÉÏ hrd->entry_point_offset_minus1[i] = bs_read_u(b, hrd->entry_point_offset_minus1_bytes); // u(v) } } } if (pps->slice_segment_header_extension_present_flag) { hrd->slice_segment_header_extension_length = bs_read_ue(b); hrd->slice_segment_header_extension_data_byte.resize(hrd->slice_segment_header_extension_length); for (int i = 0; i < hrd->slice_segment_header_extension_length; i++) { hrd->slice_segment_header_extension_data_byte[i] = bs_read_u8(b); } } // byte_alignment() } void h265_read_slice_layer_rbsp(h265_stream_t* h, bs_t* b) { h265_read_slice_header(h, b); #if 0 slice_data_rbsp_t* slice_data = h->slice_data; if ( slice_data != NULL ) { if ( slice_data->rbsp_buf != NULL ) free( slice_data->rbsp_buf ); uint8_t *sptr = b->p + (!!b->bits_left); // CABAC-specific: skip alignment bits, if there are any slice_data->rbsp_size = b->end - sptr; slice_data->rbsp_buf = (uint8_t*)malloc(slice_data->rbsp_size); memcpy( slice_data->rbsp_buf, sptr, slice_data->rbsp_size ); // ugly hack: since next NALU starts at byte border, we are going to be padded by trailing_bits; return; } // FIXME should read or skip data //slice_data( ); /* all categories of slice_data( ) syntax */ read_rbsp_slice_trailing_bits(h, b); #endif } //7.3.2.5 Access unit delimiter RBSP syntax void h265_read_aud_rbsp(h265_stream_t* h, bs_t* b) { h->aud->pic_type = bs_read_u(b,3); h265_read_rbsp_trailing_bits(b); } //7.3.2.6 End of sequence RBSP syntax void h265_read_end_of_seq_rbsp(h265_stream_t* h, bs_t* b) { } //7.3.2.7 End of stream RBSP syntax void h265_read_end_of_stream_rbsp(h265_stream_t* h, bs_t* b) { } int h265_more_rbsp_data(bs_t* b) { if ( bs_eof(b) ) { return 0; } if ( bs_peek_u1(b) == 1 ) { return 0; } // if next bit is 1, we've reached the stop bit return 1; } int h265_more_rbsp_trailing_data(bs_t* b) { return !bs_eof(b); } int __read_ff_coded_number(bs_t* b) { int n1 = 0; int n2; do { n2 = bs_read_u8(b); n1 += n2; } while (n2 == 0xff); return n1; } void h265_read_sei(h265_stream_t* h, bs_t* b) { h->sei->payloadType = __read_ff_coded_number(b); h->sei->payloadSize = __read_ff_coded_number(b); h265_read_sei_payload(h, b, h->sei->payloadType, h->sei->payloadSize); h265_read_rbsp_trailing_bits(b); } //7.3.2.4 Supplemental enhancement information RBSP syntax void h265_read_sei_rbsp(h265_stream_t* h, bs_t* b) { //return; for (int i = 0; i < h->num_seis; i++) { h265_sei_free(h->seis[i]); } h->num_seis = 0; do { h->num_seis++; h->seis = (h265_sei_t**)realloc(h->seis, h->num_seis * sizeof(sei_t*)); h->seis[h->num_seis - 1] = h265_sei_new(); h->sei = h->seis[h->num_seis - 1]; h265_read_sei(h, b); } while(h265_more_rbsp_data(b)); h265_more_rbsp_trailing_data(b); } //7.3.2.10 RBSP slice trailing bits syntax // Óëh.264ÂÔÓв»Í¬ void h265_read_rbsp_slice_trailing_bits(bs_t* b) { h265_read_rbsp_trailing_bits(b); while( h265_more_rbsp_trailing_data(b) ) { int cabac_zero_word = bs_read_f(b,16); // equal to 0x0000 } } //7.3.2.11 RBSP trailing bits syntax void h265_read_rbsp_trailing_bits(bs_t* b) { int rbsp_stop_one_bit = bs_read_u1( b ); // equal to 1 while( !bs_byte_aligned(b) ) { int rbsp_alignment_zero_bit = bs_read_u1( b ); // equal to 0 7 bits } }