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

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

Issue 1954633002: MEDIA_LOG for large encoded timestamp gaps in decoder stream. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Feedback Created 4 years, 6 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
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 24 matching lines...) Expand all
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
DaleCurtis 2016/06/22 01:19:24 Are these still necessary?
chcunningham 2016/06/23 23:39:52 Removed
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698