Index: media/audio/alsa/alsa_output.cc |
diff --git a/media/audio/alsa/alsa_output.cc b/media/audio/alsa/alsa_output.cc |
index 27ab0d1fd2002cd7d38ba86de355a1f8abd6f1f2..59cc3fc3b7ecbb921e8c253c6fbb37a7406cdf43 100644 |
--- a/media/audio/alsa/alsa_output.cc |
+++ b/media/audio/alsa/alsa_output.cc |
@@ -37,16 +37,19 @@ |
#include <stddef.h> |
#include <algorithm> |
+#include <utility> |
#include "base/bind.h" |
#include "base/logging.h" |
#include "base/memory/free_deleter.h" |
#include "base/stl_util.h" |
#include "base/threading/thread_task_runner_handle.h" |
+#include "base/time/default_tick_clock.h" |
#include "base/trace_event/trace_event.h" |
#include "media/audio/alsa/alsa_util.h" |
#include "media/audio/alsa/alsa_wrapper.h" |
#include "media/audio/alsa/audio_manager_alsa.h" |
+#include "media/base/audio_timestamp_helper.h" |
#include "media/base/channel_mixer.h" |
#include "media/base/data_buffer.h" |
#include "media/base/seekable_buffer.h" |
@@ -125,7 +128,7 @@ std::ostream& operator<<(std::ostream& os, |
case AlsaPcmOutputStream::kIsClosed: |
os << "kIsClosed"; |
break; |
- }; |
+ } |
return os; |
} |
@@ -151,7 +154,8 @@ AlsaPcmOutputStream::AlsaPcmOutputStream(const std::string& device_name, |
packet_size_(params.GetBytesPerBuffer()), |
latency_(std::max( |
base::TimeDelta::FromMicroseconds(kMinLatencyMicros), |
- FramesToTimeDelta(params.frames_per_buffer() * 2, sample_rate_))), |
+ AudioTimestampHelper::FramesToTime(params.frames_per_buffer() * 2, |
+ sample_rate_))), |
bytes_per_output_frame_(bytes_per_frame_), |
alsa_buffer_frames_(0), |
stop_stream_(false), |
@@ -164,6 +168,7 @@ AlsaPcmOutputStream::AlsaPcmOutputStream(const std::string& device_name, |
volume_(1.0f), |
source_callback_(NULL), |
audio_bus_(AudioBus::Create(params)), |
+ tick_clock_(new base::DefaultTickClock()), |
weak_factory_(this) { |
DCHECK(manager_->GetTaskRunner()->BelongsToCurrentThread()); |
DCHECK_EQ(audio_bus_->frames() * bytes_per_frame_, packet_size_); |
@@ -345,6 +350,12 @@ void AlsaPcmOutputStream::GetVolume(double* volume) { |
*volume = volume_; |
} |
+void AlsaPcmOutputStream::SetTickClockForTesting( |
+ std::unique_ptr<base::TickClock> tick_clock) { |
+ DCHECK(tick_clock); |
+ tick_clock_ = std::move(tick_clock); |
+} |
+ |
void AlsaPcmOutputStream::BufferPacket(bool* source_exhausted) { |
DCHECK(CalledOnValidThread()); |
@@ -361,13 +372,14 @@ void AlsaPcmOutputStream::BufferPacket(bool* source_exhausted) { |
// WritePacket() consumes only the current chunk of data. |
if (!buffer_->forward_bytes()) { |
// Before making a request to source for data we need to determine the |
- // delay (in bytes) for the requested data to be played. |
- const uint32_t hardware_delay = GetCurrentDelay() * bytes_per_frame_; |
+ // delay for the requested data to be played. |
+ const base::TimeDelta delay = |
+ AudioTimestampHelper::FramesToTime(GetCurrentDelay(), sample_rate_); |
scoped_refptr<media::DataBuffer> packet = |
new media::DataBuffer(packet_size_); |
- int frames_filled = RunDataCallback( |
- audio_bus_.get(), hardware_delay); |
+ int frames_filled = |
+ RunDataCallback(delay, tick_clock_->NowTicks(), audio_bus_.get()); |
size_t packet_size = frames_filled * bytes_per_frame_; |
DCHECK_LE(packet_size, packet_size_); |
@@ -516,7 +528,7 @@ void AlsaPcmOutputStream::ScheduleNextWrite(bool source_exhausted) { |
} else if (available_frames < kTargetFramesAvailable) { |
// Schedule the next write for the moment when the available buffer of the |
// sound card hits |kTargetFramesAvailable|. |
- next_fill_time = FramesToTimeDelta( |
+ next_fill_time = AudioTimestampHelper::FramesToTime( |
kTargetFramesAvailable - available_frames, sample_rate_); |
} else if (!source_exhausted) { |
// The sound card has |kTargetFramesAvailable| or more frames available. |
@@ -534,13 +546,6 @@ void AlsaPcmOutputStream::ScheduleNextWrite(bool source_exhausted) { |
next_fill_time); |
} |
-// static |
-base::TimeDelta AlsaPcmOutputStream::FramesToTimeDelta(int frames, |
- double sample_rate) { |
- return base::TimeDelta::FromMicroseconds( |
- frames * base::Time::kMicrosecondsPerSecond / sample_rate); |
-} |
- |
std::string AlsaPcmOutputStream::FindDeviceForChannels(uint32_t channels) { |
// Constants specified by the ALSA API for device hints. |
static const int kGetAllDevices = -1; |
@@ -777,12 +782,13 @@ AlsaPcmOutputStream::InternalState AlsaPcmOutputStream::state() { |
return state_; |
} |
-int AlsaPcmOutputStream::RunDataCallback(AudioBus* audio_bus, |
- uint32_t total_bytes_delay) { |
+int AlsaPcmOutputStream::RunDataCallback(base::TimeDelta delay, |
+ base::TimeTicks delay_timestamp, |
+ AudioBus* audio_bus) { |
TRACE_EVENT0("audio", "AlsaPcmOutputStream::RunDataCallback"); |
if (source_callback_) |
- return source_callback_->OnMoreData(audio_bus, total_bytes_delay, 0); |
+ return source_callback_->OnMoreData(delay, delay_timestamp, 0, audio_bus); |
return 0; |
} |