blob: 2524fb47b11eee413b38686f5f5a2f990bb04732 [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>
Niels Möller2e47f7c2018-10-16 10:41:42 +020015#include <utility>
16
17#include "api/media_transport_interface.h"
Bjorn Mellem273d0292018-11-01 16:42:44 -070018#include "rtc_base/asyncinvoker.h"
19#include "rtc_base/criticalsection.h"
20#include "rtc_base/thread.h"
Bjorn Mellem175aa2e2018-11-08 11:23:22 -080021#include "rtc_base/thread_checker.h"
Niels Möller2e47f7c2018-10-16 10:41:42 +020022
23namespace webrtc {
24
Bjorn Mellem175aa2e2018-11-08 11:23:22 -080025// Wrapper used to hand out unique_ptrs to loopback media transports without
26// ownership changes.
27class WrapperMediaTransport : public MediaTransportInterface {
28 public:
29 explicit WrapperMediaTransport(MediaTransportInterface* wrapped)
30 : wrapped_(wrapped) {}
31
32 RTCError SendAudioFrame(uint64_t channel_id,
33 MediaTransportEncodedAudioFrame frame) override {
34 return wrapped_->SendAudioFrame(channel_id, std::move(frame));
35 }
36
37 RTCError SendVideoFrame(
38 uint64_t channel_id,
39 const MediaTransportEncodedVideoFrame& frame) override {
40 return wrapped_->SendVideoFrame(channel_id, frame);
41 }
42
43 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
55 void SetTargetTransferRateObserver(
56 webrtc::TargetTransferRateObserver* observer) override {
57 wrapped_->SetTargetTransferRateObserver(observer);
58 }
59
60 void SetMediaTransportStateCallback(
61 MediaTransportStateCallback* callback) override {
62 wrapped_->SetMediaTransportStateCallback(callback);
63 }
64
65 RTCError SendData(int channel_id,
66 const SendDataParams& params,
67 const rtc::CopyOnWriteBuffer& buffer) override {
68 return wrapped_->SendData(channel_id, params, buffer);
69 }
70
71 RTCError CloseChannel(int channel_id) override {
72 return wrapped_->CloseChannel(channel_id);
73 }
74
75 void SetDataSink(DataChannelSink* sink) override {
76 wrapped_->SetDataSink(sink);
77 }
78
79 private:
80 MediaTransportInterface* wrapped_;
81};
82
83class WrapperMediaTransportFactory : public MediaTransportFactory {
84 public:
85 explicit WrapperMediaTransportFactory(MediaTransportInterface* wrapped)
86 : wrapped_(wrapped) {}
87
88 RTCErrorOr<std::unique_ptr<MediaTransportInterface>> CreateMediaTransport(
89 rtc::PacketTransportInternal* packet_transport,
90 rtc::Thread* network_thread,
91 const MediaTransportSettings& settings) override {
92 return {absl::make_unique<WrapperMediaTransport>(wrapped_)};
93 }
94
95 private:
96 MediaTransportInterface* wrapped_;
97};
98
Niels Möller2e47f7c2018-10-16 10:41:42 +020099// Contains two MediaTransportsInterfaces that are connected to each other.
100// Currently supports audio only.
101class MediaTransportPair {
102 public:
Bjorn Mellem273d0292018-11-01 16:42:44 -0700103 explicit MediaTransportPair(rtc::Thread* thread)
104 : first_(thread, &second_), second_(thread, &first_) {}
Niels Möller2e47f7c2018-10-16 10:41:42 +0200105
106 // Ownership stays with MediaTransportPair
Bjorn Mellem273d0292018-11-01 16:42:44 -0700107 MediaTransportInterface* first() { return &first_; }
108 MediaTransportInterface* second() { return &second_; }
109
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800110 std::unique_ptr<MediaTransportFactory> first_factory() {
111 return absl::make_unique<WrapperMediaTransportFactory>(&first_);
112 }
113
114 std::unique_ptr<MediaTransportFactory> second_factory() {
115 return absl::make_unique<WrapperMediaTransportFactory>(&second_);
116 }
117
118 void SetState(MediaTransportState state) {
119 first_.SetState(state);
120 second_.SetState(state);
121 }
122
Bjorn Mellem273d0292018-11-01 16:42:44 -0700123 void FlushAsyncInvokes() {
124 first_.FlushAsyncInvokes();
125 second_.FlushAsyncInvokes();
126 }
Niels Möller2e47f7c2018-10-16 10:41:42 +0200127
128 private:
129 class LoopbackMediaTransport : public MediaTransportInterface {
130 public:
Bjorn Mellem273d0292018-11-01 16:42:44 -0700131 LoopbackMediaTransport(rtc::Thread* thread, LoopbackMediaTransport* other)
132 : thread_(thread), other_(other) {}
133
134 ~LoopbackMediaTransport() {
135 rtc::CritScope lock(&sink_lock_);
136 RTC_CHECK(sink_ == nullptr);
137 RTC_CHECK(data_sink_ == nullptr);
138 }
Niels Möller2e47f7c2018-10-16 10:41:42 +0200139
140 RTCError SendAudioFrame(uint64_t channel_id,
141 MediaTransportEncodedAudioFrame frame) override {
Bjorn Mellem273d0292018-11-01 16:42:44 -0700142 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_,
143 [this, channel_id, frame] {
144 other_->OnData(channel_id, std::move(frame));
145 });
Niels Möller2e47f7c2018-10-16 10:41:42 +0200146 return RTCError::OK();
147 };
148
149 RTCError SendVideoFrame(
150 uint64_t channel_id,
151 const MediaTransportEncodedVideoFrame& frame) override {
152 return RTCError::OK();
153 }
154
155 RTCError RequestKeyFrame(uint64_t channel_id) override {
156 return RTCError::OK();
157 }
158
159 void SetReceiveAudioSink(MediaTransportAudioSinkInterface* sink) override {
Bjorn Mellem273d0292018-11-01 16:42:44 -0700160 rtc::CritScope lock(&sink_lock_);
Niels Möller2e47f7c2018-10-16 10:41:42 +0200161 if (sink) {
162 RTC_CHECK(sink_ == nullptr);
163 }
164 sink_ = sink;
165 }
166
167 void SetReceiveVideoSink(MediaTransportVideoSinkInterface* sink) override {}
168
Piotr (Peter) Slatala6b9d8232018-10-26 07:59:46 -0700169 void SetTargetTransferRateObserver(
170 webrtc::TargetTransferRateObserver* observer) override {}
171
Bjorn Mellemeb2c6412018-10-31 15:25:32 -0700172 void SetMediaTransportStateCallback(
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800173 MediaTransportStateCallback* callback) override {
174 rtc::CritScope lock(&sink_lock_);
175 state_callback_ = callback;
176 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this] {
177 RTC_DCHECK_RUN_ON(thread_);
178 OnStateChanged();
179 });
180 }
Bjorn Mellemeb2c6412018-10-31 15:25:32 -0700181
182 RTCError SendData(int channel_id,
183 const SendDataParams& params,
184 const rtc::CopyOnWriteBuffer& buffer) override {
Bjorn Mellem273d0292018-11-01 16:42:44 -0700185 invoker_.AsyncInvoke<void>(
186 RTC_FROM_HERE, thread_, [this, channel_id, params, buffer] {
187 other_->OnData(channel_id, params.type, buffer);
188 });
189 return RTCError::OK();
Bjorn Mellemeb2c6412018-10-31 15:25:32 -0700190 }
191
192 RTCError CloseChannel(int channel_id) override {
Bjorn Mellem273d0292018-11-01 16:42:44 -0700193 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, channel_id] {
194 other_->OnRemoteCloseChannel(channel_id);
195 rtc::CritScope lock(&sink_lock_);
196 if (data_sink_) {
197 data_sink_->OnChannelClosed(channel_id);
198 }
199 });
200 return RTCError::OK();
Bjorn Mellemeb2c6412018-10-31 15:25:32 -0700201 }
202
Bjorn Mellem273d0292018-11-01 16:42:44 -0700203 void SetDataSink(DataChannelSink* sink) override {
204 rtc::CritScope lock(&sink_lock_);
205 data_sink_ = sink;
206 }
207
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800208 void SetState(MediaTransportState state) {
209 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, state] {
210 RTC_DCHECK_RUN_ON(thread_);
211 state_ = state;
212 OnStateChanged();
213 });
214 }
215
Bjorn Mellem273d0292018-11-01 16:42:44 -0700216 void FlushAsyncInvokes() { invoker_.Flush(thread_); }
Bjorn Mellemeb2c6412018-10-31 15:25:32 -0700217
Niels Möller2e47f7c2018-10-16 10:41:42 +0200218 private:
219 void OnData(uint64_t channel_id, MediaTransportEncodedAudioFrame frame) {
Bjorn Mellem273d0292018-11-01 16:42:44 -0700220 rtc::CritScope lock(&sink_lock_);
Niels Möller2e47f7c2018-10-16 10:41:42 +0200221 if (sink_) {
222 sink_->OnData(channel_id, frame);
223 }
224 }
225
Bjorn Mellem273d0292018-11-01 16:42:44 -0700226 void OnData(int channel_id,
227 DataMessageType type,
228 const rtc::CopyOnWriteBuffer& buffer) {
229 rtc::CritScope lock(&sink_lock_);
230 if (data_sink_) {
231 data_sink_->OnDataReceived(channel_id, type, buffer);
232 }
233 }
234
235 void OnRemoteCloseChannel(int channel_id) {
236 rtc::CritScope lock(&sink_lock_);
237 if (data_sink_) {
238 data_sink_->OnChannelClosing(channel_id);
239 data_sink_->OnChannelClosed(channel_id);
240 }
241 }
242
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800243 void OnStateChanged() RTC_RUN_ON(thread_) {
244 rtc::CritScope lock(&sink_lock_);
245 if (state_callback_) {
246 state_callback_->OnStateChanged(state_);
247 }
248 }
249
Bjorn Mellem273d0292018-11-01 16:42:44 -0700250 rtc::Thread* const thread_;
251 rtc::CriticalSection sink_lock_;
252
253 MediaTransportAudioSinkInterface* sink_ RTC_GUARDED_BY(sink_lock_) =
254 nullptr;
255 DataChannelSink* data_sink_ RTC_GUARDED_BY(sink_lock_) = nullptr;
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800256 MediaTransportStateCallback* state_callback_ RTC_GUARDED_BY(sink_lock_) =
257 nullptr;
258
259 MediaTransportState state_ RTC_GUARDED_BY(thread_) =
260 MediaTransportState::kPending;
261
Bjorn Mellem273d0292018-11-01 16:42:44 -0700262 LoopbackMediaTransport* const other_;
263
264 rtc::AsyncInvoker invoker_;
Niels Möller2e47f7c2018-10-16 10:41:42 +0200265 };
266
Bjorn Mellem273d0292018-11-01 16:42:44 -0700267 LoopbackMediaTransport first_;
268 LoopbackMediaTransport second_;
Niels Möller2e47f7c2018-10-16 10:41:42 +0200269};
270
271} // namespace webrtc
272
273#endif // API_TEST_LOOPBACK_MEDIA_TRANSPORT_H_