Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / content / renderer / media / webrtc_audio_capturer_unittest.cc
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
3 // found in the LICENSE file.
4
5 #include "base/command_line.h"
6 #include "base/logging.h"
7 #include "content/public/common/content_switches.h"
8 #include "content/renderer/media/mock_media_constraint_factory.h"
9 #include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h"
10 #include "content/renderer/media/webrtc_audio_capturer.h"
11 #include "content/renderer/media/webrtc_local_audio_track.h"
12 #include "media/audio/audio_parameters.h"
13 #include "media/base/audio_bus.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
17
18 using ::testing::_;
19 using ::testing::AtLeast;
20
21 namespace content {
22
23 namespace {
24
25 class MockCapturerSource : public media::AudioCapturerSource {
26  public:
27   MockCapturerSource() {}
28   MOCK_METHOD3(Initialize, void(const media::AudioParameters& params,
29                                 CaptureCallback* callback,
30                                 int session_id));
31   MOCK_METHOD0(Start, void());
32   MOCK_METHOD0(Stop, void());
33   MOCK_METHOD1(SetVolume, void(double volume));
34   MOCK_METHOD1(SetAutomaticGainControl, void(bool enable));
35
36  protected:
37   virtual ~MockCapturerSource() {}
38 };
39
40 class MockPeerConnectionAudioSink : public PeerConnectionAudioSink {
41  public:
42   MockPeerConnectionAudioSink() {}
43   ~MockPeerConnectionAudioSink() {}
44   virtual int OnData(const int16* audio_data, int sample_rate,
45                      int number_of_channels, int number_of_frames,
46                      const std::vector<int>& channels,
47                      int audio_delay_milliseconds, int current_volume,
48                      bool need_audio_processing, bool key_pressed) OVERRIDE {
49     EXPECT_EQ(sample_rate, params_.sample_rate());
50     EXPECT_EQ(number_of_channels, params_.channels());
51     EXPECT_EQ(number_of_frames, params_.frames_per_buffer());
52     OnDataCallback(audio_data, channels, audio_delay_milliseconds,
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  private:
69   media::AudioParameters params_;
70 };
71
72 }  // namespace
73
74 class WebRtcAudioCapturerTest : public testing::Test {
75  protected:
76   WebRtcAudioCapturerTest()
77 #if defined(OS_ANDROID)
78       : params_(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
79                 media::CHANNEL_LAYOUT_STEREO, 48000, 16, 960) {
80     // Android works with a buffer size bigger than 20ms.
81 #else
82       : params_(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
83                 media::CHANNEL_LAYOUT_STEREO, 48000, 16, 128) {
84 #endif
85   }
86
87   void DisableAudioTrackProcessing() {
88     CommandLine::ForCurrentProcess()->AppendSwitch(
89         switches::kDisableAudioTrackProcessing);
90   }
91
92   void VerifyAudioParams(const blink::WebMediaConstraints& constraints,
93                          bool need_audio_processing) {
94     capturer_ = WebRtcAudioCapturer::CreateCapturer(
95         -1, StreamDeviceInfo(MEDIA_DEVICE_AUDIO_CAPTURE,
96                              "", "", params_.sample_rate(),
97                              params_.channel_layout(),
98                              params_.frames_per_buffer()),
99         constraints, NULL, NULL);
100     capturer_source_ = new MockCapturerSource();
101     EXPECT_CALL(*capturer_source_.get(), Initialize(_, capturer_.get(), -1));
102     EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true));
103     EXPECT_CALL(*capturer_source_.get(), Start());
104     capturer_->SetCapturerSourceForTesting(capturer_source_, params_);
105
106     scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter(
107         WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL));
108     track_.reset(new WebRtcLocalAudioTrack(adapter, capturer_, NULL));
109     track_->Start();
110
111     // Connect a mock sink to the track.
112     scoped_ptr<MockPeerConnectionAudioSink> sink(
113         new MockPeerConnectionAudioSink());
114     track_->AddSink(sink.get());
115
116     int delay_ms = 65;
117     bool key_pressed = true;
118     double volume = 0.9;
119
120     // MaxVolume() in WebRtcAudioCapturer is hard-coded to return 255, we add
121     // 0.5 to do the correct truncation like the production code does.
122     int expected_volume_value = volume * capturer_->MaxVolume() + 0.5;
123     scoped_ptr<media::AudioBus> audio_bus = media::AudioBus::Create(params_);
124     audio_bus->Zero();
125
126     media::AudioCapturerSource::CaptureCallback* callback =
127         static_cast<media::AudioCapturerSource::CaptureCallback*>(capturer_);
128
129     // Verify the sink is getting the correct values.
130     EXPECT_CALL(*sink, FormatIsSet());
131     EXPECT_CALL(*sink,
132                 OnDataCallback(_, _, delay_ms, expected_volume_value,
133                                need_audio_processing, key_pressed))
134         .Times(AtLeast(1));
135     callback->Capture(audio_bus.get(), delay_ms, volume, key_pressed);
136
137     // Verify the cached values in the capturer fits what we expect.
138     base::TimeDelta cached_delay;
139     int cached_volume = !expected_volume_value;
140     bool cached_key_pressed = !key_pressed;
141     capturer_->GetAudioProcessingParams(&cached_delay, &cached_volume,
142                                         &cached_key_pressed);
143     EXPECT_EQ(cached_delay.InMilliseconds(), delay_ms);
144     EXPECT_EQ(cached_volume, expected_volume_value);
145     EXPECT_EQ(cached_key_pressed, key_pressed);
146
147     track_->RemoveSink(sink.get());
148     EXPECT_CALL(*capturer_source_.get(), Stop());
149     capturer_->Stop();
150   }
151
152   media::AudioParameters params_;
153   scoped_refptr<MockCapturerSource> capturer_source_;
154   scoped_refptr<WebRtcAudioCapturer> capturer_;
155   scoped_ptr<WebRtcLocalAudioTrack> track_;
156 };
157
158 // Pass the delay value, volume and key_pressed info via capture callback, and
159 // those values should be correctly stored and passed to the track.
160 TEST_F(WebRtcAudioCapturerTest, VerifyAudioParamsWithoutAudioProcessing) {
161   DisableAudioTrackProcessing();
162   // Use constraints with default settings.
163   MockMediaConstraintFactory constraint_factory;
164   VerifyAudioParams(constraint_factory.CreateWebMediaConstraints(), true);
165 }
166
167 TEST_F(WebRtcAudioCapturerTest, VerifyAudioParamsWithAudioProcessing) {
168   // Turn off the default constraints to verify that the sink will get packets
169   // with a buffer size smaller than 10ms.
170   MockMediaConstraintFactory constraint_factory;
171   constraint_factory.DisableDefaultAudioConstraints();
172   VerifyAudioParams(constraint_factory.CreateWebMediaConstraints(), false);
173 }
174
175 TEST_F(WebRtcAudioCapturerTest, FailToCreateCapturerWithWrongConstraints) {
176   MockMediaConstraintFactory constraint_factory;
177   const std::string dummy_constraint = "dummy";
178   constraint_factory.AddMandatory(dummy_constraint, true);
179
180   scoped_refptr<WebRtcAudioCapturer> capturer(
181       WebRtcAudioCapturer::CreateCapturer(
182           0, StreamDeviceInfo(MEDIA_DEVICE_AUDIO_CAPTURE,
183                                "", "", params_.sample_rate(),
184                                params_.channel_layout(),
185                                params_.frames_per_buffer()),
186           constraint_factory.CreateWebMediaConstraints(), NULL, NULL)
187   );
188   EXPECT_TRUE(capturer == NULL);
189 }
190
191
192 }  // namespace content