OLD | NEW |
---|---|
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 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
452 DVLOG(1) << "\tsample_rate : " << samples_per_second_ | 452 DVLOG(1) << "\tsample_rate : " << samples_per_second_ |
453 << " -> " << config.samples_per_second(); | 453 << " -> " << config.samples_per_second(); |
454 return false; | 454 return false; |
455 } | 455 } |
456 | 456 |
457 // Clean up existing decoder if necessary. | 457 // Clean up existing decoder if necessary. |
458 CloseDecoder(); | 458 CloseDecoder(); |
459 | 459 |
460 // Allocate the output buffer if necessary. | 460 // Allocate the output buffer if necessary. |
461 if (!output_buffer_) | 461 if (!output_buffer_) |
462 output_buffer_.reset(new int16[kMaxOpusOutputPacketSizeSamples]); | 462 output_buffer_.reset(new float[kMaxOpusOutputPacketSizeSamples]); |
463 | 463 |
464 // Parse the Opus Extra Data. | 464 // Parse the Opus Extra Data. |
465 OpusExtraData opus_extra_data; | 465 OpusExtraData opus_extra_data; |
466 if (!ParseOpusExtraData(config.extra_data(), config.extra_data_size(), | 466 if (!ParseOpusExtraData(config.extra_data(), config.extra_data_size(), |
467 config, | 467 config, |
468 &opus_extra_data)) | 468 &opus_extra_data)) |
469 return false; | 469 return false; |
470 | 470 |
471 if (!config.codec_delay().InMicroseconds()) | 471 if (!config.codec_delay().InMicroseconds()) |
472 return false; | 472 return false; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
528 void OpusAudioDecoder::ResetTimestampState() { | 528 void OpusAudioDecoder::ResetTimestampState() { |
529 output_timestamp_helper_->SetBaseTimestamp(kNoTimestamp()); | 529 output_timestamp_helper_->SetBaseTimestamp(kNoTimestamp()); |
530 last_input_timestamp_ = kNoTimestamp(); | 530 last_input_timestamp_ = kNoTimestamp(); |
531 frames_to_discard_ = TimeDeltaToAudioFrames( | 531 frames_to_discard_ = TimeDeltaToAudioFrames( |
532 demuxer_stream_->audio_decoder_config().seek_preroll(), | 532 demuxer_stream_->audio_decoder_config().seek_preroll(), |
533 samples_per_second_); | 533 samples_per_second_); |
534 } | 534 } |
535 | 535 |
536 bool OpusAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& input, | 536 bool OpusAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& input, |
537 scoped_refptr<AudioBuffer>* output_buffer) { | 537 scoped_refptr<AudioBuffer>* output_buffer) { |
538 int frames_decoded = opus_multistream_decode(opus_decoder_, | 538 int frames_decoded = |
539 input->data(), | 539 opus_multistream_decode_float(opus_decoder_, |
540 input->data_size(), | 540 input->data(), |
541 &output_buffer_[0], | 541 input->data_size(), |
542 kMaxOpusOutputPacketSizeSamples, | 542 &output_buffer_[0], |
543 0); | 543 kMaxOpusOutputPacketSizeSamples, |
544 0); | |
544 if (frames_decoded < 0) { | 545 if (frames_decoded < 0) { |
545 DVLOG(0) << "opus_multistream_decode failed for" | 546 DVLOG(0) << "opus_multistream_decode failed for" |
546 << " timestamp: " << input->timestamp().InMicroseconds() | 547 << " timestamp: " << input->timestamp().InMicroseconds() |
547 << " us, duration: " << input->duration().InMicroseconds() | 548 << " us, duration: " << input->duration().InMicroseconds() |
548 << " us, packet size: " << input->data_size() << " bytes with" | 549 << " us, packet size: " << input->data_size() << " bytes with" |
549 << " status: " << opus_strerror(frames_decoded); | 550 << " status: " << opus_strerror(frames_decoded); |
550 return false; | 551 return false; |
551 } | 552 } |
552 | 553 |
553 uint8* decoded_audio_data = reinterpret_cast<uint8*>(&output_buffer_[0]); | 554 uint8* decoded_audio_data = reinterpret_cast<uint8*>(&output_buffer_[0]); |
(...skipping 11 matching lines...) Expand all Loading... | |
565 // there is a seek to zero. | 566 // there is a seek to zero. |
566 // TODO(vigneshv): This should be checked for start of stream rather than | 567 // TODO(vigneshv): This should be checked for start of stream rather than |
567 // input timestamp of zero to accomodate streams that don't start at zero. | 568 // input timestamp of zero to accomodate streams that don't start at zero. |
568 if (input->timestamp() == base::TimeDelta()) | 569 if (input->timestamp() == base::TimeDelta()) |
569 frames_to_discard_ = frame_delay_at_start_; | 570 frames_to_discard_ = frame_delay_at_start_; |
570 | 571 |
571 if (bytes_decoded > 0 && frames_decoded > frames_to_discard_) { | 572 if (bytes_decoded > 0 && frames_decoded > frames_to_discard_) { |
572 // Copy the audio samples into an output buffer. | 573 // Copy the audio samples into an output buffer. |
573 uint8* data[] = { decoded_audio_data }; | 574 uint8* data[] = { decoded_audio_data }; |
574 *output_buffer = AudioBuffer::CopyFrom( | 575 *output_buffer = AudioBuffer::CopyFrom( |
575 kSampleFormatS16, | 576 kSampleFormatF32, |
576 ChannelLayoutToChannelCount(channel_layout_), | 577 ChannelLayoutToChannelCount(channel_layout_), |
577 frames_decoded, | 578 frames_decoded, |
578 data, | 579 data, |
579 output_timestamp_helper_->GetTimestamp() - timestamp_offset_, | 580 output_timestamp_helper_->GetTimestamp() - timestamp_offset_, |
580 output_timestamp_helper_->GetFrameDuration(frames_decoded)); | 581 output_timestamp_helper_->GetFrameDuration(frames_decoded)); |
581 output_timestamp_helper_->AddFrames(frames_decoded); | 582 output_timestamp_helper_->AddFrames(frames_decoded); |
582 if (frames_to_discard_ > 0) { | 583 if (frames_to_discard_ > 0) { |
583 output_buffer->get()->TrimStart(frames_to_discard_); | 584 output_buffer->get()->TrimStart(frames_to_discard_); |
584 frames_decoded -= frames_to_discard_; | 585 frames_decoded -= frames_to_discard_; |
585 frames_to_discard_ = 0; | 586 frames_to_discard_ = 0; |
586 } | 587 } |
587 if (input->discard_padding().InMicroseconds() > 0) { | 588 if (input->discard_padding().InMicroseconds() > 0) { |
588 int discard_padding = TimeDeltaToAudioFrames(input->discard_padding(), | 589 int discard_padding = TimeDeltaToAudioFrames(input->discard_padding(), |
589 samples_per_second_); | 590 samples_per_second_); |
590 if (discard_padding < 0 || discard_padding > frames_decoded) { | 591 if (discard_padding < 0 || discard_padding > frames_decoded) { |
591 DVLOG(1) << "Invalid file. Incorrect discard padding value."; | 592 DVLOG(1) << "Invalid file. Incorrect discard padding value."; |
592 return false; | 593 return false; |
593 } | 594 } |
594 output_buffer->get()->TrimEnd(discard_padding); | 595 output_buffer->get()->TrimEnd(discard_padding); |
595 frames_decoded -= discard_padding; | 596 frames_decoded -= discard_padding; |
596 } | 597 } |
597 } else if (bytes_decoded > 0) { | 598 } else if (bytes_decoded > 0) { |
598 frames_to_discard_ -= frames_decoded; | 599 frames_to_discard_ -= frames_decoded; |
599 frames_decoded = 0; | 600 frames_decoded = 0; |
600 } | 601 } |
601 | 602 |
602 // Decoding finished successfully, update statistics. | 603 // Decoding finished successfully, update statistics. |
603 PipelineStatistics statistics; | 604 PipelineStatistics statistics; |
604 statistics.audio_bytes_decoded = | 605 statistics.audio_bytes_decoded = bytes_decoded; |
vignesh
2013/12/11 20:10:18
not sure if this change is required. even though w
acolwell GONE FROM CHROMIUM
2013/12/11 20:22:32
This is actually still wrong. This stat is suppose
DaleCurtis
2013/12/11 22:19:36
Done.
| |
605 frames_decoded * | |
606 demuxer_stream_->audio_decoder_config().bytes_per_frame(); | |
607 statistics_cb_.Run(statistics); | 606 statistics_cb_.Run(statistics); |
608 | 607 |
608 // Discard the buffer to indicate we need more data. | |
609 if (!frames_decoded) | |
610 *output_buffer = NULL; | |
611 | |
609 return true; | 612 return true; |
610 } | 613 } |
611 | 614 |
612 } // namespace media | 615 } // namespace media |
OLD | NEW |