| Index: media/audio/win/audio_low_latency_output_win.cc
|
| diff --git a/media/audio/win/audio_low_latency_output_win.cc b/media/audio/win/audio_low_latency_output_win.cc
|
| index 9fa035d80ba6aec06859dfcea5c2f04202e0e1cd..847a5a2b029bc08dbf0999fa852098b82053576e 100644
|
| --- a/media/audio/win/audio_low_latency_output_win.cc
|
| +++ b/media/audio/win/audio_low_latency_output_win.cc
|
| @@ -11,6 +11,7 @@
|
| #include "base/macros.h"
|
| #include "base/metrics/histogram.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| +#include "base/time/time.h"
|
| #include "base/trace_event/trace_event.h"
|
| #include "base/win/scoped_propvariant.h"
|
| #include "media/audio/audio_device_description.h"
|
| @@ -511,31 +512,35 @@ bool WASAPIAudioOutputStream::RenderAudioFromSource(UINT64 device_frequency) {
|
| // can typically be utilized by an acoustic echo-control (AEC)
|
| // unit at the render side.
|
| UINT64 position = 0;
|
| - uint32_t audio_delay_bytes = 0;
|
| - hr = audio_clock_->GetPosition(&position, NULL);
|
| + UINT64 qpc_position = 0;
|
| + base::TimeDelta delay;
|
| + base::TimeTicks delay_timestamp;
|
| + hr = audio_clock_->GetPosition(&position, &qpc_position);
|
| if (SUCCEEDED(hr)) {
|
| - // Stream position of the sample that is currently playing
|
| - // through the speaker.
|
| - double pos_sample_playing_frames = format_.Format.nSamplesPerSec *
|
| - (static_cast<double>(position) / device_frequency);
|
| -
|
| - // Stream position of the last sample written to the endpoint
|
| - // buffer. Note that, the packet we are about to receive in
|
| - // the upcoming callback is also included.
|
| - size_t pos_last_sample_written_frames =
|
| - num_written_frames_ + packet_size_frames_;
|
| -
|
| - // Derive the actual delay value which will be fed to the
|
| - // render client using the OnMoreData() callback.
|
| - audio_delay_bytes = (pos_last_sample_written_frames -
|
| - pos_sample_playing_frames) * format_.Format.nBlockAlign;
|
| + // Number of frames already played out through the speaker.
|
| + const uint64_t played_out_frames =
|
| + format_.Format.nSamplesPerSec * position / device_frequency;
|
| +
|
| + // Number of frames that have been written to the buffer but not yet
|
| + // played out.
|
| + const uint64_t delay_frames = num_written_frames_ - played_out_frames;
|
| +
|
| + // Convert the delay from frames to time.
|
| + delay = base::TimeDelta::FromMicroseconds(
|
| + delay_frames * base::Time::kMicrosecondsPerSecond /
|
| + format_.Format.nSamplesPerSec);
|
| +
|
| + delay_timestamp = base::TimeTicks::FromQPCValue(qpc_position);
|
| + } else {
|
| + // Use a delay of zero.
|
| + delay_timestamp = base::TimeTicks::Now();
|
| }
|
|
|
| // Read a data packet from the registered client source and
|
| // deliver a delay estimate in the same callback to the client.
|
|
|
| int frames_filled =
|
| - source_->OnMoreData(audio_bus_.get(), audio_delay_bytes, 0);
|
| + source_->OnMoreData(delay, delay_timestamp, 0, audio_bus_.get());
|
| uint32_t num_filled_bytes = frames_filled * format_.Format.nBlockAlign;
|
| DCHECK_LE(num_filled_bytes, packet_size_bytes_);
|
|
|
| @@ -641,7 +646,7 @@ HRESULT WASAPIAudioOutputStream::ExclusiveModeInitialization(
|
| }
|
|
|
| void WASAPIAudioOutputStream::StopThread() {
|
| - if (render_thread_ ) {
|
| + if (render_thread_) {
|
| if (render_thread_->HasBeenStarted()) {
|
| // Wait until the thread completes and perform cleanup.
|
| SetEvent(stop_render_event_.Get());
|
|
|