| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/video_frame_stream.h" | 5 #include "media/filters/video_frame_stream.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/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/message_loop/message_loop_proxy.h" | 12 #include "base/single_thread_task_runner.h" |
| 13 #include "media/base/bind_to_loop.h" | 13 #include "media/base/bind_to_loop.h" |
| 14 #include "media/base/decoder_buffer.h" | 14 #include "media/base/decoder_buffer.h" |
| 15 #include "media/base/demuxer_stream.h" | 15 #include "media/base/demuxer_stream.h" |
| 16 #include "media/base/video_decoder_config.h" | 16 #include "media/base/video_decoder_config.h" |
| 17 #include "media/filters/decrypting_demuxer_stream.h" | 17 #include "media/filters/decrypting_demuxer_stream.h" |
| 18 #include "media/filters/video_decoder_selector.h" | 18 #include "media/filters/video_decoder_selector.h" |
| 19 | 19 |
| 20 namespace media { | 20 namespace media { |
| 21 | 21 |
| 22 VideoFrameStream::VideoFrameStream( | 22 VideoFrameStream::VideoFrameStream( |
| 23 const scoped_refptr<base::MessageLoopProxy>& message_loop, | 23 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
| 24 ScopedVector<VideoDecoder> decoders, | 24 ScopedVector<VideoDecoder> decoders, |
| 25 const SetDecryptorReadyCB& set_decryptor_ready_cb) | 25 const SetDecryptorReadyCB& set_decryptor_ready_cb) |
| 26 : message_loop_(message_loop), | 26 : task_runner_(task_runner), |
| 27 weak_factory_(this), | 27 weak_factory_(this), |
| 28 state_(STATE_UNINITIALIZED), | 28 state_(STATE_UNINITIALIZED), |
| 29 stream_(NULL), | 29 stream_(NULL), |
| 30 decoder_selector_(new VideoDecoderSelector(message_loop, | 30 decoder_selector_(new VideoDecoderSelector(task_runner, |
| 31 decoders.Pass(), | 31 decoders.Pass(), |
| 32 set_decryptor_ready_cb)) { | 32 set_decryptor_ready_cb)) { |
| 33 } | 33 } |
| 34 | 34 |
| 35 VideoFrameStream::~VideoFrameStream() { | 35 VideoFrameStream::~VideoFrameStream() { |
| 36 DCHECK(state_ == STATE_UNINITIALIZED || state_ == STATE_STOPPED) << state_; | 36 DCHECK(state_ == STATE_UNINITIALIZED || state_ == STATE_STOPPED) << state_; |
| 37 } | 37 } |
| 38 | 38 |
| 39 void VideoFrameStream::Initialize(DemuxerStream* stream, | 39 void VideoFrameStream::Initialize(DemuxerStream* stream, |
| 40 const StatisticsCB& statistics_cb, | 40 const StatisticsCB& statistics_cb, |
| 41 const InitCB& init_cb) { | 41 const InitCB& init_cb) { |
| 42 DVLOG(2) << __FUNCTION__; | 42 DVLOG(2) << __FUNCTION__; |
| 43 DCHECK(message_loop_->BelongsToCurrentThread()); | 43 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 44 DCHECK_EQ(state_, STATE_UNINITIALIZED) << state_; | 44 DCHECK_EQ(state_, STATE_UNINITIALIZED) << state_; |
| 45 DCHECK(init_cb_.is_null()); | 45 DCHECK(init_cb_.is_null()); |
| 46 DCHECK(!init_cb.is_null()); | 46 DCHECK(!init_cb.is_null()); |
| 47 | 47 |
| 48 statistics_cb_ = statistics_cb; | 48 statistics_cb_ = statistics_cb; |
| 49 init_cb_ = init_cb; | 49 init_cb_ = init_cb; |
| 50 stream_ = stream; | 50 stream_ = stream; |
| 51 | 51 |
| 52 state_ = STATE_INITIALIZING; | 52 state_ = STATE_INITIALIZING; |
| 53 // TODO(xhwang): VideoDecoderSelector only needs a config to select a decoder. | 53 // TODO(xhwang): VideoDecoderSelector only needs a config to select a decoder. |
| 54 decoder_selector_->SelectVideoDecoder( | 54 decoder_selector_->SelectVideoDecoder( |
| 55 stream, | 55 stream, |
| 56 base::Bind(&VideoFrameStream::OnDecoderSelected, | 56 base::Bind(&VideoFrameStream::OnDecoderSelected, |
| 57 weak_factory_.GetWeakPtr())); | 57 weak_factory_.GetWeakPtr())); |
| 58 } | 58 } |
| 59 | 59 |
| 60 void VideoFrameStream::Read(const ReadCB& read_cb) { | 60 void VideoFrameStream::Read(const ReadCB& read_cb) { |
| 61 DVLOG(2) << __FUNCTION__; | 61 DVLOG(2) << __FUNCTION__; |
| 62 DCHECK(message_loop_->BelongsToCurrentThread()); | 62 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 63 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || | 63 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || |
| 64 state_ == STATE_ERROR) << state_; | 64 state_ == STATE_ERROR) << state_; |
| 65 // No two reads in the flight at any time. | 65 // No two reads in the flight at any time. |
| 66 DCHECK(read_cb_.is_null()); | 66 DCHECK(read_cb_.is_null()); |
| 67 // No read during resetting or stopping process. | 67 // No read during resetting or stopping process. |
| 68 DCHECK(reset_cb_.is_null()); | 68 DCHECK(reset_cb_.is_null()); |
| 69 DCHECK(stop_cb_.is_null()); | 69 DCHECK(stop_cb_.is_null()); |
| 70 | 70 |
| 71 if (state_ == STATE_ERROR) { | 71 if (state_ == STATE_ERROR) { |
| 72 message_loop_->PostTask(FROM_HERE, base::Bind( | 72 task_runner_->PostTask(FROM_HERE, base::Bind( |
| 73 read_cb, DECODE_ERROR, scoped_refptr<VideoFrame>())); | 73 read_cb, DECODE_ERROR, scoped_refptr<VideoFrame>())); |
| 74 return; | 74 return; |
| 75 } | 75 } |
| 76 | 76 |
| 77 read_cb_ = read_cb; | 77 read_cb_ = read_cb; |
| 78 | 78 |
| 79 if (state_ == STATE_FLUSHING_DECODER) { | 79 if (state_ == STATE_FLUSHING_DECODER) { |
| 80 FlushDecoder(); | 80 FlushDecoder(); |
| 81 return; | 81 return; |
| 82 } | 82 } |
| 83 | 83 |
| 84 ReadFromDemuxerStream(); | 84 ReadFromDemuxerStream(); |
| 85 } | 85 } |
| 86 | 86 |
| 87 void VideoFrameStream::Reset(const base::Closure& closure) { | 87 void VideoFrameStream::Reset(const base::Closure& closure) { |
| 88 DVLOG(2) << __FUNCTION__; | 88 DVLOG(2) << __FUNCTION__; |
| 89 DCHECK(message_loop_->BelongsToCurrentThread()); | 89 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 90 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_; | 90 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_; |
| 91 DCHECK(reset_cb_.is_null()); | 91 DCHECK(reset_cb_.is_null()); |
| 92 DCHECK(stop_cb_.is_null()); | 92 DCHECK(stop_cb_.is_null()); |
| 93 | 93 |
| 94 reset_cb_ = closure; | 94 reset_cb_ = closure; |
| 95 | 95 |
| 96 // During decoder reinitialization, VideoDecoder does not need to be and | 96 // During decoder reinitialization, VideoDecoder does not need to be and |
| 97 // cannot be Reset(). |decrypting_demuxer_stream_| was reset before decoder | 97 // cannot be Reset(). |decrypting_demuxer_stream_| was reset before decoder |
| 98 // reinitialization. | 98 // reinitialization. |
| 99 if (state_ == STATE_REINITIALIZING_DECODER) | 99 if (state_ == STATE_REINITIALIZING_DECODER) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 114 decrypting_demuxer_stream_->Reset(base::Bind( | 114 decrypting_demuxer_stream_->Reset(base::Bind( |
| 115 &VideoFrameStream::ResetDecoder, weak_factory_.GetWeakPtr())); | 115 &VideoFrameStream::ResetDecoder, weak_factory_.GetWeakPtr())); |
| 116 return; | 116 return; |
| 117 } | 117 } |
| 118 | 118 |
| 119 ResetDecoder(); | 119 ResetDecoder(); |
| 120 } | 120 } |
| 121 | 121 |
| 122 void VideoFrameStream::Stop(const base::Closure& closure) { | 122 void VideoFrameStream::Stop(const base::Closure& closure) { |
| 123 DVLOG(2) << __FUNCTION__; | 123 DVLOG(2) << __FUNCTION__; |
| 124 DCHECK(message_loop_->BelongsToCurrentThread()); | 124 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 125 DCHECK_NE(state_, STATE_STOPPED) << state_; | 125 DCHECK_NE(state_, STATE_STOPPED) << state_; |
| 126 DCHECK(stop_cb_.is_null()); | 126 DCHECK(stop_cb_.is_null()); |
| 127 | 127 |
| 128 stop_cb_ = closure; | 128 stop_cb_ = closure; |
| 129 | 129 |
| 130 if (state_ == STATE_INITIALIZING) { | 130 if (state_ == STATE_INITIALIZING) { |
| 131 decoder_selector_->Abort(); | 131 decoder_selector_->Abort(); |
| 132 return; | 132 return; |
| 133 } | 133 } |
| 134 | 134 |
| 135 DCHECK(init_cb_.is_null()); | 135 DCHECK(init_cb_.is_null()); |
| 136 | 136 |
| 137 // All pending callbacks will be dropped. | 137 // All pending callbacks will be dropped. |
| 138 weak_factory_.InvalidateWeakPtrs(); | 138 weak_factory_.InvalidateWeakPtrs(); |
| 139 | 139 |
| 140 // Post callbacks to prevent reentrance into this object. | 140 // Post callbacks to prevent reentrance into this object. |
| 141 if (!read_cb_.is_null()) | 141 if (!read_cb_.is_null()) |
| 142 message_loop_->PostTask(FROM_HERE, base::Bind( | 142 task_runner_->PostTask(FROM_HERE, base::Bind( |
| 143 base::ResetAndReturn(&read_cb_), ABORTED, scoped_refptr<VideoFrame>())); | 143 base::ResetAndReturn(&read_cb_), ABORTED, scoped_refptr<VideoFrame>())); |
| 144 if (!reset_cb_.is_null()) | 144 if (!reset_cb_.is_null()) |
| 145 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&reset_cb_)); | 145 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&reset_cb_)); |
| 146 | 146 |
| 147 if (decrypting_demuxer_stream_) { | 147 if (decrypting_demuxer_stream_) { |
| 148 decrypting_demuxer_stream_->Reset(base::Bind( | 148 decrypting_demuxer_stream_->Reset(base::Bind( |
| 149 &VideoFrameStream::StopDecoder, weak_factory_.GetWeakPtr())); | 149 &VideoFrameStream::StopDecoder, weak_factory_.GetWeakPtr())); |
| 150 return; | 150 return; |
| 151 } | 151 } |
| 152 | 152 |
| 153 // We may not have a |decoder_| if Stop() was called during initialization. | 153 // We may not have a |decoder_| if Stop() was called during initialization. |
| 154 if (decoder_) { | 154 if (decoder_) { |
| 155 StopDecoder(); | 155 StopDecoder(); |
| 156 return; | 156 return; |
| 157 } | 157 } |
| 158 | 158 |
| 159 state_ = STATE_STOPPED; | 159 state_ = STATE_STOPPED; |
| 160 stream_ = NULL; | 160 stream_ = NULL; |
| 161 decoder_.reset(); | 161 decoder_.reset(); |
| 162 decrypting_demuxer_stream_.reset(); | 162 decrypting_demuxer_stream_.reset(); |
| 163 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_)); | 163 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_)); |
| 164 } | 164 } |
| 165 | 165 |
| 166 bool VideoFrameStream::CanReadWithoutStalling() const { | 166 bool VideoFrameStream::CanReadWithoutStalling() const { |
| 167 DCHECK(message_loop_->BelongsToCurrentThread()); | 167 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 168 return decoder_->CanReadWithoutStalling(); | 168 return decoder_->CanReadWithoutStalling(); |
| 169 } | 169 } |
| 170 | 170 |
| 171 void VideoFrameStream::OnDecoderSelected( | 171 void VideoFrameStream::OnDecoderSelected( |
| 172 scoped_ptr<VideoDecoder> selected_decoder, | 172 scoped_ptr<VideoDecoder> selected_decoder, |
| 173 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { | 173 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { |
| 174 DVLOG(2) << __FUNCTION__; | 174 DVLOG(2) << __FUNCTION__; |
| 175 DCHECK(message_loop_->BelongsToCurrentThread()); | 175 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 176 DCHECK_EQ(state_, STATE_INITIALIZING) << state_; | 176 DCHECK_EQ(state_, STATE_INITIALIZING) << state_; |
| 177 DCHECK(!init_cb_.is_null()); | 177 DCHECK(!init_cb_.is_null()); |
| 178 DCHECK(read_cb_.is_null()); | 178 DCHECK(read_cb_.is_null()); |
| 179 DCHECK(reset_cb_.is_null()); | 179 DCHECK(reset_cb_.is_null()); |
| 180 | 180 |
| 181 decoder_selector_.reset(); | 181 decoder_selector_.reset(); |
| 182 | 182 |
| 183 if (!selected_decoder) { | 183 if (!selected_decoder) { |
| 184 state_ = STATE_UNINITIALIZED; | 184 state_ = STATE_UNINITIALIZED; |
| 185 base::ResetAndReturn(&init_cb_).Run(false, false); | 185 base::ResetAndReturn(&init_cb_).Run(false, false); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 | 303 |
| 304 state_ = STATE_PENDING_DEMUXER_READ; | 304 state_ = STATE_PENDING_DEMUXER_READ; |
| 305 stream_->Read( | 305 stream_->Read( |
| 306 base::Bind(&VideoFrameStream::OnBufferReady, weak_factory_.GetWeakPtr())); | 306 base::Bind(&VideoFrameStream::OnBufferReady, weak_factory_.GetWeakPtr())); |
| 307 } | 307 } |
| 308 | 308 |
| 309 void VideoFrameStream::OnBufferReady( | 309 void VideoFrameStream::OnBufferReady( |
| 310 DemuxerStream::Status status, | 310 DemuxerStream::Status status, |
| 311 const scoped_refptr<DecoderBuffer>& buffer) { | 311 const scoped_refptr<DecoderBuffer>& buffer) { |
| 312 DVLOG(2) << __FUNCTION__; | 312 DVLOG(2) << __FUNCTION__; |
| 313 DCHECK(message_loop_->BelongsToCurrentThread()); | 313 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 314 DCHECK_EQ(state_, STATE_PENDING_DEMUXER_READ) << state_; | 314 DCHECK_EQ(state_, STATE_PENDING_DEMUXER_READ) << state_; |
| 315 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status; | 315 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status; |
| 316 DCHECK(!read_cb_.is_null()); | 316 DCHECK(!read_cb_.is_null()); |
| 317 DCHECK(stop_cb_.is_null()); | 317 DCHECK(stop_cb_.is_null()); |
| 318 | 318 |
| 319 state_ = STATE_NORMAL; | 319 state_ = STATE_NORMAL; |
| 320 | 320 |
| 321 if (status == DemuxerStream::kConfigChanged) { | 321 if (status == DemuxerStream::kConfigChanged) { |
| 322 state_ = STATE_FLUSHING_DECODER; | 322 state_ = STATE_FLUSHING_DECODER; |
| 323 if (!reset_cb_.is_null()) { | 323 if (!reset_cb_.is_null()) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 346 SatisfyRead(DEMUXER_READ_ABORTED, NULL); | 346 SatisfyRead(DEMUXER_READ_ABORTED, NULL); |
| 347 return; | 347 return; |
| 348 } | 348 } |
| 349 | 349 |
| 350 DCHECK(status == DemuxerStream::kOk) << status; | 350 DCHECK(status == DemuxerStream::kOk) << status; |
| 351 Decode(buffer); | 351 Decode(buffer); |
| 352 } | 352 } |
| 353 | 353 |
| 354 void VideoFrameStream::ReinitializeDecoder() { | 354 void VideoFrameStream::ReinitializeDecoder() { |
| 355 DVLOG(2) << __FUNCTION__; | 355 DVLOG(2) << __FUNCTION__; |
| 356 DCHECK(message_loop_->BelongsToCurrentThread()); | 356 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 357 DCHECK_EQ(state_, STATE_FLUSHING_DECODER) << state_; | 357 DCHECK_EQ(state_, STATE_FLUSHING_DECODER) << state_; |
| 358 | 358 |
| 359 DCHECK(stream_->video_decoder_config().IsValidConfig()); | 359 DCHECK(stream_->video_decoder_config().IsValidConfig()); |
| 360 state_ = STATE_REINITIALIZING_DECODER; | 360 state_ = STATE_REINITIALIZING_DECODER; |
| 361 decoder_->Initialize(stream_->video_decoder_config(), | 361 decoder_->Initialize(stream_->video_decoder_config(), |
| 362 base::Bind(&VideoFrameStream::OnDecoderReinitialized, | 362 base::Bind(&VideoFrameStream::OnDecoderReinitialized, |
| 363 weak_factory_.GetWeakPtr())); | 363 weak_factory_.GetWeakPtr())); |
| 364 } | 364 } |
| 365 | 365 |
| 366 void VideoFrameStream::OnDecoderReinitialized(PipelineStatus status) { | 366 void VideoFrameStream::OnDecoderReinitialized(PipelineStatus status) { |
| 367 DVLOG(2) << __FUNCTION__; | 367 DVLOG(2) << __FUNCTION__; |
| 368 DCHECK(message_loop_->BelongsToCurrentThread()); | 368 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 369 DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER) << state_; | 369 DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER) << state_; |
| 370 DCHECK(stop_cb_.is_null()); | 370 DCHECK(stop_cb_.is_null()); |
| 371 | 371 |
| 372 // ReinitializeDecoder() can be called in two cases: | 372 // ReinitializeDecoder() can be called in two cases: |
| 373 // 1, Flushing decoder finished (see OnFrameReady()). | 373 // 1, Flushing decoder finished (see OnFrameReady()). |
| 374 // 2, Reset() was called during flushing decoder (see OnDecoderReset()). | 374 // 2, Reset() was called during flushing decoder (see OnDecoderReset()). |
| 375 // Also, Reset() can be called during pending ReinitializeDecoder(). | 375 // Also, Reset() can be called during pending ReinitializeDecoder(). |
| 376 // This function needs to handle them all! | 376 // This function needs to handle them all! |
| 377 | 377 |
| 378 state_ = (status == PIPELINE_OK) ? STATE_NORMAL : STATE_ERROR; | 378 state_ = (status == PIPELINE_OK) ? STATE_NORMAL : STATE_ERROR; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 389 if (state_ == STATE_ERROR) { | 389 if (state_ == STATE_ERROR) { |
| 390 SatisfyRead(DECODE_ERROR, NULL); | 390 SatisfyRead(DECODE_ERROR, NULL); |
| 391 return; | 391 return; |
| 392 } | 392 } |
| 393 | 393 |
| 394 ReadFromDemuxerStream(); | 394 ReadFromDemuxerStream(); |
| 395 } | 395 } |
| 396 | 396 |
| 397 void VideoFrameStream::ResetDecoder() { | 397 void VideoFrameStream::ResetDecoder() { |
| 398 DVLOG(2) << __FUNCTION__; | 398 DVLOG(2) << __FUNCTION__; |
| 399 DCHECK(message_loop_->BelongsToCurrentThread()); | 399 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 400 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || | 400 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || |
| 401 state_ == STATE_ERROR) << state_; | 401 state_ == STATE_ERROR) << state_; |
| 402 DCHECK(!reset_cb_.is_null()); | 402 DCHECK(!reset_cb_.is_null()); |
| 403 | 403 |
| 404 decoder_->Reset(base::Bind(&VideoFrameStream::OnDecoderReset, | 404 decoder_->Reset(base::Bind(&VideoFrameStream::OnDecoderReset, |
| 405 weak_factory_.GetWeakPtr())); | 405 weak_factory_.GetWeakPtr())); |
| 406 } | 406 } |
| 407 | 407 |
| 408 void VideoFrameStream::OnDecoderReset() { | 408 void VideoFrameStream::OnDecoderReset() { |
| 409 DVLOG(2) << __FUNCTION__; | 409 DVLOG(2) << __FUNCTION__; |
| 410 DCHECK(message_loop_->BelongsToCurrentThread()); | 410 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 411 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || | 411 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || |
| 412 state_ == STATE_ERROR) << state_; | 412 state_ == STATE_ERROR) << state_; |
| 413 // If Reset() was called during pending read, read callback should be fired | 413 // If Reset() was called during pending read, read callback should be fired |
| 414 // before the reset callback is fired. | 414 // before the reset callback is fired. |
| 415 DCHECK(read_cb_.is_null()); | 415 DCHECK(read_cb_.is_null()); |
| 416 DCHECK(!reset_cb_.is_null()); | 416 DCHECK(!reset_cb_.is_null()); |
| 417 DCHECK(stop_cb_.is_null()); | 417 DCHECK(stop_cb_.is_null()); |
| 418 | 418 |
| 419 if (state_ != STATE_FLUSHING_DECODER) { | 419 if (state_ != STATE_FLUSHING_DECODER) { |
| 420 base::ResetAndReturn(&reset_cb_).Run(); | 420 base::ResetAndReturn(&reset_cb_).Run(); |
| 421 return; | 421 return; |
| 422 } | 422 } |
| 423 | 423 |
| 424 // The resetting process will be continued in OnDecoderReinitialized(). | 424 // The resetting process will be continued in OnDecoderReinitialized(). |
| 425 ReinitializeDecoder(); | 425 ReinitializeDecoder(); |
| 426 } | 426 } |
| 427 | 427 |
| 428 void VideoFrameStream::StopDecoder() { | 428 void VideoFrameStream::StopDecoder() { |
| 429 DVLOG(2) << __FUNCTION__; | 429 DVLOG(2) << __FUNCTION__; |
| 430 DCHECK(message_loop_->BelongsToCurrentThread()); | 430 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 431 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_; | 431 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_; |
| 432 DCHECK(!stop_cb_.is_null()); | 432 DCHECK(!stop_cb_.is_null()); |
| 433 | 433 |
| 434 decoder_->Stop(base::Bind(&VideoFrameStream::OnDecoderStopped, | 434 decoder_->Stop(base::Bind(&VideoFrameStream::OnDecoderStopped, |
| 435 weak_factory_.GetWeakPtr())); | 435 weak_factory_.GetWeakPtr())); |
| 436 } | 436 } |
| 437 | 437 |
| 438 void VideoFrameStream::OnDecoderStopped() { | 438 void VideoFrameStream::OnDecoderStopped() { |
| 439 DVLOG(2) << __FUNCTION__; | 439 DVLOG(2) << __FUNCTION__; |
| 440 DCHECK(message_loop_->BelongsToCurrentThread()); | 440 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 441 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_; | 441 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_; |
| 442 // If Stop() was called during pending read/reset, read/reset callback should | 442 // If Stop() was called during pending read/reset, read/reset callback should |
| 443 // be fired before the stop callback is fired. | 443 // be fired before the stop callback is fired. |
| 444 DCHECK(read_cb_.is_null()); | 444 DCHECK(read_cb_.is_null()); |
| 445 DCHECK(reset_cb_.is_null()); | 445 DCHECK(reset_cb_.is_null()); |
| 446 DCHECK(!stop_cb_.is_null()); | 446 DCHECK(!stop_cb_.is_null()); |
| 447 | 447 |
| 448 state_ = STATE_STOPPED; | 448 state_ = STATE_STOPPED; |
| 449 stream_ = NULL; | 449 stream_ = NULL; |
| 450 decoder_.reset(); | 450 decoder_.reset(); |
| 451 decrypting_demuxer_stream_.reset(); | 451 decrypting_demuxer_stream_.reset(); |
| 452 base::ResetAndReturn(&stop_cb_).Run(); | 452 base::ResetAndReturn(&stop_cb_).Run(); |
| 453 } | 453 } |
| 454 | 454 |
| 455 } // namespace media | 455 } // namespace media |
| OLD | NEW |