OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/decoder_stream.h" | 5 #include "media/filters/decoder_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" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 decoder_selector_( | 49 decoder_selector_( |
50 new DecoderSelector<StreamType>(task_runner, | 50 new DecoderSelector<StreamType>(task_runner, |
51 decoders.Pass(), | 51 decoders.Pass(), |
52 set_decryptor_ready_cb)), | 52 set_decryptor_ready_cb)), |
53 active_splice_(false), | 53 active_splice_(false), |
54 pending_decode_requests_(0), | 54 pending_decode_requests_(0), |
55 weak_factory_(this) {} | 55 weak_factory_(this) {} |
56 | 56 |
57 template <DemuxerStream::Type StreamType> | 57 template <DemuxerStream::Type StreamType> |
58 DecoderStream<StreamType>::~DecoderStream() { | 58 DecoderStream<StreamType>::~DecoderStream() { |
59 DCHECK(state_ == STATE_UNINITIALIZED || state_ == STATE_STOPPED) << state_; | 59 FUNCTION_DVLOG(2); |
| 60 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 61 |
| 62 // TODO(xhwang): Fold DecoderSelector::Abort() into the dtor. |
| 63 if (state_ == STATE_INITIALIZING) |
| 64 decoder_selector_->Abort(); |
| 65 |
| 66 if (!init_cb_.is_null()) { |
| 67 task_runner_->PostTask(FROM_HERE, |
| 68 base::Bind(base::ResetAndReturn(&init_cb_), false)); |
| 69 } |
| 70 if (!read_cb_.is_null()) { |
| 71 task_runner_->PostTask(FROM_HERE, base::Bind( |
| 72 base::ResetAndReturn(&read_cb_), ABORTED, scoped_refptr<Output>())); |
| 73 } |
| 74 if (!reset_cb_.is_null()) |
| 75 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&reset_cb_)); |
| 76 |
| 77 if (decrypting_demuxer_stream_) |
| 78 decrypting_demuxer_stream_->Stop(); |
| 79 |
| 80 stream_ = NULL; |
| 81 decoder_.reset(); |
| 82 decrypting_demuxer_stream_.reset(); |
60 } | 83 } |
61 | 84 |
62 template <DemuxerStream::Type StreamType> | 85 template <DemuxerStream::Type StreamType> |
63 void DecoderStream<StreamType>::Initialize(DemuxerStream* stream, | 86 void DecoderStream<StreamType>::Initialize(DemuxerStream* stream, |
64 bool low_delay, | 87 bool low_delay, |
65 const StatisticsCB& statistics_cb, | 88 const StatisticsCB& statistics_cb, |
66 const InitCB& init_cb) { | 89 const InitCB& init_cb) { |
67 FUNCTION_DVLOG(2); | 90 FUNCTION_DVLOG(2); |
68 DCHECK(task_runner_->BelongsToCurrentThread()); | 91 DCHECK(task_runner_->BelongsToCurrentThread()); |
69 DCHECK_EQ(state_, STATE_UNINITIALIZED) << state_; | 92 DCHECK_EQ(state_, STATE_UNINITIALIZED) << state_; |
(...skipping 12 matching lines...) Expand all Loading... |
82 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected, | 105 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected, |
83 weak_factory_.GetWeakPtr()), | 106 weak_factory_.GetWeakPtr()), |
84 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, | 107 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, |
85 weak_factory_.GetWeakPtr())); | 108 weak_factory_.GetWeakPtr())); |
86 } | 109 } |
87 | 110 |
88 template <DemuxerStream::Type StreamType> | 111 template <DemuxerStream::Type StreamType> |
89 void DecoderStream<StreamType>::Read(const ReadCB& read_cb) { | 112 void DecoderStream<StreamType>::Read(const ReadCB& read_cb) { |
90 FUNCTION_DVLOG(2); | 113 FUNCTION_DVLOG(2); |
91 DCHECK(task_runner_->BelongsToCurrentThread()); | 114 DCHECK(task_runner_->BelongsToCurrentThread()); |
92 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_INITIALIZING && | 115 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_INITIALIZING) |
93 state_ != STATE_STOPPED) << state_; | 116 << state_; |
94 // No two reads in the flight at any time. | 117 // No two reads in the flight at any time. |
95 DCHECK(read_cb_.is_null()); | 118 DCHECK(read_cb_.is_null()); |
96 // No read during resetting or stopping process. | 119 // No read during resetting or stopping process. |
97 DCHECK(reset_cb_.is_null()); | 120 DCHECK(reset_cb_.is_null()); |
98 DCHECK(stop_cb_.is_null()); | |
99 | 121 |
100 if (state_ == STATE_ERROR) { | 122 if (state_ == STATE_ERROR) { |
101 task_runner_->PostTask( | 123 task_runner_->PostTask( |
102 FROM_HERE, base::Bind(read_cb, DECODE_ERROR, scoped_refptr<Output>())); | 124 FROM_HERE, base::Bind(read_cb, DECODE_ERROR, scoped_refptr<Output>())); |
103 return; | 125 return; |
104 } | 126 } |
105 | 127 |
106 if (state_ == STATE_END_OF_STREAM && ready_outputs_.empty()) { | 128 if (state_ == STATE_END_OF_STREAM && ready_outputs_.empty()) { |
107 task_runner_->PostTask( | 129 task_runner_->PostTask( |
108 FROM_HERE, base::Bind(read_cb, OK, StreamTraits::CreateEOSOutput())); | 130 FROM_HERE, base::Bind(read_cb, OK, StreamTraits::CreateEOSOutput())); |
109 return; | 131 return; |
110 } | 132 } |
111 | 133 |
112 if (!ready_outputs_.empty()) { | 134 if (!ready_outputs_.empty()) { |
113 task_runner_->PostTask(FROM_HERE, | 135 task_runner_->PostTask(FROM_HERE, |
114 base::Bind(read_cb, OK, ready_outputs_.front())); | 136 base::Bind(read_cb, OK, ready_outputs_.front())); |
115 ready_outputs_.pop_front(); | 137 ready_outputs_.pop_front(); |
116 } else { | 138 } else { |
117 read_cb_ = read_cb; | 139 read_cb_ = read_cb; |
118 } | 140 } |
119 | 141 |
120 if (state_ == STATE_NORMAL && CanDecodeMore()) | 142 if (state_ == STATE_NORMAL && CanDecodeMore()) |
121 ReadFromDemuxerStream(); | 143 ReadFromDemuxerStream(); |
122 } | 144 } |
123 | 145 |
124 template <DemuxerStream::Type StreamType> | 146 template <DemuxerStream::Type StreamType> |
125 void DecoderStream<StreamType>::Reset(const base::Closure& closure) { | 147 void DecoderStream<StreamType>::Reset(const base::Closure& closure) { |
126 FUNCTION_DVLOG(2); | 148 FUNCTION_DVLOG(2); |
127 DCHECK(task_runner_->BelongsToCurrentThread()); | 149 DCHECK(task_runner_->BelongsToCurrentThread()); |
128 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_; | 150 DCHECK(state_ != STATE_UNINITIALIZED)<< state_; |
129 DCHECK(reset_cb_.is_null()); | 151 DCHECK(reset_cb_.is_null()); |
130 DCHECK(stop_cb_.is_null()); | |
131 | 152 |
132 reset_cb_ = closure; | 153 reset_cb_ = closure; |
133 | 154 |
134 if (!read_cb_.is_null()) { | 155 if (!read_cb_.is_null()) { |
135 task_runner_->PostTask(FROM_HERE, base::Bind( | 156 task_runner_->PostTask(FROM_HERE, base::Bind( |
136 base::ResetAndReturn(&read_cb_), ABORTED, scoped_refptr<Output>())); | 157 base::ResetAndReturn(&read_cb_), ABORTED, scoped_refptr<Output>())); |
137 } | 158 } |
138 | 159 |
139 ready_outputs_.clear(); | 160 ready_outputs_.clear(); |
140 | 161 |
(...skipping 12 matching lines...) Expand all Loading... |
153 if (decrypting_demuxer_stream_) { | 174 if (decrypting_demuxer_stream_) { |
154 decrypting_demuxer_stream_->Reset(base::Bind( | 175 decrypting_demuxer_stream_->Reset(base::Bind( |
155 &DecoderStream<StreamType>::ResetDecoder, weak_factory_.GetWeakPtr())); | 176 &DecoderStream<StreamType>::ResetDecoder, weak_factory_.GetWeakPtr())); |
156 return; | 177 return; |
157 } | 178 } |
158 | 179 |
159 ResetDecoder(); | 180 ResetDecoder(); |
160 } | 181 } |
161 | 182 |
162 template <DemuxerStream::Type StreamType> | 183 template <DemuxerStream::Type StreamType> |
163 void DecoderStream<StreamType>::Stop(const base::Closure& closure) { | |
164 FUNCTION_DVLOG(2); | |
165 DCHECK(task_runner_->BelongsToCurrentThread()); | |
166 DCHECK_NE(state_, STATE_STOPPED) << state_; | |
167 DCHECK(stop_cb_.is_null()); | |
168 | |
169 // TODO(xhwang): This is the only asynchronousness in DecoderStream::Stop(). | |
170 // Fix this so that we can merge the stopping code into the dtor. | |
171 if (state_ == STATE_INITIALIZING) { | |
172 stop_cb_ = closure; | |
173 decoder_selector_->Abort(); | |
174 return; | |
175 } | |
176 | |
177 DCHECK(init_cb_.is_null()); | |
178 | |
179 // All pending callbacks will be dropped. | |
180 weak_factory_.InvalidateWeakPtrs(); | |
181 | |
182 // Post callbacks to prevent reentrance into this object. | |
183 if (!read_cb_.is_null()) { | |
184 task_runner_->PostTask(FROM_HERE, base::Bind( | |
185 base::ResetAndReturn(&read_cb_), ABORTED, scoped_refptr<Output>())); | |
186 } | |
187 if (!reset_cb_.is_null()) | |
188 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&reset_cb_)); | |
189 | |
190 if (decrypting_demuxer_stream_) | |
191 decrypting_demuxer_stream_->Stop(); | |
192 | |
193 stream_ = NULL; | |
194 decoder_.reset(); | |
195 decrypting_demuxer_stream_.reset(); | |
196 | |
197 state_ = STATE_STOPPED; | |
198 task_runner_->PostTask(FROM_HERE, closure); | |
199 } | |
200 | |
201 template <DemuxerStream::Type StreamType> | |
202 bool DecoderStream<StreamType>::CanReadWithoutStalling() const { | 184 bool DecoderStream<StreamType>::CanReadWithoutStalling() const { |
203 DCHECK(task_runner_->BelongsToCurrentThread()); | 185 DCHECK(task_runner_->BelongsToCurrentThread()); |
204 return !ready_outputs_.empty() || decoder_->CanReadWithoutStalling(); | 186 return !ready_outputs_.empty() || decoder_->CanReadWithoutStalling(); |
205 } | 187 } |
206 | 188 |
207 template <> | 189 template <> |
208 bool DecoderStream<DemuxerStream::AUDIO>::CanReadWithoutStalling() const { | 190 bool DecoderStream<DemuxerStream::AUDIO>::CanReadWithoutStalling() const { |
209 DCHECK(task_runner_->BelongsToCurrentThread()); | 191 DCHECK(task_runner_->BelongsToCurrentThread()); |
210 return true; | 192 return true; |
211 } | 193 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 DCHECK(reset_cb_.is_null()); | 226 DCHECK(reset_cb_.is_null()); |
245 | 227 |
246 decoder_selector_.reset(); | 228 decoder_selector_.reset(); |
247 if (decrypting_demuxer_stream) | 229 if (decrypting_demuxer_stream) |
248 stream_ = decrypting_demuxer_stream.get(); | 230 stream_ = decrypting_demuxer_stream.get(); |
249 | 231 |
250 if (!selected_decoder) { | 232 if (!selected_decoder) { |
251 state_ = STATE_UNINITIALIZED; | 233 state_ = STATE_UNINITIALIZED; |
252 StreamTraits::FinishInitialization( | 234 StreamTraits::FinishInitialization( |
253 base::ResetAndReturn(&init_cb_), selected_decoder.get(), stream_); | 235 base::ResetAndReturn(&init_cb_), selected_decoder.get(), stream_); |
254 } else { | 236 return; |
255 state_ = STATE_NORMAL; | |
256 decoder_ = selected_decoder.Pass(); | |
257 decrypting_demuxer_stream_ = decrypting_demuxer_stream.Pass(); | |
258 StreamTraits::FinishInitialization( | |
259 base::ResetAndReturn(&init_cb_), decoder_.get(), stream_); | |
260 } | 237 } |
261 | 238 |
262 // Stop() called during initialization. | 239 state_ = STATE_NORMAL; |
263 if (!stop_cb_.is_null()) { | 240 decoder_ = selected_decoder.Pass(); |
264 Stop(base::ResetAndReturn(&stop_cb_)); | 241 decrypting_demuxer_stream_ = decrypting_demuxer_stream.Pass(); |
265 return; | 242 StreamTraits::FinishInitialization( |
266 } | 243 base::ResetAndReturn(&init_cb_), decoder_.get(), stream_); |
267 } | 244 } |
268 | 245 |
269 template <DemuxerStream::Type StreamType> | 246 template <DemuxerStream::Type StreamType> |
270 void DecoderStream<StreamType>::SatisfyRead( | 247 void DecoderStream<StreamType>::SatisfyRead( |
271 Status status, | 248 Status status, |
272 const scoped_refptr<Output>& output) { | 249 const scoped_refptr<Output>& output) { |
273 DCHECK(!read_cb_.is_null()); | 250 DCHECK(!read_cb_.is_null()); |
274 base::ResetAndReturn(&read_cb_).Run(status, output); | 251 base::ResetAndReturn(&read_cb_).Run(status, output); |
275 } | 252 } |
276 | 253 |
277 template <DemuxerStream::Type StreamType> | 254 template <DemuxerStream::Type StreamType> |
278 void DecoderStream<StreamType>::Decode( | 255 void DecoderStream<StreamType>::Decode( |
279 const scoped_refptr<DecoderBuffer>& buffer) { | 256 const scoped_refptr<DecoderBuffer>& buffer) { |
280 FUNCTION_DVLOG(2); | 257 FUNCTION_DVLOG(2); |
281 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_; | 258 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_; |
282 DCHECK_LT(pending_decode_requests_, GetMaxDecodeRequests()); | 259 DCHECK_LT(pending_decode_requests_, GetMaxDecodeRequests()); |
283 DCHECK(reset_cb_.is_null()); | 260 DCHECK(reset_cb_.is_null()); |
284 DCHECK(stop_cb_.is_null()); | |
285 DCHECK(buffer); | 261 DCHECK(buffer); |
286 | 262 |
287 int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size(); | 263 int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size(); |
288 | 264 |
289 TRACE_EVENT_ASYNC_BEGIN0("media", GetTraceString<StreamType>(), this); | 265 TRACE_EVENT_ASYNC_BEGIN0("media", GetTraceString<StreamType>(), this); |
290 ++pending_decode_requests_; | 266 ++pending_decode_requests_; |
291 decoder_->Decode(buffer, | 267 decoder_->Decode(buffer, |
292 base::Bind(&DecoderStream<StreamType>::OnDecodeDone, | 268 base::Bind(&DecoderStream<StreamType>::OnDecodeDone, |
293 weak_factory_.GetWeakPtr(), | 269 weak_factory_.GetWeakPtr(), |
294 buffer_size, | 270 buffer_size, |
295 buffer->end_of_stream())); | 271 buffer->end_of_stream())); |
296 } | 272 } |
297 | 273 |
298 template <DemuxerStream::Type StreamType> | 274 template <DemuxerStream::Type StreamType> |
299 void DecoderStream<StreamType>::FlushDecoder() { | 275 void DecoderStream<StreamType>::FlushDecoder() { |
300 Decode(DecoderBuffer::CreateEOSBuffer()); | 276 Decode(DecoderBuffer::CreateEOSBuffer()); |
301 } | 277 } |
302 | 278 |
303 template <DemuxerStream::Type StreamType> | 279 template <DemuxerStream::Type StreamType> |
304 void DecoderStream<StreamType>::OnDecodeDone(int buffer_size, | 280 void DecoderStream<StreamType>::OnDecodeDone(int buffer_size, |
305 bool end_of_stream, | 281 bool end_of_stream, |
306 typename Decoder::Status status) { | 282 typename Decoder::Status status) { |
307 FUNCTION_DVLOG(2) << status; | 283 FUNCTION_DVLOG(2) << status; |
308 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || | 284 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || |
309 state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR) | 285 state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR) |
310 << state_; | 286 << state_; |
311 DCHECK(stop_cb_.is_null()); | |
312 DCHECK_GT(pending_decode_requests_, 0); | 287 DCHECK_GT(pending_decode_requests_, 0); |
313 | 288 |
314 --pending_decode_requests_; | 289 --pending_decode_requests_; |
315 | 290 |
316 TRACE_EVENT_ASYNC_END0("media", GetTraceString<StreamType>(), this); | 291 TRACE_EVENT_ASYNC_END0("media", GetTraceString<StreamType>(), this); |
317 | 292 |
318 if (state_ == STATE_ERROR) { | 293 if (state_ == STATE_ERROR) { |
319 DCHECK(read_cb_.is_null()); | 294 DCHECK(read_cb_.is_null()); |
320 return; | 295 return; |
321 } | 296 } |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 ready_outputs_.pop_front(); | 371 ready_outputs_.pop_front(); |
397 SatisfyRead(OK, output); | 372 SatisfyRead(OK, output); |
398 } | 373 } |
399 | 374 |
400 template <DemuxerStream::Type StreamType> | 375 template <DemuxerStream::Type StreamType> |
401 void DecoderStream<StreamType>::ReadFromDemuxerStream() { | 376 void DecoderStream<StreamType>::ReadFromDemuxerStream() { |
402 FUNCTION_DVLOG(2); | 377 FUNCTION_DVLOG(2); |
403 DCHECK_EQ(state_, STATE_NORMAL) << state_; | 378 DCHECK_EQ(state_, STATE_NORMAL) << state_; |
404 DCHECK(CanDecodeMore()); | 379 DCHECK(CanDecodeMore()); |
405 DCHECK(reset_cb_.is_null()); | 380 DCHECK(reset_cb_.is_null()); |
406 DCHECK(stop_cb_.is_null()); | |
407 | 381 |
408 state_ = STATE_PENDING_DEMUXER_READ; | 382 state_ = STATE_PENDING_DEMUXER_READ; |
409 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady, | 383 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady, |
410 weak_factory_.GetWeakPtr())); | 384 weak_factory_.GetWeakPtr())); |
411 } | 385 } |
412 | 386 |
413 template <DemuxerStream::Type StreamType> | 387 template <DemuxerStream::Type StreamType> |
414 void DecoderStream<StreamType>::OnBufferReady( | 388 void DecoderStream<StreamType>::OnBufferReady( |
415 DemuxerStream::Status status, | 389 DemuxerStream::Status status, |
416 const scoped_refptr<DecoderBuffer>& buffer) { | 390 const scoped_refptr<DecoderBuffer>& buffer) { |
417 FUNCTION_DVLOG(2) << ": " << status << ", " | 391 FUNCTION_DVLOG(2) << ": " << status << ", " |
418 << (buffer ? buffer->AsHumanReadableString() : "NULL"); | 392 << (buffer ? buffer->AsHumanReadableString() : "NULL"); |
419 | 393 |
420 DCHECK(task_runner_->BelongsToCurrentThread()); | 394 DCHECK(task_runner_->BelongsToCurrentThread()); |
421 DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR || | 395 DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR) |
422 state_ == STATE_STOPPED) | |
423 << state_; | 396 << state_; |
424 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status; | 397 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status; |
425 DCHECK(stop_cb_.is_null()); | |
426 | 398 |
427 // Decoding has been stopped (e.g due to an error). | 399 // Decoding has been stopped (e.g due to an error). |
428 if (state_ != STATE_PENDING_DEMUXER_READ) { | 400 if (state_ != STATE_PENDING_DEMUXER_READ) { |
429 DCHECK(state_ == STATE_ERROR || state_ == STATE_STOPPED); | 401 DCHECK(state_ == STATE_ERROR); |
430 DCHECK(read_cb_.is_null()); | 402 DCHECK(read_cb_.is_null()); |
431 return; | 403 return; |
432 } | 404 } |
433 | 405 |
434 state_ = STATE_NORMAL; | 406 state_ = STATE_NORMAL; |
435 | 407 |
436 if (status == DemuxerStream::kConfigChanged) { | 408 if (status == DemuxerStream::kConfigChanged) { |
437 FUNCTION_DVLOG(2) << ": " << "ConfigChanged"; | 409 FUNCTION_DVLOG(2) << ": " << "ConfigChanged"; |
438 DCHECK(stream_->SupportsConfigChanges()); | 410 DCHECK(stream_->SupportsConfigChanges()); |
439 | 411 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
500 weak_factory_.GetWeakPtr()), | 472 weak_factory_.GetWeakPtr()), |
501 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, | 473 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, |
502 weak_factory_.GetWeakPtr())); | 474 weak_factory_.GetWeakPtr())); |
503 } | 475 } |
504 | 476 |
505 template <DemuxerStream::Type StreamType> | 477 template <DemuxerStream::Type StreamType> |
506 void DecoderStream<StreamType>::OnDecoderReinitialized(PipelineStatus status) { | 478 void DecoderStream<StreamType>::OnDecoderReinitialized(PipelineStatus status) { |
507 FUNCTION_DVLOG(2); | 479 FUNCTION_DVLOG(2); |
508 DCHECK(task_runner_->BelongsToCurrentThread()); | 480 DCHECK(task_runner_->BelongsToCurrentThread()); |
509 DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER) << state_; | 481 DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER) << state_; |
510 DCHECK(stop_cb_.is_null()); | |
511 | 482 |
512 // ReinitializeDecoder() can be called in two cases: | 483 // ReinitializeDecoder() can be called in two cases: |
513 // 1, Flushing decoder finished (see OnDecodeOutputReady()). | 484 // 1, Flushing decoder finished (see OnDecodeOutputReady()). |
514 // 2, Reset() was called during flushing decoder (see OnDecoderReset()). | 485 // 2, Reset() was called during flushing decoder (see OnDecoderReset()). |
515 // Also, Reset() can be called during pending ReinitializeDecoder(). | 486 // Also, Reset() can be called during pending ReinitializeDecoder(). |
516 // This function needs to handle them all! | 487 // This function needs to handle them all! |
517 | 488 |
518 state_ = (status == PIPELINE_OK) ? STATE_NORMAL : STATE_ERROR; | 489 state_ = (status == PIPELINE_OK) ? STATE_NORMAL : STATE_ERROR; |
519 | 490 |
520 if (!reset_cb_.is_null()) { | 491 if (!reset_cb_.is_null()) { |
(...skipping 27 matching lines...) Expand all Loading... |
548 template <DemuxerStream::Type StreamType> | 519 template <DemuxerStream::Type StreamType> |
549 void DecoderStream<StreamType>::OnDecoderReset() { | 520 void DecoderStream<StreamType>::OnDecoderReset() { |
550 FUNCTION_DVLOG(2); | 521 FUNCTION_DVLOG(2); |
551 DCHECK(task_runner_->BelongsToCurrentThread()); | 522 DCHECK(task_runner_->BelongsToCurrentThread()); |
552 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || | 523 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || |
553 state_ == STATE_ERROR || state_ == STATE_END_OF_STREAM) << state_; | 524 state_ == STATE_ERROR || state_ == STATE_END_OF_STREAM) << state_; |
554 // If Reset() was called during pending read, read callback should be fired | 525 // If Reset() was called during pending read, read callback should be fired |
555 // before the reset callback is fired. | 526 // before the reset callback is fired. |
556 DCHECK(read_cb_.is_null()); | 527 DCHECK(read_cb_.is_null()); |
557 DCHECK(!reset_cb_.is_null()); | 528 DCHECK(!reset_cb_.is_null()); |
558 DCHECK(stop_cb_.is_null()); | |
559 | 529 |
560 if (state_ != STATE_FLUSHING_DECODER) { | 530 if (state_ != STATE_FLUSHING_DECODER) { |
561 state_ = STATE_NORMAL; | 531 state_ = STATE_NORMAL; |
562 active_splice_ = false; | 532 active_splice_ = false; |
563 base::ResetAndReturn(&reset_cb_).Run(); | 533 base::ResetAndReturn(&reset_cb_).Run(); |
564 return; | 534 return; |
565 } | 535 } |
566 | 536 |
567 // The resetting process will be continued in OnDecoderReinitialized(). | 537 // The resetting process will be continued in OnDecoderReinitialized(). |
568 ReinitializeDecoder(); | 538 ReinitializeDecoder(); |
569 } | 539 } |
570 | 540 |
571 template class DecoderStream<DemuxerStream::VIDEO>; | 541 template class DecoderStream<DemuxerStream::VIDEO>; |
572 template class DecoderStream<DemuxerStream::AUDIO>; | 542 template class DecoderStream<DemuxerStream::AUDIO>; |
573 | 543 |
574 } // namespace media | 544 } // namespace media |
OLD | NEW |