Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1433)

Unified Diff: webrtc/api/peerconnection.cc

Issue 2600153004: Adding support for Unified Plan offer/answer negotiation.
Patch Set: Got tests working (aside from ones that need to be completely rewritten) Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/api/peerconnection.h ('k') | webrtc/api/peerconnection_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/api/peerconnection.cc
diff --git a/webrtc/api/peerconnection.cc b/webrtc/api/peerconnection.cc
index cdf5a97b6854f31d8baa8d7f2e89f5fca2d4d09f..5aaf23645ec1ce102218a5e89fd4146be12d37e6 100644
--- a/webrtc/api/peerconnection.cc
+++ b/webrtc/api/peerconnection.cc
@@ -351,32 +351,45 @@ bool IsValidOfferToReceiveMedia(int value) {
(value <= Options::kMaxOfferToReceiveMedia);
}
-// Add the stream and RTP data channel info to |session_options|.
-void AddSendStreams(
- cricket::MediaSessionOptions* session_options,
+// Add options to |[audio/video]_media_description_options| from |senders|.
+void AddRtpSenderOptions(
const std::vector<rtc::scoped_refptr<
RtpSenderProxyWithInternal<RtpSenderInternal>>>& senders,
- const std::map<std::string, rtc::scoped_refptr<DataChannel>>&
- rtp_data_channels) {
- session_options->streams.clear();
+ cricket::MediaDescriptionOptions* audio_media_description_options,
+ cricket::MediaDescriptionOptions* video_media_description_options) {
for (const auto& sender : senders) {
- session_options->AddSendStream(sender->media_type(), sender->id(),
- sender->internal()->stream_id());
+ if (sender->media_type() == cricket::MEDIA_TYPE_AUDIO) {
+ if (audio_media_description_options) {
+ audio_media_description_options->AddAudioSender(
+ sender->id(), sender->internal()->stream_id());
+ }
+ } else {
+ RTC_DCHECK(sender->media_type() == cricket::MEDIA_TYPE_VIDEO);
+ if (video_media_description_options) {
+ video_media_description_options->AddVideoSender(
+ sender->id(), sender->internal()->stream_id(), 1);
+ }
+ }
}
+}
+// Add options to |session_options| from |rtp_data_channels|.
+void AddRtpDataChannelOptions(
+ const std::map<std::string, rtc::scoped_refptr<DataChannel>>&
+ rtp_data_channels,
+ cricket::MediaDescriptionOptions* data_media_description_options) {
+ if (!data_media_description_options) {
+ return;
+ }
// Check for data channels.
for (const auto& kv : rtp_data_channels) {
const DataChannel* channel = kv.second;
if (channel->state() == DataChannel::kConnecting ||
channel->state() == DataChannel::kOpen) {
- // |streamid| and |sync_label| are both set to the DataChannel label
- // here so they can be signaled the same way as MediaStreams and Tracks.
- // For MediaStreams, the sync_label is the MediaStream label and the
- // track label is the same as |streamid|.
- const std::string& streamid = channel->label();
- const std::string& sync_label = channel->label();
- session_options->AddSendStream(cricket::MEDIA_TYPE_DATA, streamid,
- sync_label);
+ // Legacy RTP data channels are signaled with the track/stream ID set to
+ // the data channel's label.
+ data_media_description_options->AddRtpDataChannel(channel->label(),
+ channel->label());
}
}
}
@@ -459,92 +472,88 @@ std::string GenerateRtcpCname() {
return cname;
}
-bool ExtractMediaSessionOptions(
+bool ValidateOfferAnswerOptions(
+ const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options) {
+ return IsValidOfferToReceiveMedia(rtc_options.offer_to_receive_audio) &&
+ IsValidOfferToReceiveMedia(rtc_options.offer_to_receive_video);
+}
+
+// From |rtc_options| and |is_offer|, fill |recv_audio| and |recv_video|.
+// TODO: delete, it's simpler without a function
+void ExtractAudioVideoRecvPreferences(
const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options,
bool is_offer,
- cricket::MediaSessionOptions* session_options) {
+ bool* recv_audio,
+ bool* recv_video) {
typedef PeerConnectionInterface::RTCOfferAnswerOptions RTCOfferAnswerOptions;
- if (!IsValidOfferToReceiveMedia(rtc_options.offer_to_receive_audio) ||
- !IsValidOfferToReceiveMedia(rtc_options.offer_to_receive_video)) {
- return false;
- }
- // If constraints don't prevent us, we always accept video.
+ // If constraints don't prevent us, we always accept audio.
if (rtc_options.offer_to_receive_audio != RTCOfferAnswerOptions::kUndefined) {
- session_options->recv_audio = (rtc_options.offer_to_receive_audio > 0);
+ *recv_audio = (rtc_options.offer_to_receive_audio > 0);
} else {
- session_options->recv_audio = true;
+ *recv_audio = true;
}
+
// For offers, we only offer video if we have it or it's forced by options.
// For answers, we will always accept video (if offered).
if (rtc_options.offer_to_receive_video != RTCOfferAnswerOptions::kUndefined) {
- session_options->recv_video = (rtc_options.offer_to_receive_video > 0);
+ *recv_video = (rtc_options.offer_to_receive_video > 0);
} else if (is_offer) {
- session_options->recv_video = false;
+ *recv_video = false;
} else {
- session_options->recv_video = true;
+ *recv_video = true;
}
+}
+// From |rtc_options|, fill parts of |session_options| shared by all generated
+// m= sections (in other words, nothign that involves a map/array).
+void ExtractSharedMediaSessionOptions(
+ const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options,
+ cricket::MediaSessionOptions* session_options) {
session_options->vad_enabled = rtc_options.voice_activity_detection;
session_options->bundle_enabled = rtc_options.use_rtp_mux;
- for (auto& kv : session_options->transport_options) {
- kv.second.ice_restart = rtc_options.ice_restart;
- }
-
- return true;
}
-bool ParseConstraintsForAnswer(const MediaConstraintsInterface* constraints,
- cricket::MediaSessionOptions* session_options) {
+bool ConvertConstraintsToOfferAnswerOptions(
+ const MediaConstraintsInterface* constraints,
+ PeerConnectionInterface::RTCOfferAnswerOptions* offer_answer_options) {
+ if (!constraints) {
+ return true;
+ }
+
bool value = false;
size_t mandatory_constraints_satisfied = 0;
- // kOfferToReceiveAudio defaults to true according to spec.
- if (!FindConstraint(constraints,
- MediaConstraintsInterface::kOfferToReceiveAudio, &value,
- &mandatory_constraints_satisfied) ||
- value) {
- session_options->recv_audio = true;
+ if (FindConstraint(constraints,
+ MediaConstraintsInterface::kOfferToReceiveAudio, &value,
+ &mandatory_constraints_satisfied)) {
+ offer_answer_options->offer_to_receive_audio =
+ value ? PeerConnectionInterface::RTCOfferAnswerOptions::
+ kOfferToReceiveMediaTrue
+ : 0;
}
-
- // kOfferToReceiveVideo defaults to false according to spec. But
- // if it is an answer and video is offered, we should still accept video
- // per default.
- value = false;
- if (!FindConstraint(constraints,
- MediaConstraintsInterface::kOfferToReceiveVideo, &value,
- &mandatory_constraints_satisfied) ||
- value) {
- session_options->recv_video = true;
+ if (FindConstraint(constraints,
+ MediaConstraintsInterface::kOfferToReceiveVideo, &value,
+ &mandatory_constraints_satisfied)) {
+ offer_answer_options->offer_to_receive_video =
+ value ? PeerConnectionInterface::RTCOfferAnswerOptions::
+ kOfferToReceiveMediaTrue
+ : 0;
}
-
if (FindConstraint(constraints,
MediaConstraintsInterface::kVoiceActivityDetection, &value,
&mandatory_constraints_satisfied)) {
- session_options->vad_enabled = value;
+ offer_answer_options->voice_activity_detection = value;
}
-
if (FindConstraint(constraints, MediaConstraintsInterface::kUseRtpMux, &value,
&mandatory_constraints_satisfied)) {
- session_options->bundle_enabled = value;
- } else {
- // kUseRtpMux defaults to true according to spec.
- session_options->bundle_enabled = true;
+ offer_answer_options->use_rtp_mux = value;
}
-
- bool ice_restart = false;
if (FindConstraint(constraints, MediaConstraintsInterface::kIceRestart,
&value, &mandatory_constraints_satisfied)) {
- // kIceRestart defaults to false according to spec.
- ice_restart = true;
- }
- for (auto& kv : session_options->transport_options) {
- kv.second.ice_restart = ice_restart;
+ offer_answer_options->ice_restart = value;
}
- if (!constraints) {
- return true;
- }
return mandatory_constraints_satisfied == constraints->GetMandatory().size();
}
@@ -988,49 +997,17 @@ void PeerConnection::CreateOffer(CreateSessionDescriptionObserver* observer,
LOG(LS_ERROR) << "CreateOffer - observer is NULL.";
return;
}
- RTCOfferAnswerOptions options;
-
- bool value;
- size_t mandatory_constraints = 0;
-
- if (FindConstraint(constraints,
- MediaConstraintsInterface::kOfferToReceiveAudio,
- &value,
- &mandatory_constraints)) {
- options.offer_to_receive_audio =
- value ? RTCOfferAnswerOptions::kOfferToReceiveMediaTrue : 0;
- }
-
- if (FindConstraint(constraints,
- MediaConstraintsInterface::kOfferToReceiveVideo,
- &value,
- &mandatory_constraints)) {
- options.offer_to_receive_video =
- value ? RTCOfferAnswerOptions::kOfferToReceiveMediaTrue : 0;
- }
- if (FindConstraint(constraints,
- MediaConstraintsInterface::kVoiceActivityDetection,
- &value,
- &mandatory_constraints)) {
- options.voice_activity_detection = value;
- }
-
- if (FindConstraint(constraints,
- MediaConstraintsInterface::kIceRestart,
- &value,
- &mandatory_constraints)) {
- options.ice_restart = value;
- }
-
- if (FindConstraint(constraints,
- MediaConstraintsInterface::kUseRtpMux,
- &value,
- &mandatory_constraints)) {
- options.use_rtp_mux = value;
+ PeerConnectionInterface::RTCOfferAnswerOptions offer_answer_options;
+ if (!ConvertConstraintsToOfferAnswerOptions(constraints,
+ &offer_answer_options)) {
+ std::string error = "CreateOffer called with invalid constraints.";
+ LOG(LS_ERROR) << error;
+ PostCreateSessionDescriptionFailure(observer, error);
+ return;
}
- CreateOffer(observer, options);
+ CreateOffer(observer, offer_answer_options);
}
void PeerConnection::CreateOffer(CreateSessionDescriptionObserver* observer,
@@ -1041,14 +1018,14 @@ void PeerConnection::CreateOffer(CreateSessionDescriptionObserver* observer,
return;
}
- cricket::MediaSessionOptions session_options;
- if (!GetOptionsForOffer(options, &session_options)) {
+ if (!ValidateOfferAnswerOptions(options)) {
std::string error = "CreateOffer called with invalid options.";
LOG(LS_ERROR) << error;
PostCreateSessionDescriptionFailure(observer, error);
- return;
}
+ cricket::MediaSessionOptions session_options;
+ GetOptionsForOffer(options, &session_options);
session_->CreateOffer(observer, options, session_options);
}
@@ -1061,14 +1038,26 @@ void PeerConnection::CreateAnswer(
return;
}
- cricket::MediaSessionOptions session_options;
- if (!GetOptionsForAnswer(constraints, &session_options)) {
+ if (!session_->remote_description() ||
+ session_->remote_description()->type() !=
+ SessionDescriptionInterface::kOffer) {
+ std::string error = "CreateAnswer called without remote offer.";
+ LOG(LS_ERROR) << error;
+ PostCreateSessionDescriptionFailure(observer, error);
+ return;
+ }
+
+ PeerConnectionInterface::RTCOfferAnswerOptions offer_answer_options;
+ if (!ConvertConstraintsToOfferAnswerOptions(constraints,
+ &offer_answer_options)) {
std::string error = "CreateAnswer called with invalid constraints.";
LOG(LS_ERROR) << error;
PostCreateSessionDescriptionFailure(observer, error);
return;
}
+ cricket::MediaSessionOptions session_options;
+ GetOptionsForAnswer(offer_answer_options, &session_options);
session_->CreateAnswer(observer, session_options);
}
@@ -1081,13 +1070,7 @@ void PeerConnection::CreateAnswer(CreateSessionDescriptionObserver* observer,
}
cricket::MediaSessionOptions session_options;
- if (!GetOptionsForAnswer(options, &session_options)) {
- std::string error = "CreateAnswer called with invalid options.";
- LOG(LS_ERROR) << error;
- PostCreateSessionDescriptionFailure(observer, error);
- return;
- }
-
+ GetOptionsForAnswer(options, &session_options);
session_->CreateAnswer(observer, session_options);
}
@@ -1691,82 +1674,254 @@ void PeerConnection::PostCreateSessionDescriptionFailure(
MSG_CREATE_SESSIONDESCRIPTION_FAILED, msg);
}
-bool PeerConnection::GetOptionsForOffer(
+void PeerConnection::GetOptionsForOffer(
const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options,
cricket::MediaSessionOptions* session_options) {
- // TODO(deadbeef): Once we have transceivers, enumerate them here instead of
- // ContentInfos.
+ ExtractSharedMediaSessionOptions(rtc_options, session_options);
+
+ // Figure out transceiver directional preferences.
+ bool send_audio = HasRtpSender(cricket::MEDIA_TYPE_AUDIO);
+ bool send_video = HasRtpSender(cricket::MEDIA_TYPE_VIDEO);
+ // By default, generate sendrecv/recvonly m= sections.
+ bool recv_audio = true;
+ bool recv_video = true;
+ // By default, only offer a new m= section if we have media to send with it.
+ bool offer_new_audio_description = send_audio;
+ bool offer_new_video_description = send_video;
+ bool offer_new_data_description = HasDataChannels();
+ // The "offer_to_receive_X" options allow those defaults to be overridden.
+ if (rtc_options.offer_to_receive_audio != RTCOfferAnswerOptions::kUndefined) {
+ recv_audio = (rtc_options.offer_to_receive_audio > 0);
+ offer_new_audio_description = (rtc_options.offer_to_receive_audio > 0);
+ }
+ if (rtc_options.offer_to_receive_video != RTCOfferAnswerOptions::kUndefined) {
+ recv_video = (rtc_options.offer_to_receive_video > 0);
+ offer_new_video_description = (rtc_options.offer_to_receive_video > 0);
+ }
+
+ int audio_index = -1;
+ int video_index = -1;
+ int data_index = -1;
+ // If a current description exists, generate m= sections in the same order,
+ // using the first audio/video/data section that appears and rejecting
+ // extraneous ones.
if (session_->local_description()) {
for (const cricket::ContentInfo& content :
session_->local_description()->description()->contents()) {
- session_options->transport_options[content.name] =
- cricket::TransportOptions();
+ if (IsAudioContent(&content)) {
+ // If we already have an audio m= section, reject this extra one.
+ if (audio_index != -1) {
+ session_options->media_description_options.push_back(
+ cricket::MediaDescriptionOptions(
+ cricket::MEDIA_TYPE_AUDIO, content.name,
+ cricket::RtpTransceiverDirection(false, false), true));
+ } else {
+ session_options->media_description_options.push_back(
+ cricket::MediaDescriptionOptions(
+ cricket::MEDIA_TYPE_AUDIO, content.name,
+ cricket::RtpTransceiverDirection(send_audio, recv_audio),
+ false));
+ audio_index = session_options->media_description_options.size() - 1;
+ }
+ } else if (IsVideoContent(&content)) {
+ // If we already have an video m= section, reject this extra one.
+ if (video_index != -1) {
+ session_options->media_description_options.push_back(
+ cricket::MediaDescriptionOptions(
+ cricket::MEDIA_TYPE_VIDEO, content.name,
+ cricket::RtpTransceiverDirection(false, false), true));
+ } else {
+ session_options->media_description_options.push_back(
+ cricket::MediaDescriptionOptions(
+ cricket::MEDIA_TYPE_VIDEO, content.name,
+ cricket::RtpTransceiverDirection(send_video, recv_video),
+ false));
+ video_index = session_options->media_description_options.size() - 1;
+ }
+ } else {
+ RTC_DCHECK(IsDataContent(&content));
+ // If we already have an data m= section, reject this extra one.
+ if (data_index != -1) {
+ session_options->media_description_options.push_back(
+ cricket::MediaDescriptionOptions(
+ cricket::MEDIA_TYPE_DATA, content.name,
+ cricket::RtpTransceiverDirection(false, false), true));
+ } else {
+ session_options->media_description_options.push_back(
+ cricket::MediaDescriptionOptions(
+ cricket::MEDIA_TYPE_DATA, content.name,
+ // Direction for data sections is meaningless, but legacy
+ // endpoints might expect sendrecv.
+ cricket::RtpTransceiverDirection(true, true), false));
+ data_index = session_options->media_description_options.size() - 1;
+ }
+ }
}
}
- session_options->enable_ice_renomination =
- configuration_.enable_ice_renomination;
-
- if (!ExtractMediaSessionOptions(rtc_options, true, session_options)) {
- return false;
- }
-
- AddSendStreams(session_options, senders_, rtp_data_channels_);
- // Offer to receive audio/video if the constraint is not set and there are
- // send streams, or we're currently receiving.
- if (rtc_options.offer_to_receive_audio == RTCOfferAnswerOptions::kUndefined) {
- session_options->recv_audio =
- session_options->HasSendMediaStream(cricket::MEDIA_TYPE_AUDIO) ||
- !remote_audio_tracks_.empty();
- }
- if (rtc_options.offer_to_receive_video == RTCOfferAnswerOptions::kUndefined) {
- session_options->recv_video =
- session_options->HasSendMediaStream(cricket::MEDIA_TYPE_VIDEO) ||
- !remote_video_tracks_.empty();
- }
+ // Add audio/video/data m= sections to the end if needed.
+ if (audio_index == -1 && offer_new_audio_description) {
+ session_options->media_description_options.push_back(
+ cricket::MediaDescriptionOptions(
+ cricket::MEDIA_TYPE_AUDIO, cricket::CN_AUDIO,
+ cricket::RtpTransceiverDirection(send_audio, recv_audio), false));
+ audio_index = session_options->media_description_options.size() - 1;
+ }
+ if (video_index == -1 && offer_new_video_description) {
+ session_options->media_description_options.push_back(
+ cricket::MediaDescriptionOptions(
+ cricket::MEDIA_TYPE_VIDEO, cricket::CN_VIDEO,
+ cricket::RtpTransceiverDirection(send_video, recv_video), false));
+ video_index = session_options->media_description_options.size() - 1;
+ }
+ if (data_index == -1 && offer_new_data_description) {
+ session_options->media_description_options.push_back(
+ cricket::MediaDescriptionOptions(
+ cricket::MEDIA_TYPE_DATA, cricket::CN_DATA,
+ cricket::RtpTransceiverDirection(true, true), false));
+ data_index = session_options->media_description_options.size() - 1;
+ }
+
+ cricket::MediaDescriptionOptions* audio_media_description_options =
+ audio_index == -1
+ ? nullptr
+ : &session_options->media_description_options[audio_index];
+ cricket::MediaDescriptionOptions* video_media_description_options =
+ video_index == -1
+ ? nullptr
+ : &session_options->media_description_options[video_index];
+ cricket::MediaDescriptionOptions* data_media_description_options =
+ data_index == -1
+ ? nullptr
+ : &session_options->media_description_options[data_index];
+
+ // Apply ICE restart flag and renomination flag.
+ for (auto& options : session_options->media_description_options) {
+ options.transport_options.ice_restart = rtc_options.ice_restart;
+ options.transport_options.enable_ice_renomination =
+ configuration_.enable_ice_renomination;
+ }
+
+ AddRtpSenderOptions(senders_, audio_media_description_options,
+ video_media_description_options);
+ AddRtpDataChannelOptions(rtp_data_channels_, data_media_description_options);
// Intentionally unset the data channel type for RTP data channel with the
// second condition. Otherwise the RTP data channels would be successfully
// negotiated by default and the unit tests in WebRtcDataBrowserTest will fail
// when building with chromium. We want to leave RTP data channels broken, so
// people won't try to use them.
- if (HasDataChannels() && session_->data_channel_type() != cricket::DCT_RTP) {
+ if (session_->data_channel_type() != cricket::DCT_RTP) {
session_options->data_channel_type = session_->data_channel_type();
}
- session_options->bundle_enabled =
- session_options->bundle_enabled &&
- (session_options->has_audio() || session_options->has_video() ||
- session_options->has_data());
-
session_options->rtcp_cname = rtcp_cname_;
session_options->crypto_options = factory_->options().crypto_options;
- return true;
-}
-
-void PeerConnection::InitializeOptionsForAnswer(
- cricket::MediaSessionOptions* session_options) {
- session_options->recv_audio = false;
- session_options->recv_video = false;
- session_options->enable_ice_renomination =
- configuration_.enable_ice_renomination;
}
-void PeerConnection::FinishOptionsForAnswer(
+void PeerConnection::GetOptionsForAnswer(
+ const RTCOfferAnswerOptions& rtc_options,
cricket::MediaSessionOptions* session_options) {
- // TODO(deadbeef): Once we have transceivers, enumerate them here instead of
- // ContentInfos.
- if (session_->remote_description()) {
- // Initialize the transport_options map.
- for (const cricket::ContentInfo& content :
- session_->remote_description()->description()->contents()) {
- session_options->transport_options[content.name] =
- cricket::TransportOptions();
+ ExtractSharedMediaSessionOptions(rtc_options, session_options);
+
+ // Figure out transceiver directional preferences.
+ bool send_audio = HasRtpSender(cricket::MEDIA_TYPE_AUDIO);
+ bool send_video = HasRtpSender(cricket::MEDIA_TYPE_VIDEO);
+ // By default, generate sendrecv/recvonly m= sections.
+ bool recv_audio = true;
+ bool recv_video = true;
+ // The "offer_to_receive_X" options allow those defaults to be overridden.
+ if (rtc_options.offer_to_receive_audio != RTCOfferAnswerOptions::kUndefined) {
+ recv_audio = (rtc_options.offer_to_receive_audio > 0);
+ }
+ if (rtc_options.offer_to_receive_video != RTCOfferAnswerOptions::kUndefined) {
+ recv_video = (rtc_options.offer_to_receive_video > 0);
+ }
+
+ int audio_index = -1;
+ int video_index = -1;
+ int data_index = -1;
+ // There should be a pending remote description that's an offer...
+ RTC_DCHECK(session_->remote_description());
+ RTC_DCHECK(session_->remote_description()->type() ==
+ SessionDescriptionInterface::kOffer);
+ // Generate m= sections that match those in the offer.
+ // Note that mediasession.cc will handle intersection our preferred direction
+ // with the offered direction.
+ for (const cricket::ContentInfo& content :
+ session_->remote_description()->description()->contents()) {
+ if (IsAudioContent(&content)) {
+ // If we already have an audio m= section, reject this extra one.
+ if (audio_index != -1) {
+ session_options->media_description_options.push_back(
+ cricket::MediaDescriptionOptions(
+ cricket::MEDIA_TYPE_AUDIO, content.name,
+ cricket::RtpTransceiverDirection(false, false), true));
+ } else {
+ session_options->media_description_options.push_back(
+ cricket::MediaDescriptionOptions(
+ cricket::MEDIA_TYPE_AUDIO, content.name,
+ cricket::RtpTransceiverDirection(send_audio, recv_audio),
+ false));
+ audio_index = session_options->media_description_options.size() - 1;
+ }
+ } else if (IsVideoContent(&content)) {
+ // If we already have an video m= section, reject this extra one.
+ if (video_index != -1) {
+ session_options->media_description_options.push_back(
+ cricket::MediaDescriptionOptions(
+ cricket::MEDIA_TYPE_VIDEO, content.name,
+ cricket::RtpTransceiverDirection(false, false), true));
+ } else {
+ session_options->media_description_options.push_back(
+ cricket::MediaDescriptionOptions(
+ cricket::MEDIA_TYPE_VIDEO, content.name,
+ cricket::RtpTransceiverDirection(send_video, recv_video),
+ false));
+ video_index = session_options->media_description_options.size() - 1;
+ }
+ } else {
+ RTC_DCHECK(IsDataContent(&content));
+ // If we already have an data m= section, reject this extra one.
+ if (data_index != -1) {
+ session_options->media_description_options.push_back(
+ cricket::MediaDescriptionOptions(
+ cricket::MEDIA_TYPE_DATA, content.name,
+ cricket::RtpTransceiverDirection(false, false), true));
+ } else {
+ session_options->media_description_options.push_back(
+ cricket::MediaDescriptionOptions(
+ cricket::MEDIA_TYPE_DATA, content.name,
+ // Direction for data sections is meaningless, but legacy
+ // endpoints might expect sendrecv.
+ cricket::RtpTransceiverDirection(true, true), false));
+ data_index = session_options->media_description_options.size() - 1;
+ }
}
}
- AddSendStreams(session_options, senders_, rtp_data_channels_);
- // RTP data channel is handled in MediaSessionOptions::AddStream. SCTP streams
- // are not signaled in the SDP so does not go through that path and must be
- // handled here.
+
+ cricket::MediaDescriptionOptions* audio_media_description_options =
+ audio_index == -1
+ ? nullptr
+ : &session_options->media_description_options[audio_index];
+ cricket::MediaDescriptionOptions* video_media_description_options =
+ video_index == -1
+ ? nullptr
+ : &session_options->media_description_options[video_index];
+ cricket::MediaDescriptionOptions* data_media_description_options =
+ data_index == -1
+ ? nullptr
+ : &session_options->media_description_options[data_index];
+
+ // Apply ICE renomination flag.
+ for (auto& options : session_options->media_description_options) {
+ options.transport_options.enable_ice_renomination =
+ configuration_.enable_ice_renomination;
+ }
+
+ AddRtpSenderOptions(senders_, audio_media_description_options,
+ video_media_description_options);
+ AddRtpDataChannelOptions(rtp_data_channels_, data_media_description_options);
+
// Intentionally unset the data channel type for RTP data channel. Otherwise
// the RTP data channels would be successfully negotiated by default and the
// unit tests in WebRtcDataBrowserTest will fail when building with chromium.
@@ -1774,38 +1929,9 @@ void PeerConnection::FinishOptionsForAnswer(
if (session_->data_channel_type() != cricket::DCT_RTP) {
session_options->data_channel_type = session_->data_channel_type();
}
- session_options->bundle_enabled =
- session_options->bundle_enabled &&
- (session_options->has_audio() || session_options->has_video() ||
- session_options->has_data());
-
- session_options->crypto_options = factory_->options().crypto_options;
-}
-bool PeerConnection::GetOptionsForAnswer(
- const MediaConstraintsInterface* constraints,
- cricket::MediaSessionOptions* session_options) {
- InitializeOptionsForAnswer(session_options);
- if (!ParseConstraintsForAnswer(constraints, session_options)) {
- return false;
- }
session_options->rtcp_cname = rtcp_cname_;
-
- FinishOptionsForAnswer(session_options);
- return true;
-}
-
-bool PeerConnection::GetOptionsForAnswer(
- const RTCOfferAnswerOptions& options,
- cricket::MediaSessionOptions* session_options) {
- InitializeOptionsForAnswer(session_options);
- if (!ExtractMediaSessionOptions(options, false, session_options)) {
- return false;
- }
- session_options->rtcp_cname = rtcp_cname_;
-
- FinishOptionsForAnswer(session_options);
- return true;
+ session_options->crypto_options = factory_->options().crypto_options;
}
void PeerConnection::RemoveTracks(cricket::MediaType media_type) {
@@ -2286,6 +2412,15 @@ void PeerConnection::OnDataChannelOpenMessage(
observer_->OnDataChannel(std::move(proxy_channel));
}
+bool PeerConnection::HasRtpSender(cricket::MediaType type) const {
+ return std::find_if(
+ senders_.begin(), senders_.end(),
+ [type](const rtc::scoped_refptr<
+ RtpSenderProxyWithInternal<RtpSenderInternal>>& sender) {
+ return sender->media_type() == type;
+ }) != senders_.end();
+}
+
RtpSenderInternal* PeerConnection::FindSenderById(const std::string& id) {
auto it = std::find_if(
senders_.begin(), senders_.end(),
« no previous file with comments | « webrtc/api/peerconnection.h ('k') | webrtc/api/peerconnection_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698