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 | |
45 template <DemuxerStream::Type StreamType> | 60 template <DemuxerStream::Type StreamType> |
46 DecoderStream<StreamType>::DecoderStream( | 61 DecoderStream<StreamType>::DecoderStream( |
47 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | 62 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
48 ScopedVector<Decoder> decoders, | 63 ScopedVector<Decoder> decoders, |
49 const scoped_refptr<MediaLog>& media_log) | 64 const scoped_refptr<MediaLog>& media_log) |
50 : task_runner_(task_runner), | 65 : traits_(media_log), |
66 task_runner_(task_runner), | |
51 media_log_(media_log), | 67 media_log_(media_log), |
52 state_(STATE_UNINITIALIZED), | 68 state_(STATE_UNINITIALIZED), |
53 stream_(NULL), | 69 stream_(NULL), |
54 decoder_selector_(new DecoderSelector<StreamType>(task_runner, | 70 decoder_selector_(new DecoderSelector<StreamType>(task_runner, |
55 std::move(decoders), | 71 std::move(decoders), |
56 media_log)), | 72 media_log)), |
57 decoded_frames_since_fallback_(0), | 73 decoded_frames_since_fallback_(0), |
58 active_splice_(false), | 74 active_splice_(false), |
59 decoding_eos_(false), | 75 decoding_eos_(false), |
60 pending_decode_requests_(0), | 76 pending_decode_requests_(0), |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
103 DCHECK(task_runner_->BelongsToCurrentThread()); | 119 DCHECK(task_runner_->BelongsToCurrentThread()); |
104 DCHECK_EQ(state_, STATE_UNINITIALIZED); | 120 DCHECK_EQ(state_, STATE_UNINITIALIZED); |
105 DCHECK(init_cb_.is_null()); | 121 DCHECK(init_cb_.is_null()); |
106 DCHECK(!init_cb.is_null()); | 122 DCHECK(!init_cb.is_null()); |
107 | 123 |
108 statistics_cb_ = statistics_cb; | 124 statistics_cb_ = statistics_cb; |
109 init_cb_ = init_cb; | 125 init_cb_ = init_cb; |
110 waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb; | 126 waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb; |
111 stream_ = stream; | 127 stream_ = stream; |
112 | 128 |
129 traits_.OnStreamReset(GetConfig<Config>(stream_)); | |
DaleCurtis
2016/06/24 00:11:29
Why was GetConfig() necessary again? Seems like yo
chcunningham
2016/06/24 01:56:34
We chatted. Documenting for posterity:
I disliked
| |
130 | |
113 state_ = STATE_INITIALIZING; | 131 state_ = STATE_INITIALIZING; |
114 SelectDecoder(cdm_context); | 132 SelectDecoder(cdm_context); |
115 } | 133 } |
116 | 134 |
117 template <DemuxerStream::Type StreamType> | 135 template <DemuxerStream::Type StreamType> |
118 void DecoderStream<StreamType>::Read(const ReadCB& read_cb) { | 136 void DecoderStream<StreamType>::Read(const ReadCB& read_cb) { |
119 FUNCTION_DVLOG(2); | 137 FUNCTION_DVLOG(2); |
120 DCHECK(task_runner_->BelongsToCurrentThread()); | 138 DCHECK(task_runner_->BelongsToCurrentThread()); |
121 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_INITIALIZING) | 139 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_INITIALIZING) |
122 << state_; | 140 << state_; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
158 | 176 |
159 reset_cb_ = closure; | 177 reset_cb_ = closure; |
160 | 178 |
161 if (!read_cb_.is_null()) { | 179 if (!read_cb_.is_null()) { |
162 task_runner_->PostTask(FROM_HERE, | 180 task_runner_->PostTask(FROM_HERE, |
163 base::Bind(base::ResetAndReturn(&read_cb_), ABORTED, | 181 base::Bind(base::ResetAndReturn(&read_cb_), ABORTED, |
164 scoped_refptr<Output>())); | 182 scoped_refptr<Output>())); |
165 } | 183 } |
166 | 184 |
167 ready_outputs_.clear(); | 185 ready_outputs_.clear(); |
186 traits_.OnStreamReset(GetConfig<Config>(stream_)); | |
168 | 187 |
169 // It's possible to have received a DECODE_ERROR and entered STATE_ERROR right | 188 // 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, | 189 // before a Reset() is executed. If we are still waiting for a demuxer read, |
171 // OnBufferReady() will handle the reset callback. | 190 // OnBufferReady() will handle the reset callback. |
172 // See crbug.com/597605 and crbug.com/607454. | 191 // See crbug.com/597605 and crbug.com/607454. |
173 if (state_ == STATE_ERROR && !pending_demuxer_read_) { | 192 if (state_ == STATE_ERROR && !pending_demuxer_read_) { |
174 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&reset_cb_)); | 193 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&reset_cb_)); |
175 return; | 194 return; |
176 } | 195 } |
177 | 196 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
238 template <DemuxerStream::Type StreamType> | 257 template <DemuxerStream::Type StreamType> |
239 base::TimeDelta DecoderStream<StreamType>::AverageDuration() const { | 258 base::TimeDelta DecoderStream<StreamType>::AverageDuration() const { |
240 DCHECK(task_runner_->BelongsToCurrentThread()); | 259 DCHECK(task_runner_->BelongsToCurrentThread()); |
241 return duration_tracker_.count() ? duration_tracker_.Average() | 260 return duration_tracker_.count() ? duration_tracker_.Average() |
242 : base::TimeDelta(); | 261 : base::TimeDelta(); |
243 } | 262 } |
244 | 263 |
245 template <DemuxerStream::Type StreamType> | 264 template <DemuxerStream::Type StreamType> |
246 void DecoderStream<StreamType>::SelectDecoder(CdmContext* cdm_context) { | 265 void DecoderStream<StreamType>::SelectDecoder(CdmContext* cdm_context) { |
247 decoder_selector_->SelectDecoder( | 266 decoder_selector_->SelectDecoder( |
248 stream_, cdm_context, | 267 &traits_, stream_, cdm_context, |
249 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected, | 268 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected, |
250 weak_factory_.GetWeakPtr()), | 269 weak_factory_.GetWeakPtr()), |
251 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, | 270 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, |
252 fallback_weak_factory_.GetWeakPtr()), | 271 fallback_weak_factory_.GetWeakPtr()), |
253 waiting_for_decryption_key_cb_); | 272 waiting_for_decryption_key_cb_); |
254 } | 273 } |
255 | 274 |
256 template <DemuxerStream::Type StreamType> | 275 template <DemuxerStream::Type StreamType> |
257 void DecoderStream<StreamType>::OnDecoderSelected( | 276 void DecoderStream<StreamType>::OnDecoderSelected( |
258 std::unique_ptr<Decoder> selected_decoder, | 277 std::unique_ptr<Decoder> selected_decoder, |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
353 | 372 |
354 template <DemuxerStream::Type StreamType> | 373 template <DemuxerStream::Type StreamType> |
355 void DecoderStream<StreamType>::DecodeInternal( | 374 void DecoderStream<StreamType>::DecodeInternal( |
356 const scoped_refptr<DecoderBuffer>& buffer) { | 375 const scoped_refptr<DecoderBuffer>& buffer) { |
357 FUNCTION_DVLOG(2); | 376 FUNCTION_DVLOG(2); |
358 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_; | 377 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_; |
359 DCHECK_LT(pending_decode_requests_, GetMaxDecodeRequests()); | 378 DCHECK_LT(pending_decode_requests_, GetMaxDecodeRequests()); |
360 DCHECK(reset_cb_.is_null()); | 379 DCHECK(reset_cb_.is_null()); |
361 DCHECK(buffer.get()); | 380 DCHECK(buffer.get()); |
362 | 381 |
382 traits_.OnDecode(buffer); | |
383 | |
363 int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size(); | 384 int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size(); |
364 | 385 |
365 TRACE_EVENT_ASYNC_BEGIN2( | 386 TRACE_EVENT_ASYNC_BEGIN2( |
366 "media", GetTraceString<StreamType>(), this, "key frame", | 387 "media", GetTraceString<StreamType>(), this, "key frame", |
367 !buffer->end_of_stream() && buffer->is_key_frame(), "timestamp (ms)", | 388 !buffer->end_of_stream() && buffer->is_key_frame(), "timestamp (ms)", |
368 !buffer->end_of_stream() ? buffer->timestamp().InMilliseconds() : 0); | 389 !buffer->end_of_stream() ? buffer->timestamp().InMilliseconds() : 0); |
369 | 390 |
370 if (buffer->end_of_stream()) | 391 if (buffer->end_of_stream()) |
371 decoding_eos_ = true; | 392 decoding_eos_ = true; |
372 else if (buffer->duration() != kNoTimestamp()) | 393 else if (buffer->duration() != kNoTimestamp()) |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
418 case DecodeStatus::DECODE_ERROR: | 439 case DecodeStatus::DECODE_ERROR: |
419 if (!decoded_frames_since_fallback_) { | 440 if (!decoded_frames_since_fallback_) { |
420 pending_decode_requests_ = 0; | 441 pending_decode_requests_ = 0; |
421 | 442 |
422 // Prevent all pending decode requests and outputs form those requests | 443 // Prevent all pending decode requests and outputs form those requests |
423 // from being called back. | 444 // from being called back. |
424 fallback_weak_factory_.InvalidateWeakPtrs(); | 445 fallback_weak_factory_.InvalidateWeakPtrs(); |
425 | 446 |
426 state_ = STATE_REINITIALIZING_DECODER; | 447 state_ = STATE_REINITIALIZING_DECODER; |
427 decoder_selector_->SelectDecoder( | 448 decoder_selector_->SelectDecoder( |
428 stream_, nullptr, | 449 &traits_, stream_, nullptr, |
429 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected, | 450 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected, |
430 weak_factory_.GetWeakPtr()), | 451 weak_factory_.GetWeakPtr()), |
431 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, | 452 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, |
432 fallback_weak_factory_.GetWeakPtr()), | 453 fallback_weak_factory_.GetWeakPtr()), |
433 waiting_for_decryption_key_cb_); | 454 waiting_for_decryption_key_cb_); |
434 return; | 455 return; |
435 } | 456 } |
436 state_ = STATE_ERROR; | 457 state_ = STATE_ERROR; |
437 MEDIA_LOG(ERROR, media_log_) << GetStreamTypeString() << " decode error"; | 458 MEDIA_LOG(ERROR, media_log_) << GetStreamTypeString() << " decode error"; |
438 ready_outputs_.clear(); | 459 ready_outputs_.clear(); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
481 if (state_ == STATE_ERROR) { | 502 if (state_ == STATE_ERROR) { |
482 DCHECK(read_cb_.is_null()); | 503 DCHECK(read_cb_.is_null()); |
483 return; | 504 return; |
484 } | 505 } |
485 | 506 |
486 // Drop decoding result if Reset() was called during decoding. | 507 // Drop decoding result if Reset() was called during decoding. |
487 // The resetting process will be handled when the decoder is reset. | 508 // The resetting process will be handled when the decoder is reset. |
488 if (!reset_cb_.is_null()) | 509 if (!reset_cb_.is_null()) |
489 return; | 510 return; |
490 | 511 |
512 traits_.OnDecodeDone(output); | |
513 | |
491 ++decoded_frames_since_fallback_; | 514 ++decoded_frames_since_fallback_; |
492 | 515 |
493 // |decoder_| sucessfully decoded a frame. No need to keep buffers for a | 516 // |decoder_| sucessfully decoded a frame. No need to keep buffers for a |
494 // fallback decoder. | 517 // fallback decoder. |
495 // Note: |fallback_buffers_| might still have buffers, and we will keep | 518 // Note: |fallback_buffers_| might still have buffers, and we will keep |
496 // reading from there before requesting new buffers from |stream_|. | 519 // reading from there before requesting new buffers from |stream_|. |
497 pending_buffers_.clear(); | 520 pending_buffers_.clear(); |
498 | 521 |
499 if (!read_cb_.is_null()) { | 522 if (!read_cb_.is_null()) { |
500 // If |ready_outputs_| was non-empty, the read would have already been | 523 // 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 | 704 |
682 template <DemuxerStream::Type StreamType> | 705 template <DemuxerStream::Type StreamType> |
683 void DecoderStream<StreamType>::ReinitializeDecoder() { | 706 void DecoderStream<StreamType>::ReinitializeDecoder() { |
684 FUNCTION_DVLOG(2); | 707 FUNCTION_DVLOG(2); |
685 DCHECK(task_runner_->BelongsToCurrentThread()); | 708 DCHECK(task_runner_->BelongsToCurrentThread()); |
686 DCHECK_EQ(state_, STATE_FLUSHING_DECODER); | 709 DCHECK_EQ(state_, STATE_FLUSHING_DECODER); |
687 DCHECK_EQ(pending_decode_requests_, 0); | 710 DCHECK_EQ(pending_decode_requests_, 0); |
688 | 711 |
689 state_ = STATE_REINITIALIZING_DECODER; | 712 state_ = STATE_REINITIALIZING_DECODER; |
690 // Decoders should not need a new CDM during reinitialization. | 713 // Decoders should not need a new CDM during reinitialization. |
691 DecoderStreamTraits<StreamType>::InitializeDecoder( | 714 traits_.InitializeDecoder( |
692 decoder_.get(), stream_, nullptr, | 715 decoder_.get(), stream_, nullptr, |
693 base::Bind(&DecoderStream<StreamType>::OnDecoderReinitialized, | 716 base::Bind(&DecoderStream<StreamType>::OnDecoderReinitialized, |
694 weak_factory_.GetWeakPtr()), | 717 weak_factory_.GetWeakPtr()), |
695 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, | 718 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, |
696 fallback_weak_factory_.GetWeakPtr())); | 719 fallback_weak_factory_.GetWeakPtr())); |
697 } | 720 } |
698 | 721 |
699 template <DemuxerStream::Type StreamType> | 722 template <DemuxerStream::Type StreamType> |
700 void DecoderStream<StreamType>::OnDecoderReinitialized(bool success) { | 723 void DecoderStream<StreamType>::OnDecoderReinitialized(bool success) { |
701 FUNCTION_DVLOG(2); | 724 FUNCTION_DVLOG(2); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
781 } | 804 } |
782 | 805 |
783 // The resetting process will be continued in OnDecoderReinitialized(). | 806 // The resetting process will be continued in OnDecoderReinitialized(). |
784 ReinitializeDecoder(); | 807 ReinitializeDecoder(); |
785 } | 808 } |
786 | 809 |
787 template class DecoderStream<DemuxerStream::VIDEO>; | 810 template class DecoderStream<DemuxerStream::VIDEO>; |
788 template class DecoderStream<DemuxerStream::AUDIO>; | 811 template class DecoderStream<DemuxerStream::AUDIO>; |
789 | 812 |
790 } // namespace media | 813 } // namespace media |
OLD | NEW |