audio_discard_helper_unittest.cc 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  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. #include "media/base/audio_discard_helper.h"
  5. #include <stddef.h>
  6. #include <memory>
  7. #include "media/base/audio_buffer.h"
  8. #include "media/base/audio_bus.h"
  9. #include "media/base/decoder_buffer.h"
  10. #include "media/base/test_helpers.h"
  11. #include "media/base/timestamp_constants.h"
  12. #include "testing/gtest/include/gtest/gtest.h"
  13. namespace media {
  14. static const float kDataStep = 0.01f;
  15. static const size_t kSampleRate = 48000;
  16. static DecoderBuffer::TimeInfo CreateTimeInfo(base::TimeDelta timestamp,
  17. base::TimeDelta duration) {
  18. DecoderBuffer::TimeInfo time_info;
  19. time_info.timestamp = timestamp;
  20. time_info.duration = duration;
  21. return time_info;
  22. }
  23. static scoped_refptr<AudioBuffer> CreateDecodedBuffer(int frames) {
  24. return MakeAudioBuffer(kSampleFormatPlanarF32, CHANNEL_LAYOUT_MONO, 1,
  25. kSampleRate, 0.0f, kDataStep, frames, kNoTimestamp);
  26. }
  27. static float ExtractDecodedData(const AudioBuffer& buffer, int index) {
  28. // This is really inefficient, but we can't access the raw AudioBuffer if any
  29. // start trimming has been applied.
  30. std::unique_ptr<AudioBus> temp_bus =
  31. AudioBus::Create(buffer.channel_count(), 1);
  32. buffer.ReadFrames(1, index, 0, temp_bus.get());
  33. return temp_bus->channel(0)[0] * std::numeric_limits<uint16_t>::max();
  34. }
  35. TEST(AudioDiscardHelperTest, TimeDeltaToFrames) {
  36. AudioDiscardHelper discard_helper(kSampleRate, 0, false);
  37. EXPECT_EQ(0u, discard_helper.TimeDeltaToFrames(base::TimeDelta()));
  38. EXPECT_EQ(kSampleRate / 100,
  39. discard_helper.TimeDeltaToFrames(base::Milliseconds(10)));
  40. // Ensure partial frames are rounded down correctly. The equation below
  41. // calculates a frame count with a fractional part < 0.5.
  42. const int small_remainder =
  43. base::Time::kMicrosecondsPerSecond * (kSampleRate - 0.9) / kSampleRate;
  44. EXPECT_EQ(kSampleRate - 1, discard_helper.TimeDeltaToFrames(
  45. base::Microseconds(small_remainder)));
  46. // Ditto, but rounded up using a fractional part > 0.5.
  47. const int large_remainder =
  48. base::Time::kMicrosecondsPerSecond * (kSampleRate - 0.4) / kSampleRate;
  49. EXPECT_EQ(kSampleRate, discard_helper.TimeDeltaToFrames(
  50. base::Microseconds(large_remainder)));
  51. }
  52. TEST(AudioDiscardHelperTest, BasicProcessBuffers) {
  53. AudioDiscardHelper discard_helper(kSampleRate, 0, false);
  54. ASSERT_FALSE(discard_helper.initialized());
  55. const base::TimeDelta kTimestamp = base::TimeDelta();
  56. // Use an estimated duration which doesn't match the number of decoded frames
  57. // to ensure the helper is correctly setting durations based on output frames.
  58. const base::TimeDelta kEstimatedDuration = base::Milliseconds(9);
  59. const base::TimeDelta kActualDuration = base::Milliseconds(10);
  60. const int kTestFrames = discard_helper.TimeDeltaToFrames(kActualDuration);
  61. DecoderBuffer::TimeInfo time_info =
  62. CreateTimeInfo(kTimestamp, kEstimatedDuration);
  63. scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
  64. // Verify the basic case where nothing is discarded.
  65. ASSERT_TRUE(discard_helper.ProcessBuffers(time_info, decoded_buffer.get()));
  66. ASSERT_TRUE(discard_helper.initialized());
  67. EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
  68. EXPECT_EQ(kActualDuration, decoded_buffer->duration());
  69. EXPECT_EQ(kTestFrames, decoded_buffer->frame_count());
  70. // Verify a Reset() takes us back to an uninitialized state.
  71. discard_helper.Reset(0);
  72. ASSERT_FALSE(discard_helper.initialized());
  73. // Verify a NULL output buffer returns false.
  74. ASSERT_FALSE(discard_helper.ProcessBuffers(time_info, NULL));
  75. }
  76. TEST(AudioDiscardHelperTest, NegativeTimestampClampsToZero) {
  77. AudioDiscardHelper discard_helper(kSampleRate, 0, false);
  78. ASSERT_FALSE(discard_helper.initialized());
  79. const base::TimeDelta kTimestamp = -base::Seconds(1);
  80. const base::TimeDelta kDuration = base::Milliseconds(10);
  81. const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
  82. DecoderBuffer::TimeInfo time_info = CreateTimeInfo(kTimestamp, kDuration);
  83. scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
  84. // Verify the basic case where nothing is discarded.
  85. ASSERT_TRUE(discard_helper.ProcessBuffers(time_info, decoded_buffer.get()));
  86. ASSERT_TRUE(discard_helper.initialized());
  87. EXPECT_EQ(base::TimeDelta(), decoded_buffer->timestamp());
  88. EXPECT_EQ(kDuration, decoded_buffer->duration());
  89. EXPECT_EQ(kTestFrames, decoded_buffer->frame_count());
  90. }
  91. TEST(AudioDiscardHelperTest, ProcessBuffersWithInitialDiscard) {
  92. AudioDiscardHelper discard_helper(kSampleRate, 0, false);
  93. ASSERT_FALSE(discard_helper.initialized());
  94. const base::TimeDelta kTimestamp = base::TimeDelta();
  95. const base::TimeDelta kDuration = base::Milliseconds(10);
  96. const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
  97. // Tell the helper we want to discard half of the initial frames.
  98. const int kDiscardFrames = kTestFrames / 2;
  99. discard_helper.Reset(kDiscardFrames);
  100. DecoderBuffer::TimeInfo time_info = CreateTimeInfo(kTimestamp, kDuration);
  101. scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
  102. // Verify half the frames end up discarded.
  103. ASSERT_TRUE(discard_helper.ProcessBuffers(time_info, decoded_buffer.get()));
  104. ASSERT_TRUE(discard_helper.initialized());
  105. EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
  106. EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
  107. EXPECT_EQ(kDiscardFrames, decoded_buffer->frame_count());
  108. ASSERT_FLOAT_EQ(kDiscardFrames * kDataStep,
  109. ExtractDecodedData(*decoded_buffer, 0));
  110. }
  111. TEST(AudioDiscardHelperTest, ProcessBuffersWithLargeInitialDiscard) {
  112. AudioDiscardHelper discard_helper(kSampleRate, 0, false);
  113. ASSERT_FALSE(discard_helper.initialized());
  114. const base::TimeDelta kTimestamp = base::TimeDelta();
  115. const base::TimeDelta kDuration = base::Milliseconds(10);
  116. const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
  117. // Tell the helper we want to discard 1.5 buffers worth of frames.
  118. discard_helper.Reset(kTestFrames * 1.5);
  119. DecoderBuffer::TimeInfo time_info = CreateTimeInfo(kTimestamp, kDuration);
  120. scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
  121. // The first call should fail since no output buffer remains.
  122. ASSERT_FALSE(discard_helper.ProcessBuffers(time_info, decoded_buffer.get()));
  123. ASSERT_TRUE(discard_helper.initialized());
  124. // Generate another set of buffers and expect half the output frames.
  125. time_info = CreateTimeInfo(kTimestamp + kDuration, kDuration);
  126. decoded_buffer = CreateDecodedBuffer(kTestFrames);
  127. ASSERT_TRUE(discard_helper.ProcessBuffers(time_info, decoded_buffer.get()));
  128. // The timestamp should match that of the initial buffer.
  129. const int kDiscardFrames = kTestFrames / 2;
  130. EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
  131. EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
  132. EXPECT_EQ(kDiscardFrames, decoded_buffer->frame_count());
  133. ASSERT_FLOAT_EQ(kDiscardFrames * kDataStep,
  134. ExtractDecodedData(*decoded_buffer, 0));
  135. }
  136. TEST(AudioDiscardHelperTest, AllowNonMonotonicTimestamps) {
  137. AudioDiscardHelper discard_helper(kSampleRate, 0, false);
  138. ASSERT_FALSE(discard_helper.initialized());
  139. const base::TimeDelta kTimestamp = base::TimeDelta();
  140. const base::TimeDelta kDuration = base::Milliseconds(10);
  141. const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
  142. DecoderBuffer::TimeInfo time_info = CreateTimeInfo(kTimestamp, kDuration);
  143. scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
  144. ASSERT_TRUE(discard_helper.ProcessBuffers(time_info, decoded_buffer.get()));
  145. ASSERT_TRUE(discard_helper.initialized());
  146. EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
  147. EXPECT_EQ(kDuration, decoded_buffer->duration());
  148. EXPECT_EQ(kTestFrames, decoded_buffer->frame_count());
  149. // Process the same input buffer again to ensure input timestamps which go
  150. // backwards in time are not errors.
  151. ASSERT_TRUE(discard_helper.ProcessBuffers(time_info, decoded_buffer.get()));
  152. EXPECT_EQ(kTimestamp + kDuration, decoded_buffer->timestamp());
  153. EXPECT_EQ(kDuration, decoded_buffer->duration());
  154. EXPECT_EQ(kTestFrames, decoded_buffer->frame_count());
  155. }
  156. TEST(AudioDiscardHelperTest, DiscardEndPadding) {
  157. AudioDiscardHelper discard_helper(kSampleRate, 0, false);
  158. ASSERT_FALSE(discard_helper.initialized());
  159. const base::TimeDelta kTimestamp = base::TimeDelta();
  160. const base::TimeDelta kDuration = base::Milliseconds(10);
  161. const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
  162. DecoderBuffer::TimeInfo time_info = CreateTimeInfo(kTimestamp, kDuration);
  163. scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
  164. // Set a discard padding equivalent to half the buffer.
  165. time_info.discard_padding = std::make_pair(base::TimeDelta(), kDuration / 2);
  166. ASSERT_TRUE(discard_helper.ProcessBuffers(time_info, decoded_buffer.get()));
  167. ASSERT_TRUE(discard_helper.initialized());
  168. EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
  169. EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
  170. EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
  171. }
  172. TEST(AudioDiscardHelperTest, BadDiscardEndPadding) {
  173. AudioDiscardHelper discard_helper(kSampleRate, 0, false);
  174. ASSERT_FALSE(discard_helper.initialized());
  175. const base::TimeDelta kTimestamp = base::TimeDelta();
  176. const base::TimeDelta kDuration = base::Milliseconds(10);
  177. const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
  178. DecoderBuffer::TimeInfo time_info = CreateTimeInfo(kTimestamp, kDuration);
  179. scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
  180. // Set a discard padding equivalent to double the buffer size.
  181. time_info.discard_padding = std::make_pair(base::TimeDelta(), kDuration * 2);
  182. // Verify the end discard padding is rejected.
  183. ASSERT_FALSE(discard_helper.ProcessBuffers(time_info, decoded_buffer.get()));
  184. ASSERT_TRUE(discard_helper.initialized());
  185. }
  186. TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardEndPadding) {
  187. AudioDiscardHelper discard_helper(kSampleRate, 0, false);
  188. ASSERT_FALSE(discard_helper.initialized());
  189. const base::TimeDelta kTimestamp = base::TimeDelta();
  190. const base::TimeDelta kDuration = base::Milliseconds(10);
  191. const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
  192. DecoderBuffer::TimeInfo time_info = CreateTimeInfo(kTimestamp, kDuration);
  193. scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
  194. // Set a discard padding equivalent to a quarter of the buffer.
  195. time_info.discard_padding = std::make_pair(base::TimeDelta(), kDuration / 4);
  196. // Set an initial discard of a quarter of the buffer.
  197. const int kDiscardFrames = kTestFrames / 4;
  198. discard_helper.Reset(kDiscardFrames);
  199. ASSERT_TRUE(discard_helper.ProcessBuffers(time_info, decoded_buffer.get()));
  200. ASSERT_TRUE(discard_helper.initialized());
  201. EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
  202. EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
  203. EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
  204. ASSERT_FLOAT_EQ(kDiscardFrames * kDataStep,
  205. ExtractDecodedData(*decoded_buffer, 0));
  206. }
  207. TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPadding) {
  208. AudioDiscardHelper discard_helper(kSampleRate, 0, false);
  209. ASSERT_FALSE(discard_helper.initialized());
  210. const base::TimeDelta kTimestamp = base::TimeDelta();
  211. const base::TimeDelta kDuration = base::Milliseconds(10);
  212. const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
  213. DecoderBuffer::TimeInfo time_info = CreateTimeInfo(kTimestamp, kDuration);
  214. scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
  215. // Set all the discard values to be different to ensure each is properly used.
  216. const int kDiscardFrames = kTestFrames / 4;
  217. time_info.discard_padding = std::make_pair(kDuration / 8, kDuration / 16);
  218. discard_helper.Reset(kDiscardFrames);
  219. ASSERT_TRUE(discard_helper.ProcessBuffers(time_info, decoded_buffer.get()));
  220. ASSERT_TRUE(discard_helper.initialized());
  221. EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
  222. EXPECT_EQ(kDuration - kDuration / 4 - kDuration / 8 - kDuration / 16,
  223. decoded_buffer->duration());
  224. EXPECT_EQ(kTestFrames - kTestFrames / 4 - kTestFrames / 8 - kTestFrames / 16,
  225. decoded_buffer->frame_count());
  226. }
  227. TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPaddingAndDecoderDelay) {
  228. // Use a decoder delay of 5ms.
  229. const int kDecoderDelay = kSampleRate / 100 / 2;
  230. AudioDiscardHelper discard_helper(kSampleRate, kDecoderDelay, false);
  231. ASSERT_FALSE(discard_helper.initialized());
  232. discard_helper.Reset(kDecoderDelay);
  233. const base::TimeDelta kTimestamp = base::TimeDelta();
  234. const base::TimeDelta kDuration = base::Milliseconds(10);
  235. const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
  236. DecoderBuffer::TimeInfo time_info = CreateTimeInfo(kTimestamp, kDuration);
  237. scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
  238. // Set a discard padding equivalent to half of the buffer.
  239. time_info.discard_padding = std::make_pair(kDuration / 2, base::TimeDelta());
  240. // All of the first buffer should be discarded, half from the inital delay and
  241. // another half from the front discard padding.
  242. //
  243. // Encoded Discard Delay
  244. // |--------| |---------| |----|
  245. // |AAAAAAAA| --> |....|AAAA| --> |AAAA| -------> NULL
  246. // |--------| |---------| |----|
  247. // Decoded Discard Front Padding
  248. //
  249. ASSERT_FALSE(discard_helper.ProcessBuffers(time_info, decoded_buffer.get()));
  250. ASSERT_TRUE(discard_helper.initialized());
  251. // Processing another buffer that has front discard set to half the buffer's
  252. // duration should discard the back half of the buffer since kDecoderDelay is
  253. // half a buffer. The end padding should not be discarded until another
  254. // buffer is processed. kDuration / 4 is chosen for the end discard since it
  255. // will force the end discard to start after position zero within the next
  256. // decoded buffer.
  257. //
  258. // Encoded Discard Front Padding (from B)
  259. // |--------| |---------| |----|
  260. // |BBBBBBBB| --> |AAAA|BBBB| ----------> |AAAA|
  261. // |--------| |---------| |----|
  262. // Decoded
  263. // (includes carryover from A)
  264. //
  265. time_info.timestamp += kDuration;
  266. time_info.discard_padding = std::make_pair(kDuration / 2, kDuration / 4);
  267. decoded_buffer = CreateDecodedBuffer(kTestFrames);
  268. ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(*decoded_buffer, 0));
  269. ASSERT_NEAR(kDecoderDelay * kDataStep,
  270. ExtractDecodedData(*decoded_buffer, kDecoderDelay),
  271. kDataStep / 1000);
  272. ASSERT_TRUE(discard_helper.ProcessBuffers(time_info, decoded_buffer.get()));
  273. EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
  274. EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
  275. EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
  276. // Verify it was actually the latter half of the buffer that was removed.
  277. ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(*decoded_buffer, 0));
  278. // Verify the end discard padding is carried over to the next buffer. Use
  279. // kDuration / 2 for the end discard padding so that the next buffer has its
  280. // start entirely discarded.
  281. //
  282. // Encoded Discard End Padding (from B)
  283. // |--------| |---------| |-------|
  284. // |CCCCCCCC| --> |BBBB|CCCC| ----------> |BB|CCCC|
  285. // |--------| |---------| |-------|
  286. // Decoded
  287. // (includes carryover from B)
  288. //
  289. time_info.timestamp += kDuration;
  290. time_info.discard_padding = std::make_pair(base::TimeDelta(), kDuration / 2);
  291. decoded_buffer = CreateDecodedBuffer(kTestFrames);
  292. ASSERT_TRUE(discard_helper.ProcessBuffers(time_info, decoded_buffer.get()));
  293. EXPECT_EQ(kTimestamp + kDuration / 2, decoded_buffer->timestamp());
  294. EXPECT_EQ(3 * kDuration / 4, decoded_buffer->duration());
  295. EXPECT_EQ(3 * kTestFrames / 4, decoded_buffer->frame_count());
  296. // Verify it was actually the second quarter of the buffer that was removed.
  297. const int kDiscardFrames = kTestFrames / 4;
  298. ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(*decoded_buffer, 0));
  299. ASSERT_FLOAT_EQ(
  300. kDiscardFrames * 2 * kDataStep,
  301. ExtractDecodedData(*decoded_buffer, kDecoderDelay - kDiscardFrames));
  302. // One last test to ensure carryover discard from the start works.
  303. //
  304. // Encoded Discard End Padding (from C)
  305. // |--------| |---------| |----|
  306. // |DDDDDDDD| --> |CCCC|DDDD| ----------> |DDDD|
  307. // |--------| |---------| |----|
  308. // Decoded
  309. // (includes carryover from C)
  310. //
  311. time_info.timestamp += kDuration;
  312. time_info.discard_padding = DecoderBuffer::DiscardPadding();
  313. decoded_buffer = CreateDecodedBuffer(kTestFrames);
  314. ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(*decoded_buffer, 0));
  315. ASSERT_TRUE(discard_helper.ProcessBuffers(time_info, decoded_buffer.get()));
  316. EXPECT_EQ(kTimestamp + kDuration / 2 + 3 * kDuration / 4,
  317. decoded_buffer->timestamp());
  318. EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
  319. EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
  320. ASSERT_FLOAT_EQ(kTestFrames / 2 * kDataStep,
  321. ExtractDecodedData(*decoded_buffer, 0));
  322. }
  323. TEST(AudioDiscardHelperTest, DelayedDiscardInitialDiscardAndDiscardPadding) {
  324. AudioDiscardHelper discard_helper(kSampleRate, 0, true);
  325. ASSERT_FALSE(discard_helper.initialized());
  326. const base::TimeDelta kTimestamp = base::TimeDelta();
  327. const base::TimeDelta kDuration = base::Milliseconds(10);
  328. const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
  329. DecoderBuffer::TimeInfo time_info = CreateTimeInfo(kTimestamp, kDuration);
  330. // Set all the discard values to be different to ensure each is properly used.
  331. const int kDiscardFrames = kTestFrames / 4;
  332. time_info.discard_padding = std::make_pair(kDuration / 8, kDuration / 16);
  333. discard_helper.Reset(kDiscardFrames);
  334. // Verify nothing is output for the first buffer, yet initialized is true.
  335. ASSERT_FALSE(discard_helper.ProcessBuffers(time_info, NULL));
  336. ASSERT_TRUE(discard_helper.initialized());
  337. // Create an encoded buffer with no discard padding.
  338. time_info = CreateTimeInfo(kTimestamp + kDuration, kDuration);
  339. scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
  340. // Verify that when the decoded buffer is consumed, the discards from the
  341. // previous encoded buffer are applied.
  342. ASSERT_TRUE(discard_helper.ProcessBuffers(time_info, decoded_buffer.get()));
  343. EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
  344. EXPECT_EQ(kDuration - kDuration / 4 - kDuration / 8 - kDuration / 16,
  345. decoded_buffer->duration());
  346. EXPECT_EQ(kTestFrames - kTestFrames / 4 - kTestFrames / 8 - kTestFrames / 16,
  347. decoded_buffer->frame_count());
  348. }
  349. TEST(AudioDiscardHelperTest, CompleteDiscard) {
  350. AudioDiscardHelper discard_helper(kSampleRate, 0, false);
  351. ASSERT_FALSE(discard_helper.initialized());
  352. const base::TimeDelta kTimestamp = base::TimeDelta();
  353. const base::TimeDelta kDuration = base::Milliseconds(10);
  354. const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
  355. discard_helper.Reset(0);
  356. DecoderBuffer::TimeInfo time_info = CreateTimeInfo(kTimestamp, kDuration);
  357. time_info.discard_padding =
  358. std::make_pair(kInfiniteDuration, base::TimeDelta());
  359. scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
  360. // Verify all of the first buffer is discarded.
  361. ASSERT_FALSE(discard_helper.ProcessBuffers(time_info, decoded_buffer.get()));
  362. ASSERT_TRUE(discard_helper.initialized());
  363. time_info.timestamp = kTimestamp + kDuration;
  364. time_info.discard_padding = DecoderBuffer::DiscardPadding();
  365. // Verify a second buffer goes through untouched.
  366. decoded_buffer = CreateDecodedBuffer(kTestFrames / 2);
  367. ASSERT_TRUE(discard_helper.ProcessBuffers(time_info, decoded_buffer.get()));
  368. EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
  369. EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
  370. EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
  371. ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(*decoded_buffer, 0));
  372. }
  373. TEST(AudioDiscardHelperTest, CompleteDiscardWithDelayedDiscard) {
  374. AudioDiscardHelper discard_helper(kSampleRate, 0, true);
  375. ASSERT_FALSE(discard_helper.initialized());
  376. const base::TimeDelta kTimestamp = base::TimeDelta();
  377. const base::TimeDelta kDuration = base::Milliseconds(10);
  378. const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
  379. discard_helper.Reset(0);
  380. DecoderBuffer::TimeInfo time_info = CreateTimeInfo(kTimestamp, kDuration);
  381. time_info.discard_padding =
  382. std::make_pair(kInfiniteDuration, base::TimeDelta());
  383. scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
  384. // Setup a delayed discard.
  385. ASSERT_FALSE(discard_helper.ProcessBuffers(time_info, NULL));
  386. ASSERT_TRUE(discard_helper.initialized());
  387. // Verify the first output buffer is dropped.
  388. time_info.timestamp = kTimestamp + kDuration;
  389. time_info.discard_padding = DecoderBuffer::DiscardPadding();
  390. ASSERT_FALSE(discard_helper.ProcessBuffers(time_info, decoded_buffer.get()));
  391. // Verify the second buffer goes through untouched.
  392. time_info.timestamp = kTimestamp + 2 * kDuration;
  393. decoded_buffer = CreateDecodedBuffer(kTestFrames / 2);
  394. ASSERT_TRUE(discard_helper.ProcessBuffers(time_info, decoded_buffer.get()));
  395. EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
  396. EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
  397. EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
  398. ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(*decoded_buffer, 0));
  399. }
  400. TEST(AudioDiscardHelperTest, CompleteDiscardWithInitialDiscardDecoderDelay) {
  401. // Use a decoder delay of 5ms.
  402. const int kDecoderDelay = kSampleRate / 100 / 2;
  403. AudioDiscardHelper discard_helper(kSampleRate, kDecoderDelay, false);
  404. ASSERT_FALSE(discard_helper.initialized());
  405. discard_helper.Reset(kDecoderDelay);
  406. const base::TimeDelta kTimestamp = base::TimeDelta();
  407. const base::TimeDelta kDuration = base::Milliseconds(10);
  408. const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
  409. DecoderBuffer::TimeInfo time_info = CreateTimeInfo(kTimestamp, kDuration);
  410. time_info.discard_padding =
  411. std::make_pair(kInfiniteDuration, base::TimeDelta());
  412. scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
  413. // Verify all of the first buffer is discarded.
  414. ASSERT_FALSE(discard_helper.ProcessBuffers(time_info, decoded_buffer.get()));
  415. ASSERT_TRUE(discard_helper.initialized());
  416. time_info.timestamp = kTimestamp + kDuration;
  417. time_info.discard_padding = DecoderBuffer::DiscardPadding();
  418. // Verify 5ms off the front of the second buffer is discarded.
  419. decoded_buffer = CreateDecodedBuffer(kTestFrames * 2);
  420. ASSERT_TRUE(discard_helper.ProcessBuffers(time_info, decoded_buffer.get()));
  421. EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
  422. EXPECT_EQ(kDuration * 2 - kDuration / 2, decoded_buffer->duration());
  423. EXPECT_EQ(kTestFrames * 2 - kDecoderDelay, decoded_buffer->frame_count());
  424. ASSERT_FLOAT_EQ(kDecoderDelay * kDataStep,
  425. ExtractDecodedData(*decoded_buffer, 0));
  426. }
  427. } // namespace media