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" |
| 10 #include "media/base/audio_timestamp_helper.h" |
9 #include "media/base/channel_layout.h" | 11 #include "media/base/channel_layout.h" |
10 | 12 |
11 namespace { | 13 namespace { |
12 const int kBitsPerSample = 16; | 14 const int kBitsPerSample = 16; |
13 const int kFramesPerBuffer = 1024; | 15 const int kFramesPerBuffer = 1024; |
14 const int kSampleRate = 48000; | 16 const int kSampleRate = 48000; |
15 } // namespace | 17 } // namespace |
16 | 18 |
17 namespace chromecast { | 19 namespace chromecast { |
18 namespace media { | 20 namespace media { |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread()); | 135 DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread()); |
134 | 136 |
135 *volume = volume_; | 137 *volume = volume_; |
136 } | 138 } |
137 | 139 |
138 // ::media::AudioConverter::InputCallback implementation | 140 // ::media::AudioConverter::InputCallback implementation |
139 double ProvideInput(::media::AudioBus* audio_bus, | 141 double ProvideInput(::media::AudioBus* audio_bus, |
140 uint32_t frames_delayed) override { | 142 uint32_t frames_delayed) override { |
141 DCHECK(source_callback_); | 143 DCHECK(source_callback_); |
142 | 144 |
143 uint32_t bytes_delay = frames_delayed * input_params_.GetBytesPerFrame(); | 145 const base::TimeDelta delay = ::media::AudioTimestampHelper::FramesToTime( |
144 source_callback_->OnMoreData(audio_bus, bytes_delay, 0); | 146 frames_delayed, input_params_.sample_rate()); |
| 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 = ::media::AudioTimestampHelper::TimeToFrames( |
254 total_bytes_delay / output_params_.GetBytesPerFrame(); | 258 delay, output_params_.sample_rate()); |
255 mixer_->ConvertWithDelay(frames_delayed, dest); | 259 mixer_->ConvertWithDelay(frames_delayed, dest); |
256 return dest->frames(); | 260 return dest->frames(); |
257 } | 261 } |
258 | 262 |
259 void CastAudioMixer::OnError(::media::AudioOutputStream* stream) { | 263 void CastAudioMixer::OnError(::media::AudioOutputStream* stream) { |
260 DCHECK(thread_checker_.CalledOnValidThread()); | 264 DCHECK(thread_checker_.CalledOnValidThread()); |
261 DCHECK(output_stream_ == stream); | 265 DCHECK(output_stream_ == stream); |
262 | 266 |
263 // TODO(ameyak): Add rate limiting. If errors are seen to occur | 267 // TODO(ameyak): Add rate limiting. If errors are seen to occur |
264 // above some arbitrary value in a specified amount | 268 // above some arbitrary value in a specified amount |
(...skipping 10 matching lines...) Expand all Loading... |
275 // Assume error state | 279 // Assume error state |
276 output_stream_->Close(); | 280 output_stream_->Close(); |
277 output_stream_ = nullptr; | 281 output_stream_ = nullptr; |
278 error_ = true; | 282 error_ = true; |
279 for (auto it = proxy_streams_.begin(); it != proxy_streams_.end(); it++) | 283 for (auto it = proxy_streams_.begin(); it != proxy_streams_.end(); it++) |
280 (*it)->OnError(); | 284 (*it)->OnError(); |
281 } | 285 } |
282 } | 286 } |
283 | 287 |
284 } // namespace media | 288 } // namespace media |
285 } // namespace chromecast | 289 } // namespace chromecast |
OLD | NEW |