commit ebb256065b0d789f59c37cdbd6a3774baac4c917
parent 4e5fb22d6ad08de4e28f7502ccbac2e90bb10556
Author: Dan Baker <dbaker@mozilla.com>
Date: Thu, 23 Oct 2025 17:45:48 -0600
Bug 1995393 - Vendor libwebrtc from 190613939f
Upstream commit: https://webrtc.googlesource.com/src/+/190613939f9a75c36155c825039bccbcbdbe03c9
sdp munging: refactor and split up munging detection
Bug: webrtc:414284082
Change-Id: I66e65c625195bb7e437d4664a4fb64a75557a0a4
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/404561
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Evan Shrubsole <eshr@webrtc.org>
Commit-Queue: Philipp Hancke <phancke@meta.com>
Cr-Commit-Position: refs/heads/main@{#45386}
Diffstat:
3 files changed, 142 insertions(+), 107 deletions(-)
diff --git a/third_party/libwebrtc/README.mozilla.last-vendor b/third_party/libwebrtc/README.mozilla.last-vendor
@@ -1,4 +1,4 @@
# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc
-libwebrtc updated from /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-10-23T23:42:48.011803+00:00.
+libwebrtc updated from /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-10-23T23:45:36.154676+00:00.
# base of lastest vendoring
-921ba4cd77
+190613939f
diff --git a/third_party/libwebrtc/api/uma_metrics.h b/third_party/libwebrtc/api/uma_metrics.h
@@ -177,7 +177,8 @@ enum RtcpMuxPolicyUsage {
// Metrics for SDP munging.
// These values are persisted to logs. Entries should not be renumbered and
-// numeric values should never be reused. Keep in sync with SdpMungingType from
+// numeric values should never be reused. Keep in (loose) sync with
+// SdpMungingType from Chromium's
// tools/metrics/histograms/metadata/web_rtc/enums.xml
enum SdpMungingType {
kNoModification = 0,
diff --git a/third_party/libwebrtc/pc/sdp_munging_detector.cc b/third_party/libwebrtc/pc/sdp_munging_detector.cc
@@ -104,7 +104,7 @@ SdpMungingType DetermineTransportModification(
return SdpMungingType::kNoModification;
}
-SdpMungingType DetermineAudioSdpMungingType(
+SdpMungingType DetermineAudioSdpModification(
const MediaContentDescription* last_created_media_description,
const MediaContentDescription* media_description_to_set) {
RTC_DCHECK(last_created_media_description);
@@ -281,7 +281,78 @@ SdpMungingType DetermineAudioSdpMungingType(
return SdpMungingType::kNoModification;
}
-SdpMungingType DetermineVideoSdpMungingType(
+SdpMungingType DetermineRtcpModification(
+ const MediaContentDescription* last_created_media_description,
+ const MediaContentDescription* media_description_to_set) {
+ // rtcp-mux.
+ if (last_created_media_description->rtcp_mux() !=
+ media_description_to_set->rtcp_mux()) {
+ RTC_LOG(LS_WARNING) << "SDP munging: rtcp-mux modified.";
+ return SdpMungingType::kRtcpMux;
+ }
+
+ // rtcp-rsize.
+ if (last_created_media_description->rtcp_reduced_size() !=
+ media_description_to_set->rtcp_reduced_size()) {
+ RTC_LOG(LS_WARNING) << "SDP munging: rtcp-rsize modified.";
+ return last_created_media_description->type() == MediaType::AUDIO
+ ? SdpMungingType::kAudioCodecsRtcpReducedSize
+ : SdpMungingType::kVideoCodecsRtcpReducedSize;
+ }
+ return SdpMungingType::kNoModification;
+}
+
+SdpMungingType DetermineCodecModification(
+ const MediaContentDescription* last_created_media_description,
+ const MediaContentDescription* media_description_to_set) {
+ MediaType media_type = last_created_media_description->type();
+ // Validate codecs. We should have bailed out earlier if codecs were added
+ // or removed.
+ auto last_created_codecs = last_created_media_description->codecs();
+ auto codecs_to_set = media_description_to_set->codecs();
+ if (last_created_codecs.size() == codecs_to_set.size()) {
+ for (size_t i = 0; i < last_created_codecs.size(); i++) {
+ if (last_created_codecs[i] == codecs_to_set[i]) {
+ continue;
+ }
+ // Codec position swapped.
+ for (size_t j = i + 1; j < last_created_codecs.size(); j++) {
+ if (last_created_codecs[i] == codecs_to_set[j]) {
+ return media_type == MediaType::AUDIO
+ ? SdpMungingType::kAudioCodecsReordered
+ : SdpMungingType::kVideoCodecsReordered;
+ }
+ }
+ // Same codec but id changed.
+ if (last_created_codecs[i].name == codecs_to_set[i].name &&
+ last_created_codecs[i].id != codecs_to_set[i].id) {
+ return SdpMungingType::kPayloadTypes;
+ }
+ if (last_created_codecs[i].params != codecs_to_set[i].params) {
+ return media_type == MediaType::AUDIO
+ ? SdpMungingType::kAudioCodecsFmtp
+ : SdpMungingType::kVideoCodecsFmtp;
+ }
+ if (last_created_codecs[i].feedback_params !=
+ codecs_to_set[i].feedback_params) {
+ return media_type == MediaType::AUDIO
+ ? SdpMungingType::kAudioCodecsRtcpFb
+ : SdpMungingType::kVideoCodecsRtcpFb;
+ }
+ // Nonstandard a=packetization:raw added by munging
+ if (media_type == MediaType::VIDEO &&
+ last_created_codecs[i].packetization !=
+ codecs_to_set[i].packetization) {
+ return SdpMungingType::kVideoCodecsModifiedWithRawPacketization;
+ }
+ // At this point clockrate or channels changed. This should already be
+ // rejected later in the process so ignore for munging.
+ }
+ }
+ return SdpMungingType::kNoModification;
+}
+
+SdpMungingType DetermineVideoSdpModification(
const MediaContentDescription* last_created_media_description,
const MediaContentDescription* media_description_to_set) {
RTC_DCHECK(last_created_media_description);
@@ -359,55 +430,19 @@ SdpMungingType DetermineVideoSdpMungingType(
RTC_LOG(LS_WARNING) << "SDP munging: sps-pps-idr-in-keyframe enabled.";
return SdpMungingType::kVideoCodecsFmtpH264SpsPpsIdrInKeyframe;
}
-
return SdpMungingType::kNoModification;
}
-} // namespace
-
-// Determine if the SDP was modified between createOffer and
-// setLocalDescription.
-SdpMungingType DetermineSdpMungingType(
- const SessionDescriptionInterface* sdesc,
- const SessionDescriptionInterface* last_created_desc) {
- if (!sdesc || !sdesc->description()) {
- RTC_LOG(LS_WARNING) << "SDP munging: Failed to parse session description.";
- // This is done to ensure the pointers are valid and should not happen at
- // this point.
- RTC_DCHECK_NOTREACHED();
- return SdpMungingType::kCurrentDescriptionFailedToParse;
- }
-
- if (!last_created_desc || !last_created_desc->description()) {
- RTC_LOG(LS_WARNING) << "SDP munging: SetLocalDescription called without "
- "CreateOffer or CreateAnswer.";
- if (sdesc->GetType() == SdpType::kOffer) {
- return SdpMungingType::kWithoutCreateOffer;
- } else { // answer or pranswer.
- return SdpMungingType::kWithoutCreateAnswer;
- }
- }
-
- // TODO: crbug.com/40567530 - we currently allow answer->pranswer
- // so can not check sdesc->GetType() == last_created_desc->GetType().
-
+SdpMungingType DetermineContentsModification(
+ const ContentInfos& last_created_contents,
+ const ContentInfos& contents_to_set) {
SdpMungingType type;
-
- // TODO: crbug.com/40567530 - change Chromium so that pointer comparison works
- // at least for implicit local description.
- if (sdesc->description() == last_created_desc->description()) {
- return SdpMungingType::kNoModification;
- }
-
- // Validate contents.
- const auto& last_created_contents =
- last_created_desc->description()->contents();
- const auto& contents_to_set = sdesc->description()->contents();
if (last_created_contents.size() != contents_to_set.size()) {
RTC_LOG(LS_WARNING) << "SDP munging: Number of m= sections does not match "
"last created description.";
return SdpMungingType::kNumberOfContents;
}
+
for (size_t content_index = 0; content_index < last_created_contents.size();
content_index++) {
// TODO: crbug.com/40567530 - more checks are needed here.
@@ -434,80 +469,32 @@ SdpMungingType DetermineSdpMungingType(
continue;
}
if (media_type == MediaType::VIDEO) {
- type = DetermineVideoSdpMungingType(last_created_media_description,
- media_description_to_set);
+ type = DetermineVideoSdpModification(last_created_media_description,
+ media_description_to_set);
if (type != SdpMungingType::kNoModification) {
return type;
}
} else if (media_type == MediaType::AUDIO) {
- type = DetermineAudioSdpMungingType(last_created_media_description,
- media_description_to_set);
+ type = DetermineAudioSdpModification(last_created_media_description,
+ media_description_to_set);
if (type != SdpMungingType::kNoModification) {
return type;
}
}
- // rtcp-mux.
- if (last_created_media_description->rtcp_mux() !=
- media_description_to_set->rtcp_mux()) {
- RTC_LOG(LS_WARNING) << "SDP munging: rtcp-mux modified.";
- return SdpMungingType::kRtcpMux;
+ type = DetermineRtcpModification(last_created_media_description,
+ media_description_to_set);
+ if (type != SdpMungingType::kNoModification) {
+ return type;
}
- // rtcp-rsize.
- if (last_created_media_description->rtcp_reduced_size() !=
- media_description_to_set->rtcp_reduced_size()) {
- RTC_LOG(LS_WARNING) << "SDP munging: rtcp-rsize modified.";
- return media_type == MediaType::AUDIO
- ? SdpMungingType::kAudioCodecsRtcpReducedSize
- : SdpMungingType::kVideoCodecsRtcpReducedSize;
+ type = DetermineCodecModification(last_created_media_description,
+ media_description_to_set);
+ if (type != SdpMungingType::kNoModification) {
+ return type;
}
- // Validate codecs. We should have bailed out earlier if codecs were added
- // or removed.
- auto last_created_codecs = last_created_media_description->codecs();
- auto codecs_to_set = media_description_to_set->codecs();
- if (last_created_codecs.size() == codecs_to_set.size()) {
- for (size_t i = 0; i < last_created_codecs.size(); i++) {
- if (last_created_codecs[i] == codecs_to_set[i]) {
- continue;
- }
- // Codec position swapped.
- for (size_t j = i + 1; j < last_created_codecs.size(); j++) {
- if (last_created_codecs[i] == codecs_to_set[j]) {
- return media_type == MediaType::AUDIO
- ? SdpMungingType::kAudioCodecsReordered
- : SdpMungingType::kVideoCodecsReordered;
- }
- }
- // Same codec but id changed.
- if (last_created_codecs[i].name == codecs_to_set[i].name &&
- last_created_codecs[i].id != codecs_to_set[i].id) {
- return SdpMungingType::kPayloadTypes;
- }
- if (last_created_codecs[i].params != codecs_to_set[i].params) {
- return media_type == MediaType::AUDIO
- ? SdpMungingType::kAudioCodecsFmtp
- : SdpMungingType::kVideoCodecsFmtp;
- }
- if (last_created_codecs[i].feedback_params !=
- codecs_to_set[i].feedback_params) {
- return media_type == MediaType::AUDIO
- ? SdpMungingType::kAudioCodecsRtcpFb
- : SdpMungingType::kVideoCodecsRtcpFb;
- }
- // Nonstandard a=packetization:raw added by munging
- if (media_type == MediaType::VIDEO &&
- last_created_codecs[i].packetization !=
- codecs_to_set[i].packetization) {
- return SdpMungingType::kVideoCodecsModifiedWithRawPacketization;
- }
- // At this point clockrate or channels changed. This should already be
- // rejected later in the process so ignore for munging.
- }
- }
-
- // sendrecv et al.
+ // Validate direction (sendrecv et al).
if (last_created_media_description->direction() !=
media_description_to_set->direction()) {
RTC_LOG(LS_WARNING) << "SDP munging: transceiver direction modified.";
@@ -550,6 +537,52 @@ SdpMungingType DetermineSdpMungingType(
}
}
}
+ return SdpMungingType::kNoModification;
+}
+
+} // namespace
+
+// Determine if the SDP was modified between createOffer and
+// setLocalDescription.
+SdpMungingType DetermineSdpMungingType(
+ const SessionDescriptionInterface* sdesc,
+ const SessionDescriptionInterface* last_created_desc) {
+ if (!sdesc || !sdesc->description()) {
+ RTC_LOG(LS_WARNING) << "SDP munging: Failed to parse session description.";
+ // This is done to ensure the pointers are valid and should not happen at
+ // this point.
+ RTC_DCHECK_NOTREACHED();
+ return SdpMungingType::kCurrentDescriptionFailedToParse;
+ }
+
+ if (!last_created_desc || !last_created_desc->description()) {
+ RTC_LOG(LS_WARNING) << "SDP munging: SetLocalDescription called without "
+ "CreateOffer or CreateAnswer.";
+ if (sdesc->GetType() == SdpType::kOffer) {
+ return SdpMungingType::kWithoutCreateOffer;
+ } else { // answer or pranswer.
+ return SdpMungingType::kWithoutCreateAnswer;
+ }
+ }
+
+ // TODO: crbug.com/40567530 - we currently allow answer->pranswer
+ // so can not check sdesc->GetType() == last_created_desc->GetType().
+
+ SdpMungingType type;
+
+ // TODO: crbug.com/40567530 - change Chromium so that pointer comparison works
+ // at least for implicit local description.
+ if (sdesc->description() == last_created_desc->description()) {
+ return SdpMungingType::kNoModification;
+ }
+
+ // Validate contents.
+ type = DetermineContentsModification(
+ last_created_desc->description()->contents(),
+ sdesc->description()->contents());
+ if (type != SdpMungingType::kNoModification) {
+ return type;
+ }
// Validate transport descriptions.
type = DetermineTransportModification(
@@ -560,7 +593,8 @@ SdpMungingType DetermineSdpMungingType(
}
// Validate number of candidates.
- for (size_t content_index = 0; content_index < last_created_contents.size();
+ for (size_t content_index = 0;
+ content_index < last_created_desc->description()->contents().size();
content_index++) {
// All contents have a (possibly empty) candidate set.
// Check that this holds.