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

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: Code review. 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/memory/scoped_ptr.h"
6 #include "base/sync_socket.h"
7 #include "base/time/time.h"
8 #include "content/browser/renderer_host/media/audio_input_sync_writer.h"
9 #include "content/public/test/test_browser_thread_bundle.h"
10 #include "media/audio/audio_parameters.h"
11 #include "media/base/audio_bus.h"
12 #include "media/base/channel_layout.h"
13 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 using ::testing::_;
17 using base::TimeDelta;
18 using media::AudioBus;
19 using media::AudioParameters;
20
21 namespace content {
22
23 // Mocked out sockets used for Send/ReceiveWithTimeout. Counts the number of
24 // outstanding reads, i.e. the diff between send and receive calls.
25 class MockCancelableSyncSocket : public base::CancelableSyncSocket {
26 public:
27 MockCancelableSyncSocket(int buffer_size)
28 : in_failure_mode_(false),
29 writes_(0),
30 reads_(0),
31 receives_(0),
32 buffer_size_(buffer_size),
33 read_buffer_index_(0) {}
34
35 size_t Send(const void* buffer, size_t length) override {
36 EXPECT_EQ(length, sizeof(uint32_t));
37
38 ++writes_;
39 EXPECT_LE(NumberOfBuffersFilled(), buffer_size_);
40 return length;
41 }
42
43 size_t ReceiveWithTimeout(void* buffer, size_t length,
44 TimeDelta timeout) override {
45 EXPECT_EQ(0u, length % sizeof(uint32_t));
46
47 if (in_failure_mode_)
48 return 0;
49 if (receives_ == reads_)
50 return 0;
51
52 uint32_t* ptr = static_cast<uint32_t*>(buffer);
53 size_t received = 0;
54 for (; received < length / sizeof(uint32_t) && receives_ < reads_;
55 ++received, ++ptr) {
56 ++receives_;
57 EXPECT_LE(receives_, reads_);
58 *ptr = ++read_buffer_index_;
59 }
60 return received * sizeof(uint32_t);
61 }
62
63 size_t Peek() override {
64 return (reads_ - receives_) * sizeof(uint32_t);
65 }
66
67 // Simluates reading |buffers| number of buffers from the ring buffer.
68 void Read(int buffers) {
69 reads_ += buffers;
70 EXPECT_LE(reads_, writes_);
71 }
72
73 // When |in_failure_mode_| == true, the socket fails to receive.
74 void SetFailureMode(bool in_failure_mode) {
75 in_failure_mode_ = in_failure_mode;
76 }
77
78 int NumberOfBuffersFilled() { return writes_ - reads_; }
79
80 private:
81 bool in_failure_mode_;
82 int writes_;
83 int reads_;
84 int receives_;
85 int buffer_size_;
86 uint32_t read_buffer_index_;
87
88 DISALLOW_COPY_AND_ASSIGN(MockCancelableSyncSocket);
89 };
90
91 class AudioInputSyncWriterUnderTest : public AudioInputSyncWriter {
92 public:
93 AudioInputSyncWriterUnderTest(void* shared_memory,
94 size_t shared_memory_size,
95 int shared_memory_segment_count,
96 const media::AudioParameters& params,
97 base::CancelableSyncSocket* socket)
98 : AudioInputSyncWriter(shared_memory, shared_memory_size,
99 shared_memory_segment_count, params) {
100 socket_.reset(socket);
101 }
102
103 ~AudioInputSyncWriterUnderTest() override {}
104
105 MOCK_METHOD1(AddToNativeLog, void(const std::string& message));
106 };
107
108 class AudioInputSyncWriterTest : public testing::Test {
109 public:
110 AudioInputSyncWriterTest()
111 : socket_(nullptr) {
112 const media::ChannelLayout layout =
113 media::ChannelLayout::CHANNEL_LAYOUT_MONO;
114 const int channels = media::ChannelLayoutToChannelCount(layout);
115 const int sampling_frequency_hz = 16000;
116 const int frames = sampling_frequency_hz / 100; // 10 ms
117 const int bits_per_sample = 16;
118
119 AudioParameters audio_params(
120 AudioParameters::AUDIO_FAKE, layout, channels,
121 sampling_frequency_hz, bits_per_sample, frames);
122
123 const uint32 segment_size =
124 sizeof(media::AudioInputBufferParameters) +
125 AudioBus::CalculateMemorySize(audio_params);
126 size_t data_size = kSegments * segment_size;
127 data_.reset(new uint8[data_size]);
128
129 socket_ = new MockCancelableSyncSocket(kSegments);
130 writer_.reset(new AudioInputSyncWriterUnderTest(
131 data_.get(), data_size, kSegments, audio_params, socket_));
132 audio_bus_ = AudioBus::Create(audio_params);
133 }
134
135 ~AudioInputSyncWriterTest() override {
136 }
137
138 protected:
139 const int kSegments = 10;
140
141 scoped_ptr<AudioInputSyncWriterUnderTest> writer_;
142 MockCancelableSyncSocket* socket_;
143 scoped_ptr<AudioBus> audio_bus_;
144 scoped_ptr<uint8[]> data_;
145
146 private:
147 TestBrowserThreadBundle thread_bundle_;
148
149 DISALLOW_COPY_AND_ASSIGN(AudioInputSyncWriterTest);
150 };
151
152 TEST_F(AudioInputSyncWriterTest, SingleWriteAndRead) {
153 // We always expect one log call at first write.
154 EXPECT_CALL(*writer_.get(), AddToNativeLog(_));
155
156 writer_->Write(audio_bus_.get(), 0, false, 0);
157 EXPECT_EQ(1, socket_->NumberOfBuffersFilled());
158 EXPECT_EQ(0u, socket_->Peek());
159
160 socket_->Read(1);
161 EXPECT_EQ(0, socket_->NumberOfBuffersFilled());
162 EXPECT_EQ(sizeof(uint32_t), socket_->Peek());
163 }
164
165 TEST_F(AudioInputSyncWriterTest, MultipleWritesAndReads) {
166 EXPECT_CALL(*writer_.get(), AddToNativeLog(_));
167
168 for (int i = 1; i <= 2 * kSegments; ++i) {
169 writer_->Write(audio_bus_.get(), 0, false, 0);
170 EXPECT_EQ(1, socket_->NumberOfBuffersFilled());
171 EXPECT_EQ(0u, socket_->Peek());
172
173 socket_->Read(1);
174 EXPECT_EQ(0, socket_->NumberOfBuffersFilled());
175 EXPECT_EQ(sizeof(uint32_t), socket_->Peek());
176 }
177 }
178
179 TEST_F(AudioInputSyncWriterTest, MultipleWritesNoReads) {
180 EXPECT_CALL(*writer_.get(), AddToNativeLog(_)).Times(1 + kSegments);
181
182 for (int i = 1; i <= kSegments; ++i) {
183 writer_->Write(audio_bus_.get(), 0, false, 0);
184 EXPECT_EQ(i, socket_->NumberOfBuffersFilled());
185 EXPECT_EQ(0u, socket_->Peek());
186 }
187
188 // Now the ring buffer is full, do more writes. We should get an extra error
189 // log call for each write. See top EXPECT_CALL.
190 for (int i = 1; i <= kSegments; ++i) {
191 writer_->Write(audio_bus_.get(), 0, false, 0);
192 EXPECT_EQ(kSegments, socket_->NumberOfBuffersFilled());
193 EXPECT_EQ(0u, socket_->Peek());
194 }
195 }
196
197 TEST_F(AudioInputSyncWriterTest, FillAndEmptyRingBuffer) {
198 EXPECT_CALL(*writer_.get(), AddToNativeLog(_)).Times(2);
199
200 // Fill ring buffer.
201 for (int i = 1; i <= kSegments; ++i) {
202 writer_->Write(audio_bus_.get(), 0, false, 0);
203 }
204 EXPECT_EQ(kSegments, socket_->NumberOfBuffersFilled());
205 EXPECT_EQ(0u, socket_->Peek());
206
207 // Empty half of the ring buffer.
208 int buffers_to_read = kSegments / 2;
209 socket_->Read(buffers_to_read);
210 EXPECT_EQ(kSegments - buffers_to_read, socket_->NumberOfBuffersFilled());
211 EXPECT_EQ(buffers_to_read * sizeof(uint32_t), socket_->Peek());
212
213 // Fill up again. The first write should do receive until that queue is
214 // empty.
215 for (int i = kSegments - buffers_to_read + 1; i <= kSegments; ++i) {
216 writer_->Write(audio_bus_.get(), 0, false, 0);
217 EXPECT_EQ(i, socket_->NumberOfBuffersFilled());
218 EXPECT_EQ(0u, socket_->Peek());
219 }
220
221 // Another write, should render and extra error log call.
222 writer_->Write(audio_bus_.get(), 0, false, 0);
223 EXPECT_EQ(kSegments, socket_->NumberOfBuffersFilled());
224 EXPECT_EQ(0u, socket_->Peek());
225
226 // Empty the ring buffer.
227 socket_->Read(kSegments);
228 EXPECT_EQ(0, socket_->NumberOfBuffersFilled());
229 EXPECT_EQ(kSegments * sizeof(uint32_t), socket_->Peek());
230
231 // Another write, should do receive until that queue is empty.
232 writer_->Write(audio_bus_.get(), 0, false, 0);
233 EXPECT_EQ(1, socket_->NumberOfBuffersFilled());
234 EXPECT_EQ(0u, socket_->Peek());
235 }
236
237 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698