Associate payload_type with rid
When a value is set in RtpEncodingParameters::codec, the corresponding
payload_type will be set in the SDP a=rid: line.
a=rtpmap:96 VP8/90000
...
a=rtpmap:97 VP9/90000
...
a=rid:r0 send pt=96
a=rid:r1 send pt=97
Bug: webrtc:362277533
Change-Id: Ia9688a5fc83c53cf46621d97e87f8dd363a4d7f0
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/361240
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Florent Castelli <orphis@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#43049}
diff --git a/AUTHORS b/AUTHORS
index 064e126..971987d 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -122,6 +122,7 @@
Saul Kravitz <Saul.Kravitz@celera.com>
Sergio Garcia Murillo <sergio.garcia.murillo@gmail.com>
Shaofan Qi <vshaqi@gmail.com>
+Shigemasa Watanabe <shigemasa7watanabe@gmail.com>
Shuhai Peng <shuhai.peng@intel.com>
Seija <doremylover123@gmail.com>
Silviu Caragea <silviu.cpp@gmail.com>
diff --git a/pc/rtp_sender.h b/pc/rtp_sender.h
index 6c654ca..d8a4d82 100644
--- a/pc/rtp_sender.h
+++ b/pc/rtp_sender.h
@@ -105,6 +105,7 @@
// Used by the owning transceiver to inform the sender on the currently
// selected codecs.
virtual void SetSendCodecs(std::vector<cricket::Codec> send_codecs) = 0;
+ virtual std::vector<cricket::Codec> GetSendCodecs() const = 0;
};
// Shared implementation for RtpSenderInternal interface.
@@ -225,6 +226,9 @@
void SetSendCodecs(std::vector<cricket::Codec> send_codecs) override {
send_codecs_ = send_codecs;
}
+ std::vector<cricket::Codec> GetSendCodecs() const override {
+ return send_codecs_;
+ }
protected:
// If `set_streams_observer` is not null, it is invoked when SetStreams()
diff --git a/pc/sdp_offer_answer.cc b/pc/sdp_offer_answer.cc
index 9d49296..5386faf 100644
--- a/pc/sdp_offer_answer.cc
+++ b/pc/sdp_offer_answer.cc
@@ -794,7 +794,17 @@
if (encoding.rid.empty()) {
continue;
}
- send_rids.push_back(RidDescription(encoding.rid, RidDirection::kSend));
+ auto send_rid = RidDescription(encoding.rid, RidDirection::kSend);
+ if (encoding.codec) {
+ auto send_codecs = transceiver->sender_internal()->GetSendCodecs();
+ for (const cricket::Codec& codec : send_codecs) {
+ if (codec.MatchesRtpCodec(*encoding.codec)) {
+ send_rid.payload_types.push_back(codec.id);
+ break;
+ }
+ }
+ }
+ send_rids.push_back(send_rid);
send_layers.AddLayer(SimulcastLayer(encoding.rid, !encoding.active));
}
diff --git a/pc/sdp_offer_answer_unittest.cc b/pc/sdp_offer_answer_unittest.cc
index 1ee5215..3cbda98 100644
--- a/pc/sdp_offer_answer_unittest.cc
+++ b/pc/sdp_offer_answer_unittest.cc
@@ -41,7 +41,9 @@
#include "rtc_base/rtc_certificate_generator.h"
#include "rtc_base/thread.h"
#include "system_wrappers/include/metrics.h"
+#include "test/gmock.h"
#include "test/gtest.h"
+#include "test/scoped_key_value_config.h"
// This file contains unit tests that relate to the behavior of the
// SdpOfferAnswer module.
@@ -87,7 +89,9 @@
OpenH264DecoderTemplateAdapter,
Dav1dDecoderTemplateAdapter>>(),
nullptr /* audio_mixer */,
- nullptr /* audio_processing */)) {
+ nullptr /* audio_processing */,
+ nullptr /* audio_frame_processor */,
+ std::make_unique<test::ScopedKeyValueConfig>(field_trials_, ""))) {
metrics::Reset();
}
@@ -108,7 +112,21 @@
pc_factory_, result.MoveValue(), std::move(observer));
}
+ std::optional<RtpCodecCapability> FindFirstSendCodecWithName(
+ cricket::MediaType media_type,
+ const std::string& name) const {
+ std::vector<RtpCodecCapability> codecs =
+ pc_factory_->GetRtpSenderCapabilities(media_type).codecs;
+ for (const auto& codec : codecs) {
+ if (absl::EqualsIgnoreCase(codec.name, name)) {
+ return codec;
+ }
+ }
+ return std::nullopt;
+ }
+
protected:
+ test::ScopedKeyValueConfig field_trials_;
std::unique_ptr<rtc::Thread> signaling_thread_;
rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_;
@@ -610,6 +628,51 @@
EXPECT_TRUE(pc->SetRemoteDescription(std::move(rejected_answer)));
}
+TEST_F(SdpOfferAnswerTest, SimulcastOfferWithMixedCodec) {
+ test::ScopedKeyValueConfig field_trials(
+ field_trials_, "WebRTC-MixedCodecSimulcast/Enabled/");
+
+ auto pc = CreatePeerConnection();
+
+ std::optional<RtpCodecCapability> vp8_codec = FindFirstSendCodecWithName(
+ cricket::MEDIA_TYPE_VIDEO, cricket::kVp8CodecName);
+ ASSERT_TRUE(vp8_codec);
+ std::optional<RtpCodecCapability> vp9_codec = FindFirstSendCodecWithName(
+ cricket::MEDIA_TYPE_VIDEO, cricket::kVp9CodecName);
+ ASSERT_TRUE(vp9_codec);
+
+ RtpTransceiverInit init;
+ RtpEncodingParameters rid1;
+ rid1.rid = "1";
+ rid1.codec = *vp8_codec;
+ init.send_encodings.push_back(rid1);
+ RtpEncodingParameters rid2;
+ rid2.rid = "2";
+ rid2.codec = *vp9_codec;
+ init.send_encodings.push_back(rid2);
+
+ auto transceiver = pc->AddTransceiver(cricket::MEDIA_TYPE_VIDEO, init);
+ auto offer = pc->CreateOffer();
+ auto& offer_contents = offer->description()->contents();
+ auto send_codecs = offer_contents[0].media_description()->codecs();
+ // Verify that the serialized SDP includes pt=.
+ std::string sdp;
+ offer->ToString(&sdp);
+ EXPECT_THAT(sdp, testing::HasSubstr("a=rid:1 send pt=" +
+ std::to_string(send_codecs[0].id)));
+ EXPECT_THAT(sdp, testing::HasSubstr("a=rid:2 send pt=" +
+ std::to_string(send_codecs[1].id)));
+ // Verify that SDP containing pt= can be parsed correctly.
+ auto offer2 = CreateSessionDescription(SdpType::kOffer, sdp);
+ auto& offer_contents2 = offer2->description()->contents();
+ auto send_rids2 = offer_contents2[0].media_description()->streams()[0].rids();
+ auto send_codecs2 = offer_contents2[0].media_description()->codecs();
+ EXPECT_EQ(send_rids2[0].payload_types.size(), 1u);
+ EXPECT_EQ(send_rids2[0].payload_types[0], send_codecs2[0].id);
+ EXPECT_EQ(send_rids2[1].payload_types.size(), 1u);
+ EXPECT_EQ(send_rids2[1].payload_types[0], send_codecs2[1].id);
+}
+
TEST_F(SdpOfferAnswerTest, ExpectAllSsrcsSpecifiedInSsrcGroupFid) {
auto pc = CreatePeerConnection();
std::string sdp =
diff --git a/pc/test/mock_rtp_sender_internal.h b/pc/test/mock_rtp_sender_internal.h
index 925e9ec..a8ef817 100644
--- a/pc/test/mock_rtp_sender_internal.h
+++ b/pc/test/mock_rtp_sender_internal.h
@@ -69,6 +69,10 @@
(const RtpParameters&),
(override));
MOCK_METHOD(void, SetSendCodecs, (std::vector<cricket::Codec>), (override));
+ MOCK_METHOD(std::vector<cricket::Codec>,
+ GetSendCodecs,
+ (),
+ (const, override));
MOCK_METHOD(rtc::scoped_refptr<DtmfSenderInterface>,
GetDtmfSender,
(),