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

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: Add comments etc 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; 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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698