Update BitBuffer methods to style guide

Specifically, use reference instead of pointer for out parameter
and place the out parameter last, for the following methods

ReadUInt8
ReadUInt16
ReadUInt32
ReadBits
PeekBits
ReadNonSymmetric
ReadSignedExponentialGolomb
ReadExponentialGolomb

Bug: webrtc:11933
Change-Id: I3f1efe3e29155985277b0cd18700ddea25fe7914
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/218504
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Commit-Queue: Björn Terelius <terelius@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34037}
This commit is contained in:
Björn Terelius
2021-05-17 17:20:53 +02:00
committed by WebRTC LUCI CQ
parent 7c286c062c
commit a77e16ca2c
12 changed files with 289 additions and 261 deletions

View File

@ -28,11 +28,13 @@ const int kMaxQpValue = 51;
namespace webrtc {
#define RETURN_ON_FAIL(x, res) \
if (!(x)) { \
RTC_LOG_F(LS_ERROR) << "FAILED: " #x; \
return res; \
}
#define RETURN_ON_FAIL(x, res) \
do { \
if (!(x)) { \
RTC_LOG_F(LS_ERROR) << "FAILED: " #x; \
return res; \
} \
} while (0)
#define RETURN_INV_ON_FAIL(x) RETURN_ON_FAIL(x, kInvalidStream)
@ -62,64 +64,63 @@ H264BitstreamParser::Result H264BitstreamParser::ParseNonParameterSetNalu(
uint32_t bits_tmp;
// first_mb_in_slice: ue(v)
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp));
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(golomb_tmp));
// slice_type: ue(v)
uint32_t slice_type;
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&slice_type));
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(slice_type));
// slice_type's 5..9 range is used to indicate that all slices of a picture
// have the same value of slice_type % 5, we don't care about that, so we map
// to the corresponding 0..4 range.
slice_type %= 5;
// pic_parameter_set_id: ue(v)
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp));
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(golomb_tmp));
if (sps_->separate_colour_plane_flag == 1) {
// colour_plane_id
RETURN_INV_ON_FAIL(slice_reader.ReadBits(&bits_tmp, 2));
RETURN_INV_ON_FAIL(slice_reader.ReadBits(2, bits_tmp));
}
// frame_num: u(v)
// Represented by log2_max_frame_num bits.
RETURN_INV_ON_FAIL(
slice_reader.ReadBits(&bits_tmp, sps_->log2_max_frame_num));
RETURN_INV_ON_FAIL(slice_reader.ReadBits(sps_->log2_max_frame_num, bits_tmp));
uint32_t field_pic_flag = 0;
if (sps_->frame_mbs_only_flag == 0) {
// field_pic_flag: u(1)
RETURN_INV_ON_FAIL(slice_reader.ReadBits(&field_pic_flag, 1));
RETURN_INV_ON_FAIL(slice_reader.ReadBits(1, field_pic_flag));
if (field_pic_flag != 0) {
// bottom_field_flag: u(1)
RETURN_INV_ON_FAIL(slice_reader.ReadBits(&bits_tmp, 1));
RETURN_INV_ON_FAIL(slice_reader.ReadBits(1, bits_tmp));
}
}
if (is_idr) {
// idr_pic_id: ue(v)
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp));
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(golomb_tmp));
}
// pic_order_cnt_lsb: u(v)
// Represented by sps_.log2_max_pic_order_cnt_lsb bits.
if (sps_->pic_order_cnt_type == 0) {
RETURN_INV_ON_FAIL(
slice_reader.ReadBits(&bits_tmp, sps_->log2_max_pic_order_cnt_lsb));
slice_reader.ReadBits(sps_->log2_max_pic_order_cnt_lsb, bits_tmp));
if (pps_->bottom_field_pic_order_in_frame_present_flag &&
field_pic_flag == 0) {
// delta_pic_order_cnt_bottom: se(v)
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp));
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(golomb_tmp));
}
}
if (sps_->pic_order_cnt_type == 1 &&
!sps_->delta_pic_order_always_zero_flag) {
// delta_pic_order_cnt[0]: se(v)
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp));
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(golomb_tmp));
if (pps_->bottom_field_pic_order_in_frame_present_flag && !field_pic_flag) {
// delta_pic_order_cnt[1]: se(v)
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp));
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(golomb_tmp));
}
}
if (pps_->redundant_pic_cnt_present_flag) {
// redundant_pic_cnt: ue(v)
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp));
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(golomb_tmp));
}
if (slice_type == H264::SliceType::kB) {
// direct_spatial_mv_pred_flag: u(1)
RETURN_INV_ON_FAIL(slice_reader.ReadBits(&bits_tmp, 1));
RETURN_INV_ON_FAIL(slice_reader.ReadBits(1, bits_tmp));
}
switch (slice_type) {
case H264::SliceType::kP:
@ -128,13 +129,13 @@ H264BitstreamParser::Result H264BitstreamParser::ParseNonParameterSetNalu(
uint32_t num_ref_idx_active_override_flag;
// num_ref_idx_active_override_flag: u(1)
RETURN_INV_ON_FAIL(
slice_reader.ReadBits(&num_ref_idx_active_override_flag, 1));
slice_reader.ReadBits(1, num_ref_idx_active_override_flag));
if (num_ref_idx_active_override_flag != 0) {
// num_ref_idx_l0_active_minus1: ue(v)
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp));
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(golomb_tmp));
if (slice_type == H264::SliceType::kB) {
// num_ref_idx_l1_active_minus1: ue(v)
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp));
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(golomb_tmp));
}
}
break;
@ -158,20 +159,20 @@ H264BitstreamParser::Result H264BitstreamParser::ParseNonParameterSetNalu(
// ref_pic_list_modification_flag_l0: u(1)
uint32_t ref_pic_list_modification_flag_l0;
RETURN_INV_ON_FAIL(
slice_reader.ReadBits(&ref_pic_list_modification_flag_l0, 1));
slice_reader.ReadBits(1, ref_pic_list_modification_flag_l0));
if (ref_pic_list_modification_flag_l0) {
uint32_t modification_of_pic_nums_idc;
do {
// modification_of_pic_nums_idc: ue(v)
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(
&modification_of_pic_nums_idc));
RETURN_INV_ON_FAIL(
slice_reader.ReadExponentialGolomb(modification_of_pic_nums_idc));
if (modification_of_pic_nums_idc == 0 ||
modification_of_pic_nums_idc == 1) {
// abs_diff_pic_num_minus1: ue(v)
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp));
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(golomb_tmp));
} else if (modification_of_pic_nums_idc == 2) {
// long_term_pic_num: ue(v)
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp));
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(golomb_tmp));
}
} while (modification_of_pic_nums_idc != 3);
}
@ -180,20 +181,20 @@ H264BitstreamParser::Result H264BitstreamParser::ParseNonParameterSetNalu(
// ref_pic_list_modification_flag_l1: u(1)
uint32_t ref_pic_list_modification_flag_l1;
RETURN_INV_ON_FAIL(
slice_reader.ReadBits(&ref_pic_list_modification_flag_l1, 1));
slice_reader.ReadBits(1, ref_pic_list_modification_flag_l1));
if (ref_pic_list_modification_flag_l1) {
uint32_t modification_of_pic_nums_idc;
do {
// modification_of_pic_nums_idc: ue(v)
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(
&modification_of_pic_nums_idc));
RETURN_INV_ON_FAIL(
slice_reader.ReadExponentialGolomb(modification_of_pic_nums_idc));
if (modification_of_pic_nums_idc == 0 ||
modification_of_pic_nums_idc == 1) {
// abs_diff_pic_num_minus1: ue(v)
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp));
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(golomb_tmp));
} else if (modification_of_pic_nums_idc == 2) {
// long_term_pic_num: ue(v)
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp));
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(golomb_tmp));
}
} while (modification_of_pic_nums_idc != 3);
}
@ -215,35 +216,35 @@ H264BitstreamParser::Result H264BitstreamParser::ParseNonParameterSetNalu(
if (is_idr) {
// no_output_of_prior_pics_flag: u(1)
// long_term_reference_flag: u(1)
RETURN_INV_ON_FAIL(slice_reader.ReadBits(&bits_tmp, 2));
RETURN_INV_ON_FAIL(slice_reader.ReadBits(2, bits_tmp));
} else {
// adaptive_ref_pic_marking_mode_flag: u(1)
uint32_t adaptive_ref_pic_marking_mode_flag;
RETURN_INV_ON_FAIL(
slice_reader.ReadBits(&adaptive_ref_pic_marking_mode_flag, 1));
slice_reader.ReadBits(1, adaptive_ref_pic_marking_mode_flag));
if (adaptive_ref_pic_marking_mode_flag) {
uint32_t memory_management_control_operation;
do {
// memory_management_control_operation: ue(v)
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(
&memory_management_control_operation));
memory_management_control_operation));
if (memory_management_control_operation == 1 ||
memory_management_control_operation == 3) {
// difference_of_pic_nums_minus1: ue(v)
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp));
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(golomb_tmp));
}
if (memory_management_control_operation == 2) {
// long_term_pic_num: ue(v)
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp));
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(golomb_tmp));
}
if (memory_management_control_operation == 3 ||
memory_management_control_operation == 6) {
// long_term_frame_idx: ue(v)
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp));
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(golomb_tmp));
}
if (memory_management_control_operation == 4) {
// max_long_term_frame_idx_plus1: ue(v)
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp));
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(golomb_tmp));
}
} while (memory_management_control_operation != 0);
}
@ -252,12 +253,12 @@ H264BitstreamParser::Result H264BitstreamParser::ParseNonParameterSetNalu(
if (pps_->entropy_coding_mode_flag && slice_type != H264::SliceType::kI &&
slice_type != H264::SliceType::kSi) {
// cabac_init_idc: ue(v)
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(&golomb_tmp));
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(golomb_tmp));
}
int32_t last_slice_qp_delta;
RETURN_INV_ON_FAIL(
slice_reader.ReadSignedExponentialGolomb(&last_slice_qp_delta));
slice_reader.ReadSignedExponentialGolomb(last_slice_qp_delta));
if (abs(last_slice_qp_delta) > kMaxAbsQpDeltaValue) {
// Something has gone wrong, and the parsed value is invalid.
RTC_LOG(LS_WARNING) << "Parsed QP value out of range.";

View File

@ -18,9 +18,11 @@
#include "rtc_base/checks.h"
#define RETURN_EMPTY_ON_FAIL(x) \
if (!(x)) { \
return absl::nullopt; \
}
do { \
if (!(x)) { \
return absl::nullopt; \
} \
} while (0)
namespace {
const int kMaxPicInitQpDeltaValue = 25;
@ -64,14 +66,14 @@ absl::optional<uint32_t> PpsParser::ParsePpsIdFromSlice(const uint8_t* data,
uint32_t golomb_tmp;
// first_mb_in_slice: ue(v)
if (!slice_reader.ReadExponentialGolomb(&golomb_tmp))
if (!slice_reader.ReadExponentialGolomb(golomb_tmp))
return absl::nullopt;
// slice_type: ue(v)
if (!slice_reader.ReadExponentialGolomb(&golomb_tmp))
if (!slice_reader.ReadExponentialGolomb(golomb_tmp))
return absl::nullopt;
// pic_parameter_set_id: ue(v)
uint32_t slice_pps_id;
if (!slice_reader.ReadExponentialGolomb(&slice_pps_id))
if (!slice_reader.ReadExponentialGolomb(slice_pps_id))
return absl::nullopt;
return slice_pps_id;
}
@ -86,30 +88,29 @@ absl::optional<PpsParser::PpsState> PpsParser::ParseInternal(
uint32_t golomb_ignored;
// entropy_coding_mode_flag: u(1)
uint32_t entropy_coding_mode_flag;
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadBits(&entropy_coding_mode_flag, 1));
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadBits(1, entropy_coding_mode_flag));
pps.entropy_coding_mode_flag = entropy_coding_mode_flag != 0;
// bottom_field_pic_order_in_frame_present_flag: u(1)
uint32_t bottom_field_pic_order_in_frame_present_flag;
RETURN_EMPTY_ON_FAIL(
bit_buffer->ReadBits(&bottom_field_pic_order_in_frame_present_flag, 1));
bit_buffer->ReadBits(1, bottom_field_pic_order_in_frame_present_flag));
pps.bottom_field_pic_order_in_frame_present_flag =
bottom_field_pic_order_in_frame_present_flag != 0;
// num_slice_groups_minus1: ue(v)
uint32_t num_slice_groups_minus1;
RETURN_EMPTY_ON_FAIL(
bit_buffer->ReadExponentialGolomb(&num_slice_groups_minus1));
bit_buffer->ReadExponentialGolomb(num_slice_groups_minus1));
if (num_slice_groups_minus1 > 0) {
uint32_t slice_group_map_type;
// slice_group_map_type: ue(v)
RETURN_EMPTY_ON_FAIL(
bit_buffer->ReadExponentialGolomb(&slice_group_map_type));
bit_buffer->ReadExponentialGolomb(slice_group_map_type));
if (slice_group_map_type == 0) {
for (uint32_t i_group = 0; i_group <= num_slice_groups_minus1;
++i_group) {
// run_length_minus1[iGroup]: ue(v)
RETURN_EMPTY_ON_FAIL(
bit_buffer->ReadExponentialGolomb(&golomb_ignored));
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadExponentialGolomb(golomb_ignored));
}
} else if (slice_group_map_type == 1) {
// TODO(sprang): Implement support for dispersed slice group map type.
@ -118,23 +119,21 @@ absl::optional<PpsParser::PpsState> PpsParser::ParseInternal(
for (uint32_t i_group = 0; i_group <= num_slice_groups_minus1;
++i_group) {
// top_left[iGroup]: ue(v)
RETURN_EMPTY_ON_FAIL(
bit_buffer->ReadExponentialGolomb(&golomb_ignored));
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadExponentialGolomb(golomb_ignored));
// bottom_right[iGroup]: ue(v)
RETURN_EMPTY_ON_FAIL(
bit_buffer->ReadExponentialGolomb(&golomb_ignored));
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadExponentialGolomb(golomb_ignored));
}
} else if (slice_group_map_type == 3 || slice_group_map_type == 4 ||
slice_group_map_type == 5) {
// slice_group_change_direction_flag: u(1)
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadBits(&bits_tmp, 1));
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadBits(1, bits_tmp));
// slice_group_change_rate_minus1: ue(v)
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadExponentialGolomb(&golomb_ignored));
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadExponentialGolomb(golomb_ignored));
} else if (slice_group_map_type == 6) {
// pic_size_in_map_units_minus1: ue(v)
uint32_t pic_size_in_map_units_minus1;
RETURN_EMPTY_ON_FAIL(
bit_buffer->ReadExponentialGolomb(&pic_size_in_map_units_minus1));
bit_buffer->ReadExponentialGolomb(pic_size_in_map_units_minus1));
uint32_t slice_group_id_bits = 0;
uint32_t num_slice_groups = num_slice_groups_minus1 + 1;
// If num_slice_groups is not a power of two an additional bit is required
@ -149,39 +148,39 @@ absl::optional<PpsParser::PpsState> PpsParser::ParseInternal(
// slice_group_id[i]: u(v)
// Represented by ceil(log2(num_slice_groups_minus1 + 1)) bits.
RETURN_EMPTY_ON_FAIL(
bit_buffer->ReadBits(&bits_tmp, slice_group_id_bits));
bit_buffer->ReadBits(slice_group_id_bits, bits_tmp));
}
}
}
// num_ref_idx_l0_default_active_minus1: ue(v)
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadExponentialGolomb(&golomb_ignored));
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadExponentialGolomb(golomb_ignored));
// num_ref_idx_l1_default_active_minus1: ue(v)
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadExponentialGolomb(&golomb_ignored));
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadExponentialGolomb(golomb_ignored));
// weighted_pred_flag: u(1)
uint32_t weighted_pred_flag;
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadBits(&weighted_pred_flag, 1));
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadBits(1, weighted_pred_flag));
pps.weighted_pred_flag = weighted_pred_flag != 0;
// weighted_bipred_idc: u(2)
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadBits(&pps.weighted_bipred_idc, 2));
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadBits(2, pps.weighted_bipred_idc));
// pic_init_qp_minus26: se(v)
RETURN_EMPTY_ON_FAIL(
bit_buffer->ReadSignedExponentialGolomb(&pps.pic_init_qp_minus26));
bit_buffer->ReadSignedExponentialGolomb(pps.pic_init_qp_minus26));
// Sanity-check parsed value
if (pps.pic_init_qp_minus26 > kMaxPicInitQpDeltaValue ||
pps.pic_init_qp_minus26 < kMinPicInitQpDeltaValue) {
RETURN_EMPTY_ON_FAIL(false);
}
// pic_init_qs_minus26: se(v)
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadExponentialGolomb(&golomb_ignored));
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadExponentialGolomb(golomb_ignored));
// chroma_qp_index_offset: se(v)
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadExponentialGolomb(&golomb_ignored));
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadExponentialGolomb(golomb_ignored));
// deblocking_filter_control_present_flag: u(1)
// constrained_intra_pred_flag: u(1)
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadBits(&bits_tmp, 2));
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadBits(2, bits_tmp));
// redundant_pic_cnt_present_flag: u(1)
RETURN_EMPTY_ON_FAIL(
bit_buffer->ReadBits(&pps.redundant_pic_cnt_present_flag, 1));
bit_buffer->ReadBits(1, pps.redundant_pic_cnt_present_flag));
return pps;
}
@ -189,11 +188,15 @@ absl::optional<PpsParser::PpsState> PpsParser::ParseInternal(
bool PpsParser::ParsePpsIdsInternal(rtc::BitBuffer* bit_buffer,
uint32_t* pps_id,
uint32_t* sps_id) {
if (pps_id == nullptr)
return false;
// pic_parameter_set_id: ue(v)
if (!bit_buffer->ReadExponentialGolomb(pps_id))
if (!bit_buffer->ReadExponentialGolomb(*pps_id))
return false;
if (sps_id == nullptr)
return false;
// seq_parameter_set_id: ue(v)
if (!bit_buffer->ReadExponentialGolomb(sps_id))
if (!bit_buffer->ReadExponentialGolomb(*sps_id))
return false;
return true;
}

View File

@ -71,14 +71,14 @@ absl::optional<SpsParser::SpsState> SpsParser::ParseSpsUpToVui(
// profile_idc: u(8). We need it to determine if we need to read/skip chroma
// formats.
uint8_t profile_idc;
RETURN_EMPTY_ON_FAIL(buffer->ReadUInt8(&profile_idc));
RETURN_EMPTY_ON_FAIL(buffer->ReadUInt8(profile_idc));
// constraint_set0_flag through constraint_set5_flag + reserved_zero_2bits
// 1 bit each for the flags + 2 bits = 8 bits = 1 byte.
RETURN_EMPTY_ON_FAIL(buffer->ConsumeBytes(1));
// level_idc: u(8)
RETURN_EMPTY_ON_FAIL(buffer->ConsumeBytes(1));
// seq_parameter_set_id: ue(v)
RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(&sps.id));
RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(sps.id));
sps.separate_colour_plane_flag = 0;
// See if profile_idc has chroma format information.
if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 ||
@ -86,21 +86,20 @@ absl::optional<SpsParser::SpsState> SpsParser::ParseSpsUpToVui(
profile_idc == 86 || profile_idc == 118 || profile_idc == 128 ||
profile_idc == 138 || profile_idc == 139 || profile_idc == 134) {
// chroma_format_idc: ue(v)
RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(&chroma_format_idc));
RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(chroma_format_idc));
if (chroma_format_idc == 3) {
// separate_colour_plane_flag: u(1)
RETURN_EMPTY_ON_FAIL(
buffer->ReadBits(&sps.separate_colour_plane_flag, 1));
RETURN_EMPTY_ON_FAIL(buffer->ReadBits(1, sps.separate_colour_plane_flag));
}
// bit_depth_luma_minus8: ue(v)
RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(&golomb_ignored));
RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(golomb_ignored));
// bit_depth_chroma_minus8: ue(v)
RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(&golomb_ignored));
RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(golomb_ignored));
// qpprime_y_zero_transform_bypass_flag: u(1)
RETURN_EMPTY_ON_FAIL(buffer->ConsumeBits(1));
// seq_scaling_matrix_present_flag: u(1)
uint32_t seq_scaling_matrix_present_flag;
RETURN_EMPTY_ON_FAIL(buffer->ReadBits(&seq_scaling_matrix_present_flag, 1));
RETURN_EMPTY_ON_FAIL(buffer->ReadBits(1, seq_scaling_matrix_present_flag));
if (seq_scaling_matrix_present_flag) {
// Process the scaling lists just enough to be able to properly
// skip over them, so we can still read the resolution on streams
@ -110,7 +109,7 @@ absl::optional<SpsParser::SpsState> SpsParser::ParseSpsUpToVui(
// seq_scaling_list_present_flag[i] : u(1)
uint32_t seq_scaling_list_present_flags;
RETURN_EMPTY_ON_FAIL(
buffer->ReadBits(&seq_scaling_list_present_flags, 1));
buffer->ReadBits(1, seq_scaling_list_present_flags));
if (seq_scaling_list_present_flags != 0) {
int last_scale = 8;
int next_scale = 8;
@ -120,7 +119,7 @@ absl::optional<SpsParser::SpsState> SpsParser::ParseSpsUpToVui(
int32_t delta_scale;
// delta_scale: se(v)
RETURN_EMPTY_ON_FAIL(
buffer->ReadSignedExponentialGolomb(&delta_scale));
buffer->ReadSignedExponentialGolomb(delta_scale));
RETURN_EMPTY_ON_FAIL(delta_scale >= kScalingDeltaMin &&
delta_scale <= kScaldingDeltaMax);
next_scale = (last_scale + delta_scale + 256) % 256;
@ -140,18 +139,18 @@ absl::optional<SpsParser::SpsState> SpsParser::ParseSpsUpToVui(
// log2_max_frame_num_minus4: ue(v)
uint32_t log2_max_frame_num_minus4;
if (!buffer->ReadExponentialGolomb(&log2_max_frame_num_minus4) ||
if (!buffer->ReadExponentialGolomb(log2_max_frame_num_minus4) ||
log2_max_frame_num_minus4 > kMaxLog2Minus4) {
return OptionalSps();
}
sps.log2_max_frame_num = log2_max_frame_num_minus4 + 4;
// pic_order_cnt_type: ue(v)
RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(&sps.pic_order_cnt_type));
RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(sps.pic_order_cnt_type));
if (sps.pic_order_cnt_type == 0) {
// log2_max_pic_order_cnt_lsb_minus4: ue(v)
uint32_t log2_max_pic_order_cnt_lsb_minus4;
if (!buffer->ReadExponentialGolomb(&log2_max_pic_order_cnt_lsb_minus4) ||
if (!buffer->ReadExponentialGolomb(log2_max_pic_order_cnt_lsb_minus4) ||
log2_max_pic_order_cnt_lsb_minus4 > kMaxLog2Minus4) {
return OptionalSps();
}
@ -159,22 +158,22 @@ absl::optional<SpsParser::SpsState> SpsParser::ParseSpsUpToVui(
} else if (sps.pic_order_cnt_type == 1) {
// delta_pic_order_always_zero_flag: u(1)
RETURN_EMPTY_ON_FAIL(
buffer->ReadBits(&sps.delta_pic_order_always_zero_flag, 1));
buffer->ReadBits(1, sps.delta_pic_order_always_zero_flag));
// offset_for_non_ref_pic: se(v)
RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(&golomb_ignored));
RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(golomb_ignored));
// offset_for_top_to_bottom_field: se(v)
RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(&golomb_ignored));
RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(golomb_ignored));
// num_ref_frames_in_pic_order_cnt_cycle: ue(v)
uint32_t num_ref_frames_in_pic_order_cnt_cycle;
RETURN_EMPTY_ON_FAIL(
buffer->ReadExponentialGolomb(&num_ref_frames_in_pic_order_cnt_cycle));
buffer->ReadExponentialGolomb(num_ref_frames_in_pic_order_cnt_cycle));
for (size_t i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; ++i) {
// offset_for_ref_frame[i]: se(v)
RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(&golomb_ignored));
RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(golomb_ignored));
}
}
// max_num_ref_frames: ue(v)
RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(&sps.max_num_ref_frames));
RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(sps.max_num_ref_frames));
// gaps_in_frame_num_value_allowed_flag: u(1)
RETURN_EMPTY_ON_FAIL(buffer->ConsumeBits(1));
//
@ -185,13 +184,13 @@ absl::optional<SpsParser::SpsState> SpsParser::ParseSpsUpToVui(
//
// pic_width_in_mbs_minus1: ue(v)
uint32_t pic_width_in_mbs_minus1;
RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(&pic_width_in_mbs_minus1));
RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(pic_width_in_mbs_minus1));
// pic_height_in_map_units_minus1: ue(v)
uint32_t pic_height_in_map_units_minus1;
RETURN_EMPTY_ON_FAIL(
buffer->ReadExponentialGolomb(&pic_height_in_map_units_minus1));
buffer->ReadExponentialGolomb(pic_height_in_map_units_minus1));
// frame_mbs_only_flag: u(1)
RETURN_EMPTY_ON_FAIL(buffer->ReadBits(&sps.frame_mbs_only_flag, 1));
RETURN_EMPTY_ON_FAIL(buffer->ReadBits(1, sps.frame_mbs_only_flag));
if (!sps.frame_mbs_only_flag) {
// mb_adaptive_frame_field_flag: u(1)
RETURN_EMPTY_ON_FAIL(buffer->ConsumeBits(1));
@ -207,19 +206,18 @@ absl::optional<SpsParser::SpsState> SpsParser::ParseSpsUpToVui(
uint32_t frame_crop_right_offset = 0;
uint32_t frame_crop_top_offset = 0;
uint32_t frame_crop_bottom_offset = 0;
RETURN_EMPTY_ON_FAIL(buffer->ReadBits(&frame_cropping_flag, 1));
RETURN_EMPTY_ON_FAIL(buffer->ReadBits(1, frame_cropping_flag));
if (frame_cropping_flag) {
// frame_crop_{left, right, top, bottom}_offset: ue(v)
RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(frame_crop_left_offset));
RETURN_EMPTY_ON_FAIL(
buffer->ReadExponentialGolomb(&frame_crop_left_offset));
buffer->ReadExponentialGolomb(frame_crop_right_offset));
RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(frame_crop_top_offset));
RETURN_EMPTY_ON_FAIL(
buffer->ReadExponentialGolomb(&frame_crop_right_offset));
RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(&frame_crop_top_offset));
RETURN_EMPTY_ON_FAIL(
buffer->ReadExponentialGolomb(&frame_crop_bottom_offset));
buffer->ReadExponentialGolomb(frame_crop_bottom_offset));
}
// vui_parameters_present_flag: u(1)
RETURN_EMPTY_ON_FAIL(buffer->ReadBits(&sps.vui_params_present, 1));
RETURN_EMPTY_ON_FAIL(buffer->ReadBits(1, sps.vui_params_present));
// Far enough! We don't use the rest of the SPS.

