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