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

Side by Side Diff: media/renderers/renderer_impl.cc

Issue 2552493002: [Media] Record time it takes to start rendering audio and video (Closed)
Patch Set: Use RestartPlaybackStream and OnFirstFrameRender Created 4 years 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/renderers/renderer_impl.h ('k') | media/renderers/video_renderer_impl.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/renderers/renderer_impl.h" 5 #include "media/renderers/renderer_impl.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.h" 10 #include "base/callback.h"
11 #include "base/callback_helpers.h" 11 #include "base/callback_helpers.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/compiler_specific.h" 13 #include "base/compiler_specific.h"
14 #include "base/location.h" 14 #include "base/location.h"
15 #include "base/metrics/histogram_macros.h"
15 #include "base/single_thread_task_runner.h" 16 #include "base/single_thread_task_runner.h"
16 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
17 #include "media/base/audio_decoder_config.h" 18 #include "media/base/audio_decoder_config.h"
18 #include "media/base/audio_renderer.h" 19 #include "media/base/audio_renderer.h"
19 #include "media/base/bind_to_current_loop.h" 20 #include "media/base/bind_to_current_loop.h"
20 #include "media/base/demuxer_stream_provider.h" 21 #include "media/base/demuxer_stream_provider.h"
21 #include "media/base/media_switches.h" 22 #include "media/base/media_switches.h"
22 #include "media/base/renderer_client.h" 23 #include "media/base/renderer_client.h"
23 #include "media/base/time_source.h" 24 #include "media/base/time_source.h"
24 #include "media/base/video_decoder_config.h" 25 #include "media/base/video_decoder_config.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 DCHECK(type_ == DemuxerStream::VIDEO); 59 DCHECK(type_ == DemuxerStream::VIDEO);
59 renderer_->OnVideoOpacityChange(opaque); 60 renderer_->OnVideoOpacityChange(opaque);
60 } 61 }
61 void OnDurationChange(base::TimeDelta duration) override { 62 void OnDurationChange(base::TimeDelta duration) override {
62 // RendererClients should only be notified of duration changes in certain 63 // RendererClients should only be notified of duration changes in certain
63 // scenarios, none of which should arise for RendererClientInternal. 64 // scenarios, none of which should arise for RendererClientInternal.
64 // Duration changes should be sent to the pipeline by the DemuxerStream, via 65 // Duration changes should be sent to the pipeline by the DemuxerStream, via
65 // the DemuxerHost interface. 66 // the DemuxerHost interface.
66 NOTREACHED(); 67 NOTREACHED();
67 } 68 }
69 void OnFirstFrameRender() override { renderer_->OnFirstFrameRender(type_); }
68 70
69 private: 71 private:
70 DemuxerStream::Type type_; 72 DemuxerStream::Type type_;
71 RendererImpl* renderer_; 73 RendererImpl* renderer_;
72 }; 74 };
73 75
74 RendererImpl::RendererImpl( 76 RendererImpl::RendererImpl(
75 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 77 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
76 std::unique_ptr<AudioRenderer> audio_renderer, 78 std::unique_ptr<AudioRenderer> audio_renderer,
77 std::unique_ptr<VideoRenderer> video_renderer) 79 std::unique_ptr<VideoRenderer> video_renderer)
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 bool video = (stream->type() == DemuxerStream::VIDEO); 231 bool video = (stream->type() == DemuxerStream::VIDEO);
230 DVLOG(1) << __func__ << (video ? " video" : " audio") << " stream=" << stream 232 DVLOG(1) << __func__ << (video ? " video" : " audio") << " stream=" << stream
231 << " enabled=" << stream->enabled() << " time=" << time.InSecondsF(); 233 << " enabled=" << stream->enabled() << " time=" << time.InSecondsF();
232 if ((state_ != STATE_PLAYING) || (audio_ended_ && video_ended_)) 234 if ((state_ != STATE_PLAYING) || (audio_ended_ && video_ended_))
233 return; 235 return;
234 if (stream->type() == DemuxerStream::VIDEO) { 236 if (stream->type() == DemuxerStream::VIDEO) {
235 DCHECK(video_renderer_); 237 DCHECK(video_renderer_);
236 if (restarting_video_) 238 if (restarting_video_)
237 return; 239 return;
238 restarting_video_ = true; 240 restarting_video_ = true;
241
242 if (stream->enabled() && video_preroll_start_time_.is_null())
243 video_preroll_start_time_ = base::TimeTicks::Now();
244
239 video_renderer_->Flush( 245 video_renderer_->Flush(
240 base::Bind(&RendererImpl::RestartVideoRenderer, weak_this_, time)); 246 base::Bind(&RendererImpl::RestartVideoRenderer, weak_this_, time));
241 } else if (stream->type() == DemuxerStream::AUDIO) { 247 } else if (stream->type() == DemuxerStream::AUDIO) {
242 DCHECK(audio_renderer_); 248 DCHECK(audio_renderer_);
243 DCHECK(time_source_); 249 DCHECK(time_source_);
244 if (restarting_audio_) 250 if (restarting_audio_)
245 return; 251 return;
246 restarting_audio_ = true; 252 restarting_audio_ = true;
253
254 if (stream->enabled() && audio_preroll_start_time_.is_null())
255 audio_preroll_start_time_ = base::TimeTicks::Now();
256
247 // Stop ticking (transition into paused state) in audio renderer before 257 // Stop ticking (transition into paused state) in audio renderer before
248 // calling Flush, since after Flush we are going to restart playback by 258 // calling Flush, since after Flush we are going to restart playback by
249 // calling audio renderer StartPlaying which would fail in playing state. 259 // calling audio renderer StartPlaying which would fail in playing state.
250 if (time_ticking_) { 260 if (time_ticking_) {
251 time_ticking_ = false; 261 time_ticking_ = false;
252 time_source_->StopTicking(); 262 time_source_->StopTicking();
253 } 263 }
254 audio_renderer_->Flush( 264 audio_renderer_->Flush(
255 base::Bind(&RendererImpl::RestartAudioRenderer, weak_this_, time)); 265 base::Bind(&RendererImpl::RestartAudioRenderer, weak_this_, time));
256 } 266 }
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 : &video_buffering_state_; 645 : &video_buffering_state_;
636 646
637 DVLOG(1) << __func__ << (type == DemuxerStream::AUDIO ? " audio " : " video ") 647 DVLOG(1) << __func__ << (type == DemuxerStream::AUDIO ? " audio " : " video ")
638 << BufferingStateStr(*buffering_state) << " -> " 648 << BufferingStateStr(*buffering_state) << " -> "
639 << BufferingStateStr(new_buffering_state); 649 << BufferingStateStr(new_buffering_state);
640 DCHECK(task_runner_->BelongsToCurrentThread()); 650 DCHECK(task_runner_->BelongsToCurrentThread());
641 651
642 bool was_waiting_for_enough_data = WaitingForEnoughData(); 652 bool was_waiting_for_enough_data = WaitingForEnoughData();
643 653
644 if (restarting_audio_ || restarting_video_) { 654 if (restarting_audio_ || restarting_video_) {
645 if (HandleRestartedStreamBufferingChanges(type, new_buffering_state)) 655 if (HandleRestartedStreamBufferingChanges(type, new_buffering_state)) {
646 return; 656 return;
657 }
647 } 658 }
648 659
649 // When audio is present and has enough data, defer video underflow callbacks 660 // When audio is present and has enough data, defer video underflow callbacks
650 // for some time to avoid unnecessary glitches in audio; see 661 // for some time to avoid unnecessary glitches in audio; see
651 // http://crbug.com/144683#c53. 662 // http://crbug.com/144683#c53.
652 if (audio_renderer_ && type == DemuxerStream::VIDEO && 663 if (audio_renderer_ && type == DemuxerStream::VIDEO &&
653 state_ == STATE_PLAYING) { 664 state_ == STATE_PLAYING) {
654 if (video_buffering_state_ == BUFFERING_HAVE_ENOUGH && 665 if (video_buffering_state_ == BUFFERING_HAVE_ENOUGH &&
655 audio_buffering_state_ == BUFFERING_HAVE_ENOUGH && 666 audio_buffering_state_ == BUFFERING_HAVE_ENOUGH &&
656 new_buffering_state == BUFFERING_HAVE_NOTHING && 667 new_buffering_state == BUFFERING_HAVE_NOTHING &&
657 deferred_video_underflow_cb_.IsCancelled()) { 668 deferred_video_underflow_cb_.IsCancelled()) {
658 DVLOG(4) << __func__ << " Deferring HAVE_NOTHING for video stream."; 669 DVLOG(1) << __func__ << " Deferring HAVE_NOTHING for video stream.";
servolk 2016/12/13 19:46:28 Nit: why? this could be noisy in logs. Let's keep
whywhat 2016/12/13 21:44:10 Oops, uploaded accidental change after debug loggi
659 deferred_video_underflow_cb_.Reset( 670 deferred_video_underflow_cb_.Reset(
660 base::Bind(&RendererImpl::OnBufferingStateChange, 671 base::Bind(&RendererImpl::OnBufferingStateChange,
661 weak_factory_.GetWeakPtr(), type, new_buffering_state)); 672 weak_factory_.GetWeakPtr(), type, new_buffering_state));
662 task_runner_->PostDelayedTask(FROM_HERE, 673 task_runner_->PostDelayedTask(FROM_HERE,
663 deferred_video_underflow_cb_.callback(), 674 deferred_video_underflow_cb_.callback(),
664 video_underflow_threshold_); 675 video_underflow_threshold_);
665 return; 676 return;
666 } 677 }
667 678
668 DVLOG(4) << "deferred_video_underflow_cb_.Cancel()";
servolk 2016/12/13 19:46:28 Also: why?
whywhat 2016/12/13 21:44:10 ditto
669 deferred_video_underflow_cb_.Cancel(); 679 deferred_video_underflow_cb_.Cancel();
670 } else if (!deferred_video_underflow_cb_.IsCancelled() && 680 } else if (!deferred_video_underflow_cb_.IsCancelled() &&
671 type == DemuxerStream::AUDIO && 681 type == DemuxerStream::AUDIO &&
672 new_buffering_state == BUFFERING_HAVE_NOTHING) { 682 new_buffering_state == BUFFERING_HAVE_NOTHING) {
673 // If audio underflows while we have a deferred video underflow in progress 683 // If audio underflows while we have a deferred video underflow in progress
674 // we want to mark video as underflowed immediately and cancel the deferral. 684 // we want to mark video as underflowed immediately and cancel the deferral.
675 deferred_video_underflow_cb_.Cancel(); 685 deferred_video_underflow_cb_.Cancel();
676 video_buffering_state_ = BUFFERING_HAVE_NOTHING; 686 video_buffering_state_ = BUFFERING_HAVE_NOTHING;
677 } 687 }
678 688
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 void RendererImpl::OnVideoNaturalSizeChange(const gfx::Size& size) { 848 void RendererImpl::OnVideoNaturalSizeChange(const gfx::Size& size) {
839 DCHECK(task_runner_->BelongsToCurrentThread()); 849 DCHECK(task_runner_->BelongsToCurrentThread());
840 client_->OnVideoNaturalSizeChange(size); 850 client_->OnVideoNaturalSizeChange(size);
841 } 851 }
842 852
843 void RendererImpl::OnVideoOpacityChange(bool opaque) { 853 void RendererImpl::OnVideoOpacityChange(bool opaque) {
844 DCHECK(task_runner_->BelongsToCurrentThread()); 854 DCHECK(task_runner_->BelongsToCurrentThread());
845 client_->OnVideoOpacityChange(opaque); 855 client_->OnVideoOpacityChange(opaque);
846 } 856 }
847 857
858 void RendererImpl::OnFirstFrameRender(DemuxerStream::Type type) {
859 DCHECK(task_runner_->BelongsToCurrentThread());
860 if (type == DemuxerStream::AUDIO && !audio_preroll_start_time_.is_null()) {
861 UMA_HISTOGRAM_MEDIUM_TIMES(
862 "Media.Audio.PrerollTime",
863 base::TimeTicks::Now() - audio_preroll_start_time_);
864 audio_preroll_start_time_ = base::TimeTicks();
865 } else if (type == DemuxerStream::VIDEO &&
866 !video_preroll_start_time_.is_null()) {
867 UMA_HISTOGRAM_MEDIUM_TIMES(
868 "Media.Video.PrerollTime",
869 base::TimeTicks::Now() - video_preroll_start_time_);
870 video_preroll_start_time_ = base::TimeTicks();
871 }
872 }
873
848 } // namespace media 874 } // namespace media
OLDNEW
« no previous file with comments | « media/renderers/renderer_impl.h ('k') | media/renderers/video_renderer_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698