| 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 |