Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(353)

Side by Side Diff: remoting/protocol/connection_unittest.cc

Issue 2371323007: Add audio support in WebrtcConnectionToHost, audio unittest (Closed)
Patch Set: more reliable test Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « remoting/protocol/BUILD.gn ('k') | remoting/protocol/session_config.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #define _USE_MATH_DEFINES // For VC++ to get M_PI. This has to be first.
6
5 #include <utility> 7 #include <utility>
6 8
7 #include "base/bind.h" 9 #include "base/bind.h"
8 #include "base/macros.h" 10 #include "base/macros.h"
9 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
10 #include "base/message_loop/message_loop.h" 12 #include "base/message_loop/message_loop.h"
11 #include "base/run_loop.h" 13 #include "base/run_loop.h"
12 #include "remoting/base/constants.h" 14 #include "remoting/base/constants.h"
15 #include "remoting/proto/audio.pb.h"
16 #include "remoting/protocol/audio_source.h"
17 #include "remoting/protocol/audio_stream.h"
18 #include "remoting/protocol/audio_stub.h"
13 #include "remoting/protocol/fake_session.h" 19 #include "remoting/protocol/fake_session.h"
14 #include "remoting/protocol/fake_video_renderer.h" 20 #include "remoting/protocol/fake_video_renderer.h"
15 #include "remoting/protocol/ice_connection_to_client.h" 21 #include "remoting/protocol/ice_connection_to_client.h"
16 #include "remoting/protocol/ice_connection_to_host.h" 22 #include "remoting/protocol/ice_connection_to_host.h"
17 #include "remoting/protocol/protocol_mock_objects.h" 23 #include "remoting/protocol/protocol_mock_objects.h"
18 #include "remoting/protocol/transport_context.h" 24 #include "remoting/protocol/transport_context.h"
19 #include "remoting/protocol/video_stream.h" 25 #include "remoting/protocol/video_stream.h"
20 #include "remoting/protocol/webrtc_connection_to_client.h" 26 #include "remoting/protocol/webrtc_connection_to_client.h"
21 #include "remoting/protocol/webrtc_connection_to_host.h" 27 #include "remoting/protocol/webrtc_connection_to_host.h"
22 #include "testing/gmock/include/gmock/gmock.h" 28 #include "testing/gmock/include/gmock/gmock.h"
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 92
87 callback_->OnCaptureResult(webrtc::DesktopCapturer::Result::SUCCESS, 93 callback_->OnCaptureResult(webrtc::DesktopCapturer::Result::SUCCESS,
88 std::move(frame)); 94 std::move(frame));
89 } 95 }
90 96
91 private: 97 private:
92 Callback* callback_ = nullptr; 98 Callback* callback_ = nullptr;
93 bool first_frame_sent_ = false; 99 bool first_frame_sent_ = false;
94 }; 100 };
95 101
102 static const int kAudioSampleRate = AudioPacket::SAMPLING_RATE_48000;
103 static const int kAudioPacketDurationMs = 50;
104 static constexpr int kSamplesPerAudioPacket =
105 kAudioSampleRate * kAudioPacketDurationMs /
106 base::Time::kMillisecondsPerSecond;
107 static constexpr base::TimeDelta kAudioPacketDuration =
108 base::TimeDelta::FromMilliseconds(kAudioPacketDurationMs);
109
110 static const int kAudioChannels = 2;
111
112 static const int kTestAudioSignalFrequencyLeftHz = 3000;
113 static const int kTestAudioSignalFrequencyRightHz = 2000;
114
115 class TestAudioSource : public AudioSource {
116 public:
117 TestAudioSource() {}
118 ~TestAudioSource() override {}
119
120 // AudioSource interface.
121 bool Start(const PacketCapturedCallback& callback) override {
122 callback_ = callback;
123 timer_.Start(FROM_HERE, kAudioPacketDuration,
124 base::Bind(&TestAudioSource::GenerateAudioSamples,
125 base::Unretained(this)));
126 return true;
127 }
128
129 private:
130 static int16_t GetSampleValue(double pos, int frequency) {
131 const int kMaxSampleValue = 32767;
132 return static_cast<int>(
133 sin(pos * 2 * M_PI * frequency / kAudioSampleRate) * kMaxSampleValue +
134 0.5);
135 }
136
137 void GenerateAudioSamples() {
138 std::vector<int16_t> data(kSamplesPerAudioPacket * kAudioChannels);
139 for (int i = 0; i < kSamplesPerAudioPacket; ++i) {
140 data[i * kAudioChannels] = GetSampleValue(
141 position_samples_ + i, kTestAudioSignalFrequencyLeftHz);
142 data[i * kAudioChannels + 1] = GetSampleValue(
143 position_samples_ + i, kTestAudioSignalFrequencyRightHz);
144 }
145 position_samples_ += kSamplesPerAudioPacket;
146
147 std::unique_ptr<AudioPacket> packet(new AudioPacket());
148 packet->add_data(reinterpret_cast<char*>(&(data[0])),
149 kSamplesPerAudioPacket * kAudioChannels * sizeof(int16_t));
150 packet->set_encoding(AudioPacket::ENCODING_RAW);
151 packet->set_sampling_rate(AudioPacket::SAMPLING_RATE_48000);
152 packet->set_bytes_per_sample(AudioPacket::BYTES_PER_SAMPLE_2);
153 packet->set_channels(AudioPacket::CHANNELS_STEREO);
154 callback_.Run(std::move(packet));
155 }
156
157 PacketCapturedCallback callback_;
158 base::RepeatingTimer timer_;
159 int position_samples_ = 0;
160 };
161
162 class FakeAudioPlayer : public AudioStub {
163 public:
164 FakeAudioPlayer() : weak_factory_(this) {}
165 ~FakeAudioPlayer() override {}
166
167 // AudioStub interface.
168 void ProcessAudioPacket(std::unique_ptr<AudioPacket> packet,
169 const base::Closure& done) override {
170 EXPECT_EQ(AudioPacket::ENCODING_RAW, packet->encoding());
171 EXPECT_EQ(AudioPacket::SAMPLING_RATE_48000, packet->sampling_rate());
172 EXPECT_EQ(AudioPacket::BYTES_PER_SAMPLE_2, packet->bytes_per_sample());
173 EXPECT_EQ(AudioPacket::CHANNELS_STEREO, packet->channels());
174
175 data_.insert(data_.end(), packet->data(0).begin(), packet->data(0).end());
176
177 if (run_loop_ && data_.size() >= samples_expected_ * 4)
178 run_loop_->Quit();
179
180 if (!done.is_null())
181 done.Run();
182 }
183
184 void WaitForSamples(size_t samples_expected) {
185 samples_expected_ = samples_expected;
186 base::RunLoop run_loop;
187 run_loop_ = &run_loop;
188 run_loop.Run();
189 run_loop_ = nullptr;
190 }
191
192 void Verify() {
193 const int16_t* data = reinterpret_cast<const int16_t*>(data_.data());
194 int num_samples = data_.size() / kAudioChannels / sizeof(int16_t);
195
196 int skipped_samples = 0;
197 while (skipped_samples < num_samples &&
198 data[skipped_samples * kAudioChannels] == 0 &&
199 data[skipped_samples * kAudioChannels + 1] == 0) {
200 skipped_samples += kAudioChannels;
201 }
202
203 // Estimate signal frequency by counting how often it crosses 0.
204 int left = 0;
205 int right = 0;
206 for (int i = skipped_samples + 1; i < num_samples; ++i) {
207 if (data[(i - 1) * kAudioChannels] < 0 && data[i * kAudioChannels] >= 0) {
208 ++left;
209 }
210 if (data[(i - 1) * kAudioChannels + 1] < 0 &&
211 data[i * kAudioChannels + 1] >= 0) {
212 ++right;
213 }
214 }
215 int left_hz = (left * kAudioSampleRate / (num_samples - skipped_samples));
216 EXPECT_LE(kTestAudioSignalFrequencyLeftHz - 50, left_hz);
217 EXPECT_GE(kTestAudioSignalFrequencyLeftHz + 50, left_hz);
218 int right_hz = (right * kAudioSampleRate / (num_samples - skipped_samples));
219 EXPECT_LE(kTestAudioSignalFrequencyRightHz - 50, right_hz);
220 EXPECT_GE(kTestAudioSignalFrequencyRightHz + 50, right_hz);
221 }
222
223 base::WeakPtr<AudioStub> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
224
225 private:
226 std::vector<char> data_;
227 base::RunLoop* run_loop_ = nullptr;
228 size_t samples_expected_ = 0;
229
230 base::WeakPtrFactory<FakeAudioPlayer> weak_factory_;
231 };
232
96 } // namespace 233 } // namespace
97 234
98 class ConnectionTest : public testing::Test, 235 class ConnectionTest : public testing::Test,
99 public testing::WithParamInterface<bool> { 236 public testing::WithParamInterface<bool> {
100 public: 237 public:
101 ConnectionTest() {} 238 ConnectionTest() {}
102 239
103 void DestroyHost() { 240 void DestroyHost() {
104 host_connection_.reset(); 241 host_connection_.reset();
105 run_loop_->Quit(); 242 run_loop_->Quit();
(...skipping 27 matching lines...) Expand all
133 // Setup host side. 270 // Setup host side.
134 host_connection_->SetEventHandler(&host_event_handler_); 271 host_connection_->SetEventHandler(&host_event_handler_);
135 host_connection_->set_clipboard_stub(&host_clipboard_stub_); 272 host_connection_->set_clipboard_stub(&host_clipboard_stub_);
136 host_connection_->set_host_stub(&host_stub_); 273 host_connection_->set_host_stub(&host_stub_);
137 host_connection_->set_input_stub(&host_input_stub_); 274 host_connection_->set_input_stub(&host_input_stub_);
138 275
139 // Setup client side. 276 // Setup client side.
140 client_connection_->set_client_stub(&client_stub_); 277 client_connection_->set_client_stub(&client_stub_);
141 client_connection_->set_clipboard_stub(&client_clipboard_stub_); 278 client_connection_->set_clipboard_stub(&client_clipboard_stub_);
142 client_connection_->set_video_renderer(&client_video_renderer_); 279 client_connection_->set_video_renderer(&client_video_renderer_);
280
281 client_connection_->InitializeAudio(message_loop_.task_runner(),
282 client_audio_player_.GetWeakPtr());
143 } 283 }
144 284
145 void Connect() { 285 void Connect() {
146 { 286 {
147 testing::InSequence sequence; 287 testing::InSequence sequence;
148 EXPECT_CALL(host_event_handler_, OnConnectionAuthenticating()); 288 EXPECT_CALL(host_event_handler_, OnConnectionAuthenticating());
149 EXPECT_CALL(host_event_handler_, OnConnectionAuthenticated()); 289 EXPECT_CALL(host_event_handler_, OnConnectionAuthenticated());
150 } 290 }
151 EXPECT_CALL(host_event_handler_, OnConnectionChannelsConnected()) 291 EXPECT_CALL(host_event_handler_, OnConnectionChannelsConnected())
152 .WillOnce(InvokeWithoutArgs(this, &ConnectionTest::OnHostConnected)); 292 .WillOnce(InvokeWithoutArgs(this, &ConnectionTest::OnHostConnected));
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 MockHostStub host_stub_; 399 MockHostStub host_stub_;
260 MockInputStub host_input_stub_; 400 MockInputStub host_input_stub_;
261 std::unique_ptr<ConnectionToClient> host_connection_; 401 std::unique_ptr<ConnectionToClient> host_connection_;
262 FakeSession* host_session_; // Owned by |host_connection_|. 402 FakeSession* host_session_; // Owned by |host_connection_|.
263 bool host_connected_ = false; 403 bool host_connected_ = false;
264 404
265 MockConnectionToHostEventCallback client_event_handler_; 405 MockConnectionToHostEventCallback client_event_handler_;
266 MockClientStub client_stub_; 406 MockClientStub client_stub_;
267 MockClipboardStub client_clipboard_stub_; 407 MockClipboardStub client_clipboard_stub_;
268 FakeVideoRenderer client_video_renderer_; 408 FakeVideoRenderer client_video_renderer_;
409 FakeAudioPlayer client_audio_player_;
269 std::unique_ptr<ConnectionToHost> client_connection_; 410 std::unique_ptr<ConnectionToHost> client_connection_;
270 FakeSession* client_session_; // Owned by |client_connection_|. 411 FakeSession* client_session_; // Owned by |client_connection_|.
271 std::unique_ptr<FakeSession> owned_client_session_; 412 std::unique_ptr<FakeSession> owned_client_session_;
272 bool client_connected_ = false; 413 bool client_connected_ = false;
273 414
274 private: 415 private:
275 DISALLOW_COPY_AND_ASSIGN(ConnectionTest); 416 DISALLOW_COPY_AND_ASSIGN(ConnectionTest);
276 }; 417 };
277 418
278 INSTANTIATE_TEST_CASE_P(Ice, ConnectionTest, ::testing::Values(false)); 419 INSTANTIATE_TEST_CASE_P(Ice, ConnectionTest, ::testing::Values(false));
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 stats.host_stats.encode_delay + 572 stats.host_stats.encode_delay +
432 stats.host_stats.send_pending_delay <= 573 stats.host_stats.send_pending_delay <=
433 stats.client_stats.time_received); 574 stats.client_stats.time_received);
434 EXPECT_TRUE(stats.client_stats.time_received <= 575 EXPECT_TRUE(stats.client_stats.time_received <=
435 stats.client_stats.time_decoded); 576 stats.client_stats.time_decoded);
436 EXPECT_TRUE(stats.client_stats.time_decoded <= 577 EXPECT_TRUE(stats.client_stats.time_decoded <=
437 stats.client_stats.time_rendered); 578 stats.client_stats.time_rendered);
438 EXPECT_TRUE(stats.client_stats.time_rendered <= finish_time); 579 EXPECT_TRUE(stats.client_stats.time_rendered <= finish_time);
439 } 580 }
440 581
582 TEST_P(ConnectionTest, Audio) {
583 Connect();
584
585 std::unique_ptr<AudioStream> audio_stream =
586 host_connection_->StartAudioStream(base::MakeUnique<TestAudioSource>());
587
588 // Wait for 1 second worth of audio samples.
589 client_audio_player_.WaitForSamples(kAudioSampleRate * 2);
590 client_audio_player_.Verify();
591 }
592
441 } // namespace protocol 593 } // namespace protocol
442 } // namespace remoting 594 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/protocol/BUILD.gn ('k') | remoting/protocol/session_config.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698