| 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
|
|
|