Skip to content

Commit

Permalink
[WebRTC] Make H265 packetizing more resilient to bad input
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=265043
<rdar://118460064>

Reviewed by Youenn Fablet.

Change a release assert to runtime failure to prevent easily hit
crashes.

Also improve performance of H265::FindNaluIndices() by making
H265::NaluIndex the same as H264::NaluIndex so there is no need to copy
identical data structures.

* Source/ThirdParty/libwebrtc/Source/webrtc/common_video/h265/h265_common.cc:
(webrtc::H265::FindNaluIndices): Remove.
- This code is no longer necessary because all it did was call
  H264::FindNaluIndices() and then translate H264::NaluIndex objects to
  H265::NaluIndex objects.  Changes in h265_common.h make this code
  obsolete.
* Source/ThirdParty/libwebrtc/Source/webrtc/common_video/h265/h265_common.h:
(struct H265::NaluIndex):
- Change to make identical to H264::NaluIndex with a using statement.
(webrtc::H265::FindNaluIndices):
- Change to an inline method that calls H264::FindNaluIndices().

* Source/ThirdParty/libwebrtc/Source/webrtc/modules/rtp_rtcp/source/rtp_format_h265.cc:
(webrtc::RtpPacketizerH265::RtpPacketizerH265):
- Fix typo that called H264::FindNaluIndices() instead of
  H265::FindNaluIndices().  Because of how H265::FindNaluIndices() was
  defined, this did not result in a bug, was likely a copy-paste
  mistake.
(webrtc::RtpPacketizerH265::GeneratePackets):
- Add missing checks for return values from PacketizeFu() and
  PacketizeSingleNalu().
(webrtc::RtpPacketizerH265::PacketizeSingleNalu):
- Change release assert into runtime check that returns early if
  fragment.size() is zero.

* Source/ThirdParty/libwebrtc/WebKit/0001-Make-H265-packetizing-more-resilient-to-bad-input.patch: Add.

Canonical link: https://commits.webkit.org/271214@main
  • Loading branch information
