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

Side by Side Diff: media/base/audio_discard_helper_unittest.cc

Issue 259453003: Introduce AudioDiscardHelper. Refactor audio decoders to use it. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Simplify! Created 6 years, 8 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 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
5 #include "base/memory/scoped_ptr.h"
6 #include "media/base/audio_buffer.h"
7 #include "media/base/audio_discard_helper.h"
8 #include "media/base/buffers.h"
9 #include "media/base/decoder_buffer.h"
10 #include "media/base/test_helpers.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 namespace media {
14
15 static const int kSampleRate = 48000;
16
17 static scoped_refptr<DecoderBuffer> CreateEncodedBuffer(
18 base::TimeDelta timestamp,
19 base::TimeDelta duration) {
20 scoped_refptr<DecoderBuffer> result(new DecoderBuffer(1));
21 result->set_timestamp(timestamp);
22 result->set_duration(duration);
23 return result;
24 }
25
26 static scoped_refptr<AudioBuffer> CreateDecodedBuffer(int frames) {
27 return MakeAudioBuffer(kSampleFormatPlanarF32,
28 CHANNEL_LAYOUT_MONO,
29 1,
30 kSampleRate,
31 0.0f,
32 0.01f,
33 frames,
34 kNoTimestamp(),
35 kNoTimestamp());
36 }
37
38 TEST(AudioDiscardHelperTest, TimeDeltaToFrames) {
39 AudioDiscardHelper discard_helper(kSampleRate);
40
41 EXPECT_EQ(0, discard_helper.TimeDeltaToFrames(base::TimeDelta()));
42 EXPECT_EQ(
43 kSampleRate / 100,
44 discard_helper.TimeDeltaToFrames(base::TimeDelta::FromMilliseconds(10)));
45
46 // Ensure partial frames are always rounded up. The equation below calculates
47 // a frame count with a fractional part < 0.5.
48 const int small_remainder =
49 base::Time::kMicrosecondsPerSecond * (kSampleRate - 0.9) / kSampleRate;
50 EXPECT_EQ(kSampleRate,
51 discard_helper.TimeDeltaToFrames(
52 base::TimeDelta::FromMicroseconds(small_remainder)));
53 }
54
55 TEST(AudioDiscardHelperTest, BasicProcessBuffers) {
56 AudioDiscardHelper discard_helper(kSampleRate);
57 ASSERT_FALSE(discard_helper.initialized());
58
59 const base::TimeDelta kTimestamp = base::TimeDelta();
60
61 // Use an estimated duration which doesn't match the number of decoded frames
62 // to ensure the helper is correctly setting durations based on output frames.
63 const base::TimeDelta kEstimatedDuration =
64 base::TimeDelta::FromMilliseconds(9);
65 const base::TimeDelta kActualDuration = base::TimeDelta::FromMilliseconds(10);
66 const int kTestFrames = discard_helper.TimeDeltaToFrames(kActualDuration);
67
68 scoped_refptr<DecoderBuffer> encoded_buffer =
69 CreateEncodedBuffer(kTimestamp, kEstimatedDuration);
70 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
71
72 // Verify the basic case where nothing is discarded.
73 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
74 ASSERT_TRUE(discard_helper.initialized());
75 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
76 EXPECT_EQ(kActualDuration, decoded_buffer->duration());
77 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count());
78
79 // Verify a Reset() takes us back to an uninitialized state.
80 discard_helper.Reset(0);
81 ASSERT_FALSE(discard_helper.initialized());
82
83 // Verify a NULL output buffer returns false.
84 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, NULL));
85 }
86
87 TEST(AudioDiscardHelperTest, ProcessBuffersWithInitialDiscard) {
88 AudioDiscardHelper discard_helper(kSampleRate);
89 ASSERT_FALSE(discard_helper.initialized());
90
91 const base::TimeDelta kTimestamp = base::TimeDelta();
92 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
93 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
94
95 // Tell the helper we want to discard half of the initial frames.
96 discard_helper.Reset(kTestFrames / 2);
97
98 scoped_refptr<DecoderBuffer> encoded_buffer =
99 CreateEncodedBuffer(kTimestamp, kDuration);
100 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
101
102 // Verify half the frames end up discarded.
103 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
104 ASSERT_TRUE(discard_helper.initialized());
105 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
106 EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
107 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
108 }
109
110 TEST(AudioDiscardHelperTest, ProcessBuffersWithLargeInitialDiscard) {
111 AudioDiscardHelper discard_helper(kSampleRate);
112 ASSERT_FALSE(discard_helper.initialized());
113
114 const base::TimeDelta kTimestamp = base::TimeDelta();
115 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
116 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
117
118 // Tell the helper we want to discard 1.5 buffers worth of frames.
119 discard_helper.Reset(kTestFrames * 1.5);
120
121 scoped_refptr<DecoderBuffer> encoded_buffer =
122 CreateEncodedBuffer(kTimestamp, kDuration);
123 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
124
125 // The first call should fail since no output buffer remains.
126 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
127 ASSERT_TRUE(discard_helper.initialized());
128
129 // Generate another set of buffers and expect half the output frames.
130 encoded_buffer = CreateEncodedBuffer(kTimestamp + kDuration, kDuration);
131 decoded_buffer = CreateDecodedBuffer(kTestFrames);
132 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
133
134 // The timestamp should match that of the initial buffer.
135 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
136 EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
137 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
138 }
139
140 TEST(AudioDiscardHelperTest, AllowNonMonotonicTimestamps) {
141 AudioDiscardHelper discard_helper(kSampleRate);
142 ASSERT_FALSE(discard_helper.initialized());
143
144 const base::TimeDelta kTimestamp = base::TimeDelta();
145 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
146 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
147
148 scoped_refptr<DecoderBuffer> encoded_buffer =
149 CreateEncodedBuffer(kTimestamp, kDuration);
150 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
151
152 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
153 ASSERT_TRUE(discard_helper.initialized());
154 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
155 EXPECT_EQ(kDuration, decoded_buffer->duration());
156 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count());
157
158 // Process the same input buffer again to ensure input timestamps which go
wolenetz 2014/04/28 21:52:07 nit: timestamp really isn't going backwards in tim
DaleCurtis 2014/04/28 23:09:03 kTimestamp on buffer 2 is now behind kTimestamp+kD
159 // backwards in time are not errors.
160 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
161 EXPECT_EQ(kTimestamp + kDuration, decoded_buffer->timestamp());
162 EXPECT_EQ(kDuration, decoded_buffer->duration());
163 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count());
164 }
165
166 TEST(AudioDiscardHelperTest, DiscardPadding) {
wolenetz 2014/04/28 21:52:07 Versus ProcessBuffersWithInitialDiscard and Initia
DaleCurtis 2014/04/28 23:09:03 Done. Doing so required improving the accuracy of
167 AudioDiscardHelper discard_helper(kSampleRate);
168 ASSERT_FALSE(discard_helper.initialized());
169
170 const base::TimeDelta kTimestamp = base::TimeDelta();
171 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
172 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
173
174 scoped_refptr<DecoderBuffer> encoded_buffer =
175 CreateEncodedBuffer(kTimestamp, kDuration);
176 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
177
178 // Set a discard padding equivalent to half the buffer.
179 encoded_buffer->set_discard_padding(kDuration / 2);
180
181 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
182 ASSERT_TRUE(discard_helper.initialized());
183 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
184 EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
185 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
186 }
187
188 TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPadding) {
189 AudioDiscardHelper discard_helper(kSampleRate);
190 ASSERT_FALSE(discard_helper.initialized());
191
192 const base::TimeDelta kTimestamp = base::TimeDelta();
193 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
194 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
195
196 scoped_refptr<DecoderBuffer> encoded_buffer =
197 CreateEncodedBuffer(kTimestamp, kDuration);
198 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
199
200 // Set a discard padding equivalent to a quarter of the buffer.
201 encoded_buffer->set_discard_padding(kDuration / 4);
202
203 // Set an initial discard of a quarter of the buffer.
204 discard_helper.Reset(kTestFrames / 4);
205
206 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
207 ASSERT_TRUE(discard_helper.initialized());
208 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
209 EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
210 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
211 }
212
wolenetz 2014/04/28 21:52:07 nit: remove extra line.
DaleCurtis 2014/04/28 23:09:03 Done.
213
214 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698