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" | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |