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