| 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/browser/media/cma_message_filter_host.h" | 5 #include "chromecast/browser/media/cma_message_filter_host.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind_to_current_loop.h" |
| 9 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| 10 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
| 11 #include "base/memory/shared_memory.h" | 12 #include "base/memory/shared_memory.h" |
| 12 #include "base/sync_socket.h" | 13 #include "base/sync_socket.h" |
| 13 #include "chromecast/browser/media/cma_message_loop.h" | 14 #include "chromecast/browser/media/cma_message_loop.h" |
| 14 #include "chromecast/browser/media/media_pipeline_host.h" | 15 #include "chromecast/browser/media/media_pipeline_host.h" |
| 15 #include "chromecast/common/media/cma_messages.h" | 16 #include "chromecast/common/media/cma_messages.h" |
| 16 #include "chromecast/media/cdm/browser_cdm_cast.h" | 17 #include "chromecast/media/cdm/browser_cdm_cast.h" |
| 17 #include "chromecast/media/cma/backend/video_plane.h" | 18 #include "chromecast/media/cma/backend/video_plane.h" |
| 18 #include "chromecast/media/cma/pipeline/av_pipeline_client.h" | 19 #include "chromecast/media/cma/pipeline/av_pipeline_client.h" |
| 19 #include "chromecast/media/cma/pipeline/media_pipeline_client.h" | 20 #include "chromecast/media/cma/pipeline/media_pipeline_client.h" |
| 20 #include "chromecast/media/cma/pipeline/video_pipeline_client.h" | 21 #include "chromecast/media/cma/pipeline/video_pipeline_client.h" |
| 21 #include "content/public/browser/browser_thread.h" | 22 #include "content/public/browser/browser_thread.h" |
| 22 #include "content/public/browser/render_process_host.h" | 23 #include "content/public/browser/render_process_host.h" |
| 23 #include "media/base/bind_to_current_loop.h" | |
| 24 #include "ui/gfx/geometry/point_f.h" | 24 #include "ui/gfx/geometry/point_f.h" |
| 25 #include "ui/gfx/geometry/quad_f.h" | 25 #include "ui/gfx/geometry/quad_f.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 |
| 31 #define FORWARD_CALL(arg_pipeline, arg_fn, ...) \ | 31 #define FORWARD_CALL(arg_pipeline, arg_fn, ...) \ |
| 32 task_runner_->PostTask( \ | 32 task_runner_->PostTask( \ |
| 33 FROM_HERE, \ | 33 FROM_HERE, \ |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 } | 203 } |
| 204 | 204 |
| 205 | 205 |
| 206 // *** Handle incoming messages *** | 206 // *** Handle incoming messages *** |
| 207 | 207 |
| 208 void CmaMessageFilterHost::CreateMedia(int media_id, LoadType load_type) { | 208 void CmaMessageFilterHost::CreateMedia(int media_id, LoadType load_type) { |
| 209 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 209 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 210 | 210 |
| 211 scoped_ptr<MediaPipelineHost> media_pipeline_host(new MediaPipelineHost()); | 211 scoped_ptr<MediaPipelineHost> media_pipeline_host(new MediaPipelineHost()); |
| 212 MediaPipelineClient client; | 212 MediaPipelineClient client; |
| 213 client.time_update_cb = ::media::BindToCurrentLoop(base::Bind( | 213 client.time_update_cb = base::BindToCurrentLoop(base::Bind( |
| 214 &CmaMessageFilterHost::OnTimeUpdate, weak_this_, media_id)); | 214 &CmaMessageFilterHost::OnTimeUpdate, weak_this_, media_id)); |
| 215 client.buffering_state_cb = ::media::BindToCurrentLoop(base::Bind( | 215 client.buffering_state_cb = base::BindToCurrentLoop(base::Bind( |
| 216 &CmaMessageFilterHost::OnBufferingNotification, weak_this_, media_id)); | 216 &CmaMessageFilterHost::OnBufferingNotification, weak_this_, media_id)); |
| 217 client.error_cb = ::media::BindToCurrentLoop( | 217 client.error_cb = base::BindToCurrentLoop( |
| 218 base::Bind(&CmaMessageFilterHost::OnPlaybackError, | 218 base::Bind(&CmaMessageFilterHost::OnPlaybackError, |
| 219 weak_this_, media_id, media::kNoTrackId)); | 219 weak_this_, media_id, media::kNoTrackId)); |
| 220 task_runner_->PostTask( | 220 task_runner_->PostTask( |
| 221 FROM_HERE, | 221 FROM_HERE, |
| 222 base::Bind(&SetMediaPipeline, | 222 base::Bind(&SetMediaPipeline, |
| 223 process_id_, media_id, media_pipeline_host.get())); | 223 process_id_, media_id, media_pipeline_host.get())); |
| 224 task_runner_->PostTask( | 224 task_runner_->PostTask( |
| 225 FROM_HERE, | 225 FROM_HERE, |
| 226 base::Bind(&MediaPipelineHost::Initialize, | 226 base::Bind(&MediaPipelineHost::Initialize, |
| 227 base::Unretained(media_pipeline_host.get()), | 227 base::Unretained(media_pipeline_host.get()), |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 foreign_memory_handle, foreign_socket_handle)); | 305 foreign_memory_handle, foreign_socket_handle)); |
| 306 return; | 306 return; |
| 307 } | 307 } |
| 308 | 308 |
| 309 // Note: the IPC message can be sent only once the pipe has been fully | 309 // Note: the IPC message can be sent only once the pipe has been fully |
| 310 // configured. Part of this configuration is done in | 310 // configured. Part of this configuration is done in |
| 311 // |MediaPipelineHost::SetAvPipe|. | 311 // |MediaPipelineHost::SetAvPipe|. |
| 312 // TODO(erickung): investigate possible memory leak here. | 312 // TODO(erickung): investigate possible memory leak here. |
| 313 // If the weak pointer in |av_pipe_set_cb| gets invalidated, | 313 // If the weak pointer in |av_pipe_set_cb| gets invalidated, |
| 314 // then |foreign_memory_handle| leaks. | 314 // then |foreign_memory_handle| leaks. |
| 315 base::Closure pipe_read_activity_cb = ::media::BindToCurrentLoop( | 315 base::Closure pipe_read_activity_cb = base::BindToCurrentLoop( |
| 316 base::Bind(&CmaMessageFilterHost::OnPipeReadActivity, weak_this_, | 316 base::Bind(&CmaMessageFilterHost::OnPipeReadActivity, weak_this_, |
| 317 media_id, track_id)); | 317 media_id, track_id)); |
| 318 base::Closure av_pipe_set_cb = ::media::BindToCurrentLoop( | 318 base::Closure av_pipe_set_cb = base::BindToCurrentLoop( |
| 319 base::Bind(&CmaMessageFilterHost::OnAvPipeSet, weak_this_, | 319 base::Bind(&CmaMessageFilterHost::OnAvPipeSet, weak_this_, |
| 320 media_id, track_id, | 320 media_id, track_id, |
| 321 foreign_memory_handle, base::Passed(&foreign_socket))); | 321 foreign_memory_handle, base::Passed(&foreign_socket))); |
| 322 task_runner_->PostTask( | 322 task_runner_->PostTask( |
| 323 FROM_HERE, | 323 FROM_HERE, |
| 324 base::Bind(&MediaPipelineHost::SetAvPipe, | 324 base::Bind(&MediaPipelineHost::SetAvPipe, |
| 325 base::Unretained(media_pipeline), | 325 base::Unretained(media_pipeline), |
| 326 track_id, | 326 track_id, |
| 327 base::Passed(&shared_memory), | 327 base::Passed(&shared_memory), |
| 328 pipe_read_activity_cb, | 328 pipe_read_activity_cb, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 348 int media_id, TrackId track_id, const ::media::AudioDecoderConfig& config) { | 348 int media_id, TrackId track_id, const ::media::AudioDecoderConfig& config) { |
| 349 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 349 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 350 MediaPipelineHost* media_pipeline = LookupById(media_id); | 350 MediaPipelineHost* media_pipeline = LookupById(media_id); |
| 351 if (!media_pipeline) { | 351 if (!media_pipeline) { |
| 352 Send(new CmaMsg_TrackStateChanged( | 352 Send(new CmaMsg_TrackStateChanged( |
| 353 media_id, track_id, ::media::PIPELINE_ERROR_ABORT)); | 353 media_id, track_id, ::media::PIPELINE_ERROR_ABORT)); |
| 354 return; | 354 return; |
| 355 } | 355 } |
| 356 | 356 |
| 357 AvPipelineClient client; | 357 AvPipelineClient client; |
| 358 client.eos_cb = ::media::BindToCurrentLoop(base::Bind( | 358 client.eos_cb = base::BindToCurrentLoop(base::Bind( |
| 359 &CmaMessageFilterHost::OnEos, weak_this_, media_id, track_id)); | 359 &CmaMessageFilterHost::OnEos, weak_this_, media_id, track_id)); |
| 360 client.playback_error_cb = ::media::BindToCurrentLoop(base::Bind( | 360 client.playback_error_cb = base::BindToCurrentLoop(base::Bind( |
| 361 &CmaMessageFilterHost::OnPlaybackError, weak_this_, media_id, track_id)); | 361 &CmaMessageFilterHost::OnPlaybackError, weak_this_, media_id, track_id)); |
| 362 client.statistics_cb = ::media::BindToCurrentLoop( | 362 client.statistics_cb = base::BindToCurrentLoop( |
| 363 base::Bind(&CmaMessageFilterHost::OnStatisticsUpdated, weak_this_, | 363 base::Bind(&CmaMessageFilterHost::OnStatisticsUpdated, weak_this_, |
| 364 media_id, track_id)); | 364 media_id, track_id)); |
| 365 | 365 |
| 366 ::media::PipelineStatusCB pipeline_status_cb = ::media::BindToCurrentLoop( | 366 ::media::PipelineStatusCB pipeline_status_cb = base::BindToCurrentLoop( |
| 367 base::Bind(&CmaMessageFilterHost::OnTrackStateChanged, weak_this_, | 367 base::Bind(&CmaMessageFilterHost::OnTrackStateChanged, weak_this_, |
| 368 media_id, track_id)); | 368 media_id, track_id)); |
| 369 task_runner_->PostTask( | 369 task_runner_->PostTask( |
| 370 FROM_HERE, | 370 FROM_HERE, |
| 371 base::Bind(&MediaPipelineHost::AudioInitialize, | 371 base::Bind(&MediaPipelineHost::AudioInitialize, |
| 372 base::Unretained(media_pipeline), | 372 base::Unretained(media_pipeline), |
| 373 track_id, client, config, pipeline_status_cb)); | 373 track_id, client, config, pipeline_status_cb)); |
| 374 } | 374 } |
| 375 | 375 |
| 376 void CmaMessageFilterHost::VideoInitialize( | 376 void CmaMessageFilterHost::VideoInitialize( |
| 377 int media_id, TrackId track_id, const ::media::VideoDecoderConfig& config) { | 377 int media_id, TrackId track_id, const ::media::VideoDecoderConfig& config) { |
| 378 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 378 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 379 MediaPipelineHost* media_pipeline = LookupById(media_id); | 379 MediaPipelineHost* media_pipeline = LookupById(media_id); |
| 380 if (!media_pipeline) { | 380 if (!media_pipeline) { |
| 381 Send(new CmaMsg_TrackStateChanged( | 381 Send(new CmaMsg_TrackStateChanged( |
| 382 media_id, track_id, ::media::PIPELINE_ERROR_ABORT)); | 382 media_id, track_id, ::media::PIPELINE_ERROR_ABORT)); |
| 383 return; | 383 return; |
| 384 } | 384 } |
| 385 | 385 |
| 386 VideoPipelineClient client; | 386 VideoPipelineClient client; |
| 387 client.av_pipeline_client.eos_cb = ::media::BindToCurrentLoop( | 387 client.av_pipeline_client.eos_cb = base::BindToCurrentLoop( |
| 388 base::Bind(&CmaMessageFilterHost::OnEos, weak_this_, | 388 base::Bind(&CmaMessageFilterHost::OnEos, weak_this_, |
| 389 media_id, track_id)); | 389 media_id, track_id)); |
| 390 client.av_pipeline_client.playback_error_cb = ::media::BindToCurrentLoop( | 390 client.av_pipeline_client.playback_error_cb = base::BindToCurrentLoop( |
| 391 base::Bind(&CmaMessageFilterHost::OnPlaybackError, weak_this_, | 391 base::Bind(&CmaMessageFilterHost::OnPlaybackError, weak_this_, |
| 392 media_id, track_id)); | 392 media_id, track_id)); |
| 393 client.av_pipeline_client.statistics_cb = ::media::BindToCurrentLoop( | 393 client.av_pipeline_client.statistics_cb = base::BindToCurrentLoop( |
| 394 base::Bind(&CmaMessageFilterHost::OnStatisticsUpdated, weak_this_, | 394 base::Bind(&CmaMessageFilterHost::OnStatisticsUpdated, weak_this_, |
| 395 media_id, track_id)); | 395 media_id, track_id)); |
| 396 client.natural_size_changed_cb = ::media::BindToCurrentLoop( | 396 client.natural_size_changed_cb = base::BindToCurrentLoop( |
| 397 base::Bind(&CmaMessageFilterHost::OnNaturalSizeChanged, weak_this_, | 397 base::Bind(&CmaMessageFilterHost::OnNaturalSizeChanged, weak_this_, |
| 398 media_id, track_id)); | 398 media_id, track_id)); |
| 399 | 399 |
| 400 ::media::PipelineStatusCB pipeline_status_cb = ::media::BindToCurrentLoop( | 400 ::media::PipelineStatusCB pipeline_status_cb = base::BindToCurrentLoop( |
| 401 base::Bind(&CmaMessageFilterHost::OnTrackStateChanged, weak_this_, | 401 base::Bind(&CmaMessageFilterHost::OnTrackStateChanged, weak_this_, |
| 402 media_id, track_id)); | 402 media_id, track_id)); |
| 403 task_runner_->PostTask( | 403 task_runner_->PostTask( |
| 404 FROM_HERE, | 404 FROM_HERE, |
| 405 base::Bind(&MediaPipelineHost::VideoInitialize, | 405 base::Bind(&MediaPipelineHost::VideoInitialize, |
| 406 base::Unretained(media_pipeline), | 406 base::Unretained(media_pipeline), |
| 407 track_id, client, config, pipeline_status_cb)); | 407 track_id, client, config, pipeline_status_cb)); |
| 408 } | 408 } |
| 409 | 409 |
| 410 void CmaMessageFilterHost::StartPlayingFrom( | 410 void CmaMessageFilterHost::StartPlayingFrom( |
| 411 int media_id, base::TimeDelta time) { | 411 int media_id, base::TimeDelta time) { |
| 412 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 412 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 413 MediaPipelineHost* media_pipeline = LookupById(media_id); | 413 MediaPipelineHost* media_pipeline = LookupById(media_id); |
| 414 if (!media_pipeline) | 414 if (!media_pipeline) |
| 415 return; | 415 return; |
| 416 FORWARD_CALL(media_pipeline, StartPlayingFrom, time); | 416 FORWARD_CALL(media_pipeline, StartPlayingFrom, time); |
| 417 } | 417 } |
| 418 | 418 |
| 419 void CmaMessageFilterHost::Flush(int media_id) { | 419 void CmaMessageFilterHost::Flush(int media_id) { |
| 420 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 420 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 421 MediaPipelineHost* media_pipeline = LookupById(media_id); | 421 MediaPipelineHost* media_pipeline = LookupById(media_id); |
| 422 if (!media_pipeline) { | 422 if (!media_pipeline) { |
| 423 Send(new CmaMsg_MediaStateChanged( | 423 Send(new CmaMsg_MediaStateChanged( |
| 424 media_id, ::media::PIPELINE_ERROR_ABORT)); | 424 media_id, ::media::PIPELINE_ERROR_ABORT)); |
| 425 return; | 425 return; |
| 426 } | 426 } |
| 427 ::media::PipelineStatusCB pipeline_status_cb = ::media::BindToCurrentLoop( | 427 ::media::PipelineStatusCB pipeline_status_cb = base::BindToCurrentLoop( |
| 428 base::Bind(&CmaMessageFilterHost::OnMediaStateChanged, weak_this_, | 428 base::Bind(&CmaMessageFilterHost::OnMediaStateChanged, weak_this_, |
| 429 media_id)); | 429 media_id)); |
| 430 FORWARD_CALL(media_pipeline, Flush, pipeline_status_cb); | 430 FORWARD_CALL(media_pipeline, Flush, pipeline_status_cb); |
| 431 } | 431 } |
| 432 | 432 |
| 433 void CmaMessageFilterHost::Stop(int media_id) { | 433 void CmaMessageFilterHost::Stop(int media_id) { |
| 434 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 434 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 435 MediaPipelineHost* media_pipeline = LookupById(media_id); | 435 MediaPipelineHost* media_pipeline = LookupById(media_id); |
| 436 if (!media_pipeline) | 436 if (!media_pipeline) |
| 437 return; | 437 return; |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 } | 531 } |
| 532 | 532 |
| 533 void CmaMessageFilterHost::OnNaturalSizeChanged( | 533 void CmaMessageFilterHost::OnNaturalSizeChanged( |
| 534 int media_id, TrackId track_id, const gfx::Size& size) { | 534 int media_id, TrackId track_id, const gfx::Size& size) { |
| 535 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 535 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 536 Send(new CmaMsg_NaturalSizeChanged(media_id, track_id, size)); | 536 Send(new CmaMsg_NaturalSizeChanged(media_id, track_id, size)); |
| 537 } | 537 } |
| 538 | 538 |
| 539 } // namespace media | 539 } // namespace media |
| 540 } // namespace chromecast | 540 } // namespace chromecast |
| OLD | NEW |