Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Side by Side Diff: content/renderer/media/audio_renderer_impl_unittest.cc

Issue 9826023: Merge AudioRendererImpl and AudioRendererBase; add NullAudioSink (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 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/bind.h"
6 #include "base/bind_helpers.h"
7 #include "base/message_loop.h"
8 #include "base/process_util.h"
9 #include "base/synchronization/waitable_event.h"
10 #include "base/test/test_timeouts.h"
11 #include "base/time.h"
12 #include "content/common/child_process.h"
13 #include "content/common/child_thread.h"
14 #include "content/renderer/media/audio_renderer_impl.h"
15 #include "content/renderer/mock_content_renderer_client.h"
16 #include "content/renderer/render_process.h"
17 #include "content/renderer/render_thread_impl.h"
18 #include "ipc/ipc_channel.h"
19 #include "media/base/data_buffer.h"
20 #include "media/base/mock_callback.h"
21 #include "media/base/mock_filter_host.h"
22 #include "media/base/mock_filters.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24
25 using ::testing::Return;
26
27 namespace {
28 // This class is a mock of the child process singleton which is needed
29 // to be able to create a RenderThread object.
30 class MockRenderProcess : public RenderProcess {
31 public:
32 MockRenderProcess() {}
33 virtual ~MockRenderProcess() {}
34
35 // RenderProcess implementation.
36 virtual skia::PlatformCanvas* GetDrawingCanvas(TransportDIB** memory,
37 const gfx::Rect& rect) { return NULL; }
38 virtual void ReleaseTransportDIB(TransportDIB* memory) {}
39 virtual bool UseInProcessPlugins() const { return false; }
40 virtual void AddBindings(int bindings) {}
41 virtual int GetEnabledBindings() const { return 0; }
42 virtual bool HasInitializedMediaLibrary() const { return false; }
43
44 private:
45 DISALLOW_COPY_AND_ASSIGN(MockRenderProcess);
46 };
47 }
48
49 // This callback can be posted on the IO thread and will signal an event when
50 // done. The caller can then wait for this signal to ensure that no
51 // additional tasks remain in the task queue.
52 void WaitCallback(base::WaitableEvent* event) {
53 event->Signal();
54 }
55
56 // Class we would be testing.
57 class TestAudioRendererImpl : public AudioRendererImpl {
58 public:
59 explicit TestAudioRendererImpl(media::AudioRendererSink* sink)
60 : AudioRendererImpl(sink) {
61 }
62 };
63
64 class AudioRendererImplTest
65 : public ::testing::Test,
66 public IPC::Channel::Listener {
67 public:
68 // IPC::Channel::Listener implementation.
69 virtual bool OnMessageReceived(const IPC::Message& message) {
70 NOTIMPLEMENTED();
71 return true;
72 }
73
74 static const int kSize;
75
76 AudioRendererImplTest() {}
77 virtual ~AudioRendererImplTest() {}
78
79 virtual void SetUp() {
80 // This part sets up a RenderThread environment to ensure that
81 // RenderThread::current() (<=> TLS pointer) is valid.
82 // Main parts are inspired by the RenderViewFakeResourcesTest.
83 // Note that, the IPC part is not utilized in this test.
84 content::GetContentClient()->set_renderer(&mock_content_renderer_client_);
85
86 static const char kThreadName[] = "RenderThread";
87 channel_.reset(new IPC::Channel(kThreadName,
88 IPC::Channel::MODE_SERVER, this));
89 ASSERT_TRUE(channel_->Connect());
90
91 mock_process_.reset(new MockRenderProcess);
92 render_thread_ = new RenderThreadImpl(kThreadName);
93
94 // Setup expectations for initialization.
95 decoder_ = new media::MockAudioDecoder();
96
97 EXPECT_CALL(*decoder_, bits_per_channel())
98 .WillRepeatedly(Return(16));
99 EXPECT_CALL(*decoder_, channel_layout())
100 .WillRepeatedly(Return(CHANNEL_LAYOUT_MONO));
101 EXPECT_CALL(*decoder_, samples_per_second())
102 .WillRepeatedly(Return(44100));
103
104 // Create a sink for the audio renderer.
105 scoped_refptr<media::AudioRendererSink> default_sink =
106 new AudioDevice();
107
108 // Create and initialize the audio renderer.
109 renderer_ = new TestAudioRendererImpl(default_sink.get());
110 renderer_->Initialize(decoder_,
111 media::NewExpectedStatusCB(media::PIPELINE_OK),
112 NewUnderflowClosure(), NewTimeClosure());
113
114 // We need an event to verify that all tasks are done before leaving
115 // our tests.
116 event_.reset(new base::WaitableEvent(false, false));
117 }
118
119 virtual void TearDown() {
120 mock_process_.reset();
121 }
122
123 MOCK_METHOD0(OnUnderflow, void());
124
125 base::Closure NewUnderflowClosure() {
126 return base::Bind(&AudioRendererImplTest::OnUnderflow,
127 base::Unretained(this));
128 }
129
130 void OnTimeCallback(
131 base::TimeDelta current_time, base::TimeDelta max_time) {
132 CHECK(current_time <= max_time);
133 }
134
135 media::AudioRenderer::TimeCB NewTimeClosure() {
136 return base::Bind(&AudioRendererImplTest::OnTimeCallback,
137 base::Unretained(this));
138 }
139
140 protected:
141 // Posts a final task to the IO message loop and waits for completion.
142 void WaitForIOThreadCompletion() {
143 ChildProcess::current()->io_message_loop()->PostTask(
144 FROM_HERE, base::Bind(&WaitCallback, base::Unretained(event_.get())));
145 EXPECT_TRUE(event_->TimedWait(
146 base::TimeDelta::FromMilliseconds(TestTimeouts::action_timeout_ms())));
147 }
148
149 MessageLoopForIO message_loop_;
150 content::MockContentRendererClient mock_content_renderer_client_;
151 scoped_ptr<IPC::Channel> channel_;
152 RenderThreadImpl* render_thread_; // owned by mock_process_
153 scoped_ptr<MockRenderProcess> mock_process_;
154 scoped_refptr<media::MockAudioDecoder> decoder_;
155 scoped_refptr<AudioRendererImpl> renderer_;
156 scoped_ptr<base::WaitableEvent> event_;
157
158 private:
159 DISALLOW_COPY_AND_ASSIGN(AudioRendererImplTest);
160 };
161
162 const int AudioRendererImplTest::kSize = 1024;
163
164 TEST_F(AudioRendererImplTest, SetPlaybackRate) {
165 // Execute SetPlaybackRate() codepath by toggling play/pause.
166 // These methods will be called on the pipeline thread but calling from
167 // here is fine for this test. Tasks will be posted internally on
168 // the IO thread.
169 renderer_->SetPlaybackRate(0.0f);
170 renderer_->SetPlaybackRate(1.0f);
171 renderer_->SetPlaybackRate(0.0f);
172
173 renderer_->Stop(media::NewExpectedClosure());
174 WaitForIOThreadCompletion();
175 }
176
177 TEST_F(AudioRendererImplTest, SetVolume) {
178 // Execute SetVolume() codepath.
179 // This method will be called on the pipeline thread IRL.
180 // Tasks will be posted internally on the IO thread.
181 renderer_->SetVolume(0.5f);
182
183 renderer_->Stop(media::NewExpectedClosure());
184 WaitForIOThreadCompletion();
185 }
186
187 TEST_F(AudioRendererImplTest, UpdateEarliestEndTime) {
188 renderer_->SetPlaybackRate(1.0f);
189 WaitForIOThreadCompletion();
190 base::Time time_now = base::Time(); // Null time by default.
191 renderer_->set_earliest_end_time(time_now);
192 renderer_->UpdateEarliestEndTime(renderer_->bytes_per_second(),
193 base::TimeDelta::FromMilliseconds(100),
194 time_now);
195 int time_delta = (renderer_->earliest_end_time() - time_now).InMilliseconds();
196 EXPECT_EQ(1100, time_delta);
197 renderer_->Stop(media::NewExpectedClosure());
198 WaitForIOThreadCompletion();
199 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698