blob: b04c20c4b6d699d61b249319ac31252fe463f96c [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
Yves Gerey3e707812018-11-28 16:47:49 +010013#include <algorithm>
Steve Anton6e634bf2017-11-13 10:44:53 -080014#include <string>
15
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
Steve Anton6e634bf2017-11-13 10:44:53 -080065 for (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
Steve Anton6e634bf2017-11-13 10:44:53 -080070 for (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 Anton6e634bf2017-11-13 10:44:53 -080086 RTC_DCHECK(std::find(senders_.begin(), senders_.end(), sender) ==
87 senders_.end());
88 senders_.push_back(sender);
89}
90
91bool RtpTransceiver::RemoveSender(RtpSenderInterface* sender) {
92 RTC_DCHECK(!unified_plan_);
93 if (sender) {
94 RTC_DCHECK_EQ(media_type(), sender->media_type());
95 }
96 auto it = std::find(senders_.begin(), senders_.end(), sender);
97 if (it == senders_.end()) {
98 return false;
99 }
100 (*it)->internal()->Stop();
101 senders_.erase(it);
102 return true;
103}
104
105void RtpTransceiver::AddReceiver(
106 rtc::scoped_refptr<RtpReceiverProxyWithInternal<RtpReceiverInternal>>
107 receiver) {
Amit Hilbuchdd9390c2018-11-13 16:26:05 -0800108 RTC_DCHECK(!stopped_);
Steve Anton6e634bf2017-11-13 10:44:53 -0800109 RTC_DCHECK(!unified_plan_);
110 RTC_DCHECK(receiver);
Steve Anton69470252018-02-09 11:43:08 -0800111 RTC_DCHECK_EQ(media_type(), receiver->media_type());
Steve Anton6e634bf2017-11-13 10:44:53 -0800112 RTC_DCHECK(std::find(receivers_.begin(), receivers_.end(), receiver) ==
113 receivers_.end());
114 receivers_.push_back(receiver);
115}
116
117bool RtpTransceiver::RemoveReceiver(RtpReceiverInterface* receiver) {
118 RTC_DCHECK(!unified_plan_);
119 if (receiver) {
120 RTC_DCHECK_EQ(media_type(), receiver->media_type());
121 }
122 auto it = std::find(receivers_.begin(), receivers_.end(), receiver);
123 if (it == receivers_.end()) {
124 return false;
125 }
126 (*it)->internal()->Stop();
127 receivers_.erase(it);
128 return true;
129}
130
Steve Antonf9381f02017-12-14 10:23:57 -0800131rtc::scoped_refptr<RtpSenderInternal> RtpTransceiver::sender_internal() const {
132 RTC_DCHECK(unified_plan_);
133 RTC_CHECK_EQ(1u, senders_.size());
134 return senders_[0]->internal();
135}
136
137rtc::scoped_refptr<RtpReceiverInternal> RtpTransceiver::receiver_internal()
138 const {
139 RTC_DCHECK(unified_plan_);
140 RTC_CHECK_EQ(1u, receivers_.size());
141 return receivers_[0]->internal();
142}
143
Steve Anton69470252018-02-09 11:43:08 -0800144cricket::MediaType RtpTransceiver::media_type() const {
145 return media_type_;
146}
147
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200148absl::optional<std::string> RtpTransceiver::mid() const {
Steve Anton6e634bf2017-11-13 10:44:53 -0800149 return mid_;
150}
151
Amit Hilbuchdd9390c2018-11-13 16:26:05 -0800152void RtpTransceiver::OnFirstPacketReceived(cricket::ChannelInterface*) {
Steve Anton60776752018-01-10 11:51:34 -0800153 for (auto receiver : receivers_) {
154 receiver->internal()->NotifyFirstPacketReceived();
155 }
156}
157
Steve Anton6e634bf2017-11-13 10:44:53 -0800158rtc::scoped_refptr<RtpSenderInterface> RtpTransceiver::sender() const {
159 RTC_DCHECK(unified_plan_);
160 RTC_CHECK_EQ(1u, senders_.size());
161 return senders_[0];
162}
163
164rtc::scoped_refptr<RtpReceiverInterface> RtpTransceiver::receiver() const {
165 RTC_DCHECK(unified_plan_);
166 RTC_CHECK_EQ(1u, receivers_.size());
167 return receivers_[0];
168}
169
Steve Antondcc3c022017-12-22 16:02:54 -0800170void RtpTransceiver::set_current_direction(RtpTransceiverDirection direction) {
Steve Anton3d954a62018-04-02 11:27:23 -0700171 RTC_LOG(LS_INFO) << "Changing transceiver (MID=" << mid_.value_or("<not set>")
172 << ") current direction from "
173 << (current_direction_ ? RtpTransceiverDirectionToString(
174 *current_direction_)
175 : "<not set>")
176 << " to " << RtpTransceiverDirectionToString(direction)
177 << ".";
Steve Antondcc3c022017-12-22 16:02:54 -0800178 current_direction_ = direction;
179 if (RtpTransceiverDirectionHasSend(*current_direction_)) {
180 has_ever_been_used_to_send_ = true;
181 }
182}
183
Steve Anton0f5400a2018-07-17 14:25:36 -0700184void RtpTransceiver::set_fired_direction(RtpTransceiverDirection direction) {
185 fired_direction_ = direction;
186}
187
Steve Anton6e634bf2017-11-13 10:44:53 -0800188bool RtpTransceiver::stopped() const {
189 return stopped_;
190}
191
192RtpTransceiverDirection RtpTransceiver::direction() const {
193 return direction_;
194}
195
196void RtpTransceiver::SetDirection(RtpTransceiverDirection new_direction) {
Steve Anton52d86772018-02-20 15:48:12 -0800197 if (stopped()) {
198 return;
199 }
200 if (new_direction == direction_) {
201 return;
202 }
203 direction_ = new_direction;
204 SignalNegotiationNeeded();
Steve Anton6e634bf2017-11-13 10:44:53 -0800205}
206
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200207absl::optional<RtpTransceiverDirection> RtpTransceiver::current_direction()
Steve Anton6e634bf2017-11-13 10:44:53 -0800208 const {
209 return current_direction_;
210}
211
Steve Anton0f5400a2018-07-17 14:25:36 -0700212absl::optional<RtpTransceiverDirection> RtpTransceiver::fired_direction()
213 const {
214 return fired_direction_;
215}
216
Steve Anton6e634bf2017-11-13 10:44:53 -0800217void RtpTransceiver::Stop() {
218 for (auto sender : senders_) {
219 sender->internal()->Stop();
220 }
221 for (auto receiver : receivers_) {
222 receiver->internal()->Stop();
223 }
224 stopped_ = true;
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200225 current_direction_ = absl::nullopt;
Steve Anton6e634bf2017-11-13 10:44:53 -0800226}
227
228void RtpTransceiver::SetCodecPreferences(
229 rtc::ArrayView<RtpCodecCapability> codecs) {
230 // TODO(steveanton): Implement this.
231 RTC_NOTREACHED() << "Not implemented";
232}
233
234} // namespace webrtc