| 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 video_buffering_state_(BUFFERING_HAVE_NOTHING), | 79 video_buffering_state_(BUFFERING_HAVE_NOTHING), |
| 80 audio_ended_(false), | 80 audio_ended_(false), |
| 81 video_ended_(false), | 81 video_ended_(false), |
| 82 cdm_context_(nullptr), | 82 cdm_context_(nullptr), |
| 83 underflow_disabled_for_testing_(false), | 83 underflow_disabled_for_testing_(false), |
| 84 clockless_video_playback_enabled_for_testing_(false), | 84 clockless_video_playback_enabled_for_testing_(false), |
| 85 video_underflow_threshold_( | 85 video_underflow_threshold_( |
| 86 base::TimeDelta::FromMilliseconds(kDefaultVideoUnderflowThresholdMs)), | 86 base::TimeDelta::FromMilliseconds(kDefaultVideoUnderflowThresholdMs)), |
| 87 weak_factory_(this) { | 87 weak_factory_(this) { |
| 88 weak_this_ = weak_factory_.GetWeakPtr(); | 88 weak_this_ = weak_factory_.GetWeakPtr(); |
| 89 DVLOG(1) << __FUNCTION__; | 89 DVLOG(1) << __func__; |
| 90 | 90 |
| 91 // TODO(dalecurtis): Remove once experiments for http://crbug.com/470940 are | 91 // TODO(dalecurtis): Remove once experiments for http://crbug.com/470940 are |
| 92 // complete. | 92 // complete. |
| 93 int threshold_ms = 0; | 93 int threshold_ms = 0; |
| 94 std::string threshold_ms_str( | 94 std::string threshold_ms_str( |
| 95 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 95 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 96 switches::kVideoUnderflowThresholdMs)); | 96 switches::kVideoUnderflowThresholdMs)); |
| 97 if (base::StringToInt(threshold_ms_str, &threshold_ms) && threshold_ms > 0) { | 97 if (base::StringToInt(threshold_ms_str, &threshold_ms) && threshold_ms > 0) { |
| 98 video_underflow_threshold_ = | 98 video_underflow_threshold_ = |
| 99 base::TimeDelta::FromMilliseconds(threshold_ms); | 99 base::TimeDelta::FromMilliseconds(threshold_ms); |
| 100 } | 100 } |
| 101 } | 101 } |
| 102 | 102 |
| 103 RendererImpl::~RendererImpl() { | 103 RendererImpl::~RendererImpl() { |
| 104 DVLOG(1) << __FUNCTION__; | 104 DVLOG(1) << __func__; |
| 105 DCHECK(task_runner_->BelongsToCurrentThread()); | 105 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 106 | 106 |
| 107 // Tear down in opposite order of construction as |video_renderer_| can still | 107 // Tear down in opposite order of construction as |video_renderer_| can still |
| 108 // need |time_source_| (which can be |audio_renderer_|) to be alive. | 108 // need |time_source_| (which can be |audio_renderer_|) to be alive. |
| 109 video_renderer_.reset(); | 109 video_renderer_.reset(); |
| 110 audio_renderer_.reset(); | 110 audio_renderer_.reset(); |
| 111 | 111 |
| 112 if (!init_cb_.is_null()) { | 112 if (!init_cb_.is_null()) { |
| 113 FinishInitialization(PIPELINE_ERROR_ABORT); | 113 FinishInitialization(PIPELINE_ERROR_ABORT); |
| 114 } else if (!flush_cb_.is_null()) { | 114 } else if (!flush_cb_.is_null()) { |
| 115 base::ResetAndReturn(&flush_cb_).Run(); | 115 base::ResetAndReturn(&flush_cb_).Run(); |
| 116 } | 116 } |
| 117 } | 117 } |
| 118 | 118 |
| 119 void RendererImpl::Initialize(DemuxerStreamProvider* demuxer_stream_provider, | 119 void RendererImpl::Initialize(DemuxerStreamProvider* demuxer_stream_provider, |
| 120 RendererClient* client, | 120 RendererClient* client, |
| 121 const PipelineStatusCB& init_cb) { | 121 const PipelineStatusCB& init_cb) { |
| 122 DVLOG(1) << __FUNCTION__; | 122 DVLOG(1) << __func__; |
| 123 DCHECK(task_runner_->BelongsToCurrentThread()); | 123 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 124 DCHECK_EQ(state_, STATE_UNINITIALIZED); | 124 DCHECK_EQ(state_, STATE_UNINITIALIZED); |
| 125 DCHECK(!init_cb.is_null()); | 125 DCHECK(!init_cb.is_null()); |
| 126 DCHECK(client); | 126 DCHECK(client); |
| 127 DCHECK(demuxer_stream_provider->GetStream(DemuxerStream::AUDIO) || | 127 DCHECK(demuxer_stream_provider->GetStream(DemuxerStream::AUDIO) || |
| 128 demuxer_stream_provider->GetStream(DemuxerStream::VIDEO)); | 128 demuxer_stream_provider->GetStream(DemuxerStream::VIDEO)); |
| 129 | 129 |
| 130 client_ = client; | 130 client_ = client; |
| 131 demuxer_stream_provider_ = demuxer_stream_provider; | 131 demuxer_stream_provider_ = demuxer_stream_provider; |
| 132 init_cb_ = init_cb; | 132 init_cb_ = init_cb; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 146 state_ = STATE_INIT_PENDING_CDM; | 146 state_ = STATE_INIT_PENDING_CDM; |
| 147 return; | 147 return; |
| 148 } | 148 } |
| 149 | 149 |
| 150 state_ = STATE_INITIALIZING; | 150 state_ = STATE_INITIALIZING; |
| 151 InitializeAudioRenderer(); | 151 InitializeAudioRenderer(); |
| 152 } | 152 } |
| 153 | 153 |
| 154 void RendererImpl::SetCdm(CdmContext* cdm_context, | 154 void RendererImpl::SetCdm(CdmContext* cdm_context, |
| 155 const CdmAttachedCB& cdm_attached_cb) { | 155 const CdmAttachedCB& cdm_attached_cb) { |
| 156 DVLOG(1) << __FUNCTION__; | 156 DVLOG(1) << __func__; |
| 157 DCHECK(task_runner_->BelongsToCurrentThread()); | 157 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 158 DCHECK(cdm_context); | 158 DCHECK(cdm_context); |
| 159 | 159 |
| 160 if (cdm_context_) { | 160 if (cdm_context_) { |
| 161 DVLOG(1) << "Switching CDM not supported."; | 161 DVLOG(1) << "Switching CDM not supported."; |
| 162 cdm_attached_cb.Run(false); | 162 cdm_attached_cb.Run(false); |
| 163 return; | 163 return; |
| 164 } | 164 } |
| 165 | 165 |
| 166 cdm_context_ = cdm_context; | 166 cdm_context_ = cdm_context; |
| 167 | 167 |
| 168 if (state_ != STATE_INIT_PENDING_CDM) { | 168 if (state_ != STATE_INIT_PENDING_CDM) { |
| 169 cdm_attached_cb.Run(true); | 169 cdm_attached_cb.Run(true); |
| 170 return; | 170 return; |
| 171 } | 171 } |
| 172 | 172 |
| 173 DCHECK(!init_cb_.is_null()); | 173 DCHECK(!init_cb_.is_null()); |
| 174 state_ = STATE_INITIALIZING; | 174 state_ = STATE_INITIALIZING; |
| 175 // |cdm_attached_cb| will be fired after initialization finishes. | 175 // |cdm_attached_cb| will be fired after initialization finishes. |
| 176 pending_cdm_attached_cb_ = cdm_attached_cb; | 176 pending_cdm_attached_cb_ = cdm_attached_cb; |
| 177 | 177 |
| 178 InitializeAudioRenderer(); | 178 InitializeAudioRenderer(); |
| 179 } | 179 } |
| 180 | 180 |
| 181 void RendererImpl::Flush(const base::Closure& flush_cb) { | 181 void RendererImpl::Flush(const base::Closure& flush_cb) { |
| 182 DVLOG(1) << __FUNCTION__; | 182 DVLOG(1) << __func__; |
| 183 DCHECK(task_runner_->BelongsToCurrentThread()); | 183 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 184 DCHECK(flush_cb_.is_null()); | 184 DCHECK(flush_cb_.is_null()); |
| 185 | 185 |
| 186 if (state_ != STATE_PLAYING) { | 186 if (state_ != STATE_PLAYING) { |
| 187 DCHECK_EQ(state_, STATE_ERROR); | 187 DCHECK_EQ(state_, STATE_ERROR); |
| 188 return; | 188 return; |
| 189 } | 189 } |
| 190 | 190 |
| 191 flush_cb_ = flush_cb; | 191 flush_cb_ = flush_cb; |
| 192 state_ = STATE_FLUSHING; | 192 state_ = STATE_FLUSHING; |
| 193 | 193 |
| 194 if (time_ticking_) | 194 if (time_ticking_) |
| 195 PausePlayback(); | 195 PausePlayback(); |
| 196 | 196 |
| 197 FlushAudioRenderer(); | 197 FlushAudioRenderer(); |
| 198 } | 198 } |
| 199 | 199 |
| 200 void RendererImpl::StartPlayingFrom(base::TimeDelta time) { | 200 void RendererImpl::StartPlayingFrom(base::TimeDelta time) { |
| 201 DVLOG(1) << __FUNCTION__; | 201 DVLOG(1) << __func__; |
| 202 DCHECK(task_runner_->BelongsToCurrentThread()); | 202 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 203 | 203 |
| 204 if (state_ != STATE_PLAYING) { | 204 if (state_ != STATE_PLAYING) { |
| 205 DCHECK_EQ(state_, STATE_ERROR); | 205 DCHECK_EQ(state_, STATE_ERROR); |
| 206 return; | 206 return; |
| 207 } | 207 } |
| 208 | 208 |
| 209 time_source_->SetMediaTime(time); | 209 time_source_->SetMediaTime(time); |
| 210 | 210 |
| 211 if (audio_renderer_) | 211 if (audio_renderer_) |
| 212 audio_renderer_->StartPlaying(); | 212 audio_renderer_->StartPlaying(); |
| 213 if (video_renderer_) | 213 if (video_renderer_) |
| 214 video_renderer_->StartPlayingFrom(time); | 214 video_renderer_->StartPlayingFrom(time); |
| 215 } | 215 } |
| 216 | 216 |
| 217 void RendererImpl::RestartStreamPlayback(DemuxerStream* stream, | 217 void RendererImpl::RestartStreamPlayback(DemuxerStream* stream, |
| 218 base::TimeDelta time) { | 218 base::TimeDelta time) { |
| 219 DVLOG(1) << __FUNCTION__ << " stream=" << stream | 219 DVLOG(1) << __func__ << " stream=" << stream << " time=" << time.InSecondsF(); |
| 220 << " time=" << time.InSecondsF(); | |
| 221 DCHECK(task_runner_->BelongsToCurrentThread()); | 220 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 222 if (state_ != STATE_PLAYING) | 221 if (state_ != STATE_PLAYING) |
| 223 return; | 222 return; |
| 224 if (stream->type() == DemuxerStream::VIDEO) { | 223 if (stream->type() == DemuxerStream::VIDEO) { |
| 225 DCHECK(video_renderer_); | 224 DCHECK(video_renderer_); |
| 226 if (restarting_video_) | 225 if (restarting_video_) |
| 227 return; | 226 return; |
| 228 restarting_video_ = true; | 227 restarting_video_ = true; |
| 229 video_renderer_->Flush( | 228 video_renderer_->Flush( |
| 230 base::Bind(&RendererImpl::RestartVideoRenderer, weak_this_, time)); | 229 base::Bind(&RendererImpl::RestartVideoRenderer, weak_this_, time)); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 241 time_ticking_ = false; | 240 time_ticking_ = false; |
| 242 time_source_->StopTicking(); | 241 time_source_->StopTicking(); |
| 243 } | 242 } |
| 244 audio_renderer_->Flush( | 243 audio_renderer_->Flush( |
| 245 base::Bind(&RendererImpl::RestartAudioRenderer, weak_this_, time)); | 244 base::Bind(&RendererImpl::RestartAudioRenderer, weak_this_, time)); |
| 246 } | 245 } |
| 247 } | 246 } |
| 248 | 247 |
| 249 void RendererImpl::RestartVideoRenderer(base::TimeDelta time) { | 248 void RendererImpl::RestartVideoRenderer(base::TimeDelta time) { |
| 250 DCHECK(task_runner_->BelongsToCurrentThread()); | 249 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 251 DVLOG(2) << __FUNCTION__; | 250 DVLOG(2) << __func__; |
| 252 video_ended_ = false; | 251 video_ended_ = false; |
| 253 if (state_ == STATE_PLAYING) { | 252 if (state_ == STATE_PLAYING) { |
| 254 DCHECK(video_renderer_); | 253 DCHECK(video_renderer_); |
| 255 video_renderer_->StartPlayingFrom(time); | 254 video_renderer_->StartPlayingFrom(time); |
| 256 } | 255 } |
| 257 } | 256 } |
| 258 | 257 |
| 259 void RendererImpl::RestartAudioRenderer(base::TimeDelta time) { | 258 void RendererImpl::RestartAudioRenderer(base::TimeDelta time) { |
| 260 DCHECK(task_runner_->BelongsToCurrentThread()); | 259 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 261 DVLOG(2) << __FUNCTION__; | 260 DVLOG(2) << __func__; |
| 262 audio_ended_ = false; | 261 audio_ended_ = false; |
| 263 if (state_ == STATE_PLAYING) { | 262 if (state_ == STATE_PLAYING) { |
| 264 DCHECK(time_source_); | 263 DCHECK(time_source_); |
| 265 DCHECK(audio_renderer_); | 264 DCHECK(audio_renderer_); |
| 266 audio_renderer_->StartPlaying(); | 265 audio_renderer_->StartPlaying(); |
| 267 } | 266 } |
| 268 } | 267 } |
| 269 | 268 |
| 270 void RendererImpl::SetPlaybackRate(double playback_rate) { | 269 void RendererImpl::SetPlaybackRate(double playback_rate) { |
| 271 DVLOG(1) << __FUNCTION__ << "(" << playback_rate << ")"; | 270 DVLOG(1) << __func__ << "(" << playback_rate << ")"; |
| 272 DCHECK(task_runner_->BelongsToCurrentThread()); | 271 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 273 | 272 |
| 274 // Playback rate changes are only carried out while playing. | 273 // Playback rate changes are only carried out while playing. |
| 275 if (state_ != STATE_PLAYING) | 274 if (state_ != STATE_PLAYING) |
| 276 return; | 275 return; |
| 277 | 276 |
| 278 time_source_->SetPlaybackRate(playback_rate); | 277 time_source_->SetPlaybackRate(playback_rate); |
| 279 | 278 |
| 280 const double old_rate = playback_rate_; | 279 const double old_rate = playback_rate_; |
| 281 playback_rate_ = playback_rate; | 280 playback_rate_ = playback_rate; |
| 282 if (!time_ticking_ || !video_renderer_) | 281 if (!time_ticking_ || !video_renderer_) |
| 283 return; | 282 return; |
| 284 | 283 |
| 285 if (old_rate == 0 && playback_rate > 0) | 284 if (old_rate == 0 && playback_rate > 0) |
| 286 video_renderer_->OnTimeStateChanged(true); | 285 video_renderer_->OnTimeStateChanged(true); |
| 287 else if (old_rate > 0 && playback_rate == 0) | 286 else if (old_rate > 0 && playback_rate == 0) |
| 288 video_renderer_->OnTimeStateChanged(false); | 287 video_renderer_->OnTimeStateChanged(false); |
| 289 } | 288 } |
| 290 | 289 |
| 291 void RendererImpl::SetVolume(float volume) { | 290 void RendererImpl::SetVolume(float volume) { |
| 292 DVLOG(1) << __FUNCTION__; | 291 DVLOG(1) << __func__; |
| 293 DCHECK(task_runner_->BelongsToCurrentThread()); | 292 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 294 | 293 |
| 295 if (audio_renderer_) | 294 if (audio_renderer_) |
| 296 audio_renderer_->SetVolume(volume); | 295 audio_renderer_->SetVolume(volume); |
| 297 } | 296 } |
| 298 | 297 |
| 299 base::TimeDelta RendererImpl::GetMediaTime() { | 298 base::TimeDelta RendererImpl::GetMediaTime() { |
| 300 // No BelongsToCurrentThread() checking because this can be called from other | 299 // No BelongsToCurrentThread() checking because this can be called from other |
| 301 // threads. | 300 // threads. |
| 302 return time_source_->CurrentMediaTime(); | 301 return time_source_->CurrentMediaTime(); |
| 303 } | 302 } |
| 304 | 303 |
| 305 bool RendererImpl::HasAudio() { | 304 bool RendererImpl::HasAudio() { |
| 306 DCHECK(task_runner_->BelongsToCurrentThread()); | 305 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 307 return audio_renderer_ != NULL; | 306 return audio_renderer_ != NULL; |
| 308 } | 307 } |
| 309 | 308 |
| 310 bool RendererImpl::HasVideo() { | 309 bool RendererImpl::HasVideo() { |
| 311 DCHECK(task_runner_->BelongsToCurrentThread()); | 310 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 312 return video_renderer_ != NULL; | 311 return video_renderer_ != NULL; |
| 313 } | 312 } |
| 314 | 313 |
| 315 void RendererImpl::DisableUnderflowForTesting() { | 314 void RendererImpl::DisableUnderflowForTesting() { |
| 316 DVLOG(1) << __FUNCTION__; | 315 DVLOG(1) << __func__; |
| 317 DCHECK(task_runner_->BelongsToCurrentThread()); | 316 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 318 DCHECK_EQ(state_, STATE_UNINITIALIZED); | 317 DCHECK_EQ(state_, STATE_UNINITIALIZED); |
| 319 | 318 |
| 320 underflow_disabled_for_testing_ = true; | 319 underflow_disabled_for_testing_ = true; |
| 321 } | 320 } |
| 322 | 321 |
| 323 void RendererImpl::EnableClocklessVideoPlaybackForTesting() { | 322 void RendererImpl::EnableClocklessVideoPlaybackForTesting() { |
| 324 DVLOG(1) << __FUNCTION__; | 323 DVLOG(1) << __func__; |
| 325 DCHECK(task_runner_->BelongsToCurrentThread()); | 324 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 326 DCHECK_EQ(state_, STATE_UNINITIALIZED); | 325 DCHECK_EQ(state_, STATE_UNINITIALIZED); |
| 327 DCHECK(underflow_disabled_for_testing_) | 326 DCHECK(underflow_disabled_for_testing_) |
| 328 << "Underflow must be disabled for clockless video playback"; | 327 << "Underflow must be disabled for clockless video playback"; |
| 329 | 328 |
| 330 clockless_video_playback_enabled_for_testing_ = true; | 329 clockless_video_playback_enabled_for_testing_ = true; |
| 331 } | 330 } |
| 332 | 331 |
| 333 bool RendererImpl::GetWallClockTimes( | 332 bool RendererImpl::GetWallClockTimes( |
| 334 const std::vector<base::TimeDelta>& media_timestamps, | 333 const std::vector<base::TimeDelta>& media_timestamps, |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 void RendererImpl::FinishInitialization(PipelineStatus status) { | 370 void RendererImpl::FinishInitialization(PipelineStatus status) { |
| 372 DCHECK(!init_cb_.is_null()); | 371 DCHECK(!init_cb_.is_null()); |
| 373 | 372 |
| 374 if (!pending_cdm_attached_cb_.is_null()) | 373 if (!pending_cdm_attached_cb_.is_null()) |
| 375 base::ResetAndReturn(&pending_cdm_attached_cb_).Run(status == PIPELINE_OK); | 374 base::ResetAndReturn(&pending_cdm_attached_cb_).Run(status == PIPELINE_OK); |
| 376 | 375 |
| 377 base::ResetAndReturn(&init_cb_).Run(status); | 376 base::ResetAndReturn(&init_cb_).Run(status); |
| 378 } | 377 } |
| 379 | 378 |
| 380 void RendererImpl::InitializeAudioRenderer() { | 379 void RendererImpl::InitializeAudioRenderer() { |
| 381 DVLOG(1) << __FUNCTION__; | 380 DVLOG(1) << __func__; |
| 382 DCHECK(task_runner_->BelongsToCurrentThread()); | 381 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 383 DCHECK_EQ(state_, STATE_INITIALIZING); | 382 DCHECK_EQ(state_, STATE_INITIALIZING); |
| 384 DCHECK(!init_cb_.is_null()); | 383 DCHECK(!init_cb_.is_null()); |
| 385 | 384 |
| 386 PipelineStatusCB done_cb = | 385 PipelineStatusCB done_cb = |
| 387 base::Bind(&RendererImpl::OnAudioRendererInitializeDone, weak_this_); | 386 base::Bind(&RendererImpl::OnAudioRendererInitializeDone, weak_this_); |
| 388 | 387 |
| 389 if (!demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO)) { | 388 if (!demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO)) { |
| 390 audio_renderer_.reset(); | 389 audio_renderer_.reset(); |
| 391 task_runner_->PostTask(FROM_HERE, base::Bind(done_cb, PIPELINE_OK)); | 390 task_runner_->PostTask(FROM_HERE, base::Bind(done_cb, PIPELINE_OK)); |
| 392 return; | 391 return; |
| 393 } | 392 } |
| 394 | 393 |
| 395 audio_renderer_client_.reset( | 394 audio_renderer_client_.reset( |
| 396 new RendererClientInternal(DemuxerStream::AUDIO, this)); | 395 new RendererClientInternal(DemuxerStream::AUDIO, this)); |
| 397 // Note: After the initialization of a renderer, error events from it may | 396 // Note: After the initialization of a renderer, error events from it may |
| 398 // happen at any time and all future calls must guard against STATE_ERROR. | 397 // happen at any time and all future calls must guard against STATE_ERROR. |
| 399 audio_renderer_->Initialize( | 398 audio_renderer_->Initialize( |
| 400 demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO), cdm_context_, | 399 demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO), cdm_context_, |
| 401 audio_renderer_client_.get(), done_cb); | 400 audio_renderer_client_.get(), done_cb); |
| 402 } | 401 } |
| 403 | 402 |
| 404 void RendererImpl::OnAudioRendererInitializeDone(PipelineStatus status) { | 403 void RendererImpl::OnAudioRendererInitializeDone(PipelineStatus status) { |
| 405 DVLOG(1) << __FUNCTION__ << ": " << status; | 404 DVLOG(1) << __func__ << ": " << status; |
| 406 DCHECK(task_runner_->BelongsToCurrentThread()); | 405 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 407 | 406 |
| 408 // OnError() may be fired at any time by the renderers, even if they thought | 407 // OnError() may be fired at any time by the renderers, even if they thought |
| 409 // they initialized successfully (due to delayed output device setup). | 408 // they initialized successfully (due to delayed output device setup). |
| 410 if (state_ != STATE_INITIALIZING) { | 409 if (state_ != STATE_INITIALIZING) { |
| 411 DCHECK(init_cb_.is_null()); | 410 DCHECK(init_cb_.is_null()); |
| 412 audio_renderer_.reset(); | 411 audio_renderer_.reset(); |
| 413 return; | 412 return; |
| 414 } | 413 } |
| 415 | 414 |
| 416 if (status != PIPELINE_OK) { | 415 if (status != PIPELINE_OK) { |
| 417 FinishInitialization(status); | 416 FinishInitialization(status); |
| 418 return; | 417 return; |
| 419 } | 418 } |
| 420 | 419 |
| 421 DCHECK(!init_cb_.is_null()); | 420 DCHECK(!init_cb_.is_null()); |
| 422 InitializeVideoRenderer(); | 421 InitializeVideoRenderer(); |
| 423 } | 422 } |
| 424 | 423 |
| 425 void RendererImpl::InitializeVideoRenderer() { | 424 void RendererImpl::InitializeVideoRenderer() { |
| 426 DVLOG(1) << __FUNCTION__; | 425 DVLOG(1) << __func__; |
| 427 DCHECK(task_runner_->BelongsToCurrentThread()); | 426 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 428 DCHECK_EQ(state_, STATE_INITIALIZING); | 427 DCHECK_EQ(state_, STATE_INITIALIZING); |
| 429 DCHECK(!init_cb_.is_null()); | 428 DCHECK(!init_cb_.is_null()); |
| 430 | 429 |
| 431 PipelineStatusCB done_cb = | 430 PipelineStatusCB done_cb = |
| 432 base::Bind(&RendererImpl::OnVideoRendererInitializeDone, weak_this_); | 431 base::Bind(&RendererImpl::OnVideoRendererInitializeDone, weak_this_); |
| 433 | 432 |
| 434 if (!demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO)) { | 433 if (!demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO)) { |
| 435 video_renderer_.reset(); | 434 video_renderer_.reset(); |
| 436 task_runner_->PostTask(FROM_HERE, base::Bind(done_cb, PIPELINE_OK)); | 435 task_runner_->PostTask(FROM_HERE, base::Bind(done_cb, PIPELINE_OK)); |
| 437 return; | 436 return; |
| 438 } | 437 } |
| 439 | 438 |
| 440 video_renderer_client_.reset( | 439 video_renderer_client_.reset( |
| 441 new RendererClientInternal(DemuxerStream::VIDEO, this)); | 440 new RendererClientInternal(DemuxerStream::VIDEO, this)); |
| 442 video_renderer_->Initialize( | 441 video_renderer_->Initialize( |
| 443 demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO), cdm_context_, | 442 demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO), cdm_context_, |
| 444 video_renderer_client_.get(), | 443 video_renderer_client_.get(), |
| 445 base::Bind(&RendererImpl::GetWallClockTimes, base::Unretained(this)), | 444 base::Bind(&RendererImpl::GetWallClockTimes, base::Unretained(this)), |
| 446 done_cb); | 445 done_cb); |
| 447 } | 446 } |
| 448 | 447 |
| 449 void RendererImpl::OnVideoRendererInitializeDone(PipelineStatus status) { | 448 void RendererImpl::OnVideoRendererInitializeDone(PipelineStatus status) { |
| 450 DVLOG(1) << __FUNCTION__ << ": " << status; | 449 DVLOG(1) << __func__ << ": " << status; |
| 451 DCHECK(task_runner_->BelongsToCurrentThread()); | 450 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 452 | 451 |
| 453 // OnError() may be fired at any time by the renderers, even if they thought | 452 // OnError() may be fired at any time by the renderers, even if they thought |
| 454 // they initialized successfully (due to delayed output device setup). | 453 // they initialized successfully (due to delayed output device setup). |
| 455 if (state_ != STATE_INITIALIZING) { | 454 if (state_ != STATE_INITIALIZING) { |
| 456 DCHECK(init_cb_.is_null()); | 455 DCHECK(init_cb_.is_null()); |
| 457 audio_renderer_.reset(); | 456 audio_renderer_.reset(); |
| 458 video_renderer_.reset(); | 457 video_renderer_.reset(); |
| 459 return; | 458 return; |
| 460 } | 459 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 474 } | 473 } |
| 475 | 474 |
| 476 state_ = STATE_PLAYING; | 475 state_ = STATE_PLAYING; |
| 477 DCHECK(time_source_); | 476 DCHECK(time_source_); |
| 478 DCHECK(audio_renderer_ || video_renderer_); | 477 DCHECK(audio_renderer_ || video_renderer_); |
| 479 | 478 |
| 480 FinishInitialization(PIPELINE_OK); | 479 FinishInitialization(PIPELINE_OK); |
| 481 } | 480 } |
| 482 | 481 |
| 483 void RendererImpl::FlushAudioRenderer() { | 482 void RendererImpl::FlushAudioRenderer() { |
| 484 DVLOG(1) << __FUNCTION__; | 483 DVLOG(1) << __func__; |
| 485 DCHECK(task_runner_->BelongsToCurrentThread()); | 484 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 486 DCHECK_EQ(state_, STATE_FLUSHING); | 485 DCHECK_EQ(state_, STATE_FLUSHING); |
| 487 DCHECK(!flush_cb_.is_null()); | 486 DCHECK(!flush_cb_.is_null()); |
| 488 | 487 |
| 489 if (!audio_renderer_) { | 488 if (!audio_renderer_) { |
| 490 OnAudioRendererFlushDone(); | 489 OnAudioRendererFlushDone(); |
| 491 return; | 490 return; |
| 492 } | 491 } |
| 493 | 492 |
| 494 audio_renderer_->Flush( | 493 audio_renderer_->Flush( |
| 495 base::Bind(&RendererImpl::OnAudioRendererFlushDone, weak_this_)); | 494 base::Bind(&RendererImpl::OnAudioRendererFlushDone, weak_this_)); |
| 496 } | 495 } |
| 497 | 496 |
| 498 void RendererImpl::OnAudioRendererFlushDone() { | 497 void RendererImpl::OnAudioRendererFlushDone() { |
| 499 DVLOG(1) << __FUNCTION__; | 498 DVLOG(1) << __func__; |
| 500 DCHECK(task_runner_->BelongsToCurrentThread()); | 499 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 501 | 500 |
| 502 if (state_ == STATE_ERROR) { | 501 if (state_ == STATE_ERROR) { |
| 503 DCHECK(flush_cb_.is_null()); | 502 DCHECK(flush_cb_.is_null()); |
| 504 return; | 503 return; |
| 505 } | 504 } |
| 506 | 505 |
| 507 DCHECK_EQ(state_, STATE_FLUSHING); | 506 DCHECK_EQ(state_, STATE_FLUSHING); |
| 508 DCHECK(!flush_cb_.is_null()); | 507 DCHECK(!flush_cb_.is_null()); |
| 509 | 508 |
| 510 // If we had a deferred video renderer underflow prior to the flush, it should | 509 // If we had a deferred video renderer underflow prior to the flush, it should |
| 511 // have been cleared by the audio renderer changing to BUFFERING_HAVE_NOTHING. | 510 // have been cleared by the audio renderer changing to BUFFERING_HAVE_NOTHING. |
| 512 DCHECK(deferred_video_underflow_cb_.IsCancelled()); | 511 DCHECK(deferred_video_underflow_cb_.IsCancelled()); |
| 513 | 512 |
| 514 DCHECK_EQ(audio_buffering_state_, BUFFERING_HAVE_NOTHING); | 513 DCHECK_EQ(audio_buffering_state_, BUFFERING_HAVE_NOTHING); |
| 515 audio_ended_ = false; | 514 audio_ended_ = false; |
| 516 FlushVideoRenderer(); | 515 FlushVideoRenderer(); |
| 517 } | 516 } |
| 518 | 517 |
| 519 void RendererImpl::FlushVideoRenderer() { | 518 void RendererImpl::FlushVideoRenderer() { |
| 520 DVLOG(1) << __FUNCTION__; | 519 DVLOG(1) << __func__; |
| 521 DCHECK(task_runner_->BelongsToCurrentThread()); | 520 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 522 DCHECK_EQ(state_, STATE_FLUSHING); | 521 DCHECK_EQ(state_, STATE_FLUSHING); |
| 523 DCHECK(!flush_cb_.is_null()); | 522 DCHECK(!flush_cb_.is_null()); |
| 524 | 523 |
| 525 if (!video_renderer_) { | 524 if (!video_renderer_) { |
| 526 OnVideoRendererFlushDone(); | 525 OnVideoRendererFlushDone(); |
| 527 return; | 526 return; |
| 528 } | 527 } |
| 529 | 528 |
| 530 video_renderer_->Flush( | 529 video_renderer_->Flush( |
| 531 base::Bind(&RendererImpl::OnVideoRendererFlushDone, weak_this_)); | 530 base::Bind(&RendererImpl::OnVideoRendererFlushDone, weak_this_)); |
| 532 } | 531 } |
| 533 | 532 |
| 534 void RendererImpl::OnVideoRendererFlushDone() { | 533 void RendererImpl::OnVideoRendererFlushDone() { |
| 535 DVLOG(1) << __FUNCTION__; | 534 DVLOG(1) << __func__; |
| 536 DCHECK(task_runner_->BelongsToCurrentThread()); | 535 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 537 | 536 |
| 538 if (state_ == STATE_ERROR) { | 537 if (state_ == STATE_ERROR) { |
| 539 DCHECK(flush_cb_.is_null()); | 538 DCHECK(flush_cb_.is_null()); |
| 540 return; | 539 return; |
| 541 } | 540 } |
| 542 | 541 |
| 543 DCHECK_EQ(state_, STATE_FLUSHING); | 542 DCHECK_EQ(state_, STATE_FLUSHING); |
| 544 DCHECK(!flush_cb_.is_null()); | 543 DCHECK(!flush_cb_.is_null()); |
| 545 | 544 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 569 } | 568 } |
| 570 | 569 |
| 571 bool RendererImpl::HandleRestartedStreamBufferingChanges( | 570 bool RendererImpl::HandleRestartedStreamBufferingChanges( |
| 572 DemuxerStream::Type type, | 571 DemuxerStream::Type type, |
| 573 BufferingState new_buffering_state) { | 572 BufferingState new_buffering_state) { |
| 574 // When restarting playback we want to defer the BUFFERING_HAVE_NOTHING for | 573 // When restarting playback we want to defer the BUFFERING_HAVE_NOTHING for |
| 575 // the stream being restarted, to allow continuing uninterrupted playback on | 574 // the stream being restarted, to allow continuing uninterrupted playback on |
| 576 // the other stream. | 575 // the other stream. |
| 577 if (type == DemuxerStream::VIDEO && restarting_video_) { | 576 if (type == DemuxerStream::VIDEO && restarting_video_) { |
| 578 if (new_buffering_state == BUFFERING_HAVE_ENOUGH) { | 577 if (new_buffering_state == BUFFERING_HAVE_ENOUGH) { |
| 579 DVLOG(1) << __FUNCTION__ << " Got BUFFERING_HAVE_ENOUGH for video stream," | 578 DVLOG(1) << __func__ << " Got BUFFERING_HAVE_ENOUGH for video stream," |
| 580 " resuming playback."; | 579 " resuming playback."; |
| 581 restarting_video_ = false; | 580 restarting_video_ = false; |
| 582 if (state_ == STATE_PLAYING && | 581 if (state_ == STATE_PLAYING && |
| 583 !deferred_video_underflow_cb_.IsCancelled()) { | 582 !deferred_video_underflow_cb_.IsCancelled()) { |
| 584 // If deferred_video_underflow_cb_ wasn't triggered, then audio should | 583 // If deferred_video_underflow_cb_ wasn't triggered, then audio should |
| 585 // still be playing, we only need to unpause the video stream. | 584 // still be playing, we only need to unpause the video stream. |
| 586 DVLOG(4) << "deferred_video_underflow_cb_.Cancel()"; | 585 DVLOG(4) << "deferred_video_underflow_cb_.Cancel()"; |
| 587 deferred_video_underflow_cb_.Cancel(); | 586 deferred_video_underflow_cb_.Cancel(); |
| 588 video_buffering_state_ = new_buffering_state; | 587 video_buffering_state_ = new_buffering_state; |
| 589 if (playback_rate_ > 0) | 588 if (playback_rate_ > 0) |
| 590 video_renderer_->OnTimeStateChanged(true); | 589 video_renderer_->OnTimeStateChanged(true); |
| 591 return true; | 590 return true; |
| 592 } | 591 } |
| 593 } | 592 } |
| 594 // We don't handle the BUFFERING_HAVE_NOTHING case explicitly here, since | 593 // We don't handle the BUFFERING_HAVE_NOTHING case explicitly here, since |
| 595 // the existing logic for deferring video underflow reporting in | 594 // the existing logic for deferring video underflow reporting in |
| 596 // OnBufferingStateChange is exactly what we need. So fall through to the | 595 // OnBufferingStateChange is exactly what we need. So fall through to the |
| 597 // regular video underflow handling path in OnBufferingStateChange. | 596 // regular video underflow handling path in OnBufferingStateChange. |
| 598 } | 597 } |
| 599 | 598 |
| 600 if (type == DemuxerStream::AUDIO && restarting_audio_) { | 599 if (type == DemuxerStream::AUDIO && restarting_audio_) { |
| 601 if (new_buffering_state == BUFFERING_HAVE_NOTHING) { | 600 if (new_buffering_state == BUFFERING_HAVE_NOTHING) { |
| 602 if (deferred_video_underflow_cb_.IsCancelled() && | 601 if (deferred_video_underflow_cb_.IsCancelled() && |
| 603 deferred_audio_restart_underflow_cb_.IsCancelled()) { | 602 deferred_audio_restart_underflow_cb_.IsCancelled()) { |
| 604 DVLOG(1) << __FUNCTION__ << " Deferring BUFFERING_HAVE_NOTHING for " | 603 DVLOG(1) << __func__ << " Deferring BUFFERING_HAVE_NOTHING for " |
| 605 "audio stream which is being restarted."; | 604 "audio stream which is being restarted."; |
| 606 audio_buffering_state_ = new_buffering_state; | 605 audio_buffering_state_ = new_buffering_state; |
| 607 deferred_audio_restart_underflow_cb_.Reset( | 606 deferred_audio_restart_underflow_cb_.Reset( |
| 608 base::Bind(&RendererImpl::OnBufferingStateChange, weak_this_, type, | 607 base::Bind(&RendererImpl::OnBufferingStateChange, weak_this_, type, |
| 609 new_buffering_state)); | 608 new_buffering_state)); |
| 610 task_runner_->PostDelayedTask( | 609 task_runner_->PostDelayedTask( |
| 611 FROM_HERE, deferred_audio_restart_underflow_cb_.callback(), | 610 FROM_HERE, deferred_audio_restart_underflow_cb_.callback(), |
| 612 base::TimeDelta::FromMilliseconds( | 611 base::TimeDelta::FromMilliseconds( |
| 613 kAudioRestartUnderflowThresholdMs)); | 612 kAudioRestartUnderflowThresholdMs)); |
| 614 return true; | 613 return true; |
| 615 } | 614 } |
| 616 // Cancel the deferred callback and report the underflow immediately. | 615 // Cancel the deferred callback and report the underflow immediately. |
| 617 DVLOG(4) << "deferred_audio_restart_underflow_cb_.Cancel()"; | 616 DVLOG(4) << "deferred_audio_restart_underflow_cb_.Cancel()"; |
| 618 deferred_audio_restart_underflow_cb_.Cancel(); | 617 deferred_audio_restart_underflow_cb_.Cancel(); |
| 619 } else if (new_buffering_state == BUFFERING_HAVE_ENOUGH) { | 618 } else if (new_buffering_state == BUFFERING_HAVE_ENOUGH) { |
| 620 DVLOG(1) << __FUNCTION__ << " Got BUFFERING_HAVE_ENOUGH for audio stream," | 619 DVLOG(1) << __func__ << " Got BUFFERING_HAVE_ENOUGH for audio stream," |
| 621 " resuming playback."; | 620 " resuming playback."; |
| 622 deferred_audio_restart_underflow_cb_.Cancel(); | 621 deferred_audio_restart_underflow_cb_.Cancel(); |
| 623 // Now that we have decoded enough audio, pause playback momentarily to | 622 // Now that we have decoded enough audio, pause playback momentarily to |
| 624 // ensure video renderer is synchronised with audio. | 623 // ensure video renderer is synchronised with audio. |
| 625 PausePlayback(); | 624 PausePlayback(); |
| 626 restarting_audio_ = false; | 625 restarting_audio_ = false; |
| 627 } | 626 } |
| 628 } | 627 } |
| 629 return false; | 628 return false; |
| 630 } | 629 } |
| 631 | 630 |
| 632 void RendererImpl::OnBufferingStateChange(DemuxerStream::Type type, | 631 void RendererImpl::OnBufferingStateChange(DemuxerStream::Type type, |
| 633 BufferingState new_buffering_state) { | 632 BufferingState new_buffering_state) { |
| 634 DCHECK((type == DemuxerStream::AUDIO) || (type == DemuxerStream::VIDEO)); | 633 DCHECK((type == DemuxerStream::AUDIO) || (type == DemuxerStream::VIDEO)); |
| 635 BufferingState* buffering_state = type == DemuxerStream::AUDIO | 634 BufferingState* buffering_state = type == DemuxerStream::AUDIO |
| 636 ? &audio_buffering_state_ | 635 ? &audio_buffering_state_ |
| 637 : &video_buffering_state_; | 636 : &video_buffering_state_; |
| 638 | 637 |
| 639 DVLOG(1) << __FUNCTION__ | 638 DVLOG(1) << __func__ << (type == DemuxerStream::AUDIO ? " audio " : " video ") |
| 640 << (type == DemuxerStream::AUDIO ? " audio " : " video ") | |
| 641 << BufferingStateStr(*buffering_state) << " -> " | 639 << BufferingStateStr(*buffering_state) << " -> " |
| 642 << BufferingStateStr(new_buffering_state); | 640 << BufferingStateStr(new_buffering_state); |
| 643 DCHECK(task_runner_->BelongsToCurrentThread()); | 641 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 644 | 642 |
| 645 bool was_waiting_for_enough_data = WaitingForEnoughData(); | 643 bool was_waiting_for_enough_data = WaitingForEnoughData(); |
| 646 | 644 |
| 647 if (restarting_audio_ || restarting_video_) { | 645 if (restarting_audio_ || restarting_video_) { |
| 648 if (HandleRestartedStreamBufferingChanges(type, new_buffering_state)) | 646 if (HandleRestartedStreamBufferingChanges(type, new_buffering_state)) |
| 649 return; | 647 return; |
| 650 } | 648 } |
| 651 | 649 |
| 652 // When audio is present and has enough data, defer video underflow callbacks | 650 // When audio is present and has enough data, defer video underflow callbacks |
| 653 // for some time to avoid unnecessary glitches in audio; see | 651 // for some time to avoid unnecessary glitches in audio; see |
| 654 // http://crbug.com/144683#c53. | 652 // http://crbug.com/144683#c53. |
| 655 if (audio_renderer_ && type == DemuxerStream::VIDEO && | 653 if (audio_renderer_ && type == DemuxerStream::VIDEO && |
| 656 state_ == STATE_PLAYING) { | 654 state_ == STATE_PLAYING) { |
| 657 if (video_buffering_state_ == BUFFERING_HAVE_ENOUGH && | 655 if (video_buffering_state_ == BUFFERING_HAVE_ENOUGH && |
| 658 audio_buffering_state_ == BUFFERING_HAVE_ENOUGH && | 656 audio_buffering_state_ == BUFFERING_HAVE_ENOUGH && |
| 659 new_buffering_state == BUFFERING_HAVE_NOTHING && | 657 new_buffering_state == BUFFERING_HAVE_NOTHING && |
| 660 deferred_video_underflow_cb_.IsCancelled()) { | 658 deferred_video_underflow_cb_.IsCancelled()) { |
| 661 DVLOG(4) << __FUNCTION__ << " Deferring HAVE_NOTHING for video stream."; | 659 DVLOG(4) << __func__ << " Deferring HAVE_NOTHING for video stream."; |
| 662 deferred_video_underflow_cb_.Reset( | 660 deferred_video_underflow_cb_.Reset( |
| 663 base::Bind(&RendererImpl::OnBufferingStateChange, | 661 base::Bind(&RendererImpl::OnBufferingStateChange, |
| 664 weak_factory_.GetWeakPtr(), type, new_buffering_state)); | 662 weak_factory_.GetWeakPtr(), type, new_buffering_state)); |
| 665 task_runner_->PostDelayedTask(FROM_HERE, | 663 task_runner_->PostDelayedTask(FROM_HERE, |
| 666 deferred_video_underflow_cb_.callback(), | 664 deferred_video_underflow_cb_.callback(), |
| 667 video_underflow_threshold_); | 665 video_underflow_threshold_); |
| 668 return; | 666 return; |
| 669 } | 667 } |
| 670 | 668 |
| 671 DVLOG(4) << "deferred_video_underflow_cb_.Cancel()"; | 669 DVLOG(4) << "deferred_video_underflow_cb_.Cancel()"; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 708 if (state_ != STATE_PLAYING) | 706 if (state_ != STATE_PLAYING) |
| 709 return false; | 707 return false; |
| 710 if (audio_renderer_ && audio_buffering_state_ != BUFFERING_HAVE_ENOUGH) | 708 if (audio_renderer_ && audio_buffering_state_ != BUFFERING_HAVE_ENOUGH) |
| 711 return true; | 709 return true; |
| 712 if (video_renderer_ && video_buffering_state_ != BUFFERING_HAVE_ENOUGH) | 710 if (video_renderer_ && video_buffering_state_ != BUFFERING_HAVE_ENOUGH) |
| 713 return true; | 711 return true; |
| 714 return false; | 712 return false; |
| 715 } | 713 } |
| 716 | 714 |
| 717 void RendererImpl::PausePlayback() { | 715 void RendererImpl::PausePlayback() { |
| 718 DVLOG(1) << __FUNCTION__; | 716 DVLOG(1) << __func__; |
| 719 DCHECK(task_runner_->BelongsToCurrentThread()); | 717 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 720 switch (state_) { | 718 switch (state_) { |
| 721 case STATE_PLAYING: | 719 case STATE_PLAYING: |
| 722 DCHECK(PlaybackHasEnded() || WaitingForEnoughData() || restarting_audio_) | 720 DCHECK(PlaybackHasEnded() || WaitingForEnoughData() || restarting_audio_) |
| 723 << "Playback should only pause due to ending or underflowing or" | 721 << "Playback should only pause due to ending or underflowing or" |
| 724 " when restarting audio stream"; | 722 " when restarting audio stream"; |
| 725 | 723 |
| 726 break; | 724 break; |
| 727 | 725 |
| 728 case STATE_FLUSHING: | 726 case STATE_FLUSHING: |
| (...skipping 13 matching lines...) Expand all Loading... |
| 742 | 740 |
| 743 if (time_ticking_) { | 741 if (time_ticking_) { |
| 744 time_ticking_ = false; | 742 time_ticking_ = false; |
| 745 time_source_->StopTicking(); | 743 time_source_->StopTicking(); |
| 746 } | 744 } |
| 747 if (playback_rate_ > 0 && video_renderer_) | 745 if (playback_rate_ > 0 && video_renderer_) |
| 748 video_renderer_->OnTimeStateChanged(false); | 746 video_renderer_->OnTimeStateChanged(false); |
| 749 } | 747 } |
| 750 | 748 |
| 751 void RendererImpl::StartPlayback() { | 749 void RendererImpl::StartPlayback() { |
| 752 DVLOG(1) << __FUNCTION__; | 750 DVLOG(1) << __func__; |
| 753 DCHECK(task_runner_->BelongsToCurrentThread()); | 751 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 754 DCHECK_EQ(state_, STATE_PLAYING); | 752 DCHECK_EQ(state_, STATE_PLAYING); |
| 755 DCHECK(!time_ticking_); | 753 DCHECK(!time_ticking_); |
| 756 DCHECK(!WaitingForEnoughData()); | 754 DCHECK(!WaitingForEnoughData()); |
| 757 | 755 |
| 758 time_ticking_ = true; | 756 time_ticking_ = true; |
| 759 time_source_->StartTicking(); | 757 time_source_->StartTicking(); |
| 760 if (playback_rate_ > 0 && video_renderer_) | 758 if (playback_rate_ > 0 && video_renderer_) |
| 761 video_renderer_->OnTimeStateChanged(true); | 759 video_renderer_->OnTimeStateChanged(true); |
| 762 } | 760 } |
| 763 | 761 |
| 764 void RendererImpl::OnRendererEnded(DemuxerStream::Type type) { | 762 void RendererImpl::OnRendererEnded(DemuxerStream::Type type) { |
| 765 DVLOG(1) << __FUNCTION__ | 763 DVLOG(1) << __func__ << (type == DemuxerStream::AUDIO ? " audio" : " video"); |
| 766 << (type == DemuxerStream::AUDIO ? " audio" : " video"); | |
| 767 DCHECK(task_runner_->BelongsToCurrentThread()); | 764 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 768 DCHECK((type == DemuxerStream::AUDIO) || (type == DemuxerStream::VIDEO)); | 765 DCHECK((type == DemuxerStream::AUDIO) || (type == DemuxerStream::VIDEO)); |
| 769 | 766 |
| 770 if (state_ != STATE_PLAYING) | 767 if (state_ != STATE_PLAYING) |
| 771 return; | 768 return; |
| 772 | 769 |
| 773 if (type == DemuxerStream::AUDIO) { | 770 if (type == DemuxerStream::AUDIO) { |
| 774 DCHECK(!audio_ended_); | 771 DCHECK(!audio_ended_); |
| 775 audio_ended_ = true; | 772 audio_ended_ = true; |
| 776 } else { | 773 } else { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 789 if (audio_renderer_ && !audio_ended_) | 786 if (audio_renderer_ && !audio_ended_) |
| 790 return false; | 787 return false; |
| 791 | 788 |
| 792 if (video_renderer_ && !video_ended_) | 789 if (video_renderer_ && !video_ended_) |
| 793 return false; | 790 return false; |
| 794 | 791 |
| 795 return true; | 792 return true; |
| 796 } | 793 } |
| 797 | 794 |
| 798 void RendererImpl::RunEndedCallbackIfNeeded() { | 795 void RendererImpl::RunEndedCallbackIfNeeded() { |
| 799 DVLOG(1) << __FUNCTION__; | 796 DVLOG(1) << __func__; |
| 800 DCHECK(task_runner_->BelongsToCurrentThread()); | 797 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 801 | 798 |
| 802 if (!PlaybackHasEnded()) | 799 if (!PlaybackHasEnded()) |
| 803 return; | 800 return; |
| 804 | 801 |
| 805 if (time_ticking_) | 802 if (time_ticking_) |
| 806 PausePlayback(); | 803 PausePlayback(); |
| 807 | 804 |
| 808 client_->OnEnded(); | 805 client_->OnEnded(); |
| 809 } | 806 } |
| 810 | 807 |
| 811 void RendererImpl::OnError(PipelineStatus error) { | 808 void RendererImpl::OnError(PipelineStatus error) { |
| 812 DVLOG(1) << __FUNCTION__ << "(" << error << ")"; | 809 DVLOG(1) << __func__ << "(" << error << ")"; |
| 813 DCHECK(task_runner_->BelongsToCurrentThread()); | 810 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 814 DCHECK_NE(PIPELINE_OK, error) << "PIPELINE_OK isn't an error!"; | 811 DCHECK_NE(PIPELINE_OK, error) << "PIPELINE_OK isn't an error!"; |
| 815 | 812 |
| 816 // An error has already been delivered. | 813 // An error has already been delivered. |
| 817 if (state_ == STATE_ERROR) | 814 if (state_ == STATE_ERROR) |
| 818 return; | 815 return; |
| 819 | 816 |
| 820 const State old_state = state_; | 817 const State old_state = state_; |
| 821 state_ = STATE_ERROR; | 818 state_ = STATE_ERROR; |
| 822 | 819 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 843 DCHECK(task_runner_->BelongsToCurrentThread()); | 840 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 844 client_->OnVideoNaturalSizeChange(size); | 841 client_->OnVideoNaturalSizeChange(size); |
| 845 } | 842 } |
| 846 | 843 |
| 847 void RendererImpl::OnVideoOpacityChange(bool opaque) { | 844 void RendererImpl::OnVideoOpacityChange(bool opaque) { |
| 848 DCHECK(task_runner_->BelongsToCurrentThread()); | 845 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 849 client_->OnVideoOpacityChange(opaque); | 846 client_->OnVideoOpacityChange(opaque); |
| 850 } | 847 } |
| 851 | 848 |
| 852 } // namespace media | 849 } // namespace media |
| OLD | NEW |