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

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

Issue 465044: Refactor FFmpegVideoDecoder to try and generalize code common to all video decoders. (Closed)
Patch Set: Fix SCOPED_TRACE since VS faults on %zd. Created 11 years 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
« no previous file with comments | « media/filters/ffmpeg_audio_decoder.h ('k') | media/filters/ffmpeg_demuxer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
2 // source code is governed by a BSD-style license that can be found in the 2 // source code is governed by a BSD-style license that can be found in the
3 // LICENSE file. 3 // LICENSE file.
4 4
5 #include "media/filters/ffmpeg_audio_decoder.h" 5 #include "media/filters/ffmpeg_audio_decoder.h"
6 6
7 #include "media/base/callback.h"
7 #include "media/base/data_buffer.h" 8 #include "media/base/data_buffer.h"
8 #include "media/base/limits.h" 9 #include "media/base/limits.h"
9 #include "media/filters/ffmpeg_common.h" 10 #include "media/filters/ffmpeg_common.h"
10 #include "media/filters/ffmpeg_demuxer.h" 11 #include "media/filters/ffmpeg_demuxer.h"
11 12
12 namespace media { 13 namespace media {
13 14
14 // Size of the decoded audio buffer. 15 // Size of the decoded audio buffer.
15 const size_t FFmpegAudioDecoder::kOutputBufferSize = 16 const size_t FFmpegAudioDecoder::kOutputBufferSize =
16 AVCODEC_MAX_AUDIO_FRAME_SIZE; 17 AVCODEC_MAX_AUDIO_FRAME_SIZE;
17 18
18 FFmpegAudioDecoder::FFmpegAudioDecoder() 19 FFmpegAudioDecoder::FFmpegAudioDecoder()
19 : codec_context_(NULL) { 20 : codec_context_(NULL) {
20 } 21 }
21 22
22 FFmpegAudioDecoder::~FFmpegAudioDecoder() { 23 FFmpegAudioDecoder::~FFmpegAudioDecoder() {
23 } 24 }
24 25
25 // static 26 // static
26 bool FFmpegAudioDecoder::IsMediaFormatSupported(const MediaFormat& format) { 27 bool FFmpegAudioDecoder::IsMediaFormatSupported(const MediaFormat& format) {
27 std::string mime_type; 28 std::string mime_type;
28 return format.GetAsString(MediaFormat::kMimeType, &mime_type) && 29 return format.GetAsString(MediaFormat::kMimeType, &mime_type) &&
29 mime_type::kFFmpegAudio == mime_type; 30 mime_type::kFFmpegAudio == mime_type;
30 } 31 }
31 32
32 bool FFmpegAudioDecoder::OnInitialize(DemuxerStream* demuxer_stream) { 33 void FFmpegAudioDecoder::DoInitialize(DemuxerStream* demuxer_stream,
34 bool* success,
35 Task* done_cb) {
36 AutoTaskRunner done_runner(done_cb);
37 *success = false;
38
33 // Get the AVStream by querying for the provider interface. 39 // Get the AVStream by querying for the provider interface.
34 AVStreamProvider* av_stream_provider; 40 AVStreamProvider* av_stream_provider;
35 if (!demuxer_stream->QueryInterface(&av_stream_provider)) { 41 if (!demuxer_stream->QueryInterface(&av_stream_provider)) {
36 return false; 42 return;
37 } 43 }
38 AVStream* av_stream = av_stream_provider->GetAVStream(); 44 AVStream* av_stream = av_stream_provider->GetAVStream();
39 45
40 // Grab the AVStream's codec context and make sure we have sensible values. 46 // Grab the AVStream's codec context and make sure we have sensible values.
41 codec_context_ = av_stream->codec; 47 codec_context_ = av_stream->codec;
42 int bps = av_get_bits_per_sample_format(codec_context_->sample_fmt); 48 int bps = av_get_bits_per_sample_format(codec_context_->sample_fmt);
43 DCHECK_GT(codec_context_->channels, 0); 49 DCHECK_GT(codec_context_->channels, 0);
44 DCHECK_GT(bps, 0); 50 DCHECK_GT(bps, 0);
45 DCHECK_GT(codec_context_->sample_rate, 0); 51 DCHECK_GT(codec_context_->sample_rate, 0);
46 if (codec_context_->channels == 0 || 52 if (codec_context_->channels == 0 ||
47 static_cast<size_t>(codec_context_->channels) > Limits::kMaxChannels || 53 static_cast<size_t>(codec_context_->channels) > Limits::kMaxChannels ||
48 bps == 0 || 54 bps == 0 ||
49 static_cast<size_t>(bps) > Limits::kMaxBPS || 55 static_cast<size_t>(bps) > Limits::kMaxBPS ||
50 codec_context_->sample_rate == 0 || 56 codec_context_->sample_rate == 0 ||
51 static_cast<size_t>(codec_context_->sample_rate) > Limits::kMaxSampleRate) 57 (static_cast<size_t>(codec_context_->sample_rate) >
52 return false; 58 Limits::kMaxSampleRate)) {
59 return;
60 }
53 61
54 // Serialize calls to avcodec_open(). 62 // Serialize calls to avcodec_open().
55 AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id); 63 AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
56 { 64 {
57 AutoLock auto_lock(FFmpegLock::get()->lock()); 65 AutoLock auto_lock(FFmpegLock::get()->lock());
58 if (!codec || avcodec_open(codec_context_, codec) < 0) { 66 if (!codec || avcodec_open(codec_context_, codec) < 0) {
59 return false; 67 return;
60 } 68 }
61 } 69 }
62 70
63 // When calling avcodec_find_decoder(), |codec_context_| might be altered by 71 // When calling avcodec_find_decoder(), |codec_context_| might be altered by
64 // the decoder to give more accurate values of the output format of the 72 // the decoder to give more accurate values of the output format of the
65 // decoder. So set the media format after a decoder is allocated. 73 // decoder. So set the media format after a decoder is allocated.
66 // TODO(hclam): Reuse the information provided by the demuxer for now, we may 74 // TODO(hclam): Reuse the information provided by the demuxer for now, we may
67 // need to wait until the first buffer is decoded to know the correct 75 // need to wait until the first buffer is decoded to know the correct
68 // information. 76 // information.
69 media_format_.SetAsInteger(MediaFormat::kChannels, codec_context_->channels); 77 media_format_.SetAsInteger(MediaFormat::kChannels, codec_context_->channels);
70 media_format_.SetAsInteger(MediaFormat::kSampleBits, 78 media_format_.SetAsInteger(MediaFormat::kSampleBits,
71 av_get_bits_per_sample_format(codec_context_->sample_fmt)); 79 av_get_bits_per_sample_format(codec_context_->sample_fmt));
72 media_format_.SetAsInteger(MediaFormat::kSampleRate, 80 media_format_.SetAsInteger(MediaFormat::kSampleRate,
73 codec_context_->sample_rate); 81 codec_context_->sample_rate);
74 media_format_.SetAsString(MediaFormat::kMimeType, 82 media_format_.SetAsString(MediaFormat::kMimeType,
75 mime_type::kUncompressedAudio); 83 mime_type::kUncompressedAudio);
76 84
77 // Prepare the output buffer. 85 // Prepare the output buffer.
78 output_buffer_.reset(static_cast<uint8*>(av_malloc(kOutputBufferSize))); 86 output_buffer_.reset(static_cast<uint8*>(av_malloc(kOutputBufferSize)));
79 if (!output_buffer_.get()) { 87 if (!output_buffer_.get()) {
80 host()->SetError(PIPELINE_ERROR_OUT_OF_MEMORY); 88 host()->SetError(PIPELINE_ERROR_OUT_OF_MEMORY);
81 return false; 89 return;
82 } 90 }
83 return true; 91 *success = true;
84 } 92 }
85 93
86 void FFmpegAudioDecoder::OnSeek(base::TimeDelta time) { 94 void FFmpegAudioDecoder::DoSeek(base::TimeDelta time, Task* done_cb) {
87 avcodec_flush_buffers(codec_context_); 95 avcodec_flush_buffers(codec_context_);
88 estimated_next_timestamp_ = StreamSample::kInvalidTimestamp; 96 estimated_next_timestamp_ = StreamSample::kInvalidTimestamp;
97 done_cb->Run();
98 delete done_cb;
89 } 99 }
90 100
91 void FFmpegAudioDecoder::OnStop() { 101 void FFmpegAudioDecoder::DoDecode(Buffer* input, Task* done_cb) {
92 } 102 AutoTaskRunner done_runner(done_cb);
93 103
94 void FFmpegAudioDecoder::OnDecode(Buffer* input) {
95 // Due to FFmpeg API changes we no longer have const read-only pointers. 104 // Due to FFmpeg API changes we no longer have const read-only pointers.
96 AVPacket packet; 105 AVPacket packet;
97 av_init_packet(&packet); 106 av_init_packet(&packet);
98 packet.data = const_cast<uint8*>(input->GetData()); 107 packet.data = const_cast<uint8*>(input->GetData());
99 packet.size = input->GetDataSize(); 108 packet.size = input->GetDataSize();
100 109
101 int16_t* output_buffer = reinterpret_cast<int16_t*>(output_buffer_.get()); 110 int16_t* output_buffer = reinterpret_cast<int16_t*>(output_buffer_.get());
102 int output_buffer_size = kOutputBufferSize; 111 int output_buffer_size = kOutputBufferSize;
103 int result = avcodec_decode_audio3(codec_context_, 112 int result = avcodec_decode_audio3(codec_context_,
104 output_buffer, 113 output_buffer,
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 base::TimeDelta FFmpegAudioDecoder::CalculateDuration(size_t size) { 192 base::TimeDelta FFmpegAudioDecoder::CalculateDuration(size_t size) {
184 int64 denominator = codec_context_->channels * 193 int64 denominator = codec_context_->channels *
185 av_get_bits_per_sample_format(codec_context_->sample_fmt) / 8 * 194 av_get_bits_per_sample_format(codec_context_->sample_fmt) / 8 *
186 codec_context_->sample_rate; 195 codec_context_->sample_rate;
187 double microseconds = size / 196 double microseconds = size /
188 (denominator / static_cast<double>(base::Time::kMicrosecondsPerSecond)); 197 (denominator / static_cast<double>(base::Time::kMicrosecondsPerSecond));
189 return base::TimeDelta::FromMicroseconds(static_cast<int64>(microseconds)); 198 return base::TimeDelta::FromMicroseconds(static_cast<int64>(microseconds));
190 } 199 }
191 200
192 } // namespace 201 } // namespace
OLDNEW
« no previous file with comments | « media/filters/ffmpeg_audio_decoder.h ('k') | media/filters/ffmpeg_demuxer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698