Use rtc::Buffer and rtc::ByteBufferReader instead of raw data pointers in H264SpsPpsTracker

Bug: webrtc:42225170
Change-Id: I07ec0e8a1aba8eec04ed1dd5c6f7a4bbbdb7a43a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/364641
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#43180}
This commit is contained in:
Sergio Garcia Murillo 2024-10-04 14:04:34 +02:00 committed by WebRTC LUCI CQ
parent e17aad2c1d
commit 6976a1e4ee
3 changed files with 34 additions and 62 deletions

View File

@ -236,6 +236,8 @@ rtc_library("video_coding") {
"../../api/video:video_rtp_headers",
"../../api/video_codecs:video_codecs_api",
"../../common_video",
"../../rtc_base:buffer",
"../../rtc_base:byte_buffer",
"../../rtc_base:checks",
"../../rtc_base:copy_on_write_buffer",
"../../rtc_base:event_tracer",

View File

@ -19,6 +19,7 @@
#include "common_video/h264/pps_parser.h"
#include "common_video/h264/sps_parser.h"
#include "modules/video_coding/codecs/h264/include/h264_globals.h"
#include "rtc_base/byte_buffer.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
@ -29,21 +30,6 @@ namespace {
const uint8_t start_code_h264[] = {0, 0, 0, 1};
} // namespace
H264SpsPpsTracker::H264SpsPpsTracker() = default;
H264SpsPpsTracker::~H264SpsPpsTracker() = default;
H264SpsPpsTracker::PpsInfo::PpsInfo() = default;
H264SpsPpsTracker::PpsInfo::PpsInfo(PpsInfo&& rhs) = default;
H264SpsPpsTracker::PpsInfo& H264SpsPpsTracker::PpsInfo::operator=(
PpsInfo&& rhs) = default;
H264SpsPpsTracker::PpsInfo::~PpsInfo() = default;
H264SpsPpsTracker::SpsInfo::SpsInfo() = default;
H264SpsPpsTracker::SpsInfo::SpsInfo(SpsInfo&& rhs) = default;
H264SpsPpsTracker::SpsInfo& H264SpsPpsTracker::SpsInfo::operator=(
SpsInfo&& rhs) = default;
H264SpsPpsTracker::SpsInfo::~SpsInfo() = default;
H264SpsPpsTracker::FixedBitstream H264SpsPpsTracker::CopyAndFixBitstream(
rtc::ArrayView<const uint8_t> bitstream,
RTPVideoHeader* video_header) {
@ -102,9 +88,7 @@ H264SpsPpsTracker::FixedBitstream H264SpsPpsTracker::CopyAndFixBitstream(
// If the SPS/PPS was supplied out of band then we will have saved
// the actual bitstream in `data`.
if (sps->second.data && pps->second.data) {
RTC_DCHECK_GT(sps->second.size, 0);
RTC_DCHECK_GT(pps->second.size, 0);
if (!sps->second.data.empty() && !pps->second.data.empty()) {
append_sps_pps = true;
}
}
@ -122,21 +106,24 @@ H264SpsPpsTracker::FixedBitstream H264SpsPpsTracker::CopyAndFixBitstream(
size_t required_size = 0;
if (append_sps_pps) {
required_size += sps->second.size + sizeof(start_code_h264);
required_size += pps->second.size + sizeof(start_code_h264);
required_size += sps->second.data.size() + sizeof(start_code_h264);
required_size += pps->second.data.size() + sizeof(start_code_h264);
}
if (h264_header.packetization_type == kH264StapA) {
const uint8_t* nalu_ptr = bitstream.data() + 1;
while (nalu_ptr < bitstream.data() + bitstream.size() - 1) {
rtc::ByteBufferReader nalu(bitstream.subview(1));
while (nalu.Length() > 0) {
required_size += sizeof(start_code_h264);
// The first two bytes describe the length of a segment.
uint16_t segment_length = nalu_ptr[0] << 8 | nalu_ptr[1];
nalu_ptr += 2;
uint16_t segment_length;
if (!nalu.ReadUInt16(&segment_length))
return {kDrop};
if (segment_length == 0 || segment_length > nalu.Length()) {
return {kDrop};
}
required_size += segment_length;
nalu_ptr += segment_length;
nalu.Consume(segment_length);
}
} else {
if (!h264_header.nalus.empty()) {
@ -152,11 +139,11 @@ H264SpsPpsTracker::FixedBitstream H264SpsPpsTracker::CopyAndFixBitstream(
if (append_sps_pps) {
// Insert SPS.
fixed.bitstream.AppendData(start_code_h264);
fixed.bitstream.AppendData(sps->second.data.get(), sps->second.size);
fixed.bitstream.AppendData(sps->second.data);
// Insert PPS.
fixed.bitstream.AppendData(start_code_h264);
fixed.bitstream.AppendData(pps->second.data.get(), pps->second.size);
fixed.bitstream.AppendData(pps->second.data);
// Update codec header to reflect the newly added SPS and PPS.
h264_header.nalus.push_back(
@ -168,21 +155,19 @@ H264SpsPpsTracker::FixedBitstream H264SpsPpsTracker::CopyAndFixBitstream(
// Copy the rest of the bitstream and insert start codes.
if (h264_header.packetization_type == kH264StapA) {
const uint8_t* nalu_ptr = bitstream.data() + 1;
while (nalu_ptr < bitstream.data() + bitstream.size() - 1) {
rtc::ByteBufferReader nalu(bitstream.subview(1));
while (nalu.Length() > 0) {
fixed.bitstream.AppendData(start_code_h264);
// The first two bytes describe the length of a segment.
uint16_t segment_length = nalu_ptr[0] << 8 | nalu_ptr[1];
nalu_ptr += 2;
size_t copy_end = nalu_ptr - bitstream.data() + segment_length;
if (copy_end > bitstream.size()) {
uint16_t segment_length;
if (!nalu.ReadUInt16(&segment_length))
return {kDrop};
if (segment_length == 0 || segment_length > nalu.Length()) {
return {kDrop};
}
fixed.bitstream.AppendData(nalu_ptr, segment_length);
nalu_ptr += segment_length;
fixed.bitstream.AppendData(nalu.Data(), segment_length);
nalu.Consume(segment_length);
}
} else {
if (!h264_header.nalus.empty()) {
@ -234,20 +219,14 @@ void H264SpsPpsTracker::InsertSpsPpsNalus(const std::vector<uint8_t>& sps,
}
SpsInfo sps_info;
sps_info.size = sps.size();
sps_info.width = parsed_sps->width;
sps_info.height = parsed_sps->height;
uint8_t* sps_data = new uint8_t[sps_info.size];
memcpy(sps_data, sps.data(), sps_info.size);
sps_info.data.reset(sps_data);
sps_info.data.SetData(sps);
sps_data_[parsed_sps->id] = std::move(sps_info);
PpsInfo pps_info;
pps_info.size = pps.size();
pps_info.sps_id = parsed_pps->sps_id;
uint8_t* pps_data = new uint8_t[pps_info.size];
memcpy(pps_data, pps.data(), pps_info.size);
pps_info.data.reset(pps_data);
pps_info.data.SetData(pps);
pps_data_[parsed_pps->id] = std::move(pps_info);
RTC_LOG(LS_INFO) << "Inserted SPS id " << parsed_sps->id << " and PPS id "

View File

@ -19,6 +19,7 @@
#include "api/array_view.h"
#include "modules/rtp_rtcp/source/rtp_video_header.h"
#include "rtc_base/buffer.h"
#include "rtc_base/copy_on_write_buffer.h"
namespace webrtc {
@ -32,8 +33,10 @@ class H264SpsPpsTracker {
rtc::CopyOnWriteBuffer bitstream;
};
H264SpsPpsTracker();
~H264SpsPpsTracker();
H264SpsPpsTracker() = default;
H264SpsPpsTracker(const H264SpsPpsTracker& other) = default;
H264SpsPpsTracker& operator=(const H264SpsPpsTracker& other) = default;
~H264SpsPpsTracker() = default;
// Returns fixed bitstream and modifies `video_header`.
FixedBitstream CopyAndFixBitstream(rtc::ArrayView<const uint8_t> bitstream,
@ -44,26 +47,14 @@ class H264SpsPpsTracker {
private:
struct PpsInfo {
PpsInfo();
PpsInfo(PpsInfo&& rhs);
PpsInfo& operator=(PpsInfo&& rhs);
~PpsInfo();
int sps_id = -1;
size_t size = 0;
std::unique_ptr<uint8_t[]> data;
rtc::Buffer data;
};
struct SpsInfo {
SpsInfo();
SpsInfo(SpsInfo&& rhs);
SpsInfo& operator=(SpsInfo&& rhs);
~SpsInfo();
size_t size = 0;
int width = -1;
int height = -1;
std::unique_ptr<uint8_t[]> data;
rtc::Buffer data;
};
std::map<int, PpsInfo> pps_data_;