Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "media/base/audio_discard_helper.h" | |
| 6 | |
| 7 #include <cmath> | |
| 8 | |
| 9 #include "base/logging.h" | |
| 10 #include "media/base/audio_buffer.h" | |
| 11 #include "media/base/buffers.h" | |
| 12 #include "media/base/decoder_buffer.h" | |
| 13 | |
| 14 namespace media { | |
| 15 | |
| 16 static void WarnOnNonMonotonicTimestamps(base::TimeDelta last_timestamp, | |
| 17 base::TimeDelta current_timestamp) { | |
| 18 if (last_timestamp == kNoTimestamp() || last_timestamp < current_timestamp) | |
| 19 return; | |
| 20 | |
| 21 const base::TimeDelta diff = current_timestamp - last_timestamp; | |
| 22 DLOG(WARNING) << "Input timestamps are not monotonically increasing! " | |
| 23 << " ts " << current_timestamp.InMicroseconds() << " us" | |
| 24 << " diff " << diff.InMicroseconds() << " us"; | |
| 25 } | |
| 26 | |
| 27 AudioDiscardHelper::AudioDiscardHelper(int sample_rate) | |
| 28 : sample_rate_(sample_rate), | |
| 29 timestamp_helper_(sample_rate_), | |
| 30 discard_frames_(0), | |
| 31 last_input_timestamp_(kNoTimestamp()) { | |
|
wolenetz
2014/04/28 21:52:07
nit: is any sanity checking needed on sample_rate_
DaleCurtis
2014/04/28 23:09:03
As far as this code is concerned it just needs to
| |
| 32 } | |
| 33 | |
| 34 AudioDiscardHelper::~AudioDiscardHelper() { | |
| 35 } | |
| 36 | |
| 37 int AudioDiscardHelper::TimeDeltaToFrames(base::TimeDelta duration) const { | |
| 38 DCHECK(duration >= base::TimeDelta()); | |
| 39 return std::ceil(duration.InSecondsF() * sample_rate_); | |
|
wolenetz
2014/04/28 21:52:07
With ceil(), might we hit off-by-one stuff here? (
DaleCurtis
2014/04/28 23:09:03
Since this floating point value is calculated from
| |
| 40 } | |
| 41 | |
| 42 void AudioDiscardHelper::Reset(size_t initial_discard) { | |
| 43 discard_frames_ = initial_discard; | |
| 44 last_input_timestamp_ = kNoTimestamp(); | |
| 45 timestamp_helper_.SetBaseTimestamp(kNoTimestamp()); | |
| 46 } | |
| 47 | |
| 48 bool AudioDiscardHelper::ProcessBuffers( | |
| 49 const scoped_refptr<DecoderBuffer>& encoded_buffer, | |
| 50 const scoped_refptr<AudioBuffer>& decoded_buffer) { | |
| 51 DCHECK(!encoded_buffer->end_of_stream()); | |
| 52 DCHECK(encoded_buffer->timestamp() != kNoTimestamp()); | |
| 53 | |
| 54 // Issue a debug warning when we see non-monotonic timestamps. Only a warning | |
| 55 // to allow chained OGG playback. | |
| 56 WarnOnNonMonotonicTimestamps(last_input_timestamp_, | |
| 57 encoded_buffer->timestamp()); | |
| 58 last_input_timestamp_ = encoded_buffer->timestamp(); | |
| 59 | |
| 60 // If this is the first buffer seen, setup the timestamp helper. | |
| 61 if (!initialized()) | |
| 62 timestamp_helper_.SetBaseTimestamp(encoded_buffer->timestamp()); | |
| 63 DCHECK(initialized()); | |
| 64 | |
| 65 if (!decoded_buffer || !decoded_buffer->frame_count()) | |
| 66 return false; | |
| 67 | |
| 68 if (discard_frames_ > 0) { | |
| 69 const size_t decoded_frames = decoded_buffer->frame_count(); | |
| 70 const size_t frames_to_discard = std::min(discard_frames_, decoded_frames); | |
| 71 discard_frames_ -= frames_to_discard; | |
| 72 | |
| 73 // If everything would be discarded, indicate a new buffer is required. | |
| 74 if (frames_to_discard == decoded_frames) | |
| 75 return false; | |
| 76 | |
| 77 decoded_buffer->TrimStart(frames_to_discard); | |
|
wolenetz
2014/04/28 21:52:07
TrimStart() will modify decoded_buffer's duration_
DaleCurtis
2014/04/28 22:03:51
It's this codes expectation that it is the sole au
wolenetz
2014/04/28 22:37:56
Regarding assumption of ability to set duration/ti
DaleCurtis
2014/04/28 23:09:03
I think that comment can be removed now. I'll do
| |
| 78 } | |
| 79 | |
| 80 // TODO(dalecurtis): Applying the current buffer's discard padding doesn't | |
| 81 // make sense in the Vorbis case because there is a delay of one buffer before | |
| 82 // decoded buffers are returned. Fix and add support for more than just end | |
| 83 // trimming. | |
|
wolenetz
2014/04/28 21:52:07
nit: reference bug?
DaleCurtis
2014/04/28 23:09:03
Done.
| |
| 84 if (encoded_buffer->discard_padding() > base::TimeDelta()) { | |
| 85 const size_t decoded_frames = decoded_buffer->frame_count(); | |
| 86 const size_t end_frames_to_discard = | |
| 87 TimeDeltaToFrames(encoded_buffer->discard_padding()); | |
| 88 if (end_frames_to_discard > decoded_frames) { | |
|
wolenetz
2014/04/28 21:52:07
Is end discard aware of start discard? (If not, co
DaleCurtis
2014/04/28 22:03:51
It's expected that users of discard_padding() will
| |
| 89 DLOG(ERROR) << "Invalid file. Incorrect discard padding value."; | |
|
wolenetz
2014/04/28 21:52:07
nit: If this helper will be used by MSE, not just
DaleCurtis
2014/04/28 23:09:03
Done.
| |
| 90 return false; | |
| 91 } | |
| 92 | |
| 93 // If everything would be discarded, indicate a new buffer is required. | |
| 94 if (end_frames_to_discard == decoded_frames) | |
| 95 return false; | |
| 96 | |
| 97 decoded_buffer->TrimEnd(end_frames_to_discard); | |
| 98 } else { | |
| 99 DCHECK(encoded_buffer->discard_padding() == base::TimeDelta()); | |
| 100 } | |
| 101 | |
| 102 // Assign timestamp and duration to the buffer. | |
| 103 decoded_buffer->set_timestamp(timestamp_helper_.GetTimestamp()); | |
| 104 decoded_buffer->set_duration( | |
| 105 timestamp_helper_.GetFrameDuration(decoded_buffer->frame_count())); | |
| 106 timestamp_helper_.AddFrames(decoded_buffer->frame_count()); | |
| 107 return true; | |
| 108 } | |
| 109 | |
| 110 } // namespace media | |
| OLD | NEW |