| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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_discard_helper.h" | 5 #include "media/base/audio_discard_helper.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "media/base/audio_buffer.h" | 10 #include "media/base/audio_buffer.h" |
| 11 | 11 |
| 12 namespace media { | 12 namespace media { |
| 13 | 13 |
| 14 static void WarnOnNonMonotonicTimestamps(base::TimeDelta last_timestamp, | 14 static void WarnOnNonMonotonicTimestamps(base::TimeDelta last_timestamp, |
| 15 base::TimeDelta current_timestamp) { | 15 base::TimeDelta current_timestamp) { |
| 16 if (last_timestamp == kNoTimestamp() || last_timestamp < current_timestamp) | 16 if (last_timestamp == kNoTimestamp || last_timestamp < current_timestamp) |
| 17 return; | 17 return; |
| 18 | 18 |
| 19 const base::TimeDelta diff = current_timestamp - last_timestamp; | 19 const base::TimeDelta diff = current_timestamp - last_timestamp; |
| 20 DLOG(WARNING) << "Input timestamps are not monotonically increasing! " | 20 DLOG(WARNING) << "Input timestamps are not monotonically increasing! " |
| 21 << " ts " << current_timestamp.InMicroseconds() << " us" | 21 << " ts " << current_timestamp.InMicroseconds() << " us" |
| 22 << " diff " << diff.InMicroseconds() << " us"; | 22 << " diff " << diff.InMicroseconds() << " us"; |
| 23 } | 23 } |
| 24 | 24 |
| 25 AudioDiscardHelper::AudioDiscardHelper(int sample_rate, size_t decoder_delay) | 25 AudioDiscardHelper::AudioDiscardHelper(int sample_rate, size_t decoder_delay) |
| 26 : sample_rate_(sample_rate), | 26 : sample_rate_(sample_rate), |
| 27 decoder_delay_(decoder_delay), | 27 decoder_delay_(decoder_delay), |
| 28 timestamp_helper_(sample_rate_), | 28 timestamp_helper_(sample_rate_), |
| 29 discard_frames_(0), | 29 discard_frames_(0), |
| 30 last_input_timestamp_(kNoTimestamp()), | 30 last_input_timestamp_(kNoTimestamp), |
| 31 delayed_discard_(false), | 31 delayed_discard_(false), |
| 32 delayed_end_discard_(0) { | 32 delayed_end_discard_(0) { |
| 33 DCHECK_GT(sample_rate_, 0); | 33 DCHECK_GT(sample_rate_, 0); |
| 34 } | 34 } |
| 35 | 35 |
| 36 AudioDiscardHelper::~AudioDiscardHelper() { | 36 AudioDiscardHelper::~AudioDiscardHelper() { |
| 37 } | 37 } |
| 38 | 38 |
| 39 size_t AudioDiscardHelper::TimeDeltaToFrames(base::TimeDelta duration) const { | 39 size_t AudioDiscardHelper::TimeDeltaToFrames(base::TimeDelta duration) const { |
| 40 DCHECK(duration >= base::TimeDelta()); | 40 DCHECK(duration >= base::TimeDelta()); |
| 41 return duration.InSecondsF() * sample_rate_ + 0.5; | 41 return duration.InSecondsF() * sample_rate_ + 0.5; |
| 42 } | 42 } |
| 43 | 43 |
| 44 void AudioDiscardHelper::Reset(size_t initial_discard) { | 44 void AudioDiscardHelper::Reset(size_t initial_discard) { |
| 45 discard_frames_ = initial_discard; | 45 discard_frames_ = initial_discard; |
| 46 last_input_timestamp_ = kNoTimestamp(); | 46 last_input_timestamp_ = kNoTimestamp; |
| 47 timestamp_helper_.SetBaseTimestamp(kNoTimestamp()); | 47 timestamp_helper_.SetBaseTimestamp(kNoTimestamp); |
| 48 delayed_discard_ = false; | 48 delayed_discard_ = false; |
| 49 delayed_discard_padding_ = DecoderBuffer::DiscardPadding(); | 49 delayed_discard_padding_ = DecoderBuffer::DiscardPadding(); |
| 50 } | 50 } |
| 51 | 51 |
| 52 bool AudioDiscardHelper::ProcessBuffers( | 52 bool AudioDiscardHelper::ProcessBuffers( |
| 53 const scoped_refptr<DecoderBuffer>& encoded_buffer, | 53 const scoped_refptr<DecoderBuffer>& encoded_buffer, |
| 54 const scoped_refptr<AudioBuffer>& decoded_buffer) { | 54 const scoped_refptr<AudioBuffer>& decoded_buffer) { |
| 55 DCHECK(!encoded_buffer->end_of_stream()); | 55 DCHECK(!encoded_buffer->end_of_stream()); |
| 56 DCHECK(encoded_buffer->timestamp() != kNoTimestamp()); | 56 DCHECK(encoded_buffer->timestamp() != kNoTimestamp); |
| 57 | 57 |
| 58 // Issue a debug warning when we see non-monotonic timestamps. Only a warning | 58 // Issue a debug warning when we see non-monotonic timestamps. Only a warning |
| 59 // to allow chained OGG playback. | 59 // to allow chained OGG playback. |
| 60 WarnOnNonMonotonicTimestamps(last_input_timestamp_, | 60 WarnOnNonMonotonicTimestamps(last_input_timestamp_, |
| 61 encoded_buffer->timestamp()); | 61 encoded_buffer->timestamp()); |
| 62 last_input_timestamp_ = encoded_buffer->timestamp(); | 62 last_input_timestamp_ = encoded_buffer->timestamp(); |
| 63 | 63 |
| 64 // If this is the first buffer seen, setup the timestamp helper. | 64 // If this is the first buffer seen, setup the timestamp helper. |
| 65 const bool first_buffer = !initialized(); | 65 const bool first_buffer = !initialized(); |
| 66 if (first_buffer) { | 66 if (first_buffer) { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 | 132 |
| 133 // Handle front discard padding. | 133 // Handle front discard padding. |
| 134 if (current_discard_padding.first > base::TimeDelta()) { | 134 if (current_discard_padding.first > base::TimeDelta()) { |
| 135 const size_t decoded_frames = decoded_buffer->frame_count(); | 135 const size_t decoded_frames = decoded_buffer->frame_count(); |
| 136 | 136 |
| 137 // If a complete buffer discard is requested and there's no decoder delay, | 137 // If a complete buffer discard is requested and there's no decoder delay, |
| 138 // just discard all remaining frames from this buffer. With decoder delay | 138 // just discard all remaining frames from this buffer. With decoder delay |
| 139 // we have to estimate the correct number of frames to discard based on the | 139 // we have to estimate the correct number of frames to discard based on the |
| 140 // duration of the encoded buffer. | 140 // duration of the encoded buffer. |
| 141 const size_t start_frames_to_discard = | 141 const size_t start_frames_to_discard = |
| 142 current_discard_padding.first == kInfiniteDuration() | 142 current_discard_padding.first == kInfiniteDuration |
| 143 ? (decoder_delay_ > 0 | 143 ? (decoder_delay_ > 0 |
| 144 ? TimeDeltaToFrames(encoded_buffer->duration()) | 144 ? TimeDeltaToFrames(encoded_buffer->duration()) |
| 145 : decoded_frames) | 145 : decoded_frames) |
| 146 : TimeDeltaToFrames(current_discard_padding.first); | 146 : TimeDeltaToFrames(current_discard_padding.first); |
| 147 | 147 |
| 148 // Regardless of the timestamp on the encoded buffer, the corresponding | 148 // Regardless of the timestamp on the encoded buffer, the corresponding |
| 149 // decoded output will appear |decoder_delay_| frames later. | 149 // decoded output will appear |decoder_delay_| frames later. |
| 150 size_t discard_start = decoder_delay_; | 150 size_t discard_start = decoder_delay_; |
| 151 if (decoder_delay_ > 0) { | 151 if (decoder_delay_ > 0) { |
| 152 // If we have a |decoder_delay_| and have already discarded frames from | 152 // If we have a |decoder_delay_| and have already discarded frames from |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 DVLOG(3) << __FUNCTION__ << " ts: " << timestamp_helper_.GetTimestamp() | 232 DVLOG(3) << __FUNCTION__ << " ts: " << timestamp_helper_.GetTimestamp() |
| 233 << " frames: " << decoded_buffer->frame_count(); | 233 << " frames: " << decoded_buffer->frame_count(); |
| 234 | 234 |
| 235 // Assign timestamp to the buffer. | 235 // Assign timestamp to the buffer. |
| 236 decoded_buffer->set_timestamp(timestamp_helper_.GetTimestamp()); | 236 decoded_buffer->set_timestamp(timestamp_helper_.GetTimestamp()); |
| 237 timestamp_helper_.AddFrames(decoded_buffer->frame_count()); | 237 timestamp_helper_.AddFrames(decoded_buffer->frame_count()); |
| 238 return true; | 238 return true; |
| 239 } | 239 } |
| 240 | 240 |
| 241 } // namespace media | 241 } // namespace media |
| OLD | NEW |