Index: content/renderer/media/webrtc_audio_capturer_unittest.cc |
diff --git a/content/renderer/media/webrtc_audio_capturer_unittest.cc b/content/renderer/media/webrtc_audio_capturer_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..373b95ba50e17a28e962d3c769253082cb899ab2 |
--- /dev/null |
+++ b/content/renderer/media/webrtc_audio_capturer_unittest.cc |
@@ -0,0 +1,152 @@ |
+// Copyright 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "base/logging.h" |
+#include "build/build_config.h" |
+#include "content/public/renderer/media_stream_audio_sink.h" |
+#include "content/renderer/media/mock_constraint_factory.h" |
+#include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h" |
+#include "content/renderer/media/webrtc_audio_capturer.h" |
+#include "content/renderer/media/webrtc_local_audio_track.h" |
+#include "media/base/audio_bus.h" |
+#include "media/base/audio_parameters.h" |
+#include "testing/gmock/include/gmock/gmock.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "third_party/WebKit/public/platform/WebMediaConstraints.h" |
+ |
+using ::testing::_; |
+using ::testing::AtLeast; |
+ |
+namespace content { |
+ |
+namespace { |
+ |
+class MockCapturerSource : public media::AudioCapturerSource { |
+ public: |
+ MockCapturerSource() {} |
+ MOCK_METHOD3(Initialize, void(const media::AudioParameters& params, |
+ CaptureCallback* callback, |
+ int session_id)); |
+ MOCK_METHOD0(Start, void()); |
+ MOCK_METHOD0(Stop, void()); |
+ MOCK_METHOD1(SetVolume, void(double volume)); |
+ MOCK_METHOD1(SetAutomaticGainControl, void(bool enable)); |
+ |
+ protected: |
+ ~MockCapturerSource() override {} |
+}; |
+ |
+class MockMediaStreamAudioSink : public MediaStreamAudioSink { |
+ public: |
+ MockMediaStreamAudioSink() {} |
+ ~MockMediaStreamAudioSink() override {} |
+ void OnData(const media::AudioBus& audio_bus, |
+ base::TimeTicks estimated_capture_time) override { |
+ EXPECT_EQ(audio_bus.channels(), params_.channels()); |
+ EXPECT_EQ(audio_bus.frames(), params_.frames_per_buffer()); |
+ EXPECT_FALSE(estimated_capture_time.is_null()); |
+ OnDataCallback(); |
+ } |
+ MOCK_METHOD0(OnDataCallback, void()); |
+ void OnSetFormat(const media::AudioParameters& params) override { |
+ params_ = params; |
+ FormatIsSet(); |
+ } |
+ MOCK_METHOD0(FormatIsSet, void()); |
+ |
+ private: |
+ media::AudioParameters params_; |
+}; |
+ |
+} // namespace |
+ |
+class WebRtcAudioCapturerTest : public testing::Test { |
+ protected: |
+ WebRtcAudioCapturerTest() |
+#if defined(OS_ANDROID) |
+ : params_(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |
+ media::CHANNEL_LAYOUT_STEREO, 48000, 16, 960) { |
+ // Android works with a buffer size bigger than 20ms. |
+#else |
+ : params_(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |
+ media::CHANNEL_LAYOUT_STEREO, 48000, 16, 128) { |
+#endif |
+ } |
+ |
+ void VerifyAudioParams(const blink::WebMediaConstraints& constraints, |
+ bool need_audio_processing) { |
+ const std::unique_ptr<WebRtcAudioCapturer> capturer = |
+ WebRtcAudioCapturer::CreateCapturer( |
+ -1, StreamDeviceInfo( |
+ MEDIA_DEVICE_AUDIO_CAPTURE, "", "", params_.sample_rate(), |
+ params_.channel_layout(), params_.frames_per_buffer()), |
+ constraints, nullptr, nullptr); |
+ const scoped_refptr<MockCapturerSource> capturer_source( |
+ new MockCapturerSource()); |
+ EXPECT_CALL(*capturer_source.get(), Initialize(_, capturer.get(), -1)); |
+ EXPECT_CALL(*capturer_source.get(), SetAutomaticGainControl(true)); |
+ EXPECT_CALL(*capturer_source.get(), Start()); |
+ capturer->SetCapturerSource(capturer_source, params_); |
+ |
+ scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter( |
+ WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); |
+ const std::unique_ptr<WebRtcLocalAudioTrack> track( |
+ new WebRtcLocalAudioTrack(adapter.get())); |
+ capturer->AddTrack(track.get()); |
+ |
+ // Connect a mock sink to the track. |
+ std::unique_ptr<MockMediaStreamAudioSink> sink( |
+ new MockMediaStreamAudioSink()); |
+ track->AddSink(sink.get()); |
+ |
+ int delay_ms = 65; |
+ bool key_pressed = true; |
+ double volume = 0.9; |
+ |
+ std::unique_ptr<media::AudioBus> audio_bus = |
+ media::AudioBus::Create(params_); |
+ audio_bus->Zero(); |
+ |
+ media::AudioCapturerSource::CaptureCallback* callback = |
+ static_cast<media::AudioCapturerSource::CaptureCallback*>( |
+ capturer.get()); |
+ |
+ // Verify the sink is getting the correct values. |
+ EXPECT_CALL(*sink, FormatIsSet()); |
+ EXPECT_CALL(*sink, OnDataCallback()).Times(AtLeast(1)); |
+ callback->Capture(audio_bus.get(), delay_ms, volume, key_pressed); |
+ |
+ track->RemoveSink(sink.get()); |
+ EXPECT_CALL(*capturer_source.get(), Stop()); |
+ capturer->Stop(); |
+ } |
+ |
+ media::AudioParameters params_; |
+}; |
+ |
+TEST_F(WebRtcAudioCapturerTest, VerifyAudioParamsWithAudioProcessing) { |
+ // Turn off the default constraints to verify that the sink will get packets |
+ // with a buffer size smaller than 10ms. |
+ MockConstraintFactory constraint_factory; |
+ constraint_factory.DisableDefaultAudioConstraints(); |
+ VerifyAudioParams(constraint_factory.CreateWebMediaConstraints(), false); |
+} |
+ |
+TEST_F(WebRtcAudioCapturerTest, FailToCreateCapturerWithWrongConstraints) { |
+ MockConstraintFactory constraint_factory; |
+ const std::string dummy_constraint = "dummy"; |
+ // Set a non-audio constraint. |
+ constraint_factory.basic().width.setExact(240); |
+ |
+ std::unique_ptr<WebRtcAudioCapturer> capturer( |
+ WebRtcAudioCapturer::CreateCapturer( |
+ 0, StreamDeviceInfo(MEDIA_DEVICE_AUDIO_CAPTURE, "", "", |
+ params_.sample_rate(), params_.channel_layout(), |
+ params_.frames_per_buffer()), |
+ constraint_factory.CreateWebMediaConstraints(), NULL, NULL)); |
+ EXPECT_TRUE(capturer.get() == NULL); |
+} |
+ |
+ |
+} // namespace content |