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

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

Issue 141243003: Add AudioBufferStream. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@decoderstream_rebased
Patch Set: add TODOs Created 6 years, 10 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
OLDNEW
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/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 "base/callback_helpers.h" 8 #include "base/callback_helpers.h"
9 #include "base/location.h" 9 #include "base/location.h"
10 #include "base/single_thread_task_runner.h" 10 #include "base/single_thread_task_runner.h"
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 // AudioBuffer allocated, so unref it. 66 // AudioBuffer allocated, so unref it.
67 static void ReleaseAudioBufferImpl(void* opaque, uint8* data) { 67 static void ReleaseAudioBufferImpl(void* opaque, uint8* data) {
68 scoped_refptr<AudioBuffer> buffer; 68 scoped_refptr<AudioBuffer> buffer;
69 buffer.swap(reinterpret_cast<AudioBuffer**>(&opaque)); 69 buffer.swap(reinterpret_cast<AudioBuffer**>(&opaque));
70 } 70 }
71 71
72 FFmpegAudioDecoder::FFmpegAudioDecoder( 72 FFmpegAudioDecoder::FFmpegAudioDecoder(
73 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) 73 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
74 : task_runner_(task_runner), 74 : task_runner_(task_runner),
75 weak_factory_(this), 75 weak_factory_(this),
76 demuxer_stream_(NULL), 76 state_(kUninitialized),
77 bytes_per_channel_(0), 77 bytes_per_channel_(0),
78 channel_layout_(CHANNEL_LAYOUT_NONE), 78 channel_layout_(CHANNEL_LAYOUT_NONE),
79 channels_(0), 79 channels_(0),
80 samples_per_second_(0), 80 samples_per_second_(0),
81 av_sample_format_(0), 81 av_sample_format_(0),
82 last_input_timestamp_(kNoTimestamp()), 82 last_input_timestamp_(kNoTimestamp()),
83 output_frames_to_drop_(0) { 83 output_frames_to_drop_(0) {}
84
85 FFmpegAudioDecoder::~FFmpegAudioDecoder() {
86 DCHECK_EQ(state_, kUninitialized);
87 DCHECK(!codec_context_);
88 DCHECK(!av_frame_);
84 } 89 }
85 90
86 void FFmpegAudioDecoder::Initialize( 91 void FFmpegAudioDecoder::Initialize(const AudioDecoderConfig& config,
87 DemuxerStream* stream, 92 const PipelineStatusCB& status_cb) {
88 const PipelineStatusCB& status_cb,
89 const StatisticsCB& statistics_cb) {
90 DCHECK(task_runner_->BelongsToCurrentThread()); 93 DCHECK(task_runner_->BelongsToCurrentThread());
94 DCHECK(decode_cb_.is_null());
95 DCHECK(reset_cb_.is_null());
96 DCHECK(!config.is_encrypted());
97
98 FFmpegGlue::InitializeFFmpeg();
99 weak_this_ = weak_factory_.GetWeakPtr();
100
101 config_ = config;
91 PipelineStatusCB initialize_cb = BindToCurrentLoop(status_cb); 102 PipelineStatusCB initialize_cb = BindToCurrentLoop(status_cb);
92 103
93 FFmpegGlue::InitializeFFmpeg(); 104 if (!config.IsValidConfig() || !ConfigureDecoder()) {
94 105 initialize_cb.Run(DECODER_ERROR_NOT_SUPPORTED);
95 if (demuxer_stream_) {
96 // TODO(scherkus): initialization currently happens more than once in
97 // PipelineIntegrationTest.BasicPlayback.
98 LOG(ERROR) << "Initialize has already been called.";
99 CHECK(false);
100 }
101
102 weak_this_ = weak_factory_.GetWeakPtr();
103 demuxer_stream_ = stream;
104
105 if (!ConfigureDecoder()) {
106 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED);
107 return; 106 return;
108 } 107 }
109 108
110 statistics_cb_ = statistics_cb; 109 // Success!
110 state_ = kNormal;
111 initialize_cb.Run(PIPELINE_OK); 111 initialize_cb.Run(PIPELINE_OK);
112 } 112 }
113 113
114 void FFmpegAudioDecoder::Read(const ReadCB& read_cb) { 114 void FFmpegAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer,
115 const DecodeCB& decode_cb) {
115 DCHECK(task_runner_->BelongsToCurrentThread()); 116 DCHECK(task_runner_->BelongsToCurrentThread());
116 DCHECK(!read_cb.is_null()); 117 DCHECK(!decode_cb.is_null());
117 CHECK(read_cb_.is_null()) << "Overlapping decodes are not supported."; 118 CHECK_NE(state_, kUninitialized);
118 DCHECK(reset_cb_.is_null()); 119 CHECK(decode_cb_.is_null()) << "Overlapping decodes are not supported.";
119 DCHECK(stop_cb_.is_null()); 120 decode_cb_ = BindToCurrentLoop(decode_cb);
120 121
121 read_cb_ = BindToCurrentLoop(read_cb); 122 if (state_ == kError) {
122 123 base::ResetAndReturn(&decode_cb_).Run(kDecodeError, NULL);
123 // If we don't have any queued audio from the last packet we decoded, ask for
124 // more data from the demuxer to satisfy this read.
125 if (queued_audio_.empty()) {
126 ReadFromDemuxerStream();
127 return; 124 return;
128 } 125 }
129 126
130 base::ResetAndReturn(&read_cb_).Run( 127 // Return empty frames if decoding has finished.
131 queued_audio_.front().status, queued_audio_.front().buffer); 128 if (state_ == kDecodeFinished) {
132 queued_audio_.pop_front(); 129 base::ResetAndReturn(&decode_cb_).Run(kOk, AudioBuffer::CreateEOSBuffer());
130 return;
131 }
132
133 DecodeBuffer(buffer);
133 } 134 }
134 135
135 int FFmpegAudioDecoder::bits_per_channel() { 136 int FFmpegAudioDecoder::bits_per_channel() {
136 DCHECK(task_runner_->BelongsToCurrentThread());
137 return bytes_per_channel_ * 8; 137 return bytes_per_channel_ * 8;
138 } 138 }
139 139
140 ChannelLayout FFmpegAudioDecoder::channel_layout() { 140 ChannelLayout FFmpegAudioDecoder::channel_layout() {
141 DCHECK(task_runner_->BelongsToCurrentThread());
142 return channel_layout_; 141 return channel_layout_;
143 } 142 }
144 143
145 int FFmpegAudioDecoder::samples_per_second() { 144 int FFmpegAudioDecoder::samples_per_second() {
146 DCHECK(task_runner_->BelongsToCurrentThread());
147 return samples_per_second_; 145 return samples_per_second_;
148 } 146 }
149 147
150 void FFmpegAudioDecoder::Reset(const base::Closure& closure) { 148 void FFmpegAudioDecoder::Reset(const base::Closure& closure) {
151 DCHECK(task_runner_->BelongsToCurrentThread()); 149 DCHECK(task_runner_->BelongsToCurrentThread());
150 DCHECK(reset_cb_.is_null());
152 reset_cb_ = BindToCurrentLoop(closure); 151 reset_cb_ = BindToCurrentLoop(closure);
153 152
154 // A demuxer read is pending, we'll wait until it finishes. 153 // Defer the reset if a decode is pending.
155 if (!read_cb_.is_null()) 154 if (!decode_cb_.is_null())
156 return; 155 return;
157 156
158 DoReset(); 157 DoReset();
159 } 158 }
160 159
161 void FFmpegAudioDecoder::Stop(const base::Closure& closure) { 160 void FFmpegAudioDecoder::Stop(const base::Closure& closure) {
162 DCHECK(task_runner_->BelongsToCurrentThread()); 161 DCHECK(task_runner_->BelongsToCurrentThread());
163 stop_cb_ = BindToCurrentLoop(closure); 162 base::ScopedClosureRunner runner(BindToCurrentLoop(closure));
164 163
165 // A demuxer read is pending, we'll wait until it finishes. 164 if (state_ == kUninitialized)
166 if (!read_cb_.is_null())
167 return; 165 return;
168 166
169 if (!reset_cb_.is_null()) { 167 if (!decode_cb_.is_null()) {
170 DoReset(); 168 base::ResetAndReturn(&decode_cb_).Run(kAborted, NULL);
171 return; 169 // Reset is pending only when decode is pending.
170 if (!reset_cb_.is_null())
171 base::ResetAndReturn(&reset_cb_).Run();
172 } 172 }
173 173
174 DoStop(); 174 ReleaseFFmpegResources();
175 ResetTimestampState();
176 state_ = kUninitialized;
175 } 177 }
176 178
177 FFmpegAudioDecoder::~FFmpegAudioDecoder() {} 179 bool FFmpegAudioDecoder::HasQueuedData() const {
180 return !queued_audio_.empty();
181 }
178 182
183 // Callback called from within FFmpeg to allocate a buffer based on
184 // the dimensions of |codec_context|. See AVCodecContext.get_buffer2
185 // documentation inside FFmpeg.
179 int FFmpegAudioDecoder::GetAudioBuffer(AVCodecContext* codec, 186 int FFmpegAudioDecoder::GetAudioBuffer(AVCodecContext* codec,
180 AVFrame* frame, 187 AVFrame* frame,
181 int flags) { 188 int flags) {
182 // Since this routine is called by FFmpeg when a buffer is required for audio 189 // Since this routine is called by FFmpeg when a buffer is required for audio
183 // data, use the values supplied by FFmpeg (ignoring the current settings). 190 // data, use the values supplied by FFmpeg (ignoring the current settings).
184 // RunDecodeLoop() gets to determine if the buffer is useable or not. 191 // FFmpegDecode() gets to determine if the buffer is useable or not.
185 AVSampleFormat format = static_cast<AVSampleFormat>(frame->format); 192 AVSampleFormat format = static_cast<AVSampleFormat>(frame->format);
186 SampleFormat sample_format = AVSampleFormatToSampleFormat(format); 193 SampleFormat sample_format = AVSampleFormatToSampleFormat(format);
187 int channels = DetermineChannels(frame); 194 int channels = DetermineChannels(frame);
188 if ((channels <= 0) || (channels >= limits::kMaxChannels)) { 195 if ((channels <= 0) || (channels >= limits::kMaxChannels)) {
189 DLOG(ERROR) << "Requested number of channels (" << channels 196 DLOG(ERROR) << "Requested number of channels (" << channels
190 << ") exceeds limit."; 197 << ") exceeds limit.";
191 return AVERROR(EINVAL); 198 return AVERROR(EINVAL);
192 } 199 }
193 200
194 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format); 201 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 241
235 // Now create an AVBufferRef for the data just allocated. It will own the 242 // Now create an AVBufferRef for the data just allocated. It will own the
236 // reference to the AudioBuffer object. 243 // reference to the AudioBuffer object.
237 void* opaque = NULL; 244 void* opaque = NULL;
238 buffer.swap(reinterpret_cast<AudioBuffer**>(&opaque)); 245 buffer.swap(reinterpret_cast<AudioBuffer**>(&opaque));
239 frame->buf[0] = av_buffer_create( 246 frame->buf[0] = av_buffer_create(
240 frame->data[0], buffer_size_in_bytes, ReleaseAudioBufferImpl, opaque, 0); 247 frame->data[0], buffer_size_in_bytes, ReleaseAudioBufferImpl, opaque, 0);
241 return 0; 248 return 0;
242 } 249 }
243 250
244 void FFmpegAudioDecoder::DoStop() { 251 void FFmpegAudioDecoder::DoReset() {
245 DCHECK(task_runner_->BelongsToCurrentThread()); 252 DCHECK(decode_cb_.is_null());
246 DCHECK(!stop_cb_.is_null()); 253 DCHECK(!reset_cb_.is_null());
247 DCHECK(read_cb_.is_null());
248 DCHECK(reset_cb_.is_null());
249 254
255 avcodec_flush_buffers(codec_context_.get());
256 state_ = kNormal;
250 ResetTimestampState(); 257 ResetTimestampState();
251 queued_audio_.clear(); 258 base::ResetAndReturn(&reset_cb_).Run();
252 ReleaseFFmpegResources();
253 base::ResetAndReturn(&stop_cb_).Run();
254 } 259 }
255 260
256 void FFmpegAudioDecoder::DoReset() { 261 void FFmpegAudioDecoder::DecodeBuffer(
262 const scoped_refptr<DecoderBuffer>& buffer) {
257 DCHECK(task_runner_->BelongsToCurrentThread()); 263 DCHECK(task_runner_->BelongsToCurrentThread());
258 DCHECK(!reset_cb_.is_null()); 264 DCHECK_NE(state_, kUninitialized);
259 DCHECK(read_cb_.is_null()); 265 DCHECK_NE(state_, kDecodeFinished);
266 DCHECK_NE(state_, kError);
267 DCHECK(reset_cb_.is_null());
268 DCHECK(!decode_cb_.is_null());
260 269
261 avcodec_flush_buffers(codec_context_.get()); 270 if (!buffer) {
262 ResetTimestampState(); 271 DCHECK(!queued_audio_.empty());
263 queued_audio_.clear(); 272 base::ResetAndReturn(&decode_cb_)
264 base::ResetAndReturn(&reset_cb_).Run(); 273 .Run(queued_audio_.front().status, queued_audio_.front().buffer);
265
266 if (!stop_cb_.is_null())
267 DoStop();
268 }
269
270 void FFmpegAudioDecoder::ReadFromDemuxerStream() {
271 DCHECK(!read_cb_.is_null());
272 demuxer_stream_->Read(base::Bind(
273 &FFmpegAudioDecoder::BufferReady, weak_this_));
274 }
275
276 void FFmpegAudioDecoder::BufferReady(
277 DemuxerStream::Status status,
278 const scoped_refptr<DecoderBuffer>& input) {
279 DCHECK(task_runner_->BelongsToCurrentThread());
280 DCHECK(!read_cb_.is_null());
281 DCHECK(queued_audio_.empty());
282 DCHECK_EQ(status != DemuxerStream::kOk, !input.get()) << status;
283
284 // Pending Reset: ignore the buffer we just got, send kAborted to |read_cb_|
285 // and carry out the Reset().
286 // If there happens to also be a pending Stop(), that will be handled at
287 // the end of DoReset().
288 if (!reset_cb_.is_null()) {
289 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
290 DoReset();
291 return;
292 }
293
294 // Pending Stop: ignore the buffer we just got, send kAborted to |read_cb_|
295 // and carry out the Stop().
296 if (!stop_cb_.is_null()) {
297 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
298 DoStop();
299 return;
300 }
301
302 if (status == DemuxerStream::kAborted) {
303 DCHECK(!input.get());
304 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
305 return;
306 }
307
308 if (status == DemuxerStream::kConfigChanged) {
309 DCHECK(!input.get());
310
311 // Send a "end of stream" buffer to the decode loop
312 // to output any remaining data still in the decoder.
313 RunDecodeLoop(DecoderBuffer::CreateEOSBuffer(), true);
314
315 DVLOG(1) << "Config changed.";
316
317 if (!ConfigureDecoder()) {
318 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL);
319 return;
320 }
321
322 ResetTimestampState();
323
324 if (queued_audio_.empty()) {
325 ReadFromDemuxerStream();
326 return;
327 }
328
329 base::ResetAndReturn(&read_cb_).Run(
330 queued_audio_.front().status, queued_audio_.front().buffer);
331 queued_audio_.pop_front(); 274 queued_audio_.pop_front();
332 return; 275 return;
333 } 276 }
334 277
335 DCHECK_EQ(status, DemuxerStream::kOk); 278 DCHECK(buffer && queued_audio_.empty());
336 DCHECK(input.get()); 279
280 // During decode, because reads are issued asynchronously, it is possible to
281 // receive multiple end of stream buffers since each decode is acked. When the
282 // first end of stream buffer is read, FFmpeg may still have frames queued
283 // up in the decoder so we need to go through the decode loop until it stops
284 // giving sensible data. After that, the decoder should output empty
285 // frames. There are three states the decoder can be in:
286 //
287 // kNormal: This is the starting state. Buffers are decoded. Decode errors
288 // are discarded.
289 // kFlushCodec: There isn't any more input data. Call avcodec_decode_audio4
290 // until no more data is returned to flush out remaining
291 // frames. The input buffer is ignored at this point.
292 // kDecodeFinished: All calls return empty frames.
293 // kError: Unexpected error happened.
294 //
295 // These are the possible state transitions.
296 //
297 // kNormal -> kFlushCodec:
298 // When buffer->end_of_stream() is first true.
299 // kNormal -> kError:
300 // A decoding error occurs and decoding needs to stop.
301 // kFlushCodec -> kDecodeFinished:
302 // When avcodec_decode_audio4() returns 0 data.
303 // kFlushCodec -> kError:
304 // When avcodec_decode_audio4() errors out.
305 // (any state) -> kNormal:
306 // Any time Reset() is called.
337 307
338 // Make sure we are notified if http://crbug.com/49709 returns. Issue also 308 // Make sure we are notified if http://crbug.com/49709 returns. Issue also
339 // occurs with some damaged files. 309 // occurs with some damaged files.
340 if (!input->end_of_stream() && input->timestamp() == kNoTimestamp() && 310 if (!buffer->end_of_stream() && buffer->timestamp() == kNoTimestamp() &&
341 output_timestamp_helper_->base_timestamp() == kNoTimestamp()) { 311 output_timestamp_helper_->base_timestamp() == kNoTimestamp()) {
342 DVLOG(1) << "Received a buffer without timestamps!"; 312 DVLOG(1) << "Received a buffer without timestamps!";
343 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); 313 base::ResetAndReturn(&decode_cb_).Run(kDecodeError, NULL);
344 return; 314 return;
345 } 315 }
346 316
347 if (!input->end_of_stream()) { 317 if (!buffer->end_of_stream()) {
348 if (last_input_timestamp_ == kNoTimestamp() && 318 if (last_input_timestamp_ == kNoTimestamp() &&
349 codec_context_->codec_id == AV_CODEC_ID_VORBIS && 319 codec_context_->codec_id == AV_CODEC_ID_VORBIS &&
350 input->timestamp() < base::TimeDelta()) { 320 buffer->timestamp() < base::TimeDelta()) {
351 // Dropping frames for negative timestamps as outlined in section A.2 321 // Dropping frames for negative timestamps as outlined in section A.2
352 // in the Vorbis spec. http://xiph.org/vorbis/doc/Vorbis_I_spec.html 322 // in the Vorbis spec. http://xiph.org/vorbis/doc/Vorbis_I_spec.html
353 output_frames_to_drop_ = floor( 323 output_frames_to_drop_ = floor(
354 0.5 + -input->timestamp().InSecondsF() * samples_per_second_); 324 0.5 + -buffer->timestamp().InSecondsF() * samples_per_second_);
355 } else { 325 } else {
356 if (last_input_timestamp_ != kNoTimestamp() && 326 if (last_input_timestamp_ != kNoTimestamp() &&
357 input->timestamp() < last_input_timestamp_) { 327 buffer->timestamp() < last_input_timestamp_) {
358 const base::TimeDelta diff = input->timestamp() - last_input_timestamp_; 328 const base::TimeDelta diff =
329 buffer->timestamp() - last_input_timestamp_;
359 DLOG(WARNING) 330 DLOG(WARNING)
360 << "Input timestamps are not monotonically increasing! " 331 << "Input timestamps are not monotonically increasing! "
361 << " ts " << input->timestamp().InMicroseconds() << " us" 332 << " ts " << buffer->timestamp().InMicroseconds() << " us"
362 << " diff " << diff.InMicroseconds() << " us"; 333 << " diff " << diff.InMicroseconds() << " us";
363 } 334 }
364 335
365 last_input_timestamp_ = input->timestamp(); 336 last_input_timestamp_ = buffer->timestamp();
366 } 337 }
367 } 338 }
368 339
369 RunDecodeLoop(input, false); 340 // Transition to kFlushCodec on the first end of stream buffer.
341 if (state_ == kNormal && buffer->end_of_stream()) {
342 state_ = kFlushCodec;
343 }
370 344
371 // We exhausted the provided packet, but it wasn't enough for a frame. Ask 345 scoped_refptr<AudioBuffer> audio_buffer;
372 // for more data in order to fulfill this read. 346 if (!FFmpegDecode(buffer)) {
373 if (queued_audio_.empty()) { 347 state_ = kError;
374 ReadFromDemuxerStream(); 348 base::ResetAndReturn(&decode_cb_).Run(kDecodeError, NULL);
375 return; 349 return;
376 } 350 }
377 351
378 // Execute callback to return the first frame we decoded. 352 if (queued_audio_.empty()) {
379 base::ResetAndReturn(&read_cb_).Run( 353 if (state_ == kFlushCodec) {
380 queued_audio_.front().status, queued_audio_.front().buffer); 354 DCHECK(buffer->end_of_stream());
355 state_ = kDecodeFinished;
356 base::ResetAndReturn(&decode_cb_)
357 .Run(kOk, AudioBuffer::CreateEOSBuffer());
358 return;
359 }
360
361 base::ResetAndReturn(&decode_cb_).Run(kNotEnoughData, NULL);
362 return;
363 }
364
365 base::ResetAndReturn(&decode_cb_)
366 .Run(queued_audio_.front().status, queued_audio_.front().buffer);
381 queued_audio_.pop_front(); 367 queued_audio_.pop_front();
382 } 368 }
383 369
384 bool FFmpegAudioDecoder::ConfigureDecoder() { 370 bool FFmpegAudioDecoder::FFmpegDecode(
385 const AudioDecoderConfig& config = demuxer_stream_->audio_decoder_config(); 371 const scoped_refptr<DecoderBuffer>& buffer) {
386 372
387 if (!config.IsValidConfig()) { 373 DCHECK(queued_audio_.empty());
388 DLOG(ERROR) << "Invalid audio stream -"
389 << " codec: " << config.codec()
390 << " channel layout: " << config.channel_layout()
391 << " bits per channel: " << config.bits_per_channel()
392 << " samples per second: " << config.samples_per_second();
393 return false;
394 }
395 374
396 if (config.is_encrypted()) {
397 DLOG(ERROR) << "Encrypted audio stream not supported";
398 return false;
399 }
400
401 if (codec_context_.get() &&
402 (bytes_per_channel_ != config.bytes_per_channel() ||
403 channel_layout_ != config.channel_layout() ||
404 samples_per_second_ != config.samples_per_second())) {
405 DVLOG(1) << "Unsupported config change :";
406 DVLOG(1) << "\tbytes_per_channel : " << bytes_per_channel_
407 << " -> " << config.bytes_per_channel();
408 DVLOG(1) << "\tchannel_layout : " << channel_layout_
409 << " -> " << config.channel_layout();
410 DVLOG(1) << "\tsample_rate : " << samples_per_second_
411 << " -> " << config.samples_per_second();
412 return false;
413 }
414
415 // Release existing decoder resources if necessary.
416 ReleaseFFmpegResources();
417
418 // Initialize AVCodecContext structure.
419 codec_context_.reset(avcodec_alloc_context3(NULL));
420 AudioDecoderConfigToAVCodecContext(config, codec_context_.get());
421
422 codec_context_->opaque = this;
423 codec_context_->get_buffer2 = GetAudioBufferImpl;
424 codec_context_->refcounted_frames = 1;
425
426 AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
427 if (!codec || avcodec_open2(codec_context_.get(), codec, NULL) < 0) {
428 DLOG(ERROR) << "Could not initialize audio decoder: "
429 << codec_context_->codec_id;
430 return false;
431 }
432
433 // Success!
434 av_frame_.reset(av_frame_alloc());
435 channel_layout_ = config.channel_layout();
436 samples_per_second_ = config.samples_per_second();
437 output_timestamp_helper_.reset(
438 new AudioTimestampHelper(config.samples_per_second()));
439
440 // Store initial values to guard against midstream configuration changes.
441 channels_ = codec_context_->channels;
442 if (channels_ != ChannelLayoutToChannelCount(channel_layout_)) {
443 DLOG(ERROR) << "Audio configuration specified "
444 << ChannelLayoutToChannelCount(channel_layout_)
445 << " channels, but FFmpeg thinks the file contains "
446 << channels_ << " channels";
447 return false;
448 }
449 av_sample_format_ = codec_context_->sample_fmt;
450 sample_format_ = AVSampleFormatToSampleFormat(
451 static_cast<AVSampleFormat>(av_sample_format_));
452 bytes_per_channel_ = SampleFormatToBytesPerChannel(sample_format_);
453
454 return true;
455 }
456
457 void FFmpegAudioDecoder::ReleaseFFmpegResources() {
458 codec_context_.reset();
459 av_frame_.reset();
460 }
461
462 void FFmpegAudioDecoder::ResetTimestampState() {
463 output_timestamp_helper_->SetBaseTimestamp(kNoTimestamp());
464 last_input_timestamp_ = kNoTimestamp();
465 output_frames_to_drop_ = 0;
466 }
467
468 void FFmpegAudioDecoder::RunDecodeLoop(
469 const scoped_refptr<DecoderBuffer>& input,
470 bool skip_eos_append) {
471 AVPacket packet; 375 AVPacket packet;
472 av_init_packet(&packet); 376 av_init_packet(&packet);
473 if (input->end_of_stream()) { 377 if (buffer->end_of_stream()) {
474 packet.data = NULL; 378 packet.data = NULL;
475 packet.size = 0; 379 packet.size = 0;
476 } else { 380 } else {
477 packet.data = const_cast<uint8*>(input->data()); 381 packet.data = const_cast<uint8*>(buffer->data());
478 packet.size = input->data_size(); 382 packet.size = buffer->data_size();
479 } 383 }
480 384
481 // Each audio packet may contain several frames, so we must call the decoder 385 // Each audio packet may contain several frames, so we must call the decoder
482 // until we've exhausted the packet. Regardless of the packet size we always 386 // until we've exhausted the packet. Regardless of the packet size we always
483 // want to hand it to the decoder at least once, otherwise we would end up 387 // want to hand it to the decoder at least once, otherwise we would end up
484 // skipping end of stream packets since they have a size of zero. 388 // skipping end of stream packets since they have a size of zero.
485 do { 389 do {
486 int frame_decoded = 0; 390 int frame_decoded = 0;
487 int result = avcodec_decode_audio4( 391 int result = avcodec_decode_audio4(
488 codec_context_.get(), av_frame_.get(), &frame_decoded, &packet); 392 codec_context_.get(), av_frame_.get(), &frame_decoded, &packet);
489 393
490 if (result < 0) { 394 if (result < 0) {
491 DCHECK(!input->end_of_stream()) 395 DCHECK(!buffer->end_of_stream())
492 << "End of stream buffer produced an error! " 396 << "End of stream buffer produced an error! "
493 << "This is quite possibly a bug in the audio decoder not handling " 397 << "This is quite possibly a bug in the audio decoder not handling "
494 << "end of stream AVPackets correctly."; 398 << "end of stream AVPackets correctly.";
495 399
496 DLOG(WARNING) 400 DLOG(WARNING)
497 << "Failed to decode an audio frame with timestamp: " 401 << "Failed to decode an audio frame with timestamp: "
498 << input->timestamp().InMicroseconds() << " us, duration: " 402 << buffer->timestamp().InMicroseconds() << " us, duration: "
499 << input->duration().InMicroseconds() << " us, packet size: " 403 << buffer->duration().InMicroseconds() << " us, packet size: "
500 << input->data_size() << " bytes"; 404 << buffer->data_size() << " bytes";
501 405
502 break; 406 break;
503 } 407 }
504 408
505 // Update packet size and data pointer in case we need to call the decoder 409 // Update packet size and data pointer in case we need to call the decoder
506 // with the remaining bytes from this packet. 410 // with the remaining bytes from this packet.
507 packet.size -= result; 411 packet.size -= result;
508 packet.data += result; 412 packet.data += result;
509 413
510 if (output_timestamp_helper_->base_timestamp() == kNoTimestamp() && 414 if (output_timestamp_helper_->base_timestamp() == kNoTimestamp() &&
511 !input->end_of_stream()) { 415 !buffer->end_of_stream()) {
512 DCHECK(input->timestamp() != kNoTimestamp()); 416 DCHECK(buffer->timestamp() != kNoTimestamp());
513 if (output_frames_to_drop_ > 0) { 417 if (output_frames_to_drop_ > 0) {
514 // Currently Vorbis is the only codec that causes us to drop samples. 418 // Currently Vorbis is the only codec that causes us to drop samples.
515 // If we have to drop samples it always means the timeline starts at 0. 419 // If we have to drop samples it always means the timeline starts at 0.
516 DCHECK_EQ(codec_context_->codec_id, AV_CODEC_ID_VORBIS); 420 DCHECK_EQ(codec_context_->codec_id, AV_CODEC_ID_VORBIS);
517 output_timestamp_helper_->SetBaseTimestamp(base::TimeDelta()); 421 output_timestamp_helper_->SetBaseTimestamp(base::TimeDelta());
518 } else { 422 } else {
519 output_timestamp_helper_->SetBaseTimestamp(input->timestamp()); 423 output_timestamp_helper_->SetBaseTimestamp(buffer->timestamp());
520 } 424 }
521 } 425 }
522 426
523 scoped_refptr<AudioBuffer> output; 427 scoped_refptr<AudioBuffer> output;
524 int decoded_frames = 0; 428 int decoded_frames = 0;
525 int original_frames = 0; 429 int original_frames = 0;
526 int channels = DetermineChannels(av_frame_.get()); 430 int channels = DetermineChannels(av_frame_.get());
527 if (frame_decoded) { 431 if (frame_decoded) {
528 if (av_frame_->sample_rate != samples_per_second_ || 432
433 // TODO(rileya) Remove this check once we properly support midstream audio
434 // config changes.
435 if (av_frame_->sample_rate != config_.samples_per_second() ||
529 channels != channels_ || 436 channels != channels_ ||
530 av_frame_->format != av_sample_format_) { 437 av_frame_->format != av_sample_format_) {
531 DLOG(ERROR) << "Unsupported midstream configuration change!" 438 DLOG(ERROR) << "Unsupported midstream configuration change!"
532 << " Sample Rate: " << av_frame_->sample_rate << " vs " 439 << " Sample Rate: " << av_frame_->sample_rate << " vs "
533 << samples_per_second_ 440 << samples_per_second_
534 << ", Channels: " << channels << " vs " 441 << ", Channels: " << channels << " vs "
535 << channels_ 442 << channels_
536 << ", Sample Format: " << av_frame_->format << " vs " 443 << ", Sample Format: " << av_frame_->format << " vs "
537 << av_sample_format_; 444 << av_sample_format_;
538 445
539 // This is an unrecoverable error, so bail out. 446 // This is an unrecoverable error, so bail out.
540 QueuedAudioBuffer queue_entry = { kDecodeError, NULL }; 447 QueuedAudioBuffer queue_entry = { kDecodeError, NULL };
541 queued_audio_.push_back(queue_entry); 448 queued_audio_.push_back(queue_entry);
542 av_frame_unref(av_frame_.get()); 449 av_frame_unref(av_frame_.get());
543 break; 450 break;
544 } 451 }
545 452
546 // Get the AudioBuffer that the data was decoded into. Adjust the number 453 // Get the AudioBuffer that the data was decoded into. Adjust the number
547 // of frames, in case fewer than requested were actually decoded. 454 // of frames, in case fewer than requested were actually decoded.
548 output = reinterpret_cast<AudioBuffer*>( 455 output = reinterpret_cast<AudioBuffer*>(
549 av_buffer_get_opaque(av_frame_->buf[0])); 456 av_buffer_get_opaque(av_frame_->buf[0]));
457
550 DCHECK_EQ(channels_, output->channel_count()); 458 DCHECK_EQ(channels_, output->channel_count());
551 original_frames = av_frame_->nb_samples; 459 original_frames = av_frame_->nb_samples;
552 int unread_frames = output->frame_count() - original_frames; 460 int unread_frames = output->frame_count() - original_frames;
553 DCHECK_GE(unread_frames, 0); 461 DCHECK_GE(unread_frames, 0);
554 if (unread_frames > 0) 462 if (unread_frames > 0)
555 output->TrimEnd(unread_frames); 463 output->TrimEnd(unread_frames);
556 464
557 // If there are frames to drop, get rid of as many as we can. 465 // If there are frames to drop, get rid of as many as we can.
558 if (output_frames_to_drop_ > 0) { 466 if (output_frames_to_drop_ > 0) {
559 int drop = std::min(output->frame_count(), output_frames_to_drop_); 467 int drop = std::min(output->frame_count(), output_frames_to_drop_);
560 output->TrimStart(drop); 468 output->TrimStart(drop);
561 output_frames_to_drop_ -= drop; 469 output_frames_to_drop_ -= drop;
562 } 470 }
563 471
564 decoded_frames = output->frame_count(); 472 decoded_frames = output->frame_count();
565 av_frame_unref(av_frame_.get()); 473 av_frame_unref(av_frame_.get());
566 } 474 }
567 475
568 // WARNING: |av_frame_| no longer has valid data at this point. 476 // WARNING: |av_frame_| no longer has valid data at this point.
569 477
570 if (decoded_frames > 0) { 478 if (decoded_frames > 0) {
571 // Set the timestamp/duration once all the extra frames have been 479 // Set the timestamp/duration once all the extra frames have been
572 // discarded. 480 // discarded.
573 output->set_timestamp(output_timestamp_helper_->GetTimestamp()); 481 output->set_timestamp(output_timestamp_helper_->GetTimestamp());
574 output->set_duration( 482 output->set_duration(
575 output_timestamp_helper_->GetFrameDuration(decoded_frames)); 483 output_timestamp_helper_->GetFrameDuration(decoded_frames));
576 output_timestamp_helper_->AddFrames(decoded_frames); 484 output_timestamp_helper_->AddFrames(decoded_frames);
577 } else if (IsEndOfStream(result, original_frames, input) && 485 } else if (IsEndOfStream(result, original_frames, buffer)) {
578 !skip_eos_append) {
579 DCHECK_EQ(packet.size, 0); 486 DCHECK_EQ(packet.size, 0);
580 output = AudioBuffer::CreateEOSBuffer(); 487 output = AudioBuffer::CreateEOSBuffer();
581 } else { 488 } else {
582 // In case all the frames in the buffer were dropped. 489 // In case all the frames in the buffer were dropped.
583 output = NULL; 490 output = NULL;
584 } 491 }
585 492
586 if (output.get()) { 493 if (output.get()) {
587 QueuedAudioBuffer queue_entry = { kOk, output }; 494 QueuedAudioBuffer queue_entry = { kOk, output };
588 queued_audio_.push_back(queue_entry); 495 queued_audio_.push_back(queue_entry);
589 } 496 }
497 } while (packet.size > 0);
590 498
591 // Decoding finished successfully, update statistics. 499 return true;
592 if (result > 0) { 500 }
593 PipelineStatistics statistics; 501
594 statistics.audio_bytes_decoded = result; 502 void FFmpegAudioDecoder::ReleaseFFmpegResources() {
595 statistics_cb_.Run(statistics); 503 codec_context_.reset();
596 } 504 av_frame_.reset();
597 } while (packet.size > 0); 505 }
506
507 bool FFmpegAudioDecoder::ConfigureDecoder() {
508 if (!config_.IsValidConfig()) {
509 DLOG(ERROR) << "Invalid audio stream -"
510 << " codec: " << config_.codec()
511 << " channel layout: " << config_.channel_layout()
512 << " bits per channel: " << config_.bits_per_channel()
513 << " samples per second: " << config_.samples_per_second();
514 return false;
515 }
516
517 if (config_.is_encrypted()) {
518 DLOG(ERROR) << "Encrypted audio stream not supported";
519 return false;
520 }
521
522 // TODO(rileya) Remove this check once we properly support midstream audio
523 // config changes.
524 if (codec_context_.get() &&
525 (bytes_per_channel_ != config_.bytes_per_channel() ||
526 channel_layout_ != config_.channel_layout() ||
527 samples_per_second_ != config_.samples_per_second())) {
528 DVLOG(1) << "Unsupported config change :";
529 DVLOG(1) << "\tbytes_per_channel : " << bytes_per_channel_
530 << " -> " << config_.bytes_per_channel();
531 DVLOG(1) << "\tchannel_layout : " << channel_layout_
532 << " -> " << config_.channel_layout();
533 DVLOG(1) << "\tsample_rate : " << samples_per_second_
534 << " -> " << config_.samples_per_second();
535 return false;
536 }
537
538 // Release existing decoder resources if necessary.
539 ReleaseFFmpegResources();
540
541 // Initialize AVCodecContext structure.
542 codec_context_.reset(avcodec_alloc_context3(NULL));
543 AudioDecoderConfigToAVCodecContext(config_, codec_context_.get());
544
545 codec_context_->opaque = this;
546 codec_context_->get_buffer2 = GetAudioBufferImpl;
547 codec_context_->refcounted_frames = 1;
548
549 AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
550 if (!codec || avcodec_open2(codec_context_.get(), codec, NULL) < 0) {
551 DLOG(ERROR) << "Could not initialize audio decoder: "
552 << codec_context_->codec_id;
553 ReleaseFFmpegResources();
554 state_ = kUninitialized;
555 return false;
556 }
557
558 // Success!
559 av_frame_.reset(av_frame_alloc());
560 channel_layout_ = config_.channel_layout();
561 samples_per_second_ = config_.samples_per_second();
562 output_timestamp_helper_.reset(
563 new AudioTimestampHelper(config_.samples_per_second()));
564
565 // Store initial values to guard against midstream configuration changes.
566 channels_ = codec_context_->channels;
567 if (channels_ != ChannelLayoutToChannelCount(channel_layout_)) {
568 DLOG(ERROR) << "Audio configuration specified "
569 << ChannelLayoutToChannelCount(channel_layout_)
570 << " channels, but FFmpeg thinks the file contains "
571 << channels_ << " channels";
572 return false;
573 }
574 av_sample_format_ = codec_context_->sample_fmt;
575 sample_format_ = AVSampleFormatToSampleFormat(
576 static_cast<AVSampleFormat>(av_sample_format_));
577 bytes_per_channel_ = SampleFormatToBytesPerChannel(sample_format_);
578
579 return true;
580 }
581
582 void FFmpegAudioDecoder::ResetTimestampState() {
583 output_timestamp_helper_->SetBaseTimestamp(kNoTimestamp());
584 last_input_timestamp_ = kNoTimestamp();
585 output_frames_to_drop_ = 0;
598 } 586 }
599 587
600 } // namespace media 588 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698