Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/memory/scoped_ptr.h" | 5 #include "base/memory/scoped_ptr.h" |
| 6 #include "media/base/audio_buffer.h" | 6 #include "media/base/audio_buffer.h" |
| 7 #include "media/base/audio_bus.h" | 7 #include "media/base/audio_bus.h" |
| 8 #include "media/base/audio_splicer.h" | 8 #include "media/base/audio_splicer.h" |
| 9 #include "media/base/audio_timestamp_helper.h" | 9 #include "media/base/audio_timestamp_helper.h" |
| 10 #include "media/base/buffers.h" | 10 #include "media/base/buffers.h" |
| 11 #include "media/base/test_helpers.h" | 11 #include "media/base/test_helpers.h" |
| 12 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
| 13 | 13 |
| 14 namespace media { | 14 namespace media { |
| 15 | 15 |
| 16 static const SampleFormat kSampleFormat = kSampleFormatF32; | 16 static const SampleFormat kSampleFormat = kSampleFormatF32; |
| 17 static const int kChannels = 1; | 17 static const int kChannels = 1; |
| 18 static const int kDefaultSampleRate = 44100; | 18 static const int kDefaultSampleRate = 44100; |
| 19 static const int kDefaultBufferSize = 100; | 19 static const int kDefaultBufferSize = 100; |
| 20 | 20 |
| 21 class AudioSplicerTest : public ::testing::Test { | 21 class AudioSplicerTest : public ::testing::Test { |
| 22 public: | 22 public: |
| 23 AudioSplicerTest() | 23 AudioSplicerTest() |
| 24 : splicer_(kDefaultSampleRate), | 24 : splicer_(kDefaultSampleRate), |
| 25 input_timestamp_helper_(kDefaultSampleRate) { | 25 input_timestamp_helper_(kDefaultSampleRate), |
| 26 output_timestamp_helper_(kDefaultSampleRate) { | |
| 26 input_timestamp_helper_.SetBaseTimestamp(base::TimeDelta()); | 27 input_timestamp_helper_.SetBaseTimestamp(base::TimeDelta()); |
| 28 output_timestamp_helper_.SetBaseTimestamp(base::TimeDelta()); | |
| 27 } | 29 } |
| 28 | 30 |
| 29 scoped_refptr<AudioBuffer> GetNextInputBuffer(float value) { | 31 scoped_refptr<AudioBuffer> GetNextInputBuffer(float value) { |
| 30 return GetNextInputBuffer(value, kDefaultBufferSize); | 32 return GetNextInputBuffer(value, kDefaultBufferSize); |
| 31 } | 33 } |
| 32 | 34 |
| 33 scoped_refptr<AudioBuffer> GetNextInputBuffer(float value, int frame_size) { | 35 scoped_refptr<AudioBuffer> GetNextInputBuffer(float value, int frame_size) { |
| 34 scoped_refptr<AudioBuffer> buffer = MakeInterleavedAudioBuffer<float>( | 36 scoped_refptr<AudioBuffer> buffer = MakeInterleavedAudioBuffer<float>( |
| 35 kSampleFormat, | 37 kSampleFormat, |
| 36 kChannels, | 38 kChannels, |
| 37 value, | 39 value, |
| 38 0.0f, | 40 0.0f, |
| 39 frame_size, | 41 frame_size, |
| 40 input_timestamp_helper_.GetTimestamp(), | 42 input_timestamp_helper_.GetTimestamp(), |
| 41 input_timestamp_helper_.GetFrameDuration(frame_size)); | 43 input_timestamp_helper_.GetFrameDuration(frame_size)); |
| 42 input_timestamp_helper_.AddFrames(frame_size); | 44 input_timestamp_helper_.AddFrames(frame_size); |
| 43 return buffer; | 45 return buffer; |
| 44 } | 46 } |
| 45 | 47 |
| 46 bool VerifyData(scoped_refptr<AudioBuffer> buffer, float value) { | 48 bool VerifyData(const scoped_refptr<AudioBuffer>& buffer, float value) { |
| 47 int frames = buffer->frame_count(); | 49 int frames = buffer->frame_count(); |
| 48 scoped_ptr<AudioBus> bus = AudioBus::Create(kChannels, frames); | 50 scoped_ptr<AudioBus> bus = AudioBus::Create(kChannels, frames); |
| 49 buffer->ReadFrames(frames, 0, 0, bus.get()); | 51 buffer->ReadFrames(frames, 0, 0, bus.get()); |
| 50 for (int i = 0; i < frames; ++i) { | 52 for (int ch = 0; ch < buffer->channel_count(); ++ch) { |
| 51 if (bus->channel(0)[i] != value) | 53 for (int i = 0; i < frames; ++i) { |
| 52 return false; | 54 if (bus->channel(ch)[i] != value) |
| 55 return false; | |
| 56 } | |
| 53 } | 57 } |
| 54 return true; | 58 return true; |
| 55 } | 59 } |
| 56 | 60 |
| 61 void VerifyNextBuffer(const scoped_refptr<AudioBuffer>& input, float value) { | |
| 62 ASSERT_TRUE(splicer_.HasNextBuffer()); | |
| 63 scoped_refptr<AudioBuffer> output = splicer_.GetNextBuffer(); | |
| 64 EXPECT_EQ(input->timestamp(), output->timestamp()); | |
| 65 EXPECT_EQ(input->duration(), output->duration()); | |
| 66 EXPECT_EQ(input->frame_count(), output->frame_count()); | |
| 67 EXPECT_TRUE(VerifyData(output, value)); | |
| 68 output_timestamp_helper_.AddFrames(output->frame_count()); | |
| 69 } | |
| 70 | |
| 71 void VerifyPreSpliceOutput( | |
| 72 const scoped_refptr<AudioBuffer>& overlapped_buffer, | |
| 73 const scoped_refptr<AudioBuffer>& overlapping_buffer, | |
| 74 float overlapped_value) { | |
| 75 const base::TimeDelta kSpliceTimestamp = overlapping_buffer->timestamp(); | |
| 76 const int kExpectedPreSpliceSize = | |
| 77 output_timestamp_helper_.GetFramesToTarget(kSpliceTimestamp); | |
| 78 const base::TimeDelta kExpectedPreSpliceDuration = | |
| 79 output_timestamp_helper_.GetFrameDuration(kExpectedPreSpliceSize); | |
| 80 | |
| 81 ASSERT_TRUE(splicer_.HasNextBuffer()); | |
| 82 scoped_refptr<AudioBuffer> pre_splice_output = splicer_.GetNextBuffer(); | |
| 83 EXPECT_EQ(overlapped_buffer->timestamp(), pre_splice_output->timestamp()); | |
| 84 EXPECT_EQ(kExpectedPreSpliceDuration, pre_splice_output->duration()); | |
| 85 EXPECT_EQ(kExpectedPreSpliceSize, pre_splice_output->frame_count()); | |
| 86 EXPECT_TRUE(VerifyData(pre_splice_output, overlapped_value)); | |
| 87 output_timestamp_helper_.AddFrames(pre_splice_output->frame_count()); | |
| 88 } | |
| 89 | |
| 90 base::TimeDelta CalculateCrossfadeDuration( | |
| 91 const scoped_refptr<AudioBuffer>& overlapped_buffer, | |
| 92 const scoped_refptr<AudioBuffer>& overlapping_buffer) { | |
| 93 return std::min(max_crossfade_duration(), | |
| 94 std::min(overlapped_buffer->timestamp() + | |
| 95 overlapped_buffer->duration() - | |
| 96 overlapping_buffer->timestamp(), | |
| 97 overlapping_buffer->duration())); | |
| 98 } | |
| 99 | |
| 100 void VerifyCrossfadeOutput( | |
| 101 const scoped_refptr<AudioBuffer>& overlapped_buffer, | |
| 102 const scoped_refptr<AudioBuffer>& overlapping_buffer, | |
| 103 float overlapped_value, | |
| 104 float overlapping_value, | |
| 105 base::TimeDelta* expected_crossfade_duration, | |
| 106 int64* expected_crossfade_size) { | |
| 107 ASSERT_TRUE(splicer_.HasNextBuffer()); | |
| 108 | |
| 109 const base::TimeDelta kSpliceTimestamp = | |
|
acolwell GONE FROM CHROMIUM
2014/02/27 17:10:14
I'm a little concerned that we are trying to repli
DaleCurtis
2014/02/27 19:45:01
I generally dislike constant only verification in
DaleCurtis
2014/02/28 00:24:41
Mostly done. I also cleaned up the verify syntax.
| |
| 110 output_timestamp_helper_.GetTimestamp(); | |
| 111 *expected_crossfade_size = output_timestamp_helper_.GetFramesToTarget( | |
| 112 kSpliceTimestamp + | |
| 113 CalculateCrossfadeDuration(overlapped_buffer, overlapping_buffer)); | |
| 114 // Don't use the calculated duration directly as it may differ in truthiness | |
| 115 // by a few microseconds from what the AudioTimestampHelper is returning. | |
| 116 *expected_crossfade_duration = | |
| 117 output_timestamp_helper_.GetFrameDuration(*expected_crossfade_size); | |
| 118 | |
| 119 scoped_refptr<AudioBuffer> crossfade_output = splicer_.GetNextBuffer(); | |
| 120 EXPECT_EQ(kSpliceTimestamp, crossfade_output->timestamp()); | |
| 121 EXPECT_EQ(*expected_crossfade_duration, crossfade_output->duration()); | |
| 122 EXPECT_EQ(*expected_crossfade_size, crossfade_output->frame_count()); | |
| 123 output_timestamp_helper_.AddFrames(crossfade_output->frame_count()); | |
| 124 | |
| 125 // Verify the actual crossfade. | |
| 126 const int frames = crossfade_output->frame_count(); | |
| 127 scoped_ptr<AudioBus> bus = AudioBus::Create(kChannels, frames); | |
| 128 crossfade_output->ReadFrames(frames, 0, 0, bus.get()); | |
| 129 for (int ch = 0; ch < crossfade_output->channel_count(); ++ch) { | |
| 130 float cf_ratio = 0; | |
| 131 const float cf_increment = 1.0f / frames; | |
| 132 for (int i = 0; i < frames; ++i, cf_ratio += cf_increment) { | |
| 133 const float actual = bus->channel(ch)[i]; | |
| 134 const float expected = | |
| 135 (1.0f - cf_ratio) * overlapped_value + cf_ratio * overlapping_value; | |
| 136 ASSERT_FLOAT_EQ(expected, actual) << "i=" << i; | |
| 137 } | |
| 138 } | |
| 139 } | |
| 140 | |
| 141 bool AddInput(const scoped_refptr<AudioBuffer>& input) { | |
| 142 // Since the splicer doesn't make copies it's working directly on the input | |
| 143 // buffers. We must make a copy before adding to ensure the original buffer | |
| 144 // is not modified in unexpected ways. | |
| 145 scoped_refptr<AudioBuffer> buffer_copy = | |
| 146 input->end_of_stream() | |
| 147 ? AudioBuffer::CreateEOSBuffer() | |
| 148 : AudioBuffer::CopyFrom(kSampleFormat, | |
| 149 input->channel_count(), | |
| 150 input->frame_count(), | |
| 151 &input->channel_data()[0], | |
| 152 input->timestamp(), | |
| 153 input->duration()); | |
| 154 return splicer_.AddInput(buffer_copy); | |
| 155 } | |
| 156 | |
| 157 base::TimeDelta max_crossfade_duration() { | |
| 158 return splicer_.max_crossfade_duration_; | |
| 159 } | |
| 160 | |
| 57 protected: | 161 protected: |
| 58 AudioSplicer splicer_; | 162 AudioSplicer splicer_; |
| 59 AudioTimestampHelper input_timestamp_helper_; | 163 AudioTimestampHelper input_timestamp_helper_; |
| 164 AudioTimestampHelper output_timestamp_helper_; | |
| 60 | 165 |
| 61 DISALLOW_COPY_AND_ASSIGN(AudioSplicerTest); | 166 DISALLOW_COPY_AND_ASSIGN(AudioSplicerTest); |
| 62 }; | 167 }; |
| 63 | 168 |
| 64 TEST_F(AudioSplicerTest, PassThru) { | 169 TEST_F(AudioSplicerTest, PassThru) { |
| 65 EXPECT_FALSE(splicer_.HasNextBuffer()); | 170 EXPECT_FALSE(splicer_.HasNextBuffer()); |
| 66 | 171 |
| 67 // Test single buffer pass-thru behavior. | 172 // Test single buffer pass-thru behavior. |
| 68 scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); | 173 scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); |
| 69 EXPECT_TRUE(splicer_.AddInput(input_1)); | 174 EXPECT_TRUE(AddInput(input_1)); |
| 70 EXPECT_TRUE(splicer_.HasNextBuffer()); | 175 VerifyNextBuffer(input_1, 0.1f); |
| 71 | |
| 72 scoped_refptr<AudioBuffer> output_1 = splicer_.GetNextBuffer(); | |
| 73 EXPECT_FALSE(splicer_.HasNextBuffer()); | 176 EXPECT_FALSE(splicer_.HasNextBuffer()); |
| 74 EXPECT_EQ(input_1->timestamp(), output_1->timestamp()); | |
| 75 EXPECT_EQ(input_1->duration(), output_1->duration()); | |
| 76 EXPECT_EQ(input_1->frame_count(), output_1->frame_count()); | |
| 77 EXPECT_TRUE(VerifyData(output_1, 0.1f)); | |
| 78 | 177 |
| 79 // Test that multiple buffers can be queued in the splicer. | 178 // Test that multiple buffers can be queued in the splicer. |
| 80 scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f); | 179 scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f); |
| 81 scoped_refptr<AudioBuffer> input_3 = GetNextInputBuffer(0.3f); | 180 scoped_refptr<AudioBuffer> input_3 = GetNextInputBuffer(0.3f); |
| 82 EXPECT_TRUE(splicer_.AddInput(input_2)); | 181 EXPECT_TRUE(AddInput(input_2)); |
| 83 EXPECT_TRUE(splicer_.AddInput(input_3)); | 182 EXPECT_TRUE(AddInput(input_3)); |
| 84 EXPECT_TRUE(splicer_.HasNextBuffer()); | 183 VerifyNextBuffer(input_2, 0.2f); |
| 85 | 184 VerifyNextBuffer(input_3, 0.3f); |
| 86 scoped_refptr<AudioBuffer> output_2 = splicer_.GetNextBuffer(); | |
| 87 EXPECT_TRUE(splicer_.HasNextBuffer()); | |
| 88 EXPECT_EQ(input_2->timestamp(), output_2->timestamp()); | |
| 89 EXPECT_EQ(input_2->duration(), output_2->duration()); | |
| 90 EXPECT_EQ(input_2->frame_count(), output_2->frame_count()); | |
| 91 | |
| 92 scoped_refptr<AudioBuffer> output_3 = splicer_.GetNextBuffer(); | |
| 93 EXPECT_FALSE(splicer_.HasNextBuffer()); | 185 EXPECT_FALSE(splicer_.HasNextBuffer()); |
| 94 EXPECT_EQ(input_3->timestamp(), output_3->timestamp()); | |
| 95 EXPECT_EQ(input_3->duration(), output_3->duration()); | |
| 96 EXPECT_EQ(input_3->frame_count(), output_3->frame_count()); | |
| 97 } | 186 } |
| 98 | 187 |
| 99 TEST_F(AudioSplicerTest, Reset) { | 188 TEST_F(AudioSplicerTest, Reset) { |
| 100 scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); | 189 scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); |
| 101 EXPECT_TRUE(splicer_.AddInput(input_1)); | 190 EXPECT_TRUE(AddInput(input_1)); |
| 102 EXPECT_TRUE(splicer_.HasNextBuffer()); | 191 ASSERT_TRUE(splicer_.HasNextBuffer()); |
| 103 | 192 |
| 104 splicer_.Reset(); | 193 splicer_.Reset(); |
| 105 EXPECT_FALSE(splicer_.HasNextBuffer()); | 194 EXPECT_FALSE(splicer_.HasNextBuffer()); |
| 106 | 195 |
| 107 // Add some bytes to the timestamp helper so that the | 196 // Add some bytes to the timestamp helper so that the |
| 108 // next buffer starts many frames beyond the end of | 197 // next buffer starts many frames beyond the end of |
| 109 // |input_1|. This is to make sure that Reset() actually | 198 // |input_1|. This is to make sure that Reset() actually |
| 110 // clears its state and doesn't try to insert a gap. | 199 // clears its state and doesn't try to insert a gap. |
| 111 input_timestamp_helper_.AddFrames(100); | 200 input_timestamp_helper_.AddFrames(100); |
| 112 | 201 |
| 113 // Verify that a new input buffer passes through as expected. | 202 // Verify that a new input buffer passes through as expected. |
| 114 scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f); | 203 scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f); |
| 115 EXPECT_TRUE(splicer_.AddInput(input_2)); | 204 EXPECT_TRUE(AddInput(input_2)); |
| 116 EXPECT_TRUE(splicer_.HasNextBuffer()); | 205 ASSERT_TRUE(splicer_.HasNextBuffer()); |
| 117 | 206 VerifyNextBuffer(input_2, 0.2f); |
| 118 scoped_refptr<AudioBuffer> output_2 = splicer_.GetNextBuffer(); | |
| 119 EXPECT_FALSE(splicer_.HasNextBuffer()); | 207 EXPECT_FALSE(splicer_.HasNextBuffer()); |
| 120 EXPECT_EQ(input_2->timestamp(), output_2->timestamp()); | |
| 121 EXPECT_EQ(input_2->duration(), output_2->duration()); | |
| 122 EXPECT_EQ(input_2->frame_count(), output_2->frame_count()); | |
| 123 } | 208 } |
| 124 | 209 |
| 125 TEST_F(AudioSplicerTest, EndOfStream) { | 210 TEST_F(AudioSplicerTest, EndOfStream) { |
| 126 scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); | 211 scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); |
| 127 scoped_refptr<AudioBuffer> input_2 = AudioBuffer::CreateEOSBuffer(); | 212 scoped_refptr<AudioBuffer> input_2 = AudioBuffer::CreateEOSBuffer(); |
| 128 scoped_refptr<AudioBuffer> input_3 = GetNextInputBuffer(0.2f); | 213 scoped_refptr<AudioBuffer> input_3 = GetNextInputBuffer(0.2f); |
| 129 EXPECT_TRUE(input_2->end_of_stream()); | 214 EXPECT_TRUE(input_2->end_of_stream()); |
| 130 | 215 |
| 131 EXPECT_TRUE(splicer_.AddInput(input_1)); | 216 EXPECT_TRUE(AddInput(input_1)); |
| 132 EXPECT_TRUE(splicer_.AddInput(input_2)); | 217 EXPECT_TRUE(AddInput(input_2)); |
| 133 EXPECT_TRUE(splicer_.HasNextBuffer()); | |
| 134 | 218 |
| 135 scoped_refptr<AudioBuffer> output_1 = splicer_.GetNextBuffer(); | 219 VerifyNextBuffer(input_1, 0.1f); |
| 220 | |
| 136 scoped_refptr<AudioBuffer> output_2 = splicer_.GetNextBuffer(); | 221 scoped_refptr<AudioBuffer> output_2 = splicer_.GetNextBuffer(); |
| 137 EXPECT_FALSE(splicer_.HasNextBuffer()); | 222 EXPECT_FALSE(splicer_.HasNextBuffer()); |
| 138 EXPECT_EQ(input_1->timestamp(), output_1->timestamp()); | |
| 139 EXPECT_EQ(input_1->duration(), output_1->duration()); | |
| 140 EXPECT_EQ(input_1->frame_count(), output_1->frame_count()); | |
| 141 | |
| 142 EXPECT_TRUE(output_2->end_of_stream()); | 223 EXPECT_TRUE(output_2->end_of_stream()); |
| 143 | 224 |
| 144 // Verify that buffers can be added again after Reset(). | 225 // Verify that buffers can be added again after Reset(). |
| 145 splicer_.Reset(); | 226 splicer_.Reset(); |
| 146 EXPECT_TRUE(splicer_.AddInput(input_3)); | 227 EXPECT_TRUE(AddInput(input_3)); |
| 147 scoped_refptr<AudioBuffer> output_3 = splicer_.GetNextBuffer(); | 228 VerifyNextBuffer(input_3, 0.2f); |
| 148 EXPECT_FALSE(splicer_.HasNextBuffer()); | 229 EXPECT_FALSE(splicer_.HasNextBuffer()); |
| 149 EXPECT_EQ(input_3->timestamp(), output_3->timestamp()); | |
| 150 EXPECT_EQ(input_3->duration(), output_3->duration()); | |
| 151 EXPECT_EQ(input_3->frame_count(), output_3->frame_count()); | |
| 152 } | 230 } |
| 153 | 231 |
| 154 | |
| 155 // Test the gap insertion code. | 232 // Test the gap insertion code. |
| 156 // +--------------+ +--------------+ | 233 // +--------------+ +--------------+ |
| 157 // |11111111111111| |22222222222222| | 234 // |11111111111111| |22222222222222| |
| 158 // +--------------+ +--------------+ | 235 // +--------------+ +--------------+ |
| 159 // Results in: | 236 // Results in: |
| 160 // +--------------+----+--------------+ | 237 // +--------------+----+--------------+ |
| 161 // |11111111111111|0000|22222222222222| | 238 // |11111111111111|0000|22222222222222| |
| 162 // +--------------+----+--------------+ | 239 // +--------------+----+--------------+ |
| 163 TEST_F(AudioSplicerTest, GapInsertion) { | 240 TEST_F(AudioSplicerTest, GapInsertion) { |
| 164 scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); | 241 scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); |
| 165 | 242 |
| 166 // Add bytes to the timestamp helper so that the next buffer | 243 // Add bytes to the timestamp helper so that the next buffer |
| 167 // will have a starting timestamp that indicates a gap is | 244 // will have a starting timestamp that indicates a gap is |
| 168 // present. | 245 // present. |
| 169 const int kGapSize = 7; | 246 const int kGapSize = 7; |
| 170 input_timestamp_helper_.AddFrames(kGapSize); | 247 input_timestamp_helper_.AddFrames(kGapSize); |
| 171 scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f); | 248 scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f); |
| 172 | 249 |
| 173 EXPECT_TRUE(splicer_.AddInput(input_1)); | 250 EXPECT_TRUE(AddInput(input_1)); |
| 174 EXPECT_TRUE(splicer_.AddInput(input_2)); | 251 EXPECT_TRUE(AddInput(input_2)); |
| 175 | |
| 176 // Verify that a gap buffer is generated. | |
| 177 EXPECT_TRUE(splicer_.HasNextBuffer()); | |
| 178 scoped_refptr<AudioBuffer> output_1 = splicer_.GetNextBuffer(); | |
| 179 scoped_refptr<AudioBuffer> output_2 = splicer_.GetNextBuffer(); | |
| 180 scoped_refptr<AudioBuffer> output_3 = splicer_.GetNextBuffer(); | |
| 181 EXPECT_FALSE(splicer_.HasNextBuffer()); | |
| 182 | 252 |
| 183 // Verify that the first input buffer passed through unmodified. | 253 // Verify that the first input buffer passed through unmodified. |
| 184 EXPECT_EQ(input_1->timestamp(), output_1->timestamp()); | 254 VerifyNextBuffer(input_1, 0.1f); |
| 185 EXPECT_EQ(input_1->duration(), output_1->duration()); | |
| 186 EXPECT_EQ(input_1->frame_count(), output_1->frame_count()); | |
| 187 EXPECT_TRUE(VerifyData(output_1, 0.1f)); | |
| 188 | 255 |
| 189 // Verify the contents of the gap buffer. | 256 // Verify the contents of the gap buffer. |
| 257 scoped_refptr<AudioBuffer> output_2 = splicer_.GetNextBuffer(); | |
| 190 base::TimeDelta gap_timestamp = | 258 base::TimeDelta gap_timestamp = |
| 191 input_1->timestamp() + input_1->duration(); | 259 input_1->timestamp() + input_1->duration(); |
| 192 base::TimeDelta gap_duration = input_2->timestamp() - gap_timestamp; | 260 base::TimeDelta gap_duration = input_2->timestamp() - gap_timestamp; |
| 193 EXPECT_GT(gap_duration, base::TimeDelta()); | 261 EXPECT_GT(gap_duration, base::TimeDelta()); |
| 194 EXPECT_EQ(gap_timestamp, output_2->timestamp()); | 262 EXPECT_EQ(gap_timestamp, output_2->timestamp()); |
| 195 EXPECT_EQ(gap_duration, output_2->duration()); | 263 EXPECT_EQ(gap_duration, output_2->duration()); |
| 196 EXPECT_EQ(kGapSize, output_2->frame_count()); | 264 EXPECT_EQ(kGapSize, output_2->frame_count()); |
| 197 EXPECT_TRUE(VerifyData(output_2, 0.0f)); | 265 EXPECT_TRUE(VerifyData(output_2, 0.0f)); |
| 198 | 266 |
| 199 // Verify that the second input buffer passed through unmodified. | 267 // Verify that the second input buffer passed through unmodified. |
| 200 EXPECT_EQ(input_2->timestamp(), output_3->timestamp()); | 268 VerifyNextBuffer(input_2, 0.2f); |
| 201 EXPECT_EQ(input_2->duration(), output_3->duration()); | 269 EXPECT_FALSE(splicer_.HasNextBuffer()); |
| 202 EXPECT_EQ(input_2->frame_count(), output_3->frame_count()); | |
| 203 EXPECT_TRUE(VerifyData(output_3, 0.2f)); | |
| 204 } | 270 } |
| 205 | 271 |
| 206 | |
| 207 // Test that an error is signalled when the gap between input buffers is | 272 // Test that an error is signalled when the gap between input buffers is |
| 208 // too large. | 273 // too large. |
| 209 TEST_F(AudioSplicerTest, GapTooLarge) { | 274 TEST_F(AudioSplicerTest, GapTooLarge) { |
| 210 scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); | 275 scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); |
| 211 | 276 |
| 212 // Add a seconds worth of bytes so that an unacceptably large | 277 // Add a seconds worth of bytes so that an unacceptably large |
| 213 // gap exists between |input_1| and |input_2|. | 278 // gap exists between |input_1| and |input_2|. |
| 214 const int kGapSize = kDefaultSampleRate; | 279 const int kGapSize = kDefaultSampleRate; |
| 215 input_timestamp_helper_.AddFrames(kGapSize); | 280 input_timestamp_helper_.AddFrames(kGapSize); |
| 216 scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f); | 281 scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f); |
| 217 | 282 |
| 218 EXPECT_TRUE(splicer_.AddInput(input_1)); | 283 EXPECT_TRUE(AddInput(input_1)); |
| 219 EXPECT_FALSE(splicer_.AddInput(input_2)); | 284 EXPECT_FALSE(AddInput(input_2)); |
| 220 | 285 |
| 221 EXPECT_TRUE(splicer_.HasNextBuffer()); | 286 VerifyNextBuffer(input_1, 0.1f); |
| 222 scoped_refptr<AudioBuffer> output_1 = splicer_.GetNextBuffer(); | |
| 223 | |
| 224 // Verify that the first input buffer passed through unmodified. | |
| 225 EXPECT_EQ(input_1->timestamp(), output_1->timestamp()); | |
| 226 EXPECT_EQ(input_1->duration(), output_1->duration()); | |
| 227 EXPECT_EQ(input_1->frame_count(), output_1->frame_count()); | |
| 228 EXPECT_TRUE(VerifyData(output_1, 0.1f)); | |
| 229 | 287 |
| 230 // Verify that the second buffer is not available. | 288 // Verify that the second buffer is not available. |
| 231 EXPECT_FALSE(splicer_.HasNextBuffer()); | 289 EXPECT_FALSE(splicer_.HasNextBuffer()); |
| 232 | 290 |
| 233 // Reset the timestamp helper so it can generate a buffer that is | 291 // Reset the timestamp helper so it can generate a buffer that is |
| 234 // right after |input_1|. | 292 // right after |input_1|. |
| 235 input_timestamp_helper_.SetBaseTimestamp( | 293 input_timestamp_helper_.SetBaseTimestamp( |
| 236 input_1->timestamp() + input_1->duration()); | 294 input_1->timestamp() + input_1->duration()); |
| 237 | 295 |
| 238 // Verify that valid buffers are still accepted. | 296 // Verify that valid buffers are still accepted. |
| 239 scoped_refptr<AudioBuffer> input_3 = GetNextInputBuffer(0.3f); | 297 scoped_refptr<AudioBuffer> input_3 = GetNextInputBuffer(0.3f); |
| 240 EXPECT_TRUE(splicer_.AddInput(input_3)); | 298 EXPECT_TRUE(AddInput(input_3)); |
| 241 EXPECT_TRUE(splicer_.HasNextBuffer()); | 299 VerifyNextBuffer(input_3, 0.3f); |
| 242 scoped_refptr<AudioBuffer> output_2 = splicer_.GetNextBuffer(); | |
| 243 EXPECT_FALSE(splicer_.HasNextBuffer()); | 300 EXPECT_FALSE(splicer_.HasNextBuffer()); |
| 244 EXPECT_EQ(input_3->timestamp(), output_2->timestamp()); | |
| 245 EXPECT_EQ(input_3->duration(), output_2->duration()); | |
| 246 EXPECT_EQ(input_3->frame_count(), output_2->frame_count()); | |
| 247 EXPECT_TRUE(VerifyData(output_2, 0.3f)); | |
| 248 } | 301 } |
| 249 | 302 |
| 250 | |
| 251 // Verifies that an error is signalled if AddInput() is called | 303 // Verifies that an error is signalled if AddInput() is called |
| 252 // with a timestamp that is earlier than the first buffer added. | 304 // with a timestamp that is earlier than the first buffer added. |
| 253 TEST_F(AudioSplicerTest, BufferAddedBeforeBase) { | 305 TEST_F(AudioSplicerTest, BufferAddedBeforeBase) { |
| 254 input_timestamp_helper_.SetBaseTimestamp( | 306 input_timestamp_helper_.SetBaseTimestamp( |
| 255 base::TimeDelta::FromMicroseconds(10)); | 307 base::TimeDelta::FromMicroseconds(10)); |
| 256 scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); | 308 scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); |
| 257 | 309 |
| 258 // Reset the timestamp helper so the next buffer will have a timestamp earlier | 310 // Reset the timestamp helper so the next buffer will have a timestamp earlier |
| 259 // than |input_1|. | 311 // than |input_1|. |
| 260 input_timestamp_helper_.SetBaseTimestamp(base::TimeDelta::FromSeconds(0)); | 312 input_timestamp_helper_.SetBaseTimestamp(base::TimeDelta::FromSeconds(0)); |
| 261 scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.1f); | 313 scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.1f); |
| 262 | 314 |
| 263 EXPECT_GT(input_1->timestamp(), input_2->timestamp()); | 315 EXPECT_GT(input_1->timestamp(), input_2->timestamp()); |
| 264 EXPECT_TRUE(splicer_.AddInput(input_1)); | 316 EXPECT_TRUE(AddInput(input_1)); |
| 265 EXPECT_FALSE(splicer_.AddInput(input_2)); | 317 EXPECT_FALSE(AddInput(input_2)); |
| 266 } | 318 } |
| 267 | 319 |
| 268 | |
| 269 // Test when one buffer partially overlaps another. | 320 // Test when one buffer partially overlaps another. |
| 270 // +--------------+ | 321 // +--------------+ |
| 271 // |11111111111111| | 322 // |11111111111111| |
| 272 // +--------------+ | 323 // +--------------+ |
| 273 // +--------------+ | 324 // +--------------+ |
| 274 // |22222222222222| | 325 // |22222222222222| |
| 275 // +--------------+ | 326 // +--------------+ |
| 276 // Results in: | 327 // Results in: |
| 277 // +--------------+----------+ | 328 // +--------------+----------+ |
| 278 // |11111111111111|2222222222| | 329 // |11111111111111|2222222222| |
| 279 // +--------------+----------+ | 330 // +--------------+----------+ |
| 280 TEST_F(AudioSplicerTest, PartialOverlap) { | 331 TEST_F(AudioSplicerTest, PartialOverlap) { |
| 281 scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); | 332 scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); |
| 282 | 333 |
| 283 // Reset timestamp helper so that the next buffer will have a | 334 // Reset timestamp helper so that the next buffer will have a |
| 284 // timestamp that starts in the middle of |input_1|. | 335 // timestamp that starts in the middle of |input_1|. |
| 285 const int kOverlapSize = input_1->frame_count() / 4; | 336 const int kOverlapSize = input_1->frame_count() / 4; |
| 286 input_timestamp_helper_.SetBaseTimestamp(input_1->timestamp()); | 337 input_timestamp_helper_.SetBaseTimestamp(input_1->timestamp()); |
| 287 input_timestamp_helper_.AddFrames(input_1->frame_count() - kOverlapSize); | 338 input_timestamp_helper_.AddFrames(input_1->frame_count() - kOverlapSize); |
| 288 | 339 |
| 289 scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f); | 340 scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f); |
| 290 | 341 |
| 291 EXPECT_TRUE(splicer_.AddInput(input_1)); | 342 EXPECT_TRUE(AddInput(input_1)); |
| 292 EXPECT_TRUE(splicer_.AddInput(input_2)); | 343 EXPECT_TRUE(AddInput(input_2)); |
| 293 | 344 |
| 294 EXPECT_TRUE(splicer_.HasNextBuffer()); | 345 // Verify that the first input buffer passed through unmodified. |
| 295 scoped_refptr<AudioBuffer> output_1 = splicer_.GetNextBuffer(); | 346 VerifyNextBuffer(input_1, 0.1f); |
| 347 ASSERT_TRUE(splicer_.HasNextBuffer()); | |
| 348 | |
| 296 scoped_refptr<AudioBuffer> output_2 = splicer_.GetNextBuffer(); | 349 scoped_refptr<AudioBuffer> output_2 = splicer_.GetNextBuffer(); |
| 297 EXPECT_FALSE(splicer_.HasNextBuffer()); | 350 EXPECT_FALSE(splicer_.HasNextBuffer()); |
| 298 | 351 |
| 299 // Verify that the first input buffer passed through unmodified. | |
| 300 EXPECT_EQ(input_1->timestamp(), output_1->timestamp()); | |
| 301 EXPECT_EQ(input_1->duration(), output_1->duration()); | |
| 302 EXPECT_EQ(input_1->frame_count(), output_1->frame_count()); | |
| 303 EXPECT_TRUE(VerifyData(output_1, 0.1f)); | |
| 304 | |
| 305 // Verify that the second input buffer was truncated to only contain | 352 // Verify that the second input buffer was truncated to only contain |
| 306 // the samples that are after the end of |input_1|. Note that data is not | 353 // the samples that are after the end of |input_1|. |
| 307 // copied, so |input_2|'s values are modified. | |
| 308 base::TimeDelta expected_timestamp = | 354 base::TimeDelta expected_timestamp = |
| 309 input_1->timestamp() + input_1->duration(); | 355 input_1->timestamp() + input_1->duration(); |
| 310 base::TimeDelta expected_duration = | 356 base::TimeDelta expected_duration = |
| 311 (input_2->timestamp() + input_2->duration()) - expected_timestamp; | 357 (input_2->timestamp() + input_2->duration()) - expected_timestamp; |
| 312 EXPECT_EQ(expected_timestamp, output_2->timestamp()); | 358 EXPECT_EQ(expected_timestamp, output_2->timestamp()); |
| 313 EXPECT_EQ(expected_duration, output_2->duration()); | 359 EXPECT_EQ(expected_duration, output_2->duration()); |
| 314 EXPECT_TRUE(VerifyData(output_2, 0.2f)); | 360 EXPECT_TRUE(VerifyData(output_2, 0.2f)); |
| 315 } | 361 } |
| 316 | 362 |
| 317 | |
| 318 // Test that an input buffer that is completely overlapped by a buffer | 363 // Test that an input buffer that is completely overlapped by a buffer |
| 319 // that was already added is dropped. | 364 // that was already added is dropped. |
| 320 // +--------------+ | 365 // +--------------+ |
| 321 // |11111111111111| | 366 // |11111111111111| |
| 322 // +--------------+ | 367 // +--------------+ |
| 323 // +-----+ | 368 // +-----+ |
| 324 // |22222| | 369 // |22222| |
| 325 // +-----+ | 370 // +-----+ |
| 326 // +-------------+ | 371 // +-------------+ |
| 327 // |3333333333333| | 372 // |3333333333333| |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 341 input_timestamp_helper_.AddFrames(kOverlapOffset); | 386 input_timestamp_helper_.AddFrames(kOverlapOffset); |
| 342 | 387 |
| 343 scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f, kOverlapSize); | 388 scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f, kOverlapSize); |
| 344 | 389 |
| 345 // Reset the timestamp helper so the next buffer will be right after | 390 // Reset the timestamp helper so the next buffer will be right after |
| 346 // |input_1|. | 391 // |input_1|. |
| 347 input_timestamp_helper_.SetBaseTimestamp(input_1->timestamp()); | 392 input_timestamp_helper_.SetBaseTimestamp(input_1->timestamp()); |
| 348 input_timestamp_helper_.AddFrames(input_1->frame_count()); | 393 input_timestamp_helper_.AddFrames(input_1->frame_count()); |
| 349 scoped_refptr<AudioBuffer> input_3 = GetNextInputBuffer(0.3f); | 394 scoped_refptr<AudioBuffer> input_3 = GetNextInputBuffer(0.3f); |
| 350 | 395 |
| 351 EXPECT_TRUE(splicer_.AddInput(input_1)); | 396 EXPECT_TRUE(AddInput(input_1)); |
| 352 EXPECT_TRUE(splicer_.AddInput(input_2)); | 397 EXPECT_TRUE(AddInput(input_2)); |
| 353 EXPECT_TRUE(splicer_.AddInput(input_3)); | 398 EXPECT_TRUE(AddInput(input_3)); |
| 354 | 399 |
| 355 EXPECT_TRUE(splicer_.HasNextBuffer()); | 400 VerifyNextBuffer(input_1, 0.1f); |
| 356 scoped_refptr<AudioBuffer> output_1 = splicer_.GetNextBuffer(); | 401 VerifyNextBuffer(input_3, 0.3f); |
| 357 scoped_refptr<AudioBuffer> output_2 = splicer_.GetNextBuffer(); | 402 EXPECT_FALSE(splicer_.HasNextBuffer()); |
| 358 EXPECT_FALSE(splicer_.HasNextBuffer()); | 403 } |
| 359 | 404 |
| 360 // Verify that the first input buffer passed through unmodified. | 405 // Test crossfade when one buffer partially overlaps another. |
| 361 EXPECT_EQ(input_1->timestamp(), output_1->timestamp()); | 406 // +--------------+ |
| 362 EXPECT_EQ(input_1->duration(), output_1->duration()); | 407 // |11111111111111| |
| 363 EXPECT_EQ(input_1->frame_count(), output_1->frame_count()); | 408 // +--------------+ |
| 364 EXPECT_TRUE(VerifyData(output_1, 0.1f)); | 409 // +--------------+ |
| 365 | 410 // |22222222222222| |
| 366 // Verify that the second output buffer only contains | 411 // +--------------+ |
| 367 // the samples that are in |input_3|. | 412 // Results in: |
| 368 EXPECT_EQ(input_3->timestamp(), output_2->timestamp()); | 413 // +----------+----+----------+ |
| 369 EXPECT_EQ(input_3->duration(), output_2->duration()); | 414 // |1111111111|xxxx|2222222222| |
| 370 EXPECT_EQ(input_3->frame_count(), output_2->frame_count()); | 415 // +----------+----+----------+ |
| 371 EXPECT_TRUE(VerifyData(output_2, 0.3f)); | 416 // Where "xxxx" represents the crossfaded portion of the signal. |
| 417 TEST_F(AudioSplicerTest, PartialOverlapCrossfade) { | |
| 418 const int kCrossfadeSize = | |
| 419 input_timestamp_helper_.GetFramesToTarget(max_crossfade_duration()); | |
| 420 const int kBufferSize = kCrossfadeSize * 2; | |
| 421 | |
| 422 scoped_refptr<AudioBuffer> extra_pre_splice_buffer = | |
| 423 GetNextInputBuffer(0.2f, kBufferSize); | |
| 424 scoped_refptr<AudioBuffer> overlapped_buffer = | |
| 425 GetNextInputBuffer(1.0f, kBufferSize); | |
| 426 | |
| 427 // Reset timestamp helper so that the next buffer will have a timestamp that | |
| 428 // starts in the middle of |overlapped_buffer|. | |
| 429 input_timestamp_helper_.SetBaseTimestamp(overlapped_buffer->timestamp()); | |
| 430 input_timestamp_helper_.AddFrames(overlapped_buffer->frame_count() - | |
| 431 kCrossfadeSize); | |
| 432 const base::TimeDelta splice_timestamp = | |
| 433 input_timestamp_helper_.GetTimestamp(); | |
| 434 splicer_.SetSpliceTimestamp(splice_timestamp); | |
| 435 scoped_refptr<AudioBuffer> overlapping_buffer = | |
| 436 GetNextInputBuffer(0.0f, kBufferSize); | |
| 437 | |
| 438 // |extra_pre_splice_buffer| is entirely before the splice and should be ready | |
| 439 // for output. | |
| 440 EXPECT_TRUE(AddInput(extra_pre_splice_buffer)); | |
| 441 VerifyNextBuffer(extra_pre_splice_buffer, 0.2f); | |
| 442 | |
| 443 // The splicer should be internally queuing input since |overlapped_buffer| is | |
| 444 // part of the splice. | |
| 445 EXPECT_TRUE(AddInput(overlapped_buffer)); | |
| 446 EXPECT_FALSE(splicer_.HasNextBuffer()); | |
| 447 | |
| 448 // |overlapping_buffer| should complete the splice, so ensure output is now | |
| 449 // available. | |
| 450 EXPECT_TRUE(AddInput(overlapping_buffer)); | |
| 451 ASSERT_TRUE(splicer_.HasNextBuffer()); | |
| 452 | |
| 453 // Add one more buffer to make sure it's passed through untouched. | |
| 454 scoped_refptr<AudioBuffer> extra_post_splice_buffer = | |
| 455 GetNextInputBuffer(0.5f, kBufferSize); | |
| 456 EXPECT_TRUE(AddInput(extra_post_splice_buffer)); | |
| 457 | |
| 458 VerifyPreSpliceOutput(overlapped_buffer, overlapping_buffer, 1.0f); | |
| 459 | |
| 460 int64 expected_crossfade_size = 0; | |
| 461 base::TimeDelta expected_crossfade_duration; | |
| 462 VerifyCrossfadeOutput(overlapped_buffer, | |
| 463 overlapping_buffer, | |
| 464 1.0f, | |
| 465 0.0f, | |
| 466 &expected_crossfade_duration, | |
| 467 &expected_crossfade_size); | |
| 468 const int kExpectedPostSpliceSize = | |
| 469 overlapping_buffer->frame_count() - expected_crossfade_size; | |
| 470 | |
| 471 // Retrieve the remaining portion after crossfade. | |
| 472 ASSERT_TRUE(splicer_.HasNextBuffer()); | |
| 473 scoped_refptr<AudioBuffer> post_splice_output = splicer_.GetNextBuffer(); | |
| 474 EXPECT_EQ(output_timestamp_helper_.GetTimestamp(), | |
| 475 post_splice_output->timestamp()); | |
| 476 EXPECT_EQ(kExpectedPostSpliceSize, post_splice_output->frame_count()); | |
| 477 EXPECT_EQ(output_timestamp_helper_.GetFrameDuration(kExpectedPostSpliceSize), | |
| 478 post_splice_output->duration()); | |
| 479 | |
| 480 EXPECT_TRUE(VerifyData(post_splice_output, 0.0f)); | |
| 481 | |
| 482 VerifyNextBuffer(extra_post_splice_buffer, 0.5f); | |
| 483 EXPECT_FALSE(splicer_.HasNextBuffer()); | |
| 484 } | |
| 485 | |
| 486 // Test crossfade when one buffer partially overlaps another, but an end of | |
| 487 // stream buffer is received before the crossfade duration is reached. | |
| 488 // +--------------+ | |
| 489 // |11111111111111| | |
| 490 // +--------------+ | |
| 491 // +---------++---+ | |
| 492 // |222222222||EOS| | |
| 493 // +---------++---+ | |
| 494 // Results in: | |
| 495 // +----------+----+----++---+ | |
| 496 // |1111111111|xxxx|2222||EOS| | |
| 497 // +----------+----+----++---+ | |
| 498 // Where "x" represents the crossfaded portion of the signal. | |
| 499 TEST_F(AudioSplicerTest, PartialOverlapCrossfadeEndOfStream) { | |
| 500 const int kCrossfadeSize = | |
| 501 input_timestamp_helper_.GetFramesToTarget(max_crossfade_duration()); | |
| 502 | |
| 503 scoped_refptr<AudioBuffer> overlapped_buffer = | |
| 504 GetNextInputBuffer(1.0f, kCrossfadeSize * 2); | |
| 505 | |
| 506 // Reset timestamp helper so that the next buffer will have a timestamp that | |
| 507 // starts 3/4 of the way into |overlapped_buffer|. | |
| 508 input_timestamp_helper_.SetBaseTimestamp(overlapped_buffer->timestamp()); | |
| 509 input_timestamp_helper_.AddFrames(3 * overlapped_buffer->frame_count() / 4); | |
| 510 const base::TimeDelta splice_timestamp = | |
| 511 input_timestamp_helper_.GetTimestamp(); | |
| 512 splicer_.SetSpliceTimestamp(splice_timestamp); | |
| 513 scoped_refptr<AudioBuffer> overlapping_buffer = | |
| 514 GetNextInputBuffer(0.0f, kCrossfadeSize / 3); | |
| 515 | |
| 516 // The splicer should be internally queuing input since |overlapped_buffer| is | |
| 517 // part of the splice. | |
| 518 EXPECT_TRUE(AddInput(overlapped_buffer)); | |
| 519 EXPECT_FALSE(splicer_.HasNextBuffer()); | |
| 520 | |
| 521 // |overlapping_buffer| should not have enough data to complete the splice, so | |
| 522 // ensure output is not available. | |
| 523 EXPECT_TRUE(AddInput(overlapping_buffer)); | |
| 524 EXPECT_FALSE(splicer_.HasNextBuffer()); | |
| 525 | |
| 526 // Now add an EOS buffer which should complete the splice. | |
| 527 EXPECT_TRUE(AddInput(AudioBuffer::CreateEOSBuffer())); | |
| 528 ASSERT_TRUE(splicer_.HasNextBuffer()); | |
| 529 | |
| 530 VerifyPreSpliceOutput(overlapped_buffer, overlapping_buffer, 1.0f); | |
| 531 int64 expected_crossfade_size = 0; | |
| 532 base::TimeDelta expected_crossfade_duration; | |
| 533 VerifyCrossfadeOutput(overlapped_buffer, | |
| 534 overlapping_buffer, | |
| 535 1.0f, | |
| 536 0.0f, | |
| 537 &expected_crossfade_duration, | |
| 538 &expected_crossfade_size); | |
| 539 | |
| 540 // Ensure the last buffer is an EOS buffer. | |
| 541 ASSERT_TRUE(splicer_.HasNextBuffer()); | |
| 542 scoped_refptr<AudioBuffer> post_splice_output = splicer_.GetNextBuffer(); | |
| 543 EXPECT_TRUE(post_splice_output->end_of_stream()); | |
| 544 | |
| 545 EXPECT_FALSE(splicer_.HasNextBuffer()); | |
| 546 } | |
| 547 | |
| 548 // Test crossfade when one buffer partially overlaps another, but the amount of | |
| 549 // overlapped data is less than the crossfade duration. | |
| 550 // +------------+ | |
| 551 // |111111111111| | |
| 552 // +------------+ | |
| 553 // +--------------+ | |
| 554 // |22222222222222| | |
| 555 // +--------------+ | |
| 556 // Results in: | |
| 557 // +----------+-+------------+ | |
| 558 // |1111111111|x|222222222222| | |
| 559 // +----------+-+------------+ | |
| 560 // Where "x" represents the crossfaded portion of the signal. | |
| 561 TEST_F(AudioSplicerTest, PartialOverlapCrossfadeShortPreSplice) { | |
| 562 const int kCrossfadeSize = | |
| 563 input_timestamp_helper_.GetFramesToTarget(max_crossfade_duration()); | |
| 564 | |
| 565 scoped_refptr<AudioBuffer> overlapped_buffer = | |
| 566 GetNextInputBuffer(1.0f, kCrossfadeSize / 2); | |
| 567 | |
| 568 // Reset timestamp helper so that the next buffer will have a timestamp that | |
| 569 // starts in the middle of |overlapped_buffer|. | |
| 570 input_timestamp_helper_.SetBaseTimestamp(overlapped_buffer->timestamp()); | |
| 571 input_timestamp_helper_.AddFrames(overlapped_buffer->frame_count() / 2); | |
| 572 const base::TimeDelta splice_timestamp = | |
| 573 input_timestamp_helper_.GetTimestamp(); | |
| 574 splicer_.SetSpliceTimestamp(splice_timestamp); | |
| 575 scoped_refptr<AudioBuffer> overlapping_buffer = | |
| 576 GetNextInputBuffer(0.0f, kCrossfadeSize * 2); | |
| 577 | |
| 578 // The splicer should be internally queuing input since |overlapped_buffer| is | |
| 579 // part of the splice. | |
| 580 EXPECT_TRUE(AddInput(overlapped_buffer)); | |
| 581 EXPECT_FALSE(splicer_.HasNextBuffer()); | |
| 582 | |
| 583 // |overlapping_buffer| should complete the splice, so ensure output is now | |
| 584 // available. | |
| 585 EXPECT_TRUE(AddInput(overlapping_buffer)); | |
| 586 ASSERT_TRUE(splicer_.HasNextBuffer()); | |
| 587 | |
| 588 VerifyPreSpliceOutput(overlapped_buffer, overlapping_buffer, 1.0f); | |
| 589 | |
| 590 int64 expected_crossfade_size = 0; | |
| 591 base::TimeDelta expected_crossfade_duration; | |
| 592 VerifyCrossfadeOutput(overlapped_buffer, | |
| 593 overlapping_buffer, | |
| 594 1.0f, | |
| 595 0.0f, | |
| 596 &expected_crossfade_duration, | |
| 597 &expected_crossfade_size); | |
| 598 | |
| 599 // Retrieve the remaining portion after crossfade. | |
| 600 ASSERT_TRUE(splicer_.HasNextBuffer()); | |
| 601 scoped_refptr<AudioBuffer> post_splice_output = splicer_.GetNextBuffer(); | |
| 602 EXPECT_EQ(output_timestamp_helper_.GetTimestamp(), | |
| 603 post_splice_output->timestamp()); | |
| 604 EXPECT_EQ(overlapping_buffer->duration() - expected_crossfade_duration, | |
| 605 post_splice_output->duration()); | |
| 606 EXPECT_EQ(overlapping_buffer->frame_count() - expected_crossfade_size, | |
| 607 post_splice_output->frame_count()); | |
| 608 EXPECT_TRUE(VerifyData(post_splice_output, 0.0f)); | |
| 609 | |
| 610 EXPECT_FALSE(splicer_.HasNextBuffer()); | |
| 372 } | 611 } |
| 373 | 612 |
| 374 } // namespace media | 613 } // namespace media |
| OLD | NEW |