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/audio_decoder_alsa.h" | 5 #include "chromecast/media/cma/backend/alsa/audio_decoder_alsa.h" |
6 | 6 |
7 #include <time.h> | 7 #include <time.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <limits> | 10 #include <limits> |
11 | 11 |
12 #include "base/callback_helpers.h" | 12 #include "base/callback_helpers.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/macros.h" | 14 #include "base/macros.h" |
15 #include "base/trace_event/trace_event.h" | 15 #include "base/trace_event/trace_event.h" |
16 #include "chromecast/base/task_runner_impl.h" | 16 #include "chromecast/base/task_runner_impl.h" |
17 #include "chromecast/media/cma/backend/alsa/media_pipeline_backend_alsa.h" | 17 #include "chromecast/media/cma/backend/alsa/media_pipeline_backend_alsa.h" |
| 18 #include "chromecast/media/cma/base/decoder_buffer_adapter.h" |
18 #include "chromecast/media/cma/base/decoder_buffer_base.h" | 19 #include "chromecast/media/cma/base/decoder_buffer_base.h" |
19 #include "chromecast/public/media/cast_decoder_buffer.h" | 20 #include "chromecast/public/media/cast_decoder_buffer.h" |
| 21 #include "media/base/audio_buffer.h" |
| 22 #include "media/base/audio_bus.h" |
| 23 #include "media/base/channel_layout.h" |
| 24 #include "media/base/decoder_buffer.h" |
| 25 #include "media/base/sample_format.h" |
| 26 #include "media/filters/audio_renderer_algorithm.h" |
20 | 27 |
21 #define TRACE_FUNCTION_ENTRY0() TRACE_EVENT0("cma", __FUNCTION__) | 28 #define TRACE_FUNCTION_ENTRY0() TRACE_EVENT0("cma", __FUNCTION__) |
22 | 29 |
23 #define TRACE_FUNCTION_ENTRY1(arg1) \ | 30 #define TRACE_FUNCTION_ENTRY1(arg1) \ |
24 TRACE_EVENT1("cma", __FUNCTION__, #arg1, arg1) | 31 TRACE_EVENT1("cma", __FUNCTION__, #arg1, arg1) |
25 | 32 |
26 #define TRACE_FUNCTION_ENTRY2(arg1, arg2) \ | 33 #define TRACE_FUNCTION_ENTRY2(arg1, arg2) \ |
27 TRACE_EVENT2("cma", __FUNCTION__, #arg1, arg1, #arg2, arg2) | 34 TRACE_EVENT2("cma", __FUNCTION__, #arg1, arg1, #arg2, arg2) |
28 | 35 |
29 namespace chromecast { | 36 namespace chromecast { |
30 namespace media { | 37 namespace media { |
31 | 38 |
32 namespace { | 39 namespace { |
33 | 40 |
| 41 const int kNumChannels = 2; |
| 42 const int kBitsPerSample = 32; |
| 43 const int kDefaultFramesPerBuffer = 1024; |
| 44 const int kSilenceBufferFrames = 2048; |
| 45 const int kMaxOutputMs = 20; |
| 46 const int kMillisecondsPerSecond = 1000; |
| 47 |
| 48 const double kPlaybackRateEpsilon = 0.001; |
| 49 |
34 const CastAudioDecoder::OutputFormat kDecoderSampleFormat = | 50 const CastAudioDecoder::OutputFormat kDecoderSampleFormat = |
35 CastAudioDecoder::kOutputPlanarFloat; | 51 CastAudioDecoder::kOutputPlanarFloat; |
36 | 52 |
37 const int64_t kInvalidDelayTimestamp = std::numeric_limits<int64_t>::min(); | 53 const int64_t kInvalidTimestamp = std::numeric_limits<int64_t>::min(); |
38 | 54 |
39 AudioDecoderAlsa::RenderingDelay kInvalidRenderingDelay() { | 55 const int64_t kNoPendingOutput = -1; |
40 AudioDecoderAlsa::RenderingDelay delay; | |
41 delay.timestamp_microseconds = kInvalidDelayTimestamp; | |
42 delay.delay_microseconds = 0; | |
43 return delay; | |
44 } | |
45 | 56 |
46 } // namespace | 57 } // namespace |
47 | 58 |
| 59 AudioDecoderAlsa::RateShifterInfo::RateShifterInfo(float playback_rate) |
| 60 : rate(playback_rate), input_frames(0), output_frames(0) {} |
| 61 |
48 AudioDecoderAlsa::AudioDecoderAlsa(MediaPipelineBackendAlsa* backend) | 62 AudioDecoderAlsa::AudioDecoderAlsa(MediaPipelineBackendAlsa* backend) |
49 : backend_(backend), | 63 : backend_(backend), |
50 task_runner_(backend->GetTaskRunner()), | 64 task_runner_(backend->GetTaskRunner()), |
51 delegate_(nullptr), | 65 delegate_(nullptr), |
52 is_eos_(false), | 66 pending_buffer_complete_(false), |
53 error_(false), | 67 got_eos_(false), |
| 68 pushed_eos_(false), |
| 69 mixer_error_(false), |
| 70 rate_shifter_output_( |
| 71 ::media::AudioBus::Create(kNumChannels, kDefaultFramesPerBuffer)), |
| 72 current_pts_(kInvalidTimestamp), |
| 73 pending_output_frames_(kNoPendingOutput), |
54 volume_multiplier_(1.0f), | 74 volume_multiplier_(1.0f), |
55 weak_factory_(this) { | 75 weak_factory_(this) { |
56 TRACE_FUNCTION_ENTRY0(); | 76 TRACE_FUNCTION_ENTRY0(); |
57 DCHECK(backend_); | 77 DCHECK(backend_); |
58 DCHECK(task_runner_.get()); | 78 DCHECK(task_runner_.get()); |
59 DCHECK(task_runner_->BelongsToCurrentThread()); | 79 DCHECK(task_runner_->BelongsToCurrentThread()); |
60 } | 80 } |
61 | 81 |
62 AudioDecoderAlsa::~AudioDecoderAlsa() { | 82 AudioDecoderAlsa::~AudioDecoderAlsa() { |
63 TRACE_FUNCTION_ENTRY0(); | 83 TRACE_FUNCTION_ENTRY0(); |
64 DCHECK(task_runner_->BelongsToCurrentThread()); | 84 DCHECK(task_runner_->BelongsToCurrentThread()); |
65 } | 85 } |
66 | 86 |
67 void AudioDecoderAlsa::SetDelegate( | 87 void AudioDecoderAlsa::SetDelegate( |
68 MediaPipelineBackend::Decoder::Delegate* delegate) { | 88 MediaPipelineBackend::Decoder::Delegate* delegate) { |
69 DCHECK(delegate); | 89 DCHECK(delegate); |
70 delegate_ = delegate; | 90 delegate_ = delegate; |
71 } | 91 } |
72 | 92 |
73 void AudioDecoderAlsa::Initialize() { | 93 void AudioDecoderAlsa::Initialize() { |
74 TRACE_FUNCTION_ENTRY0(); | 94 TRACE_FUNCTION_ENTRY0(); |
75 DCHECK(delegate_); | 95 DCHECK(delegate_); |
76 stats_ = Statistics(); | 96 stats_ = Statistics(); |
77 is_eos_ = false; | 97 pending_buffer_complete_ = false; |
78 last_buffer_pts_ = std::numeric_limits<int64_t>::min(); | 98 got_eos_ = false; |
| 99 pushed_eos_ = false; |
| 100 current_pts_ = kInvalidTimestamp; |
| 101 pending_output_frames_ = kNoPendingOutput; |
79 | 102 |
80 last_known_delay_.timestamp_microseconds = kInvalidDelayTimestamp; | 103 last_mixer_delay_.timestamp_microseconds = kInvalidTimestamp; |
81 last_known_delay_.delay_microseconds = 0; | 104 last_mixer_delay_.delay_microseconds = 0; |
82 } | 105 } |
83 | 106 |
84 bool AudioDecoderAlsa::Start(int64_t start_pts) { | 107 bool AudioDecoderAlsa::Start(int64_t start_pts) { |
85 TRACE_FUNCTION_ENTRY0(); | 108 TRACE_FUNCTION_ENTRY0(); |
86 current_pts_ = start_pts; | 109 current_pts_ = start_pts; |
87 DCHECK(IsValidConfig(config_)); | 110 DCHECK(IsValidConfig(config_)); |
88 mixer_input_.reset(new StreamMixerAlsaInput( | 111 mixer_input_.reset(new StreamMixerAlsaInput( |
89 this, config_.samples_per_second, backend_->Primary())); | 112 this, config_.samples_per_second, backend_->Primary())); |
90 mixer_input_->SetVolumeMultiplier(volume_multiplier_); | 113 mixer_input_->SetVolumeMultiplier(volume_multiplier_); |
91 // Create decoder_ if necessary. This can happen if Stop() was called, and | 114 // Create decoder_ if necessary. This can happen if Stop() was called, and |
92 // SetConfig() was not called since then. | 115 // SetConfig() was not called since then. |
93 if (!decoder_) | 116 if (!decoder_) { |
94 CreateDecoder(); | 117 CreateDecoder(); |
| 118 } |
| 119 if (!rate_shifter_) { |
| 120 CreateRateShifter(config_.samples_per_second); |
| 121 } |
95 return true; | 122 return true; |
96 } | 123 } |
97 | 124 |
98 void AudioDecoderAlsa::Stop() { | 125 void AudioDecoderAlsa::Stop() { |
99 TRACE_FUNCTION_ENTRY0(); | 126 TRACE_FUNCTION_ENTRY0(); |
100 decoder_.reset(); | 127 decoder_.reset(); |
101 mixer_input_.reset(); | 128 mixer_input_.reset(); |
| 129 rate_shifter_.reset(); |
| 130 weak_factory_.InvalidateWeakPtrs(); |
102 | 131 |
103 Initialize(); | 132 Initialize(); |
104 } | 133 } |
105 | 134 |
106 bool AudioDecoderAlsa::Pause() { | 135 bool AudioDecoderAlsa::Pause() { |
107 TRACE_FUNCTION_ENTRY0(); | 136 TRACE_FUNCTION_ENTRY0(); |
108 DCHECK(mixer_input_); | 137 DCHECK(mixer_input_); |
109 mixer_input_->SetPaused(true); | 138 mixer_input_->SetPaused(true); |
110 return true; | 139 return true; |
111 } | 140 } |
112 | 141 |
113 bool AudioDecoderAlsa::Resume() { | 142 bool AudioDecoderAlsa::Resume() { |
114 TRACE_FUNCTION_ENTRY0(); | 143 TRACE_FUNCTION_ENTRY0(); |
115 DCHECK(mixer_input_); | 144 DCHECK(mixer_input_); |
116 mixer_input_->SetPaused(false); | 145 mixer_input_->SetPaused(false); |
117 return true; | 146 return true; |
118 } | 147 } |
119 | 148 |
| 149 bool AudioDecoderAlsa::SetPlaybackRate(float rate) { |
| 150 if (std::abs(rate - 1.0) < kPlaybackRateEpsilon) { |
| 151 // AudioRendererAlgorithm treats values close to 1 as exactly 1. |
| 152 rate = 1.0f; |
| 153 } |
| 154 LOG(INFO) << "SetPlaybackRate to " << rate; |
| 155 |
| 156 while (!rate_shifter_info_.empty() && |
| 157 rate_shifter_info_.back().input_frames == 0) { |
| 158 rate_shifter_info_.pop_back(); |
| 159 } |
| 160 rate_shifter_info_.push_back(RateShifterInfo(rate)); |
| 161 return true; |
| 162 } |
| 163 |
120 AudioDecoderAlsa::BufferStatus AudioDecoderAlsa::PushBuffer( | 164 AudioDecoderAlsa::BufferStatus AudioDecoderAlsa::PushBuffer( |
121 CastDecoderBuffer* buffer) { | 165 CastDecoderBuffer* buffer) { |
122 TRACE_FUNCTION_ENTRY0(); | 166 TRACE_FUNCTION_ENTRY0(); |
123 DCHECK(task_runner_->BelongsToCurrentThread()); | 167 DCHECK(task_runner_->BelongsToCurrentThread()); |
124 DCHECK(buffer); | 168 DCHECK(buffer); |
125 DCHECK(!is_eos_); | 169 DCHECK(!got_eos_); |
126 DCHECK(!error_); | 170 DCHECK(!mixer_error_); |
| 171 DCHECK(!pending_buffer_complete_); |
127 | 172 |
128 uint64_t input_bytes = buffer->end_of_stream() ? 0 : buffer->data_size(); | 173 uint64_t input_bytes = buffer->end_of_stream() ? 0 : buffer->data_size(); |
129 scoped_refptr<DecoderBufferBase> buffer_base( | 174 scoped_refptr<DecoderBufferBase> buffer_base( |
130 static_cast<DecoderBufferBase*>(buffer)); | 175 static_cast<DecoderBufferBase*>(buffer)); |
131 if (!buffer->end_of_stream()) { | 176 if (!buffer->end_of_stream()) { |
132 last_buffer_pts_ = buffer->timestamp(); | 177 current_pts_ = buffer->timestamp(); |
133 current_pts_ = std::min(current_pts_, last_buffer_pts_); | |
134 } | 178 } |
135 | 179 |
136 // If the buffer is already decoded, do not attempt to decode. Call | 180 // If the buffer is already decoded, do not attempt to decode. Call |
137 // OnBufferDecoded asynchronously on the main thread. | 181 // OnBufferDecoded asynchronously on the main thread. |
138 if (BypassDecoder()) { | 182 if (BypassDecoder()) { |
139 DCHECK(!decoder_); | 183 DCHECK(!decoder_); |
140 task_runner_->PostTask( | 184 task_runner_->PostTask( |
141 FROM_HERE, | 185 FROM_HERE, |
142 base::Bind(&AudioDecoderAlsa::OnBufferDecoded, | 186 base::Bind(&AudioDecoderAlsa::OnBufferDecoded, |
143 weak_factory_.GetWeakPtr(), input_bytes, | 187 weak_factory_.GetWeakPtr(), input_bytes, |
(...skipping 23 matching lines...) Expand all Loading... |
167 } | 211 } |
168 | 212 |
169 bool AudioDecoderAlsa::SetConfig(const AudioConfig& config) { | 213 bool AudioDecoderAlsa::SetConfig(const AudioConfig& config) { |
170 TRACE_FUNCTION_ENTRY0(); | 214 TRACE_FUNCTION_ENTRY0(); |
171 DCHECK(task_runner_->BelongsToCurrentThread()); | 215 DCHECK(task_runner_->BelongsToCurrentThread()); |
172 if (!IsValidConfig(config)) { | 216 if (!IsValidConfig(config)) { |
173 LOG(ERROR) << "Invalid audio config passed to SetConfig"; | 217 LOG(ERROR) << "Invalid audio config passed to SetConfig"; |
174 return false; | 218 return false; |
175 } | 219 } |
176 | 220 |
| 221 if (!rate_shifter_ || |
| 222 config.samples_per_second != config_.samples_per_second) { |
| 223 CreateRateShifter(config.samples_per_second); |
| 224 } |
| 225 |
177 if (mixer_input_ && config.samples_per_second != config_.samples_per_second) { | 226 if (mixer_input_ && config.samples_per_second != config_.samples_per_second) { |
178 // Destroy the old input first to ensure that the mixer output sample rate | 227 // Destroy the old input first to ensure that the mixer output sample rate |
179 // is updated. | 228 // is updated. |
180 mixer_input_.reset(); | 229 mixer_input_.reset(); |
181 mixer_input_.reset(new StreamMixerAlsaInput( | 230 mixer_input_.reset(new StreamMixerAlsaInput( |
182 this, config.samples_per_second, backend_->Primary())); | 231 this, config.samples_per_second, backend_->Primary())); |
183 mixer_input_->SetVolumeMultiplier(volume_multiplier_); | 232 mixer_input_->SetVolumeMultiplier(volume_multiplier_); |
| 233 pending_output_frames_ = kNoPendingOutput; |
184 } | 234 } |
185 | 235 |
186 config_ = config; | 236 config_ = config; |
187 decoder_.reset(); | 237 decoder_.reset(); |
188 CreateDecoder(); | 238 CreateDecoder(); |
| 239 |
| 240 if (pending_buffer_complete_ && !rate_shifter_->IsQueueFull()) { |
| 241 pending_buffer_complete_ = false; |
| 242 delegate_->OnPushBufferComplete(MediaPipelineBackendAlsa::kBufferSuccess); |
| 243 } |
189 return true; | 244 return true; |
190 } | 245 } |
191 | 246 |
192 void AudioDecoderAlsa::CreateDecoder() { | 247 void AudioDecoderAlsa::CreateDecoder() { |
193 DCHECK(!decoder_); | 248 DCHECK(!decoder_); |
194 DCHECK(IsValidConfig(config_)); | 249 DCHECK(IsValidConfig(config_)); |
195 | 250 |
196 // No need to create a decoder if the samples are already decoded. | 251 // No need to create a decoder if the samples are already decoded. |
197 if (BypassDecoder()) { | 252 if (BypassDecoder()) { |
198 LOG(INFO) << "Data is not coded. Decoder will not be used."; | 253 LOG(INFO) << "Data is not coded. Decoder will not be used."; |
199 return; | 254 return; |
200 } | 255 } |
201 | 256 |
202 // Create a decoder. | 257 // Create a decoder. |
203 decoder_ = CastAudioDecoder::Create( | 258 decoder_ = CastAudioDecoder::Create( |
204 task_runner_, | 259 task_runner_, |
205 config_, | 260 config_, |
206 kDecoderSampleFormat, | 261 kDecoderSampleFormat, |
207 base::Bind(&AudioDecoderAlsa::OnDecoderInitialized, | 262 base::Bind(&AudioDecoderAlsa::OnDecoderInitialized, |
208 weak_factory_.GetWeakPtr())); | 263 weak_factory_.GetWeakPtr())); |
209 } | 264 } |
210 | 265 |
| 266 void AudioDecoderAlsa::CreateRateShifter(int samples_per_second) { |
| 267 rate_shifter_info_.clear(); |
| 268 rate_shifter_info_.push_back(RateShifterInfo(1.0f)); |
| 269 |
| 270 rate_shifter_.reset(new ::media::AudioRendererAlgorithm()); |
| 271 rate_shifter_->Initialize(::media::AudioParameters( |
| 272 ::media::AudioParameters::AUDIO_PCM_LINEAR, |
| 273 ::media::CHANNEL_LAYOUT_STEREO, samples_per_second, kBitsPerSample, |
| 274 kDefaultFramesPerBuffer)); |
| 275 } |
| 276 |
211 bool AudioDecoderAlsa::SetVolume(float multiplier) { | 277 bool AudioDecoderAlsa::SetVolume(float multiplier) { |
212 TRACE_FUNCTION_ENTRY1(multiplier); | 278 TRACE_FUNCTION_ENTRY1(multiplier); |
213 DCHECK(task_runner_->BelongsToCurrentThread()); | 279 DCHECK(task_runner_->BelongsToCurrentThread()); |
214 volume_multiplier_ = multiplier; | 280 volume_multiplier_ = multiplier; |
215 if (mixer_input_) | 281 if (mixer_input_) |
216 mixer_input_->SetVolumeMultiplier(volume_multiplier_); | 282 mixer_input_->SetVolumeMultiplier(volume_multiplier_); |
217 return true; | 283 return true; |
218 } | 284 } |
219 | 285 |
220 AudioDecoderAlsa::RenderingDelay AudioDecoderAlsa::GetRenderingDelay() { | 286 AudioDecoderAlsa::RenderingDelay AudioDecoderAlsa::GetRenderingDelay() { |
221 TRACE_FUNCTION_ENTRY0(); | 287 TRACE_FUNCTION_ENTRY0(); |
222 return last_known_delay_; | 288 AudioDecoderAlsa::RenderingDelay delay = last_mixer_delay_; |
| 289 if (delay.timestamp_microseconds != kInvalidTimestamp) { |
| 290 double usec_per_sample = 1000000.0 / config_.samples_per_second; |
| 291 |
| 292 // Account for data that has been queued in the rate shifters. |
| 293 for (const RateShifterInfo& info : rate_shifter_info_) { |
| 294 double queued_output_frames = |
| 295 (info.input_frames / info.rate) - info.output_frames; |
| 296 delay.delay_microseconds += queued_output_frames * usec_per_sample; |
| 297 } |
| 298 |
| 299 // Account for data that is in the process of being pushed to the mixer. |
| 300 if (pending_output_frames_ != kNoPendingOutput) { |
| 301 delay.delay_microseconds += pending_output_frames_ * usec_per_sample; |
| 302 } |
| 303 } |
| 304 |
| 305 return delay; |
223 } | 306 } |
224 | 307 |
225 void AudioDecoderAlsa::OnDecoderInitialized(bool success) { | 308 void AudioDecoderAlsa::OnDecoderInitialized(bool success) { |
226 TRACE_FUNCTION_ENTRY0(); | 309 TRACE_FUNCTION_ENTRY0(); |
227 DCHECK(task_runner_->BelongsToCurrentThread()); | 310 DCHECK(task_runner_->BelongsToCurrentThread()); |
228 LOG(INFO) << "Decoder initialization was " | 311 LOG(INFO) << "Decoder initialization was " |
229 << (success ? "successful" : "unsuccessful"); | 312 << (success ? "successful" : "unsuccessful"); |
230 if (!success) | 313 if (!success) |
231 delegate_->OnDecoderError(); | 314 delegate_->OnDecoderError(); |
232 } | 315 } |
233 | 316 |
234 void AudioDecoderAlsa::OnBufferDecoded( | 317 void AudioDecoderAlsa::OnBufferDecoded( |
235 uint64_t input_bytes, | 318 uint64_t input_bytes, |
236 CastAudioDecoder::Status status, | 319 CastAudioDecoder::Status status, |
237 const scoped_refptr<DecoderBufferBase>& decoded) { | 320 const scoped_refptr<DecoderBufferBase>& decoded) { |
238 TRACE_FUNCTION_ENTRY0(); | 321 TRACE_FUNCTION_ENTRY0(); |
239 DCHECK(task_runner_->BelongsToCurrentThread()); | 322 DCHECK(task_runner_->BelongsToCurrentThread()); |
240 DCHECK(!is_eos_); | 323 DCHECK(!got_eos_); |
241 | 324 DCHECK(!pending_buffer_complete_); |
242 Statistics delta = Statistics(); | 325 DCHECK(rate_shifter_); |
243 | 326 |
244 if (status == CastAudioDecoder::Status::kDecodeError) { | 327 if (status == CastAudioDecoder::Status::kDecodeError) { |
245 LOG(ERROR) << "Decode error"; | 328 LOG(ERROR) << "Decode error"; |
246 task_runner_->PostTask(FROM_HERE, | 329 delegate_->OnPushBufferComplete(MediaPipelineBackendAlsa::kBufferFailed); |
247 base::Bind(&AudioDecoderAlsa::OnWritePcmCompletion, | 330 return; |
248 weak_factory_.GetWeakPtr(), | 331 } |
249 MediaPipelineBackendAlsa::kBufferFailed, | 332 if (mixer_error_) { |
250 kInvalidRenderingDelay())); | 333 delegate_->OnPushBufferComplete(MediaPipelineBackendAlsa::kBufferFailed); |
251 UpdateStatistics(delta); | |
252 return; | 334 return; |
253 } | 335 } |
254 | 336 |
| 337 Statistics delta; |
255 delta.decoded_bytes = input_bytes; | 338 delta.decoded_bytes = input_bytes; |
256 UpdateStatistics(delta); | 339 UpdateStatistics(delta); |
257 | 340 |
258 if (decoded->end_of_stream()) | 341 if (decoded->end_of_stream()) { |
259 is_eos_ = true; | 342 got_eos_ = true; |
| 343 } else { |
| 344 int input_frames = decoded->data_size() / (kNumChannels * sizeof(float)); |
260 | 345 |
| 346 DCHECK(!rate_shifter_info_.empty()); |
| 347 RateShifterInfo* rate_info = &rate_shifter_info_.front(); |
| 348 // Bypass rate shifter if the rate is 1.0, and there are no frames queued |
| 349 // in the rate shifter. |
| 350 if (rate_info->rate == 1.0 && rate_shifter_->frames_buffered() == 0 && |
| 351 pending_output_frames_ == kNoPendingOutput) { |
| 352 DCHECK_EQ(rate_info->output_frames, rate_info->input_frames); |
| 353 pending_buffer_complete_ = true; |
| 354 pending_output_frames_ = input_frames; |
| 355 if (got_eos_) { |
| 356 DCHECK(!pushed_eos_); |
| 357 pushed_eos_ = true; |
| 358 } |
| 359 mixer_input_->WritePcm(decoded); |
| 360 return; |
| 361 } |
| 362 |
| 363 // Otherwise, queue data into the rate shifter, and then try to push the |
| 364 // rate-shifted data. |
| 365 const uint8_t* channels[kNumChannels] = { |
| 366 decoded->data(), decoded->data() + input_frames * sizeof(float)}; |
| 367 scoped_refptr<::media::AudioBuffer> buffer = ::media::AudioBuffer::CopyFrom( |
| 368 ::media::kSampleFormatPlanarF32, ::media::CHANNEL_LAYOUT_STEREO, |
| 369 kNumChannels, config_.samples_per_second, input_frames, channels, |
| 370 base::TimeDelta()); |
| 371 rate_shifter_->EnqueueBuffer(buffer); |
| 372 rate_shifter_info_.back().input_frames += input_frames; |
| 373 } |
| 374 |
| 375 PushRateShifted(); |
| 376 DCHECK(!rate_shifter_info_.empty()); |
| 377 // Can't check got_eos_ here, since it may have already been reset by a call |
| 378 // to Stop(). |
| 379 if (decoded->end_of_stream() || (!rate_shifter_->IsQueueFull() && |
| 380 rate_shifter_info_.front().rate != 1.0)) { |
| 381 delegate_->OnPushBufferComplete(MediaPipelineBackendAlsa::kBufferSuccess); |
| 382 } else { |
| 383 pending_buffer_complete_ = true; |
| 384 } |
| 385 } |
| 386 |
| 387 void AudioDecoderAlsa::PushRateShifted() { |
261 DCHECK(mixer_input_); | 388 DCHECK(mixer_input_); |
262 mixer_input_->WritePcm(decoded); | 389 |
| 390 if (pending_output_frames_ != kNoPendingOutput) { |
| 391 return; |
| 392 } |
| 393 |
| 394 if (got_eos_) { |
| 395 // Push some silence into the rate shifter so we can get out any remaining |
| 396 // rate-shifted data. |
| 397 rate_shifter_->EnqueueBuffer(::media::AudioBuffer::CreateEmptyBuffer( |
| 398 ::media::CHANNEL_LAYOUT_STEREO, kNumChannels, |
| 399 config_.samples_per_second, kSilenceBufferFrames, base::TimeDelta())); |
| 400 } |
| 401 |
| 402 DCHECK(!rate_shifter_info_.empty()); |
| 403 RateShifterInfo* rate_info = &rate_shifter_info_.front(); |
| 404 int64_t possible_output_frames = rate_info->input_frames / rate_info->rate; |
| 405 DCHECK_GE(possible_output_frames, rate_info->output_frames); |
| 406 |
| 407 int desired_output_frames = possible_output_frames - rate_info->output_frames; |
| 408 if (desired_output_frames == 0) { |
| 409 if (got_eos_) { |
| 410 DCHECK(!pushed_eos_); |
| 411 pending_output_frames_ = 0; |
| 412 pushed_eos_ = true; |
| 413 |
| 414 scoped_refptr<DecoderBufferBase> eos_buffer( |
| 415 new DecoderBufferAdapter(::media::DecoderBuffer::CreateEOSBuffer())); |
| 416 mixer_input_->WritePcm(eos_buffer); |
| 417 } |
| 418 return; |
| 419 } |
| 420 // Don't push too many frames at a time. |
| 421 desired_output_frames = std::min( |
| 422 desired_output_frames, |
| 423 config_.samples_per_second * kMaxOutputMs / kMillisecondsPerSecond); |
| 424 |
| 425 if (desired_output_frames > rate_shifter_output_->frames()) { |
| 426 rate_shifter_output_ = |
| 427 ::media::AudioBus::Create(kNumChannels, desired_output_frames); |
| 428 } |
| 429 |
| 430 int out_frames = rate_shifter_->FillBuffer( |
| 431 rate_shifter_output_.get(), 0, desired_output_frames, rate_info->rate); |
| 432 if (out_frames <= 0) { |
| 433 return; |
| 434 } |
| 435 |
| 436 rate_info->output_frames += out_frames; |
| 437 DCHECK_GE(possible_output_frames, rate_info->output_frames); |
| 438 |
| 439 int channel_data_size = out_frames * sizeof(float); |
| 440 scoped_refptr<DecoderBufferBase> output_buffer(new DecoderBufferAdapter( |
| 441 new ::media::DecoderBuffer(channel_data_size * kNumChannels))); |
| 442 for (int c = 0; c < kNumChannels; ++c) { |
| 443 memcpy(output_buffer->writable_data() + c * channel_data_size, |
| 444 rate_shifter_output_->channel(c), channel_data_size); |
| 445 } |
| 446 pending_output_frames_ = out_frames; |
| 447 mixer_input_->WritePcm(output_buffer); |
| 448 |
| 449 if (rate_shifter_info_.size() > 1 && |
| 450 possible_output_frames == rate_info->output_frames) { |
| 451 double remaining_input_frames = |
| 452 rate_info->input_frames - (rate_info->output_frames * rate_info->rate); |
| 453 rate_shifter_info_.pop_front(); |
| 454 |
| 455 rate_info = &rate_shifter_info_.front(); |
| 456 LOG(INFO) << "New playback rate in effect: " << rate_info->rate; |
| 457 rate_info->input_frames += remaining_input_frames; |
| 458 DCHECK_EQ(0, rate_info->output_frames); |
| 459 |
| 460 // If new playback rate is 1.0, clear out 'extra' data in the rate shifter. |
| 461 // When doing rate shifting, the rate shifter queue holds data after it has |
| 462 // been logically played; once we switch to passthrough mode (rate == 1.0), |
| 463 // that old data needs to be cleared out. |
| 464 if (rate_info->rate == 1.0) { |
| 465 int extra_frames = rate_shifter_->frames_buffered() - |
| 466 static_cast<int>(rate_info->input_frames); |
| 467 if (extra_frames > 0) { |
| 468 // Clear out extra buffered data. |
| 469 std::unique_ptr<::media::AudioBus> dropped = |
| 470 ::media::AudioBus::Create(kNumChannels, extra_frames); |
| 471 int cleared_frames = |
| 472 rate_shifter_->FillBuffer(dropped.get(), 0, extra_frames, 1.0f); |
| 473 DCHECK_EQ(extra_frames, cleared_frames); |
| 474 } |
| 475 rate_info->input_frames = rate_shifter_->frames_buffered(); |
| 476 } |
| 477 } |
263 } | 478 } |
264 | 479 |
265 bool AudioDecoderAlsa::BypassDecoder() const { | 480 bool AudioDecoderAlsa::BypassDecoder() const { |
266 DCHECK(task_runner_->BelongsToCurrentThread()); | 481 DCHECK(task_runner_->BelongsToCurrentThread()); |
267 // The mixer input requires planar float PCM data. | 482 // The mixer input requires planar float PCM data. |
268 return (config_.codec == kCodecPCM && | 483 return (config_.codec == kCodecPCM && |
269 config_.sample_format == kSampleFormatPlanarF32); | 484 config_.sample_format == kSampleFormatPlanarF32); |
270 } | 485 } |
271 | 486 |
272 void AudioDecoderAlsa::OnWritePcmCompletion(BufferStatus status, | 487 void AudioDecoderAlsa::OnWritePcmCompletion(BufferStatus status, |
273 const RenderingDelay& delay) { | 488 const RenderingDelay& delay) { |
274 TRACE_FUNCTION_ENTRY0(); | 489 TRACE_FUNCTION_ENTRY0(); |
275 DCHECK(task_runner_->BelongsToCurrentThread()); | 490 DCHECK(task_runner_->BelongsToCurrentThread()); |
276 if (status == MediaPipelineBackendAlsa::kBufferSuccess && !is_eos_) | 491 DCHECK_EQ(MediaPipelineBackendAlsa::kBufferSuccess, status); |
277 current_pts_ = last_buffer_pts_; | 492 pending_output_frames_ = kNoPendingOutput; |
278 if (delay.timestamp_microseconds != kInvalidDelayTimestamp) | 493 last_mixer_delay_ = delay; |
279 last_known_delay_ = delay; | 494 |
280 delegate_->OnPushBufferComplete(status); | 495 if (pushed_eos_) { |
281 if (is_eos_) | 496 if (pending_buffer_complete_) { |
| 497 pending_buffer_complete_ = false; |
| 498 delegate_->OnPushBufferComplete(MediaPipelineBackendAlsa::kBufferSuccess); |
| 499 } |
282 delegate_->OnEndOfStream(); | 500 delegate_->OnEndOfStream(); |
| 501 } else { |
| 502 task_runner_->PostTask(FROM_HERE, base::Bind(&AudioDecoderAlsa::PushMorePcm, |
| 503 weak_factory_.GetWeakPtr())); |
| 504 } |
| 505 } |
| 506 |
| 507 void AudioDecoderAlsa::PushMorePcm() { |
| 508 PushRateShifted(); |
| 509 |
| 510 DCHECK(!rate_shifter_info_.empty()); |
| 511 if (pending_buffer_complete_) { |
| 512 double rate = rate_shifter_info_.front().rate; |
| 513 if ((rate == 1.0 && pending_output_frames_ == kNoPendingOutput) || |
| 514 (rate != 1.0 && !rate_shifter_->IsQueueFull())) { |
| 515 pending_buffer_complete_ = false; |
| 516 delegate_->OnPushBufferComplete(MediaPipelineBackendAlsa::kBufferSuccess); |
| 517 } |
| 518 } |
283 } | 519 } |
284 | 520 |
285 void AudioDecoderAlsa::OnMixerError(MixerError error) { | 521 void AudioDecoderAlsa::OnMixerError(MixerError error) { |
286 TRACE_FUNCTION_ENTRY0(); | 522 TRACE_FUNCTION_ENTRY0(); |
287 DCHECK(task_runner_->BelongsToCurrentThread()); | 523 DCHECK(task_runner_->BelongsToCurrentThread()); |
288 if (error != MixerError::kInputIgnored) | 524 if (error != MixerError::kInputIgnored) |
289 LOG(ERROR) << "Mixer error occurred."; | 525 LOG(ERROR) << "Mixer error occurred."; |
290 error_ = true; | 526 mixer_error_ = true; |
291 delegate_->OnDecoderError(); | 527 delegate_->OnDecoderError(); |
292 } | 528 } |
293 | 529 |
294 } // namespace media | 530 } // namespace media |
295 } // namespace chromecast | 531 } // namespace chromecast |
OLD | NEW |