blob: ef4bbf4ad8f9872828a7ff75be3624892607cc09 [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));
32 MOCK_METHOD1(OnKeyFrameRequested, void(uint64_t));
33};
34
Bjorn Mellem273d0292018-11-01 16:42:44 -070035class MockDataChannelSink : public DataChannelSink {
36 public:
37 MOCK_METHOD3(OnDataReceived,
38 void(int, DataMessageType, const rtc::CopyOnWriteBuffer&));
39 MOCK_METHOD1(OnChannelClosing, void(int));
40 MOCK_METHOD1(OnChannelClosed, void(int));
41};
42
Bjorn Mellem175aa2e2018-11-08 11:23:22 -080043class MockStateCallback : public MediaTransportStateCallback {
44 public:
45 MOCK_METHOD1(OnStateChanged, void(MediaTransportState));
46};
47
Niels Möller2e47f7c2018-10-16 10:41:42 +020048// Test only uses the sequence number.
49MediaTransportEncodedAudioFrame CreateAudioFrame(int sequence_number) {
50 static constexpr int kSamplingRateHz = 48000;
51 static constexpr int kStartingSampleIndex = 0;
52 static constexpr int kSamplesPerChannel = 480;
53 static constexpr uint8_t kPayloadType = 17;
54
55 return MediaTransportEncodedAudioFrame(
56 kSamplingRateHz, kStartingSampleIndex, kSamplesPerChannel,
57 sequence_number, MediaTransportEncodedAudioFrame::FrameType::kSpeech,
58 kPayloadType, std::vector<uint8_t>(kSamplesPerChannel));
59}
60
Niels Möllerd5696fb2018-11-28 15:34:37 +010061MediaTransportEncodedVideoFrame CreateVideoFrame(
62 int frame_id,
63 const webrtc::EncodedImage& encoded_image) {
64 return MediaTransportEncodedVideoFrame(frame_id, /*referenced_frame_ids=*/{},
65 kVideoCodecVP8, encoded_image);
66}
67
Niels Möller2e47f7c2018-10-16 10:41:42 +020068} // namespace
69
70TEST(LoopbackMediaTransport, AudioWithNoSinkSilentlyIgnored) {
Bjorn Mellem273d0292018-11-01 16:42:44 -070071 std::unique_ptr<rtc::Thread> thread = rtc::Thread::Create();
72 thread->Start();
73 MediaTransportPair transport_pair(thread.get());
Niels Möller2e47f7c2018-10-16 10:41:42 +020074 transport_pair.first()->SendAudioFrame(1, CreateAudioFrame(0));
75 transport_pair.second()->SendAudioFrame(2, CreateAudioFrame(0));
Bjorn Mellem273d0292018-11-01 16:42:44 -070076 transport_pair.FlushAsyncInvokes();
Niels Möller2e47f7c2018-10-16 10:41:42 +020077}
78
79TEST(LoopbackMediaTransport, AudioDeliveredToSink) {
Bjorn Mellem273d0292018-11-01 16:42:44 -070080 std::unique_ptr<rtc::Thread> thread = rtc::Thread::Create();
81 thread->Start();
82 MediaTransportPair transport_pair(thread.get());
Niels Möller2e47f7c2018-10-16 10:41:42 +020083 testing::StrictMock<MockMediaTransportAudioSinkInterface> sink;
84 EXPECT_CALL(sink,
85 OnData(1, testing::Property(
86 &MediaTransportEncodedAudioFrame::sequence_number,
87 testing::Eq(10))));
88 transport_pair.second()->SetReceiveAudioSink(&sink);
89 transport_pair.first()->SendAudioFrame(1, CreateAudioFrame(10));
90
Bjorn Mellem273d0292018-11-01 16:42:44 -070091 transport_pair.FlushAsyncInvokes();
Niels Möller2e47f7c2018-10-16 10:41:42 +020092 transport_pair.second()->SetReceiveAudioSink(nullptr);
93}
94
Niels Möllerd5696fb2018-11-28 15:34:37 +010095TEST(LoopbackMediaTransport, VideoDeliveredToSink) {
96 std::unique_ptr<rtc::Thread> thread = rtc::Thread::Create();
97 thread->Start();
98 MediaTransportPair transport_pair(thread.get());
99 testing::StrictMock<MockMediaTransportVideoSinkInterface> sink;
100 uint8_t encoded_data[] = {1, 2, 3};
101 EncodedImage encoded_image;
102 encoded_image._buffer = encoded_data;
103 encoded_image._length = sizeof(encoded_data);
104
105 EXPECT_CALL(sink, OnData(1, testing::Property(
106 &MediaTransportEncodedVideoFrame::frame_id,
107 testing::Eq(10))))
108 .WillOnce(testing::Invoke(
109 [&encoded_image](int frame_id,
110 const MediaTransportEncodedVideoFrame& frame) {
111 EXPECT_NE(frame.encoded_image()._buffer, encoded_image._buffer);
112 EXPECT_EQ(frame.encoded_image()._length, encoded_image._length);
113 EXPECT_EQ(
114 0, memcmp(frame.encoded_image()._buffer, encoded_image._buffer,
115 std::min(frame.encoded_image()._length,
116 encoded_image._length)));
117 }));
118
119 transport_pair.second()->SetReceiveVideoSink(&sink);
120 transport_pair.first()->SendVideoFrame(1,
121 CreateVideoFrame(10, encoded_image));
122
123 transport_pair.FlushAsyncInvokes();
124 transport_pair.second()->SetReceiveVideoSink(nullptr);
125}
126
Bjorn Mellem273d0292018-11-01 16:42:44 -0700127TEST(LoopbackMediaTransport, DataDeliveredToSink) {
128 std::unique_ptr<rtc::Thread> thread = rtc::Thread::Create();
129 thread->Start();
130 MediaTransportPair transport_pair(thread.get());
131
132 MockDataChannelSink sink;
133 transport_pair.first()->SetDataSink(&sink);
134
135 const int channel_id = 1;
136 EXPECT_CALL(sink,
137 OnDataReceived(
138 channel_id, DataMessageType::kText,
139 testing::Property<rtc::CopyOnWriteBuffer, const char*>(
140 &rtc::CopyOnWriteBuffer::cdata, testing::StrEq("foo"))));
141
142 SendDataParams params;
143 params.type = DataMessageType::kText;
144 rtc::CopyOnWriteBuffer buffer("foo");
145 transport_pair.second()->SendData(channel_id, params, buffer);
146
147 transport_pair.FlushAsyncInvokes();
148 transport_pair.first()->SetDataSink(nullptr);
149}
150
151TEST(LoopbackMediaTransport, CloseDeliveredToSink) {
152 std::unique_ptr<rtc::Thread> thread = rtc::Thread::Create();
153 thread->Start();
154 MediaTransportPair transport_pair(thread.get());
155
156 MockDataChannelSink first_sink;
157 transport_pair.first()->SetDataSink(&first_sink);
158
159 MockDataChannelSink second_sink;
160 transport_pair.second()->SetDataSink(&second_sink);
161
162 const int channel_id = 1;
163 {
164 testing::InSequence s;
165 EXPECT_CALL(second_sink, OnChannelClosing(channel_id));
166 EXPECT_CALL(second_sink, OnChannelClosed(channel_id));
167 EXPECT_CALL(first_sink, OnChannelClosed(channel_id));
168 }
169
170 transport_pair.first()->CloseChannel(channel_id);
171
172 transport_pair.FlushAsyncInvokes();
173 transport_pair.first()->SetDataSink(nullptr);
174 transport_pair.second()->SetDataSink(nullptr);
175}
176
Bjorn Mellem175aa2e2018-11-08 11:23:22 -0800177TEST(LoopbackMediaTransport, InitialStateDeliveredWhenCallbackSet) {
178 std::unique_ptr<rtc::Thread> thread = rtc::Thread::Create();
179 thread->Start();
180 MediaTransportPair transport_pair(thread.get());
181
182 MockStateCallback state_callback;
183
184 EXPECT_CALL(state_callback, OnStateChanged(MediaTransportState::kPending));
185 transport_pair.first()->SetMediaTransportStateCallback(&state_callback);
186 transport_pair.FlushAsyncInvokes();
187}
188
189TEST(LoopbackMediaTransport, ChangedStateDeliveredWhenCallbackSet) {
190 std::unique_ptr<rtc::Thread> thread = rtc::Thread::Create();
191 thread->Start();
192 MediaTransportPair transport_pair(thread.get());
193
194 transport_pair.SetState(MediaTransportState::kWritable);
195 transport_pair.FlushAsyncInvokes();
196
197 MockStateCallback state_callback;
198
199 EXPECT_CALL(state_callback, OnStateChanged(MediaTransportState::kWritable));
200 transport_pair.first()->SetMediaTransportStateCallback(&state_callback);
201 transport_pair.FlushAsyncInvokes();
202}
203
204TEST(LoopbackMediaTransport, StateChangeDeliveredToCallback) {
205 std::unique_ptr<rtc::Thread> thread = rtc::Thread::Create();
206 thread->Start();
207 MediaTransportPair transport_pair(thread.get());
208
209 MockStateCallback state_callback;
210
211 EXPECT_CALL(state_callback, OnStateChanged(MediaTransportState::kPending));
212 EXPECT_CALL(state_callback, OnStateChanged(MediaTransportState::kWritable));
213 transport_pair.first()->SetMediaTransportStateCallback(&state_callback);
214 transport_pair.SetState(MediaTransportState::kWritable);
215 transport_pair.FlushAsyncInvokes();
216}
217
Niels Möller2e47f7c2018-10-16 10:41:42 +0200218} // namespace webrtc