blob: f1bce1c937ecc5fc1cf656a391972d367962901d [file] [log] [blame]
Niels Möllere0446cb2018-11-30 09:35:52 +01001/*
2 * Copyright 2018 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
11#include "api/test/loopback_media_transport.h"
12
Mirko Bonadei317a1f02019-09-17 17:06:18 +020013#include <memory>
14
Steve Antona59dcc32019-03-25 13:53:07 -070015#include "absl/algorithm/container.h"
Steve Anton10542f22019-01-11 09:11:00 -080016#include "rtc_base/time_utils.h"
Niels Möllere0446cb2018-11-30 09:35:52 +010017
18namespace webrtc {
19
20namespace {
21
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -070022constexpr size_t kLoopbackMaxDatagramSize = 1200;
23
Niels Möllere0446cb2018-11-30 09:35:52 +010024// Wrapper used to hand out unique_ptrs to loopback media transports without
25// ownership changes.
26class WrapperMediaTransport : public MediaTransportInterface {
27 public:
28 explicit WrapperMediaTransport(MediaTransportInterface* wrapped)
29 : wrapped_(wrapped) {}
30
31 RTCError SendAudioFrame(uint64_t channel_id,
32 MediaTransportEncodedAudioFrame frame) override {
33 return wrapped_->SendAudioFrame(channel_id, std::move(frame));
34 }
35
36 RTCError SendVideoFrame(
37 uint64_t channel_id,
38 const MediaTransportEncodedVideoFrame& frame) override {
39 return wrapped_->SendVideoFrame(channel_id, frame);
40 }
41
Niels Möller1c7f5f62018-12-10 11:06:02 +010042 void SetKeyFrameRequestCallback(
43 MediaTransportKeyFrameRequestCallback* callback) override {
44 wrapped_->SetKeyFrameRequestCallback(callback);
45 }
46
Niels Möllere0446cb2018-11-30 09:35:52 +010047 RTCError RequestKeyFrame(uint64_t channel_id) override {
48 return wrapped_->RequestKeyFrame(channel_id);
49 }
50
51 void SetReceiveAudioSink(MediaTransportAudioSinkInterface* sink) override {
52 wrapped_->SetReceiveAudioSink(sink);
53 }
54
55 void SetReceiveVideoSink(MediaTransportVideoSinkInterface* sink) override {
56 wrapped_->SetReceiveVideoSink(sink);
57 }
58
Niels Möller46879152019-01-07 15:54:47 +010059 void AddTargetTransferRateObserver(
60 TargetTransferRateObserver* observer) override {
61 wrapped_->AddTargetTransferRateObserver(observer);
62 }
63
64 void RemoveTargetTransferRateObserver(
65 TargetTransferRateObserver* observer) override {
66 wrapped_->RemoveTargetTransferRateObserver(observer);
67 }
68
Niels Möllere0446cb2018-11-30 09:35:52 +010069 void SetMediaTransportStateCallback(
70 MediaTransportStateCallback* callback) override {
71 wrapped_->SetMediaTransportStateCallback(callback);
72 }
73
Bjorn Mellem9ded4852019-02-28 12:27:11 -080074 RTCError OpenChannel(int channel_id) override {
75 return wrapped_->OpenChannel(channel_id);
76 }
77
Niels Möllere0446cb2018-11-30 09:35:52 +010078 RTCError SendData(int channel_id,
79 const SendDataParams& params,
80 const rtc::CopyOnWriteBuffer& buffer) override {
81 return wrapped_->SendData(channel_id, params, buffer);
82 }
83
84 RTCError CloseChannel(int channel_id) override {
85 return wrapped_->CloseChannel(channel_id);
86 }
87
88 void SetDataSink(DataChannelSink* sink) override {
89 wrapped_->SetDataSink(sink);
90 }
91
Bjorn A Mellemb689af42019-08-21 10:44:59 -070092 bool IsReadyToSend() const override { return wrapped_->IsReadyToSend(); }
93
Piotr (Peter) Slatala48c54932019-01-28 06:50:38 -080094 void SetAllocatedBitrateLimits(
95 const MediaTransportAllocatedBitrateLimits& limits) override {}
96
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -080097 absl::optional<std::string> GetTransportParametersOffer() const override {
98 return wrapped_->GetTransportParametersOffer();
99 }
100
Niels Möllere0446cb2018-11-30 09:35:52 +0100101 private:
102 MediaTransportInterface* wrapped_;
103};
104
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700105class WrapperDatagramTransport : public DatagramTransportInterface {
106 public:
107 explicit WrapperDatagramTransport(DatagramTransportInterface* wrapped)
108 : wrapped_(wrapped) {}
109
110 // Datagram transport overrides.
111 void Connect(rtc::PacketTransportInternal* packet_transport) override {
112 return wrapped_->Connect(packet_transport);
113 }
114
115 CongestionControlInterface* congestion_control() override {
116 return wrapped_->congestion_control();
117 }
118
119 void SetTransportStateCallback(
120 MediaTransportStateCallback* callback) override {
121 return wrapped_->SetTransportStateCallback(callback);
122 }
123
124 RTCError SendDatagram(rtc::ArrayView<const uint8_t> data,
125 DatagramId datagram_id) override {
126 return wrapped_->SendDatagram(data, datagram_id);
127 }
128
129 size_t GetLargestDatagramSize() const override {
130 return wrapped_->GetLargestDatagramSize();
131 }
132
133 void SetDatagramSink(DatagramSinkInterface* sink) override {
134 return wrapped_->SetDatagramSink(sink);
135 }
136
137 std::string GetTransportParameters() const override {
138 return wrapped_->GetTransportParameters();
139 }
140
141 // Data channel overrides.
142 RTCError OpenChannel(int channel_id) override {
143 return wrapped_->OpenChannel(channel_id);
144 }
145
146 RTCError SendData(int channel_id,
147 const SendDataParams& params,
148 const rtc::CopyOnWriteBuffer& buffer) override {
149 return wrapped_->SendData(channel_id, params, buffer);
150 }
151
152 RTCError CloseChannel(int channel_id) override {
153 return wrapped_->CloseChannel(channel_id);
154 }
155
156 void SetDataSink(DataChannelSink* sink) override {
157 wrapped_->SetDataSink(sink);
158 }
159
160 bool IsReadyToSend() const override { return wrapped_->IsReadyToSend(); }
161
162 private:
163 DatagramTransportInterface* wrapped_;
164};
165
Niels Möllere0446cb2018-11-30 09:35:52 +0100166} // namespace
167
168WrapperMediaTransportFactory::WrapperMediaTransportFactory(
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700169 MediaTransportInterface* wrapped_media_transport,
170 DatagramTransportInterface* wrapped_datagram_transport)
171 : wrapped_media_transport_(wrapped_media_transport),
172 wrapped_datagram_transport_(wrapped_datagram_transport) {}
Niels Möllere0446cb2018-11-30 09:35:52 +0100173
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800174WrapperMediaTransportFactory::WrapperMediaTransportFactory(
175 MediaTransportFactory* wrapped)
176 : wrapped_factory_(wrapped) {}
177
Niels Möllere0446cb2018-11-30 09:35:52 +0100178RTCErrorOr<std::unique_ptr<MediaTransportInterface>>
179WrapperMediaTransportFactory::CreateMediaTransport(
180 rtc::PacketTransportInternal* packet_transport,
181 rtc::Thread* network_thread,
182 const MediaTransportSettings& settings) {
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800183 created_transport_count_++;
184 if (wrapped_factory_) {
185 return wrapped_factory_->CreateMediaTransport(packet_transport,
186 network_thread, settings);
187 }
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200188 return {std::make_unique<WrapperMediaTransport>(wrapped_media_transport_)};
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700189}
190
191RTCErrorOr<std::unique_ptr<DatagramTransportInterface>>
192WrapperMediaTransportFactory::CreateDatagramTransport(
193 rtc::Thread* network_thread,
194 const MediaTransportSettings& settings) {
195 created_transport_count_++;
196 if (wrapped_factory_) {
197 return wrapped_factory_->CreateDatagramTransport(network_thread, settings);
198 }
199 return {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200200 std::make_unique<WrapperDatagramTransport>(wrapped_datagram_transport_)};
Niels Möllere0446cb2018-11-30 09:35:52 +0100201}
202
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800203std::string WrapperMediaTransportFactory::GetTransportName() const {
204 if (wrapped_factory_) {
205 return wrapped_factory_->GetTransportName();
206 }
207 return "wrapped-transport";
208}
209
210int WrapperMediaTransportFactory::created_transport_count() const {
211 return created_transport_count_;
212}
213
214RTCErrorOr<std::unique_ptr<MediaTransportInterface>>
215WrapperMediaTransportFactory::CreateMediaTransport(
216 rtc::Thread* network_thread,
217 const MediaTransportSettings& settings) {
218 created_transport_count_++;
219 if (wrapped_factory_) {
220 return wrapped_factory_->CreateMediaTransport(network_thread, settings);
221 }
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200222 return {std::make_unique<WrapperMediaTransport>(wrapped_media_transport_)};
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800223}
224
225MediaTransportPair::MediaTransportPair(rtc::Thread* thread)
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700226 : first_(thread),
227 second_(thread),
228 first_datagram_transport_(thread),
229 second_datagram_transport_(thread),
230 first_factory_(&first_, &first_datagram_transport_),
231 second_factory_(&second_, &second_datagram_transport_) {
232 first_.Connect(&second_);
233 second_.Connect(&first_);
234 first_datagram_transport_.Connect(&second_datagram_transport_);
235 second_datagram_transport_.Connect(&first_datagram_transport_);
236}
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800237
238MediaTransportPair::~MediaTransportPair() = default;
239
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700240MediaTransportPair::LoopbackDataChannelTransport::LoopbackDataChannelTransport(
241 rtc::Thread* thread)
242 : thread_(thread) {}
243
244MediaTransportPair::LoopbackDataChannelTransport::
245 ~LoopbackDataChannelTransport() {
246 RTC_CHECK(data_sink_ == nullptr);
247}
248
249void MediaTransportPair::LoopbackDataChannelTransport::Connect(
250 LoopbackDataChannelTransport* other) {
251 other_ = other;
252}
253
Niels Möllere0446cb2018-11-30 09:35:52 +0100254MediaTransportPair::LoopbackMediaTransport::LoopbackMediaTransport(
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700255 rtc::Thread* thread)
256 : dc_transport_(thread), thread_(thread), other_(nullptr) {
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800257 RTC_LOG(LS_INFO) << "LoopbackMediaTransport";
258}
Niels Möllere0446cb2018-11-30 09:35:52 +0100259
260MediaTransportPair::LoopbackMediaTransport::~LoopbackMediaTransport() {
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800261 RTC_LOG(LS_INFO) << "~LoopbackMediaTransport";
Niels Möllere0446cb2018-11-30 09:35:52 +0100262 rtc::CritScope lock(&sink_lock_);
263 RTC_CHECK(audio_sink_ == nullptr);
264 RTC_CHECK(video_sink_ == nullptr);
Niels Möller46879152019-01-07 15:54:47 +0100265 RTC_CHECK(target_transfer_rate_observers_.empty());
266 RTC_CHECK(rtt_observers_.empty());
Niels Möllere0446cb2018-11-30 09:35:52 +0100267}
268
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700269void MediaTransportPair::LoopbackMediaTransport::Connect(
270 LoopbackMediaTransport* other) {
271 other_ = other;
272 dc_transport_.Connect(&other->dc_transport_);
273}
274
275void MediaTransportPair::LoopbackMediaTransport::Connect(
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700276 rtc::PacketTransportInternal* packet_transport) {
277 if (state_after_connect_) {
278 SetState(*state_after_connect_);
279 }
280}
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700281
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800282absl::optional<std::string>
283MediaTransportPair::LoopbackMediaTransport::GetTransportParametersOffer()
284 const {
285 return "loopback-media-transport-parameters";
286}
287
Niels Möllere0446cb2018-11-30 09:35:52 +0100288RTCError MediaTransportPair::LoopbackMediaTransport::SendAudioFrame(
289 uint64_t channel_id,
290 MediaTransportEncodedAudioFrame frame) {
291 {
292 rtc::CritScope lock(&stats_lock_);
293 ++stats_.sent_audio_frames;
294 }
295 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, channel_id, frame] {
Mirko Bonadei05cf6be2019-01-31 21:38:12 +0100296 other_->OnData(channel_id, frame);
Niels Möllere0446cb2018-11-30 09:35:52 +0100297 });
298 return RTCError::OK();
299}
300
301RTCError MediaTransportPair::LoopbackMediaTransport::SendVideoFrame(
302 uint64_t channel_id,
303 const MediaTransportEncodedVideoFrame& frame) {
304 {
305 rtc::CritScope lock(&stats_lock_);
306 ++stats_.sent_video_frames;
307 }
308 // Ensure that we own the referenced data.
309 MediaTransportEncodedVideoFrame frame_copy = frame;
310 frame_copy.Retain();
311 invoker_.AsyncInvoke<void>(
Mirko Bonadei80a86872019-02-04 15:01:43 +0100312 RTC_FROM_HERE, thread_, [this, channel_id, frame_copy]() mutable {
Niels Möllere0446cb2018-11-30 09:35:52 +0100313 other_->OnData(channel_id, std::move(frame_copy));
314 });
315 return RTCError::OK();
316}
317
Niels Möller1c7f5f62018-12-10 11:06:02 +0100318void MediaTransportPair::LoopbackMediaTransport::SetKeyFrameRequestCallback(
319 MediaTransportKeyFrameRequestCallback* callback) {
320 rtc::CritScope lock(&sink_lock_);
321 if (callback) {
322 RTC_CHECK(key_frame_callback_ == nullptr);
323 }
324 key_frame_callback_ = callback;
325}
326
Niels Möllere0446cb2018-11-30 09:35:52 +0100327RTCError MediaTransportPair::LoopbackMediaTransport::RequestKeyFrame(
328 uint64_t channel_id) {
Niels Möller1c7f5f62018-12-10 11:06:02 +0100329 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, channel_id] {
330 other_->OnKeyFrameRequested(channel_id);
331 });
Niels Möllere0446cb2018-11-30 09:35:52 +0100332 return RTCError::OK();
333}
334
335void MediaTransportPair::LoopbackMediaTransport::SetReceiveAudioSink(
336 MediaTransportAudioSinkInterface* sink) {
337 rtc::CritScope lock(&sink_lock_);
338 if (sink) {
339 RTC_CHECK(audio_sink_ == nullptr);
340 }
341 audio_sink_ = sink;
342}
343
344void MediaTransportPair::LoopbackMediaTransport::SetReceiveVideoSink(
345 MediaTransportVideoSinkInterface* sink) {
346 rtc::CritScope lock(&sink_lock_);
347 if (sink) {
348 RTC_CHECK(video_sink_ == nullptr);
349 }
350 video_sink_ = sink;
351}
352
Niels Möller46879152019-01-07 15:54:47 +0100353void MediaTransportPair::LoopbackMediaTransport::AddTargetTransferRateObserver(
354 TargetTransferRateObserver* observer) {
355 RTC_CHECK(observer);
356 {
357 rtc::CritScope cs(&sink_lock_);
Steve Antona59dcc32019-03-25 13:53:07 -0700358 RTC_CHECK(
359 !absl::c_linear_search(target_transfer_rate_observers_, observer));
Niels Möller46879152019-01-07 15:54:47 +0100360 target_transfer_rate_observers_.push_back(observer);
361 }
362 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this] {
363 RTC_DCHECK_RUN_ON(thread_);
364 const DataRate kBitrate = DataRate::kbps(300);
365 const Timestamp now = Timestamp::us(rtc::TimeMicros());
366
367 TargetTransferRate transfer_rate;
368 transfer_rate.at_time = now;
369 transfer_rate.target_rate = kBitrate;
370 transfer_rate.network_estimate.at_time = now;
371 transfer_rate.network_estimate.round_trip_time = TimeDelta::ms(20);
372 transfer_rate.network_estimate.bwe_period = TimeDelta::seconds(3);
373 transfer_rate.network_estimate.bandwidth = kBitrate;
374
375 rtc::CritScope cs(&sink_lock_);
376
377 for (auto* o : target_transfer_rate_observers_) {
378 o->OnTargetTransferRate(transfer_rate);
379 }
380 });
381}
382
383void MediaTransportPair::LoopbackMediaTransport::
384 RemoveTargetTransferRateObserver(TargetTransferRateObserver* observer) {
385 rtc::CritScope cs(&sink_lock_);
Steve Antona59dcc32019-03-25 13:53:07 -0700386 auto it = absl::c_find(target_transfer_rate_observers_, observer);
Niels Möller46879152019-01-07 15:54:47 +0100387 if (it == target_transfer_rate_observers_.end()) {
388 RTC_LOG(LS_WARNING)
389 << "Attempt to remove an unknown TargetTransferRate observer";
390 return;
391 }
392 target_transfer_rate_observers_.erase(it);
393}
394
395void MediaTransportPair::LoopbackMediaTransport::AddRttObserver(
396 MediaTransportRttObserver* observer) {
397 RTC_CHECK(observer);
398 {
399 rtc::CritScope cs(&sink_lock_);
Steve Antona59dcc32019-03-25 13:53:07 -0700400 RTC_CHECK(!absl::c_linear_search(rtt_observers_, observer));
Niels Möller46879152019-01-07 15:54:47 +0100401 rtt_observers_.push_back(observer);
402 }
403 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this] {
404 RTC_DCHECK_RUN_ON(thread_);
405
406 rtc::CritScope cs(&sink_lock_);
407 for (auto* o : rtt_observers_) {
408 o->OnRttUpdated(20);
409 }
410 });
411}
412
413void MediaTransportPair::LoopbackMediaTransport::RemoveRttObserver(
414 MediaTransportRttObserver* observer) {
415 rtc::CritScope cs(&sink_lock_);
Steve Antona59dcc32019-03-25 13:53:07 -0700416 auto it = absl::c_find(rtt_observers_, observer);
Niels Möller46879152019-01-07 15:54:47 +0100417 if (it == rtt_observers_.end()) {
418 RTC_LOG(LS_WARNING) << "Attempt to remove an unknown RTT observer";
419 return;
420 }
421 rtt_observers_.erase(it);
422}
423
Niels Möllere0446cb2018-11-30 09:35:52 +0100424void MediaTransportPair::LoopbackMediaTransport::SetMediaTransportStateCallback(
425 MediaTransportStateCallback* callback) {
426 rtc::CritScope lock(&sink_lock_);
427 state_callback_ = callback;
428 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this] {
429 RTC_DCHECK_RUN_ON(thread_);
430 OnStateChanged();
431 });
432}
433
Bjorn Mellem9ded4852019-02-28 12:27:11 -0800434RTCError MediaTransportPair::LoopbackMediaTransport::OpenChannel(
435 int channel_id) {
436 // No-op. No need to open channels for the loopback.
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700437 return dc_transport_.OpenChannel(channel_id);
438}
439
440RTCError MediaTransportPair::LoopbackDataChannelTransport::OpenChannel(
441 int channel_id) {
442 // No-op. No need to open channels for the loopback.
Bjorn Mellem9ded4852019-02-28 12:27:11 -0800443 return RTCError::OK();
444}
445
Niels Möllere0446cb2018-11-30 09:35:52 +0100446RTCError MediaTransportPair::LoopbackMediaTransport::SendData(
447 int channel_id,
448 const SendDataParams& params,
449 const rtc::CopyOnWriteBuffer& buffer) {
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700450 return dc_transport_.SendData(channel_id, params, buffer);
451}
452
453RTCError MediaTransportPair::LoopbackDataChannelTransport::SendData(
454 int channel_id,
455 const SendDataParams& params,
456 const rtc::CopyOnWriteBuffer& buffer) {
Niels Möllere0446cb2018-11-30 09:35:52 +0100457 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_,
458 [this, channel_id, params, buffer] {
459 other_->OnData(channel_id, params.type, buffer);
460 });
461 return RTCError::OK();
462}
463
464RTCError MediaTransportPair::LoopbackMediaTransport::CloseChannel(
465 int channel_id) {
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700466 return dc_transport_.CloseChannel(channel_id);
467}
468
469RTCError MediaTransportPair::LoopbackDataChannelTransport::CloseChannel(
470 int channel_id) {
Niels Möllere0446cb2018-11-30 09:35:52 +0100471 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, channel_id] {
472 other_->OnRemoteCloseChannel(channel_id);
473 rtc::CritScope lock(&sink_lock_);
474 if (data_sink_) {
475 data_sink_->OnChannelClosed(channel_id);
476 }
477 });
478 return RTCError::OK();
479}
480
481void MediaTransportPair::LoopbackMediaTransport::SetDataSink(
482 DataChannelSink* sink) {
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700483 dc_transport_.SetDataSink(sink);
484}
485
486bool MediaTransportPair::LoopbackMediaTransport::IsReadyToSend() const {
487 return dc_transport_.IsReadyToSend();
488}
489
490void MediaTransportPair::LoopbackDataChannelTransport::SetDataSink(
491 DataChannelSink* sink) {
Niels Möllere0446cb2018-11-30 09:35:52 +0100492 rtc::CritScope lock(&sink_lock_);
493 data_sink_ = sink;
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700494 if (data_sink_ && ready_to_send_) {
495 data_sink_->OnReadyToSend();
496 }
Niels Möllere0446cb2018-11-30 09:35:52 +0100497}
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700498
499bool MediaTransportPair::LoopbackDataChannelTransport::IsReadyToSend() const {
500 rtc::CritScope lock(&sink_lock_);
501 return ready_to_send_;
502}
503
Niels Möllere0446cb2018-11-30 09:35:52 +0100504void MediaTransportPair::LoopbackMediaTransport::SetState(
505 MediaTransportState state) {
506 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, state] {
507 RTC_DCHECK_RUN_ON(thread_);
508 state_ = state;
509 OnStateChanged();
510 });
511}
512
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700513void MediaTransportPair::LoopbackMediaTransport::SetStateAfterConnect(
514 MediaTransportState state) {
515 state_after_connect_ = state;
516}
517
Niels Möllere0446cb2018-11-30 09:35:52 +0100518void MediaTransportPair::LoopbackMediaTransport::FlushAsyncInvokes() {
519 invoker_.Flush(thread_);
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700520 dc_transport_.FlushAsyncInvokes();
521}
522
523void MediaTransportPair::LoopbackDataChannelTransport::FlushAsyncInvokes() {
524 invoker_.Flush(thread_);
Niels Möllere0446cb2018-11-30 09:35:52 +0100525}
526
527MediaTransportPair::Stats
528MediaTransportPair::LoopbackMediaTransport::GetStats() {
529 rtc::CritScope lock(&stats_lock_);
530 return stats_;
531}
532
533void MediaTransportPair::LoopbackMediaTransport::OnData(
534 uint64_t channel_id,
535 MediaTransportEncodedAudioFrame frame) {
536 {
537 rtc::CritScope lock(&sink_lock_);
Sergey Silkine049eba2019-02-18 09:52:26 +0000538 if (audio_sink_) {
Niels Möllere0446cb2018-11-30 09:35:52 +0100539 audio_sink_->OnData(channel_id, frame);
540 }
541 }
542 {
543 rtc::CritScope lock(&stats_lock_);
544 ++stats_.received_audio_frames;
545 }
546}
547
548void MediaTransportPair::LoopbackMediaTransport::OnData(
549 uint64_t channel_id,
550 MediaTransportEncodedVideoFrame frame) {
551 {
552 rtc::CritScope lock(&sink_lock_);
553 if (video_sink_) {
554 video_sink_->OnData(channel_id, frame);
555 }
556 }
557 {
558 rtc::CritScope lock(&stats_lock_);
559 ++stats_.received_video_frames;
560 }
561}
562
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700563void MediaTransportPair::LoopbackDataChannelTransport::OnData(
Niels Möllere0446cb2018-11-30 09:35:52 +0100564 int channel_id,
565 DataMessageType type,
566 const rtc::CopyOnWriteBuffer& buffer) {
567 rtc::CritScope lock(&sink_lock_);
568 if (data_sink_) {
569 data_sink_->OnDataReceived(channel_id, type, buffer);
570 }
571}
572
Niels Möller1c7f5f62018-12-10 11:06:02 +0100573void MediaTransportPair::LoopbackMediaTransport::OnKeyFrameRequested(
574 int channel_id) {
575 rtc::CritScope lock(&sink_lock_);
576 if (key_frame_callback_) {
577 key_frame_callback_->OnKeyFrameRequested(channel_id);
578 }
579}
580
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700581void MediaTransportPair::LoopbackDataChannelTransport::OnRemoteCloseChannel(
Niels Möllere0446cb2018-11-30 09:35:52 +0100582 int channel_id) {
583 rtc::CritScope lock(&sink_lock_);
584 if (data_sink_) {
585 data_sink_->OnChannelClosing(channel_id);
586 data_sink_->OnChannelClosed(channel_id);
587 }
588}
589
590void MediaTransportPair::LoopbackMediaTransport::OnStateChanged() {
591 rtc::CritScope lock(&sink_lock_);
592 if (state_callback_) {
593 state_callback_->OnStateChanged(state_);
594 }
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700595
596 dc_transport_.OnReadyToSend(state_ == MediaTransportState::kWritable);
597}
598
599void MediaTransportPair::LoopbackDataChannelTransport::OnReadyToSend(
600 bool ready_to_send) {
601 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, ready_to_send] {
602 rtc::CritScope lock(&sink_lock_);
603 ready_to_send_ = ready_to_send;
604 // Propagate state to data channel sink, if present.
605 if (data_sink_ && ready_to_send_) {
606 data_sink_->OnReadyToSend();
607 }
608 });
Niels Möllere0446cb2018-11-30 09:35:52 +0100609}
Piotr (Peter) Slatala48c54932019-01-28 06:50:38 -0800610
611void MediaTransportPair::LoopbackMediaTransport::SetAllocatedBitrateLimits(
612 const MediaTransportAllocatedBitrateLimits& limits) {}
613
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700614MediaTransportPair::LoopbackDatagramTransport::LoopbackDatagramTransport(
615 rtc::Thread* thread)
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700616 : thread_(thread), dc_transport_(thread) {}
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700617
618void MediaTransportPair::LoopbackDatagramTransport::Connect(
619 LoopbackDatagramTransport* other) {
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700620 other_ = other;
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700621 dc_transport_.Connect(&other->dc_transport_);
622}
623
624void MediaTransportPair::LoopbackDatagramTransport::Connect(
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700625 rtc::PacketTransportInternal* packet_transport) {
626 if (state_after_connect_) {
627 SetState(*state_after_connect_);
628 }
629}
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700630
631CongestionControlInterface*
632MediaTransportPair::LoopbackDatagramTransport::congestion_control() {
633 return nullptr;
634}
635
636void MediaTransportPair::LoopbackDatagramTransport::SetTransportStateCallback(
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700637 MediaTransportStateCallback* callback) {
638 RTC_DCHECK_RUN_ON(thread_);
639 state_callback_ = callback;
640 if (state_callback_) {
641 state_callback_->OnStateChanged(state_);
642 }
643}
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700644
645RTCError MediaTransportPair::LoopbackDatagramTransport::SendDatagram(
646 rtc::ArrayView<const uint8_t> data,
647 DatagramId datagram_id) {
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700648 rtc::CopyOnWriteBuffer buffer;
649 buffer.SetData(data.data(), data.size());
650 invoker_.AsyncInvoke<void>(
651 RTC_FROM_HERE, thread_, [this, datagram_id, buffer = std::move(buffer)] {
652 RTC_DCHECK_RUN_ON(thread_);
653 other_->DeliverDatagram(std::move(buffer));
654 if (sink_) {
655 DatagramAck ack;
656 ack.datagram_id = datagram_id;
657 ack.receive_timestamp = Timestamp::us(rtc::TimeMicros());
658 sink_->OnDatagramAcked(ack);
659 }
660 });
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700661 return RTCError::OK();
662}
663
664size_t MediaTransportPair::LoopbackDatagramTransport::GetLargestDatagramSize()
665 const {
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700666 return kLoopbackMaxDatagramSize;
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700667}
668
669void MediaTransportPair::LoopbackDatagramTransport::SetDatagramSink(
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700670 DatagramSinkInterface* sink) {
671 RTC_DCHECK_RUN_ON(thread_);
672 sink_ = sink;
673}
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700674
675std::string
676MediaTransportPair::LoopbackDatagramTransport::GetTransportParameters() const {
677 return transport_parameters_;
678}
679
680RTCError MediaTransportPair::LoopbackDatagramTransport::OpenChannel(
681 int channel_id) {
682 return dc_transport_.OpenChannel(channel_id);
683}
684
685RTCError MediaTransportPair::LoopbackDatagramTransport::SendData(
686 int channel_id,
687 const SendDataParams& params,
688 const rtc::CopyOnWriteBuffer& buffer) {
689 return dc_transport_.SendData(channel_id, params, buffer);
690}
691
692RTCError MediaTransportPair::LoopbackDatagramTransport::CloseChannel(
693 int channel_id) {
694 return dc_transport_.CloseChannel(channel_id);
695}
696
697void MediaTransportPair::LoopbackDatagramTransport::SetDataSink(
698 DataChannelSink* sink) {
699 dc_transport_.SetDataSink(sink);
700}
701
702bool MediaTransportPair::LoopbackDatagramTransport::IsReadyToSend() const {
703 return dc_transport_.IsReadyToSend();
704}
705
706void MediaTransportPair::LoopbackDatagramTransport::SetState(
707 MediaTransportState state) {
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700708 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, state] {
709 RTC_DCHECK_RUN_ON(thread_);
710 state_ = state;
711 if (state_callback_) {
712 state_callback_->OnStateChanged(state_);
713 }
714 });
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700715 dc_transport_.OnReadyToSend(state == MediaTransportState::kWritable);
716}
717
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700718void MediaTransportPair::LoopbackDatagramTransport::SetStateAfterConnect(
719 MediaTransportState state) {
720 state_after_connect_ = state;
721}
722
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700723void MediaTransportPair::LoopbackDatagramTransport::FlushAsyncInvokes() {
724 dc_transport_.FlushAsyncInvokes();
725}
726
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700727void MediaTransportPair::LoopbackDatagramTransport::DeliverDatagram(
728 rtc::CopyOnWriteBuffer buffer) {
729 RTC_DCHECK_RUN_ON(thread_);
730 if (sink_) {
731 sink_->OnDatagramReceived(buffer);
732 }
733}
734
Niels Möllere0446cb2018-11-30 09:35:52 +0100735} // namespace webrtc