OLD | NEW |
---|---|
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/message_loop_proxy.h" | 10 #include "base/message_loop_proxy.h" |
(...skipping 25 matching lines...) Expand all Loading... | |
36 // 3. An end of stream buffer is received. | 36 // 3. An end of stream buffer is received. |
37 return result == 0 && decoded_size == 0 && input->IsEndOfStream(); | 37 return result == 0 && decoded_size == 0 && input->IsEndOfStream(); |
38 } | 38 } |
39 | 39 |
40 FFmpegAudioDecoder::FFmpegAudioDecoder( | 40 FFmpegAudioDecoder::FFmpegAudioDecoder( |
41 const scoped_refptr<base::MessageLoopProxy>& message_loop) | 41 const scoped_refptr<base::MessageLoopProxy>& message_loop) |
42 : message_loop_(message_loop), | 42 : message_loop_(message_loop), |
43 codec_context_(NULL), | 43 codec_context_(NULL), |
44 bits_per_channel_(0), | 44 bits_per_channel_(0), |
45 channel_layout_(CHANNEL_LAYOUT_NONE), | 45 channel_layout_(CHANNEL_LAYOUT_NONE), |
46 channels_(0), | |
46 samples_per_second_(0), | 47 samples_per_second_(0), |
48 av_sample_format_(0), | |
47 bytes_per_frame_(0), | 49 bytes_per_frame_(0), |
48 last_input_timestamp_(kNoTimestamp()), | 50 last_input_timestamp_(kNoTimestamp()), |
49 output_bytes_to_drop_(0), | 51 output_bytes_to_drop_(0), |
50 av_frame_(NULL) { | 52 av_frame_(NULL) { |
51 } | 53 } |
52 | 54 |
53 void FFmpegAudioDecoder::Initialize( | 55 void FFmpegAudioDecoder::Initialize( |
54 const scoped_refptr<DemuxerStream>& stream, | 56 const scoped_refptr<DemuxerStream>& stream, |
55 const PipelineStatusCB& status_cb, | 57 const PipelineStatusCB& status_cb, |
56 const StatisticsCB& statistics_cb) { | 58 const StatisticsCB& statistics_cb) { |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
296 } | 298 } |
297 | 299 |
298 // Success! | 300 // Success! |
299 av_frame_ = avcodec_alloc_frame(); | 301 av_frame_ = avcodec_alloc_frame(); |
300 bits_per_channel_ = config.bits_per_channel(); | 302 bits_per_channel_ = config.bits_per_channel(); |
301 channel_layout_ = config.channel_layout(); | 303 channel_layout_ = config.channel_layout(); |
302 samples_per_second_ = config.samples_per_second(); | 304 samples_per_second_ = config.samples_per_second(); |
303 output_timestamp_helper_.reset(new AudioTimestampHelper( | 305 output_timestamp_helper_.reset(new AudioTimestampHelper( |
304 config.bytes_per_frame(), config.samples_per_second())); | 306 config.bytes_per_frame(), config.samples_per_second())); |
305 bytes_per_frame_ = config.bytes_per_frame(); | 307 bytes_per_frame_ = config.bytes_per_frame(); |
308 | |
309 // Store initial values to guard against mid-frame configuration changes. | |
scherkus (not reviewing)
2013/02/12 02:16:56
consistent terminology nit: s/mid-frame/mid-stream
DaleCurtis
2013/02/12 02:41:24
Done.
| |
310 channels_ = codec_context_->channels; | |
311 av_sample_format_ = codec_context_->sample_fmt; | |
312 | |
306 return true; | 313 return true; |
307 } | 314 } |
308 | 315 |
309 void FFmpegAudioDecoder::ReleaseFFmpegResources() { | 316 void FFmpegAudioDecoder::ReleaseFFmpegResources() { |
310 if (codec_context_) { | 317 if (codec_context_) { |
311 av_free(codec_context_->extradata); | 318 av_free(codec_context_->extradata); |
312 avcodec_close(codec_context_); | 319 avcodec_close(codec_context_); |
313 av_free(codec_context_); | 320 av_free(codec_context_); |
314 } | 321 } |
315 | 322 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
380 // If we have to drop samples it always means the timeline starts at 0. | 387 // If we have to drop samples it always means the timeline starts at 0. |
381 DCHECK_EQ(codec_context_->codec_id, CODEC_ID_VORBIS); | 388 DCHECK_EQ(codec_context_->codec_id, CODEC_ID_VORBIS); |
382 output_timestamp_helper_->SetBaseTimestamp(base::TimeDelta()); | 389 output_timestamp_helper_->SetBaseTimestamp(base::TimeDelta()); |
383 } else { | 390 } else { |
384 output_timestamp_helper_->SetBaseTimestamp(input->GetTimestamp()); | 391 output_timestamp_helper_->SetBaseTimestamp(input->GetTimestamp()); |
385 } | 392 } |
386 } | 393 } |
387 | 394 |
388 int decoded_audio_size = 0; | 395 int decoded_audio_size = 0; |
389 if (frame_decoded) { | 396 if (frame_decoded) { |
390 int output_sample_rate = av_frame_->sample_rate; | 397 if (av_frame_->sample_rate != samples_per_second_ || |
391 if (output_sample_rate != samples_per_second_) { | 398 av_frame_->channels != channels_ || |
392 DLOG(ERROR) << "Output sample rate (" << output_sample_rate | 399 av_frame_->format != av_sample_format_) { |
393 << ") doesn't match expected rate " << samples_per_second_; | 400 DLOG(ERROR) << "Unsupported mid-frame configuration change!" |
scherkus (not reviewing)
2013/02/12 02:16:56
consistent terminology nit: s/mid-frame/mid-stream
DaleCurtis
2013/02/12 02:41:24
Done.
| |
401 << " Sample Rate: " << av_frame_->sample_rate << " vs " | |
402 << samples_per_second_ | |
403 << ", Channels: " << av_frame_->channels << " vs " | |
404 << channels_ | |
405 << ", Sample Format: " << av_frame_->format << " vs " | |
406 << av_sample_format_; | |
394 | 407 |
395 // This is an unrecoverable error, so bail out. | 408 // This is an unrecoverable error, so bail out. |
396 QueuedAudioBuffer queue_entry = { kDecodeError, NULL }; | 409 QueuedAudioBuffer queue_entry = { kDecodeError, NULL }; |
397 queued_audio_.push_back(queue_entry); | 410 queued_audio_.push_back(queue_entry); |
398 break; | 411 break; |
399 } | 412 } |
400 | 413 |
401 decoded_audio_size = av_samples_get_buffer_size( | 414 decoded_audio_size = av_samples_get_buffer_size( |
402 NULL, codec_context_->channels, av_frame_->nb_samples, | 415 NULL, codec_context_->channels, av_frame_->nb_samples, |
403 codec_context_->sample_fmt, 1); | 416 codec_context_->sample_fmt, 1); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
474 // Decoding finished successfully, update statistics. | 487 // Decoding finished successfully, update statistics. |
475 if (result > 0) { | 488 if (result > 0) { |
476 PipelineStatistics statistics; | 489 PipelineStatistics statistics; |
477 statistics.audio_bytes_decoded = result; | 490 statistics.audio_bytes_decoded = result; |
478 statistics_cb_.Run(statistics); | 491 statistics_cb_.Run(statistics); |
479 } | 492 } |
480 } while (packet.size > 0); | 493 } while (packet.size > 0); |
481 } | 494 } |
482 | 495 |
483 } // namespace media | 496 } // namespace media |
OLD | NEW |