blob: c67a9d5ec1fbeb7bf6b94a8ead9877d3e1735586 [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
Niels Möllerd5696fb2018-11-28 15:34:37 +010011#include <algorithm>
Bjorn Mellem273d0292018-11-01 16:42:44 -070012#include <memory>
Niels Möller2e47f7c2018-10-16 10:41:42 +020013#include <vector>
14
15#include "api/test/loopback_media_transport.h"
16#include "test/gmock.h"
17
18namespace webrtc {
19
20namespace {
21
22class MockMediaTransportAudioSinkInterface
23 : public MediaTransportAudioSinkInterface {
24 public:
25 MOCK_METHOD2(OnData, void(uint64_t, MediaTransportEncodedAudioFrame));
26};
27
Niels Möllerd5696fb2018-11-28 15:34:37 +010028class MockMediaTransportVideoSinkInterface
29 : public MediaTransportVideoSinkInterface {
30 public:
31 MOCK_METHOD2(OnData, void(uint64_t, MediaTransportEncodedVideoFrame));
Niels Möller1c7f5f62018-12-10 11:06:02 +010032};
33
34class MockMediaTransportKeyFrameRequestCallback
35 : public MediaTransportKeyFrameRequestCallback {
36 public:
Niels Möllerd5696fb2018-11-28 15:34:37 +010037 MOCK_METHOD1(OnKeyFrameRequested, void(uint64_t));
38};
39
Bjorn Mellem273d0292018-11-01 16:42:44 -070040class MockDataChannelSink : public DataChannelSink {
41 public:
42 MOCK_METHOD3(OnDataReceived,
43 void(int, DataMessageType, const rtc::CopyOnWriteBuffer&));
44 MOCK_METHOD1(OnChannelClosing, void(int));
45 MOCK_METHOD1(OnChannelClosed, void(int));
46};
47
Bjorn Mellem175aa2e2018-11-08 11:23:22 -080048class MockStateCallback : public MediaTransportStateCallback {
49 public:
50 MOCK_METHOD1(OnStateChanged, void(MediaTransportState));
51};
52
Niels Möller2e47f7c2018-10-16 10:41:42 +020053// Test only uses the sequence number.
54MediaTransportEncodedAudioFrame CreateAudioFrame(int sequence_number) {
55 static constexpr int kSamplingRateHz = 48000;
56 static constexpr int kStartingSampleIndex = 0;
57 static constexpr int kSamplesPerChannel = 480;
Niels Möllerd8a1b7a2018-12-06 13:00:27 +010058 static constexpr int kPayloadType = 17;
Niels Möller2e47f7c2018-10-16 10:41:42 +020059
60 return MediaTransportEncodedAudioFrame(
61 kSamplingRateHz, kStartingSampleIndex, kSamplesPerChannel,
62 sequence_number, MediaTransportEncodedAudioFrame::FrameType::kSpeech,
63 kPayloadType, std::vector<uint8_t>(kSamplesPerChannel));
64}
65
Niels Möllerd5696fb2018-11-28 15:34:37 +010066MediaTransportEncodedVideoFrame CreateVideoFrame(
67 int frame_id,
68 const webrtc::EncodedImage& encoded_image) {
Niels Möllerd8a1b7a2018-12-06 13:00:27 +010069 static constexpr int kPayloadType = 18;
Niels Möllerd5696fb2018-11-28 15:34:37 +010070 return MediaTransportEncodedVideoFrame(frame_id, /*referenced_frame_ids=*/{},
Niels Möllerd8a1b7a2018-12-06 13:00:27 +010071 kPayloadType, encoded_image);
Niels Möllerd5696fb2018-11-28 15:34:37 +010072}
73
Niels Möller2e47f7c2018-10-16 10:41:42 +020074} // namespace
75
76TEST(LoopbackMediaTransport, AudioWithNoSinkSilentlyIgnored) {
Bjorn Mellem273d0292018-11-01 16:42:44 -070077 std::unique_ptr<rtc::Thread> thread = rtc::Thread::Create();
78 thread->Start();
79 MediaTransportPair transport_pair(thread.get());
Niels Möller2e47f7c2018-10-16 10:41:42 +020080 transport_pair.first()->SendAudioFrame(1, CreateAudioFrame(0));
81 transport_pair.second()->SendAudioFrame(2, CreateAudioFrame(0));
Bjorn Mellem273d0292018-11-01 16:42:44 -070082 transport_pair.FlushAsyncInvokes();
Niels Möller2e47f7c2018-10-16 10:41:42 +020083}
84
85TEST(LoopbackMediaTransport, AudioDeliveredToSink) {
Bjorn Mellem273d0292018-11-01 16:42:44 -070086 std::unique_ptr<rtc::Thread> thread = rtc::Thread::Create();
87 thread->Start();
88 MediaTransportPair transport_pair(thread.get());
Niels Möller2e47f7c2018-10-16 10:41:42 +020089 testing::StrictMock<MockMediaTransportAudioSinkInterface> sink;
90 EXPECT_CALL(sink,
91 OnData(1, testing::Property(
92 &MediaTransportEncodedAudioFrame::sequence_number,
93 testing::Eq(10))));
94 transport_pair.second()->SetReceiveAudioSink(&sink);
95 transport_pair.first()->SendAudioFrame(1, CreateAudioFrame(10));
96
Bjorn Mellem273d0292018-11-01 16:42:44 -070097 transport_pair.FlushAsyncInvokes();
Niels Möller2e47f7c2018-10-16 10:41:42 +020098 transport_pair.second()->SetReceiveAudioSink(nullptr);
99}
100
Niels Möllerd5696fb2018-11-28 15:34:37 +0100101TEST(LoopbackMediaTransport, VideoDeliveredToSink) {
102 std::unique_ptr<rtc::Thread> thread = rtc::Thread::Create();
103 thread->Start();
104 MediaTransportPair transport_pair(thread.get());
105 testing::StrictMock<MockMediaTransportVideoSinkInterface> sink;
106 uint8_t encoded_data[] = {1, 2, 3};
107 EncodedImage encoded_image;
108 encoded_image._buffer = encoded_data;
109 encoded_image._length = sizeof(encoded_data);
110
111 EXPECT_CALL(sink, OnData(1, testing::Property(
112 &MediaTransportEncodedVideoFrame::frame_id,
113 testing::Eq(10))))
114 .WillOnce(testing::Invoke(
115 [&encoded_image](int frame_id,
116 const MediaTransportEncodedVideoFrame& frame) {
117 EXPECT_NE(frame.encoded_image()._buffer, encoded_image._buffer);
118 EXPECT_EQ(frame.encoded_image()._length, encoded_image._length);
119 EXPECT_EQ(
120 0, memcmp(frame.encoded_image()._buffer, encoded_image._buffer,
121 std::min(frame.encoded_image()._length,
122 encoded_image._length)));
123 }));
124
125 transport_pair.second()->SetReceiveVideoSink(&sink);
126 transport_pair.first()->SendVideoFrame(1,
127 CreateVideoFrame(10, encoded_image));
128
129 transport_pair.FlushAsyncInvokes();
130 transport_pair.second()->SetReceiveVideoSink(nullptr);
131}
132
Niels Möller1c7f5f62018-12-10 11:06:02 +0100133TEST(LoopbackMediaTransport, VideoKeyFrameRequestDeliveredToCallback) {
134 std::unique_ptr<rtc::Thread> thread = rtc::Thread::Create();
135 thread->Start();
136 MediaTransportPair transport_pair(thread.get());
137 testing::StrictMock<MockMediaTransportKeyFrameRequestCallback> callback1;
138 testing::StrictMock<MockMediaTransportKeyFrameRequestCallback> callback2;
139 const uint64_t kFirstChannelId = 1111;
140 const uint64_t kSecondChannelId = 2222;
141
142 EXPECT_CALL(callback1, OnKeyFrameRequested(kSecondChannelId));
143 EXPECT_CALL(callback2, OnKeyFrameRequested(kFirstChannelId));
144 transport_pair.first()->SetKeyFrameRequestCallback(&callback1);
145 transport_pair.second()->SetKeyFrameRequestCallback(&callback2);
146
147 transport_pair.first()->RequestKeyFrame(kFirstChannelId);
148 transport_pair.second()->RequestKeyFrame(kSecondChannelId);
149
150 transport_pair.FlushAsyncInvokes();
151}
152
Bjorn Mellem273d0292018-11-01 16:42:44 -0700153TEST(LoopbackMediaTransport, DataDeliveredToSink) {
154 std::unique_ptr<rtc::Thread> thread = rtc::Thread::Create();
155 thread->Start();
156 MediaTransportPair transport_pair(thread.get());
157
158 MockDataChannelSink sink;
159 transport_pair.first()->SetDataSink(&sink);
160
161 const int channel_id = 1;
162 EXPECT_CALL(sink,
163 OnDataReceived(
164 channel_id, DataMessageType::kText,
165 testing::Property<rtc::CopyOnWriteBuffer, const char*>(
166 &rtc::CopyOnWriteBuffer::cdata, testing::StrEq("foo"))));
167
168 SendDataParams params;
169 params.type = DataMessageType::kText;
170 rtc::CopyOnWriteBuffer buffer("foo");
171 transport_pair.second()->SendData(channel_id, params, buffer);
172
173 transport_pair.FlushAsyncInvokes();
174 transport_pair.first()->SetDataSink(nullptr);
175}
176
177TEST(LoopbackMediaTransport, CloseDeliveredToSink) {
178 std::unique_ptr<rtc::Thread> thread = rtc::Thread::Create();
179 thread->Start();
180 MediaTransportPair transport_pair(thread.get());
181
182 MockDataChannelSink first_sink;
183 transport_pair.first()->SetDataSink(&first_sink);
184
185 MockDataChannelSink second_sink;
186 transport_pair.second()->SetDataSink(&second_sink);
187
188 const int channel_id = 1;
189 {
190 testing::InSequence s;
191 EXPECT_CALL(second_sink, OnChannelClosing(channel_id));
192 EXPECT_CALL(second_sink, OnChannelClosed(channel_id));
193 EXPECT_CALL(first_sink, OnChannelClosed(channel_id));
194 }
195
196 transport_pair.first()->CloseChannel(channel_id);
197
198 transport_pair.FlushAsyncInvokes();
199 transport_pair.first()->SetDataSink(nullptr);
200 transport_pair.second()->SetDataSink(nullptr);
201}
202
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800203TEST(LoopbackMediaTransport, InitialStateDeliveredWhenCallbackSet) {
204 std::unique_ptr<rtc::Thread> thread = rtc::Thread::Create();
205 thread->Start();
206 MediaTransportPair transport_pair(thread.get());
207
208 MockStateCallback state_callback;
209
210 EXPECT_CALL(state_callback, OnStateChanged(MediaTransportState::kPending));
211 transport_pair.first()->SetMediaTransportStateCallback(&state_callback);
212 transport_pair.FlushAsyncInvokes();
213}
214
215TEST(LoopbackMediaTransport, ChangedStateDeliveredWhenCallbackSet) {
216 std::unique_ptr<rtc::Thread> thread = rtc::Thread::Create();
217 thread->Start();
218 MediaTransportPair transport_pair(thread.get());
219
220 transport_pair.SetState(MediaTransportState::kWritable);
221 transport_pair.FlushAsyncInvokes();
222
223 MockStateCallback state_callback;
224
225 EXPECT_CALL(state_callback, OnStateChanged(MediaTransportState::kWritable));
226 transport_pair.first()->SetMediaTransportStateCallback(&state_callback);
227 transport_pair.FlushAsyncInvokes();
228}
229
230TEST(LoopbackMediaTransport, StateChangeDeliveredToCallback) {
231 std::unique_ptr<rtc::Thread> thread = rtc::Thread::Create();
232 thread->Start();
233 MediaTransportPair transport_pair(thread.get());
234
235 MockStateCallback state_callback;
236
237 EXPECT_CALL(state_callback, OnStateChanged(MediaTransportState::kPending));
238 EXPECT_CALL(state_callback, OnStateChanged(MediaTransportState::kWritable));
239 transport_pair.first()->SetMediaTransportStateCallback(&state_callback);
240 transport_pair.SetState(MediaTransportState::kWritable);
241 transport_pair.FlushAsyncInvokes();
242}
243
Niels Möller2e47f7c2018-10-16 10:41:42 +0200244} // namespace webrtc