X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fcbs_h265_syntax_template.c;h=5d216aad3655f6a8aba8c4f6db24227f9900584d;hb=985c0dac674846721ec8ff23344c16ac7d1c9a1e;hp=f1e1bb0e7e60ff7975b0f21e22b28c29b6851bd4;hpb=fda424b300c1a0b991296aa585691609d01196bd;p=ffmpeg diff --git a/libavcodec/cbs_h265_syntax_template.c b/libavcodec/cbs_h265_syntax_template.c index f1e1bb0e7e6..5d216aad365 100644 --- a/libavcodec/cbs_h265_syntax_template.c +++ b/libavcodec/cbs_h265_syntax_template.c @@ -33,13 +33,13 @@ static int FUNC(nal_unit_header)(CodedBitstreamContext *ctx, RWContext *rw, { int err; - u(1, forbidden_zero_bit, 0, 0); + fixed(1, forbidden_zero_bit, 0); if (expected_nal_unit_type >= 0) u(6, nal_unit_type, expected_nal_unit_type, expected_nal_unit_type); else - u(6, nal_unit_type, 0, 63); + ub(6, nal_unit_type); u(6, nuh_layer_id, 0, 62); u(3, nuh_temporal_id_plus1, 1, 7); @@ -59,7 +59,7 @@ static int FUNC(byte_alignment)(CodedBitstreamContext *ctx, RWContext *rw) } static int FUNC(extension_data)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawPSExtensionData *current) + H265RawExtensionData *current) { int err; size_t k; @@ -80,7 +80,7 @@ static int FUNC(extension_data)(CodedBitstreamContext *ctx, RWContext *rw, } #else for (k = 0; k < current->bit_length; k++) - xu(1, extension_data, current->data[k / 8] >> (7 - k % 8), 0, 1, 0); + xu(1, extension_data, current->data[k / 8] >> (7 - k % 8) & 1, 0, 1, 0); #endif return 0; } @@ -95,7 +95,7 @@ static int FUNC(profile_tier_level)(CodedBitstreamContext *ctx, RWContext *rw, if (profile_present_flag) { u(2, general_profile_space, 0, 0); flag(general_tier_flag); - u(5, general_profile_idc, 0, 31); + ub(5, general_profile_idc); for (j = 0; j < 32; j++) flags(general_profile_compatibility_flag[j], 1, j); @@ -150,7 +150,7 @@ static int FUNC(profile_tier_level)(CodedBitstreamContext *ctx, RWContext *rw, #undef profile_compatible } - u(8, general_level_idc, 0, 255); + ub(8, general_level_idc); for (i = 0; i < max_num_sub_layers_minus1; i++) { flags(sub_layer_profile_present_flag[i], 1, i); @@ -166,7 +166,7 @@ static int FUNC(profile_tier_level)(CodedBitstreamContext *ctx, RWContext *rw, if (current->sub_layer_profile_present_flag[i]) { us(2, sub_layer_profile_space[i], 0, 0, 1, i); flags(sub_layer_tier_flag[i], 1, i); - us(5, sub_layer_profile_idc[i], 0, 31, 1, i); + ubs(5, sub_layer_profile_idc[i], 1, i); for (j = 0; j < 32; j++) flags(sub_layer_profile_compatibility_flag[i][j], 2, i, j); @@ -220,7 +220,7 @@ static int FUNC(profile_tier_level)(CodedBitstreamContext *ctx, RWContext *rw, #undef profile_compatible } if (current->sub_layer_level_present_flag[i]) - us(8, sub_layer_level_idc[i], 0, 255, 1, i); + ubs(8, sub_layer_level_idc[i], 1, i); } return 0; @@ -265,20 +265,20 @@ static int FUNC(hrd_parameters)(CodedBitstreamContext *ctx, RWContext *rw, current->vcl_hrd_parameters_present_flag) { flag(sub_pic_hrd_params_present_flag); if (current->sub_pic_hrd_params_present_flag) { - u(8, tick_divisor_minus2, 0, 255); - u(5, du_cpb_removal_delay_increment_length_minus1, 0, 31); + ub(8, tick_divisor_minus2); + ub(5, du_cpb_removal_delay_increment_length_minus1); flag(sub_pic_cpb_params_in_pic_timing_sei_flag); - u(5, dpb_output_delay_du_length_minus1, 0, 31); + ub(5, dpb_output_delay_du_length_minus1); } - u(4, bit_rate_scale, 0, 15); - u(4, cpb_size_scale, 0, 15); + ub(4, bit_rate_scale); + ub(4, cpb_size_scale); if (current->sub_pic_hrd_params_present_flag) - u(4, cpb_size_du_scale, 0, 15); + ub(4, cpb_size_du_scale); - u(5, initial_cpb_removal_delay_length_minus1, 0, 31); - u(5, au_cpb_removal_delay_length_minus1, 0, 31); - u(5, dpb_output_delay_length_minus1, 0, 31); + ub(5, initial_cpb_removal_delay_length_minus1); + ub(5, au_cpb_removal_delay_length_minus1); + ub(5, dpb_output_delay_length_minus1); } else { infer(sub_pic_hrd_params_present_flag, 0); @@ -323,10 +323,10 @@ static int FUNC(vui_parameters)(CodedBitstreamContext *ctx, RWContext *rw, flag(aspect_ratio_info_present_flag); if (current->aspect_ratio_info_present_flag) { - u(8, aspect_ratio_idc, 0, 255); + ub(8, aspect_ratio_idc); if (current->aspect_ratio_idc == 255) { - u(16, sar_width, 0, 65535); - u(16, sar_height, 0, 65535); + ub(16, sar_width); + ub(16, sar_height); } } else { infer(aspect_ratio_idc, 0); @@ -338,13 +338,13 @@ static int FUNC(vui_parameters)(CodedBitstreamContext *ctx, RWContext *rw, flag(video_signal_type_present_flag); if (current->video_signal_type_present_flag) { - u(3, video_format, 0, 7); + ub(3, video_format); flag(video_full_range_flag); flag(colour_description_present_flag); if (current->colour_description_present_flag) { - u(8, colour_primaries, 0, 255); - u(8, transfer_characteristics, 0, 255); - u(8, matrix_coefficients, 0, 255); + ub(8, colour_primaries); + ub(8, transfer_characteristics); + ub(8, matrix_coefficients); } else { infer(colour_primaries, 2); infer(transfer_characteristics, 2); @@ -426,7 +426,7 @@ static int FUNC(vps)(CodedBitstreamContext *ctx, RWContext *rw, CHECK(FUNC(nal_unit_header)(ctx, rw, ¤t->nal_unit_header, HEVC_NAL_VPS)); - u(4, vps_video_parameter_set_id, 0, 15); + ub(4, vps_video_parameter_set_id); flag(vps_base_layer_internal_flag); flag(vps_base_layer_available_flag); @@ -522,7 +522,7 @@ static int FUNC(st_ref_pic_set)(CodedBitstreamContext *ctx, RWContext *rw, infer(inter_ref_pic_set_prediction_flag, 0); if (current->inter_ref_pic_set_prediction_flag) { - unsigned int ref_rps_idx, num_delta_pocs; + unsigned int ref_rps_idx, num_delta_pocs, num_ref_pics; const H265RawSTRefPicSet *ref; int delta_rps, d_poc; int ref_delta_poc_s0[HEVC_MAX_REFS], ref_delta_poc_s1[HEVC_MAX_REFS]; @@ -538,18 +538,28 @@ static int FUNC(st_ref_pic_set)(CodedBitstreamContext *ctx, RWContext *rw, ref_rps_idx = st_rps_idx - (current->delta_idx_minus1 + 1); ref = &sps->st_ref_pic_set[ref_rps_idx]; num_delta_pocs = ref->num_negative_pics + ref->num_positive_pics; + av_assert0(num_delta_pocs < HEVC_MAX_DPB_SIZE); flag(delta_rps_sign); ue(abs_delta_rps_minus1, 0, INT16_MAX); delta_rps = (1 - 2 * current->delta_rps_sign) * (current->abs_delta_rps_minus1 + 1); + num_ref_pics = 0; for (j = 0; j <= num_delta_pocs; j++) { flags(used_by_curr_pic_flag[j], 1, j); if (!current->used_by_curr_pic_flag[j]) flags(use_delta_flag[j], 1, j); else infer(use_delta_flag[j], 1); + if (current->use_delta_flag[j]) + ++num_ref_pics; + } + if (num_ref_pics >= HEVC_MAX_DPB_SIZE) { + av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid stream: " + "short-term ref pic set %d " + "contains too many pictures.\n", st_rps_idx); + return AVERROR_INVALIDDATA; } // Since the stored form of an RPS here is actually the delta-step @@ -723,8 +733,7 @@ static int FUNC(sps_scc_extension)(CodedBitstreamContext *ctx, RWContext *rw, int bit_depth = comp == 0 ? current->bit_depth_luma_minus8 + 8 : current->bit_depth_chroma_minus8 + 8; for (i = 0; i <= current->sps_num_palette_predictor_initializer_minus1; i++) - us(bit_depth, sps_palette_predictor_initializers[comp][i], - 0, MAX_UINT_BITS(bit_depth), 2, comp, i); + ubs(bit_depth, sps_palette_predictor_initializers[comp][i], 2, comp, i); } } } @@ -735,6 +744,32 @@ static int FUNC(sps_scc_extension)(CodedBitstreamContext *ctx, RWContext *rw, return 0; } +static int FUNC(vui_parameters_default)(CodedBitstreamContext *ctx, + RWContext *rw, H265RawVUI *current, + H265RawSPS *sps) +{ + infer(aspect_ratio_idc, 0); + + infer(video_format, 5); + infer(video_full_range_flag, 0); + infer(colour_primaries, 2); + infer(transfer_characteristics, 2); + infer(matrix_coefficients, 2); + + infer(chroma_sample_loc_type_top_field, 0); + infer(chroma_sample_loc_type_bottom_field, 0); + + infer(tiles_fixed_structure_flag, 0); + infer(motion_vectors_over_pic_boundaries_flag, 1); + infer(min_spatial_segmentation_idc, 0); + infer(max_bytes_per_pic_denom, 2); + infer(max_bits_per_min_cu_denom, 1); + infer(log2_max_mv_length_horizontal, 15); + infer(log2_max_mv_length_vertical, 15); + + return 0; +} + static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw, H265RawSPS *current) { @@ -748,7 +783,7 @@ static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw, CHECK(FUNC(nal_unit_header)(ctx, rw, ¤t->nal_unit_header, HEVC_NAL_SPS)); - u(4, sps_video_parameter_set_id, 0, 15); + ub(4, sps_video_parameter_set_id); h265->active_vps = vps = h265->vps[current->sps_video_parameter_set_id]; u(3, sps_max_sub_layers_minus1, 0, HEVC_MAX_SUB_LAYERS - 1); @@ -887,9 +922,8 @@ static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw, if (current->long_term_ref_pics_present_flag) { ue(num_long_term_ref_pics_sps, 0, HEVC_MAX_LONG_TERM_REF_PICS); for (i = 0; i < current->num_long_term_ref_pics_sps; i++) { - us(current->log2_max_pic_order_cnt_lsb_minus4 + 4, - lt_ref_pic_poc_lsb_sps[i], - 0, MAX_UINT_BITS(current->log2_max_pic_order_cnt_lsb_minus4 + 4), 1, i); + ubs(current->log2_max_pic_order_cnt_lsb_minus4 + 4, + lt_ref_pic_poc_lsb_sps[i], 1, i); flags(used_by_curr_pic_lt_sps_flag[i], 1, i); } } @@ -900,6 +934,8 @@ static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw, flag(vui_parameters_present_flag); if (current->vui_parameters_present_flag) CHECK(FUNC(vui_parameters)(ctx, rw, ¤t->vui, current)); + else + CHECK(FUNC(vui_parameters_default)(ctx, rw, ¤t->vui, current)); flag(sps_extension_present_flag); if (current->sps_extension_present_flag) { @@ -907,7 +943,7 @@ static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw, flag(sps_multilayer_extension_flag); flag(sps_3d_extension_flag); flag(sps_scc_extension_flag); - u(4, sps_extension_4bits, 0, MAX_UINT_BITS(4)); + ub(4, sps_extension_4bits); } if (current->sps_range_extension_flag) @@ -986,8 +1022,7 @@ static int FUNC(pps_scc_extension)(CodedBitstreamContext *ctx, RWContext *rw, int bit_depth = comp == 0 ? current->luma_bit_depth_entry_minus8 + 8 : current->chroma_bit_depth_entry_minus8 + 8; for (i = 0; i < current->pps_num_palette_predictor_initializer; i++) - us(bit_depth, pps_palette_predictor_initializers[comp][i], - 0, MAX_UINT_BITS(bit_depth), 2, comp, i); + ubs(bit_depth, pps_palette_predictor_initializers[comp][i], 2, comp, i); } } } @@ -1018,7 +1053,7 @@ static int FUNC(pps)(CodedBitstreamContext *ctx, RWContext *rw, flag(dependent_slice_segments_enabled_flag); flag(output_flag_present_flag); - u(3, num_extra_slice_header_bits, 0, 7); + ub(3, num_extra_slice_header_bits); flag(sign_data_hiding_enabled_flag); flag(cabac_init_present_flag); @@ -1100,7 +1135,7 @@ static int FUNC(pps)(CodedBitstreamContext *ctx, RWContext *rw, flag(pps_multilayer_extension_flag); flag(pps_3d_extension_flag); flag(pps_scc_extension_flag); - u(4, pps_extension_4bits, 0, MAX_UINT_BITS(4)); + ub(4, pps_extension_4bits); } if (current->pps_range_extension_flag) CHECK(FUNC(pps_range_extension)(ctx, rw, current)); @@ -1278,7 +1313,7 @@ static int FUNC(slice_segment_header)(CodedBitstreamContext *ctx, RWContext *rw, flag(first_slice_segment_in_pic_flag); if (current->nal_unit_header.nal_unit_type >= HEVC_NAL_BLA_W_LP && - current->nal_unit_header.nal_unit_type <= HEVC_NAL_IRAP_VCL23) + current->nal_unit_header.nal_unit_type <= HEVC_NAL_RSV_IRAP_VCL23) flag(no_output_of_prior_pics_flag); ue(slice_pic_parameter_set_id, 0, 63); @@ -1334,9 +1369,9 @@ static int FUNC(slice_segment_header)(CodedBitstreamContext *ctx, RWContext *rw, if (current->nal_unit_header.nal_unit_type != HEVC_NAL_IDR_W_RADL && current->nal_unit_header.nal_unit_type != HEVC_NAL_IDR_N_LP) { const H265RawSTRefPicSet *rps; + int dpb_slots_remaining; - u(sps->log2_max_pic_order_cnt_lsb_minus4 + 4, slice_pic_order_cnt_lsb, - 0, MAX_UINT_BITS(sps->log2_max_pic_order_cnt_lsb_minus4 + 4)); + ub(sps->log2_max_pic_order_cnt_lsb_minus4 + 4, slice_pic_order_cnt_lsb); flag(short_term_ref_pic_set_sps_flag); if (!current->short_term_ref_pic_set_sps_flag) { @@ -1353,6 +1388,22 @@ static int FUNC(slice_segment_header)(CodedBitstreamContext *ctx, RWContext *rw, rps = &sps->st_ref_pic_set[0]; } + dpb_slots_remaining = HEVC_MAX_DPB_SIZE - 1 - + rps->num_negative_pics - rps->num_positive_pics; + if (pps->pps_curr_pic_ref_enabled_flag && + (sps->sample_adaptive_offset_enabled_flag || + !pps->pps_deblocking_filter_disabled_flag || + pps->deblocking_filter_override_enabled_flag)) { + // This picture will occupy two DPB slots. + if (dpb_slots_remaining == 0) { + av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid stream: " + "short-term ref pic set contains too many pictures " + "to use with current picture reference enabled.\n"); + return AVERROR_INVALIDDATA; + } + --dpb_slots_remaining; + } + num_pic_total_curr = 0; for (i = 0; i < rps->num_negative_pics; i++) if (rps->used_by_curr_pic_s0_flag[i]) @@ -1365,13 +1416,15 @@ static int FUNC(slice_segment_header)(CodedBitstreamContext *ctx, RWContext *rw, unsigned int idx_size; if (sps->num_long_term_ref_pics_sps > 0) { - ue(num_long_term_sps, 0, sps->num_long_term_ref_pics_sps); + ue(num_long_term_sps, 0, FFMIN(sps->num_long_term_ref_pics_sps, + dpb_slots_remaining)); idx_size = av_log2(sps->num_long_term_ref_pics_sps - 1) + 1; + dpb_slots_remaining -= current->num_long_term_sps; } else { infer(num_long_term_sps, 0); idx_size = 0; } - ue(num_long_term_pics, 0, HEVC_MAX_LONG_TERM_REF_PICS); + ue(num_long_term_pics, 0, dpb_slots_remaining); for (i = 0; i < current->num_long_term_sps + current->num_long_term_pics; i++) { @@ -1382,8 +1435,7 @@ static int FUNC(slice_segment_header)(CodedBitstreamContext *ctx, RWContext *rw, if (sps->used_by_curr_pic_lt_sps_flag[current->lt_idx_sps[i]]) ++num_pic_total_curr; } else { - us(sps->log2_max_pic_order_cnt_lsb_minus4 + 4, poc_lsb_lt[i], - 0, MAX_UINT_BITS(sps->log2_max_pic_order_cnt_lsb_minus4 + 4), 1, i); + ubs(sps->log2_max_pic_order_cnt_lsb_minus4 + 4, poc_lsb_lt[i], 1, i); flags(used_by_curr_pic_lt_flag[i], 1, i); if (current->used_by_curr_pic_lt_flag[i]) ++num_pic_total_curr; @@ -1548,8 +1600,7 @@ static int FUNC(slice_segment_header)(CodedBitstreamContext *ctx, RWContext *rw, if (current->num_entry_point_offsets > 0) { ue(offset_len_minus1, 0, 31); for (i = 0; i < current->num_entry_point_offsets; i++) - us(current->offset_len_minus1 + 1, entry_point_offset_minus1[i], - 0, MAX_UINT_BITS(current->offset_len_minus1 + 1), 1, i); + ubs(current->offset_len_minus1 + 1, entry_point_offset_minus1[i], 1, i); } } @@ -1564,9 +1615,9 @@ static int FUNC(slice_segment_header)(CodedBitstreamContext *ctx, RWContext *rw, return 0; } -static int FUNC(sei_buffering_period)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIBufferingPeriod *current, - uint32_t *payload_size) +static int FUNC(sei_buffering_period) + (CodedBitstreamContext *ctx, RWContext *rw, + H265RawSEIBufferingPeriod *current, SEIMessageState *sei) { CodedBitstreamH265Context *h265 = ctx->priv_data; const H265RawSPS *sps; @@ -1574,7 +1625,7 @@ static int FUNC(sei_buffering_period)(CodedBitstreamContext *ctx, RWContext *rw, int err, i, length; #ifdef READ - int start_pos, end_pos, bits_left; + int start_pos, end_pos; start_pos = get_bits_count(rw); #endif @@ -1610,9 +1661,9 @@ static int FUNC(sei_buffering_period)(CodedBitstreamContext *ctx, RWContext *rw, infer(irap_cpb_params_present_flag, 0); if (current->irap_cpb_params_present_flag) { length = hrd->au_cpb_removal_delay_length_minus1 + 1; - u(length, cpb_delay_offset, 0, MAX_UINT_BITS(length)); + ub(length, cpb_delay_offset); length = hrd->dpb_output_delay_length_minus1 + 1; - u(length, dpb_delay_offset, 0, MAX_UINT_BITS(length)); + ub(length, dpb_delay_offset); } else { infer(cpb_delay_offset, 0); infer(dpb_delay_offset, 0); @@ -1621,23 +1672,19 @@ static int FUNC(sei_buffering_period)(CodedBitstreamContext *ctx, RWContext *rw, flag(concatenation_flag); length = hrd->au_cpb_removal_delay_length_minus1 + 1; - u(length, au_cpb_removal_delay_delta_minus1, 0, MAX_UINT_BITS(length)); + ub(length, au_cpb_removal_delay_delta_minus1); if (hrd->nal_hrd_parameters_present_flag) { for (i = 0; i <= hrd->cpb_cnt_minus1[0]; i++) { length = hrd->initial_cpb_removal_delay_length_minus1 + 1; - us(length, nal_initial_cpb_removal_delay[i], - 0, MAX_UINT_BITS(length), 1, i); - us(length, nal_initial_cpb_removal_offset[i], - 0, MAX_UINT_BITS(length), 1, i); + ubs(length, nal_initial_cpb_removal_delay[i], 1, i); + ubs(length, nal_initial_cpb_removal_offset[i], 1, i); if (hrd->sub_pic_hrd_params_present_flag || current->irap_cpb_params_present_flag) { - us(length, nal_initial_alt_cpb_removal_delay[i], - 0, MAX_UINT_BITS(length), 1, i); - us(length, nal_initial_alt_cpb_removal_offset[i], - 0, MAX_UINT_BITS(length), 1, i); + ubs(length, nal_initial_alt_cpb_removal_delay[i], 1, i); + ubs(length, nal_initial_alt_cpb_removal_offset[i], 1, i); } } } @@ -1645,41 +1692,42 @@ static int FUNC(sei_buffering_period)(CodedBitstreamContext *ctx, RWContext *rw, for (i = 0; i <= hrd->cpb_cnt_minus1[0]; i++) { length = hrd->initial_cpb_removal_delay_length_minus1 + 1; - us(length, vcl_initial_cpb_removal_delay[i], - 0, MAX_UINT_BITS(length), 1, i); - us(length, vcl_initial_cpb_removal_offset[i], - 0, MAX_UINT_BITS(length), 1, i); + ubs(length, vcl_initial_cpb_removal_delay[i], 1, i); + ubs(length, vcl_initial_cpb_removal_offset[i], 1, i); if (hrd->sub_pic_hrd_params_present_flag || current->irap_cpb_params_present_flag) { - us(length, vcl_initial_alt_cpb_removal_delay[i], - 0, MAX_UINT_BITS(length), 1, i); - us(length, vcl_initial_alt_cpb_removal_offset[i], - 0, MAX_UINT_BITS(length), 1, i); + ubs(length, vcl_initial_alt_cpb_removal_delay[i], 1, i); + ubs(length, vcl_initial_alt_cpb_removal_offset[i], 1, i); } } } #ifdef READ - // payload_extension_present() - true if we are before the last 1-bit - // in the payload structure, which must be in the last byte. end_pos = get_bits_count(rw); - bits_left = *payload_size * 8 - (end_pos - start_pos); - if (bits_left > 0 && - (bits_left > 7 || ff_ctz(show_bits(rw, bits_left)) < bits_left - 1)) + if (cbs_h265_payload_extension_present(rw, sei->payload_size, + end_pos - start_pos)) flag(use_alt_cpb_params_flag); else infer(use_alt_cpb_params_flag, 0); #else - if (current->use_alt_cpb_params_flag) + // If unknown extension data exists, then use_alt_cpb_params_flag is + // coded in the bitstream and must be written even if it's 0. + if (current->use_alt_cpb_params_flag || sei->extension_present) { flag(use_alt_cpb_params_flag); + // Ensure this bit is not the last in the payload by making the + // more_data_in_payload() check evaluate to true, so it may not + // be mistaken as something else by decoders. + sei->extension_present = 1; + } #endif return 0; } -static int FUNC(sei_pic_timing)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIPicTiming *current) +static int FUNC(sei_pic_timing) + (CodedBitstreamContext *ctx, RWContext *rw, + H265RawSEIPicTiming *current, SEIMessageState *sei) { CodedBitstreamH265Context *h265 = ctx->priv_data; const H265RawSPS *sps; @@ -1720,14 +1768,14 @@ static int FUNC(sei_pic_timing)(CodedBitstreamContext *ctx, RWContext *rw, if (hrd && (hrd->nal_hrd_parameters_present_flag || hrd->vcl_hrd_parameters_present_flag)) { length = hrd->au_cpb_removal_delay_length_minus1 + 1; - u(length, au_cpb_removal_delay_minus1, 0, MAX_UINT_BITS(length)); + ub(length, au_cpb_removal_delay_minus1); length = hrd->dpb_output_delay_length_minus1 + 1; - u(length, pic_dpb_output_delay, 0, MAX_UINT_BITS(length)); + ub(length, pic_dpb_output_delay); if (hrd->sub_pic_hrd_params_present_flag) { length = hrd->dpb_output_delay_du_length_minus1 + 1; - u(length, pic_dpb_output_du_delay, 0, MAX_UINT_BITS(length)); + ub(length, pic_dpb_output_du_delay); } if (hrd->sub_pic_hrd_params_present_flag && @@ -1738,16 +1786,14 @@ static int FUNC(sei_pic_timing)(CodedBitstreamContext *ctx, RWContext *rw, length = hrd->du_cpb_removal_delay_increment_length_minus1 + 1; if (current->du_common_cpb_removal_delay_flag) - u(length, du_common_cpb_removal_delay_increment_minus1, - 0, MAX_UINT_BITS(length)); + ub(length, du_common_cpb_removal_delay_increment_minus1); for (i = 0; i <= current->num_decoding_units_minus1; i++) { ues(num_nalus_in_du_minus1[i], 0, HEVC_MAX_SLICE_SEGMENTS, 1, i); if (!current->du_common_cpb_removal_delay_flag && i < current->num_decoding_units_minus1) - us(length, du_cpb_removal_delay_increment_minus1[i], - 0, MAX_UINT_BITS(length), 1, i); + ubs(length, du_cpb_removal_delay_increment_minus1[i], 1, i); } } } @@ -1755,8 +1801,9 @@ static int FUNC(sei_pic_timing)(CodedBitstreamContext *ctx, RWContext *rw, return 0; } -static int FUNC(sei_pan_scan_rect)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIPanScanRect *current) +static int FUNC(sei_pan_scan_rect) + (CodedBitstreamContext *ctx, RWContext *rw, + H265RawSEIPanScanRect *current, SEIMessageState *sei) { int err, i; @@ -1781,72 +1828,9 @@ static int FUNC(sei_pan_scan_rect)(CodedBitstreamContext *ctx, RWContext *rw, return 0; } -static int FUNC(sei_user_data_registered)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIUserDataRegistered *current, - uint32_t *payload_size) -{ - int err, i, j; - - HEADER("User Data Registered ITU-T T.35"); - - u(8, itu_t_t35_country_code, 0x00, 0xff); - if (current->itu_t_t35_country_code != 0xff) - i = 1; - else { - u(8, itu_t_t35_country_code_extension_byte, 0x00, 0xff); - i = 2; - } - -#ifdef READ - if (*payload_size < i) { - av_log(ctx->log_ctx, AV_LOG_ERROR, - "Invalid SEI user data registered payload.\n"); - return AVERROR_INVALIDDATA; - } - current->data_length = *payload_size - i; -#else - *payload_size = i + current->data_length; -#endif - - allocate(current->data, current->data_length); - for (j = 0; j < current->data_length; j++) - xu(8, itu_t_t35_payload_byte[i], current->data[j], 0x00, 0xff, 1, i + j); - - return 0; -} - -static int FUNC(sei_user_data_unregistered)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIUserDataUnregistered *current, - uint32_t *payload_size) -{ - int err, i; - - HEADER("User Data Unregistered"); - -#ifdef READ - if (*payload_size < 16) { - av_log(ctx->log_ctx, AV_LOG_ERROR, - "Invalid SEI user data unregistered payload.\n"); - return AVERROR_INVALIDDATA; - } - current->data_length = *payload_size - 16; -#else - *payload_size = 16 + current->data_length; -#endif - - for (i = 0; i < 16; i++) - us(8, uuid_iso_iec_11578[i], 0x00, 0xff, 1, i); - - allocate(current->data, current->data_length); - - for (i = 0; i < current->data_length; i++) - xu(8, user_data_payload_byte[i], current->data[i], 0x00, 0xff, 1, i); - - return 0; -} - -static int FUNC(sei_recovery_point)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIRecoveryPoint *current) +static int FUNC(sei_recovery_point) + (CodedBitstreamContext *ctx, RWContext *rw, + H265RawSEIRecoveryPoint *current, SEIMessageState *sei) { int err; @@ -1860,8 +1844,9 @@ static int FUNC(sei_recovery_point)(CodedBitstreamContext *ctx, RWContext *rw, return 0; } -static int FUNC(sei_display_orientation)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIDisplayOrientation *current) +static int FUNC(sei_display_orientation) + (CodedBitstreamContext *ctx, RWContext *rw, + H265RawSEIDisplayOrientation *current, SEIMessageState *sei) { int err; @@ -1871,15 +1856,16 @@ static int FUNC(sei_display_orientation)(CodedBitstreamContext *ctx, RWContext * if (!current->display_orientation_cancel_flag) { flag(hor_flip); flag(ver_flip); - u(16, anticlockwise_rotation, 0, 65535); + ub(16, anticlockwise_rotation); flag(display_orientation_persistence_flag); } return 0; } -static int FUNC(sei_active_parameter_sets)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIActiveParameterSets *current) +static int FUNC(sei_active_parameter_sets) + (CodedBitstreamContext *ctx, RWContext *rw, + H265RawSEIActiveParameterSets *current, SEIMessageState *sei) { CodedBitstreamH265Context *h265 = ctx->priv_data; const H265RawVPS *vps; @@ -1914,8 +1900,9 @@ static int FUNC(sei_active_parameter_sets)(CodedBitstreamContext *ctx, RWContext return 0; } -static int FUNC(sei_decoded_picture_hash)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIDecodedPictureHash *current) +static int FUNC(sei_decoded_picture_hash) + (CodedBitstreamContext *ctx, RWContext *rw, + H265RawSEIDecodedPictureHash *current, SEIMessageState *sei) { CodedBitstreamH265Context *h265 = ctx->priv_data; const H265RawSPS *sps = h265->active_sps; @@ -1945,8 +1932,9 @@ static int FUNC(sei_decoded_picture_hash)(CodedBitstreamContext *ctx, RWContext return 0; } -static int FUNC(sei_time_code)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEITimeCode *current) +static int FUNC(sei_time_code) + (CodedBitstreamContext *ctx, RWContext *rw, + H265RawSEITimeCode *current, SEIMessageState *sei) { int err, i; @@ -1964,7 +1952,7 @@ static int FUNC(sei_time_code)(CodedBitstreamContext *ctx, RWContext *rw, flags(discontinuity_flag[i], 1, i); flags(cnt_dropped_flag[i], 1, i); - us(9, n_frames[i], 0, MAX_UINT_BITS(9), 1, i); + ubs(9, n_frames[i], 1, i); if (current->full_timestamp_flag[i]) { us(6, seconds_value[i], 0, 59, 1, i); @@ -1984,151 +1972,41 @@ static int FUNC(sei_time_code)(CodedBitstreamContext *ctx, RWContext *rw, } } - us(5, time_offset_length[i], 0, 31, 1, i); + ubs(5, time_offset_length[i], 1, i); if (current->time_offset_length[i] > 0) - us(current->time_offset_length[i], time_offset_value[i], - 0, MAX_UINT_BITS(current->time_offset_length[i]), 1, i); + ibs(current->time_offset_length[i], time_offset_value[i], 1, i); + else + infer(time_offset_value[i], 0); } } return 0; } -static int FUNC(sei_mastering_display)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIMasteringDisplayColourVolume *current) +static int FUNC(sei_alpha_channel_info) + (CodedBitstreamContext *ctx, RWContext *rw, + H265RawSEIAlphaChannelInfo *current, SEIMessageState *sei) { - int err, c; - - HEADER("Mastering Display Colour Volume"); - - for (c = 0; c < 3; c++) { - us(16, display_primaries_x[c], 0, 50000, 1, c); - us(16, display_primaries_y[c], 0, 50000, 1, c); - } - - u(16, white_point_x, 0, 50000); - u(16, white_point_y, 0, 50000); - - u(32, max_display_mastering_luminance, - 1, MAX_UINT_BITS(32)); - u(32, min_display_mastering_luminance, - 0, current->max_display_mastering_luminance - 1); - - return 0; -} - -static int FUNC(sei_content_light_level)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIContentLightLevelInfo *current) -{ - int err; - - HEADER("Content Light Level"); - - u(16, max_content_light_level, 0, MAX_UINT_BITS(16)); - u(16, max_pic_average_light_level, 0, MAX_UINT_BITS(16)); - - return 0; -} - -static int FUNC(sei_alternative_transfer_characteristics)(CodedBitstreamContext *ctx, - RWContext *rw, - H265RawSEIAlternativeTransferCharacteristics *current) -{ - int err; - - HEADER("Alternative Transfer Characteristics"); - - u(8, preferred_transfer_characteristics, 0, 255); - - return 0; -} - -static int FUNC(sei_payload)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIPayload *current, int prefix) -{ - int err, i; - int start_position, end_position; - -#ifdef READ - start_position = get_bits_count(rw); -#else - start_position = put_bits_count(rw); -#endif - - switch (current->payload_type) { -#define SEI_TYPE_CHECK_VALID(name, prefix_valid, suffix_valid) do { \ - if (prefix && !prefix_valid) { \ - av_log(ctx->log_ctx, AV_LOG_ERROR, "SEI type %s invalid " \ - "as prefix SEI!\n", #name); \ - return AVERROR_INVALIDDATA; \ - } \ - if (!prefix && !suffix_valid) { \ - av_log(ctx->log_ctx, AV_LOG_ERROR, "SEI type %s invalid " \ - "as suffix SEI!\n", #name); \ - return AVERROR_INVALIDDATA; \ - } \ - } while (0) -#define SEI_TYPE_N(type, prefix_valid, suffix_valid, name) \ - case HEVC_SEI_TYPE_ ## type: \ - SEI_TYPE_CHECK_VALID(name, prefix_valid, suffix_valid); \ - CHECK(FUNC(sei_ ## name)(ctx, rw, ¤t->payload.name)); \ - break -#define SEI_TYPE_S(type, prefix_valid, suffix_valid, name) \ - case HEVC_SEI_TYPE_ ## type: \ - SEI_TYPE_CHECK_VALID(name, prefix_valid, suffix_valid); \ - CHECK(FUNC(sei_ ## name)(ctx, rw, ¤t->payload.name, \ - ¤t->payload_size)); \ - break - - SEI_TYPE_S(BUFFERING_PERIOD, 1, 0, buffering_period); - SEI_TYPE_N(PICTURE_TIMING, 1, 0, pic_timing); - SEI_TYPE_N(PAN_SCAN_RECT, 1, 0, pan_scan_rect); - SEI_TYPE_S(USER_DATA_REGISTERED_ITU_T_T35, - 1, 1, user_data_registered); - SEI_TYPE_S(USER_DATA_UNREGISTERED, 1, 1, user_data_unregistered); - SEI_TYPE_N(RECOVERY_POINT, 1, 0, recovery_point); - SEI_TYPE_N(DISPLAY_ORIENTATION, 1, 0, display_orientation); - SEI_TYPE_N(ACTIVE_PARAMETER_SETS, 1, 0, active_parameter_sets); - SEI_TYPE_N(DECODED_PICTURE_HASH, 0, 1, decoded_picture_hash); - SEI_TYPE_N(TIME_CODE, 1, 0, time_code); - SEI_TYPE_N(MASTERING_DISPLAY_INFO, 1, 0, mastering_display); - SEI_TYPE_N(CONTENT_LIGHT_LEVEL_INFO, 1, 0, content_light_level); - SEI_TYPE_N(ALTERNATIVE_TRANSFER_CHARACTERISTICS, - 1, 0, alternative_transfer_characteristics); - -#undef SEI_TYPE - default: - { -#ifdef READ - current->payload.other.data_length = current->payload_size; -#endif - allocate(current->payload.other.data, current->payload.other.data_length); - - for (i = 0; i < current->payload_size; i++) - xu(8, payload_byte[i], current->payload.other.data[i], 0, 255, - 1, i); - } - } - - if (byte_alignment(rw)) { - fixed(1, bit_equal_to_one, 1); - while (byte_alignment(rw)) - fixed(1, bit_equal_to_zero, 0); - } - -#ifdef READ - end_position = get_bits_count(rw); - if (end_position < start_position + 8 * current->payload_size) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Incorrect SEI payload length: " - "header %"PRIu32" bits, actually %d bits.\n", - 8 * current->payload_size, - end_position - start_position); - return AVERROR_INVALIDDATA; + int err, length; + + HEADER("Alpha Channel Information"); + + flag(alpha_channel_cancel_flag); + if (!current->alpha_channel_cancel_flag) { + ub(3, alpha_channel_use_idc); + ub(3, alpha_channel_bit_depth_minus8); + length = current->alpha_channel_bit_depth_minus8 + 9; + ub(length, alpha_transparent_value); + ub(length, alpha_opaque_value); + flag(alpha_channel_incr_flag); + flag(alpha_channel_clip_flag); + if (current->alpha_channel_clip_flag) + flag(alpha_channel_clip_type_flag); + } else { + infer(alpha_channel_use_idc, 2); + infer(alpha_channel_incr_flag, 0); + infer(alpha_channel_clip_flag, 0); } -#else - end_position = put_bits_count(rw); - current->payload_size = (end_position - start_position) >> 3; -#endif return 0; } @@ -2136,7 +2014,7 @@ static int FUNC(sei_payload)(CodedBitstreamContext *ctx, RWContext *rw, static int FUNC(sei)(CodedBitstreamContext *ctx, RWContext *rw, H265RawSEI *current, int prefix) { - int err, k; + int err; if (prefix) HEADER("Prefix Supplemental Enhancement Information"); @@ -2147,72 +2025,7 @@ static int FUNC(sei)(CodedBitstreamContext *ctx, RWContext *rw, prefix ? HEVC_NAL_SEI_PREFIX : HEVC_NAL_SEI_SUFFIX)); -#ifdef READ - for (k = 0; k < H265_MAX_SEI_PAYLOADS; k++) { - uint32_t payload_type = 0; - uint32_t payload_size = 0; - uint32_t tmp; - - while (show_bits(rw, 8) == 0xff) { - fixed(8, ff_byte, 0xff); - payload_type += 255; - } - xu(8, last_payload_type_byte, tmp, 0, 254, 0); - payload_type += tmp; - - while (show_bits(rw, 8) == 0xff) { - fixed(8, ff_byte, 0xff); - payload_size += 255; - } - xu(8, last_payload_size_byte, tmp, 0, 254, 0); - payload_size += tmp; - - current->payload[k].payload_type = payload_type; - current->payload[k].payload_size = payload_size; - - CHECK(FUNC(sei_payload)(ctx, rw, ¤t->payload[k], prefix)); - - if (!cbs_h2645_read_more_rbsp_data(rw)) - break; - } - if (k >= H265_MAX_SEI_PAYLOADS) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Too many payloads in " - "SEI message: found %d.\n", k); - return AVERROR_INVALIDDATA; - } - current->payload_count = k + 1; -#else - for (k = 0; k < current->payload_count; k++) { - PutBitContext start_state; - uint32_t tmp; - int need_size, i; - - // Somewhat clumsy: we write the payload twice when - // we don't know the size in advance. This will mess - // with trace output, but is otherwise harmless. - start_state = *rw; - need_size = !current->payload[k].payload_size; - for (i = 0; i < 1 + need_size; i++) { - *rw = start_state; - - tmp = current->payload[k].payload_type; - while (tmp >= 255) { - fixed(8, ff_byte, 0xff); - tmp -= 255; - } - xu(8, last_payload_type_byte, tmp, 0, 254, 0); - - tmp = current->payload[k].payload_size; - while (tmp >= 255) { - fixed(8, ff_byte, 0xff); - tmp -= 255; - } - xu(8, last_payload_size_byte, tmp, 0, 254, 0); - - CHECK(FUNC(sei_payload)(ctx, rw, ¤t->payload[k], prefix)); - } - } -#endif + CHECK(FUNC_SEI(message_list)(ctx, rw, ¤t->message_list, prefix)); CHECK(FUNC(rbsp_trailing_bits)(ctx, rw));