Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Unified Diff: media/audio/mac/audio_auhal_mac.cc

Issue 2101303004: Pass delay and timestamp to AudioSourceCallback::OnMoreData. (Closed) Base URL: https://chromium.googlesource.com/chromium/src@master
Patch Set: Fix Mac CQ errors. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: media/audio/mac/audio_auhal_mac.cc
diff --git a/media/audio/mac/audio_auhal_mac.cc b/media/audio/mac/audio_auhal_mac.cc
index c02098c2346e6bfb232a357c6de8e1f652e9d314..d4d6075bd84a2bac8a586b1cb7337beee28a9b7c 100644
--- a/media/audio/mac/audio_auhal_mac.cc
+++ b/media/audio/mac/audio_auhal_mac.cc
@@ -6,16 +6,19 @@
#include <CoreServices/CoreServices.h>
+#include <algorithm>
+#include <string>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/mac/mac_logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/stringprintf.h"
-#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "media/audio/mac/audio_manager_mac.h"
#include "media/base/audio_pull_fifo.h"
+#include "media/base/audio_timestamp_helper.h"
namespace media {
@@ -51,9 +54,7 @@ AUHALStream::AUHALStream(AudioManagerMac* manager,
device_(device),
audio_unit_(0),
volume_(1),
- hardware_latency_frames_(0),
stopped_(true),
- current_hardware_pending_bytes_(0),
current_lost_frames_(0),
last_sample_time_(0.0),
last_number_of_frames_(0),
@@ -117,7 +118,7 @@ bool AUHALStream::Open() {
bool configured = ConfigureAUHAL();
if (configured)
- hardware_latency_frames_ = GetHardwareLatency();
+ hardware_latency_ = GetHardwareLatency();
return configured;
}
@@ -237,10 +238,7 @@ OSStatus AUHALStream::Render(
// Make |output_bus_| wrap the output AudioBufferList.
WrapBufferList(data, output_bus_.get(), number_of_frames);
- // Update the playout latency.
- const double playout_latency_frames = GetPlayoutLatency(output_time_stamp);
- current_hardware_pending_bytes_ = static_cast<uint32_t>(
- (playout_latency_frames + 0.5) * params_.GetBytesPerFrame());
+ current_playout_time_ = GetPlayoutTime(output_time_stamp);
if (audio_fifo_)
audio_fifo_->Consume(output_bus_.get(), output_bus_->frames());
@@ -259,10 +257,14 @@ void AUHALStream::ProvideInput(int frame_delay, AudioBus* dest) {
return;
}
+ const base::TimeTicks playout_time =
+ current_playout_time_ +
+ AudioTimestampHelper::FramesToTime(frame_delay, params_.sample_rate());
+ const base::TimeTicks now = base::TimeTicks::Now();
+ const base::TimeDelta delay = playout_time - now;
+
// Supply the input data and render the output data.
- source_->OnMoreData(dest, current_hardware_pending_bytes_ +
- frame_delay * params_.GetBytesPerFrame(),
- current_lost_frames_);
+ source_->OnMoreData(delay, now, current_lost_frames_, dest);
dest->Scale(volume_);
current_lost_frames_ = 0;
}
@@ -289,10 +291,10 @@ OSStatus AUHALStream::InputProc(
io_data);
}
-double AUHALStream::GetHardwareLatency() {
+base::TimeDelta AUHALStream::GetHardwareLatency() {
if (!audio_unit_ || device_ == kAudioObjectUnknown) {
DLOG(WARNING) << "AudioUnit is NULL or device ID is unknown";
- return 0.0;
+ return base::TimeDelta();
}
// Get audio unit latency.
@@ -307,7 +309,7 @@ double AUHALStream::GetHardwareLatency() {
&size);
if (result != noErr) {
OSSTATUS_DLOG(WARNING, result) << "Could not get AudioUnit latency";
- return 0.0;
+ return base::TimeDelta();
}
// Get output audio device latency.
@@ -328,34 +330,29 @@ double AUHALStream::GetHardwareLatency() {
&device_latency_frames);
if (result != noErr) {
OSSTATUS_DLOG(WARNING, result) << "Could not get audio device latency";
- return 0.0;
+ return base::TimeDelta();
}
- return static_cast<double>((audio_unit_latency_sec *
- output_format_.mSampleRate) + device_latency_frames);
+ int latency_frames = audio_unit_latency_sec * output_format_.mSampleRate +
+ device_latency_frames;
+
+ return AudioTimestampHelper::FramesToTime(latency_frames,
+ params_.sample_rate());
}
-double AUHALStream::GetPlayoutLatency(
+base::TimeTicks AUHALStream::GetPlayoutTime(
const AudioTimeStamp* output_time_stamp) {
- // Ensure mHostTime is valid.
+ // A platform bug has been observed where the platform sometimes reports that
+ // the next frames will be output at an invalid time or a time in the past.
+ // Because the target playout time cannot be invalid or in the past, return
+ // "now" in these cases.
if ((output_time_stamp->mFlags & kAudioTimeStampHostTimeValid) == 0)
- return 0;
-
- // Get the delay between the moment getting the callback and the scheduled
- // time stamp that tells when the data is going to be played out.
- UInt64 output_time_ns = AudioConvertHostTimeToNanos(
- output_time_stamp->mHostTime);
- UInt64 now_ns = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime());
-
- // Prevent overflow leading to huge delay information; occurs regularly on
- // the bots, probably less so in the wild.
- if (now_ns > output_time_ns)
- return 0;
-
- double delay_frames = static_cast<double>
- (1e-9 * (output_time_ns - now_ns) * output_format_.mSampleRate);
+ return base::TimeTicks::Now();
- return (delay_frames + hardware_latency_frames_);
+ return std::max(base::TimeTicks::FromMachAbsoluteTime(
+ output_time_stamp->mHostTime),
+ base::TimeTicks::Now()) +
+ hardware_latency_;
}
void AUHALStream::UpdatePlayoutTimestamp(const AudioTimeStamp* timestamp) {

Powered by Google App Engine
This is Rietveld 408576698