summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorxhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-17 08:32:52 +0000
committerxhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-17 08:32:52 +0000
commit4beec40bbd48c2f04b194f0f82d70fa07485811f (patch)
treed47bd9e75d0335b096489c0c2682edb2913e53f1 /media
parent317b66eb10f6361698c03b3e6e25c15e123ff185 (diff)
downloadchromium_src-4beec40bbd48c2f04b194f0f82d70fa07485811f.zip
chromium_src-4beec40bbd48c2f04b194f0f82d70fa07485811f.tar.gz
chromium_src-4beec40bbd48c2f04b194f0f82d70fa07485811f.tar.bz2
Fold DecoderStream::Stop() into the dtor.
BUG=349211 TEST=Existing tests pass. Review URL: https://codereview.chromium.org/393313004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@283713 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/filters/audio_renderer_impl.cc23
-rw-r--r--media/filters/audio_renderer_impl.h3
-rw-r--r--media/filters/decoder_stream.cc100
-rw-r--r--media/filters/decoder_stream.h15
-rw-r--r--media/filters/video_frame_stream_unittest.cc94
-rw-r--r--media/filters/video_renderer_impl.cc19
-rw-r--r--media/filters/video_renderer_impl.h3
7 files changed, 95 insertions, 162 deletions
diff --git a/media/filters/audio_renderer_impl.cc b/media/filters/audio_renderer_impl.cc
index e6937fc..bbe0d78 100644
--- a/media/filters/audio_renderer_impl.cc
+++ b/media/filters/audio_renderer_impl.cc
@@ -48,9 +48,9 @@ AudioRendererImpl::AudioRendererImpl(
AudioHardwareConfig* hardware_config)
: task_runner_(task_runner),
sink_(sink),
- audio_buffer_stream_(task_runner,
- decoders.Pass(),
- set_decryptor_ready_cb),
+ audio_buffer_stream_(new AudioBufferStream(task_runner,
+ decoders.Pass(),
+ set_decryptor_ready_cb)),
hardware_config_(hardware_config),
state_(kUninitialized),
buffering_state_(BUFFERING_HAVE_NOTHING),
@@ -60,9 +60,9 @@ AudioRendererImpl::AudioRendererImpl(
received_end_of_stream_(false),
rendered_end_of_stream_(false),
weak_factory_(this) {
- audio_buffer_stream_.set_splice_observer(base::Bind(
+ audio_buffer_stream_->set_splice_observer(base::Bind(
&AudioRendererImpl::OnNewSpliceBuffer, weak_factory_.GetWeakPtr()));
- audio_buffer_stream_.set_config_change_observer(base::Bind(
+ audio_buffer_stream_->set_config_change_observer(base::Bind(
&AudioRendererImpl::OnConfigChange, weak_factory_.GetWeakPtr()));
}
@@ -155,8 +155,8 @@ void AudioRendererImpl::DoFlush_Locked() {
DCHECK(!pending_read_);
DCHECK_EQ(state_, kFlushed);
- audio_buffer_stream_.Reset(base::Bind(&AudioRendererImpl::ResetDecoderDone,
- weak_factory_.GetWeakPtr()));
+ audio_buffer_stream_->Reset(base::Bind(&AudioRendererImpl::ResetDecoderDone,
+ weak_factory_.GetWeakPtr()));
}
void AudioRendererImpl::ResetDecoderDone() {
@@ -215,7 +215,8 @@ void AudioRendererImpl::Stop(const base::Closure& callback) {
sink_ = NULL;
}
- audio_buffer_stream_.Stop(callback);
+ audio_buffer_stream_.reset();
+ task_runner_->PostTask(FROM_HERE, callback);
}
void AudioRendererImpl::StartPlayingFrom(base::TimeDelta timestamp) {
@@ -296,7 +297,7 @@ void AudioRendererImpl::Initialize(DemuxerStream* stream,
audio_clock_.reset(new AudioClock(audio_parameters_.sample_rate()));
- audio_buffer_stream_.Initialize(
+ audio_buffer_stream_->Initialize(
stream,
false,
statistics_cb,
@@ -486,8 +487,8 @@ void AudioRendererImpl::AttemptRead_Locked() {
return;
pending_read_ = true;
- audio_buffer_stream_.Read(base::Bind(&AudioRendererImpl::DecodedAudioReady,
- weak_factory_.GetWeakPtr()));
+ audio_buffer_stream_->Read(base::Bind(&AudioRendererImpl::DecodedAudioReady,
+ weak_factory_.GetWeakPtr()));
}
bool AudioRendererImpl::CanRead_Locked() {
diff --git a/media/filters/audio_renderer_impl.h b/media/filters/audio_renderer_impl.h
index cc06fa3..5f6ebdd 100644
--- a/media/filters/audio_renderer_impl.h
+++ b/media/filters/audio_renderer_impl.h
@@ -22,6 +22,7 @@
#include <deque>
#include "base/gtest_prod_util.h"
+#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/synchronization/lock.h"
#include "media/base/audio_decoder.h"
@@ -197,7 +198,7 @@ class MEDIA_EXPORT AudioRendererImpl
// may deadlock between |task_runner_| and the audio callback thread.
scoped_refptr<media::AudioRendererSink> sink_;
- AudioBufferStream audio_buffer_stream_;
+ scoped_ptr<AudioBufferStream> audio_buffer_stream_;
// Interface to the hardware audio params.
const AudioHardwareConfig* const hardware_config_;
diff --git a/media/filters/decoder_stream.cc b/media/filters/decoder_stream.cc
index f8714f2..66c64d3 100644
--- a/media/filters/decoder_stream.cc
+++ b/media/filters/decoder_stream.cc
@@ -56,7 +56,30 @@ DecoderStream<StreamType>::DecoderStream(
template <DemuxerStream::Type StreamType>
DecoderStream<StreamType>::~DecoderStream() {
- DCHECK(state_ == STATE_UNINITIALIZED || state_ == STATE_STOPPED) << state_;
+ FUNCTION_DVLOG(2);
+ DCHECK(task_runner_->BelongsToCurrentThread());
+
+ // TODO(xhwang): Fold DecoderSelector::Abort() into the dtor.
+ if (state_ == STATE_INITIALIZING)
+ decoder_selector_->Abort();
+
+ if (!init_cb_.is_null()) {
+ task_runner_->PostTask(FROM_HERE,
+ base::Bind(base::ResetAndReturn(&init_cb_), false));
+ }
+ if (!read_cb_.is_null()) {
+ task_runner_->PostTask(FROM_HERE, base::Bind(
+ base::ResetAndReturn(&read_cb_), ABORTED, scoped_refptr<Output>()));
+ }
+ if (!reset_cb_.is_null())
+ task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&reset_cb_));
+
+ if (decrypting_demuxer_stream_)
+ decrypting_demuxer_stream_->Stop();
+
+ stream_ = NULL;
+ decoder_.reset();
+ decrypting_demuxer_stream_.reset();
}
template <DemuxerStream::Type StreamType>
@@ -89,13 +112,12 @@ template <DemuxerStream::Type StreamType>
void DecoderStream<StreamType>::Read(const ReadCB& read_cb) {
FUNCTION_DVLOG(2);
DCHECK(task_runner_->BelongsToCurrentThread());
- DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_INITIALIZING &&
- state_ != STATE_STOPPED) << state_;
+ DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_INITIALIZING)
+ << state_;
// No two reads in the flight at any time.
DCHECK(read_cb_.is_null());
// No read during resetting or stopping process.
DCHECK(reset_cb_.is_null());
- DCHECK(stop_cb_.is_null());
if (state_ == STATE_ERROR) {
task_runner_->PostTask(
@@ -125,9 +147,8 @@ template <DemuxerStream::Type StreamType>
void DecoderStream<StreamType>::Reset(const base::Closure& closure) {
FUNCTION_DVLOG(2);
DCHECK(task_runner_->BelongsToCurrentThread());
- DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_;
+ DCHECK(state_ != STATE_UNINITIALIZED)<< state_;
DCHECK(reset_cb_.is_null());
- DCHECK(stop_cb_.is_null());
reset_cb_ = closure;
@@ -160,45 +181,6 @@ void DecoderStream<StreamType>::Reset(const base::Closure& closure) {
}
template <DemuxerStream::Type StreamType>
-void DecoderStream<StreamType>::Stop(const base::Closure& closure) {
- FUNCTION_DVLOG(2);
- DCHECK(task_runner_->BelongsToCurrentThread());
- DCHECK_NE(state_, STATE_STOPPED) << state_;
- DCHECK(stop_cb_.is_null());
-
- // TODO(xhwang): This is the only asynchronousness in DecoderStream::Stop().
- // Fix this so that we can merge the stopping code into the dtor.
- if (state_ == STATE_INITIALIZING) {
- stop_cb_ = closure;
- decoder_selector_->Abort();
- return;
- }
-
- DCHECK(init_cb_.is_null());
-
- // All pending callbacks will be dropped.
- weak_factory_.InvalidateWeakPtrs();
-
- // Post callbacks to prevent reentrance into this object.
- if (!read_cb_.is_null()) {
- task_runner_->PostTask(FROM_HERE, base::Bind(
- base::ResetAndReturn(&read_cb_), ABORTED, scoped_refptr<Output>()));
- }
- if (!reset_cb_.is_null())
- task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&reset_cb_));
-
- if (decrypting_demuxer_stream_)
- decrypting_demuxer_stream_->Stop();
-
- stream_ = NULL;
- decoder_.reset();
- decrypting_demuxer_stream_.reset();
-
- state_ = STATE_STOPPED;
- task_runner_->PostTask(FROM_HERE, closure);
-}
-
-template <DemuxerStream::Type StreamType>
bool DecoderStream<StreamType>::CanReadWithoutStalling() const {
DCHECK(task_runner_->BelongsToCurrentThread());
return !ready_outputs_.empty() || decoder_->CanReadWithoutStalling();
@@ -251,19 +233,14 @@ void DecoderStream<StreamType>::OnDecoderSelected(
state_ = STATE_UNINITIALIZED;
StreamTraits::FinishInitialization(
base::ResetAndReturn(&init_cb_), selected_decoder.get(), stream_);
- } else {
- state_ = STATE_NORMAL;
- decoder_ = selected_decoder.Pass();
- decrypting_demuxer_stream_ = decrypting_demuxer_stream.Pass();
- StreamTraits::FinishInitialization(
- base::ResetAndReturn(&init_cb_), decoder_.get(), stream_);
- }
-
- // Stop() called during initialization.
- if (!stop_cb_.is_null()) {
- Stop(base::ResetAndReturn(&stop_cb_));
return;
}
+
+ state_ = STATE_NORMAL;
+ decoder_ = selected_decoder.Pass();
+ decrypting_demuxer_stream_ = decrypting_demuxer_stream.Pass();
+ StreamTraits::FinishInitialization(
+ base::ResetAndReturn(&init_cb_), decoder_.get(), stream_);
}
template <DemuxerStream::Type StreamType>
@@ -281,7 +258,6 @@ void DecoderStream<StreamType>::Decode(
DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_;
DCHECK_LT(pending_decode_requests_, GetMaxDecodeRequests());
DCHECK(reset_cb_.is_null());
- DCHECK(stop_cb_.is_null());
DCHECK(buffer);
int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size();
@@ -308,7 +284,6 @@ void DecoderStream<StreamType>::OnDecodeDone(int buffer_size,
DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR)
<< state_;
- DCHECK(stop_cb_.is_null());
DCHECK_GT(pending_decode_requests_, 0);
--pending_decode_requests_;
@@ -403,7 +378,6 @@ void DecoderStream<StreamType>::ReadFromDemuxerStream() {
DCHECK_EQ(state_, STATE_NORMAL) << state_;
DCHECK(CanDecodeMore());
DCHECK(reset_cb_.is_null());
- DCHECK(stop_cb_.is_null());
state_ = STATE_PENDING_DEMUXER_READ;
stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady,
@@ -418,15 +392,13 @@ void DecoderStream<StreamType>::OnBufferReady(
<< (buffer ? buffer->AsHumanReadableString() : "NULL");
DCHECK(task_runner_->BelongsToCurrentThread());
- DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR ||
- state_ == STATE_STOPPED)
+ DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR)
<< state_;
DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status;
- DCHECK(stop_cb_.is_null());
// Decoding has been stopped (e.g due to an error).
if (state_ != STATE_PENDING_DEMUXER_READ) {
- DCHECK(state_ == STATE_ERROR || state_ == STATE_STOPPED);
+ DCHECK(state_ == STATE_ERROR);
DCHECK(read_cb_.is_null());
return;
}
@@ -507,7 +479,6 @@ void DecoderStream<StreamType>::OnDecoderReinitialized(PipelineStatus status) {
FUNCTION_DVLOG(2);
DCHECK(task_runner_->BelongsToCurrentThread());
DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER) << state_;
- DCHECK(stop_cb_.is_null());
// ReinitializeDecoder() can be called in two cases:
// 1, Flushing decoder finished (see OnDecodeOutputReady()).
@@ -555,7 +526,6 @@ void DecoderStream<StreamType>::OnDecoderReset() {
// before the reset callback is fired.
DCHECK(read_cb_.is_null());
DCHECK(!reset_cb_.is_null());
- DCHECK(stop_cb_.is_null());
if (state_ != STATE_FLUSHING_DECODER) {
state_ = STATE_NORMAL;
diff --git a/media/filters/decoder_stream.h b/media/filters/decoder_stream.h
index 32c1a28..c077a18 100644
--- a/media/filters/decoder_stream.h
+++ b/media/filters/decoder_stream.h
@@ -65,23 +65,16 @@ class MEDIA_EXPORT DecoderStream {
// Reads a decoded Output and returns it via the |read_cb|. Note that
// |read_cb| is always called asynchronously. This method should only be
// called after initialization has succeeded and must not be called during
- // any pending Reset() and/or Stop().
+ // pending Reset().
void Read(const ReadCB& read_cb);
// Resets the decoder, flushes all decoded outputs and/or internal buffers,
// fires any existing pending read callback and calls |closure| on completion.
// Note that |closure| is always called asynchronously. This method should
// only be called after initialization has succeeded and must not be called
- // during any pending Reset() and/or Stop().
+ // during pending Reset().
void Reset(const base::Closure& closure);
- // Stops the decoder, fires any existing pending read callback or reset
- // callback and calls |closure| on completion. Note that |closure| is always
- // called asynchronously. The DecoderStream cannot be used anymore after
- // it is stopped. This method can be called at any time but not during another
- // pending Stop().
- void Stop(const base::Closure& closure);
-
// Returns true if the decoder currently has the ability to decode and return
// an Output.
// TODO(rileya): Remove the need for this by refactoring Decoder queueing
@@ -117,12 +110,11 @@ class MEDIA_EXPORT DecoderStream {
enum State {
STATE_UNINITIALIZED,
STATE_INITIALIZING,
- STATE_NORMAL, // Includes idle, pending decoder decode/reset/stop.
+ STATE_NORMAL, // Includes idle, pending decoder decode/reset.
STATE_FLUSHING_DECODER,
STATE_PENDING_DEMUXER_READ,
STATE_REINITIALIZING_DECODER,
STATE_END_OF_STREAM, // End of stream reached; returns EOS on all reads.
- STATE_STOPPED,
STATE_ERROR
};
@@ -174,7 +166,6 @@ class MEDIA_EXPORT DecoderStream {
ReadCB read_cb_;
base::Closure reset_cb_;
- base::Closure stop_cb_;
DemuxerStream* stream_;
bool low_delay_;
diff --git a/media/filters/video_frame_stream_unittest.cc b/media/filters/video_frame_stream_unittest.cc
index f249404..492e7cf 100644
--- a/media/filters/video_frame_stream_unittest.cc
+++ b/media/filters/video_frame_stream_unittest.cc
@@ -76,14 +76,19 @@ class VideoFrameStreamTest
}
~VideoFrameStreamTest() {
+ // Check that the pipeline statistics callback was fired correctly.
+ if (decoder_)
+ EXPECT_EQ(decoder_->total_bytes_decoded(), total_bytes_decoded_);
+
+ is_initialized_ = false;
+ decoder_ = NULL;
+ video_frame_stream_.reset();
+ message_loop_.RunUntilIdle();
+
DCHECK(!pending_initialize_);
DCHECK(!pending_read_);
DCHECK(!pending_reset_);
DCHECK(!pending_stop_);
-
- if (is_initialized_)
- Stop();
- EXPECT_FALSE(is_initialized_);
}
MOCK_METHOD1(OnNewSpliceBuffer, void(base::TimeDelta));
@@ -157,16 +162,6 @@ class VideoFrameStreamTest
pending_reset_ = false;
}
- void OnStopped() {
- DCHECK(!pending_initialize_);
- DCHECK(!pending_read_);
- DCHECK(!pending_reset_);
- DCHECK(pending_stop_);
- pending_stop_ = false;
- is_initialized_ = false;
- decoder_ = NULL;
- }
-
void ReadOneFrame() {
frame_read_ = NULL;
pending_read_ = true;
@@ -270,7 +265,7 @@ class VideoFrameStreamTest
break;
// These two cases are only interesting to test during
- // VideoFrameStream::Stop(). There's no need to satisfy a callback.
+ // VideoFrameStream destruction. There's no need to satisfy a callback.
case SET_DECRYPTOR:
case DECRYPTOR_NO_KEY:
NOTREACHED();
@@ -315,15 +310,6 @@ class VideoFrameStreamTest
SatisfyPendingCallback(DECODER_RESET);
}
- void Stop() {
- // Check that the pipeline statistics callback was fired correctly.
- EXPECT_EQ(decoder_->total_bytes_decoded(), total_bytes_decoded_);
- pending_stop_ = true;
- video_frame_stream_->Stop(base::Bind(&VideoFrameStreamTest::OnStopped,
- base::Unretained(this)));
- message_loop_.RunUntilIdle();
- }
-
base::MessageLoop message_loop_;
scoped_ptr<VideoFrameStream> video_frame_stream_;
@@ -577,118 +563,98 @@ TEST_P(VideoFrameStreamTest, Reset_DuringNoKeyRead) {
Reset();
}
-TEST_P(VideoFrameStreamTest, Stop_BeforeInitialization) {
- pending_stop_ = true;
- video_frame_stream_->Stop(
- base::Bind(&VideoFrameStreamTest::OnStopped, base::Unretained(this)));
- message_loop_.RunUntilIdle();
+// In the following Destroy_* tests, |video_frame_stream_| is destroyed in
+// VideoFrameStreamTest dtor.
+
+TEST_P(VideoFrameStreamTest, Destroy_BeforeInitialization) {
}
-TEST_P(VideoFrameStreamTest, Stop_DuringSetDecryptor) {
+TEST_P(VideoFrameStreamTest, Destroy_DuringSetDecryptor) {
if (!GetParam().is_encrypted) {
DVLOG(1) << "SetDecryptor test only runs when the stream is encrytped.";
return;
}
EnterPendingState(SET_DECRYPTOR);
- pending_stop_ = true;
- video_frame_stream_->Stop(
- base::Bind(&VideoFrameStreamTest::OnStopped, base::Unretained(this)));
- message_loop_.RunUntilIdle();
}
-TEST_P(VideoFrameStreamTest, Stop_DuringInitialization) {
+TEST_P(VideoFrameStreamTest, Destroy_DuringInitialization) {
EnterPendingState(DECODER_INIT);
- Stop();
}
-TEST_P(VideoFrameStreamTest, Stop_AfterInitialization) {
+TEST_P(VideoFrameStreamTest, Destroy_AfterInitialization) {
Initialize();
- Stop();
}
-TEST_P(VideoFrameStreamTest, Stop_DuringReinitialization) {
+TEST_P(VideoFrameStreamTest, Destroy_DuringReinitialization) {
Initialize();
EnterPendingState(DECODER_REINIT);
- Stop();
}
-TEST_P(VideoFrameStreamTest, Stop_AfterReinitialization) {
+TEST_P(VideoFrameStreamTest, Destroy_AfterReinitialization) {
Initialize();
EnterPendingState(DECODER_REINIT);
SatisfyPendingCallback(DECODER_REINIT);
- Stop();
}
-TEST_P(VideoFrameStreamTest, Stop_DuringDemuxerRead_Normal) {
+TEST_P(VideoFrameStreamTest, Destroy_DuringDemuxerRead_Normal) {
Initialize();
EnterPendingState(DEMUXER_READ_NORMAL);
- Stop();
}
-TEST_P(VideoFrameStreamTest, Stop_DuringDemuxerRead_ConfigChange) {
+TEST_P(VideoFrameStreamTest, Destroy_DuringDemuxerRead_ConfigChange) {
Initialize();
EnterPendingState(DEMUXER_READ_CONFIG_CHANGE);
- Stop();
}
-TEST_P(VideoFrameStreamTest, Stop_DuringNormalDecoderDecode) {
+TEST_P(VideoFrameStreamTest, Destroy_DuringNormalDecoderDecode) {
Initialize();
EnterPendingState(DECODER_DECODE);
- Stop();
}
-TEST_P(VideoFrameStreamTest, Stop_AfterNormalRead) {
+TEST_P(VideoFrameStreamTest, Destroy_AfterNormalRead) {
Initialize();
Read();
- Stop();
}
-TEST_P(VideoFrameStreamTest, Stop_AfterConfigChangeRead) {
+TEST_P(VideoFrameStreamTest, Destroy_AfterConfigChangeRead) {
Initialize();
EnterPendingState(DEMUXER_READ_CONFIG_CHANGE);
SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE);
- Stop();
}
-TEST_P(VideoFrameStreamTest, Stop_DuringNoKeyRead) {
+TEST_P(VideoFrameStreamTest, Destroy_DuringNoKeyRead) {
Initialize();
EnterPendingState(DECRYPTOR_NO_KEY);
- Stop();
}
-TEST_P(VideoFrameStreamTest, Stop_DuringReset) {
+TEST_P(VideoFrameStreamTest, Destroy_DuringReset) {
Initialize();
EnterPendingState(DECODER_RESET);
- Stop();
}
-TEST_P(VideoFrameStreamTest, Stop_AfterReset) {
+TEST_P(VideoFrameStreamTest, Destroy_AfterReset) {
Initialize();
Reset();
- Stop();
}
-TEST_P(VideoFrameStreamTest, Stop_DuringRead_DuringReset) {
+TEST_P(VideoFrameStreamTest, Destroy_DuringRead_DuringReset) {
Initialize();
EnterPendingState(DECODER_DECODE);
EnterPendingState(DECODER_RESET);
- Stop();
}
-TEST_P(VideoFrameStreamTest, Stop_AfterRead_DuringReset) {
+TEST_P(VideoFrameStreamTest, Destroy_AfterRead_DuringReset) {
Initialize();
EnterPendingState(DECODER_DECODE);
EnterPendingState(DECODER_RESET);
SatisfyPendingCallback(DECODER_DECODE);
- Stop();
}
-TEST_P(VideoFrameStreamTest, Stop_AfterRead_AfterReset) {
+TEST_P(VideoFrameStreamTest, Destroy_AfterRead_AfterReset) {
Initialize();
Read();
Reset();
- Stop();
}
TEST_P(VideoFrameStreamTest, DecoderErrorWhenReading) {
diff --git a/media/filters/video_renderer_impl.cc b/media/filters/video_renderer_impl.cc
index 1cbf1bc..a544bac 100644
--- a/media/filters/video_renderer_impl.cc
+++ b/media/filters/video_renderer_impl.cc
@@ -25,7 +25,9 @@ VideoRendererImpl::VideoRendererImpl(
const PaintCB& paint_cb,
bool drop_frames)
: task_runner_(task_runner),
- video_frame_stream_(task_runner, decoders.Pass(), set_decryptor_ready_cb),
+ video_frame_stream_(new VideoFrameStream(task_runner,
+ decoders.Pass(),
+ set_decryptor_ready_cb)),
low_delay_(false),
received_end_of_stream_(false),
rendered_end_of_stream_(false),
@@ -66,7 +68,7 @@ void VideoRendererImpl::Flush(const base::Closure& callback) {
received_end_of_stream_ = false;
rendered_end_of_stream_ = false;
- video_frame_stream_.Reset(
+ video_frame_stream_->Reset(
base::Bind(&VideoRendererImpl::OnVideoFrameStreamResetDone,
weak_factory_.GetWeakPtr()));
}
@@ -75,7 +77,7 @@ void VideoRendererImpl::Stop(const base::Closure& callback) {
DCHECK(task_runner_->BelongsToCurrentThread());
base::AutoLock auto_lock(lock_);
if (state_ == kUninitialized || state_ == kStopped) {
- callback.Run();
+ task_runner_->PostTask(FROM_HERE, callback);
return;
}
@@ -102,7 +104,8 @@ void VideoRendererImpl::Stop(const base::Closure& callback) {
base::PlatformThread::Join(thread_to_join);
}
- video_frame_stream_.Stop(callback);
+ video_frame_stream_.reset();
+ task_runner_->PostTask(FROM_HERE, callback);
}
void VideoRendererImpl::StartPlayingFrom(base::TimeDelta timestamp) {
@@ -153,7 +156,7 @@ void VideoRendererImpl::Initialize(DemuxerStream* stream,
get_duration_cb_ = get_duration_cb;
state_ = kInitializing;
- video_frame_stream_.Initialize(
+ video_frame_stream_->Initialize(
stream,
low_delay,
statistics_cb,
@@ -360,7 +363,7 @@ void VideoRendererImpl::FrameReady(VideoFrameStream::Status status,
bool VideoRendererImpl::HaveEnoughData_Locked() {
DCHECK_EQ(state_, kPlaying);
return received_end_of_stream_ ||
- !video_frame_stream_.CanReadWithoutStalling() ||
+ !video_frame_stream_->CanReadWithoutStalling() ||
ready_frames_.size() >= static_cast<size_t>(limits::kMaxVideoFrames) ||
(low_delay_ && ready_frames_.size() > 0);
}
@@ -440,8 +443,8 @@ void VideoRendererImpl::AttemptRead_Locked() {
switch (state_) {
case kPlaying:
pending_read_ = true;
- video_frame_stream_.Read(base::Bind(&VideoRendererImpl::FrameReady,
- weak_factory_.GetWeakPtr()));
+ video_frame_stream_->Read(base::Bind(&VideoRendererImpl::FrameReady,
+ weak_factory_.GetWeakPtr()));
return;
case kUninitialized:
diff --git a/media/filters/video_renderer_impl.h b/media/filters/video_renderer_impl.h
index 0f142be..06262da 100644
--- a/media/filters/video_renderer_impl.h
+++ b/media/filters/video_renderer_impl.h
@@ -8,6 +8,7 @@
#include <deque>
#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "base/synchronization/condition_variable.h"
@@ -123,7 +124,7 @@ class MEDIA_EXPORT VideoRendererImpl
base::Lock lock_;
// Provides video frames to VideoRendererImpl.
- VideoFrameStream video_frame_stream_;
+ scoped_ptr<VideoFrameStream> video_frame_stream_;
// Flag indicating low-delay mode.
bool low_delay_;