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