Chromium Code Reviews| 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) { | 236 base::TimeTicks CrasUnifiedStream::GetTargetPlayoutTime( |
| 237 uint32_t latency_usec; | 237 const struct timespec& latency_ts) { |
| 238 | |
| 239 // Treat negative latency (if we are too slow to render) as 0. | 238 // Treat negative latency (if we are too slow to render) as 0. |
| 240 if (latency_ts.tv_sec < 0 || latency_ts.tv_nsec < 0) { | 239 if (latency_ts.tv_sec < 0 || latency_ts.tv_nsec < 0) { |
| 241 latency_usec = 0; | 240 return base::TimeTicks::Now(); |
| 242 } else { | |
| 243 latency_usec = (latency_ts.tv_sec * base::Time::kMicrosecondsPerSecond) + | |
| 244 latency_ts.tv_nsec / base::Time::kNanosecondsPerMicrosecond; | |
| 245 } | 241 } |
| 246 | 242 |
| 247 double frames_latency = | 243 return base::TimeTicks::Now() + base::TimeDelta::FromTimeSpec(latency_ts); |
| 248 latency_usec * params_.sample_rate() / base::Time::kMicrosecondsPerSecond; | |
| 249 | |
| 250 return static_cast<unsigned int>(frames_latency * bytes_per_frame_); | |
| 251 } | 244 } |
| 252 | 245 |
| 253 // Static callback asking for samples. | 246 // Static callback asking for samples. |
| 254 int CrasUnifiedStream::UnifiedCallback(cras_client* client, | 247 int CrasUnifiedStream::UnifiedCallback(cras_client* client, |
| 255 cras_stream_id_t stream_id, | 248 cras_stream_id_t stream_id, |
| 256 uint8_t* input_samples, | 249 uint8_t* input_samples, |
| 257 uint8_t* output_samples, | 250 uint8_t* output_samples, |
| 258 unsigned int frames, | 251 unsigned int frames, |
| 259 const timespec* input_ts, | 252 const timespec* input_ts, |
| 260 const timespec* output_ts, | 253 const timespec* output_ts, |
|
jameswest
2016/09/16 21:59:43
Do you know if |output_ts| is target playout time?
miu
2016/09/16 23:38:28
That would be my interpretation (that output_ts is
jameswest
2016/09/19 23:32:36
I couldn't find anything with a quick search, so I
| |
| 261 void* arg) { | 254 void* arg) { |
| 262 CrasUnifiedStream* me = static_cast<CrasUnifiedStream*>(arg); | 255 CrasUnifiedStream* me = static_cast<CrasUnifiedStream*>(arg); |
| 263 return me->DispatchCallback(frames, | 256 return me->DispatchCallback(frames, |
| 264 input_samples, | 257 input_samples, |
| 265 output_samples, | 258 output_samples, |
| 266 input_ts, | 259 input_ts, |
| 267 output_ts); | 260 output_ts); |
| 268 } | 261 } |
| 269 | 262 |
| 270 // Static callback for stream errors. | 263 // Static callback for stream errors. |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 299 uint32_t CrasUnifiedStream::WriteAudio(size_t frames, | 292 uint32_t CrasUnifiedStream::WriteAudio(size_t frames, |
| 300 uint8_t* buffer, | 293 uint8_t* buffer, |
| 301 const timespec* sample_ts) { | 294 const timespec* sample_ts) { |
| 302 DCHECK_EQ(frames, static_cast<size_t>(output_bus_->frames())); | 295 DCHECK_EQ(frames, static_cast<size_t>(output_bus_->frames())); |
| 303 | 296 |
| 304 // Determine latency and pass that on to the source. | 297 // Determine latency and pass that on to the source. |
| 305 timespec latency_ts = {0, 0}; | 298 timespec latency_ts = {0, 0}; |
| 306 cras_client_calc_playback_latency(sample_ts, &latency_ts); | 299 cras_client_calc_playback_latency(sample_ts, &latency_ts); |
| 307 | 300 |
| 308 int frames_filled = source_callback_->OnMoreData( | 301 int frames_filled = source_callback_->OnMoreData( |
| 309 output_bus_.get(), GetBytesLatency(latency_ts), 0); | 302 GetTargetPlayoutTime(latency_ts), 0, output_bus_.get()); |
| 310 | 303 |
| 311 // Note: If this ever changes to output raw float the data must be clipped and | 304 // 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. | 305 // sanitized since it may come from an untrusted source such as NaCl. |
| 313 output_bus_->ToInterleaved( | 306 output_bus_->ToInterleaved( |
| 314 frames_filled, bytes_per_frame_ / params_.channels(), buffer); | 307 frames_filled, bytes_per_frame_ / params_.channels(), buffer); |
| 315 | 308 |
| 316 return frames_filled; | 309 return frames_filled; |
| 317 } | 310 } |
| 318 | 311 |
| 319 void CrasUnifiedStream::NotifyStreamError(int err) { | 312 void CrasUnifiedStream::NotifyStreamError(int err) { |
| 320 // This will remove the stream from the client. | 313 // This will remove the stream from the client. |
| 321 if (source_callback_) | 314 if (source_callback_) |
| 322 source_callback_->OnError(this); | 315 source_callback_->OnError(this); |
| 323 } | 316 } |
| 324 | 317 |
| 325 } // namespace media | 318 } // namespace media |
| OLD | NEW |