David Kilzer authored and ddkilzer committed Nov 28, 2023
1 parent b1f4d81 commit 7e7d41f
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ namespace H265 {

const uint8_t kNaluTypeMask = 0x7E;

#ifndef WEBRTC_WEBKIT_BUILD
std::vector<NaluIndex> FindNaluIndices(const uint8_t* buffer,
size_t buffer_size) {
std::vector<H264::NaluIndex> indices =
Expand All @@ -28,6 +29,7 @@ std::vector<NaluIndex> FindNaluIndices(const uint8_t* buffer,
}
return results;
}
#endif

NaluType ParseNaluType(uint8_t data) {
return static_cast<NaluType>((data & kNaluTypeMask) >> 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
#include <memory>
#include <vector>

#ifdef WEBRTC_WEBKIT_BUILD
#include "common_video/h264/h264_common.h"
#endif
#include "rtc_base/buffer.h"

namespace webrtc {
Expand Down Expand Up @@ -58,6 +61,9 @@ enum NaluType : uint8_t {

enum SliceType : uint8_t { kB = 0, kP = 1, kI = 2 };

#ifdef WEBRTC_WEBKIT_BUILD
using NaluIndex = H264::NaluIndex;
#else
struct NaluIndex {
// Start index of NALU, including start sequence.
size_t start_offset;
Expand All @@ -66,10 +72,18 @@ struct NaluIndex {
// Length of NALU payload, in bytes, counting from payload_start_offset.
size_t payload_size;
};
#endif

// Returns a vector of the NALU indices in the given buffer.
#ifdef WEBRTC_WEBKIT_BUILD
inline std::vector<NaluIndex> FindNaluIndices(const uint8_t* buffer,
size_t buffer_size) {
return H264::FindNaluIndices(buffer, buffer_size);
}
#else
std::vector<NaluIndex> FindNaluIndices(const uint8_t* buffer,
size_t buffer_size);
#endif

// Get the NAL type from the header byte immediately following start sequence.
NaluType ParseNaluType(uint8_t data);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@

#include "absl/types/optional.h"
#include "absl/types/variant.h"
#ifndef WEBRTC_WEBKIT_BUILD
#include "common_video/h264/h264_common.h"
#endif
#include "common_video/h265/h265_common.h"
#include "common_video/h265/h265_pps_parser.h"
#include "common_video/h265/h265_sps_parser.h"
Expand Down Expand Up @@ -84,11 +86,19 @@ RtpPacketizerH265::RtpPacketizerH265(rtc::ArrayView<const uint8_t> payload,
RTC_CHECK(packetization_mode == H265PacketizationMode::NonInterleaved ||
packetization_mode == H265PacketizationMode::SingleNalUnit);

#ifdef WEBRTC_WEBKIT_BUILD
for (const auto& nalu :
H265::FindNaluIndices(payload.data(), payload.size())) {
input_fragments_.push_back(
payload.subview(nalu.payload_start_offset, nalu.payload_size));
}
#else
for (const auto& nalu :
H264::FindNaluIndices(payload.data(), payload.size())) {
input_fragments_.push_back(
payload.subview(nalu.payload_start_offset, nalu.payload_size));
}
#endif

if (!GeneratePackets(packetization_mode)) {
// If failed to generate all the packets, discard already generated
Expand Down Expand Up @@ -124,10 +134,22 @@ bool RtpPacketizerH265::GeneratePackets(
single_packet_capacity -= limits_.last_packet_reduction_len;
}
if (fragment_len > single_packet_capacity) {
#ifdef WEBRTC_WEBKIT_BUILD
if (!PacketizeFu(i)) {
return false;
}
#else
PacketizeFu(i);
#endif
++i;
} else {
#ifdef WEBRTC_WEBKIT_BUILD
if (!PacketizeSingleNalu(i)) {
return false;
}
#else
PacketizeSingleNalu(i);
#endif
++i;
}
}
Expand Down Expand Up @@ -201,7 +223,13 @@ bool RtpPacketizerH265::PacketizeSingleNalu(size_t fragment_index) {
<< limits_.max_payload_len;
return false;
}
#ifdef WEBRTC_WEBKIT_BUILD
if (fragment.size() == 0u) {
return false;
}
#else
RTC_CHECK_GT(fragment.size(), 0u);
#endif
packets_.push(PacketUnit(fragment, true /* first */, true /* last */,
false /* aggregated */, fragment[0]));
++num_packets_left_;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/common_video/h265/h265_common.cc b/Source/ThirdParty/libwebrtc/Source/webrtc/common_video/h265/h265_common.cc
index 6dc8a79ae35d..9307a5087d3b 100644
--- a/Source/ThirdParty/libwebrtc/Source/webrtc/common_video/h265/h265_common.cc
+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/common_video/h265/h265_common.cc
@@ -17,6 +17,7 @@ namespace H265 {

const uint8_t kNaluTypeMask = 0x7E;

+#ifndef WEBRTC_WEBKIT_BUILD
std::vector<NaluIndex> FindNaluIndices(const uint8_t* buffer,
size_t buffer_size) {
std::vector<H264::NaluIndex> indices =
@@ -28,6 +29,7 @@ std::vector<NaluIndex> FindNaluIndices(const uint8_t* buffer,
}
return results;
}
+#endif

NaluType ParseNaluType(uint8_t data) {
return static_cast<NaluType>((data & kNaluTypeMask) >> 1);
diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/common_video/h265/h265_common.h b/Source/ThirdParty/libwebrtc/Source/webrtc/common_video/h265/h265_common.h
index a829195a1007..459ee5b33b3e 100644
--- a/Source/ThirdParty/libwebrtc/Source/webrtc/common_video/h265/h265_common.h
+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/common_video/h265/h265_common.h
@@ -14,6 +14,9 @@
#include <memory>
#include <vector>

+#ifdef WEBRTC_WEBKIT_BUILD
+#include "common_video/h264/h264_common.h"
+#endif
#include "rtc_base/buffer.h"

namespace webrtc {
@@ -58,6 +61,9 @@ enum NaluType : uint8_t {

enum SliceType : uint8_t { kB = 0, kP = 1, kI = 2 };

+#ifdef WEBRTC_WEBKIT_BUILD
+using NaluIndex = H264::NaluIndex;
+#else
struct NaluIndex {
// Start index of NALU, including start sequence.
size_t start_offset;
@@ -66,10 +72,18 @@ struct NaluIndex {
// Length of NALU payload, in bytes, counting from payload_start_offset.
size_t payload_size;
};
+#endif

// Returns a vector of the NALU indices in the given buffer.
+#ifdef WEBRTC_WEBKIT_BUILD
+inline std::vector<NaluIndex> FindNaluIndices(const uint8_t* buffer,
+ size_t buffer_size) {
+ return H264::FindNaluIndices(buffer, buffer_size);
+}
+#else
std::vector<NaluIndex> FindNaluIndices(const uint8_t* buffer,
size_t buffer_size);
+#endif

// Get the NAL type from the header byte immediately following start sequence.
NaluType ParseNaluType(uint8_t data);
diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/rtp_rtcp/source/rtp_format_h265.cc b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/rtp_rtcp/source/rtp_format_h265.cc
index 9865d7cb8244..122eb98d4b38 100644
--- a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/rtp_rtcp/source/rtp_format_h265.cc
+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/rtp_rtcp/source/rtp_format_h265.cc
@@ -8,7 +8,9 @@

#include "absl/types/optional.h"
#include "absl/types/variant.h"
+#ifndef WEBRTC_WEBKIT_BUILD
#include "common_video/h264/h264_common.h"
+#endif
#include "common_video/h265/h265_common.h"
#include "common_video/h265/h265_pps_parser.h"
#include "common_video/h265/h265_sps_parser.h"
@@ -84,11 +86,19 @@ RtpPacketizerH265::RtpPacketizerH265(rtc::ArrayView<const uint8_t> payload,
RTC_CHECK(packetization_mode == H265PacketizationMode::NonInterleaved ||
packetization_mode == H265PacketizationMode::SingleNalUnit);

+#ifdef WEBRTC_WEBKIT_BUILD
+ for (const auto& nalu :
+ H265::FindNaluIndices(payload.data(), payload.size())) {
+ input_fragments_.push_back(
+ payload.subview(nalu.payload_start_offset, nalu.payload_size));
+ }
+#else
for (const auto& nalu :
H264::FindNaluIndices(payload.data(), payload.size())) {
input_fragments_.push_back(
payload.subview(nalu.payload_start_offset, nalu.payload_size));
}
+#endif

if (!GeneratePackets(packetization_mode)) {
// If failed to generate all the packets, discard already generated
@@ -124,10 +134,22 @@ bool RtpPacketizerH265::GeneratePackets(
single_packet_capacity -= limits_.last_packet_reduction_len;
}
if (fragment_len > single_packet_capacity) {
+#ifdef WEBRTC_WEBKIT_BUILD
+ if (!PacketizeFu(i)) {
+ return false;
+ }
+#else
PacketizeFu(i);
+#endif
++i;
} else {
+#ifdef WEBRTC_WEBKIT_BUILD
+ if (!PacketizeSingleNalu(i)) {
+ return false;
+ }
+#else
PacketizeSingleNalu(i);
+#endif
++i;
}
}
@@ -201,7 +223,13 @@ bool RtpPacketizerH265::PacketizeSingleNalu(size_t fragment_index) {
<< limits_.max_payload_len;
return false;
}
+#ifdef WEBRTC_WEBKIT_BUILD
+ if (fragment.size() == 0u) {
+ return false;
+ }
+#else
RTC_CHECK_GT(fragment.size(), 0u);
+#endif
packets_.push(PacketUnit(fragment, true /* first */, true /* last */,
false /* aggregated */, fragment[0]));
++num_packets_left_;
--
2.39.3 (Apple Git-145)

0 comments on commit 7e7d41f

Please sign in to comment.