Chromium Code Reviews| 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/command_line.h" | |
| 5 #include "base/logging.h" | 6 #include "base/logging.h" |
| 7 #include "content/public/common/content_switches.h" | |
| 8 #include "content/renderer/media/mock_media_constraint_factory.h" | |
| 6 #include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h" | 9 #include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h" |
| 7 #include "content/renderer/media/webrtc_audio_capturer.h" | 10 #include "content/renderer/media/webrtc_audio_capturer.h" |
| 8 #include "content/renderer/media/webrtc_local_audio_track.h" | 11 #include "content/renderer/media/webrtc_local_audio_track.h" |
| 9 #include "media/audio/audio_parameters.h" | 12 #include "media/audio/audio_parameters.h" |
| 10 #include "media/base/audio_bus.h" | 13 #include "media/base/audio_bus.h" |
| 11 #include "testing/gmock/include/gmock/gmock.h" | 14 #include "testing/gmock/include/gmock/gmock.h" |
| 12 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 13 #include "third_party/WebKit/public/platform/WebMediaConstraints.h" | 16 #include "third_party/WebKit/public/platform/WebMediaConstraints.h" |
| 14 | 17 |
| 15 using ::testing::_; | 18 using ::testing::_; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 31 MOCK_METHOD1(SetAutomaticGainControl, void(bool enable)); | 34 MOCK_METHOD1(SetAutomaticGainControl, void(bool enable)); |
| 32 | 35 |
| 33 protected: | 36 protected: |
| 34 virtual ~MockCapturerSource() {} | 37 virtual ~MockCapturerSource() {} |
| 35 }; | 38 }; |
| 36 | 39 |
| 37 class MockPeerConnectionAudioSink : public PeerConnectionAudioSink { | 40 class MockPeerConnectionAudioSink : public PeerConnectionAudioSink { |
| 38 public: | 41 public: |
| 39 MockPeerConnectionAudioSink() {} | 42 MockPeerConnectionAudioSink() {} |
| 40 ~MockPeerConnectionAudioSink() {} | 43 ~MockPeerConnectionAudioSink() {} |
| 41 MOCK_METHOD9(OnData, int(const int16* audio_data, | 44 virtual int OnData(const int16* audio_data, int sample_rate, |
| 42 int sample_rate, | 45 int number_of_channels, int number_of_frames, |
| 43 int number_of_channels, | 46 const std::vector<int>& channels, |
| 44 int number_of_frames, | 47 int audio_delay_milliseconds, int current_volume, |
| 45 const std::vector<int>& channels, | 48 bool need_audio_processing, bool key_pressed) OVERRIDE { |
| 46 int audio_delay_milliseconds, | 49 EXPECT_EQ(sample_rate, params_.sample_rate()); |
| 47 int current_volume, | 50 EXPECT_EQ(number_of_channels, params_.channels()); |
| 48 bool need_audio_processing, | 51 EXPECT_EQ(number_of_frames, params_.frames_per_buffer()); |
| 49 bool key_pressed)); | 52 OnDataCallback(audio_data, channels, audio_delay_milliseconds, |
| 50 MOCK_METHOD1(OnSetFormat, void(const media::AudioParameters& params)); | 53 current_volume, need_audio_processing, key_pressed); |
| 54 return 0; | |
| 55 } | |
| 56 MOCK_METHOD6(OnDataCallback, void(const int16* audio_data, | |
| 57 const std::vector<int>& channels, | |
| 58 int audio_delay_milliseconds, | |
| 59 int current_volume, | |
| 60 bool need_audio_processing, | |
| 61 bool key_pressed)); | |
| 62 virtual void OnSetFormat(const media::AudioParameters& params) OVERRIDE { | |
| 63 params_ = params; | |
| 64 FormatIsSet(); | |
| 65 } | |
| 66 MOCK_METHOD0(FormatIsSet, void()); | |
| 67 | |
| 68 const media::AudioParameters& params() const { return params_; } | |
|
tommi (sloooow) - chröme
2014/03/11 13:30:58
nit: audio_parameters() const
no longer working on chromium
2014/03/11 14:34:44
:) Just realized that it was not used. Removed.
| |
| 69 | |
| 70 private: | |
| 71 media::AudioParameters params_; | |
| 51 }; | 72 }; |
| 52 | 73 |
| 53 } // namespace | 74 } // namespace |
| 54 | 75 |
| 55 class WebRtcAudioCapturerTest : public testing::Test { | 76 class WebRtcAudioCapturerTest : public testing::Test { |
| 56 protected: | 77 protected: |
| 57 WebRtcAudioCapturerTest() | 78 WebRtcAudioCapturerTest() |
| 58 #if defined(OS_ANDROID) | 79 #if defined(OS_ANDROID) |
| 59 : params_(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, | 80 : params_(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |
| 60 media::CHANNEL_LAYOUT_STEREO, 48000, 16, 960) { | 81 media::CHANNEL_LAYOUT_STEREO, 48000, 16, 960) { |
| 61 // Android works with a buffer size bigger than 20ms. | 82 // Android works with a buffer size bigger than 20ms. |
| 62 #else | 83 #else |
| 63 : params_(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, | 84 : params_(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |
| 64 media::CHANNEL_LAYOUT_STEREO, 48000, 16, 128) { | 85 media::CHANNEL_LAYOUT_STEREO, 48000, 16, 128) { |
| 65 #endif | 86 #endif |
| 66 blink::WebMediaConstraints constraints; | 87 } |
| 88 | |
| 89 void EnableAudioTrackProcessing() { | |
| 90 CommandLine::ForCurrentProcess()->AppendSwitch( | |
| 91 switches::kEnableAudioTrackProcessing); | |
| 92 } | |
| 93 | |
| 94 void VerifyAudioParams(const blink::WebMediaConstraints& constraints, | |
| 95 bool need_audio_processing) { | |
| 67 capturer_ = WebRtcAudioCapturer::CreateCapturer( | 96 capturer_ = WebRtcAudioCapturer::CreateCapturer( |
| 68 -1, StreamDeviceInfo(MEDIA_DEVICE_AUDIO_CAPTURE, | 97 -1, StreamDeviceInfo(MEDIA_DEVICE_AUDIO_CAPTURE, |
| 69 "", "", params_.sample_rate(), | 98 "", "", params_.sample_rate(), |
| 70 params_.channel_layout(), | 99 params_.channel_layout(), |
| 71 params_.frames_per_buffer()), | 100 params_.frames_per_buffer()), |
| 72 constraints, | 101 constraints, NULL); |
| 73 NULL); | |
| 74 capturer_source_ = new MockCapturerSource(); | 102 capturer_source_ = new MockCapturerSource(); |
| 75 EXPECT_CALL(*capturer_source_.get(), Initialize(_, capturer_.get(), -1)); | 103 EXPECT_CALL(*capturer_source_.get(), Initialize(_, capturer_.get(), -1)); |
| 76 capturer_->SetCapturerSourceForTesting(capturer_source_, params_); | 104 capturer_->SetCapturerSourceForTesting(capturer_source_, params_); |
| 77 | 105 |
| 78 EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true)); | 106 EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true)); |
| 79 EXPECT_CALL(*capturer_source_.get(), Start()); | 107 EXPECT_CALL(*capturer_source_.get(), Start()); |
| 80 scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter( | 108 scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter( |
| 81 WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); | 109 WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); |
| 82 track_.reset(new WebRtcLocalAudioTrack(adapter, capturer_, NULL)); | 110 track_.reset(new WebRtcLocalAudioTrack(adapter, capturer_, NULL)); |
| 83 static_cast<WebRtcLocalAudioSourceProvider*>( | 111 static_cast<WebRtcLocalAudioSourceProvider*>( |
| 84 track_->audio_source_provider())->SetSinkParamsForTesting(params_); | 112 track_->audio_source_provider())->SetSinkParamsForTesting(params_); |
| 85 track_->Start(); | 113 track_->Start(); |
| 114 | |
| 115 // Connect a mock sink to the track. | |
| 116 scoped_ptr<MockPeerConnectionAudioSink> sink( | |
| 117 new MockPeerConnectionAudioSink()); | |
| 118 track_->AddSink(sink.get()); | |
| 119 | |
| 120 int delay_ms = 65; | |
| 121 bool key_pressed = true; | |
| 122 double volume = 0.9; | |
| 123 // MaxVolume() in WebRtcAudioCapturer is hard-coded to return 255, we add | |
|
phoglund_chromium
2014/03/11 14:43:21
Nit: prefer blank line before comment.
no longer working on chromium
2014/03/11 15:22:30
Done.
| |
| 124 // 0.5 to do the correct truncation as how the production code does. | |
|
phoglund_chromium
2014/03/11 14:43:21
Nit: like the production code does.
no longer working on chromium
2014/03/11 15:22:30
Done.
| |
| 125 int expected_volume_value = volume * capturer_->MaxVolume() + 0.5; | |
| 126 scoped_ptr<media::AudioBus> audio_bus = media::AudioBus::Create(params_); | |
|
phoglund_chromium
2014/03/11 14:43:21
Alright, umm, so you do 0.9 * 255 = 229.5 and add
no longer working on chromium
2014/03/11 15:22:30
Hard-coding the value is not preferred in any sens
phoglund_chromium
2014/03/11 16:20:34
I think in tests it makes sense, since I think it
| |
| 127 audio_bus->Zero(); | |
| 128 | |
| 129 media::AudioCapturerSource::CaptureCallback* callback = | |
| 130 static_cast<media::AudioCapturerSource::CaptureCallback*>(capturer_); | |
| 131 // Verify the sink is getting the correct values. | |
|
phoglund_chromium
2014/03/11 14:43:21
Nit: blank line before comment.
no longer working on chromium
2014/03/11 15:22:30
Done.
| |
| 132 EXPECT_CALL(*sink, FormatIsSet()); | |
| 133 EXPECT_CALL(*sink, | |
| 134 OnDataCallback(_, _, delay_ms, expected_volume_value, | |
| 135 need_audio_processing, key_pressed)); | |
| 136 callback->Capture(audio_bus.get(), delay_ms, volume, key_pressed); | |
| 137 | |
| 138 // Verify the cached values in the capturer fits what we expect. | |
| 139 base::TimeDelta cached_delay; | |
| 140 int cached_volume = !expected_volume_value; | |
| 141 bool cached_key_pressed = !key_pressed; | |
| 142 capturer_->GetAudioProcessingParams(&cached_delay, &cached_volume, | |
| 143 &cached_key_pressed); | |
| 144 EXPECT_EQ(cached_delay.InMilliseconds(), delay_ms); | |
| 145 EXPECT_EQ(cached_volume, expected_volume_value); | |
| 146 EXPECT_EQ(cached_key_pressed, key_pressed); | |
| 147 | |
| 148 track_->RemoveSink(sink.get()); | |
| 149 EXPECT_CALL(*capturer_source_.get(), Stop()); | |
| 150 capturer_->Stop(); | |
| 86 } | 151 } |
| 87 | 152 |
| 88 media::AudioParameters params_; | 153 media::AudioParameters params_; |
| 89 scoped_refptr<MockCapturerSource> capturer_source_; | 154 scoped_refptr<MockCapturerSource> capturer_source_; |
| 90 scoped_refptr<WebRtcAudioCapturer> capturer_; | 155 scoped_refptr<WebRtcAudioCapturer> capturer_; |
| 91 scoped_ptr<WebRtcLocalAudioTrack> track_; | 156 scoped_ptr<WebRtcLocalAudioTrack> track_; |
| 92 }; | 157 }; |
| 93 | 158 |
| 94 // Pass the delay value, volume and key_pressed info via capture callback, and | 159 // Pass the delay value, volume and key_pressed info via capture callback, and |
| 95 // those values should be correctly stored and passed to the track. | 160 // those values should be correctly stored and passed to the track. |
| 96 TEST_F(WebRtcAudioCapturerTest, VerifyAudioParams) { | 161 TEST_F(WebRtcAudioCapturerTest, VerifyAudioParams) { |
| 97 // Connect a mock sink to the track. | 162 // Use constraints with default settings. |
| 98 scoped_ptr<MockPeerConnectionAudioSink> sink( | 163 blink::WebMediaConstraints constraints; |
| 99 new MockPeerConnectionAudioSink()); | 164 VerifyAudioParams(constraints, true); |
| 100 track_->AddSink(sink.get()); | 165 } |
| 101 | 166 |
| 102 int delay_ms = 65; | 167 TEST_F(WebRtcAudioCapturerTest, VerifyAudioParamsWithAudioProcessing) { |
| 103 bool key_pressed = true; | 168 EnableAudioTrackProcessing(); |
| 104 double volume = 0.9; | 169 // Turn off the default constraints. |
|
phoglund_chromium
2014/03/11 14:43:21
Perhaps explain why you turn off the default const
no longer working on chromium
2014/03/11 15:22:30
Done.
| |
| 105 // MaxVolume() in WebRtcAudioCapturer is hard-coded to return 255, we add 0.5 | 170 MockMediaConstraintFactory constraint_factory; |
| 106 // to do the correct truncation as how the production code does. | 171 constraint_factory.DisableDefaultAudioConstraints(); |
| 107 int expected_volume_value = volume * capturer_->MaxVolume() + 0.5; | 172 VerifyAudioParams(constraint_factory.CreateWebMediaConstraints(), false); |
| 108 scoped_ptr<media::AudioBus> audio_bus = media::AudioBus::Create(params_); | |
| 109 audio_bus->Zero(); | |
| 110 #if defined(OS_ANDROID) | |
| 111 const int expected_buffer_size = params_.sample_rate() / 100; | |
| 112 #else | |
| 113 const int expected_buffer_size = params_.frames_per_buffer(); | |
| 114 #endif | |
| 115 bool expected_need_audio_processing = true; | |
| 116 media::AudioCapturerSource::CaptureCallback* callback = | |
| 117 static_cast<media::AudioCapturerSource::CaptureCallback*>(capturer_); | |
| 118 // Verify the sink is getting the correct values. | |
| 119 EXPECT_CALL(*sink, OnSetFormat(_)); | |
| 120 EXPECT_CALL(*sink, | |
| 121 OnData(_, params_.sample_rate(), params_.channels(), | |
| 122 expected_buffer_size, _, delay_ms, | |
| 123 expected_volume_value, expected_need_audio_processing, | |
| 124 key_pressed)).Times(AtLeast(1)); | |
| 125 callback->Capture(audio_bus.get(), delay_ms, volume, key_pressed); | |
| 126 | |
| 127 // Verify the cached values in the capturer fits what we expect. | |
| 128 base::TimeDelta cached_delay; | |
| 129 int cached_volume = !expected_volume_value; | |
| 130 bool cached_key_pressed = !key_pressed; | |
| 131 capturer_->GetAudioProcessingParams(&cached_delay, &cached_volume, | |
| 132 &cached_key_pressed); | |
| 133 EXPECT_EQ(cached_delay.InMilliseconds(), delay_ms); | |
| 134 EXPECT_EQ(cached_volume, expected_volume_value); | |
| 135 EXPECT_EQ(cached_key_pressed, key_pressed); | |
| 136 | |
| 137 track_->RemoveSink(sink.get()); | |
| 138 EXPECT_CALL(*capturer_source_.get(), Stop()); | |
| 139 capturer_->Stop(); | |
| 140 } | 173 } |
| 141 | 174 |
| 142 } // namespace content | 175 } // namespace content |
| OLD | NEW |