blob: 475c58665d2ac3c84f0553713c4be834b428348c [file] [log] [blame]
Niels Möller2e47f7c2018-10-16 10:41:42 +02001/*
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#ifndef API_TEST_LOOPBACK_MEDIA_TRANSPORT_H_
12#define API_TEST_LOOPBACK_MEDIA_TRANSPORT_H_
13
Bjorn Mellem175aa2e2018-11-08 11:23:22 -080014#include <memory>
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -080015#include <string>
Niels Möller2e47f7c2018-10-16 10:41:42 +020016#include <utility>
Niels Möller46879152019-01-07 15:54:47 +010017#include <vector>
Niels Möller2e47f7c2018-10-16 10:41:42 +020018
Niels Möller65f17ca2019-09-12 13:59:36 +020019#include "api/transport/datagram_transport_interface.h"
20#include "api/transport/media/media_transport_interface.h"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "rtc_base/async_invoker.h"
22#include "rtc_base/critical_section.h"
Bjorn Mellem273d0292018-11-01 16:42:44 -070023#include "rtc_base/thread.h"
Bjorn Mellem175aa2e2018-11-08 11:23:22 -080024#include "rtc_base/thread_checker.h"
Niels Möller2e47f7c2018-10-16 10:41:42 +020025
26namespace webrtc {
27
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -080028// Wrapper used to hand out unique_ptrs to loopback media
29// transport without ownership changes to the underlying
30// transport.
31// It works in two modes:
32// It can either wrap a factory, or it can wrap an existing interface.
33// In the former mode, it delegates the work to the wrapped factory.
34// In the latter mode, it always returns static instance of the transport
35// interface.
36//
37// Example use:
38// Factory wrap_static_interface = Wrapper(media_transport_interface);
39// Factory wrap_factory = Wrapper(wrap_static_interface);
40// The second factory may be created multiple times, and ownership may be passed
41// to the client. The first factory counts the number of invocations of
42// CreateMediaTransport();
Bjorn Mellem175aa2e2018-11-08 11:23:22 -080043class WrapperMediaTransportFactory : public MediaTransportFactory {
44 public:
Bjorn A Mellemb689af42019-08-21 10:44:59 -070045 WrapperMediaTransportFactory(
46 MediaTransportInterface* wrapped_media_transport,
47 DatagramTransportInterface* wrapped_datagram_transport);
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -080048 explicit WrapperMediaTransportFactory(MediaTransportFactory* wrapped);
Bjorn Mellem175aa2e2018-11-08 11:23:22 -080049
50 RTCErrorOr<std::unique_ptr<MediaTransportInterface>> CreateMediaTransport(
51 rtc::PacketTransportInternal* packet_transport,
52 rtc::Thread* network_thread,
Niels Möllere0446cb2018-11-30 09:35:52 +010053 const MediaTransportSettings& settings) override;
Bjorn Mellem175aa2e2018-11-08 11:23:22 -080054
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -080055 RTCErrorOr<std::unique_ptr<MediaTransportInterface>> CreateMediaTransport(
56 rtc::Thread* network_thread,
57 const MediaTransportSettings& settings) override;
58
Bjorn A Mellemb689af42019-08-21 10:44:59 -070059 RTCErrorOr<std::unique_ptr<DatagramTransportInterface>>
60 CreateDatagramTransport(rtc::Thread* network_thread,
61 const MediaTransportSettings& settings) override;
62
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -080063 std::string GetTransportName() const override;
64
65 int created_transport_count() const;
66
Bjorn Mellem175aa2e2018-11-08 11:23:22 -080067 private:
Bjorn A Mellemb689af42019-08-21 10:44:59 -070068 MediaTransportInterface* wrapped_media_transport_ = nullptr;
69 DatagramTransportInterface* wrapped_datagram_transport_ = nullptr;
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -080070 MediaTransportFactory* wrapped_factory_ = nullptr;
71 int created_transport_count_ = 0;
Bjorn Mellem175aa2e2018-11-08 11:23:22 -080072};
73
Niels Möller2e47f7c2018-10-16 10:41:42 +020074// Contains two MediaTransportsInterfaces that are connected to each other.
75// Currently supports audio only.
76class MediaTransportPair {
77 public:
Niels Möllerc68d2822018-11-20 14:52:05 +010078 struct Stats {
79 int sent_audio_frames = 0;
80 int received_audio_frames = 0;
Niels Möllerd5696fb2018-11-28 15:34:37 +010081 int sent_video_frames = 0;
82 int received_video_frames = 0;
Niels Möllerc68d2822018-11-20 14:52:05 +010083 };
84
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -080085 explicit MediaTransportPair(rtc::Thread* thread);
86 ~MediaTransportPair();
Niels Möller2e47f7c2018-10-16 10:41:42 +020087
88 // Ownership stays with MediaTransportPair
Bjorn Mellem273d0292018-11-01 16:42:44 -070089 MediaTransportInterface* first() { return &first_; }
90 MediaTransportInterface* second() { return &second_; }
91
Bjorn A Mellemb689af42019-08-21 10:44:59 -070092 DatagramTransportInterface* first_datagram_transport() {
93 return &first_datagram_transport_;
94 }
95 DatagramTransportInterface* second_datagram_transport() {
96 return &second_datagram_transport_;
97 }
98
Bjorn Mellem175aa2e2018-11-08 11:23:22 -080099 std::unique_ptr<MediaTransportFactory> first_factory() {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200100 return std::make_unique<WrapperMediaTransportFactory>(&first_factory_);
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800101 }
102
103 std::unique_ptr<MediaTransportFactory> second_factory() {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200104 return std::make_unique<WrapperMediaTransportFactory>(&second_factory_);
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800105 }
106
107 void SetState(MediaTransportState state) {
108 first_.SetState(state);
109 second_.SetState(state);
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700110 first_datagram_transport_.SetState(state);
111 second_datagram_transport_.SetState(state);
112 }
113
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700114 void SetFirstState(MediaTransportState state) {
115 first_.SetState(state);
116 first_datagram_transport_.SetState(state);
117 }
118
119 void SetSecondStateAfterConnect(MediaTransportState state) {
120 second_.SetState(state);
121 second_datagram_transport_.SetState(state);
122 }
123
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700124 void SetFirstDatagramTransportParameters(const std::string& params) {
125 first_datagram_transport_.set_transport_parameters(params);
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800126 }
127
Bjorn Mellem273d0292018-11-01 16:42:44 -0700128 void FlushAsyncInvokes() {
129 first_.FlushAsyncInvokes();
130 second_.FlushAsyncInvokes();
131 }
Niels Möller2e47f7c2018-10-16 10:41:42 +0200132
Niels Möllerc68d2822018-11-20 14:52:05 +0100133 Stats FirstStats() { return first_.GetStats(); }
134 Stats SecondStats() { return second_.GetStats(); }
135
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800136 int first_factory_transport_count() const {
137 return first_factory_.created_transport_count();
138 }
139
140 int second_factory_transport_count() const {
141 return second_factory_.created_transport_count();
142 }
143
Niels Möller2e47f7c2018-10-16 10:41:42 +0200144 private:
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700145 class LoopbackDataChannelTransport : public DataChannelTransportInterface {
146 public:
147 explicit LoopbackDataChannelTransport(rtc::Thread* thread);
148 ~LoopbackDataChannelTransport() override;
149
150 void Connect(LoopbackDataChannelTransport* other);
151
152 RTCError OpenChannel(int channel_id) override;
153
154 RTCError SendData(int channel_id,
155 const SendDataParams& params,
156 const rtc::CopyOnWriteBuffer& buffer) override;
157
158 RTCError CloseChannel(int channel_id) override;
159
160 bool IsReadyToSend() const override;
161
162 void SetDataSink(DataChannelSink* sink) override;
163
164 void OnReadyToSend(bool ready_to_send);
165
166 void FlushAsyncInvokes();
167
168 private:
169 void OnData(int channel_id,
170 DataMessageType type,
171 const rtc::CopyOnWriteBuffer& buffer);
172
173 void OnRemoteCloseChannel(int channel_id);
174
175 rtc::Thread* const thread_;
176 rtc::CriticalSection sink_lock_;
177 DataChannelSink* data_sink_ RTC_GUARDED_BY(sink_lock_) = nullptr;
178
179 bool ready_to_send_ RTC_GUARDED_BY(sink_lock_) = false;
180
181 LoopbackDataChannelTransport* other_;
182
183 rtc::AsyncInvoker invoker_;
184 };
185
Niels Möller2e47f7c2018-10-16 10:41:42 +0200186 class LoopbackMediaTransport : public MediaTransportInterface {
187 public:
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700188 explicit LoopbackMediaTransport(rtc::Thread* thread);
Bjorn Mellem273d0292018-11-01 16:42:44 -0700189
Niels Möllere0446cb2018-11-30 09:35:52 +0100190 ~LoopbackMediaTransport() override;
Niels Möller2e47f7c2018-10-16 10:41:42 +0200191
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700192 // Connects this loopback transport to another loopback transport.
193 void Connect(LoopbackMediaTransport* other);
194
195 void Connect(rtc::PacketTransportInternal* transport) override;
196
Niels Möller2e47f7c2018-10-16 10:41:42 +0200197 RTCError SendAudioFrame(uint64_t channel_id,
Niels Möllere0446cb2018-11-30 09:35:52 +0100198 MediaTransportEncodedAudioFrame frame) override;
Niels Möller2e47f7c2018-10-16 10:41:42 +0200199
200 RTCError SendVideoFrame(
201 uint64_t channel_id,
Niels Möllere0446cb2018-11-30 09:35:52 +0100202 const MediaTransportEncodedVideoFrame& frame) override;
Niels Möller2e47f7c2018-10-16 10:41:42 +0200203
Niels Möller1c7f5f62018-12-10 11:06:02 +0100204 void SetKeyFrameRequestCallback(
205 MediaTransportKeyFrameRequestCallback* callback) override;
206
Niels Möllere0446cb2018-11-30 09:35:52 +0100207 RTCError RequestKeyFrame(uint64_t channel_id) override;
Niels Möller2e47f7c2018-10-16 10:41:42 +0200208
Niels Möllere0446cb2018-11-30 09:35:52 +0100209 void SetReceiveAudioSink(MediaTransportAudioSinkInterface* sink) override;
Niels Möller2e47f7c2018-10-16 10:41:42 +0200210
Niels Möllere0446cb2018-11-30 09:35:52 +0100211 void SetReceiveVideoSink(MediaTransportVideoSinkInterface* sink) override;
Niels Möller2e47f7c2018-10-16 10:41:42 +0200212
Niels Möller46879152019-01-07 15:54:47 +0100213 void AddTargetTransferRateObserver(
214 TargetTransferRateObserver* observer) override;
215
216 void RemoveTargetTransferRateObserver(
217 TargetTransferRateObserver* observer) override;
218
219 void AddRttObserver(MediaTransportRttObserver* observer) override;
220 void RemoveRttObserver(MediaTransportRttObserver* observer) override;
221
Bjorn Mellemeb2c6412018-10-31 15:25:32 -0700222 void SetMediaTransportStateCallback(
Niels Möllere0446cb2018-11-30 09:35:52 +0100223 MediaTransportStateCallback* callback) override;
Bjorn Mellemeb2c6412018-10-31 15:25:32 -0700224
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700225 void SetState(MediaTransportState state);
226
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700227 // When Connect() is called, the media transport will enter this state.
228 // This is useful for mimicking zero-RTT connectivity, for example.
229 void SetStateAfterConnect(MediaTransportState state);
230
Bjorn Mellem9ded4852019-02-28 12:27:11 -0800231 RTCError OpenChannel(int channel_id) override;
232
Bjorn Mellemeb2c6412018-10-31 15:25:32 -0700233 RTCError SendData(int channel_id,
234 const SendDataParams& params,
Niels Möllere0446cb2018-11-30 09:35:52 +0100235 const rtc::CopyOnWriteBuffer& buffer) override;
Bjorn Mellemeb2c6412018-10-31 15:25:32 -0700236
Niels Möllere0446cb2018-11-30 09:35:52 +0100237 RTCError CloseChannel(int channel_id) override;
Bjorn Mellemeb2c6412018-10-31 15:25:32 -0700238
Niels Möllere0446cb2018-11-30 09:35:52 +0100239 void SetDataSink(DataChannelSink* sink) override;
Bjorn Mellem273d0292018-11-01 16:42:44 -0700240
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700241 bool IsReadyToSend() const override;
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800242
Niels Möllere0446cb2018-11-30 09:35:52 +0100243 void FlushAsyncInvokes();
Bjorn Mellemeb2c6412018-10-31 15:25:32 -0700244
Niels Möllere0446cb2018-11-30 09:35:52 +0100245 Stats GetStats();
Niels Möllerc68d2822018-11-20 14:52:05 +0100246
Piotr (Peter) Slatala48c54932019-01-28 06:50:38 -0800247 void SetAllocatedBitrateLimits(
248 const MediaTransportAllocatedBitrateLimits& limits) override;
249
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800250 absl::optional<std::string> GetTransportParametersOffer() const override;
251
Niels Möller2e47f7c2018-10-16 10:41:42 +0200252 private:
Niels Möllere0446cb2018-11-30 09:35:52 +0100253 void OnData(uint64_t channel_id, MediaTransportEncodedAudioFrame frame);
Niels Möller2e47f7c2018-10-16 10:41:42 +0200254
Niels Möllere0446cb2018-11-30 09:35:52 +0100255 void OnData(uint64_t channel_id, MediaTransportEncodedVideoFrame frame);
Niels Möllerd5696fb2018-11-28 15:34:37 +0100256
Niels Möller1c7f5f62018-12-10 11:06:02 +0100257 void OnKeyFrameRequested(int channel_id);
258
Niels Möllere0446cb2018-11-30 09:35:52 +0100259 void OnStateChanged() RTC_RUN_ON(thread_);
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800260
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700261 // Implementation of the data channel transport.
262 LoopbackDataChannelTransport dc_transport_;
263
Bjorn Mellem273d0292018-11-01 16:42:44 -0700264 rtc::Thread* const thread_;
265 rtc::CriticalSection sink_lock_;
Niels Möllerc68d2822018-11-20 14:52:05 +0100266 rtc::CriticalSection stats_lock_;
Bjorn Mellem273d0292018-11-01 16:42:44 -0700267
Niels Möllerd5696fb2018-11-28 15:34:37 +0100268 MediaTransportAudioSinkInterface* audio_sink_ RTC_GUARDED_BY(sink_lock_) =
269 nullptr;
270 MediaTransportVideoSinkInterface* video_sink_ RTC_GUARDED_BY(sink_lock_) =
Bjorn Mellem273d0292018-11-01 16:42:44 -0700271 nullptr;
Niels Möller1c7f5f62018-12-10 11:06:02 +0100272
273 MediaTransportKeyFrameRequestCallback* key_frame_callback_
274 RTC_GUARDED_BY(sink_lock_) = nullptr;
275
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800276 MediaTransportStateCallback* state_callback_ RTC_GUARDED_BY(sink_lock_) =
277 nullptr;
278
Niels Möller46879152019-01-07 15:54:47 +0100279 std::vector<TargetTransferRateObserver*> target_transfer_rate_observers_
280 RTC_GUARDED_BY(sink_lock_);
281 std::vector<MediaTransportRttObserver*> rtt_observers_
282 RTC_GUARDED_BY(sink_lock_);
283
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800284 MediaTransportState state_ RTC_GUARDED_BY(thread_) =
285 MediaTransportState::kPending;
286
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700287 absl::optional<MediaTransportState> state_after_connect_;
288
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700289 LoopbackMediaTransport* other_;
Bjorn Mellem273d0292018-11-01 16:42:44 -0700290
Niels Möllerc68d2822018-11-20 14:52:05 +0100291 Stats stats_ RTC_GUARDED_BY(stats_lock_);
292
Bjorn Mellem273d0292018-11-01 16:42:44 -0700293 rtc::AsyncInvoker invoker_;
Niels Möller2e47f7c2018-10-16 10:41:42 +0200294 };
295
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700296 class LoopbackDatagramTransport : public DatagramTransportInterface {
297 public:
298 explicit LoopbackDatagramTransport(rtc::Thread* thread);
299
300 void Connect(LoopbackDatagramTransport* other);
301
302 // Datagram transport overrides.
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700303 void Connect(rtc::PacketTransportInternal* packet_transport) override;
304 CongestionControlInterface* congestion_control() override;
305 void SetTransportStateCallback(
306 MediaTransportStateCallback* callback) override;
307 RTCError SendDatagram(rtc::ArrayView<const uint8_t> data,
308 DatagramId datagram_id) override;
309 size_t GetLargestDatagramSize() const override;
310 void SetDatagramSink(DatagramSinkInterface* sink) override;
311 std::string GetTransportParameters() const override;
312
313 // Data channel overrides.
314 RTCError OpenChannel(int channel_id) override;
315 RTCError SendData(int channel_id,
316 const SendDataParams& params,
317 const rtc::CopyOnWriteBuffer& buffer) override;
318 RTCError CloseChannel(int channel_id) override;
319 void SetDataSink(DataChannelSink* sink) override;
320 bool IsReadyToSend() const override;
321
322 // Loopback-specific functionality.
323 void SetState(MediaTransportState state);
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700324
325 // When Connect() is called, the datagram transport will enter this state.
326 // This is useful for mimicking zero-RTT connectivity, for example.
327 void SetStateAfterConnect(MediaTransportState state);
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700328 void FlushAsyncInvokes();
329
330 void set_transport_parameters(const std::string& value) {
331 transport_parameters_ = value;
332 }
333
334 private:
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700335 void DeliverDatagram(rtc::CopyOnWriteBuffer buffer);
336
337 rtc::Thread* thread_;
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700338 LoopbackDataChannelTransport dc_transport_;
339
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700340 MediaTransportState state_ RTC_GUARDED_BY(thread_) =
341 MediaTransportState::kPending;
342 DatagramSinkInterface* sink_ RTC_GUARDED_BY(thread_) = nullptr;
343 MediaTransportStateCallback* state_callback_ RTC_GUARDED_BY(thread_) =
344 nullptr;
345 LoopbackDatagramTransport* other_;
346
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700347 std::string transport_parameters_;
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700348
349 absl::optional<MediaTransportState> state_after_connect_;
Bjorn A Mellem8e1343a2019-09-30 15:12:47 -0700350
351 rtc::AsyncInvoker invoker_;
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700352 };
353
Bjorn Mellem273d0292018-11-01 16:42:44 -0700354 LoopbackMediaTransport first_;
355 LoopbackMediaTransport second_;
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700356 LoopbackDatagramTransport first_datagram_transport_;
357 LoopbackDatagramTransport second_datagram_transport_;
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800358 WrapperMediaTransportFactory first_factory_;
359 WrapperMediaTransportFactory second_factory_;
Niels Möller2e47f7c2018-10-16 10:41:42 +0200360};
361
362} // namespace webrtc
363
364#endif // API_TEST_LOOPBACK_MEDIA_TRANSPORT_H_