Chromium Code Reviews| 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 |