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

Side by Side Diff: content/browser/renderer_host/media/audio_input_sync_writer_unittest.cc

Issue 1302423006: Ensure that data is not overwritten in the audio input shared memory ring buffer that sits on the b… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed log call expectations for Android in unit test. Rebase. Created 5 years, 3 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
OLDNEW
(Empty)
1 // Copyright 2015 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/compiler_specific.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/sync_socket.h"
8 #include "base/time/time.h"
9 #include "content/browser/renderer_host/media/audio_input_sync_writer.h"
10 #include "content/public/test/test_browser_thread_bundle.h"
11 #include "media/audio/audio_parameters.h"
12 #include "media/base/audio_bus.h"
13 #include "media/base/channel_layout.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 using ::testing::_;
18 using base::TimeDelta;
19 using media::AudioBus;
20 using media::AudioParameters;
21
22 namespace content {
23
24 namespace {
25
26 // Number of audio buffers in the faked ring buffer.
27 const int kSegments = 10;
28
29 // Audio buffer parameters.
30 const int channels = 1;
31 const int sampling_frequency_hz = 16000;
32 const int frames = sampling_frequency_hz / 100; // 10 ms
33 const int bits_per_sample = 16;
34
35 // Faked ring buffer. Must be aligned.
36 #define DATA_ALIGNMENT 16
37 COMPILE_ASSERT(AudioBus::kChannelAlignment == DATA_ALIGNMENT,
38 Data_alignment_not_same_as_AudioBus);
39 ALIGNAS(DATA_ALIGNMENT) uint8 data[kSegments *
40 (sizeof(media::AudioInputBufferParameters) + frames * channels *
41 sizeof(float))];
42
43 } // namespace
44
45 // Mocked out sockets used for Send/ReceiveWithTimeout. Counts the number of
46 // outstanding reads, i.e. the diff between send and receive calls.
47 class MockCancelableSyncSocket : public base::CancelableSyncSocket {
48 public:
49 MockCancelableSyncSocket(int buffer_size)
50 : in_failure_mode_(false),
51 writes_(0),
52 reads_(0),
53 receives_(0),
54 buffer_size_(buffer_size),
55 read_buffer_index_(0) {}
56
57 size_t Send(const void* buffer, size_t length) override {
58 EXPECT_EQ(length, sizeof(uint32_t));
59
60 ++writes_;
61 EXPECT_LE(NumberOfBuffersFilled(), buffer_size_);
62 return length;
63 }
64
65 size_t Receive(void* buffer, size_t length) override {
66 EXPECT_EQ(0u, length % sizeof(uint32_t));
67
68 if (in_failure_mode_)
69 return 0;
70 if (receives_ == reads_)
71 return 0;
72
73 uint32_t* ptr = static_cast<uint32_t*>(buffer);
74 size_t received = 0;
75 for (; received < length / sizeof(uint32_t) && receives_ < reads_;
76 ++received, ++ptr) {
77 ++receives_;
78 EXPECT_LE(receives_, reads_);
79 *ptr = ++read_buffer_index_;
80 }
81 return received * sizeof(uint32_t);
82 }
83
84 size_t Peek() override {
85 return (reads_ - receives_) * sizeof(uint32_t);
86 }
87
88 // Simluates reading |buffers| number of buffers from the ring buffer.
89 void Read(int buffers) {
90 reads_ += buffers;
91 EXPECT_LE(reads_, writes_);
92 }
93
94 // When |in_failure_mode_| == true, the socket fails to receive.
95 void SetFailureMode(bool in_failure_mode) {
96 in_failure_mode_ = in_failure_mode;
97 }
98
99 int NumberOfBuffersFilled() { return writes_ - reads_; }
100
101 private:
102 bool in_failure_mode_;
103 int writes_;
104 int reads_;
105 int receives_;
106 int buffer_size_;
107 uint32_t read_buffer_index_;
108
109 DISALLOW_COPY_AND_ASSIGN(MockCancelableSyncSocket);
110 };
111
112 class AudioInputSyncWriterUnderTest : public AudioInputSyncWriter {
113 public:
114 AudioInputSyncWriterUnderTest(void* shared_memory,
115 size_t shared_memory_size,
116 int shared_memory_segment_count,
117 const media::AudioParameters& params,
118 base::CancelableSyncSocket* socket)
119 : AudioInputSyncWriter(shared_memory, shared_memory_size,
120 shared_memory_segment_count, params) {
121 socket_.reset(socket);
122 }
123
124 ~AudioInputSyncWriterUnderTest() override {}
125
126 MOCK_METHOD1(AddToNativeLog, void(const std::string& message));
127 };
128
129 class AudioInputSyncWriterTest : public testing::Test {
130 public:
131 AudioInputSyncWriterTest()
132 : socket_(nullptr) {
133 const media::ChannelLayout layout =
134 media::GuessChannelLayout(channels);
135 EXPECT_NE(media::ChannelLayout::CHANNEL_LAYOUT_UNSUPPORTED, layout);
136 AudioParameters audio_params(
137 AudioParameters::AUDIO_FAKE, layout, sampling_frequency_hz,
138 bits_per_sample, frames);
139
140 const uint32 segment_size =
141 sizeof(media::AudioInputBufferParameters) +
142 AudioBus::CalculateMemorySize(audio_params);
143 size_t data_size = kSegments * segment_size;
144 EXPECT_LE(data_size, sizeof(data));
145
146 socket_ = new MockCancelableSyncSocket(kSegments);
147 writer_.reset(new AudioInputSyncWriterUnderTest(
148 &data[0], data_size, kSegments, audio_params, socket_));
149 audio_bus_ = AudioBus::Create(audio_params);
150 }
151
152 ~AudioInputSyncWriterTest() override {
153 }
154
155 // Get total number of expected log calls. On non-Android we expect one log
156 // call at first Write() call, zero on Android. Besides that only for errors.
157 int GetTotalNumberOfExpectedLogCalls(int expected_calls_due_to_error) {
158 #if defined(OS_ANDROID)
159 return expected_calls_due_to_error;
160 #else
161 return expected_calls_due_to_error + 1;
162 #endif
163 }
164
165 protected:
166 scoped_ptr<AudioInputSyncWriterUnderTest> writer_;
167 MockCancelableSyncSocket* socket_;
168 scoped_ptr<AudioBus> audio_bus_;
169
170 private:
171 TestBrowserThreadBundle thread_bundle_;
172
173 DISALLOW_COPY_AND_ASSIGN(AudioInputSyncWriterTest);
174 };
175
176 TEST_F(AudioInputSyncWriterTest, SingleWriteAndRead) {
177 // We always expect one log call at first write.
178 EXPECT_CALL(*writer_.get(), AddToNativeLog(_))
179 .Times(GetTotalNumberOfExpectedLogCalls(0));
180
181 writer_->Write(audio_bus_.get(), 0, false, 0);
182 EXPECT_EQ(1, socket_->NumberOfBuffersFilled());
183 EXPECT_EQ(0u, socket_->Peek());
184
185 socket_->Read(1);
186 EXPECT_EQ(0, socket_->NumberOfBuffersFilled());
187 EXPECT_EQ(sizeof(uint32_t), socket_->Peek());
188 }
189
190 TEST_F(AudioInputSyncWriterTest, MultipleWritesAndReads) {
191 EXPECT_CALL(*writer_.get(), AddToNativeLog(_))
192 .Times(GetTotalNumberOfExpectedLogCalls(0));
193
194 for (int i = 1; i <= 2 * kSegments; ++i) {
195 writer_->Write(audio_bus_.get(), 0, false, 0);
196 EXPECT_EQ(1, socket_->NumberOfBuffersFilled());
197 EXPECT_EQ(0u, socket_->Peek());
198
199 socket_->Read(1);
200 EXPECT_EQ(0, socket_->NumberOfBuffersFilled());
201 EXPECT_EQ(sizeof(uint32_t), socket_->Peek());
202 }
203 }
204
205 TEST_F(AudioInputSyncWriterTest, MultipleWritesNoReads) {
206 EXPECT_CALL(*writer_.get(), AddToNativeLog(_))
207 .Times(GetTotalNumberOfExpectedLogCalls(kSegments));
208
209 for (int i = 1; i <= kSegments; ++i) {
210 writer_->Write(audio_bus_.get(), 0, false, 0);
211 EXPECT_EQ(i, socket_->NumberOfBuffersFilled());
212 EXPECT_EQ(0u, socket_->Peek());
213 }
214
215 // Now the ring buffer is full, do more writes. We should get an extra error
216 // log call for each write. See top EXPECT_CALL.
217 for (int i = 1; i <= kSegments; ++i) {
218 writer_->Write(audio_bus_.get(), 0, false, 0);
219 EXPECT_EQ(kSegments, socket_->NumberOfBuffersFilled());
220 EXPECT_EQ(0u, socket_->Peek());
221 }
222 }
223
224 TEST_F(AudioInputSyncWriterTest, FillAndEmptyRingBuffer) {
225 EXPECT_CALL(*writer_.get(), AddToNativeLog(_))
226 .Times(GetTotalNumberOfExpectedLogCalls(1));
227
228 // Fill ring buffer.
229 for (int i = 1; i <= kSegments; ++i) {
230 writer_->Write(audio_bus_.get(), 0, false, 0);
231 }
232 EXPECT_EQ(kSegments, socket_->NumberOfBuffersFilled());
233 EXPECT_EQ(0u, socket_->Peek());
234
235 // Empty half of the ring buffer.
236 int buffers_to_read = kSegments / 2;
237 socket_->Read(buffers_to_read);
238 EXPECT_EQ(kSegments - buffers_to_read, socket_->NumberOfBuffersFilled());
239 EXPECT_EQ(buffers_to_read * sizeof(uint32_t), socket_->Peek());
240
241 // Fill up again. The first write should do receive until that queue is
242 // empty.
243 for (int i = kSegments - buffers_to_read + 1; i <= kSegments; ++i) {
244 writer_->Write(audio_bus_.get(), 0, false, 0);
245 EXPECT_EQ(i, socket_->NumberOfBuffersFilled());
246 EXPECT_EQ(0u, socket_->Peek());
247 }
248
249 // Another write, should render and extra error log call.
250 writer_->Write(audio_bus_.get(), 0, false, 0);
251 EXPECT_EQ(kSegments, socket_->NumberOfBuffersFilled());
252 EXPECT_EQ(0u, socket_->Peek());
253
254 // Empty the ring buffer.
255 socket_->Read(kSegments);
256 EXPECT_EQ(0, socket_->NumberOfBuffersFilled());
257 EXPECT_EQ(kSegments * sizeof(uint32_t), socket_->Peek());
258
259 // Another write, should do receive until that queue is empty.
260 writer_->Write(audio_bus_.get(), 0, false, 0);
261 EXPECT_EQ(1, socket_->NumberOfBuffersFilled());
262 EXPECT_EQ(0u, socket_->Peek());
263 }
264
265 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/media/audio_input_sync_writer.cc ('k') | content/content_tests.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698