Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(258)

Side by Side Diff: media/base/audio_splicer.cc

Issue 405143003: Merge 279817 "Don't crash on splice frame failure with bad content." (Closed) Base URL: svn://svn.chromium.org/chrome/branches/2062/src/
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/base/audio_splicer.h ('k') | media/base/audio_splicer_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "media/base/audio_splicer.h" 5 #include "media/base/audio_splicer.h"
6 6
7 #include <cstdlib> 7 #include <cstdlib>
8 #include <deque> 8 #include <deque>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "media/base/audio_buffer.h" 11 #include "media/base/audio_buffer.h"
12 #include "media/base/audio_bus.h" 12 #include "media/base/audio_bus.h"
13 #include "media/base/audio_decoder_config.h" 13 #include "media/base/audio_decoder_config.h"
14 #include "media/base/audio_timestamp_helper.h" 14 #include "media/base/audio_timestamp_helper.h"
15 #include "media/base/vector_math.h" 15 #include "media/base/vector_math.h"
16 16
17 namespace media { 17 namespace media {
18 18
19 // Largest gap or overlap allowed by this class. Anything
20 // larger than this will trigger an error.
21 // This is an arbitrary value, but the initial selection of 50ms
22 // roughly represents the duration of 2 compressed AAC or MP3 frames.
23 static const int kMaxTimeDeltaInMilliseconds = 50;
24
25 // Minimum gap size needed before the splicer will take action to 19 // Minimum gap size needed before the splicer will take action to
26 // fill a gap. This avoids periodically inserting and then dropping samples 20 // fill a gap. This avoids periodically inserting and then dropping samples
27 // when the buffer timestamps are slightly off because of timestamp rounding 21 // when the buffer timestamps are slightly off because of timestamp rounding
28 // in the source content. Unit is frames. 22 // in the source content. Unit is frames.
29 static const int kMinGapSize = 2; 23 static const int kMinGapSize = 2;
30 24
31 // AudioBuffer::TrimStart() is not as accurate as the timestamp helper, so 25 // AudioBuffer::TrimStart() is not as accurate as the timestamp helper, so
32 // manually adjust the duration and timestamp after trimming. 26 // manually adjust the duration and timestamp after trimming.
33 static void AccurateTrimStart(int frames_to_trim, 27 static void AccurateTrimStart(int frames_to_trim,
34 const scoped_refptr<AudioBuffer> buffer, 28 const scoped_refptr<AudioBuffer> buffer,
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 if (output_timestamp_helper_.base_timestamp() > input->timestamp()) { 130 if (output_timestamp_helper_.base_timestamp() > input->timestamp()) {
137 DVLOG(1) << "Input timestamp is before the base timestamp."; 131 DVLOG(1) << "Input timestamp is before the base timestamp.";
138 return false; 132 return false;
139 } 133 }
140 134
141 const base::TimeDelta timestamp = input->timestamp(); 135 const base::TimeDelta timestamp = input->timestamp();
142 const base::TimeDelta expected_timestamp = 136 const base::TimeDelta expected_timestamp =
143 output_timestamp_helper_.GetTimestamp(); 137 output_timestamp_helper_.GetTimestamp();
144 const base::TimeDelta delta = timestamp - expected_timestamp; 138 const base::TimeDelta delta = timestamp - expected_timestamp;
145 139
146 if (std::abs(delta.InMilliseconds()) > kMaxTimeDeltaInMilliseconds) { 140 if (std::abs(delta.InMilliseconds()) >
141 AudioSplicer::kMaxTimeDeltaInMilliseconds) {
147 DVLOG(1) << "Timestamp delta too large: " << delta.InMicroseconds() << "us"; 142 DVLOG(1) << "Timestamp delta too large: " << delta.InMicroseconds() << "us";
148 return false; 143 return false;
149 } 144 }
150 145
151 int frames_to_fill = 0; 146 int frames_to_fill = 0;
152 if (delta != base::TimeDelta()) 147 if (delta != base::TimeDelta())
153 frames_to_fill = output_timestamp_helper_.GetFramesToTarget(timestamp); 148 frames_to_fill = output_timestamp_helper_.GetFramesToTarget(timestamp);
154 149
155 if (frames_to_fill == 0 || std::abs(frames_to_fill) < kMinGapSize) { 150 if (frames_to_fill == 0 || std::abs(frames_to_fill) < kMinGapSize) {
156 AddOutputBuffer(input); 151 AddOutputBuffer(input);
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 output_sanitizer_->ResetTimestampState( 298 output_sanitizer_->ResetTimestampState(
304 0, pre_splice_sanitizer_->timestamp_helper().base_timestamp()); 299 0, pre_splice_sanitizer_->timestamp_helper().base_timestamp());
305 } 300 }
306 301
307 // If a splice frame was incorrectly marked due to poor demuxed timestamps, we 302 // If a splice frame was incorrectly marked due to poor demuxed timestamps, we
308 // may not actually have a splice. Here we check if any frames exist before 303 // may not actually have a splice. Here we check if any frames exist before
309 // the splice. In this case, just transfer all data to the output sanitizer. 304 // the splice. In this case, just transfer all data to the output sanitizer.
310 if (pre_splice_sanitizer_->GetFrameCount() <= 305 if (pre_splice_sanitizer_->GetFrameCount() <=
311 output_ts_helper.GetFramesToTarget(splice_timestamp_)) { 306 output_ts_helper.GetFramesToTarget(splice_timestamp_)) {
312 CHECK(pre_splice_sanitizer_->DrainInto(output_sanitizer_.get())); 307 CHECK(pre_splice_sanitizer_->DrainInto(output_sanitizer_.get()));
313 CHECK(post_splice_sanitizer_->DrainInto(output_sanitizer_.get())); 308
309 // If the file contains incorrectly muxed timestamps, there may be huge gaps
310 // between the demuxed and decoded timestamps.
311 if (!post_splice_sanitizer_->DrainInto(output_sanitizer_.get()))
312 return false;
313
314 reset_splice_timestamps(); 314 reset_splice_timestamps();
315 return true; 315 return true;
316 } 316 }
317 317
318 // Wait until we have enough data to crossfade or end of stream. 318 // Wait until we have enough data to crossfade or end of stream.
319 if (!input->end_of_stream() && 319 if (!input->end_of_stream() &&
320 input->timestamp() + input->duration() < max_splice_end_timestamp_) { 320 input->timestamp() + input->duration() < max_splice_end_timestamp_) {
321 return true; 321 return true;
322 } 322 }
323 323
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 AccurateTrimStart(frames_to_trim, remainder, output_ts_helper); 498 AccurateTrimStart(frames_to_trim, remainder, output_ts_helper);
499 CHECK(output_sanitizer_->AddInput(remainder)); 499 CHECK(output_sanitizer_->AddInput(remainder));
500 } 500 }
501 501
502 // Transfer all remaining buffers out and reset once empty. 502 // Transfer all remaining buffers out and reset once empty.
503 CHECK(post_splice_sanitizer_->DrainInto(output_sanitizer_.get())); 503 CHECK(post_splice_sanitizer_->DrainInto(output_sanitizer_.get()));
504 post_splice_sanitizer_->Reset(); 504 post_splice_sanitizer_->Reset();
505 } 505 }
506 506
507 } // namespace media 507 } // namespace media
OLDNEW
« no previous file with comments | « media/base/audio_splicer.h ('k') | media/base/audio_splicer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698