blob: f3f24d4c98d9831d8dc1662c5d00c1ecb78ba4c9 [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
14#include <utility>
15
16#include "api/media_transport_interface.h"
Bjorn Mellem273d0292018-11-01 16:42:44 -070017#include "rtc_base/asyncinvoker.h"
18#include "rtc_base/criticalsection.h"
19#include "rtc_base/thread.h"
Niels Möller2e47f7c2018-10-16 10:41:42 +020020
21namespace webrtc {
22
23// Contains two MediaTransportsInterfaces that are connected to each other.
24// Currently supports audio only.
25class MediaTransportPair {
26 public:
Bjorn Mellem273d0292018-11-01 16:42:44 -070027 explicit MediaTransportPair(rtc::Thread* thread)
28 : first_(thread, &second_), second_(thread, &first_) {}
Niels Möller2e47f7c2018-10-16 10:41:42 +020029
30 // Ownership stays with MediaTransportPair
Bjorn Mellem273d0292018-11-01 16:42:44 -070031 MediaTransportInterface* first() { return &first_; }
32 MediaTransportInterface* second() { return &second_; }
33
34 void FlushAsyncInvokes() {
35 first_.FlushAsyncInvokes();
36 second_.FlushAsyncInvokes();
37 }
Niels Möller2e47f7c2018-10-16 10:41:42 +020038
39 private:
40 class LoopbackMediaTransport : public MediaTransportInterface {
41 public:
Bjorn Mellem273d0292018-11-01 16:42:44 -070042 LoopbackMediaTransport(rtc::Thread* thread, LoopbackMediaTransport* other)
43 : thread_(thread), other_(other) {}
44
45 ~LoopbackMediaTransport() {
46 rtc::CritScope lock(&sink_lock_);
47 RTC_CHECK(sink_ == nullptr);
48 RTC_CHECK(data_sink_ == nullptr);
49 }
Niels Möller2e47f7c2018-10-16 10:41:42 +020050
51 RTCError SendAudioFrame(uint64_t channel_id,
52 MediaTransportEncodedAudioFrame frame) override {
Bjorn Mellem273d0292018-11-01 16:42:44 -070053 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_,
54 [this, channel_id, frame] {
55 other_->OnData(channel_id, std::move(frame));
56 });
Niels Möller2e47f7c2018-10-16 10:41:42 +020057 return RTCError::OK();
58 };
59
60 RTCError SendVideoFrame(
61 uint64_t channel_id,
62 const MediaTransportEncodedVideoFrame& frame) override {
63 return RTCError::OK();
64 }
65
66 RTCError RequestKeyFrame(uint64_t channel_id) override {
67 return RTCError::OK();
68 }
69
70 void SetReceiveAudioSink(MediaTransportAudioSinkInterface* sink) override {
Bjorn Mellem273d0292018-11-01 16:42:44 -070071 rtc::CritScope lock(&sink_lock_);
Niels Möller2e47f7c2018-10-16 10:41:42 +020072 if (sink) {
73 RTC_CHECK(sink_ == nullptr);
74 }
75 sink_ = sink;
76 }
77
78 void SetReceiveVideoSink(MediaTransportVideoSinkInterface* sink) override {}
79
Piotr (Peter) Slatala6b9d8232018-10-26 07:59:46 -070080 void SetTargetTransferRateObserver(
81 webrtc::TargetTransferRateObserver* observer) override {}
82
Bjorn Mellemeb2c6412018-10-31 15:25:32 -070083 void SetMediaTransportStateCallback(
84 MediaTransportStateCallback* callback) override {}
85
86 RTCError SendData(int channel_id,
87 const SendDataParams& params,
88 const rtc::CopyOnWriteBuffer& buffer) override {
Bjorn Mellem273d0292018-11-01 16:42:44 -070089 invoker_.AsyncInvoke<void>(
90 RTC_FROM_HERE, thread_, [this, channel_id, params, buffer] {
91 other_->OnData(channel_id, params.type, buffer);
92 });
93 return RTCError::OK();
Bjorn Mellemeb2c6412018-10-31 15:25:32 -070094 }
95
96 RTCError CloseChannel(int channel_id) override {
Bjorn Mellem273d0292018-11-01 16:42:44 -070097 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, channel_id] {
98 other_->OnRemoteCloseChannel(channel_id);
99 rtc::CritScope lock(&sink_lock_);
100 if (data_sink_) {
101 data_sink_->OnChannelClosed(channel_id);
102 }
103 });
104 return RTCError::OK();
Bjorn Mellemeb2c6412018-10-31 15:25:32 -0700105 }
106
Bjorn Mellem273d0292018-11-01 16:42:44 -0700107 void SetDataSink(DataChannelSink* sink) override {
108 rtc::CritScope lock(&sink_lock_);
109 data_sink_ = sink;
110 }
111
112 void FlushAsyncInvokes() { invoker_.Flush(thread_); }
Bjorn Mellemeb2c6412018-10-31 15:25:32 -0700113
Niels Möller2e47f7c2018-10-16 10:41:42 +0200114 private:
115 void OnData(uint64_t channel_id, MediaTransportEncodedAudioFrame frame) {
Bjorn Mellem273d0292018-11-01 16:42:44 -0700116 rtc::CritScope lock(&sink_lock_);
Niels Möller2e47f7c2018-10-16 10:41:42 +0200117 if (sink_) {
118 sink_->OnData(channel_id, frame);
119 }
120 }
121
Bjorn Mellem273d0292018-11-01 16:42:44 -0700122 void OnData(int channel_id,
123 DataMessageType type,
124 const rtc::CopyOnWriteBuffer& buffer) {
125 rtc::CritScope lock(&sink_lock_);
126 if (data_sink_) {
127 data_sink_->OnDataReceived(channel_id, type, buffer);
128 }
129 }
130
131 void OnRemoteCloseChannel(int channel_id) {
132 rtc::CritScope lock(&sink_lock_);
133 if (data_sink_) {
134 data_sink_->OnChannelClosing(channel_id);
135 data_sink_->OnChannelClosed(channel_id);
136 }
137 }
138
139 rtc::Thread* const thread_;
140 rtc::CriticalSection sink_lock_;
141
142 MediaTransportAudioSinkInterface* sink_ RTC_GUARDED_BY(sink_lock_) =
143 nullptr;
144 DataChannelSink* data_sink_ RTC_GUARDED_BY(sink_lock_) = nullptr;
145 LoopbackMediaTransport* const other_;
146
147 rtc::AsyncInvoker invoker_;
Niels Möller2e47f7c2018-10-16 10:41:42 +0200148 };
149
Bjorn Mellem273d0292018-11-01 16:42:44 -0700150 LoopbackMediaTransport first_;
151 LoopbackMediaTransport second_;
Niels Möller2e47f7c2018-10-16 10:41:42 +0200152};
153
154} // namespace webrtc
155
156#endif // API_TEST_LOOPBACK_MEDIA_TRANSPORT_H_