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:

committed by
WebRTC LUCI CQ

parent
7c286c062c
commit
a77e16ca2c
@ -28,11 +28,13 @@ const int kMaxQpValue = 51;
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
#define RETURN_ON_FAIL(x, res) \
|
#define RETURN_ON_FAIL(x, res) \
|
||||||
if (!(x)) { \
|
do { \
|
||||||
RTC_LOG_F(LS_ERROR) << "FAILED: " #x; \
|
if (!(x)) { \
|
||||||
return res; \
|
RTC_LOG_F(LS_ERROR) << "FAILED: " #x; \
|
||||||
}
|
return res; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define RETURN_INV_ON_FAIL(x) RETURN_ON_FAIL(x, kInvalidStream)
|
#define RETURN_INV_ON_FAIL(x) RETURN_ON_FAIL(x, kInvalidStream)
|
||||||
|
|
||||||
@ -62,64 +64,63 @@ H264BitstreamParser::Result H264BitstreamParser::ParseNonParameterSetNalu(
|
|||||||
uint32_t bits_tmp;
|
uint32_t bits_tmp;
|
||||||
|
|
||||||
// first_mb_in_slice: ue(v)
|
// 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)
|
// slice_type: ue(v)
|
||||||
uint32_t slice_type;
|
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
|
// 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
|
// have the same value of slice_type % 5, we don't care about that, so we map
|
||||||
// to the corresponding 0..4 range.
|
// to the corresponding 0..4 range.
|
||||||
slice_type %= 5;
|
slice_type %= 5;
|
||||||
// pic_parameter_set_id: ue(v)
|
// 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) {
|
if (sps_->separate_colour_plane_flag == 1) {
|
||||||
// colour_plane_id
|
// 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)
|
// frame_num: u(v)
|
||||||
// Represented by log2_max_frame_num bits.
|
// Represented by log2_max_frame_num bits.
|
||||||
RETURN_INV_ON_FAIL(
|
RETURN_INV_ON_FAIL(slice_reader.ReadBits(sps_->log2_max_frame_num, bits_tmp));
|
||||||
slice_reader.ReadBits(&bits_tmp, sps_->log2_max_frame_num));
|
|
||||||
uint32_t field_pic_flag = 0;
|
uint32_t field_pic_flag = 0;
|
||||||
if (sps_->frame_mbs_only_flag == 0) {
|
if (sps_->frame_mbs_only_flag == 0) {
|
||||||
// field_pic_flag: u(1)
|
// 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) {
|
if (field_pic_flag != 0) {
|
||||||
// bottom_field_flag: u(1)
|
// 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) {
|
if (is_idr) {
|
||||||
// idr_pic_id: ue(v)
|
// 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)
|
// pic_order_cnt_lsb: u(v)
|
||||||
// Represented by sps_.log2_max_pic_order_cnt_lsb bits.
|
// Represented by sps_.log2_max_pic_order_cnt_lsb bits.
|
||||||
if (sps_->pic_order_cnt_type == 0) {
|
if (sps_->pic_order_cnt_type == 0) {
|
||||||
RETURN_INV_ON_FAIL(
|
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 &&
|
if (pps_->bottom_field_pic_order_in_frame_present_flag &&
|
||||||
field_pic_flag == 0) {
|
field_pic_flag == 0) {
|
||||||
// delta_pic_order_cnt_bottom: se(v)
|
// 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 &&
|
if (sps_->pic_order_cnt_type == 1 &&
|
||||||
!sps_->delta_pic_order_always_zero_flag) {
|
!sps_->delta_pic_order_always_zero_flag) {
|
||||||
// delta_pic_order_cnt[0]: se(v)
|
// 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) {
|
if (pps_->bottom_field_pic_order_in_frame_present_flag && !field_pic_flag) {
|
||||||
// delta_pic_order_cnt[1]: se(v)
|
// 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) {
|
if (pps_->redundant_pic_cnt_present_flag) {
|
||||||
// redundant_pic_cnt: ue(v)
|
// 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) {
|
if (slice_type == H264::SliceType::kB) {
|
||||||
// direct_spatial_mv_pred_flag: u(1)
|
// 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) {
|
switch (slice_type) {
|
||||||
case H264::SliceType::kP:
|
case H264::SliceType::kP:
|
||||||
@ -128,13 +129,13 @@ H264BitstreamParser::Result H264BitstreamParser::ParseNonParameterSetNalu(
|
|||||||
uint32_t num_ref_idx_active_override_flag;
|
uint32_t num_ref_idx_active_override_flag;
|
||||||
// num_ref_idx_active_override_flag: u(1)
|
// num_ref_idx_active_override_flag: u(1)
|
||||||
RETURN_INV_ON_FAIL(
|
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) {
|
if (num_ref_idx_active_override_flag != 0) {
|
||||||
// num_ref_idx_l0_active_minus1: ue(v)
|
// 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) {
|
if (slice_type == H264::SliceType::kB) {
|
||||||
// num_ref_idx_l1_active_minus1: ue(v)
|
// 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;
|
break;
|
||||||
@ -158,20 +159,20 @@ H264BitstreamParser::Result H264BitstreamParser::ParseNonParameterSetNalu(
|
|||||||
// ref_pic_list_modification_flag_l0: u(1)
|
// ref_pic_list_modification_flag_l0: u(1)
|
||||||
uint32_t ref_pic_list_modification_flag_l0;
|
uint32_t ref_pic_list_modification_flag_l0;
|
||||||
RETURN_INV_ON_FAIL(
|
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) {
|
if (ref_pic_list_modification_flag_l0) {
|
||||||
uint32_t modification_of_pic_nums_idc;
|
uint32_t modification_of_pic_nums_idc;
|
||||||
do {
|
do {
|
||||||
// modification_of_pic_nums_idc: ue(v)
|
// modification_of_pic_nums_idc: ue(v)
|
||||||
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(
|
RETURN_INV_ON_FAIL(
|
||||||
&modification_of_pic_nums_idc));
|
slice_reader.ReadExponentialGolomb(modification_of_pic_nums_idc));
|
||||||
if (modification_of_pic_nums_idc == 0 ||
|
if (modification_of_pic_nums_idc == 0 ||
|
||||||
modification_of_pic_nums_idc == 1) {
|
modification_of_pic_nums_idc == 1) {
|
||||||
// abs_diff_pic_num_minus1: ue(v)
|
// 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) {
|
} else if (modification_of_pic_nums_idc == 2) {
|
||||||
// long_term_pic_num: ue(v)
|
// 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);
|
} while (modification_of_pic_nums_idc != 3);
|
||||||
}
|
}
|
||||||
@ -180,20 +181,20 @@ H264BitstreamParser::Result H264BitstreamParser::ParseNonParameterSetNalu(
|
|||||||
// ref_pic_list_modification_flag_l1: u(1)
|
// ref_pic_list_modification_flag_l1: u(1)
|
||||||
uint32_t ref_pic_list_modification_flag_l1;
|
uint32_t ref_pic_list_modification_flag_l1;
|
||||||
RETURN_INV_ON_FAIL(
|
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) {
|
if (ref_pic_list_modification_flag_l1) {
|
||||||
uint32_t modification_of_pic_nums_idc;
|
uint32_t modification_of_pic_nums_idc;
|
||||||
do {
|
do {
|
||||||
// modification_of_pic_nums_idc: ue(v)
|
// modification_of_pic_nums_idc: ue(v)
|
||||||
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(
|
RETURN_INV_ON_FAIL(
|
||||||
&modification_of_pic_nums_idc));
|
slice_reader.ReadExponentialGolomb(modification_of_pic_nums_idc));
|
||||||
if (modification_of_pic_nums_idc == 0 ||
|
if (modification_of_pic_nums_idc == 0 ||
|
||||||
modification_of_pic_nums_idc == 1) {
|
modification_of_pic_nums_idc == 1) {
|
||||||
// abs_diff_pic_num_minus1: ue(v)
|
// 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) {
|
} else if (modification_of_pic_nums_idc == 2) {
|
||||||
// long_term_pic_num: ue(v)
|
// 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);
|
} while (modification_of_pic_nums_idc != 3);
|
||||||
}
|
}
|
||||||
@ -215,35 +216,35 @@ H264BitstreamParser::Result H264BitstreamParser::ParseNonParameterSetNalu(
|
|||||||
if (is_idr) {
|
if (is_idr) {
|
||||||
// no_output_of_prior_pics_flag: u(1)
|
// no_output_of_prior_pics_flag: u(1)
|
||||||
// long_term_reference_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 {
|
} else {
|
||||||
// adaptive_ref_pic_marking_mode_flag: u(1)
|
// adaptive_ref_pic_marking_mode_flag: u(1)
|
||||||
uint32_t adaptive_ref_pic_marking_mode_flag;
|
uint32_t adaptive_ref_pic_marking_mode_flag;
|
||||||
RETURN_INV_ON_FAIL(
|
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) {
|
if (adaptive_ref_pic_marking_mode_flag) {
|
||||||
uint32_t memory_management_control_operation;
|
uint32_t memory_management_control_operation;
|
||||||
do {
|
do {
|
||||||
// memory_management_control_operation: ue(v)
|
// memory_management_control_operation: ue(v)
|
||||||
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(
|
RETURN_INV_ON_FAIL(slice_reader.ReadExponentialGolomb(
|
||||||
&memory_management_control_operation));
|
memory_management_control_operation));
|
||||||
if (memory_management_control_operation == 1 ||
|
if (memory_management_control_operation == 1 ||
|
||||||
memory_management_control_operation == 3) {
|
memory_management_control_operation == 3) {
|
||||||
// difference_of_pic_nums_minus1: ue(v)
|
// 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) {
|
if (memory_management_control_operation == 2) {
|
||||||
// long_term_pic_num: ue(v)
|
// 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 ||
|
if (memory_management_control_operation == 3 ||
|
||||||
memory_management_control_operation == 6) {
|
memory_management_control_operation == 6) {
|
||||||
// long_term_frame_idx: ue(v)
|
// 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) {
|
if (memory_management_control_operation == 4) {
|
||||||
// max_long_term_frame_idx_plus1: ue(v)
|
// 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);
|
} 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 &&
|
if (pps_->entropy_coding_mode_flag && slice_type != H264::SliceType::kI &&
|
||||||
slice_type != H264::SliceType::kSi) {
|
slice_type != H264::SliceType::kSi) {
|
||||||
// cabac_init_idc: ue(v)
|
// 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;
|
int32_t last_slice_qp_delta;
|
||||||
RETURN_INV_ON_FAIL(
|
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) {
|
if (abs(last_slice_qp_delta) > kMaxAbsQpDeltaValue) {
|
||||||
// Something has gone wrong, and the parsed value is invalid.
|
// Something has gone wrong, and the parsed value is invalid.
|
||||||
RTC_LOG(LS_WARNING) << "Parsed QP value out of range.";
|
RTC_LOG(LS_WARNING) << "Parsed QP value out of range.";
|
||||||
|
@ -18,9 +18,11 @@
|
|||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
|
|
||||||
#define RETURN_EMPTY_ON_FAIL(x) \
|
#define RETURN_EMPTY_ON_FAIL(x) \
|
||||||
if (!(x)) { \
|
do { \
|
||||||
return absl::nullopt; \
|
if (!(x)) { \
|
||||||
}
|
return absl::nullopt; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const int kMaxPicInitQpDeltaValue = 25;
|
const int kMaxPicInitQpDeltaValue = 25;
|
||||||
@ -64,14 +66,14 @@ absl::optional<uint32_t> PpsParser::ParsePpsIdFromSlice(const uint8_t* data,
|
|||||||
|
|
||||||
uint32_t golomb_tmp;
|
uint32_t golomb_tmp;
|
||||||
// first_mb_in_slice: ue(v)
|
// first_mb_in_slice: ue(v)
|
||||||
if (!slice_reader.ReadExponentialGolomb(&golomb_tmp))
|
if (!slice_reader.ReadExponentialGolomb(golomb_tmp))
|
||||||
return absl::nullopt;
|
return absl::nullopt;
|
||||||
// slice_type: ue(v)
|
// slice_type: ue(v)
|
||||||
if (!slice_reader.ReadExponentialGolomb(&golomb_tmp))
|
if (!slice_reader.ReadExponentialGolomb(golomb_tmp))
|
||||||
return absl::nullopt;
|
return absl::nullopt;
|
||||||
// pic_parameter_set_id: ue(v)
|
// pic_parameter_set_id: ue(v)
|
||||||
uint32_t slice_pps_id;
|
uint32_t slice_pps_id;
|
||||||
if (!slice_reader.ReadExponentialGolomb(&slice_pps_id))
|
if (!slice_reader.ReadExponentialGolomb(slice_pps_id))
|
||||||
return absl::nullopt;
|
return absl::nullopt;
|
||||||
return slice_pps_id;
|
return slice_pps_id;
|
||||||
}
|
}
|
||||||
@ -86,30 +88,29 @@ absl::optional<PpsParser::PpsState> PpsParser::ParseInternal(
|
|||||||
uint32_t golomb_ignored;
|
uint32_t golomb_ignored;
|
||||||
// entropy_coding_mode_flag: u(1)
|
// entropy_coding_mode_flag: u(1)
|
||||||
uint32_t entropy_coding_mode_flag;
|
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;
|
pps.entropy_coding_mode_flag = entropy_coding_mode_flag != 0;
|
||||||
// bottom_field_pic_order_in_frame_present_flag: u(1)
|
// bottom_field_pic_order_in_frame_present_flag: u(1)
|
||||||
uint32_t bottom_field_pic_order_in_frame_present_flag;
|
uint32_t bottom_field_pic_order_in_frame_present_flag;
|
||||||
RETURN_EMPTY_ON_FAIL(
|
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 =
|
pps.bottom_field_pic_order_in_frame_present_flag =
|
||||||
bottom_field_pic_order_in_frame_present_flag != 0;
|
bottom_field_pic_order_in_frame_present_flag != 0;
|
||||||
|
|
||||||
// num_slice_groups_minus1: ue(v)
|
// num_slice_groups_minus1: ue(v)
|
||||||
uint32_t num_slice_groups_minus1;
|
uint32_t num_slice_groups_minus1;
|
||||||
RETURN_EMPTY_ON_FAIL(
|
RETURN_EMPTY_ON_FAIL(
|
||||||
bit_buffer->ReadExponentialGolomb(&num_slice_groups_minus1));
|
bit_buffer->ReadExponentialGolomb(num_slice_groups_minus1));
|
||||||
if (num_slice_groups_minus1 > 0) {
|
if (num_slice_groups_minus1 > 0) {
|
||||||
uint32_t slice_group_map_type;
|
uint32_t slice_group_map_type;
|
||||||
// slice_group_map_type: ue(v)
|
// slice_group_map_type: ue(v)
|
||||||
RETURN_EMPTY_ON_FAIL(
|
RETURN_EMPTY_ON_FAIL(
|
||||||
bit_buffer->ReadExponentialGolomb(&slice_group_map_type));
|
bit_buffer->ReadExponentialGolomb(slice_group_map_type));
|
||||||
if (slice_group_map_type == 0) {
|
if (slice_group_map_type == 0) {
|
||||||
for (uint32_t i_group = 0; i_group <= num_slice_groups_minus1;
|
for (uint32_t i_group = 0; i_group <= num_slice_groups_minus1;
|
||||||
++i_group) {
|
++i_group) {
|
||||||
// run_length_minus1[iGroup]: ue(v)
|
// run_length_minus1[iGroup]: ue(v)
|
||||||
RETURN_EMPTY_ON_FAIL(
|
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadExponentialGolomb(golomb_ignored));
|
||||||
bit_buffer->ReadExponentialGolomb(&golomb_ignored));
|
|
||||||
}
|
}
|
||||||
} else if (slice_group_map_type == 1) {
|
} else if (slice_group_map_type == 1) {
|
||||||
// TODO(sprang): Implement support for dispersed slice group map type.
|
// 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;
|
for (uint32_t i_group = 0; i_group <= num_slice_groups_minus1;
|
||||||
++i_group) {
|
++i_group) {
|
||||||
// top_left[iGroup]: ue(v)
|
// top_left[iGroup]: ue(v)
|
||||||
RETURN_EMPTY_ON_FAIL(
|
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadExponentialGolomb(golomb_ignored));
|
||||||
bit_buffer->ReadExponentialGolomb(&golomb_ignored));
|
|
||||||
// bottom_right[iGroup]: ue(v)
|
// bottom_right[iGroup]: ue(v)
|
||||||
RETURN_EMPTY_ON_FAIL(
|
RETURN_EMPTY_ON_FAIL(bit_buffer->ReadExponentialGolomb(golomb_ignored));
|
||||||
bit_buffer->ReadExponentialGolomb(&golomb_ignored));
|
|
||||||
}
|
}
|
||||||
} else if (slice_group_map_type == 3 || slice_group_map_type == 4 ||
|
} else if (slice_group_map_type == 3 || slice_group_map_type == 4 ||
|
||||||
slice_group_map_type == 5) {
|
slice_group_map_type == 5) {
|
||||||
// slice_group_change_direction_flag: u(1)
|
// 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)
|
// 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) {
|
} else if (slice_group_map_type == 6) {
|
||||||
// pic_size_in_map_units_minus1: ue(v)
|
// pic_size_in_map_units_minus1: ue(v)
|
||||||
uint32_t pic_size_in_map_units_minus1;
|
uint32_t pic_size_in_map_units_minus1;
|
||||||
RETURN_EMPTY_ON_FAIL(
|
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 slice_group_id_bits = 0;
|
||||||
uint32_t num_slice_groups = num_slice_groups_minus1 + 1;
|
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
|
// 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)
|
// slice_group_id[i]: u(v)
|
||||||
// Represented by ceil(log2(num_slice_groups_minus1 + 1)) bits.
|
// Represented by ceil(log2(num_slice_groups_minus1 + 1)) bits.
|
||||||
RETURN_EMPTY_ON_FAIL(
|
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)
|
// 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)
|
// 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)
|
// weighted_pred_flag: u(1)
|
||||||
uint32_t weighted_pred_flag;
|
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;
|
pps.weighted_pred_flag = weighted_pred_flag != 0;
|
||||||
// weighted_bipred_idc: u(2)
|
// 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)
|
// pic_init_qp_minus26: se(v)
|
||||||
RETURN_EMPTY_ON_FAIL(
|
RETURN_EMPTY_ON_FAIL(
|
||||||
bit_buffer->ReadSignedExponentialGolomb(&pps.pic_init_qp_minus26));
|
bit_buffer->ReadSignedExponentialGolomb(pps.pic_init_qp_minus26));
|
||||||
// Sanity-check parsed value
|
// Sanity-check parsed value
|
||||||
if (pps.pic_init_qp_minus26 > kMaxPicInitQpDeltaValue ||
|
if (pps.pic_init_qp_minus26 > kMaxPicInitQpDeltaValue ||
|
||||||
pps.pic_init_qp_minus26 < kMinPicInitQpDeltaValue) {
|
pps.pic_init_qp_minus26 < kMinPicInitQpDeltaValue) {
|
||||||
RETURN_EMPTY_ON_FAIL(false);
|
RETURN_EMPTY_ON_FAIL(false);
|
||||||
}
|
}
|
||||||
// pic_init_qs_minus26: se(v)
|
// 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)
|
// 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)
|
// deblocking_filter_control_present_flag: u(1)
|
||||||
// constrained_intra_pred_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)
|
// redundant_pic_cnt_present_flag: u(1)
|
||||||
RETURN_EMPTY_ON_FAIL(
|
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;
|
return pps;
|
||||||
}
|
}
|
||||||
@ -189,11 +188,15 @@ absl::optional<PpsParser::PpsState> PpsParser::ParseInternal(
|
|||||||
bool PpsParser::ParsePpsIdsInternal(rtc::BitBuffer* bit_buffer,
|
bool PpsParser::ParsePpsIdsInternal(rtc::BitBuffer* bit_buffer,
|
||||||
uint32_t* pps_id,
|
uint32_t* pps_id,
|
||||||
uint32_t* sps_id) {
|
uint32_t* sps_id) {
|
||||||
|
if (pps_id == nullptr)
|
||||||
|
return false;
|
||||||
// pic_parameter_set_id: ue(v)
|
// 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;
|
return false;
|
||||||
// seq_parameter_set_id: ue(v)
|
// seq_parameter_set_id: ue(v)
|
||||||
if (!bit_buffer->ReadExponentialGolomb(sps_id))
|
if (!bit_buffer->ReadExponentialGolomb(*sps_id))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -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
|
// profile_idc: u(8). We need it to determine if we need to read/skip chroma
|
||||||
// formats.
|
// formats.
|
||||||
uint8_t profile_idc;
|
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
|
// constraint_set0_flag through constraint_set5_flag + reserved_zero_2bits
|
||||||
// 1 bit each for the flags + 2 bits = 8 bits = 1 byte.
|
// 1 bit each for the flags + 2 bits = 8 bits = 1 byte.
|
||||||
RETURN_EMPTY_ON_FAIL(buffer->ConsumeBytes(1));
|
RETURN_EMPTY_ON_FAIL(buffer->ConsumeBytes(1));
|
||||||
// level_idc: u(8)
|
// level_idc: u(8)
|
||||||
RETURN_EMPTY_ON_FAIL(buffer->ConsumeBytes(1));
|
RETURN_EMPTY_ON_FAIL(buffer->ConsumeBytes(1));
|
||||||
// seq_parameter_set_id: ue(v)
|
// 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;
|
sps.separate_colour_plane_flag = 0;
|
||||||
// See if profile_idc has chroma format information.
|
// See if profile_idc has chroma format information.
|
||||||
if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 ||
|
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 == 86 || profile_idc == 118 || profile_idc == 128 ||
|
||||||
profile_idc == 138 || profile_idc == 139 || profile_idc == 134) {
|
profile_idc == 138 || profile_idc == 139 || profile_idc == 134) {
|
||||||
// chroma_format_idc: ue(v)
|
// 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) {
|
if (chroma_format_idc == 3) {
|
||||||
// separate_colour_plane_flag: u(1)
|
// separate_colour_plane_flag: u(1)
|
||||||
RETURN_EMPTY_ON_FAIL(
|
RETURN_EMPTY_ON_FAIL(buffer->ReadBits(1, sps.separate_colour_plane_flag));
|
||||||
buffer->ReadBits(&sps.separate_colour_plane_flag, 1));
|
|
||||||
}
|
}
|
||||||
// bit_depth_luma_minus8: ue(v)
|
// 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)
|
// 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)
|
// qpprime_y_zero_transform_bypass_flag: u(1)
|
||||||
RETURN_EMPTY_ON_FAIL(buffer->ConsumeBits(1));
|
RETURN_EMPTY_ON_FAIL(buffer->ConsumeBits(1));
|
||||||
// seq_scaling_matrix_present_flag: u(1)
|
// seq_scaling_matrix_present_flag: u(1)
|
||||||
uint32_t seq_scaling_matrix_present_flag;
|
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) {
|
if (seq_scaling_matrix_present_flag) {
|
||||||
// Process the scaling lists just enough to be able to properly
|
// Process the scaling lists just enough to be able to properly
|
||||||
// skip over them, so we can still read the resolution on streams
|
// 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)
|
// seq_scaling_list_present_flag[i] : u(1)
|
||||||
uint32_t seq_scaling_list_present_flags;
|
uint32_t seq_scaling_list_present_flags;
|
||||||
RETURN_EMPTY_ON_FAIL(
|
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) {
|
if (seq_scaling_list_present_flags != 0) {
|
||||||
int last_scale = 8;
|
int last_scale = 8;
|
||||||
int next_scale = 8;
|
int next_scale = 8;
|
||||||
@ -120,7 +119,7 @@ absl::optional<SpsParser::SpsState> SpsParser::ParseSpsUpToVui(
|
|||||||
int32_t delta_scale;
|
int32_t delta_scale;
|
||||||
// delta_scale: se(v)
|
// delta_scale: se(v)
|
||||||
RETURN_EMPTY_ON_FAIL(
|
RETURN_EMPTY_ON_FAIL(
|
||||||
buffer->ReadSignedExponentialGolomb(&delta_scale));
|
buffer->ReadSignedExponentialGolomb(delta_scale));
|
||||||
RETURN_EMPTY_ON_FAIL(delta_scale >= kScalingDeltaMin &&
|
RETURN_EMPTY_ON_FAIL(delta_scale >= kScalingDeltaMin &&
|
||||||
delta_scale <= kScaldingDeltaMax);
|
delta_scale <= kScaldingDeltaMax);
|
||||||
next_scale = (last_scale + delta_scale + 256) % 256;
|
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)
|
// log2_max_frame_num_minus4: ue(v)
|
||||||
uint32_t log2_max_frame_num_minus4;
|
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) {
|
log2_max_frame_num_minus4 > kMaxLog2Minus4) {
|
||||||
return OptionalSps();
|
return OptionalSps();
|
||||||
}
|
}
|
||||||
sps.log2_max_frame_num = log2_max_frame_num_minus4 + 4;
|
sps.log2_max_frame_num = log2_max_frame_num_minus4 + 4;
|
||||||
|
|
||||||
// pic_order_cnt_type: ue(v)
|
// 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) {
|
if (sps.pic_order_cnt_type == 0) {
|
||||||
// log2_max_pic_order_cnt_lsb_minus4: ue(v)
|
// log2_max_pic_order_cnt_lsb_minus4: ue(v)
|
||||||
uint32_t log2_max_pic_order_cnt_lsb_minus4;
|
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) {
|
log2_max_pic_order_cnt_lsb_minus4 > kMaxLog2Minus4) {
|
||||||
return OptionalSps();
|
return OptionalSps();
|
||||||
}
|
}
|
||||||
@ -159,22 +158,22 @@ absl::optional<SpsParser::SpsState> SpsParser::ParseSpsUpToVui(
|
|||||||
} else if (sps.pic_order_cnt_type == 1) {
|
} else if (sps.pic_order_cnt_type == 1) {
|
||||||
// delta_pic_order_always_zero_flag: u(1)
|
// delta_pic_order_always_zero_flag: u(1)
|
||||||
RETURN_EMPTY_ON_FAIL(
|
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)
|
// 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)
|
// 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)
|
// num_ref_frames_in_pic_order_cnt_cycle: ue(v)
|
||||||
uint32_t num_ref_frames_in_pic_order_cnt_cycle;
|
uint32_t num_ref_frames_in_pic_order_cnt_cycle;
|
||||||
RETURN_EMPTY_ON_FAIL(
|
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) {
|
for (size_t i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; ++i) {
|
||||||
// offset_for_ref_frame[i]: se(v)
|
// 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)
|
// 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)
|
// gaps_in_frame_num_value_allowed_flag: u(1)
|
||||||
RETURN_EMPTY_ON_FAIL(buffer->ConsumeBits(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)
|
// pic_width_in_mbs_minus1: ue(v)
|
||||||
uint32_t pic_width_in_mbs_minus1;
|
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)
|
// pic_height_in_map_units_minus1: ue(v)
|
||||||
uint32_t pic_height_in_map_units_minus1;
|
uint32_t pic_height_in_map_units_minus1;
|
||||||
RETURN_EMPTY_ON_FAIL(
|
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)
|
// 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) {
|
if (!sps.frame_mbs_only_flag) {
|
||||||
// mb_adaptive_frame_field_flag: u(1)
|
// mb_adaptive_frame_field_flag: u(1)
|
||||||
RETURN_EMPTY_ON_FAIL(buffer->ConsumeBits(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_right_offset = 0;
|
||||||
uint32_t frame_crop_top_offset = 0;
|
uint32_t frame_crop_top_offset = 0;
|
||||||
uint32_t frame_crop_bottom_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) {
|
if (frame_cropping_flag) {
|
||||||
// frame_crop_{left, right, top, bottom}_offset: ue(v)
|
// frame_crop_{left, right, top, bottom}_offset: ue(v)
|
||||||
|
RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(frame_crop_left_offset));
|
||||||
RETURN_EMPTY_ON_FAIL(
|
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(
|
RETURN_EMPTY_ON_FAIL(
|
||||||
buffer->ReadExponentialGolomb(&frame_crop_right_offset));
|
buffer->ReadExponentialGolomb(frame_crop_bottom_offset));
|
||||||
RETURN_EMPTY_ON_FAIL(buffer->ReadExponentialGolomb(&frame_crop_top_offset));
|
|
||||||
RETURN_EMPTY_ON_FAIL(
|
|
||||||
buffer->ReadExponentialGolomb(&frame_crop_bottom_offset));
|
|
||||||
}
|
}
|
||||||
// vui_parameters_present_flag: u(1)
|
// 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.
|
// Far enough! We don't use the rest of the SPS.
|
||||||
|
|
||||||
|
@ -45,29 +45,31 @@ enum SpsValidEvent {
|
|||||||
kSpsRewrittenMax = 8
|
kSpsRewrittenMax = 8
|
||||||
};
|
};
|
||||||
|
|
||||||
#define RETURN_FALSE_ON_FAIL(x) \
|
#define RETURN_FALSE_ON_FAIL(x) \
|
||||||
if (!(x)) { \
|
do { \
|
||||||
RTC_LOG_F(LS_ERROR) << " (line:" << __LINE__ << ") FAILED: " #x; \
|
if (!(x)) { \
|
||||||
return false; \
|
RTC_LOG_F(LS_ERROR) << " (line:" << __LINE__ << ") FAILED: " #x; \
|
||||||
}
|
return false; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define COPY_UINT8(src, dest, tmp) \
|
#define COPY_UINT8(src, dest, tmp) \
|
||||||
do { \
|
do { \
|
||||||
RETURN_FALSE_ON_FAIL((src)->ReadUInt8(&tmp)); \
|
RETURN_FALSE_ON_FAIL((src)->ReadUInt8(tmp)); \
|
||||||
if (dest) \
|
if (dest) \
|
||||||
RETURN_FALSE_ON_FAIL((dest)->WriteUInt8(tmp)); \
|
RETURN_FALSE_ON_FAIL((dest)->WriteUInt8(tmp)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define COPY_EXP_GOLOMB(src, dest, tmp) \
|
#define COPY_EXP_GOLOMB(src, dest, tmp) \
|
||||||
do { \
|
do { \
|
||||||
RETURN_FALSE_ON_FAIL((src)->ReadExponentialGolomb(&tmp)); \
|
RETURN_FALSE_ON_FAIL((src)->ReadExponentialGolomb(tmp)); \
|
||||||
if (dest) \
|
if (dest) \
|
||||||
RETURN_FALSE_ON_FAIL((dest)->WriteExponentialGolomb(tmp)); \
|
RETURN_FALSE_ON_FAIL((dest)->WriteExponentialGolomb(tmp)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define COPY_BITS(src, dest, tmp, bits) \
|
#define COPY_BITS(src, dest, tmp, bits) \
|
||||||
do { \
|
do { \
|
||||||
RETURN_FALSE_ON_FAIL((src)->ReadBits(&tmp, bits)); \
|
RETURN_FALSE_ON_FAIL((src)->ReadBits(bits, tmp)); \
|
||||||
if (dest) \
|
if (dest) \
|
||||||
RETURN_FALSE_ON_FAIL((dest)->WriteBits(tmp, bits)); \
|
RETURN_FALSE_ON_FAIL((dest)->WriteBits(tmp, bits)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
@ -369,7 +371,7 @@ bool CopyAndRewriteVui(const SpsParser::SpsState& sps,
|
|||||||
|
|
||||||
// bitstream_restriction_flag: u(1)
|
// bitstream_restriction_flag: u(1)
|
||||||
uint32_t bitstream_restriction_flag;
|
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));
|
RETURN_FALSE_ON_FAIL(destination->WriteBits(1, 1));
|
||||||
if (bitstream_restriction_flag == 0) {
|
if (bitstream_restriction_flag == 0) {
|
||||||
// We're adding one from scratch.
|
// 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.
|
// want, then we don't need to be rewriting.
|
||||||
uint32_t max_num_reorder_frames, max_dec_frame_buffering;
|
uint32_t max_num_reorder_frames, max_dec_frame_buffering;
|
||||||
RETURN_FALSE_ON_FAIL(
|
RETURN_FALSE_ON_FAIL(
|
||||||
source->ReadExponentialGolomb(&max_num_reorder_frames));
|
source->ReadExponentialGolomb(max_num_reorder_frames));
|
||||||
RETURN_FALSE_ON_FAIL(
|
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(0));
|
||||||
RETURN_FALSE_ON_FAIL(
|
RETURN_FALSE_ON_FAIL(
|
||||||
destination->WriteExponentialGolomb(sps.max_num_ref_frames));
|
destination->WriteExponentialGolomb(sps.max_num_ref_frames));
|
||||||
@ -511,15 +513,15 @@ bool CopyOrRewriteVideoSignalTypeInfo(
|
|||||||
uint8_t colour_primaries = 3; // H264 default: unspecified
|
uint8_t colour_primaries = 3; // H264 default: unspecified
|
||||||
uint8_t transfer_characteristics = 3; // H264 default: unspecified
|
uint8_t transfer_characteristics = 3; // H264 default: unspecified
|
||||||
uint8_t matrix_coefficients = 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) {
|
if (video_signal_type_present_flag) {
|
||||||
RETURN_FALSE_ON_FAIL(source->ReadBits(&video_format, 3));
|
RETURN_FALSE_ON_FAIL(source->ReadBits(3, video_format));
|
||||||
RETURN_FALSE_ON_FAIL(source->ReadBits(&video_full_range_flag, 1));
|
RETURN_FALSE_ON_FAIL(source->ReadBits(1, video_full_range_flag));
|
||||||
RETURN_FALSE_ON_FAIL(source->ReadBits(&colour_description_present_flag, 1));
|
RETURN_FALSE_ON_FAIL(source->ReadBits(1, colour_description_present_flag));
|
||||||
if (colour_description_present_flag) {
|
if (colour_description_present_flag) {
|
||||||
RETURN_FALSE_ON_FAIL(source->ReadUInt8(&colour_primaries));
|
RETURN_FALSE_ON_FAIL(source->ReadUInt8(colour_primaries));
|
||||||
RETURN_FALSE_ON_FAIL(source->ReadUInt8(&transfer_characteristics));
|
RETURN_FALSE_ON_FAIL(source->ReadUInt8(transfer_characteristics));
|
||||||
RETURN_FALSE_ON_FAIL(source->ReadUInt8(&matrix_coefficients));
|
RETURN_FALSE_ON_FAIL(source->ReadUInt8(matrix_coefficients));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,7 +693,7 @@ bool FixedLengthDeltaDecoder::IsSuitableDecoderFor(const std::string& input) {
|
|||||||
|
|
||||||
uint32_t encoding_type_bits;
|
uint32_t encoding_type_bits;
|
||||||
const bool result =
|
const bool result =
|
||||||
reader.ReadBits(&encoding_type_bits, kBitsInHeaderForEncodingType);
|
reader.ReadBits(kBitsInHeaderForEncodingType, encoding_type_bits);
|
||||||
RTC_DCHECK(result);
|
RTC_DCHECK(result);
|
||||||
|
|
||||||
const auto encoding_type = static_cast<EncodingType>(encoding_type_bits);
|
const auto encoding_type = static_cast<EncodingType>(encoding_type_bits);
|
||||||
@ -729,7 +729,7 @@ std::unique_ptr<FixedLengthDeltaDecoder> FixedLengthDeltaDecoder::Create(
|
|||||||
// Encoding type
|
// Encoding type
|
||||||
uint32_t encoding_type_bits;
|
uint32_t encoding_type_bits;
|
||||||
const bool result =
|
const bool result =
|
||||||
reader->ReadBits(&encoding_type_bits, kBitsInHeaderForEncodingType);
|
reader->ReadBits(kBitsInHeaderForEncodingType, encoding_type_bits);
|
||||||
RTC_DCHECK(result);
|
RTC_DCHECK(result);
|
||||||
const EncodingType encoding = static_cast<EncodingType>(encoding_type_bits);
|
const EncodingType encoding = static_cast<EncodingType>(encoding_type_bits);
|
||||||
if (encoding != EncodingType::kFixedSizeUnsignedDeltasNoEarlyWrapNoOpt &&
|
if (encoding != EncodingType::kFixedSizeUnsignedDeltasNoEarlyWrapNoOpt &&
|
||||||
@ -742,7 +742,7 @@ std::unique_ptr<FixedLengthDeltaDecoder> FixedLengthDeltaDecoder::Create(
|
|||||||
uint32_t read_buffer;
|
uint32_t read_buffer;
|
||||||
|
|
||||||
// delta_width_bits
|
// delta_width_bits
|
||||||
if (!reader->ReadBits(&read_buffer, kBitsInHeaderForDeltaWidthBits)) {
|
if (!reader->ReadBits(kBitsInHeaderForDeltaWidthBits, read_buffer)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
RTC_DCHECK_LE(read_buffer, 64 - 1); // See encoding for -1's rationale.
|
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;
|
value_width_bits = kDefaultValueWidthBits;
|
||||||
} else {
|
} else {
|
||||||
// signed_deltas
|
// signed_deltas
|
||||||
if (!reader->ReadBits(&read_buffer, kBitsInHeaderForSignedDeltas)) {
|
if (!reader->ReadBits(kBitsInHeaderForSignedDeltas, read_buffer)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
signed_deltas = rtc::dchecked_cast<bool>(read_buffer);
|
signed_deltas = rtc::dchecked_cast<bool>(read_buffer);
|
||||||
|
|
||||||
// values_optional
|
// values_optional
|
||||||
if (!reader->ReadBits(&read_buffer, kBitsInHeaderForValuesOptional)) {
|
if (!reader->ReadBits(kBitsInHeaderForValuesOptional, read_buffer)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
RTC_DCHECK_LE(read_buffer, 1);
|
RTC_DCHECK_LE(read_buffer, 1);
|
||||||
values_optional = rtc::dchecked_cast<bool>(read_buffer);
|
values_optional = rtc::dchecked_cast<bool>(read_buffer);
|
||||||
|
|
||||||
// value_width_bits
|
// value_width_bits
|
||||||
if (!reader->ReadBits(&read_buffer, kBitsInHeaderForValueWidthBits)) {
|
if (!reader->ReadBits(kBitsInHeaderForValueWidthBits, read_buffer)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
RTC_DCHECK_LE(read_buffer, 64 - 1); // See encoding for -1's rationale.
|
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()) {
|
if (params_.values_optional()) {
|
||||||
for (size_t i = 0; i < num_of_deltas_; ++i) {
|
for (size_t i = 0; i < num_of_deltas_; ++i) {
|
||||||
uint32_t exists;
|
uint32_t exists;
|
||||||
if (!reader_->ReadBits(&exists, 1u)) {
|
if (!reader_->ReadBits(1u, exists)) {
|
||||||
RTC_LOG(LS_WARNING) << "Failed to read existence-indicating bit.";
|
RTC_LOG(LS_WARNING) << "Failed to read existence-indicating bit.";
|
||||||
return std::vector<absl::optional<uint64_t>>();
|
return std::vector<absl::optional<uint64_t>>();
|
||||||
}
|
}
|
||||||
@ -877,7 +877,7 @@ bool FixedLengthDeltaDecoder::ParseDelta(uint64_t* delta) {
|
|||||||
uint32_t higher_bits;
|
uint32_t higher_bits;
|
||||||
|
|
||||||
if (higher_bit_count > 0) {
|
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.";
|
RTC_LOG(LS_WARNING) << "Failed to read higher half of delta.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -885,7 +885,7 @@ bool FixedLengthDeltaDecoder::ParseDelta(uint64_t* delta) {
|
|||||||
higher_bits = 0;
|
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.";
|
RTC_LOG(LS_WARNING) << "Failed to read lower half of delta.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ size_t DecodeVarInt(rtc::BitBuffer* input, uint64_t* output) {
|
|||||||
uint64_t decoded = 0;
|
uint64_t decoded = 0;
|
||||||
for (size_t i = 0; i < kMaxVarIntLengthBytes; ++i) {
|
for (size_t i = 0; i < kMaxVarIntLengthBytes; ++i) {
|
||||||
uint8_t byte;
|
uint8_t byte;
|
||||||
if (!input->ReadUInt8(&byte)) {
|
if (!input->ReadUInt8(byte)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
decoded +=
|
decoded +=
|
||||||
|
@ -47,14 +47,14 @@ RtpDependencyDescriptorReader::RtpDependencyDescriptorReader(
|
|||||||
|
|
||||||
uint32_t RtpDependencyDescriptorReader::ReadBits(size_t bit_count) {
|
uint32_t RtpDependencyDescriptorReader::ReadBits(size_t bit_count) {
|
||||||
uint32_t value = 0;
|
uint32_t value = 0;
|
||||||
if (!buffer_.ReadBits(&value, bit_count))
|
if (!buffer_.ReadBits(bit_count, value))
|
||||||
parsing_failed_ = true;
|
parsing_failed_ = true;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t RtpDependencyDescriptorReader::ReadNonSymmetric(size_t num_values) {
|
uint32_t RtpDependencyDescriptorReader::ReadNonSymmetric(size_t num_values) {
|
||||||
uint32_t value = 0;
|
uint32_t value = 0;
|
||||||
if (!buffer_.ReadNonSymmetric(&value, num_values))
|
if (!buffer_.ReadNonSymmetric(num_values, value))
|
||||||
parsing_failed_ = true;
|
parsing_failed_ = true;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -40,12 +40,12 @@ constexpr int kFailedToParse = 0;
|
|||||||
bool ParsePictureId(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) {
|
bool ParsePictureId(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) {
|
||||||
uint32_t picture_id;
|
uint32_t picture_id;
|
||||||
uint32_t m_bit;
|
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) {
|
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;
|
vp9->max_picture_id = kMaxTwoBytePictureId;
|
||||||
} else {
|
} 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->max_picture_id = kMaxOneBytePictureId;
|
||||||
}
|
}
|
||||||
vp9->picture_id = picture_id;
|
vp9->picture_id = picture_id;
|
||||||
@ -60,10 +60,10 @@ bool ParsePictureId(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) {
|
|||||||
//
|
//
|
||||||
bool ParseLayerInfoCommon(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) {
|
bool ParseLayerInfoCommon(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) {
|
||||||
uint32_t t, u_bit, s, d_bit;
|
uint32_t t, u_bit, s, d_bit;
|
||||||
RETURN_FALSE_ON_ERROR(parser->ReadBits(&t, 3));
|
RETURN_FALSE_ON_ERROR(parser->ReadBits(3, t));
|
||||||
RETURN_FALSE_ON_ERROR(parser->ReadBits(&u_bit, 1));
|
RETURN_FALSE_ON_ERROR(parser->ReadBits(1, u_bit));
|
||||||
RETURN_FALSE_ON_ERROR(parser->ReadBits(&s, 3));
|
RETURN_FALSE_ON_ERROR(parser->ReadBits(3, s));
|
||||||
RETURN_FALSE_ON_ERROR(parser->ReadBits(&d_bit, 1));
|
RETURN_FALSE_ON_ERROR(parser->ReadBits(1, d_bit));
|
||||||
vp9->temporal_idx = t;
|
vp9->temporal_idx = t;
|
||||||
vp9->temporal_up_switch = u_bit ? true : false;
|
vp9->temporal_up_switch = u_bit ? true : false;
|
||||||
if (s >= kMaxSpatialLayers)
|
if (s >= kMaxSpatialLayers)
|
||||||
@ -84,7 +84,7 @@ bool ParseLayerInfoCommon(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) {
|
|||||||
bool ParseLayerInfoNonFlexibleMode(rtc::BitBuffer* parser,
|
bool ParseLayerInfoNonFlexibleMode(rtc::BitBuffer* parser,
|
||||||
RTPVideoHeaderVP9* vp9) {
|
RTPVideoHeaderVP9* vp9) {
|
||||||
uint8_t tl0picidx;
|
uint8_t tl0picidx;
|
||||||
RETURN_FALSE_ON_ERROR(parser->ReadUInt8(&tl0picidx));
|
RETURN_FALSE_ON_ERROR(parser->ReadUInt8(tl0picidx));
|
||||||
vp9->tl0_pic_idx = tl0picidx;
|
vp9->tl0_pic_idx = tl0picidx;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -117,8 +117,8 @@ bool ParseRefIndices(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint32_t p_diff;
|
uint32_t p_diff;
|
||||||
RETURN_FALSE_ON_ERROR(parser->ReadBits(&p_diff, 7));
|
RETURN_FALSE_ON_ERROR(parser->ReadBits(7, p_diff));
|
||||||
RETURN_FALSE_ON_ERROR(parser->ReadBits(&n_bit, 1));
|
RETURN_FALSE_ON_ERROR(parser->ReadBits(1, n_bit));
|
||||||
|
|
||||||
vp9->pid_diff[vp9->num_ref_pics] = p_diff;
|
vp9->pid_diff[vp9->num_ref_pics] = p_diff;
|
||||||
uint32_t scaled_pid = vp9->picture_id;
|
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) {
|
bool ParseSsData(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) {
|
||||||
uint32_t n_s, y_bit, g_bit;
|
uint32_t n_s, y_bit, g_bit;
|
||||||
RETURN_FALSE_ON_ERROR(parser->ReadBits(&n_s, 3));
|
RETURN_FALSE_ON_ERROR(parser->ReadBits(3, n_s));
|
||||||
RETURN_FALSE_ON_ERROR(parser->ReadBits(&y_bit, 1));
|
RETURN_FALSE_ON_ERROR(parser->ReadBits(1, y_bit));
|
||||||
RETURN_FALSE_ON_ERROR(parser->ReadBits(&g_bit, 1));
|
RETURN_FALSE_ON_ERROR(parser->ReadBits(1, g_bit));
|
||||||
RETURN_FALSE_ON_ERROR(parser->ConsumeBits(3));
|
RETURN_FALSE_ON_ERROR(parser->ConsumeBits(3));
|
||||||
vp9->num_spatial_layers = n_s + 1;
|
vp9->num_spatial_layers = n_s + 1;
|
||||||
vp9->spatial_layer_resolution_present = y_bit ? true : false;
|
vp9->spatial_layer_resolution_present = y_bit ? true : false;
|
||||||
@ -164,20 +164,20 @@ bool ParseSsData(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) {
|
|||||||
|
|
||||||
if (y_bit) {
|
if (y_bit) {
|
||||||
for (size_t i = 0; i < vp9->num_spatial_layers; ++i) {
|
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->width[i]));
|
||||||
RETURN_FALSE_ON_ERROR(parser->ReadUInt16(&vp9->height[i]));
|
RETURN_FALSE_ON_ERROR(parser->ReadUInt16(vp9->height[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (g_bit) {
|
if (g_bit) {
|
||||||
uint8_t n_g;
|
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;
|
vp9->gof.num_frames_in_gof = n_g;
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < vp9->gof.num_frames_in_gof; ++i) {
|
for (size_t i = 0; i < vp9->gof.num_frames_in_gof; ++i) {
|
||||||
uint32_t t, u_bit, r;
|
uint32_t t, u_bit, r;
|
||||||
RETURN_FALSE_ON_ERROR(parser->ReadBits(&t, 3));
|
RETURN_FALSE_ON_ERROR(parser->ReadBits(3, t));
|
||||||
RETURN_FALSE_ON_ERROR(parser->ReadBits(&u_bit, 1));
|
RETURN_FALSE_ON_ERROR(parser->ReadBits(1, u_bit));
|
||||||
RETURN_FALSE_ON_ERROR(parser->ReadBits(&r, 2));
|
RETURN_FALSE_ON_ERROR(parser->ReadBits(2, r));
|
||||||
RETURN_FALSE_ON_ERROR(parser->ConsumeBits(2));
|
RETURN_FALSE_ON_ERROR(parser->ConsumeBits(2));
|
||||||
vp9->gof.temporal_idx[i] = t;
|
vp9->gof.temporal_idx[i] = t;
|
||||||
vp9->gof.temporal_up_switch[i] = u_bit ? true : false;
|
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) {
|
for (uint8_t p = 0; p < vp9->gof.num_ref_pics[i]; ++p) {
|
||||||
uint8_t p_diff;
|
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;
|
vp9->gof.pid_diff[i][p] = p_diff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -214,7 +214,7 @@ int VideoRtpDepacketizerVp9::ParseRtpPayload(
|
|||||||
// Parse mandatory first byte of payload descriptor.
|
// Parse mandatory first byte of payload descriptor.
|
||||||
rtc::BitBuffer parser(rtp_payload.data(), rtp_payload.size());
|
rtc::BitBuffer parser(rtp_payload.data(), rtp_payload.size());
|
||||||
uint8_t first_byte;
|
uint8_t first_byte;
|
||||||
if (!parser.ReadUInt8(&first_byte)) {
|
if (!parser.ReadUInt8(first_byte)) {
|
||||||
RTC_LOG(LS_ERROR) << "Payload length is zero.";
|
RTC_LOG(LS_ERROR) << "Payload length is zero.";
|
||||||
return kFailedToParse;
|
return kFailedToParse;
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ class BitstreamReader {
|
|||||||
std::function<bool()> f_true,
|
std::function<bool()> f_true,
|
||||||
std::function<bool()> f_false = [] { return true; }) {
|
std::function<bool()> f_false = [] { return true; }) {
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
if (!buffer_->ReadBits(&val, 1)) {
|
if (!buffer_->ReadBits(1, val)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (val != 0) {
|
if (val != 0) {
|
||||||
@ -63,7 +63,7 @@ class BitstreamReader {
|
|||||||
|
|
||||||
absl::optional<bool> ReadBoolean() {
|
absl::optional<bool> ReadBoolean() {
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
if (!buffer_->ReadBits(&val, 1)) {
|
if (!buffer_->ReadBits(1, val)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
return {val != 0};
|
return {val != 0};
|
||||||
@ -76,7 +76,7 @@ class BitstreamReader {
|
|||||||
// logged as warning, if provided.
|
// logged as warning, if provided.
|
||||||
bool VerifyNextBooleanIs(bool expected_val, absl::string_view error_msg) {
|
bool VerifyNextBooleanIs(bool expected_val, absl::string_view error_msg) {
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
if (!buffer_->ReadBits(&val, 1)) {
|
if (!buffer_->ReadBits(1, val)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((val != 0) != expected_val) {
|
if ((val != 0) != expected_val) {
|
||||||
@ -100,7 +100,7 @@ class BitstreamReader {
|
|||||||
RTC_DCHECK_LE(bits, 32);
|
RTC_DCHECK_LE(bits, 32);
|
||||||
RTC_DCHECK_LE(bits, sizeof(T) * 8);
|
RTC_DCHECK_LE(bits, sizeof(T) * 8);
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
if (!buffer_->ReadBits(&val, bits)) {
|
if (!buffer_->ReadBits(bits, val)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
return (static_cast<T>(val));
|
return (static_cast<T>(val));
|
||||||
@ -115,7 +115,7 @@ class BitstreamReader {
|
|||||||
uint32_t expected_val,
|
uint32_t expected_val,
|
||||||
absl::string_view error_msg) {
|
absl::string_view error_msg) {
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
if (!buffer_->ReadBits(&val, num_bits)) {
|
if (!buffer_->ReadBits(num_bits, val)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (val != expected_val) {
|
if (val != expected_val) {
|
||||||
@ -134,11 +134,11 @@ class BitstreamReader {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
absl::optional<T> ReadSigned(int bits = sizeof(T) * 8) {
|
absl::optional<T> ReadSigned(int bits = sizeof(T) * 8) {
|
||||||
uint32_t sign;
|
uint32_t sign;
|
||||||
if (!buffer_->ReadBits(&sign, 1)) {
|
if (!buffer_->ReadBits(1, sign)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
if (!buffer_->ReadBits(&val, bits)) {
|
if (!buffer_->ReadBits(bits, val)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
int64_t sign_val = val;
|
int64_t sign_val = val;
|
||||||
|
@ -83,36 +83,36 @@ uint64_t BitBuffer::RemainingBitCount() const {
|
|||||||
return (static_cast<uint64_t>(byte_count_) - byte_offset_) * 8 - bit_offset_;
|
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;
|
uint32_t bit_val;
|
||||||
if (!ReadBits(&bit_val, sizeof(uint8_t) * 8)) {
|
if (!ReadBits(sizeof(uint8_t) * 8, bit_val)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
RTC_DCHECK(bit_val <= std::numeric_limits<uint8_t>::max());
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BitBuffer::ReadUInt16(uint16_t* val) {
|
bool BitBuffer::ReadUInt16(uint16_t& val) {
|
||||||
uint32_t bit_val;
|
uint32_t bit_val;
|
||||||
if (!ReadBits(&bit_val, sizeof(uint16_t) * 8)) {
|
if (!ReadBits(sizeof(uint16_t) * 8, bit_val)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
RTC_DCHECK(bit_val <= std::numeric_limits<uint16_t>::max());
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BitBuffer::ReadUInt32(uint32_t* val) {
|
bool BitBuffer::ReadUInt32(uint32_t& val) {
|
||||||
return ReadBits(val, sizeof(uint32_t) * 8);
|
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
|
// 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
|
// current code reads one byte beyond end of buffer in the case that
|
||||||
// RemainingBitCount() == 0 and bit_count == 0.
|
// RemainingBitCount() == 0 and bit_count == 0.
|
||||||
RTC_DCHECK(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;
|
return false;
|
||||||
}
|
}
|
||||||
const uint8_t* bytes = bytes_ + byte_offset_;
|
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
|
// If we're reading fewer bits than what's left in the current byte, just
|
||||||
// return the portion of this byte that we need.
|
// return the portion of this byte that we need.
|
||||||
if (bit_count < remaining_bits_in_current_byte) {
|
if (bit_count < remaining_bits_in_current_byte) {
|
||||||
*val = HighestBits(bits, bit_offset_ + bit_count);
|
val = HighestBits(bits, bit_offset_ + bit_count);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Otherwise, subtract what we've read from the bit count and read as many
|
// 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 <<= bit_count;
|
||||||
bits |= HighestBits(*bytes, bit_count);
|
bits |= HighestBits(*bytes, bit_count);
|
||||||
}
|
}
|
||||||
*val = bits;
|
val = bits;
|
||||||
return true;
|
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
|
// 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
|
// current code reads one byte beyond end of buffer in the case that
|
||||||
// RemainingBitCount() == 0 and bit_count == 0.
|
// RemainingBitCount() == 0 and bit_count == 0.
|
||||||
RTC_DCHECK(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;
|
return false;
|
||||||
}
|
}
|
||||||
const uint8_t* bytes = bytes_ + byte_offset_;
|
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
|
// If we're reading fewer bits than what's left in the current byte, just
|
||||||
// return the portion of this byte that we need.
|
// return the portion of this byte that we need.
|
||||||
if (bit_count < remaining_bits_in_current_byte) {
|
if (bit_count < remaining_bits_in_current_byte) {
|
||||||
*val = HighestBits(bits, bit_offset_ + bit_count);
|
val = HighestBits(bits, bit_offset_ + bit_count);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Otherwise, subtract what we've read from the bit count and read as many
|
// 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 <<= bit_count;
|
||||||
bits |= HighestBits(*bytes, bit_count);
|
bits |= HighestBits(*bytes, bit_count);
|
||||||
}
|
}
|
||||||
*val = bits;
|
val = bits;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BitBuffer::ReadBits(uint32_t* val, size_t bit_count) {
|
bool BitBuffer::ReadBits(size_t bit_count, uint32_t& val) {
|
||||||
return PeekBits(val, bit_count) && ConsumeBits(bit_count);
|
return PeekBits(bit_count, val) && ConsumeBits(bit_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BitBuffer::ReadBits(uint64_t* val, size_t bit_count) {
|
bool BitBuffer::ReadBits(size_t bit_count, uint64_t& val) {
|
||||||
return PeekBits(val, bit_count) && ConsumeBits(bit_count);
|
return PeekBits(bit_count, val) && ConsumeBits(bit_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BitBuffer::ConsumeBytes(size_t byte_count) {
|
bool BitBuffer::ConsumeBytes(size_t byte_count) {
|
||||||
@ -197,39 +197,36 @@ bool BitBuffer::ConsumeBits(size_t bit_count) {
|
|||||||
return true;
|
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_GT(num_values, 0);
|
||||||
RTC_DCHECK_LE(num_values, uint32_t{1} << 31);
|
RTC_DCHECK_LE(num_values, uint32_t{1} << 31);
|
||||||
if (num_values == 1) {
|
if (num_values == 1) {
|
||||||
// When there is only one possible value, it requires zero bits to store it.
|
// When there is only one possible value, it requires zero bits to store it.
|
||||||
// But ReadBits doesn't support reading zero bits.
|
// But ReadBits doesn't support reading zero bits.
|
||||||
*val = 0;
|
val = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
size_t count_bits = CountBits(num_values);
|
size_t count_bits = CountBits(num_values);
|
||||||
uint32_t num_min_bits_values = (uint32_t{1} << count_bits) - 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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*val < num_min_bits_values) {
|
if (val < num_min_bits_values) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t extra_bit;
|
uint32_t extra_bit;
|
||||||
if (!ReadBits(&extra_bit, /*bit_count=*/1)) {
|
if (!ReadBits(/*bit_count=*/1, extra_bit)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*val = (*val << 1) + extra_bit - num_min_bits_values;
|
val = (val << 1) + extra_bit - num_min_bits_values;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BitBuffer::ReadExponentialGolomb(uint32_t* val) {
|
bool BitBuffer::ReadExponentialGolomb(uint32_t& val) {
|
||||||
if (!val) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Store off the current byte/bit offset, in case we want to restore them due
|
// Store off the current byte/bit offset, in case we want to restore them due
|
||||||
// to a failed parse.
|
// to a failed parse.
|
||||||
size_t original_byte_offset = byte_offset_;
|
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.
|
// Count the number of leading 0 bits by peeking/consuming them one at a time.
|
||||||
size_t zero_bit_count = 0;
|
size_t zero_bit_count = 0;
|
||||||
uint32_t peeked_bit;
|
uint32_t peeked_bit;
|
||||||
while (PeekBits(&peeked_bit, 1) && peeked_bit == 0) {
|
while (PeekBits(1, peeked_bit) && peeked_bit == 0) {
|
||||||
zero_bit_count++;
|
zero_bit_count++;
|
||||||
ConsumeBits(1);
|
ConsumeBits(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We should either be at the end of the stream, or the next bit should be 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
|
// 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
|
// bits fits in a uint32_t and that we have enough bits left for it, and then
|
||||||
// read the value.
|
// read the value.
|
||||||
size_t value_bit_count = zero_bit_count + 1;
|
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));
|
RTC_CHECK(Seek(original_byte_offset, original_bit_offset));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*val -= 1;
|
val -= 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BitBuffer::ReadSignedExponentialGolomb(int32_t* val) {
|
bool BitBuffer::ReadSignedExponentialGolomb(int32_t& val) {
|
||||||
uint32_t unsigned_val;
|
uint32_t unsigned_val;
|
||||||
if (!ReadExponentialGolomb(&unsigned_val)) {
|
if (!ReadExponentialGolomb(unsigned_val)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((unsigned_val & 1) == 0) {
|
if ((unsigned_val & 1) == 0) {
|
||||||
*val = -static_cast<int32_t>(unsigned_val / 2);
|
val = -static_cast<int32_t>(unsigned_val / 2);
|
||||||
} else {
|
} else {
|
||||||
*val = (unsigned_val + 1) / 2;
|
val = (unsigned_val + 1) / 2;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <stddef.h> // For size_t.
|
#include <stddef.h> // For size_t.
|
||||||
#include <stdint.h> // For integer types.
|
#include <stdint.h> // For integer types.
|
||||||
|
|
||||||
|
#include "absl/base/attributes.h"
|
||||||
#include "rtc_base/constructor_magic.h"
|
#include "rtc_base/constructor_magic.h"
|
||||||
|
|
||||||
namespace rtc {
|
namespace rtc {
|
||||||
@ -38,20 +39,35 @@ class BitBuffer {
|
|||||||
|
|
||||||
// Reads byte-sized values from the buffer. Returns false if there isn't
|
// Reads byte-sized values from the buffer. Returns false if there isn't
|
||||||
// enough data left for the specified type.
|
// enough data left for the specified type.
|
||||||
bool ReadUInt8(uint8_t* val);
|
bool ReadUInt8(uint8_t& val);
|
||||||
bool ReadUInt16(uint16_t* val);
|
bool ReadUInt16(uint16_t& val);
|
||||||
bool ReadUInt32(uint32_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
|
// Reads bit-sized values from the buffer. Returns false if there isn't enough
|
||||||
// data left for the specified bit count.
|
// data left for the specified bit count.
|
||||||
bool ReadBits(uint32_t* val, size_t bit_count);
|
bool ReadBits(size_t bit_count, uint32_t& val);
|
||||||
bool ReadBits(uint64_t* val, size_t bit_count);
|
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
|
// 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
|
// data left for the specified number of bits. Doesn't move the current
|
||||||
// offset.
|
// offset.
|
||||||
bool PeekBits(uint32_t* val, size_t bit_count);
|
bool PeekBits(size_t bit_count, uint32_t& val);
|
||||||
bool PeekBits(uint64_t* val, size_t bit_count);
|
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].
|
// Reads value in range [0, num_values - 1].
|
||||||
// This encoding is similar to ReadBits(val, Ceil(Log2(num_values)),
|
// 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.
|
// Value v in range [k, num_values - 1] is encoded as (v+k) in n bits.
|
||||||
// https://aomediacodec.github.io/av1-spec/#nsn
|
// https://aomediacodec.github.io/av1-spec/#nsn
|
||||||
// Returns false if there isn't enough data left.
|
// 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.
|
// Reads the exponential golomb encoded value at the current offset.
|
||||||
// Exponential golomb values are encoded as:
|
// Exponential golomb values are encoded as:
|
||||||
@ -73,11 +93,18 @@ class BitBuffer {
|
|||||||
// and increment the result by 1.
|
// and increment the result by 1.
|
||||||
// Returns false if there isn't enough data left for the specified type, or if
|
// Returns false if there isn't enough data left for the specified type, or if
|
||||||
// the value wouldn't fit in a uint32_t.
|
// 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
|
// Reads signed exponential golomb values at the current offset. Signed
|
||||||
// exponential golomb values are just the unsigned values mapped to the
|
// exponential golomb values are just the unsigned values mapped to the
|
||||||
// sequence 0, 1, -1, 2, -2, etc. in order.
|
// 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
|
// Moves current position |byte_count| bytes forward. Returns false if
|
||||||
// there aren't enough bytes left in the buffer.
|
// there aren't enough bytes left in the buffer.
|
||||||
|
@ -49,13 +49,13 @@ TEST(BitBufferTest, ReadBytesAligned) {
|
|||||||
uint16_t val16;
|
uint16_t val16;
|
||||||
uint32_t val32;
|
uint32_t val32;
|
||||||
BitBuffer buffer(bytes, 8);
|
BitBuffer buffer(bytes, 8);
|
||||||
EXPECT_TRUE(buffer.ReadUInt8(&val8));
|
EXPECT_TRUE(buffer.ReadUInt8(val8));
|
||||||
EXPECT_EQ(0x0Au, val8);
|
EXPECT_EQ(0x0Au, val8);
|
||||||
EXPECT_TRUE(buffer.ReadUInt8(&val8));
|
EXPECT_TRUE(buffer.ReadUInt8(val8));
|
||||||
EXPECT_EQ(0xBCu, val8);
|
EXPECT_EQ(0xBCu, val8);
|
||||||
EXPECT_TRUE(buffer.ReadUInt16(&val16));
|
EXPECT_TRUE(buffer.ReadUInt16(val16));
|
||||||
EXPECT_EQ(0xDEF1u, val16);
|
EXPECT_EQ(0xDEF1u, val16);
|
||||||
EXPECT_TRUE(buffer.ReadUInt32(&val32));
|
EXPECT_TRUE(buffer.ReadUInt32(val32));
|
||||||
EXPECT_EQ(0x23456789u, val32);
|
EXPECT_EQ(0x23456789u, val32);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,13 +68,13 @@ TEST(BitBufferTest, ReadBytesOffset4) {
|
|||||||
BitBuffer buffer(bytes, 9);
|
BitBuffer buffer(bytes, 9);
|
||||||
EXPECT_TRUE(buffer.ConsumeBits(4));
|
EXPECT_TRUE(buffer.ConsumeBits(4));
|
||||||
|
|
||||||
EXPECT_TRUE(buffer.ReadUInt8(&val8));
|
EXPECT_TRUE(buffer.ReadUInt8(val8));
|
||||||
EXPECT_EQ(0xABu, val8);
|
EXPECT_EQ(0xABu, val8);
|
||||||
EXPECT_TRUE(buffer.ReadUInt8(&val8));
|
EXPECT_TRUE(buffer.ReadUInt8(val8));
|
||||||
EXPECT_EQ(0xCDu, val8);
|
EXPECT_EQ(0xCDu, val8);
|
||||||
EXPECT_TRUE(buffer.ReadUInt16(&val16));
|
EXPECT_TRUE(buffer.ReadUInt16(val16));
|
||||||
EXPECT_EQ(0xEF12u, val16);
|
EXPECT_EQ(0xEF12u, val16);
|
||||||
EXPECT_TRUE(buffer.ReadUInt32(&val32));
|
EXPECT_TRUE(buffer.ReadUInt32(val32));
|
||||||
EXPECT_EQ(0x34567890u, val32);
|
EXPECT_EQ(0x34567890u, val32);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,15 +102,15 @@ TEST(BitBufferTest, ReadBytesOffset3) {
|
|||||||
uint32_t val32;
|
uint32_t val32;
|
||||||
BitBuffer buffer(bytes, 8);
|
BitBuffer buffer(bytes, 8);
|
||||||
EXPECT_TRUE(buffer.ConsumeBits(3));
|
EXPECT_TRUE(buffer.ConsumeBits(3));
|
||||||
EXPECT_TRUE(buffer.ReadUInt8(&val8));
|
EXPECT_TRUE(buffer.ReadUInt8(val8));
|
||||||
EXPECT_EQ(0xFEu, val8);
|
EXPECT_EQ(0xFEu, val8);
|
||||||
EXPECT_TRUE(buffer.ReadUInt16(&val16));
|
EXPECT_TRUE(buffer.ReadUInt16(val16));
|
||||||
EXPECT_EQ(0xDCBAu, val16);
|
EXPECT_EQ(0xDCBAu, val16);
|
||||||
EXPECT_TRUE(buffer.ReadUInt32(&val32));
|
EXPECT_TRUE(buffer.ReadUInt32(val32));
|
||||||
EXPECT_EQ(0x98765432u, val32);
|
EXPECT_EQ(0x98765432u, val32);
|
||||||
// 5 bits left unread. Not enough to read a uint8_t.
|
// 5 bits left unread. Not enough to read a uint8_t.
|
||||||
EXPECT_EQ(5u, buffer.RemainingBitCount());
|
EXPECT_EQ(5u, buffer.RemainingBitCount());
|
||||||
EXPECT_FALSE(buffer.ReadUInt8(&val8));
|
EXPECT_FALSE(buffer.ReadUInt8(val8));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BitBufferTest, ReadBits) {
|
TEST(BitBufferTest, ReadBits) {
|
||||||
@ -120,26 +120,26 @@ TEST(BitBufferTest, ReadBits) {
|
|||||||
const uint8_t bytes[] = {0x4D, 0x32};
|
const uint8_t bytes[] = {0x4D, 0x32};
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
BitBuffer buffer(bytes, 2);
|
BitBuffer buffer(bytes, 2);
|
||||||
EXPECT_TRUE(buffer.ReadBits(&val, 3));
|
EXPECT_TRUE(buffer.ReadBits(3, val));
|
||||||
// 0b010
|
// 0b010
|
||||||
EXPECT_EQ(0x2u, val);
|
EXPECT_EQ(0x2u, val);
|
||||||
EXPECT_TRUE(buffer.ReadBits(&val, 2));
|
EXPECT_TRUE(buffer.ReadBits(2, val));
|
||||||
// 0b01
|
// 0b01
|
||||||
EXPECT_EQ(0x1u, val);
|
EXPECT_EQ(0x1u, val);
|
||||||
EXPECT_TRUE(buffer.ReadBits(&val, 7));
|
EXPECT_TRUE(buffer.ReadBits(7, val));
|
||||||
// 0b1010011
|
// 0b1010011
|
||||||
EXPECT_EQ(0x53u, val);
|
EXPECT_EQ(0x53u, val);
|
||||||
EXPECT_TRUE(buffer.ReadBits(&val, 2));
|
EXPECT_TRUE(buffer.ReadBits(2, val));
|
||||||
// 0b00
|
// 0b00
|
||||||
EXPECT_EQ(0x0u, val);
|
EXPECT_EQ(0x0u, val);
|
||||||
EXPECT_TRUE(buffer.ReadBits(&val, 1));
|
EXPECT_TRUE(buffer.ReadBits(1, val));
|
||||||
// 0b1
|
// 0b1
|
||||||
EXPECT_EQ(0x1u, val);
|
EXPECT_EQ(0x1u, val);
|
||||||
EXPECT_TRUE(buffer.ReadBits(&val, 1));
|
EXPECT_TRUE(buffer.ReadBits(1, val));
|
||||||
// 0b0
|
// 0b0
|
||||||
EXPECT_EQ(0x0u, val);
|
EXPECT_EQ(0x0u, val);
|
||||||
|
|
||||||
EXPECT_FALSE(buffer.ReadBits(&val, 1));
|
EXPECT_FALSE(buffer.ReadBits(1, val));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BitBufferTest, ReadBits64) {
|
TEST(BitBufferTest, ReadBits64) {
|
||||||
@ -149,29 +149,29 @@ TEST(BitBufferTest, ReadBits64) {
|
|||||||
uint64_t val;
|
uint64_t val;
|
||||||
|
|
||||||
// Peek and read first 33 bits.
|
// Peek and read first 33 bits.
|
||||||
EXPECT_TRUE(buffer.PeekBits(&val, 33));
|
EXPECT_TRUE(buffer.PeekBits(33, val));
|
||||||
EXPECT_EQ(0x4D32AB5400FFFE01ull >> (64 - 33), val);
|
EXPECT_EQ(0x4D32AB5400FFFE01ull >> (64 - 33), val);
|
||||||
val = 0;
|
val = 0;
|
||||||
EXPECT_TRUE(buffer.ReadBits(&val, 33));
|
EXPECT_TRUE(buffer.ReadBits(33, val));
|
||||||
EXPECT_EQ(0x4D32AB5400FFFE01ull >> (64 - 33), val);
|
EXPECT_EQ(0x4D32AB5400FFFE01ull >> (64 - 33), val);
|
||||||
|
|
||||||
// Peek and read next 31 bits.
|
// Peek and read next 31 bits.
|
||||||
constexpr uint64_t kMask31Bits = (1ull << 32) - 1;
|
constexpr uint64_t kMask31Bits = (1ull << 32) - 1;
|
||||||
EXPECT_TRUE(buffer.PeekBits(&val, 31));
|
EXPECT_TRUE(buffer.PeekBits(31, val));
|
||||||
EXPECT_EQ(0x4D32AB5400FFFE01ull & kMask31Bits, val);
|
EXPECT_EQ(0x4D32AB5400FFFE01ull & kMask31Bits, val);
|
||||||
val = 0;
|
val = 0;
|
||||||
EXPECT_TRUE(buffer.ReadBits(&val, 31));
|
EXPECT_TRUE(buffer.ReadBits(31, val));
|
||||||
EXPECT_EQ(0x4D32AB5400FFFE01ull & kMask31Bits, val);
|
EXPECT_EQ(0x4D32AB5400FFFE01ull & kMask31Bits, val);
|
||||||
|
|
||||||
// Peek and read remaining 64 bits.
|
// Peek and read remaining 64 bits.
|
||||||
EXPECT_TRUE(buffer.PeekBits(&val, 64));
|
EXPECT_TRUE(buffer.PeekBits(64, val));
|
||||||
EXPECT_EQ(0xABCDEF0123456789ull, val);
|
EXPECT_EQ(0xABCDEF0123456789ull, val);
|
||||||
val = 0;
|
val = 0;
|
||||||
EXPECT_TRUE(buffer.ReadBits(&val, 64));
|
EXPECT_TRUE(buffer.ReadBits(64, val));
|
||||||
EXPECT_EQ(0xABCDEF0123456789ull, val);
|
EXPECT_EQ(0xABCDEF0123456789ull, val);
|
||||||
|
|
||||||
// Nothing more to read.
|
// Nothing more to read.
|
||||||
EXPECT_FALSE(buffer.ReadBits(&val, 1));
|
EXPECT_FALSE(buffer.ReadBits(1, val));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BitBufferDeathTest, SetOffsetValues) {
|
TEST(BitBufferDeathTest, SetOffsetValues) {
|
||||||
@ -219,10 +219,10 @@ TEST(BitBufferTest, ReadNonSymmetricSameNumberOfBitsWhenNumValuesPowerOf2) {
|
|||||||
|
|
||||||
uint32_t values[4];
|
uint32_t values[4];
|
||||||
ASSERT_EQ(reader.RemainingBitCount(), 16u);
|
ASSERT_EQ(reader.RemainingBitCount(), 16u);
|
||||||
EXPECT_TRUE(reader.ReadNonSymmetric(&values[0], /*num_values=*/1 << 4));
|
EXPECT_TRUE(reader.ReadNonSymmetric(/*num_values=*/1 << 4, values[0]));
|
||||||
EXPECT_TRUE(reader.ReadNonSymmetric(&values[1], /*num_values=*/1 << 4));
|
EXPECT_TRUE(reader.ReadNonSymmetric(/*num_values=*/1 << 4, values[1]));
|
||||||
EXPECT_TRUE(reader.ReadNonSymmetric(&values[2], /*num_values=*/1 << 4));
|
EXPECT_TRUE(reader.ReadNonSymmetric(/*num_values=*/1 << 4, values[2]));
|
||||||
EXPECT_TRUE(reader.ReadNonSymmetric(&values[3], /*num_values=*/1 << 4));
|
EXPECT_TRUE(reader.ReadNonSymmetric(/*num_values=*/1 << 4, values[3]));
|
||||||
ASSERT_EQ(reader.RemainingBitCount(), 0u);
|
ASSERT_EQ(reader.RemainingBitCount(), 0u);
|
||||||
|
|
||||||
EXPECT_THAT(values, ElementsAre(0xf, 0x3, 0xa, 0x0));
|
EXPECT_THAT(values, ElementsAre(0xf, 0x3, 0xa, 0x0));
|
||||||
@ -276,12 +276,12 @@ TEST(BitBufferWriterTest, NonSymmetricReadsMatchesWrites) {
|
|||||||
|
|
||||||
rtc::BitBuffer reader(bytes, 2);
|
rtc::BitBuffer reader(bytes, 2);
|
||||||
uint32_t values[6];
|
uint32_t values[6];
|
||||||
EXPECT_TRUE(reader.ReadNonSymmetric(&values[0], /*num_values=*/6));
|
EXPECT_TRUE(reader.ReadNonSymmetric(/*num_values=*/6, values[0]));
|
||||||
EXPECT_TRUE(reader.ReadNonSymmetric(&values[1], /*num_values=*/6));
|
EXPECT_TRUE(reader.ReadNonSymmetric(/*num_values=*/6, values[1]));
|
||||||
EXPECT_TRUE(reader.ReadNonSymmetric(&values[2], /*num_values=*/6));
|
EXPECT_TRUE(reader.ReadNonSymmetric(/*num_values=*/6, values[2]));
|
||||||
EXPECT_TRUE(reader.ReadNonSymmetric(&values[3], /*num_values=*/6));
|
EXPECT_TRUE(reader.ReadNonSymmetric(/*num_values=*/6, values[3]));
|
||||||
EXPECT_TRUE(reader.ReadNonSymmetric(&values[4], /*num_values=*/6));
|
EXPECT_TRUE(reader.ReadNonSymmetric(/*num_values=*/6, values[4]));
|
||||||
EXPECT_TRUE(reader.ReadNonSymmetric(&values[5], /*num_values=*/6));
|
EXPECT_TRUE(reader.ReadNonSymmetric(/*num_values=*/6, values[5]));
|
||||||
|
|
||||||
EXPECT_THAT(values, ElementsAre(0, 1, 2, 3, 4, 5));
|
EXPECT_THAT(values, ElementsAre(0, 1, 2, 3, 4, 5));
|
||||||
}
|
}
|
||||||
@ -292,7 +292,7 @@ TEST(BitBufferTest, ReadNonSymmetricOnlyValueConsumesNoBits) {
|
|||||||
uint32_t value = 0xFFFFFFFF;
|
uint32_t value = 0xFFFFFFFF;
|
||||||
ASSERT_EQ(reader.RemainingBitCount(), 16u);
|
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(value, 0u);
|
||||||
EXPECT_EQ(reader.RemainingBitCount(), 16u);
|
EXPECT_EQ(reader.RemainingBitCount(), 16u);
|
||||||
@ -334,7 +334,7 @@ TEST(BitBufferTest, GolombUint32Values) {
|
|||||||
byteBuffer.WriteUInt64(encoded_val);
|
byteBuffer.WriteUInt64(encoded_val);
|
||||||
uint32_t decoded_val;
|
uint32_t decoded_val;
|
||||||
EXPECT_TRUE(buffer.Seek(0, 0));
|
EXPECT_TRUE(buffer.Seek(0, 0));
|
||||||
EXPECT_TRUE(buffer.ReadExponentialGolomb(&decoded_val));
|
EXPECT_TRUE(buffer.ReadExponentialGolomb(decoded_val));
|
||||||
EXPECT_EQ(i, decoded_val);
|
EXPECT_EQ(i, decoded_val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -351,7 +351,7 @@ TEST(BitBufferTest, SignedGolombValues) {
|
|||||||
for (size_t i = 0; i < sizeof(golomb_bits); ++i) {
|
for (size_t i = 0; i < sizeof(golomb_bits); ++i) {
|
||||||
BitBuffer buffer(&golomb_bits[i], 1);
|
BitBuffer buffer(&golomb_bits[i], 1);
|
||||||
int32_t decoded_val;
|
int32_t decoded_val;
|
||||||
ASSERT_TRUE(buffer.ReadSignedExponentialGolomb(&decoded_val));
|
ASSERT_TRUE(buffer.ReadSignedExponentialGolomb(decoded_val));
|
||||||
EXPECT_EQ(expected[i], decoded_val)
|
EXPECT_EQ(expected[i], decoded_val)
|
||||||
<< "Mismatch in expected/decoded value for golomb_bits[" << i
|
<< "Mismatch in expected/decoded value for golomb_bits[" << i
|
||||||
<< "]: " << static_cast<int>(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.
|
// If it didn't, the above buffer would be valid at 3 bytes.
|
||||||
BitBuffer buffer(bytes, 1);
|
BitBuffer buffer(bytes, 1);
|
||||||
uint32_t decoded_val;
|
uint32_t decoded_val;
|
||||||
EXPECT_FALSE(buffer.ReadExponentialGolomb(&decoded_val));
|
EXPECT_FALSE(buffer.ReadExponentialGolomb(decoded_val));
|
||||||
|
|
||||||
BitBuffer longer_buffer(bytes, 2);
|
BitBuffer longer_buffer(bytes, 2);
|
||||||
EXPECT_FALSE(longer_buffer.ReadExponentialGolomb(&decoded_val));
|
EXPECT_FALSE(longer_buffer.ReadExponentialGolomb(decoded_val));
|
||||||
|
|
||||||
BitBuffer longest_buffer(bytes, 3);
|
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
|
// Golomb should have read 9 bits, so 0x01FF, and since it is golomb, the
|
||||||
// result is 0x01FF - 1 = 0x01FE.
|
// result is 0x01FF - 1 = 0x01FE.
|
||||||
EXPECT_EQ(0x01FEu, decoded_val);
|
EXPECT_EQ(0x01FEu, decoded_val);
|
||||||
@ -392,20 +392,20 @@ TEST(BitBufferWriterTest, SymmetricReadWrite) {
|
|||||||
|
|
||||||
EXPECT_TRUE(buffer.Seek(0, 0));
|
EXPECT_TRUE(buffer.Seek(0, 0));
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
EXPECT_TRUE(buffer.ReadBits(&val, 3));
|
EXPECT_TRUE(buffer.ReadBits(3, val));
|
||||||
EXPECT_EQ(0x2u, val);
|
EXPECT_EQ(0x2u, val);
|
||||||
EXPECT_TRUE(buffer.ReadBits(&val, 2));
|
EXPECT_TRUE(buffer.ReadBits(2, val));
|
||||||
EXPECT_EQ(0x1u, val);
|
EXPECT_EQ(0x1u, val);
|
||||||
EXPECT_TRUE(buffer.ReadBits(&val, 7));
|
EXPECT_TRUE(buffer.ReadBits(7, val));
|
||||||
EXPECT_EQ(0x53u, val);
|
EXPECT_EQ(0x53u, val);
|
||||||
EXPECT_TRUE(buffer.ReadBits(&val, 2));
|
EXPECT_TRUE(buffer.ReadBits(2, val));
|
||||||
EXPECT_EQ(0x0u, val);
|
EXPECT_EQ(0x0u, val);
|
||||||
EXPECT_TRUE(buffer.ReadBits(&val, 1));
|
EXPECT_TRUE(buffer.ReadBits(1, val));
|
||||||
EXPECT_EQ(0x1u, val);
|
EXPECT_EQ(0x1u, val);
|
||||||
EXPECT_TRUE(buffer.ReadBits(&val, 17));
|
EXPECT_TRUE(buffer.ReadBits(17, val));
|
||||||
EXPECT_EQ(0x1ABCDu, val);
|
EXPECT_EQ(0x1ABCDu, val);
|
||||||
// And there should be nothing left.
|
// And there should be nothing left.
|
||||||
EXPECT_FALSE(buffer.ReadBits(&val, 1));
|
EXPECT_FALSE(buffer.ReadBits(1, val));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BitBufferWriterTest, SymmetricBytesMisaligned) {
|
TEST(BitBufferWriterTest, SymmetricBytesMisaligned) {
|
||||||
@ -422,11 +422,11 @@ TEST(BitBufferWriterTest, SymmetricBytesMisaligned) {
|
|||||||
uint8_t val8;
|
uint8_t val8;
|
||||||
uint16_t val16;
|
uint16_t val16;
|
||||||
uint32_t val32;
|
uint32_t val32;
|
||||||
EXPECT_TRUE(buffer.ReadUInt8(&val8));
|
EXPECT_TRUE(buffer.ReadUInt8(val8));
|
||||||
EXPECT_EQ(0x12u, val8);
|
EXPECT_EQ(0x12u, val8);
|
||||||
EXPECT_TRUE(buffer.ReadUInt16(&val16));
|
EXPECT_TRUE(buffer.ReadUInt16(val16));
|
||||||
EXPECT_EQ(0x3456u, val16);
|
EXPECT_EQ(0x3456u, val16);
|
||||||
EXPECT_TRUE(buffer.ReadUInt32(&val32));
|
EXPECT_TRUE(buffer.ReadUInt32(val32));
|
||||||
EXPECT_EQ(0x789ABCDEu, val32);
|
EXPECT_EQ(0x789ABCDEu, val32);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,7 +440,7 @@ TEST(BitBufferWriterTest, SymmetricGolomb) {
|
|||||||
buffer.Seek(0, 0);
|
buffer.Seek(0, 0);
|
||||||
for (size_t i = 0; i < arraysize(test_string); ++i) {
|
for (size_t i = 0; i < arraysize(test_string); ++i) {
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
EXPECT_TRUE(buffer.ReadExponentialGolomb(&val));
|
EXPECT_TRUE(buffer.ReadExponentialGolomb(val));
|
||||||
EXPECT_LE(val, std::numeric_limits<uint8_t>::max());
|
EXPECT_LE(val, std::numeric_limits<uint8_t>::max());
|
||||||
EXPECT_EQ(test_string[i], static_cast<char>(val));
|
EXPECT_EQ(test_string[i], static_cast<char>(val));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user