blob: 4e8fb0e099f0d4134359e421fcd0578f86845bad [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
Steve Antona59dcc32019-03-25 13:53:07 -070013#include "absl/algorithm/container.h"
Niels Möllere0446cb2018-11-30 09:35:52 +010014#include "absl/memory/memory.h"
Steve Anton10542f22019-01-11 09:11:00 -080015#include "rtc_base/time_utils.h"
Niels Möllere0446cb2018-11-30 09:35:52 +010016
17namespace webrtc {
18
19namespace {
20
21// Wrapper used to hand out unique_ptrs to loopback media transports without
22// ownership changes.
23class WrapperMediaTransport : public MediaTransportInterface {
24 public:
25 explicit WrapperMediaTransport(MediaTransportInterface* wrapped)
26 : wrapped_(wrapped) {}
27
28 RTCError SendAudioFrame(uint64_t channel_id,
29 MediaTransportEncodedAudioFrame frame) override {
30 return wrapped_->SendAudioFrame(channel_id, std::move(frame));
31 }
32
33 RTCError SendVideoFrame(
34 uint64_t channel_id,
35 const MediaTransportEncodedVideoFrame& frame) override {
36 return wrapped_->SendVideoFrame(channel_id, frame);
37 }
38
Niels Möller1c7f5f62018-12-10 11:06:02 +010039 void SetKeyFrameRequestCallback(
40 MediaTransportKeyFrameRequestCallback* callback) override {
41 wrapped_->SetKeyFrameRequestCallback(callback);
42 }
43
Niels Möllere0446cb2018-11-30 09:35:52 +010044 RTCError RequestKeyFrame(uint64_t channel_id) override {
45 return wrapped_->RequestKeyFrame(channel_id);
46 }
47
48 void SetReceiveAudioSink(MediaTransportAudioSinkInterface* sink) override {
49 wrapped_->SetReceiveAudioSink(sink);
50 }
51
52 void SetReceiveVideoSink(MediaTransportVideoSinkInterface* sink) override {
53 wrapped_->SetReceiveVideoSink(sink);
54 }
55
Niels Möller46879152019-01-07 15:54:47 +010056 void AddTargetTransferRateObserver(
57 TargetTransferRateObserver* observer) override {
58 wrapped_->AddTargetTransferRateObserver(observer);
59 }
60
61 void RemoveTargetTransferRateObserver(
62 TargetTransferRateObserver* observer) override {
63 wrapped_->RemoveTargetTransferRateObserver(observer);
64 }
65
Niels Möllere0446cb2018-11-30 09:35:52 +010066 void SetMediaTransportStateCallback(
67 MediaTransportStateCallback* callback) override {
68 wrapped_->SetMediaTransportStateCallback(callback);
69 }
70
Bjorn Mellem9ded4852019-02-28 12:27:11 -080071 RTCError OpenChannel(int channel_id) override {
72 return wrapped_->OpenChannel(channel_id);
73 }
74
Niels Möllere0446cb2018-11-30 09:35:52 +010075 RTCError SendData(int channel_id,
76 const SendDataParams& params,
77 const rtc::CopyOnWriteBuffer& buffer) override {
78 return wrapped_->SendData(channel_id, params, buffer);
79 }
80
81 RTCError CloseChannel(int channel_id) override {
82 return wrapped_->CloseChannel(channel_id);
83 }
84
85 void SetDataSink(DataChannelSink* sink) override {
86 wrapped_->SetDataSink(sink);
87 }
88
Piotr (Peter) Slatala48c54932019-01-28 06:50:38 -080089 void SetAllocatedBitrateLimits(
90 const MediaTransportAllocatedBitrateLimits& limits) override {}
91
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -080092 absl::optional<std::string> GetTransportParametersOffer() const override {
93 return wrapped_->GetTransportParametersOffer();
94 }
95
Niels Möllere0446cb2018-11-30 09:35:52 +010096 private:
97 MediaTransportInterface* wrapped_;
98};
99
100} // namespace
101
102WrapperMediaTransportFactory::WrapperMediaTransportFactory(
103 MediaTransportInterface* wrapped)
104 : wrapped_(wrapped) {}
105
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800106WrapperMediaTransportFactory::WrapperMediaTransportFactory(
107 MediaTransportFactory* wrapped)
108 : wrapped_factory_(wrapped) {}
109
Niels Möllere0446cb2018-11-30 09:35:52 +0100110RTCErrorOr<std::unique_ptr<MediaTransportInterface>>
111WrapperMediaTransportFactory::CreateMediaTransport(
112 rtc::PacketTransportInternal* packet_transport,
113 rtc::Thread* network_thread,
114 const MediaTransportSettings& settings) {
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800115 created_transport_count_++;
116 if (wrapped_factory_) {
117 return wrapped_factory_->CreateMediaTransport(packet_transport,
118 network_thread, settings);
119 }
Niels Möllere0446cb2018-11-30 09:35:52 +0100120 return {absl::make_unique<WrapperMediaTransport>(wrapped_)};
121}
122
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800123std::string WrapperMediaTransportFactory::GetTransportName() const {
124 if (wrapped_factory_) {
125 return wrapped_factory_->GetTransportName();
126 }
127 return "wrapped-transport";
128}
129
130int WrapperMediaTransportFactory::created_transport_count() const {
131 return created_transport_count_;
132}
133
134RTCErrorOr<std::unique_ptr<MediaTransportInterface>>
135WrapperMediaTransportFactory::CreateMediaTransport(
136 rtc::Thread* network_thread,
137 const MediaTransportSettings& settings) {
138 created_transport_count_++;
139 if (wrapped_factory_) {
140 return wrapped_factory_->CreateMediaTransport(network_thread, settings);
141 }
142 return {absl::make_unique<WrapperMediaTransport>(wrapped_)};
143}
144
145MediaTransportPair::MediaTransportPair(rtc::Thread* thread)
146 : first_(thread, &second_),
147 second_(thread, &first_),
148 first_factory_(&first_),
149 second_factory_(&second_) {}
150
151MediaTransportPair::~MediaTransportPair() = default;
152
Niels Möllere0446cb2018-11-30 09:35:52 +0100153MediaTransportPair::LoopbackMediaTransport::LoopbackMediaTransport(
154 rtc::Thread* thread,
155 LoopbackMediaTransport* other)
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800156 : thread_(thread), other_(other) {
157 RTC_LOG(LS_INFO) << "LoopbackMediaTransport";
158}
Niels Möllere0446cb2018-11-30 09:35:52 +0100159
160MediaTransportPair::LoopbackMediaTransport::~LoopbackMediaTransport() {
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800161 RTC_LOG(LS_INFO) << "~LoopbackMediaTransport";
Niels Möllere0446cb2018-11-30 09:35:52 +0100162 rtc::CritScope lock(&sink_lock_);
163 RTC_CHECK(audio_sink_ == nullptr);
164 RTC_CHECK(video_sink_ == nullptr);
165 RTC_CHECK(data_sink_ == nullptr);
Niels Möller46879152019-01-07 15:54:47 +0100166 RTC_CHECK(target_transfer_rate_observers_.empty());
167 RTC_CHECK(rtt_observers_.empty());
Niels Möllere0446cb2018-11-30 09:35:52 +0100168}
169
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800170absl::optional<std::string>
171MediaTransportPair::LoopbackMediaTransport::GetTransportParametersOffer()
172 const {
173 return "loopback-media-transport-parameters";
174}
175
Niels Möllere0446cb2018-11-30 09:35:52 +0100176RTCError MediaTransportPair::LoopbackMediaTransport::SendAudioFrame(
177 uint64_t channel_id,
178 MediaTransportEncodedAudioFrame frame) {
179 {
180 rtc::CritScope lock(&stats_lock_);
181 ++stats_.sent_audio_frames;
182 }
183 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, channel_id, frame] {
Mirko Bonadei05cf6be2019-01-31 21:38:12 +0100184 other_->OnData(channel_id, frame);
Niels Möllere0446cb2018-11-30 09:35:52 +0100185 });
186 return RTCError::OK();
187}
188
189RTCError MediaTransportPair::LoopbackMediaTransport::SendVideoFrame(
190 uint64_t channel_id,
191 const MediaTransportEncodedVideoFrame& frame) {
192 {
193 rtc::CritScope lock(&stats_lock_);
194 ++stats_.sent_video_frames;
195 }
196 // Ensure that we own the referenced data.
197 MediaTransportEncodedVideoFrame frame_copy = frame;
198 frame_copy.Retain();
199 invoker_.AsyncInvoke<void>(
Mirko Bonadei80a86872019-02-04 15:01:43 +0100200 RTC_FROM_HERE, thread_, [this, channel_id, frame_copy]() mutable {
Niels Möllere0446cb2018-11-30 09:35:52 +0100201 other_->OnData(channel_id, std::move(frame_copy));
202 });
203 return RTCError::OK();
204}
205
Niels Möller1c7f5f62018-12-10 11:06:02 +0100206void MediaTransportPair::LoopbackMediaTransport::SetKeyFrameRequestCallback(
207 MediaTransportKeyFrameRequestCallback* callback) {
208 rtc::CritScope lock(&sink_lock_);
209 if (callback) {
210 RTC_CHECK(key_frame_callback_ == nullptr);
211 }
212 key_frame_callback_ = callback;
213}
214
Niels Möllere0446cb2018-11-30 09:35:52 +0100215RTCError MediaTransportPair::LoopbackMediaTransport::RequestKeyFrame(
216 uint64_t channel_id) {
Niels Möller1c7f5f62018-12-10 11:06:02 +0100217 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, channel_id] {
218 other_->OnKeyFrameRequested(channel_id);
219 });
Niels Möllere0446cb2018-11-30 09:35:52 +0100220 return RTCError::OK();
221}
222
223void MediaTransportPair::LoopbackMediaTransport::SetReceiveAudioSink(
224 MediaTransportAudioSinkInterface* sink) {
225 rtc::CritScope lock(&sink_lock_);
226 if (sink) {
227 RTC_CHECK(audio_sink_ == nullptr);
228 }
229 audio_sink_ = sink;
230}
231
232void MediaTransportPair::LoopbackMediaTransport::SetReceiveVideoSink(
233 MediaTransportVideoSinkInterface* sink) {
234 rtc::CritScope lock(&sink_lock_);
235 if (sink) {
236 RTC_CHECK(video_sink_ == nullptr);
237 }
238 video_sink_ = sink;
239}
240
Niels Möller46879152019-01-07 15:54:47 +0100241void MediaTransportPair::LoopbackMediaTransport::AddTargetTransferRateObserver(
242 TargetTransferRateObserver* observer) {
243 RTC_CHECK(observer);
244 {
245 rtc::CritScope cs(&sink_lock_);
Steve Antona59dcc32019-03-25 13:53:07 -0700246 RTC_CHECK(
247 !absl::c_linear_search(target_transfer_rate_observers_, observer));
Niels Möller46879152019-01-07 15:54:47 +0100248 target_transfer_rate_observers_.push_back(observer);
249 }
250 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this] {
251 RTC_DCHECK_RUN_ON(thread_);
252 const DataRate kBitrate = DataRate::kbps(300);
253 const Timestamp now = Timestamp::us(rtc::TimeMicros());
254
255 TargetTransferRate transfer_rate;
256 transfer_rate.at_time = now;
257 transfer_rate.target_rate = kBitrate;
258 transfer_rate.network_estimate.at_time = now;
259 transfer_rate.network_estimate.round_trip_time = TimeDelta::ms(20);
260 transfer_rate.network_estimate.bwe_period = TimeDelta::seconds(3);
261 transfer_rate.network_estimate.bandwidth = kBitrate;
262
263 rtc::CritScope cs(&sink_lock_);
264
265 for (auto* o : target_transfer_rate_observers_) {
266 o->OnTargetTransferRate(transfer_rate);
267 }
268 });
269}
270
271void MediaTransportPair::LoopbackMediaTransport::
272 RemoveTargetTransferRateObserver(TargetTransferRateObserver* observer) {
273 rtc::CritScope cs(&sink_lock_);
Steve Antona59dcc32019-03-25 13:53:07 -0700274 auto it = absl::c_find(target_transfer_rate_observers_, observer);
Niels Möller46879152019-01-07 15:54:47 +0100275 if (it == target_transfer_rate_observers_.end()) {
276 RTC_LOG(LS_WARNING)
277 << "Attempt to remove an unknown TargetTransferRate observer";
278 return;
279 }
280 target_transfer_rate_observers_.erase(it);
281}
282
283void MediaTransportPair::LoopbackMediaTransport::AddRttObserver(
284 MediaTransportRttObserver* observer) {
285 RTC_CHECK(observer);
286 {
287 rtc::CritScope cs(&sink_lock_);
Steve Antona59dcc32019-03-25 13:53:07 -0700288 RTC_CHECK(!absl::c_linear_search(rtt_observers_, observer));
Niels Möller46879152019-01-07 15:54:47 +0100289 rtt_observers_.push_back(observer);
290 }
291 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this] {
292 RTC_DCHECK_RUN_ON(thread_);
293
294 rtc::CritScope cs(&sink_lock_);
295 for (auto* o : rtt_observers_) {
296 o->OnRttUpdated(20);
297 }
298 });
299}
300
301void MediaTransportPair::LoopbackMediaTransport::RemoveRttObserver(
302 MediaTransportRttObserver* observer) {
303 rtc::CritScope cs(&sink_lock_);
Steve Antona59dcc32019-03-25 13:53:07 -0700304 auto it = absl::c_find(rtt_observers_, observer);
Niels Möller46879152019-01-07 15:54:47 +0100305 if (it == rtt_observers_.end()) {
306 RTC_LOG(LS_WARNING) << "Attempt to remove an unknown RTT observer";
307 return;
308 }
309 rtt_observers_.erase(it);
310}
311
Niels Möllere0446cb2018-11-30 09:35:52 +0100312void MediaTransportPair::LoopbackMediaTransport::SetMediaTransportStateCallback(
313 MediaTransportStateCallback* callback) {
314 rtc::CritScope lock(&sink_lock_);
315 state_callback_ = callback;
316 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this] {
317 RTC_DCHECK_RUN_ON(thread_);
318 OnStateChanged();
319 });
320}
321
Bjorn Mellem9ded4852019-02-28 12:27:11 -0800322RTCError MediaTransportPair::LoopbackMediaTransport::OpenChannel(
323 int channel_id) {
324 // No-op. No need to open channels for the loopback.
325 return RTCError::OK();
326}
327
Niels Möllere0446cb2018-11-30 09:35:52 +0100328RTCError MediaTransportPair::LoopbackMediaTransport::SendData(
329 int channel_id,
330 const SendDataParams& params,
331 const rtc::CopyOnWriteBuffer& buffer) {
332 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_,
333 [this, channel_id, params, buffer] {
334 other_->OnData(channel_id, params.type, buffer);
335 });
336 return RTCError::OK();
337}
338
339RTCError MediaTransportPair::LoopbackMediaTransport::CloseChannel(
340 int channel_id) {
341 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, channel_id] {
342 other_->OnRemoteCloseChannel(channel_id);
343 rtc::CritScope lock(&sink_lock_);
344 if (data_sink_) {
345 data_sink_->OnChannelClosed(channel_id);
346 }
347 });
348 return RTCError::OK();
349}
350
351void MediaTransportPair::LoopbackMediaTransport::SetDataSink(
352 DataChannelSink* sink) {
353 rtc::CritScope lock(&sink_lock_);
354 data_sink_ = sink;
355}
356void MediaTransportPair::LoopbackMediaTransport::SetState(
357 MediaTransportState state) {
358 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, state] {
359 RTC_DCHECK_RUN_ON(thread_);
360 state_ = state;
361 OnStateChanged();
362 });
363}
364
365void MediaTransportPair::LoopbackMediaTransport::FlushAsyncInvokes() {
366 invoker_.Flush(thread_);
367}
368
369MediaTransportPair::Stats
370MediaTransportPair::LoopbackMediaTransport::GetStats() {
371 rtc::CritScope lock(&stats_lock_);
372 return stats_;
373}
374
375void MediaTransportPair::LoopbackMediaTransport::OnData(
376 uint64_t channel_id,
377 MediaTransportEncodedAudioFrame frame) {
378 {
379 rtc::CritScope lock(&sink_lock_);
Sergey Silkine049eba2019-02-18 09:52:26 +0000380 if (audio_sink_) {
Niels Möllere0446cb2018-11-30 09:35:52 +0100381 audio_sink_->OnData(channel_id, frame);
382 }
383 }
384 {
385 rtc::CritScope lock(&stats_lock_);
386 ++stats_.received_audio_frames;
387 }
388}
389
390void MediaTransportPair::LoopbackMediaTransport::OnData(
391 uint64_t channel_id,
392 MediaTransportEncodedVideoFrame frame) {
393 {
394 rtc::CritScope lock(&sink_lock_);
395 if (video_sink_) {
396 video_sink_->OnData(channel_id, frame);
397 }
398 }
399 {
400 rtc::CritScope lock(&stats_lock_);
401 ++stats_.received_video_frames;
402 }
403}
404
405void MediaTransportPair::LoopbackMediaTransport::OnData(
406 int channel_id,
407 DataMessageType type,
408 const rtc::CopyOnWriteBuffer& buffer) {
409 rtc::CritScope lock(&sink_lock_);
410 if (data_sink_) {
411 data_sink_->OnDataReceived(channel_id, type, buffer);
412 }
413}
414
Niels Möller1c7f5f62018-12-10 11:06:02 +0100415void MediaTransportPair::LoopbackMediaTransport::OnKeyFrameRequested(
416 int channel_id) {
417 rtc::CritScope lock(&sink_lock_);
418 if (key_frame_callback_) {
419 key_frame_callback_->OnKeyFrameRequested(channel_id);
420 }
421}
422
Niels Möllere0446cb2018-11-30 09:35:52 +0100423void MediaTransportPair::LoopbackMediaTransport::OnRemoteCloseChannel(
424 int channel_id) {
425 rtc::CritScope lock(&sink_lock_);
426 if (data_sink_) {
427 data_sink_->OnChannelClosing(channel_id);
428 data_sink_->OnChannelClosed(channel_id);
429 }
430}
431
432void MediaTransportPair::LoopbackMediaTransport::OnStateChanged() {
433 rtc::CritScope lock(&sink_lock_);
434 if (state_callback_) {
435 state_callback_->OnStateChanged(state_);
436 }
437}
Piotr (Peter) Slatala48c54932019-01-28 06:50:38 -0800438
439void MediaTransportPair::LoopbackMediaTransport::SetAllocatedBitrateLimits(
440 const MediaTransportAllocatedBitrateLimits& limits) {}
441
Niels Möllere0446cb2018-11-30 09:35:52 +0100442} // namespace webrtc