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

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

Issue 12224114: Guard against midstream audio configuration changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 10 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 "base/callback_helpers.h"
9 #include "base/location.h" 9 #include "base/location.h"
10 #include "base/message_loop_proxy.h" 10 #include "base/message_loop_proxy.h"
(...skipping 25 matching lines...) Expand all
36 // 3. An end of stream buffer is received. 36 // 3. An end of stream buffer is received.
37 return result == 0 && decoded_size == 0 && input->IsEndOfStream(); 37 return result == 0 && decoded_size == 0 && input->IsEndOfStream();
38 } 38 }
39 39
40 FFmpegAudioDecoder::FFmpegAudioDecoder( 40 FFmpegAudioDecoder::FFmpegAudioDecoder(
41 const scoped_refptr<base::MessageLoopProxy>& message_loop) 41 const scoped_refptr<base::MessageLoopProxy>& message_loop)
42 : message_loop_(message_loop), 42 : message_loop_(message_loop),
43 codec_context_(NULL), 43 codec_context_(NULL),
44 bits_per_channel_(0), 44 bits_per_channel_(0),
45 channel_layout_(CHANNEL_LAYOUT_NONE), 45 channel_layout_(CHANNEL_LAYOUT_NONE),
46 channels_(0),
46 samples_per_second_(0), 47 samples_per_second_(0),
48 av_sample_format_(0),
47 bytes_per_frame_(0), 49 bytes_per_frame_(0),
48 last_input_timestamp_(kNoTimestamp()), 50 last_input_timestamp_(kNoTimestamp()),
49 output_bytes_to_drop_(0), 51 output_bytes_to_drop_(0),
50 av_frame_(NULL) { 52 av_frame_(NULL) {
51 } 53 }
52 54
53 void FFmpegAudioDecoder::Initialize( 55 void FFmpegAudioDecoder::Initialize(
54 const scoped_refptr<DemuxerStream>& stream, 56 const scoped_refptr<DemuxerStream>& stream,
55 const PipelineStatusCB& status_cb, 57 const PipelineStatusCB& status_cb,
56 const StatisticsCB& statistics_cb) { 58 const StatisticsCB& statistics_cb) {
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 } 298 }
297 299
298 // Success! 300 // Success!
299 av_frame_ = avcodec_alloc_frame(); 301 av_frame_ = avcodec_alloc_frame();
300 bits_per_channel_ = config.bits_per_channel(); 302 bits_per_channel_ = config.bits_per_channel();
301 channel_layout_ = config.channel_layout(); 303 channel_layout_ = config.channel_layout();
302 samples_per_second_ = config.samples_per_second(); 304 samples_per_second_ = config.samples_per_second();
303 output_timestamp_helper_.reset(new AudioTimestampHelper( 305 output_timestamp_helper_.reset(new AudioTimestampHelper(
304 config.bytes_per_frame(), config.samples_per_second())); 306 config.bytes_per_frame(), config.samples_per_second()));
305 bytes_per_frame_ = config.bytes_per_frame(); 307 bytes_per_frame_ = config.bytes_per_frame();
308
309 // Store initial values to guard against mid-frame configuration changes.
scherkus (not reviewing) 2013/02/12 02:16:56 consistent terminology nit: s/mid-frame/mid-stream
DaleCurtis 2013/02/12 02:41:24 Done.
310 channels_ = codec_context_->channels;
311 av_sample_format_ = codec_context_->sample_fmt;
312
306 return true; 313 return true;
307 } 314 }
308 315
309 void FFmpegAudioDecoder::ReleaseFFmpegResources() { 316 void FFmpegAudioDecoder::ReleaseFFmpegResources() {
310 if (codec_context_) { 317 if (codec_context_) {
311 av_free(codec_context_->extradata); 318 av_free(codec_context_->extradata);
312 avcodec_close(codec_context_); 319 avcodec_close(codec_context_);
313 av_free(codec_context_); 320 av_free(codec_context_);
314 } 321 }
315 322
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 // If we have to drop samples it always means the timeline starts at 0. 387 // If we have to drop samples it always means the timeline starts at 0.
381 DCHECK_EQ(codec_context_->codec_id, CODEC_ID_VORBIS); 388 DCHECK_EQ(codec_context_->codec_id, CODEC_ID_VORBIS);
382 output_timestamp_helper_->SetBaseTimestamp(base::TimeDelta()); 389 output_timestamp_helper_->SetBaseTimestamp(base::TimeDelta());
383 } else { 390 } else {
384 output_timestamp_helper_->SetBaseTimestamp(input->GetTimestamp()); 391 output_timestamp_helper_->SetBaseTimestamp(input->GetTimestamp());
385 } 392 }
386 } 393 }
387 394
388 int decoded_audio_size = 0; 395 int decoded_audio_size = 0;
389 if (frame_decoded) { 396 if (frame_decoded) {
390 int output_sample_rate = av_frame_->sample_rate; 397 if (av_frame_->sample_rate != samples_per_second_ ||
391 if (output_sample_rate != samples_per_second_) { 398 av_frame_->channels != channels_ ||
392 DLOG(ERROR) << "Output sample rate (" << output_sample_rate 399 av_frame_->format != av_sample_format_) {
393 << ") doesn't match expected rate " << samples_per_second_; 400 DLOG(ERROR) << "Unsupported mid-frame configuration change!"
scherkus (not reviewing) 2013/02/12 02:16:56 consistent terminology nit: s/mid-frame/mid-stream
DaleCurtis 2013/02/12 02:41:24 Done.
401 << " Sample Rate: " << av_frame_->sample_rate << " vs "
402 << samples_per_second_
403 << ", Channels: " << av_frame_->channels << " vs "
404 << channels_
405 << ", Sample Format: " << av_frame_->format << " vs "
406 << av_sample_format_;
394 407
395 // This is an unrecoverable error, so bail out. 408 // This is an unrecoverable error, so bail out.
396 QueuedAudioBuffer queue_entry = { kDecodeError, NULL }; 409 QueuedAudioBuffer queue_entry = { kDecodeError, NULL };
397 queued_audio_.push_back(queue_entry); 410 queued_audio_.push_back(queue_entry);
398 break; 411 break;
399 } 412 }
400 413
401 decoded_audio_size = av_samples_get_buffer_size( 414 decoded_audio_size = av_samples_get_buffer_size(
402 NULL, codec_context_->channels, av_frame_->nb_samples, 415 NULL, codec_context_->channels, av_frame_->nb_samples,
403 codec_context_->sample_fmt, 1); 416 codec_context_->sample_fmt, 1);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 // Decoding finished successfully, update statistics. 487 // Decoding finished successfully, update statistics.
475 if (result > 0) { 488 if (result > 0) {
476 PipelineStatistics statistics; 489 PipelineStatistics statistics;
477 statistics.audio_bytes_decoded = result; 490 statistics.audio_bytes_decoded = result;
478 statistics_cb_.Run(statistics); 491 statistics_cb_.Run(statistics);
479 } 492 }
480 } while (packet.size > 0); 493 } while (packet.size > 0);
481 } 494 }
482 495
483 } // namespace media 496 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698