diff options
author | fischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-27 20:36:10 +0000 |
---|---|---|
committer | fischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-27 20:36:10 +0000 |
commit | ab34561dd992607626f7b7c7ee06d429de55df04 (patch) | |
tree | ec9f032f24ced4f86c4b866de1415cbc977ca7a7 /media | |
parent | b492263fad2d811e7d942e63a61ce2f6a3fdfa7c (diff) | |
download | chromium_src-ab34561dd992607626f7b7c7ee06d429de55df04.zip chromium_src-ab34561dd992607626f7b7c7ee06d429de55df04.tar.gz chromium_src-ab34561dd992607626f7b7c7ee06d429de55df04.tar.bz2 |
Detect errors in audio output and report them upstream.
Stop feeding audio packets to AUDIO DemuxerStreams once audio has been disabled.
BUG=111409
TEST=uninstall pulseaudio, make /dev/snd inaccessible, and observe <video> plays correctly (muted) instead of hanging.
Review URL: http://codereview.chromium.org/9234066
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@119488 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r-- | media/audio/linux/alsa_output.cc | 2 | ||||
-rw-r--r-- | media/audio/linux/alsa_output_unittest.cc | 10 | ||||
-rw-r--r-- | media/base/audio_renderer_sink.h | 5 | ||||
-rw-r--r-- | media/filters/ffmpeg_demuxer.cc | 12 | ||||
-rw-r--r-- | media/filters/ffmpeg_demuxer.h | 4 |
5 files changed, 23 insertions, 10 deletions
diff --git a/media/audio/linux/alsa_output.cc b/media/audio/linux/alsa_output.cc index b3f931d..75de924 100644 --- a/media/audio/linux/alsa_output.cc +++ b/media/audio/linux/alsa_output.cc @@ -268,6 +268,8 @@ bool AlsaPcmOutputStream::Open() { // Finish initializing the stream if the device was opened successfully. if (playback_handle_ == NULL) { stop_stream_ = true; + TransitionTo(kInError); + return false; } else { bytes_per_output_frame_ = should_downmix_ ? 2 * bytes_per_sample_ : bytes_per_frame_; diff --git a/media/audio/linux/alsa_output_unittest.cc b/media/audio/linux/alsa_output_unittest.cc index f1870d2..a8359f6 100644 --- a/media/audio/linux/alsa_output_unittest.cc +++ b/media/audio/linux/alsa_output_unittest.cc @@ -355,11 +355,10 @@ TEST_F(AlsaPcmOutputStreamTest, PcmOpenFailed) { EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) .WillOnce(Return(kDummyMessage)); - ASSERT_TRUE(test_stream_->Open()); - ASSERT_EQ(AlsaPcmOutputStream::kIsOpened, test_stream_->state()); + ASSERT_FALSE(test_stream_->Open()); + ASSERT_EQ(AlsaPcmOutputStream::kInError, test_stream_->state()); // Ensure internal state is set for a no-op stream if PcmOpen() failes. - EXPECT_EQ(AlsaPcmOutputStream::kIsOpened, test_stream_->state()); EXPECT_TRUE(test_stream_->stop_stream_); EXPECT_TRUE(test_stream_->playback_handle_ == NULL); EXPECT_FALSE(test_stream_->buffer_.get()); @@ -384,11 +383,10 @@ TEST_F(AlsaPcmOutputStreamTest, PcmSetParamsFailed) { // If open fails, the stream stays in kCreated because it has effectively had // no changes. - ASSERT_TRUE(test_stream_->Open()); - EXPECT_EQ(AlsaPcmOutputStream::kIsOpened, test_stream_->state()); + ASSERT_FALSE(test_stream_->Open()); + EXPECT_EQ(AlsaPcmOutputStream::kInError, test_stream_->state()); // Ensure internal state is set for a no-op stream if PcmSetParams() failes. - EXPECT_EQ(AlsaPcmOutputStream::kIsOpened, test_stream_->state()); EXPECT_TRUE(test_stream_->stop_stream_); EXPECT_TRUE(test_stream_->playback_handle_ == NULL); EXPECT_FALSE(test_stream_->buffer_.get()); diff --git a/media/base/audio_renderer_sink.h b/media/base/audio_renderer_sink.h index 5888c6b..350210c 100644 --- a/media/base/audio_renderer_sink.h +++ b/media/base/audio_renderer_sink.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -32,6 +32,9 @@ class AudioRendererSink size_t number_of_frames, size_t audio_delay_milliseconds) = 0; + // Signals an error has occurred. + virtual void OnError() = 0; + protected: virtual ~RenderCallback() {} }; diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc index 6e3627e..0cb2ea4 100644 --- a/media/filters/ffmpeg_demuxer.cc +++ b/media/filters/ffmpeg_demuxer.cc @@ -289,7 +289,8 @@ FFmpegDemuxer::FFmpegDemuxer(MessageLoop* message_loop, bool local_source) max_duration_(base::TimeDelta::FromMicroseconds(-1)), deferred_status_(PIPELINE_OK), first_seek_hack_(true), - start_time_(kNoTimestamp()) { + start_time_(kNoTimestamp()), + audio_disabled_(false) { DCHECK(message_loop_); } @@ -662,7 +663,9 @@ void FFmpegDemuxer::DemuxTask() { // Defend against ffmpeg giving us a bad stream index. if (packet->stream_index >= 0 && packet->stream_index < static_cast<int>(streams_.size()) && - streams_[packet->stream_index]) { + streams_[packet->stream_index] && + (!audio_disabled_ || + streams_[packet->stream_index]->type() != DemuxerStream::AUDIO)) { FFmpegDemuxerStream* demuxer_stream = streams_[packet->stream_index]; // If a packet is returned by FFmpeg's av_parser_parse2() @@ -699,6 +702,7 @@ void FFmpegDemuxer::StopTask(const base::Closure& callback) { void FFmpegDemuxer::DisableAudioStreamTask() { DCHECK_EQ(MessageLoop::current(), message_loop_); + audio_disabled_ = true; StreamVector::iterator iter; for (iter = streams_.begin(); iter != streams_.end(); ++iter) { if (*iter && (*iter)->type() == DemuxerStream::AUDIO) { @@ -722,8 +726,10 @@ void FFmpegDemuxer::StreamHasEnded() { DCHECK_EQ(MessageLoop::current(), message_loop_); StreamVector::iterator iter; for (iter = streams_.begin(); iter != streams_.end(); ++iter) { - if (!*iter) + if (!*iter || + (audio_disabled_ && (*iter)->type() == DemuxerStream::AUDIO)) { continue; + } scoped_ptr_malloc<AVPacket, ScopedPtrAVFreePacket> packet(new AVPacket()); memset(packet.get(), 0, sizeof(*packet.get())); (*iter)->EnqueuePacket(packet.Pass()); diff --git a/media/filters/ffmpeg_demuxer.h b/media/filters/ffmpeg_demuxer.h index 66c6ac5..a180113 100644 --- a/media/filters/ffmpeg_demuxer.h +++ b/media/filters/ffmpeg_demuxer.h @@ -261,6 +261,10 @@ class MEDIA_EXPORT FFmpegDemuxer : public Demuxer, public FFmpegURLProtocol { // is 0. base::TimeDelta start_time_; + // Whether audio has been disabled for this demuxer (in which case this class + // drops packets destined for AUDIO demuxer streams on the floor). + bool audio_disabled_; + DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxer); }; |