summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authordalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-08 09:43:12 +0000
committerdalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-08 09:44:37 +0000
commiteb7928a731f7f9a7282fcb503295d37e5a8ce1eb (patch)
treec77842c0f38fb2932c443afdfa2bba803cba9010 /media
parent0d830e6b4659a688c94dd33e9fb0a8d4bc5c9b9b (diff)
downloadchromium_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.cc6
-rw-r--r--media/base/audio_splicer_unittest.cc44
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