Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Side by Side Diff: media/filters/decoder_stream.cc

Issue 1879353003: Attempt decoder fallback if first decode fails (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: new test for EOS flushing edge case Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/filters/decoder_stream.h ('k') | media/filters/video_frame_stream_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 state_(STATE_UNINITIALIZED), 52 state_(STATE_UNINITIALIZED),
53 stream_(NULL), 53 stream_(NULL),
54 decoder_selector_(new DecoderSelector<StreamType>(task_runner, 54 decoder_selector_(new DecoderSelector<StreamType>(task_runner,
55 std::move(decoders), 55 std::move(decoders),
56 media_log)), 56 media_log)),
57 decoded_frames_since_fallback_(0), 57 decoded_frames_since_fallback_(0),
58 active_splice_(false), 58 active_splice_(false),
59 decoding_eos_(false), 59 decoding_eos_(false),
60 pending_decode_requests_(0), 60 pending_decode_requests_(0),
61 duration_tracker_(8), 61 duration_tracker_(8),
62 weak_factory_(this) {} 62 weak_factory_(this),
63 fallback_weak_factory_(this) {}
63 64
64 template <DemuxerStream::Type StreamType> 65 template <DemuxerStream::Type StreamType>
65 DecoderStream<StreamType>::~DecoderStream() { 66 DecoderStream<StreamType>::~DecoderStream() {
66 FUNCTION_DVLOG(2); 67 FUNCTION_DVLOG(2);
67 DCHECK(task_runner_->BelongsToCurrentThread()); 68 DCHECK(task_runner_->BelongsToCurrentThread());
68 69
69 decoder_selector_.reset(); 70 decoder_selector_.reset();
70 71
71 if (!init_cb_.is_null()) { 72 if (!init_cb_.is_null()) {
72 task_runner_->PostTask(FROM_HERE, 73 task_runner_->PostTask(FROM_HERE,
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 : base::TimeDelta(); 225 : base::TimeDelta();
225 } 226 }
226 227
227 template <DemuxerStream::Type StreamType> 228 template <DemuxerStream::Type StreamType>
228 void DecoderStream<StreamType>::SelectDecoder(CdmContext* cdm_context) { 229 void DecoderStream<StreamType>::SelectDecoder(CdmContext* cdm_context) {
229 decoder_selector_->SelectDecoder( 230 decoder_selector_->SelectDecoder(
230 stream_, cdm_context, 231 stream_, cdm_context,
231 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected, 232 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected,
232 weak_factory_.GetWeakPtr()), 233 weak_factory_.GetWeakPtr()),
233 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, 234 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady,
234 weak_factory_.GetWeakPtr()), 235 fallback_weak_factory_.GetWeakPtr()),
235 waiting_for_decryption_key_cb_); 236 waiting_for_decryption_key_cb_);
236 } 237 }
237 238
238 template <DemuxerStream::Type StreamType> 239 template <DemuxerStream::Type StreamType>
239 void DecoderStream<StreamType>::OnDecoderSelected( 240 void DecoderStream<StreamType>::OnDecoderSelected(
240 scoped_ptr<Decoder> selected_decoder, 241 scoped_ptr<Decoder> selected_decoder,
241 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { 242 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) {
242 FUNCTION_DVLOG(2) << ": " 243 FUNCTION_DVLOG(2) << ": "
243 << (selected_decoder ? selected_decoder->GetDisplayName() 244 << (selected_decoder ? selected_decoder->GetDisplayName()
244 : "No decoder selected."); 245 : "No decoder selected.");
245 DCHECK(task_runner_->BelongsToCurrentThread()); 246 DCHECK(task_runner_->BelongsToCurrentThread());
246 DCHECK(state_ == STATE_INITIALIZING || state_ == STATE_REINITIALIZING_DECODER) 247 DCHECK(state_ == STATE_INITIALIZING ||
248 state_ == STATE_REINITIALIZING_DECODER ||
249 state_ == STATE_CONFIG_CHANGE_RECEIVED_WHILE_REINITIALIZING_DECODER)
247 << state_; 250 << state_;
248 if (state_ == STATE_INITIALIZING) { 251 if (state_ == STATE_INITIALIZING) {
249 DCHECK(!init_cb_.is_null()); 252 DCHECK(!init_cb_.is_null());
250 DCHECK(read_cb_.is_null()); 253 DCHECK(read_cb_.is_null());
251 DCHECK(reset_cb_.is_null()); 254 DCHECK(reset_cb_.is_null());
252 } else { 255 } else if (state_ == STATE_REINITIALIZING_DECODER) {
253 DCHECK(decoder_); 256 DCHECK(decoder_);
254 } 257 }
255 258
256 previous_decoder_ = std::move(decoder_); 259 previous_decoder_ = std::move(decoder_);
257 decoded_frames_since_fallback_ = 0; 260 decoded_frames_since_fallback_ = 0;
258 decoder_ = std::move(selected_decoder); 261 decoder_ = std::move(selected_decoder);
259 if (decrypting_demuxer_stream) { 262 if (decrypting_demuxer_stream) {
260 decrypting_demuxer_stream_ = std::move(decrypting_demuxer_stream); 263 decrypting_demuxer_stream_ = std::move(decrypting_demuxer_stream);
261 stream_ = decrypting_demuxer_stream_.get(); 264 stream_ = decrypting_demuxer_stream_.get();
262 } 265 }
263 266
267 // TODO(tguilbert): crbug.com/603713 support config changes on decoder reinit.
268 if (state_ == STATE_CONFIG_CHANGE_RECEIVED_WHILE_REINITIALIZING_DECODER) {
269 CompleteDecoderReinitialization(false);
270 return;
271 }
272
273 // Attempt to decode buffers from previous decoders (when those decoders have
274 // never successfully outputed a frame).
275 fallback_buffers_ = pending_buffers_;
276
264 if (!decoder_) { 277 if (!decoder_) {
265 if (state_ == STATE_INITIALIZING) { 278 if (state_ == STATE_INITIALIZING) {
266 state_ = STATE_UNINITIALIZED; 279 state_ = STATE_UNINITIALIZED;
267 MEDIA_LOG(ERROR, media_log_) << GetStreamTypeString() 280 MEDIA_LOG(ERROR, media_log_) << GetStreamTypeString()
268 << " decoder initialization failed"; 281 << " decoder initialization failed";
269 base::ResetAndReturn(&init_cb_).Run(false); 282 base::ResetAndReturn(&init_cb_).Run(false);
270 } else { 283 } else {
271 CompleteDecoderReinitialization(false); 284 CompleteDecoderReinitialization(false);
272 } 285 }
273 return; 286 return;
(...skipping 21 matching lines...) Expand all
295 Status status, 308 Status status,
296 const scoped_refptr<Output>& output) { 309 const scoped_refptr<Output>& output) {
297 DCHECK(!read_cb_.is_null()); 310 DCHECK(!read_cb_.is_null());
298 base::ResetAndReturn(&read_cb_).Run(status, output); 311 base::ResetAndReturn(&read_cb_).Run(status, output);
299 } 312 }
300 313
301 template <DemuxerStream::Type StreamType> 314 template <DemuxerStream::Type StreamType>
302 void DecoderStream<StreamType>::Decode( 315 void DecoderStream<StreamType>::Decode(
303 const scoped_refptr<DecoderBuffer>& buffer) { 316 const scoped_refptr<DecoderBuffer>& buffer) {
304 FUNCTION_DVLOG(2); 317 FUNCTION_DVLOG(2);
318
319 // We don't know if the decoder will error out on first decode yet. Save the
320 // buffer to feed it to the fallback decoder later if needed.
321 if (!decoded_frames_since_fallback_)
322 pending_buffers_.push_back(buffer);
323
324 DecodeInternal(buffer);
325 }
326
327 template <DemuxerStream::Type StreamType>
328 void DecoderStream<StreamType>::DecodeInternal(
329 const scoped_refptr<DecoderBuffer>& buffer) {
330 FUNCTION_DVLOG(2);
305 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_; 331 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_;
306 DCHECK_LT(pending_decode_requests_, GetMaxDecodeRequests()); 332 DCHECK_LT(pending_decode_requests_, GetMaxDecodeRequests());
307 DCHECK(reset_cb_.is_null()); 333 DCHECK(reset_cb_.is_null());
308 DCHECK(buffer.get()); 334 DCHECK(buffer.get());
309 335
310 int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size(); 336 int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size();
311 337
312 TRACE_EVENT_ASYNC_BEGIN2( 338 TRACE_EVENT_ASYNC_BEGIN2(
313 "media", GetTraceString<StreamType>(), this, "key frame", 339 "media", GetTraceString<StreamType>(), this, "key frame",
314 !buffer->end_of_stream() && buffer->is_key_frame(), "timestamp (ms)", 340 !buffer->end_of_stream() && buffer->is_key_frame(), "timestamp (ms)",
315 !buffer->end_of_stream() ? buffer->timestamp().InMilliseconds() : 0); 341 !buffer->end_of_stream() ? buffer->timestamp().InMilliseconds() : 0);
316 342
317 if (buffer->end_of_stream()) 343 if (buffer->end_of_stream())
318 decoding_eos_ = true; 344 decoding_eos_ = true;
319 else if (buffer->duration() != kNoTimestamp()) 345 else if (buffer->duration() != kNoTimestamp())
320 duration_tracker_.AddSample(buffer->duration()); 346 duration_tracker_.AddSample(buffer->duration());
321 347
322 ++pending_decode_requests_; 348 ++pending_decode_requests_;
323 decoder_->Decode(buffer, 349 decoder_->Decode(buffer, base::Bind(&DecoderStream<StreamType>::OnDecodeDone,
324 base::Bind(&DecoderStream<StreamType>::OnDecodeDone, 350 fallback_weak_factory_.GetWeakPtr(),
325 weak_factory_.GetWeakPtr(), 351 buffer_size, buffer->end_of_stream()));
326 buffer_size,
327 buffer->end_of_stream()));
328 } 352 }
329 353
330 template <DemuxerStream::Type StreamType> 354 template <DemuxerStream::Type StreamType>
331 void DecoderStream<StreamType>::FlushDecoder() { 355 void DecoderStream<StreamType>::FlushDecoder() {
332 Decode(DecoderBuffer::CreateEOSBuffer()); 356 // Send the EOS directly to the decoder, bypassing a potential add to
357 // |pending_buffers_|.
358 DecodeInternal(DecoderBuffer::CreateEOSBuffer());
333 } 359 }
334 360
335 template <DemuxerStream::Type StreamType> 361 template <DemuxerStream::Type StreamType>
336 void DecoderStream<StreamType>::OnDecodeDone(int buffer_size, 362 void DecoderStream<StreamType>::OnDecodeDone(int buffer_size,
337 bool end_of_stream, 363 bool end_of_stream,
338 DecodeStatus status) { 364 DecodeStatus status) {
339 FUNCTION_DVLOG(2) << ": " << status; 365 FUNCTION_DVLOG(2) << ": " << status;
340 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || 366 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
341 state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR) 367 state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR)
342 << state_; 368 << state_;
(...skipping 13 matching lines...) Expand all
356 return; 382 return;
357 } 383 }
358 384
359 // Drop decoding result if Reset() was called during decoding. 385 // Drop decoding result if Reset() was called during decoding.
360 // The resetting process will be handled when the decoder is reset. 386 // The resetting process will be handled when the decoder is reset.
361 if (!reset_cb_.is_null()) 387 if (!reset_cb_.is_null())
362 return; 388 return;
363 389
364 switch (status) { 390 switch (status) {
365 case DecodeStatus::DECODE_ERROR: 391 case DecodeStatus::DECODE_ERROR:
392 if (!decoded_frames_since_fallback_) {
393 pending_decode_requests_ = 0;
394
395 // Prevent all pending decode requests and outputs form those requests
396 // from being called back.
397 fallback_weak_factory_.InvalidateWeakPtrs();
398
399 state_ = STATE_REINITIALIZING_DECODER;
400 decoder_selector_->SelectDecoder(
401 stream_, nullptr,
402 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected,
403 weak_factory_.GetWeakPtr()),
404 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady,
405 fallback_weak_factory_.GetWeakPtr()),
406 waiting_for_decryption_key_cb_);
407 return;
408 }
366 state_ = STATE_ERROR; 409 state_ = STATE_ERROR;
367 MEDIA_LOG(ERROR, media_log_) << GetStreamTypeString() << " decode error"; 410 MEDIA_LOG(ERROR, media_log_) << GetStreamTypeString() << " decode error";
368 ready_outputs_.clear(); 411 ready_outputs_.clear();
369 if (!read_cb_.is_null()) 412 if (!read_cb_.is_null())
370 SatisfyRead(DECODE_ERROR, NULL); 413 SatisfyRead(DECODE_ERROR, NULL);
371 return; 414 return;
372 415
373 case DecodeStatus::ABORTED: 416 case DecodeStatus::ABORTED:
374 // Decoder can return DecodeStatus::ABORTED during Reset() or during 417 // Decoder can return DecodeStatus::ABORTED during Reset() or during
375 // destruction. 418 // destruction.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 if (state_ == STATE_ERROR) { 454 if (state_ == STATE_ERROR) {
412 DCHECK(read_cb_.is_null()); 455 DCHECK(read_cb_.is_null());
413 return; 456 return;
414 } 457 }
415 458
416 // Drop decoding result if Reset() was called during decoding. 459 // Drop decoding result if Reset() was called during decoding.
417 // The resetting process will be handled when the decoder is reset. 460 // The resetting process will be handled when the decoder is reset.
418 if (!reset_cb_.is_null()) 461 if (!reset_cb_.is_null())
419 return; 462 return;
420 463
464 ++decoded_frames_since_fallback_;
465
466 // |decoder_| sucessfully decoded a frame. No need to keep buffers for a
467 // fallback decoder.
468 // Note: |fallback_buffers_| might still have buffers, and we will keep
469 // reading from there before requesting new buffers from |stream_|.
470 pending_buffers_.clear();
471
421 if (!read_cb_.is_null()) { 472 if (!read_cb_.is_null()) {
422 // If |ready_outputs_| was non-empty, the read would have already been 473 // If |ready_outputs_| was non-empty, the read would have already been
423 // satisifed by Read(). 474 // satisifed by Read().
424 DCHECK(ready_outputs_.empty()); 475 DCHECK(ready_outputs_.empty());
425 SatisfyRead(OK, output); 476 SatisfyRead(OK, output);
426 return; 477 return;
427 } 478 }
428 479
429 // Store decoded output. 480 // Store decoded output.
430 ready_outputs_.push_back(output); 481 ready_outputs_.push_back(output);
431 482
432 // Destruct any previous decoder once we've decoded enough frames to ensure 483 // Destruct any previous decoder once we've decoded enough frames to ensure
433 // that it's no longer in use. 484 // that it's no longer in use.
434 if (previous_decoder_ && 485 if (previous_decoder_ &&
435 ++decoded_frames_since_fallback_ > limits::kMaxVideoFrames) { 486 decoded_frames_since_fallback_ > limits::kMaxVideoFrames) {
436 previous_decoder_.reset(); 487 previous_decoder_.reset();
437 } 488 }
438 } 489 }
439 490
440 template <DemuxerStream::Type StreamType> 491 template <DemuxerStream::Type StreamType>
441 void DecoderStream<StreamType>::ReadFromDemuxerStream() { 492 void DecoderStream<StreamType>::ReadFromDemuxerStream() {
442 FUNCTION_DVLOG(2); 493 FUNCTION_DVLOG(2);
443 DCHECK_EQ(state_, STATE_NORMAL); 494 DCHECK_EQ(state_, STATE_NORMAL);
444 DCHECK(CanDecodeMore()); 495 DCHECK(CanDecodeMore());
445 DCHECK(reset_cb_.is_null()); 496 DCHECK(reset_cb_.is_null());
446 497
498 if (!fallback_buffers_.empty()) {
499 scoped_refptr<DecoderBuffer> buffer = fallback_buffers_.front();
500 fallback_buffers_.pop_front();
501
502 // Decode the buffer without re-appending it to |pending_buffers_|.
503 DecodeInternal(buffer);
504 return;
505 }
506
447 state_ = STATE_PENDING_DEMUXER_READ; 507 state_ = STATE_PENDING_DEMUXER_READ;
448 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady, 508 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady,
449 weak_factory_.GetWeakPtr())); 509 weak_factory_.GetWeakPtr()));
450 } 510 }
451 511
452 template <DemuxerStream::Type StreamType> 512 template <DemuxerStream::Type StreamType>
453 void DecoderStream<StreamType>::OnBufferReady( 513 void DecoderStream<StreamType>::OnBufferReady(
454 DemuxerStream::Status status, 514 DemuxerStream::Status status,
455 const scoped_refptr<DecoderBuffer>& buffer) { 515 const scoped_refptr<DecoderBuffer>& buffer) {
456 FUNCTION_DVLOG(2) << ": " << status << ", " 516 FUNCTION_DVLOG(2) << ": " << status << ", "
457 << (buffer.get() ? buffer->AsHumanReadableString() 517 << (buffer.get() ? buffer->AsHumanReadableString()
458 : "NULL"); 518 : "NULL");
459 519
460 DCHECK(task_runner_->BelongsToCurrentThread()); 520 DCHECK(task_runner_->BelongsToCurrentThread());
461 DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR) 521 if (decoded_frames_since_fallback_) {
462 << state_; 522 DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR)
523 << state_;
524 } else {
525 DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR ||
526 STATE_REINITIALIZING_DECODER)
527 << state_;
528 }
463 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status; 529 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status;
464 530
531 // If parallel decode requests are supported, multiple read requests might
532 // have been sent to the demuxer. The buffers might arrive while the decoder
533 // is reinitializing after falling back on first decode error.
534 if (state_ == STATE_REINITIALIZING_DECODER &&
535 !decoded_frames_since_fallback_) {
536 switch (status) {
537 case DemuxerStream::kOk:
538 // Save valid buffers to be consumed by the new decoder.
539 // |pending_buffers_| is copied to |fallback_buffers| in
540 // OnDecoderSelected().
541 pending_buffers_.push_back(buffer);
542 break;
543 case DemuxerStream::kConfigChanged:
544 // TODO(tguilbert): crbug.com/603713
545 // |decoder_| might have a stale config by the time it is reinitialized.
546 // Ideally, we would save the config from |stream_| and reinitialize the
547 // decoder by playing back the sequence of buffers and config changes.
548 state_ = STATE_CONFIG_CHANGE_RECEIVED_WHILE_REINITIALIZING_DECODER;
549 pending_buffers_.clear();
550 break;
551 case DemuxerStream::kAborted:
552 // |this| will read from the demuxer stream again in OnDecoderSelected()
553 // and receive a kAborted then.
554 pending_buffers_.clear();
555 break;
556 }
557 return;
558 }
559
465 // Decoding has been stopped (e.g due to an error). 560 // Decoding has been stopped (e.g due to an error).
466 if (state_ != STATE_PENDING_DEMUXER_READ) { 561 if (state_ != STATE_PENDING_DEMUXER_READ) {
467 DCHECK(state_ == STATE_ERROR); 562 DCHECK(state_ == STATE_ERROR);
468 DCHECK(read_cb_.is_null()); 563 DCHECK(read_cb_.is_null());
469 return; 564 return;
470 } 565 }
471 566
472 state_ = STATE_NORMAL; 567 state_ = STATE_NORMAL;
473 568
474 if (status == DemuxerStream::kConfigChanged) { 569 if (status == DemuxerStream::kConfigChanged) {
475 FUNCTION_DVLOG(2) << ": " << "ConfigChanged"; 570 FUNCTION_DVLOG(2) << ": " << "ConfigChanged";
476 DCHECK(stream_->SupportsConfigChanges()); 571 DCHECK(stream_->SupportsConfigChanges());
477 572
573 // Pending buffers might not match the reinitialized decoder's new config.
574 //
575 // Note: as part of crbug.com/603713, we should record the config in order
576 // to play it back to the fallback decoder.
577 //
578 // Clearing the buffers is an acceptable workaround for the time being. It
579 // assures us that we maintain a consistent state, at the cost of
580 // potentially dropping some frames. Flushing the decoder will cause one of
581 // the following outcomes:
582 // - The decoder outputs a valid frame during flushing (we no longer
583 // care about |pending_buffers_| and fallback scenarios).
584 // - The decoder returns a DECODE_ERROR via OnDecodeDone() without having
585 // outputted a frame (we fallback to a new decoder which will read
586 // straight from the demuxer, dropping some frames).
587 // - The decoder is flushed without returning a frame or without a
588 // DECODE_ERROR (we reinitialize the decoder as if a normal flush
589 // happened, and read straight from the demuxer, which could lead to some
590 // lost frames if we were to fallback then).
591 pending_buffers_.clear();
592
478 if (!config_change_observer_cb_.is_null()) 593 if (!config_change_observer_cb_.is_null())
479 config_change_observer_cb_.Run(); 594 config_change_observer_cb_.Run();
480 595
481 state_ = STATE_FLUSHING_DECODER; 596 state_ = STATE_FLUSHING_DECODER;
482 if (!reset_cb_.is_null()) { 597 if (!reset_cb_.is_null()) {
483 // If we are using DecryptingDemuxerStream, we already called DDS::Reset() 598 // If we are using DecryptingDemuxerStream, we already called DDS::Reset()
484 // which will continue the resetting process in it's callback. 599 // which will continue the resetting process in it's callback.
485 if (!decrypting_demuxer_stream_) 600 if (!decrypting_demuxer_stream_)
486 Reset(base::ResetAndReturn(&reset_cb_)); 601 Reset(base::ResetAndReturn(&reset_cb_));
487 // Reinitialization will continue after Reset() is done. 602 // Reinitialization will continue after Reset() is done.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 DCHECK_EQ(state_, STATE_FLUSHING_DECODER); 643 DCHECK_EQ(state_, STATE_FLUSHING_DECODER);
529 DCHECK_EQ(pending_decode_requests_, 0); 644 DCHECK_EQ(pending_decode_requests_, 0);
530 645
531 state_ = STATE_REINITIALIZING_DECODER; 646 state_ = STATE_REINITIALIZING_DECODER;
532 // Decoders should not need a new CDM during reinitialization. 647 // Decoders should not need a new CDM during reinitialization.
533 DecoderStreamTraits<StreamType>::InitializeDecoder( 648 DecoderStreamTraits<StreamType>::InitializeDecoder(
534 decoder_.get(), stream_, nullptr, 649 decoder_.get(), stream_, nullptr,
535 base::Bind(&DecoderStream<StreamType>::OnDecoderReinitialized, 650 base::Bind(&DecoderStream<StreamType>::OnDecoderReinitialized,
536 weak_factory_.GetWeakPtr()), 651 weak_factory_.GetWeakPtr()),
537 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, 652 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady,
538 weak_factory_.GetWeakPtr())); 653 fallback_weak_factory_.GetWeakPtr()));
539 } 654 }
540 655
541 template <DemuxerStream::Type StreamType> 656 template <DemuxerStream::Type StreamType>
542 void DecoderStream<StreamType>::OnDecoderReinitialized(bool success) { 657 void DecoderStream<StreamType>::OnDecoderReinitialized(bool success) {
543 FUNCTION_DVLOG(2); 658 FUNCTION_DVLOG(2);
544 DCHECK(task_runner_->BelongsToCurrentThread()); 659 DCHECK(task_runner_->BelongsToCurrentThread());
545 DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER); 660 DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER);
546 661
547 // ReinitializeDecoder() can be called in two cases: 662 // ReinitializeDecoder() can be called in two cases:
548 // 1, Flushing decoder finished (see OnDecodeOutputReady()). 663 // 1, Flushing decoder finished (see OnDecodeOutputReady()).
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 void DecoderStream<StreamType>::OnDecoderReset() { 719 void DecoderStream<StreamType>::OnDecoderReset() {
605 FUNCTION_DVLOG(2); 720 FUNCTION_DVLOG(2);
606 DCHECK(task_runner_->BelongsToCurrentThread()); 721 DCHECK(task_runner_->BelongsToCurrentThread());
607 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || 722 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
608 state_ == STATE_ERROR || state_ == STATE_END_OF_STREAM) << state_; 723 state_ == STATE_ERROR || state_ == STATE_END_OF_STREAM) << state_;
609 // If Reset() was called during pending read, read callback should be fired 724 // If Reset() was called during pending read, read callback should be fired
610 // before the reset callback is fired. 725 // before the reset callback is fired.
611 DCHECK(read_cb_.is_null()); 726 DCHECK(read_cb_.is_null());
612 DCHECK(!reset_cb_.is_null()); 727 DCHECK(!reset_cb_.is_null());
613 728
729 // Make sure we read directly from the demuxer after a reset.
730 fallback_buffers_.clear();
731 pending_buffers_.clear();
732
614 if (state_ != STATE_FLUSHING_DECODER) { 733 if (state_ != STATE_FLUSHING_DECODER) {
615 state_ = STATE_NORMAL; 734 state_ = STATE_NORMAL;
616 active_splice_ = false; 735 active_splice_ = false;
617 base::ResetAndReturn(&reset_cb_).Run(); 736 base::ResetAndReturn(&reset_cb_).Run();
618 return; 737 return;
619 } 738 }
620 739
621 // The resetting process will be continued in OnDecoderReinitialized(). 740 // The resetting process will be continued in OnDecoderReinitialized().
622 ReinitializeDecoder(); 741 ReinitializeDecoder();
623 } 742 }
624 743
625 template class DecoderStream<DemuxerStream::VIDEO>; 744 template class DecoderStream<DemuxerStream::VIDEO>;
626 template class DecoderStream<DemuxerStream::AUDIO>; 745 template class DecoderStream<DemuxerStream::AUDIO>;
627 746
628 } // namespace media 747 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/decoder_stream.h ('k') | media/filters/video_frame_stream_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698