Index: media/base/audio_splicer_unittest.cc |
diff --git a/media/base/audio_splicer_unittest.cc b/media/base/audio_splicer_unittest.cc |
deleted file mode 100644 |
index de674d70ce8fb95661a1890c86b42670473dba17..0000000000000000000000000000000000000000 |
--- a/media/base/audio_splicer_unittest.cc |
+++ /dev/null |
@@ -1,770 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "media/base/audio_splicer.h" |
- |
-#include <memory> |
- |
-#include "base/macros.h" |
-#include "media/base/audio_buffer.h" |
-#include "media/base/audio_bus.h" |
-#include "media/base/audio_timestamp_helper.h" |
-#include "media/base/test_helpers.h" |
-#include "media/base/timestamp_constants.h" |
-#include "testing/gtest/include/gtest/gtest.h" |
- |
-namespace media { |
- |
-// Do not change this format. AddInput() and GetValue() only work with float. |
-static const SampleFormat kSampleFormat = kSampleFormatF32; |
-static_assert(kSampleFormat == kSampleFormatF32, "invalid splice format"); |
- |
-static const int kChannels = 1; |
-static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_MONO; |
-static const int kDefaultSampleRate = 44100; |
-static const int kDefaultBufferSize = 100; |
- |
-class AudioSplicerTest : public ::testing::Test { |
- public: |
- AudioSplicerTest() |
- : splicer_(kDefaultSampleRate, new MediaLog()), |
- input_timestamp_helper_(kDefaultSampleRate) { |
- input_timestamp_helper_.SetBaseTimestamp(base::TimeDelta()); |
- } |
- |
- scoped_refptr<AudioBuffer> GetNextInputBuffer(float value) { |
- return GetNextInputBuffer(value, kDefaultBufferSize); |
- } |
- |
- scoped_refptr<AudioBuffer> GetNextInputBuffer(float value, int frame_size) { |
- scoped_refptr<AudioBuffer> buffer = |
- MakeAudioBuffer<float>(kSampleFormat, |
- kChannelLayout, |
- kChannels, |
- kDefaultSampleRate, |
- value, |
- 0.0f, |
- frame_size, |
- input_timestamp_helper_.GetTimestamp()); |
- input_timestamp_helper_.AddFrames(frame_size); |
- return buffer; |
- } |
- |
- float GetValue(const scoped_refptr<AudioBuffer>& buffer) { |
- return reinterpret_cast<const float*>(buffer->channel_data()[0])[0]; |
- } |
- |
- bool VerifyData(const scoped_refptr<AudioBuffer>& buffer, float value) { |
- int frames = buffer->frame_count(); |
- std::unique_ptr<AudioBus> bus = AudioBus::Create(kChannels, frames); |
- buffer->ReadFrames(frames, 0, 0, bus.get()); |
- for (int ch = 0; ch < buffer->channel_count(); ++ch) { |
- for (int i = 0; i < frames; ++i) { |
- if (bus->channel(ch)[i] != value) |
- return false; |
- } |
- } |
- return true; |
- } |
- |
- void VerifyNextBuffer(const scoped_refptr<AudioBuffer>& input) { |
- ASSERT_TRUE(splicer_.HasNextBuffer()); |
- scoped_refptr<AudioBuffer> output = splicer_.GetNextBuffer(); |
- EXPECT_EQ(input->timestamp(), output->timestamp()); |
- EXPECT_EQ(input->duration(), output->duration()); |
- EXPECT_EQ(input->frame_count(), output->frame_count()); |
- EXPECT_TRUE(VerifyData(output, GetValue(input))); |
- } |
- |
- void VerifyPreSpliceOutput( |
- const scoped_refptr<AudioBuffer>& overlapped_buffer, |
- const scoped_refptr<AudioBuffer>& overlapping_buffer, |
- int expected_pre_splice_size, |
- base::TimeDelta expected_pre_splice_duration) { |
- ASSERT_TRUE(splicer_.HasNextBuffer()); |
- scoped_refptr<AudioBuffer> pre_splice_output = splicer_.GetNextBuffer(); |
- EXPECT_EQ(overlapped_buffer->timestamp(), pre_splice_output->timestamp()); |
- EXPECT_EQ(expected_pre_splice_size, pre_splice_output->frame_count()); |
- EXPECT_EQ(expected_pre_splice_duration, pre_splice_output->duration()); |
- EXPECT_TRUE(VerifyData(pre_splice_output, GetValue(overlapped_buffer))); |
- } |
- |
- void VerifyCrossfadeOutput( |
- const scoped_refptr<AudioBuffer>& overlapped_buffer_1, |
- const scoped_refptr<AudioBuffer>& overlapped_buffer_2, |
- const scoped_refptr<AudioBuffer>& overlapping_buffer, |
- int second_overlap_index, |
- int expected_crossfade_size, |
- base::TimeDelta expected_crossfade_duration) { |
- ASSERT_TRUE(splicer_.HasNextBuffer()); |
- |
- scoped_refptr<AudioBuffer> crossfade_output = splicer_.GetNextBuffer(); |
- EXPECT_EQ(expected_crossfade_size, crossfade_output->frame_count()); |
- EXPECT_EQ(expected_crossfade_duration, crossfade_output->duration()); |
- |
- // The splice timestamp may be adjusted by a microsecond. |
- EXPECT_NEAR(overlapping_buffer->timestamp().InMicroseconds(), |
- crossfade_output->timestamp().InMicroseconds(), |
- 1); |
- |
- // Verify the actual crossfade. |
- const int frames = crossfade_output->frame_count(); |
- float overlapped_value = GetValue(overlapped_buffer_1); |
- const float overlapping_value = GetValue(overlapping_buffer); |
- std::unique_ptr<AudioBus> bus = AudioBus::Create(kChannels, frames); |
- crossfade_output->ReadFrames(frames, 0, 0, bus.get()); |
- for (int ch = 0; ch < crossfade_output->channel_count(); ++ch) { |
- float cf_ratio = 0; |
- const float cf_increment = 1.0f / frames; |
- for (int i = 0; i < frames; ++i, cf_ratio += cf_increment) { |
- if (overlapped_buffer_2.get() && i >= second_overlap_index) |
- overlapped_value = GetValue(overlapped_buffer_2); |
- const float actual = bus->channel(ch)[i]; |
- const float expected = |
- (1.0f - cf_ratio) * overlapped_value + cf_ratio * overlapping_value; |
- ASSERT_FLOAT_EQ(expected, actual) << "i=" << i; |
- } |
- } |
- } |
- |
- bool AddInput(const scoped_refptr<AudioBuffer>& input) { |
- // Since the splicer doesn't make copies it's working directly on the input |
- // buffers. We must make a copy before adding to ensure the original buffer |
- // is not modified in unexpected ways. |
- scoped_refptr<AudioBuffer> buffer_copy = |
- input->end_of_stream() |
- ? AudioBuffer::CreateEOSBuffer() |
- : AudioBuffer::CopyFrom(kSampleFormat, |
- input->channel_layout(), |
- input->channel_count(), |
- input->sample_rate(), |
- input->frame_count(), |
- &input->channel_data()[0], |
- input->timestamp()); |
- return splicer_.AddInput(buffer_copy); |
- } |
- |
- base::TimeDelta max_crossfade_duration() { |
- return splicer_.max_crossfade_duration_; |
- } |
- |
- protected: |
- AudioSplicer splicer_; |
- AudioTimestampHelper input_timestamp_helper_; |
- |
- DISALLOW_COPY_AND_ASSIGN(AudioSplicerTest); |
-}; |
- |
-TEST_F(AudioSplicerTest, PassThru) { |
- EXPECT_FALSE(splicer_.HasNextBuffer()); |
- |
- // Test single buffer pass-thru behavior. |
- scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); |
- EXPECT_TRUE(AddInput(input_1)); |
- VerifyNextBuffer(input_1); |
- EXPECT_FALSE(splicer_.HasNextBuffer()); |
- |
- // Test that multiple buffers can be queued in the splicer. |
- scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f); |
- scoped_refptr<AudioBuffer> input_3 = GetNextInputBuffer(0.3f); |
- EXPECT_TRUE(AddInput(input_2)); |
- EXPECT_TRUE(AddInput(input_3)); |
- VerifyNextBuffer(input_2); |
- VerifyNextBuffer(input_3); |
- EXPECT_FALSE(splicer_.HasNextBuffer()); |
-} |
- |
-TEST_F(AudioSplicerTest, Reset) { |
- scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); |
- EXPECT_TRUE(AddInput(input_1)); |
- ASSERT_TRUE(splicer_.HasNextBuffer()); |
- |
- splicer_.Reset(); |
- EXPECT_FALSE(splicer_.HasNextBuffer()); |
- |
- // Add some bytes to the timestamp helper so that the |
- // next buffer starts many frames beyond the end of |
- // |input_1|. This is to make sure that Reset() actually |
- // clears its state and doesn't try to insert a gap. |
- input_timestamp_helper_.AddFrames(100); |
- |
- // Verify that a new input buffer passes through as expected. |
- scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f); |
- EXPECT_TRUE(AddInput(input_2)); |
- VerifyNextBuffer(input_2); |
- EXPECT_FALSE(splicer_.HasNextBuffer()); |
-} |
- |
-TEST_F(AudioSplicerTest, EndOfStream) { |
- scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); |
- scoped_refptr<AudioBuffer> input_2 = AudioBuffer::CreateEOSBuffer(); |
- scoped_refptr<AudioBuffer> input_3 = GetNextInputBuffer(0.2f); |
- EXPECT_TRUE(input_2->end_of_stream()); |
- |
- EXPECT_TRUE(AddInput(input_1)); |
- EXPECT_TRUE(AddInput(input_2)); |
- |
- VerifyNextBuffer(input_1); |
- |
- scoped_refptr<AudioBuffer> output_2 = splicer_.GetNextBuffer(); |
- EXPECT_FALSE(splicer_.HasNextBuffer()); |
- EXPECT_TRUE(output_2->end_of_stream()); |
- |
- // Verify that buffers can be added again after Reset(). |
- splicer_.Reset(); |
- EXPECT_TRUE(AddInput(input_3)); |
- VerifyNextBuffer(input_3); |
- EXPECT_FALSE(splicer_.HasNextBuffer()); |
-} |
- |
-// Test the gap insertion code. |
-// +--------------+ +--------------+ |
-// |11111111111111| |22222222222222| |
-// +--------------+ +--------------+ |
-// Results in: |
-// +--------------+----+--------------+ |
-// |11111111111111|0000|22222222222222| |
-// +--------------+----+--------------+ |
-TEST_F(AudioSplicerTest, GapInsertion) { |
- scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); |
- |
- // Add bytes to the timestamp helper so that the next buffer |
- // will have a starting timestamp that indicates a gap is |
- // present. |
- const int kGapSize = 7; |
- input_timestamp_helper_.AddFrames(kGapSize); |
- scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f); |
- |
- EXPECT_TRUE(AddInput(input_1)); |
- EXPECT_TRUE(AddInput(input_2)); |
- |
- // Verify that the first input buffer passed through unmodified. |
- VerifyNextBuffer(input_1); |
- |
- // Verify the contents of the gap buffer. |
- scoped_refptr<AudioBuffer> output_2 = splicer_.GetNextBuffer(); |
- base::TimeDelta gap_timestamp = |
- input_1->timestamp() + input_1->duration(); |
- base::TimeDelta gap_duration = input_2->timestamp() - gap_timestamp; |
- EXPECT_GT(gap_duration, base::TimeDelta()); |
- EXPECT_EQ(gap_timestamp, output_2->timestamp()); |
- EXPECT_NEAR( |
- gap_duration.InMicroseconds(), output_2->duration().InMicroseconds(), 1); |
- EXPECT_EQ(kGapSize, output_2->frame_count()); |
- EXPECT_TRUE(VerifyData(output_2, 0.0f)); |
- |
- // Verify that the second input buffer passed through unmodified. |
- VerifyNextBuffer(input_2); |
- EXPECT_FALSE(splicer_.HasNextBuffer()); |
-} |
- |
-// Test that an error is signalled when the gap between input buffers is |
-// too large. |
-TEST_F(AudioSplicerTest, GapTooLarge) { |
- scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); |
- |
- // Add a seconds worth of bytes so that an unacceptably large |
- // gap exists between |input_1| and |input_2|. |
- const int kGapSize = kDefaultSampleRate; |
- input_timestamp_helper_.AddFrames(kGapSize); |
- scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f); |
- |
- EXPECT_TRUE(AddInput(input_1)); |
- EXPECT_FALSE(AddInput(input_2)); |
- |
- VerifyNextBuffer(input_1); |
- |
- // Verify that the second buffer is not available. |
- EXPECT_FALSE(splicer_.HasNextBuffer()); |
- |
- // Reset the timestamp helper so it can generate a buffer that is |
- // right after |input_1|. |
- input_timestamp_helper_.SetBaseTimestamp( |
- input_1->timestamp() + input_1->duration()); |
- |
- // Verify that valid buffers are still accepted. |
- scoped_refptr<AudioBuffer> input_3 = GetNextInputBuffer(0.3f); |
- EXPECT_TRUE(AddInput(input_3)); |
- VerifyNextBuffer(input_3); |
- EXPECT_FALSE(splicer_.HasNextBuffer()); |
-} |
- |
-// Verifies that an error is signalled if AddInput() is called |
-// with a timestamp that is earlier than the first buffer added. |
-TEST_F(AudioSplicerTest, BufferAddedBeforeBase) { |
- input_timestamp_helper_.SetBaseTimestamp( |
- base::TimeDelta::FromMicroseconds(10)); |
- scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); |
- |
- // Reset the timestamp helper so the next buffer will have a timestamp earlier |
- // than |input_1|. |
- input_timestamp_helper_.SetBaseTimestamp(base::TimeDelta::FromSeconds(0)); |
- scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.1f); |
- |
- EXPECT_GT(input_1->timestamp(), input_2->timestamp()); |
- EXPECT_TRUE(AddInput(input_1)); |
- EXPECT_FALSE(AddInput(input_2)); |
-} |
- |
-// Test when one buffer partially overlaps another. |
-// +--------------+ |
-// |11111111111111| |
-// +--------------+ |
-// +--------------+ |
-// |22222222222222| |
-// +--------------+ |
-// Results in: |
-// +--------------+----------+ |
-// |11111111111111|2222222222| |
-// +--------------+----------+ |
-TEST_F(AudioSplicerTest, PartialOverlap) { |
- scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); |
- |
- // Reset timestamp helper so that the next buffer will have a |
- // timestamp that starts in the middle of |input_1|. |
- const int kOverlapSize = input_1->frame_count() / 4; |
- input_timestamp_helper_.SetBaseTimestamp(input_1->timestamp()); |
- input_timestamp_helper_.AddFrames(input_1->frame_count() - kOverlapSize); |
- |
- scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f); |
- |
- EXPECT_TRUE(AddInput(input_1)); |
- EXPECT_TRUE(AddInput(input_2)); |
- |
- // Verify that the first input buffer passed through unmodified. |
- VerifyNextBuffer(input_1); |
- |
- ASSERT_TRUE(splicer_.HasNextBuffer()); |
- scoped_refptr<AudioBuffer> output_2 = splicer_.GetNextBuffer(); |
- EXPECT_FALSE(splicer_.HasNextBuffer()); |
- |
- // Verify that the second input buffer was truncated to only contain |
- // the samples that are after the end of |input_1|. |
- base::TimeDelta expected_timestamp = |
- input_1->timestamp() + input_1->duration(); |
- base::TimeDelta expected_duration = |
- (input_2->timestamp() + input_2->duration()) - expected_timestamp; |
- EXPECT_EQ(expected_timestamp, output_2->timestamp()); |
- EXPECT_EQ(expected_duration, output_2->duration()); |
- EXPECT_TRUE(VerifyData(output_2, GetValue(input_2))); |
-} |
- |
-// Test that an input buffer that is completely overlapped by a buffer |
-// that was already added is dropped. |
-// +--------------+ |
-// |11111111111111| |
-// +--------------+ |
-// +-----+ |
-// |22222| |
-// +-----+ |
-// +-------------+ |
-// |3333333333333| |
-// +-------------+ |
-// Results in: |
-// +--------------+-------------+ |
-// |11111111111111|3333333333333| |
-// +--------------+-------------+ |
-TEST_F(AudioSplicerTest, DropBuffer) { |
- scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f); |
- |
- // Reset timestamp helper so that the next buffer will have a |
- // timestamp that starts in the middle of |input_1|. |
- const int kOverlapOffset = input_1->frame_count() / 2; |
- const int kOverlapSize = input_1->frame_count() / 4; |
- input_timestamp_helper_.SetBaseTimestamp(input_1->timestamp()); |
- input_timestamp_helper_.AddFrames(kOverlapOffset); |
- |
- scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f, kOverlapSize); |
- |
- // Reset the timestamp helper so the next buffer will be right after |
- // |input_1|. |
- input_timestamp_helper_.SetBaseTimestamp(input_1->timestamp()); |
- input_timestamp_helper_.AddFrames(input_1->frame_count()); |
- scoped_refptr<AudioBuffer> input_3 = GetNextInputBuffer(0.3f); |
- |
- EXPECT_TRUE(AddInput(input_1)); |
- EXPECT_TRUE(AddInput(input_2)); |
- EXPECT_TRUE(AddInput(input_3)); |
- |
- VerifyNextBuffer(input_1); |
- VerifyNextBuffer(input_3); |
- EXPECT_FALSE(splicer_.HasNextBuffer()); |
-} |
- |
-// Test crossfade when one buffer partially overlaps another. |
-// +--------------+ |
-// |11111111111111| |
-// +--------------+ |
-// +--------------+ |
-// |22222222222222| |
-// +--------------+ |
-// Results in: |
-// +----------+----+----------+ |
-// |1111111111|xxxx|2222222222| |
-// +----------+----+----------+ |
-// Where "xxxx" represents the crossfaded portion of the signal. |
-TEST_F(AudioSplicerTest, PartialOverlapCrossfade) { |
- const int kCrossfadeSize = |
- input_timestamp_helper_.GetFramesToTarget(max_crossfade_duration()); |
- const int kBufferSize = kCrossfadeSize * 2; |
- |
- scoped_refptr<AudioBuffer> extra_pre_splice_buffer = |
- GetNextInputBuffer(0.2f, kBufferSize); |
- scoped_refptr<AudioBuffer> overlapped_buffer = |
- GetNextInputBuffer(1.0f, kBufferSize); |
- |
- // Reset timestamp helper so that the next buffer will have a timestamp that |
- // starts in the middle of |overlapped_buffer|. |
- input_timestamp_helper_.SetBaseTimestamp(overlapped_buffer->timestamp()); |
- input_timestamp_helper_.AddFrames(overlapped_buffer->frame_count() - |
- kCrossfadeSize); |
- splicer_.SetSpliceTimestamp(input_timestamp_helper_.GetTimestamp()); |
- scoped_refptr<AudioBuffer> overlapping_buffer = |
- GetNextInputBuffer(0.0f, kBufferSize); |
- |
- // |extra_pre_splice_buffer| is entirely before the splice and should be ready |
- // for output. |
- EXPECT_TRUE(AddInput(extra_pre_splice_buffer)); |
- VerifyNextBuffer(extra_pre_splice_buffer); |
- |
- // The splicer should be internally queuing input since |overlapped_buffer| is |
- // part of the splice. |
- EXPECT_TRUE(AddInput(overlapped_buffer)); |
- EXPECT_FALSE(splicer_.HasNextBuffer()); |
- |
- // |overlapping_buffer| completes the splice. |
- splicer_.SetSpliceTimestamp(kNoTimestamp); |
- EXPECT_TRUE(AddInput(overlapping_buffer)); |
- ASSERT_TRUE(splicer_.HasNextBuffer()); |
- |
- // Add one more buffer to make sure it's passed through untouched. |
- scoped_refptr<AudioBuffer> extra_post_splice_buffer = |
- GetNextInputBuffer(0.5f, kBufferSize); |
- EXPECT_TRUE(AddInput(extra_post_splice_buffer)); |
- |
- VerifyPreSpliceOutput(overlapped_buffer, |
- overlapping_buffer, |
- 221, |
- base::TimeDelta::FromMicroseconds(5011)); |
- |
- // Due to rounding the crossfade size may vary by up to a frame. |
- const int kExpectedCrossfadeSize = 220; |
- EXPECT_NEAR(kExpectedCrossfadeSize, kCrossfadeSize, 1); |
- |
- VerifyCrossfadeOutput(overlapped_buffer, |
- NULL, |
- overlapping_buffer, |
- 0, |
- kExpectedCrossfadeSize, |
- base::TimeDelta::FromMicroseconds(4988)); |
- |
- // Retrieve the remaining portion after crossfade. |
- ASSERT_TRUE(splicer_.HasNextBuffer()); |
- scoped_refptr<AudioBuffer> post_splice_output = splicer_.GetNextBuffer(); |
- EXPECT_EQ(base::TimeDelta::FromMicroseconds(20022), |
- post_splice_output->timestamp()); |
- EXPECT_EQ(overlapping_buffer->frame_count() - kExpectedCrossfadeSize, |
- post_splice_output->frame_count()); |
- EXPECT_EQ(base::TimeDelta::FromMicroseconds(5034), |
- post_splice_output->duration()); |
- |
- EXPECT_TRUE(VerifyData(post_splice_output, GetValue(overlapping_buffer))); |
- |
- VerifyNextBuffer(extra_post_splice_buffer); |
- EXPECT_FALSE(splicer_.HasNextBuffer()); |
-} |
- |
-// Test crossfade when one buffer partially overlaps another, but an end of |
-// stream buffer is received before the crossfade duration is reached. |
-// +--------------+ |
-// |11111111111111| |
-// +--------------+ |
-// +---------++---+ |
-// |222222222||EOS| |
-// +---------++---+ |
-// Results in: |
-// +----------+----+----++---+ |
-// |1111111111|xxxx|2222||EOS| |
-// +----------+----+----++---+ |
-// Where "x" represents the crossfaded portion of the signal. |
-TEST_F(AudioSplicerTest, PartialOverlapCrossfadeEndOfStream) { |
- const int kCrossfadeSize = |
- input_timestamp_helper_.GetFramesToTarget(max_crossfade_duration()); |
- |
- scoped_refptr<AudioBuffer> overlapped_buffer = |
- GetNextInputBuffer(1.0f, kCrossfadeSize * 2); |
- |
- // Reset timestamp helper so that the next buffer will have a timestamp that |
- // starts 3/4 of the way into |overlapped_buffer|. |
- input_timestamp_helper_.SetBaseTimestamp(overlapped_buffer->timestamp()); |
- input_timestamp_helper_.AddFrames(3 * overlapped_buffer->frame_count() / 4); |
- splicer_.SetSpliceTimestamp(input_timestamp_helper_.GetTimestamp()); |
- scoped_refptr<AudioBuffer> overlapping_buffer = |
- GetNextInputBuffer(0.0f, kCrossfadeSize / 3); |
- |
- // The splicer should be internally queuing input since |overlapped_buffer| is |
- // part of the splice. |
- EXPECT_TRUE(AddInput(overlapped_buffer)); |
- EXPECT_FALSE(splicer_.HasNextBuffer()); |
- |
- // |overlapping_buffer| should not have enough data to complete the splice, so |
- // ensure output is not available. |
- splicer_.SetSpliceTimestamp(kNoTimestamp); |
- EXPECT_TRUE(AddInput(overlapping_buffer)); |
- EXPECT_FALSE(splicer_.HasNextBuffer()); |
- |
- // Now add an EOS buffer which should complete the splice. |
- EXPECT_TRUE(AddInput(AudioBuffer::CreateEOSBuffer())); |
- |
- VerifyPreSpliceOutput(overlapped_buffer, |
- overlapping_buffer, |
- 331, |
- base::TimeDelta::FromMicroseconds(7505)); |
- VerifyCrossfadeOutput(overlapped_buffer, |
- NULL, |
- overlapping_buffer, |
- 0, |
- overlapping_buffer->frame_count(), |
- overlapping_buffer->duration()); |
- |
- // Ensure the last buffer is an EOS buffer. |
- ASSERT_TRUE(splicer_.HasNextBuffer()); |
- scoped_refptr<AudioBuffer> post_splice_output = splicer_.GetNextBuffer(); |
- EXPECT_TRUE(post_splice_output->end_of_stream()); |
- |
- EXPECT_FALSE(splicer_.HasNextBuffer()); |
-} |
- |
-// Test crossfade when one buffer partially overlaps another, but the amount of |
-// overlapped data is less than the crossfade duration. |
-// +------------+ |
-// |111111111111| |
-// +------------+ |
-// +--------------+ |
-// |22222222222222| |
-// +--------------+ |
-// Results in: |
-// +----------+-+------------+ |
-// |1111111111|x|222222222222| |
-// +----------+-+------------+ |
-// Where "x" represents the crossfaded portion of the signal. |
-TEST_F(AudioSplicerTest, PartialOverlapCrossfadeShortPreSplice) { |
- const int kCrossfadeSize = |
- input_timestamp_helper_.GetFramesToTarget(max_crossfade_duration()); |
- |
- scoped_refptr<AudioBuffer> overlapped_buffer = |
- GetNextInputBuffer(1.0f, kCrossfadeSize / 2); |
- |
- // Reset timestamp helper so that the next buffer will have a timestamp that |
- // starts in the middle of |overlapped_buffer|. |
- input_timestamp_helper_.SetBaseTimestamp(overlapped_buffer->timestamp()); |
- input_timestamp_helper_.AddFrames(overlapped_buffer->frame_count() / 2); |
- splicer_.SetSpliceTimestamp(input_timestamp_helper_.GetTimestamp()); |
- scoped_refptr<AudioBuffer> overlapping_buffer = |
- GetNextInputBuffer(0.0f, kCrossfadeSize * 2); |
- |
- // The splicer should be internally queuing input since |overlapped_buffer| is |
- // part of the splice. |
- EXPECT_TRUE(AddInput(overlapped_buffer)); |
- EXPECT_FALSE(splicer_.HasNextBuffer()); |
- |
- // |overlapping_buffer| completes the splice. |
- splicer_.SetSpliceTimestamp(kNoTimestamp); |
- EXPECT_TRUE(AddInput(overlapping_buffer)); |
- |
- const int kExpectedPreSpliceSize = 55; |
- const base::TimeDelta kExpectedPreSpliceDuration = |
- base::TimeDelta::FromMicroseconds(1247); |
- VerifyPreSpliceOutput(overlapped_buffer, |
- overlapping_buffer, |
- kExpectedPreSpliceSize, |
- kExpectedPreSpliceDuration); |
- VerifyCrossfadeOutput(overlapped_buffer, |
- NULL, |
- overlapping_buffer, |
- 0, |
- kExpectedPreSpliceSize, |
- kExpectedPreSpliceDuration); |
- |
- // Retrieve the remaining portion after crossfade. |
- ASSERT_TRUE(splicer_.HasNextBuffer()); |
- scoped_refptr<AudioBuffer> post_splice_output = splicer_.GetNextBuffer(); |
- EXPECT_EQ(overlapping_buffer->timestamp() + kExpectedPreSpliceDuration, |
- post_splice_output->timestamp()); |
- EXPECT_EQ(overlapping_buffer->frame_count() - kExpectedPreSpliceSize, |
- post_splice_output->frame_count()); |
- EXPECT_EQ(overlapping_buffer->duration() - kExpectedPreSpliceDuration, |
- post_splice_output->duration()); |
- |
- EXPECT_TRUE(VerifyData(post_splice_output, GetValue(overlapping_buffer))); |
- EXPECT_FALSE(splicer_.HasNextBuffer()); |
-} |
- |
-// Test behavior when a splice frame is incorrectly marked and does not actually |
-// overlap. |
-// +----------+ |
-// |1111111111| |
-// +----------+ |
-// +--------------+ |
-// |22222222222222| |
-// +--------------+ |
-// Results in: |
-// +----------+--------------+ |
-// |1111111111|22222222222222| |
-// +----------+--------------+ |
-TEST_F(AudioSplicerTest, IncorrectlyMarkedSplice) { |
- const int kBufferSize = |
- input_timestamp_helper_.GetFramesToTarget(max_crossfade_duration()) * 2; |
- |
- scoped_refptr<AudioBuffer> first_buffer = |
- GetNextInputBuffer(1.0f, kBufferSize); |
- // Fuzz the duration slightly so that the buffer overlaps the splice timestamp |
- // by a microsecond, which is not enough to crossfade. |
- const base::TimeDelta kSpliceTimestamp = |
- input_timestamp_helper_.GetTimestamp() - |
- base::TimeDelta::FromMicroseconds(1); |
- splicer_.SetSpliceTimestamp(kSpliceTimestamp); |
- scoped_refptr<AudioBuffer> second_buffer = |
- GetNextInputBuffer(0.0f, kBufferSize); |
- second_buffer->set_timestamp(kSpliceTimestamp); |
- |
- // The splicer should be internally queuing input since |first_buffer| is part |
- // of the supposed splice. |
- EXPECT_TRUE(AddInput(first_buffer)); |
- EXPECT_FALSE(splicer_.HasNextBuffer()); |
- |
- // |second_buffer| should complete the supposed splice, so ensure output is |
- // now available. |
- splicer_.SetSpliceTimestamp(kNoTimestamp); |
- EXPECT_TRUE(AddInput(second_buffer)); |
- |
- VerifyNextBuffer(first_buffer); |
- VerifyNextBuffer(second_buffer); |
- EXPECT_FALSE(splicer_.HasNextBuffer()); |
-} |
- |
-// Test behavior when a splice frame is incorrectly marked and there is a gap |
-// between whats in the pre splice and post splice. |
-// +--------+ |
-// |11111111| |
-// +--------+ |
-// +--------------+ |
-// |22222222222222| |
-// +--------------+ |
-// Results in: |
-// +--------+-+--------------+ |
-// |11111111|0|22222222222222| |
-// +--------+-+--------------+ |
-TEST_F(AudioSplicerTest, IncorrectlyMarkedSpliceWithGap) { |
- const int kBufferSize = |
- input_timestamp_helper_.GetFramesToTarget(max_crossfade_duration()) * 2; |
- const int kGapSize = 2; |
- |
- scoped_refptr<AudioBuffer> first_buffer = |
- GetNextInputBuffer(1.0f, kBufferSize - kGapSize); |
- scoped_refptr<AudioBuffer> gap_buffer = |
- GetNextInputBuffer(0.0f, kGapSize); |
- splicer_.SetSpliceTimestamp(input_timestamp_helper_.GetTimestamp()); |
- scoped_refptr<AudioBuffer> second_buffer = |
- GetNextInputBuffer(0.0f, kBufferSize); |
- |
- // The splicer should pass through the first buffer since it's not part of the |
- // splice. |
- EXPECT_TRUE(AddInput(first_buffer)); |
- VerifyNextBuffer(first_buffer); |
- |
- // Do not add |gap_buffer|. |
- |
- // |second_buffer| will complete the supposed splice. |
- splicer_.SetSpliceTimestamp(kNoTimestamp); |
- EXPECT_TRUE(AddInput(second_buffer)); |
- |
- VerifyNextBuffer(gap_buffer); |
- VerifyNextBuffer(second_buffer); |
- EXPECT_FALSE(splicer_.HasNextBuffer()); |
-} |
- |
-// Test behavior when a splice frame is incorrectly marked and there is a gap |
-// between what's in the pre splice and post splice that is too large to recover |
-// from. |
-// +--------+ |
-// |11111111| |
-// +--------+ |
-// +------+ |
-// |222222| |
-// +------+ |
-// Results in an error and not a crash. |
-TEST_F(AudioSplicerTest, IncorrectlyMarkedSpliceWithBadGap) { |
- const int kBufferSize = |
- input_timestamp_helper_.GetFramesToTarget(max_crossfade_duration()) * 2; |
- const int kGapSize = kBufferSize + |
- input_timestamp_helper_.GetFramesToTarget( |
- base::TimeDelta::FromMilliseconds( |
- AudioSplicer::kMaxTimeDeltaInMilliseconds + 1)); |
- |
- scoped_refptr<AudioBuffer> first_buffer = |
- GetNextInputBuffer(1.0f, kBufferSize); |
- scoped_refptr<AudioBuffer> gap_buffer = |
- GetNextInputBuffer(0.0f, kGapSize); |
- splicer_.SetSpliceTimestamp(input_timestamp_helper_.GetTimestamp()); |
- scoped_refptr<AudioBuffer> second_buffer = |
- GetNextInputBuffer(0.0f, kBufferSize); |
- |
- // The splicer should pass through the first buffer since it's not part of the |
- // splice. |
- EXPECT_TRUE(AddInput(first_buffer)); |
- VerifyNextBuffer(first_buffer); |
- |
- // Do not add |gap_buffer|. |
- |
- // |second_buffer| will complete the supposed splice. |
- splicer_.SetSpliceTimestamp(kNoTimestamp); |
- EXPECT_FALSE(AddInput(second_buffer)); |
-} |
- |
-// Ensure we don't crash when a splice frame is incorrectly marked such that the |
-// splice timestamp has already passed when SetSpliceTimestamp() is called. |
-// This can happen if the encoded timestamps are too far behind the decoded |
-// timestamps. |
-TEST_F(AudioSplicerTest, IncorrectlyMarkedPastSplice) { |
- const int kBufferSize = 200; |
- |
- scoped_refptr<AudioBuffer> first_buffer = |
- GetNextInputBuffer(1.0f, kBufferSize); |
- EXPECT_TRUE(AddInput(first_buffer)); |
- VerifyNextBuffer(first_buffer); |
- |
- // Start the splice at a timestamp which has already occurred. |
- splicer_.SetSpliceTimestamp(base::TimeDelta()); |
- |
- scoped_refptr<AudioBuffer> second_buffer = |
- GetNextInputBuffer(0.5f, kBufferSize); |
- EXPECT_TRUE(AddInput(second_buffer)); |
- EXPECT_FALSE(splicer_.HasNextBuffer()); |
- |
- // |third_buffer| will complete the supposed splice. The buffer size is set |
- // such that unchecked the splicer would try to trim off a negative number of |
- // frames. |
- splicer_.SetSpliceTimestamp(kNoTimestamp); |
- scoped_refptr<AudioBuffer> third_buffer = |
- GetNextInputBuffer(0.0f, kBufferSize * 10); |
- third_buffer->set_timestamp(base::TimeDelta()); |
- EXPECT_TRUE(AddInput(third_buffer)); |
- |
- // The second buffer should come through unmodified. |
- VerifyNextBuffer(second_buffer); |
- |
- // The third buffer should be partially dropped since it overlaps the second. |
- ASSERT_TRUE(splicer_.HasNextBuffer()); |
- const base::TimeDelta second_buffer_end_ts = |
- second_buffer->timestamp() + second_buffer->duration(); |
- scoped_refptr<AudioBuffer> output = splicer_.GetNextBuffer(); |
- EXPECT_EQ(second_buffer_end_ts, output->timestamp()); |
- EXPECT_EQ(third_buffer->duration() - |
- (second_buffer_end_ts - third_buffer->timestamp()), |
- output->duration()); |
- EXPECT_TRUE(VerifyData(output, GetValue(third_buffer))); |
-} |
- |
-} // namespace media |