| Index: media/filters/opus_audio_decoder.cc
|
| diff --git a/media/filters/opus_audio_decoder.cc b/media/filters/opus_audio_decoder.cc
|
| index 115799ab71193fe829265268c3898a5cbbc6cf95..b3e903b2313ffde57e533247ee3022d87e632223 100644
|
| --- a/media/filters/opus_audio_decoder.cc
|
| +++ b/media/filters/opus_audio_decoder.cc
|
| @@ -4,6 +4,8 @@
|
|
|
| #include "media/filters/opus_audio_decoder.h"
|
|
|
| +#include <cmath>
|
| +
|
| #include "base/bind.h"
|
| #include "base/callback_helpers.h"
|
| #include "base/location.h"
|
| @@ -250,7 +252,6 @@ OpusAudioDecoder::OpusAudioDecoder(
|
| channel_layout_(CHANNEL_LAYOUT_NONE),
|
| samples_per_second_(0),
|
| last_input_timestamp_(kNoTimestamp()),
|
| - output_bytes_to_drop_(0),
|
| skip_samples_(0) {
|
| }
|
|
|
| @@ -457,10 +458,24 @@ bool OpusAudioDecoder::ConfigureDecoder() {
|
| config,
|
| &opus_header);
|
|
|
| - skip_samples_ = opus_header.skip_samples;
|
| -
|
| - if (skip_samples_ > 0)
|
| - output_bytes_to_drop_ = skip_samples_ * config.bytes_per_frame();
|
| + if (!config.codec_delay().InMicroseconds()) {
|
| + // TODO(vigneshv): Replace this with return false once ffmpeg demuxer code
|
| + // starts populating the config correctly.
|
| + skip_samples_ = opus_header.skip_samples;
|
| + } else {
|
| + // Convert from seconds to samples.
|
| + skip_samples_ = std::ceil(config.codec_delay().InMicroseconds() *
|
| + config.samples_per_second() / 1000000.0);
|
| + if (skip_samples_ < 0) {
|
| + DVLOG(1) << "Invalid file. Incorrect value for codec delay.";
|
| + return false;
|
| + }
|
| + if (skip_samples_ != opus_header.skip_samples) {
|
| + DVLOG(1) << "Invalid file. Codec Delay in container does not match the "
|
| + << "value in Opus header.";
|
| + return false;
|
| + }
|
| + }
|
|
|
| uint8 channel_mapping[kMaxVorbisChannels];
|
| memcpy(&channel_mapping,
|
| @@ -487,9 +502,6 @@ bool OpusAudioDecoder::ConfigureDecoder() {
|
| return false;
|
| }
|
|
|
| - // TODO(tomfinegan): Handle audio delay once the matroska spec is updated
|
| - // to represent the value.
|
| -
|
| bits_per_channel_ = config.bits_per_channel();
|
| channel_layout_ = config.channel_layout();
|
| samples_per_second_ = config.samples_per_second();
|
| @@ -508,7 +520,7 @@ void OpusAudioDecoder::CloseDecoder() {
|
| void OpusAudioDecoder::ResetTimestampState() {
|
| output_timestamp_helper_->SetBaseTimestamp(kNoTimestamp());
|
| last_input_timestamp_ = kNoTimestamp();
|
| - output_bytes_to_drop_ = 0;
|
| + skip_samples_ = 0;
|
| }
|
|
|
| bool OpusAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& input,
|
| @@ -539,16 +551,6 @@ bool OpusAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& input,
|
| output_timestamp_helper_->SetBaseTimestamp(input->timestamp());
|
| }
|
|
|
| - if (decoded_audio_size > 0 && output_bytes_to_drop_ > 0) {
|
| - int dropped_size = std::min(decoded_audio_size, output_bytes_to_drop_);
|
| - DCHECK_EQ(dropped_size % kBytesPerChannel, 0);
|
| - decoded_audio_data += dropped_size;
|
| - decoded_audio_size -= dropped_size;
|
| - output_bytes_to_drop_ -= dropped_size;
|
| - samples_decoded = decoded_audio_size /
|
| - demuxer_stream_->audio_decoder_config().bytes_per_frame();
|
| - }
|
| -
|
| if (decoded_audio_size > 0) {
|
| // Copy the audio samples into an output buffer.
|
| uint8* data[] = { decoded_audio_data };
|
| @@ -560,8 +562,28 @@ bool OpusAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& input,
|
| output_timestamp_helper_->GetTimestamp(),
|
| output_timestamp_helper_->GetFrameDuration(samples_decoded));
|
| output_timestamp_helper_->AddFrames(samples_decoded);
|
| + if (skip_samples_ > 0) {
|
| + int dropped_size = std::min(samples_decoded, skip_samples_);
|
| + output_buffer->get()->TrimStart(dropped_size);
|
| + skip_samples_ -= dropped_size;
|
| + samples_decoded -= dropped_size;
|
| + }
|
| + if (input->discard_padding().InMicroseconds() > 0) {
|
| + int discard_padding = std::ceil(
|
| + input->discard_padding().InMicroseconds() *
|
| + samples_per_second_ / 1000000.0);
|
| + if (discard_padding < 0 || discard_padding > samples_decoded) {
|
| + DVLOG(1) << "Invalid file. Incorrect discard padding value.";
|
| + return false;
|
| + }
|
| + output_buffer->get()->TrimEnd(std::min(samples_decoded, discard_padding));
|
| + samples_decoded -= discard_padding;
|
| + }
|
| }
|
|
|
| + decoded_audio_size =
|
| + samples_decoded *
|
| + demuxer_stream_->audio_decoder_config().bytes_per_frame();
|
| // Decoding finished successfully, update statistics.
|
| PipelineStatistics statistics;
|
| statistics.audio_bytes_decoded = decoded_audio_size;
|
|
|