Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: chromecast/media/cma/backend/alsa/audio_decoder_alsa.cc

Issue 2557513002: [Chromecast] Add support for different playback rates to ALSA backend (Closed)
Patch Set: use CreateEmptyBuffer Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698