blob: 9b43da2015694ff9254128fa558ec57595cbf812 [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
13#include "absl/memory/memory.h"
Steve Anton10542f22019-01-11 09:11:00 -080014#include "rtc_base/time_utils.h"
Niels Möllere0446cb2018-11-30 09:35:52 +010015
16namespace webrtc {
17
18namespace {
19
20// Wrapper used to hand out unique_ptrs to loopback media transports without
21// ownership changes.
22class WrapperMediaTransport : public MediaTransportInterface {
23 public:
24 explicit WrapperMediaTransport(MediaTransportInterface* wrapped)
25 : wrapped_(wrapped) {}
26
27 RTCError SendAudioFrame(uint64_t channel_id,
28 MediaTransportEncodedAudioFrame frame) override {
29 return wrapped_->SendAudioFrame(channel_id, std::move(frame));
30 }
31
32 RTCError SendVideoFrame(
33 uint64_t channel_id,
34 const MediaTransportEncodedVideoFrame& frame) override {
35 return wrapped_->SendVideoFrame(channel_id, frame);
36 }
37
Niels Möller1c7f5f62018-12-10 11:06:02 +010038 void SetKeyFrameRequestCallback(
39 MediaTransportKeyFrameRequestCallback* callback) override {
40 wrapped_->SetKeyFrameRequestCallback(callback);
41 }
42
Niels Möllere0446cb2018-11-30 09:35:52 +010043 RTCError RequestKeyFrame(uint64_t channel_id) override {
44 return wrapped_->RequestKeyFrame(channel_id);
45 }
46
47 void SetReceiveAudioSink(MediaTransportAudioSinkInterface* sink) override {
48 wrapped_->SetReceiveAudioSink(sink);
49 }
50
51 void SetReceiveVideoSink(MediaTransportVideoSinkInterface* sink) override {
52 wrapped_->SetReceiveVideoSink(sink);
53 }
54
Niels Möller46879152019-01-07 15:54:47 +010055 void AddTargetTransferRateObserver(
56 TargetTransferRateObserver* observer) override {
57 wrapped_->AddTargetTransferRateObserver(observer);
58 }
59
60 void RemoveTargetTransferRateObserver(
61 TargetTransferRateObserver* observer) override {
62 wrapped_->RemoveTargetTransferRateObserver(observer);
63 }
64
Niels Möllere0446cb2018-11-30 09:35:52 +010065 void SetMediaTransportStateCallback(
66 MediaTransportStateCallback* callback) override {
67 wrapped_->SetMediaTransportStateCallback(callback);
68 }
69
Bjorn Mellem9ded4852019-02-28 12:27:11 -080070 RTCError OpenChannel(int channel_id) override {
71 return wrapped_->OpenChannel(channel_id);
72 }
73
Niels Möllere0446cb2018-11-30 09:35:52 +010074 RTCError SendData(int channel_id,
75 const SendDataParams& params,
76 const rtc::CopyOnWriteBuffer& buffer) override {
77 return wrapped_->SendData(channel_id, params, buffer);
78 }
79
80 RTCError CloseChannel(int channel_id) override {
81 return wrapped_->CloseChannel(channel_id);
82 }
83
84 void SetDataSink(DataChannelSink* sink) override {
85 wrapped_->SetDataSink(sink);
86 }
87
Piotr (Peter) Slatala48c54932019-01-28 06:50:38 -080088 void SetAllocatedBitrateLimits(
89 const MediaTransportAllocatedBitrateLimits& limits) override {}
90
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -080091 absl::optional<std::string> GetTransportParametersOffer() const override {
92 return wrapped_->GetTransportParametersOffer();
93 }
94
Niels Möllere0446cb2018-11-30 09:35:52 +010095 private:
96 MediaTransportInterface* wrapped_;
97};
98
99} // namespace
100
101WrapperMediaTransportFactory::WrapperMediaTransportFactory(
102 MediaTransportInterface* wrapped)
103 : wrapped_(wrapped) {}
104
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800105WrapperMediaTransportFactory::WrapperMediaTransportFactory(
106 MediaTransportFactory* wrapped)
107 : wrapped_factory_(wrapped) {}
108
Niels Möllere0446cb2018-11-30 09:35:52 +0100109RTCErrorOr<std::unique_ptr<MediaTransportInterface>>
110WrapperMediaTransportFactory::CreateMediaTransport(
111 rtc::PacketTransportInternal* packet_transport,
112 rtc::Thread* network_thread,
113 const MediaTransportSettings& settings) {
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800114 created_transport_count_++;
115 if (wrapped_factory_) {
116 return wrapped_factory_->CreateMediaTransport(packet_transport,
117 network_thread, settings);
118 }
Niels Möllere0446cb2018-11-30 09:35:52 +0100119 return {absl::make_unique<WrapperMediaTransport>(wrapped_)};
120}
121
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800122std::string WrapperMediaTransportFactory::GetTransportName() const {
123 if (wrapped_factory_) {
124 return wrapped_factory_->GetTransportName();
125 }
126 return "wrapped-transport";
127}
128
129int WrapperMediaTransportFactory::created_transport_count() const {
130 return created_transport_count_;
131}
132
133RTCErrorOr<std::unique_ptr<MediaTransportInterface>>
134WrapperMediaTransportFactory::CreateMediaTransport(
135 rtc::Thread* network_thread,
136 const MediaTransportSettings& settings) {
137 created_transport_count_++;
138 if (wrapped_factory_) {
139 return wrapped_factory_->CreateMediaTransport(network_thread, settings);
140 }
141 return {absl::make_unique<WrapperMediaTransport>(wrapped_)};
142}
143
144MediaTransportPair::MediaTransportPair(rtc::Thread* thread)
145 : first_(thread, &second_),
146 second_(thread, &first_),
147 first_factory_(&first_),
148 second_factory_(&second_) {}
149
150MediaTransportPair::~MediaTransportPair() = default;
151
Niels Möllere0446cb2018-11-30 09:35:52 +0100152MediaTransportPair::LoopbackMediaTransport::LoopbackMediaTransport(
153 rtc::Thread* thread,
154 LoopbackMediaTransport* other)
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800155 : thread_(thread), other_(other) {
156 RTC_LOG(LS_INFO) << "LoopbackMediaTransport";
157}
Niels Möllere0446cb2018-11-30 09:35:52 +0100158
159MediaTransportPair::LoopbackMediaTransport::~LoopbackMediaTransport() {
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800160 RTC_LOG(LS_INFO) << "~LoopbackMediaTransport";
Niels Möllere0446cb2018-11-30 09:35:52 +0100161 rtc::CritScope lock(&sink_lock_);
162 RTC_CHECK(audio_sink_ == nullptr);
163 RTC_CHECK(video_sink_ == nullptr);
164 RTC_CHECK(data_sink_ == nullptr);
Niels Möller46879152019-01-07 15:54:47 +0100165 RTC_CHECK(target_transfer_rate_observers_.empty());
166 RTC_CHECK(rtt_observers_.empty());
Niels Möllere0446cb2018-11-30 09:35:52 +0100167}
168
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800169absl::optional<std::string>
170MediaTransportPair::LoopbackMediaTransport::GetTransportParametersOffer()
171 const {
172 return "loopback-media-transport-parameters";
173}
174
Niels Möllere0446cb2018-11-30 09:35:52 +0100175RTCError MediaTransportPair::LoopbackMediaTransport::SendAudioFrame(
176 uint64_t channel_id,
177 MediaTransportEncodedAudioFrame frame) {
178 {
179 rtc::CritScope lock(&stats_lock_);
180 ++stats_.sent_audio_frames;
181 }
182 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, channel_id, frame] {
Mirko Bonadei05cf6be2019-01-31 21:38:12 +0100183 other_->OnData(channel_id, frame);
Niels Möllere0446cb2018-11-30 09:35:52 +0100184 });
185 return RTCError::OK();
186}
187
188RTCError MediaTransportPair::LoopbackMediaTransport::SendVideoFrame(
189 uint64_t channel_id,
190 const MediaTransportEncodedVideoFrame& frame) {
191 {
192 rtc::CritScope lock(&stats_lock_);
193 ++stats_.sent_video_frames;
194 }
195 // Ensure that we own the referenced data.
196 MediaTransportEncodedVideoFrame frame_copy = frame;
197 frame_copy.Retain();
198 invoker_.AsyncInvoke<void>(
Mirko Bonadei80a86872019-02-04 15:01:43 +0100199 RTC_FROM_HERE, thread_, [this, channel_id, frame_copy]() mutable {
Niels Möllere0446cb2018-11-30 09:35:52 +0100200 other_->OnData(channel_id, std::move(frame_copy));
201 });
202 return RTCError::OK();
203}
204
Niels Möller1c7f5f62018-12-10 11:06:02 +0100205void MediaTransportPair::LoopbackMediaTransport::SetKeyFrameRequestCallback(
206 MediaTransportKeyFrameRequestCallback* callback) {
207 rtc::CritScope lock(&sink_lock_);
208 if (callback) {
209 RTC_CHECK(key_frame_callback_ == nullptr);
210 }
211 key_frame_callback_ = callback;
212}
213
Niels Möllere0446cb2018-11-30 09:35:52 +0100214RTCError MediaTransportPair::LoopbackMediaTransport::RequestKeyFrame(
215 uint64_t channel_id) {
Niels Möller1c7f5f62018-12-10 11:06:02 +0100216 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, channel_id] {
217 other_->OnKeyFrameRequested(channel_id);
218 });
Niels Möllere0446cb2018-11-30 09:35:52 +0100219 return RTCError::OK();
220}
221
222void MediaTransportPair::LoopbackMediaTransport::SetReceiveAudioSink(
223 MediaTransportAudioSinkInterface* sink) {
224 rtc::CritScope lock(&sink_lock_);
225 if (sink) {
226 RTC_CHECK(audio_sink_ == nullptr);
227 }
228 audio_sink_ = sink;
229}
230
231void MediaTransportPair::LoopbackMediaTransport::SetReceiveVideoSink(
232 MediaTransportVideoSinkInterface* sink) {
233 rtc::CritScope lock(&sink_lock_);
234 if (sink) {
235 RTC_CHECK(video_sink_ == nullptr);
236 }
237 video_sink_ = sink;
238}
239
Niels Möller46879152019-01-07 15:54:47 +0100240void MediaTransportPair::LoopbackMediaTransport::AddTargetTransferRateObserver(
241 TargetTransferRateObserver* observer) {
242 RTC_CHECK(observer);
243 {
244 rtc::CritScope cs(&sink_lock_);
245 RTC_CHECK(std::find(target_transfer_rate_observers_.begin(),
246 target_transfer_rate_observers_.end(),
247 observer) == target_transfer_rate_observers_.end());
248 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_);
274 auto it = std::find(target_transfer_rate_observers_.begin(),
275 target_transfer_rate_observers_.end(), observer);
276 if (it == target_transfer_rate_observers_.end()) {
277 RTC_LOG(LS_WARNING)
278 << "Attempt to remove an unknown TargetTransferRate observer";
279 return;
280 }
281 target_transfer_rate_observers_.erase(it);
282}
283
284void MediaTransportPair::LoopbackMediaTransport::AddRttObserver(
285 MediaTransportRttObserver* observer) {
286 RTC_CHECK(observer);
287 {
288 rtc::CritScope cs(&sink_lock_);
289 RTC_CHECK(std::find(rtt_observers_.begin(), rtt_observers_.end(),
290 observer) == rtt_observers_.end());
291 rtt_observers_.push_back(observer);
292 }
293 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this] {
294 RTC_DCHECK_RUN_ON(thread_);
295
296 rtc::CritScope cs(&sink_lock_);
297 for (auto* o : rtt_observers_) {
298 o->OnRttUpdated(20);
299 }
300 });
301}
302
303void MediaTransportPair::LoopbackMediaTransport::RemoveRttObserver(
304 MediaTransportRttObserver* observer) {
305 rtc::CritScope cs(&sink_lock_);
306 auto it = std::find(rtt_observers_.begin(), rtt_observers_.end(), observer);
307 if (it == rtt_observers_.end()) {
308 RTC_LOG(LS_WARNING) << "Attempt to remove an unknown RTT observer";
309 return;
310 }
311 rtt_observers_.erase(it);
312}
313
Niels Möllere0446cb2018-11-30 09:35:52 +0100314void MediaTransportPair::LoopbackMediaTransport::SetMediaTransportStateCallback(
315 MediaTransportStateCallback* callback) {
316 rtc::CritScope lock(&sink_lock_);
317 state_callback_ = callback;
318 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this] {
319 RTC_DCHECK_RUN_ON(thread_);
320 OnStateChanged();
321 });
322}
323
Bjorn Mellem9ded4852019-02-28 12:27:11 -0800324RTCError MediaTransportPair::LoopbackMediaTransport::OpenChannel(
325 int channel_id) {
326 // No-op. No need to open channels for the loopback.
327 return RTCError::OK();
328}
329
Niels Möllere0446cb2018-11-30 09:35:52 +0100330RTCError MediaTransportPair::LoopbackMediaTransport::SendData(
331 int channel_id,
332 const SendDataParams& params,
333 const rtc::CopyOnWriteBuffer& buffer) {
334 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_,
335 [this, channel_id, params, buffer] {
336 other_->OnData(channel_id, params.type, buffer);
337 });
338 return RTCError::OK();
339}
340
341RTCError MediaTransportPair::LoopbackMediaTransport::CloseChannel(
342 int channel_id) {
343 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, channel_id] {
344 other_->OnRemoteCloseChannel(channel_id);
345 rtc::CritScope lock(&sink_lock_);
346 if (data_sink_) {
347 data_sink_->OnChannelClosed(channel_id);
348 }
349 });
350 return RTCError::OK();
351}
352
353void MediaTransportPair::LoopbackMediaTransport::SetDataSink(
354 DataChannelSink* sink) {
355 rtc::CritScope lock(&sink_lock_);
356 data_sink_ = sink;
357}
358void MediaTransportPair::LoopbackMediaTransport::SetState(
359 MediaTransportState state) {
360 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, state] {
361 RTC_DCHECK_RUN_ON(thread_);
362 state_ = state;
363 OnStateChanged();
364 });
365}
366
367void MediaTransportPair::LoopbackMediaTransport::FlushAsyncInvokes() {
368 invoker_.Flush(thread_);
369}
370
371MediaTransportPair::Stats
372MediaTransportPair::LoopbackMediaTransport::GetStats() {
373 rtc::CritScope lock(&stats_lock_);
374 return stats_;
375}
376
377void MediaTransportPair::LoopbackMediaTransport::OnData(
378 uint64_t channel_id,
379 MediaTransportEncodedAudioFrame frame) {
380 {
381 rtc::CritScope lock(&sink_lock_);
Sergey Silkine049eba2019-02-18 09:52:26 +0000382 if (audio_sink_) {
Niels Möllere0446cb2018-11-30 09:35:52 +0100383 audio_sink_->OnData(channel_id, frame);
384 }
385 }
386 {
387 rtc::CritScope lock(&stats_lock_);
388 ++stats_.received_audio_frames;
389 }
390}
391
392void MediaTransportPair::LoopbackMediaTransport::OnData(
393 uint64_t channel_id,
394 MediaTransportEncodedVideoFrame frame) {
395 {
396 rtc::CritScope lock(&sink_lock_);
397 if (video_sink_) {
398 video_sink_->OnData(channel_id, frame);
399 }
400 }
401 {
402 rtc::CritScope lock(&stats_lock_);
403 ++stats_.received_video_frames;
404 }
405}
406
407void MediaTransportPair::LoopbackMediaTransport::OnData(
408 int channel_id,
409 DataMessageType type,
410 const rtc::CopyOnWriteBuffer& buffer) {
411 rtc::CritScope lock(&sink_lock_);
412 if (data_sink_) {
413 data_sink_->OnDataReceived(channel_id, type, buffer);
414 }
415}
416
Niels Möller1c7f5f62018-12-10 11:06:02 +0100417void MediaTransportPair::LoopbackMediaTransport::OnKeyFrameRequested(
418 int channel_id) {
419 rtc::CritScope lock(&sink_lock_);
420 if (key_frame_callback_) {
421 key_frame_callback_->OnKeyFrameRequested(channel_id);
422 }
423}
424
Niels Möllere0446cb2018-11-30 09:35:52 +0100425void MediaTransportPair::LoopbackMediaTransport::OnRemoteCloseChannel(
426 int channel_id) {
427 rtc::CritScope lock(&sink_lock_);
428 if (data_sink_) {
429 data_sink_->OnChannelClosing(channel_id);
430 data_sink_->OnChannelClosed(channel_id);
431 }
432}
433
434void MediaTransportPair::LoopbackMediaTransport::OnStateChanged() {
435 rtc::CritScope lock(&sink_lock_);
436 if (state_callback_) {
437 state_callback_->OnStateChanged(state_);
438 }
439}
Piotr (Peter) Slatala48c54932019-01-28 06:50:38 -0800440
441void MediaTransportPair::LoopbackMediaTransport::SetAllocatedBitrateLimits(
442 const MediaTransportAllocatedBitrateLimits& limits) {}
443
Niels Möllere0446cb2018-11-30 09:35:52 +0100444} // namespace webrtc