Index: media/filters/ffmpeg_audio_decoder.cc |
diff --git a/media/filters/ffmpeg_audio_decoder.cc b/media/filters/ffmpeg_audio_decoder.cc |
index cb3f846078329514071f4791569be5aa59b7b128..d2086a833dd5a764586ec2d2430ba9154b442d81 100644 |
--- a/media/filters/ffmpeg_audio_decoder.cc |
+++ b/media/filters/ffmpeg_audio_decoder.cc |
@@ -8,7 +8,6 @@ |
#include "media/base/data_buffer.h" |
#include "media/base/demuxer.h" |
#include "media/base/filter_host.h" |
-#include "media/base/limits.h" |
#include "media/ffmpeg/ffmpeg_common.h" |
namespace media { |
@@ -50,7 +49,7 @@ FFmpegAudioDecoder::FFmpegAudioDecoder(MessageLoop* message_loop) |
codec_context_(NULL), |
bits_per_channel_(0), |
channel_layout_(CHANNEL_LAYOUT_NONE), |
- sample_rate_(0), |
+ samples_per_second_(0), |
decoded_audio_size_(AVCODEC_MAX_AUDIO_FRAME_SIZE), |
decoded_audio_(static_cast<uint8*>(av_malloc(decoded_audio_size_))), |
pending_reads_(0) { |
@@ -58,6 +57,14 @@ FFmpegAudioDecoder::FFmpegAudioDecoder(MessageLoop* message_loop) |
FFmpegAudioDecoder::~FFmpegAudioDecoder() { |
av_free(decoded_audio_); |
+ |
+ // XXX: should we require Stop() to be called? this might end up getting |
+ // called on a random thread due to refcounting. |
+ if (codec_context_) { |
+ av_free(codec_context_->extradata); |
+ avcodec_close(codec_context_); |
+ av_free(codec_context_); |
+ } |
} |
void FFmpegAudioDecoder::Flush(FilterCallback* callback) { |
@@ -94,8 +101,8 @@ ChannelLayout FFmpegAudioDecoder::channel_layout() { |
return channel_layout_; |
} |
-int FFmpegAudioDecoder::sample_rate() { |
- return sample_rate_; |
+int FFmpegAudioDecoder::samples_per_second() { |
+ return samples_per_second_; |
} |
void FFmpegAudioDecoder::DoInitialize( |
@@ -105,48 +112,41 @@ void FFmpegAudioDecoder::DoInitialize( |
scoped_ptr<FilterCallback> c(callback); |
demuxer_stream_ = stream; |
- AVStream* av_stream = demuxer_stream_->GetAVStream(); |
- CHECK(av_stream); |
- |
+ const AudioDecoderConfig& config = stream->audio_decoder_config(); |
stats_callback_.reset(stats_callback); |
- // Grab the AVStream's codec context and make sure we have sensible values. |
- codec_context_ = av_stream->codec; |
- int bps = av_get_bits_per_sample_fmt(codec_context_->sample_fmt); |
- if (codec_context_->channels <= 0 || |
- codec_context_->channels > Limits::kMaxChannels || |
- (codec_context_->channel_layout == 0 && codec_context_->channels > 2) || |
- bps <= 0 || bps > Limits::kMaxBitsPerSample || |
- codec_context_->sample_rate <= 0 || |
- codec_context_->sample_rate > Limits::kMaxSampleRate) { |
+ // TODO(scherkus): this check should go in PipelineImpl prior to creating |
+ // decoder objects. |
+ if (!config.IsValidConfig()) { |
DLOG(ERROR) << "Invalid audio stream -" |
- << " channels: " << codec_context_->channels |
- << " channel layout:" << codec_context_->channel_layout |
- << " bps: " << bps |
- << " sample rate: " << codec_context_->sample_rate; |
+ << " codec: " << config.codec() |
+ << " channel layout: " << config.channel_layout() |
+ << " bits per channel: " << config.bits_per_channel() |
+ << " samples per second: " << config.samples_per_second(); |
- host()->SetError(PIPELINE_ERROR_DECODE); |
+ host()->SetError(DECODER_ERROR_NOT_SUPPORTED); |
callback->Run(); |
return; |
} |
- // Serialize calls to avcodec_open(). |
+ // Initialize AVCodecContext structure. |
+ codec_context_ = avcodec_alloc_context(); |
+ AudioDecoderConfigToAVCodecContext(config, codec_context_); |
+ |
AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id); |
if (!codec || avcodec_open(codec_context_, codec) < 0) { |
DLOG(ERROR) << "Could not initialize audio decoder: " |
<< codec_context_->codec_id; |
- host()->SetError(PIPELINE_ERROR_DECODE); |
+ host()->SetError(DECODER_ERROR_NOT_SUPPORTED); |
callback->Run(); |
return; |
} |
// Success! |
- bits_per_channel_ = av_get_bits_per_sample_fmt(codec_context_->sample_fmt); |
- channel_layout_ = |
- ChannelLayoutToChromeChannelLayout(codec_context_->channel_layout, |
- codec_context_->channels); |
- sample_rate_ = codec_context_->sample_rate; |
+ bits_per_channel_ = config.bits_per_channel(); |
+ channel_layout_ = config.channel_layout(); |
+ samples_per_second_ = config.samples_per_second(); |
callback->Run(); |
} |
@@ -286,7 +286,7 @@ void FFmpegAudioDecoder::UpdateDurationAndTimestamp( |
base::TimeDelta FFmpegAudioDecoder::CalculateDuration(int size) { |
int64 denominator = ChannelLayoutToChannelCount(channel_layout_) * |
- bits_per_channel_ / 8 * sample_rate_; |
+ bits_per_channel_ / 8 * samples_per_second_; |
double microseconds = size / |
(denominator / static_cast<double>(base::Time::kMicrosecondsPerSecond)); |
return base::TimeDelta::FromMicroseconds(static_cast<int64>(microseconds)); |