Index: media/filters/audio_clock.cc |
diff --git a/media/filters/audio_clock.cc b/media/filters/audio_clock.cc |
index 19c5c2c28ab0fb08fec22844b0201a61d5f11aa1..0bd0a6c4ac93c971131eed8486e5da7900b7f2e2 100644 |
--- a/media/filters/audio_clock.cc |
+++ b/media/filters/audio_clock.cc |
@@ -8,6 +8,7 @@ |
#include <stddef.h> |
#include <algorithm> |
+#include <cmath> |
#include "base/logging.h" |
@@ -19,9 +20,8 @@ AudioClock::AudioClock(base::TimeDelta start_timestamp, int sample_rate) |
static_cast<double>(base::Time::kMicrosecondsPerSecond) / |
sample_rate), |
total_buffered_frames_(0), |
- front_timestamp_(start_timestamp), |
- back_timestamp_(start_timestamp) { |
-} |
+ front_timestamp_micros_(start_timestamp.InMicroseconds()), |
+ back_timestamp_micros_(start_timestamp.InMicroseconds()) {} |
AudioClock::~AudioClock() { |
} |
@@ -36,8 +36,10 @@ void AudioClock::WroteAudio(int frames_written, |
DCHECK_GE(playback_rate, 0); |
// First write: initialize buffer with silence. |
- if (start_timestamp_ == front_timestamp_ && buffered_.empty()) |
+ if (start_timestamp_.InMicroseconds() == front_timestamp_micros_ && |
+ buffered_.empty()) { |
PushBufferedAudioData(delay_frames, 0.0); |
+ } |
// Move frames from |buffered_| into the computed timestamp based on |
// |delay_frames|. |
@@ -53,14 +55,16 @@ void AudioClock::WroteAudio(int frames_written, |
// Update our front and back timestamps. The back timestamp is considered the |
// authoritative source of truth, so base the front timestamp on range of data |
// buffered. Doing so avoids accumulation errors on the front timestamp. |
- back_timestamp_ += base::TimeDelta::FromMicroseconds( |
- frames_written * playback_rate * microseconds_per_frame_); |
+ back_timestamp_micros_ += |
+ frames_written * playback_rate * microseconds_per_frame_; |
+ |
// Don't let front timestamp move earlier in time, as could occur due to delay |
// frames pushed in the first write, above. |
- front_timestamp_ = std::max(front_timestamp_, |
- back_timestamp_ - ComputeBufferedMediaDuration()); |
- DCHECK_GE(front_timestamp_, start_timestamp_); |
- DCHECK_LE(front_timestamp_, back_timestamp_); |
+ front_timestamp_micros_ = |
+ std::max(front_timestamp_micros_, |
+ back_timestamp_micros_ - ComputeBufferedMediaDurationMicros()); |
+ DCHECK_GE(front_timestamp_micros_, start_timestamp_.InMicroseconds()); |
+ DCHECK_LE(front_timestamp_micros_, back_timestamp_micros_); |
} |
void AudioClock::CompensateForSuspendedWrites(base::TimeDelta elapsed, |
@@ -81,12 +85,15 @@ void AudioClock::CompensateForSuspendedWrites(base::TimeDelta elapsed, |
} |
base::TimeDelta AudioClock::TimeUntilPlayback(base::TimeDelta timestamp) const { |
- DCHECK_GE(timestamp, front_timestamp_); |
- DCHECK_LE(timestamp, back_timestamp_); |
+ // Use front/back_timestamp() methods rather than internal members. The public |
+ // methods round to the nearest microsecond for conversion to TimeDelta and |
+ // the rounded value will likely be used by the caller. |
+ DCHECK_GE(timestamp, front_timestamp()); |
+ DCHECK_LE(timestamp, back_timestamp()); |
int64_t frames_until_timestamp = 0; |
double timestamp_us = timestamp.InMicroseconds(); |
- double media_time_us = front_timestamp_.InMicroseconds(); |
+ double media_time_us = front_timestamp().InMicroseconds(); |
for (size_t i = 0; i < buffered_.size(); ++i) { |
// Leading silence is always accounted prior to anything else. |
@@ -113,8 +120,8 @@ base::TimeDelta AudioClock::TimeUntilPlayback(base::TimeDelta timestamp) const { |
frames_until_timestamp += buffered_[i].frames; |
} |
- return base::TimeDelta::FromMicroseconds(frames_until_timestamp * |
- microseconds_per_frame_); |
+ return base::TimeDelta::FromMicroseconds( |
+ std::round(frames_until_timestamp * microseconds_per_frame_)); |
} |
void AudioClock::ContiguousAudioDataBufferedForTesting( |
@@ -179,12 +186,11 @@ void AudioClock::PopBufferedAudioData(int64_t frames) { |
} |
} |
-base::TimeDelta AudioClock::ComputeBufferedMediaDuration() const { |
+double AudioClock::ComputeBufferedMediaDurationMicros() const { |
double scaled_frames = 0; |
for (const auto& buffer : buffered_) |
scaled_frames += buffer.frames * buffer.playback_rate; |
- return base::TimeDelta::FromMicroseconds(scaled_frames * |
- microseconds_per_frame_); |
+ return scaled_frames * microseconds_per_frame_; |
} |
} // namespace media |