| 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/media/cma/filters/cma_renderer.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_to_current_loop.h" |
| 8 #include "base/callback_helpers.h" | 9 #include "base/callback_helpers.h" |
| 9 #include "base/location.h" | 10 #include "base/location.h" |
| 10 #include "base/message_loop/message_loop_proxy.h" | 11 #include "base/message_loop/message_loop_proxy.h" |
| 11 #include "chromecast/media/cma/base/balanced_media_task_runner_factory.h" | 12 #include "chromecast/media/cma/base/balanced_media_task_runner_factory.h" |
| 12 #include "chromecast/media/cma/base/cma_logging.h" | 13 #include "chromecast/media/cma/base/cma_logging.h" |
| 13 #include "chromecast/media/cma/filters/demuxer_stream_adapter.h" | 14 #include "chromecast/media/cma/filters/demuxer_stream_adapter.h" |
| 14 #include "chromecast/media/cma/pipeline/audio_pipeline.h" | 15 #include "chromecast/media/cma/pipeline/audio_pipeline.h" |
| 15 #include "chromecast/media/cma/pipeline/av_pipeline_client.h" | 16 #include "chromecast/media/cma/pipeline/av_pipeline_client.h" |
| 16 #include "chromecast/media/cma/pipeline/media_pipeline.h" | 17 #include "chromecast/media/cma/pipeline/media_pipeline.h" |
| 17 #include "chromecast/media/cma/pipeline/media_pipeline_client.h" | 18 #include "chromecast/media/cma/pipeline/media_pipeline_client.h" |
| 18 #include "chromecast/media/cma/pipeline/video_pipeline.h" | 19 #include "chromecast/media/cma/pipeline/video_pipeline.h" |
| 19 #include "chromecast/media/cma/pipeline/video_pipeline_client.h" | 20 #include "chromecast/media/cma/pipeline/video_pipeline_client.h" |
| 20 #include "media/base/bind_to_current_loop.h" | |
| 21 #include "media/base/demuxer_stream_provider.h" | 21 #include "media/base/demuxer_stream_provider.h" |
| 22 #include "media/base/pipeline_status.h" | 22 #include "media/base/pipeline_status.h" |
| 23 #include "media/base/time_delta_interpolator.h" | 23 #include "media/base/time_delta_interpolator.h" |
| 24 #include "media/base/video_frame.h" | 24 #include "media/base/video_frame.h" |
| 25 #include "media/base/video_renderer_sink.h" | 25 #include "media/base/video_renderer_sink.h" |
| 26 #include "ui/gfx/geometry/size.h" | 26 #include "ui/gfx/geometry/size.h" |
| 27 | 27 |
| 28 namespace chromecast { | 28 namespace chromecast { |
| 29 namespace media { | 29 namespace media { |
| 30 | 30 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 demuxer_stream_provider_ = demuxer_stream_provider; | 99 demuxer_stream_provider_ = demuxer_stream_provider; |
| 100 statistics_cb_ = statistics_cb; | 100 statistics_cb_ = statistics_cb; |
| 101 buffering_state_cb_ = buffering_state_cb; | 101 buffering_state_cb_ = buffering_state_cb; |
| 102 ended_cb_ = ended_cb; | 102 ended_cb_ = ended_cb; |
| 103 error_cb_ = error_cb; | 103 error_cb_ = error_cb; |
| 104 // TODO(erickung): wire up waiting_for_decryption_key_cb. | 104 // TODO(erickung): wire up waiting_for_decryption_key_cb. |
| 105 waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb; | 105 waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb; |
| 106 | 106 |
| 107 MediaPipelineClient media_pipeline_client; | 107 MediaPipelineClient media_pipeline_client; |
| 108 media_pipeline_client.error_cb = error_cb_; | 108 media_pipeline_client.error_cb = error_cb_; |
| 109 media_pipeline_client.buffering_state_cb = ::media::BindToCurrentLoop( | 109 media_pipeline_client.buffering_state_cb = base::BindToCurrentLoop( |
| 110 base::Bind(&CmaRenderer::OnBufferingNotification, weak_this_)); | 110 base::Bind(&CmaRenderer::OnBufferingNotification, weak_this_)); |
| 111 media_pipeline_client.time_update_cb = ::media::BindToCurrentLoop( | 111 media_pipeline_client.time_update_cb = base::BindToCurrentLoop( |
| 112 base::Bind(&CmaRenderer::OnPlaybackTimeUpdated, weak_this_)); | 112 base::Bind(&CmaRenderer::OnPlaybackTimeUpdated, weak_this_)); |
| 113 media_pipeline_->SetClient(media_pipeline_client); | 113 media_pipeline_->SetClient(media_pipeline_client); |
| 114 | 114 |
| 115 init_cb_ = init_cb; | 115 init_cb_ = init_cb; |
| 116 InitializeAudioPipeline(); | 116 InitializeAudioPipeline(); |
| 117 } | 117 } |
| 118 | 118 |
| 119 void CmaRenderer::Flush(const base::Closure& flush_cb) { | 119 void CmaRenderer::Flush(const base::Closure& flush_cb) { |
| 120 CMALOG(kLogControl) << __FUNCTION__; | 120 CMALOG(kLogControl) << __FUNCTION__; |
| 121 DCHECK(thread_checker_.CalledOnValidThread()); | 121 DCHECK(thread_checker_.CalledOnValidThread()); |
| 122 BeginStateTransition(); | 122 BeginStateTransition(); |
| 123 | 123 |
| 124 DCHECK(flush_cb_.is_null()); | 124 DCHECK(flush_cb_.is_null()); |
| 125 flush_cb_ = flush_cb; | 125 flush_cb_ = flush_cb; |
| 126 | 126 |
| 127 if (state_ == kError) { | 127 if (state_ == kError) { |
| 128 OnError(::media::PIPELINE_ERROR_ABORT); | 128 OnError(::media::PIPELINE_ERROR_ABORT); |
| 129 return; | 129 return; |
| 130 } | 130 } |
| 131 | 131 |
| 132 DCHECK_EQ(state_, kPlaying) << state_; | 132 DCHECK_EQ(state_, kPlaying) << state_; |
| 133 media_pipeline_->Flush( | 133 media_pipeline_->Flush( |
| 134 ::media::BindToCurrentLoop( | 134 base::BindToCurrentLoop( |
| 135 base::Bind(&CmaRenderer::OnFlushDone, weak_this_))); | 135 base::Bind(&CmaRenderer::OnFlushDone, weak_this_))); |
| 136 | 136 |
| 137 { | 137 { |
| 138 base::AutoLock auto_lock(time_interpolator_lock_); | 138 base::AutoLock auto_lock(time_interpolator_lock_); |
| 139 time_interpolator_->StopInterpolating(); | 139 time_interpolator_->StopInterpolating(); |
| 140 } | 140 } |
| 141 } | 141 } |
| 142 | 142 |
| 143 void CmaRenderer::StartPlayingFrom(base::TimeDelta time) { | 143 void CmaRenderer::StartPlayingFrom(base::TimeDelta time) { |
| 144 CMALOG(kLogControl) << __FUNCTION__ << ": " << time.InMilliseconds(); | 144 CMALOG(kLogControl) << __FUNCTION__ << ": " << time.InMilliseconds(); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 #endif | 226 #endif |
| 227 cdm_attached_cb.Run(true); | 227 cdm_attached_cb.Run(true); |
| 228 } | 228 } |
| 229 | 229 |
| 230 void CmaRenderer::InitializeAudioPipeline() { | 230 void CmaRenderer::InitializeAudioPipeline() { |
| 231 DCHECK(thread_checker_.CalledOnValidThread()); | 231 DCHECK(thread_checker_.CalledOnValidThread()); |
| 232 DCHECK_EQ(state_, kUninitialized) << state_; | 232 DCHECK_EQ(state_, kUninitialized) << state_; |
| 233 DCHECK(!init_cb_.is_null()); | 233 DCHECK(!init_cb_.is_null()); |
| 234 | 234 |
| 235 ::media::PipelineStatusCB audio_initialization_done_cb = | 235 ::media::PipelineStatusCB audio_initialization_done_cb = |
| 236 ::media::BindToCurrentLoop( | 236 base::BindToCurrentLoop( |
| 237 base::Bind(&CmaRenderer::OnAudioPipelineInitializeDone, weak_this_)); | 237 base::Bind(&CmaRenderer::OnAudioPipelineInitializeDone, weak_this_)); |
| 238 | 238 |
| 239 ::media::DemuxerStream* stream = | 239 ::media::DemuxerStream* stream = |
| 240 demuxer_stream_provider_->GetStream(::media::DemuxerStream::AUDIO); | 240 demuxer_stream_provider_->GetStream(::media::DemuxerStream::AUDIO); |
| 241 if (!stream) { | 241 if (!stream) { |
| 242 audio_initialization_done_cb.Run(::media::PIPELINE_OK); | 242 audio_initialization_done_cb.Run(::media::PIPELINE_OK); |
| 243 return; | 243 return; |
| 244 } | 244 } |
| 245 | 245 |
| 246 // Receive events from the audio pipeline. | 246 // Receive events from the audio pipeline. |
| 247 AvPipelineClient av_pipeline_client; | 247 AvPipelineClient av_pipeline_client; |
| 248 av_pipeline_client.eos_cb = ::media::BindToCurrentLoop( | 248 av_pipeline_client.eos_cb = base::BindToCurrentLoop( |
| 249 base::Bind(&CmaRenderer::OnEosReached, weak_this_, true)); | 249 base::Bind(&CmaRenderer::OnEosReached, weak_this_, true)); |
| 250 av_pipeline_client.playback_error_cb = ::media::BindToCurrentLoop( | 250 av_pipeline_client.playback_error_cb = base::BindToCurrentLoop( |
| 251 base::Bind(&CmaRenderer::OnError, weak_this_)); | 251 base::Bind(&CmaRenderer::OnError, weak_this_)); |
| 252 av_pipeline_client.statistics_cb = ::media::BindToCurrentLoop( | 252 av_pipeline_client.statistics_cb = base::BindToCurrentLoop( |
| 253 base::Bind(&CmaRenderer::OnStatisticsUpdated, weak_this_)); | 253 base::Bind(&CmaRenderer::OnStatisticsUpdated, weak_this_)); |
| 254 audio_pipeline_->SetClient(av_pipeline_client); | 254 audio_pipeline_->SetClient(av_pipeline_client); |
| 255 | 255 |
| 256 scoped_ptr<CodedFrameProvider> frame_provider( | 256 scoped_ptr<CodedFrameProvider> frame_provider( |
| 257 new DemuxerStreamAdapter( | 257 new DemuxerStreamAdapter( |
| 258 base::MessageLoopProxy::current(), | 258 base::MessageLoopProxy::current(), |
| 259 media_task_runner_factory_, | 259 media_task_runner_factory_, |
| 260 stream)); | 260 stream)); |
| 261 | 261 |
| 262 const ::media::AudioDecoderConfig& config = stream->audio_decoder_config(); | 262 const ::media::AudioDecoderConfig& config = stream->audio_decoder_config(); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 286 | 286 |
| 287 InitializeVideoPipeline(); | 287 InitializeVideoPipeline(); |
| 288 } | 288 } |
| 289 | 289 |
| 290 void CmaRenderer::InitializeVideoPipeline() { | 290 void CmaRenderer::InitializeVideoPipeline() { |
| 291 DCHECK(thread_checker_.CalledOnValidThread()); | 291 DCHECK(thread_checker_.CalledOnValidThread()); |
| 292 DCHECK_EQ(state_, kUninitialized) << state_; | 292 DCHECK_EQ(state_, kUninitialized) << state_; |
| 293 DCHECK(!init_cb_.is_null()); | 293 DCHECK(!init_cb_.is_null()); |
| 294 | 294 |
| 295 ::media::PipelineStatusCB video_initialization_done_cb = | 295 ::media::PipelineStatusCB video_initialization_done_cb = |
| 296 ::media::BindToCurrentLoop( | 296 base::BindToCurrentLoop( |
| 297 base::Bind(&CmaRenderer::OnVideoPipelineInitializeDone, weak_this_)); | 297 base::Bind(&CmaRenderer::OnVideoPipelineInitializeDone, weak_this_)); |
| 298 | 298 |
| 299 ::media::DemuxerStream* stream = | 299 ::media::DemuxerStream* stream = |
| 300 demuxer_stream_provider_->GetStream(::media::DemuxerStream::VIDEO); | 300 demuxer_stream_provider_->GetStream(::media::DemuxerStream::VIDEO); |
| 301 if (!stream) { | 301 if (!stream) { |
| 302 video_initialization_done_cb.Run(::media::PIPELINE_OK); | 302 video_initialization_done_cb.Run(::media::PIPELINE_OK); |
| 303 return; | 303 return; |
| 304 } | 304 } |
| 305 | 305 |
| 306 // Receive events from the video pipeline. | 306 // Receive events from the video pipeline. |
| 307 VideoPipelineClient client; | 307 VideoPipelineClient client; |
| 308 client.av_pipeline_client.eos_cb = ::media::BindToCurrentLoop( | 308 client.av_pipeline_client.eos_cb = base::BindToCurrentLoop( |
| 309 base::Bind(&CmaRenderer::OnEosReached, weak_this_, false)); | 309 base::Bind(&CmaRenderer::OnEosReached, weak_this_, false)); |
| 310 client.av_pipeline_client.playback_error_cb = ::media::BindToCurrentLoop( | 310 client.av_pipeline_client.playback_error_cb = base::BindToCurrentLoop( |
| 311 base::Bind(&CmaRenderer::OnError, weak_this_)); | 311 base::Bind(&CmaRenderer::OnError, weak_this_)); |
| 312 client.av_pipeline_client.statistics_cb = ::media::BindToCurrentLoop( | 312 client.av_pipeline_client.statistics_cb = base::BindToCurrentLoop( |
| 313 base::Bind(&CmaRenderer::OnStatisticsUpdated, weak_this_)); | 313 base::Bind(&CmaRenderer::OnStatisticsUpdated, weak_this_)); |
| 314 client.natural_size_changed_cb = ::media::BindToCurrentLoop( | 314 client.natural_size_changed_cb = base::BindToCurrentLoop( |
| 315 base::Bind(&CmaRenderer::OnNaturalSizeChanged, weak_this_)); | 315 base::Bind(&CmaRenderer::OnNaturalSizeChanged, weak_this_)); |
| 316 video_pipeline_->SetClient(client); | 316 video_pipeline_->SetClient(client); |
| 317 | 317 |
| 318 scoped_ptr<CodedFrameProvider> frame_provider( | 318 scoped_ptr<CodedFrameProvider> frame_provider( |
| 319 new DemuxerStreamAdapter( | 319 new DemuxerStreamAdapter( |
| 320 base::MessageLoopProxy::current(), | 320 base::MessageLoopProxy::current(), |
| 321 media_task_runner_factory_, | 321 media_task_runner_factory_, |
| 322 stream)); | 322 stream)); |
| 323 | 323 |
| 324 const ::media::VideoDecoderConfig& config = stream->video_decoder_config(); | 324 const ::media::VideoDecoderConfig& config = stream->video_decoder_config(); |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 is_pending_transition_ = true; | 465 is_pending_transition_ = true; |
| 466 } | 466 } |
| 467 | 467 |
| 468 void CmaRenderer::CompleteStateTransition(State new_state) { | 468 void CmaRenderer::CompleteStateTransition(State new_state) { |
| 469 state_ = new_state; | 469 state_ = new_state; |
| 470 is_pending_transition_ = false; | 470 is_pending_transition_ = false; |
| 471 } | 471 } |
| 472 | 472 |
| 473 } // namespace media | 473 } // namespace media |
| 474 } // namespace chromecast | 474 } // namespace chromecast |
| OLD | NEW |