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 |