OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/audio/cras/cras_unified.h" | 5 #include "media/audio/cras/cras_unified.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/macros.h" | 8 #include "base/macros.h" |
9 #include "media/audio/cras/audio_manager_cras.h" | 9 #include "media/audio/cras/audio_manager_cras.h" |
10 | 10 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
54 : client_(NULL), | 54 : client_(NULL), |
55 stream_id_(0), | 55 stream_id_(0), |
56 params_(params), | 56 params_(params), |
57 bytes_per_frame_(0), | 57 bytes_per_frame_(0), |
58 is_playing_(false), | 58 is_playing_(false), |
59 volume_(1.0), | 59 volume_(1.0), |
60 manager_(manager), | 60 manager_(manager), |
61 source_callback_(NULL), | 61 source_callback_(NULL), |
62 stream_direction_(CRAS_STREAM_OUTPUT) { | 62 stream_direction_(CRAS_STREAM_OUTPUT) { |
63 DCHECK(manager_); | 63 DCHECK(manager_); |
64 DCHECK(params_.channels() > 0); | 64 DCHECK_GT(params_.channels(), 0); |
65 | 65 |
66 output_bus_ = AudioBus::Create(params); | 66 output_bus_ = AudioBus::Create(params); |
67 } | 67 } |
68 | 68 |
69 CrasUnifiedStream::~CrasUnifiedStream() { | 69 CrasUnifiedStream::~CrasUnifiedStream() { |
70 DCHECK(!is_playing_); | 70 DCHECK(!is_playing_); |
71 } | 71 } |
72 | 72 |
73 bool CrasUnifiedStream::Open() { | 73 bool CrasUnifiedStream::Open() { |
74 // Sanity check input values. | 74 // Sanity check input values. |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
226 if (!client_) | 226 if (!client_) |
227 return; | 227 return; |
228 volume_ = static_cast<float>(volume); | 228 volume_ = static_cast<float>(volume); |
229 cras_client_set_stream_volume(client_, stream_id_, volume_); | 229 cras_client_set_stream_volume(client_, stream_id_, volume_); |
230 } | 230 } |
231 | 231 |
232 void CrasUnifiedStream::GetVolume(double* volume) { | 232 void CrasUnifiedStream::GetVolume(double* volume) { |
233 *volume = volume_; | 233 *volume = volume_; |
234 } | 234 } |
235 | 235 |
236 uint32_t CrasUnifiedStream::GetBytesLatency(const struct timespec& latency_ts) { | |
237 uint32_t latency_usec; | |
238 | |
239 // Treat negative latency (if we are too slow to render) as 0. | |
240 if (latency_ts.tv_sec < 0 || latency_ts.tv_nsec < 0) { | |
241 latency_usec = 0; | |
242 } else { | |
243 latency_usec = (latency_ts.tv_sec * base::Time::kMicrosecondsPerSecond) + | |
244 latency_ts.tv_nsec / base::Time::kNanosecondsPerMicrosecond; | |
245 } | |
246 | |
247 double frames_latency = | |
248 latency_usec * params_.sample_rate() / base::Time::kMicrosecondsPerSecond; | |
249 | |
250 return static_cast<unsigned int>(frames_latency * bytes_per_frame_); | |
251 } | |
252 | |
253 // Static callback asking for samples. | 236 // Static callback asking for samples. |
254 int CrasUnifiedStream::UnifiedCallback(cras_client* client, | 237 int CrasUnifiedStream::UnifiedCallback(cras_client* client, |
255 cras_stream_id_t stream_id, | 238 cras_stream_id_t stream_id, |
256 uint8_t* input_samples, | 239 uint8_t* input_samples, |
257 uint8_t* output_samples, | 240 uint8_t* output_samples, |
258 unsigned int frames, | 241 unsigned int frames, |
259 const timespec* input_ts, | 242 const timespec* input_ts, |
260 const timespec* output_ts, | 243 const timespec* output_ts, |
261 void* arg) { | 244 void* arg) { |
262 CrasUnifiedStream* me = static_cast<CrasUnifiedStream*>(arg); | 245 CrasUnifiedStream* me = static_cast<CrasUnifiedStream*>(arg); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
298 | 281 |
299 uint32_t CrasUnifiedStream::WriteAudio(size_t frames, | 282 uint32_t CrasUnifiedStream::WriteAudio(size_t frames, |
300 uint8_t* buffer, | 283 uint8_t* buffer, |
301 const timespec* sample_ts) { | 284 const timespec* sample_ts) { |
302 DCHECK_EQ(frames, static_cast<size_t>(output_bus_->frames())); | 285 DCHECK_EQ(frames, static_cast<size_t>(output_bus_->frames())); |
303 | 286 |
304 // Determine latency and pass that on to the source. | 287 // Determine latency and pass that on to the source. |
305 timespec latency_ts = {0, 0}; | 288 timespec latency_ts = {0, 0}; |
306 cras_client_calc_playback_latency(sample_ts, &latency_ts); | 289 cras_client_calc_playback_latency(sample_ts, &latency_ts); |
307 | 290 |
291 // Treat negative latency (if we are too slow to render) as 0. | |
292 const base::TimeDelta delay = latency_ts.tv_sec > 0 && latency_ts.tv_nsec > 0 | |
miu
2016/09/28 23:04:41
Is it possible for tv_sec to be greater than zero,
jameswest
2016/09/29 00:52:24
That shouldn't happen, and even if it does, using
| |
293 ? base::TimeDelta::FromTimeSpec(latency_ts) | |
294 : base::TimeDelta(); | |
295 | |
308 int frames_filled = source_callback_->OnMoreData( | 296 int frames_filled = source_callback_->OnMoreData( |
309 output_bus_.get(), GetBytesLatency(latency_ts), 0); | 297 delay, base::TimeTicks::Now(), 0, output_bus_.get()); |
310 | 298 |
311 // Note: If this ever changes to output raw float the data must be clipped and | 299 // Note: If this ever changes to output raw float the data must be clipped and |
312 // sanitized since it may come from an untrusted source such as NaCl. | 300 // sanitized since it may come from an untrusted source such as NaCl. |
313 output_bus_->ToInterleaved( | 301 output_bus_->ToInterleaved( |
314 frames_filled, bytes_per_frame_ / params_.channels(), buffer); | 302 frames_filled, bytes_per_frame_ / params_.channels(), buffer); |
315 | 303 |
316 return frames_filled; | 304 return frames_filled; |
317 } | 305 } |
318 | 306 |
319 void CrasUnifiedStream::NotifyStreamError(int err) { | 307 void CrasUnifiedStream::NotifyStreamError(int err) { |
320 // This will remove the stream from the client. | 308 // This will remove the stream from the client. |
321 if (source_callback_) | 309 if (source_callback_) |
322 source_callback_->OnError(this); | 310 source_callback_->OnError(this); |
323 } | 311 } |
324 | 312 |
325 } // namespace media | 313 } // namespace media |
OLD | NEW |