1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-12 19:18:44 +02:00
FFmpeg/libavcodec/cbs_h264_syntax_template.c
Andreas Rheinhardt a1a8815220 libavcodec: Reduce the size of some arrays
This commit uses smaller types for some static const arrays to reduce
their size in case the entries can be represented in the smaller type.
The biggest savings came from inv_map_table in vp9.c.

Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
Signed-off-by: James Almer <jamrial@gmail.com>
2019-06-20 14:47:46 -03:00

1423 lines
46 KiB
C

/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
static int FUNC(rbsp_trailing_bits)(CodedBitstreamContext *ctx, RWContext *rw)
{
int err;
fixed(1, rbsp_stop_one_bit, 1);
while (byte_alignment(rw) != 0)
fixed(1, rbsp_alignment_zero_bit, 0);
return 0;
}
static int FUNC(nal_unit_header)(CodedBitstreamContext *ctx, RWContext *rw,
H264RawNALUnitHeader *current,
uint32_t valid_type_mask)
{
int err;
fixed(1, forbidden_zero_bit, 0);
ub(2, nal_ref_idc);
ub(5, nal_unit_type);
if (!(1 << current->nal_unit_type & valid_type_mask)) {
av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid NAL unit type %d.\n",
current->nal_unit_type);
return AVERROR_INVALIDDATA;
}
if (current->nal_unit_type == 14 ||
current->nal_unit_type == 20 ||
current->nal_unit_type == 21) {
if (current->nal_unit_type != 21)
flag(svc_extension_flag);
else
flag(avc_3d_extension_flag);
if (current->svc_extension_flag) {
av_log(ctx->log_ctx, AV_LOG_ERROR, "SVC not supported.\n");
return AVERROR_PATCHWELCOME;
} else if (current->avc_3d_extension_flag) {
av_log(ctx->log_ctx, AV_LOG_ERROR, "3DAVC not supported.\n");
return AVERROR_PATCHWELCOME;
} else {
av_log(ctx->log_ctx, AV_LOG_ERROR, "MVC not supported.\n");
return AVERROR_PATCHWELCOME;
}
}
return 0;
}
static int FUNC(scaling_list)(CodedBitstreamContext *ctx, RWContext *rw,
H264RawScalingList *current,
int size_of_scaling_list)
{
int err, i, scale;
scale = 8;
for (i = 0; i < size_of_scaling_list; i++) {
ses(delta_scale[i], -128, +127, 1, i);
scale = (scale + current->delta_scale[i] + 256) % 256;
if (scale == 0)
break;
}
return 0;
}
static int FUNC(hrd_parameters)(CodedBitstreamContext *ctx, RWContext *rw,
H264RawHRD *current)
{
int err, i;
ue(cpb_cnt_minus1, 0, 31);
ub(4, bit_rate_scale);
ub(4, cpb_size_scale);
for (i = 0; i <= current->cpb_cnt_minus1; i++) {
ues(bit_rate_value_minus1[i], 0, UINT32_MAX - 1, 1, i);
ues(cpb_size_value_minus1[i], 0, UINT32_MAX - 1, 1, i);
flags(cbr_flag[i], 1, i);
}
ub(5, initial_cpb_removal_delay_length_minus1);
ub(5, cpb_removal_delay_length_minus1);
ub(5, dpb_output_delay_length_minus1);
ub(5, time_offset_length);
return 0;
}
static int FUNC(vui_parameters)(CodedBitstreamContext *ctx, RWContext *rw,
H264RawVUI *current, H264RawSPS *sps)
{
int err;
flag(aspect_ratio_info_present_flag);
if (current->aspect_ratio_info_present_flag) {
ub(8, aspect_ratio_idc);
if (current->aspect_ratio_idc == 255) {
ub(16, sar_width);
ub(16, sar_height);
}
} else {
infer(aspect_ratio_idc, 0);
}
flag(overscan_info_present_flag);
if (current->overscan_info_present_flag)
flag(overscan_appropriate_flag);
flag(video_signal_type_present_flag);
if (current->video_signal_type_present_flag) {
ub(3, video_format);
flag(video_full_range_flag);
flag(colour_description_present_flag);
if (current->colour_description_present_flag) {
ub(8, colour_primaries);
ub(8, transfer_characteristics);
ub(8, matrix_coefficients);
}
} else {
infer(video_format, 5);
infer(video_full_range_flag, 0);
infer(colour_primaries, 2);
infer(transfer_characteristics, 2);
infer(matrix_coefficients, 2);
}
flag(chroma_loc_info_present_flag);
if (current->chroma_loc_info_present_flag) {
ue(chroma_sample_loc_type_top_field, 0, 5);
ue(chroma_sample_loc_type_bottom_field, 0, 5);
} else {
infer(chroma_sample_loc_type_top_field, 0);
infer(chroma_sample_loc_type_bottom_field, 0);
}
flag(timing_info_present_flag);
if (current->timing_info_present_flag) {
u(32, num_units_in_tick, 1, UINT32_MAX);
u(32, time_scale, 1, UINT32_MAX);
flag(fixed_frame_rate_flag);
} else {
infer(fixed_frame_rate_flag, 0);
}
flag(nal_hrd_parameters_present_flag);
if (current->nal_hrd_parameters_present_flag)
CHECK(FUNC(hrd_parameters)(ctx, rw, &current->nal_hrd_parameters));
flag(vcl_hrd_parameters_present_flag);
if (current->vcl_hrd_parameters_present_flag)
CHECK(FUNC(hrd_parameters)(ctx, rw, &current->vcl_hrd_parameters));
if (current->nal_hrd_parameters_present_flag ||
current->vcl_hrd_parameters_present_flag)
flag(low_delay_hrd_flag);
else
infer(low_delay_hrd_flag, 1 - current->fixed_frame_rate_flag);
flag(pic_struct_present_flag);
flag(bitstream_restriction_flag);
if (current->bitstream_restriction_flag) {
flag(motion_vectors_over_pic_boundaries_flag);
ue(max_bytes_per_pic_denom, 0, 16);
ue(max_bits_per_mb_denom, 0, 16);
// The current version of the standard constrains this to be in
// [0,15], but older versions allow 16.
ue(log2_max_mv_length_horizontal, 0, 16);
ue(log2_max_mv_length_vertical, 0, 16);
ue(max_num_reorder_frames, 0, H264_MAX_DPB_FRAMES);
ue(max_dec_frame_buffering, 0, H264_MAX_DPB_FRAMES);
} else {
infer(motion_vectors_over_pic_boundaries_flag, 1);
infer(max_bytes_per_pic_denom, 2);
infer(max_bits_per_mb_denom, 1);
infer(log2_max_mv_length_horizontal, 15);
infer(log2_max_mv_length_vertical, 15);
if ((sps->profile_idc == 44 || sps->profile_idc == 86 ||
sps->profile_idc == 100 || sps->profile_idc == 110 ||
sps->profile_idc == 122 || sps->profile_idc == 244) &&
sps->constraint_set3_flag) {
infer(max_num_reorder_frames, 0);
infer(max_dec_frame_buffering, 0);
} else {
infer(max_num_reorder_frames, H264_MAX_DPB_FRAMES);
infer(max_dec_frame_buffering, H264_MAX_DPB_FRAMES);
}
}
return 0;
}
static int FUNC(vui_parameters_default)(CodedBitstreamContext *ctx,
RWContext *rw, H264RawVUI *current,
H264RawSPS *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(fixed_frame_rate_flag, 0);
infer(low_delay_hrd_flag, 1);
infer(pic_struct_present_flag, 0);
infer(motion_vectors_over_pic_boundaries_flag, 1);
infer(max_bytes_per_pic_denom, 2);
infer(max_bits_per_mb_denom, 1);
infer(log2_max_mv_length_horizontal, 15);
infer(log2_max_mv_length_vertical, 15);
if ((sps->profile_idc == 44 || sps->profile_idc == 86 ||
sps->profile_idc == 100 || sps->profile_idc == 110 ||
sps->profile_idc == 122 || sps->profile_idc == 244) &&
sps->constraint_set3_flag) {
infer(max_num_reorder_frames, 0);
infer(max_dec_frame_buffering, 0);
} else {
infer(max_num_reorder_frames, H264_MAX_DPB_FRAMES);
infer(max_dec_frame_buffering, H264_MAX_DPB_FRAMES);
}
return 0;
}
static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw,
H264RawSPS *current)
{
int err, i;
HEADER("Sequence Parameter Set");
CHECK(FUNC(nal_unit_header)(ctx, rw, &current->nal_unit_header,
1 << H264_NAL_SPS));
ub(8, profile_idc);
flag(constraint_set0_flag);
flag(constraint_set1_flag);
flag(constraint_set2_flag);
flag(constraint_set3_flag);
flag(constraint_set4_flag);
flag(constraint_set5_flag);
u(2, reserved_zero_2bits, 0, 0);
ub(8, level_idc);
ue(seq_parameter_set_id, 0, 31);
if (current->profile_idc == 100 || current->profile_idc == 110 ||
current->profile_idc == 122 || current->profile_idc == 244 ||
current->profile_idc == 44 || current->profile_idc == 83 ||
current->profile_idc == 86 || current->profile_idc == 118 ||
current->profile_idc == 128 || current->profile_idc == 138) {
ue(chroma_format_idc, 0, 3);
if (current->chroma_format_idc == 3)
flag(separate_colour_plane_flag);
else
infer(separate_colour_plane_flag, 0);
ue(bit_depth_luma_minus8, 0, 6);
ue(bit_depth_chroma_minus8, 0, 6);
flag(qpprime_y_zero_transform_bypass_flag);
flag(seq_scaling_matrix_present_flag);
if (current->seq_scaling_matrix_present_flag) {
for (i = 0; i < ((current->chroma_format_idc != 3) ? 8 : 12); i++) {
flags(seq_scaling_list_present_flag[i], 1, i);
if (current->seq_scaling_list_present_flag[i]) {
if (i < 6)
CHECK(FUNC(scaling_list)(ctx, rw,
&current->scaling_list_4x4[i],
16));
else
CHECK(FUNC(scaling_list)(ctx, rw,
&current->scaling_list_8x8[i - 6],
64));
}
}
}
} else {
infer(chroma_format_idc, current->profile_idc == 183 ? 0 : 1);
infer(separate_colour_plane_flag, 0);
infer(bit_depth_luma_minus8, 0);
infer(bit_depth_chroma_minus8, 0);
}
ue(log2_max_frame_num_minus4, 0, 12);
ue(pic_order_cnt_type, 0, 2);
if (current->pic_order_cnt_type == 0) {
ue(log2_max_pic_order_cnt_lsb_minus4, 0, 12);
} else if (current->pic_order_cnt_type == 1) {
flag(delta_pic_order_always_zero_flag);
se(offset_for_non_ref_pic, INT32_MIN + 1, INT32_MAX);
se(offset_for_top_to_bottom_field, INT32_MIN + 1, INT32_MAX);
ue(num_ref_frames_in_pic_order_cnt_cycle, 0, 255);
for (i = 0; i < current->num_ref_frames_in_pic_order_cnt_cycle; i++)
ses(offset_for_ref_frame[i], INT32_MIN + 1, INT32_MAX, 1, i);
}
ue(max_num_ref_frames, 0, H264_MAX_DPB_FRAMES);
flag(gaps_in_frame_num_allowed_flag);
ue(pic_width_in_mbs_minus1, 0, H264_MAX_MB_WIDTH);
ue(pic_height_in_map_units_minus1, 0, H264_MAX_MB_HEIGHT);
flag(frame_mbs_only_flag);
if (!current->frame_mbs_only_flag)
flag(mb_adaptive_frame_field_flag);
flag(direct_8x8_inference_flag);
flag(frame_cropping_flag);
if (current->frame_cropping_flag) {
ue(frame_crop_left_offset, 0, H264_MAX_WIDTH);
ue(frame_crop_right_offset, 0, H264_MAX_WIDTH);
ue(frame_crop_top_offset, 0, H264_MAX_HEIGHT);
ue(frame_crop_bottom_offset, 0, H264_MAX_HEIGHT);
}
flag(vui_parameters_present_flag);
if (current->vui_parameters_present_flag)
CHECK(FUNC(vui_parameters)(ctx, rw, &current->vui, current));
else
CHECK(FUNC(vui_parameters_default)(ctx, rw, &current->vui, current));
CHECK(FUNC(rbsp_trailing_bits)(ctx, rw));
return 0;
}
static int FUNC(sps_extension)(CodedBitstreamContext *ctx, RWContext *rw,
H264RawSPSExtension *current)
{
int err;
HEADER("Sequence Parameter Set Extension");
CHECK(FUNC(nal_unit_header)(ctx, rw, &current->nal_unit_header,
1 << H264_NAL_SPS_EXT));
ue(seq_parameter_set_id, 0, 31);
ue(aux_format_idc, 0, 3);
if (current->aux_format_idc != 0) {
int bits;
ue(bit_depth_aux_minus8, 0, 4);
flag(alpha_incr_flag);
bits = current->bit_depth_aux_minus8 + 9;
ub(bits, alpha_opaque_value);
ub(bits, alpha_transparent_value);
}
flag(additional_extension_flag);
CHECK(FUNC(rbsp_trailing_bits)(ctx, rw));
return 0;
}
static int FUNC(pps)(CodedBitstreamContext *ctx, RWContext *rw,
H264RawPPS *current)
{
CodedBitstreamH264Context *h264 = ctx->priv_data;
const H264RawSPS *sps;
int err, i;
HEADER("Picture Parameter Set");
CHECK(FUNC(nal_unit_header)(ctx, rw, &current->nal_unit_header,
1 << H264_NAL_PPS));
ue(pic_parameter_set_id, 0, 255);
ue(seq_parameter_set_id, 0, 31);
sps = h264->sps[current->seq_parameter_set_id];
if (!sps) {
av_log(ctx->log_ctx, AV_LOG_ERROR, "SPS id %d not available.\n",
current->seq_parameter_set_id);
return AVERROR_INVALIDDATA;
}
flag(entropy_coding_mode_flag);
flag(bottom_field_pic_order_in_frame_present_flag);
ue(num_slice_groups_minus1, 0, 7);
if (current->num_slice_groups_minus1 > 0) {
unsigned int pic_size;
int iGroup;
pic_size = (sps->pic_width_in_mbs_minus1 + 1) *
(sps->pic_height_in_map_units_minus1 + 1);
ue(slice_group_map_type, 0, 6);
if (current->slice_group_map_type == 0) {
for (iGroup = 0; iGroup <= current->num_slice_groups_minus1; iGroup++)
ues(run_length_minus1[iGroup], 0, pic_size - 1, 1, iGroup);
} else if (current->slice_group_map_type == 2) {
for (iGroup = 0; iGroup < current->num_slice_groups_minus1; iGroup++) {
ues(top_left[iGroup], 0, pic_size - 1, 1, iGroup);
ues(bottom_right[iGroup],
current->top_left[iGroup], pic_size - 1, 1, iGroup);
}
} else if (current->slice_group_map_type == 3 ||
current->slice_group_map_type == 4 ||
current->slice_group_map_type == 5) {
flag(slice_group_change_direction_flag);
ue(slice_group_change_rate_minus1, 0, pic_size - 1);
} else if (current->slice_group_map_type == 6) {
ue(pic_size_in_map_units_minus1, pic_size - 1, pic_size - 1);
allocate(current->slice_group_id,
current->pic_size_in_map_units_minus1 + 1);
for (i = 0; i <= current->pic_size_in_map_units_minus1; i++)
us(av_log2(2 * current->num_slice_groups_minus1 + 1),
slice_group_id[i], 0, current->num_slice_groups_minus1, 1, i);
}
}
ue(num_ref_idx_l0_default_active_minus1, 0, 31);
ue(num_ref_idx_l1_default_active_minus1, 0, 31);
flag(weighted_pred_flag);
u(2, weighted_bipred_idc, 0, 2);
se(pic_init_qp_minus26, -26 - 6 * sps->bit_depth_luma_minus8, +25);
se(pic_init_qs_minus26, -26, +25);
se(chroma_qp_index_offset, -12, +12);
flag(deblocking_filter_control_present_flag);
flag(constrained_intra_pred_flag);
flag(redundant_pic_cnt_present_flag);
if (more_rbsp_data(current->more_rbsp_data))
{
flag(transform_8x8_mode_flag);
flag(pic_scaling_matrix_present_flag);
if (current->pic_scaling_matrix_present_flag) {
for (i = 0; i < 6 + (((sps->chroma_format_idc != 3) ? 2 : 6) *
current->transform_8x8_mode_flag); i++) {
flags(pic_scaling_list_present_flag[i], 1, i);
if (current->pic_scaling_list_present_flag[i]) {
if (i < 6)
CHECK(FUNC(scaling_list)(ctx, rw,
&current->scaling_list_4x4[i],
16));
else
CHECK(FUNC(scaling_list)(ctx, rw,
&current->scaling_list_8x8[i - 6],
64));
}
}
}
se(second_chroma_qp_index_offset, -12, +12);
} else {
infer(transform_8x8_mode_flag, 0);
infer(pic_scaling_matrix_present_flag, 0);
infer(second_chroma_qp_index_offset, current->chroma_qp_index_offset);
}
CHECK(FUNC(rbsp_trailing_bits)(ctx, rw));
return 0;
}
static int FUNC(sei_buffering_period)(CodedBitstreamContext *ctx, RWContext *rw,
H264RawSEIBufferingPeriod *current)
{
CodedBitstreamH264Context *h264 = ctx->priv_data;
const H264RawSPS *sps;
int err, i, length;
HEADER("Buffering Period");
ue(seq_parameter_set_id, 0, 31);
sps = h264->sps[current->seq_parameter_set_id];
if (!sps) {
av_log(ctx->log_ctx, AV_LOG_ERROR, "SPS id %d not available.\n",
current->seq_parameter_set_id);
return AVERROR_INVALIDDATA;
}
h264->active_sps = sps;
if (sps->vui.nal_hrd_parameters_present_flag) {
for (i = 0; i <= sps->vui.nal_hrd_parameters.cpb_cnt_minus1; i++) {
length = sps->vui.nal_hrd_parameters.initial_cpb_removal_delay_length_minus1 + 1;
xu(length, initial_cpb_removal_delay[SchedSelIdx],
current->nal.initial_cpb_removal_delay[i],
1, MAX_UINT_BITS(length), 1, i);
xu(length, initial_cpb_removal_delay_offset[SchedSelIdx],
current->nal.initial_cpb_removal_delay_offset[i],
0, MAX_UINT_BITS(length), 1, i);
}
}
if (sps->vui.vcl_hrd_parameters_present_flag) {
for (i = 0; i <= sps->vui.vcl_hrd_parameters.cpb_cnt_minus1; i++) {
length = sps->vui.vcl_hrd_parameters.initial_cpb_removal_delay_length_minus1 + 1;
xu(length, initial_cpb_removal_delay[SchedSelIdx],
current->vcl.initial_cpb_removal_delay[i],
1, MAX_UINT_BITS(length), 1, i);
xu(length, initial_cpb_removal_delay_offset[SchedSelIdx],
current->vcl.initial_cpb_removal_delay_offset[i],
0, MAX_UINT_BITS(length), 1, i);
}
}
return 0;
}
static int FUNC(sei_pic_timestamp)(CodedBitstreamContext *ctx, RWContext *rw,
H264RawSEIPicTimestamp *current,
const H264RawSPS *sps)
{
uint8_t time_offset_length;
int err;
u(2, ct_type, 0, 2);
flag(nuit_field_based_flag);
u(5, counting_type, 0, 6);
flag(full_timestamp_flag);
flag(discontinuity_flag);
flag(cnt_dropped_flag);
ub(8, n_frames);
if (current->full_timestamp_flag) {
u(6, seconds_value, 0, 59);
u(6, minutes_value, 0, 59);
u(5, hours_value, 0, 23);
} else {
flag(seconds_flag);
if (current->seconds_flag) {
u(6, seconds_value, 0, 59);
flag(minutes_flag);
if (current->minutes_flag) {
u(6, minutes_value, 0, 59);
flag(hours_flag);
if (current->hours_flag)
u(5, hours_value, 0, 23);
}
}
}
if (sps->vui.nal_hrd_parameters_present_flag)
time_offset_length = sps->vui.nal_hrd_parameters.time_offset_length;
else if (sps->vui.vcl_hrd_parameters_present_flag)
time_offset_length = sps->vui.vcl_hrd_parameters.time_offset_length;
else
time_offset_length = 24;
if (time_offset_length > 0)
ib(time_offset_length, time_offset);
else
infer(time_offset, 0);
return 0;
}
static int FUNC(sei_pic_timing)(CodedBitstreamContext *ctx, RWContext *rw,
H264RawSEIPicTiming *current)
{
CodedBitstreamH264Context *h264 = ctx->priv_data;
const H264RawSPS *sps;
int err;
HEADER("Picture Timing");
sps = h264->active_sps;
if (!sps) {
// If there is exactly one possible SPS but it is not yet active
// then just assume that it should be the active one.
int i, k = -1;
for (i = 0; i < H264_MAX_SPS_COUNT; i++) {
if (h264->sps[i]) {
if (k >= 0) {
k = -1;
break;
}
k = i;
}
}
if (k >= 0)
sps = h264->sps[k];
}
if (!sps) {
av_log(ctx->log_ctx, AV_LOG_ERROR,
"No active SPS for pic_timing.\n");
return AVERROR_INVALIDDATA;
}
if (sps->vui.nal_hrd_parameters_present_flag ||
sps->vui.vcl_hrd_parameters_present_flag) {
const H264RawHRD *hrd;
if (sps->vui.nal_hrd_parameters_present_flag)
hrd = &sps->vui.nal_hrd_parameters;
else if (sps->vui.vcl_hrd_parameters_present_flag)
hrd = &sps->vui.vcl_hrd_parameters;
else {
av_log(ctx->log_ctx, AV_LOG_ERROR,
"No HRD parameters for pic_timing.\n");
return AVERROR_INVALIDDATA;
}
ub(hrd->cpb_removal_delay_length_minus1 + 1, cpb_removal_delay);
ub(hrd->dpb_output_delay_length_minus1 + 1, dpb_output_delay);
}
if (sps->vui.pic_struct_present_flag) {
static const uint8_t num_clock_ts[9] = {
1, 1, 1, 2, 2, 3, 3, 2, 3
};
int i;
u(4, pic_struct, 0, 8);
if (current->pic_struct > 8)
return AVERROR_INVALIDDATA;
for (i = 0; i < num_clock_ts[current->pic_struct]; i++) {
flags(clock_timestamp_flag[i], 1, i);
if (current->clock_timestamp_flag[i])
CHECK(FUNC(sei_pic_timestamp)(ctx, rw,
&current->timestamp[i], sps));
}
}
return 0;
}
static int FUNC(sei_pan_scan_rect)(CodedBitstreamContext *ctx, RWContext *rw,
H264RawSEIPanScanRect *current)
{
int err, i;
HEADER("Pan-Scan Rectangle");
ue(pan_scan_rect_id, 0, UINT32_MAX - 1);
flag(pan_scan_rect_cancel_flag);
if (!current->pan_scan_rect_cancel_flag) {
ue(pan_scan_cnt_minus1, 0, 2);
for (i = 0; i <= current->pan_scan_cnt_minus1; i++) {
ses(pan_scan_rect_left_offset[i], INT32_MIN + 1, INT32_MAX, 1, i);
ses(pan_scan_rect_right_offset[i], INT32_MIN + 1, INT32_MAX, 1, i);
ses(pan_scan_rect_top_offset[i], INT32_MIN + 1, INT32_MAX, 1, i);
ses(pan_scan_rect_bottom_offset[i], INT32_MIN + 1, INT32_MAX, 1, i);
}
ue(pan_scan_rect_repetition_period, 0, 16384);
}
return 0;
}
static int FUNC(sei_user_data_registered)(CodedBitstreamContext *ctx, RWContext *rw,
H264RawSEIUserDataRegistered *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,
H264RawSEIUserDataUnregistered *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,
H264RawSEIRecoveryPoint *current)
{
int err;
HEADER("Recovery Point");
ue(recovery_frame_cnt, 0, 65535);
flag(exact_match_flag);
flag(broken_link_flag);
u(2, changing_slice_group_idc, 0, 2);
return 0;
}
static int FUNC(sei_display_orientation)(CodedBitstreamContext *ctx, RWContext *rw,
H264RawSEIDisplayOrientation *current)
{
int err;
HEADER("Display Orientation");
flag(display_orientation_cancel_flag);
if (!current->display_orientation_cancel_flag) {
flag(hor_flip);
flag(ver_flip);
ub(16, anticlockwise_rotation);
ue(display_orientation_repetition_period, 0, 16384);
flag(display_orientation_extension_flag);
}
return 0;
}
static int FUNC(sei_mastering_display_colour_volume)(CodedBitstreamContext *ctx, RWContext *rw,
H264RawSEIMasteringDisplayColourVolume *current)
{
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_alternative_transfer_characteristics)(CodedBitstreamContext *ctx,
RWContext *rw,
H264RawSEIAlternativeTransferCharacteristics *current)
{
int err;
HEADER("Alternative Transfer Characteristics");
ub(8, preferred_transfer_characteristics);
return 0;
}
static int FUNC(sei_payload)(CodedBitstreamContext *ctx, RWContext *rw,
H264RawSEIPayload *current)
{
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) {
case H264_SEI_TYPE_BUFFERING_PERIOD:
CHECK(FUNC(sei_buffering_period)
(ctx, rw, &current->payload.buffering_period));
break;
case H264_SEI_TYPE_PIC_TIMING:
CHECK(FUNC(sei_pic_timing)
(ctx, rw, &current->payload.pic_timing));
break;
case H264_SEI_TYPE_PAN_SCAN_RECT:
CHECK(FUNC(sei_pan_scan_rect)
(ctx, rw, &current->payload.pan_scan_rect));
break;
case H264_SEI_TYPE_FILLER_PAYLOAD:
{
for (i = 0; i < current->payload_size; i++)
fixed(8, ff_byte, 0xff);
}
break;
case H264_SEI_TYPE_USER_DATA_REGISTERED:
CHECK(FUNC(sei_user_data_registered)
(ctx, rw, &current->payload.user_data_registered, &current->payload_size));
break;
case H264_SEI_TYPE_USER_DATA_UNREGISTERED:
CHECK(FUNC(sei_user_data_unregistered)
(ctx, rw, &current->payload.user_data_unregistered, &current->payload_size));
break;
case H264_SEI_TYPE_RECOVERY_POINT:
CHECK(FUNC(sei_recovery_point)
(ctx, rw, &current->payload.recovery_point));
break;
case H264_SEI_TYPE_DISPLAY_ORIENTATION:
CHECK(FUNC(sei_display_orientation)
(ctx, rw, &current->payload.display_orientation));
break;
case H264_SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME:
CHECK(FUNC(sei_mastering_display_colour_volume)
(ctx, rw, &current->payload.mastering_display_colour_volume));
break;
case H264_SEI_TYPE_ALTERNATIVE_TRANSFER:
CHECK(FUNC(sei_alternative_transfer_characteristics)
(ctx, rw, &current->payload.alternative_transfer_characteristics));
break;
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.other.data_length; 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;
}
#else
end_position = put_bits_count(rw);
current->payload_size = (end_position - start_position) / 8;
#endif
return 0;
}
static int FUNC(sei)(CodedBitstreamContext *ctx, RWContext *rw,
H264RawSEI *current)
{
int err, k;
HEADER("Supplemental Enhancement Information");
CHECK(FUNC(nal_unit_header)(ctx, rw, &current->nal_unit_header,
1 << H264_NAL_SEI));
#ifdef READ
for (k = 0; k < H264_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, &current->payload[k]));
if (!cbs_h2645_read_more_rbsp_data(rw))
break;
}
if (k >= H264_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, &current->payload[k]));
}
}
#endif
CHECK(FUNC(rbsp_trailing_bits)(ctx, rw));
return 0;
}
static int FUNC(aud)(CodedBitstreamContext *ctx, RWContext *rw,
H264RawAUD *current)
{
int err;
HEADER("Access Unit Delimiter");
CHECK(FUNC(nal_unit_header)(ctx, rw, &current->nal_unit_header,
1 << H264_NAL_AUD));
ub(3, primary_pic_type);
CHECK(FUNC(rbsp_trailing_bits)(ctx, rw));
return 0;
}
static int FUNC(ref_pic_list_modification)(CodedBitstreamContext *ctx, RWContext *rw,
H264RawSliceHeader *current)
{
CodedBitstreamH264Context *h264 = ctx->priv_data;
const H264RawSPS *sps = h264->active_sps;
int err, i, mopn;
if (current->slice_type % 5 != 2 &&
current->slice_type % 5 != 4) {
flag(ref_pic_list_modification_flag_l0);
if (current->ref_pic_list_modification_flag_l0) {
for (i = 0; i < H264_MAX_RPLM_COUNT; i++) {
xue(modification_of_pic_nums_idc,
current->rplm_l0[i].modification_of_pic_nums_idc, 0, 3, 0);
mopn = current->rplm_l0[i].modification_of_pic_nums_idc;
if (mopn == 3)
break;
if (mopn == 0 || mopn == 1)
xue(abs_diff_pic_num_minus1,
current->rplm_l0[i].abs_diff_pic_num_minus1,
0, (1 + current->field_pic_flag) *
(1 << (sps->log2_max_frame_num_minus4 + 4)), 0);
else if (mopn == 2)
xue(long_term_pic_num,
current->rplm_l0[i].long_term_pic_num,
0, sps->max_num_ref_frames - 1, 0);
}
}
}
if (current->slice_type % 5 == 1) {
flag(ref_pic_list_modification_flag_l1);
if (current->ref_pic_list_modification_flag_l1) {
for (i = 0; i < H264_MAX_RPLM_COUNT; i++) {
xue(modification_of_pic_nums_idc,
current->rplm_l1[i].modification_of_pic_nums_idc, 0, 3, 0);
mopn = current->rplm_l1[i].modification_of_pic_nums_idc;
if (mopn == 3)
break;
if (mopn == 0 || mopn == 1)
xue(abs_diff_pic_num_minus1,
current->rplm_l1[i].abs_diff_pic_num_minus1,
0, (1 + current->field_pic_flag) *
(1 << (sps->log2_max_frame_num_minus4 + 4)), 0);
else if (mopn == 2)
xue(long_term_pic_num,
current->rplm_l1[i].long_term_pic_num,
0, sps->max_num_ref_frames - 1, 0);
}
}
}
return 0;
}
static int FUNC(pred_weight_table)(CodedBitstreamContext *ctx, RWContext *rw,
H264RawSliceHeader *current)
{
CodedBitstreamH264Context *h264 = ctx->priv_data;
const H264RawSPS *sps = h264->active_sps;
int chroma;
int err, i, j;
ue(luma_log2_weight_denom, 0, 7);
chroma = !sps->separate_colour_plane_flag && sps->chroma_format_idc != 0;
if (chroma)
ue(chroma_log2_weight_denom, 0, 7);
for (i = 0; i <= current->num_ref_idx_l0_active_minus1; i++) {
flags(luma_weight_l0_flag[i], 1, i);
if (current->luma_weight_l0_flag[i]) {
ses(luma_weight_l0[i], -128, +127, 1, i);
ses(luma_offset_l0[i], -128, +127, 1, i);
}
if (chroma) {
flags(chroma_weight_l0_flag[i], 1, i);
if (current->chroma_weight_l0_flag[i]) {
for (j = 0; j < 2; j++) {
ses(chroma_weight_l0[i][j], -128, +127, 2, i, j);
ses(chroma_offset_l0[i][j], -128, +127, 2, i, j);
}
}
}
}
if (current->slice_type % 5 == 1) {
for (i = 0; i <= current->num_ref_idx_l1_active_minus1; i++) {
flags(luma_weight_l1_flag[i], 1, i);
if (current->luma_weight_l1_flag[i]) {
ses(luma_weight_l1[i], -128, +127, 1, i);
ses(luma_offset_l1[i], -128, +127, 1, i);
}
if (chroma) {
flags(chroma_weight_l1_flag[i], 1, i);
if (current->chroma_weight_l1_flag[i]) {
for (j = 0; j < 2; j++) {
ses(chroma_weight_l1[i][j], -128, +127, 2, i, j);
ses(chroma_offset_l1[i][j], -128, +127, 2, i, j);
}
}
}
}
}
return 0;
}
static int FUNC(dec_ref_pic_marking)(CodedBitstreamContext *ctx, RWContext *rw,
H264RawSliceHeader *current, int idr_pic_flag)
{
CodedBitstreamH264Context *h264 = ctx->priv_data;
const H264RawSPS *sps = h264->active_sps;
int err, i;
uint32_t mmco;
if (idr_pic_flag) {
flag(no_output_of_prior_pics_flag);
flag(long_term_reference_flag);
} else {
flag(adaptive_ref_pic_marking_mode_flag);
if (current->adaptive_ref_pic_marking_mode_flag) {
for (i = 0; i < H264_MAX_MMCO_COUNT; i++) {
xue(memory_management_control_operation,
current->mmco[i].memory_management_control_operation,
0, 6, 0);
mmco = current->mmco[i].memory_management_control_operation;
if (mmco == 0)
break;
if (mmco == 1 || mmco == 3)
xue(difference_of_pic_nums_minus1,
current->mmco[i].difference_of_pic_nums_minus1,
0, INT32_MAX, 0);
if (mmco == 2)
xue(long_term_pic_num,
current->mmco[i].long_term_pic_num,
0, sps->max_num_ref_frames - 1, 0);
if (mmco == 3 || mmco == 6)
xue(long_term_frame_idx,
current->mmco[i].long_term_frame_idx,
0, sps->max_num_ref_frames - 1, 0);
if (mmco == 4)
xue(max_long_term_frame_idx_plus1,
current->mmco[i].max_long_term_frame_idx_plus1,
0, sps->max_num_ref_frames, 0);
}
if (i == H264_MAX_MMCO_COUNT) {
av_log(ctx->log_ctx, AV_LOG_ERROR, "Too many "
"memory management control operations.\n");
return AVERROR_INVALIDDATA;
}
}
}
return 0;
}
static int FUNC(slice_header)(CodedBitstreamContext *ctx, RWContext *rw,
H264RawSliceHeader *current)
{
CodedBitstreamH264Context *h264 = ctx->priv_data;
const H264RawSPS *sps;
const H264RawPPS *pps;
int err;
int idr_pic_flag;
int slice_type_i, slice_type_p, slice_type_b;
int slice_type_si, slice_type_sp;
HEADER("Slice Header");
CHECK(FUNC(nal_unit_header)(ctx, rw, &current->nal_unit_header,
1 << H264_NAL_SLICE |
1 << H264_NAL_IDR_SLICE |
1 << H264_NAL_AUXILIARY_SLICE));
if (current->nal_unit_header.nal_unit_type == H264_NAL_AUXILIARY_SLICE) {
if (!h264->last_slice_nal_unit_type) {
av_log(ctx->log_ctx, AV_LOG_ERROR, "Auxiliary slice "
"is not decodable without the main picture "
"in the same access unit.\n");
return AVERROR_INVALIDDATA;
}
idr_pic_flag = h264->last_slice_nal_unit_type == H264_NAL_IDR_SLICE;
} else {
idr_pic_flag = current->nal_unit_header.nal_unit_type == H264_NAL_IDR_SLICE;
}
ue(first_mb_in_slice, 0, H264_MAX_MB_PIC_SIZE - 1);
ue(slice_type, 0, 9);
slice_type_i = current->slice_type % 5 == 2;
slice_type_p = current->slice_type % 5 == 0;
slice_type_b = current->slice_type % 5 == 1;
slice_type_si = current->slice_type % 5 == 4;
slice_type_sp = current->slice_type % 5 == 3;
if (idr_pic_flag && !(slice_type_i || slice_type_si)) {
av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid slice type %d "
"for IDR picture.\n", current->slice_type);
return AVERROR_INVALIDDATA;
}
ue(pic_parameter_set_id, 0, 255);
pps = h264->pps[current->pic_parameter_set_id];
if (!pps) {
av_log(ctx->log_ctx, AV_LOG_ERROR, "PPS id %d not available.\n",
current->pic_parameter_set_id);
return AVERROR_INVALIDDATA;
}
h264->active_pps = pps;
sps = h264->sps[pps->seq_parameter_set_id];
if (!sps) {
av_log(ctx->log_ctx, AV_LOG_ERROR, "SPS id %d not available.\n",
pps->seq_parameter_set_id);
return AVERROR_INVALIDDATA;
}
h264->active_sps = sps;
if (sps->separate_colour_plane_flag)
u(2, colour_plane_id, 0, 2);
ub(sps->log2_max_frame_num_minus4 + 4, frame_num);
if (!sps->frame_mbs_only_flag) {
flag(field_pic_flag);
if (current->field_pic_flag)
flag(bottom_field_flag);
else
infer(bottom_field_flag, 0);
} else {
infer(field_pic_flag, 0);
infer(bottom_field_flag, 0);
}
if (idr_pic_flag)
ue(idr_pic_id, 0, 65535);
if (sps->pic_order_cnt_type == 0) {
ub(sps->log2_max_pic_order_cnt_lsb_minus4 + 4, pic_order_cnt_lsb);
if (pps->bottom_field_pic_order_in_frame_present_flag &&
!current->field_pic_flag)
se(delta_pic_order_cnt_bottom, INT32_MIN + 1, INT32_MAX);
} else if (sps->pic_order_cnt_type == 1) {
if (!sps->delta_pic_order_always_zero_flag) {
se(delta_pic_order_cnt[0], INT32_MIN + 1, INT32_MAX);
if (pps->bottom_field_pic_order_in_frame_present_flag &&
!current->field_pic_flag)
se(delta_pic_order_cnt[1], INT32_MIN + 1, INT32_MAX);
else
infer(delta_pic_order_cnt[1], 0);
} else {
infer(delta_pic_order_cnt[0], 0);
infer(delta_pic_order_cnt[1], 0);
}
}
if (pps->redundant_pic_cnt_present_flag)
ue(redundant_pic_cnt, 0, 127);
else
infer(redundant_pic_cnt, 0);
if (current->nal_unit_header.nal_unit_type != H264_NAL_AUXILIARY_SLICE
&& !current->redundant_pic_cnt)
h264->last_slice_nal_unit_type =
current->nal_unit_header.nal_unit_type;
if (slice_type_b)
flag(direct_spatial_mv_pred_flag);
if (slice_type_p || slice_type_sp || slice_type_b) {
flag(num_ref_idx_active_override_flag);
if (current->num_ref_idx_active_override_flag) {
ue(num_ref_idx_l0_active_minus1, 0, 31);
if (slice_type_b)
ue(num_ref_idx_l1_active_minus1, 0, 31);
} else {
infer(num_ref_idx_l0_active_minus1,
pps->num_ref_idx_l0_default_active_minus1);
infer(num_ref_idx_l1_active_minus1,
pps->num_ref_idx_l1_default_active_minus1);
}
}
if (current->nal_unit_header.nal_unit_type == 20 ||
current->nal_unit_header.nal_unit_type == 21) {
av_log(ctx->log_ctx, AV_LOG_ERROR, "MVC / 3DAVC not supported.\n");
return AVERROR_PATCHWELCOME;
} else {
CHECK(FUNC(ref_pic_list_modification)(ctx, rw, current));
}
if ((pps->weighted_pred_flag && (slice_type_p || slice_type_sp)) ||
(pps->weighted_bipred_idc == 1 && slice_type_b)) {
CHECK(FUNC(pred_weight_table)(ctx, rw, current));
}
if (current->nal_unit_header.nal_ref_idc != 0) {
CHECK(FUNC(dec_ref_pic_marking)(ctx, rw, current, idr_pic_flag));
}
if (pps->entropy_coding_mode_flag &&
!slice_type_i && !slice_type_si) {
ue(cabac_init_idc, 0, 2);
}
se(slice_qp_delta, - 51 - 6 * sps->bit_depth_luma_minus8,
+ 51 + 6 * sps->bit_depth_luma_minus8);
if (slice_type_sp || slice_type_si) {
if (slice_type_sp)
flag(sp_for_switch_flag);
se(slice_qs_delta, -51, +51);
}
if (pps->deblocking_filter_control_present_flag) {
ue(disable_deblocking_filter_idc, 0, 2);
if (current->disable_deblocking_filter_idc != 1) {
se(slice_alpha_c0_offset_div2, -6, +6);
se(slice_beta_offset_div2, -6, +6);
} else {
infer(slice_alpha_c0_offset_div2, 0);
infer(slice_beta_offset_div2, 0);
}
} else {
infer(disable_deblocking_filter_idc, 0);
infer(slice_alpha_c0_offset_div2, 0);
infer(slice_beta_offset_div2, 0);
}
if (pps->num_slice_groups_minus1 > 0 &&
pps->slice_group_map_type >= 3 &&
pps->slice_group_map_type <= 5) {
unsigned int pic_size, max, bits;
pic_size = (sps->pic_width_in_mbs_minus1 + 1) *
(sps->pic_height_in_map_units_minus1 + 1);
max = (pic_size + pps->slice_group_change_rate_minus1) /
(pps->slice_group_change_rate_minus1 + 1);
bits = av_log2(2 * max - 1);
u(bits, slice_group_change_cycle, 0, max);
}
if (pps->entropy_coding_mode_flag) {
while (byte_alignment(rw))
fixed(1, cabac_alignment_one_bit, 1);
}
return 0;
}
static int FUNC(filler)(CodedBitstreamContext *ctx, RWContext *rw,
H264RawFiller *current)
{
int err;
HEADER("Filler Data");
CHECK(FUNC(nal_unit_header)(ctx, rw, &current->nal_unit_header,
1 << H264_NAL_FILLER_DATA));
#ifdef READ
while (show_bits(rw, 8) == 0xff) {
fixed(8, ff_byte, 0xff);
++current->filler_size;
}
#else
{
uint32_t i;
for (i = 0; i < current->filler_size; i++)
fixed(8, ff_byte, 0xff);
}
#endif
CHECK(FUNC(rbsp_trailing_bits)(ctx, rw));
return 0;
}
static int FUNC(end_of_sequence)(CodedBitstreamContext *ctx, RWContext *rw,
H264RawNALUnitHeader *current)
{
HEADER("End of Sequence");
return FUNC(nal_unit_header)(ctx, rw, current,
1 << H264_NAL_END_SEQUENCE);
}
static int FUNC(end_of_stream)(CodedBitstreamContext *ctx, RWContext *rw,
H264RawNALUnitHeader *current)
{
HEADER("End of Stream");
return FUNC(nal_unit_header)(ctx, rw, current,
1 << H264_NAL_END_STREAM);
}