Index: media/audio/audio_output_controller.cc |
diff --git a/media/audio/audio_output_controller.cc b/media/audio/audio_output_controller.cc |
index 9b8f52387d8e7a4f638d73c7d1127ae2a2f394e2..a8d12dc3685b66e3001225a2285f8aa3ec7d3382 100644 |
--- a/media/audio/audio_output_controller.cc |
+++ b/media/audio/audio_output_controller.cc |
@@ -6,6 +6,7 @@ |
#include <stdint.h> |
+#include <algorithm> |
#include <limits> |
#include "base/bind.h" |
@@ -292,9 +293,9 @@ void AudioOutputController::DoReportError() { |
handler_->OnError(); |
} |
-int AudioOutputController::OnMoreData(AudioBus* dest, |
- uint32_t total_bytes_delay, |
- uint32_t frames_skipped) { |
+int AudioOutputController::OnMoreData(base::TimeTicks target_playout_time, |
+ int prior_frames_skipped, |
+ AudioBus* dest) { |
TRACE_EVENT0("audio", "AudioOutputController::OnMoreData"); |
// Indicate that we haven't wedged (at least not indefinitely, WedgeCheck() |
@@ -306,9 +307,20 @@ int AudioOutputController::OnMoreData(AudioBus* dest, |
sync_reader_->Read(dest); |
+ // If |target_playout_time| is prior to base::TimeTicks::Now(), use a delay of |
+ // zero. This can happen if base::TimeTicks::Now() was passed as |
+ // |target_playout_time| and the clock has advanced. |
+ // TODO(jameswest): Change AudioRendererSink::RenderCallback::Render to use |
+ // the same signature as AudioOutputStream::AudioSourceCallback::OnMoreData |
+ // and pass |target_playout_time| to SyncReader. |
+ const base::TimeDelta delay = |
+ std::max(target_playout_time - base::TimeTicks::Now(), base::TimeDelta()); |
+ const int total_bytes_delay = |
+ delay.InSecondsF() * params_.GetBytesPerSecond(); |
const int frames = dest->frames(); |
sync_reader_->UpdatePendingBytes( |
- total_bytes_delay + frames * params_.GetBytesPerFrame(), frames_skipped); |
+ total_bytes_delay + frames * params_.GetBytesPerFrame(), |
+ prior_frames_skipped); |
bool need_to_duplicate = false; |
{ |
@@ -316,17 +328,12 @@ int AudioOutputController::OnMoreData(AudioBus* dest, |
need_to_duplicate = !duplication_targets_.empty(); |
} |
if (need_to_duplicate) { |
- const base::TimeTicks reference_time = |
- base::TimeTicks::Now() + |
- base::TimeDelta::FromMicroseconds(base::Time::kMicrosecondsPerSecond * |
- total_bytes_delay / |
- params_.GetBytesPerSecond()); |
std::unique_ptr<AudioBus> copy(AudioBus::Create(params_)); |
dest->CopyTo(copy.get()); |
message_loop_->PostTask( |
FROM_HERE, |
base::Bind(&AudioOutputController::BroadcastDataToDuplicationTargets, |
- this, base::Passed(©), reference_time)); |
+ this, base::Passed(©), target_playout_time)); |
} |
if (will_monitor_audio_levels()) |