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

Side by Side Diff: webrtc/pc/peerconnection.cc

Issue 3001083002: Revert of Adding support for Unified Plan offer/answer negotiation. (Closed)
Patch Set: Created 3 years, 4 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 unified diff | Download patch
« no previous file with comments | « webrtc/pc/peerconnection.h ('k') | webrtc/pc/peerconnectioninterface_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 ? desc->streams() 126 ? desc->streams()
127 : std::vector<cricket::StreamParams>(); 127 : std::vector<cricket::StreamParams>();
128 } 128 }
129 129
130 bool IsValidOfferToReceiveMedia(int value) { 130 bool IsValidOfferToReceiveMedia(int value) {
131 typedef PeerConnectionInterface::RTCOfferAnswerOptions Options; 131 typedef PeerConnectionInterface::RTCOfferAnswerOptions Options;
132 return (value >= Options::kUndefined) && 132 return (value >= Options::kUndefined) &&
133 (value <= Options::kMaxOfferToReceiveMedia); 133 (value <= Options::kMaxOfferToReceiveMedia);
134 } 134 }
135 135
136 // Add options to |[audio/video]_media_description_options| from |senders|. 136 // Add the stream and RTP data channel info to |session_options|.
137 void AddRtpSenderOptions( 137 void AddSendStreams(
138 cricket::MediaSessionOptions* session_options,
138 const std::vector<rtc::scoped_refptr< 139 const std::vector<rtc::scoped_refptr<
139 RtpSenderProxyWithInternal<RtpSenderInternal>>>& senders, 140 RtpSenderProxyWithInternal<RtpSenderInternal>>>& senders,
140 cricket::MediaDescriptionOptions* audio_media_description_options, 141 const std::map<std::string, rtc::scoped_refptr<DataChannel>>&
141 cricket::MediaDescriptionOptions* video_media_description_options) { 142 rtp_data_channels) {
143 session_options->streams.clear();
142 for (const auto& sender : senders) { 144 for (const auto& sender : senders) {
143 if (sender->media_type() == cricket::MEDIA_TYPE_AUDIO) { 145 session_options->AddSendStream(sender->media_type(), sender->id(),
144 if (audio_media_description_options) { 146 sender->internal()->stream_id());
145 audio_media_description_options->AddAudioSender(
146 sender->id(), sender->internal()->stream_id());
147 }
148 } else {
149 RTC_DCHECK(sender->media_type() == cricket::MEDIA_TYPE_VIDEO);
150 if (video_media_description_options) {
151 video_media_description_options->AddVideoSender(
152 sender->id(), sender->internal()->stream_id(), 1);
153 }
154 }
155 } 147 }
156 }
157 148
158 // Add options to |session_options| from |rtp_data_channels|.
159 void AddRtpDataChannelOptions(
160 const std::map<std::string, rtc::scoped_refptr<DataChannel>>&
161 rtp_data_channels,
162 cricket::MediaDescriptionOptions* data_media_description_options) {
163 if (!data_media_description_options) {
164 return;
165 }
166 // Check for data channels. 149 // Check for data channels.
167 for (const auto& kv : rtp_data_channels) { 150 for (const auto& kv : rtp_data_channels) {
168 const DataChannel* channel = kv.second; 151 const DataChannel* channel = kv.second;
169 if (channel->state() == DataChannel::kConnecting || 152 if (channel->state() == DataChannel::kConnecting ||
170 channel->state() == DataChannel::kOpen) { 153 channel->state() == DataChannel::kOpen) {
171 // Legacy RTP data channels are signaled with the track/stream ID set to 154 // |streamid| and |sync_label| are both set to the DataChannel label
172 // the data channel's label. 155 // here so they can be signaled the same way as MediaStreams and Tracks.
173 data_media_description_options->AddRtpDataChannel(channel->label(), 156 // For MediaStreams, the sync_label is the MediaStream label and the
174 channel->label()); 157 // track label is the same as |streamid|.
158 const std::string& streamid = channel->label();
159 const std::string& sync_label = channel->label();
160 session_options->AddSendStream(cricket::MEDIA_TYPE_DATA, streamid,
161 sync_label);
175 } 162 }
176 } 163 }
177 } 164 }
178 165
179 uint32_t ConvertIceTransportTypeToCandidateFilter( 166 uint32_t ConvertIceTransportTypeToCandidateFilter(
180 PeerConnectionInterface::IceTransportsType type) { 167 PeerConnectionInterface::IceTransportsType type) {
181 switch (type) { 168 switch (type) {
182 case PeerConnectionInterface::kNone: 169 case PeerConnectionInterface::kNone:
183 return cricket::CF_NONE; 170 return cricket::CF_NONE;
184 case PeerConnectionInterface::kRelay: 171 case PeerConnectionInterface::kRelay:
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 // Generate a RTCP CNAME when a PeerConnection is created. 307 // Generate a RTCP CNAME when a PeerConnection is created.
321 std::string GenerateRtcpCname() { 308 std::string GenerateRtcpCname() {
322 std::string cname; 309 std::string cname;
323 if (!rtc::CreateRandomString(kRtcpCnameLength, &cname)) { 310 if (!rtc::CreateRandomString(kRtcpCnameLength, &cname)) {
324 LOG(LS_ERROR) << "Failed to generate CNAME."; 311 LOG(LS_ERROR) << "Failed to generate CNAME.";
325 RTC_NOTREACHED(); 312 RTC_NOTREACHED();
326 } 313 }
327 return cname; 314 return cname;
328 } 315 }
329 316
330 bool ValidateOfferAnswerOptions( 317 bool ExtractMediaSessionOptions(
331 const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options) { 318 const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options,
332 return IsValidOfferToReceiveMedia(rtc_options.offer_to_receive_audio) && 319 bool is_offer,
333 IsValidOfferToReceiveMedia(rtc_options.offer_to_receive_video); 320 cricket::MediaSessionOptions* session_options) {
321 typedef PeerConnectionInterface::RTCOfferAnswerOptions RTCOfferAnswerOptions;
322 if (!IsValidOfferToReceiveMedia(rtc_options.offer_to_receive_audio) ||
323 !IsValidOfferToReceiveMedia(rtc_options.offer_to_receive_video)) {
324 return false;
325 }
326
327 // If constraints don't prevent us, we always accept video.
328 if (rtc_options.offer_to_receive_audio != RTCOfferAnswerOptions::kUndefined) {
329 session_options->recv_audio = (rtc_options.offer_to_receive_audio > 0);
330 } else {
331 session_options->recv_audio = true;
332 }
333 // For offers, we only offer video if we have it or it's forced by options.
334 // For answers, we will always accept video (if offered).
335 if (rtc_options.offer_to_receive_video != RTCOfferAnswerOptions::kUndefined) {
336 session_options->recv_video = (rtc_options.offer_to_receive_video > 0);
337 } else if (is_offer) {
338 session_options->recv_video = false;
339 } else {
340 session_options->recv_video = true;
341 }
342
343 session_options->vad_enabled = rtc_options.voice_activity_detection;
344 session_options->bundle_enabled = rtc_options.use_rtp_mux;
345 for (auto& kv : session_options->transport_options) {
346 kv.second.ice_restart = rtc_options.ice_restart;
347 }
348
349 return true;
334 } 350 }
335 351
336 // From |rtc_options|, fill parts of |session_options| shared by all generated 352 bool ParseConstraintsForAnswer(const MediaConstraintsInterface* constraints,
337 // m= sections (in other words, nothing that involves a map/array). 353 cricket::MediaSessionOptions* session_options) {
338 void ExtractSharedMediaSessionOptions( 354 bool value = false;
339 const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options, 355 size_t mandatory_constraints_satisfied = 0;
340 cricket::MediaSessionOptions* session_options) {
341 session_options->vad_enabled = rtc_options.voice_activity_detection;
342 session_options->bundle_enabled = rtc_options.use_rtp_mux;
343 }
344 356
345 bool ConvertConstraintsToOfferAnswerOptions( 357 // kOfferToReceiveAudio defaults to true according to spec.
346 const MediaConstraintsInterface* constraints, 358 if (!FindConstraint(constraints,
347 PeerConnectionInterface::RTCOfferAnswerOptions* offer_answer_options) { 359 MediaConstraintsInterface::kOfferToReceiveAudio, &value,
360 &mandatory_constraints_satisfied) ||
361 value) {
362 session_options->recv_audio = true;
363 }
364
365 // kOfferToReceiveVideo defaults to false according to spec. But
366 // if it is an answer and video is offered, we should still accept video
367 // per default.
368 value = false;
369 if (!FindConstraint(constraints,
370 MediaConstraintsInterface::kOfferToReceiveVideo, &value,
371 &mandatory_constraints_satisfied) ||
372 value) {
373 session_options->recv_video = true;
374 }
375
376 if (FindConstraint(constraints,
377 MediaConstraintsInterface::kVoiceActivityDetection, &value,
378 &mandatory_constraints_satisfied)) {
379 session_options->vad_enabled = value;
380 }
381
382 if (FindConstraint(constraints, MediaConstraintsInterface::kUseRtpMux, &value,
383 &mandatory_constraints_satisfied)) {
384 session_options->bundle_enabled = value;
385 } else {
386 // kUseRtpMux defaults to true according to spec.
387 session_options->bundle_enabled = true;
388 }
389
390 bool ice_restart = false;
391 if (FindConstraint(constraints, MediaConstraintsInterface::kIceRestart,
392 &value, &mandatory_constraints_satisfied)) {
393 // kIceRestart defaults to false according to spec.
394 ice_restart = true;
395 }
396 for (auto& kv : session_options->transport_options) {
397 kv.second.ice_restart = ice_restart;
398 }
399
348 if (!constraints) { 400 if (!constraints) {
349 return true; 401 return true;
350 } 402 }
351
352 bool value = false;
353 size_t mandatory_constraints_satisfied = 0;
354
355 if (FindConstraint(constraints,
356 MediaConstraintsInterface::kOfferToReceiveAudio, &value,
357 &mandatory_constraints_satisfied)) {
358 offer_answer_options->offer_to_receive_audio =
359 value ? PeerConnectionInterface::RTCOfferAnswerOptions::
360 kOfferToReceiveMediaTrue
361 : 0;
362 }
363
364 if (FindConstraint(constraints,
365 MediaConstraintsInterface::kOfferToReceiveVideo, &value,
366 &mandatory_constraints_satisfied)) {
367 offer_answer_options->offer_to_receive_video =
368 value ? PeerConnectionInterface::RTCOfferAnswerOptions::
369 kOfferToReceiveMediaTrue
370 : 0;
371 }
372 if (FindConstraint(constraints,
373 MediaConstraintsInterface::kVoiceActivityDetection, &value,
374 &mandatory_constraints_satisfied)) {
375 offer_answer_options->voice_activity_detection = value;
376 }
377 if (FindConstraint(constraints, MediaConstraintsInterface::kUseRtpMux, &value,
378 &mandatory_constraints_satisfied)) {
379 offer_answer_options->use_rtp_mux = value;
380 }
381 if (FindConstraint(constraints, MediaConstraintsInterface::kIceRestart,
382 &value, &mandatory_constraints_satisfied)) {
383 offer_answer_options->ice_restart = value;
384 }
385
386 return mandatory_constraints_satisfied == constraints->GetMandatory().size(); 403 return mandatory_constraints_satisfied == constraints->GetMandatory().size();
387 } 404 }
388 405
389 PeerConnection::PeerConnection(PeerConnectionFactory* factory, 406 PeerConnection::PeerConnection(PeerConnectionFactory* factory,
390 std::unique_ptr<RtcEventLog> event_log, 407 std::unique_ptr<RtcEventLog> event_log,
391 std::unique_ptr<Call> call) 408 std::unique_ptr<Call> call)
392 : factory_(factory), 409 : factory_(factory),
393 observer_(NULL), 410 observer_(NULL),
394 uma_observer_(NULL), 411 uma_observer_(NULL),
395 event_log_(std::move(event_log)), 412 event_log_(std::move(event_log)),
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 return DataChannelProxy::Create(signaling_thread(), channel.get()); 835 return DataChannelProxy::Create(signaling_thread(), channel.get());
819 } 836 }
820 837
821 void PeerConnection::CreateOffer(CreateSessionDescriptionObserver* observer, 838 void PeerConnection::CreateOffer(CreateSessionDescriptionObserver* observer,
822 const MediaConstraintsInterface* constraints) { 839 const MediaConstraintsInterface* constraints) {
823 TRACE_EVENT0("webrtc", "PeerConnection::CreateOffer"); 840 TRACE_EVENT0("webrtc", "PeerConnection::CreateOffer");
824 if (!observer) { 841 if (!observer) {
825 LOG(LS_ERROR) << "CreateOffer - observer is NULL."; 842 LOG(LS_ERROR) << "CreateOffer - observer is NULL.";
826 return; 843 return;
827 } 844 }
828 PeerConnectionInterface::RTCOfferAnswerOptions offer_answer_options; 845 RTCOfferAnswerOptions options;
829 // Always create an offer even if |ConvertConstraintsToOfferAnswerOptions|
830 // returns false for now. Because |ConvertConstraintsToOfferAnswerOptions|
831 // compares the mandatory fields parsed with the mandatory fields added in the
832 // |constraints| and some downstream applications might create offers with
833 // mandatory fields which would not be parsed in the helper method. For
834 // example, in Chromium/remoting, |kEnableDtlsSrtp| is added to the
835 // |constraints| as a mandatory field but it is not parsed.
836 ConvertConstraintsToOfferAnswerOptions(constraints, &offer_answer_options);
837 846
838 CreateOffer(observer, offer_answer_options); 847 bool value;
848 size_t mandatory_constraints = 0;
849
850 if (FindConstraint(constraints,
851 MediaConstraintsInterface::kOfferToReceiveAudio,
852 &value,
853 &mandatory_constraints)) {
854 options.offer_to_receive_audio =
855 value ? RTCOfferAnswerOptions::kOfferToReceiveMediaTrue : 0;
856 }
857
858 if (FindConstraint(constraints,
859 MediaConstraintsInterface::kOfferToReceiveVideo,
860 &value,
861 &mandatory_constraints)) {
862 options.offer_to_receive_video =
863 value ? RTCOfferAnswerOptions::kOfferToReceiveMediaTrue : 0;
864 }
865
866 if (FindConstraint(constraints,
867 MediaConstraintsInterface::kVoiceActivityDetection,
868 &value,
869 &mandatory_constraints)) {
870 options.voice_activity_detection = value;
871 }
872
873 if (FindConstraint(constraints,
874 MediaConstraintsInterface::kIceRestart,
875 &value,
876 &mandatory_constraints)) {
877 options.ice_restart = value;
878 }
879
880 if (FindConstraint(constraints,
881 MediaConstraintsInterface::kUseRtpMux,
882 &value,
883 &mandatory_constraints)) {
884 options.use_rtp_mux = value;
885 }
886
887 CreateOffer(observer, options);
839 } 888 }
840 889
841 void PeerConnection::CreateOffer(CreateSessionDescriptionObserver* observer, 890 void PeerConnection::CreateOffer(CreateSessionDescriptionObserver* observer,
842 const RTCOfferAnswerOptions& options) { 891 const RTCOfferAnswerOptions& options) {
843 TRACE_EVENT0("webrtc", "PeerConnection::CreateOffer"); 892 TRACE_EVENT0("webrtc", "PeerConnection::CreateOffer");
844 if (!observer) { 893 if (!observer) {
845 LOG(LS_ERROR) << "CreateOffer - observer is NULL."; 894 LOG(LS_ERROR) << "CreateOffer - observer is NULL.";
846 return; 895 return;
847 } 896 }
848 897
849 if (!ValidateOfferAnswerOptions(options)) { 898 cricket::MediaSessionOptions session_options;
899 if (!GetOptionsForOffer(options, &session_options)) {
850 std::string error = "CreateOffer called with invalid options."; 900 std::string error = "CreateOffer called with invalid options.";
851 LOG(LS_ERROR) << error; 901 LOG(LS_ERROR) << error;
852 PostCreateSessionDescriptionFailure(observer, error); 902 PostCreateSessionDescriptionFailure(observer, error);
853 return; 903 return;
854 } 904 }
855 905
856 cricket::MediaSessionOptions session_options;
857 GetOptionsForOffer(options, &session_options);
858 session_->CreateOffer(observer, options, session_options); 906 session_->CreateOffer(observer, options, session_options);
859 } 907 }
860 908
861 void PeerConnection::CreateAnswer( 909 void PeerConnection::CreateAnswer(
862 CreateSessionDescriptionObserver* observer, 910 CreateSessionDescriptionObserver* observer,
863 const MediaConstraintsInterface* constraints) { 911 const MediaConstraintsInterface* constraints) {
864 TRACE_EVENT0("webrtc", "PeerConnection::CreateAnswer"); 912 TRACE_EVENT0("webrtc", "PeerConnection::CreateAnswer");
865 if (!observer) { 913 if (!observer) {
866 LOG(LS_ERROR) << "CreateAnswer - observer is NULL."; 914 LOG(LS_ERROR) << "CreateAnswer - observer is NULL.";
867 return; 915 return;
868 } 916 }
869 917
870 if (!session_->remote_description() || 918 cricket::MediaSessionOptions session_options;
871 session_->remote_description()->type() != 919 if (!GetOptionsForAnswer(constraints, &session_options)) {
872 SessionDescriptionInterface::kOffer) {
873 std::string error = "CreateAnswer called without remote offer.";
874 LOG(LS_ERROR) << error;
875 PostCreateSessionDescriptionFailure(observer, error);
876 return;
877 }
878
879 PeerConnectionInterface::RTCOfferAnswerOptions offer_answer_options;
880 if (!ConvertConstraintsToOfferAnswerOptions(constraints,
881 &offer_answer_options)) {
882 std::string error = "CreateAnswer called with invalid constraints."; 920 std::string error = "CreateAnswer called with invalid constraints.";
883 LOG(LS_ERROR) << error; 921 LOG(LS_ERROR) << error;
884 PostCreateSessionDescriptionFailure(observer, error); 922 PostCreateSessionDescriptionFailure(observer, error);
885 return; 923 return;
886 } 924 }
887 925
888 cricket::MediaSessionOptions session_options;
889 GetOptionsForAnswer(offer_answer_options, &session_options);
890 session_->CreateAnswer(observer, session_options); 926 session_->CreateAnswer(observer, session_options);
891 } 927 }
892 928
893 void PeerConnection::CreateAnswer(CreateSessionDescriptionObserver* observer, 929 void PeerConnection::CreateAnswer(CreateSessionDescriptionObserver* observer,
894 const RTCOfferAnswerOptions& options) { 930 const RTCOfferAnswerOptions& options) {
895 TRACE_EVENT0("webrtc", "PeerConnection::CreateAnswer"); 931 TRACE_EVENT0("webrtc", "PeerConnection::CreateAnswer");
896 if (!observer) { 932 if (!observer) {
897 LOG(LS_ERROR) << "CreateAnswer - observer is NULL."; 933 LOG(LS_ERROR) << "CreateAnswer - observer is NULL.";
898 return; 934 return;
899 } 935 }
900 936
901 cricket::MediaSessionOptions session_options; 937 cricket::MediaSessionOptions session_options;
902 GetOptionsForAnswer(options, &session_options); 938 if (!GetOptionsForAnswer(options, &session_options)) {
939 std::string error = "CreateAnswer called with invalid options.";
940 LOG(LS_ERROR) << error;
941 PostCreateSessionDescriptionFailure(observer, error);
942 return;
943 }
903 944
904 session_->CreateAnswer(observer, session_options); 945 session_->CreateAnswer(observer, session_options);
905 } 946 }
906 947
907 void PeerConnection::SetLocalDescription( 948 void PeerConnection::SetLocalDescription(
908 SetSessionDescriptionObserver* observer, 949 SetSessionDescriptionObserver* observer,
909 SessionDescriptionInterface* desc) { 950 SessionDescriptionInterface* desc) {
910 TRACE_EVENT0("webrtc", "PeerConnection::SetLocalDescription"); 951 TRACE_EVENT0("webrtc", "PeerConnection::SetLocalDescription");
911 if (IsClosed()) { 952 if (IsClosed()) {
912 return; 953 return;
(...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after
1650 1691
1651 void PeerConnection::PostCreateSessionDescriptionFailure( 1692 void PeerConnection::PostCreateSessionDescriptionFailure(
1652 CreateSessionDescriptionObserver* observer, 1693 CreateSessionDescriptionObserver* observer,
1653 const std::string& error) { 1694 const std::string& error) {
1654 CreateSessionDescriptionMsg* msg = new CreateSessionDescriptionMsg(observer); 1695 CreateSessionDescriptionMsg* msg = new CreateSessionDescriptionMsg(observer);
1655 msg->error = error; 1696 msg->error = error;
1656 signaling_thread()->Post(RTC_FROM_HERE, this, 1697 signaling_thread()->Post(RTC_FROM_HERE, this,
1657 MSG_CREATE_SESSIONDESCRIPTION_FAILED, msg); 1698 MSG_CREATE_SESSIONDESCRIPTION_FAILED, msg);
1658 } 1699 }
1659 1700
1660 void PeerConnection::GetOptionsForOffer( 1701 bool PeerConnection::GetOptionsForOffer(
1661 const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options, 1702 const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options,
1662 cricket::MediaSessionOptions* session_options) { 1703 cricket::MediaSessionOptions* session_options) {
1663 ExtractSharedMediaSessionOptions(rtc_options, session_options); 1704 // TODO(deadbeef): Once we have transceivers, enumerate them here instead of
1705 // ContentInfos.
1706 if (session_->local_description()) {
1707 for (const cricket::ContentInfo& content :
1708 session_->local_description()->description()->contents()) {
1709 session_options->transport_options[content.name] =
1710 cricket::TransportOptions();
1711 }
1712 }
1713 session_options->enable_ice_renomination =
1714 configuration_.enable_ice_renomination;
1664 1715
1665 // Figure out transceiver directional preferences. 1716 if (!ExtractMediaSessionOptions(rtc_options, true, session_options)) {
1666 bool send_audio = HasRtpSender(cricket::MEDIA_TYPE_AUDIO); 1717 return false;
1667 bool send_video = HasRtpSender(cricket::MEDIA_TYPE_VIDEO);
1668
1669 // By default, generate sendrecv/recvonly m= sections.
1670 bool recv_audio = true;
1671 bool recv_video = true;
1672
1673 // By default, only offer a new m= section if we have media to send with it.
1674 bool offer_new_audio_description = send_audio;
1675 bool offer_new_video_description = send_video;
1676 bool offer_new_data_description = HasDataChannels();
1677
1678 // The "offer_to_receive_X" options allow those defaults to be overridden.
1679 if (rtc_options.offer_to_receive_audio != RTCOfferAnswerOptions::kUndefined) {
1680 recv_audio = (rtc_options.offer_to_receive_audio > 0);
1681 offer_new_audio_description =
1682 offer_new_audio_description || (rtc_options.offer_to_receive_audio > 0);
1683 }
1684 if (rtc_options.offer_to_receive_video != RTCOfferAnswerOptions::kUndefined) {
1685 recv_video = (rtc_options.offer_to_receive_video > 0);
1686 offer_new_video_description =
1687 offer_new_video_description || (rtc_options.offer_to_receive_video > 0);
1688 } 1718 }
1689 1719
1690 int audio_index = -1; 1720 AddSendStreams(session_options, senders_, rtp_data_channels_);
1691 int video_index = -1; 1721 // Offer to receive audio/video if the constraint is not set and there are
1692 int data_index = -1; 1722 // send streams, or we're currently receiving.
1693 // If a current description exists, generate m= sections in the same order, 1723 if (rtc_options.offer_to_receive_audio == RTCOfferAnswerOptions::kUndefined) {
1694 // using the first audio/video/data section that appears and rejecting 1724 session_options->recv_audio =
1695 // extraneous ones. 1725 session_options->HasSendMediaStream(cricket::MEDIA_TYPE_AUDIO) ||
1696 if (session_->local_description()) { 1726 !remote_audio_tracks_.empty();
1697 GenerateMediaDescriptionOptions(
1698 session_->local_description(),
1699 cricket::RtpTransceiverDirection(send_audio, recv_audio),
1700 cricket::RtpTransceiverDirection(send_video, recv_video), &audio_index,
1701 &video_index, &data_index, session_options);
1702 } 1727 }
1703 1728 if (rtc_options.offer_to_receive_video == RTCOfferAnswerOptions::kUndefined) {
1704 // Add audio/video/data m= sections to the end if needed. 1729 session_options->recv_video =
1705 if (audio_index == -1 && offer_new_audio_description) { 1730 session_options->HasSendMediaStream(cricket::MEDIA_TYPE_VIDEO) ||
1706 session_options->media_description_options.push_back( 1731 !remote_video_tracks_.empty();
1707 cricket::MediaDescriptionOptions(
1708 cricket::MEDIA_TYPE_AUDIO, cricket::CN_AUDIO,
1709 cricket::RtpTransceiverDirection(send_audio, recv_audio), false));
1710 audio_index = session_options->media_description_options.size() - 1;
1711 } 1732 }
1712 if (video_index == -1 && offer_new_video_description) {
1713 session_options->media_description_options.push_back(
1714 cricket::MediaDescriptionOptions(
1715 cricket::MEDIA_TYPE_VIDEO, cricket::CN_VIDEO,
1716 cricket::RtpTransceiverDirection(send_video, recv_video), false));
1717 video_index = session_options->media_description_options.size() - 1;
1718 }
1719 if (data_index == -1 && offer_new_data_description) {
1720 session_options->media_description_options.push_back(
1721 cricket::MediaDescriptionOptions(
1722 cricket::MEDIA_TYPE_DATA, cricket::CN_DATA,
1723 cricket::RtpTransceiverDirection(true, true), false));
1724 data_index = session_options->media_description_options.size() - 1;
1725 }
1726
1727 cricket::MediaDescriptionOptions* audio_media_description_options =
1728 audio_index == -1
1729 ? nullptr
1730 : &session_options->media_description_options[audio_index];
1731 cricket::MediaDescriptionOptions* video_media_description_options =
1732 video_index == -1
1733 ? nullptr
1734 : &session_options->media_description_options[video_index];
1735 cricket::MediaDescriptionOptions* data_media_description_options =
1736 data_index == -1
1737 ? nullptr
1738 : &session_options->media_description_options[data_index];
1739
1740 // Apply ICE restart flag and renomination flag.
1741 for (auto& options : session_options->media_description_options) {
1742 options.transport_options.ice_restart = rtc_options.ice_restart;
1743 options.transport_options.enable_ice_renomination =
1744 configuration_.enable_ice_renomination;
1745 }
1746
1747 AddRtpSenderOptions(senders_, audio_media_description_options,
1748 video_media_description_options);
1749 AddRtpDataChannelOptions(rtp_data_channels_, data_media_description_options);
1750 1733
1751 // Intentionally unset the data channel type for RTP data channel with the 1734 // Intentionally unset the data channel type for RTP data channel with the
1752 // second condition. Otherwise the RTP data channels would be successfully 1735 // second condition. Otherwise the RTP data channels would be successfully
1753 // negotiated by default and the unit tests in WebRtcDataBrowserTest will fail 1736 // negotiated by default and the unit tests in WebRtcDataBrowserTest will fail
1754 // when building with chromium. We want to leave RTP data channels broken, so 1737 // when building with chromium. We want to leave RTP data channels broken, so
1755 // people won't try to use them. 1738 // people won't try to use them.
1756 if (!rtp_data_channels_.empty() || 1739 if (HasDataChannels() && session_->data_channel_type() != cricket::DCT_RTP) {
1757 session_->data_channel_type() != cricket::DCT_RTP) {
1758 session_options->data_channel_type = session_->data_channel_type(); 1740 session_options->data_channel_type = session_->data_channel_type();
1759 } 1741 }
1760 1742
1743 session_options->bundle_enabled =
1744 session_options->bundle_enabled &&
1745 (session_options->has_audio() || session_options->has_video() ||
1746 session_options->has_data());
1747
1761 session_options->rtcp_cname = rtcp_cname_; 1748 session_options->rtcp_cname = rtcp_cname_;
1762 session_options->crypto_options = factory_->options().crypto_options; 1749 session_options->crypto_options = factory_->options().crypto_options;
1750 return true;
1763 } 1751 }
1764 1752
1765 void PeerConnection::GetOptionsForAnswer( 1753 void PeerConnection::InitializeOptionsForAnswer(
1766 const RTCOfferAnswerOptions& rtc_options,
1767 cricket::MediaSessionOptions* session_options) { 1754 cricket::MediaSessionOptions* session_options) {
1768 ExtractSharedMediaSessionOptions(rtc_options, session_options); 1755 session_options->recv_audio = false;
1756 session_options->recv_video = false;
1757 session_options->enable_ice_renomination =
1758 configuration_.enable_ice_renomination;
1759 }
1769 1760
1770 // Figure out transceiver directional preferences. 1761 void PeerConnection::FinishOptionsForAnswer(
1771 bool send_audio = HasRtpSender(cricket::MEDIA_TYPE_AUDIO); 1762 cricket::MediaSessionOptions* session_options) {
1772 bool send_video = HasRtpSender(cricket::MEDIA_TYPE_VIDEO); 1763 // TODO(deadbeef): Once we have transceivers, enumerate them here instead of
1773 1764 // ContentInfos.
1774 // By default, generate sendrecv/recvonly m= sections. The direction is also 1765 if (session_->remote_description()) {
1775 // restricted by the direction in the offer. 1766 // Initialize the transport_options map.
1776 bool recv_audio = true; 1767 for (const cricket::ContentInfo& content :
1777 bool recv_video = true; 1768 session_->remote_description()->description()->contents()) {
1778 1769 session_options->transport_options[content.name] =
1779 // The "offer_to_receive_X" options allow those defaults to be overridden. 1770 cricket::TransportOptions();
1780 if (rtc_options.offer_to_receive_audio != RTCOfferAnswerOptions::kUndefined) { 1771 }
1781 recv_audio = (rtc_options.offer_to_receive_audio > 0);
1782 } 1772 }
1783 if (rtc_options.offer_to_receive_video != RTCOfferAnswerOptions::kUndefined) { 1773 AddSendStreams(session_options, senders_, rtp_data_channels_);
1784 recv_video = (rtc_options.offer_to_receive_video > 0); 1774 // RTP data channel is handled in MediaSessionOptions::AddStream. SCTP streams
1785 } 1775 // are not signaled in the SDP so does not go through that path and must be
1786 1776 // handled here.
1787 int audio_index = -1;
1788 int video_index = -1;
1789 int data_index = -1;
1790 // There should be a pending remote description that's an offer...
1791 RTC_DCHECK(session_->remote_description());
1792 RTC_DCHECK(session_->remote_description()->type() ==
1793 SessionDescriptionInterface::kOffer);
1794 // Generate m= sections that match those in the offer.
1795 // Note that mediasession.cc will handle intersection our preferred direction
1796 // with the offered direction.
1797 GenerateMediaDescriptionOptions(
1798 session_->remote_description(),
1799 cricket::RtpTransceiverDirection(send_audio, recv_audio),
1800 cricket::RtpTransceiverDirection(send_video, recv_video), &audio_index,
1801 &video_index, &data_index, session_options);
1802
1803 cricket::MediaDescriptionOptions* audio_media_description_options =
1804 audio_index == -1
1805 ? nullptr
1806 : &session_options->media_description_options[audio_index];
1807 cricket::MediaDescriptionOptions* video_media_description_options =
1808 video_index == -1
1809 ? nullptr
1810 : &session_options->media_description_options[video_index];
1811 cricket::MediaDescriptionOptions* data_media_description_options =
1812 data_index == -1
1813 ? nullptr
1814 : &session_options->media_description_options[data_index];
1815
1816 // Apply ICE renomination flag.
1817 for (auto& options : session_options->media_description_options) {
1818 options.transport_options.enable_ice_renomination =
1819 configuration_.enable_ice_renomination;
1820 }
1821
1822 AddRtpSenderOptions(senders_, audio_media_description_options,
1823 video_media_description_options);
1824 AddRtpDataChannelOptions(rtp_data_channels_, data_media_description_options);
1825
1826 // Intentionally unset the data channel type for RTP data channel. Otherwise 1777 // Intentionally unset the data channel type for RTP data channel. Otherwise
1827 // the RTP data channels would be successfully negotiated by default and the 1778 // the RTP data channels would be successfully negotiated by default and the
1828 // unit tests in WebRtcDataBrowserTest will fail when building with chromium. 1779 // unit tests in WebRtcDataBrowserTest will fail when building with chromium.
1829 // We want to leave RTP data channels broken, so people won't try to use them. 1780 // We want to leave RTP data channels broken, so people won't try to use them.
1830 if (!rtp_data_channels_.empty() || 1781 if (session_->data_channel_type() != cricket::DCT_RTP) {
1831 session_->data_channel_type() != cricket::DCT_RTP) {
1832 session_options->data_channel_type = session_->data_channel_type(); 1782 session_options->data_channel_type = session_->data_channel_type();
1833 } 1783 }
1784 session_options->bundle_enabled =
1785 session_options->bundle_enabled &&
1786 (session_options->has_audio() || session_options->has_video() ||
1787 session_options->has_data());
1834 1788
1835 session_options->rtcp_cname = rtcp_cname_;
1836 session_options->crypto_options = factory_->options().crypto_options; 1789 session_options->crypto_options = factory_->options().crypto_options;
1837 } 1790 }
1838 1791
1839 void PeerConnection::GenerateMediaDescriptionOptions( 1792 bool PeerConnection::GetOptionsForAnswer(
1840 const SessionDescriptionInterface* session_desc, 1793 const MediaConstraintsInterface* constraints,
1841 cricket::RtpTransceiverDirection audio_direction,
1842 cricket::RtpTransceiverDirection video_direction,
1843 int* audio_index,
1844 int* video_index,
1845 int* data_index,
1846 cricket::MediaSessionOptions* session_options) { 1794 cricket::MediaSessionOptions* session_options) {
1847 for (const cricket::ContentInfo& content : 1795 InitializeOptionsForAnswer(session_options);
1848 session_desc->description()->contents()) { 1796 if (!ParseConstraintsForAnswer(constraints, session_options)) {
1849 if (IsAudioContent(&content)) { 1797 return false;
1850 // If we already have an audio m= section, reject this extra one.
1851 if (*audio_index != -1) {
1852 session_options->media_description_options.push_back(
1853 cricket::MediaDescriptionOptions(
1854 cricket::MEDIA_TYPE_AUDIO, content.name,
1855 cricket::RtpTransceiverDirection(false, false), true));
1856 } else {
1857 session_options->media_description_options.push_back(
1858 cricket::MediaDescriptionOptions(
1859 cricket::MEDIA_TYPE_AUDIO, content.name, audio_direction,
1860 !audio_direction.send && !audio_direction.recv));
1861 *audio_index = session_options->media_description_options.size() - 1;
1862 }
1863 } else if (IsVideoContent(&content)) {
1864 // If we already have an video m= section, reject this extra one.
1865 if (*video_index != -1) {
1866 session_options->media_description_options.push_back(
1867 cricket::MediaDescriptionOptions(
1868 cricket::MEDIA_TYPE_VIDEO, content.name,
1869 cricket::RtpTransceiverDirection(false, false), true));
1870 } else {
1871 session_options->media_description_options.push_back(
1872 cricket::MediaDescriptionOptions(
1873 cricket::MEDIA_TYPE_VIDEO, content.name, video_direction,
1874 !video_direction.send && !video_direction.recv));
1875 *video_index = session_options->media_description_options.size() - 1;
1876 }
1877 } else {
1878 RTC_DCHECK(IsDataContent(&content));
1879 // If we already have an data m= section, reject this extra one.
1880 if (*data_index != -1) {
1881 session_options->media_description_options.push_back(
1882 cricket::MediaDescriptionOptions(
1883 cricket::MEDIA_TYPE_DATA, content.name,
1884 cricket::RtpTransceiverDirection(false, false), true));
1885 } else {
1886 session_options->media_description_options.push_back(
1887 cricket::MediaDescriptionOptions(
1888 cricket::MEDIA_TYPE_DATA, content.name,
1889 // Direction for data sections is meaningless, but legacy
1890 // endpoints might expect sendrecv.
1891 cricket::RtpTransceiverDirection(true, true), false));
1892 *data_index = session_options->media_description_options.size() - 1;
1893 }
1894 }
1895 } 1798 }
1799 session_options->rtcp_cname = rtcp_cname_;
1800
1801 FinishOptionsForAnswer(session_options);
1802 return true;
1803 }
1804
1805 bool PeerConnection::GetOptionsForAnswer(
1806 const RTCOfferAnswerOptions& options,
1807 cricket::MediaSessionOptions* session_options) {
1808 InitializeOptionsForAnswer(session_options);
1809 if (!ExtractMediaSessionOptions(options, false, session_options)) {
1810 return false;
1811 }
1812 session_options->rtcp_cname = rtcp_cname_;
1813
1814 FinishOptionsForAnswer(session_options);
1815 return true;
1896 } 1816 }
1897 1817
1898 void PeerConnection::RemoveTracks(cricket::MediaType media_type) { 1818 void PeerConnection::RemoveTracks(cricket::MediaType media_type) {
1899 UpdateLocalTracks(std::vector<cricket::StreamParams>(), media_type); 1819 UpdateLocalTracks(std::vector<cricket::StreamParams>(), media_type);
1900 UpdateRemoteStreamsList(std::vector<cricket::StreamParams>(), false, 1820 UpdateRemoteStreamsList(std::vector<cricket::StreamParams>(), false,
1901 media_type, nullptr); 1821 media_type, nullptr);
1902 } 1822 }
1903 1823
1904 void PeerConnection::UpdateRemoteStreamsList( 1824 void PeerConnection::UpdateRemoteStreamsList(
1905 const cricket::StreamParamsVec& streams, 1825 const cricket::StreamParamsVec& streams,
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
2358 if (!channel.get()) { 2278 if (!channel.get()) {
2359 LOG(LS_ERROR) << "Failed to create DataChannel from the OPEN message."; 2279 LOG(LS_ERROR) << "Failed to create DataChannel from the OPEN message.";
2360 return; 2280 return;
2361 } 2281 }
2362 2282
2363 rtc::scoped_refptr<DataChannelInterface> proxy_channel = 2283 rtc::scoped_refptr<DataChannelInterface> proxy_channel =
2364 DataChannelProxy::Create(signaling_thread(), channel); 2284 DataChannelProxy::Create(signaling_thread(), channel);
2365 observer_->OnDataChannel(std::move(proxy_channel)); 2285 observer_->OnDataChannel(std::move(proxy_channel));
2366 } 2286 }
2367 2287
2368 bool PeerConnection::HasRtpSender(cricket::MediaType type) const {
2369 return std::find_if(
2370 senders_.begin(), senders_.end(),
2371 [type](const rtc::scoped_refptr<
2372 RtpSenderProxyWithInternal<RtpSenderInternal>>& sender) {
2373 return sender->media_type() == type;
2374 }) != senders_.end();
2375 }
2376
2377 RtpSenderInternal* PeerConnection::FindSenderById(const std::string& id) { 2288 RtpSenderInternal* PeerConnection::FindSenderById(const std::string& id) {
2378 auto it = std::find_if( 2289 auto it = std::find_if(
2379 senders_.begin(), senders_.end(), 2290 senders_.begin(), senders_.end(),
2380 [id](const rtc::scoped_refptr< 2291 [id](const rtc::scoped_refptr<
2381 RtpSenderProxyWithInternal<RtpSenderInternal>>& sender) { 2292 RtpSenderProxyWithInternal<RtpSenderInternal>>& sender) {
2382 return sender->id() == id; 2293 return sender->id() == id;
2383 }); 2294 });
2384 return it != senders_.end() ? (*it)->internal() : nullptr; 2295 return it != senders_.end() ? (*it)->internal() : nullptr;
2385 } 2296 }
2386 2297
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
2523 return event_log_->StartLogging(file, max_size_bytes); 2434 return event_log_->StartLogging(file, max_size_bytes);
2524 } 2435 }
2525 2436
2526 void PeerConnection::StopRtcEventLog_w() { 2437 void PeerConnection::StopRtcEventLog_w() {
2527 if (event_log_) { 2438 if (event_log_) {
2528 event_log_->StopLogging(); 2439 event_log_->StopLogging();
2529 } 2440 }
2530 } 2441 }
2531 2442
2532 } // namespace webrtc 2443 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/pc/peerconnection.h ('k') | webrtc/pc/peerconnectioninterface_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698