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

Side by Side Diff: media/filters/opus_audio_decoder.cc

Issue 141243003: Add AudioBufferStream. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@decoderstream_rebased
Patch Set: address comments Created 6 years, 9 months 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "media/filters/opus_audio_decoder.h" 5 #include "media/filters/opus_audio_decoder.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 249
250 for (int i = 0; i < extra_data->channels; ++i) 250 for (int i = 0; i < extra_data->channels; ++i)
251 extra_data->stream_map[i] = *(data + kOpusExtraDataStreamMapOffset + i); 251 extra_data->stream_map[i] = *(data + kOpusExtraDataStreamMapOffset + i);
252 return true; 252 return true;
253 } 253 }
254 254
255 OpusAudioDecoder::OpusAudioDecoder( 255 OpusAudioDecoder::OpusAudioDecoder(
256 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) 256 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
257 : task_runner_(task_runner), 257 : task_runner_(task_runner),
258 weak_factory_(this), 258 weak_factory_(this),
259 demuxer_stream_(NULL),
260 opus_decoder_(NULL), 259 opus_decoder_(NULL),
261 channel_layout_(CHANNEL_LAYOUT_NONE), 260 channel_layout_(CHANNEL_LAYOUT_NONE),
262 samples_per_second_(0), 261 samples_per_second_(0),
263 sample_format_(kSampleFormatF32), 262 sample_format_(kSampleFormatF32),
264 bits_per_channel_(SampleFormatToBytesPerChannel(sample_format_) * 8), 263 bits_per_channel_(SampleFormatToBytesPerChannel(sample_format_) * 8),
265 last_input_timestamp_(kNoTimestamp()), 264 last_input_timestamp_(kNoTimestamp()),
266 frames_to_discard_(0), 265 frames_to_discard_(0),
267 frame_delay_at_start_(0), 266 frame_delay_at_start_(0),
268 start_input_timestamp_(kNoTimestamp()) { 267 start_input_timestamp_(kNoTimestamp()) {
269 } 268 }
270 269
271 void OpusAudioDecoder::Initialize( 270 void OpusAudioDecoder::Initialize(const AudioDecoderConfig& config,
272 DemuxerStream* stream, 271 const PipelineStatusCB& status_cb) {
273 const PipelineStatusCB& status_cb,
274 const StatisticsCB& statistics_cb) {
275 DCHECK(task_runner_->BelongsToCurrentThread()); 272 DCHECK(task_runner_->BelongsToCurrentThread());
276 PipelineStatusCB initialize_cb = BindToCurrentLoop(status_cb); 273 PipelineStatusCB initialize_cb = BindToCurrentLoop(status_cb);
277 274
278 if (demuxer_stream_) {
279 // TODO(scherkus): initialization currently happens more than once in
280 // PipelineIntegrationTest.BasicPlayback.
281 DLOG(ERROR) << "Initialize has already been called.";
282 CHECK(false);
283 }
284
285 weak_this_ = weak_factory_.GetWeakPtr(); 275 weak_this_ = weak_factory_.GetWeakPtr();
286 demuxer_stream_ = stream; 276 config_ = config;
287 277
288 if (!ConfigureDecoder()) { 278 if (!ConfigureDecoder()) {
289 initialize_cb.Run(DECODER_ERROR_NOT_SUPPORTED); 279 initialize_cb.Run(DECODER_ERROR_NOT_SUPPORTED);
290 return; 280 return;
291 } 281 }
292 282
293 statistics_cb_ = statistics_cb;
294 initialize_cb.Run(PIPELINE_OK); 283 initialize_cb.Run(PIPELINE_OK);
295 } 284 }
296 285
297 void OpusAudioDecoder::Read(const ReadCB& read_cb) { 286 void OpusAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer,
287 const DecodeCB& decode_cb) {
298 DCHECK(task_runner_->BelongsToCurrentThread()); 288 DCHECK(task_runner_->BelongsToCurrentThread());
299 DCHECK(!read_cb.is_null()); 289 DCHECK(!decode_cb.is_null());
300 CHECK(read_cb_.is_null()) << "Overlapping decodes are not supported.";
301 DCHECK(stop_cb_.is_null());
302 read_cb_ = BindToCurrentLoop(read_cb);
303 290
304 ReadFromDemuxerStream(); 291 DecodeBuffer(buffer, BindToCurrentLoop(decode_cb));
305 } 292 }
306 293
307 int OpusAudioDecoder::bits_per_channel() { 294 int OpusAudioDecoder::bits_per_channel() {
308 DCHECK(task_runner_->BelongsToCurrentThread()); 295 DCHECK(task_runner_->BelongsToCurrentThread());
309 return bits_per_channel_; 296 return bits_per_channel_;
310 } 297 }
311 298
312 ChannelLayout OpusAudioDecoder::channel_layout() { 299 ChannelLayout OpusAudioDecoder::channel_layout() {
313 DCHECK(task_runner_->BelongsToCurrentThread()); 300 DCHECK(task_runner_->BelongsToCurrentThread());
314 return channel_layout_; 301 return channel_layout_;
315 } 302 }
316 303
317 int OpusAudioDecoder::samples_per_second() { 304 int OpusAudioDecoder::samples_per_second() {
318 DCHECK(task_runner_->BelongsToCurrentThread()); 305 DCHECK(task_runner_->BelongsToCurrentThread());
319 return samples_per_second_; 306 return samples_per_second_;
320 } 307 }
321 308
322 void OpusAudioDecoder::Reset(const base::Closure& closure) { 309 void OpusAudioDecoder::Reset(const base::Closure& closure) {
323 DCHECK(task_runner_->BelongsToCurrentThread()); 310 DCHECK(task_runner_->BelongsToCurrentThread());
324 reset_cb_ = BindToCurrentLoop(closure);
325 311
326 // A demuxer read is pending, we'll wait until it finishes. 312 opus_multistream_decoder_ctl(opus_decoder_, OPUS_RESET_STATE);
327 if (!read_cb_.is_null()) 313 ResetTimestampState();
328 return; 314 task_runner_->PostTask(FROM_HERE, closure);
329
330 DoReset();
331 } 315 }
332 316
333 void OpusAudioDecoder::Stop(const base::Closure& closure) { 317 void OpusAudioDecoder::Stop(const base::Closure& closure) {
334 DCHECK(task_runner_->BelongsToCurrentThread()); 318 DCHECK(task_runner_->BelongsToCurrentThread());
335 stop_cb_ = BindToCurrentLoop(closure);
336 319
337 // A demuxer read is pending, we'll wait until it finishes. 320 opus_multistream_decoder_ctl(opus_decoder_, OPUS_RESET_STATE);
338 if (!read_cb_.is_null()) 321 ResetTimestampState();
339 return; 322 CloseDecoder();
340 323 task_runner_->PostTask(FROM_HERE, closure);
xhwang 2014/03/05 00:40:46 Nice!
341 if (!reset_cb_.is_null()) {
342 DoReset();
343 return;
344 }
345
346 DoStop();
347 } 324 }
348 325
349 OpusAudioDecoder::~OpusAudioDecoder() {} 326 OpusAudioDecoder::~OpusAudioDecoder() {}
350 327
351 void OpusAudioDecoder::DoReset() { 328 void OpusAudioDecoder::DecodeBuffer(
352 DCHECK(!reset_cb_.is_null()); 329 const scoped_refptr<DecoderBuffer>& input,
330 const DecodeCB& decode_cb) {
331 DCHECK(task_runner_->BelongsToCurrentThread());
332 DCHECK(!decode_cb.is_null());
353 333
354 opus_multistream_decoder_ctl(opus_decoder_, OPUS_RESET_STATE);
355 ResetTimestampState();
356 base::ResetAndReturn(&reset_cb_).Run();
357
358 if (!stop_cb_.is_null())
359 DoStop();
360 }
361
362 void OpusAudioDecoder::DoStop() {
363 DCHECK(!stop_cb_.is_null());
364
365 opus_multistream_decoder_ctl(opus_decoder_, OPUS_RESET_STATE);
366 ResetTimestampState();
367 CloseDecoder();
368 base::ResetAndReturn(&stop_cb_).Run();
369 }
370
371 void OpusAudioDecoder::ReadFromDemuxerStream() {
372 DCHECK(!read_cb_.is_null());
373 demuxer_stream_->Read(base::Bind(&OpusAudioDecoder::BufferReady, weak_this_));
374 }
375
376 void OpusAudioDecoder::BufferReady(
377 DemuxerStream::Status status,
378 const scoped_refptr<DecoderBuffer>& input) {
379 DCHECK(task_runner_->BelongsToCurrentThread());
380 DCHECK(!read_cb_.is_null());
381 DCHECK_EQ(status != DemuxerStream::kOk, !input.get()) << status;
382
383 // Drop the buffer, fire |read_cb_| and complete the pending Reset().
384 // If there happens to also be a pending Stop(), that will be handled at
385 // the end of DoReset().
386 if (!reset_cb_.is_null()) {
387 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
388 DoReset();
389 return;
390 }
391
392 // Drop the buffer, fire |read_cb_| and complete the pending Stop().
393 if (!stop_cb_.is_null()) {
394 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
395 DoStop();
396 return;
397 }
398
399 if (status == DemuxerStream::kAborted) {
400 DCHECK(!input.get());
401 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
402 return;
403 }
404
405 if (status == DemuxerStream::kConfigChanged) {
406 DCHECK(!input.get());
407 DVLOG(1) << "Config changed.";
408
409 if (!ConfigureDecoder()) {
410 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL);
411 return;
412 }
413
414 ResetTimestampState();
415 ReadFromDemuxerStream();
416 return;
417 }
418
419 DCHECK_EQ(status, DemuxerStream::kOk);
420 DCHECK(input.get()); 334 DCHECK(input.get());
421 335
422 // Libopus does not buffer output. Decoding is complete when an end of stream 336 // Libopus does not buffer output. Decoding is complete when an end of stream
423 // input buffer is received. 337 // input buffer is received.
424 if (input->end_of_stream()) { 338 if (input->end_of_stream()) {
425 base::ResetAndReturn(&read_cb_).Run(kOk, AudioBuffer::CreateEOSBuffer()); 339 decode_cb.Run(kOk, AudioBuffer::CreateEOSBuffer());
426 return; 340 return;
427 } 341 }
428 342
429 // Make sure we are notified if http://crbug.com/49709 returns. Issue also 343 // Make sure we are notified if http://crbug.com/49709 returns. Issue also
430 // occurs with some damaged files. 344 // occurs with some damaged files.
431 if (input->timestamp() == kNoTimestamp() && 345 if (input->timestamp() == kNoTimestamp() &&
432 output_timestamp_helper_->base_timestamp() == kNoTimestamp()) { 346 output_timestamp_helper_->base_timestamp() == kNoTimestamp()) {
433 DLOG(ERROR) << "Received a buffer without timestamps!"; 347 DLOG(ERROR) << "Received a buffer without timestamps!";
434 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); 348 decode_cb.Run(kDecodeError, NULL);
435 return; 349 return;
436 } 350 }
437 351
438 if (last_input_timestamp_ != kNoTimestamp() && 352 if (last_input_timestamp_ != kNoTimestamp() &&
439 input->timestamp() != kNoTimestamp() && 353 input->timestamp() != kNoTimestamp() &&
440 input->timestamp() < last_input_timestamp_) { 354 input->timestamp() < last_input_timestamp_) {
441 base::TimeDelta diff = input->timestamp() - last_input_timestamp_; 355 base::TimeDelta diff = input->timestamp() - last_input_timestamp_;
442 DLOG(ERROR) << "Input timestamps are not monotonically increasing! " 356 DLOG(ERROR) << "Input timestamps are not monotonically increasing! "
443 << " ts " << input->timestamp().InMicroseconds() << " us" 357 << " ts " << input->timestamp().InMicroseconds() << " us"
444 << " diff " << diff.InMicroseconds() << " us"; 358 << " diff " << diff.InMicroseconds() << " us";
445 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); 359 decode_cb.Run(kDecodeError, NULL);
446 return; 360 return;
447 } 361 }
448 362
449 // Apply the necessary codec delay. 363 // Apply the necessary codec delay.
450 if (start_input_timestamp_ == kNoTimestamp()) 364 if (start_input_timestamp_ == kNoTimestamp())
451 start_input_timestamp_ = input->timestamp(); 365 start_input_timestamp_ = input->timestamp();
452 if (last_input_timestamp_ == kNoTimestamp() && 366 if (last_input_timestamp_ == kNoTimestamp() &&
453 input->timestamp() == start_input_timestamp_) { 367 input->timestamp() == start_input_timestamp_) {
454 frames_to_discard_ = frame_delay_at_start_; 368 frames_to_discard_ = frame_delay_at_start_;
455 } 369 }
456 370
457 last_input_timestamp_ = input->timestamp(); 371 last_input_timestamp_ = input->timestamp();
458 372
459 scoped_refptr<AudioBuffer> output_buffer; 373 scoped_refptr<AudioBuffer> output_buffer;
460 374
461 if (!Decode(input, &output_buffer)) { 375 if (!Decode(input, &output_buffer)) {
462 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); 376 decode_cb.Run(kDecodeError, NULL);
463 return; 377 return;
464 } 378 }
465 379
466 if (output_buffer.get()) { 380 if (output_buffer.get()) {
467 // Execute callback to return the decoded audio. 381 // Execute callback to return the decoded audio.
468 base::ResetAndReturn(&read_cb_).Run(kOk, output_buffer); 382 decode_cb.Run(kOk, output_buffer);
469 } else { 383 } else {
470 // We exhausted the input data, but it wasn't enough for a frame. Ask for 384 // We exhausted the input data, but it wasn't enough for a frame.
471 // more data in order to fulfill this read. 385 decode_cb.Run(kNotEnoughData, NULL);
472 ReadFromDemuxerStream();
473 } 386 }
474 } 387 }
475 388
476 bool OpusAudioDecoder::ConfigureDecoder() { 389 bool OpusAudioDecoder::ConfigureDecoder() {
477 const AudioDecoderConfig& config = demuxer_stream_->audio_decoder_config(); 390 if (config_.codec() != kCodecOpus) {
478
479 if (config.codec() != kCodecOpus) {
480 DVLOG(1) << "Codec must be kCodecOpus."; 391 DVLOG(1) << "Codec must be kCodecOpus.";
481 return false; 392 return false;
482 } 393 }
483 394
484 const int channel_count = 395 const int channel_count =
485 ChannelLayoutToChannelCount(config.channel_layout()); 396 ChannelLayoutToChannelCount(config_.channel_layout());
486 if (!config.IsValidConfig() || channel_count > kMaxVorbisChannels) { 397 if (!config_.IsValidConfig() || channel_count > kMaxVorbisChannels) {
487 DLOG(ERROR) << "Invalid or unsupported audio stream -" 398 DLOG(ERROR) << "Invalid or unsupported audio stream -"
488 << " codec: " << config.codec() 399 << " codec: " << config_.codec()
489 << " channel count: " << channel_count 400 << " channel count: " << channel_count
490 << " channel layout: " << config.channel_layout() 401 << " channel layout: " << config_.channel_layout()
491 << " bits per channel: " << config.bits_per_channel() 402 << " bits per channel: " << config_.bits_per_channel()
492 << " samples per second: " << config.samples_per_second(); 403 << " samples per second: " << config_.samples_per_second();
493 return false; 404 return false;
494 } 405 }
495 406
496 if (config.is_encrypted()) { 407 if (config_.is_encrypted()) {
497 DLOG(ERROR) << "Encrypted audio stream not supported."; 408 DLOG(ERROR) << "Encrypted audio stream not supported.";
498 return false; 409 return false;
499 } 410 }
500 411
412 // TODO(rileya) Remove this check once we properly support midstream audio
413 // config changes.
501 if (opus_decoder_ && 414 if (opus_decoder_ &&
502 (channel_layout_ != config.channel_layout() || 415 (channel_layout_ != config_.channel_layout() ||
503 samples_per_second_ != config.samples_per_second())) { 416 samples_per_second_ != config_.samples_per_second())) {
504 DLOG(ERROR) << "Unsupported config change -" 417 DLOG(ERROR) << "Unsupported config change -"
505 << ", channel_layout: " << channel_layout_ 418 << ", channel_layout: " << channel_layout_
506 << " -> " << config.channel_layout() 419 << " -> " << config_.channel_layout()
507 << ", sample_rate: " << samples_per_second_ 420 << ", sample_rate: " << samples_per_second_
508 << " -> " << config.samples_per_second(); 421 << " -> " << config_.samples_per_second();
509 return false; 422 return false;
510 } 423 }
511 424
512 // Clean up existing decoder if necessary. 425 // Clean up existing decoder if necessary.
513 CloseDecoder(); 426 CloseDecoder();
514 427
515 // Parse the Opus Extra Data. 428 // Parse the Opus Extra Data.
516 OpusExtraData opus_extra_data; 429 OpusExtraData opus_extra_data;
517 if (!ParseOpusExtraData(config.extra_data(), config.extra_data_size(), 430 if (!ParseOpusExtraData(config_.extra_data(), config_.extra_data_size(),
518 config, 431 config_,
519 &opus_extra_data)) 432 &opus_extra_data))
520 return false; 433 return false;
521 434
522 // Convert from seconds to samples. 435 // Convert from seconds to samples.
523 timestamp_offset_ = config.codec_delay(); 436 timestamp_offset_ = config_.codec_delay();
524 frame_delay_at_start_ = TimeDeltaToAudioFrames(config.codec_delay(), 437 frame_delay_at_start_ = TimeDeltaToAudioFrames(config_.codec_delay(),
525 config.samples_per_second()); 438 config_.samples_per_second());
526 if (timestamp_offset_ <= base::TimeDelta() || frame_delay_at_start_ < 0) { 439 if (timestamp_offset_ <= base::TimeDelta() || frame_delay_at_start_ < 0) {
527 DLOG(ERROR) << "Invalid file. Incorrect value for codec delay: " 440 DLOG(ERROR) << "Invalid file. Incorrect value for codec delay: "
528 << config.codec_delay().InMicroseconds(); 441 << config_.codec_delay().InMicroseconds();
529 return false; 442 return false;
530 } 443 }
531 444
532 if (frame_delay_at_start_ != opus_extra_data.skip_samples) { 445 if (frame_delay_at_start_ != opus_extra_data.skip_samples) {
533 DLOG(ERROR) << "Invalid file. Codec Delay in container does not match the " 446 DLOG(ERROR) << "Invalid file. Codec Delay in container does not match the "
534 << "value in Opus Extra Data."; 447 << "value in Opus Extra Data.";
535 return false; 448 return false;
536 } 449 }
537 450
538 uint8 channel_mapping[kMaxVorbisChannels] = {0}; 451 uint8 channel_mapping[kMaxVorbisChannels] = {0};
539 memcpy(&channel_mapping, 452 memcpy(&channel_mapping,
540 kDefaultOpusChannelLayout, 453 kDefaultOpusChannelLayout,
541 kMaxChannelsWithDefaultLayout); 454 kMaxChannelsWithDefaultLayout);
542 455
543 if (channel_count > kMaxChannelsWithDefaultLayout) { 456 if (channel_count > kMaxChannelsWithDefaultLayout) {
544 RemapOpusChannelLayout(opus_extra_data.stream_map, 457 RemapOpusChannelLayout(opus_extra_data.stream_map,
545 channel_count, 458 channel_count,
546 channel_mapping); 459 channel_mapping);
547 } 460 }
548 461
549 // Init Opus. 462 // Init Opus.
550 int status = OPUS_INVALID_STATE; 463 int status = OPUS_INVALID_STATE;
551 opus_decoder_ = opus_multistream_decoder_create(config.samples_per_second(), 464 opus_decoder_ = opus_multistream_decoder_create(config_.samples_per_second(),
552 channel_count, 465 channel_count,
553 opus_extra_data.num_streams, 466 opus_extra_data.num_streams,
554 opus_extra_data.num_coupled, 467 opus_extra_data.num_coupled,
555 channel_mapping, 468 channel_mapping,
556 &status); 469 &status);
557 if (!opus_decoder_ || status != OPUS_OK) { 470 if (!opus_decoder_ || status != OPUS_OK) {
558 DLOG(ERROR) << "opus_multistream_decoder_create failed status=" 471 DLOG(ERROR) << "opus_multistream_decoder_create failed status="
559 << opus_strerror(status); 472 << opus_strerror(status);
560 return false; 473 return false;
561 } 474 }
562 475
563 status = opus_multistream_decoder_ctl( 476 status = opus_multistream_decoder_ctl(
564 opus_decoder_, OPUS_SET_GAIN(opus_extra_data.gain_db)); 477 opus_decoder_, OPUS_SET_GAIN(opus_extra_data.gain_db));
565 if (status != OPUS_OK) { 478 if (status != OPUS_OK) {
566 DLOG(ERROR) << "Failed to set OPUS header gain; status=" 479 DLOG(ERROR) << "Failed to set OPUS header gain; status="
567 << opus_strerror(status); 480 << opus_strerror(status);
568 return false; 481 return false;
569 } 482 }
570 483
571 channel_layout_ = config.channel_layout(); 484 channel_layout_ = config_.channel_layout();
572 samples_per_second_ = config.samples_per_second(); 485 samples_per_second_ = config_.samples_per_second();
573 output_timestamp_helper_.reset( 486 output_timestamp_helper_.reset(
574 new AudioTimestampHelper(config.samples_per_second())); 487 new AudioTimestampHelper(config_.samples_per_second()));
575 start_input_timestamp_ = kNoTimestamp(); 488 start_input_timestamp_ = kNoTimestamp();
576 return true; 489 return true;
577 } 490 }
578 491
579 void OpusAudioDecoder::CloseDecoder() { 492 void OpusAudioDecoder::CloseDecoder() {
580 if (opus_decoder_) { 493 if (opus_decoder_) {
581 opus_multistream_decoder_destroy(opus_decoder_); 494 opus_multistream_decoder_destroy(opus_decoder_);
582 opus_decoder_ = NULL; 495 opus_decoder_ = NULL;
583 } 496 }
584 } 497 }
585 498
586 void OpusAudioDecoder::ResetTimestampState() { 499 void OpusAudioDecoder::ResetTimestampState() {
587 output_timestamp_helper_->SetBaseTimestamp(kNoTimestamp()); 500 output_timestamp_helper_->SetBaseTimestamp(kNoTimestamp());
588 last_input_timestamp_ = kNoTimestamp(); 501 last_input_timestamp_ = kNoTimestamp();
589 frames_to_discard_ = TimeDeltaToAudioFrames( 502 frames_to_discard_ =
590 demuxer_stream_->audio_decoder_config().seek_preroll(), 503 TimeDeltaToAudioFrames(config_.seek_preroll(), samples_per_second_);
591 samples_per_second_);
592 } 504 }
593 505
594 bool OpusAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& input, 506 bool OpusAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& input,
595 scoped_refptr<AudioBuffer>* output_buffer) { 507 scoped_refptr<AudioBuffer>* output_buffer) {
596 // Allocate a buffer for the output samples. 508 // Allocate a buffer for the output samples.
597 *output_buffer = AudioBuffer::CreateBuffer( 509 *output_buffer = AudioBuffer::CreateBuffer(
598 sample_format_, 510 sample_format_,
599 ChannelLayoutToChannelCount(channel_layout_), 511 ChannelLayoutToChannelCount(channel_layout_),
600 kMaxOpusOutputPacketSizeSamples); 512 kMaxOpusOutputPacketSizeSamples);
601 const int buffer_size = 513 const int buffer_size =
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 return false; 562 return false;
651 } 563 }
652 output_buffer->get()->TrimEnd(discard_padding); 564 output_buffer->get()->TrimEnd(discard_padding);
653 frames_to_output -= discard_padding; 565 frames_to_output -= discard_padding;
654 } 566 }
655 } else { 567 } else {
656 frames_to_discard_ -= frames_to_output; 568 frames_to_discard_ -= frames_to_output;
657 frames_to_output = 0; 569 frames_to_output = 0;
658 } 570 }
659 571
660 // Decoding finished successfully, update statistics.
661 PipelineStatistics statistics;
662 statistics.audio_bytes_decoded = input->data_size();
663 statistics_cb_.Run(statistics);
664
665 // Assign timestamp and duration to the buffer. 572 // Assign timestamp and duration to the buffer.
666 output_buffer->get()->set_timestamp( 573 output_buffer->get()->set_timestamp(
667 output_timestamp_helper_->GetTimestamp() - timestamp_offset_); 574 output_timestamp_helper_->GetTimestamp() - timestamp_offset_);
668 output_buffer->get()->set_duration( 575 output_buffer->get()->set_duration(
669 output_timestamp_helper_->GetFrameDuration(frames_to_output)); 576 output_timestamp_helper_->GetFrameDuration(frames_to_output));
670 output_timestamp_helper_->AddFrames(frames_decoded); 577 output_timestamp_helper_->AddFrames(frames_decoded);
671 578
672 // Discard the buffer to indicate we need more data. 579 // Discard the buffer to indicate we need more data.
673 if (!frames_to_output) 580 if (!frames_to_output)
674 *output_buffer = NULL; 581 *output_buffer = NULL;
675 582
676 return true; 583 return true;
677 } 584 }
678 585
679 } // namespace media 586 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698