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

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

Issue 2841553003: media: Discard the previous decoder immediately on fallback (Closed)
Patch Set: Remove out of date comments Created 3 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/gpu_video_decoder.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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 MediaLog* media_log) 49 MediaLog* media_log)
50 : traits_(media_log), 50 : traits_(media_log),
51 task_runner_(task_runner), 51 task_runner_(task_runner),
52 media_log_(media_log), 52 media_log_(media_log),
53 state_(STATE_UNINITIALIZED), 53 state_(STATE_UNINITIALIZED),
54 stream_(NULL), 54 stream_(NULL),
55 cdm_context_(nullptr), 55 cdm_context_(nullptr),
56 decoder_selector_(new DecoderSelector<StreamType>(task_runner, 56 decoder_selector_(new DecoderSelector<StreamType>(task_runner,
57 std::move(decoders), 57 std::move(decoders),
58 media_log)), 58 media_log)),
59 decoded_frames_since_fallback_(0), 59 decoder_produced_a_frame_(false),
60 decoding_eos_(false), 60 decoding_eos_(false),
61 pending_decode_requests_(0), 61 pending_decode_requests_(0),
62 duration_tracker_(8), 62 duration_tracker_(8),
63 received_config_change_during_reinit_(false), 63 received_config_change_during_reinit_(false),
64 pending_demuxer_read_(false), 64 pending_demuxer_read_(false),
65 weak_factory_(this), 65 weak_factory_(this),
66 fallback_weak_factory_(this) { 66 fallback_weak_factory_(this) {
67 FUNCTION_DVLOG(1); 67 FUNCTION_DVLOG(1);
68 } 68 }
69 69
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 DCHECK(state_ == STATE_INITIALIZING || state_ == STATE_REINITIALIZING_DECODER) 277 DCHECK(state_ == STATE_INITIALIZING || state_ == STATE_REINITIALIZING_DECODER)
278 << state_; 278 << state_;
279 if (state_ == STATE_INITIALIZING) { 279 if (state_ == STATE_INITIALIZING) {
280 DCHECK(!init_cb_.is_null()); 280 DCHECK(!init_cb_.is_null());
281 DCHECK(read_cb_.is_null()); 281 DCHECK(read_cb_.is_null());
282 DCHECK(reset_cb_.is_null()); 282 DCHECK(reset_cb_.is_null());
283 } else if (state_ == STATE_REINITIALIZING_DECODER) { 283 } else if (state_ == STATE_REINITIALIZING_DECODER) {
284 DCHECK(decoder_); 284 DCHECK(decoder_);
285 } 285 }
286 286
287 previous_decoder_ = std::move(decoder_);
288 decoded_frames_since_fallback_ = 0;
289 decoder_ = std::move(selected_decoder); 287 decoder_ = std::move(selected_decoder);
290 if (decrypting_demuxer_stream) { 288 if (decrypting_demuxer_stream) {
291 decrypting_demuxer_stream_ = std::move(decrypting_demuxer_stream); 289 decrypting_demuxer_stream_ = std::move(decrypting_demuxer_stream);
292 stream_ = decrypting_demuxer_stream_.get(); 290 stream_ = decrypting_demuxer_stream_.get();
293 } 291 }
294 292
295 // TODO(tguilbert): crbug.com/603713 support config changes on decoder reinit. 293 // TODO(tguilbert): crbug.com/603713 support config changes on decoder reinit.
296 if (received_config_change_during_reinit_) { 294 if (received_config_change_during_reinit_) {
297 CompleteDecoderReinitialization(false); 295 CompleteDecoderReinitialization(false);
298 return; 296 return;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 base::ResetAndReturn(&read_cb_).Run(status, output); 337 base::ResetAndReturn(&read_cb_).Run(status, output);
340 } 338 }
341 339
342 template <DemuxerStream::Type StreamType> 340 template <DemuxerStream::Type StreamType>
343 void DecoderStream<StreamType>::Decode( 341 void DecoderStream<StreamType>::Decode(
344 const scoped_refptr<DecoderBuffer>& buffer) { 342 const scoped_refptr<DecoderBuffer>& buffer) {
345 FUNCTION_DVLOG(3); 343 FUNCTION_DVLOG(3);
346 344
347 // We don't know if the decoder will error out on first decode yet. Save the 345 // We don't know if the decoder will error out on first decode yet. Save the
348 // buffer to feed it to the fallback decoder later if needed. 346 // buffer to feed it to the fallback decoder later if needed.
349 if (!decoded_frames_since_fallback_) 347 if (!decoder_produced_a_frame_)
350 pending_buffers_.push_back(buffer); 348 pending_buffers_.push_back(buffer);
351 349
352 // It's possible for a buffer to arrive from the demuxer right after the 350 // It's possible for a buffer to arrive from the demuxer right after the
353 // fallback decoder successfully completed its initialization. At this point 351 // fallback decoder successfully completed its initialization. At this point
354 // |pending_buffers_| has already been copied to |fallback_buffers_| and we 352 // |pending_buffers_| has already been copied to |fallback_buffers_| and we
355 // need to append it ourselves. 353 // need to append it ourselves.
356 if (!fallback_buffers_.empty()) { 354 if (!fallback_buffers_.empty()) {
357 fallback_buffers_.push_back(buffer); 355 fallback_buffers_.push_back(buffer);
358 356
359 scoped_refptr<DecoderBuffer> temp = fallback_buffers_.front(); 357 scoped_refptr<DecoderBuffer> temp = fallback_buffers_.front();
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 return; 422 return;
425 } 423 }
426 424
427 // Drop decoding result if Reset() was called during decoding. 425 // Drop decoding result if Reset() was called during decoding.
428 // The resetting process will be handled when the decoder is reset. 426 // The resetting process will be handled when the decoder is reset.
429 if (!reset_cb_.is_null()) 427 if (!reset_cb_.is_null())
430 return; 428 return;
431 429
432 switch (status) { 430 switch (status) {
433 case DecodeStatus::DECODE_ERROR: 431 case DecodeStatus::DECODE_ERROR:
434 if (!decoded_frames_since_fallback_) { 432 if (!decoder_produced_a_frame_) {
435 pending_decode_requests_ = 0; 433 pending_decode_requests_ = 0;
436 434
437 // Prevent all pending decode requests and outputs form those requests 435 // Prevent all pending decode requests and outputs from those requests
438 // from being called back. 436 // from being called back.
439 fallback_weak_factory_.InvalidateWeakPtrs(); 437 fallback_weak_factory_.InvalidateWeakPtrs();
440 438
441 FUNCTION_DVLOG(1) 439 FUNCTION_DVLOG(1)
442 << ": Falling back to new decoder after initial decode error."; 440 << ": Falling back to new decoder after initial decode error.";
443 state_ = STATE_REINITIALIZING_DECODER; 441 state_ = STATE_REINITIALIZING_DECODER;
444 SelectDecoder(); 442 SelectDecoder();
445 return; 443 return;
446 } 444 }
447 FUNCTION_DVLOG(1) << ": Decode error!"; 445 FUNCTION_DVLOG(1) << ": Decode error!";
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 if (state_ == STATE_ERROR) { 491 if (state_ == STATE_ERROR) {
494 DCHECK(read_cb_.is_null()); 492 DCHECK(read_cb_.is_null());
495 return; 493 return;
496 } 494 }
497 495
498 // Drop decoding result if Reset() was called during decoding. 496 // Drop decoding result if Reset() was called during decoding.
499 // The resetting process will be handled when the decoder is reset. 497 // The resetting process will be handled when the decoder is reset.
500 if (!reset_cb_.is_null()) 498 if (!reset_cb_.is_null())
501 return; 499 return;
502 500
501 decoder_produced_a_frame_ = true;
503 traits_.OnDecodeDone(output); 502 traits_.OnDecodeDone(output);
504 503
505 ++decoded_frames_since_fallback_;
506
507 // |decoder_| sucessfully decoded a frame. No need to keep buffers for a 504 // |decoder_| sucessfully decoded a frame. No need to keep buffers for a
508 // fallback decoder. 505 // fallback decoder.
509 // Note: |fallback_buffers_| might still have buffers, and we will keep 506 // Note: |fallback_buffers_| might still have buffers, and we will keep
510 // reading from there before requesting new buffers from |stream_|. 507 // reading from there before requesting new buffers from |stream_|.
511 pending_buffers_.clear(); 508 pending_buffers_.clear();
512 509
513 if (!read_cb_.is_null()) { 510 if (!read_cb_.is_null()) {
514 // If |ready_outputs_| was non-empty, the read would have already been 511 // If |ready_outputs_| was non-empty, the read would have already been
515 // satisifed by Read(). 512 // satisifed by Read().
516 DCHECK(ready_outputs_.empty()); 513 DCHECK(ready_outputs_.empty());
517 SatisfyRead(OK, output); 514 SatisfyRead(OK, output);
518 return; 515 return;
519 } 516 }
520 517
521 // Store decoded output. 518 // Store decoded output.
522 ready_outputs_.push_back(output); 519 ready_outputs_.push_back(output);
523
524 // Destruct any previous decoder once we've decoded enough frames to ensure
525 // that it's no longer in use.
526 if (previous_decoder_ &&
527 decoded_frames_since_fallback_ > limits::kMaxVideoFrames) {
528 previous_decoder_.reset();
529 }
530 } 520 }
531 521
532 template <DemuxerStream::Type StreamType> 522 template <DemuxerStream::Type StreamType>
533 void DecoderStream<StreamType>::ReadFromDemuxerStream() { 523 void DecoderStream<StreamType>::ReadFromDemuxerStream() {
534 FUNCTION_DVLOG(3); 524 FUNCTION_DVLOG(3);
535 DCHECK_EQ(state_, STATE_NORMAL); 525 DCHECK_EQ(state_, STATE_NORMAL);
536 DCHECK(CanDecodeMore()); 526 DCHECK(CanDecodeMore());
537 DCHECK(reset_cb_.is_null()); 527 DCHECK(reset_cb_.is_null());
538 528
539 if (!fallback_buffers_.empty()) { 529 if (!fallback_buffers_.empty()) {
(...skipping 17 matching lines...) Expand all
557 template <DemuxerStream::Type StreamType> 547 template <DemuxerStream::Type StreamType>
558 void DecoderStream<StreamType>::OnBufferReady( 548 void DecoderStream<StreamType>::OnBufferReady(
559 DemuxerStream::Status status, 549 DemuxerStream::Status status,
560 const scoped_refptr<DecoderBuffer>& buffer) { 550 const scoped_refptr<DecoderBuffer>& buffer) {
561 FUNCTION_DVLOG(3) << ": " << status << ", " 551 FUNCTION_DVLOG(3) << ": " << status << ", "
562 << (buffer.get() ? buffer->AsHumanReadableString() 552 << (buffer.get() ? buffer->AsHumanReadableString()
563 : "NULL"); 553 : "NULL");
564 554
565 DCHECK(task_runner_->BelongsToCurrentThread()); 555 DCHECK(task_runner_->BelongsToCurrentThread());
566 DCHECK(pending_demuxer_read_); 556 DCHECK(pending_demuxer_read_);
567 if (decoded_frames_since_fallback_) { 557 if (!decoder_produced_a_frame_) {
568 DCHECK(pending_demuxer_read_ || state_ == STATE_ERROR) << state_;
watk 2017/04/24 23:13:02 Two lines above we DCHECK(pending_demuxer_read_) s
569 } else {
570 DCHECK(state_ == STATE_ERROR || state_ == STATE_REINITIALIZING_DECODER || 558 DCHECK(state_ == STATE_ERROR || state_ == STATE_REINITIALIZING_DECODER ||
571 state_ == STATE_NORMAL) 559 state_ == STATE_NORMAL)
572 << state_; 560 << state_;
573 } 561 }
574 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status; 562 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status;
575 pending_demuxer_read_ = false; 563 pending_demuxer_read_ = false;
576 564
577 // If parallel decode requests are supported, multiple read requests might 565 // If parallel decode requests are supported, multiple read requests might
578 // have been sent to the demuxer. The buffers might arrive while the decoder 566 // have been sent to the demuxer. The buffers might arrive while the decoder
579 // is reinitializing after falling back on first decode error. 567 // is reinitializing after falling back on first decode error.
580 if (state_ == STATE_REINITIALIZING_DECODER && 568 if (state_ == STATE_REINITIALIZING_DECODER && !decoder_produced_a_frame_) {
581 !decoded_frames_since_fallback_) {
582 switch (status) { 569 switch (status) {
583 case DemuxerStream::kOk: 570 case DemuxerStream::kOk:
584 // Save valid buffers to be consumed by the new decoder. 571 // Save valid buffers to be consumed by the new decoder.
585 // |pending_buffers_| is copied to |fallback_buffers| in 572 // |pending_buffers_| is copied to |fallback_buffers| in
586 // OnDecoderSelected(). 573 // OnDecoderSelected().
587 pending_buffers_.push_back(buffer); 574 pending_buffers_.push_back(buffer);
588 break; 575 break;
589 case DemuxerStream::kConfigChanged: 576 case DemuxerStream::kConfigChanged:
590 // TODO(tguilbert): crbug.com/603713 577 // TODO(tguilbert): crbug.com/603713
591 // |decoder_| might have a stale config by the time it is reinitialized. 578 // |decoder_| might have a stale config by the time it is reinitialized.
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 } 769 }
783 770
784 // The resetting process will be continued in OnDecoderReinitialized(). 771 // The resetting process will be continued in OnDecoderReinitialized().
785 ReinitializeDecoder(); 772 ReinitializeDecoder();
786 } 773 }
787 774
788 template class DecoderStream<DemuxerStream::VIDEO>; 775 template class DecoderStream<DemuxerStream::VIDEO>;
789 template class DecoderStream<DemuxerStream::AUDIO>; 776 template class DecoderStream<DemuxerStream::AUDIO>;
790 777
791 } // namespace media 778 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/decoder_stream.h ('k') | media/filters/gpu_video_decoder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698