blob: e00cc23b6e457b48a15c193d4bb589dc55040cbd [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
Steve Anton40d55332019-01-07 10:21:47 -080019#include "absl/memory/memory.h"
Niels Möller65f17ca2019-09-12 13:59:36 +020020#include "api/transport/datagram_transport_interface.h"
21#include "api/transport/media/media_transport_interface.h"
Steve Anton10542f22019-01-11 09:11:00 -080022#include "rtc_base/async_invoker.h"
23#include "rtc_base/critical_section.h"
Bjorn Mellem273d0292018-11-01 16:42:44 -070024#include "rtc_base/thread.h"
Bjorn Mellem175aa2e2018-11-08 11:23:22 -080025#include "rtc_base/thread_checker.h"
Niels Möller2e47f7c2018-10-16 10:41:42 +020026
27namespace webrtc {
28
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -080029// Wrapper used to hand out unique_ptrs to loopback media
30// transport without ownership changes to the underlying
31// transport.
32// It works in two modes:
33// It can either wrap a factory, or it can wrap an existing interface.
34// In the former mode, it delegates the work to the wrapped factory.
35// In the latter mode, it always returns static instance of the transport
36// interface.
37//
38// Example use:
39// Factory wrap_static_interface = Wrapper(media_transport_interface);
40// Factory wrap_factory = Wrapper(wrap_static_interface);
41// The second factory may be created multiple times, and ownership may be passed
42// to the client. The first factory counts the number of invocations of
43// CreateMediaTransport();
Bjorn Mellem175aa2e2018-11-08 11:23:22 -080044class WrapperMediaTransportFactory : public MediaTransportFactory {
45 public:
Bjorn A Mellemb689af42019-08-21 10:44:59 -070046 WrapperMediaTransportFactory(
47 MediaTransportInterface* wrapped_media_transport,
48 DatagramTransportInterface* wrapped_datagram_transport);
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -080049 explicit WrapperMediaTransportFactory(MediaTransportFactory* wrapped);
Bjorn Mellem175aa2e2018-11-08 11:23:22 -080050
51 RTCErrorOr<std::unique_ptr<MediaTransportInterface>> CreateMediaTransport(
52 rtc::PacketTransportInternal* packet_transport,
53 rtc::Thread* network_thread,
Niels Möllere0446cb2018-11-30 09:35:52 +010054 const MediaTransportSettings& settings) override;
Bjorn Mellem175aa2e2018-11-08 11:23:22 -080055
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -080056 RTCErrorOr<std::unique_ptr<MediaTransportInterface>> CreateMediaTransport(
57 rtc::Thread* network_thread,
58 const MediaTransportSettings& settings) override;
59
Bjorn A Mellemb689af42019-08-21 10:44:59 -070060 RTCErrorOr<std::unique_ptr<DatagramTransportInterface>>
61 CreateDatagramTransport(rtc::Thread* network_thread,
62 const MediaTransportSettings& settings) override;
63
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -080064 std::string GetTransportName() const override;
65
66 int created_transport_count() const;
67
Bjorn Mellem175aa2e2018-11-08 11:23:22 -080068 private:
Bjorn A Mellemb689af42019-08-21 10:44:59 -070069 MediaTransportInterface* wrapped_media_transport_ = nullptr;
70 DatagramTransportInterface* wrapped_datagram_transport_ = nullptr;
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -080071 MediaTransportFactory* wrapped_factory_ = nullptr;
72 int created_transport_count_ = 0;
Bjorn Mellem175aa2e2018-11-08 11:23:22 -080073};
74
Niels Möller2e47f7c2018-10-16 10:41:42 +020075// Contains two MediaTransportsInterfaces that are connected to each other.
76// Currently supports audio only.
77class MediaTransportPair {
78 public:
Niels Möllerc68d2822018-11-20 14:52:05 +010079 struct Stats {
80 int sent_audio_frames = 0;
81 int received_audio_frames = 0;
Niels Möllerd5696fb2018-11-28 15:34:37 +010082 int sent_video_frames = 0;
83 int received_video_frames = 0;
Niels Möllerc68d2822018-11-20 14:52:05 +010084 };
85
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -080086 explicit MediaTransportPair(rtc::Thread* thread);
87 ~MediaTransportPair();
Niels Möller2e47f7c2018-10-16 10:41:42 +020088
89 // Ownership stays with MediaTransportPair
Bjorn Mellem273d0292018-11-01 16:42:44 -070090 MediaTransportInterface* first() { return &first_; }
91 MediaTransportInterface* second() { return &second_; }
92
Bjorn A Mellemb689af42019-08-21 10:44:59 -070093 DatagramTransportInterface* first_datagram_transport() {
94 return &first_datagram_transport_;
95 }
96 DatagramTransportInterface* second_datagram_transport() {
97 return &second_datagram_transport_;
98 }
99
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800100 std::unique_ptr<MediaTransportFactory> first_factory() {
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800101 return absl::make_unique<WrapperMediaTransportFactory>(&first_factory_);
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800102 }
103
104 std::unique_ptr<MediaTransportFactory> second_factory() {
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800105 return absl::make_unique<WrapperMediaTransportFactory>(&second_factory_);
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800106 }
107
108 void SetState(MediaTransportState state) {
109 first_.SetState(state);
110 second_.SetState(state);
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700111 first_datagram_transport_.SetState(state);
112 second_datagram_transport_.SetState(state);
113 }
114
115 void SetFirstDatagramTransportParameters(const std::string& params) {
116 first_datagram_transport_.set_transport_parameters(params);
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800117 }
118
Bjorn Mellem273d0292018-11-01 16:42:44 -0700119 void FlushAsyncInvokes() {
120 first_.FlushAsyncInvokes();
121 second_.FlushAsyncInvokes();
122 }
Niels Möller2e47f7c2018-10-16 10:41:42 +0200123
Niels Möllerc68d2822018-11-20 14:52:05 +0100124 Stats FirstStats() { return first_.GetStats(); }
125 Stats SecondStats() { return second_.GetStats(); }
126
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800127 int first_factory_transport_count() const {
128 return first_factory_.created_transport_count();
129 }
130
131 int second_factory_transport_count() const {
132 return second_factory_.created_transport_count();
133 }
134
Niels Möller2e47f7c2018-10-16 10:41:42 +0200135 private:
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700136 class LoopbackDataChannelTransport : public DataChannelTransportInterface {
137 public:
138 explicit LoopbackDataChannelTransport(rtc::Thread* thread);
139 ~LoopbackDataChannelTransport() override;
140
141 void Connect(LoopbackDataChannelTransport* other);
142
143 RTCError OpenChannel(int channel_id) override;
144
145 RTCError SendData(int channel_id,
146 const SendDataParams& params,
147 const rtc::CopyOnWriteBuffer& buffer) override;
148
149 RTCError CloseChannel(int channel_id) override;
150
151 bool IsReadyToSend() const override;
152
153 void SetDataSink(DataChannelSink* sink) override;
154
155 void OnReadyToSend(bool ready_to_send);
156
157 void FlushAsyncInvokes();
158
159 private:
160 void OnData(int channel_id,
161 DataMessageType type,
162 const rtc::CopyOnWriteBuffer& buffer);
163
164 void OnRemoteCloseChannel(int channel_id);
165
166 rtc::Thread* const thread_;
167 rtc::CriticalSection sink_lock_;
168 DataChannelSink* data_sink_ RTC_GUARDED_BY(sink_lock_) = nullptr;
169
170 bool ready_to_send_ RTC_GUARDED_BY(sink_lock_) = false;
171
172 LoopbackDataChannelTransport* other_;
173
174 rtc::AsyncInvoker invoker_;
175 };
176
Niels Möller2e47f7c2018-10-16 10:41:42 +0200177 class LoopbackMediaTransport : public MediaTransportInterface {
178 public:
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700179 explicit LoopbackMediaTransport(rtc::Thread* thread);
Bjorn Mellem273d0292018-11-01 16:42:44 -0700180
Niels Möllere0446cb2018-11-30 09:35:52 +0100181 ~LoopbackMediaTransport() override;
Niels Möller2e47f7c2018-10-16 10:41:42 +0200182
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700183 // Connects this loopback transport to another loopback transport.
184 void Connect(LoopbackMediaTransport* other);
185
186 void Connect(rtc::PacketTransportInternal* transport) override;
187
Niels Möller2e47f7c2018-10-16 10:41:42 +0200188 RTCError SendAudioFrame(uint64_t channel_id,
Niels Möllere0446cb2018-11-30 09:35:52 +0100189 MediaTransportEncodedAudioFrame frame) override;
Niels Möller2e47f7c2018-10-16 10:41:42 +0200190
191 RTCError SendVideoFrame(
192 uint64_t channel_id,
Niels Möllere0446cb2018-11-30 09:35:52 +0100193 const MediaTransportEncodedVideoFrame& frame) override;
Niels Möller2e47f7c2018-10-16 10:41:42 +0200194
Niels Möller1c7f5f62018-12-10 11:06:02 +0100195 void SetKeyFrameRequestCallback(
196 MediaTransportKeyFrameRequestCallback* callback) override;
197
Niels Möllere0446cb2018-11-30 09:35:52 +0100198 RTCError RequestKeyFrame(uint64_t channel_id) override;
Niels Möller2e47f7c2018-10-16 10:41:42 +0200199
Niels Möllere0446cb2018-11-30 09:35:52 +0100200 void SetReceiveAudioSink(MediaTransportAudioSinkInterface* sink) override;
Niels Möller2e47f7c2018-10-16 10:41:42 +0200201
Niels Möllere0446cb2018-11-30 09:35:52 +0100202 void SetReceiveVideoSink(MediaTransportVideoSinkInterface* sink) override;
Niels Möller2e47f7c2018-10-16 10:41:42 +0200203
Niels Möller46879152019-01-07 15:54:47 +0100204 void AddTargetTransferRateObserver(
205 TargetTransferRateObserver* observer) override;
206
207 void RemoveTargetTransferRateObserver(
208 TargetTransferRateObserver* observer) override;
209
210 void AddRttObserver(MediaTransportRttObserver* observer) override;
211 void RemoveRttObserver(MediaTransportRttObserver* observer) override;
212
Bjorn Mellemeb2c6412018-10-31 15:25:32 -0700213 void SetMediaTransportStateCallback(
Niels Möllere0446cb2018-11-30 09:35:52 +0100214 MediaTransportStateCallback* callback) override;
Bjorn Mellemeb2c6412018-10-31 15:25:32 -0700215
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700216 void SetState(MediaTransportState state);
217
Bjorn Mellem9ded4852019-02-28 12:27:11 -0800218 RTCError OpenChannel(int channel_id) override;
219
Bjorn Mellemeb2c6412018-10-31 15:25:32 -0700220 RTCError SendData(int channel_id,
221 const SendDataParams& params,
Niels Möllere0446cb2018-11-30 09:35:52 +0100222 const rtc::CopyOnWriteBuffer& buffer) override;
Bjorn Mellemeb2c6412018-10-31 15:25:32 -0700223
Niels Möllere0446cb2018-11-30 09:35:52 +0100224 RTCError CloseChannel(int channel_id) override;
Bjorn Mellemeb2c6412018-10-31 15:25:32 -0700225
Niels Möllere0446cb2018-11-30 09:35:52 +0100226 void SetDataSink(DataChannelSink* sink) override;
Bjorn Mellem273d0292018-11-01 16:42:44 -0700227
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700228 bool IsReadyToSend() const override;
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800229
Niels Möllere0446cb2018-11-30 09:35:52 +0100230 void FlushAsyncInvokes();
Bjorn Mellemeb2c6412018-10-31 15:25:32 -0700231
Niels Möllere0446cb2018-11-30 09:35:52 +0100232 Stats GetStats();
Niels Möllerc68d2822018-11-20 14:52:05 +0100233
Piotr (Peter) Slatala48c54932019-01-28 06:50:38 -0800234 void SetAllocatedBitrateLimits(
235 const MediaTransportAllocatedBitrateLimits& limits) override;
236
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800237 absl::optional<std::string> GetTransportParametersOffer() const override;
238
Niels Möller2e47f7c2018-10-16 10:41:42 +0200239 private:
Niels Möllere0446cb2018-11-30 09:35:52 +0100240 void OnData(uint64_t channel_id, MediaTransportEncodedAudioFrame frame);
Niels Möller2e47f7c2018-10-16 10:41:42 +0200241
Niels Möllere0446cb2018-11-30 09:35:52 +0100242 void OnData(uint64_t channel_id, MediaTransportEncodedVideoFrame frame);
Niels Möllerd5696fb2018-11-28 15:34:37 +0100243
Niels Möller1c7f5f62018-12-10 11:06:02 +0100244 void OnKeyFrameRequested(int channel_id);
245
Niels Möllere0446cb2018-11-30 09:35:52 +0100246 void OnStateChanged() RTC_RUN_ON(thread_);
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800247
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700248 // Implementation of the data channel transport.
249 LoopbackDataChannelTransport dc_transport_;
250
Bjorn Mellem273d0292018-11-01 16:42:44 -0700251 rtc::Thread* const thread_;
252 rtc::CriticalSection sink_lock_;
Niels Möllerc68d2822018-11-20 14:52:05 +0100253 rtc::CriticalSection stats_lock_;
Bjorn Mellem273d0292018-11-01 16:42:44 -0700254
Niels Möllerd5696fb2018-11-28 15:34:37 +0100255 MediaTransportAudioSinkInterface* audio_sink_ RTC_GUARDED_BY(sink_lock_) =
256 nullptr;
257 MediaTransportVideoSinkInterface* video_sink_ RTC_GUARDED_BY(sink_lock_) =
Bjorn Mellem273d0292018-11-01 16:42:44 -0700258 nullptr;
Niels Möller1c7f5f62018-12-10 11:06:02 +0100259
260 MediaTransportKeyFrameRequestCallback* key_frame_callback_
261 RTC_GUARDED_BY(sink_lock_) = nullptr;
262
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800263 MediaTransportStateCallback* state_callback_ RTC_GUARDED_BY(sink_lock_) =
264 nullptr;
265
Niels Möller46879152019-01-07 15:54:47 +0100266 std::vector<TargetTransferRateObserver*> target_transfer_rate_observers_
267 RTC_GUARDED_BY(sink_lock_);
268 std::vector<MediaTransportRttObserver*> rtt_observers_
269 RTC_GUARDED_BY(sink_lock_);
270
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800271 MediaTransportState state_ RTC_GUARDED_BY(thread_) =
272 MediaTransportState::kPending;
273
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700274 LoopbackMediaTransport* other_;
Bjorn Mellem273d0292018-11-01 16:42:44 -0700275
Niels Möllerc68d2822018-11-20 14:52:05 +0100276 Stats stats_ RTC_GUARDED_BY(stats_lock_);
277
Bjorn Mellem273d0292018-11-01 16:42:44 -0700278 rtc::AsyncInvoker invoker_;
Niels Möller2e47f7c2018-10-16 10:41:42 +0200279 };
280
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700281 class LoopbackDatagramTransport : public DatagramTransportInterface {
282 public:
283 explicit LoopbackDatagramTransport(rtc::Thread* thread);
284
285 void Connect(LoopbackDatagramTransport* other);
286
287 // Datagram transport overrides.
288 // TODO(mellem): Implement these when tests actually need to use them.
289 void Connect(rtc::PacketTransportInternal* packet_transport) override;
290 CongestionControlInterface* congestion_control() override;
291 void SetTransportStateCallback(
292 MediaTransportStateCallback* callback) override;
293 RTCError SendDatagram(rtc::ArrayView<const uint8_t> data,
294 DatagramId datagram_id) override;
295 size_t GetLargestDatagramSize() const override;
296 void SetDatagramSink(DatagramSinkInterface* sink) override;
297 std::string GetTransportParameters() const override;
298
299 // Data channel overrides.
300 RTCError OpenChannel(int channel_id) override;
301 RTCError SendData(int channel_id,
302 const SendDataParams& params,
303 const rtc::CopyOnWriteBuffer& buffer) override;
304 RTCError CloseChannel(int channel_id) override;
305 void SetDataSink(DataChannelSink* sink) override;
306 bool IsReadyToSend() const override;
307
308 // Loopback-specific functionality.
309 void SetState(MediaTransportState state);
310 void FlushAsyncInvokes();
311
312 void set_transport_parameters(const std::string& value) {
313 transport_parameters_ = value;
314 }
315
316 private:
317 LoopbackDataChannelTransport dc_transport_;
318
319 std::string transport_parameters_;
320 };
321
Bjorn Mellem273d0292018-11-01 16:42:44 -0700322 LoopbackMediaTransport first_;
323 LoopbackMediaTransport second_;
Bjorn A Mellemb689af42019-08-21 10:44:59 -0700324 LoopbackDatagramTransport first_datagram_transport_;
325 LoopbackDatagramTransport second_datagram_transport_;
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -0800326 WrapperMediaTransportFactory first_factory_;
327 WrapperMediaTransportFactory second_factory_;
Niels Möller2e47f7c2018-10-16 10:41:42 +0200328};
329
330} // namespace webrtc
331
332#endif // API_TEST_LOOPBACK_MEDIA_TRANSPORT_H_