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 |