input_sync_writer_unittest.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  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. #include "services/audio/input_sync_writer.h"
  5. #include <stddef.h>
  6. #include <stdint.h>
  7. #include <memory>
  8. #include <string>
  9. #include <utility>
  10. #include "base/compiler_specific.h"
  11. #include "base/memory/ptr_util.h"
  12. #include "base/memory/raw_ptr.h"
  13. #include "base/memory/read_only_shared_memory_region.h"
  14. #include "base/sync_socket.h"
  15. #include "base/test/mock_callback.h"
  16. #include "base/test/task_environment.h"
  17. #include "base/time/time.h"
  18. #include "build/build_config.h"
  19. #include "media/base/audio_bus.h"
  20. #include "media/base/audio_parameters.h"
  21. #include "media/base/channel_layout.h"
  22. #include "testing/gmock/include/gmock/gmock.h"
  23. #include "testing/gtest/include/gtest/gtest.h"
  24. using ::testing::_;
  25. namespace audio {
  26. namespace {
  27. // Number of audio buffers in the faked ring buffer.
  28. const int kSegments = 10;
  29. } // namespace
  30. // Mocked out sockets used for Send/ReceiveWithTimeout. Counts the number of
  31. // outstanding reads, i.e. the diff between send and receive calls.
  32. class MockCancelableSyncSocket : public base::CancelableSyncSocket {
  33. public:
  34. explicit MockCancelableSyncSocket(int buffer_size)
  35. : in_failure_mode_(false),
  36. writes_(0),
  37. reads_(0),
  38. receives_(0),
  39. buffer_size_(buffer_size),
  40. read_buffer_index_(0) {}
  41. MockCancelableSyncSocket(const MockCancelableSyncSocket&) = delete;
  42. MockCancelableSyncSocket& operator=(const MockCancelableSyncSocket&) = delete;
  43. size_t Send(const void* buffer, size_t length) override {
  44. EXPECT_EQ(length, sizeof(uint32_t));
  45. ++writes_;
  46. EXPECT_LE(NumberOfBuffersFilled(), buffer_size_);
  47. return length;
  48. }
  49. size_t Receive(void* buffer, size_t length) override {
  50. EXPECT_EQ(0u, length % sizeof(uint32_t));
  51. if (in_failure_mode_)
  52. return 0;
  53. if (receives_ == reads_)
  54. return 0;
  55. uint32_t* ptr = static_cast<uint32_t*>(buffer);
  56. size_t received = 0;
  57. for (; received < length / sizeof(uint32_t) && receives_ < reads_;
  58. ++received, ++ptr) {
  59. ++receives_;
  60. EXPECT_LE(receives_, reads_);
  61. *ptr = ++read_buffer_index_;
  62. }
  63. return received * sizeof(uint32_t);
  64. }
  65. size_t Peek() override { return (reads_ - receives_) * sizeof(uint32_t); }
  66. // Simluates reading |buffers| number of buffers from the ring buffer.
  67. void Read(int buffers) {
  68. reads_ += buffers;
  69. EXPECT_LE(reads_, writes_);
  70. }
  71. // When |in_failure_mode_| == true, the socket fails to receive.
  72. void SetFailureMode(bool in_failure_mode) {
  73. in_failure_mode_ = in_failure_mode;
  74. }
  75. int NumberOfBuffersFilled() { return writes_ - reads_; }
  76. private:
  77. bool in_failure_mode_;
  78. int writes_;
  79. int reads_;
  80. int receives_;
  81. int buffer_size_;
  82. uint32_t read_buffer_index_;
  83. };
  84. class InputSyncWriterTest : public testing::Test {
  85. public:
  86. InputSyncWriterTest() {
  87. const int sampling_frequency_hz = 16000;
  88. const int frames = sampling_frequency_hz / 100; // 10 ms
  89. const media::AudioParameters audio_params(
  90. media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_MONO,
  91. sampling_frequency_hz, frames);
  92. const uint32_t data_size =
  93. ComputeAudioInputBufferSize(audio_params, kSegments);
  94. auto shared_memory = base::ReadOnlySharedMemoryRegion::Create(data_size);
  95. EXPECT_TRUE(shared_memory.IsValid());
  96. auto socket = std::make_unique<MockCancelableSyncSocket>(kSegments);
  97. socket_ = socket.get();
  98. writer_ = std::make_unique<InputSyncWriter>(
  99. mock_logger_.Get(), std::move(shared_memory), std::move(socket),
  100. kSegments, audio_params);
  101. audio_bus_ = media::AudioBus::Create(audio_params);
  102. }
  103. InputSyncWriterTest(const InputSyncWriterTest&) = delete;
  104. InputSyncWriterTest& operator=(const InputSyncWriterTest&) = delete;
  105. ~InputSyncWriterTest() override {}
  106. // Get total number of expected log calls. On non-Android we expect one log
  107. // call at first Write() call, zero on Android. We also expect all call in the
  108. // with a glitch summary from the destructor. Besides that only for errors
  109. // and fifo info.
  110. int GetTotalNumberOfExpectedLogCalls(int expected_calls_due_to_error) {
  111. #if BUILDFLAG(IS_ANDROID)
  112. return expected_calls_due_to_error + 1;
  113. #else
  114. return expected_calls_due_to_error + 2;
  115. #endif
  116. }
  117. // Tests expected numbers which are given as arguments.
  118. bool TestSocketAndFifoExpectations(int number_of_buffers_in_socket,
  119. size_t number_of_verifications_in_socket,
  120. size_t number_of_buffers_in_fifo) {
  121. EXPECT_EQ(number_of_buffers_in_socket, socket_->NumberOfBuffersFilled());
  122. EXPECT_EQ(number_of_verifications_in_socket, socket_->Peek());
  123. EXPECT_EQ(number_of_buffers_in_fifo, writer_->overflow_data_.size());
  124. return number_of_buffers_in_socket == socket_->NumberOfBuffersFilled() &&
  125. number_of_verifications_in_socket == socket_->Peek() &&
  126. number_of_buffers_in_fifo == writer_->overflow_data_.size();
  127. }
  128. protected:
  129. using MockLogger =
  130. base::MockCallback<base::RepeatingCallback<void(const std::string&)>>;
  131. base::test::TaskEnvironment env_;
  132. MockLogger mock_logger_;
  133. std::unique_ptr<InputSyncWriter> writer_;
  134. raw_ptr<MockCancelableSyncSocket> socket_;
  135. std::unique_ptr<media::AudioBus> audio_bus_;
  136. };
  137. TEST_F(InputSyncWriterTest, SingleWriteAndRead) {
  138. EXPECT_CALL(mock_logger_, Run(_)).Times(GetTotalNumberOfExpectedLogCalls(0));
  139. writer_->Write(audio_bus_.get(), 0, false, base::TimeTicks::Now());
  140. EXPECT_TRUE(TestSocketAndFifoExpectations(1, 0, 0));
  141. socket_->Read(1);
  142. EXPECT_TRUE(TestSocketAndFifoExpectations(0, 1 * sizeof(uint32_t), 0));
  143. }
  144. TEST_F(InputSyncWriterTest, MultipleWritesAndReads) {
  145. EXPECT_CALL(mock_logger_, Run(_)).Times(GetTotalNumberOfExpectedLogCalls(0));
  146. for (int i = 1; i <= 2 * kSegments; ++i) {
  147. writer_->Write(audio_bus_.get(), 0, false, base::TimeTicks::Now());
  148. EXPECT_TRUE(TestSocketAndFifoExpectations(1, 0, 0));
  149. socket_->Read(1);
  150. EXPECT_TRUE(TestSocketAndFifoExpectations(0, 1 * sizeof(uint32_t), 0));
  151. }
  152. }
  153. TEST_F(InputSyncWriterTest, MultipleWritesNoReads) {
  154. EXPECT_CALL(mock_logger_, Run(_)).Times(GetTotalNumberOfExpectedLogCalls(1));
  155. // Fill the ring buffer.
  156. for (int i = 1; i <= kSegments; ++i) {
  157. writer_->Write(audio_bus_.get(), 0, false, base::TimeTicks::Now());
  158. EXPECT_TRUE(TestSocketAndFifoExpectations(i, 0, 0));
  159. }
  160. // Now the ring buffer is full, do more writes. We should start filling the
  161. // fifo and should get one extra log call for that.
  162. for (size_t i = 1; i <= kSegments; ++i) {
  163. writer_->Write(audio_bus_.get(), 0, false, base::TimeTicks::Now());
  164. EXPECT_TRUE(TestSocketAndFifoExpectations(kSegments, 0, i));
  165. }
  166. }
  167. TEST_F(InputSyncWriterTest, FillAndEmptyRingBuffer) {
  168. EXPECT_CALL(mock_logger_, Run(_)).Times(GetTotalNumberOfExpectedLogCalls(2));
  169. // Fill the ring buffer.
  170. for (int i = 1; i <= kSegments; ++i) {
  171. writer_->Write(audio_bus_.get(), 0, false, base::TimeTicks::Now());
  172. }
  173. EXPECT_TRUE(TestSocketAndFifoExpectations(kSegments, 0, 0));
  174. // Empty half of the ring buffer.
  175. const int buffers_to_read = kSegments / 2;
  176. socket_->Read(buffers_to_read);
  177. EXPECT_TRUE(TestSocketAndFifoExpectations(
  178. kSegments - buffers_to_read, buffers_to_read * sizeof(uint32_t), 0));
  179. // Fill up again. The first write should do receive until that queue is
  180. // empty.
  181. for (int i = kSegments - buffers_to_read + 1; i <= kSegments; ++i) {
  182. writer_->Write(audio_bus_.get(), 0, false, base::TimeTicks::Now());
  183. EXPECT_TRUE(TestSocketAndFifoExpectations(i, 0, 0));
  184. }
  185. // Another write, should put the data in the fifo, and render an extra log
  186. // call.
  187. writer_->Write(audio_bus_.get(), 0, false, base::TimeTicks::Now());
  188. EXPECT_TRUE(TestSocketAndFifoExpectations(kSegments, 0, 1));
  189. // Empty the ring buffer.
  190. socket_->Read(kSegments);
  191. EXPECT_TRUE(
  192. TestSocketAndFifoExpectations(0, kSegments * sizeof(uint32_t), 1));
  193. // Another write, should do receive until that queue is empty and write both
  194. // the data in the fifo and the new data, and render a log call.
  195. writer_->Write(audio_bus_.get(), 0, false, base::TimeTicks::Now());
  196. EXPECT_TRUE(TestSocketAndFifoExpectations(2, 0, 0));
  197. // Read the two data blocks.
  198. socket_->Read(2);
  199. EXPECT_TRUE(TestSocketAndFifoExpectations(0, 2 * sizeof(uint32_t), 0));
  200. }
  201. TEST_F(InputSyncWriterTest, FillRingBufferAndFifo) {
  202. EXPECT_CALL(mock_logger_, Run(_)).Times(GetTotalNumberOfExpectedLogCalls(2));
  203. // Fill the ring buffer.
  204. for (int i = 1; i <= kSegments; ++i) {
  205. writer_->Write(audio_bus_.get(), 0, false, base::TimeTicks::Now());
  206. }
  207. EXPECT_TRUE(TestSocketAndFifoExpectations(kSegments, 0, 0));
  208. // Fill the fifo. Should render one log call for starting filling it.
  209. const size_t max_fifo_size = InputSyncWriter::kMaxOverflowBusesSize;
  210. for (size_t i = 1; i <= max_fifo_size; ++i) {
  211. writer_->Write(audio_bus_.get(), 0, false, base::TimeTicks::Now());
  212. }
  213. EXPECT_TRUE(TestSocketAndFifoExpectations(kSegments, 0, max_fifo_size));
  214. // Another write, data should be dropped and render one log call.
  215. writer_->Write(audio_bus_.get(), 0, false, base::TimeTicks::Now());
  216. EXPECT_TRUE(TestSocketAndFifoExpectations(kSegments, 0, max_fifo_size));
  217. }
  218. TEST_F(InputSyncWriterTest, MultipleFillAndEmptyRingBufferAndPartOfFifo) {
  219. EXPECT_CALL(mock_logger_, Run(_)).Times(GetTotalNumberOfExpectedLogCalls(4));
  220. // Fill the ring buffer.
  221. for (int i = 1; i <= kSegments; ++i) {
  222. writer_->Write(audio_bus_.get(), 0, false, base::TimeTicks::Now());
  223. }
  224. EXPECT_TRUE(TestSocketAndFifoExpectations(kSegments, 0, 0));
  225. // Write more data, should be put in the fifo and render one log call for
  226. // starting filling it.
  227. for (size_t i = 1; i <= 2 * kSegments; ++i) {
  228. writer_->Write(audio_bus_.get(), 0, false, base::TimeTicks::Now());
  229. }
  230. EXPECT_TRUE(TestSocketAndFifoExpectations(kSegments, 0, 2 * kSegments));
  231. // Empty the ring buffer.
  232. socket_->Read(kSegments);
  233. EXPECT_TRUE(TestSocketAndFifoExpectations(0, kSegments * sizeof(uint32_t),
  234. 2 * kSegments));
  235. // Another write should fill up the ring buffer with data from the fifo and
  236. // put this data into the fifo.
  237. writer_->Write(audio_bus_.get(), 0, false, base::TimeTicks::Now());
  238. EXPECT_TRUE(TestSocketAndFifoExpectations(kSegments, 0, kSegments + 1));
  239. // Empty the ring buffer again.
  240. socket_->Read(kSegments);
  241. EXPECT_TRUE(TestSocketAndFifoExpectations(0, kSegments * sizeof(uint32_t),
  242. kSegments + 1));
  243. // Another write should fill up the ring buffer with data from the fifo and
  244. // put this data into the fifo.
  245. writer_->Write(audio_bus_.get(), 0, false, base::TimeTicks::Now());
  246. EXPECT_TRUE(TestSocketAndFifoExpectations(kSegments, 0, 2));
  247. // Empty the ring buffer again.
  248. socket_->Read(kSegments);
  249. EXPECT_TRUE(
  250. TestSocketAndFifoExpectations(0, kSegments * sizeof(uint32_t), 2));
  251. // Another write should put the remaining data in the fifo in the ring buffer
  252. // together with this data. Should render a log call for emptying the fifo.
  253. writer_->Write(audio_bus_.get(), 0, false, base::TimeTicks::Now());
  254. EXPECT_TRUE(TestSocketAndFifoExpectations(3, 0, 0));
  255. // Read the remaining data.
  256. socket_->Read(3);
  257. EXPECT_TRUE(TestSocketAndFifoExpectations(0, 3 * sizeof(uint32_t), 0));
  258. // Fill the ring buffer and part of the fifo. Should render one log call for
  259. // starting filling it.
  260. for (int i = 1; i <= kSegments + 2; ++i) {
  261. writer_->Write(audio_bus_.get(), 0, false, base::TimeTicks::Now());
  262. }
  263. EXPECT_TRUE(TestSocketAndFifoExpectations(kSegments, 0, 2));
  264. // Empty both. Should render a log call for emptying the fifo.
  265. socket_->Read(kSegments);
  266. writer_->Write(audio_bus_.get(), 0, false, base::TimeTicks::Now());
  267. socket_->Read(3);
  268. EXPECT_TRUE(TestSocketAndFifoExpectations(0, 3 * sizeof(uint32_t), 0));
  269. }
  270. } // namespace audio