| 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 "chromecast/media/cma/filters/cma_renderer.h" | 5 #include "chromecast/renderer/media/cma_renderer.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback_helpers.h" | 8 #include "base/callback_helpers.h" |
| 9 #include "base/location.h" | 9 #include "base/location.h" |
| 10 #include "base/single_thread_task_runner.h" | 10 #include "base/single_thread_task_runner.h" |
| 11 #include "base/thread_task_runner_handle.h" | 11 #include "base/thread_task_runner_handle.h" |
| 12 #include "chromecast/media/cma/base/balanced_media_task_runner_factory.h" | 12 #include "chromecast/media/cma/base/balanced_media_task_runner_factory.h" |
| 13 #include "chromecast/media/cma/base/cma_logging.h" | 13 #include "chromecast/media/cma/base/cma_logging.h" |
| 14 #include "chromecast/media/cma/filters/demuxer_stream_adapter.h" | |
| 15 #include "chromecast/media/cma/filters/hole_frame_factory.h" | |
| 16 #include "chromecast/media/cma/pipeline/audio_pipeline.h" | |
| 17 #include "chromecast/media/cma/pipeline/av_pipeline_client.h" | 14 #include "chromecast/media/cma/pipeline/av_pipeline_client.h" |
| 18 #include "chromecast/media/cma/pipeline/media_pipeline.h" | |
| 19 #include "chromecast/media/cma/pipeline/media_pipeline_client.h" | 15 #include "chromecast/media/cma/pipeline/media_pipeline_client.h" |
| 20 #include "chromecast/media/cma/pipeline/video_pipeline.h" | |
| 21 #include "chromecast/media/cma/pipeline/video_pipeline_client.h" | 16 #include "chromecast/media/cma/pipeline/video_pipeline_client.h" |
| 17 #include "chromecast/renderer/media/audio_pipeline_proxy.h" |
| 18 #include "chromecast/renderer/media/demuxer_stream_adapter.h" |
| 19 #include "chromecast/renderer/media/hole_frame_factory.h" |
| 20 #include "chromecast/renderer/media/media_pipeline_proxy.h" |
| 21 #include "chromecast/renderer/media/video_pipeline_proxy.h" |
| 22 #include "media/base/bind_to_current_loop.h" | 22 #include "media/base/bind_to_current_loop.h" |
| 23 #include "media/base/demuxer_stream_provider.h" | 23 #include "media/base/demuxer_stream_provider.h" |
| 24 #include "media/base/pipeline_status.h" | 24 #include "media/base/pipeline_status.h" |
| 25 #include "media/base/time_delta_interpolator.h" | 25 #include "media/base/time_delta_interpolator.h" |
| 26 #include "media/base/video_renderer_sink.h" | 26 #include "media/base/video_renderer_sink.h" |
| 27 #include "media/renderers/gpu_video_accelerator_factories.h" | 27 #include "media/renderers/gpu_video_accelerator_factories.h" |
| 28 #include "ui/gfx/geometry/size.h" | 28 #include "ui/gfx/geometry/size.h" |
| 29 | 29 |
| 30 namespace chromecast { | 30 namespace chromecast { |
| 31 namespace media { | 31 namespace media { |
| 32 | 32 |
| 33 namespace { | 33 namespace { |
| 34 | 34 |
| 35 // Maximum difference between audio frame PTS and video frame PTS | 35 // Maximum difference between audio frame PTS and video frame PTS |
| 36 // for frames read from the DemuxerStream. | 36 // for frames read from the DemuxerStream. |
| 37 const base::TimeDelta kMaxDeltaFetcher( | 37 const base::TimeDelta kMaxDeltaFetcher(base::TimeDelta::FromMilliseconds(2000)); |
| 38 base::TimeDelta::FromMilliseconds(2000)); | |
| 39 | 38 |
| 40 void MediaPipelineClientDummyCallback() {} | 39 void MediaPipelineClientDummyCallback() { |
| 40 } |
| 41 | 41 |
| 42 } // namespace | 42 } // namespace |
| 43 | 43 |
| 44 CmaRenderer::CmaRenderer( | 44 CmaRenderer::CmaRenderer( |
| 45 scoped_ptr<MediaPipeline> media_pipeline, | 45 scoped_ptr<MediaPipelineProxy> media_pipeline, |
| 46 ::media::VideoRendererSink* video_renderer_sink, | 46 ::media::VideoRendererSink* video_renderer_sink, |
| 47 const scoped_refptr<::media::GpuVideoAcceleratorFactories>& gpu_factories) | 47 const scoped_refptr<::media::GpuVideoAcceleratorFactories>& gpu_factories) |
| 48 : media_task_runner_factory_( | 48 : media_task_runner_factory_( |
| 49 new BalancedMediaTaskRunnerFactory(kMaxDeltaFetcher)), | 49 new BalancedMediaTaskRunnerFactory(kMaxDeltaFetcher)), |
| 50 media_pipeline_(media_pipeline.Pass()), | 50 media_pipeline_(media_pipeline.Pass()), |
| 51 audio_pipeline_(media_pipeline_->GetAudioPipeline()), | 51 audio_pipeline_(media_pipeline_->GetAudioPipeline()), |
| 52 video_pipeline_(media_pipeline_->GetVideoPipeline()), | 52 video_pipeline_(media_pipeline_->GetVideoPipeline()), |
| 53 video_renderer_sink_(video_renderer_sink), | 53 video_renderer_sink_(video_renderer_sink), |
| 54 state_(kUninitialized), | 54 state_(kUninitialized), |
| 55 is_pending_transition_(false), | 55 is_pending_transition_(false), |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb; | 115 waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb; |
| 116 | 116 |
| 117 MediaPipelineClient media_pipeline_client; | 117 MediaPipelineClient media_pipeline_client; |
| 118 media_pipeline_client.error_cb = error_cb_; | 118 media_pipeline_client.error_cb = error_cb_; |
| 119 media_pipeline_client.buffering_state_cb = ::media::BindToCurrentLoop( | 119 media_pipeline_client.buffering_state_cb = ::media::BindToCurrentLoop( |
| 120 base::Bind(&CmaRenderer::OnBufferingNotification, weak_this_)); | 120 base::Bind(&CmaRenderer::OnBufferingNotification, weak_this_)); |
| 121 media_pipeline_client.time_update_cb = ::media::BindToCurrentLoop( | 121 media_pipeline_client.time_update_cb = ::media::BindToCurrentLoop( |
| 122 base::Bind(&CmaRenderer::OnPlaybackTimeUpdated, weak_this_)); | 122 base::Bind(&CmaRenderer::OnPlaybackTimeUpdated, weak_this_)); |
| 123 media_pipeline_client.pipeline_backend_created_cb = | 123 media_pipeline_client.pipeline_backend_created_cb = |
| 124 base::Bind(&MediaPipelineClientDummyCallback); | 124 base::Bind(&MediaPipelineClientDummyCallback); |
| 125 media_pipeline_client.pipeline_backend_destroyed_cb | 125 media_pipeline_client.pipeline_backend_destroyed_cb = |
| 126 = base::Bind(&MediaPipelineClientDummyCallback); | 126 base::Bind(&MediaPipelineClientDummyCallback); |
| 127 media_pipeline_->SetClient(media_pipeline_client); | 127 media_pipeline_->SetClient(media_pipeline_client); |
| 128 | 128 |
| 129 init_cb_ = init_cb; | 129 init_cb_ = init_cb; |
| 130 InitializeAudioPipeline(); | 130 InitializeAudioPipeline(); |
| 131 } | 131 } |
| 132 | 132 |
| 133 void CmaRenderer::Flush(const base::Closure& flush_cb) { | 133 void CmaRenderer::Flush(const base::Closure& flush_cb) { |
| 134 CMALOG(kLogControl) << __FUNCTION__; | 134 CMALOG(kLogControl) << __FUNCTION__; |
| 135 DCHECK(thread_checker_.CalledOnValidThread()); | 135 DCHECK(thread_checker_.CalledOnValidThread()); |
| 136 BeginStateTransition(); | 136 BeginStateTransition(); |
| 137 | 137 |
| 138 DCHECK(flush_cb_.is_null()); | 138 DCHECK(flush_cb_.is_null()); |
| 139 flush_cb_ = flush_cb; | 139 flush_cb_ = flush_cb; |
| 140 | 140 |
| 141 if (state_ == kError) { | 141 if (state_ == kError) { |
| 142 OnError(::media::PIPELINE_ERROR_ABORT); | 142 OnError(::media::PIPELINE_ERROR_ABORT); |
| 143 return; | 143 return; |
| 144 } | 144 } |
| 145 | 145 |
| 146 DCHECK_EQ(state_, kPlaying) << state_; | 146 DCHECK_EQ(state_, kPlaying) << state_; |
| 147 media_pipeline_->Flush( | 147 media_pipeline_->Flush(::media::BindToCurrentLoop( |
| 148 ::media::BindToCurrentLoop( | 148 base::Bind(&CmaRenderer::OnFlushDone, weak_this_))); |
| 149 base::Bind(&CmaRenderer::OnFlushDone, weak_this_))); | |
| 150 | 149 |
| 151 { | 150 { |
| 152 base::AutoLock auto_lock(time_interpolator_lock_); | 151 base::AutoLock auto_lock(time_interpolator_lock_); |
| 153 time_interpolator_->StopInterpolating(); | 152 time_interpolator_->StopInterpolating(); |
| 154 } | 153 } |
| 155 } | 154 } |
| 156 | 155 |
| 157 void CmaRenderer::StartPlayingFrom(base::TimeDelta time) { | 156 void CmaRenderer::StartPlayingFrom(base::TimeDelta time) { |
| 158 CMALOG(kLogControl) << __FUNCTION__ << ": " << time.InMilliseconds(); | 157 CMALOG(kLogControl) << __FUNCTION__ << ": " << time.InMilliseconds(); |
| 159 DCHECK(thread_checker_.CalledOnValidThread()); | 158 DCHECK(thread_checker_.CalledOnValidThread()); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 | 240 |
| 242 void CmaRenderer::InitializeAudioPipeline() { | 241 void CmaRenderer::InitializeAudioPipeline() { |
| 243 DCHECK(thread_checker_.CalledOnValidThread()); | 242 DCHECK(thread_checker_.CalledOnValidThread()); |
| 244 DCHECK_EQ(state_, kUninitialized) << state_; | 243 DCHECK_EQ(state_, kUninitialized) << state_; |
| 245 DCHECK(!init_cb_.is_null()); | 244 DCHECK(!init_cb_.is_null()); |
| 246 | 245 |
| 247 ::media::DemuxerStream* stream = | 246 ::media::DemuxerStream* stream = |
| 248 demuxer_stream_provider_->GetStream(::media::DemuxerStream::AUDIO); | 247 demuxer_stream_provider_->GetStream(::media::DemuxerStream::AUDIO); |
| 249 ::media::PipelineStatusCB audio_initialization_done_cb = | 248 ::media::PipelineStatusCB audio_initialization_done_cb = |
| 250 ::media::BindToCurrentLoop( | 249 ::media::BindToCurrentLoop( |
| 251 base::Bind(&CmaRenderer::OnAudioPipelineInitializeDone, weak_this_, | 250 base::Bind(&CmaRenderer::OnAudioPipelineInitializeDone, |
| 251 weak_this_, |
| 252 stream != nullptr)); | 252 stream != nullptr)); |
| 253 if (!stream) { | 253 if (!stream) { |
| 254 CMALOG(kLogControl) << __FUNCTION__ << ": no audio stream, skipping init."; | 254 CMALOG(kLogControl) << __FUNCTION__ << ": no audio stream, skipping init."; |
| 255 audio_initialization_done_cb.Run(::media::PIPELINE_OK); | 255 audio_initialization_done_cb.Run(::media::PIPELINE_OK); |
| 256 return; | 256 return; |
| 257 } | 257 } |
| 258 | 258 |
| 259 // Receive events from the audio pipeline. | 259 // Receive events from the audio pipeline. |
| 260 AvPipelineClient av_pipeline_client; | 260 AvPipelineClient av_pipeline_client; |
| 261 av_pipeline_client.eos_cb = ::media::BindToCurrentLoop( | 261 av_pipeline_client.eos_cb = ::media::BindToCurrentLoop( |
| 262 base::Bind(&CmaRenderer::OnEosReached, weak_this_, true)); | 262 base::Bind(&CmaRenderer::OnEosReached, weak_this_, true)); |
| 263 av_pipeline_client.playback_error_cb = ::media::BindToCurrentLoop( | 263 av_pipeline_client.playback_error_cb = |
| 264 base::Bind(&CmaRenderer::OnError, weak_this_)); | 264 ::media::BindToCurrentLoop(base::Bind(&CmaRenderer::OnError, weak_this_)); |
| 265 av_pipeline_client.statistics_cb = ::media::BindToCurrentLoop( | 265 av_pipeline_client.statistics_cb = ::media::BindToCurrentLoop( |
| 266 base::Bind(&CmaRenderer::OnStatisticsUpdated, weak_this_)); | 266 base::Bind(&CmaRenderer::OnStatisticsUpdated, weak_this_)); |
| 267 audio_pipeline_->SetClient(av_pipeline_client); | 267 audio_pipeline_->SetClient(av_pipeline_client); |
| 268 | 268 |
| 269 scoped_ptr<CodedFrameProvider> frame_provider(new DemuxerStreamAdapter( | 269 scoped_ptr<CodedFrameProvider> frame_provider(new DemuxerStreamAdapter( |
| 270 base::ThreadTaskRunnerHandle::Get(), media_task_runner_factory_, stream)); | 270 base::ThreadTaskRunnerHandle::Get(), media_task_runner_factory_, stream)); |
| 271 | 271 |
| 272 const ::media::AudioDecoderConfig& config = stream->audio_decoder_config(); | 272 const ::media::AudioDecoderConfig& config = stream->audio_decoder_config(); |
| 273 if (config.codec() == ::media::kCodecAAC) | 273 if (config.codec() == ::media::kCodecAAC) |
| 274 stream->EnableBitstreamConverter(); | 274 stream->EnableBitstreamConverter(); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 300 | 300 |
| 301 void CmaRenderer::InitializeVideoPipeline() { | 301 void CmaRenderer::InitializeVideoPipeline() { |
| 302 DCHECK(thread_checker_.CalledOnValidThread()); | 302 DCHECK(thread_checker_.CalledOnValidThread()); |
| 303 DCHECK_EQ(state_, kUninitialized) << state_; | 303 DCHECK_EQ(state_, kUninitialized) << state_; |
| 304 DCHECK(!init_cb_.is_null()); | 304 DCHECK(!init_cb_.is_null()); |
| 305 | 305 |
| 306 ::media::DemuxerStream* stream = | 306 ::media::DemuxerStream* stream = |
| 307 demuxer_stream_provider_->GetStream(::media::DemuxerStream::VIDEO); | 307 demuxer_stream_provider_->GetStream(::media::DemuxerStream::VIDEO); |
| 308 ::media::PipelineStatusCB video_initialization_done_cb = | 308 ::media::PipelineStatusCB video_initialization_done_cb = |
| 309 ::media::BindToCurrentLoop( | 309 ::media::BindToCurrentLoop( |
| 310 base::Bind(&CmaRenderer::OnVideoPipelineInitializeDone, weak_this_, | 310 base::Bind(&CmaRenderer::OnVideoPipelineInitializeDone, |
| 311 weak_this_, |
| 311 stream != nullptr)); | 312 stream != nullptr)); |
| 312 if (!stream) { | 313 if (!stream) { |
| 313 CMALOG(kLogControl) << __FUNCTION__ << ": no video stream, skipping init."; | 314 CMALOG(kLogControl) << __FUNCTION__ << ": no video stream, skipping init."; |
| 314 video_initialization_done_cb.Run(::media::PIPELINE_OK); | 315 video_initialization_done_cb.Run(::media::PIPELINE_OK); |
| 315 return; | 316 return; |
| 316 } | 317 } |
| 317 | 318 |
| 318 // Receive events from the video pipeline. | 319 // Receive events from the video pipeline. |
| 319 VideoPipelineClient client; | 320 VideoPipelineClient client; |
| 320 client.av_pipeline_client.eos_cb = ::media::BindToCurrentLoop( | 321 client.av_pipeline_client.eos_cb = ::media::BindToCurrentLoop( |
| 321 base::Bind(&CmaRenderer::OnEosReached, weak_this_, false)); | 322 base::Bind(&CmaRenderer::OnEosReached, weak_this_, false)); |
| 322 client.av_pipeline_client.playback_error_cb = ::media::BindToCurrentLoop( | 323 client.av_pipeline_client.playback_error_cb = |
| 323 base::Bind(&CmaRenderer::OnError, weak_this_)); | 324 ::media::BindToCurrentLoop(base::Bind(&CmaRenderer::OnError, weak_this_)); |
| 324 client.av_pipeline_client.statistics_cb = ::media::BindToCurrentLoop( | 325 client.av_pipeline_client.statistics_cb = ::media::BindToCurrentLoop( |
| 325 base::Bind(&CmaRenderer::OnStatisticsUpdated, weak_this_)); | 326 base::Bind(&CmaRenderer::OnStatisticsUpdated, weak_this_)); |
| 326 client.natural_size_changed_cb = ::media::BindToCurrentLoop( | 327 client.natural_size_changed_cb = ::media::BindToCurrentLoop( |
| 327 base::Bind(&CmaRenderer::OnNaturalSizeChanged, weak_this_)); | 328 base::Bind(&CmaRenderer::OnNaturalSizeChanged, weak_this_)); |
| 328 video_pipeline_->SetClient(client); | 329 video_pipeline_->SetClient(client); |
| 329 | 330 |
| 330 scoped_ptr<CodedFrameProvider> frame_provider(new DemuxerStreamAdapter( | 331 scoped_ptr<CodedFrameProvider> frame_provider(new DemuxerStreamAdapter( |
| 331 base::ThreadTaskRunnerHandle::Get(), media_task_runner_factory_, stream)); | 332 base::ThreadTaskRunnerHandle::Get(), media_task_runner_factory_, stream)); |
| 332 | 333 |
| 333 const ::media::VideoDecoderConfig& config = stream->video_decoder_config(); | 334 const ::media::VideoDecoderConfig& config = stream->video_decoder_config(); |
| 334 if (config.codec() == ::media::kCodecH264) | 335 if (config.codec() == ::media::kCodecH264) |
| 335 stream->EnableBitstreamConverter(); | 336 stream->EnableBitstreamConverter(); |
| 336 | 337 |
| 337 initial_natural_size_ = config.natural_size(); | 338 initial_natural_size_ = config.natural_size(); |
| 338 | 339 |
| 339 std::vector<::media::VideoDecoderConfig> configs; | 340 std::vector<::media::VideoDecoderConfig> configs; |
| 340 configs.push_back(config); | 341 configs.push_back(config); |
| 341 media_pipeline_->InitializeVideo( | 342 media_pipeline_->InitializeVideo( |
| 342 configs, | 343 configs, frame_provider.Pass(), video_initialization_done_cb); |
| 343 frame_provider.Pass(), | |
| 344 video_initialization_done_cb); | |
| 345 } | 344 } |
| 346 | 345 |
| 347 void CmaRenderer::OnVideoPipelineInitializeDone( | 346 void CmaRenderer::OnVideoPipelineInitializeDone( |
| 348 bool video_stream_present, | 347 bool video_stream_present, |
| 349 ::media::PipelineStatus status) { | 348 ::media::PipelineStatus status) { |
| 350 CMALOG(kLogControl) << __FUNCTION__ << ": state=" << state_; | 349 CMALOG(kLogControl) << __FUNCTION__ << ": state=" << state_; |
| 351 DCHECK(thread_checker_.CalledOnValidThread()); | 350 DCHECK(thread_checker_.CalledOnValidThread()); |
| 352 | 351 |
| 353 // OnError() may be fired at any time, even before initialization is complete. | 352 // OnError() may be fired at any time, even before initialization is complete. |
| 354 if (state_ == kError) | 353 if (state_ == kError) |
| (...skipping 21 matching lines...) Expand all Loading... |
| 376 if (is_audio) { | 375 if (is_audio) { |
| 377 DCHECK(!received_audio_eos_); | 376 DCHECK(!received_audio_eos_); |
| 378 received_audio_eos_ = true; | 377 received_audio_eos_ = true; |
| 379 } else { | 378 } else { |
| 380 DCHECK(!received_video_eos_); | 379 DCHECK(!received_video_eos_); |
| 381 received_video_eos_ = true; | 380 received_video_eos_ = true; |
| 382 } | 381 } |
| 383 | 382 |
| 384 bool audio_finished = !has_audio_ || received_audio_eos_; | 383 bool audio_finished = !has_audio_ || received_audio_eos_; |
| 385 bool video_finished = !has_video_ || received_video_eos_; | 384 bool video_finished = !has_video_ || received_video_eos_; |
| 386 CMALOG(kLogControl) << __FUNCTION__ | 385 CMALOG(kLogControl) << __FUNCTION__ << " audio_finished=" << audio_finished |
| 387 << " audio_finished=" << audio_finished | |
| 388 << " video_finished=" << video_finished; | 386 << " video_finished=" << video_finished; |
| 389 if (audio_finished && video_finished) | 387 if (audio_finished && video_finished) |
| 390 ended_cb_.Run(); | 388 ended_cb_.Run(); |
| 391 } | 389 } |
| 392 | 390 |
| 393 void CmaRenderer::OnStatisticsUpdated( | 391 void CmaRenderer::OnStatisticsUpdated( |
| 394 const ::media::PipelineStatistics& stats) { | 392 const ::media::PipelineStatistics& stats) { |
| 395 DCHECK(thread_checker_.CalledOnValidThread()); | 393 DCHECK(thread_checker_.CalledOnValidThread()); |
| 396 statistics_cb_.Run(stats); | 394 statistics_cb_.Run(stats); |
| 397 } | 395 } |
| 398 | 396 |
| 399 void CmaRenderer::OnNaturalSizeChanged(const gfx::Size& size) { | 397 void CmaRenderer::OnNaturalSizeChanged(const gfx::Size& size) { |
| 400 DCHECK(thread_checker_.CalledOnValidThread()); | 398 DCHECK(thread_checker_.CalledOnValidThread()); |
| 401 video_renderer_sink_->PaintFrameUsingOldRenderingPath( | 399 video_renderer_sink_->PaintFrameUsingOldRenderingPath( |
| 402 hole_frame_factory_->CreateHoleFrame(size)); | 400 hole_frame_factory_->CreateHoleFrame(size)); |
| 403 } | 401 } |
| 404 | 402 |
| 405 void CmaRenderer::OnPlaybackTimeUpdated( | 403 void CmaRenderer::OnPlaybackTimeUpdated(base::TimeDelta time, |
| 406 base::TimeDelta time, | 404 base::TimeDelta max_time, |
| 407 base::TimeDelta max_time, | 405 base::TimeTicks capture_time) { |
| 408 base::TimeTicks capture_time) { | |
| 409 DCHECK(thread_checker_.CalledOnValidThread()); | 406 DCHECK(thread_checker_.CalledOnValidThread()); |
| 410 if (state_ != kPlaying) { | 407 if (state_ != kPlaying) { |
| 411 LOG(WARNING) << "Ignoring a late time update"; | 408 LOG(WARNING) << "Ignoring a late time update"; |
| 412 return; | 409 return; |
| 413 } | 410 } |
| 414 | 411 |
| 415 // TODO(halliwell): arguably, TimeDeltaInterpolator::SetBounds should perform | 412 // TODO(halliwell): arguably, TimeDeltaInterpolator::SetBounds should perform |
| 416 // this calculation to avoid calling TimeTicks::Now twice (it's slower and has | 413 // this calculation to avoid calling TimeTicks::Now twice (it's slower and has |
| 417 // potential accuracy problems). | 414 // potential accuracy problems). |
| 418 base::TimeDelta lower_bound = | 415 base::TimeDelta lower_bound = |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 477 is_pending_transition_ = true; | 474 is_pending_transition_ = true; |
| 478 } | 475 } |
| 479 | 476 |
| 480 void CmaRenderer::CompleteStateTransition(State new_state) { | 477 void CmaRenderer::CompleteStateTransition(State new_state) { |
| 481 state_ = new_state; | 478 state_ = new_state; |
| 482 is_pending_transition_ = false; | 479 is_pending_transition_ = false; |
| 483 } | 480 } |
| 484 | 481 |
| 485 } // namespace media | 482 } // namespace media |
| 486 } // namespace chromecast | 483 } // namespace chromecast |
| OLD | NEW |