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

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

Issue 10669022: Add status parameter to DemuxerStream::ReadCB (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 5 months 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 | Annotate | Revision Log
OLDNEW
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 "media/base/audio_decoder_config.h" 9 #include "media/base/audio_decoder_config.h"
9 #include "media/base/data_buffer.h" 10 #include "media/base/data_buffer.h"
10 #include "media/base/decoder_buffer.h" 11 #include "media/base/decoder_buffer.h"
11 #include "media/base/demuxer.h" 12 #include "media/base/demuxer.h"
12 #include "media/base/pipeline.h" 13 #include "media/base/pipeline.h"
13 #include "media/ffmpeg/ffmpeg_common.h" 14 #include "media/ffmpeg/ffmpeg_common.h"
14 #include "media/filters/ffmpeg_glue.h" 15 #include "media/filters/ffmpeg_glue.h"
15 16
16 namespace media { 17 namespace media {
17 18
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 void FFmpegAudioDecoder::DoRead(const ReadCB& read_cb) { 159 void FFmpegAudioDecoder::DoRead(const ReadCB& read_cb) {
159 DCHECK_EQ(MessageLoop::current(), message_loop_); 160 DCHECK_EQ(MessageLoop::current(), message_loop_);
160 DCHECK(!read_cb.is_null()); 161 DCHECK(!read_cb.is_null());
161 CHECK(read_cb_.is_null()) << "Overlapping decodes are not supported."; 162 CHECK(read_cb_.is_null()) << "Overlapping decodes are not supported.";
162 163
163 read_cb_ = read_cb; 164 read_cb_ = read_cb;
164 ReadFromDemuxerStream(); 165 ReadFromDemuxerStream();
165 } 166 }
166 167
167 void FFmpegAudioDecoder::DoDecodeBuffer( 168 void FFmpegAudioDecoder::DoDecodeBuffer(
169 DemuxerStream::Status status,
168 const scoped_refptr<DecoderBuffer>& input) { 170 const scoped_refptr<DecoderBuffer>& input) {
169 DCHECK_EQ(MessageLoop::current(), message_loop_); 171 DCHECK_EQ(MessageLoop::current(), message_loop_);
170 DCHECK(!read_cb_.is_null()); 172 DCHECK(!read_cb_.is_null());
171 173
172 if (!input) { 174 if (status != DemuxerStream::kOk) {
Ami GONE FROM CHROMIUM 2012/06/26 00:33:21 DCHECK(!input) ?
acolwell GONE FROM CHROMIUM 2012/07/12 01:19:38 Done.
173 // DemuxeStream::Read() was aborted so we abort the decoder's pending read. 175 // TODO(acolwell): Add support for reinitializing the decoder when
174 DeliverSamples(NULL); 176 // |status| == kConfigChanged. For now we just trigger a decode error.
177 AudioDecoder::Status decoder_status =
178 (status == DemuxerStream::kAborted) ? kAborted : kDecodeError;
179 base::ResetAndReturn(&read_cb_).Run(decoder_status, NULL);
175 return; 180 return;
176 } 181 }
177 182
178 // FFmpeg tends to seek Ogg audio streams in the middle of nowhere, giving us 183 // FFmpeg tends to seek Ogg audio streams in the middle of nowhere, giving us
179 // a whole bunch of AV_NOPTS_VALUE packets. Discard them until we find 184 // a whole bunch of AV_NOPTS_VALUE packets. Discard them until we find
180 // something valid. Refer to http://crbug.com/49709 185 // something valid. Refer to http://crbug.com/49709
181 if (input->GetTimestamp() == kNoTimestamp() && 186 if (input->GetTimestamp() == kNoTimestamp() &&
182 estimated_next_timestamp_ == kNoTimestamp() && 187 estimated_next_timestamp_ == kNoTimestamp() &&
183 !input->IsEndOfStream()) { 188 !input->IsEndOfStream()) {
184 ReadFromDemuxerStream(); 189 ReadFromDemuxerStream();
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 } else if (IsEndOfStream(result, decoded_audio_size, input)) { 243 } else if (IsEndOfStream(result, decoded_audio_size, input)) {
239 // Create an end of stream output buffer. 244 // Create an end of stream output buffer.
240 output = new DataBuffer(0); 245 output = new DataBuffer(0);
241 output->SetTimestamp(input->GetTimestamp()); 246 output->SetTimestamp(input->GetTimestamp());
242 output->SetDuration(input->GetDuration()); 247 output->SetDuration(input->GetDuration());
243 } 248 }
244 249
245 // Decoding finished successfully, update stats and execute callback. 250 // Decoding finished successfully, update stats and execute callback.
246 statistics_cb_.Run(statistics); 251 statistics_cb_.Run(statistics);
247 if (output) { 252 if (output) {
248 DeliverSamples(output); 253 base::ResetAndReturn(&read_cb_).Run(kOk, output);
249 } else { 254 } else {
250 ReadFromDemuxerStream(); 255 ReadFromDemuxerStream();
251 } 256 }
252 } 257 }
253 258
254 void FFmpegAudioDecoder::ReadFromDemuxerStream() { 259 void FFmpegAudioDecoder::ReadFromDemuxerStream() {
255 DCHECK(!read_cb_.is_null()); 260 DCHECK(!read_cb_.is_null());
256 261
257 demuxer_stream_->Read(base::Bind(&FFmpegAudioDecoder::DecodeBuffer, this)); 262 demuxer_stream_->Read(base::Bind(&FFmpegAudioDecoder::DecodeBuffer, this));
258 } 263 }
259 264
260 void FFmpegAudioDecoder::DecodeBuffer( 265 void FFmpegAudioDecoder::DecodeBuffer(
266 DemuxerStream::Status status,
261 const scoped_refptr<DecoderBuffer>& buffer) { 267 const scoped_refptr<DecoderBuffer>& buffer) {
268 DCHECK_EQ(status != DemuxerStream::kOk, !buffer);
269
262 // TODO(scherkus): fix FFmpegDemuxerStream::Read() to not execute our read 270 // TODO(scherkus): fix FFmpegDemuxerStream::Read() to not execute our read
263 // callback on the same execution stack so we can get rid of forced task post. 271 // callback on the same execution stack so we can get rid of forced task post.
264 message_loop_->PostTask(FROM_HERE, base::Bind( 272 message_loop_->PostTask(FROM_HERE, base::Bind(
265 &FFmpegAudioDecoder::DoDecodeBuffer, this, buffer)); 273 &FFmpegAudioDecoder::DoDecodeBuffer, this, status, buffer));
266 } 274 }
267 275
268 void FFmpegAudioDecoder::UpdateDurationAndTimestamp( 276 void FFmpegAudioDecoder::UpdateDurationAndTimestamp(
269 const Buffer* input, 277 const Buffer* input,
270 DataBuffer* output) { 278 DataBuffer* output) {
271 // Always calculate duration based on the actual number of samples decoded. 279 // Always calculate duration based on the actual number of samples decoded.
272 base::TimeDelta duration = CalculateDuration(output->GetDataSize()); 280 base::TimeDelta duration = CalculateDuration(output->GetDataSize());
273 output->SetDuration(duration); 281 output->SetDuration(duration);
274 282
275 // Use the incoming timestamp if it's valid. 283 // Use the incoming timestamp if it's valid.
(...skipping 12 matching lines...) Expand all
288 } 296 }
289 297
290 base::TimeDelta FFmpegAudioDecoder::CalculateDuration(int size) { 298 base::TimeDelta FFmpegAudioDecoder::CalculateDuration(int size) {
291 int64 denominator = ChannelLayoutToChannelCount(channel_layout_) * 299 int64 denominator = ChannelLayoutToChannelCount(channel_layout_) *
292 bits_per_channel_ / 8 * samples_per_second_; 300 bits_per_channel_ / 8 * samples_per_second_;
293 double microseconds = size / 301 double microseconds = size /
294 (denominator / static_cast<double>(base::Time::kMicrosecondsPerSecond)); 302 (denominator / static_cast<double>(base::Time::kMicrosecondsPerSecond));
295 return base::TimeDelta::FromMicroseconds(static_cast<int64>(microseconds)); 303 return base::TimeDelta::FromMicroseconds(static_cast<int64>(microseconds));
296 } 304 }
297 305
298 void FFmpegAudioDecoder::DeliverSamples(const scoped_refptr<Buffer>& samples) {
299 // Reset the callback before running to protect against reentrancy.
300 ReadCB read_cb = read_cb_;
301 read_cb_.Reset();
302 read_cb.Run(samples);
303 }
304
305 } // namespace media 306 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698