Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "chromecast/media/audio/cast_audio_mixer.h" | 5 #include "chromecast/media/audio/cast_audio_mixer.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | |
| 7 #include "chromecast/media/audio/cast_audio_manager.h" | 8 #include "chromecast/media/audio/cast_audio_manager.h" |
| 8 #include "chromecast/media/audio/cast_audio_output_stream.h" | 9 #include "chromecast/media/audio/cast_audio_output_stream.h" |
| 9 #include "media/base/channel_layout.h" | 10 #include "media/base/channel_layout.h" |
| 10 | 11 |
| 11 namespace { | 12 namespace { |
| 12 const int kBitsPerSample = 16; | 13 const int kBitsPerSample = 16; |
| 13 const int kFramesPerBuffer = 1024; | 14 const int kFramesPerBuffer = 1024; |
| 14 const int kSampleRate = 48000; | 15 const int kSampleRate = 48000; |
| 15 } // namespace | 16 } // namespace |
| 16 | 17 |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 133 DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread()); | 134 DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread()); |
| 134 | 135 |
| 135 *volume = volume_; | 136 *volume = volume_; |
| 136 } | 137 } |
| 137 | 138 |
| 138 // ::media::AudioConverter::InputCallback implementation | 139 // ::media::AudioConverter::InputCallback implementation |
| 139 double ProvideInput(::media::AudioBus* audio_bus, | 140 double ProvideInput(::media::AudioBus* audio_bus, |
| 140 uint32_t frames_delayed) override { | 141 uint32_t frames_delayed) override { |
| 141 DCHECK(source_callback_); | 142 DCHECK(source_callback_); |
| 142 | 143 |
| 143 uint32_t bytes_delay = frames_delayed * input_params_.GetBytesPerFrame(); | 144 const base::TimeDelta delay = base::TimeDelta::FromMicroseconds( |
| 144 source_callback_->OnMoreData(audio_bus, bytes_delay, 0); | 145 frames_delayed * base::Time::kMicrosecondsPerSecond / |
| 146 input_params_.sample_rate()); | |
|
chcunningham
2016/09/23 20:53:29
int division
jameswest
2016/09/29 00:52:24
Moved to utility function.
| |
| 147 source_callback_->OnMoreData(delay, base::TimeTicks::Now(), 0, audio_bus); | |
| 145 return volume_; | 148 return volume_; |
| 146 } | 149 } |
| 147 | 150 |
| 148 CastAudioManager* const audio_manager_; | 151 CastAudioManager* const audio_manager_; |
| 149 CastAudioMixer* const audio_mixer_; | 152 CastAudioMixer* const audio_mixer_; |
| 150 | 153 |
| 151 std::unique_ptr<ResamplerProxy> proxy_; | 154 std::unique_ptr<ResamplerProxy> proxy_; |
| 152 AudioSourceCallback* source_callback_; | 155 AudioSourceCallback* source_callback_; |
| 153 const ::media::AudioParameters input_params_; | 156 const ::media::AudioParameters input_params_; |
| 154 const ::media::AudioParameters output_params_; | 157 const ::media::AudioParameters output_params_; |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 238 void CastAudioMixer::RemoveInput( | 241 void CastAudioMixer::RemoveInput( |
| 239 ::media::AudioConverter::InputCallback* input_callback) { | 242 ::media::AudioConverter::InputCallback* input_callback) { |
| 240 DCHECK(thread_checker_.CalledOnValidThread()); | 243 DCHECK(thread_checker_.CalledOnValidThread()); |
| 241 | 244 |
| 242 mixer_->RemoveInput(input_callback); | 245 mixer_->RemoveInput(input_callback); |
| 243 // Stop |output_stream_| if there are no inputs and the stream is running. | 246 // Stop |output_stream_| if there are no inputs and the stream is running. |
| 244 if (mixer_->empty() && output_stream_) | 247 if (mixer_->empty() && output_stream_) |
| 245 output_stream_->Stop(); | 248 output_stream_->Stop(); |
| 246 } | 249 } |
| 247 | 250 |
| 248 int CastAudioMixer::OnMoreData(::media::AudioBus* dest, | 251 int CastAudioMixer::OnMoreData(base::TimeDelta delay, |
| 249 uint32_t total_bytes_delay, | 252 base::TimeTicks /* delay_timestamp */, |
| 250 uint32_t frames_skipped) { | 253 int /* prior_frames_skipped */, |
| 254 ::media::AudioBus* dest) { | |
| 251 DCHECK(thread_checker_.CalledOnValidThread()); | 255 DCHECK(thread_checker_.CalledOnValidThread()); |
| 252 | 256 |
| 253 uint32_t frames_delayed = | 257 uint32_t frames_delayed = delay.InSecondsF() * output_params_.sample_rate(); |
|
chcunningham
2016/09/23 20:53:29
What do you think about delay in frames instead of
miu
2016/09/28 23:04:41
I'm torn between both, myself. But, overall, I sup
jameswest
2016/09/29 00:52:24
I'm personally ambivalent. One thing I'll add is t
| |
| 254 total_bytes_delay / output_params_.GetBytesPerFrame(); | |
| 255 mixer_->ConvertWithDelay(frames_delayed, dest); | 258 mixer_->ConvertWithDelay(frames_delayed, dest); |
| 256 return dest->frames(); | 259 return dest->frames(); |
| 257 } | 260 } |
| 258 | 261 |
| 259 void CastAudioMixer::OnError(::media::AudioOutputStream* stream) { | 262 void CastAudioMixer::OnError(::media::AudioOutputStream* stream) { |
| 260 DCHECK(thread_checker_.CalledOnValidThread()); | 263 DCHECK(thread_checker_.CalledOnValidThread()); |
| 261 DCHECK(output_stream_ == stream); | 264 DCHECK(output_stream_ == stream); |
| 262 | 265 |
| 263 // TODO(ameyak): Add rate limiting. If errors are seen to occur | 266 // TODO(ameyak): Add rate limiting. If errors are seen to occur |
| 264 // above some arbitrary value in a specified amount | 267 // above some arbitrary value in a specified amount |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 275 // Assume error state | 278 // Assume error state |
| 276 output_stream_->Close(); | 279 output_stream_->Close(); |
| 277 output_stream_ = nullptr; | 280 output_stream_ = nullptr; |
| 278 error_ = true; | 281 error_ = true; |
| 279 for (auto it = proxy_streams_.begin(); it != proxy_streams_.end(); it++) | 282 for (auto it = proxy_streams_.begin(); it != proxy_streams_.end(); it++) |
| 280 (*it)->OnError(); | 283 (*it)->OnError(); |
| 281 } | 284 } |
| 282 } | 285 } |
| 283 | 286 |
| 284 } // namespace media | 287 } // namespace media |
| 285 } // namespace chromecast | 288 } // namespace chromecast |
| OLD | NEW |