blob: a000b5809d8d62b3f2679a3897107f952bf1d7a3 [file] [log] [blame]
Steve Anton6e634bf2017-11-13 10:44:53 -08001/*
2 * Copyright 2017 The WebRTC project authors. All Rights Reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Steve Anton10542f22019-01-11 09:11:00 -080011#include "pc/rtp_transceiver.h"
Steve Anton6e634bf2017-11-13 10:44:53 -080012
13#include <string>
14
Steve Anton64b626b2019-01-28 17:25:26 -080015#include "absl/algorithm/container.h"
Steve Anton10542f22019-01-11 09:11:00 -080016#include "pc/rtp_media_utils.h"
Yves Gerey3e707812018-11-28 16:47:49 +010017#include "rtc_base/checks.h"
18#include "rtc_base/logging.h"
Steve Antondcc3c022017-12-22 16:02:54 -080019
Steve Anton6e634bf2017-11-13 10:44:53 -080020namespace webrtc {
21
22RtpTransceiver::RtpTransceiver(cricket::MediaType media_type)
23 : unified_plan_(false), media_type_(media_type) {
24 RTC_DCHECK(media_type == cricket::MEDIA_TYPE_AUDIO ||
25 media_type == cricket::MEDIA_TYPE_VIDEO);
26}
27
Steve Anton79e79602017-11-20 10:25:56 -080028RtpTransceiver::RtpTransceiver(
29 rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> sender,
30 rtc::scoped_refptr<RtpReceiverProxyWithInternal<RtpReceiverInternal>>
31 receiver)
32 : unified_plan_(true), media_type_(sender->media_type()) {
33 RTC_DCHECK(media_type_ == cricket::MEDIA_TYPE_AUDIO ||
34 media_type_ == cricket::MEDIA_TYPE_VIDEO);
35 RTC_DCHECK_EQ(sender->media_type(), receiver->media_type());
36 senders_.push_back(sender);
37 receivers_.push_back(receiver);
38}
39
Steve Anton6e634bf2017-11-13 10:44:53 -080040RtpTransceiver::~RtpTransceiver() {
41 Stop();
42}
43
Amit Hilbuchdd9390c2018-11-13 16:26:05 -080044void RtpTransceiver::SetChannel(cricket::ChannelInterface* channel) {
45 // Cannot set a non-null channel on a stopped transceiver.
46 if (stopped_ && channel) {
47 return;
48 }
49
Steve Anton6e634bf2017-11-13 10:44:53 -080050 if (channel) {
51 RTC_DCHECK_EQ(media_type(), channel->media_type());
52 }
Steve Anton60776752018-01-10 11:51:34 -080053
54 if (channel_) {
Amit Hilbuchdd9390c2018-11-13 16:26:05 -080055 channel_->SignalFirstPacketReceived().disconnect(this);
Steve Anton60776752018-01-10 11:51:34 -080056 }
57
Steve Anton6e634bf2017-11-13 10:44:53 -080058 channel_ = channel;
Steve Anton60776752018-01-10 11:51:34 -080059
60 if (channel_) {
Amit Hilbuchdd9390c2018-11-13 16:26:05 -080061 channel_->SignalFirstPacketReceived().connect(
Steve Anton60776752018-01-10 11:51:34 -080062 this, &RtpTransceiver::OnFirstPacketReceived);
63 }
64
Mirko Bonadei739baf02019-01-27 17:29:42 +010065 for (const auto& sender : senders_) {
Amit Hilbuchdd9390c2018-11-13 16:26:05 -080066 sender->internal()->SetMediaChannel(channel_ ? channel_->media_channel()
67 : nullptr);
Steve Anton6e634bf2017-11-13 10:44:53 -080068 }
Steve Anton60776752018-01-10 11:51:34 -080069
Mirko Bonadei739baf02019-01-27 17:29:42 +010070 for (const auto& receiver : receivers_) {
Amit Hilbuchdd9390c2018-11-13 16:26:05 -080071 if (!channel_) {
Steve Anton6e634bf2017-11-13 10:44:53 -080072 receiver->internal()->Stop();
73 }
Amit Hilbuchdd9390c2018-11-13 16:26:05 -080074
75 receiver->internal()->SetMediaChannel(channel_ ? channel_->media_channel()
76 : nullptr);
Steve Anton6e634bf2017-11-13 10:44:53 -080077 }
78}
79
80void RtpTransceiver::AddSender(
81 rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> sender) {
Amit Hilbuchdd9390c2018-11-13 16:26:05 -080082 RTC_DCHECK(!stopped_);
Steve Anton6e634bf2017-11-13 10:44:53 -080083 RTC_DCHECK(!unified_plan_);
84 RTC_DCHECK(sender);
Steve Anton69470252018-02-09 11:43:08 -080085 RTC_DCHECK_EQ(media_type(), sender->media_type());
Steve Anton64b626b2019-01-28 17:25:26 -080086 RTC_DCHECK(!absl::c_linear_search(senders_, sender));
Steve Anton6e634bf2017-11-13 10:44:53 -080087 senders_.push_back(sender);
88}
89
90bool RtpTransceiver::RemoveSender(RtpSenderInterface* sender) {
91 RTC_DCHECK(!unified_plan_);
92 if (sender) {
93 RTC_DCHECK_EQ(media_type(), sender->media_type());
94 }
Steve Anton64b626b2019-01-28 17:25:26 -080095 auto it = absl::c_find(senders_, sender);
Steve Anton6e634bf2017-11-13 10:44:53 -080096 if (it == senders_.end()) {
97 return false;
98 }
99 (*it)->internal()->Stop();
100 senders_.erase(it);
101 return true;
102}
103
104void RtpTransceiver::AddReceiver(
105 rtc::scoped_refptr<RtpReceiverProxyWithInternal<RtpReceiverInternal>>
106 receiver) {
Amit Hilbuchdd9390c2018-11-13 16:26:05 -0800107 RTC_DCHECK(!stopped_);
Steve Anton6e634bf2017-11-13 10:44:53 -0800108 RTC_DCHECK(!unified_plan_);
109 RTC_DCHECK(receiver);
Steve Anton69470252018-02-09 11:43:08 -0800110 RTC_DCHECK_EQ(media_type(), receiver->media_type());
Steve Anton64b626b2019-01-28 17:25:26 -0800111 RTC_DCHECK(!absl::c_linear_search(receivers_, receiver));
Steve Anton6e634bf2017-11-13 10:44:53 -0800112 receivers_.push_back(receiver);
113}
114
115bool RtpTransceiver::RemoveReceiver(RtpReceiverInterface* receiver) {
116 RTC_DCHECK(!unified_plan_);
117 if (receiver) {
118 RTC_DCHECK_EQ(media_type(), receiver->media_type());
119 }
Steve Anton64b626b2019-01-28 17:25:26 -0800120 auto it = absl::c_find(receivers_, receiver);
Steve Anton6e634bf2017-11-13 10:44:53 -0800121 if (it == receivers_.end()) {
122 return false;
123 }
124 (*it)->internal()->Stop();
125 receivers_.erase(it);
126 return true;
127}
128
Steve Antonf9381f02017-12-14 10:23:57 -0800129rtc::scoped_refptr<RtpSenderInternal> RtpTransceiver::sender_internal() const {
130 RTC_DCHECK(unified_plan_);
131 RTC_CHECK_EQ(1u, senders_.size());
132 return senders_[0]->internal();
133}
134
135rtc::scoped_refptr<RtpReceiverInternal> RtpTransceiver::receiver_internal()
136 const {
137 RTC_DCHECK(unified_plan_);
138 RTC_CHECK_EQ(1u, receivers_.size());
139 return receivers_[0]->internal();
140}
141
Steve Anton69470252018-02-09 11:43:08 -0800142cricket::MediaType RtpTransceiver::media_type() const {
143 return media_type_;
144}
145
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200146absl::optional<std::string> RtpTransceiver::mid() const {
Steve Anton6e634bf2017-11-13 10:44:53 -0800147 return mid_;
148}
149
Amit Hilbuchdd9390c2018-11-13 16:26:05 -0800150void RtpTransceiver::OnFirstPacketReceived(cricket::ChannelInterface*) {
Mirko Bonadei739baf02019-01-27 17:29:42 +0100151 for (const auto& receiver : receivers_) {
Steve Anton60776752018-01-10 11:51:34 -0800152 receiver->internal()->NotifyFirstPacketReceived();
153 }
154}
155
Steve Anton6e634bf2017-11-13 10:44:53 -0800156rtc::scoped_refptr<RtpSenderInterface> RtpTransceiver::sender() const {
157 RTC_DCHECK(unified_plan_);
158 RTC_CHECK_EQ(1u, senders_.size());
159 return senders_[0];
160}
161
162rtc::scoped_refptr<RtpReceiverInterface> RtpTransceiver::receiver() const {
163 RTC_DCHECK(unified_plan_);
164 RTC_CHECK_EQ(1u, receivers_.size());
165 return receivers_[0];
166}
167
Steve Antondcc3c022017-12-22 16:02:54 -0800168void RtpTransceiver::set_current_direction(RtpTransceiverDirection direction) {
Steve Anton3d954a62018-04-02 11:27:23 -0700169 RTC_LOG(LS_INFO) << "Changing transceiver (MID=" << mid_.value_or("<not set>")
170 << ") current direction from "
171 << (current_direction_ ? RtpTransceiverDirectionToString(
172 *current_direction_)
173 : "<not set>")
174 << " to " << RtpTransceiverDirectionToString(direction)
175 << ".";
Steve Antondcc3c022017-12-22 16:02:54 -0800176 current_direction_ = direction;
177 if (RtpTransceiverDirectionHasSend(*current_direction_)) {
178 has_ever_been_used_to_send_ = true;
179 }
180}
181
Steve Anton0f5400a2018-07-17 14:25:36 -0700182void RtpTransceiver::set_fired_direction(RtpTransceiverDirection direction) {
183 fired_direction_ = direction;
184}
185
Steve Anton6e634bf2017-11-13 10:44:53 -0800186bool RtpTransceiver::stopped() const {
187 return stopped_;
188}
189
190RtpTransceiverDirection RtpTransceiver::direction() const {
191 return direction_;
192}
193
194void RtpTransceiver::SetDirection(RtpTransceiverDirection new_direction) {
Steve Anton52d86772018-02-20 15:48:12 -0800195 if (stopped()) {
196 return;
197 }
198 if (new_direction == direction_) {
199 return;
200 }
201 direction_ = new_direction;
202 SignalNegotiationNeeded();
Steve Anton6e634bf2017-11-13 10:44:53 -0800203}
204
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200205absl::optional<RtpTransceiverDirection> RtpTransceiver::current_direction()
Steve Anton6e634bf2017-11-13 10:44:53 -0800206 const {
207 return current_direction_;
208}
209
Steve Anton0f5400a2018-07-17 14:25:36 -0700210absl::optional<RtpTransceiverDirection> RtpTransceiver::fired_direction()
211 const {
212 return fired_direction_;
213}
214
Steve Anton6e634bf2017-11-13 10:44:53 -0800215void RtpTransceiver::Stop() {
Mirko Bonadei739baf02019-01-27 17:29:42 +0100216 for (const auto& sender : senders_) {
Steve Anton6e634bf2017-11-13 10:44:53 -0800217 sender->internal()->Stop();
218 }
Mirko Bonadei739baf02019-01-27 17:29:42 +0100219 for (const auto& receiver : receivers_) {
Steve Anton6e634bf2017-11-13 10:44:53 -0800220 receiver->internal()->Stop();
221 }
222 stopped_ = true;
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200223 current_direction_ = absl::nullopt;
Steve Anton6e634bf2017-11-13 10:44:53 -0800224}
225
226void RtpTransceiver::SetCodecPreferences(
227 rtc::ArrayView<RtpCodecCapability> codecs) {
228 // TODO(steveanton): Implement this.
229 RTC_NOTREACHED() << "Not implemented";
230}
231
232} // namespace webrtc