Reland "Use Payload Type suggester for all codec merging"
This reverts commit b7abaee819771ca297bac4c51ec0daf62bd9a3fc.
Reason for revert: Suspicion that suspected breakage wasn't real
Original change's description:
> Revert "Use Payload Type suggester for all codec merging"
>
> This reverts commit 0bac2aae596771db020f01a57fee4828081fbc38.
>
> Reason for revert: Suspected breakages downstream
>
> Original change's description:
> > Use Payload Type suggester for all codec merging
> >
> > Bug: webrtc:360058654
> > Change-Id: Id475762253c427c1800c2352a60fc0121c2dc388
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/364783
> > Reviewed-by: Florent Castelli <orphis@webrtc.org>
> > Commit-Queue: Harald Alvestrand <hta@webrtc.org>
> > Cr-Commit-Position: refs/heads/main@{#43267}
>
> Bug: webrtc:360058654, b/375132036
> Change-Id: Ieda626270193e7e6c93903b3c03a691b2bf0c1e2
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366540
> Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
> Commit-Queue: Harald Alvestrand <hta@webrtc.org>
> Reviewed-by: Florent Castelli <orphis@webrtc.org>
> Cr-Commit-Position: refs/heads/main@{#43290}
Bug: webrtc:360058654, b/375132036
Change-Id: Id6e72f7aac81023da43de7627c24dd1a792ea461
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/374304
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#43739}
diff --git a/pc/media_session.cc b/pc/media_session.cc
index 6e85c60..4f297ba 100644
--- a/pc/media_session.cc
+++ b/pc/media_session.cc
@@ -508,7 +508,6 @@
char buffer[100];
rtc::SimpleStringBuilder param(buffer);
param << opus_codec << "/" << opus_codec;
- RTC_LOG(LS_ERROR) << "DEBUG: Setting RED param to " << param.str();
codec.SetParam(kCodecParamNotInNameValueFormat, param.str());
}
}
@@ -656,9 +655,10 @@
// Adds all codecs from `reference_codecs` to `offered_codecs` that don't
// already exist in `offered_codecs` and ensure the payload types don't
// collide.
-void MergeCodecs(const CodecList& reference_codecs,
- CodecList& offered_codecs,
- UsedPayloadTypes* used_pltypes) {
+webrtc::RTCError MergeCodecs(const CodecList& reference_codecs,
+ CodecList& offered_codecs,
+ std::string mid,
+ webrtc::PayloadTypeSuggester& pt_suggester) {
// Add all new codecs that are not RTX/RED codecs.
// The two-pass splitting of the loops means preferring payload types
// of actual codecs with respect to collisions.
@@ -667,7 +667,11 @@
reference_codec.GetResiliencyType() != Codec::ResiliencyType::kRed &&
!FindMatchingCodec(reference_codecs, offered_codecs, reference_codec)) {
Codec codec = reference_codec;
- used_pltypes->FindAndSetIdUsed(&codec);
+ auto id_or_error = pt_suggester.SuggestPayloadType(mid, codec);
+ if (!id_or_error.ok()) {
+ return id_or_error.MoveError();
+ }
+ codec.id = id_or_error.value();
offered_codecs.push_back(codec);
}
}
@@ -694,15 +698,35 @@
rtx_codec.params[kCodecParamAssociatedPayloadType] =
rtc::ToString(matching_codec->id);
- used_pltypes->FindAndSetIdUsed(&rtx_codec);
+ auto id_or_error = pt_suggester.SuggestPayloadType(mid, rtx_codec);
+ if (!id_or_error.ok()) {
+ return id_or_error.MoveError();
+ }
+ rtx_codec.id = id_or_error.value();
offered_codecs.push_back(rtx_codec);
} else if (reference_codec.GetResiliencyType() ==
Codec::ResiliencyType::kRed &&
!FindMatchingCodec(reference_codecs, offered_codecs,
reference_codec)) {
Codec red_codec = reference_codec;
- const Codec* associated_codec =
- GetAssociatedCodecForRed(reference_codecs, red_codec);
+ const Codec* associated_codec = nullptr;
+ // Special case: For voice RED, if parameter is not set, look for
+ // OPUS as the matching codec.
+ // This is because we add the RED codec in audio engine init, but
+ // can't set the parameter until PTs are assigned.
+ if (red_codec.type == Codec::Type::kAudio &&
+ red_codec.params.find(kCodecParamNotInNameValueFormat) ==
+ red_codec.params.end()) {
+ for (const Codec& codec : reference_codecs) {
+ if (absl::EqualsIgnoreCase(codec.name, kOpusCodecName)) {
+ associated_codec = &codec;
+ break;
+ }
+ }
+ } else {
+ associated_codec =
+ GetAssociatedCodecForRed(reference_codecs, red_codec);
+ }
if (associated_codec) {
std::optional<Codec> matching_codec = FindMatchingCodec(
reference_codecs, offered_codecs, *associated_codec);
@@ -716,11 +740,15 @@
rtc::ToString(matching_codec->id) + "/" +
rtc::ToString(matching_codec->id);
}
- used_pltypes->FindAndSetIdUsed(&red_codec);
+ auto id_or_error = pt_suggester.SuggestPayloadType(mid, red_codec);
+ if (!id_or_error.ok()) {
+ return id_or_error.MoveError();
+ }
+ red_codec.id = id_or_error.value();
offered_codecs.push_back(red_codec);
}
}
- offered_codecs.CheckConsistency();
+ return webrtc::RTCError::OK();
}
// `codecs` is a full list of codecs with correct payload type mappings, which
@@ -807,19 +835,28 @@
}
// Compute the union of `codecs1` and `codecs2`.
-CodecList ComputeCodecsUnion(const CodecList codecs1, const CodecList codecs2) {
+webrtc::RTCErrorOr<CodecList> ComputeCodecsUnion(
+ const CodecList& codecs1,
+ const CodecList& codecs2,
+ std::string mid,
+ webrtc::PayloadTypeSuggester& pt_suggester) {
CodecList all_codecs;
- UsedPayloadTypes used_payload_types;
for (const Codec& codec : codecs1) {
Codec codec_mutable = codec;
- used_payload_types.FindAndSetIdUsed(&codec_mutable);
+ auto id_or_error = pt_suggester.SuggestPayloadType(mid, codec);
+ if (!id_or_error.ok()) {
+ return id_or_error.MoveError();
+ }
+ codec_mutable.id = id_or_error.value();
all_codecs.push_back(codec_mutable);
}
// Use MergeCodecs to merge the second half of our list as it already checks
// and fixes problems with duplicate payload types.
- MergeCodecs(codecs2, all_codecs, &used_payload_types);
-
+ webrtc::RTCError error = MergeCodecs(codecs2, all_codecs, mid, pt_suggester);
+ if (!error.ok()) {
+ return error;
+ }
return all_codecs;
}
@@ -1213,7 +1250,8 @@
const MediaSessionOptions& session_options,
const ContentInfo* current_content,
const CodecList& codecs,
- const CodecList& supported_codecs) {
+ const CodecList& supported_codecs,
+ webrtc::PayloadTypeSuggester& pt_suggester) {
CodecList filtered_codecs;
if (!media_description_options.codec_preferences.empty()) {
@@ -1252,7 +1290,19 @@
// Use ComputeCodecsUnion to avoid having duplicate payload IDs.
// This is a no-op for audio until RTX is added.
- filtered_codecs = ComputeCodecsUnion(filtered_codecs, other_codecs);
+ // TODO(hta): figure out why current_content is not always there.
+ std::string mid;
+ if (current_content) {
+ mid = current_content->name;
+ } else {
+ mid = "";
+ }
+ auto codecs_or_error =
+ ComputeCodecsUnion(filtered_codecs, other_codecs, mid, pt_suggester);
+ if (!codecs_or_error.ok()) {
+ return codecs_or_error.MoveError();
+ }
+ filtered_codecs = codecs_or_error.MoveValue();
}
if (media_description_options.type == MEDIA_TYPE_AUDIO &&
@@ -1329,6 +1379,7 @@
transport_desc_factory_->trials().IsEnabled(
"WebRTC-PayloadTypesInTransport")) {
RTC_CHECK(transport_desc_factory_);
+ RTC_CHECK(pt_suggester_);
if (media_engine) {
audio_send_codecs_ = CodecList(media_engine->voice().send_codecs());
audio_recv_codecs_ = CodecList(media_engine->voice().recv_codecs());
@@ -1817,20 +1868,29 @@
RTC_CHECK_NOTREACHED();
}
-void MergeCodecsFromDescription(
+webrtc::RTCError MergeCodecsFromDescription(
const std::vector<const ContentInfo*>& current_active_contents,
CodecList& audio_codecs,
CodecList& video_codecs,
- UsedPayloadTypes* used_pltypes) {
+ webrtc::PayloadTypeSuggester& pt_suggester) {
for (const ContentInfo* content : current_active_contents) {
if (IsMediaContentOfType(content, MEDIA_TYPE_AUDIO)) {
- MergeCodecs(CodecList{content->media_description()->codecs()},
- audio_codecs, used_pltypes);
+ webrtc::RTCError error =
+ MergeCodecs(CodecList{content->media_description()->codecs()},
+ audio_codecs, content->name, pt_suggester);
+ if (!error.ok()) {
+ return error;
+ }
} else if (IsMediaContentOfType(content, MEDIA_TYPE_VIDEO)) {
- MergeCodecs(CodecList{content->media_description()->codecs()},
- video_codecs, used_pltypes);
+ webrtc::RTCError error =
+ MergeCodecs(CodecList{content->media_description()->codecs()},
+ video_codecs, content->name, pt_suggester);
+ if (!error.ok()) {
+ return error;
+ }
}
}
+ return webrtc::RTCError::OK();
}
// Getting codecs for an offer involves these steps:
@@ -1846,15 +1906,20 @@
// First - get all codecs from the current description if the media type
// is used. Add them to `used_pltypes` so the payload type is not reused if a
// new media type is added.
- UsedPayloadTypes used_pltypes;
CodecList video_codec_list(*video_codecs);
CodecList audio_codec_list(*audio_codecs);
- MergeCodecsFromDescription(current_active_contents, audio_codec_list,
- video_codec_list, &used_pltypes);
+ webrtc::RTCError error =
+ MergeCodecsFromDescription(current_active_contents, audio_codec_list,
+ video_codec_list, *pt_suggester_);
+ RTC_CHECK(error.ok());
// Add our codecs that are not in the current description.
- MergeCodecs(CodecList{all_audio_codecs_}, audio_codec_list, &used_pltypes);
- MergeCodecs(CodecList{all_video_codecs_}, video_codec_list, &used_pltypes);
+ error = MergeCodecs(CodecList{all_audio_codecs_}, audio_codec_list, "",
+ *pt_suggester_);
+ RTC_CHECK(error.ok());
+ error = MergeCodecs(CodecList{all_video_codecs_}, video_codec_list, "",
+ *pt_suggester_);
+ RTC_CHECK(error.ok());
*audio_codecs = audio_codec_list.codecs();
*video_codecs = video_codec_list.codecs();
}
@@ -1874,11 +1939,12 @@
// First - get all codecs from the current description if the media type
// is used. Add them to `used_pltypes` so the payload type is not reused if a
// new media type is added.
- UsedPayloadTypes used_pltypes;
CodecList video_codec_list(*video_codecs);
CodecList audio_codec_list(*audio_codecs);
- MergeCodecsFromDescription(current_active_contents, audio_codec_list,
- video_codec_list, &used_pltypes);
+ webrtc::RTCError error =
+ MergeCodecsFromDescription(current_active_contents, audio_codec_list,
+ video_codec_list, *pt_suggester_);
+ RTC_CHECK(error.ok());
// Second - filter out codecs that we don't support at all and should ignore.
CodecList filtered_offered_audio_codecs;
@@ -1909,8 +1975,12 @@
// Add codecs that are not in the current description but were in
// `remote_offer`.
- MergeCodecs(filtered_offered_audio_codecs, audio_codec_list, &used_pltypes);
- MergeCodecs(filtered_offered_video_codecs, video_codec_list, &used_pltypes);
+ error = MergeCodecs(filtered_offered_audio_codecs, audio_codec_list, "",
+ *pt_suggester_);
+ RTC_CHECK(error.ok());
+ error = MergeCodecs(filtered_offered_video_codecs, video_codec_list, "",
+ *pt_suggester_);
+ RTC_CHECK(error.ok());
*audio_codecs = audio_codec_list.codecs();
*video_codecs = video_codec_list.codecs();
}
@@ -2223,9 +2293,9 @@
? GetAudioCodecsForAnswer(offer_rtd, answer_rtd)
: GetVideoCodecsForAnswer(offer_rtd, answer_rtd);
webrtc::RTCErrorOr<std::vector<Codec>> error_or_filtered_codecs =
- GetNegotiatedCodecsForAnswer(media_description_options, session_options,
- current_content, CodecList(codecs),
- CodecList(supported_codecs));
+ GetNegotiatedCodecsForAnswer(
+ media_description_options, session_options, current_content,
+ CodecList(codecs), CodecList(supported_codecs), *pt_suggester_);
if (!error_or_filtered_codecs.ok()) {
return error_or_filtered_codecs.MoveError();
}
@@ -2457,9 +2527,10 @@
video_sendrecv_codecs_.clear();
// Use ComputeCodecsUnion to avoid having duplicate payload IDs
- all_video_codecs_ = ComputeCodecsUnion(CodecList(video_recv_codecs_),
- CodecList(video_send_codecs_));
-
+ auto error_or_codecs = ComputeCodecsUnion(
+ video_recv_codecs_, video_send_codecs_, "", *pt_suggester_);
+ RTC_CHECK(error_or_codecs.ok());
+ all_video_codecs_ = error_or_codecs.MoveValue();
// Use NegotiateCodecs to merge our codec lists, since the operation is
// essentially the same. Put send_codecs as the offered_codecs, which is the
// order we'd like to follow. The reasoning is that encoding is usually more
diff --git a/pc/test/integration_test_helpers.cc b/pc/test/integration_test_helpers.cc
index 39588d2..885d654 100644
--- a/pc/test/integration_test_helpers.cc
+++ b/pc/test/integration_test_helpers.cc
@@ -20,6 +20,7 @@
#include "absl/functional/any_invocable.h"
#include "api/audio/builtin_audio_processing_builder.h"
#include "api/enable_media_with_defaults.h"
+#include "api/field_trials_view.h"
#include "api/jsep.h"
#include "api/peer_connection_interface.h"
#include "api/rtc_event_log/rtc_event_log_factory.h"
diff --git a/pc/used_ids.h b/pc/used_ids.h
index 42ef00a..d55eead 100644
--- a/pc/used_ids.h
+++ b/pc/used_ids.h
@@ -14,9 +14,7 @@
#include <vector>
#include "api/rtp_parameters.h"
-#include "media/base/codec.h"
#include "rtc_base/checks.h"
-#include "rtc_base/logging.h"
namespace cricket {
template <typename IdStruct>
@@ -88,41 +86,6 @@
std::set<int> id_set_;
};
-// Helper class used for finding duplicate RTP payload types among audio, video
-// and data codecs. When bundle is used the payload types may not collide.
-class UsedPayloadTypes : public UsedIds<Codec> {
- public:
- UsedPayloadTypes()
- : UsedIds<Codec>(kFirstDynamicPayloadTypeLowerRange,
- kLastDynamicPayloadTypeUpperRange) {}
-
- // Check if a payload type is valid. The range [64-95] is forbidden
- // when rtcp-mux is used.
- static bool IsIdValid(Codec codec, bool rtcp_mux) {
- if (rtcp_mux && (codec.id > kLastDynamicPayloadTypeLowerRange &&
- codec.id < kFirstDynamicPayloadTypeUpperRange)) {
- return false;
- }
- return codec.id >= 0 && codec.id <= kLastDynamicPayloadTypeUpperRange;
- }
-
- protected:
- bool IsIdUsed(int new_id) override {
- // Range marked for RTCP avoidance is "used".
- if (new_id > kLastDynamicPayloadTypeLowerRange &&
- new_id < kFirstDynamicPayloadTypeUpperRange)
- return true;
- return UsedIds<Codec>::IsIdUsed(new_id);
- }
-
- private:
- static const int kFirstDynamicPayloadTypeLowerRange = 35;
- static const int kLastDynamicPayloadTypeLowerRange = 63;
-
- static const int kFirstDynamicPayloadTypeUpperRange = 96;
- static const int kLastDynamicPayloadTypeUpperRange = 127;
-};
-
// Helper class used for finding duplicate RTP Header extension ids among
// audio and video extensions.
class UsedRtpHeaderExtensionIds : public UsedIds<webrtc::RtpExtension> {