diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn index 0aba776cc2..82177ad26c 100644 --- a/modules/video_coding/BUILD.gn +++ b/modules/video_coding/BUILD.gn @@ -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", diff --git a/modules/video_coding/h264_sps_pps_tracker.cc b/modules/video_coding/h264_sps_pps_tracker.cc index 0d7931cbd6..177162783c 100644 --- a/modules/video_coding/h264_sps_pps_tracker.cc +++ b/modules/video_coding/h264_sps_pps_tracker.cc @@ -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 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& 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 " diff --git a/modules/video_coding/h264_sps_pps_tracker.h b/modules/video_coding/h264_sps_pps_tracker.h index 3c0928d324..249616a4f2 100644 --- a/modules/video_coding/h264_sps_pps_tracker.h +++ b/modules/video_coding/h264_sps_pps_tracker.h @@ -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 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 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 data; + rtc::Buffer data; }; std::map pps_data_;