| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 #include "base/synchronization/waitable_event.h" | 5 #include "base/synchronization/waitable_event.h" |
| 6 #include "base/test/test_timeouts.h" | 6 #include "base/test/test_timeouts.h" |
| 7 #include "content/renderer/media/webrtc_audio_capturer.h" | 7 #include "content/renderer/media/webrtc_audio_capturer.h" |
| 8 #include "content/renderer/media/webrtc_local_audio_track.h" | 8 #include "content/renderer/media/webrtc_local_audio_track.h" |
| 9 #include "media/audio/audio_parameters.h" | 9 #include "media/audio/audio_parameters.h" |
| 10 #include "media/base/audio_bus.h" | 10 #include "media/base/audio_bus.h" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 // base::PlatformThread::Delegate: | 42 // base::PlatformThread::Delegate: |
| 43 virtual void ThreadMain() OVERRIDE { | 43 virtual void ThreadMain() OVERRIDE { |
| 44 while (true) { | 44 while (true) { |
| 45 if (closure_.IsSignaled()) | 45 if (closure_.IsSignaled()) |
| 46 return; | 46 return; |
| 47 | 47 |
| 48 media::AudioCapturerSource::CaptureCallback* callback = | 48 media::AudioCapturerSource::CaptureCallback* callback = |
| 49 static_cast<media::AudioCapturerSource::CaptureCallback*>( | 49 static_cast<media::AudioCapturerSource::CaptureCallback*>( |
| 50 capturer_.get()); | 50 capturer_.get()); |
| 51 audio_bus_->Zero(); | 51 audio_bus_->Zero(); |
| 52 callback->Capture(audio_bus_.get(), 0, 0); | 52 callback->Capture(audio_bus_.get(), 0, 0, false); |
| 53 | 53 |
| 54 // Sleep 1ms to yield the resource for the main thread. | 54 // Sleep 1ms to yield the resource for the main thread. |
| 55 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1)); | 55 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1)); |
| 56 } | 56 } |
| 57 } | 57 } |
| 58 | 58 |
| 59 void Start() { | 59 void Start() { |
| 60 base::PlatformThread::CreateWithPriority( | 60 base::PlatformThread::CreateWithPriority( |
| 61 0, this, &thread_, base::kThreadPriority_RealtimeAudio); | 61 0, this, &thread_, base::kThreadPriority_RealtimeAudio); |
| 62 CHECK(!thread_.is_null()); | 62 CHECK(!thread_.is_null()); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 88 MOCK_METHOD1(SetAutomaticGainControl, void(bool enable)); | 88 MOCK_METHOD1(SetAutomaticGainControl, void(bool enable)); |
| 89 | 89 |
| 90 protected: | 90 protected: |
| 91 virtual ~MockCapturerSource() {} | 91 virtual ~MockCapturerSource() {} |
| 92 }; | 92 }; |
| 93 | 93 |
| 94 class MockWebRtcAudioCapturerSink : public WebRtcAudioCapturerSink { | 94 class MockWebRtcAudioCapturerSink : public WebRtcAudioCapturerSink { |
| 95 public: | 95 public: |
| 96 MockWebRtcAudioCapturerSink() {} | 96 MockWebRtcAudioCapturerSink() {} |
| 97 ~MockWebRtcAudioCapturerSink() {} | 97 ~MockWebRtcAudioCapturerSink() {} |
| 98 MOCK_METHOD5(CaptureData, void(const int16* audio_data, | 98 MOCK_METHOD6(CaptureData, |
| 99 int number_of_channels, | 99 void(const int16* audio_data, |
| 100 int number_of_frames, | 100 int number_of_channels, |
| 101 int audio_delay_milliseconds, | 101 int number_of_frames, |
| 102 double volume)); | 102 int audio_delay_milliseconds, |
| 103 double volume, |
| 104 bool key_pressed)); |
| 103 MOCK_METHOD1(SetCaptureFormat, void(const media::AudioParameters& params)); | 105 MOCK_METHOD1(SetCaptureFormat, void(const media::AudioParameters& params)); |
| 104 }; | 106 }; |
| 105 | 107 |
| 106 } // namespace | 108 } // namespace |
| 107 | 109 |
| 108 class WebRtcLocalAudioTrackTest : public ::testing::Test { | 110 class WebRtcLocalAudioTrackTest : public ::testing::Test { |
| 109 protected: | 111 protected: |
| 110 virtual void SetUp() OVERRIDE { | 112 virtual void SetUp() OVERRIDE { |
| 111 capturer_ = WebRtcAudioCapturer::CreateCapturer(); | 113 capturer_ = WebRtcAudioCapturer::CreateCapturer(); |
| 112 capturer_source_ = new MockCapturerSource(); | 114 capturer_source_ = new MockCapturerSource(); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 140 EXPECT_CALL(*capturer_source_.get(), Start()).WillOnce(Return()); | 142 EXPECT_CALL(*capturer_source_.get(), Start()).WillOnce(Return()); |
| 141 scoped_refptr<WebRtcLocalAudioTrack> track = | 143 scoped_refptr<WebRtcLocalAudioTrack> track = |
| 142 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); | 144 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); |
| 143 track->Start(); | 145 track->Start(); |
| 144 EXPECT_TRUE(track->enabled()); | 146 EXPECT_TRUE(track->enabled()); |
| 145 scoped_ptr<MockWebRtcAudioCapturerSink> sink( | 147 scoped_ptr<MockWebRtcAudioCapturerSink> sink( |
| 146 new MockWebRtcAudioCapturerSink()); | 148 new MockWebRtcAudioCapturerSink()); |
| 147 const media::AudioParameters params = capturer_->audio_parameters(); | 149 const media::AudioParameters params = capturer_->audio_parameters(); |
| 148 base::WaitableEvent event(false, false); | 150 base::WaitableEvent event(false, false); |
| 149 EXPECT_CALL(*sink, SetCaptureFormat(_)).WillOnce(Return()); | 151 EXPECT_CALL(*sink, SetCaptureFormat(_)).WillOnce(Return()); |
| 150 EXPECT_CALL(*sink, CaptureData( | 152 EXPECT_CALL( |
| 151 _, params.channels(), params.frames_per_buffer(), 0, 0)) | 153 *sink, |
| 154 CaptureData( |
| 155 _, params.channels(), params.frames_per_buffer(), 0, 0, false)) |
| 152 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event)); | 156 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event)); |
| 153 track->AddSink(sink.get()); | 157 track->AddSink(sink.get()); |
| 154 | 158 |
| 155 EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); | 159 EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); |
| 156 track->RemoveSink(sink.get()); | 160 track->RemoveSink(sink.get()); |
| 157 | 161 |
| 158 EXPECT_CALL(*capturer_source_.get(), Stop()).WillOnce(Return()); | 162 EXPECT_CALL(*capturer_source_.get(), Stop()).WillOnce(Return()); |
| 159 track->Stop(); | 163 track->Stop(); |
| 160 track = NULL; | 164 track = NULL; |
| 161 } | 165 } |
| 162 | 166 |
| 163 // The same setup as ConnectAndDisconnectOneSink, but enable and disable the | 167 // The same setup as ConnectAndDisconnectOneSink, but enable and disable the |
| 164 // audio track on the fly. When the audio track is disabled, there is no data | 168 // audio track on the fly. When the audio track is disabled, there is no data |
| 165 // callback to the sink; when the audio track is enabled, there comes data | 169 // callback to the sink; when the audio track is enabled, there comes data |
| 166 // callback. | 170 // callback. |
| 167 // TODO(xians): Enable this test after resolving the racing issue that TSAN | 171 // TODO(xians): Enable this test after resolving the racing issue that TSAN |
| 168 // reports on MediaStreamTrack::enabled(); | 172 // reports on MediaStreamTrack::enabled(); |
| 169 TEST_F(WebRtcLocalAudioTrackTest, DISABLED_DisableEnableAudioTrack) { | 173 TEST_F(WebRtcLocalAudioTrackTest, DISABLED_DisableEnableAudioTrack) { |
| 170 EXPECT_CALL(*capturer_source_.get(), Start()).WillOnce(Return()); | 174 EXPECT_CALL(*capturer_source_.get(), Start()).WillOnce(Return()); |
| 171 scoped_refptr<WebRtcLocalAudioTrack> track = | 175 scoped_refptr<WebRtcLocalAudioTrack> track = |
| 172 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); | 176 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); |
| 173 track->Start(); | 177 track->Start(); |
| 174 EXPECT_TRUE(track->enabled()); | 178 EXPECT_TRUE(track->enabled()); |
| 175 EXPECT_TRUE(track->set_enabled(false)); | 179 EXPECT_TRUE(track->set_enabled(false)); |
| 176 scoped_ptr<MockWebRtcAudioCapturerSink> sink( | 180 scoped_ptr<MockWebRtcAudioCapturerSink> sink( |
| 177 new MockWebRtcAudioCapturerSink()); | 181 new MockWebRtcAudioCapturerSink()); |
| 178 const media::AudioParameters params = capturer_->audio_parameters(); | 182 const media::AudioParameters params = capturer_->audio_parameters(); |
| 179 base::WaitableEvent event(false, false); | 183 base::WaitableEvent event(false, false); |
| 180 EXPECT_CALL(*sink, SetCaptureFormat(_)).WillOnce(Return()); | 184 EXPECT_CALL(*sink, SetCaptureFormat(_)).WillOnce(Return()); |
| 181 EXPECT_CALL(*sink, CaptureData( | 185 EXPECT_CALL( |
| 182 _, params.channels(), params.frames_per_buffer(), 0, 0)) | 186 *sink, |
| 187 CaptureData( |
| 188 _, params.channels(), params.frames_per_buffer(), 0, 0, false)) |
| 183 .Times(0); | 189 .Times(0); |
| 184 track->AddSink(sink.get()); | 190 track->AddSink(sink.get()); |
| 185 EXPECT_FALSE(event.TimedWait(TestTimeouts::tiny_timeout())); | 191 EXPECT_FALSE(event.TimedWait(TestTimeouts::tiny_timeout())); |
| 186 | 192 |
| 187 event.Reset(); | 193 event.Reset(); |
| 188 EXPECT_CALL(*sink, CaptureData( | 194 EXPECT_CALL( |
| 189 _, params.channels(), params.frames_per_buffer(), 0, 0)) | 195 *sink, |
| 196 CaptureData( |
| 197 _, params.channels(), params.frames_per_buffer(), 0, 0, false)) |
| 190 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event)); | 198 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event)); |
| 191 EXPECT_TRUE(track->set_enabled(true)); | 199 EXPECT_TRUE(track->set_enabled(true)); |
| 192 EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); | 200 EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout())); |
| 193 track->RemoveSink(sink.get()); | 201 track->RemoveSink(sink.get()); |
| 194 | 202 |
| 195 EXPECT_CALL(*capturer_source_.get(), Stop()).WillOnce(Return()); | 203 EXPECT_CALL(*capturer_source_.get(), Stop()).WillOnce(Return()); |
| 196 track->Stop(); | 204 track->Stop(); |
| 197 track = NULL; | 205 track = NULL; |
| 198 } | 206 } |
| 199 | 207 |
| 200 // Create multiple audio tracks and enable/disable them, verify that the audio | 208 // Create multiple audio tracks and enable/disable them, verify that the audio |
| 201 // callbacks appear/disappear. | 209 // callbacks appear/disappear. |
| 202 TEST_F(WebRtcLocalAudioTrackTest, MultipleAudioTracks) { | 210 TEST_F(WebRtcLocalAudioTrackTest, MultipleAudioTracks) { |
| 203 EXPECT_CALL(*capturer_source_.get(), Start()).WillOnce(Return()); | 211 EXPECT_CALL(*capturer_source_.get(), Start()).WillOnce(Return()); |
| 204 scoped_refptr<WebRtcLocalAudioTrack> track_1 = | 212 scoped_refptr<WebRtcLocalAudioTrack> track_1 = |
| 205 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); | 213 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); |
| 206 track_1->Start(); | 214 track_1->Start(); |
| 207 EXPECT_TRUE(track_1->enabled()); | 215 EXPECT_TRUE(track_1->enabled()); |
| 208 scoped_ptr<MockWebRtcAudioCapturerSink> sink_1( | 216 scoped_ptr<MockWebRtcAudioCapturerSink> sink_1( |
| 209 new MockWebRtcAudioCapturerSink()); | 217 new MockWebRtcAudioCapturerSink()); |
| 210 const media::AudioParameters params = capturer_->audio_parameters(); | 218 const media::AudioParameters params = capturer_->audio_parameters(); |
| 211 base::WaitableEvent event_1(false, false); | 219 base::WaitableEvent event_1(false, false); |
| 212 EXPECT_CALL(*sink_1, SetCaptureFormat(_)).WillOnce(Return()); | 220 EXPECT_CALL(*sink_1, SetCaptureFormat(_)).WillOnce(Return()); |
| 213 EXPECT_CALL(*sink_1, CaptureData( | 221 EXPECT_CALL( |
| 214 _, params.channels(), params.frames_per_buffer(), 0, 0)) | 222 *sink_1, |
| 223 CaptureData( |
| 224 _, params.channels(), params.frames_per_buffer(), 0, 0, false)) |
| 215 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_1)); | 225 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_1)); |
| 216 track_1->AddSink(sink_1.get()); | 226 track_1->AddSink(sink_1.get()); |
| 217 EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout())); | 227 EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout())); |
| 218 | 228 |
| 219 scoped_refptr<WebRtcLocalAudioTrack> track_2 = | 229 scoped_refptr<WebRtcLocalAudioTrack> track_2 = |
| 220 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); | 230 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); |
| 221 track_2->Start(); | 231 track_2->Start(); |
| 222 EXPECT_TRUE(track_2->enabled()); | 232 EXPECT_TRUE(track_2->enabled()); |
| 223 | 233 |
| 224 // Verify both |sink_1| and |sink_2| get data. | 234 // Verify both |sink_1| and |sink_2| get data. |
| 225 event_1.Reset(); | 235 event_1.Reset(); |
| 226 base::WaitableEvent event_2(false, false); | 236 base::WaitableEvent event_2(false, false); |
| 227 | 237 |
| 228 scoped_ptr<MockWebRtcAudioCapturerSink> sink_2( | 238 scoped_ptr<MockWebRtcAudioCapturerSink> sink_2( |
| 229 new MockWebRtcAudioCapturerSink()); | 239 new MockWebRtcAudioCapturerSink()); |
| 230 EXPECT_CALL(*sink_2, SetCaptureFormat(_)).WillOnce(Return()); | 240 EXPECT_CALL(*sink_2, SetCaptureFormat(_)).WillOnce(Return()); |
| 231 EXPECT_CALL(*sink_1, CaptureData( | 241 EXPECT_CALL( |
| 232 _, params.channels(), params.frames_per_buffer(), 0, 0)) | 242 *sink_1, |
| 243 CaptureData( |
| 244 _, params.channels(), params.frames_per_buffer(), 0, 0, false)) |
| 233 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_1)); | 245 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_1)); |
| 234 EXPECT_CALL(*sink_2, CaptureData( | 246 EXPECT_CALL( |
| 235 _, params.channels(), params.frames_per_buffer(), 0, 0)) | 247 *sink_2, |
| 248 CaptureData( |
| 249 _, params.channels(), params.frames_per_buffer(), 0, 0, false)) |
| 236 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_2)); | 250 .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event_2)); |
| 237 track_2->AddSink(sink_2.get()); | 251 track_2->AddSink(sink_2.get()); |
| 238 EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout())); | 252 EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout())); |
| 239 EXPECT_TRUE(event_2.TimedWait(TestTimeouts::tiny_timeout())); | 253 EXPECT_TRUE(event_2.TimedWait(TestTimeouts::tiny_timeout())); |
| 240 | 254 |
| 241 track_1->RemoveSink(sink_1.get()); | 255 track_1->RemoveSink(sink_1.get()); |
| 242 track_1->Stop(); | 256 track_1->Stop(); |
| 243 track_1 = NULL; | 257 track_1 = NULL; |
| 244 | 258 |
| 245 EXPECT_CALL(*capturer_source_.get(), Stop()).WillOnce(Return()); | 259 EXPECT_CALL(*capturer_source_.get(), Stop()).WillOnce(Return()); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 264 } | 278 } |
| 265 | 279 |
| 266 // Start/Stop tracks and verify the capturer is correctly starting/stopping | 280 // Start/Stop tracks and verify the capturer is correctly starting/stopping |
| 267 // its source. | 281 // its source. |
| 268 TEST_F(WebRtcLocalAudioTrackTest, StartAndStopAudioTracks) { | 282 TEST_F(WebRtcLocalAudioTrackTest, StartAndStopAudioTracks) { |
| 269 // SetDefaultSink() should not trigger the Start() on |capturer_source_|. | 283 // SetDefaultSink() should not trigger the Start() on |capturer_source_|. |
| 270 base::WaitableEvent event(false, false); | 284 base::WaitableEvent event(false, false); |
| 271 scoped_ptr<MockWebRtcAudioCapturerSink> default_sink( | 285 scoped_ptr<MockWebRtcAudioCapturerSink> default_sink( |
| 272 new MockWebRtcAudioCapturerSink()); | 286 new MockWebRtcAudioCapturerSink()); |
| 273 EXPECT_CALL(*default_sink, SetCaptureFormat(_)).WillOnce(Return()); | 287 EXPECT_CALL(*default_sink, SetCaptureFormat(_)).WillOnce(Return()); |
| 274 EXPECT_CALL(*default_sink, CaptureData(_, _, _, 0, 0)) | 288 EXPECT_CALL(*default_sink, CaptureData(_, _, _, 0, 0, false)) |
| 275 .Times(AnyNumber()).WillRepeatedly(Return()); | 289 .Times(AnyNumber()).WillRepeatedly(Return()); |
| 276 capturer_->SetDefaultSink(default_sink.get()); | 290 capturer_->SetDefaultSink(default_sink.get()); |
| 277 EXPECT_CALL(*capturer_source_.get(), Start()).Times(0); | 291 EXPECT_CALL(*capturer_source_.get(), Start()).Times(0); |
| 278 EXPECT_FALSE(event.TimedWait(TestTimeouts::tiny_timeout())); | 292 EXPECT_FALSE(event.TimedWait(TestTimeouts::tiny_timeout())); |
| 279 | 293 |
| 280 // Starting the first audio track will start the |capturer_source_|. | 294 // Starting the first audio track will start the |capturer_source_|. |
| 281 event.Reset(); | 295 event.Reset(); |
| 282 EXPECT_CALL(*capturer_source_.get(), Start()).WillOnce(SignalEvent(&event)); | 296 EXPECT_CALL(*capturer_source_.get(), Start()).WillOnce(SignalEvent(&event)); |
| 283 scoped_refptr<WebRtcLocalAudioTrack> track_1 = | 297 scoped_refptr<WebRtcLocalAudioTrack> track_1 = |
| 284 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); | 298 WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 media::CHANNEL_LAYOUT_STEREO, | 341 media::CHANNEL_LAYOUT_STEREO, |
| 328 48000); | 342 48000); |
| 329 | 343 |
| 330 // Stop the track. | 344 // Stop the track. |
| 331 EXPECT_CALL(*new_source.get(), Stop()); | 345 EXPECT_CALL(*new_source.get(), Stop()); |
| 332 track->Stop(); | 346 track->Stop(); |
| 333 track = NULL; | 347 track = NULL; |
| 334 } | 348 } |
| 335 | 349 |
| 336 } // namespace content | 350 } // namespace content |
| OLD | NEW |