From 79e796015297cef94d1327e8a79b011260cc6f08 Mon Sep 17 00:00:00 2001 From: Steve Anton Date: Mon, 20 Nov 2017 10:25:56 -0800 Subject: [PATCH] Add SDP semantics option to RTCConfiguration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This setting allows the user of PeerConnection to choose whether to use Plan B (current) or Unified Plan (future) semantics. Unified Plan semantics are not yet supported. Bug: chromium:465349 Change-Id: I77a5c376c83f335f734488e11e619582a314bffe Reviewed-on: https://webrtc-review.googlesource.com/22766 Commit-Queue: Steve Anton Reviewed-by: Peter Thatcher Reviewed-by: Henrik Boström Reviewed-by: Zhi Huang Cr-Commit-Position: refs/heads/master@{#20806} --- api/peerconnectioninterface.h | 32 ++++++++++++++++++++++++++++++++ pc/peerconnection.cc | 4 +++- pc/peerconnection.h | 8 +++++--- pc/rtptransceiver.cc | 12 ++++++++++++ pc/rtptransceiver.h | 10 +++++++++- 5 files changed, 61 insertions(+), 5 deletions(-) diff --git a/api/peerconnectioninterface.h b/api/peerconnectioninterface.h index 60f16356c1..c95cc7d3a2 100644 --- a/api/peerconnectioninterface.h +++ b/api/peerconnectioninterface.h @@ -141,6 +141,10 @@ class StatsObserver : public rtc::RefCountInterface { virtual ~StatsObserver() {} }; +// For now, kDefault is interpreted as kPlanB. +// TODO(bugs.webrtc.org/8530): Switch default to kUnifiedPlan. +enum class SdpSemantics { kDefault, kPlanB, kUnifiedPlan }; + class PeerConnectionInterface : public rtc::RefCountInterface { public: // See http://dev.w3.org/2011/webrtc/editor/webrtc.html#state-definitions . @@ -476,6 +480,34 @@ class PeerConnectionInterface : public rtc::RefCountInterface { // called. webrtc::TurnCustomizer* turn_customizer = nullptr; + // Configure the SDP semantics used by this PeerConnection. Note that the + // WebRTC 1.0 specification requires kUnifiedPlan semantics. The + // RtpTransceiver API is only available with kUnifiedPlan semantics. + // + // kPlanB will cause PeerConnection to create offers and answers with at + // most one audio and one video m= section with multiple RtpSenders and + // RtpReceivers specified as multiple a=ssrc lines within the section. This + // will also cause PeerConnection to reject offers/answers with multiple m= + // sections of the same media type. + // + // kUnifiedPlan will cause PeerConnection to create offers and answers with + // multiple m= sections where each m= section maps to one RtpSender and one + // RtpReceiver (an RtpTransceiver), either both audio or both video. Plan B + // style offers or answers will be rejected in calls to SetLocalDescription + // or SetRemoteDescription. + // + // For users who only send at most one audio and one video track, this + // choice does not matter and should be left as kDefault. + // + // For users who wish to send multiple audio/video streams and need to stay + // interoperable with legacy WebRTC implementations, specify kPlanB. + // + // For users who wish to send multiple audio/video streams and/or wish to + // use the new RtpTransceiver API, specify kUnifiedPlan. + // + // TODO(steveanton): Implement support for kUnifiedPlan. + SdpSemantics sdp_semantics = SdpSemantics::kDefault; + // // Don't forget to update operator== if adding something. // diff --git a/pc/peerconnection.cc b/pc/peerconnection.cc index d617c715d0..53c891ef04 100644 --- a/pc/peerconnection.cc +++ b/pc/peerconnection.cc @@ -675,6 +675,7 @@ bool PeerConnectionInterface::RTCConfiguration::operator==( rtc::Optional ice_check_min_interval; rtc::Optional ice_regather_interval_range; webrtc::TurnCustomizer* turn_customizer; + SdpSemantics sdp_semantics; }; static_assert(sizeof(stuff_being_tested_for_equality) == sizeof(*this), "Did you add something to RTCConfiguration and forget to " @@ -710,7 +711,8 @@ bool PeerConnectionInterface::RTCConfiguration::operator==( redetermine_role_on_ice_restart == o.redetermine_role_on_ice_restart && ice_check_min_interval == o.ice_check_min_interval && ice_regather_interval_range == o.ice_regather_interval_range && - turn_customizer == o.turn_customizer; + turn_customizer == o.turn_customizer && + sdp_semantics == o.sdp_semantics; } bool PeerConnectionInterface::RTCConfiguration::operator!=( diff --git a/pc/peerconnection.h b/pc/peerconnection.h index ae6b537bda..0b00588ee1 100644 --- a/pc/peerconnection.h +++ b/pc/peerconnection.h @@ -458,9 +458,11 @@ class PeerConnection : public PeerConnectionInterface, // semantics for creating offers/answers and setting local/remote // descriptions. If this is true the RtpTransceiver API will also be available // to the user. If this is false, Plan B semantics are assumed. - // TODO(steveanton): Flip the default to be Unified Plan once sufficient time - // has passed. - bool IsUnifiedPlan() const { return false; } + // TODO(bugs.webrtc.org/8530): Flip the default to be Unified Plan once + // sufficient time has passed. + bool IsUnifiedPlan() const { + return configuration_.sdp_semantics == SdpSemantics::kUnifiedPlan; + } // Is there an RtpSender of the given type? bool HasRtpSender(cricket::MediaType type) const; diff --git a/pc/rtptransceiver.cc b/pc/rtptransceiver.cc index 7f6ed6d29b..8ca29fce53 100644 --- a/pc/rtptransceiver.cc +++ b/pc/rtptransceiver.cc @@ -20,6 +20,18 @@ RtpTransceiver::RtpTransceiver(cricket::MediaType media_type) media_type == cricket::MEDIA_TYPE_VIDEO); } +RtpTransceiver::RtpTransceiver( + rtc::scoped_refptr> sender, + rtc::scoped_refptr> + receiver) + : unified_plan_(true), media_type_(sender->media_type()) { + RTC_DCHECK(media_type_ == cricket::MEDIA_TYPE_AUDIO || + media_type_ == cricket::MEDIA_TYPE_VIDEO); + RTC_DCHECK_EQ(sender->media_type(), receiver->media_type()); + senders_.push_back(sender); + receivers_.push_back(receiver); +} + RtpTransceiver::~RtpTransceiver() { Stop(); } diff --git a/pc/rtptransceiver.h b/pc/rtptransceiver.h index 9feaac77f5..7053fad5e7 100644 --- a/pc/rtptransceiver.h +++ b/pc/rtptransceiver.h @@ -53,10 +53,18 @@ namespace webrtc { class RtpTransceiver final : public rtc::RefCountedObject { public: - // Construct an RtpTransceiver with no senders, receivers, or channel set. + // Construct a Plan B-style RtpTransceiver with no senders, receivers, or + // channel set. // |media_type| specifies the type of RtpTransceiver (and, by transitivity, // the type of senders, receivers, and channel). Can either by audio or video. explicit RtpTransceiver(cricket::MediaType media_type); + // Construct a Unified Plan-style RtpTransceiver with the given sender and + // receiver. The media type will be derived from the media types of the sender + // and receiver. The sender and receiver should have the same media type. + RtpTransceiver( + rtc::scoped_refptr> sender, + rtc::scoped_refptr> + receiver); ~RtpTransceiver() override; cricket::MediaType media_type() const { return media_type_; }