OLD | NEW |
---|---|
(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 | |
OLD | NEW |