View File

@ -45,29 +45,31 @@ enum SpsValidEvent {
kSpsRewrittenMax = 8
};
#define RETURN_FALSE_ON_FAIL(x) \
if (!(x)) { \
RTC_LOG_F(LS_ERROR) << " (line:" << __LINE__ << ") FAILED: " #x; \
return false; \
}
#define RETURN_FALSE_ON_FAIL(x) \
do { \
if (!(x)) { \
RTC_LOG_F(LS_ERROR) << " (line:" << __LINE__ << ") FAILED: " #x; \
return false; \
} \
} while (0)
#define COPY_UINT8(src, dest, tmp) \
do { \
RETURN_FALSE_ON_FAIL((src)->ReadUInt8(&tmp)); \
RETURN_FALSE_ON_FAIL((src)->ReadUInt8(tmp)); \
if (dest) \
RETURN_FALSE_ON_FAIL((dest)->WriteUInt8(tmp)); \
} while (0)
#define COPY_EXP_GOLOMB(src, dest, tmp) \
do { \
RETURN_FALSE_ON_FAIL((src)->ReadExponentialGolomb(&tmp)); \
RETURN_FALSE_ON_FAIL((src)->ReadExponentialGolomb(tmp)); \
if (dest) \
RETURN_FALSE_ON_FAIL((dest)->WriteExponentialGolomb(tmp)); \
} while (0)
#define COPY_BITS(src, dest, tmp, bits) \
do { \
RETURN_FALSE_ON_FAIL((src)->ReadBits(&tmp, bits)); \
RETURN_FALSE_ON_FAIL((src)->ReadBits(bits, tmp)); \
if (dest) \
RETURN_FALSE_ON_FAIL((dest)->WriteBits(tmp, bits)); \
} while (0)
@ -369,7 +371,7 @@ bool CopyAndRewriteVui(const SpsParser::SpsState& sps,
// bitstream_restriction_flag: u(1)
uint32_t bitstream_restriction_flag;
RETURN_FALSE_ON_FAIL(source->ReadBits(&bitstream_restriction_flag, 1));
RETURN_FALSE_ON_FAIL(source->ReadBits(1, bitstream_restriction_flag));
RETURN_FALSE_ON_FAIL(destination->WriteBits(1, 1));
if (bitstream_restriction_flag == 0) {
// We're adding one from scratch.
@ -396,9 +398,9 @@ bool CopyAndRewriteVui(const SpsParser::SpsState& sps,
// want, then we don't need to be rewriting.
uint32_t max_num_reorder_frames, max_dec_frame_buffering;
RETURN_FALSE_ON_FAIL(
source->ReadExponentialGolomb(&max_num_reorder_frames));
source->ReadExponentialGolomb(max_num_reorder_frames));
RETURN_FALSE_ON_FAIL(
source->ReadExponentialGolomb(&max_dec_frame_buffering));
source->ReadExponentialGolomb(max_dec_frame_buffering));
RETURN_FALSE_ON_FAIL(destination->WriteExponentialGolomb(0));
RETURN_FALSE_ON_FAIL(
destination->WriteExponentialGolomb(sps.max_num_ref_frames));
@ -511,15 +513,15 @@ bool CopyOrRewriteVideoSignalTypeInfo(
uint8_t colour_primaries = 3; // H264 default: unspecified
uint8_t transfer_characteristics = 3; // H264 default: unspecified
uint8_t matrix_coefficients = 3; // H264 default: unspecified
RETURN_FALSE_ON_FAIL(source->ReadBits(&video_signal_type_present_flag, 1));
RETURN_FALSE_ON_FAIL(source->ReadBits(1, video_signal_type_present_flag));
if (video_signal_type_present_flag) {
RETURN_FALSE_ON_FAIL(source->ReadBits(&video_format, 3));
RETURN_FALSE_ON_FAIL(source->ReadBits(&video_full_range_flag, 1));
RETURN_FALSE_ON_FAIL(source->ReadBits(&colour_description_present_flag, 1));
RETURN_FALSE_ON_FAIL(source->ReadBits(3, video_format));
RETURN_FALSE_ON_FAIL(source->ReadBits(1, video_full_range_flag));
RETURN_FALSE_ON_FAIL(source->ReadBits(1, colour_description_present_flag));
if (colour_description_present_flag) {
RETURN_FALSE_ON_FAIL(source->ReadUInt8(&colour_primaries));
RETURN_FALSE_ON_FAIL(source->ReadUInt8(&transfer_characteristics));
RETURN_FALSE_ON_FAIL(source->ReadUInt8(&matrix_coefficients));
RETURN_FALSE_ON_FAIL(source->ReadUInt8(colour_primaries));
RETURN_FALSE_ON_FAIL(source->ReadUInt8(transfer_characteristics));
RETURN_FALSE_ON_FAIL(source->ReadUInt8(matrix_coefficients));
}
}

View File

@ -693,7 +693,7 @@ bool FixedLengthDeltaDecoder::IsSuitableDecoderFor(const std::string& input) {
uint32_t encoding_type_bits;
const bool result =
reader.ReadBits(&encoding_type_bits, kBitsInHeaderForEncodingType);
reader.ReadBits(kBitsInHeaderForEncodingType, encoding_type_bits);
RTC_DCHECK(result);
const auto encoding_type = static_cast<EncodingType>(encoding_type_bits);
@ -729,7 +729,7 @@ std::unique_ptr<FixedLengthDeltaDecoder> FixedLengthDeltaDecoder::Create(
// Encoding type
uint32_t encoding_type_bits;
const bool result =
reader->ReadBits(&encoding_type_bits, kBitsInHeaderForEncodingType);
reader->ReadBits(kBitsInHeaderForEncodingType, encoding_type_bits);
RTC_DCHECK(result);
const EncodingType encoding = static_cast<EncodingType>(encoding_type_bits);
if (encoding != EncodingType::kFixedSizeUnsignedDeltasNoEarlyWrapNoOpt &&
@ -742,7 +742,7 @@ std::unique_ptr<FixedLengthDeltaDecoder> FixedLengthDeltaDecoder::Create(
uint32_t read_buffer;
// delta_width_bits
if (!reader->ReadBits(&read_buffer, kBitsInHeaderForDeltaWidthBits)) {
if (!reader->ReadBits(kBitsInHeaderForDeltaWidthBits, read_buffer)) {
return nullptr;
}
RTC_DCHECK_LE(read_buffer, 64 - 1); // See encoding for -1's rationale.
@ -759,20 +759,20 @@ std::unique_ptr<FixedLengthDeltaDecoder> FixedLengthDeltaDecoder::Create(
value_width_bits = kDefaultValueWidthBits;
} else {
// signed_deltas
if (!reader->ReadBits(&read_buffer, kBitsInHeaderForSignedDeltas)) {
if (!reader->ReadBits(kBitsInHeaderForSignedDeltas, read_buffer)) {
return nullptr;
}
signed_deltas = rtc::dchecked_cast<bool>(read_buffer);
// values_optional
if (!reader->ReadBits(&read_buffer, kBitsInHeaderForValuesOptional)) {
if (!reader->ReadBits(kBitsInHeaderForValuesOptional, read_buffer)) {
return nullptr;
}
RTC_DCHECK_LE(read_buffer, 1);
values_optional = rtc::dchecked_cast<bool>(read_buffer);
// value_width_bits
if (!reader->ReadBits(&read_buffer, kBitsInHeaderForValueWidthBits)) {
if (!reader->ReadBits(kBitsInHeaderForValueWidthBits, read_buffer)) {
return nullptr;
}
RTC_DCHECK_LE(read_buffer, 64 - 1); // See encoding for -1's rationale.
@ -813,7 +813,7 @@ std::vector<absl::optional<uint64_t>> FixedLengthDeltaDecoder::Decode() {
if (params_.values_optional()) {
for (size_t i = 0; i < num_of_deltas_; ++i) {
uint32_t exists;
if (!reader_->ReadBits(&exists, 1u)) {
if (!reader_->ReadBits(1u, exists)) {
RTC_LOG(LS_WARNING) << "Failed to read existence-indicating bit.";
return std::vector<absl::optional<uint64_t>>();
}
@ -877,7 +877,7 @@ bool FixedLengthDeltaDecoder::ParseDelta(uint64_t* delta) {
uint32_t higher_bits;
if (higher_bit_count > 0) {
if (!reader_->ReadBits(&higher_bits, higher_bit_count)) {
if (!reader_->ReadBits(higher_bit_count, higher_bits)) {
RTC_LOG(LS_WARNING) << "Failed to read higher half of delta.";
return false;
}
@ -885,7 +885,7 @@ bool FixedLengthDeltaDecoder::ParseDelta(uint64_t* delta) {
higher_bits = 0;
}
if (!reader_->ReadBits(&lower_bits, lower_bit_count)) {
if (!reader_->ReadBits(lower_bit_count, lower_bits)) {
RTC_LOG(LS_WARNING) << "Failed to read lower half of delta.";
return false;
}

View File

@ -64,7 +64,7 @@ size_t DecodeVarInt(rtc::BitBuffer* input, uint64_t* output) {
uint64_t decoded = 0;
for (size_t i = 0; i < kMaxVarIntLengthBytes; ++i) {
uint8_t byte;
if (!input->ReadUInt8(&byte)) {
if (!input->ReadUInt8(byte)) {
return 0;
}
decoded +=

View File

@ -47,14 +47,14 @@ RtpDependencyDescriptorReader::RtpDependencyDescriptorReader(
uint32_t RtpDependencyDescriptorReader::ReadBits(size_t bit_count) {
uint32_t value = 0;
if (!buffer_.ReadBits(&value, bit_count))
if (!buffer_.ReadBits(bit_count, value))
parsing_failed_ = true;
return value;
}
uint32_t RtpDependencyDescriptorReader::ReadNonSymmetric(size_t num_values) {
uint32_t value = 0;
if (!buffer_.ReadNonSymmetric(&value, num_values))
if (!buffer_.ReadNonSymmetric(num_values, value))
parsing_failed_ = true;
return value;
}

View File

@ -40,12 +40,12 @@ constexpr int kFailedToParse = 0;
bool ParsePictureId(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) {
uint32_t picture_id;
uint32_t m_bit;
RETURN_FALSE_ON_ERROR(parser->ReadBits(&m_bit, 1));
RETURN_FALSE_ON_ERROR(parser->ReadBits(1, m_bit));
if (m_bit) {
RETURN_FALSE_ON_ERROR(parser->ReadBits(&picture_id, 15));
RETURN_FALSE_ON_ERROR(parser->ReadBits(15, picture_id));
vp9->max_picture_id = kMaxTwoBytePictureId;
} else {
RETURN_FALSE_ON_ERROR(parser->ReadBits(&picture_id, 7));
RETURN_FALSE_ON_ERROR(parser->ReadBits(7, picture_id));
vp9->max_picture_id = kMaxOneBytePictureId;
}
vp9->picture_id = picture_id;
@ -60,10 +60,10 @@ bool ParsePictureId(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) {
//
bool ParseLayerInfoCommon(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) {
uint32_t t, u_bit, s, d_bit;
RETURN_FALSE_ON_ERROR(parser->ReadBits(&t, 3));
RETURN_FALSE_ON_ERROR(parser->ReadBits(&u_bit, 1));
RETURN_FALSE_ON_ERROR(parser->ReadBits(&s, 3));
RETURN_FALSE_ON_ERROR(parser->ReadBits(&d_bit, 1));
RETURN_FALSE_ON_ERROR(parser->ReadBits(3, t));
RETURN_FALSE_ON_ERROR(parser->ReadBits(1, u_bit));
RETURN_FALSE_ON_ERROR(parser->ReadBits(3, s));
RETURN_FALSE_ON_ERROR(parser->ReadBits(1, d_bit));
vp9->temporal_idx = t;
vp9->temporal_up_switch = u_bit ? true : false;
if (s >= kMaxSpatialLayers)
@ -84,7 +84,7 @@ bool ParseLayerInfoCommon(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) {
bool ParseLayerInfoNonFlexibleMode(rtc::BitBuffer* parser,
RTPVideoHeaderVP9* vp9) {
uint8_t tl0picidx;
RETURN_FALSE_ON_ERROR(parser->ReadUInt8(&tl0picidx));
RETURN_FALSE_ON_ERROR(parser->ReadUInt8(tl0picidx));
vp9->tl0_pic_idx = tl0picidx;
return true;
}
@ -117,8 +117,8 @@ bool ParseRefIndices(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) {
return false;
uint32_t p_diff;
RETURN_FALSE_ON_ERROR(parser->ReadBits(&p_diff, 7));
RETURN_FALSE_ON_ERROR(parser->ReadBits(&n_bit, 1));
RETURN_FALSE_ON_ERROR(parser->ReadBits(7, p_diff));
RETURN_FALSE_ON_ERROR(parser->ReadBits(1, n_bit));
vp9->pid_diff[vp9->num_ref_pics] = p_diff;
uint32_t scaled_pid = vp9->picture_id;
@ -154,9 +154,9 @@ bool ParseRefIndices(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) {
//
bool ParseSsData(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) {
uint32_t n_s, y_bit, g_bit;
RETURN_FALSE_ON_ERROR(parser->ReadBits(&n_s, 3));
RETURN_FALSE_ON_ERROR(parser->ReadBits(&y_bit, 1));
RETURN_FALSE_ON_ERROR(parser->ReadBits(&g_bit, 1));
RETURN_FALSE_ON_ERROR(parser->ReadBits(3, n_s));
RETURN_FALSE_ON_ERROR(parser->ReadBits(1, y_bit));
RETURN_FALSE_ON_ERROR(parser->ReadBits(1, g_bit));
RETURN_FALSE_ON_ERROR(parser->ConsumeBits(3));
vp9->num_spatial_layers = n_s + 1;
vp9->spatial_layer_resolution_present = y_bit ? true : false;
@ -164,20 +164,20 @@ bool ParseSsData(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) {
if (y_bit) {
for (size_t i = 0; i < vp9->num_spatial_layers; ++i) {
RETURN_FALSE_ON_ERROR(parser->ReadUInt16(&vp9->width[i]));
RETURN_FALSE_ON_ERROR(parser->ReadUInt16(&vp9->height[i]));
RETURN_FALSE_ON_ERROR(parser->ReadUInt16(vp9->width[i]));
RETURN_FALSE_ON_ERROR(parser->ReadUInt16(vp9->height[i]));
}
}
if (g_bit) {
uint8_t n_g;
RETURN_FALSE_ON_ERROR(parser->ReadUInt8(&n_g));
RETURN_FALSE_ON_ERROR(parser->ReadUInt8(n_g));
vp9->gof.num_frames_in_gof = n_g;
}
for (size_t i = 0; i < vp9->gof.num_frames_in_gof; ++i) {
uint32_t t, u_bit, r;
RETURN_FALSE_ON_ERROR(parser->ReadBits(&t, 3));
RETURN_FALSE_ON_ERROR(parser->ReadBits(&u_bit, 1));
RETURN_FALSE_ON_ERROR(parser->ReadBits(&r, 2));
RETURN_FALSE_ON_ERROR(parser->ReadBits(3, t));
RETURN_FALSE_ON_ERROR(parser->ReadBits(1, u_bit));
RETURN_FALSE_ON_ERROR(parser->ReadBits(2, r));
RETURN_FALSE_ON_ERROR(parser->ConsumeBits(2));
vp9->gof.temporal_idx[i] = t;
vp9->gof.temporal_up_switch[i] = u_bit ? true : false;
@ -185,7 +185,7 @@ bool ParseSsData(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) {
for (uint8_t p = 0; p < vp9->gof.num_ref_pics[i]; ++p) {
uint8_t p_diff;
RETURN_FALSE_ON_ERROR(parser->ReadUInt8(&p_diff));
RETURN_FALSE_ON_ERROR(parser->ReadUInt8(p_diff));
vp9->gof.pid_diff[i][p] = p_diff;
}
}
@ -214,7 +214,7 @@ int VideoRtpDepacketizerVp9::ParseRtpPayload(
// Parse mandatory first byte of payload descriptor.
rtc::BitBuffer parser(rtp_payload.data(), rtp_payload.size());
uint8_t first_byte;
if (!parser.ReadUInt8(&first_byte)) {
if (!parser.ReadUInt8(first_byte)) {
RTC_LOG(LS_ERROR) << "Payload length is zero.";
return kFailedToParse;
}

View File

@ -52,7 +52,7 @@ class BitstreamReader {
std::function<bool()> f_true,
std::function<bool()> f_false = [] { return true; }) {
uint32_t val;
if (!buffer_->ReadBits(&val, 1)) {
if (!buffer_->ReadBits(1, val)) {
return false;
}
if (val != 0) {
@ -63,7 +63,7 @@ class BitstreamReader {
absl::optional<bool> ReadBoolean() {
uint32_t val;
if (!buffer_->ReadBits(&val, 1)) {
if (!buffer_->ReadBits(1, val)) {
return {};
}
return {val != 0};
@ -76,7 +76,7 @@ class BitstreamReader {
// logged as warning, if provided.
bool VerifyNextBooleanIs(bool expected_val, absl::string_view error_msg) {
uint32_t val;
if (!buffer_->ReadBits(&val, 1)) {
if (!buffer_->ReadBits(1, val)) {
return false;
}
if ((val != 0) != expected_val) {
@ -100,7 +100,7 @@ class BitstreamReader {
RTC_DCHECK_LE(bits, 32);
RTC_DCHECK_LE(bits, sizeof(T) * 8);
uint32_t val;
if (!buffer_->ReadBits(&val, bits)) {
if (!buffer_->ReadBits(bits, val)) {
return {};
}
return (static_cast<T>(val));
@ -115,7 +115,7 @@ class BitstreamReader {
uint32_t expected_val,
absl::string_view error_msg) {
uint32_t val;
if (!buffer_->ReadBits(&val, num_bits)) {
if (!buffer_->ReadBits(num_bits, val)) {
return false;
}
if (val != expected_val) {
@ -134,11 +134,11 @@ class BitstreamReader {
template <typename T>
absl::optional<T> ReadSigned(int bits = sizeof(T) * 8) {
uint32_t sign;
if (!buffer_->ReadBits(&sign, 1)) {
if (!buffer_->ReadBits(1, sign)) {
return {};
}
uint32_t val;
if (!buffer_->ReadBits(&val, bits)) {
if (!buffer_->ReadBits(bits, val)) {
return {};
}
int64_t sign_val = val;

View File

@ -83,36 +83,36 @@ uint64_t BitBuffer::RemainingBitCount() const {
return (static_cast<uint64_t>(byte_count_) - byte_offset_) * 8 - bit_offset_;
}
bool BitBuffer::ReadUInt8(uint8_t* val) {
bool BitBuffer::ReadUInt8(uint8_t& val) {
uint32_t bit_val;
if (!ReadBits(&bit_val, sizeof(uint8_t) * 8)) {
if (!ReadBits(sizeof(uint8_t) * 8, bit_val)) {
return false;
}
RTC_DCHECK(bit_val <= std::numeric_limits<uint8_t>::max());
*val = static_cast<uint8_t>(bit_val);
val = static_cast<uint8_t>(bit_val);
return true;
}
bool BitBuffer::ReadUInt16(uint16_t* val) {
bool BitBuffer::ReadUInt16(uint16_t& val) {
uint32_t bit_val;
if (!ReadBits(&bit_val, sizeof(uint16_t) * 8)) {
if (!ReadBits(sizeof(uint16_t) * 8, bit_val)) {
return false;
}
RTC_DCHECK(bit_val <= std::numeric_limits<uint16_t>::max());
*val = static_cast<uint16_t>(bit_val);
val = static_cast<uint16_t>(bit_val);
return true;
}
bool BitBuffer::ReadUInt32(uint32_t* val) {
return ReadBits(val, sizeof(uint32_t) * 8);
bool BitBuffer::ReadUInt32(uint32_t& val) {
return ReadBits(sizeof(uint32_t) * 8, val);
}
bool BitBuffer::PeekBits(uint32_t* val, size_t bit_count) {
bool BitBuffer::PeekBits(size_t bit_count, uint32_t& val) {
// TODO(nisse): Could allow bit_count == 0 and always return success. But
// current code reads one byte beyond end of buffer in the case that
// RemainingBitCount() == 0 and bit_count == 0.
RTC_DCHECK(bit_count > 0);
if (!val || bit_count > RemainingBitCount() || bit_count > 32) {
if (bit_count > RemainingBitCount() || bit_count > 32) {
return false;
}
const uint8_t* bytes = bytes_ + byte_offset_;
@ -121,7 +121,7 @@ bool BitBuffer::PeekBits(uint32_t* val, size_t bit_count) {
// If we're reading fewer bits than what's left in the current byte, just
// return the portion of this byte that we need.
if (bit_count < remaining_bits_in_current_byte) {
*val = HighestBits(bits, bit_offset_ + bit_count);
val = HighestBits(bits, bit_offset_ + bit_count);
return true;
}
// Otherwise, subtract what we've read from the bit count and read as many
@ -137,16 +137,16 @@ bool BitBuffer::PeekBits(uint32_t* val, size_t bit_count) {
bits <<= bit_count;
bits |= HighestBits(*bytes, bit_count);
}
*val = bits;
val = bits;
return true;
}
bool BitBuffer::PeekBits(uint64_t* val, size_t bit_count) {
bool BitBuffer::PeekBits(size_t bit_count, uint64_t& val) {
// TODO(nisse): Could allow bit_count == 0 and always return success. But
// current code reads one byte beyond end of buffer in the case that
// RemainingBitCount() == 0 and bit_count == 0.
RTC_DCHECK(bit_count > 0);
if (!val || bit_count > RemainingBitCount() || bit_count > 64) {
if (bit_count > RemainingBitCount() || bit_count > 64) {
return false;
}
const uint8_t* bytes = bytes_ + byte_offset_;
@ -155,7 +155,7 @@ bool BitBuffer::PeekBits(uint64_t* val, size_t bit_count) {
// If we're reading fewer bits than what's left in the current byte, just
// return the portion of this byte that we need.
if (bit_count < remaining_bits_in_current_byte) {
*val = HighestBits(bits, bit_offset_ + bit_count);
val = HighestBits(bits, bit_offset_ + bit_count);
return true;
}
// Otherwise, subtract what we've read from the bit count and read as many
@ -171,16 +171,16 @@ bool BitBuffer::PeekBits(uint64_t* val, size_t bit_count) {
bits <<= bit_count;
bits |= HighestBits(*bytes, bit_count);
}
*val = bits;
val = bits;
return true;
}
bool BitBuffer::ReadBits(uint32_t* val, size_t bit_count) {
return PeekBits(val, bit_count) && ConsumeBits(bit_count);
bool BitBuffer::ReadBits(size_t bit_count, uint32_t& val) {
return PeekBits(bit_count, val) && ConsumeBits(bit_count);
}
bool BitBuffer::ReadBits(uint64_t* val, size_t bit_count) {
return PeekBits(val, bit_count) && ConsumeBits(bit_count);
bool BitBuffer::ReadBits(size_t bit_count, uint64_t& val) {
return PeekBits(bit_count, val) && ConsumeBits(bit_count);
}
bool BitBuffer::ConsumeBytes(size_t byte_count) {
@ -197,39 +197,36 @@ bool BitBuffer::ConsumeBits(size_t bit_count) {
return true;
}
bool BitBuffer::ReadNonSymmetric(uint32_t* val, uint32_t num_values) {
bool BitBuffer::ReadNonSymmetric(uint32_t num_values, uint32_t& val) {
RTC_DCHECK_GT(num_values, 0);
RTC_DCHECK_LE(num_values, uint32_t{1} << 31);
if (num_values == 1) {
// When there is only one possible value, it requires zero bits to store it.
// But ReadBits doesn't support reading zero bits.
*val = 0;
val = 0;
return true;
}
size_t count_bits = CountBits(num_values);
uint32_t num_min_bits_values = (uint32_t{1} << count_bits) - num_values;
if (!ReadBits(val, count_bits - 1)) {
if (!ReadBits(count_bits - 1, val)) {
return false;
}
if (*val < num_min_bits_values) {
if (val < num_min_bits_values) {
return true;
}
uint32_t extra_bit;
if (!ReadBits(&extra_bit, /*bit_count=*/1)) {
if (!ReadBits(/*bit_count=*/1, extra_bit)) {
return false;
}
*val = (*val << 1) + extra_bit - num_min_bits_values;
val = (val << 1) + extra_bit - num_min_bits_values;
return true;
}
bool BitBuffer::ReadExponentialGolomb(uint32_t* val) {
if (!val) {
return false;
}
bool BitBuffer::ReadExponentialGolomb(uint32_t& val) {
// Store off the current byte/bit offset, in case we want to restore them due
// to a failed parse.
size_t original_byte_offset = byte_offset_;
@ -238,35 +235,35 @@ bool BitBuffer::ReadExponentialGolomb(uint32_t* val) {
// Count the number of leading 0 bits by peeking/consuming them one at a time.
size_t zero_bit_count = 0;
uint32_t peeked_bit;
while (PeekBits(&peeked_bit, 1) && peeked_bit == 0) {
while (PeekBits(1, peeked_bit) && peeked_bit == 0) {
zero_bit_count++;
ConsumeBits(1);
}
// We should either be at the end of the stream, or the next bit should be 1.
RTC_DCHECK(!PeekBits(&peeked_bit, 1) || peeked_bit == 1);
RTC_DCHECK(!PeekBits(1, peeked_bit) || peeked_bit == 1);
// The bit count of the value is the number of zeros + 1. Make sure that many
// bits fits in a uint32_t and that we have enough bits left for it, and then
// read the value.
size_t value_bit_count = zero_bit_count + 1;
if (value_bit_count > 32 || !ReadBits(val, value_bit_count)) {
if (value_bit_count > 32 || !ReadBits(value_bit_count, val)) {
RTC_CHECK(Seek(original_byte_offset, original_bit_offset));
return false;
}
*val -= 1;
val -= 1;
return true;
}
bool BitBuffer::ReadSignedExponentialGolomb(int32_t* val) {
bool BitBuffer::ReadSignedExponentialGolomb(int32_t& val) {
uint32_t unsigned_val;
if (!ReadExponentialGolomb(&unsigned_val)) {
if (!ReadExponentialGolomb(unsigned_val)) {
return false;
}
if ((unsigned_val & 1) == 0) {
*val = -static_cast<int32_t>(unsigned_val / 2);
val = -static_cast<int32_t>(unsigned_val / 2);
} else {
*val = (unsigned_val + 1) / 2;
val = (unsigned_val + 1) / 2;
}
return true;
}

View File

@ -14,6 +14,7 @@
#include <stddef.h> // For size_t.
#include <stdint.h> // For integer types.
#include "absl/base/attributes.h"
#include "rtc_base/constructor_magic.h"
namespace rtc {
@ -38,20 +39,35 @@ class BitBuffer {
// Reads byte-sized values from the buffer. Returns false if there isn't
// enough data left for the specified type.
bool ReadUInt8(uint8_t* val);
bool ReadUInt16(uint16_t* val);
bool ReadUInt32(uint32_t* val);
bool ReadUInt8(uint8_t& val);
bool ReadUInt16(uint16_t& val);
bool ReadUInt32(uint32_t& val);
ABSL_DEPRECATED("") bool ReadUInt8(uint8_t* val) {
return val ? ReadUInt8(*val) : false;
}
ABSL_DEPRECATED("") bool ReadUInt16(uint16_t* val) {
return val ? ReadUInt16(*val) : false;
}
ABSL_DEPRECATED("") bool ReadUInt32(uint32_t* val) {
return val ? ReadUInt32(*val) : false;
}
// Reads bit-sized values from the buffer. Returns false if there isn't enough
// data left for the specified bit count.
bool ReadBits(uint32_t* val, size_t bit_count);
bool ReadBits(uint64_t* val, size_t bit_count);
bool ReadBits(size_t bit_count, uint32_t& val);
bool ReadBits(size_t bit_count, uint64_t& val);
ABSL_DEPRECATED("") bool ReadBits(uint32_t* val, size_t bit_count) {
return val ? ReadBits(bit_count, *val) : false;
}
// Peeks bit-sized values from the buffer. Returns false if there isn't enough
// data left for the specified number of bits. Doesn't move the current
// offset.
bool PeekBits(uint32_t* val, size_t bit_count);
bool PeekBits(uint64_t* val, size_t bit_count);
bool PeekBits(size_t bit_count, uint32_t& val);
bool PeekBits(size_t bit_count, uint64_t& val);
ABSL_DEPRECATED("") bool PeekBits(uint32_t* val, size_t bit_count) {
return val ? PeekBits(bit_count, *val) : false;
}
// Reads value in range [0, num_values - 1].
// This encoding is similar to ReadBits(val, Ceil(Log2(num_values)),
@ -63,7 +79,11 @@ class BitBuffer {
// Value v in range [k, num_values - 1] is encoded as (v+k) in n bits.
// https://aomediacodec.github.io/av1-spec/#nsn
// Returns false if there isn't enough data left.
bool ReadNonSymmetric(uint32_t* val, uint32_t num_values);
bool ReadNonSymmetric(uint32_t num_values, uint32_t& val);
ABSL_DEPRECATED("")
bool ReadNonSymmetric(uint32_t* val, uint32_t num_values) {
return val ? ReadNonSymmetric(num_values, *val) : false;
}
// Reads the exponential golomb encoded value at the current offset.
// Exponential golomb values are encoded as:
@ -73,11 +93,18 @@ class BitBuffer {
// and increment the result by 1.
// Returns false if there isn't enough data left for the specified type, or if
// the value wouldn't fit in a uint32_t.
bool ReadExponentialGolomb(uint32_t* val);
bool ReadExponentialGolomb(uint32_t& val);
ABSL_DEPRECATED("") bool ReadExponentialGolomb(uint32_t* val) {
return val ? ReadExponentialGolomb(*val) : false;
}
// Reads signed exponential golomb values at the current offset. Signed
// exponential golomb values are just the unsigned values mapped to the
// sequence 0, 1, -1, 2, -2, etc. in order.
bool ReadSignedExponentialGolomb(int32_t* val);
bool ReadSignedExponentialGolomb(int32_t& val);
ABSL_DEPRECATED("") bool ReadSignedExponentialGolomb(int32_t* val) {
return val ? ReadSignedExponentialGolomb(*val) : false;
}
// Moves current position |byte_count| bytes forward. Returns false if
// there aren't enough bytes left in the buffer.

View File

@ -49,13 +49,13 @@ TEST(BitBufferTest, ReadBytesAligned) {
uint16_t val16;
uint32_t val32;
BitBuffer buffer(bytes, 8);
EXPECT_TRUE(buffer.ReadUInt8(&val8));
EXPECT_TRUE(buffer.ReadUInt8(val8));
EXPECT_EQ(0x0Au, val8);
EXPECT_TRUE(buffer.ReadUInt8(&val8));
EXPECT_TRUE(buffer.ReadUInt8(val8));
EXPECT_EQ(0xBCu, val8);
EXPECT_TRUE(buffer.ReadUInt16(&val16));
EXPECT_TRUE(buffer.ReadUInt16(val16));
EXPECT_EQ(0xDEF1u, val16);
EXPECT_TRUE(buffer.ReadUInt32(&val32));
EXPECT_TRUE(buffer.ReadUInt32(val32));
EXPECT_EQ(0x23456789u, val32);
}
@ -68,13 +68,13 @@ TEST(BitBufferTest, ReadBytesOffset4) {
BitBuffer buffer(bytes, 9);
EXPECT_TRUE(buffer.ConsumeBits(4));
EXPECT_TRUE(buffer.ReadUInt8(&val8));
EXPECT_TRUE(buffer.ReadUInt8(val8));
EXPECT_EQ(0xABu, val8);
EXPECT_TRUE(buffer.ReadUInt8(&val8));
EXPECT_TRUE(buffer.ReadUInt8(val8));
EXPECT_EQ(0xCDu, val8);
EXPECT_TRUE(buffer.ReadUInt16(&val16));
EXPECT_TRUE(buffer.ReadUInt16(val16));
EXPECT_EQ(0xEF12u, val16);
EXPECT_TRUE(buffer.ReadUInt32(&val32));
EXPECT_TRUE(buffer.ReadUInt32(val32));
EXPECT_EQ(0x34567890u, val32);
}
@ -102,15 +102,15 @@ TEST(BitBufferTest, ReadBytesOffset3) {
uint32_t val32;
BitBuffer buffer(bytes, 8);
EXPECT_TRUE(buffer.ConsumeBits(3));
EXPECT_TRUE(buffer.ReadUInt8(&val8));
EXPECT_TRUE(buffer.ReadUInt8(val8));
EXPECT_EQ(0xFEu, val8);
EXPECT_TRUE(buffer.ReadUInt16(&val16));
EXPECT_TRUE(buffer.ReadUInt16(val16));
EXPECT_EQ(0xDCBAu, val16);
EXPECT_TRUE(buffer.ReadUInt32(&val32));
EXPECT_TRUE(buffer.ReadUInt32(val32));
EXPECT_EQ(0x98765432u, val32);
// 5 bits left unread. Not enough to read a uint8_t.
EXPECT_EQ(5u, buffer.RemainingBitCount());
EXPECT_FALSE(buffer.ReadUInt8(&val8));
EXPECT_FALSE(buffer.ReadUInt8(val8));
}
TEST(BitBufferTest, ReadBits) {
@ -120,26 +120,26 @@ TEST(BitBufferTest, ReadBits) {
const uint8_t bytes[] = {0x4D, 0x32};
uint32_t val;
BitBuffer buffer(bytes, 2);
EXPECT_TRUE(buffer.ReadBits(&val, 3));
EXPECT_TRUE(buffer.ReadBits(3, val));
// 0b010
EXPECT_EQ(0x2u, val);
EXPECT_TRUE(buffer.ReadBits(&val, 2));
EXPECT_TRUE(buffer.ReadBits(2, val));
// 0b01
EXPECT_EQ(0x1u, val);
EXPECT_TRUE(buffer.ReadBits(&val, 7));
EXPECT_TRUE(buffer.ReadBits(7, val));
// 0b1010011
EXPECT_EQ(0x53u, val);
EXPECT_TRUE(buffer.ReadBits(&val, 2));
EXPECT_TRUE(buffer.ReadBits(2, val));
// 0b00
EXPECT_EQ(0x0u, val);
EXPECT_TRUE(buffer.ReadBits(&val, 1));
EXPECT_TRUE(buffer.ReadBits(1, val));
// 0b1
EXPECT_EQ(0x1u, val);
EXPECT_TRUE(buffer.ReadBits(&val, 1));
EXPECT_TRUE(buffer.ReadBits(1, val));
// 0b0
EXPECT_EQ(0x0u, val);
EXPECT_FALSE(buffer.ReadBits(&val, 1));
EXPECT_FALSE(buffer.ReadBits(1, val));
}
TEST(BitBufferTest, ReadBits64) {
@ -149,29 +149,29 @@ TEST(BitBufferTest, ReadBits64) {
uint64_t val;
// Peek and read first 33 bits.
EXPECT_TRUE(buffer.PeekBits(&val, 33));
EXPECT_TRUE(buffer.PeekBits(33, val));
EXPECT_EQ(0x4D32AB5400FFFE01ull >> (64 - 33), val);
val = 0;
EXPECT_TRUE(buffer.ReadBits(&val, 33));
EXPECT_TRUE(buffer.ReadBits(33, val));
EXPECT_EQ(0x4D32AB5400FFFE01ull >> (64 - 33), val);
// Peek and read next 31 bits.
constexpr uint64_t kMask31Bits = (1ull << 32) - 1;
EXPECT_TRUE(buffer.PeekBits(&val, 31));
EXPECT_TRUE(buffer.PeekBits(31, val));
EXPECT_EQ(0x4D32AB5400FFFE01ull & kMask31Bits, val);
val = 0;
EXPECT_TRUE(buffer.ReadBits(&val, 31));
EXPECT_TRUE(buffer.ReadBits(31, val));
EXPECT_EQ(0x4D32AB5400FFFE01ull & kMask31Bits, val);
// Peek and read remaining 64 bits.
EXPECT_TRUE(buffer.PeekBits(&val, 64));
EXPECT_TRUE(buffer.PeekBits(64, val));
EXPECT_EQ(0xABCDEF0123456789ull, val);
val = 0;
EXPECT_TRUE(buffer.ReadBits(&val, 64));
EXPECT_TRUE(buffer.ReadBits(64, val));
EXPECT_EQ(0xABCDEF0123456789ull, val);
// Nothing more to read.
EXPECT_FALSE(buffer.ReadBits(&val, 1));
EXPECT_FALSE(buffer.ReadBits(1, val));
}
TEST(BitBufferDeathTest, SetOffsetValues) {
@ -219,10 +219,10 @@ TEST(BitBufferTest, ReadNonSymmetricSameNumberOfBitsWhenNumValuesPowerOf2) {
uint32_t values[4];
ASSERT_EQ(reader.RemainingBitCount(), 16u);
EXPECT_TRUE(reader.ReadNonSymmetric(&values[0], /*num_values=*/1 << 4));
EXPECT_TRUE(reader.ReadNonSymmetric(&values[1], /*num_values=*/1 << 4));
EXPECT_TRUE(reader.ReadNonSymmetric(&values[2], /*num_values=*/1 << 4));
EXPECT_TRUE(reader.ReadNonSymmetric(&values[3], /*num_values=*/1 << 4));
EXPECT_TRUE(reader.ReadNonSymmetric(/*num_values=*/1 << 4, values[0]));
EXPECT_TRUE(reader.ReadNonSymmetric(/*num_values=*/1 << 4, values[1]));
EXPECT_TRUE(reader.ReadNonSymmetric(/*num_values=*/1 << 4, values[2]));
EXPECT_TRUE(reader.ReadNonSymmetric(/*num_values=*/1 << 4, values[3]));
ASSERT_EQ(reader.RemainingBitCount(), 0u);
EXPECT_THAT(values, ElementsAre(0xf, 0x3, 0xa, 0x0));
@ -276,12 +276,12 @@ TEST(BitBufferWriterTest, NonSymmetricReadsMatchesWrites) {
rtc::BitBuffer reader(bytes, 2);
uint32_t values[6];
EXPECT_TRUE(reader.ReadNonSymmetric(&values[0], /*num_values=*/6));
EXPECT_TRUE(reader.ReadNonSymmetric(&values[1], /*num_values=*/6));
EXPECT_TRUE(reader.ReadNonSymmetric(&values[2], /*num_values=*/6));
EXPECT_TRUE(reader.ReadNonSymmetric(&values[3], /*num_values=*/6));
EXPECT_TRUE(reader.ReadNonSymmetric(&values[4], /*num_values=*/6));
EXPECT_TRUE(reader.ReadNonSymmetric(&values[5], /*num_values=*/6));
EXPECT_TRUE(reader.ReadNonSymmetric(/*num_values=*/6, values[0]));
EXPECT_TRUE(reader.ReadNonSymmetric(/*num_values=*/6, values[1]));
EXPECT_TRUE(reader.ReadNonSymmetric(/*num_values=*/6, values[2]));
EXPECT_TRUE(reader.ReadNonSymmetric(/*num_values=*/6, values[3]));
EXPECT_TRUE(reader.ReadNonSymmetric(/*num_values=*/6, values[4]));
EXPECT_TRUE(reader.ReadNonSymmetric(/*num_values=*/6, values[5]));
EXPECT_THAT(values, ElementsAre(0, 1, 2, 3, 4, 5));
}
@ -292,7 +292,7 @@ TEST(BitBufferTest, ReadNonSymmetricOnlyValueConsumesNoBits) {
uint32_t value = 0xFFFFFFFF;
ASSERT_EQ(reader.RemainingBitCount(), 16u);
EXPECT_TRUE(reader.ReadNonSymmetric(&value, /*num_values=*/1));
EXPECT_TRUE(reader.ReadNonSymmetric(/*num_values=*/1, value));
EXPECT_EQ(value, 0u);
EXPECT_EQ(reader.RemainingBitCount(), 16u);
@ -334,7 +334,7 @@ TEST(BitBufferTest, GolombUint32Values) {
byteBuffer.WriteUInt64(encoded_val);
uint32_t decoded_val;
EXPECT_TRUE(buffer.Seek(0, 0));
EXPECT_TRUE(buffer.ReadExponentialGolomb(&decoded_val));
EXPECT_TRUE(buffer.ReadExponentialGolomb(decoded_val));
EXPECT_EQ(i, decoded_val);
}
}
@ -351,7 +351,7 @@ TEST(BitBufferTest, SignedGolombValues) {
for (size_t i = 0; i < sizeof(golomb_bits); ++i) {
BitBuffer buffer(&golomb_bits[i], 1);
int32_t decoded_val;
ASSERT_TRUE(buffer.ReadSignedExponentialGolomb(&decoded_val));
ASSERT_TRUE(buffer.ReadSignedExponentialGolomb(decoded_val));
EXPECT_EQ(expected[i], decoded_val)
<< "Mismatch in expected/decoded value for golomb_bits[" << i
<< "]: " << static_cast<int>(golomb_bits[i]);
@ -364,13 +364,13 @@ TEST(BitBufferTest, NoGolombOverread) {
// If it didn't, the above buffer would be valid at 3 bytes.
BitBuffer buffer(bytes, 1);
uint32_t decoded_val;
EXPECT_FALSE(buffer.ReadExponentialGolomb(&decoded_val));
EXPECT_FALSE(buffer.ReadExponentialGolomb(decoded_val));
BitBuffer longer_buffer(bytes, 2);
EXPECT_FALSE(longer_buffer.ReadExponentialGolomb(&decoded_val));
EXPECT_FALSE(longer_buffer.ReadExponentialGolomb(decoded_val));
BitBuffer longest_buffer(bytes, 3);
EXPECT_TRUE(longest_buffer.ReadExponentialGolomb(&decoded_val));
EXPECT_TRUE(longest_buffer.ReadExponentialGolomb(decoded_val));
// Golomb should have read 9 bits, so 0x01FF, and since it is golomb, the
// result is 0x01FF - 1 = 0x01FE.
EXPECT_EQ(0x01FEu, decoded_val);
@ -392,20 +392,20 @@ TEST(BitBufferWriterTest, SymmetricReadWrite) {
EXPECT_TRUE(buffer.Seek(0, 0));
uint32_t val;
EXPECT_TRUE(buffer.ReadBits(&val, 3));
EXPECT_TRUE(buffer.ReadBits(3, val));
EXPECT_EQ(0x2u, val);
EXPECT_TRUE(buffer.ReadBits(&val, 2));
EXPECT_TRUE(buffer.ReadBits(2, val));
EXPECT_EQ(0x1u, val);
EXPECT_TRUE(buffer.ReadBits(&val, 7));
EXPECT_TRUE(buffer.ReadBits(7, val));
EXPECT_EQ(0x53u, val);
EXPECT_TRUE(buffer.ReadBits(&val, 2));
EXPECT_TRUE(buffer.ReadBits(2, val));
EXPECT_EQ(0x0u, val);
EXPECT_TRUE(buffer.ReadBits(&val, 1));
EXPECT_TRUE(buffer.ReadBits(1, val));
EXPECT_EQ(0x1u, val);
EXPECT_TRUE(buffer.ReadBits(&val, 17));
EXPECT_TRUE(buffer.ReadBits(17, val));
EXPECT_EQ(0x1ABCDu, val);
// And there should be nothing left.
EXPECT_FALSE(buffer.ReadBits(&val, 1));
EXPECT_FALSE(buffer.ReadBits(1, val));
}
TEST(BitBufferWriterTest, SymmetricBytesMisaligned) {
@ -422,11 +422,11 @@ TEST(BitBufferWriterTest, SymmetricBytesMisaligned) {
uint8_t val8;
uint16_t val16;
uint32_t val32;
EXPECT_TRUE(buffer.ReadUInt8(&val8));
EXPECT_TRUE(buffer.ReadUInt8(val8));
EXPECT_EQ(0x12u, val8);
EXPECT_TRUE(buffer.ReadUInt16(&val16));
EXPECT_TRUE(buffer.ReadUInt16(val16));
EXPECT_EQ(0x3456u, val16);
EXPECT_TRUE(buffer.ReadUInt32(&val32));
EXPECT_TRUE(buffer.ReadUInt32(val32));
EXPECT_EQ(0x789ABCDEu, val32);
}
@ -440,7 +440,7 @@ TEST(BitBufferWriterTest, SymmetricGolomb) {
buffer.Seek(0, 0);
for (size_t i = 0; i < arraysize(test_string); ++i) {
uint32_t val;
EXPECT_TRUE(buffer.ReadExponentialGolomb(&val));
EXPECT_TRUE(buffer.ReadExponentialGolomb(val));
EXPECT_LE(val, std::numeric_limits<uint8_t>::max());
EXPECT_EQ(test_string[i], static_cast<char>(val));
}