Use ArrayView on H264 bitstream parsing
No-Try: true
Bug: webrtc:42225170
Change-Id: I4682f400054fee5c86ea24bebf6d703fb90074da
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/354722
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Sergey Silkin <ssilkin@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42650}
diff --git a/common_video/h264/h264_bitstream_parser.cc b/common_video/h264/h264_bitstream_parser.cc
index 9f02a96..38cf0ff 100644
--- a/common_video/h264/h264_bitstream_parser.cc
+++ b/common_video/h264/h264_bitstream_parser.cc
@@ -31,15 +31,13 @@
H264BitstreamParser::~H264BitstreamParser() = default;
H264BitstreamParser::Result H264BitstreamParser::ParseNonParameterSetNalu(
- const uint8_t* source,
- size_t source_length,
+ rtc::ArrayView<const uint8_t> source,
uint8_t nalu_type) {
if (!sps_ || !pps_)
return kInvalidStream;
last_slice_qp_delta_ = absl::nullopt;
- const std::vector<uint8_t> slice_rbsp =
- H264::ParseRbsp(source, source_length);
+ const std::vector<uint8_t> slice_rbsp = H264::ParseRbsp(source);
if (slice_rbsp.size() < H264::kNaluTypeSize)
return kInvalidStream;
@@ -308,19 +306,17 @@
return kOk;
}
-void H264BitstreamParser::ParseSlice(const uint8_t* slice, size_t length) {
+void H264BitstreamParser::ParseSlice(rtc::ArrayView<const uint8_t> slice) {
H264::NaluType nalu_type = H264::ParseNaluType(slice[0]);
switch (nalu_type) {
case H264::NaluType::kSps: {
- sps_ = SpsParser::ParseSps(slice + H264::kNaluTypeSize,
- length - H264::kNaluTypeSize);
+ sps_ = SpsParser::ParseSps(slice.subview(H264::kNaluTypeSize));
if (!sps_)
RTC_DLOG(LS_WARNING) << "Unable to parse SPS from H264 bitstream.";
break;
}
case H264::NaluType::kPps: {
- pps_ = PpsParser::ParsePps(slice + H264::kNaluTypeSize,
- length - H264::kNaluTypeSize);
+ pps_ = PpsParser::ParsePps(slice.subview(H264::kNaluTypeSize));
if (!pps_)
RTC_DLOG(LS_WARNING) << "Unable to parse PPS from H264 bitstream.";
break;
@@ -330,7 +326,7 @@
case H264::NaluType::kPrefix:
break; // Ignore these nalus, as we don't care about their contents.
default:
- Result res = ParseNonParameterSetNalu(slice, length, nalu_type);
+ Result res = ParseNonParameterSetNalu(slice, nalu_type);
if (res != kOk)
RTC_DLOG(LS_INFO) << "Failed to parse bitstream. Error: " << res;
break;
@@ -339,11 +335,10 @@
void H264BitstreamParser::ParseBitstream(
rtc::ArrayView<const uint8_t> bitstream) {
- std::vector<H264::NaluIndex> nalu_indices =
- H264::FindNaluIndices(bitstream.data(), bitstream.size());
+ std::vector<H264::NaluIndex> nalu_indices = H264::FindNaluIndices(bitstream);
for (const H264::NaluIndex& index : nalu_indices)
- ParseSlice(bitstream.data() + index.payload_start_offset,
- index.payload_size);
+ ParseSlice(
+ bitstream.subview(index.payload_start_offset, index.payload_size));
}
absl::optional<int> H264BitstreamParser::GetLastSliceQp() const {
diff --git a/common_video/h264/h264_bitstream_parser.h b/common_video/h264/h264_bitstream_parser.h
index 0542782..1fad989 100644
--- a/common_video/h264/h264_bitstream_parser.h
+++ b/common_video/h264/h264_bitstream_parser.h
@@ -40,9 +40,8 @@
kInvalidStream,
kUnsupportedStream,
};
- void ParseSlice(const uint8_t* slice, size_t length);
- Result ParseNonParameterSetNalu(const uint8_t* source,
- size_t source_length,
+ void ParseSlice(rtc::ArrayView<const uint8_t> slice);
+ Result ParseNonParameterSetNalu(rtc::ArrayView<const uint8_t> source,
uint8_t nalu_type);
// SPS/PPS state, updated when parsing new SPS/PPS, used to parse slices.
diff --git a/common_video/h264/h264_common.cc b/common_video/h264/h264_common.cc
index 06d94e0..b931642 100644
--- a/common_video/h264/h264_common.cc
+++ b/common_video/h264/h264_common.cc
@@ -17,19 +17,18 @@
const uint8_t kNaluTypeMask = 0x1F;
-std::vector<NaluIndex> FindNaluIndices(const uint8_t* buffer,
- size_t buffer_size) {
+std::vector<NaluIndex> FindNaluIndices(rtc::ArrayView<const uint8_t> buffer) {
// This is sorta like Boyer-Moore, but with only the first optimization step:
// given a 3-byte sequence we're looking at, if the 3rd byte isn't 1 or 0,
// skip ahead to the next 3-byte sequence. 0s and 1s are relatively rare, so
// this will skip the majority of reads/checks.
std::vector<NaluIndex> sequences;
- if (buffer_size < kNaluShortStartSequenceSize)
+ if (buffer.size() < kNaluShortStartSequenceSize)
return sequences;
static_assert(kNaluShortStartSequenceSize >= 2,
"kNaluShortStartSequenceSize must be larger or equals to 2");
- const size_t end = buffer_size - kNaluShortStartSequenceSize;
+ const size_t end = buffer.size() - kNaluShortStartSequenceSize;
for (size_t i = 0; i < end;) {
if (buffer[i + 2] > 1) {
i += 3;
@@ -57,7 +56,7 @@
// Update length of last entry, if any.
auto it = sequences.rbegin();
if (it != sequences.rend())
- it->payload_size = buffer_size - it->payload_start_offset;
+ it->payload_size = buffer.size() - it->payload_start_offset;
return sequences;
}
@@ -66,16 +65,16 @@
return static_cast<NaluType>(data & kNaluTypeMask);
}
-std::vector<uint8_t> ParseRbsp(const uint8_t* data, size_t length) {
+std::vector<uint8_t> ParseRbsp(rtc::ArrayView<const uint8_t> data) {
std::vector<uint8_t> out;
- out.reserve(length);
+ out.reserve(data.size());
- for (size_t i = 0; i < length;) {
+ for (size_t i = 0; i < data.size();) {
// Be careful about over/underflow here. byte_length_ - 3 can underflow, and
// i + 3 can overflow, but byte_length_ - i can't, because i < byte_length_
// above, and that expression will produce the number of bytes left in
// the stream including the byte at i.
- if (length - i >= 3 && !data[i] && !data[i + 1] && data[i + 2] == 3) {
+ if (data.size() - i >= 3 && !data[i] && !data[i + 1] && data[i + 2] == 3) {
// Two rbsp bytes.
out.push_back(data[i++]);
out.push_back(data[i++]);
@@ -89,14 +88,13 @@
return out;
}
-void WriteRbsp(const uint8_t* bytes, size_t length, rtc::Buffer* destination) {
+void WriteRbsp(rtc::ArrayView<const uint8_t> bytes, rtc::Buffer* destination) {
static const uint8_t kZerosInStartSequence = 2;
static const uint8_t kEmulationByte = 0x03u;
size_t num_consecutive_zeros = 0;
- destination->EnsureCapacity(destination->size() + length);
+ destination->EnsureCapacity(destination->size() + bytes.size());
- for (size_t i = 0; i < length; ++i) {
- uint8_t byte = bytes[i];
+ for (uint8_t byte : bytes) {
if (byte <= kEmulationByte &&
num_consecutive_zeros >= kZerosInStartSequence) {
// Need to escape.
diff --git a/common_video/h264/h264_common.h b/common_video/h264/h264_common.h
index a55d647..e7df02a 100644
--- a/common_video/h264/h264_common.h
+++ b/common_video/h264/h264_common.h
@@ -63,8 +63,14 @@
};
// Returns a vector of the NALU indices in the given buffer.
-RTC_EXPORT std::vector<NaluIndex> FindNaluIndices(const uint8_t* buffer,
- size_t buffer_size);
+RTC_EXPORT std::vector<NaluIndex> FindNaluIndices(
+ rtc::ArrayView<const uint8_t> buffer);
+
+// TODO: bugs.webrtc.org/42225170 - Deprecate.
+inline std::vector<NaluIndex> FindNaluIndices(const uint8_t* buffer,
+ size_t buffer_size) {
+ return FindNaluIndices(rtc::MakeArrayView(buffer, buffer_size));
+}
// Get the NAL type from the header byte immediately following start sequence.
RTC_EXPORT NaluType ParseNaluType(uint8_t data);
@@ -83,12 +89,24 @@
// the 03 emulation byte.
// Parse the given data and remove any emulation byte escaping.
-std::vector<uint8_t> ParseRbsp(const uint8_t* data, size_t length);
+std::vector<uint8_t> ParseRbsp(rtc::ArrayView<const uint8_t> data);
+
+// TODO: bugs.webrtc.org/42225170 - Deprecate.
+inline std::vector<uint8_t> ParseRbsp(const uint8_t* data, size_t length) {
+ return ParseRbsp(rtc::MakeArrayView(data, length));
+}
// Write the given data to the destination buffer, inserting and emulation
// bytes in order to escape any data the could be interpreted as a start
// sequence.
-void WriteRbsp(const uint8_t* bytes, size_t length, rtc::Buffer* destination);
+void WriteRbsp(rtc::ArrayView<const uint8_t> bytes, rtc::Buffer* destination);
+
+// TODO: bugs.webrtc.org/42225170 - Deprecate.
+inline void WriteRbsp(const uint8_t* bytes,
+ size_t length,
+ rtc::Buffer* destination) {
+ WriteRbsp(rtc::MakeArrayView(bytes, length), destination);
+}
} // namespace H264
} // namespace webrtc
diff --git a/common_video/h264/pps_parser.cc b/common_video/h264/pps_parser.cc
index 46105d5..f12ab9b 100644
--- a/common_video/h264/pps_parser.cc
+++ b/common_video/h264/pps_parser.cc
@@ -29,16 +29,15 @@
// You can find it on this page:
// http://www.itu.int/rec/T-REC-H.264
-absl::optional<PpsParser::PpsState> PpsParser::ParsePps(const uint8_t* data,
- size_t length) {
+absl::optional<PpsParser::PpsState> PpsParser::ParsePps(
+ rtc::ArrayView<const uint8_t> data) {
// First, parse out rbsp, which is basically the source buffer minus emulation
// bytes (the last byte of a 0x00 0x00 0x03 sequence). RBSP is defined in
// section 7.3.1 of the H.264 standard.
- return ParseInternal(H264::ParseRbsp(data, length));
+ return ParseInternal(H264::ParseRbsp(data));
}
-bool PpsParser::ParsePpsIds(const uint8_t* data,
- size_t length,
+bool PpsParser::ParsePpsIds(rtc::ArrayView<const uint8_t> data,
uint32_t* pps_id,
uint32_t* sps_id) {
RTC_DCHECK(pps_id);
@@ -46,7 +45,7 @@
// First, parse out rbsp, which is basically the source buffer minus emulation
// bytes (the last byte of a 0x00 0x00 0x03 sequence). RBSP is defined in
// section 7.3.1 of the H.264 standard.
- std::vector<uint8_t> unpacked_buffer = H264::ParseRbsp(data, length);
+ std::vector<uint8_t> unpacked_buffer = H264::ParseRbsp(data);
BitstreamReader reader(unpacked_buffer);
*pps_id = reader.ReadExponentialGolomb();
*sps_id = reader.ReadExponentialGolomb();
@@ -54,9 +53,8 @@
}
absl::optional<PpsParser::SliceHeader> PpsParser::ParseSliceHeader(
- const uint8_t* data,
- size_t length) {
- std::vector<uint8_t> unpacked_buffer = H264::ParseRbsp(data, length);
+ rtc::ArrayView<const uint8_t> data) {
+ std::vector<uint8_t> unpacked_buffer = H264::ParseRbsp(data);
BitstreamReader slice_reader(unpacked_buffer);
PpsParser::SliceHeader slice_header;
diff --git a/common_video/h264/pps_parser.h b/common_video/h264/pps_parser.h
index 298c55e..d2d0609 100644
--- a/common_video/h264/pps_parser.h
+++ b/common_video/h264/pps_parser.h
@@ -47,15 +47,19 @@
};
// Unpack RBSP and parse PPS state from the supplied buffer.
- static absl::optional<PpsState> ParsePps(const uint8_t* data, size_t length);
+ static absl::optional<PpsState> ParsePps(rtc::ArrayView<const uint8_t> data);
+ // TODO: bugs.webrtc.org/42225170 - Deprecate.
+ static inline absl::optional<PpsState> ParsePps(const uint8_t* data,
+ size_t length) {
+ return ParsePps(rtc::MakeArrayView(data, length));
+ }
- static bool ParsePpsIds(const uint8_t* data,
- size_t length,
+ static bool ParsePpsIds(rtc::ArrayView<const uint8_t> data,
uint32_t* pps_id,
uint32_t* sps_id);
- static absl::optional<SliceHeader> ParseSliceHeader(const uint8_t* data,
- size_t length);
+ static absl::optional<SliceHeader> ParseSliceHeader(
+ rtc::ArrayView<const uint8_t> data);
protected:
// Parse the PPS state, for a buffer where RBSP decoding has already been
diff --git a/common_video/h264/pps_parser_unittest.cc b/common_video/h264/pps_parser_unittest.cc
index 833a39c..a325e8c 100644
--- a/common_video/h264/pps_parser_unittest.cc
+++ b/common_video/h264/pps_parser_unittest.cc
@@ -134,7 +134,7 @@
bit_buffer.GetCurrentOffset(&byte_offset, &bit_offset);
}
- H264::WriteRbsp(data, byte_offset, out_buffer);
+ H264::WriteRbsp(rtc::MakeArrayView(data, byte_offset), out_buffer);
}
class PpsParserTest : public ::testing::Test {
@@ -175,7 +175,7 @@
buffer_.Clear();
WritePps(pps, slice_group_map_type, num_slice_groups, pic_size_in_map_units,
&buffer_);
- parsed_pps_ = PpsParser::ParsePps(buffer_.data(), buffer_.size());
+ parsed_pps_ = PpsParser::ParsePps(buffer_);
ASSERT_TRUE(parsed_pps_);
EXPECT_EQ(pps.bottom_field_pic_order_in_frame_present_flag,
parsed_pps_->bottom_field_pic_order_in_frame_present_flag);
@@ -219,18 +219,17 @@
}
TEST_F(PpsParserTest, ParseSliceHeader) {
- std::vector<H264::NaluIndex> nalu_indices =
- H264::FindNaluIndices(kH264BitstreamChunk, sizeof(kH264BitstreamChunk));
+ rtc::ArrayView<const uint8_t> chunk(kH264BitstreamChunk);
+ std::vector<H264::NaluIndex> nalu_indices = H264::FindNaluIndices(chunk);
EXPECT_EQ(nalu_indices.size(), 3ull);
for (const auto& index : nalu_indices) {
H264::NaluType nalu_type =
- H264::ParseNaluType(kH264BitstreamChunk[index.payload_start_offset]);
+ H264::ParseNaluType(chunk[index.payload_start_offset]);
if (nalu_type == H264::NaluType::kIdr) {
// Skip NAL type header and parse slice header.
absl::optional<PpsParser::SliceHeader> slice_header =
- PpsParser::ParseSliceHeader(
- kH264BitstreamChunk + index.payload_start_offset + 1,
- index.payload_size - 1);
+ PpsParser::ParseSliceHeader(chunk.subview(
+ index.payload_start_offset + 1, index.payload_size - 1));
ASSERT_TRUE(slice_header.has_value());
EXPECT_EQ(slice_header->first_mb_in_slice, 0u);
EXPECT_EQ(slice_header->pic_parameter_set_id, 0u);
diff --git a/common_video/h264/sps_parser.cc b/common_video/h264/sps_parser.cc
index 6206c39..000e028 100644
--- a/common_video/h264/sps_parser.cc
+++ b/common_video/h264/sps_parser.cc
@@ -32,9 +32,9 @@
// http://www.itu.int/rec/T-REC-H.264
// Unpack RBSP and parse SPS state from the supplied buffer.
-absl::optional<SpsParser::SpsState> SpsParser::ParseSps(const uint8_t* data,
- size_t length) {
- std::vector<uint8_t> unpacked_buffer = H264::ParseRbsp(data, length);
+absl::optional<SpsParser::SpsState> SpsParser::ParseSps(
+ rtc::ArrayView<const uint8_t> data) {
+ std::vector<uint8_t> unpacked_buffer = H264::ParseRbsp(data);
BitstreamReader reader(unpacked_buffer);
return ParseSpsUpToVui(reader);
}
diff --git a/common_video/h264/sps_parser.h b/common_video/h264/sps_parser.h
index d0d7371..ae8df60 100644
--- a/common_video/h264/sps_parser.h
+++ b/common_video/h264/sps_parser.h
@@ -42,7 +42,12 @@
};
// Unpack RBSP and parse SPS state from the supplied buffer.
- static absl::optional<SpsState> ParseSps(const uint8_t* data, size_t length);
+ static absl::optional<SpsState> ParseSps(rtc::ArrayView<const uint8_t> data);
+ // TODO: bugs.webrtc.org/42225170 - Deprecate.
+ static inline absl::optional<SpsState> ParseSps(const uint8_t* data,
+ size_t length) {
+ return ParseSps(rtc::MakeArrayView(data, length));
+ }
protected:
// Parse the SPS state, up till the VUI part, for a buffer where RBSP
diff --git a/common_video/h264/sps_parser_unittest.cc b/common_video/h264/sps_parser_unittest.cc
index c9326e4..721aa3f 100644
--- a/common_video/h264/sps_parser_unittest.cc
+++ b/common_video/h264/sps_parser_unittest.cc
@@ -107,7 +107,7 @@
}
out_buffer->Clear();
- H264::WriteRbsp(rbsp, byte_count, out_buffer);
+ H264::WriteRbsp(rtc::MakeArrayView(rbsp, byte_count), out_buffer);
}
TEST(H264SpsParserTest, TestSampleSPSHdLandscape) {
@@ -116,8 +116,7 @@
const uint8_t buffer[] = {0x7A, 0x00, 0x1F, 0xBC, 0xD9, 0x40, 0x50, 0x05,
0xBA, 0x10, 0x00, 0x00, 0x03, 0x00, 0xC0, 0x00,
0x00, 0x2A, 0xE0, 0xF1, 0x83, 0x19, 0x60};
- absl::optional<SpsParser::SpsState> sps =
- SpsParser::ParseSps(buffer, arraysize(buffer));
+ absl::optional<SpsParser::SpsState> sps = SpsParser::ParseSps(buffer);
ASSERT_TRUE(sps.has_value());
EXPECT_EQ(1280u, sps->width);
EXPECT_EQ(720u, sps->height);
@@ -129,8 +128,7 @@
const uint8_t buffer[] = {0x7A, 0x00, 0x1E, 0xBC, 0xD9, 0x40, 0xA0, 0x2F,
0xF8, 0x98, 0x40, 0x00, 0x00, 0x03, 0x01, 0x80,
0x00, 0x00, 0x56, 0x83, 0xC5, 0x8B, 0x65, 0x80};
- absl::optional<SpsParser::SpsState> sps =
- SpsParser::ParseSps(buffer, arraysize(buffer));
+ absl::optional<SpsParser::SpsState> sps = SpsParser::ParseSps(buffer);
ASSERT_TRUE(sps.has_value());
EXPECT_EQ(640u, sps->width);
EXPECT_EQ(360u, sps->height);
@@ -142,8 +140,7 @@
const uint8_t buffer[] = {0x7A, 0x00, 0x0D, 0xBC, 0xD9, 0x43, 0x43, 0x3E,
0x5E, 0x10, 0x00, 0x00, 0x03, 0x00, 0x60, 0x00,
0x00, 0x15, 0xA0, 0xF1, 0x42, 0x99, 0x60};
- absl::optional<SpsParser::SpsState> sps =
- SpsParser::ParseSps(buffer, arraysize(buffer));
+ absl::optional<SpsParser::SpsState> sps = SpsParser::ParseSps(buffer);
ASSERT_TRUE(sps.has_value());
EXPECT_EQ(200u, sps->width);
EXPECT_EQ(400u, sps->height);
@@ -152,8 +149,7 @@
TEST(H264SpsParserTest, TestSyntheticSPSQvgaLandscape) {
rtc::Buffer buffer;
GenerateFakeSps(320u, 180u, 1, 0, 0, &buffer);
- absl::optional<SpsParser::SpsState> sps =
- SpsParser::ParseSps(buffer.data(), buffer.size());
+ absl::optional<SpsParser::SpsState> sps = SpsParser::ParseSps(buffer);
ASSERT_TRUE(sps.has_value());
EXPECT_EQ(320u, sps->width);
EXPECT_EQ(180u, sps->height);
@@ -163,8 +159,7 @@
TEST(H264SpsParserTest, TestSyntheticSPSWeirdResolution) {
rtc::Buffer buffer;
GenerateFakeSps(156u, 122u, 2, 0, 0, &buffer);
- absl::optional<SpsParser::SpsState> sps =
- SpsParser::ParseSps(buffer.data(), buffer.size());
+ absl::optional<SpsParser::SpsState> sps = SpsParser::ParseSps(buffer);
ASSERT_TRUE(sps.has_value());
EXPECT_EQ(156u, sps->width);
EXPECT_EQ(122u, sps->height);
@@ -178,8 +173,7 @@
0x10, 0xc2, 0x00, 0x84, 0x3b, 0x50, 0x3c, 0x01,
0x13, 0xf2, 0xcd, 0xc0, 0x40, 0x40, 0x50, 0x00,
0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xe8, 0x40};
- absl::optional<SpsParser::SpsState> sps =
- SpsParser::ParseSps(buffer, arraysize(buffer));
+ absl::optional<SpsParser::SpsState> sps = SpsParser::ParseSps(buffer);
ASSERT_TRUE(sps.has_value());
EXPECT_EQ(1920u, sps->width);
EXPECT_EQ(1080u, sps->height);
@@ -188,8 +182,7 @@
TEST(H264SpsParserTest, TestLog2MaxFrameNumMinus4) {
rtc::Buffer buffer;
GenerateFakeSps(320u, 180u, 1, 0, 0, &buffer);
- absl::optional<SpsParser::SpsState> sps =
- SpsParser::ParseSps(buffer.data(), buffer.size());
+ absl::optional<SpsParser::SpsState> sps = SpsParser::ParseSps(buffer);
ASSERT_TRUE(sps.has_value());
EXPECT_EQ(320u, sps->width);
EXPECT_EQ(180u, sps->height);
@@ -197,7 +190,7 @@
EXPECT_EQ(4u, sps->log2_max_frame_num);
GenerateFakeSps(320u, 180u, 1, 12, 0, &buffer);
- sps = SpsParser::ParseSps(buffer.data(), buffer.size());
+ sps = SpsParser::ParseSps(buffer);
ASSERT_TRUE(sps.has_value());
EXPECT_EQ(320u, sps->width);
EXPECT_EQ(180u, sps->height);
@@ -205,14 +198,13 @@
EXPECT_EQ(16u, sps->log2_max_frame_num);
GenerateFakeSps(320u, 180u, 1, 13, 0, &buffer);
- EXPECT_FALSE(SpsParser::ParseSps(buffer.data(), buffer.size()));
+ EXPECT_FALSE(SpsParser::ParseSps(buffer));
}
TEST(H264SpsParserTest, TestLog2MaxPicOrderCntMinus4) {
rtc::Buffer buffer;
GenerateFakeSps(320u, 180u, 1, 0, 0, &buffer);
- absl::optional<SpsParser::SpsState> sps =
- SpsParser::ParseSps(buffer.data(), buffer.size());
+ absl::optional<SpsParser::SpsState> sps = SpsParser::ParseSps(buffer);
ASSERT_TRUE(sps.has_value());
EXPECT_EQ(320u, sps->width);
EXPECT_EQ(180u, sps->height);
@@ -220,15 +212,14 @@
EXPECT_EQ(4u, sps->log2_max_pic_order_cnt_lsb);
GenerateFakeSps(320u, 180u, 1, 0, 12, &buffer);
- EXPECT_TRUE(static_cast<bool>(
- sps = SpsParser::ParseSps(buffer.data(), buffer.size())));
+ EXPECT_TRUE(static_cast<bool>(sps = SpsParser::ParseSps(buffer)));
EXPECT_EQ(320u, sps->width);
EXPECT_EQ(180u, sps->height);
EXPECT_EQ(1u, sps->id);
EXPECT_EQ(16u, sps->log2_max_pic_order_cnt_lsb);
GenerateFakeSps(320u, 180u, 1, 0, 13, &buffer);
- EXPECT_FALSE(SpsParser::ParseSps(buffer.data(), buffer.size()));
+ EXPECT_FALSE(SpsParser::ParseSps(buffer));
}
} // namespace webrtc
diff --git a/common_video/h264/sps_vui_rewriter.cc b/common_video/h264/sps_vui_rewriter.cc
index 117e92a..07b5805 100644
--- a/common_video/h264/sps_vui_rewriter.cc
+++ b/common_video/h264/sps_vui_rewriter.cc
@@ -135,14 +135,13 @@
}
SpsVuiRewriter::ParseResult SpsVuiRewriter::ParseAndRewriteSps(
- const uint8_t* buffer,
- size_t length,
+ rtc::ArrayView<const uint8_t> buffer,
absl::optional<SpsParser::SpsState>* sps,
const webrtc::ColorSpace* color_space,
rtc::Buffer* destination) {
// Create temporary RBSP decoded buffer of the payload (exlcuding the
// leading nalu type header byte (the SpsParser uses only the payload).
- std::vector<uint8_t> rbsp_buffer = H264::ParseRbsp(buffer, length);
+ std::vector<uint8_t> rbsp_buffer = H264::ParseRbsp(buffer);
BitstreamReader source_buffer(rbsp_buffer);
absl::optional<SpsParser::SpsState> sps_state =
SpsParser::ParseSpsUpToVui(source_buffer);
@@ -153,7 +152,7 @@
// We're going to completely muck up alignment, so we need a BitBufferWriter
// to write with.
- rtc::Buffer out_buffer(length + kMaxVuiSpsIncrease);
+ rtc::Buffer out_buffer(buffer.size() + kMaxVuiSpsIncrease);
rtc::BitBufferWriter sps_writer(out_buffer.data(), out_buffer.size());
// Check how far the SpsParser has read, and copy that data in bulk.
@@ -200,26 +199,25 @@
bit_offset = 0;
}
- RTC_DCHECK(byte_offset <= length + kMaxVuiSpsIncrease);
+ RTC_DCHECK(byte_offset <= buffer.size() + kMaxVuiSpsIncrease);
RTC_CHECK(destination != nullptr);
out_buffer.SetSize(byte_offset);
// Write updates SPS to destination with added RBSP
- H264::WriteRbsp(out_buffer.data(), out_buffer.size(), destination);
+ H264::WriteRbsp(out_buffer, destination);
return ParseResult::kVuiRewritten;
}
SpsVuiRewriter::ParseResult SpsVuiRewriter::ParseAndRewriteSps(
- const uint8_t* buffer,
- size_t length,
+ rtc::ArrayView<const uint8_t> buffer,
absl::optional<SpsParser::SpsState>* sps,
const webrtc::ColorSpace* color_space,
rtc::Buffer* destination,
Direction direction) {
ParseResult result =
- ParseAndRewriteSps(buffer, length, sps, color_space, destination);
+ ParseAndRewriteSps(buffer, sps, color_space, destination);
UpdateStats(result, direction);
return result;
}
@@ -227,22 +225,21 @@
rtc::Buffer SpsVuiRewriter::ParseOutgoingBitstreamAndRewrite(
rtc::ArrayView<const uint8_t> buffer,
const webrtc::ColorSpace* color_space) {
- std::vector<H264::NaluIndex> nalus =
- H264::FindNaluIndices(buffer.data(), buffer.size());
+ std::vector<H264::NaluIndex> nalus = H264::FindNaluIndices(buffer);
// Allocate some extra space for potentially adding a missing VUI.
rtc::Buffer output_buffer(/*size=*/0, /*capacity=*/buffer.size() +
nalus.size() * kMaxVuiSpsIncrease);
- for (const H264::NaluIndex& nalu : nalus) {
+ for (const H264::NaluIndex& nalu_index : nalus) {
// Copy NAL unit start code.
- const uint8_t* start_code_ptr = buffer.data() + nalu.start_offset;
- const size_t start_code_length =
- nalu.payload_start_offset - nalu.start_offset;
- const uint8_t* nalu_ptr = buffer.data() + nalu.payload_start_offset;
- const size_t nalu_length = nalu.payload_size;
+ rtc::ArrayView<const uint8_t> start_code = buffer.subview(
+ nalu_index.start_offset,
+ nalu_index.payload_start_offset - nalu_index.start_offset);
+ rtc::ArrayView<const uint8_t> nalu = buffer.subview(
+ nalu_index.payload_start_offset, nalu_index.payload_size);
- if (H264::ParseNaluType(nalu_ptr[0]) == H264::NaluType::kSps) {
+ if (H264::ParseNaluType(nalu[0]) == H264::NaluType::kSps) {
// Check if stream uses picture order count type 0, and if so rewrite it
// to enable faster decoding. Streams in that format incur additional
// delay because it allows decode order to differ from render order.
@@ -259,24 +256,24 @@
// Add the type header to the output buffer first, so that the rewriter
// can append modified payload on top of that.
- output_nalu.AppendData(nalu_ptr[0]);
+ output_nalu.AppendData(nalu[0]);
- ParseResult result = ParseAndRewriteSps(
- nalu_ptr + H264::kNaluTypeSize, nalu_length - H264::kNaluTypeSize,
- &sps, color_space, &output_nalu, Direction::kOutgoing);
+ ParseResult result =
+ ParseAndRewriteSps(nalu.subview(H264::kNaluTypeSize), &sps,
+ color_space, &output_nalu, Direction::kOutgoing);
if (result == ParseResult::kVuiRewritten) {
- output_buffer.AppendData(start_code_ptr, start_code_length);
+ output_buffer.AppendData(start_code);
output_buffer.AppendData(output_nalu.data(), output_nalu.size());
continue;
}
- } else if (H264::ParseNaluType(nalu_ptr[0]) == H264::NaluType::kAud) {
+ } else if (H264::ParseNaluType(nalu[0]) == H264::NaluType::kAud) {
// Skip the access unit delimiter copy.
continue;
}
// vui wasn't rewritten and it is not aud, copy the nal unit as is.
- output_buffer.AppendData(start_code_ptr, start_code_length);
- output_buffer.AppendData(nalu_ptr, nalu_length);
+ output_buffer.AppendData(start_code);
+ output_buffer.AppendData(nalu);
}
return output_buffer;
}
diff --git a/common_video/h264/sps_vui_rewriter.h b/common_video/h264/sps_vui_rewriter.h
index ef80d5b..66f7e1a 100644
--- a/common_video/h264/sps_vui_rewriter.h
+++ b/common_video/h264/sps_vui_rewriter.h
@@ -43,8 +43,7 @@
// (NALU start, type, Stap-A, etc) have already been parsed and that RBSP
// decoding has been performed.
static ParseResult ParseAndRewriteSps(
- const uint8_t* buffer,
- size_t length,
+ rtc::ArrayView<const uint8_t> buffer,
absl::optional<SpsParser::SpsState>* sps,
const ColorSpace* color_space,
rtc::Buffer* destination,
@@ -58,8 +57,7 @@
private:
static ParseResult ParseAndRewriteSps(
- const uint8_t* buffer,
- size_t length,
+ rtc::ArrayView<const uint8_t> buffer,
absl::optional<SpsParser::SpsState>* sps,
const ColorSpace* color_space,
rtc::Buffer* destination);
diff --git a/common_video/h264/sps_vui_rewriter_unittest.cc b/common_video/h264/sps_vui_rewriter_unittest.cc
index 2907949..d440905 100644
--- a/common_video/h264/sps_vui_rewriter_unittest.cc
+++ b/common_video/h264/sps_vui_rewriter_unittest.cc
@@ -297,7 +297,7 @@
byte_count++;
}
- H264::WriteRbsp(rbsp, byte_count, out_buffer);
+ H264::WriteRbsp(rtc::MakeArrayView(rbsp, byte_count), out_buffer);
}
void TestSps(const VuiHeader& vui,
@@ -310,8 +310,8 @@
absl::optional<SpsParser::SpsState> sps;
rtc::Buffer rewritten_sps;
SpsVuiRewriter::ParseResult result = SpsVuiRewriter::ParseAndRewriteSps(
- original_sps.data(), original_sps.size(), &sps, color_space,
- &rewritten_sps, SpsVuiRewriter::Direction::kIncoming);
+ original_sps, &sps, color_space, &rewritten_sps,
+ SpsVuiRewriter::Direction::kIncoming);
EXPECT_EQ(expected_parse_result, result);
ASSERT_TRUE(sps);
EXPECT_EQ(sps->width, kWidth);
@@ -324,7 +324,7 @@
// Ensure that added/rewritten SPS is parsable.
rtc::Buffer tmp;
result = SpsVuiRewriter::ParseAndRewriteSps(
- rewritten_sps.data(), rewritten_sps.size(), &sps, nullptr, &tmp,
+ rewritten_sps, &sps, nullptr, &tmp,
SpsVuiRewriter::Direction::kIncoming);
EXPECT_EQ(SpsVuiRewriter::ParseResult::kVuiOk, result);
ASSERT_TRUE(sps);
diff --git a/common_video/h265/h265_bitstream_parser.cc b/common_video/h265/h265_bitstream_parser.cc
index 3287d78..c9d17b0 100644
--- a/common_video/h265/h265_bitstream_parser.cc
+++ b/common_video/h265/h265_bitstream_parser.cc
@@ -80,13 +80,11 @@
// section 7.3.6.1. You can find it on this page:
// http://www.itu.int/rec/T-REC-H.265
H265BitstreamParser::Result H265BitstreamParser::ParseNonParameterSetNalu(
- const uint8_t* source,
- size_t source_length,
+ rtc::ArrayView<const uint8_t> source,
uint8_t nalu_type) {
last_slice_qp_delta_ = absl::nullopt;
last_slice_pps_id_ = absl::nullopt;
- const std::vector<uint8_t> slice_rbsp =
- H265::ParseRbsp(source, source_length);
+ const std::vector<uint8_t> slice_rbsp = H265::ParseRbsp(source);
if (slice_rbsp.size() < H265::kNaluHeaderSize)
return kInvalidStream;
@@ -420,14 +418,14 @@
return &it->second;
}
-void H265BitstreamParser::ParseSlice(const uint8_t* slice, size_t length) {
+void H265BitstreamParser::ParseSlice(rtc::ArrayView<const uint8_t> slice) {
H265::NaluType nalu_type = H265::ParseNaluType(slice[0]);
switch (nalu_type) {
case H265::NaluType::kVps: {
absl::optional<H265VpsParser::VpsState> vps_state;
- if (length >= H265::kNaluHeaderSize) {
- vps_state = H265VpsParser::ParseVps(slice + H265::kNaluHeaderSize,
- length - H265::kNaluHeaderSize);
+ if (slice.size() >= H265::kNaluHeaderSize) {
+ vps_state =
+ H265VpsParser::ParseVps(slice.subview(H265::kNaluHeaderSize));
}
if (!vps_state) {
@@ -439,9 +437,9 @@
}
case H265::NaluType::kSps: {
absl::optional<H265SpsParser::SpsState> sps_state;
- if (length >= H265::kNaluHeaderSize) {
- sps_state = H265SpsParser::ParseSps(slice + H265::kNaluHeaderSize,
- length - H265::kNaluHeaderSize);
+ if (slice.size() >= H265::kNaluHeaderSize) {
+ sps_state =
+ H265SpsParser::ParseSps(slice.subview(H265::kNaluHeaderSize));
}
if (!sps_state) {
RTC_LOG(LS_WARNING) << "Unable to parse SPS from H265 bitstream.";
@@ -452,9 +450,9 @@
}
case H265::NaluType::kPps: {
absl::optional<H265PpsParser::PpsState> pps_state;
- if (length >= H265::kNaluHeaderSize) {
- std::vector<uint8_t> unpacked_buffer = H265::ParseRbsp(
- slice + H265::kNaluHeaderSize, length - H265::kNaluHeaderSize);
+ if (slice.size() >= H265::kNaluHeaderSize) {
+ std::vector<uint8_t> unpacked_buffer =
+ H265::ParseRbsp(slice.subview(H265::kNaluHeaderSize));
BitstreamReader slice_reader(unpacked_buffer);
// pic_parameter_set_id: ue(v)
uint32_t pps_id = slice_reader.ReadExponentialGolomb();
@@ -463,8 +461,8 @@
uint32_t sps_id = slice_reader.ReadExponentialGolomb();
IN_RANGE_OR_RETURN_VOID(sps_id, 0, 15);
const H265SpsParser::SpsState* sps = GetSPS(sps_id);
- pps_state = H265PpsParser::ParsePps(
- slice + H265::kNaluHeaderSize, length - H265::kNaluHeaderSize, sps);
+ pps_state =
+ H265PpsParser::ParsePps(slice.subview(H265::kNaluHeaderSize), sps);
}
if (!pps_state) {
RTC_LOG(LS_WARNING) << "Unable to parse PPS from H265 bitstream.";
@@ -480,7 +478,7 @@
case H265::NaluType::kFu:
break;
default:
- Result res = ParseNonParameterSetNalu(slice, length, nalu_type);
+ Result res = ParseNonParameterSetNalu(slice, nalu_type);
if (res != kOk) {
RTC_LOG(LS_INFO) << "Failed to parse bitstream. Error: " << res;
}
@@ -489,10 +487,10 @@
}
absl::optional<uint32_t>
-H265BitstreamParser::ParsePpsIdFromSliceSegmentLayerRbsp(const uint8_t* data,
- size_t length,
- uint8_t nalu_type) {
- std::vector<uint8_t> unpacked_buffer = H265::ParseRbsp(data, length);
+H265BitstreamParser::ParsePpsIdFromSliceSegmentLayerRbsp(
+ rtc::ArrayView<const uint8_t> data,
+ uint8_t nalu_type) {
+ std::vector<uint8_t> unpacked_buffer = H265::ParseRbsp(data);
BitstreamReader slice_reader(unpacked_buffer);
// first_slice_segment_in_pic_flag: u(1)
@@ -519,10 +517,10 @@
void H265BitstreamParser::ParseBitstream(
rtc::ArrayView<const uint8_t> bitstream) {
- std::vector<H265::NaluIndex> nalu_indices =
- H265::FindNaluIndices(bitstream.data(), bitstream.size());
+ std::vector<H265::NaluIndex> nalu_indices = H265::FindNaluIndices(bitstream);
for (const H265::NaluIndex& index : nalu_indices)
- ParseSlice(&bitstream[index.payload_start_offset], index.payload_size);
+ ParseSlice(
+ bitstream.subview(index.payload_start_offset, index.payload_size));
}
absl::optional<int> H265BitstreamParser::GetLastSliceQp() const {
diff --git a/common_video/h265/h265_bitstream_parser.h b/common_video/h265/h265_bitstream_parser.h
index 48f27ef..cf18ccb 100644
--- a/common_video/h265/h265_bitstream_parser.h
+++ b/common_video/h265/h265_bitstream_parser.h
@@ -40,8 +40,7 @@
absl::optional<uint32_t> GetLastSlicePpsId() const;
static absl::optional<uint32_t> ParsePpsIdFromSliceSegmentLayerRbsp(
- const uint8_t* data,
- size_t length,
+ rtc::ArrayView<const uint8_t> data,
uint8_t nalu_type);
protected:
@@ -50,9 +49,8 @@
kInvalidStream,
kUnsupportedStream,
};
- void ParseSlice(const uint8_t* slice, size_t length);
- Result ParseNonParameterSetNalu(const uint8_t* source,
- size_t source_length,
+ void ParseSlice(rtc::ArrayView<const uint8_t> slice);
+ Result ParseNonParameterSetNalu(rtc::ArrayView<const uint8_t> source,
uint8_t nalu_type);
const H265PpsParser::PpsState* GetPPS(uint32_t id) const;
diff --git a/common_video/h265/h265_bitstream_parser_unittest.cc b/common_video/h265/h265_bitstream_parser_unittest.cc
index 7ca9794..5889c70 100644
--- a/common_video/h265/h265_bitstream_parser_unittest.cc
+++ b/common_video/h265/h265_bitstream_parser_unittest.cc
@@ -127,8 +127,8 @@
TEST(H265BitstreamParserTest, PpsIdFromSlice) {
H265BitstreamParser h265_parser;
absl::optional<uint32_t> pps_id =
- h265_parser.ParsePpsIdFromSliceSegmentLayerRbsp(
- kH265SliceChunk, sizeof(kH265SliceChunk), H265::NaluType::kTrailR);
+ h265_parser.ParsePpsIdFromSliceSegmentLayerRbsp(kH265SliceChunk,
+ H265::NaluType::kTrailR);
ASSERT_TRUE(pps_id);
EXPECT_EQ(1u, *pps_id);
}
diff --git a/common_video/h265/h265_common.cc b/common_video/h265/h265_common.cc
index 7086449..28b29e9 100644
--- a/common_video/h265/h265_common.cc
+++ b/common_video/h265/h265_common.cc
@@ -17,10 +17,8 @@
constexpr uint8_t kNaluTypeMask = 0x7E;
-std::vector<NaluIndex> FindNaluIndices(const uint8_t* buffer,
- size_t buffer_size) {
- std::vector<H264::NaluIndex> indices =
- H264::FindNaluIndices(buffer, buffer_size);
+std::vector<NaluIndex> FindNaluIndices(rtc::ArrayView<const uint8_t> buffer) {
+ std::vector<H264::NaluIndex> indices = H264::FindNaluIndices(buffer);
std::vector<NaluIndex> results;
for (auto& index : indices) {
results.push_back(
@@ -33,12 +31,12 @@
return static_cast<NaluType>((data & kNaluTypeMask) >> 1);
}
-std::vector<uint8_t> ParseRbsp(const uint8_t* data, size_t length) {
- return H264::ParseRbsp(data, length);
+std::vector<uint8_t> ParseRbsp(rtc::ArrayView<const uint8_t> data) {
+ return H264::ParseRbsp(data);
}
-void WriteRbsp(const uint8_t* bytes, size_t length, rtc::Buffer* destination) {
- H264::WriteRbsp(bytes, length, destination);
+void WriteRbsp(rtc::ArrayView<const uint8_t> bytes, rtc::Buffer* destination) {
+ H264::WriteRbsp(bytes, destination);
}
uint32_t Log2Ceiling(uint32_t value) {
diff --git a/common_video/h265/h265_common.h b/common_video/h265/h265_common.h
index b9186dc..50ca1b3 100644
--- a/common_video/h265/h265_common.h
+++ b/common_video/h265/h265_common.h
@@ -77,8 +77,14 @@
};
// Returns a vector of the NALU indices in the given buffer.
-RTC_EXPORT std::vector<NaluIndex> FindNaluIndices(const uint8_t* buffer,
- size_t buffer_size);
+RTC_EXPORT std::vector<NaluIndex> FindNaluIndices(
+ rtc::ArrayView<const uint8_t> buffer);
+
+// TODO: bugs.webrtc.org/42225170 - Deprecate.
+inline std::vector<NaluIndex> FindNaluIndices(const uint8_t* buffer,
+ size_t buffer_size) {
+ return FindNaluIndices(rtc::MakeArrayView(buffer, buffer_size));
+}
// Get the NAL type from the header byte immediately following start sequence.
RTC_EXPORT NaluType ParseNaluType(uint8_t data);
@@ -97,12 +103,24 @@
// the 03 emulation byte.
// Parse the given data and remove any emulation byte escaping.
-std::vector<uint8_t> ParseRbsp(const uint8_t* data, size_t length);
+std::vector<uint8_t> ParseRbsp(rtc::ArrayView<const uint8_t> data);
+
+// TODO: bugs.webrtc.org/42225170 - Deprecate.
+inline std::vector<uint8_t> ParseRbsp(const uint8_t* data, size_t length) {
+ return ParseRbsp(rtc::MakeArrayView(data, length));
+}
// Write the given data to the destination buffer, inserting and emulation
// bytes in order to escape any data the could be interpreted as a start
// sequence.
-void WriteRbsp(const uint8_t* bytes, size_t length, rtc::Buffer* destination);
+void WriteRbsp(rtc::ArrayView<const uint8_t> bytes, rtc::Buffer* destination);
+
+// TODO: bugs.webrtc.org/42225170 - Deprecate.
+inline void WriteRbsp(const uint8_t* bytes,
+ size_t length,
+ rtc::Buffer* destination) {
+ WriteRbsp(rtc::MakeArrayView(bytes, length), destination);
+}
uint32_t Log2Ceiling(uint32_t value);
diff --git a/common_video/h265/h265_pps_parser.cc b/common_video/h265/h265_pps_parser.cc
index 1cc9abd..3339f65 100644
--- a/common_video/h265/h265_pps_parser.cc
+++ b/common_video/h265/h265_pps_parser.cc
@@ -63,17 +63,15 @@
// http://www.itu.int/rec/T-REC-H.265
absl::optional<H265PpsParser::PpsState> H265PpsParser::ParsePps(
- const uint8_t* data,
- size_t length,
+ rtc::ArrayView<const uint8_t> data,
const H265SpsParser::SpsState* sps) {
// First, parse out rbsp, which is basically the source buffer minus emulation
// bytes (the last byte of a 0x00 0x00 0x03 sequence). RBSP is defined in
// section 7.3.1.1 of the H.265 standard.
- return ParseInternal(H265::ParseRbsp(data, length), sps);
+ return ParseInternal(H265::ParseRbsp(data), sps);
}
-bool H265PpsParser::ParsePpsIds(const uint8_t* data,
- size_t length,
+bool H265PpsParser::ParsePpsIds(rtc::ArrayView<const uint8_t> data,
uint32_t* pps_id,
uint32_t* sps_id) {
RTC_DCHECK(pps_id);
@@ -81,7 +79,7 @@
// First, parse out rbsp, which is basically the source buffer minus emulation
// bytes (the last byte of a 0x00 0x00 0x03 sequence). RBSP is defined in
// section 7.3.1.1 of the H.265 standard.
- std::vector<uint8_t> unpacked_buffer = H265::ParseRbsp(data, length);
+ std::vector<uint8_t> unpacked_buffer = H265::ParseRbsp(data);
BitstreamReader reader(unpacked_buffer);
*pps_id = reader.ReadExponentialGolomb();
IN_RANGE_OR_RETURN_FALSE(*pps_id, 0, 63);
diff --git a/common_video/h265/h265_pps_parser.h b/common_video/h265/h265_pps_parser.h
index 62bc18f..1bd0ead 100644
--- a/common_video/h265/h265_pps_parser.h
+++ b/common_video/h265/h265_pps_parser.h
@@ -43,14 +43,26 @@
};
// Unpack RBSP and parse PPS state from the supplied buffer.
- static absl::optional<PpsState> ParsePps(const uint8_t* data,
- size_t length,
+ static absl::optional<PpsState> ParsePps(rtc::ArrayView<const uint8_t> data,
const H265SpsParser::SpsState* sps);
+ // TODO: bugs.webrtc.org/42225170 - Deprecate.
+ static inline absl::optional<PpsState> ParsePps(
+ const uint8_t* data,
+ size_t length,
+ const H265SpsParser::SpsState* sps) {
+ return ParsePps(rtc::MakeArrayView(data, length), sps);
+ }
- static bool ParsePpsIds(const uint8_t* data,
- size_t length,
+ static bool ParsePpsIds(rtc::ArrayView<const uint8_t> data,
uint32_t* pps_id,
uint32_t* sps_id);
+ // TODO: bugs.webrtc.org/42225170 - Deprecate.
+ static inline bool ParsePpsIds(const uint8_t* data,
+ size_t length,
+ uint32_t* pps_id,
+ uint32_t* sps_id) {
+ return ParsePpsIds(rtc::MakeArrayView(data, length), pps_id, sps_id);
+ }
protected:
// Parse the PPS state, for a bit buffer where RBSP decoding has already been
diff --git a/common_video/h265/h265_pps_parser_unittest.cc b/common_video/h265/h265_pps_parser_unittest.cc
index d91fc1a..c683a43 100644
--- a/common_video/h265/h265_pps_parser_unittest.cc
+++ b/common_video/h265/h265_pps_parser_unittest.cc
@@ -161,7 +161,7 @@
bit_buffer.GetCurrentOffset(&byte_offset, &bit_offset);
}
- H265::WriteRbsp(data, byte_offset, out_buffer);
+ H265::WriteRbsp(rtc::MakeArrayView(data, byte_offset), out_buffer);
}
class H265PpsParserTest : public ::testing::Test {
@@ -196,9 +196,8 @@
0x16, 0x59, 0x59, 0xa4, 0x93, 0x2b, 0x80, 0x40, 0x00, 0x00,
0x03, 0x00, 0x40, 0x00, 0x00, 0x07, 0x82};
H265SpsParser::SpsState parsed_sps =
- H265SpsParser::ParseSps(sps_buffer, arraysize(sps_buffer)).value();
- parsed_pps_ =
- H265PpsParser::ParsePps(buffer_.data(), buffer_.size(), &parsed_sps);
+ H265SpsParser::ParseSps(sps_buffer).value();
+ parsed_pps_ = H265PpsParser::ParsePps(buffer_, &parsed_sps);
ASSERT_TRUE(parsed_pps_);
EXPECT_EQ(pps.dependent_slice_segments_enabled_flag,
parsed_pps_->dependent_slice_segments_enabled_flag);
diff --git a/common_video/h265/h265_sps_parser.cc b/common_video/h265/h265_sps_parser.cc
index a2da4b9..cb59d60 100644
--- a/common_video/h265/h265_sps_parser.cc
+++ b/common_video/h265/h265_sps_parser.cc
@@ -104,10 +104,8 @@
// Unpack RBSP and parse SPS state from the supplied buffer.
absl::optional<H265SpsParser::SpsState> H265SpsParser::ParseSps(
- const uint8_t* data,
- size_t length) {
- RTC_DCHECK(data);
- return ParseSpsInternal(H265::ParseRbsp(data, length));
+ rtc::ArrayView<const uint8_t> data) {
+ return ParseSpsInternal(H265::ParseRbsp(data));
}
bool H265SpsParser::ParseScalingListData(BitstreamReader& reader) {
diff --git a/common_video/h265/h265_sps_parser.h b/common_video/h265/h265_sps_parser.h
index 7ec1706..072e2e9 100644
--- a/common_video/h265/h265_sps_parser.h
+++ b/common_video/h265/h265_sps_parser.h
@@ -104,7 +104,12 @@
};
// Unpack RBSP and parse SPS state from the supplied buffer.
- static absl::optional<SpsState> ParseSps(const uint8_t* data, size_t length);
+ static absl::optional<SpsState> ParseSps(rtc::ArrayView<const uint8_t> data);
+ // TODO: bugs.webrtc.org/42225170 - Deprecate.
+ static inline absl::optional<SpsState> ParseSps(const uint8_t* data,
+ size_t length) {
+ return ParseSps(rtc::MakeArrayView(data, length));
+ }
static bool ParseScalingListData(BitstreamReader& reader);
diff --git a/common_video/h265/h265_sps_parser_unittest.cc b/common_video/h265/h265_sps_parser_unittest.cc
index 26af4b1..46d8d2d 100644
--- a/common_video/h265/h265_sps_parser_unittest.cc
+++ b/common_video/h265/h265_sps_parser_unittest.cc
@@ -365,7 +365,7 @@
}
out_buffer->Clear();
- H265::WriteRbsp(rbsp, byte_count, out_buffer);
+ H265::WriteRbsp(rtc::MakeArrayView(rbsp, byte_count), out_buffer);
}
class H265SpsParserTest : public ::testing::Test {
@@ -389,8 +389,7 @@
0x02, 0x80, 0x80, 0x2d, 0x16, 0x59, 0x59, 0xa4,
0x93, 0x2b, 0x80, 0x40, 0x00, 0x00, 0x03, 0x00,
0x40, 0x00, 0x00, 0x07, 0x82};
- absl::optional<H265SpsParser::SpsState> sps =
- H265SpsParser::ParseSps(buffer, arraysize(buffer));
+ absl::optional<H265SpsParser::SpsState> sps = H265SpsParser::ParseSps(buffer);
ASSERT_TRUE(sps.has_value());
EXPECT_EQ(1280u, sps->width);
EXPECT_EQ(720u, sps->height);
@@ -418,8 +417,7 @@
0x05, 0x02, 0x01, 0x09, 0xf2, 0xe5, 0x95, 0x9a,
0x49, 0x32, 0xb8, 0x04, 0x00, 0x00, 0x03, 0x00,
0x04, 0x00, 0x00, 0x03, 0x00, 0x78, 0x20};
- absl::optional<H265SpsParser::SpsState> sps =
- H265SpsParser::ParseSps(buffer, arraysize(buffer));
+ absl::optional<H265SpsParser::SpsState> sps = H265SpsParser::ParseSps(buffer);
ASSERT_TRUE(sps.has_value());
EXPECT_EQ(640u, sps->width);
EXPECT_EQ(260u, sps->height);
@@ -446,8 +444,7 @@
0x08, 0x48, 0x04, 0x27, 0x72, 0xe5, 0x95, 0x9a,
0x49, 0x32, 0xb8, 0x04, 0x00, 0x00, 0x03, 0x00,
0x04, 0x00, 0x00, 0x03, 0x00, 0x78, 0x20};
- absl::optional<H265SpsParser::SpsState> sps =
- H265SpsParser::ParseSps(buffer, arraysize(buffer));
+ absl::optional<H265SpsParser::SpsState> sps = H265SpsParser::ParseSps(buffer);
ASSERT_TRUE(sps.has_value());
EXPECT_EQ(260u, sps->width);
EXPECT_EQ(260u, sps->height);
@@ -456,8 +453,7 @@
TEST_F(H265SpsParserTest, TestSyntheticSPSQvgaLandscape) {
rtc::Buffer buffer;
WriteSps(320u, 180u, 1, 0, 1, 0, &buffer);
- absl::optional<H265SpsParser::SpsState> sps =
- H265SpsParser::ParseSps(buffer.data(), buffer.size());
+ absl::optional<H265SpsParser::SpsState> sps = H265SpsParser::ParseSps(buffer);
ASSERT_TRUE(sps.has_value());
EXPECT_EQ(320u, sps->width);
EXPECT_EQ(180u, sps->height);
@@ -467,8 +463,7 @@
TEST_F(H265SpsParserTest, TestSyntheticSPSWeirdResolution) {
rtc::Buffer buffer;
WriteSps(156u, 122u, 2, 0, 1, 0, &buffer);
- absl::optional<H265SpsParser::SpsState> sps =
- H265SpsParser::ParseSps(buffer.data(), buffer.size());
+ absl::optional<H265SpsParser::SpsState> sps = H265SpsParser::ParseSps(buffer);
ASSERT_TRUE(sps.has_value());
EXPECT_EQ(156u, sps->width);
EXPECT_EQ(122u, sps->height);
@@ -478,8 +473,7 @@
TEST_F(H265SpsParserTest, TestLog2MaxSubLayersMinus1) {
rtc::Buffer buffer;
WriteSps(320u, 180u, 1, 0, 1, 0, &buffer);
- absl::optional<H265SpsParser::SpsState> sps =
- H265SpsParser::ParseSps(buffer.data(), buffer.size());
+ absl::optional<H265SpsParser::SpsState> sps = H265SpsParser::ParseSps(buffer);
ASSERT_TRUE(sps.has_value());
EXPECT_EQ(320u, sps->width);
EXPECT_EQ(180u, sps->height);
@@ -488,7 +482,7 @@
WriteSps(320u, 180u, 1, 6, 1, 0, &buffer);
absl::optional<H265SpsParser::SpsState> sps1 =
- H265SpsParser::ParseSps(buffer.data(), buffer.size());
+ H265SpsParser::ParseSps(buffer);
ASSERT_TRUE(sps1.has_value());
EXPECT_EQ(320u, sps1->width);
EXPECT_EQ(180u, sps1->height);
@@ -497,15 +491,14 @@
WriteSps(320u, 180u, 1, 7, 1, 0, &buffer);
absl::optional<H265SpsParser::SpsState> result =
- H265SpsParser::ParseSps(buffer.data(), buffer.size());
+ H265SpsParser::ParseSps(buffer);
EXPECT_FALSE(result.has_value());
}
TEST_F(H265SpsParserTest, TestSubLayerOrderingInfoPresentFlag) {
rtc::Buffer buffer;
WriteSps(320u, 180u, 1, 6, 1, 0, &buffer);
- absl::optional<H265SpsParser::SpsState> sps =
- H265SpsParser::ParseSps(buffer.data(), buffer.size());
+ absl::optional<H265SpsParser::SpsState> sps = H265SpsParser::ParseSps(buffer);
ASSERT_TRUE(sps.has_value());
EXPECT_EQ(320u, sps->width);
EXPECT_EQ(180u, sps->height);
@@ -514,7 +507,7 @@
WriteSps(320u, 180u, 1, 6, 1, 0, &buffer);
absl::optional<H265SpsParser::SpsState> sps1 =
- H265SpsParser::ParseSps(buffer.data(), buffer.size());
+ H265SpsParser::ParseSps(buffer);
ASSERT_TRUE(sps1.has_value());
EXPECT_EQ(320u, sps1->width);
EXPECT_EQ(180u, sps1->height);
@@ -525,8 +518,7 @@
TEST_F(H265SpsParserTest, TestLongTermRefPicsPresentFlag) {
rtc::Buffer buffer;
WriteSps(320u, 180u, 1, 0, 1, 0, &buffer);
- absl::optional<H265SpsParser::SpsState> sps =
- H265SpsParser::ParseSps(buffer.data(), buffer.size());
+ absl::optional<H265SpsParser::SpsState> sps = H265SpsParser::ParseSps(buffer);
ASSERT_TRUE(sps.has_value());
EXPECT_EQ(320u, sps->width);
EXPECT_EQ(180u, sps->height);
@@ -535,7 +527,7 @@
WriteSps(320u, 180u, 1, 6, 1, 1, &buffer);
absl::optional<H265SpsParser::SpsState> sps1 =
- H265SpsParser::ParseSps(buffer.data(), buffer.size());
+ H265SpsParser::ParseSps(buffer);
ASSERT_TRUE(sps1.has_value());
EXPECT_EQ(320u, sps1->width);
EXPECT_EQ(180u, sps1->height);
diff --git a/common_video/h265/h265_vps_parser.cc b/common_video/h265/h265_vps_parser.cc
index 16b967d..0a00370 100644
--- a/common_video/h265/h265_vps_parser.cc
+++ b/common_video/h265/h265_vps_parser.cc
@@ -25,10 +25,8 @@
// Unpack RBSP and parse VPS state from the supplied buffer.
absl::optional<H265VpsParser::VpsState> H265VpsParser::ParseVps(
- const uint8_t* data,
- size_t length) {
- RTC_DCHECK(data);
- return ParseInternal(H265::ParseRbsp(data, length));
+ rtc::ArrayView<const uint8_t> data) {
+ return ParseInternal(H265::ParseRbsp(data));
}
absl::optional<H265VpsParser::VpsState> H265VpsParser::ParseInternal(
diff --git a/common_video/h265/h265_vps_parser.h b/common_video/h265/h265_vps_parser.h
index c793996..e8ca1a0 100644
--- a/common_video/h265/h265_vps_parser.h
+++ b/common_video/h265/h265_vps_parser.h
@@ -29,7 +29,12 @@
};
// Unpack RBSP and parse VPS state from the supplied buffer.
- static absl::optional<VpsState> ParseVps(const uint8_t* data, size_t length);
+ static absl::optional<VpsState> ParseVps(rtc::ArrayView<const uint8_t> data);
+ // TODO: bugs.webrtc.org/42225170 - Deprecate.
+ static inline absl::optional<VpsState> ParseVps(const uint8_t* data,
+ size_t length) {
+ return ParseVps(rtc::MakeArrayView(data, length));
+ }
protected:
// Parse the VPS state, for a bit buffer where RBSP decoding has already been
diff --git a/common_video/h265/h265_vps_parser_unittest.cc b/common_video/h265/h265_vps_parser_unittest.cc
index 24e8a77..87e1f58 100644
--- a/common_video/h265/h265_vps_parser_unittest.cc
+++ b/common_video/h265/h265_vps_parser_unittest.cc
@@ -41,8 +41,7 @@
0x1c, 0x01, 0xff, 0xff, 0x04, 0x08, 0x00, 0x00, 0x03, 0x00, 0x9d,
0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x78, 0x95, 0x98, 0x09,
};
- EXPECT_TRUE(static_cast<bool>(
- vps_ = H265VpsParser::ParseVps(buffer, arraysize(buffer))));
+ EXPECT_TRUE(static_cast<bool>(vps_ = H265VpsParser::ParseVps(buffer)));
EXPECT_EQ(1u, vps_->id);
}
diff --git a/modules/rtp_rtcp/source/rtp_format_h264.cc b/modules/rtp_rtcp/source/rtp_format_h264.cc
index 9c1dc4e..7e11add 100644
--- a/modules/rtp_rtcp/source/rtp_format_h264.cc
+++ b/modules/rtp_rtcp/source/rtp_format_h264.cc
@@ -48,8 +48,7 @@
RTC_CHECK(packetization_mode == H264PacketizationMode::NonInterleaved ||
packetization_mode == H264PacketizationMode::SingleNalUnit);
- for (const auto& nalu :
- H264::FindNaluIndices(payload.data(), payload.size())) {
+ for (const auto& nalu : H264::FindNaluIndices(payload)) {
input_fragments_.push_back(
payload.subview(nalu.payload_start_offset, nalu.payload_size));
}
diff --git a/modules/rtp_rtcp/source/rtp_packetizer_h265.cc b/modules/rtp_rtcp/source/rtp_packetizer_h265.cc
index 775c50c..901b68b 100644
--- a/modules/rtp_rtcp/source/rtp_packetizer_h265.cc
+++ b/modules/rtp_rtcp/source/rtp_packetizer_h265.cc
@@ -24,8 +24,7 @@
RtpPacketizerH265::RtpPacketizerH265(rtc::ArrayView<const uint8_t> payload,
PayloadSizeLimits limits)
: limits_(limits), num_packets_left_(0) {
- for (const auto& nalu :
- H264::FindNaluIndices(payload.data(), payload.size())) {
+ for (const auto& nalu : H264::FindNaluIndices(payload)) {
if (!nalu.payload_size) {
input_fragments_.clear();
return;
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_h264.cc b/modules/rtp_rtcp/source/video_rtp_depacketizer_h264.cc
index 60fc545..fa48b7f 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_h264.cc
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_h264.cc
@@ -116,7 +116,8 @@
nalu.sps_id = -1;
nalu.pps_id = -1;
start_offset += H264::kNaluTypeSize;
-
+ rtc::ArrayView<const uint8_t> nalu_data(&payload_data[start_offset],
+ end_offset - start_offset);
switch (nalu.type) {
case H264::NaluType::kSps: {
// Check if VUI is present in SPS and if it needs to be modified to
@@ -131,8 +132,8 @@
absl::optional<SpsParser::SpsState> sps;
SpsVuiRewriter::ParseResult result = SpsVuiRewriter::ParseAndRewriteSps(
- &payload_data[start_offset], end_offset - start_offset, &sps,
- nullptr, &output_buffer, SpsVuiRewriter::Direction::kIncoming);
+ nalu_data, &sps, nullptr, &output_buffer,
+ SpsVuiRewriter::Direction::kIncoming);
switch (result) {
case SpsVuiRewriter::ParseResult::kFailure:
RTC_LOG(LS_WARNING) << "Failed to parse SPS NAL unit.";
@@ -179,9 +180,7 @@
case H264::NaluType::kPps: {
uint32_t pps_id;
uint32_t sps_id;
- if (PpsParser::ParsePpsIds(&payload_data[start_offset],
- end_offset - start_offset, &pps_id,
- &sps_id)) {
+ if (PpsParser::ParsePpsIds(nalu_data, &pps_id, &sps_id)) {
nalu.pps_id = pps_id;
nalu.sps_id = sps_id;
} else {
@@ -197,8 +196,7 @@
[[fallthrough]];
case H264::NaluType::kSlice: {
absl::optional<PpsParser::SliceHeader> slice_header =
- PpsParser::ParseSliceHeader(&payload_data[start_offset],
- end_offset - start_offset);
+ PpsParser::ParseSliceHeader(nalu_data);
if (slice_header) {
nalu.pps_id = slice_header->pic_parameter_set_id;
parsed_payload->video_header.is_first_packet_in_frame &=
@@ -249,8 +247,8 @@
if (original_nal_type == H264::NaluType::kIdr ||
original_nal_type == H264::NaluType::kSlice) {
absl::optional<PpsParser::SliceHeader> slice_header =
- PpsParser::ParseSliceHeader(rtp_payload.cdata() + 2 * kNalHeaderSize,
- rtp_payload.size() - 2 * kNalHeaderSize);
+ PpsParser::ParseSliceHeader(rtc::ArrayView<const uint8_t>(rtp_payload)
+ .subview(2 * kNalHeaderSize));
if (slice_header) {
nalu.pps_id = slice_header->pic_parameter_set_id;
is_first_packet_in_frame = slice_header->first_mb_in_slice == 0;
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_h265.cc b/modules/rtp_rtcp/source/video_rtp_depacketizer_h265.cc
index fdb5680..b415ae7 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_h265.cc
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_h265.cc
@@ -120,6 +120,8 @@
uint8_t nalu_type = (payload_data[start_offset] & kH265TypeMask) >> 1;
start_offset += kH265NalHeaderSizeBytes;
+ rtc::ArrayView<const uint8_t> nalu_data(&payload_data[start_offset],
+ end_offset - start_offset);
switch (nalu_type) {
case H265::NaluType::kBlaWLp:
case H265::NaluType::kBlaWRadl:
@@ -141,8 +143,8 @@
if (start_offset)
output_buffer->AppendData(payload_data, start_offset);
- absl::optional<H265SpsParser::SpsState> sps = H265SpsParser::ParseSps(
- &payload_data[start_offset], end_offset - start_offset);
+ absl::optional<H265SpsParser::SpsState> sps =
+ H265SpsParser::ParseSps(nalu_data);
if (sps) {
// TODO(bugs.webrtc.org/13485): Implement the size calculation taking
diff --git a/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc b/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc
index 535640e..03a8bec 100644
--- a/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc
+++ b/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc
@@ -381,7 +381,7 @@
bool contains_pps = false;
bool contains_idr = false;
const std::vector<webrtc::H264::NaluIndex> nalu_indices =
- webrtc::H264::FindNaluIndices(encoded_frame.data(), encoded_frame.size());
+ webrtc::H264::FindNaluIndices(encoded_frame);
for (const webrtc::H264::NaluIndex& index : nalu_indices) {
webrtc::H264::NaluType nalu_type = webrtc::H264::ParseNaluType(
encoded_frame.data()[index.payload_start_offset]);
diff --git a/modules/video_coding/codecs/test/videoprocessor.cc b/modules/video_coding/codecs/test/videoprocessor.cc
index c5e7ed0..2133a94 100644
--- a/modules/video_coding/codecs/test/videoprocessor.cc
+++ b/modules/video_coding/codecs/test/videoprocessor.cc
@@ -52,7 +52,7 @@
return 0;
std::vector<webrtc::H264::NaluIndex> nalu_indices =
- webrtc::H264::FindNaluIndices(encoded_frame.data(), encoded_frame.size());
+ webrtc::H264::FindNaluIndices(encoded_frame);
RTC_CHECK(!nalu_indices.empty());
diff --git a/modules/video_coding/h264_sps_pps_tracker.cc b/modules/video_coding/h264_sps_pps_tracker.cc
index 5792792..834a36d 100644
--- a/modules/video_coding/h264_sps_pps_tracker.cc
+++ b/modules/video_coding/h264_sps_pps_tracker.cc
@@ -217,9 +217,9 @@
return;
}
absl::optional<SpsParser::SpsState> parsed_sps = SpsParser::ParseSps(
- sps.data() + kNaluHeaderOffset, sps.size() - kNaluHeaderOffset);
+ rtc::ArrayView<const uint8_t>(sps).subview(kNaluHeaderOffset));
absl::optional<PpsParser::PpsState> parsed_pps = PpsParser::ParsePps(
- pps.data() + kNaluHeaderOffset, pps.size() - kNaluHeaderOffset);
+ rtc::ArrayView<const uint8_t>(pps).subview(kNaluHeaderOffset));
if (!parsed_sps) {
RTC_LOG(LS_WARNING) << "Failed to parse SPS.";
diff --git a/modules/video_coding/h26x_packet_buffer.cc b/modules/video_coding/h26x_packet_buffer.cc
index e6e7441..c1f6426 100644
--- a/modules/video_coding/h26x_packet_buffer.cc
+++ b/modules/video_coding/h26x_packet_buffer.cc
@@ -85,8 +85,8 @@
#ifdef RTC_ENABLE_H265
bool HasVps(const H26xPacketBuffer::Packet& packet) {
- std::vector<H265::NaluIndex> nalu_indices = H265::FindNaluIndices(
- packet.video_payload.cdata(), packet.video_payload.size());
+ std::vector<H265::NaluIndex> nalu_indices =
+ H265::FindNaluIndices(packet.video_payload);
return absl::c_any_of((nalu_indices), [&packet](
const H265::NaluIndex& nalu_index) {
return H265::ParseNaluType(
@@ -242,8 +242,8 @@
}
#ifdef RTC_ENABLE_H265
} else if (packet->codec() == kVideoCodecH265) {
- std::vector<H265::NaluIndex> nalu_indices = H265::FindNaluIndices(
- packet->video_payload.cdata(), packet->video_payload.size());
+ std::vector<H265::NaluIndex> nalu_indices =
+ H265::FindNaluIndices(packet->video_payload);
for (const auto& nalu_index : nalu_indices) {
uint8_t nalu_type = H265::ParseNaluType(
packet->video_payload.cdata()[nalu_index.payload_start_offset]);
@@ -339,9 +339,9 @@
return;
}
absl::optional<SpsParser::SpsState> parsed_sps = SpsParser::ParseSps(
- sps.data() + kNaluHeaderOffset, sps.size() - kNaluHeaderOffset);
+ rtc::ArrayView<const uint8_t>(sps).subview(kNaluHeaderOffset));
absl::optional<PpsParser::PpsState> parsed_pps = PpsParser::ParsePps(
- pps.data() + kNaluHeaderOffset, pps.size() - kNaluHeaderOffset);
+ rtc::ArrayView<const uint8_t>(pps).subview(kNaluHeaderOffset));
if (!parsed_sps) {
RTC_LOG(LS_WARNING) << "Failed to parse SPS.";
diff --git a/sdk/objc/components/video_codec/nalu_rewriter.cc b/sdk/objc/components/video_codec/nalu_rewriter.cc
index 73c0ed0..054d6f9 100644
--- a/sdk/objc/components/video_codec/nalu_rewriter.cc
+++ b/sdk/objc/components/video_codec/nalu_rewriter.cc
@@ -259,7 +259,7 @@
size_t length)
: start_(annexb_buffer), length_(length) {
RTC_DCHECK(annexb_buffer);
- offsets_ = H264::FindNaluIndices(annexb_buffer, length);
+ offsets_ = H264::FindNaluIndices(rtc::MakeArrayView(annexb_buffer, length));
offset_ = offsets_.begin();
}