| 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..027cb7c5073d2e5e32cb26778084160c6ecaf829 100644
|
| --- a/media/audio/win/audio_low_latency_output_win.cc
|
| +++ b/media/audio/win/audio_low_latency_output_win.cc
|
| @@ -71,6 +71,7 @@ WASAPIAudioOutputStream::WASAPIAudioOutputStream(AudioManagerWin* manager,
|
| share_mode_(GetShareMode()),
|
| num_written_frames_(0),
|
| source_(NULL),
|
| + hns_units_to_perf_count_(0.0),
|
| audio_bus_(AudioBus::Create(params)) {
|
| DCHECK(manager_);
|
|
|
| @@ -127,6 +128,14 @@ WASAPIAudioOutputStream::WASAPIAudioOutputStream(AudioManagerWin* manager,
|
| // Create the event which will be set in Stop() when capturing shall stop.
|
| stop_render_event_.Set(CreateEvent(NULL, FALSE, FALSE, NULL));
|
| DCHECK(stop_render_event_.IsValid());
|
| +
|
| + LARGE_INTEGER performance_frequency;
|
| + if (QueryPerformanceFrequency(&performance_frequency)) {
|
| + hns_units_to_perf_count_ =
|
| + (static_cast<double>(performance_frequency.QuadPart) / 10000000.0);
|
| + } else {
|
| + DLOG(ERROR) << "High-resolution performance counters are not supported.";
|
| + }
|
| }
|
|
|
| WASAPIAudioOutputStream::~WASAPIAudioOutputStream() {
|
| @@ -511,8 +520,11 @@ bool WASAPIAudioOutputStream::RenderAudioFromSource(UINT64 device_frequency) {
|
| // can typically be utilized by an acoustic echo-control (AEC)
|
| // unit at the render side.
|
| UINT64 position = 0;
|
| + UINT64 performance_counter_position = 0;
|
| uint32_t audio_delay_bytes = 0;
|
| - hr = audio_clock_->GetPosition(&position, NULL);
|
| + AudioTimestamp output_timestamp;
|
| +
|
| + hr = audio_clock_->GetPosition(&position, &performance_counter_position);
|
| if (SUCCEEDED(hr)) {
|
| // Stream position of the sample that is currently playing
|
| // through the speaker.
|
| @@ -529,13 +541,20 @@ bool WASAPIAudioOutputStream::RenderAudioFromSource(UINT64 device_frequency) {
|
| // render client using the OnMoreData() callback.
|
| audio_delay_bytes = (pos_last_sample_written_frames -
|
| pos_sample_playing_frames) * format_.Format.nBlockAlign;
|
| + if (hns_units_to_perf_count_) {
|
| + output_timestamp.frames = pos_sample_playing_frames;
|
| + output_timestamp.ticks =
|
| + base::TimeTicks::FromQPCValue(performance_counter_position *
|
| + hns_units_to_perf_count_)
|
| + .ToInternalValue();
|
| + }
|
| }
|
|
|
| // 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);
|
| + int frames_filled = source_->OnMoreData(audio_bus_.get(), audio_delay_bytes,
|
| + 0, output_timestamp);
|
| uint32_t num_filled_bytes = frames_filled * format_.Format.nBlockAlign;
|
| DCHECK_LE(num_filled_bytes, packet_size_bytes_);
|
|
|
|
|