| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/remoting/remoting_renderer_controller.h" | 5 #include "media/remoting/remoting_renderer_controller.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/threading/thread_checker.h" | 9 #include "base/threading/thread_checker.h" |
| 10 #include "media/base/video_util.h" | |
| 11 #include "media/remoting/remoting_cdm_context.h" | 10 #include "media/remoting/remoting_cdm_context.h" |
| 12 | 11 |
| 13 namespace media { | 12 namespace media { |
| 14 | 13 |
| 15 namespace { | 14 namespace { |
| 16 | 15 |
| 17 gfx::Size GetRotatedVideoSize(VideoRotation rotation, gfx::Size natural_size) { | 16 gfx::Size GetRotatedVideoSize(VideoRotation rotation, gfx::Size natural_size) { |
| 18 if (rotation == VIDEO_ROTATION_90 || rotation == VIDEO_ROTATION_270) | 17 if (rotation == VIDEO_ROTATION_90 || rotation == VIDEO_ROTATION_270) |
| 19 return gfx::Size(natural_size.height(), natural_size.width()); | 18 return gfx::Size(natural_size.height(), natural_size.width()); |
| 20 return natural_size; | 19 return natural_size; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 50 } | 49 } |
| 51 } | 50 } |
| 52 | 51 |
| 53 void RemotingRendererController::OnSessionStateChanged() { | 52 void RemotingRendererController::OnSessionStateChanged() { |
| 54 DCHECK(thread_checker_.CalledOnValidThread()); | 53 DCHECK(thread_checker_.CalledOnValidThread()); |
| 55 | 54 |
| 56 VLOG(1) << "OnSessionStateChanged: " << remoting_source_->state(); | 55 VLOG(1) << "OnSessionStateChanged: " << remoting_source_->state(); |
| 57 if (!sink_available_changed_cb_.is_null()) | 56 if (!sink_available_changed_cb_.is_null()) |
| 58 sink_available_changed_cb_.Run(IsRemoteSinkAvailable()); | 57 sink_available_changed_cb_.Run(IsRemoteSinkAvailable()); |
| 59 | 58 |
| 60 UpdateInterstitial(); | 59 UpdateInterstitial(base::nullopt); |
| 61 UpdateAndMaybeSwitch(); | 60 UpdateAndMaybeSwitch(); |
| 62 } | 61 } |
| 63 | 62 |
| 64 bool RemotingRendererController::IsRemoteSinkAvailable() { | 63 bool RemotingRendererController::IsRemoteSinkAvailable() { |
| 65 DCHECK(thread_checker_.CalledOnValidThread()); | 64 DCHECK(thread_checker_.CalledOnValidThread()); |
| 66 | 65 |
| 67 switch (remoting_source_->state()) { | 66 switch (remoting_source_->state()) { |
| 68 case SESSION_CAN_START: | 67 case SESSION_CAN_START: |
| 69 case SESSION_STARTING: | 68 case SESSION_STARTING: |
| 70 case SESSION_STARTED: | 69 case SESSION_STARTED: |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 UpdateAndMaybeSwitch(); | 111 UpdateAndMaybeSwitch(); |
| 113 } | 112 } |
| 114 | 113 |
| 115 void RemotingRendererController::OnRemotePlaybackDisabled(bool disabled) { | 114 void RemotingRendererController::OnRemotePlaybackDisabled(bool disabled) { |
| 116 DCHECK(thread_checker_.CalledOnValidThread()); | 115 DCHECK(thread_checker_.CalledOnValidThread()); |
| 117 | 116 |
| 118 is_remote_playback_disabled_ = disabled; | 117 is_remote_playback_disabled_ = disabled; |
| 119 UpdateAndMaybeSwitch(); | 118 UpdateAndMaybeSwitch(); |
| 120 } | 119 } |
| 121 | 120 |
| 121 void RemotingRendererController::OnSetPoster(const GURL& poster_url) { |
| 122 DCHECK(thread_checker_.CalledOnValidThread()); |
| 123 |
| 124 if (poster_url != poster_url_) { |
| 125 poster_url_ = poster_url; |
| 126 if (poster_url_.is_empty()) |
| 127 UpdateInterstitial(SkBitmap()); |
| 128 else |
| 129 DownloadPosterImage(); |
| 130 } |
| 131 } |
| 132 |
| 122 void RemotingRendererController::SetSwitchRendererCallback( | 133 void RemotingRendererController::SetSwitchRendererCallback( |
| 123 const base::Closure& cb) { | 134 const base::Closure& cb) { |
| 124 DCHECK(thread_checker_.CalledOnValidThread()); | 135 DCHECK(thread_checker_.CalledOnValidThread()); |
| 125 DCHECK(!cb.is_null()); | 136 DCHECK(!cb.is_null()); |
| 126 | 137 |
| 127 switch_renderer_cb_ = cb; | 138 switch_renderer_cb_ = cb; |
| 128 UpdateAndMaybeSwitch(); | 139 UpdateAndMaybeSwitch(); |
| 129 } | 140 } |
| 130 | 141 |
| 131 void RemotingRendererController::SetRemoteSinkAvailableChangedCallback( | 142 void RemotingRendererController::SetRemoteSinkAvailableChangedCallback( |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 if (has_video()) { | 176 if (has_video()) { |
| 166 is_encrypted_ |= metadata.video_decoder_config.is_encrypted(); | 177 is_encrypted_ |= metadata.video_decoder_config.is_encrypted(); |
| 167 pipeline_metadata_.natural_size = GetRotatedVideoSize( | 178 pipeline_metadata_.natural_size = GetRotatedVideoSize( |
| 168 pipeline_metadata_.video_rotation, pipeline_metadata_.natural_size); | 179 pipeline_metadata_.video_rotation, pipeline_metadata_.natural_size); |
| 169 } | 180 } |
| 170 if (has_audio()) { | 181 if (has_audio()) { |
| 171 is_encrypted_ |= metadata.audio_decoder_config.is_encrypted(); | 182 is_encrypted_ |= metadata.audio_decoder_config.is_encrypted(); |
| 172 } | 183 } |
| 173 | 184 |
| 174 if (pipeline_metadata_.natural_size != old_size) | 185 if (pipeline_metadata_.natural_size != old_size) |
| 175 UpdateInterstitial(); | 186 UpdateInterstitial(base::nullopt); |
| 176 | 187 |
| 177 UpdateAndMaybeSwitch(); | 188 UpdateAndMaybeSwitch(); |
| 178 } | 189 } |
| 179 | 190 |
| 180 bool RemotingRendererController::IsVideoCodecSupported() { | 191 bool RemotingRendererController::IsVideoCodecSupported() { |
| 181 DCHECK(thread_checker_.CalledOnValidThread()); | 192 DCHECK(thread_checker_.CalledOnValidThread()); |
| 182 DCHECK(has_video()); | 193 DCHECK(has_video()); |
| 183 | 194 |
| 184 switch (pipeline_metadata_.video_decoder_config.codec()) { | 195 switch (pipeline_metadata_.video_decoder_config.codec()) { |
| 185 case VideoCodec::kCodecH264: | 196 case VideoCodec::kCodecH264: |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 DCHECK(!is_encrypted_); | 334 DCHECK(!is_encrypted_); |
| 324 switch_renderer_cb_.Run(); | 335 switch_renderer_cb_.Run(); |
| 325 remoting_source_->StopRemoting(this); | 336 remoting_source_->StopRemoting(this); |
| 326 } | 337 } |
| 327 } | 338 } |
| 328 | 339 |
| 329 void RemotingRendererController::SetShowInterstitialCallback( | 340 void RemotingRendererController::SetShowInterstitialCallback( |
| 330 const ShowInterstitialCallback& cb) { | 341 const ShowInterstitialCallback& cb) { |
| 331 DCHECK(thread_checker_.CalledOnValidThread()); | 342 DCHECK(thread_checker_.CalledOnValidThread()); |
| 332 show_interstitial_cb_ = cb; | 343 show_interstitial_cb_ = cb; |
| 333 UpdateInterstitial(); | 344 UpdateInterstitial(SkBitmap()); |
| 345 if (!poster_url_.is_empty()) |
| 346 DownloadPosterImage(); |
| 334 } | 347 } |
| 335 | 348 |
| 336 void RemotingRendererController::UpdateInterstitial() { | 349 void RemotingRendererController::SetDownloadPosterCallback( |
| 350 const DownloadPosterCallback& cb) { |
| 351 DCHECK(thread_checker_.CalledOnValidThread()); |
| 352 DCHECK(download_poster_cb_.is_null()); |
| 353 download_poster_cb_ = cb; |
| 354 if (!poster_url_.is_empty()) |
| 355 DownloadPosterImage(); |
| 356 } |
| 357 |
| 358 void RemotingRendererController::UpdateInterstitial( |
| 359 const base::Optional<SkBitmap>& image) { |
| 337 DCHECK(thread_checker_.CalledOnValidThread()); | 360 DCHECK(thread_checker_.CalledOnValidThread()); |
| 338 if (show_interstitial_cb_.is_null() || | 361 if (show_interstitial_cb_.is_null() || |
| 339 pipeline_metadata_.natural_size.IsEmpty()) | 362 pipeline_metadata_.natural_size.IsEmpty()) |
| 340 return; | 363 return; |
| 341 | 364 |
| 342 RemotingInterstitialType type = RemotingInterstitialType::BETWEEN_SESSIONS; | 365 RemotingInterstitialType type = RemotingInterstitialType::BETWEEN_SESSIONS; |
| 343 switch (remoting_source_->state()) { | 366 switch (remoting_source_->state()) { |
| 344 case SESSION_STARTED: | 367 case SESSION_STARTED: |
| 345 type = RemotingInterstitialType::IN_SESSION; | 368 type = RemotingInterstitialType::IN_SESSION; |
| 346 break; | 369 break; |
| 347 case SESSION_PERMANENTLY_STOPPED: | 370 case SESSION_PERMANENTLY_STOPPED: |
| 348 type = RemotingInterstitialType::ENCRYPTED_MEDIA_FATAL_ERROR; | 371 type = RemotingInterstitialType::ENCRYPTED_MEDIA_FATAL_ERROR; |
| 349 break; | 372 break; |
| 350 case SESSION_UNAVAILABLE: | 373 case SESSION_UNAVAILABLE: |
| 351 case SESSION_CAN_START: | 374 case SESSION_CAN_START: |
| 352 case SESSION_STARTING: | 375 case SESSION_STARTING: |
| 353 case SESSION_STOPPING: | 376 case SESSION_STOPPING: |
| 354 break; | 377 break; |
| 355 } | 378 } |
| 356 | 379 |
| 357 // TODO(xjz): Download poster image when available. | 380 show_interstitial_cb_.Run(image, pipeline_metadata_.natural_size, type); |
| 358 show_interstitial_cb_.Run(SkBitmap(), pipeline_metadata_.natural_size, type); | 381 } |
| 382 |
| 383 void RemotingRendererController::DownloadPosterImage() { |
| 384 if (download_poster_cb_.is_null() || show_interstitial_cb_.is_null()) |
| 385 return; |
| 386 DCHECK(!poster_url_.is_empty()); |
| 387 |
| 388 download_poster_cb_.Run( |
| 389 poster_url_, |
| 390 base::Bind(&RemotingRendererController::OnPosterImageDownloaded, |
| 391 weak_factory_.GetWeakPtr(), poster_url_)); |
| 392 } |
| 393 |
| 394 void RemotingRendererController::OnPosterImageDownloaded( |
| 395 const GURL& download_url, |
| 396 const SkBitmap& image) { |
| 397 DCHECK(thread_checker_.CalledOnValidThread()); |
| 398 |
| 399 if (download_url != poster_url_) |
| 400 return; // The poster image URL has changed during the download. |
| 401 UpdateInterstitial(image); |
| 359 } | 402 } |
| 360 | 403 |
| 361 } // namespace media | 404 } // namespace media |
| OLD | NEW |