Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Side by Side Diff: media/remoting/remoting_renderer_controller.cc

Issue 2566223005: Media Remoting: Update remoting interstitial when status changes. (Closed)
Patch Set: Show unprocessed background image when exiting remoting. Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
10 #include "media/remoting/remoting_cdm_context.h" 11 #include "media/remoting/remoting_cdm_context.h"
11 12
12 namespace media { 13 namespace media {
13 14
15 namespace {
16
17 gfx::Size GetRotatedVideoSize(VideoRotation rotation, gfx::Size natural_size) {
18 if (rotation == VIDEO_ROTATION_90 || rotation == VIDEO_ROTATION_270)
19 return gfx::Size(natural_size.height(), natural_size.width());
20 return natural_size;
21 }
22
23 } // namespace
24
14 RemotingRendererController::RemotingRendererController( 25 RemotingRendererController::RemotingRendererController(
15 scoped_refptr<RemotingSourceImpl> remoting_source) 26 scoped_refptr<RemotingSourceImpl> remoting_source)
16 : remoting_source_(remoting_source), weak_factory_(this) { 27 : remoting_source_(remoting_source), weak_factory_(this) {
17 remoting_source_->AddClient(this); 28 remoting_source_->AddClient(this);
18 } 29 }
19 30
20 RemotingRendererController::~RemotingRendererController() { 31 RemotingRendererController::~RemotingRendererController() {
21 DCHECK(thread_checker_.CalledOnValidThread()); 32 DCHECK(thread_checker_.CalledOnValidThread());
22 remoting_source_->RemoveClient(this); 33 remoting_source_->RemoveClient(this);
23 } 34 }
24 35
25 void RemotingRendererController::OnStarted(bool success) { 36 void RemotingRendererController::OnStarted(bool success) {
26 DCHECK(thread_checker_.CalledOnValidThread()); 37 DCHECK(thread_checker_.CalledOnValidThread());
27 38
28 if (success) { 39 if (success) {
29 VLOG(1) << "Remoting started successively."; 40 VLOG(1) << "Remoting started successively.";
30 if (remote_rendering_started_) { 41 if (remote_rendering_started_) {
31 DCHECK(!switch_renderer_cb_.is_null()); 42 DCHECK(!switch_renderer_cb_.is_null());
32 switch_renderer_cb_.Run(); 43 switch_renderer_cb_.Run();
33 } else { 44 } else {
34 remoting_source_->StopRemoting(this); 45 remoting_source_->StopRemoting(this);
35 } 46 }
36 } else { 47 } else {
37 VLOG(1) << "Failed to start remoting."; 48 VLOG(1) << "Failed to start remoting.";
38 remote_rendering_started_ = false; 49 remote_rendering_started_ = false;
39 } 50 }
40 } 51 }
miu 2016/12/20 00:16:17 Looks like you should call UpdateInterstitial() he
xjz 2016/12/20 19:32:29 As chatted face to face, there is no need to call
41 52
42 void RemotingRendererController::OnSessionStateChanged() { 53 void RemotingRendererController::OnSessionStateChanged() {
43 DCHECK(thread_checker_.CalledOnValidThread()); 54 DCHECK(thread_checker_.CalledOnValidThread());
44 55
45 VLOG(1) << "OnSessionStateChanged: " << remoting_source_->state(); 56 VLOG(1) << "OnSessionStateChanged: " << remoting_source_->state();
57 if (remoting_source_->state() ==
miu 2016/12/20 00:16:17 How about just calling UpdateInterstitial() uncond
xjz 2016/12/20 19:32:29 Done.
58 RemotingSessionState::SESSION_PERMANENTLY_STOPPED)
59 UpdateInterstitial();
60
46 UpdateAndMaybeSwitch(); 61 UpdateAndMaybeSwitch();
47 } 62 }
48 63
49 void RemotingRendererController::OnEnteredFullscreen() { 64 void RemotingRendererController::OnEnteredFullscreen() {
50 DCHECK(thread_checker_.CalledOnValidThread()); 65 DCHECK(thread_checker_.CalledOnValidThread());
51 66
52 is_fullscreen_ = true; 67 is_fullscreen_ = true;
53 UpdateAndMaybeSwitch(); 68 UpdateAndMaybeSwitch();
54 } 69 }
55 70
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 DCHECK(thread_checker_.CalledOnValidThread()); 111 DCHECK(thread_checker_.CalledOnValidThread());
97 112
98 remoting_source_->StartDataPipe(std::move(audio_data_pipe), 113 remoting_source_->StartDataPipe(std::move(audio_data_pipe),
99 std::move(video_data_pipe), done_callback); 114 std::move(video_data_pipe), done_callback);
100 } 115 }
101 116
102 void RemotingRendererController::OnMetadataChanged( 117 void RemotingRendererController::OnMetadataChanged(
103 const PipelineMetadata& metadata) { 118 const PipelineMetadata& metadata) {
104 DCHECK(thread_checker_.CalledOnValidThread()); 119 DCHECK(thread_checker_.CalledOnValidThread());
105 120
121 const gfx::Size old_size = pipeline_metadata_.natural_size;
106 pipeline_metadata_ = metadata; 122 pipeline_metadata_ = metadata;
107 123
108 is_encrypted_ = false; 124 is_encrypted_ = false;
109 if (has_video()) { 125 if (has_video()) {
110 video_decoder_config_ = metadata.video_decoder_config; 126 is_encrypted_ |= metadata.video_decoder_config.is_encrypted();
111 is_encrypted_ |= video_decoder_config_.is_encrypted(); 127 pipeline_metadata_.natural_size = GetRotatedVideoSize(
128 pipeline_metadata_.video_rotation, pipeline_metadata_.natural_size);
112 } 129 }
113 if (has_audio()) { 130 if (has_audio()) {
114 audio_decoder_config_ = metadata.audio_decoder_config; 131 is_encrypted_ |= metadata.audio_decoder_config.is_encrypted();
115 is_encrypted_ |= audio_decoder_config_.is_encrypted();
116 } 132 }
133
134 if (pipeline_metadata_.natural_size != old_size)
135 UpdateInterstitial();
136
117 UpdateAndMaybeSwitch(); 137 UpdateAndMaybeSwitch();
118 } 138 }
119 139
120 bool RemotingRendererController::IsVideoCodecSupported() { 140 bool RemotingRendererController::IsVideoCodecSupported() {
121 DCHECK(thread_checker_.CalledOnValidThread()); 141 DCHECK(thread_checker_.CalledOnValidThread());
122 DCHECK(has_video()); 142 DCHECK(has_video());
123 143
124 switch (video_decoder_config_.codec()) { 144 switch (pipeline_metadata_.video_decoder_config.codec()) {
125 case VideoCodec::kCodecH264: 145 case VideoCodec::kCodecH264:
126 case VideoCodec::kCodecVP8: 146 case VideoCodec::kCodecVP8:
127 return true; 147 return true;
128 default: 148 default:
129 VLOG(2) << "Remoting does not support video codec: " 149 VLOG(2) << "Remoting does not support video codec: "
130 << video_decoder_config_.codec(); 150 << pipeline_metadata_.video_decoder_config.codec();
131 return false; 151 return false;
132 } 152 }
133 } 153 }
134 154
135 bool RemotingRendererController::IsAudioCodecSupported() { 155 bool RemotingRendererController::IsAudioCodecSupported() {
136 DCHECK(thread_checker_.CalledOnValidThread()); 156 DCHECK(thread_checker_.CalledOnValidThread());
137 DCHECK(has_audio()); 157 DCHECK(has_audio());
138 158
139 switch (audio_decoder_config_.codec()) { 159 switch (pipeline_metadata_.audio_decoder_config.codec()) {
140 case AudioCodec::kCodecAAC: 160 case AudioCodec::kCodecAAC:
141 case AudioCodec::kCodecMP3: 161 case AudioCodec::kCodecMP3:
142 case AudioCodec::kCodecPCM: 162 case AudioCodec::kCodecPCM:
143 case AudioCodec::kCodecVorbis: 163 case AudioCodec::kCodecVorbis:
144 case AudioCodec::kCodecFLAC: 164 case AudioCodec::kCodecFLAC:
145 case AudioCodec::kCodecAMR_NB: 165 case AudioCodec::kCodecAMR_NB:
146 case AudioCodec::kCodecAMR_WB: 166 case AudioCodec::kCodecAMR_WB:
147 case AudioCodec::kCodecPCM_MULAW: 167 case AudioCodec::kCodecPCM_MULAW:
148 case AudioCodec::kCodecGSM_MS: 168 case AudioCodec::kCodecGSM_MS:
149 case AudioCodec::kCodecPCM_S16BE: 169 case AudioCodec::kCodecPCM_S16BE:
150 case AudioCodec::kCodecPCM_S24BE: 170 case AudioCodec::kCodecPCM_S24BE:
151 case AudioCodec::kCodecOpus: 171 case AudioCodec::kCodecOpus:
152 case AudioCodec::kCodecEAC3: 172 case AudioCodec::kCodecEAC3:
153 case AudioCodec::kCodecPCM_ALAW: 173 case AudioCodec::kCodecPCM_ALAW:
154 case AudioCodec::kCodecALAC: 174 case AudioCodec::kCodecALAC:
155 case AudioCodec::kCodecAC3: 175 case AudioCodec::kCodecAC3:
156 return true; 176 return true;
157 default: 177 default:
158 VLOG(2) << "Remoting does not support audio codec: " 178 VLOG(2) << "Remoting does not support audio codec: "
159 << audio_decoder_config_.codec(); 179 << pipeline_metadata_.audio_decoder_config.codec();
160 return false; 180 return false;
161 } 181 }
162 } 182 }
163 183
164 bool RemotingRendererController::ShouldBeRemoting() { 184 bool RemotingRendererController::ShouldBeRemoting() {
165 DCHECK(thread_checker_.CalledOnValidThread()); 185 DCHECK(thread_checker_.CalledOnValidThread());
166 186
167 if (switch_renderer_cb_.is_null()) 187 if (switch_renderer_cb_.is_null())
168 return false; // No way to switch to a RemotingRenderImpl. 188 return false; // No way to switch to a RemotingRenderImpl.
169 189
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 } 251 }
232 // |switch_renderer_cb_.Run()| will be called after remoting is started 252 // |switch_renderer_cb_.Run()| will be called after remoting is started
233 // successfully. 253 // successfully.
234 remoting_source_->StartRemoting(this); 254 remoting_source_->StartRemoting(this);
235 } else { 255 } else {
236 // For encrypted content, it's only valid to switch to remoting renderer, 256 // For encrypted content, it's only valid to switch to remoting renderer,
237 // and never back to the local renderer. The RemotingCdmController will 257 // and never back to the local renderer. The RemotingCdmController will
238 // force-stop the session when remoting has ended; so no need to call 258 // force-stop the session when remoting has ended; so no need to call
239 // StopRemoting() from here. 259 // StopRemoting() from here.
240 DCHECK(!is_encrypted_); 260 DCHECK(!is_encrypted_);
261 if (!show_interstitial_cb_.is_null()) {
262 show_interstitial_cb_.Run(SkBitmap(), pipeline_metadata_.natural_size,
miu 2016/12/20 00:16:17 Hmm...It looks like you don't need this here (if y
xjz 2016/12/20 19:32:29 Done. Now let RemoteRendererImpl destructor handle
263 RemotingInterstitialType::NONE);
264 show_interstitial_cb_.Reset();
miu 2016/12/20 00:16:17 Why do we reset the callback? What if we start rem
xjz 2016/12/20 19:32:29 When we start remoting again, a new RemoteRenderer
265 }
241 switch_renderer_cb_.Run(); 266 switch_renderer_cb_.Run();
242 remoting_source_->StopRemoting(this); 267 remoting_source_->StopRemoting(this);
243 } 268 }
244 } 269 }
245 270
271 void RemotingRendererController::SetShowInterstitialCallback(
272 const ShowInterstitialCallback& cb) {
273 DCHECK(thread_checker_.CalledOnValidThread());
274 DCHECK(!cb.is_null());
miu 2016/12/20 00:16:17 As mentioned above, let RemotingRendererImpl set a
xjz 2016/12/20 19:32:29 Done.
275 DCHECK(show_interstitial_cb_.is_null());
276 show_interstitial_cb_ = cb;
277 UpdateInterstitial();
278 }
279
280 void RemotingRendererController::UpdateInterstitial() {
281 DCHECK(thread_checker_.CalledOnValidThread());
282 if (show_interstitial_cb_.is_null() ||
283 pipeline_metadata_.natural_size.IsEmpty())
284 return;
285
286 DCHECK(remote_rendering_started_);
287 // TODO(xjz): Download poster image when available.
288 show_interstitial_cb_.Run(
289 SkBitmap(), pipeline_metadata_.natural_size,
290 remoting_source_->state() == RemotingSessionState::SESSION_STARTED
291 ? RemotingInterstitialType::SUCCESS
292 : RemotingInterstitialType::FAIL);
293 }
294
246 } // namespace media 295 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698