Revert "Reland "Refactoring DataContentDescription class""
This reverts commit 26bf7c4682c7ec72465a1d4d6485d2ec01f671cc.
Reason for revert: breaks downstream test
Original change's description:
> Reland "Refactoring DataContentDescription class"
>
> This reverts commit 1859dc04fd8bd35a3d2ee1140bde3eac210bb0c2.
>
> Reason for revert: Issue likely unrelated to this CL.
>
> Original change's description:
> > Revert "Refactoring DataContentDescription class"
> >
> > This reverts commit 8a9193c217d818fea77b9540bd4ca7ebad53db76.
> >
> > Reason for revert: Breaks downstreams
> >
> > Original change's description:
> > > Refactoring DataContentDescription class
> > >
> > > This CL splits the cricket::DataContentDescription class into
> > > two classes: cricket::DataContentDescription (used for RTP data) and
> > > cricket::SctpDataContentDescription (used for SCTP only).
> > >
> > > SctpDataContentDescription no longer inherits from
> > > MediaContentDescriptionImpl, and no longer contains "codecs".
> > >
> > > Design document:
> > > https://docs.google.com/document/d/1H5LfQxJA2ikMWTQ8FZ3_GAmaXM7knfVQWiSz6ph8VQ0/edit#
> > >
> > > Bug: webrtc:10358
> > > Change-Id: Ie7160610506aeef56d1f821b5fdb5d9492201f43
> > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/132700
> > > Reviewed-by: Steve Anton <steveanton@webrtc.org>
> > > Commit-Queue: Harald Alvestrand <hta@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#27651}
> >
> > TBR=steveanton@webrtc.org,kwiberg@webrtc.org,hbos@webrtc.org,hta@webrtc.org
> >
> > Change-Id: I3b8a68cd481c41ce30eeb5ffbc5da735a9659019
> > No-Presubmit: true
> > No-Tree-Checks: true
> > No-Try: true
> > Bug: webrtc:10358
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/133360
> > Reviewed-by: Seth Hampson <shampson@webrtc.org>
> > Commit-Queue: Seth Hampson <shampson@webrtc.org>
> > Cr-Commit-Position: refs/heads/master@{#27652}
>
> # Not skipping CQ checks because original CL landed > 1 day ago.
>
> Bug: webrtc:10358
> Change-Id: Ie58f862f8c55d2a994eaee1caa107ef701b0770f
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/133624
> Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
> Reviewed-by: Harald Alvestrand <hta@webrtc.org>
> Commit-Queue: Harald Alvestrand <hta@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#27698}
TBR=danilchap@webrtc.org,steveanton@webrtc.org,kwiberg@webrtc.org,hbos@webrtc.org,hta@webrtc.org,shampson@webrtc.org
Change-Id: Ib17939d5f1e8c57652dcb34d94866654192379bb
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:10358
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/133880
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27702}
diff --git a/pc/BUILD.gn b/pc/BUILD.gn
index 7a28d88..4a4a7af 100644
--- a/pc/BUILD.gn
+++ b/pc/BUILD.gn
@@ -72,7 +72,6 @@
]
deps = [
- ":media_protocol_names",
"../api:array_view",
"../api:audio_options_api",
"../api:call_api",
@@ -122,13 +121,6 @@
]
}
-rtc_source_set("media_protocol_names") {
- sources = [
- "media_protocol_names.cc",
- "media_protocol_names.h",
- ]
-}
-
rtc_static_library("peerconnection") {
visibility = [ "*" ]
cflags = []
diff --git a/pc/media_protocol_names.cc b/pc/media_protocol_names.cc
deleted file mode 100644
index 6ce2f02..0000000
--- a/pc/media_protocol_names.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2019 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "pc/media_protocol_names.h"
-
-namespace cricket {
-
-const char kMediaProtocolRtpPrefix[] = "RTP/";
-
-const char kMediaProtocolSctp[] = "SCTP";
-const char kMediaProtocolDtlsSctp[] = "DTLS/SCTP";
-const char kMediaProtocolUdpDtlsSctp[] = "UDP/DTLS/SCTP";
-const char kMediaProtocolTcpDtlsSctp[] = "TCP/DTLS/SCTP";
-
-bool IsDtlsSctp(const std::string& protocol) {
- return protocol == kMediaProtocolDtlsSctp ||
- protocol == kMediaProtocolUdpDtlsSctp ||
- protocol == kMediaProtocolTcpDtlsSctp;
-}
-
-bool IsPlainSctp(const std::string& protocol) {
- return protocol == kMediaProtocolSctp;
-}
-
-bool IsRtpProtocol(const std::string& protocol) {
- return protocol.empty() ||
- (protocol.find(cricket::kMediaProtocolRtpPrefix) != std::string::npos);
-}
-
-bool IsSctpProtocol(const std::string& protocol) {
- return IsPlainSctp(protocol) || IsDtlsSctp(protocol);
-}
-
-} // namespace cricket
diff --git a/pc/media_protocol_names.h b/pc/media_protocol_names.h
deleted file mode 100644
index f97055d..0000000
--- a/pc/media_protocol_names.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2019 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef PC_MEDIA_PROTOCOL_NAMES_H_
-#define PC_MEDIA_PROTOCOL_NAMES_H_
-
-#include <string>
-
-namespace cricket {
-
-// Names or name prefixes of protocols as defined by SDP specifications.
-extern const char kMediaProtocolRtpPrefix[];
-extern const char kMediaProtocolSctp[];
-extern const char kMediaProtocolDtlsSctp[];
-extern const char kMediaProtocolUdpDtlsSctp[];
-extern const char kMediaProtocolTcpDtlsSctp[];
-
-// Returns true if the given media section protocol indicates use of RTP.
-bool IsRtpProtocol(const std::string& protocol);
-// Returns true if the given media section protocol indicates use of SCTP.
-bool IsSctpProtocol(const std::string& protocol);
-
-bool IsDtlsSctp(const std::string& protocol);
-bool IsPlainSctp(const std::string& protocol);
-
-} // namespace cricket
-
-#endif // PC_MEDIA_PROTOCOL_NAMES_H_
diff --git a/pc/media_session.cc b/pc/media_session.cc
index b739e90..8377f10 100644
--- a/pc/media_session.cc
+++ b/pc/media_session.cc
@@ -27,7 +27,6 @@
#include "media/base/media_constants.h"
#include "p2p/base/p2p_constants.h"
#include "pc/channel_manager.h"
-#include "pc/media_protocol_names.h"
#include "pc/rtp_media_utils.h"
#include "pc/srtp_filter.h"
#include "rtc_base/checks.h"
@@ -69,6 +68,13 @@
// but we tolerate "RTP/SAVPF" in offers we receive, for compatibility.
const char kMediaProtocolSavpf[] = "RTP/SAVPF";
+const char kMediaProtocolRtpPrefix[] = "RTP/";
+
+const char kMediaProtocolSctp[] = "SCTP";
+const char kMediaProtocolDtlsSctp[] = "DTLS/SCTP";
+const char kMediaProtocolUdpDtlsSctp[] = "UDP/DTLS/SCTP";
+const char kMediaProtocolTcpDtlsSctp[] = "TCP/DTLS/SCTP";
+
// Note that the below functions support some protocol strings purely for
// legacy compatibility, as required by JSEP in Section 5.1.2, Profile Names
// and Interoperability.
@@ -85,6 +91,20 @@
protocol == "RTP/SAVP" || protocol == "RTP/AVP";
}
+static bool IsDtlsSctp(const std::string& protocol) {
+ return protocol == kMediaProtocolDtlsSctp ||
+ protocol == kMediaProtocolUdpDtlsSctp ||
+ protocol == kMediaProtocolTcpDtlsSctp;
+}
+
+static bool IsPlainSctp(const std::string& protocol) {
+ return protocol == kMediaProtocolSctp;
+}
+
+static bool IsSctp(const std::string& protocol) {
+ return IsPlainSctp(protocol) || IsDtlsSctp(protocol);
+}
+
static RtpTransceiverDirection NegotiateRtpTransceiverDirection(
RtpTransceiverDirection offer,
RtpTransceiverDirection wants) {
@@ -469,7 +489,7 @@
StreamParamsVec* current_streams,
MediaContentDescriptionImpl<C>* content_description) {
// SCTP streams are not negotiated using SDP/ContentDescriptions.
- if (IsSctpProtocol(content_description->protocol())) {
+ if (IsSctp(content_description->protocol())) {
return true;
}
@@ -588,6 +608,11 @@
target_cryptos->end());
}
+bool IsRtpProtocol(const std::string& protocol) {
+ return protocol.empty() ||
+ (protocol.find(cricket::kMediaProtocolRtpPrefix) != std::string::npos);
+}
+
static bool IsRtpContent(SessionDescription* sdesc,
const std::string& content_name) {
bool is_rtp = false;
@@ -716,22 +741,32 @@
// crypto (in current_cryptos) and it is enabled (in secure_policy), crypto is
// created (according to crypto_suites). The created content is added to the
// offer.
-static bool CreateContentOffer(
+template <class C>
+static bool CreateMediaContentOffer(
const MediaDescriptionOptions& media_description_options,
const MediaSessionOptions& session_options,
+ const std::vector<C>& codecs,
const SecurePolicy& secure_policy,
const CryptoParamsVec* current_cryptos,
const std::vector<std::string>& crypto_suites,
const RtpHeaderExtensions& rtp_extensions,
UniqueRandomIdGenerator* ssrc_generator,
StreamParamsVec* current_streams,
- MediaContentDescription* offer) {
+ MediaContentDescriptionImpl<C>* offer) {
+ offer->AddCodecs(codecs);
+
offer->set_rtcp_mux(session_options.rtcp_mux_enabled);
if (offer->type() == cricket::MEDIA_TYPE_VIDEO) {
offer->set_rtcp_reduced_size(true);
}
offer->set_rtp_header_extensions(rtp_extensions);
+ if (!AddStreamParams(media_description_options.sender_options,
+ session_options.rtcp_cname, ssrc_generator,
+ current_streams, offer)) {
+ return false;
+ }
+
AddSimulcastToMediaDescription(media_description_options, offer);
if (secure_policy != SEC_DISABLED) {
@@ -750,30 +785,6 @@
}
return true;
}
-template <class C>
-static bool CreateMediaContentOffer(
- const MediaDescriptionOptions& media_description_options,
- const MediaSessionOptions& session_options,
- const std::vector<C>& codecs,
- const SecurePolicy& secure_policy,
- const CryptoParamsVec* current_cryptos,
- const std::vector<std::string>& crypto_suites,
- const RtpHeaderExtensions& rtp_extensions,
- UniqueRandomIdGenerator* ssrc_generator,
- StreamParamsVec* current_streams,
- MediaContentDescriptionImpl<C>* offer) {
- offer->AddCodecs(codecs);
- if (!AddStreamParams(media_description_options.sender_options,
- session_options.rtcp_cname, ssrc_generator,
- current_streams, offer)) {
- return false;
- }
-
- return CreateContentOffer(media_description_options, session_options,
- secure_policy, current_cryptos, crypto_suites,
- rtp_extensions, ssrc_generator, current_streams,
- offer);
-}
template <class C>
static bool ReferencedCodecsMatch(const std::vector<C>& codecs1,
@@ -1126,27 +1137,6 @@
audio_codecs->end());
}
-template <class C>
-static bool SetCodecsInAnswer(
- const MediaContentDescriptionImpl<C>* offer,
- const std::vector<C>& local_codecs,
- const MediaDescriptionOptions& media_description_options,
- const MediaSessionOptions& session_options,
- UniqueRandomIdGenerator* ssrc_generator,
- StreamParamsVec* current_streams,
- MediaContentDescriptionImpl<C>* answer) {
- std::vector<C> negotiated_codecs;
- NegotiateCodecs(local_codecs, offer->codecs(), &negotiated_codecs);
- answer->AddCodecs(negotiated_codecs);
- answer->set_protocol(offer->protocol());
- if (!AddStreamParams(media_description_options.sender_options,
- session_options.rtcp_cname, ssrc_generator,
- current_streams, answer)) {
- return false; // Something went seriously wrong.
- }
- return true;
-}
-
// Create a media content to be answered for the given |sender_options|
// according to the given session_options.rtcp_mux, session_options.streams,
// codecs, crypto, and current_streams. If we don't currently have crypto (in
@@ -1154,10 +1144,12 @@
// (according to crypto_suites). The codecs, rtcp_mux, and crypto are all
// negotiated with the offer. If the negotiation fails, this method returns
// false. The created content is added to the offer.
+template <class C>
static bool CreateMediaContentAnswer(
- const MediaContentDescription* offer,
+ const MediaContentDescriptionImpl<C>* offer,
const MediaDescriptionOptions& media_description_options,
const MediaSessionOptions& session_options,
+ const std::vector<C>& local_codecs,
const SecurePolicy& sdes_policy,
const CryptoParamsVec* current_cryptos,
const RtpHeaderExtensions& local_rtp_extenstions,
@@ -1165,7 +1157,12 @@
bool enable_encrypted_rtp_header_extensions,
StreamParamsVec* current_streams,
bool bundle_enabled,
- MediaContentDescription* answer) {
+ MediaContentDescriptionImpl<C>* answer) {
+ std::vector<C> negotiated_codecs;
+ NegotiateCodecs(local_codecs, offer->codecs(), &negotiated_codecs);
+ answer->AddCodecs(negotiated_codecs);
+ answer->set_protocol(offer->protocol());
+
answer->set_extmap_allow_mixed_enum(offer->extmap_allow_mixed_enum());
RtpHeaderExtensions negotiated_rtp_extensions;
NegotiateRtpHeaderExtensions(
@@ -1193,6 +1190,12 @@
return false;
}
+ if (!AddStreamParams(media_description_options.sender_options,
+ session_options.rtcp_cname, ssrc_generator,
+ current_streams, answer)) {
+ return false; // Something went seriously wrong.
+ }
+
AddSimulcastToMediaDescription(media_description_options, answer);
answer->set_direction(NegotiateRtpTransceiverDirection(
@@ -1777,10 +1780,7 @@
} else if (IsMediaContentOfType(content, MEDIA_TYPE_DATA)) {
const DataContentDescription* data =
content->media_description()->as_data();
- if (data) {
- // Only relevant for RTP datachannels
- MergeCodecs<DataCodec>(data->codecs(), data_codecs, used_pltypes);
- }
+ MergeCodecs<DataCodec>(data->codecs(), data_codecs, used_pltypes);
}
}
}
@@ -1861,16 +1861,13 @@
} else if (IsMediaContentOfType(&content, MEDIA_TYPE_DATA)) {
const DataContentDescription* data =
content.media_description()->as_data();
- if (data) {
- // RTP data. This part is inactive for SCTP data.
- for (const DataCodec& offered_data_codec : data->codecs()) {
- if (!FindMatchingCodec<DataCodec>(data->codecs(),
- filtered_offered_data_codecs,
- offered_data_codec, nullptr) &&
- FindMatchingCodec<DataCodec>(data->codecs(), data_codecs_,
- offered_data_codec, nullptr)) {
- filtered_offered_data_codecs.push_back(offered_data_codec);
- }
+ for (const DataCodec& offered_data_codec : data->codecs()) {
+ if (!FindMatchingCodec<DataCodec>(data->codecs(),
+ filtered_offered_data_codecs,
+ offered_data_codec, nullptr) &&
+ FindMatchingCodec<DataCodec>(data->codecs(), data_codecs_,
+ offered_data_codec, nullptr)) {
+ filtered_offered_data_codecs.push_back(offered_data_codec);
}
}
}
@@ -2143,90 +2140,6 @@
return true;
}
-bool MediaSessionDescriptionFactory::AddSctpDataContentForOffer(
- const MediaDescriptionOptions& media_description_options,
- const MediaSessionOptions& session_options,
- const ContentInfo* current_content,
- const SessionDescription* current_description,
- StreamParamsVec* current_streams,
- SessionDescription* desc,
- IceCredentialsIterator* ice_credentials) const {
- std::unique_ptr<SctpDataContentDescription> data(
- new SctpDataContentDescription());
-
- bool secure_transport = (transport_desc_factory_->secure() != SEC_DISABLED);
-
- cricket::SecurePolicy sdes_policy =
- IsDtlsActive(current_content, current_description) ? cricket::SEC_DISABLED
- : secure();
- std::vector<std::string> crypto_suites;
- // SDES doesn't make sense for SCTP, so we disable it, and we only
- // get SDES crypto suites for RTP-based data channels.
- sdes_policy = cricket::SEC_DISABLED;
- // Unlike SetMediaProtocol below, we need to set the protocol
- // before we call CreateMediaContentOffer. Otherwise,
- // CreateMediaContentOffer won't know this is SCTP and will
- // generate SSRCs rather than SIDs.
- // TODO(deadbeef): Offer kMediaProtocolUdpDtlsSctp (or TcpDtlsSctp), once
- // it's safe to do so. Older versions of webrtc would reject these
- // protocols; see https://bugs.chromium.org/p/webrtc/issues/detail?id=7706.
- data->set_protocol(secure_transport ? kMediaProtocolDtlsSctp
- : kMediaProtocolSctp);
-
- if (!CreateContentOffer(media_description_options, session_options,
- sdes_policy, GetCryptos(current_content),
- crypto_suites, RtpHeaderExtensions(), ssrc_generator_,
- current_streams, data.get())) {
- return false;
- }
-
- desc->AddContent(media_description_options.mid, MediaProtocolType::kSctp,
- data.release());
- if (!AddTransportOffer(media_description_options.mid,
- media_description_options.transport_options,
- current_description, desc, ice_credentials)) {
- return false;
- }
- return true;
-}
-
-bool MediaSessionDescriptionFactory::AddRtpDataContentForOffer(
- const MediaDescriptionOptions& media_description_options,
- const MediaSessionOptions& session_options,
- const ContentInfo* current_content,
- const SessionDescription* current_description,
- const DataCodecs& data_codecs,
- StreamParamsVec* current_streams,
- SessionDescription* desc,
- IceCredentialsIterator* ice_credentials) const {
- std::unique_ptr<DataContentDescription> data(new DataContentDescription());
- bool secure_transport = (transport_desc_factory_->secure() != SEC_DISABLED);
-
- cricket::SecurePolicy sdes_policy =
- IsDtlsActive(current_content, current_description) ? cricket::SEC_DISABLED
- : secure();
- std::vector<std::string> crypto_suites;
- GetSupportedDataSdesCryptoSuiteNames(session_options.crypto_options,
- &crypto_suites);
- if (!CreateMediaContentOffer(
- media_description_options, session_options, data_codecs, sdes_policy,
- GetCryptos(current_content), crypto_suites, RtpHeaderExtensions(),
- ssrc_generator_, current_streams, data.get())) {
- return false;
- }
-
- data->set_bandwidth(kDataMaxBandwidth);
- SetMediaProtocol(secure_transport, data.get());
- desc->AddContent(media_description_options.mid, MediaProtocolType::kRtp,
- media_description_options.stopped, data.release());
- if (!AddTransportOffer(media_description_options.mid,
- media_description_options.transport_options,
- current_description, desc, ice_credentials)) {
- return false;
- }
- return true;
-}
-
bool MediaSessionDescriptionFactory::AddDataContentForOffer(
const MediaDescriptionOptions& media_description_options,
const MediaSessionOptions& session_options,
@@ -2236,6 +2149,9 @@
StreamParamsVec* current_streams,
SessionDescription* desc,
IceCredentialsIterator* ice_credentials) const {
+ bool secure_transport = (transport_desc_factory_->secure() != SEC_DISABLED);
+
+ std::unique_ptr<DataContentDescription> data(new DataContentDescription());
bool is_sctp = (session_options.data_channel_type == DCT_SCTP);
// If the DataChannel type is not specified, use the DataChannel type in
// the current description.
@@ -2244,16 +2160,52 @@
is_sctp = (current_content->media_description()->protocol() ==
kMediaProtocolSctp);
}
+
+ cricket::SecurePolicy sdes_policy =
+ IsDtlsActive(current_content, current_description) ? cricket::SEC_DISABLED
+ : secure();
+ std::vector<std::string> crypto_suites;
if (is_sctp) {
- return AddSctpDataContentForOffer(
- media_description_options, session_options, current_content,
- current_description, current_streams, desc, ice_credentials);
+ // SDES doesn't make sense for SCTP, so we disable it, and we only
+ // get SDES crypto suites for RTP-based data channels.
+ sdes_policy = cricket::SEC_DISABLED;
+ // Unlike SetMediaProtocol below, we need to set the protocol
+ // before we call CreateMediaContentOffer. Otherwise,
+ // CreateMediaContentOffer won't know this is SCTP and will
+ // generate SSRCs rather than SIDs.
+ // TODO(deadbeef): Offer kMediaProtocolUdpDtlsSctp (or TcpDtlsSctp), once
+ // it's safe to do so. Older versions of webrtc would reject these
+ // protocols; see https://bugs.chromium.org/p/webrtc/issues/detail?id=7706.
+ data->set_protocol(secure_transport ? kMediaProtocolDtlsSctp
+ : kMediaProtocolSctp);
} else {
- return AddRtpDataContentForOffer(media_description_options, session_options,
- current_content, current_description,
- data_codecs, current_streams, desc,
- ice_credentials);
+ GetSupportedDataSdesCryptoSuiteNames(session_options.crypto_options,
+ &crypto_suites);
}
+
+ // Even SCTP uses a "codec".
+ if (!CreateMediaContentOffer(
+ media_description_options, session_options, data_codecs, sdes_policy,
+ GetCryptos(current_content), crypto_suites, RtpHeaderExtensions(),
+ ssrc_generator_, current_streams, data.get())) {
+ return false;
+ }
+
+ if (is_sctp) {
+ desc->AddContent(media_description_options.mid, MediaProtocolType::kSctp,
+ data.release());
+ } else {
+ data->set_bandwidth(kDataMaxBandwidth);
+ SetMediaProtocol(secure_transport, data.get());
+ desc->AddContent(media_description_options.mid, MediaProtocolType::kRtp,
+ media_description_options.stopped, data.release());
+ }
+ if (!AddTransportOffer(media_description_options.mid,
+ media_description_options.transport_options,
+ current_description, desc, ice_credentials)) {
+ return false;
+ }
+ return true;
}
// |audio_codecs| = set of all possible codecs that can be used, with correct
@@ -2335,15 +2287,9 @@
// Do not require or create SDES cryptos if DTLS is used.
cricket::SecurePolicy sdes_policy =
audio_transport->secure() ? cricket::SEC_DISABLED : secure();
- if (!SetCodecsInAnswer(offer_audio_description, filtered_codecs,
- media_description_options, session_options,
- ssrc_generator_, current_streams,
- audio_answer.get())) {
- return false;
- }
if (!CreateMediaContentAnswer(
offer_audio_description, media_description_options, session_options,
- sdes_policy, GetCryptos(current_content),
+ filtered_codecs, sdes_policy, GetCryptos(current_content),
audio_rtp_header_extensions(), ssrc_generator_,
enable_encrypted_rtp_header_extensions_, current_streams,
bundle_enabled, audio_answer.get())) {
@@ -2430,15 +2376,9 @@
// Do not require or create SDES cryptos if DTLS is used.
cricket::SecurePolicy sdes_policy =
video_transport->secure() ? cricket::SEC_DISABLED : secure();
- if (!SetCodecsInAnswer(offer_video_description, filtered_codecs,
- media_description_options, session_options,
- ssrc_generator_, current_streams,
- video_answer.get())) {
- return false;
- }
if (!CreateMediaContentAnswer(
offer_video_description, media_description_options, session_options,
- sdes_policy, GetCryptos(current_content),
+ filtered_codecs, sdes_policy, GetCryptos(current_content),
video_rtp_header_extensions(), ssrc_generator_,
enable_encrypted_rtp_header_extensions_, current_streams,
bundle_enabled, video_answer.get())) {
@@ -2486,52 +2426,29 @@
return false;
}
+ std::unique_ptr<DataContentDescription> data_answer(
+ new DataContentDescription());
// Do not require or create SDES cryptos if DTLS is used.
cricket::SecurePolicy sdes_policy =
data_transport->secure() ? cricket::SEC_DISABLED : secure();
bool bundle_enabled = offer_description->HasGroup(GROUP_TYPE_BUNDLE) &&
session_options.bundle_enabled;
RTC_CHECK(IsMediaContentOfType(offer_content, MEDIA_TYPE_DATA));
- std::unique_ptr<MediaContentDescription> data_answer;
- if (offer_content->media_description()->as_sctp()) {
- // SCTP data content
- data_answer = absl::make_unique<SctpDataContentDescription>();
- const SctpDataContentDescription* offer_data_description =
- offer_content->media_description()->as_sctp();
- // Respond with the offerer's proto, whatever it is.
- data_answer->as_sctp()->set_protocol(offer_data_description->protocol());
- if (!CreateMediaContentAnswer(
- offer_data_description, media_description_options, session_options,
- sdes_policy, GetCryptos(current_content), RtpHeaderExtensions(),
- ssrc_generator_, enable_encrypted_rtp_header_extensions_,
- current_streams, bundle_enabled, data_answer.get())) {
- return false; // Fails the session setup.
- }
- // Respond with sctpmap if the offer uses sctpmap.
- bool offer_uses_sctpmap = offer_data_description->use_sctpmap();
- data_answer->as_sctp()->set_use_sctpmap(offer_uses_sctpmap);
- } else {
- // RTP offer
- data_answer = absl::make_unique<DataContentDescription>();
-
- RTC_CHECK(offer_content->media_description()->as_data());
- const DataContentDescription* offer_data_description =
- offer_content->media_description()->as_data();
- if (!SetCodecsInAnswer(offer_data_description, data_codecs,
- media_description_options, session_options,
- ssrc_generator_, current_streams,
- data_answer->as_data())) {
- return false;
- }
- if (!CreateMediaContentAnswer(
- offer_data_description, media_description_options, session_options,
- sdes_policy, GetCryptos(current_content), RtpHeaderExtensions(),
- ssrc_generator_, enable_encrypted_rtp_header_extensions_,
- current_streams, bundle_enabled, data_answer.get())) {
- return false; // Fails the session setup.
- }
+ const DataContentDescription* offer_data_description =
+ offer_content->media_description()->as_data();
+ if (!CreateMediaContentAnswer(
+ offer_data_description, media_description_options, session_options,
+ data_codecs, sdes_policy, GetCryptos(current_content),
+ RtpHeaderExtensions(), ssrc_generator_,
+ enable_encrypted_rtp_header_extensions_, current_streams,
+ bundle_enabled, data_answer.get())) {
+ return false; // Fails the session setup.
}
+ // Respond with sctpmap if the offer uses sctpmap.
+ bool offer_uses_sctpmap = offer_data_description->use_sctpmap();
+ data_answer->set_use_sctpmap(offer_uses_sctpmap);
+
bool secure = bundle_transport ? bundle_transport->description.secure()
: data_transport->secure();
@@ -2654,26 +2571,20 @@
const AudioContentDescription* GetFirstAudioContentDescription(
const SessionDescription* sdesc) {
- auto desc = GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_AUDIO);
- return desc ? desc->as_audio() : nullptr;
+ return static_cast<const AudioContentDescription*>(
+ GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_AUDIO));
}
const VideoContentDescription* GetFirstVideoContentDescription(
const SessionDescription* sdesc) {
- auto desc = GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO);
- return desc ? desc->as_video() : nullptr;
+ return static_cast<const VideoContentDescription*>(
+ GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO));
}
const DataContentDescription* GetFirstDataContentDescription(
const SessionDescription* sdesc) {
- auto desc = GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA);
- return desc ? desc->as_data() : nullptr;
-}
-
-const SctpDataContentDescription* GetFirstSctpDataContentDescription(
- const SessionDescription* sdesc) {
- auto desc = GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA);
- return desc ? desc->as_sctp() : nullptr;
+ return static_cast<const DataContentDescription*>(
+ GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA));
}
//
@@ -2732,26 +2643,20 @@
AudioContentDescription* GetFirstAudioContentDescription(
SessionDescription* sdesc) {
- auto desc = GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_AUDIO);
- return desc ? desc->as_audio() : nullptr;
+ return static_cast<AudioContentDescription*>(
+ GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_AUDIO));
}
VideoContentDescription* GetFirstVideoContentDescription(
SessionDescription* sdesc) {
- auto desc = GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO);
- return desc ? desc->as_video() : nullptr;
+ return static_cast<VideoContentDescription*>(
+ GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO));
}
DataContentDescription* GetFirstDataContentDescription(
SessionDescription* sdesc) {
- auto desc = GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA);
- return desc ? desc->as_data() : nullptr;
-}
-
-SctpDataContentDescription* GetFirstSctpDataContentDescription(
- SessionDescription* sdesc) {
- auto desc = GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA);
- return desc ? desc->as_sctp() : nullptr;
+ return static_cast<DataContentDescription*>(
+ GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA));
}
} // namespace cricket
diff --git a/pc/media_session.h b/pc/media_session.h
index 112508e..33c8c17 100644
--- a/pc/media_session.h
+++ b/pc/media_session.h
@@ -24,7 +24,6 @@
#include "p2p/base/ice_credentials_iterator.h"
#include "p2p/base/transport_description_factory.h"
#include "pc/jsep_transport.h"
-#include "pc/media_protocol_names.h"
#include "pc/session_description.h"
#include "rtc_base/unique_id_generator.h"
@@ -240,23 +239,6 @@
SessionDescription* desc,
IceCredentialsIterator* ice_credentials) const;
- bool AddSctpDataContentForOffer(
- const MediaDescriptionOptions& media_description_options,
- const MediaSessionOptions& session_options,
- const ContentInfo* current_content,
- const SessionDescription* current_description,
- StreamParamsVec* current_streams,
- SessionDescription* desc,
- IceCredentialsIterator* ice_credentials) const;
- bool AddRtpDataContentForOffer(
- const MediaDescriptionOptions& media_description_options,
- const MediaSessionOptions& session_options,
- const ContentInfo* current_content,
- const SessionDescription* current_description,
- const DataCodecs& data_codecs,
- StreamParamsVec* current_streams,
- SessionDescription* desc,
- IceCredentialsIterator* ice_credentials) const;
bool AddDataContentForOffer(
const MediaDescriptionOptions& media_description_options,
const MediaSessionOptions& session_options,
@@ -349,8 +331,6 @@
const SessionDescription* sdesc);
const DataContentDescription* GetFirstDataContentDescription(
const SessionDescription* sdesc);
-const SctpDataContentDescription* GetFirstSctpDataContentDescription(
- const SessionDescription* sdesc);
// Non-const versions of the above functions.
// Useful when modifying an existing description.
ContentInfo* GetFirstMediaContent(ContentInfos* contents, MediaType media_type);
@@ -368,8 +348,6 @@
SessionDescription* sdesc);
DataContentDescription* GetFirstDataContentDescription(
SessionDescription* sdesc);
-SctpDataContentDescription* GetFirstSctpDataContentDescription(
- SessionDescription* sdesc);
// Helper functions to return crypto suites used for SDES.
void GetSupportedAudioSdesCryptoSuites(
@@ -391,6 +369,9 @@
const webrtc::CryptoOptions& crypto_options,
std::vector<std::string>* crypto_suite_names);
+// Returns true if the given media section protocol indicates use of RTP.
+bool IsRtpProtocol(const std::string& protocol);
+
} // namespace cricket
#endif // PC_MEDIA_SESSION_H_
diff --git a/pc/media_session_unittest.cc b/pc/media_session_unittest.cc
index bd01041..1136607 100644
--- a/pc/media_session_unittest.cc
+++ b/pc/media_session_unittest.cc
@@ -62,7 +62,6 @@
using cricket::MediaType;
using cricket::RidDescription;
using cricket::RidDirection;
-using cricket::SctpDataContentDescription;
using cricket::SEC_DISABLED;
using cricket::SEC_ENABLED;
using cricket::SEC_REQUIRED;
@@ -1337,16 +1336,15 @@
ASSERT_TRUE(offer.get() != NULL);
ContentInfo* dc_offer = offer->GetContentByName("data");
ASSERT_TRUE(dc_offer != NULL);
- SctpDataContentDescription* dcd_offer =
- dc_offer->media_description()->as_sctp();
+ DataContentDescription* dcd_offer = dc_offer->media_description()->as_data();
EXPECT_TRUE(dcd_offer->use_sctpmap());
std::unique_ptr<SessionDescription> answer =
f2_.CreateAnswer(offer.get(), opts, NULL);
const ContentInfo* dc_answer = answer->GetContentByName("data");
ASSERT_TRUE(dc_answer != NULL);
- const SctpDataContentDescription* dcd_answer =
- dc_answer->media_description()->as_sctp();
+ const DataContentDescription* dcd_answer =
+ dc_answer->media_description()->as_data();
EXPECT_TRUE(dcd_answer->use_sctpmap());
}
@@ -1358,16 +1356,15 @@
ASSERT_TRUE(offer.get() != NULL);
ContentInfo* dc_offer = offer->GetContentByName("data");
ASSERT_TRUE(dc_offer != NULL);
- SctpDataContentDescription* dcd_offer =
- dc_offer->media_description()->as_sctp();
+ DataContentDescription* dcd_offer = dc_offer->media_description()->as_data();
dcd_offer->set_use_sctpmap(false);
std::unique_ptr<SessionDescription> answer =
f2_.CreateAnswer(offer.get(), opts, NULL);
const ContentInfo* dc_answer = answer->GetContentByName("data");
ASSERT_TRUE(dc_answer != NULL);
- const SctpDataContentDescription* dcd_answer =
- dc_answer->media_description()->as_sctp();
+ const DataContentDescription* dcd_answer =
+ dc_answer->media_description()->as_data();
EXPECT_FALSE(dcd_answer->use_sctpmap());
}
@@ -1388,9 +1385,7 @@
ASSERT_TRUE(offer.get() != nullptr);
ContentInfo* dc_offer = offer->GetContentByName("data");
ASSERT_TRUE(dc_offer != nullptr);
- SctpDataContentDescription* dcd_offer =
- dc_offer->media_description()->as_sctp();
- ASSERT_TRUE(dcd_offer);
+ DataContentDescription* dcd_offer = dc_offer->media_description()->as_data();
std::vector<std::string> protos = {"DTLS/SCTP", "UDP/DTLS/SCTP",
"TCP/DTLS/SCTP"};
@@ -1400,8 +1395,8 @@
f2_.CreateAnswer(offer.get(), opts, nullptr);
const ContentInfo* dc_answer = answer->GetContentByName("data");
ASSERT_TRUE(dc_answer != nullptr);
- const SctpDataContentDescription* dcd_answer =
- dc_answer->media_description()->as_sctp();
+ const DataContentDescription* dcd_answer =
+ dc_answer->media_description()->as_data();
EXPECT_FALSE(dc_answer->rejected);
EXPECT_EQ(proto, dcd_answer->protocol());
}
@@ -1485,8 +1480,7 @@
ASSERT_TRUE(dc_offer != NULL);
DataContentDescription* dcd_offer = dc_offer->media_description()->as_data();
ASSERT_TRUE(dcd_offer != NULL);
- // Offer must be acceptable as an RTP protocol in order to be set.
- std::string protocol = "RTP/a weird unknown protocol";
+ std::string protocol = "a weird unknown protocol";
dcd_offer->set_protocol(protocol);
std::unique_ptr<SessionDescription> answer =
diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc
index bf3ad56..1b011a3 100644
--- a/pc/peer_connection.cc
+++ b/pc/peer_connection.cc
@@ -559,13 +559,24 @@
// Get the SCTP port out of a SessionDescription.
// Return -1 if not found.
int GetSctpPort(const SessionDescription* session_description) {
- const cricket::SctpDataContentDescription* data_desc =
- GetFirstSctpDataContentDescription(session_description);
+ const cricket::DataContentDescription* data_desc =
+ GetFirstDataContentDescription(session_description);
RTC_DCHECK(data_desc);
if (!data_desc) {
return -1;
}
- return data_desc->port();
+ std::string value;
+ cricket::DataCodec match_pattern(cricket::kGoogleSctpDataCodecPlType,
+ cricket::kGoogleSctpDataCodecName);
+ for (const cricket::DataCodec& codec : data_desc->codecs()) {
+ if (!codec.Matches(match_pattern)) {
+ continue;
+ }
+ if (codec.GetParam(cricket::kCodecParamPort, &value)) {
+ return rtc::FromString<int>(value);
+ }
+ }
+ return -1;
}
// Returns true if |new_desc| requests an ICE restart (i.e., new ufrag/pwd).
@@ -2413,9 +2424,8 @@
if (data_content) {
const cricket::DataContentDescription* data_desc =
data_content->media_description()->as_data();
- // data_desc will be null if this is an SCTP description.
- if (data_desc && absl::StartsWith(data_desc->protocol(),
- cricket::kMediaProtocolRtpPrefix)) {
+ if (absl::StartsWith(data_desc->protocol(),
+ cricket::kMediaProtocolRtpPrefix)) {
UpdateLocalRtpDataChannels(data_desc->streams());
}
}
diff --git a/pc/peer_connection_data_channel_unittest.cc b/pc/peer_connection_data_channel_unittest.cc
index 4080dd9..ad3817e 100644
--- a/pc/peer_connection_data_channel_unittest.cc
+++ b/pc/peer_connection_data_channel_unittest.cc
@@ -193,11 +193,14 @@
// Changes the SCTP data channel port on the given session description.
void ChangeSctpPortOnDescription(cricket::SessionDescription* desc,
int port) {
+ cricket::DataCodec sctp_codec(cricket::kGoogleSctpDataCodecPlType,
+ cricket::kGoogleSctpDataCodecName);
+ sctp_codec.SetParam(cricket::kCodecParamPort, port);
+
auto* data_content = cricket::GetFirstDataContent(desc);
RTC_DCHECK(data_content);
- auto* data_desc = data_content->media_description()->as_sctp();
- RTC_DCHECK(data_desc);
- data_desc->set_port(port);
+ auto* data_desc = data_content->media_description()->as_data();
+ data_desc->set_codecs({sctp_codec});
}
std::unique_ptr<rtc::VirtualSocketServer> vss_;
diff --git a/pc/peer_connection_integrationtest.cc b/pc/peer_connection_integrationtest.cc
index e84ffe0..6087f0f 100644
--- a/pc/peer_connection_integrationtest.cc
+++ b/pc/peer_connection_integrationtest.cc
@@ -3450,8 +3450,8 @@
}
static void MakeSpecCompliantSctpOffer(cricket::SessionDescription* desc) {
- cricket::SctpDataContentDescription* dcd_offer =
- GetFirstSctpDataContentDescription(desc);
+ cricket::DataContentDescription* dcd_offer =
+ GetFirstDataContentDescription(desc);
ASSERT_TRUE(dcd_offer);
dcd_offer->set_use_sctpmap(false);
dcd_offer->set_protocol("UDP/DTLS/SCTP");
diff --git a/pc/session_description.h b/pc/session_description.h
index e5a7dfa..7b70ddf 100644
--- a/pc/session_description.h
+++ b/pc/session_description.h
@@ -26,7 +26,6 @@
#include "media/base/stream_params.h"
#include "p2p/base/transport_description.h"
#include "p2p/base/transport_info.h"
-#include "pc/media_protocol_names.h"
#include "pc/simulcast_description.h"
#include "rtc_base/socket_address.h"
@@ -45,6 +44,12 @@
extern const char kMediaProtocolDtlsSavpf[];
+extern const char kMediaProtocolRtpPrefix[];
+
+extern const char kMediaProtocolSctp[];
+extern const char kMediaProtocolDtlsSctp[];
+extern const char kMediaProtocolUdpDtlsSctp[];
+extern const char kMediaProtocolTcpDtlsSctp[];
// Options to control how session descriptions are generated.
const int kAutoBandwidth = -1;
@@ -52,7 +57,6 @@
class AudioContentDescription;
class DataContentDescription;
class VideoContentDescription;
-class SctpDataContentDescription;
// Describes a session description media section. There are subclasses for each
// media type (audio, video, data) that will have additional information.
@@ -78,9 +82,6 @@
virtual DataContentDescription* as_data() { return nullptr; }
virtual const DataContentDescription* as_data() const { return nullptr; }
- virtual SctpDataContentDescription* as_sctp() { return nullptr; }
- virtual const SctpDataContentDescription* as_sctp() const { return nullptr; }
-
virtual bool has_codecs() const = 0;
virtual MediaContentDescription* Copy() const = 0;
@@ -88,9 +89,7 @@
// |protocol| is the expected media transport protocol, such as RTP/AVPF,
// RTP/SAVPF or SCTP/DTLS.
std::string protocol() const { return protocol_; }
- virtual void set_protocol(const std::string& protocol) {
- protocol_ = protocol;
- }
+ void set_protocol(const std::string& protocol) { protocol_ = protocol; }
webrtc::RtpTransceiverDirection direction() const { return direction_; }
void set_direction(webrtc::RtpTransceiverDirection direction) {
@@ -248,17 +247,12 @@
template <class C>
class MediaContentDescriptionImpl : public MediaContentDescription {
public:
- void set_protocol(const std::string& protocol) override {
- RTC_DCHECK(IsRtpProtocol(protocol));
- protocol_ = protocol;
- }
-
typedef C CodecType;
// Codecs should be in preference order (most preferred codec first).
const std::vector<C>& codecs() const { return codecs_; }
void set_codecs(const std::vector<C>& codecs) { codecs_ = codecs; }
- bool has_codecs() const override { return !codecs_.empty(); }
+ virtual bool has_codecs() const { return !codecs_.empty(); }
bool HasCodec(int id) {
bool found = false;
for (typename std::vector<C>::iterator iter = codecs_.begin();
@@ -324,37 +318,12 @@
virtual MediaType type() const { return MEDIA_TYPE_DATA; }
virtual DataContentDescription* as_data() { return this; }
virtual const DataContentDescription* as_data() const { return this; }
-};
-
-class SctpDataContentDescription : public MediaContentDescription {
- public:
- SctpDataContentDescription() {}
- SctpDataContentDescription* Copy() const override {
- return new SctpDataContentDescription(*this);
- }
- MediaType type() const override { return MEDIA_TYPE_DATA; }
- SctpDataContentDescription* as_sctp() override { return this; }
- const SctpDataContentDescription* as_sctp() const override { return this; }
- bool has_codecs() const override { return false; }
- void set_protocol(const std::string& protocol) override {
- RTC_DCHECK(IsSctpProtocol(protocol));
- protocol_ = protocol;
- }
bool use_sctpmap() const { return use_sctpmap_; }
void set_use_sctpmap(bool enable) { use_sctpmap_ = enable; }
- int port() const { return port_; }
- void set_port(int port) { port_ = port; }
- int max_message_size() const { return max_message_size_; }
- void set_max_message_size(int max_message_size) {
- max_message_size_ = max_message_size;
- }
private:
- bool use_sctpmap_ = true; // Note: "true" is no longer conformant.
- // Defaults should be constants imported from SCTP. Quick hack.
- int port_ = 5000;
- int max_message_size_ = 256 * 1024;
+ bool use_sctpmap_ = true;
};
// Protocol used for encoding media. This is the "top level" protocol that may
diff --git a/pc/webrtc_sdp.cc b/pc/webrtc_sdp.cc
index 7c65f87..984a1e1 100644
--- a/pc/webrtc_sdp.cc
+++ b/pc/webrtc_sdp.cc
@@ -54,30 +54,29 @@
using cricket::ContentInfo;
using cricket::CryptoParams;
using cricket::DataContentDescription;
-using cricket::ICE_CANDIDATE_COMPONENT_RTCP;
using cricket::ICE_CANDIDATE_COMPONENT_RTP;
-using cricket::kCodecParamAssociatedPayloadType;
-using cricket::kCodecParamMaxAverageBitrate;
+using cricket::ICE_CANDIDATE_COMPONENT_RTCP;
using cricket::kCodecParamMaxBitrate;
-using cricket::kCodecParamMaxPlaybackRate;
using cricket::kCodecParamMaxPTime;
using cricket::kCodecParamMaxQuantization;
using cricket::kCodecParamMinBitrate;
using cricket::kCodecParamMinPTime;
using cricket::kCodecParamPTime;
-using cricket::kCodecParamSctpProtocol;
-using cricket::kCodecParamSctpStreams;
using cricket::kCodecParamSPropStereo;
using cricket::kCodecParamStartBitrate;
using cricket::kCodecParamStereo;
-using cricket::kCodecParamUseDtx;
using cricket::kCodecParamUseInbandFec;
+using cricket::kCodecParamUseDtx;
+using cricket::kCodecParamSctpProtocol;
+using cricket::kCodecParamSctpStreams;
+using cricket::kCodecParamMaxAverageBitrate;
+using cricket::kCodecParamMaxPlaybackRate;
+using cricket::kCodecParamAssociatedPayloadType;
using cricket::MediaContentDescription;
-using cricket::MediaProtocolType;
using cricket::MediaType;
-using cricket::RidDescription;
using cricket::RtpHeaderExtensions;
-using cricket::SctpDataContentDescription;
+using cricket::MediaProtocolType;
+using cricket::RidDescription;
using cricket::SimulcastDescription;
using cricket::SimulcastLayer;
using cricket::SimulcastLayerList;
@@ -1338,6 +1337,8 @@
const MediaContentDescription* media_desc = content_info->media_description();
RTC_DCHECK(media_desc);
+ int sctp_port = cricket::kSctpDefaultPort;
+
// RFC 4566
// m=<media> <port> <proto> <fmt>
// fmt is a list of payload type numbers that MAY be used in the session.
@@ -1365,18 +1366,24 @@
fmt.append(rtc::ToString(codec.id));
}
} else if (media_type == cricket::MEDIA_TYPE_DATA) {
+ const DataContentDescription* data_desc = media_desc->as_data();
if (IsDtlsSctp(media_desc->protocol())) {
- const cricket::SctpDataContentDescription* data_desc =
- media_desc->as_sctp();
fmt.append(" ");
if (data_desc->use_sctpmap()) {
- fmt.append(rtc::ToString(data_desc->port()));
+ for (const cricket::DataCodec& codec : data_desc->codecs()) {
+ if (absl::EqualsIgnoreCase(codec.name,
+ cricket::kGoogleSctpDataCodecName) &&
+ codec.GetParam(cricket::kCodecParamPort, &sctp_port)) {
+ break;
+ }
+ }
+
+ fmt.append(rtc::ToString(sctp_port));
} else {
fmt.append(kDefaultSctpmapProtocol);
}
} else {
- const DataContentDescription* data_desc = media_desc->as_data();
for (const cricket::DataCodec& codec : data_desc->codecs()) {
fmt.append(" ");
fmt.append(rtc::ToString(codec.id));
@@ -1516,10 +1523,9 @@
AddLine(os.str(), message);
if (IsDtlsSctp(media_desc->protocol())) {
- const cricket::SctpDataContentDescription* data_desc =
- media_desc->as_sctp();
+ const DataContentDescription* data_desc = media_desc->as_data();
bool use_sctpmap = data_desc->use_sctpmap();
- BuildSctpContentAttributes(message, data_desc->port(), use_sctpmap);
+ BuildSctpContentAttributes(message, sctp_port, use_sctpmap);
} else if (IsRtp(media_desc->protocol())) {
BuildRtpContentAttributes(media_desc, media_type, msid_signaling, message);
}
@@ -1828,6 +1834,43 @@
}
}
+cricket::DataCodec FindOrMakeSctpDataCodec(DataContentDescription* media_desc) {
+ for (const auto& codec : media_desc->codecs()) {
+ if (absl::EqualsIgnoreCase(codec.name, cricket::kGoogleSctpDataCodecName)) {
+ return codec;
+ }
+ }
+ cricket::DataCodec codec_port(cricket::kGoogleSctpDataCodecPlType,
+ cricket::kGoogleSctpDataCodecName);
+ return codec_port;
+}
+
+bool AddOrModifySctpDataCodecPort(DataContentDescription* media_desc,
+ int sctp_port) {
+ // Add the SCTP Port number as a pseudo-codec "port" parameter
+ auto codec = FindOrMakeSctpDataCodec(media_desc);
+ int dummy;
+ if (codec.GetParam(cricket::kCodecParamPort, &dummy)) {
+ return false;
+ }
+ codec.SetParam(cricket::kCodecParamPort, sctp_port);
+ media_desc->AddOrReplaceCodec(codec);
+ return true;
+}
+
+bool AddOrModifySctpDataMaxMessageSize(DataContentDescription* media_desc,
+ int max_message_size) {
+ // Add the SCTP Max Message Size as a pseudo-parameter to the codec
+ auto codec = FindOrMakeSctpDataCodec(media_desc);
+ int dummy;
+ if (codec.GetParam(cricket::kCodecParamMaxMessageSize, &dummy)) {
+ return false;
+ }
+ codec.SetParam(cricket::kCodecParamMaxMessageSize, max_message_size);
+ media_desc->AddOrReplaceCodec(codec);
+ return true;
+}
+
bool GetMinValue(const std::vector<int>& values, int* value) {
if (values.empty()) {
return false;
@@ -2705,30 +2748,24 @@
payload_types, pos, &content_name, &bundle_only,
§ion_msid_signaling, &transport, candidates, error);
} else if (HasAttribute(line, kMediaTypeData)) {
- if (IsDtlsSctp(protocol)) {
- auto data_desc = absl::make_unique<SctpDataContentDescription>();
+ std::unique_ptr<DataContentDescription> data_desc =
+ ParseContentDescription<DataContentDescription>(
+ message, cricket::MEDIA_TYPE_DATA, mline_index, protocol,
+ payload_types, pos, &content_name, &bundle_only,
+ §ion_msid_signaling, &transport, candidates, error);
+
+ if (data_desc && IsDtlsSctp(protocol)) {
int p;
if (rtc::FromString(fields[3], &p)) {
- data_desc->set_port(p);
+ if (!AddOrModifySctpDataCodecPort(data_desc.get(), p)) {
+ return false;
+ }
} else if (fields[3] == kDefaultSctpmapProtocol) {
data_desc->set_use_sctpmap(false);
}
- if (!ParseContent(message, cricket::MEDIA_TYPE_DATA, mline_index,
- protocol, payload_types, pos, &content_name,
- &bundle_only, §ion_msid_signaling,
- data_desc.get(), &transport, candidates, error)) {
- return false;
- }
- content = std::move(data_desc);
- } else {
- // RTP
- std::unique_ptr<DataContentDescription> data_desc =
- ParseContentDescription<DataContentDescription>(
- message, cricket::MEDIA_TYPE_DATA, mline_index, protocol,
- payload_types, pos, &content_name, &bundle_only,
- §ion_msid_signaling, &transport, candidates, error);
- content = std::move(data_desc);
}
+
+ content = std::move(data_desc);
} else {
RTC_LOG(LS_WARNING) << "Unsupported media type: " << line;
continue;
@@ -3101,15 +3138,13 @@
line, "sctp-port attribute found in non-data media description.",
error);
}
- if (media_desc->as_sctp()->use_sctpmap()) {
- return ParseFailed(
- line, "sctp-port attribute can't be used with sctpmap.", error);
- }
int sctp_port;
if (!ParseSctpPort(line, &sctp_port, error)) {
return false;
}
- media_desc->as_sctp()->set_port(sctp_port);
+ if (!AddOrModifySctpDataCodecPort(media_desc->as_data(), sctp_port)) {
+ return false;
+ }
} else if (IsDtlsSctp(protocol) &&
HasAttribute(line, kAttributeMaxMessageSize)) {
if (media_type != cricket::MEDIA_TYPE_DATA) {
@@ -3122,7 +3157,10 @@
if (!ParseSctpMaxMessageSize(line, &max_message_size, error)) {
return false;
}
- media_desc->as_sctp()->set_max_message_size(max_message_size);
+ if (!AddOrModifySctpDataMaxMessageSize(media_desc->as_data(),
+ max_message_size)) {
+ return false;
+ }
} else if (IsRtp(protocol)) {
//
// RTP specific attrubtes
diff --git a/pc/webrtc_sdp_unittest.cc b/pc/webrtc_sdp_unittest.cc
index 78fc8e0..3de2b60 100644
--- a/pc/webrtc_sdp_unittest.cc
+++ b/pc/webrtc_sdp_unittest.cc
@@ -65,7 +65,6 @@
using cricket::RELAY_PORT_TYPE;
using cricket::RidDescription;
using cricket::RidDirection;
-using cricket::SctpDataContentDescription;
using cricket::SessionDescription;
using cricket::SimulcastDescription;
using cricket::SimulcastLayer;
@@ -1446,15 +1445,8 @@
void CompareDataContentDescription(const DataContentDescription* dcd1,
const DataContentDescription* dcd2) {
- CompareMediaContentDescription<DataContentDescription>(dcd1, dcd2);
- }
-
- void CompareSctpDataContentDescription(
- const SctpDataContentDescription* dcd1,
- const SctpDataContentDescription* dcd2) {
EXPECT_EQ(dcd1->use_sctpmap(), dcd2->use_sctpmap());
- EXPECT_EQ(dcd1->port(), dcd2->port());
- EXPECT_EQ(dcd1->max_message_size(), dcd2->max_message_size());
+ CompareMediaContentDescription<DataContentDescription>(dcd1, dcd2);
}
void CompareSessionDescription(const SessionDescription& desc1,
@@ -1492,21 +1484,10 @@
}
ASSERT_EQ(IsDataContent(&c1), IsDataContent(&c2));
- if (c1.media_description()->as_sctp()) {
- ASSERT_TRUE(c2.media_description()->as_sctp());
- const SctpDataContentDescription* scd1 =
- c1.media_description()->as_sctp();
- const SctpDataContentDescription* scd2 =
- c2.media_description()->as_sctp();
- CompareSctpDataContentDescription(scd1, scd2);
- } else {
- if (IsDataContent(&c1)) {
- const DataContentDescription* dcd1 =
- c1.media_description()->as_data();
- const DataContentDescription* dcd2 =
- c2.media_description()->as_data();
- CompareDataContentDescription(dcd1, dcd2);
- }
+ if (IsDataContent(&c1)) {
+ const DataContentDescription* dcd1 = c1.media_description()->as_data();
+ const DataContentDescription* dcd2 = c2.media_description()->as_data();
+ CompareDataContentDescription(dcd1, dcd2);
}
CompareSimulcastDescription(
@@ -1779,12 +1760,14 @@
}
void AddSctpDataChannel(bool use_sctpmap) {
- std::unique_ptr<SctpDataContentDescription> data(
- new SctpDataContentDescription());
- sctp_desc_ = data.get();
- sctp_desc_->set_use_sctpmap(use_sctpmap);
- sctp_desc_->set_protocol(cricket::kMediaProtocolDtlsSctp);
- sctp_desc_->set_port(kDefaultSctpPort);
+ std::unique_ptr<DataContentDescription> data(new DataContentDescription());
+ data_desc_ = data.get();
+ data_desc_->set_use_sctpmap(use_sctpmap);
+ data_desc_->set_protocol(cricket::kMediaProtocolDtlsSctp);
+ DataCodec codec(cricket::kGoogleSctpDataCodecPlType,
+ cricket::kGoogleSctpDataCodecName);
+ codec.SetParam(cricket::kCodecParamPort, kDefaultSctpPort);
+ data_desc_->AddCodec(codec);
desc_.AddContent(kDataContentName, MediaProtocolType::kSctp,
data.release());
desc_.AddTransportInfo(TransportInfo(
@@ -2061,7 +2044,6 @@
AudioContentDescription* audio_desc_;
VideoContentDescription* video_desc_;
DataContentDescription* data_desc_;
- SctpDataContentDescription* sctp_desc_;
Candidates candidates_;
std::unique_ptr<IceCandidateInterface> jcandidate_;
JsepSessionDescription jdesc_;
@@ -2233,26 +2215,21 @@
EXPECT_EQ(message, expected_sdp);
}
-void MutateJsepSctpPort(JsepSessionDescription* jdesc,
- const SessionDescription& desc,
- int port) {
- // Take our pre-built session description and change the SCTP port.
- cricket::SessionDescription* mutant = desc.Copy();
- SctpDataContentDescription* dcdesc =
- mutant->GetContentDescriptionByName(kDataContentName)->as_sctp();
- dcdesc->set_port(port);
- // Note: mutant's owned by jdesc now.
- ASSERT_TRUE(jdesc->Initialize(mutant, kSessionId, kSessionVersion));
-}
-
TEST_F(WebRtcSdpTest, SerializeWithSctpDataChannelAndNewPort) {
bool use_sctpmap = true;
AddSctpDataChannel(use_sctpmap);
JsepSessionDescription jsep_desc(kDummyType);
MakeDescriptionWithoutCandidates(&jsep_desc);
+ DataContentDescription* dcdesc =
+ jsep_desc.description()
+ ->GetContentDescriptionByName(kDataContentName)
+ ->as_data();
const int kNewPort = 1234;
- MutateJsepSctpPort(&jsep_desc, desc_, kNewPort);
+ cricket::DataCodec codec(cricket::kGoogleSctpDataCodecPlType,
+ cricket::kGoogleSctpDataCodecName);
+ codec.SetParam(cricket::kCodecParamPort, kNewPort);
+ dcdesc->AddOrReplaceCodec(codec);
std::string message = webrtc::SdpSerialize(jsep_desc);
@@ -2891,12 +2868,14 @@
// Helper function to set the max-message-size parameter in the
// SCTP data codec.
void MutateJsepSctpMaxMessageSize(const SessionDescription& desc,
- int new_value,
+ const std::string& new_value,
JsepSessionDescription* jdesc) {
cricket::SessionDescription* mutant = desc.Copy();
- SctpDataContentDescription* dcdesc =
- mutant->GetContentDescriptionByName(kDataContentName)->as_sctp();
- dcdesc->set_max_message_size(new_value);
+ DataContentDescription* dcdesc =
+ mutant->GetContentDescriptionByName(kDataContentName)->as_data();
+ std::vector<cricket::DataCodec> codecs(dcdesc->codecs());
+ codecs[0].SetParam(cricket::kCodecParamMaxMessageSize, new_value);
+ dcdesc->set_codecs(codecs);
jdesc->Initialize(mutant, kSessionId, kSessionVersion);
}
@@ -2908,7 +2887,7 @@
sdp_with_data.append(kSdpSctpDataChannelStringWithSctpColonPort);
sdp_with_data.append("a=max-message-size:12345\r\n");
- MutateJsepSctpMaxMessageSize(desc_, 12345, &jdesc);
+ MutateJsepSctpMaxMessageSize(desc_, "12345", &jdesc);
JsepSessionDescription jdesc_output(kDummyType);
// Verify with DTLS/SCTP.
@@ -2958,13 +2937,29 @@
// No crash is a pass.
}
+void MutateJsepSctpPort(JsepSessionDescription* jdesc,
+ const SessionDescription& desc) {
+ // take our pre-built session description and change the SCTP port.
+ std::unique_ptr<cricket::SessionDescription> mutant = desc.Clone();
+ DataContentDescription* dcdesc =
+ mutant->GetContentDescriptionByName(kDataContentName)->as_data();
+ std::vector<cricket::DataCodec> codecs(dcdesc->codecs());
+ EXPECT_EQ(1U, codecs.size());
+ EXPECT_EQ(cricket::kGoogleSctpDataCodecPlType, codecs[0].id);
+ codecs[0].SetParam(cricket::kCodecParamPort, kUnusualSctpPort);
+ dcdesc->set_codecs(codecs);
+
+ ASSERT_TRUE(
+ jdesc->Initialize(std::move(mutant), kSessionId, kSessionVersion));
+}
+
TEST_F(WebRtcSdpTest, DeserializeSdpWithSctpDataChannelAndUnusualPort) {
bool use_sctpmap = true;
AddSctpDataChannel(use_sctpmap);
// First setup the expected JsepSessionDescription.
JsepSessionDescription jdesc(kDummyType);
- MutateJsepSctpPort(&jdesc, desc_, kUnusualSctpPort);
+ MutateJsepSctpPort(&jdesc, desc_);
// Then get the deserialized JsepSessionDescription.
std::string sdp_with_data = kSdpString;
@@ -2984,7 +2979,7 @@
AddSctpDataChannel(use_sctpmap);
JsepSessionDescription jdesc(kDummyType);
- MutateJsepSctpPort(&jdesc, desc_, kUnusualSctpPort);
+ MutateJsepSctpPort(&jdesc, desc_);
// We need to test the deserialized JsepSessionDescription from
// kSdpSctpDataChannelStringWithSctpPort for
@@ -3020,7 +3015,7 @@
bool use_sctpmap = true;
AddSctpDataChannel(use_sctpmap);
JsepSessionDescription jdesc(kDummyType);
- SctpDataContentDescription* dcd = GetFirstSctpDataContentDescription(&desc_);
+ DataContentDescription* dcd = GetFirstDataContentDescription(&desc_);
dcd->set_bandwidth(100 * 1000);
ASSERT_TRUE(jdesc.Initialize(desc_.Clone(), kSessionId, kSessionVersion));