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 |