| 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 <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 24 matching lines...) Expand all Loading... |
| 35 template <> | 35 template <> |
| 36 const char* GetTraceString<DemuxerStream::VIDEO>() { | 36 const char* GetTraceString<DemuxerStream::VIDEO>() { |
| 37 return "DecoderStream<VIDEO>::Decode"; | 37 return "DecoderStream<VIDEO>::Decode"; |
| 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 <typename ConfigType> |
| 46 ConfigType GetConfig(DemuxerStream* stream) { |
| 47 return nullptr; |
| 48 } |
| 49 |
| 50 template <> |
| 51 AudioDecoderConfig GetConfig(DemuxerStream* stream) { |
| 52 return stream->audio_decoder_config(); |
| 53 } |
| 54 |
| 55 template <> |
| 56 VideoDecoderConfig GetConfig(DemuxerStream* stream) { |
| 57 return stream->video_decoder_config(); |
| 58 } |
| 59 |
| 60 // This silly method (and its specialization) convinces the compiler that we |
| 61 // won't try to cast a VideoFrame to an AudioBuffer when passing to the |
| 62 // AudioTimestampValidator. |
| 63 template <typename T> |
| 64 AudioBuffer* GetAudioBuffer(T* buffer_ptr) { |
| 65 return nullptr; |
| 66 } |
| 67 |
| 68 template <> |
| 69 AudioBuffer* GetAudioBuffer<>(AudioBuffer* buffer_ptr) { |
| 70 return buffer_ptr; |
| 71 } |
| 72 |
| 45 template <DemuxerStream::Type StreamType> | 73 template <DemuxerStream::Type StreamType> |
| 46 DecoderStream<StreamType>::DecoderStream( | 74 DecoderStream<StreamType>::DecoderStream( |
| 47 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | 75 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
| 48 ScopedVector<Decoder> decoders, | 76 ScopedVector<Decoder> decoders, |
| 49 const scoped_refptr<MediaLog>& media_log) | 77 const scoped_refptr<MediaLog>& media_log) |
| 50 : task_runner_(task_runner), | 78 : traits_(media_log), |
| 79 task_runner_(task_runner), |
| 51 media_log_(media_log), | 80 media_log_(media_log), |
| 52 state_(STATE_UNINITIALIZED), | 81 state_(STATE_UNINITIALIZED), |
| 53 stream_(NULL), | 82 stream_(NULL), |
| 54 decoder_selector_(new DecoderSelector<StreamType>(task_runner, | 83 decoder_selector_(new DecoderSelector<StreamType>(task_runner, |
| 55 std::move(decoders), | 84 std::move(decoders), |
| 56 media_log)), | 85 media_log)), |
| 57 decoded_frames_since_fallback_(0), | 86 decoded_frames_since_fallback_(0), |
| 58 active_splice_(false), | 87 active_splice_(false), |
| 59 decoding_eos_(false), | 88 decoding_eos_(false), |
| 60 pending_decode_requests_(0), | 89 pending_decode_requests_(0), |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 DCHECK(task_runner_->BelongsToCurrentThread()); | 132 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 104 DCHECK_EQ(state_, STATE_UNINITIALIZED); | 133 DCHECK_EQ(state_, STATE_UNINITIALIZED); |
| 105 DCHECK(init_cb_.is_null()); | 134 DCHECK(init_cb_.is_null()); |
| 106 DCHECK(!init_cb.is_null()); | 135 DCHECK(!init_cb.is_null()); |
| 107 | 136 |
| 108 statistics_cb_ = statistics_cb; | 137 statistics_cb_ = statistics_cb; |
| 109 init_cb_ = init_cb; | 138 init_cb_ = init_cb; |
| 110 waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb; | 139 waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb; |
| 111 stream_ = stream; | 140 stream_ = stream; |
| 112 | 141 |
| 142 traits_.OnStreamReset(GetConfig<Config>(stream_)); |
| 143 |
| 113 state_ = STATE_INITIALIZING; | 144 state_ = STATE_INITIALIZING; |
| 114 SelectDecoder(cdm_context); | 145 SelectDecoder(cdm_context); |
| 115 } | 146 } |
| 116 | 147 |
| 117 template <DemuxerStream::Type StreamType> | 148 template <DemuxerStream::Type StreamType> |
| 118 void DecoderStream<StreamType>::Read(const ReadCB& read_cb) { | 149 void DecoderStream<StreamType>::Read(const ReadCB& read_cb) { |
| 119 FUNCTION_DVLOG(2); | 150 FUNCTION_DVLOG(2); |
| 120 DCHECK(task_runner_->BelongsToCurrentThread()); | 151 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 121 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_INITIALIZING) | 152 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_INITIALIZING) |
| 122 << state_; | 153 << state_; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 | 189 |
| 159 reset_cb_ = closure; | 190 reset_cb_ = closure; |
| 160 | 191 |
| 161 if (!read_cb_.is_null()) { | 192 if (!read_cb_.is_null()) { |
| 162 task_runner_->PostTask(FROM_HERE, | 193 task_runner_->PostTask(FROM_HERE, |
| 163 base::Bind(base::ResetAndReturn(&read_cb_), ABORTED, | 194 base::Bind(base::ResetAndReturn(&read_cb_), ABORTED, |
| 164 scoped_refptr<Output>())); | 195 scoped_refptr<Output>())); |
| 165 } | 196 } |
| 166 | 197 |
| 167 ready_outputs_.clear(); | 198 ready_outputs_.clear(); |
| 199 traits_.OnStreamReset(GetConfig<Config>(stream_)); |
| 168 | 200 |
| 169 // It's possible to have received a DECODE_ERROR and entered STATE_ERROR right | 201 // It's possible to have received a DECODE_ERROR and entered STATE_ERROR right |
| 170 // before a Reset() is executed. If we are still waiting for a demuxer read, | 202 // before a Reset() is executed. If we are still waiting for a demuxer read, |
| 171 // OnBufferReady() will handle the reset callback. | 203 // OnBufferReady() will handle the reset callback. |
| 172 // See crbug.com/597605 and crbug.com/607454. | 204 // See crbug.com/597605 and crbug.com/607454. |
| 173 if (state_ == STATE_ERROR && !pending_demuxer_read_) { | 205 if (state_ == STATE_ERROR && !pending_demuxer_read_) { |
| 174 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&reset_cb_)); | 206 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&reset_cb_)); |
| 175 return; | 207 return; |
| 176 } | 208 } |
| 177 | 209 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 template <DemuxerStream::Type StreamType> | 270 template <DemuxerStream::Type StreamType> |
| 239 base::TimeDelta DecoderStream<StreamType>::AverageDuration() const { | 271 base::TimeDelta DecoderStream<StreamType>::AverageDuration() const { |
| 240 DCHECK(task_runner_->BelongsToCurrentThread()); | 272 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 241 return duration_tracker_.count() ? duration_tracker_.Average() | 273 return duration_tracker_.count() ? duration_tracker_.Average() |
| 242 : base::TimeDelta(); | 274 : base::TimeDelta(); |
| 243 } | 275 } |
| 244 | 276 |
| 245 template <DemuxerStream::Type StreamType> | 277 template <DemuxerStream::Type StreamType> |
| 246 void DecoderStream<StreamType>::SelectDecoder(CdmContext* cdm_context) { | 278 void DecoderStream<StreamType>::SelectDecoder(CdmContext* cdm_context) { |
| 247 decoder_selector_->SelectDecoder( | 279 decoder_selector_->SelectDecoder( |
| 248 stream_, cdm_context, | 280 &traits_, stream_, cdm_context, |
| 249 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected, | 281 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected, |
| 250 weak_factory_.GetWeakPtr()), | 282 weak_factory_.GetWeakPtr()), |
| 251 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, | 283 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, |
| 252 fallback_weak_factory_.GetWeakPtr()), | 284 fallback_weak_factory_.GetWeakPtr()), |
| 253 waiting_for_decryption_key_cb_); | 285 waiting_for_decryption_key_cb_); |
| 254 } | 286 } |
| 255 | 287 |
| 256 template <DemuxerStream::Type StreamType> | 288 template <DemuxerStream::Type StreamType> |
| 257 void DecoderStream<StreamType>::OnDecoderSelected( | 289 void DecoderStream<StreamType>::OnDecoderSelected( |
| 258 std::unique_ptr<Decoder> selected_decoder, | 290 std::unique_ptr<Decoder> selected_decoder, |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 | 385 |
| 354 template <DemuxerStream::Type StreamType> | 386 template <DemuxerStream::Type StreamType> |
| 355 void DecoderStream<StreamType>::DecodeInternal( | 387 void DecoderStream<StreamType>::DecodeInternal( |
| 356 const scoped_refptr<DecoderBuffer>& buffer) { | 388 const scoped_refptr<DecoderBuffer>& buffer) { |
| 357 FUNCTION_DVLOG(2); | 389 FUNCTION_DVLOG(2); |
| 358 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_; | 390 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_; |
| 359 DCHECK_LT(pending_decode_requests_, GetMaxDecodeRequests()); | 391 DCHECK_LT(pending_decode_requests_, GetMaxDecodeRequests()); |
| 360 DCHECK(reset_cb_.is_null()); | 392 DCHECK(reset_cb_.is_null()); |
| 361 DCHECK(buffer.get()); | 393 DCHECK(buffer.get()); |
| 362 | 394 |
| 395 traits_.OnDecode(buffer); |
| 396 |
| 363 int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size(); | 397 int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size(); |
| 364 | 398 |
| 365 TRACE_EVENT_ASYNC_BEGIN2( | 399 TRACE_EVENT_ASYNC_BEGIN2( |
| 366 "media", GetTraceString<StreamType>(), this, "key frame", | 400 "media", GetTraceString<StreamType>(), this, "key frame", |
| 367 !buffer->end_of_stream() && buffer->is_key_frame(), "timestamp (ms)", | 401 !buffer->end_of_stream() && buffer->is_key_frame(), "timestamp (ms)", |
| 368 !buffer->end_of_stream() ? buffer->timestamp().InMilliseconds() : 0); | 402 !buffer->end_of_stream() ? buffer->timestamp().InMilliseconds() : 0); |
| 369 | 403 |
| 370 if (buffer->end_of_stream()) | 404 if (buffer->end_of_stream()) |
| 371 decoding_eos_ = true; | 405 decoding_eos_ = true; |
| 372 else if (buffer->duration() != kNoTimestamp()) | 406 else if (buffer->duration() != kNoTimestamp()) |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 418 case DecodeStatus::DECODE_ERROR: | 452 case DecodeStatus::DECODE_ERROR: |
| 419 if (!decoded_frames_since_fallback_) { | 453 if (!decoded_frames_since_fallback_) { |
| 420 pending_decode_requests_ = 0; | 454 pending_decode_requests_ = 0; |
| 421 | 455 |
| 422 // Prevent all pending decode requests and outputs form those requests | 456 // Prevent all pending decode requests and outputs form those requests |
| 423 // from being called back. | 457 // from being called back. |
| 424 fallback_weak_factory_.InvalidateWeakPtrs(); | 458 fallback_weak_factory_.InvalidateWeakPtrs(); |
| 425 | 459 |
| 426 state_ = STATE_REINITIALIZING_DECODER; | 460 state_ = STATE_REINITIALIZING_DECODER; |
| 427 decoder_selector_->SelectDecoder( | 461 decoder_selector_->SelectDecoder( |
| 428 stream_, nullptr, | 462 &traits_, stream_, nullptr, |
| 429 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected, | 463 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected, |
| 430 weak_factory_.GetWeakPtr()), | 464 weak_factory_.GetWeakPtr()), |
| 431 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, | 465 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, |
| 432 fallback_weak_factory_.GetWeakPtr()), | 466 fallback_weak_factory_.GetWeakPtr()), |
| 433 waiting_for_decryption_key_cb_); | 467 waiting_for_decryption_key_cb_); |
| 434 return; | 468 return; |
| 435 } | 469 } |
| 436 state_ = STATE_ERROR; | 470 state_ = STATE_ERROR; |
| 437 MEDIA_LOG(ERROR, media_log_) << GetStreamTypeString() << " decode error"; | 471 MEDIA_LOG(ERROR, media_log_) << GetStreamTypeString() << " decode error"; |
| 438 ready_outputs_.clear(); | 472 ready_outputs_.clear(); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 481 if (state_ == STATE_ERROR) { | 515 if (state_ == STATE_ERROR) { |
| 482 DCHECK(read_cb_.is_null()); | 516 DCHECK(read_cb_.is_null()); |
| 483 return; | 517 return; |
| 484 } | 518 } |
| 485 | 519 |
| 486 // Drop decoding result if Reset() was called during decoding. | 520 // Drop decoding result if Reset() was called during decoding. |
| 487 // The resetting process will be handled when the decoder is reset. | 521 // The resetting process will be handled when the decoder is reset. |
| 488 if (!reset_cb_.is_null()) | 522 if (!reset_cb_.is_null()) |
| 489 return; | 523 return; |
| 490 | 524 |
| 525 traits_.OnDecodeDone(output); |
| 526 |
| 491 ++decoded_frames_since_fallback_; | 527 ++decoded_frames_since_fallback_; |
| 492 | 528 |
| 493 // |decoder_| sucessfully decoded a frame. No need to keep buffers for a | 529 // |decoder_| sucessfully decoded a frame. No need to keep buffers for a |
| 494 // fallback decoder. | 530 // fallback decoder. |
| 495 // Note: |fallback_buffers_| might still have buffers, and we will keep | 531 // Note: |fallback_buffers_| might still have buffers, and we will keep |
| 496 // reading from there before requesting new buffers from |stream_|. | 532 // reading from there before requesting new buffers from |stream_|. |
| 497 pending_buffers_.clear(); | 533 pending_buffers_.clear(); |
| 498 | 534 |
| 499 if (!read_cb_.is_null()) { | 535 if (!read_cb_.is_null()) { |
| 500 // If |ready_outputs_| was non-empty, the read would have already been | 536 // If |ready_outputs_| was non-empty, the read would have already been |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 681 | 717 |
| 682 template <DemuxerStream::Type StreamType> | 718 template <DemuxerStream::Type StreamType> |
| 683 void DecoderStream<StreamType>::ReinitializeDecoder() { | 719 void DecoderStream<StreamType>::ReinitializeDecoder() { |
| 684 FUNCTION_DVLOG(2); | 720 FUNCTION_DVLOG(2); |
| 685 DCHECK(task_runner_->BelongsToCurrentThread()); | 721 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 686 DCHECK_EQ(state_, STATE_FLUSHING_DECODER); | 722 DCHECK_EQ(state_, STATE_FLUSHING_DECODER); |
| 687 DCHECK_EQ(pending_decode_requests_, 0); | 723 DCHECK_EQ(pending_decode_requests_, 0); |
| 688 | 724 |
| 689 state_ = STATE_REINITIALIZING_DECODER; | 725 state_ = STATE_REINITIALIZING_DECODER; |
| 690 // Decoders should not need a new CDM during reinitialization. | 726 // Decoders should not need a new CDM during reinitialization. |
| 691 DecoderStreamTraits<StreamType>::InitializeDecoder( | 727 traits_.InitializeDecoder( |
| 692 decoder_.get(), stream_, nullptr, | 728 decoder_.get(), stream_, nullptr, |
| 693 base::Bind(&DecoderStream<StreamType>::OnDecoderReinitialized, | 729 base::Bind(&DecoderStream<StreamType>::OnDecoderReinitialized, |
| 694 weak_factory_.GetWeakPtr()), | 730 weak_factory_.GetWeakPtr()), |
| 695 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, | 731 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, |
| 696 fallback_weak_factory_.GetWeakPtr())); | 732 fallback_weak_factory_.GetWeakPtr())); |
| 697 } | 733 } |
| 698 | 734 |
| 699 template <DemuxerStream::Type StreamType> | 735 template <DemuxerStream::Type StreamType> |
| 700 void DecoderStream<StreamType>::OnDecoderReinitialized(bool success) { | 736 void DecoderStream<StreamType>::OnDecoderReinitialized(bool success) { |
| 701 FUNCTION_DVLOG(2); | 737 FUNCTION_DVLOG(2); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 781 } | 817 } |
| 782 | 818 |
| 783 // The resetting process will be continued in OnDecoderReinitialized(). | 819 // The resetting process will be continued in OnDecoderReinitialized(). |
| 784 ReinitializeDecoder(); | 820 ReinitializeDecoder(); |
| 785 } | 821 } |
| 786 | 822 |
| 787 template class DecoderStream<DemuxerStream::VIDEO>; | 823 template class DecoderStream<DemuxerStream::VIDEO>; |
| 788 template class DecoderStream<DemuxerStream::AUDIO>; | 824 template class DecoderStream<DemuxerStream::AUDIO>; |
| 789 | 825 |
| 790 } // namespace media | 826 } // namespace media |
| OLD | NEW |