Chromium Code Reviews| 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 T> | |
| 46 AudioBuffer* GetAudioBuffer(T* buffer_ptr) { | |
| 47 return nullptr; | |
| 48 } | |
| 49 | |
| 50 template <> | |
| 51 AudioBuffer* GetAudioBuffer<>(AudioBuffer* buffer_ptr) { | |
| 52 return buffer_ptr; | |
| 53 } | |
| 54 | |
| 45 template <DemuxerStream::Type StreamType> | 55 template <DemuxerStream::Type StreamType> |
| 46 DecoderStream<StreamType>::DecoderStream( | 56 DecoderStream<StreamType>::DecoderStream( |
| 47 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | 57 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
| 48 ScopedVector<Decoder> decoders, | 58 ScopedVector<Decoder> decoders, |
| 49 const scoped_refptr<MediaLog>& media_log) | 59 const scoped_refptr<MediaLog>& media_log) |
| 50 : task_runner_(task_runner), | 60 : task_runner_(task_runner), |
| 51 media_log_(media_log), | 61 media_log_(media_log), |
| 52 state_(STATE_UNINITIALIZED), | 62 state_(STATE_UNINITIALIZED), |
| 53 stream_(NULL), | 63 stream_(NULL), |
| 54 decoder_selector_(new DecoderSelector<StreamType>(task_runner, | 64 decoder_selector_(new DecoderSelector<StreamType>(task_runner, |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 103 DCHECK(task_runner_->BelongsToCurrentThread()); | 113 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 104 DCHECK_EQ(state_, STATE_UNINITIALIZED); | 114 DCHECK_EQ(state_, STATE_UNINITIALIZED); |
| 105 DCHECK(init_cb_.is_null()); | 115 DCHECK(init_cb_.is_null()); |
| 106 DCHECK(!init_cb.is_null()); | 116 DCHECK(!init_cb.is_null()); |
| 107 | 117 |
| 108 statistics_cb_ = statistics_cb; | 118 statistics_cb_ = statistics_cb; |
| 109 init_cb_ = init_cb; | 119 init_cb_ = init_cb; |
| 110 waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb; | 120 waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb; |
| 111 stream_ = stream; | 121 stream_ = stream; |
| 112 | 122 |
| 123 if (DecoderStreamTraits<StreamType>::kShouldValidateTimestamps) { | |
| 124 audio_ts_validator_.reset(new AudioTimestampValidator( | |
| 125 stream_->audio_decoder_config(), media_log_)); | |
| 126 } | |
| 127 | |
| 113 state_ = STATE_INITIALIZING; | 128 state_ = STATE_INITIALIZING; |
| 114 SelectDecoder(cdm_context); | 129 SelectDecoder(cdm_context); |
| 115 } | 130 } |
| 116 | 131 |
| 117 template <DemuxerStream::Type StreamType> | 132 template <DemuxerStream::Type StreamType> |
| 118 void DecoderStream<StreamType>::Read(const ReadCB& read_cb) { | 133 void DecoderStream<StreamType>::Read(const ReadCB& read_cb) { |
| 119 FUNCTION_DVLOG(2); | 134 FUNCTION_DVLOG(2); |
| 120 DCHECK(task_runner_->BelongsToCurrentThread()); | 135 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 121 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_INITIALIZING) | 136 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_INITIALIZING) |
| 122 << state_; | 137 << state_; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 159 reset_cb_ = closure; | 174 reset_cb_ = closure; |
| 160 | 175 |
| 161 if (!read_cb_.is_null()) { | 176 if (!read_cb_.is_null()) { |
| 162 task_runner_->PostTask(FROM_HERE, | 177 task_runner_->PostTask(FROM_HERE, |
| 163 base::Bind(base::ResetAndReturn(&read_cb_), ABORTED, | 178 base::Bind(base::ResetAndReturn(&read_cb_), ABORTED, |
| 164 scoped_refptr<Output>())); | 179 scoped_refptr<Output>())); |
| 165 } | 180 } |
| 166 | 181 |
| 167 ready_outputs_.clear(); | 182 ready_outputs_.clear(); |
| 168 | 183 |
| 184 if (DecoderStreamTraits<StreamType>::kShouldValidateTimestamps) { | |
| 185 audio_ts_validator_.reset(new AudioTimestampValidator( | |
| 186 stream_->audio_decoder_config(), media_log_)); | |
| 187 } | |
| 188 | |
| 169 // It's possible to have received a DECODE_ERROR and entered STATE_ERROR right | 189 // 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, | 190 // before a Reset() is executed. If we are still waiting for a demuxer read, |
| 171 // OnBufferReady() will handle the reset callback. | 191 // OnBufferReady() will handle the reset callback. |
| 172 // See crbug.com/597605 and crbug.com/607454. | 192 // See crbug.com/597605 and crbug.com/607454. |
| 173 if (state_ == STATE_ERROR && !pending_demuxer_read_) { | 193 if (state_ == STATE_ERROR && !pending_demuxer_read_) { |
| 174 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&reset_cb_)); | 194 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&reset_cb_)); |
| 175 return; | 195 return; |
| 176 } | 196 } |
| 177 | 197 |
| 178 // During decoder reinitialization, the Decoder does not need to be and | 198 // During decoder reinitialization, the Decoder does not need to be and |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 341 | 361 |
| 342 template <DemuxerStream::Type StreamType> | 362 template <DemuxerStream::Type StreamType> |
| 343 void DecoderStream<StreamType>::DecodeInternal( | 363 void DecoderStream<StreamType>::DecodeInternal( |
| 344 const scoped_refptr<DecoderBuffer>& buffer) { | 364 const scoped_refptr<DecoderBuffer>& buffer) { |
| 345 FUNCTION_DVLOG(2); | 365 FUNCTION_DVLOG(2); |
| 346 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_; | 366 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_; |
| 347 DCHECK_LT(pending_decode_requests_, GetMaxDecodeRequests()); | 367 DCHECK_LT(pending_decode_requests_, GetMaxDecodeRequests()); |
| 348 DCHECK(reset_cb_.is_null()); | 368 DCHECK(reset_cb_.is_null()); |
| 349 DCHECK(buffer.get()); | 369 DCHECK(buffer.get()); |
| 350 | 370 |
| 371 if (DecoderStreamTraits<StreamType>::kShouldValidateTimestamps) | |
| 372 audio_ts_validator_->CheckForTimestampGap(buffer); | |
| 373 | |
| 351 int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size(); | 374 int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size(); |
| 352 | 375 |
| 353 TRACE_EVENT_ASYNC_BEGIN2( | 376 TRACE_EVENT_ASYNC_BEGIN2( |
| 354 "media", GetTraceString<StreamType>(), this, "key frame", | 377 "media", GetTraceString<StreamType>(), this, "key frame", |
| 355 !buffer->end_of_stream() && buffer->is_key_frame(), "timestamp (ms)", | 378 !buffer->end_of_stream() && buffer->is_key_frame(), "timestamp (ms)", |
| 356 !buffer->end_of_stream() ? buffer->timestamp().InMilliseconds() : 0); | 379 !buffer->end_of_stream() ? buffer->timestamp().InMilliseconds() : 0); |
| 357 | 380 |
| 358 if (buffer->end_of_stream()) | 381 if (buffer->end_of_stream()) |
| 359 decoding_eos_ = true; | 382 decoding_eos_ = true; |
| 360 else if (buffer->duration() != kNoTimestamp()) | 383 else if (buffer->duration() != kNoTimestamp()) |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 469 if (state_ == STATE_ERROR) { | 492 if (state_ == STATE_ERROR) { |
| 470 DCHECK(read_cb_.is_null()); | 493 DCHECK(read_cb_.is_null()); |
| 471 return; | 494 return; |
| 472 } | 495 } |
| 473 | 496 |
| 474 // Drop decoding result if Reset() was called during decoding. | 497 // Drop decoding result if Reset() was called during decoding. |
| 475 // The resetting process will be handled when the decoder is reset. | 498 // The resetting process will be handled when the decoder is reset. |
| 476 if (!reset_cb_.is_null()) | 499 if (!reset_cb_.is_null()) |
| 477 return; | 500 return; |
| 478 | 501 |
| 502 if (DecoderStreamTraits<StreamType>::kShouldValidateTimestamps) { | |
| 503 // error: static_cast from 'media::VideoFrame *' to 'media::AudioBuffer *', | |
|
chcunningham
2016/05/27 21:35:05
This comment is just for CR discussion. I was surp
| |
| 504 // which are not related by inheritance, is not allowed | |
| 505 // if (output.get()) { | |
| 506 // AudioBuffer* audio_buffer = static_cast<AudioBuffer*>(output.get()); | |
| 507 // audio_ts_validator_->RecordOutputDuration(audio_buffer); | |
| 508 // } | |
| 509 audio_ts_validator_->RecordOutputDuration(GetAudioBuffer(output.get())); | |
| 510 } | |
| 511 | |
| 479 ++decoded_frames_since_fallback_; | 512 ++decoded_frames_since_fallback_; |
| 480 | 513 |
| 481 // |decoder_| sucessfully decoded a frame. No need to keep buffers for a | 514 // |decoder_| sucessfully decoded a frame. No need to keep buffers for a |
| 482 // fallback decoder. | 515 // fallback decoder. |
| 483 // Note: |fallback_buffers_| might still have buffers, and we will keep | 516 // Note: |fallback_buffers_| might still have buffers, and we will keep |
| 484 // reading from there before requesting new buffers from |stream_|. | 517 // reading from there before requesting new buffers from |stream_|. |
| 485 pending_buffers_.clear(); | 518 pending_buffers_.clear(); |
| 486 | 519 |
| 487 if (!read_cb_.is_null()) { | 520 if (!read_cb_.is_null()) { |
| 488 // If |ready_outputs_| was non-empty, the read would have already been | 521 // If |ready_outputs_| was non-empty, the read would have already been |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 769 } | 802 } |
| 770 | 803 |
| 771 // The resetting process will be continued in OnDecoderReinitialized(). | 804 // The resetting process will be continued in OnDecoderReinitialized(). |
| 772 ReinitializeDecoder(); | 805 ReinitializeDecoder(); |
| 773 } | 806 } |
| 774 | 807 |
| 775 template class DecoderStream<DemuxerStream::VIDEO>; | 808 template class DecoderStream<DemuxerStream::VIDEO>; |
| 776 template class DecoderStream<DemuxerStream::AUDIO>; | 809 template class DecoderStream<DemuxerStream::AUDIO>; |
| 777 | 810 |
| 778 } // namespace media | 811 } // namespace media |
| OLD | NEW |