Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(256)

Side by Side Diff: media/filters/ffmpeg_audio_decoder.cc

Issue 7867051: Introduce AudioDecoderConfig to migrate away from GetAVStream(). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: blam Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/ffmpeg_audio_decoder.h" 5 #include "media/filters/ffmpeg_audio_decoder.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "media/base/data_buffer.h" 8 #include "media/base/data_buffer.h"
9 #include "media/base/demuxer.h" 9 #include "media/base/demuxer.h"
10 #include "media/base/filter_host.h" 10 #include "media/base/filter_host.h"
11 #include "media/base/limits.h"
12 #include "media/ffmpeg/ffmpeg_common.h" 11 #include "media/ffmpeg/ffmpeg_common.h"
13 12
14 namespace media { 13 namespace media {
15 14
16 // Returns true if the decode result was an error. 15 // Returns true if the decode result was an error.
17 static bool IsErrorResult(int result, int decoded_size) { 16 static bool IsErrorResult(int result, int decoded_size) {
18 return result < 0 || 17 return result < 0 ||
19 decoded_size < 0 || 18 decoded_size < 0 ||
20 decoded_size > AVCODEC_MAX_AUDIO_FRAME_SIZE; 19 decoded_size > AVCODEC_MAX_AUDIO_FRAME_SIZE;
21 } 20 }
(...skipping 29 matching lines...) Expand all
51 bits_per_channel_(0), 50 bits_per_channel_(0),
52 channel_layout_(CHANNEL_LAYOUT_NONE), 51 channel_layout_(CHANNEL_LAYOUT_NONE),
53 sample_rate_(0), 52 sample_rate_(0),
54 decoded_audio_size_(AVCODEC_MAX_AUDIO_FRAME_SIZE), 53 decoded_audio_size_(AVCODEC_MAX_AUDIO_FRAME_SIZE),
55 decoded_audio_(static_cast<uint8*>(av_malloc(decoded_audio_size_))), 54 decoded_audio_(static_cast<uint8*>(av_malloc(decoded_audio_size_))),
56 pending_reads_(0) { 55 pending_reads_(0) {
57 } 56 }
58 57
59 FFmpegAudioDecoder::~FFmpegAudioDecoder() { 58 FFmpegAudioDecoder::~FFmpegAudioDecoder() {
60 av_free(decoded_audio_); 59 av_free(decoded_audio_);
60
61 // XXX: should we require Stop() to be called? this might end up getting
62 // called on a random thread due to refcounting.
63 if (codec_context_) {
64 av_free(codec_context_->extradata);
65 avcodec_close(codec_context_);
66 av_free(codec_context_);
67 }
61 } 68 }
62 69
63 void FFmpegAudioDecoder::Flush(FilterCallback* callback) { 70 void FFmpegAudioDecoder::Flush(FilterCallback* callback) {
64 message_loop_->PostTask( 71 message_loop_->PostTask(
65 FROM_HERE, 72 FROM_HERE,
66 NewRunnableMethod(this, &FFmpegAudioDecoder::DoFlush, callback)); 73 NewRunnableMethod(this, &FFmpegAudioDecoder::DoFlush, callback));
67 } 74 }
68 75
69 void FFmpegAudioDecoder::Initialize( 76 void FFmpegAudioDecoder::Initialize(
70 DemuxerStream* stream, 77 DemuxerStream* stream,
(...skipping 27 matching lines...) Expand all
98 return sample_rate_; 105 return sample_rate_;
99 } 106 }
100 107
101 void FFmpegAudioDecoder::DoInitialize( 108 void FFmpegAudioDecoder::DoInitialize(
102 const scoped_refptr<DemuxerStream>& stream, 109 const scoped_refptr<DemuxerStream>& stream,
103 FilterCallback* callback, 110 FilterCallback* callback,
104 StatisticsCallback* stats_callback) { 111 StatisticsCallback* stats_callback) {
105 scoped_ptr<FilterCallback> c(callback); 112 scoped_ptr<FilterCallback> c(callback);
106 113
107 demuxer_stream_ = stream; 114 demuxer_stream_ = stream;
108 AVStream* av_stream = demuxer_stream_->GetAVStream(); 115 const AudioDecoderConfig& config = stream->audio_decoder_config();
109 CHECK(av_stream);
110
111 stats_callback_.reset(stats_callback); 116 stats_callback_.reset(stats_callback);
112 117
113 // Grab the AVStream's codec context and make sure we have sensible values. 118 if (!config.IsValidConfig()) {
Ami GONE FROM CHROMIUM 2011/09/20 20:34:50 This is better, but my point was that it would be
scherkus (not reviewing) 2011/09/21 18:19:16 You're right in that the correct place for this ch
114 codec_context_ = av_stream->codec;
115 int bps = av_get_bits_per_sample_fmt(codec_context_->sample_fmt);
116 if (codec_context_->channels <= 0 ||
117 codec_context_->channels > Limits::kMaxChannels ||
118 (codec_context_->channel_layout == 0 && codec_context_->channels > 2) ||
119 bps <= 0 || bps > Limits::kMaxBitsPerSample ||
120 codec_context_->sample_rate <= 0 ||
121 codec_context_->sample_rate > Limits::kMaxSampleRate) {
122 DLOG(ERROR) << "Invalid audio stream -" 119 DLOG(ERROR) << "Invalid audio stream -"
123 << " channels: " << codec_context_->channels 120 << " codec: " << config.codec()
124 << " channel layout:" << codec_context_->channel_layout 121 << " channel layout: " << config.channel_layout()
125 << " bps: " << bps 122 << " bits per channel: " << config.bits_per_channel()
126 << " sample rate: " << codec_context_->sample_rate; 123 << " sample rate: " << config.sample_rate();
127 124
128 host()->SetError(PIPELINE_ERROR_DECODE); 125 host()->SetError(DECODER_ERROR_NOT_SUPPORTED);
129 callback->Run(); 126 callback->Run();
130 return; 127 return;
131 } 128 }
132 129
133 // Serialize calls to avcodec_open(). 130 // Initialize AVCodecContext structure.
131 codec_context_ = avcodec_alloc_context();
132 AudioDecoderConfigToAVCodecContext(config, codec_context_);
133
134 AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id); 134 AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
135 if (!codec || avcodec_open(codec_context_, codec) < 0) { 135 if (!codec || avcodec_open(codec_context_, codec) < 0) {
136 DLOG(ERROR) << "Could not initialize audio decoder: " 136 DLOG(ERROR) << "Could not initialize audio decoder: "
137 << codec_context_->codec_id; 137 << codec_context_->codec_id;
138 138
139 host()->SetError(PIPELINE_ERROR_DECODE); 139 host()->SetError(DECODER_ERROR_NOT_SUPPORTED);
140 callback->Run(); 140 callback->Run();
141 return; 141 return;
142 } 142 }
143 143
144 // Success! 144 // Success!
145 bits_per_channel_ = av_get_bits_per_sample_fmt(codec_context_->sample_fmt); 145 bits_per_channel_ = config.bits_per_channel();
146 channel_layout_ = 146 channel_layout_ = config.channel_layout();
147 ChannelLayoutToChromeChannelLayout(codec_context_->channel_layout, 147 sample_rate_ = config.sample_rate();
148 codec_context_->channels);
149 sample_rate_ = codec_context_->sample_rate;
150 148
151 callback->Run(); 149 callback->Run();
152 } 150 }
153 151
154 void FFmpegAudioDecoder::DoFlush(FilterCallback* callback) { 152 void FFmpegAudioDecoder::DoFlush(FilterCallback* callback) {
155 avcodec_flush_buffers(codec_context_); 153 avcodec_flush_buffers(codec_context_);
156 estimated_next_timestamp_ = kNoTimestamp; 154 estimated_next_timestamp_ = kNoTimestamp;
157 155
158 callback->Run(); 156 callback->Run();
159 delete callback; 157 delete callback;
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 284
287 base::TimeDelta FFmpegAudioDecoder::CalculateDuration(int size) { 285 base::TimeDelta FFmpegAudioDecoder::CalculateDuration(int size) {
288 int64 denominator = ChannelLayoutToChannelCount(channel_layout_) * 286 int64 denominator = ChannelLayoutToChannelCount(channel_layout_) *
289 bits_per_channel_ / 8 * sample_rate_; 287 bits_per_channel_ / 8 * sample_rate_;
290 double microseconds = size / 288 double microseconds = size /
291 (denominator / static_cast<double>(base::Time::kMicrosecondsPerSecond)); 289 (denominator / static_cast<double>(base::Time::kMicrosecondsPerSecond));
292 return base::TimeDelta::FromMicroseconds(static_cast<int64>(microseconds)); 290 return base::TimeDelta::FromMicroseconds(static_cast<int64>(microseconds));
293 } 291 }
294 292
295 } // namespace media 293 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698