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

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

Issue 2837613004: media: Support better decoder switching (Closed)
Patch Set: Mock*Decoder name Created 3 years, 7 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/fake_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 27 matching lines...) Expand all
38 } 38 }
39 39
40 template <> 40 template <>
41 const char* GetTraceString<DemuxerStream::AUDIO>() { 41 const char* GetTraceString<DemuxerStream::AUDIO>() {
42 return "DecoderStream<AUDIO>::Decode"; 42 return "DecoderStream<AUDIO>::Decode";
43 } 43 }
44 44
45 template <DemuxerStream::Type StreamType> 45 template <DemuxerStream::Type StreamType>
46 DecoderStream<StreamType>::DecoderStream( 46 DecoderStream<StreamType>::DecoderStream(
47 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 47 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
48 ScopedVector<Decoder> decoders, 48 CreateDecodersCB create_decoders_cb,
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 create_decoders_cb_(std::move(create_decoders_cb)),
52 media_log_(media_log), 53 media_log_(media_log),
53 state_(STATE_UNINITIALIZED), 54 state_(STATE_UNINITIALIZED),
54 stream_(NULL), 55 stream_(NULL),
55 cdm_context_(nullptr), 56 cdm_context_(nullptr),
56 decoder_selector_(new DecoderSelector<StreamType>(task_runner,
57 std::move(decoders),
58 media_log)),
59 decoder_produced_a_frame_(false), 57 decoder_produced_a_frame_(false),
58 has_fallen_back_once_on_decode_error_(false),
60 decoding_eos_(false), 59 decoding_eos_(false),
61 pending_decode_requests_(0), 60 pending_decode_requests_(0),
62 duration_tracker_(8), 61 duration_tracker_(8),
63 received_config_change_during_reinit_(false), 62 received_config_change_during_reinit_(false),
64 pending_demuxer_read_(false), 63 pending_demuxer_read_(false),
65 weak_factory_(this), 64 weak_factory_(this),
66 fallback_weak_factory_(this) { 65 fallback_weak_factory_(this) {
67 FUNCTION_DVLOG(1); 66 FUNCTION_DVLOG(1);
68 } 67 }
69 68
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 : base::TimeDelta(); 248 : base::TimeDelta();
250 } 249 }
251 250
252 template <DemuxerStream::Type StreamType> 251 template <DemuxerStream::Type StreamType>
253 void DecoderStream<StreamType>::SelectDecoder() { 252 void DecoderStream<StreamType>::SelectDecoder() {
254 // If we are already using DecryptingDemuxerStream (DDS), e.g. during 253 // If we are already using DecryptingDemuxerStream (DDS), e.g. during
255 // fallback, the |stream_| will always be clear. In this case, no need pass in 254 // fallback, the |stream_| will always be clear. In this case, no need pass in
256 // the |cdm_context_|. This will also help prevent creating a new DDS on top 255 // the |cdm_context_|. This will also help prevent creating a new DDS on top
257 // of the current DDS. 256 // of the current DDS.
258 CdmContext* cdm_context = decrypting_demuxer_stream_ ? nullptr : cdm_context_; 257 CdmContext* cdm_context = decrypting_demuxer_stream_ ? nullptr : cdm_context_;
258 std::string blacklisted_decoder = decoder_ ? decoder_->GetDisplayName() : "";
259
260 decoder_selector_.reset(new DecoderSelector<StreamType>(
261 task_runner_, create_decoders_cb_, media_log_));
259 262
260 decoder_selector_->SelectDecoder( 263 decoder_selector_->SelectDecoder(
261 &traits_, stream_, cdm_context, 264 &traits_, stream_, cdm_context, blacklisted_decoder,
262 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected, 265 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected,
263 weak_factory_.GetWeakPtr()), 266 weak_factory_.GetWeakPtr()),
264 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, 267 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady,
265 fallback_weak_factory_.GetWeakPtr()), 268 fallback_weak_factory_.GetWeakPtr()),
266 waiting_for_decryption_key_cb_); 269 waiting_for_decryption_key_cb_);
267 } 270 }
268 271
269 template <DemuxerStream::Type StreamType> 272 template <DemuxerStream::Type StreamType>
270 void DecoderStream<StreamType>::OnDecoderSelected( 273 void DecoderStream<StreamType>::OnDecoderSelected(
271 std::unique_ptr<Decoder> selected_decoder, 274 std::unique_ptr<Decoder> selected_decoder,
272 std::unique_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { 275 std::unique_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) {
273 FUNCTION_DVLOG(1) << ": " 276 FUNCTION_DVLOG(1) << ": "
274 << (selected_decoder ? selected_decoder->GetDisplayName() 277 << (selected_decoder ? selected_decoder->GetDisplayName()
275 : "No decoder selected."); 278 : "No decoder selected.");
276 DCHECK(task_runner_->BelongsToCurrentThread()); 279 DCHECK(task_runner_->BelongsToCurrentThread());
277 DCHECK(state_ == STATE_INITIALIZING || state_ == STATE_REINITIALIZING_DECODER) 280 DCHECK(state_ == STATE_INITIALIZING || state_ == STATE_REINITIALIZING_DECODER)
278 << state_; 281 << state_;
282
283 decoder_selector_.reset();
284
279 if (state_ == STATE_INITIALIZING) { 285 if (state_ == STATE_INITIALIZING) {
280 DCHECK(!init_cb_.is_null()); 286 DCHECK(!init_cb_.is_null());
281 DCHECK(read_cb_.is_null()); 287 DCHECK(read_cb_.is_null());
282 DCHECK(reset_cb_.is_null()); 288 DCHECK(reset_cb_.is_null());
283 } else if (state_ == STATE_REINITIALIZING_DECODER) { 289 } else if (state_ == STATE_REINITIALIZING_DECODER) {
284 DCHECK(decoder_); 290 DCHECK(decoder_);
285 } 291 }
286 292
287 decoder_ = std::move(selected_decoder); 293 decoder_ = std::move(selected_decoder);
288 if (decrypting_demuxer_stream) { 294 if (decrypting_demuxer_stream) {
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 return; 430 return;
425 } 431 }
426 432
427 // Drop decoding result if Reset() was called during decoding. 433 // Drop decoding result if Reset() was called during decoding.
428 // The resetting process will be handled when the decoder is reset. 434 // The resetting process will be handled when the decoder is reset.
429 if (!reset_cb_.is_null()) 435 if (!reset_cb_.is_null())
430 return; 436 return;
431 437
432 switch (status) { 438 switch (status) {
433 case DecodeStatus::DECODE_ERROR: 439 case DecodeStatus::DECODE_ERROR:
434 if (!decoder_produced_a_frame_) { 440 // Only fall back to a new decoder after failing to decode the first
441 // buffer, and if we have not fallen back before.
442 if (!decoder_produced_a_frame_ &&
443 !has_fallen_back_once_on_decode_error_) {
444 has_fallen_back_once_on_decode_error_ = true;
sandersd (OOO until July 31) 2017/05/05 00:36:46 It seems this should be reset after a successful d
xhwang 2017/05/05 02:42:59 We could do that, but then this name is not accura
435 pending_decode_requests_ = 0; 445 pending_decode_requests_ = 0;
436 446
437 // Prevent all pending decode requests and outputs from those requests 447 // Prevent all pending decode requests and outputs from those requests
438 // from being called back. 448 // from being called back.
439 fallback_weak_factory_.InvalidateWeakPtrs(); 449 fallback_weak_factory_.InvalidateWeakPtrs();
440 450
441 FUNCTION_DVLOG(1) 451 FUNCTION_DVLOG(1)
442 << ": Falling back to new decoder after initial decode error."; 452 << ": Falling back to new decoder after initial decode error.";
443 state_ = STATE_REINITIALIZING_DECODER; 453 state_ = STATE_REINITIALIZING_DECODER;
444 SelectDecoder(); 454 SelectDecoder();
445 return; 455 return;
446 } 456 }
457
447 FUNCTION_DVLOG(1) << ": Decode error!"; 458 FUNCTION_DVLOG(1) << ": Decode error!";
448 state_ = STATE_ERROR; 459 state_ = STATE_ERROR;
449 MEDIA_LOG(ERROR, media_log_) << GetStreamTypeString() << " decode error"; 460 MEDIA_LOG(ERROR, media_log_) << GetStreamTypeString() << " decode error";
450 ready_outputs_.clear(); 461 ready_outputs_.clear();
451 if (!read_cb_.is_null()) 462 if (!read_cb_.is_null())
452 SatisfyRead(DECODE_ERROR, NULL); 463 SatisfyRead(DECODE_ERROR, NULL);
453 return; 464 return;
454 465
455 case DecodeStatus::ABORTED: 466 case DecodeStatus::ABORTED:
456 // Decoder can return DecodeStatus::ABORTED during Reset() or during 467 // Decoder can return DecodeStatus::ABORTED during Reset() or during
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 } 507 }
497 508
498 // Drop decoding result if Reset() was called during decoding. 509 // Drop decoding result if Reset() was called during decoding.
499 // The resetting process will be handled when the decoder is reset. 510 // The resetting process will be handled when the decoder is reset.
500 if (!reset_cb_.is_null()) 511 if (!reset_cb_.is_null())
501 return; 512 return;
502 513
503 decoder_produced_a_frame_ = true; 514 decoder_produced_a_frame_ = true;
504 traits_.OnDecodeDone(output); 515 traits_.OnDecodeDone(output);
505 516
506 // |decoder_| sucessfully decoded a frame. No need to keep buffers for a 517 // |decoder_| successfully decoded a frame. No need to keep buffers for a
507 // fallback decoder. 518 // fallback decoder.
508 // Note: |fallback_buffers_| might still have buffers, and we will keep 519 // Note: |fallback_buffers_| might still have buffers, and we will keep
509 // reading from there before requesting new buffers from |stream_|. 520 // reading from there before requesting new buffers from |stream_|.
510 pending_buffers_.clear(); 521 pending_buffers_.clear();
511 522
512 if (!read_cb_.is_null()) { 523 if (!read_cb_.is_null()) {
513 // If |ready_outputs_| was non-empty, the read would have already been 524 // If |ready_outputs_| was non-empty, the read would have already been
514 // satisifed by Read(). 525 // satisifed by Read().
515 DCHECK(ready_outputs_.empty()); 526 DCHECK(ready_outputs_.empty());
516 SatisfyRead(OK, output); 527 SatisfyRead(OK, output);
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
771 } 782 }
772 783
773 // The resetting process will be continued in OnDecoderReinitialized(). 784 // The resetting process will be continued in OnDecoderReinitialized().
774 ReinitializeDecoder(); 785 ReinitializeDecoder();
775 } 786 }
776 787
777 template class DecoderStream<DemuxerStream::VIDEO>; 788 template class DecoderStream<DemuxerStream::VIDEO>;
778 template class DecoderStream<DemuxerStream::AUDIO>; 789 template class DecoderStream<DemuxerStream::AUDIO>;
779 790
780 } // namespace media 791 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/decoder_stream.h ('k') | media/filters/fake_video_decoder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698