diff options
author | dalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-08 09:43:12 +0000 |
---|---|---|
committer | dalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-08 09:44:37 +0000 |
commit | eb7928a731f7f9a7282fcb503295d37e5a8ce1eb (patch) | |
tree | c77842c0f38fb2932c443afdfa2bba803cba9010 /media | |
parent | 0d830e6b4659a688c94dd33e9fb0a8d4bc5c9b9b (diff) | |
download | chromium_src-eb7928a731f7f9a7282fcb503295d37e5a8ce1eb.zip chromium_src-eb7928a731f7f9a7282fcb503295d37e5a8ce1eb.tar.gz chromium_src-eb7928a731f7f9a7282fcb503295d37e5a8ce1eb.tar.bz2 |
Don't crash when splices are in the past due to bad media.
Bad media may result in splice frames way in the past. We need
to avoid crashing in this case. See the bug for more details.
BUG=400442
TEST=new media test.
Review URL: https://codereview.chromium.org/440803002
Cr-Commit-Position: refs/heads/master@{#288284}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@288284 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r-- | media/base/audio_splicer.cc | 6 | ||||
-rw-r--r-- | media/base/audio_splicer_unittest.cc | 44 |
2 files changed, 48 insertions, 2 deletions
diff --git a/media/base/audio_splicer.cc b/media/base/audio_splicer.cc index 7fafc8b..0c8ac34 100644 --- a/media/base/audio_splicer.cc +++ b/media/base/audio_splicer.cc @@ -302,8 +302,10 @@ bool AudioSplicer::AddInput(const scoped_refptr<AudioBuffer>& input) { // If a splice frame was incorrectly marked due to poor demuxed timestamps, we // may not actually have a splice. Here we check if any frames exist before // the splice. In this case, just transfer all data to the output sanitizer. - if (pre_splice_sanitizer_->GetFrameCount() <= - output_ts_helper.GetFramesToTarget(splice_timestamp_)) { + const int frames_before_splice = + output_ts_helper.GetFramesToTarget(splice_timestamp_); + if (frames_before_splice < 0 || + pre_splice_sanitizer_->GetFrameCount() <= frames_before_splice) { CHECK(pre_splice_sanitizer_->DrainInto(output_sanitizer_.get())); // If the file contains incorrectly muxed timestamps, there may be huge gaps diff --git a/media/base/audio_splicer_unittest.cc b/media/base/audio_splicer_unittest.cc index e6de2c6..86131bf 100644 --- a/media/base/audio_splicer_unittest.cc +++ b/media/base/audio_splicer_unittest.cc @@ -720,4 +720,48 @@ TEST_F(AudioSplicerTest, IncorrectlyMarkedSpliceWithBadGap) { 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 |