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 "media/base/audio_decoder_config.h" | 8 #include "media/base/audio_decoder_config.h" |
9 #include "media/base/data_buffer.h" | 9 #include "media/base/data_buffer.h" |
10 #include "media/base/demuxer.h" | 10 #include "media/base/demuxer.h" |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 } | 69 } |
70 | 70 |
71 void FFmpegAudioDecoder::Flush(const base::Closure& callback) { | 71 void FFmpegAudioDecoder::Flush(const base::Closure& callback) { |
72 message_loop_->PostTask( | 72 message_loop_->PostTask( |
73 FROM_HERE, | 73 FROM_HERE, |
74 base::Bind(&FFmpegAudioDecoder::DoFlush, this, callback)); | 74 base::Bind(&FFmpegAudioDecoder::DoFlush, this, callback)); |
75 } | 75 } |
76 | 76 |
77 void FFmpegAudioDecoder::Initialize( | 77 void FFmpegAudioDecoder::Initialize( |
78 DemuxerStream* stream, | 78 DemuxerStream* stream, |
79 const base::Closure& callback, | 79 const PipelineStatusCB& callback, |
80 const StatisticsCallback& stats_callback) { | 80 const StatisticsCallback& stats_callback) { |
81 // TODO(scherkus): change Initialize() signature to pass |stream| as a | 81 // TODO(scherkus): change Initialize() signature to pass |stream| as a |
82 // scoped_refptr<>. | 82 // scoped_refptr<>. |
83 scoped_refptr<DemuxerStream> ref_stream(stream); | 83 scoped_refptr<DemuxerStream> ref_stream(stream); |
84 message_loop_->PostTask( | 84 message_loop_->PostTask( |
85 FROM_HERE, | 85 FROM_HERE, |
86 base::Bind(&FFmpegAudioDecoder::DoInitialize, this, | 86 base::Bind(&FFmpegAudioDecoder::DoInitialize, this, |
87 ref_stream, callback, stats_callback)); | 87 ref_stream, callback, stats_callback)); |
88 } | 88 } |
89 | 89 |
(...skipping 11 matching lines...) Expand all Loading... |
101 ChannelLayout FFmpegAudioDecoder::channel_layout() { | 101 ChannelLayout FFmpegAudioDecoder::channel_layout() { |
102 return channel_layout_; | 102 return channel_layout_; |
103 } | 103 } |
104 | 104 |
105 int FFmpegAudioDecoder::samples_per_second() { | 105 int FFmpegAudioDecoder::samples_per_second() { |
106 return samples_per_second_; | 106 return samples_per_second_; |
107 } | 107 } |
108 | 108 |
109 void FFmpegAudioDecoder::DoInitialize( | 109 void FFmpegAudioDecoder::DoInitialize( |
110 const scoped_refptr<DemuxerStream>& stream, | 110 const scoped_refptr<DemuxerStream>& stream, |
111 const base::Closure& callback, | 111 const PipelineStatusCB& callback, |
112 const StatisticsCallback& stats_callback) { | 112 const StatisticsCallback& stats_callback) { |
113 demuxer_stream_ = stream; | 113 demuxer_stream_ = stream; |
114 const AudioDecoderConfig& config = stream->audio_decoder_config(); | 114 const AudioDecoderConfig& config = stream->audio_decoder_config(); |
115 stats_callback_ = stats_callback; | 115 stats_callback_ = stats_callback; |
116 | 116 |
117 // TODO(scherkus): this check should go in Pipeline prior to creating | 117 // TODO(scherkus): this check should go in Pipeline prior to creating |
118 // decoder objects. | 118 // decoder objects. |
119 if (!config.IsValidConfig()) { | 119 if (!config.IsValidConfig()) { |
120 DLOG(ERROR) << "Invalid audio stream -" | 120 DLOG(ERROR) << "Invalid audio stream -" |
121 << " codec: " << config.codec() | 121 << " codec: " << config.codec() |
122 << " channel layout: " << config.channel_layout() | 122 << " channel layout: " << config.channel_layout() |
123 << " bits per channel: " << config.bits_per_channel() | 123 << " bits per channel: " << config.bits_per_channel() |
124 << " samples per second: " << config.samples_per_second(); | 124 << " samples per second: " << config.samples_per_second(); |
125 | 125 |
126 host()->SetError(DECODER_ERROR_NOT_SUPPORTED); | 126 callback.Run(DECODER_ERROR_NOT_SUPPORTED); |
127 callback.Run(); | |
128 return; | 127 return; |
129 } | 128 } |
130 | 129 |
131 // Initialize AVCodecContext structure. | 130 // Initialize AVCodecContext structure. |
132 codec_context_ = avcodec_alloc_context(); | 131 codec_context_ = avcodec_alloc_context(); |
133 AudioDecoderConfigToAVCodecContext(config, codec_context_); | 132 AudioDecoderConfigToAVCodecContext(config, codec_context_); |
134 | 133 |
135 AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id); | 134 AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id); |
136 if (!codec || avcodec_open(codec_context_, codec) < 0) { | 135 if (!codec || avcodec_open(codec_context_, codec) < 0) { |
137 DLOG(ERROR) << "Could not initialize audio decoder: " | 136 DLOG(ERROR) << "Could not initialize audio decoder: " |
138 << codec_context_->codec_id; | 137 << codec_context_->codec_id; |
139 | 138 |
140 host()->SetError(DECODER_ERROR_NOT_SUPPORTED); | 139 callback.Run(DECODER_ERROR_NOT_SUPPORTED); |
141 callback.Run(); | |
142 return; | 140 return; |
143 } | 141 } |
144 | 142 |
145 // Success! | 143 // Success! |
146 bits_per_channel_ = config.bits_per_channel(); | 144 bits_per_channel_ = config.bits_per_channel(); |
147 channel_layout_ = config.channel_layout(); | 145 channel_layout_ = config.channel_layout(); |
148 samples_per_second_ = config.samples_per_second(); | 146 samples_per_second_ = config.samples_per_second(); |
149 | 147 |
150 callback.Run(); | 148 callback.Run(PIPELINE_OK); |
151 } | 149 } |
152 | 150 |
153 void FFmpegAudioDecoder::DoFlush(const base::Closure& callback) { | 151 void FFmpegAudioDecoder::DoFlush(const base::Closure& callback) { |
154 avcodec_flush_buffers(codec_context_); | 152 avcodec_flush_buffers(codec_context_); |
155 estimated_next_timestamp_ = kNoTimestamp(); | 153 estimated_next_timestamp_ = kNoTimestamp(); |
156 callback.Run(); | 154 callback.Run(); |
157 } | 155 } |
158 | 156 |
159 void FFmpegAudioDecoder::DoRead(const ReadCB& callback) { | 157 void FFmpegAudioDecoder::DoRead(const ReadCB& callback) { |
160 DCHECK_EQ(MessageLoop::current(), message_loop_); | 158 DCHECK_EQ(MessageLoop::current(), message_loop_); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 } | 289 } |
292 | 290 |
293 void FFmpegAudioDecoder::DeliverSamples(const scoped_refptr<Buffer>& samples) { | 291 void FFmpegAudioDecoder::DeliverSamples(const scoped_refptr<Buffer>& samples) { |
294 // Reset the callback before running to protect against reentrancy. | 292 // Reset the callback before running to protect against reentrancy. |
295 ReadCB read_cb = read_cb_; | 293 ReadCB read_cb = read_cb_; |
296 read_cb_.Reset(); | 294 read_cb_.Reset(); |
297 read_cb.Run(samples); | 295 read_cb.Run(samples); |
298 } | 296 } |
299 | 297 |
300 } // namespace media | 298 } // namespace media |
OLD | NEW |