blob: cadcff0e71e914d017455b7887a2d9fa5b3a00ee [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
22// Wrapper used to hand out unique_ptrs to loopback media transports without
23// ownership changes.
24class WrapperMediaTransport : public MediaTransportInterface {
25 public:
26 explicit WrapperMediaTransport(MediaTransportInterface* wrapped)
27 : wrapped_(wrapped) {}
28
29 RTCError SendAudioFrame(uint64_t channel_id,
30 MediaTransportEncodedAudioFrame frame) override {
31 return wrapped_->SendAudioFrame(channel_id, std::move(frame));
32 }
33
34 RTCError SendVideoFrame(
35 uint64_t channel_id,
36 const MediaTransportEncodedVideoFrame& frame) override {
37 return wrapped_->SendVideoFrame(channel_id, frame);
38 }
39
Niels Möller1c7f5f62018-12-10 11:06:02 +010040 void SetKeyFrameRequestCallback(
41 MediaTransportKeyFrameRequestCallback* callback) override {
42 wrapped_->SetKeyFrameRequestCallback(callback);
43 }
44
Niels Möllere0446cb2018-11-30 09:35:52 +010045 RTCError RequestKeyFrame(uint64_t channel_id) override {
46 return wrapped_->RequestKeyFrame(channel_id);
47 }
48
49 void SetReceiveAudioSink(MediaTransportAudioSinkInterface* sink) override {
50 wrapped_->SetReceiveAudioSink(sink);
51 }
52
53 void SetReceiveVideoSink(MediaTransportVideoSinkInterface* sink) override {
54 wrapped_->SetReceiveVideoSink(sink);
55 }
56
Niels Möller46879152019-01-07 15:54:47 +010057 void AddTargetTransferRateObserver(
58 TargetTransferRateObserver* observer) override {
59 wrapped_->AddTargetTransferRateObserver(observer);
60 }
61
62 void RemoveTargetTransferRateObserver(
63 TargetTransferRateObserver* observer) override {
64 wrapped_->RemoveTargetTransferRateObserver(observer);
65 }
66
Niels Möllere0446cb2018-11-30 09:35:52 +010067 void SetMediaTransportStateCallback(
68 MediaTransportStateCallback* callback) override {
69 wrapped_->SetMediaTransportStateCallback(callback);
70 }
71
Bjorn Mellem9ded4852019-02-28 12:27:11 -080072 RTCError OpenChannel(int channel_id) override {
73 return wrapped_->OpenChannel(channel_id);
74 }
75
Niels Möllere0446cb2018-11-30 09:35:52 +010076 RTCError SendData(int channel_id,
77 const SendDataParams& params,
78 const rtc::CopyOnWriteBuffer& buffer) override {
79 return wrapped_->SendData(channel_id, params, buffer);
80 }
81
82 RTCError CloseChannel(int channel_id) override {
83 return wrapped_->CloseChannel(channel_id);
84 }
85
86 void SetDataSink(DataChannelSink* sink) override {
87 wrapped_->SetDataSink(sink);
88 }
89
Bjorn A Mellemb689af42019-08-21 10:44:59 -070090 bool IsReadyToSend() const override { return wrapped_->IsReadyToSend(); }
91
Piotr (Peter) Slatala48c54932019-01-28 06:50:38 -080092 void SetAllocatedBitrateLimits(
93 const MediaTransportAllocatedBitrateLimits& limits) override {}
94
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -080095 absl::optional<std::string> GetTransportParametersOffer() const override {
96 return wrapped_->GetTransportParametersOffer();
97 }
98
Niels Möllere0446cb2018-11-30 09:35:52 +010099 private:
100 MediaTransportInterface* wrapped_;
101};
102
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700103class WrapperDatagramTransport : public DatagramTransportInterface {
104 public:
105 explicit WrapperDatagramTransport(DatagramTransportInterface* wrapped)
106 : wrapped_(wrapped) {}
107
108 // Datagram transport overrides.
109 void Connect(rtc::PacketTransportInternal* packet_transport) override {
110 return wrapped_->Connect(packet_transport);
111 }
112
113 CongestionControlInterface* congestion_control() override {
114 return wrapped_->congestion_control();
115 }
116
117 void SetTransportStateCallback(
118 MediaTransportStateCallback* callback) override {
119 return wrapped_->SetTransportStateCallback(callback);
120 }
121
122 RTCError SendDatagram(rtc::ArrayView<const uint8_t> data,
123 DatagramId datagram_id) override {
124 return wrapped_->SendDatagram(data, datagram_id);
125 }
126
127 size_t GetLargestDatagramSize() const override {
128 return wrapped_->GetLargestDatagramSize();
129 }
130
131 void SetDatagramSink(DatagramSinkInterface* sink) override {
132 return wrapped_->SetDatagramSink(sink);
133 }
134
135 std::string GetTransportParameters() const override {
136 return wrapped_->GetTransportParameters();
137 }
138
139 // Data channel overrides.
140 RTCError OpenChannel(int channel_id) override {
141 return wrapped_->OpenChannel(channel_id);
142 }
143
144 RTCError SendData(int channel_id,
145 const SendDataParams& params,
146 const rtc::CopyOnWriteBuffer& buffer) override {
147 return wrapped_->SendData(channel_id, params, buffer);
148 }
149
150 RTCError CloseChannel(int channel_id) override {
151 return wrapped_->CloseChannel(channel_id);
152 }
153
154 void SetDataSink(DataChannelSink* sink) override {
155 wrapped_->SetDataSink(sink);
156 }
157
158 bool IsReadyToSend() const override { return wrapped_->IsReadyToSend(); }
159
160 private:
161 DatagramTransportInterface* wrapped_;
162};
163
Niels Möllere0446cb2018-11-30 09:35:52 +0100164} // namespace
165
166WrapperMediaTransportFactory::WrapperMediaTransportFactory(
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700167 MediaTransportInterface* wrapped_media_transport,
168 DatagramTransportInterface* wrapped_datagram_transport)
169 : wrapped_media_transport_(wrapped_media_transport),
170 wrapped_datagram_transport_(wrapped_datagram_transport) {}
Niels Möllere0446cb2018-11-30 09:35:52 +0100171
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800172WrapperMediaTransportFactory::WrapperMediaTransportFactory(
173 MediaTransportFactory* wrapped)
174 : wrapped_factory_(wrapped) {}
175
Niels Möllere0446cb2018-11-30 09:35:52 +0100176RTCErrorOr<std::unique_ptr<MediaTransportInterface>>
177WrapperMediaTransportFactory::CreateMediaTransport(
178 rtc::PacketTransportInternal* packet_transport,
179 rtc::Thread* network_thread,
180 const MediaTransportSettings& settings) {
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800181 created_transport_count_++;
182 if (wrapped_factory_) {
183 return wrapped_factory_->CreateMediaTransport(packet_transport,
184 network_thread, settings);
185 }
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200186 return {std::make_unique<WrapperMediaTransport>(wrapped_media_transport_)};
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700187}
188
189RTCErrorOr<std::unique_ptr<DatagramTransportInterface>>
190WrapperMediaTransportFactory::CreateDatagramTransport(
191 rtc::Thread* network_thread,
192 const MediaTransportSettings& settings) {
193 created_transport_count_++;
194 if (wrapped_factory_) {
195 return wrapped_factory_->CreateDatagramTransport(network_thread, settings);
196 }
197 return {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200198 std::make_unique<WrapperDatagramTransport>(wrapped_datagram_transport_)};
Niels Möllere0446cb2018-11-30 09:35:52 +0100199}
200
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800201std::string WrapperMediaTransportFactory::GetTransportName() const {
202 if (wrapped_factory_) {
203 return wrapped_factory_->GetTransportName();
204 }
205 return "wrapped-transport";
206}
207
208int WrapperMediaTransportFactory::created_transport_count() const {
209 return created_transport_count_;
210}
211
212RTCErrorOr<std::unique_ptr<MediaTransportInterface>>
213WrapperMediaTransportFactory::CreateMediaTransport(
214 rtc::Thread* network_thread,
215 const MediaTransportSettings& settings) {
216 created_transport_count_++;
217 if (wrapped_factory_) {
218 return wrapped_factory_->CreateMediaTransport(network_thread, settings);
219 }
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200220 return {std::make_unique<WrapperMediaTransport>(wrapped_media_transport_)};
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800221}
222
223MediaTransportPair::MediaTransportPair(rtc::Thread* thread)
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700224 : first_(thread),
225 second_(thread),
226 first_datagram_transport_(thread),
227 second_datagram_transport_(thread),
228 first_factory_(&first_, &first_datagram_transport_),
229 second_factory_(&second_, &second_datagram_transport_) {
230 first_.Connect(&second_);
231 second_.Connect(&first_);
232 first_datagram_transport_.Connect(&second_datagram_transport_);
233 second_datagram_transport_.Connect(&first_datagram_transport_);
234}
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800235
236MediaTransportPair::~MediaTransportPair() = default;
237
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700238MediaTransportPair::LoopbackDataChannelTransport::LoopbackDataChannelTransport(
239 rtc::Thread* thread)
240 : thread_(thread) {}
241
242MediaTransportPair::LoopbackDataChannelTransport::
243 ~LoopbackDataChannelTransport() {
244 RTC_CHECK(data_sink_ == nullptr);
245}
246
247void MediaTransportPair::LoopbackDataChannelTransport::Connect(
248 LoopbackDataChannelTransport* other) {
249 other_ = other;
250}
251
Niels Möllere0446cb2018-11-30 09:35:52 +0100252MediaTransportPair::LoopbackMediaTransport::LoopbackMediaTransport(
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700253 rtc::Thread* thread)
254 : dc_transport_(thread), thread_(thread), other_(nullptr) {
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800255 RTC_LOG(LS_INFO) << "LoopbackMediaTransport";
256}
Niels Möllere0446cb2018-11-30 09:35:52 +0100257
258MediaTransportPair::LoopbackMediaTransport::~LoopbackMediaTransport() {
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800259 RTC_LOG(LS_INFO) << "~LoopbackMediaTransport";
Niels Möllere0446cb2018-11-30 09:35:52 +0100260 rtc::CritScope lock(&sink_lock_);
261 RTC_CHECK(audio_sink_ == nullptr);
262 RTC_CHECK(video_sink_ == nullptr);
Niels Möller46879152019-01-07 15:54:47 +0100263 RTC_CHECK(target_transfer_rate_observers_.empty());
264 RTC_CHECK(rtt_observers_.empty());
Niels Möllere0446cb2018-11-30 09:35:52 +0100265}
266
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700267void MediaTransportPair::LoopbackMediaTransport::Connect(
268 LoopbackMediaTransport* other) {
269 other_ = other;
270 dc_transport_.Connect(&other->dc_transport_);
271}
272
273void MediaTransportPair::LoopbackMediaTransport::Connect(
274 rtc::PacketTransportInternal* packet_transport) {}
275
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800276absl::optional<std::string>
277MediaTransportPair::LoopbackMediaTransport::GetTransportParametersOffer()
278 const {
279 return "loopback-media-transport-parameters";
280}
281
Niels Möllere0446cb2018-11-30 09:35:52 +0100282RTCError MediaTransportPair::LoopbackMediaTransport::SendAudioFrame(
283 uint64_t channel_id,
284 MediaTransportEncodedAudioFrame frame) {
285 {
286 rtc::CritScope lock(&stats_lock_);
287 ++stats_.sent_audio_frames;
288 }
289 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, channel_id, frame] {
Mirko Bonadei05cf6be2019-01-31 21:38:12 +0100290 other_->OnData(channel_id, frame);
Niels Möllere0446cb2018-11-30 09:35:52 +0100291 });
292 return RTCError::OK();
293}
294
295RTCError MediaTransportPair::LoopbackMediaTransport::SendVideoFrame(
296 uint64_t channel_id,
297 const MediaTransportEncodedVideoFrame& frame) {
298 {
299 rtc::CritScope lock(&stats_lock_);
300 ++stats_.sent_video_frames;
301 }
302 // Ensure that we own the referenced data.
303 MediaTransportEncodedVideoFrame frame_copy = frame;
304 frame_copy.Retain();
305 invoker_.AsyncInvoke<void>(
Mirko Bonadei80a86872019-02-04 15:01:43 +0100306 RTC_FROM_HERE, thread_, [this, channel_id, frame_copy]() mutable {
Niels Möllere0446cb2018-11-30 09:35:52 +0100307 other_->OnData(channel_id, std::move(frame_copy));
308 });
309 return RTCError::OK();
310}
311
Niels Möller1c7f5f62018-12-10 11:06:02 +0100312void MediaTransportPair::LoopbackMediaTransport::SetKeyFrameRequestCallback(
313 MediaTransportKeyFrameRequestCallback* callback) {
314 rtc::CritScope lock(&sink_lock_);
315 if (callback) {
316 RTC_CHECK(key_frame_callback_ == nullptr);
317 }
318 key_frame_callback_ = callback;
319}
320
Niels Möllere0446cb2018-11-30 09:35:52 +0100321RTCError MediaTransportPair::LoopbackMediaTransport::RequestKeyFrame(
322 uint64_t channel_id) {
Niels Möller1c7f5f62018-12-10 11:06:02 +0100323 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, channel_id] {
324 other_->OnKeyFrameRequested(channel_id);
325 });
Niels Möllere0446cb2018-11-30 09:35:52 +0100326 return RTCError::OK();
327}
328
329void MediaTransportPair::LoopbackMediaTransport::SetReceiveAudioSink(
330 MediaTransportAudioSinkInterface* sink) {
331 rtc::CritScope lock(&sink_lock_);
332 if (sink) {
333 RTC_CHECK(audio_sink_ == nullptr);
334 }
335 audio_sink_ = sink;
336}
337
338void MediaTransportPair::LoopbackMediaTransport::SetReceiveVideoSink(
339 MediaTransportVideoSinkInterface* sink) {
340 rtc::CritScope lock(&sink_lock_);
341 if (sink) {
342 RTC_CHECK(video_sink_ == nullptr);
343 }
344 video_sink_ = sink;
345}
346
Niels Möller46879152019-01-07 15:54:47 +0100347void MediaTransportPair::LoopbackMediaTransport::AddTargetTransferRateObserver(
348 TargetTransferRateObserver* observer) {
349 RTC_CHECK(observer);
350 {
351 rtc::CritScope cs(&sink_lock_);
Steve Antona59dcc32019-03-25 13:53:07 -0700352 RTC_CHECK(
353 !absl::c_linear_search(target_transfer_rate_observers_, observer));
Niels Möller46879152019-01-07 15:54:47 +0100354 target_transfer_rate_observers_.push_back(observer);
355 }
356 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this] {
357 RTC_DCHECK_RUN_ON(thread_);
358 const DataRate kBitrate = DataRate::kbps(300);
359 const Timestamp now = Timestamp::us(rtc::TimeMicros());
360
361 TargetTransferRate transfer_rate;
362 transfer_rate.at_time = now;
363 transfer_rate.target_rate = kBitrate;
364 transfer_rate.network_estimate.at_time = now;
365 transfer_rate.network_estimate.round_trip_time = TimeDelta::ms(20);
366 transfer_rate.network_estimate.bwe_period = TimeDelta::seconds(3);
367 transfer_rate.network_estimate.bandwidth = kBitrate;
368
369 rtc::CritScope cs(&sink_lock_);
370
371 for (auto* o : target_transfer_rate_observers_) {
372 o->OnTargetTransferRate(transfer_rate);
373 }
374 });
375}
376
377void MediaTransportPair::LoopbackMediaTransport::
378 RemoveTargetTransferRateObserver(TargetTransferRateObserver* observer) {
379 rtc::CritScope cs(&sink_lock_);
Steve Antona59dcc32019-03-25 13:53:07 -0700380 auto it = absl::c_find(target_transfer_rate_observers_, observer);
Niels Möller46879152019-01-07 15:54:47 +0100381 if (it == target_transfer_rate_observers_.end()) {
382 RTC_LOG(LS_WARNING)
383 << "Attempt to remove an unknown TargetTransferRate observer";
384 return;
385 }
386 target_transfer_rate_observers_.erase(it);
387}
388
389void MediaTransportPair::LoopbackMediaTransport::AddRttObserver(
390 MediaTransportRttObserver* observer) {
391 RTC_CHECK(observer);
392 {
393 rtc::CritScope cs(&sink_lock_);
Steve Antona59dcc32019-03-25 13:53:07 -0700394 RTC_CHECK(!absl::c_linear_search(rtt_observers_, observer));
Niels Möller46879152019-01-07 15:54:47 +0100395 rtt_observers_.push_back(observer);
396 }
397 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this] {
398 RTC_DCHECK_RUN_ON(thread_);
399
400 rtc::CritScope cs(&sink_lock_);
401 for (auto* o : rtt_observers_) {
402 o->OnRttUpdated(20);
403 }
404 });
405}
406
407void MediaTransportPair::LoopbackMediaTransport::RemoveRttObserver(
408 MediaTransportRttObserver* observer) {
409 rtc::CritScope cs(&sink_lock_);
Steve Antona59dcc32019-03-25 13:53:07 -0700410 auto it = absl::c_find(rtt_observers_, observer);
Niels Möller46879152019-01-07 15:54:47 +0100411 if (it == rtt_observers_.end()) {
412 RTC_LOG(LS_WARNING) << "Attempt to remove an unknown RTT observer";
413 return;
414 }
415 rtt_observers_.erase(it);
416}
417
Niels Möllere0446cb2018-11-30 09:35:52 +0100418void MediaTransportPair::LoopbackMediaTransport::SetMediaTransportStateCallback(
419 MediaTransportStateCallback* callback) {
420 rtc::CritScope lock(&sink_lock_);
421 state_callback_ = callback;
422 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this] {
423 RTC_DCHECK_RUN_ON(thread_);
424 OnStateChanged();
425 });
426}
427
Bjorn Mellem9ded4852019-02-28 12:27:11 -0800428RTCError MediaTransportPair::LoopbackMediaTransport::OpenChannel(
429 int channel_id) {
430 // No-op. No need to open channels for the loopback.
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700431 return dc_transport_.OpenChannel(channel_id);
432}
433
434RTCError MediaTransportPair::LoopbackDataChannelTransport::OpenChannel(
435 int channel_id) {
436 // No-op. No need to open channels for the loopback.
Bjorn Mellem9ded4852019-02-28 12:27:11 -0800437 return RTCError::OK();
438}
439
Niels Möllere0446cb2018-11-30 09:35:52 +0100440RTCError MediaTransportPair::LoopbackMediaTransport::SendData(
441 int channel_id,
442 const SendDataParams& params,
443 const rtc::CopyOnWriteBuffer& buffer) {
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700444 return dc_transport_.SendData(channel_id, params, buffer);
445}
446
447RTCError MediaTransportPair::LoopbackDataChannelTransport::SendData(
448 int channel_id,
449 const SendDataParams& params,
450 const rtc::CopyOnWriteBuffer& buffer) {
Niels Möllere0446cb2018-11-30 09:35:52 +0100451 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_,
452 [this, channel_id, params, buffer] {
453 other_->OnData(channel_id, params.type, buffer);
454 });
455 return RTCError::OK();
456}
457
458RTCError MediaTransportPair::LoopbackMediaTransport::CloseChannel(
459 int channel_id) {
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700460 return dc_transport_.CloseChannel(channel_id);
461}
462
463RTCError MediaTransportPair::LoopbackDataChannelTransport::CloseChannel(
464 int channel_id) {
Niels Möllere0446cb2018-11-30 09:35:52 +0100465 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, channel_id] {
466 other_->OnRemoteCloseChannel(channel_id);
467 rtc::CritScope lock(&sink_lock_);
468 if (data_sink_) {
469 data_sink_->OnChannelClosed(channel_id);
470 }
471 });
472 return RTCError::OK();
473}
474
475void MediaTransportPair::LoopbackMediaTransport::SetDataSink(
476 DataChannelSink* sink) {
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700477 dc_transport_.SetDataSink(sink);
478}
479
480bool MediaTransportPair::LoopbackMediaTransport::IsReadyToSend() const {
481 return dc_transport_.IsReadyToSend();
482}
483
484void MediaTransportPair::LoopbackDataChannelTransport::SetDataSink(
485 DataChannelSink* sink) {
Niels Möllere0446cb2018-11-30 09:35:52 +0100486 rtc::CritScope lock(&sink_lock_);
487 data_sink_ = sink;
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700488 if (data_sink_ && ready_to_send_) {
489 data_sink_->OnReadyToSend();
490 }
Niels Möllere0446cb2018-11-30 09:35:52 +0100491}
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700492
493bool MediaTransportPair::LoopbackDataChannelTransport::IsReadyToSend() const {
494 rtc::CritScope lock(&sink_lock_);
495 return ready_to_send_;
496}
497
Niels Möllere0446cb2018-11-30 09:35:52 +0100498void MediaTransportPair::LoopbackMediaTransport::SetState(
499 MediaTransportState state) {
500 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, state] {
501 RTC_DCHECK_RUN_ON(thread_);
502 state_ = state;
503 OnStateChanged();
504 });
505}
506
507void MediaTransportPair::LoopbackMediaTransport::FlushAsyncInvokes() {
508 invoker_.Flush(thread_);
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700509 dc_transport_.FlushAsyncInvokes();
510}
511
512void MediaTransportPair::LoopbackDataChannelTransport::FlushAsyncInvokes() {
513 invoker_.Flush(thread_);
Niels Möllere0446cb2018-11-30 09:35:52 +0100514}
515
516MediaTransportPair::Stats
517MediaTransportPair::LoopbackMediaTransport::GetStats() {
518 rtc::CritScope lock(&stats_lock_);
519 return stats_;
520}
521
522void MediaTransportPair::LoopbackMediaTransport::OnData(
523 uint64_t channel_id,
524 MediaTransportEncodedAudioFrame frame) {
525 {
526 rtc::CritScope lock(&sink_lock_);
Sergey Silkine049eba2019-02-18 09:52:26 +0000527 if (audio_sink_) {
Niels Möllere0446cb2018-11-30 09:35:52 +0100528 audio_sink_->OnData(channel_id, frame);
529 }
530 }
531 {
532 rtc::CritScope lock(&stats_lock_);
533 ++stats_.received_audio_frames;
534 }
535}
536
537void MediaTransportPair::LoopbackMediaTransport::OnData(
538 uint64_t channel_id,
539 MediaTransportEncodedVideoFrame frame) {
540 {
541 rtc::CritScope lock(&sink_lock_);
542 if (video_sink_) {
543 video_sink_->OnData(channel_id, frame);
544 }
545 }
546 {
547 rtc::CritScope lock(&stats_lock_);
548 ++stats_.received_video_frames;
549 }
550}
551
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700552void MediaTransportPair::LoopbackDataChannelTransport::OnData(
Niels Möllere0446cb2018-11-30 09:35:52 +0100553 int channel_id,
554 DataMessageType type,
555 const rtc::CopyOnWriteBuffer& buffer) {
556 rtc::CritScope lock(&sink_lock_);
557 if (data_sink_) {
558 data_sink_->OnDataReceived(channel_id, type, buffer);
559 }
560}
561
Niels Möller1c7f5f62018-12-10 11:06:02 +0100562void MediaTransportPair::LoopbackMediaTransport::OnKeyFrameRequested(
563 int channel_id) {
564 rtc::CritScope lock(&sink_lock_);
565 if (key_frame_callback_) {
566 key_frame_callback_->OnKeyFrameRequested(channel_id);
567 }
568}
569
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700570void MediaTransportPair::LoopbackDataChannelTransport::OnRemoteCloseChannel(
Niels Möllere0446cb2018-11-30 09:35:52 +0100571 int channel_id) {
572 rtc::CritScope lock(&sink_lock_);
573 if (data_sink_) {
574 data_sink_->OnChannelClosing(channel_id);
575 data_sink_->OnChannelClosed(channel_id);
576 }
577}
578
579void MediaTransportPair::LoopbackMediaTransport::OnStateChanged() {
580 rtc::CritScope lock(&sink_lock_);
581 if (state_callback_) {
582 state_callback_->OnStateChanged(state_);
583 }
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700584
585 dc_transport_.OnReadyToSend(state_ == MediaTransportState::kWritable);
586}
587
588void MediaTransportPair::LoopbackDataChannelTransport::OnReadyToSend(
589 bool ready_to_send) {
590 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, ready_to_send] {
591 rtc::CritScope lock(&sink_lock_);
592 ready_to_send_ = ready_to_send;
593 // Propagate state to data channel sink, if present.
594 if (data_sink_ && ready_to_send_) {
595 data_sink_->OnReadyToSend();
596 }
597 });
Niels Möllere0446cb2018-11-30 09:35:52 +0100598}
Piotr (Peter) Slatala48c54932019-01-28 06:50:38 -0800599
600void MediaTransportPair::LoopbackMediaTransport::SetAllocatedBitrateLimits(
601 const MediaTransportAllocatedBitrateLimits& limits) {}
602
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700603MediaTransportPair::LoopbackDatagramTransport::LoopbackDatagramTransport(
604 rtc::Thread* thread)
605 : dc_transport_(thread) {}
606
607void MediaTransportPair::LoopbackDatagramTransport::Connect(
608 LoopbackDatagramTransport* other) {
609 dc_transport_.Connect(&other->dc_transport_);
610}
611
612void MediaTransportPair::LoopbackDatagramTransport::Connect(
613 rtc::PacketTransportInternal* packet_transport) {}
614
615CongestionControlInterface*
616MediaTransportPair::LoopbackDatagramTransport::congestion_control() {
617 return nullptr;
618}
619
620void MediaTransportPair::LoopbackDatagramTransport::SetTransportStateCallback(
621 MediaTransportStateCallback* callback) {}
622
623RTCError MediaTransportPair::LoopbackDatagramTransport::SendDatagram(
624 rtc::ArrayView<const uint8_t> data,
625 DatagramId datagram_id) {
626 return RTCError::OK();
627}
628
629size_t MediaTransportPair::LoopbackDatagramTransport::GetLargestDatagramSize()
630 const {
631 return 0;
632}
633
634void MediaTransportPair::LoopbackDatagramTransport::SetDatagramSink(
635 DatagramSinkInterface* sink) {}
636
637std::string
638MediaTransportPair::LoopbackDatagramTransport::GetTransportParameters() const {
639 return transport_parameters_;
640}
641
642RTCError MediaTransportPair::LoopbackDatagramTransport::OpenChannel(
643 int channel_id) {
644 return dc_transport_.OpenChannel(channel_id);
645}
646
647RTCError MediaTransportPair::LoopbackDatagramTransport::SendData(
648 int channel_id,
649 const SendDataParams& params,
650 const rtc::CopyOnWriteBuffer& buffer) {
651 return dc_transport_.SendData(channel_id, params, buffer);
652}
653
654RTCError MediaTransportPair::LoopbackDatagramTransport::CloseChannel(
655 int channel_id) {
656 return dc_transport_.CloseChannel(channel_id);
657}
658
659void MediaTransportPair::LoopbackDatagramTransport::SetDataSink(
660 DataChannelSink* sink) {
661 dc_transport_.SetDataSink(sink);
662}
663
664bool MediaTransportPair::LoopbackDatagramTransport::IsReadyToSend() const {
665 return dc_transport_.IsReadyToSend();
666}
667
668void MediaTransportPair::LoopbackDatagramTransport::SetState(
669 MediaTransportState state) {
670 dc_transport_.OnReadyToSend(state == MediaTransportState::kWritable);
671}
672
673void MediaTransportPair::LoopbackDatagramTransport::FlushAsyncInvokes() {
674 dc_transport_.FlushAsyncInvokes();
675}
676
Niels Möllere0446cb2018-11-30 09:35:52 +0100677} // namespace webrtc