Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / renderer / media / webrtc_audio_renderer_unittest.cc
1 // Copyright 2014 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 <vector>
6
7 #include "content/renderer/media/audio_device_factory.h"
8 #include "content/renderer/media/audio_message_filter.h"
9 #include "content/renderer/media/media_stream_audio_renderer.h"
10 #include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
11 #include "content/renderer/media/webrtc_audio_device_impl.h"
12 #include "content/renderer/media/webrtc_audio_renderer.h"
13 #include "media/audio/audio_output_device.h"
14 #include "media/audio/audio_output_ipc.h"
15 #include "media/base/audio_bus.h"
16 #include "media/base/mock_audio_renderer_sink.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h"
20
21 using testing::Return;
22
23 namespace content {
24
25 namespace {
26
27 const int kHardwareSampleRate = 44100;
28 const int kHardwareBufferSize = 512;
29
30 class MockAudioOutputIPC : public media::AudioOutputIPC {
31  public:
32   MockAudioOutputIPC() {}
33   virtual ~MockAudioOutputIPC() {}
34
35   MOCK_METHOD3(CreateStream, void(media::AudioOutputIPCDelegate* delegate,
36                                   const media::AudioParameters& params,
37                                   int session_id));
38   MOCK_METHOD0(PlayStream, void());
39   MOCK_METHOD0(PauseStream, void());
40   MOCK_METHOD0(CloseStream, void());
41   MOCK_METHOD1(SetVolume, void(double volume));
42 };
43
44 class FakeAudioOutputDevice
45     : NON_EXPORTED_BASE(public media::AudioOutputDevice) {
46  public:
47   FakeAudioOutputDevice(
48       scoped_ptr<media::AudioOutputIPC> ipc,
49       const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
50       : AudioOutputDevice(ipc.Pass(),
51                           io_task_runner) {}
52   MOCK_METHOD0(Start, void());
53   MOCK_METHOD0(Stop, void());
54   MOCK_METHOD0(Pause, void());
55   MOCK_METHOD0(Play, void());
56   MOCK_METHOD1(SetVolume, bool(double volume));
57
58  protected:
59   virtual ~FakeAudioOutputDevice() {}
60 };
61
62 class MockAudioDeviceFactory : public AudioDeviceFactory {
63  public:
64   MockAudioDeviceFactory() {}
65   virtual ~MockAudioDeviceFactory() {}
66   MOCK_METHOD1(CreateOutputDevice, media::AudioOutputDevice*(int));
67   MOCK_METHOD1(CreateInputDevice, media::AudioInputDevice*(int));
68 };
69
70 class MockAudioRendererSource : public WebRtcAudioRendererSource {
71  public:
72   MockAudioRendererSource() {}
73   virtual ~MockAudioRendererSource() {}
74   MOCK_METHOD4(RenderData, void(media::AudioBus* audio_bus,
75                                 int sample_rate,
76                                 int audio_delay_milliseconds,
77                                 base::TimeDelta* current_time));
78   MOCK_METHOD1(RemoveAudioRenderer, void(WebRtcAudioRenderer* renderer));
79 };
80
81 }  // namespace
82
83 class WebRtcAudioRendererTest : public testing::Test {
84  protected:
85   WebRtcAudioRendererTest()
86       : message_loop_(new base::MessageLoopForIO),
87         mock_ipc_(new MockAudioOutputIPC()),
88         mock_output_device_(new FakeAudioOutputDevice(
89             scoped_ptr<media::AudioOutputIPC>(mock_ipc_),
90             message_loop_->message_loop_proxy())),
91         factory_(new MockAudioDeviceFactory()),
92         source_(new MockAudioRendererSource()),
93         stream_(new rtc::RefCountedObject<MockMediaStream>("label")),
94         renderer_(new WebRtcAudioRenderer(stream_, 1, 1, 1, 44100,
95                                           kHardwareBufferSize)) {
96     EXPECT_CALL(*factory_.get(), CreateOutputDevice(1))
97         .WillOnce(Return(mock_output_device_.get()));
98     EXPECT_CALL(*mock_output_device_.get(), Start());
99     EXPECT_TRUE(renderer_->Initialize(source_.get()));
100     renderer_proxy_ = renderer_->CreateSharedAudioRendererProxy(stream_);
101   }
102
103   // Used to construct |mock_output_device_|.
104   scoped_ptr<base::MessageLoopForIO> message_loop_;
105   MockAudioOutputIPC* mock_ipc_;  // Owned by AudioOuputDevice.
106
107   scoped_refptr<FakeAudioOutputDevice> mock_output_device_;
108   scoped_ptr<MockAudioDeviceFactory> factory_;
109   scoped_ptr<MockAudioRendererSource> source_;
110   scoped_refptr<webrtc::MediaStreamInterface> stream_;
111   scoped_refptr<WebRtcAudioRenderer> renderer_;
112   scoped_refptr<MediaStreamAudioRenderer> renderer_proxy_;
113 };
114
115 // Verify that the renderer will be stopped if the only proxy is stopped.
116 TEST_F(WebRtcAudioRendererTest, StopRenderer) {
117   renderer_proxy_->Start();
118
119   // |renderer_| has only one proxy, stopping the proxy should stop the sink of
120   // |renderer_|.
121   EXPECT_CALL(*mock_output_device_.get(), Stop());
122   EXPECT_CALL(*source_.get(), RemoveAudioRenderer(renderer_.get()));
123   renderer_proxy_->Stop();
124 }
125
126 // Verify that the renderer will not be stopped unless the last proxy is
127 // stopped.
128 TEST_F(WebRtcAudioRendererTest, MultipleRenderers) {
129   renderer_proxy_->Start();
130
131   // Create a vector of renderer proxies from the |renderer_|.
132   std::vector<scoped_refptr<MediaStreamAudioRenderer> > renderer_proxies_;
133   static const int kNumberOfRendererProxy = 5;
134   for (int i = 0; i < kNumberOfRendererProxy; ++i) {
135     scoped_refptr<MediaStreamAudioRenderer> renderer_proxy(
136         renderer_->CreateSharedAudioRendererProxy(stream_));
137     renderer_proxy->Start();
138     renderer_proxies_.push_back(renderer_proxy);
139   }
140
141   // Stop the |renderer_proxy_| should not stop the sink since it is used by
142   // other proxies.
143   EXPECT_CALL(*mock_output_device_.get(), Stop()).Times(0);
144   renderer_proxy_->Stop();
145
146   for (int i = 0; i < kNumberOfRendererProxy; ++i) {
147     if (i != kNumberOfRendererProxy -1) {
148       EXPECT_CALL(*mock_output_device_.get(), Stop()).Times(0);
149     } else {
150       // When the last proxy is stopped, the sink will stop.
151       EXPECT_CALL(*source_.get(), RemoveAudioRenderer(renderer_.get()));
152       EXPECT_CALL(*mock_output_device_.get(), Stop());
153     }
154     renderer_proxies_[i]->Stop();
155   }
156 }
157
158 // Verify that the sink of the renderer is using the expected sample rate and
159 // buffer size.
160 TEST_F(WebRtcAudioRendererTest, VerifySinkParameters) {
161   renderer_proxy_->Start();
162 #if defined(OS_LINUX) || defined(OS_MACOSX)
163   static const int kExpectedBufferSize = kHardwareSampleRate / 100;
164 #elif defined(OS_ANDROID)
165   static const int kExpectedBufferSize = 2 * kHardwareSampleRate / 100;
166 #else
167   // Windows.
168   static const int kExpectedBufferSize = kHardwareBufferSize;
169 #endif
170   EXPECT_EQ(kExpectedBufferSize, renderer_->frames_per_buffer());
171   EXPECT_EQ(kHardwareSampleRate, renderer_->sample_rate());
172   EXPECT_EQ(2, renderer_->channels());
173
174   EXPECT_CALL(*mock_output_device_.get(), Stop());
175   EXPECT_CALL(*source_.get(), RemoveAudioRenderer(renderer_.get()));
176   renderer_proxy_->Stop();
177 }
178
179 }  // namespace content