Skip to content

Commit 43cbc67

Browse files
David Kilzerphiln
authored andcommitted
[WebRTC] Make H265 packetizing more resilient to bad input
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
1 parent a6b445c commit 43cbc67

4 files changed

Lines changed: 181 additions & 0 deletions

File tree

Source/ThirdParty/libwebrtc/Source/webrtc/common_video/h265/h265_common.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ namespace H265 {
1717

1818
const uint8_t kNaluTypeMask = 0x7E;
1919

20+
#ifndef WEBRTC_WEBKIT_BUILD
2021
std::vector<NaluIndex> FindNaluIndices(const uint8_t* buffer,
2122
size_t buffer_size) {
2223
std::vector<H264::NaluIndex> indices =
@@ -28,6 +29,7 @@ std::vector<NaluIndex> FindNaluIndices(const uint8_t* buffer,
2829
}
2930
return results;
3031
}
32+
#endif
3133

3234
NaluType ParseNaluType(uint8_t data) {
3335
return static_cast<NaluType>((data & kNaluTypeMask) >> 1);

Source/ThirdParty/libwebrtc/Source/webrtc/common_video/h265/h265_common.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
#include <memory>
1515
#include <vector>
1616

17+
#ifdef WEBRTC_WEBKIT_BUILD
18+
#include "common_video/h264/h264_common.h"
19+
#endif
1720
#include "rtc_base/buffer.h"
1821

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

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

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

7077
// Returns a vector of the NALU indices in the given buffer.
78+
#ifdef WEBRTC_WEBKIT_BUILD
79+
inline std::vector<NaluIndex> FindNaluIndices(const uint8_t* buffer,
80+
size_t buffer_size) {
81+
return H264::FindNaluIndices(buffer, buffer_size);
82+
}
83+
#else
7184
std::vector<NaluIndex> FindNaluIndices(const uint8_t* buffer,
7285
size_t buffer_size);
86+
#endif
7387

7488
// Get the NAL type from the header byte immediately following start sequence.
7589
NaluType ParseNaluType(uint8_t data);

Source/ThirdParty/libwebrtc/Source/webrtc/modules/rtp_rtcp/source/rtp_format_h265.cc

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88

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

89+
#ifdef WEBRTC_WEBKIT_BUILD
90+
for (const auto& nalu :
91+
H265::FindNaluIndices(payload.data(), payload.size())) {
92+
input_fragments_.push_back(
93+
payload.subview(nalu.payload_start_offset, nalu.payload_size));
94+
}
95+
#else
8796
for (const auto& nalu :
8897
H264::FindNaluIndices(payload.data(), payload.size())) {
8998
input_fragments_.push_back(
9099
payload.subview(nalu.payload_start_offset, nalu.payload_size));
91100
}
101+
#endif
92102

93103
if (!GeneratePackets(packetization_mode)) {
94104
// If failed to generate all the packets, discard already generated
@@ -124,10 +134,22 @@ bool RtpPacketizerH265::GeneratePackets(
124134
single_packet_capacity -= limits_.last_packet_reduction_len;
125135
}
126136
if (fragment_len > single_packet_capacity) {
137+
#ifdef WEBRTC_WEBKIT_BUILD
138+
if (!PacketizeFu(i)) {
139+
return false;
140+
}
141+
#else
127142
PacketizeFu(i);
143+
#endif
128144
++i;
129145
} else {
146+
#ifdef WEBRTC_WEBKIT_BUILD
147+
if (!PacketizeSingleNalu(i)) {
148+
return false;
149+
}
150+
#else
130151
PacketizeSingleNalu(i);
152+
#endif
131153
++i;
132154
}
133155
}
@@ -201,7 +223,13 @@ bool RtpPacketizerH265::PacketizeSingleNalu(size_t fragment_index) {
201223
<< limits_.max_payload_len;
202224
return false;
203225
}
226+
#ifdef WEBRTC_WEBKIT_BUILD
227+
if (fragment.size() == 0u) {
228+
return false;
229+
}
230+
#else
204231
RTC_CHECK_GT(fragment.size(), 0u);
232+
#endif
205233
packets_.push(PacketUnit(fragment, true /* first */, true /* last */,
206234
false /* aggregated */, fragment[0]));
207235
++num_packets_left_;
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
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
2+
index 6dc8a79ae35d..9307a5087d3b 100644
3+
--- a/Source/ThirdParty/libwebrtc/Source/webrtc/common_video/h265/h265_common.cc
4+
+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/common_video/h265/h265_common.cc
5+
@@ -17,6 +17,7 @@ namespace H265 {
6+
7+
const uint8_t kNaluTypeMask = 0x7E;
8+
9+
+#ifndef WEBRTC_WEBKIT_BUILD
10+
std::vector<NaluIndex> FindNaluIndices(const uint8_t* buffer,
11+
size_t buffer_size) {
12+
std::vector<H264::NaluIndex> indices =
13+
@@ -28,6 +29,7 @@ std::vector<NaluIndex> FindNaluIndices(const uint8_t* buffer,
14+
}
15+
return results;
16+
}
17+
+#endif
18+
19+
NaluType ParseNaluType(uint8_t data) {
20+
return static_cast<NaluType>((data & kNaluTypeMask) >> 1);
21+
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
22+
index a829195a1007..459ee5b33b3e 100644
23+
--- a/Source/ThirdParty/libwebrtc/Source/webrtc/common_video/h265/h265_common.h
24+
+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/common_video/h265/h265_common.h
25+
@@ -14,6 +14,9 @@
26+
#include <memory>
27+
#include <vector>
28+
29+
+#ifdef WEBRTC_WEBKIT_BUILD
30+
+#include "common_video/h264/h264_common.h"
31+
+#endif
32+
#include "rtc_base/buffer.h"
33+
34+
namespace webrtc {
35+
@@ -58,6 +61,9 @@ enum NaluType : uint8_t {
36+
37+
enum SliceType : uint8_t { kB = 0, kP = 1, kI = 2 };
38+
39+
+#ifdef WEBRTC_WEBKIT_BUILD
40+
+using NaluIndex = H264::NaluIndex;
41+
+#else
42+
struct NaluIndex {
43+
// Start index of NALU, including start sequence.
44+
size_t start_offset;
45+
@@ -66,10 +72,18 @@ struct NaluIndex {
46+
// Length of NALU payload, in bytes, counting from payload_start_offset.
47+
size_t payload_size;
48+
};
49+
+#endif
50+
51+
// Returns a vector of the NALU indices in the given buffer.
52+
+#ifdef WEBRTC_WEBKIT_BUILD
53+
+inline std::vector<NaluIndex> FindNaluIndices(const uint8_t* buffer,
54+
+ size_t buffer_size) {
55+
+ return H264::FindNaluIndices(buffer, buffer_size);
56+
+}
57+
+#else
58+
std::vector<NaluIndex> FindNaluIndices(const uint8_t* buffer,
59+
size_t buffer_size);
60+
+#endif
61+
62+
// Get the NAL type from the header byte immediately following start sequence.
63+
NaluType ParseNaluType(uint8_t data);
64+
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
65+
index 9865d7cb8244..122eb98d4b38 100644
66+
--- a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/rtp_rtcp/source/rtp_format_h265.cc
67+
+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/rtp_rtcp/source/rtp_format_h265.cc
68+
@@ -8,7 +8,9 @@
69+
70+
#include "absl/types/optional.h"
71+
#include "absl/types/variant.h"
72+
+#ifndef WEBRTC_WEBKIT_BUILD
73+
#include "common_video/h264/h264_common.h"
74+
+#endif
75+
#include "common_video/h265/h265_common.h"
76+
#include "common_video/h265/h265_pps_parser.h"
77+
#include "common_video/h265/h265_sps_parser.h"
78+
@@ -84,11 +86,19 @@ RtpPacketizerH265::RtpPacketizerH265(rtc::ArrayView<const uint8_t> payload,
79+
RTC_CHECK(packetization_mode == H265PacketizationMode::NonInterleaved ||
80+
packetization_mode == H265PacketizationMode::SingleNalUnit);
81+
82+
+#ifdef WEBRTC_WEBKIT_BUILD
83+
+ for (const auto& nalu :
84+
+ H265::FindNaluIndices(payload.data(), payload.size())) {
85+
+ input_fragments_.push_back(
86+
+ payload.subview(nalu.payload_start_offset, nalu.payload_size));
87+
+ }
88+
+#else
89+
for (const auto& nalu :
90+
H264::FindNaluIndices(payload.data(), payload.size())) {
91+
input_fragments_.push_back(
92+
payload.subview(nalu.payload_start_offset, nalu.payload_size));
93+
}
94+
+#endif
95+
96+
if (!GeneratePackets(packetization_mode)) {
97+
// If failed to generate all the packets, discard already generated
98+
@@ -124,10 +134,22 @@ bool RtpPacketizerH265::GeneratePackets(
99+
single_packet_capacity -= limits_.last_packet_reduction_len;
100+
}
101+
if (fragment_len > single_packet_capacity) {
102+
+#ifdef WEBRTC_WEBKIT_BUILD
103+
+ if (!PacketizeFu(i)) {
104+
+ return false;
105+
+ }
106+
+#else
107+
PacketizeFu(i);
108+
+#endif
109+
++i;
110+
} else {
111+
+#ifdef WEBRTC_WEBKIT_BUILD
112+
+ if (!PacketizeSingleNalu(i)) {
113+
+ return false;
114+
+ }
115+
+#else
116+
PacketizeSingleNalu(i);
117+
+#endif
118+
++i;
119+
}
120+
}
121+
@@ -201,7 +223,13 @@ bool RtpPacketizerH265::PacketizeSingleNalu(size_t fragment_index) {
122+
<< limits_.max_payload_len;
123+
return false;
124+
}
125+
+#ifdef WEBRTC_WEBKIT_BUILD
126+
+ if (fragment.size() == 0u) {
127+
+ return false;
128+
+ }
129+
+#else
130+
RTC_CHECK_GT(fragment.size(), 0u);
131+
+#endif
132+
packets_.push(PacketUnit(fragment, true /* first */, true /* last */,
133+
false /* aggregated */, fragment[0]));
134+
++num_packets_left_;
135+
--
136+
2.39.3 (Apple Git-145)
137+

0 commit comments

Comments
 (0)