OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/cma/backend/alsa/stream_mixer_alsa_input_impl.h" | 5 #include "chromecast/media/cma/backend/alsa/stream_mixer_alsa_input_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 StreamMixerAlsaInput::Delegate* delegate, | 62 StreamMixerAlsaInput::Delegate* delegate, |
63 int input_samples_per_second, | 63 int input_samples_per_second, |
64 bool primary, | 64 bool primary, |
65 StreamMixerAlsa* mixer) | 65 StreamMixerAlsa* mixer) |
66 : delegate_(delegate), | 66 : delegate_(delegate), |
67 input_samples_per_second_(input_samples_per_second), | 67 input_samples_per_second_(input_samples_per_second), |
68 primary_(primary), | 68 primary_(primary), |
69 mixer_(mixer), | 69 mixer_(mixer), |
70 mixer_task_runner_(mixer_->task_runner()), | 70 mixer_task_runner_(mixer_->task_runner()), |
71 caller_task_runner_(base::ThreadTaskRunnerHandle::Get()), | 71 caller_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
| 72 resample_ratio_(1.0), |
72 state_(kStateUninitialized), | 73 state_(kStateUninitialized), |
73 volume_multiplier_(1.0f), | 74 volume_multiplier_(1.0f), |
74 queued_frames_(0), | 75 queued_frames_(0), |
75 queued_frames_including_resampler_(0), | 76 queued_frames_including_resampler_(0), |
76 current_buffer_offset_(0), | 77 current_buffer_offset_(0), |
77 max_queued_frames_(kMaxInputQueueUs * input_samples_per_second / | 78 max_queued_frames_(kMaxInputQueueUs * input_samples_per_second / |
78 base::Time::kMicrosecondsPerSecond), | 79 base::Time::kMicrosecondsPerSecond), |
79 fade_frames_remaining_(0), | 80 fade_frames_remaining_(0), |
80 fade_out_frames_total_(0), | 81 fade_out_frames_total_(0), |
81 zeroed_frames_(0), | 82 zeroed_frames_(0), |
82 weak_factory_(this) { | 83 weak_factory_(this) { |
| 84 LOG(INFO) << "Create " << this; |
83 DCHECK(delegate_); | 85 DCHECK(delegate_); |
84 DCHECK(mixer_); | 86 DCHECK(mixer_); |
85 weak_this_ = weak_factory_.GetWeakPtr(); | 87 weak_this_ = weak_factory_.GetWeakPtr(); |
86 } | 88 } |
87 | 89 |
88 StreamMixerAlsaInputImpl::~StreamMixerAlsaInputImpl() { | 90 StreamMixerAlsaInputImpl::~StreamMixerAlsaInputImpl() { |
| 91 LOG(INFO) << "Destroy " << this; |
89 DCHECK(mixer_task_runner_->BelongsToCurrentThread()); | 92 DCHECK(mixer_task_runner_->BelongsToCurrentThread()); |
90 } | 93 } |
91 | 94 |
92 int StreamMixerAlsaInputImpl::input_samples_per_second() const { | 95 int StreamMixerAlsaInputImpl::input_samples_per_second() const { |
93 return input_samples_per_second_; | 96 return input_samples_per_second_; |
94 } | 97 } |
95 | 98 |
96 float StreamMixerAlsaInputImpl::volume_multiplier() const { | 99 float StreamMixerAlsaInputImpl::volume_multiplier() const { |
97 return volume_multiplier_; | 100 return volume_multiplier_; |
98 } | 101 } |
99 | 102 |
100 bool StreamMixerAlsaInputImpl::primary() const { | 103 bool StreamMixerAlsaInputImpl::primary() const { |
101 return primary_; | 104 return primary_; |
102 } | 105 } |
103 | 106 |
104 bool StreamMixerAlsaInputImpl::IsDeleting() const { | 107 bool StreamMixerAlsaInputImpl::IsDeleting() const { |
105 DCHECK(mixer_task_runner_->BelongsToCurrentThread()); | 108 DCHECK(mixer_task_runner_->BelongsToCurrentThread()); |
106 return (state_ == kStateFinalFade || state_ == kStateDeleted); | 109 return (state_ == kStateFinalFade || state_ == kStateDeleted); |
107 } | 110 } |
108 | 111 |
109 void StreamMixerAlsaInputImpl::Initialize( | 112 void StreamMixerAlsaInputImpl::Initialize( |
110 const MediaPipelineBackendAlsa::RenderingDelay& mixer_rendering_delay) { | 113 const MediaPipelineBackendAlsa::RenderingDelay& mixer_rendering_delay) { |
111 DCHECK(mixer_task_runner_->BelongsToCurrentThread()); | 114 DCHECK(mixer_task_runner_->BelongsToCurrentThread()); |
112 DCHECK(!IsDeleting()); | 115 DCHECK(!IsDeleting()); |
113 if (mixer_->output_samples_per_second() != input_samples_per_second_) { | 116 if (mixer_->output_samples_per_second() != input_samples_per_second_) { |
114 double resample_ratio = static_cast<double>(input_samples_per_second_) / | 117 resample_ratio_ = static_cast<double>(input_samples_per_second_) / |
115 mixer_->output_samples_per_second(); | 118 mixer_->output_samples_per_second(); |
116 resampler_.reset(new ::media::MultiChannelResampler( | 119 resampler_.reset(new ::media::MultiChannelResampler( |
117 kNumOutputChannels, resample_ratio, kDefaultReadSize, | 120 kNumOutputChannels, resample_ratio_, kDefaultReadSize, |
118 base::Bind(&StreamMixerAlsaInputImpl::ReadCB, base::Unretained(this)))); | 121 base::Bind(&StreamMixerAlsaInputImpl::ReadCB, base::Unretained(this)))); |
119 resampler_->PrimeWithSilence(); | 122 resampler_->PrimeWithSilence(); |
120 } | 123 } |
121 mixer_rendering_delay_ = mixer_rendering_delay; | 124 mixer_rendering_delay_ = mixer_rendering_delay; |
122 fade_out_frames_total_ = NormalFadeFrames(); | 125 fade_out_frames_total_ = NormalFadeFrames(); |
123 fade_frames_remaining_ = NormalFadeFrames(); | 126 fade_frames_remaining_ = NormalFadeFrames(); |
124 } | 127 } |
125 | 128 |
126 void StreamMixerAlsaInputImpl::PreventDelegateCalls() { | 129 void StreamMixerAlsaInputImpl::PreventDelegateCalls() { |
127 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 130 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
(...skipping 11 matching lines...) Expand all Loading... |
139 delete_cb_ = delete_cb; | 142 delete_cb_ = delete_cb; |
140 if (state_ != kStateNormalPlayback && state_ != kStateFadingOut && | 143 if (state_ != kStateNormalPlayback && state_ != kStateFadingOut && |
141 state_ != kStateGotEos) { | 144 state_ != kStateGotEos) { |
142 DeleteThis(); | 145 DeleteThis(); |
143 return; | 146 return; |
144 } | 147 } |
145 | 148 |
146 { | 149 { |
147 base::AutoLock lock(queue_lock_); | 150 base::AutoLock lock(queue_lock_); |
148 if (state_ == kStateGotEos) { | 151 if (state_ == kStateGotEos) { |
149 fade_out_frames_total_ = queued_frames_including_resampler_; | 152 fade_out_frames_total_ = |
150 fade_frames_remaining_ = queued_frames_including_resampler_; | 153 queued_frames_including_resampler_ / resample_ratio_; |
| 154 fade_frames_remaining_ = |
| 155 queued_frames_including_resampler_ / resample_ratio_; |
151 } else if (state_ == kStateNormalPlayback) { | 156 } else if (state_ == kStateNormalPlayback) { |
152 fade_out_frames_total_ = | 157 fade_out_frames_total_ = |
153 std::min(static_cast<int>(queued_frames_including_resampler_), | 158 std::min(static_cast<int>(queued_frames_including_resampler_ / |
| 159 resample_ratio_), |
154 NormalFadeFrames()); | 160 NormalFadeFrames()); |
155 fade_frames_remaining_ = fade_out_frames_total_; | 161 fade_frames_remaining_ = fade_out_frames_total_; |
156 } | 162 } |
157 } | 163 } |
158 | 164 |
159 state_ = kStateFinalFade; | 165 state_ = kStateFinalFade; |
160 if (fade_frames_remaining_ == 0) { | 166 if (fade_frames_remaining_ == 0) { |
161 DeleteThis(); | 167 DeleteThis(); |
162 } else { | 168 } else { |
163 // Tell the mixer that some more data might be available (since when fading | 169 // Tell the mixer that some more data might be available (since when fading |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 const MediaPipelineBackendAlsa::RenderingDelay& delay) { | 220 const MediaPipelineBackendAlsa::RenderingDelay& delay) { |
215 RUN_ON_CALLER_THREAD(PostPcmCallback, delay); | 221 RUN_ON_CALLER_THREAD(PostPcmCallback, delay); |
216 delegate_->OnWritePcmCompletion(MediaPipelineBackendAlsa::kBufferSuccess, | 222 delegate_->OnWritePcmCompletion(MediaPipelineBackendAlsa::kBufferSuccess, |
217 delay); | 223 delay); |
218 } | 224 } |
219 | 225 |
220 void StreamMixerAlsaInputImpl::DidQueueData(bool end_of_stream) { | 226 void StreamMixerAlsaInputImpl::DidQueueData(bool end_of_stream) { |
221 RUN_ON_MIXER_THREAD(DidQueueData, end_of_stream); | 227 RUN_ON_MIXER_THREAD(DidQueueData, end_of_stream); |
222 DCHECK(!IsDeleting()); | 228 DCHECK(!IsDeleting()); |
223 if (end_of_stream) { | 229 if (end_of_stream) { |
| 230 LOG(INFO) << "End of stream for " << this; |
224 state_ = kStateGotEos; | 231 state_ = kStateGotEos; |
225 } else if (state_ == kStateUninitialized) { | 232 } else if (state_ == kStateUninitialized) { |
226 state_ = kStateNormalPlayback; | 233 state_ = kStateNormalPlayback; |
227 } | 234 } |
228 mixer_->OnFramesQueued(); | 235 mixer_->OnFramesQueued(); |
229 } | 236 } |
230 | 237 |
231 void StreamMixerAlsaInputImpl::AfterWriteFrames( | 238 void StreamMixerAlsaInputImpl::AfterWriteFrames( |
232 const MediaPipelineBackendAlsa::RenderingDelay& mixer_rendering_delay) { | 239 const MediaPipelineBackendAlsa::RenderingDelay& mixer_rendering_delay) { |
233 DCHECK(mixer_task_runner_->BelongsToCurrentThread()); | 240 DCHECK(mixer_task_runner_->BelongsToCurrentThread()); |
234 double resampler_queued_frames = | 241 double resampler_queued_frames = |
235 (resampler_ ? resampler_->BufferedFrames() : 0); | 242 (resampler_ ? resampler_->BufferedFrames() : 0); |
236 | 243 |
237 bool queued_more_data = false; | 244 bool queued_more_data = false; |
238 MediaPipelineBackendAlsa::RenderingDelay total_delay; | 245 MediaPipelineBackendAlsa::RenderingDelay total_delay; |
239 { | 246 { |
240 base::AutoLock lock(queue_lock_); | 247 base::AutoLock lock(queue_lock_); |
241 mixer_rendering_delay_ = mixer_rendering_delay; | 248 mixer_rendering_delay_ = mixer_rendering_delay; |
242 queued_frames_ = 0; | 249 queued_frames_ = 0; |
243 for (const auto& data : queue_) | 250 for (const auto& data : queue_) { |
244 queued_frames_ += | 251 queued_frames_ += |
245 data->data_size() / (kNumOutputChannels * sizeof(float)); | 252 data->data_size() / (kNumOutputChannels * sizeof(float)); |
| 253 } |
246 queued_frames_ -= current_buffer_offset_; | 254 queued_frames_ -= current_buffer_offset_; |
247 DCHECK_GE(queued_frames_, 0); | 255 DCHECK_GE(queued_frames_, 0); |
248 queued_frames_including_resampler_ = | 256 queued_frames_including_resampler_ = |
249 queued_frames_ + resampler_queued_frames; | 257 queued_frames_ + resampler_queued_frames; |
250 | 258 |
251 if (pending_data_ && queued_frames_ < max_queued_frames_) { | 259 if (pending_data_ && queued_frames_ < max_queued_frames_) { |
252 scoped_refptr<DecoderBufferBase> data = pending_data_; | 260 scoped_refptr<DecoderBufferBase> data = pending_data_; |
253 pending_data_ = nullptr; | 261 pending_data_ = nullptr; |
254 total_delay = QueueData(data); | 262 total_delay = QueueData(data); |
255 queued_more_data = true; | 263 queued_more_data = true; |
256 if (data->end_of_stream()) | 264 if (data->end_of_stream()) { |
| 265 LOG(INFO) << "End of stream for " << this; |
257 state_ = kStateGotEos; | 266 state_ = kStateGotEos; |
| 267 } |
258 } | 268 } |
259 } | 269 } |
260 | 270 |
261 if (queued_more_data) | 271 if (queued_more_data) |
262 PostPcmCallback(total_delay); | 272 PostPcmCallback(total_delay); |
263 } | 273 } |
264 | 274 |
265 int StreamMixerAlsaInputImpl::MaxReadSize() { | 275 int StreamMixerAlsaInputImpl::MaxReadSize() { |
266 DCHECK(mixer_task_runner_->BelongsToCurrentThread()); | 276 DCHECK(mixer_task_runner_->BelongsToCurrentThread()); |
267 if (state_ == kStatePaused || state_ == kStateDeleted) | 277 if (state_ == kStatePaused || state_ == kStateDeleted) |
268 return kPausedReadSamples; | 278 return kPausedReadSamples; |
269 if (state_ == kStateFinalFade) | 279 if (state_ == kStateFinalFade) |
270 return fade_frames_remaining_; | 280 return fade_frames_remaining_; |
271 | 281 |
272 int queued_frames; | 282 int queued_frames; |
273 { | 283 { |
274 base::AutoLock lock(queue_lock_); | 284 base::AutoLock lock(queue_lock_); |
275 if (state_ == kStateGotEos) | 285 if (state_ == kStateGotEos) |
276 return std::max(static_cast<int>(queued_frames_including_resampler_), | 286 return std::max(static_cast<int>(queued_frames_including_resampler_ / |
| 287 resample_ratio_), |
277 kDefaultReadSize); | 288 kDefaultReadSize); |
278 queued_frames = queued_frames_; | 289 queued_frames = queued_frames_; |
279 } | 290 } |
280 | 291 |
281 int available_frames = 0; | 292 int available_frames = 0; |
282 if (resampler_) { | 293 if (resampler_) { |
283 int num_chunks = queued_frames / kDefaultReadSize; | 294 int num_chunks = queued_frames / kDefaultReadSize; |
284 available_frames = resampler_->ChunkSize() * num_chunks; | 295 available_frames = resampler_->ChunkSize() * num_chunks; |
285 } else { | 296 } else { |
286 available_frames = queued_frames; | 297 available_frames = queued_frames; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 if (buffer) { | 372 if (buffer) { |
362 const float* buffer_samples = | 373 const float* buffer_samples = |
363 reinterpret_cast<const float*>(buffer->data()); | 374 reinterpret_cast<const float*>(buffer->data()); |
364 for (int i = 0; i < kNumOutputChannels; ++i) { | 375 for (int i = 0; i < kNumOutputChannels; ++i) { |
365 const float* buffer_channel = buffer_samples + (buffer_frames * i); | 376 const float* buffer_channel = buffer_samples + (buffer_frames * i); |
366 memcpy(output->channel(i) + frames_filled, | 377 memcpy(output->channel(i) + frames_filled, |
367 buffer_channel + buffer_offset, frames_to_copy * sizeof(float)); | 378 buffer_channel + buffer_offset, frames_to_copy * sizeof(float)); |
368 } | 379 } |
369 frames_left -= frames_to_copy; | 380 frames_left -= frames_to_copy; |
370 frames_filled += frames_to_copy; | 381 frames_filled += frames_to_copy; |
371 LOG_IF(WARNING, zeroed_frames_ > 0) << "Filled a total of " | 382 LOG_IF(WARNING, state_ != kStateFinalFade && zeroed_frames_ > 0) |
372 << zeroed_frames_ << " frames with 0"; | 383 << "Filled a total of " << zeroed_frames_ << " frames with 0"; |
373 zeroed_frames_ = 0; | 384 zeroed_frames_ = 0; |
374 } else { | 385 } else { |
375 // No data left in queue; fill remaining frames with zeros. | 386 // No data left in queue; fill remaining frames with zeros. |
376 LOG_IF(WARNING, zeroed_frames_ == 0) << "Starting to fill frames with 0"; | 387 LOG_IF(WARNING, state_ != kStateFinalFade && zeroed_frames_ == 0) |
| 388 << "Starting to fill frames with 0"; |
377 zeroed_frames_ += frames_left; | 389 zeroed_frames_ += frames_left; |
378 output->ZeroFramesPartial(frames_filled, frames_left); | 390 output->ZeroFramesPartial(frames_filled, frames_left); |
379 frames_filled += frames_left; | 391 frames_filled += frames_left; |
380 frames_left = 0; | 392 frames_left = 0; |
381 break; | 393 break; |
382 } | 394 } |
383 } | 395 } |
384 | 396 |
385 DCHECK_EQ(0, frames_left); | 397 DCHECK_EQ(0, frames_left); |
386 DCHECK_EQ(frames, frames_filled); | 398 DCHECK_EQ(frames, frames_filled); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 | 490 |
479 if (state_ == kStateFadingOut) { | 491 if (state_ == kStateFadingOut) { |
480 // Tell the mixer that some more data might be available (since when fading | 492 // Tell the mixer that some more data might be available (since when fading |
481 // out, we can drain the queue completely). | 493 // out, we can drain the queue completely). |
482 mixer_->OnFramesQueued(); | 494 mixer_->OnFramesQueued(); |
483 } | 495 } |
484 } | 496 } |
485 | 497 |
486 void StreamMixerAlsaInputImpl::SetVolumeMultiplier(float multiplier) { | 498 void StreamMixerAlsaInputImpl::SetVolumeMultiplier(float multiplier) { |
487 RUN_ON_MIXER_THREAD(SetVolumeMultiplier, multiplier); | 499 RUN_ON_MIXER_THREAD(SetVolumeMultiplier, multiplier); |
| 500 LOG(INFO) << this << ": stream volume = " << multiplier; |
488 DCHECK(!IsDeleting()); | 501 DCHECK(!IsDeleting()); |
489 if (multiplier > 1.0f) | 502 if (multiplier > 1.0f) |
490 multiplier = 1.0f; | 503 multiplier = 1.0f; |
491 if (multiplier < 0.0f) | 504 if (multiplier < 0.0f) |
492 multiplier = 0.0f; | 505 multiplier = 0.0f; |
493 volume_multiplier_ = multiplier; | 506 volume_multiplier_ = multiplier; |
494 } | 507 } |
495 | 508 |
496 } // namespace media | 509 } // namespace media |
497 } // namespace chromecast | 510 } // namespace chromecast |
OLD | NEW |