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/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" |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
104 if (base::StringToInt(threshold_ms_str, &threshold_ms) && threshold_ms > 0) { | 104 if (base::StringToInt(threshold_ms_str, &threshold_ms) && threshold_ms > 0) { |
105 video_underflow_threshold_ = | 105 video_underflow_threshold_ = |
106 base::TimeDelta::FromMilliseconds(threshold_ms); | 106 base::TimeDelta::FromMilliseconds(threshold_ms); |
107 } | 107 } |
108 } | 108 } |
109 | 109 |
110 RendererImpl::~RendererImpl() { | 110 RendererImpl::~RendererImpl() { |
111 DVLOG(1) << __func__; | 111 DVLOG(1) << __func__; |
112 DCHECK(task_runner_->BelongsToCurrentThread()); | 112 DCHECK(task_runner_->BelongsToCurrentThread()); |
113 | 113 |
114 state_ = STATE_SHUTDOWN; | |
115 | |
114 // Tear down in opposite order of construction as |video_renderer_| can still | 116 // Tear down in opposite order of construction as |video_renderer_| can still |
115 // need |time_source_| (which can be |audio_renderer_|) to be alive. | 117 // need |time_source_| (which can be |audio_renderer_|) to be alive. |
116 video_renderer_.reset(); | 118 video_renderer_.reset(); |
117 audio_renderer_.reset(); | 119 audio_renderer_.reset(); |
118 | 120 |
119 if (!init_cb_.is_null()) { | 121 if (!init_cb_.is_null()) { |
120 FinishInitialization(PIPELINE_ERROR_ABORT); | 122 FinishInitialization(PIPELINE_ERROR_ABORT); |
121 } else if (!flush_cb_.is_null()) { | 123 } else if (!flush_cb_.is_null()) { |
122 base::ResetAndReturn(&flush_cb_).Run(); | 124 base::ResetAndReturn(&flush_cb_).Run(); |
whywhat
2016/12/13 05:08:41
Hm, I'd rather have the callbacks owner know someh
servolk
2016/12/13 19:39:47
Wait, are you talking about RendererImpl::flush_cb
whywhat
2016/12/13 20:10:54
Wait, aren't you fixing a crash where flush_cb_ is
servolk
2016/12/13 20:57:10
No, the flush_cb_ in RendererImpl is probably null
whywhat
2016/12/13 21:43:07
Hm, the dtor checks if flush_cb_ is null before in
servolk
2016/12/13 22:18:33
Yes, that's correct and doesn't contradict what I'
| |
123 } | 125 } |
124 } | 126 } |
125 | 127 |
126 void RendererImpl::Initialize(DemuxerStreamProvider* demuxer_stream_provider, | 128 void RendererImpl::Initialize(DemuxerStreamProvider* demuxer_stream_provider, |
127 RendererClient* client, | 129 RendererClient* client, |
128 const PipelineStatusCB& init_cb) { | 130 const PipelineStatusCB& init_cb) { |
129 DVLOG(1) << __func__; | 131 DVLOG(1) << __func__; |
130 DCHECK(task_runner_->BelongsToCurrentThread()); | 132 DCHECK(task_runner_->BelongsToCurrentThread()); |
131 DCHECK_EQ(state_, STATE_UNINITIALIZED); | 133 DCHECK_EQ(state_, STATE_UNINITIALIZED); |
132 DCHECK(!init_cb.is_null()); | 134 DCHECK(!init_cb.is_null()); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
239 time_source_->StopTicking(); | 241 time_source_->StopTicking(); |
240 } | 242 } |
241 audio_renderer_->Flush( | 243 audio_renderer_->Flush( |
242 base::Bind(&RendererImpl::RestartAudioRenderer, weak_this_, time)); | 244 base::Bind(&RendererImpl::RestartAudioRenderer, weak_this_, time)); |
243 } | 245 } |
244 } | 246 } |
245 | 247 |
246 void RendererImpl::RestartVideoRenderer(base::TimeDelta time) { | 248 void RendererImpl::RestartVideoRenderer(base::TimeDelta time) { |
247 DVLOG(3) << __func__; | 249 DVLOG(3) << __func__; |
248 DCHECK(task_runner_->BelongsToCurrentThread()); | 250 DCHECK(task_runner_->BelongsToCurrentThread()); |
249 DCHECK(video_renderer_); | 251 if (state_ == STATE_PLAYING) { |
whywhat
2016/12/13 05:08:41
nit: maybe you should rather check for STATE_SHUTD
servolk
2016/12/13 19:39:47
Yes, I've considered doing that, but I've decided
whywhat
2016/12/13 20:10:54
Calling this method in any other state than PLAYIN
servolk
2016/12/13 20:57:10
I want to make two notes here:
1. Calling this met
whywhat
2016/12/13 21:43:07
I agree that fixing this specific crash by making
servolk
2016/12/13 22:18:33
I see your points. But my counterarguments are:
1.
| |
250 DCHECK_EQ(state_, STATE_PLAYING); | 252 DCHECK(video_renderer_); |
251 video_ended_ = false; | 253 video_ended_ = false; |
252 video_renderer_->StartPlayingFrom(time); | 254 video_renderer_->StartPlayingFrom(time); |
255 } | |
253 } | 256 } |
254 | 257 |
255 void RendererImpl::RestartAudioRenderer(base::TimeDelta time) { | 258 void RendererImpl::RestartAudioRenderer(base::TimeDelta time) { |
256 DVLOG(3) << __func__; | 259 DVLOG(3) << __func__; |
257 DCHECK(task_runner_->BelongsToCurrentThread()); | 260 DCHECK(task_runner_->BelongsToCurrentThread()); |
258 DCHECK_EQ(state_, STATE_PLAYING); | 261 if (state_ == STATE_PLAYING) { |
whywhat
2016/12/13 21:43:07
nit: you could still do
if (state_ != STATE_PLAYI
servolk
2016/12/13 22:18:33
Done.
| |
259 DCHECK(time_source_); | 262 DCHECK(time_source_); |
260 DCHECK(audio_renderer_); | 263 DCHECK(audio_renderer_); |
261 audio_ended_ = false; | 264 audio_ended_ = false; |
262 audio_renderer_->StartPlaying(); | 265 audio_renderer_->StartPlaying(); |
266 } | |
263 } | 267 } |
264 | 268 |
265 void RendererImpl::SetPlaybackRate(double playback_rate) { | 269 void RendererImpl::SetPlaybackRate(double playback_rate) { |
266 DVLOG(1) << __func__ << "(" << playback_rate << ")"; | 270 DVLOG(1) << __func__ << "(" << playback_rate << ")"; |
267 DCHECK(task_runner_->BelongsToCurrentThread()); | 271 DCHECK(task_runner_->BelongsToCurrentThread()); |
268 | 272 |
269 // Playback rate changes are only carried out while playing. | 273 // Playback rate changes are only carried out while playing. |
270 if (state_ != STATE_PLAYING) | 274 if (state_ != STATE_PLAYING) |
271 return; | 275 return; |
272 | 276 |
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
717 | 721 |
718 break; | 722 break; |
719 | 723 |
720 case STATE_FLUSHING: | 724 case STATE_FLUSHING: |
721 // It's OK to pause playback when flushing. | 725 // It's OK to pause playback when flushing. |
722 break; | 726 break; |
723 | 727 |
724 case STATE_UNINITIALIZED: | 728 case STATE_UNINITIALIZED: |
725 case STATE_INIT_PENDING_CDM: | 729 case STATE_INIT_PENDING_CDM: |
726 case STATE_INITIALIZING: | 730 case STATE_INITIALIZING: |
731 case STATE_SHUTDOWN: | |
727 NOTREACHED() << "Invalid state: " << state_; | 732 NOTREACHED() << "Invalid state: " << state_; |
728 break; | 733 break; |
729 | 734 |
730 case STATE_ERROR: | 735 case STATE_ERROR: |
731 // An error state may occur at any time. | 736 // An error state may occur at any time. |
732 break; | 737 break; |
733 } | 738 } |
734 | 739 |
735 if (time_ticking_) { | 740 if (time_ticking_) { |
736 time_ticking_ = false; | 741 time_ticking_ = false; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
834 DCHECK(task_runner_->BelongsToCurrentThread()); | 839 DCHECK(task_runner_->BelongsToCurrentThread()); |
835 client_->OnVideoNaturalSizeChange(size); | 840 client_->OnVideoNaturalSizeChange(size); |
836 } | 841 } |
837 | 842 |
838 void RendererImpl::OnVideoOpacityChange(bool opaque) { | 843 void RendererImpl::OnVideoOpacityChange(bool opaque) { |
839 DCHECK(task_runner_->BelongsToCurrentThread()); | 844 DCHECK(task_runner_->BelongsToCurrentThread()); |
840 client_->OnVideoOpacityChange(opaque); | 845 client_->OnVideoOpacityChange(opaque); |
841 } | 846 } |
842 | 847 |
843 } // namespace media | 848 } // namespace media |
OLD | NEW |