Chromium Code Reviews| Index: media/filters/android/media_codec_audio_decoder.cc |
| diff --git a/media/filters/android/media_codec_audio_decoder.cc b/media/filters/android/media_codec_audio_decoder.cc |
| index c818d88cb751f21ab3c227913c55d9fa1bd87909..03192890458769673c354865c329cacf23002d22 100644 |
| --- a/media/filters/android/media_codec_audio_decoder.cc |
| +++ b/media/filters/android/media_codec_audio_decoder.cc |
| @@ -4,6 +4,8 @@ |
| #include "media/filters/android/media_codec_audio_decoder.h" |
| +#include <cmath> |
| + |
| #include "base/android/build_info.h" |
| #include "base/bind.h" |
| #include "base/callback_helpers.h" |
| @@ -21,6 +23,7 @@ MediaCodecAudioDecoder::MediaCodecAudioDecoder( |
| scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
| : task_runner_(task_runner), |
| state_(STATE_UNINITIALIZED), |
| + is_passthrough_(false), |
| channel_count_(0), |
| channel_layout_(CHANNEL_LAYOUT_NONE), |
| sample_rate_(0), |
| @@ -60,11 +63,12 @@ void MediaCodecAudioDecoder::Initialize(const AudioDecoderConfig& config, |
| DCHECK_EQ(state_, STATE_UNINITIALIZED); |
| InitCB bound_init_cb = BindToCurrentLoop(init_cb); |
| + is_passthrough_ = (config.codec() == kCodecRaw); |
| // We can support only the codecs that AudioCodecBridge can decode. |
| - const bool is_codec_supported = config.codec() == kCodecVorbis || |
| - config.codec() == kCodecAAC || |
| - config.codec() == kCodecOpus; |
| + const bool is_codec_supported = |
| + config.codec() == kCodecVorbis || config.codec() == kCodecAAC || |
| + config.codec() == kCodecOpus || is_passthrough_; |
| if (!is_codec_supported) { |
| DVLOG(1) << "Unsuported codec " << GetCodecName(config.codec()); |
| bound_init_cb.Run(false); |
| @@ -297,6 +301,15 @@ void MediaCodecAudioDecoder::OnInputDataQueued(bool success) { |
| if (input_queue_.front().first->end_of_stream() && success) |
| return; |
| + if (is_passthrough_ && success) { |
| + scoped_refptr<DecoderBuffer> decoder_buffer = input_queue_.front().first; |
| + |
| + if (!decoder_buffer->end_of_stream()) { |
| + duration_queue_.push_back(std::make_pair(decoder_buffer->timestamp(), |
| + decoder_buffer->duration())); |
| + } |
| + } |
| + |
| input_queue_.front().second.Run(success ? DecodeStatus::OK |
| : DecodeStatus::DECODE_ERROR); |
| input_queue_.pop_front(); |
| @@ -355,12 +368,35 @@ bool MediaCodecAudioDecoder::OnDecodedFrame( |
| // Android MediaCodec can only output 16bit PCM audio. |
| const int bytes_per_frame = sizeof(uint16_t) * channel_count_; |
| - const size_t frame_count = out.size / bytes_per_frame; |
| + size_t frame_count = out.size / bytes_per_frame; |
| + |
| + if (is_passthrough_) { |
|
DaleCurtis
2016/11/01 23:05:13
Didn't we determine that this is all CBR? So we kn
AndyWu
2016/11/04 18:04:24
Could you please advise how to get audio bit rate?
|
| + // Retrieve duratioin information from PTS-duration pair queue. |
| + base::TimeDelta duration; |
| + while (!duration_queue_.empty()) { |
| + PtsDurationPair pts_duration = duration_queue_.front(); |
| + duration_queue_.pop_front(); |
| + |
| + base::TimeDelta diff = pts_duration.first - out.pts; |
| + if (diff.magnitude() < base::TimeDelta::FromMicroseconds(1)) { |
| + duration = pts_duration.second; |
| + break; |
| + } |
| + } |
| + |
| + // Calculate the frame count of this compressed audio buffer. |
| + frame_count = |
| + std::round(config_.samples_per_second() * duration.InSecondsF()); |
| + } |
| + |
| + const SampleFormat sample_format = |
| + is_passthrough_ ? kSampleFormatRaw : kSampleFormatS16; |
| + const size_t size = is_passthrough_ ? out.size : 0; |
| // Create AudioOutput buffer based on current parameters. |
| scoped_refptr<AudioBuffer> audio_buffer = |
| - AudioBuffer::CreateBuffer(kSampleFormatS16, channel_layout_, |
| - channel_count_, sample_rate_, frame_count); |
| + AudioBuffer::CreateBuffer(sample_format, channel_layout_, channel_count_, |
| + sample_rate_, frame_count, size); |
| // Copy data into AudioBuffer. |
| CHECK_LE(out.size, audio_buffer->data_size()); |