Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "content/renderer/media/android/webmediaplayer_android.h" | 5 #include "content/renderer/media/android/webmediaplayer_android.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <limits> | 9 #include <limits> |
| 10 | 10 |
| 11 #include "base/android/build_info.h" | 11 #include "base/android/build_info.h" |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/callback_helpers.h" | 13 #include "base/callback_helpers.h" |
| 14 #include "base/command_line.h" | 14 #include "base/command_line.h" |
| 15 #include "base/files/file_path.h" | 15 #include "base/files/file_path.h" |
| 16 #include "base/logging.h" | 16 #include "base/logging.h" |
| 17 #include "base/metrics/histogram_macros.h" | 17 #include "base/metrics/histogram_macros.h" |
| 18 #include "base/single_thread_task_runner.h" | 18 #include "base/single_thread_task_runner.h" |
| 19 #include "base/strings/string_number_conversions.h" | 19 #include "base/strings/string_number_conversions.h" |
| 20 #include "base/strings/utf_string_conversions.h" | 20 #include "base/strings/utf_string_conversions.h" |
| 21 #include "cc/blink/web_layer_impl.h" | 21 #include "cc/blink/web_layer_impl.h" |
| 22 #include "cc/layers/video_layer.h" | 22 #include "cc/layers/video_layer.h" |
| 23 #include "content/public/common/content_client.h" | 23 #include "content/public/common/content_client.h" |
| 24 #include "content/public/common/content_switches.h" | 24 #include "content/public/common/content_switches.h" |
| 25 #include "content/public/common/renderer_preferences.h" | 25 #include "content/public/common/renderer_preferences.h" |
| 26 #include "content/public/renderer/render_frame.h" | 26 #include "content/public/renderer/render_frame.h" |
| 27 #include "content/renderer/media/android/renderer_demuxer_android.h" | |
| 28 #include "content/renderer/media/android/renderer_media_player_manager.h" | 27 #include "content/renderer/media/android/renderer_media_player_manager.h" |
| 29 #include "content/renderer/render_frame_impl.h" | 28 #include "content/renderer/render_frame_impl.h" |
| 30 #include "content/renderer/render_thread_impl.h" | 29 #include "content/renderer/render_thread_impl.h" |
| 31 #include "content/renderer/render_view_impl.h" | 30 #include "content/renderer/render_view_impl.h" |
| 32 #include "gpu/GLES2/gl2extchromium.h" | 31 #include "gpu/GLES2/gl2extchromium.h" |
| 33 #include "gpu/command_buffer/client/gles2_interface.h" | 32 #include "gpu/command_buffer/client/gles2_interface.h" |
| 34 #include "gpu/command_buffer/common/constants.h" | 33 #include "gpu/command_buffer/common/constants.h" |
| 35 #include "gpu/command_buffer/common/mailbox_holder.h" | 34 #include "gpu/command_buffer/common/mailbox_holder.h" |
| 36 #include "media/base/android/media_codec_util.h" | 35 #include "media/base/android/media_codec_util.h" |
| 37 #include "media/base/android/media_common_android.h" | 36 #include "media/base/android/media_common_android.h" |
| 38 #include "media/base/android/media_player_android.h" | 37 #include "media/base/android/media_player_android.h" |
| 39 #include "media/base/bind_to_current_loop.h" | 38 #include "media/base/bind_to_current_loop.h" |
| 40 #include "media/base/cdm_context.h" | |
| 41 #include "media/base/media_content_type.h" | 39 #include "media/base/media_content_type.h" |
| 42 #include "media/base/media_keys.h" | 40 #include "media/base/media_keys.h" |
| 43 #include "media/base/media_log.h" | 41 #include "media/base/media_log.h" |
| 44 #include "media/base/media_switches.h" | 42 #include "media/base/media_switches.h" |
| 45 #include "media/base/timestamp_constants.h" | 43 #include "media/base/timestamp_constants.h" |
| 46 #include "media/base/video_frame.h" | 44 #include "media/base/video_frame.h" |
| 47 #include "media/blink/webcontentdecryptionmodule_impl.h" | 45 #include "media/blink/webcontentdecryptionmodule_impl.h" |
| 48 #include "media/blink/webmediaplayer_cast_android.h" | 46 #include "media/blink/webmediaplayer_cast_android.h" |
| 49 #include "media/blink/webmediaplayer_delegate.h" | 47 #include "media/blink/webmediaplayer_delegate.h" |
| 50 #include "media/blink/webmediaplayer_util.h" | 48 #include "media/blink/webmediaplayer_util.h" |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 134 blink::WebMediaPlayerClient* client, | 132 blink::WebMediaPlayerClient* client, |
| 135 blink::WebMediaPlayerEncryptedMediaClient* encrypted_client, | 133 blink::WebMediaPlayerEncryptedMediaClient* encrypted_client, |
| 136 base::WeakPtr<media::WebMediaPlayerDelegate> delegate, | 134 base::WeakPtr<media::WebMediaPlayerDelegate> delegate, |
| 137 RendererMediaPlayerManager* player_manager, | 135 RendererMediaPlayerManager* player_manager, |
| 138 scoped_refptr<StreamTextureFactory> factory, | 136 scoped_refptr<StreamTextureFactory> factory, |
| 139 int frame_id, | 137 int frame_id, |
| 140 bool enable_texture_copy, | 138 bool enable_texture_copy, |
| 141 const media::WebMediaPlayerParams& params) | 139 const media::WebMediaPlayerParams& params) |
| 142 : frame_(frame), | 140 : frame_(frame), |
| 143 client_(client), | 141 client_(client), |
| 144 encrypted_client_(encrypted_client), | |
| 145 delegate_(delegate), | 142 delegate_(delegate), |
| 146 delegate_id_(0), | 143 delegate_id_(0), |
| 147 defer_load_cb_(params.defer_load_cb()), | 144 defer_load_cb_(params.defer_load_cb()), |
| 148 buffered_(static_cast<size_t>(1)), | 145 buffered_(static_cast<size_t>(1)), |
| 149 media_task_runner_(params.media_task_runner()), | 146 media_task_runner_(params.media_task_runner()), |
| 150 ignore_metadata_duration_change_(false), | 147 ignore_metadata_duration_change_(false), |
|
wolenetz
2016/09/30 23:23:24
Without MSE, this field and associated conditions
DaleCurtis
2016/09/30 23:34:24
Removed.
| |
| 151 pending_seek_(false), | 148 pending_seek_(false), |
| 152 seeking_(false), | 149 seeking_(false), |
| 153 did_loading_progress_(false), | 150 did_loading_progress_(false), |
| 154 player_manager_(player_manager), | 151 player_manager_(player_manager), |
| 155 network_state_(WebMediaPlayer::NetworkStateEmpty), | 152 network_state_(WebMediaPlayer::NetworkStateEmpty), |
| 156 ready_state_(WebMediaPlayer::ReadyStateHaveNothing), | 153 ready_state_(WebMediaPlayer::ReadyStateHaveNothing), |
| 157 texture_id_(0), | 154 texture_id_(0), |
| 158 stream_id_(0), | 155 stream_id_(0), |
| 159 is_player_initialized_(false), | 156 is_player_initialized_(false), |
| 160 is_playing_(false), | 157 is_playing_(false), |
| 161 is_play_pending_(false), | 158 is_play_pending_(false), |
| 162 needs_establish_peer_(true), | 159 needs_establish_peer_(true), |
| 163 has_size_info_(false), | 160 has_size_info_(false), |
| 164 // Threaded compositing isn't enabled universally yet. | 161 // Threaded compositing isn't enabled universally yet. |
| 165 compositor_task_runner_(params.compositor_task_runner() | 162 compositor_task_runner_(params.compositor_task_runner() |
| 166 ? params.compositor_task_runner() | 163 ? params.compositor_task_runner() |
| 167 : base::ThreadTaskRunnerHandle::Get()), | 164 : base::ThreadTaskRunnerHandle::Get()), |
| 168 stream_texture_factory_(factory), | 165 stream_texture_factory_(factory), |
| 169 is_fullscreen_(false), | 166 is_fullscreen_(false), |
| 170 video_frame_provider_client_(nullptr), | 167 video_frame_provider_client_(nullptr), |
| 171 player_type_(MEDIA_PLAYER_TYPE_URL), | 168 player_type_(MEDIA_PLAYER_TYPE_URL), |
| 172 is_remote_(false), | 169 is_remote_(false), |
| 173 media_log_(params.media_log()), | 170 media_log_(params.media_log()), |
| 174 cdm_context_(nullptr), | |
| 175 allow_stored_credentials_(false), | 171 allow_stored_credentials_(false), |
| 176 is_local_resource_(false), | 172 is_local_resource_(false), |
| 177 interpolator_(&default_tick_clock_), | 173 interpolator_(&default_tick_clock_), |
| 178 frame_id_(frame_id), | 174 frame_id_(frame_id), |
| 179 enable_texture_copy_(enable_texture_copy), | 175 enable_texture_copy_(enable_texture_copy), |
| 180 suppress_deleting_texture_(false), | 176 suppress_deleting_texture_(false), |
| 181 playback_completed_(false), | 177 playback_completed_(false), |
| 182 volume_(1.0), | 178 volume_(1.0), |
| 183 volume_multiplier_(1.0), | 179 volume_multiplier_(1.0), |
| 184 weak_factory_(this) { | 180 weak_factory_(this) { |
| 185 DCHECK(player_manager_); | 181 DCHECK(player_manager_); |
| 186 | 182 |
| 187 DCHECK(main_thread_checker_.CalledOnValidThread()); | 183 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 188 | 184 |
| 189 if (delegate_) | 185 if (delegate_) |
| 190 delegate_id_ = delegate_->AddObserver(this); | 186 delegate_id_ = delegate_->AddObserver(this); |
| 191 | 187 |
| 192 player_id_ = player_manager_->RegisterMediaPlayer(this); | 188 player_id_ = player_manager_->RegisterMediaPlayer(this); |
| 193 | 189 |
| 194 TryCreateStreamTextureProxyIfNeeded(); | 190 TryCreateStreamTextureProxyIfNeeded(); |
| 195 interpolator_.SetUpperBound(base::TimeDelta()); | 191 interpolator_.SetUpperBound(base::TimeDelta()); |
| 196 | |
| 197 if (params.initial_cdm()) { | |
| 198 cdm_context_ = media::ToWebContentDecryptionModuleImpl(params.initial_cdm()) | |
| 199 ->GetCdmContext(); | |
| 200 } | |
| 201 } | 192 } |
| 202 | 193 |
| 203 WebMediaPlayerAndroid::~WebMediaPlayerAndroid() { | 194 WebMediaPlayerAndroid::~WebMediaPlayerAndroid() { |
| 204 DCHECK(main_thread_checker_.CalledOnValidThread()); | 195 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 205 SetVideoFrameProviderClient(NULL); | 196 SetVideoFrameProviderClient(NULL); |
| 206 client_->setWebLayer(NULL); | 197 client_->setWebLayer(NULL); |
| 207 | 198 |
| 208 if (is_player_initialized_) | 199 if (is_player_initialized_) |
| 209 player_manager_->DestroyPlayer(player_id_); | 200 player_manager_->DestroyPlayer(player_id_); |
| 210 | 201 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 222 | 213 |
| 223 { | 214 { |
| 224 base::AutoLock auto_lock(current_frame_lock_); | 215 base::AutoLock auto_lock(current_frame_lock_); |
| 225 current_frame_ = NULL; | 216 current_frame_ = NULL; |
| 226 } | 217 } |
| 227 | 218 |
| 228 if (delegate_) { | 219 if (delegate_) { |
| 229 delegate_->PlayerGone(delegate_id_); | 220 delegate_->PlayerGone(delegate_id_); |
| 230 delegate_->RemoveObserver(delegate_id_); | 221 delegate_->RemoveObserver(delegate_id_); |
| 231 } | 222 } |
| 232 | |
| 233 if (media_source_delegate_) { | |
| 234 // Part of |media_source_delegate_| needs to be stopped on the media thread. | |
| 235 // Wait until |media_source_delegate_| is fully stopped before tearing | |
| 236 // down other objects. | |
| 237 base::WaitableEvent waiter(base::WaitableEvent::ResetPolicy::AUTOMATIC, | |
| 238 base::WaitableEvent::InitialState::NOT_SIGNALED); | |
| 239 media_source_delegate_->Stop( | |
| 240 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&waiter))); | |
| 241 waiter.Wait(); | |
| 242 } | |
| 243 } | 223 } |
| 244 | 224 |
| 245 void WebMediaPlayerAndroid::load(LoadType load_type, | 225 void WebMediaPlayerAndroid::load(LoadType load_type, |
| 246 const blink::WebMediaPlayerSource& source, | 226 const blink::WebMediaPlayerSource& source, |
| 247 CORSMode cors_mode) { | 227 CORSMode cors_mode) { |
| 248 // Only URL or MSE blob URL is supported. | 228 // Only URL or MSE blob URL is supported. |
| 249 DCHECK(source.isURL()); | 229 DCHECK(source.isURL()); |
| 250 blink::WebURL url = source.getAsURL(); | 230 blink::WebURL url = source.getAsURL(); |
| 251 if (!defer_load_cb_.is_null()) { | 231 if (!defer_load_cb_.is_null()) { |
| 252 defer_load_cb_.Run(base::Bind(&WebMediaPlayerAndroid::DoLoad, | 232 defer_load_cb_.Run(base::Bind(&WebMediaPlayerAndroid::DoLoad, |
| 253 weak_factory_.GetWeakPtr(), load_type, url, | 233 weak_factory_.GetWeakPtr(), load_type, url, |
| 254 cors_mode)); | 234 cors_mode)); |
| 255 return; | 235 return; |
| 256 } | 236 } |
| 257 DoLoad(load_type, url, cors_mode); | 237 DoLoad(load_type, url, cors_mode); |
| 258 } | 238 } |
| 259 | 239 |
| 260 void WebMediaPlayerAndroid::DoLoad(LoadType load_type, | 240 void WebMediaPlayerAndroid::DoLoad(LoadType load_type, |
| 261 const blink::WebURL& url, | 241 const blink::WebURL& url, |
| 262 CORSMode cors_mode) { | 242 CORSMode cors_mode) { |
| 263 DCHECK(main_thread_checker_.CalledOnValidThread()); | 243 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 264 | 244 |
| 265 media::ReportMetrics(load_type, GURL(url), frame_->getSecurityOrigin()); | 245 media::ReportMetrics(load_type, GURL(url), frame_->getSecurityOrigin()); |
| 266 | 246 DCHECK_EQ(load_type, LoadTypeURL) |
| 267 switch (load_type) { | 247 << "WebMediaPlayerAndroid doesn't support MediaStream or " |
| 268 case LoadTypeURL: | 248 "MediaSource on this platform"; |
| 269 player_type_ = MEDIA_PLAYER_TYPE_URL; | |
| 270 break; | |
| 271 | |
| 272 case LoadTypeMediaSource: | |
| 273 player_type_ = MEDIA_PLAYER_TYPE_MEDIA_SOURCE; | |
| 274 break; | |
| 275 | |
| 276 case LoadTypeMediaStream: | |
| 277 CHECK(false) << "WebMediaPlayerAndroid doesn't support MediaStream on " | |
| 278 "this platform"; | |
| 279 return; | |
| 280 } | |
| 281 | 249 |
| 282 url_ = url; | 250 url_ = url; |
| 283 is_local_resource_ = IsLocalResource(); | 251 is_local_resource_ = IsLocalResource(); |
| 284 int demuxer_client_id = 0; | 252 info_loader_.reset(new MediaInfoLoader( |
| 285 if (player_type_ != MEDIA_PLAYER_TYPE_URL) { | 253 url, cors_mode, base::Bind(&WebMediaPlayerAndroid::DidLoadMediaInfo, |
| 286 RendererDemuxerAndroid* demuxer = | 254 weak_factory_.GetWeakPtr()))); |
| 287 RenderThreadImpl::current()->renderer_demuxer(); | 255 info_loader_->Start(frame_); |
| 288 demuxer_client_id = demuxer->GetNextDemuxerClientID(); | |
| 289 | |
| 290 media_source_delegate_.reset(new MediaSourceDelegate( | |
| 291 demuxer, demuxer_client_id, media_task_runner_, media_log_)); | |
| 292 | |
| 293 if (player_type_ == MEDIA_PLAYER_TYPE_MEDIA_SOURCE) { | |
| 294 media_source_delegate_->InitializeMediaSource( | |
| 295 base::Bind(&WebMediaPlayerAndroid::OnMediaSourceOpened, | |
| 296 weak_factory_.GetWeakPtr()), | |
| 297 base::Bind(&WebMediaPlayerAndroid::OnEncryptedMediaInitData, | |
| 298 weak_factory_.GetWeakPtr()), | |
| 299 base::Bind(&WebMediaPlayerAndroid::SetCdmReadyCB, | |
| 300 weak_factory_.GetWeakPtr()), | |
| 301 base::Bind(&WebMediaPlayerAndroid::UpdateNetworkState, | |
| 302 weak_factory_.GetWeakPtr()), | |
| 303 base::Bind(&WebMediaPlayerAndroid::OnDurationChanged, | |
| 304 weak_factory_.GetWeakPtr()), | |
| 305 base::Bind(&WebMediaPlayerAndroid::OnWaitingForDecryptionKey, | |
| 306 weak_factory_.GetWeakPtr())); | |
| 307 InitializePlayer(url_, frame_->document().firstPartyForCookies(), | |
| 308 true, demuxer_client_id); | |
| 309 } | |
| 310 } else { | |
| 311 info_loader_.reset( | |
| 312 new MediaInfoLoader( | |
| 313 url, | |
| 314 cors_mode, | |
| 315 base::Bind(&WebMediaPlayerAndroid::DidLoadMediaInfo, | |
| 316 weak_factory_.GetWeakPtr()))); | |
| 317 info_loader_->Start(frame_); | |
| 318 } | |
| 319 | 256 |
| 320 UpdateNetworkState(WebMediaPlayer::NetworkStateLoading); | 257 UpdateNetworkState(WebMediaPlayer::NetworkStateLoading); |
| 321 UpdateReadyState(WebMediaPlayer::ReadyStateHaveNothing); | 258 UpdateReadyState(WebMediaPlayer::ReadyStateHaveNothing); |
| 322 } | 259 } |
| 323 | 260 |
| 324 void WebMediaPlayerAndroid::DidLoadMediaInfo( | 261 void WebMediaPlayerAndroid::DidLoadMediaInfo( |
| 325 MediaInfoLoader::Status status, | 262 MediaInfoLoader::Status status, |
| 326 const GURL& redirected_url, | 263 const GURL& redirected_url, |
| 327 const GURL& first_party_for_cookies, | 264 const GURL& first_party_for_cookies, |
| 328 bool allow_stored_credentials) { | 265 bool allow_stored_credentials) { |
| 329 DCHECK(main_thread_checker_.CalledOnValidThread()); | 266 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 330 DCHECK(!media_source_delegate_); | |
| 331 if (status == MediaInfoLoader::kFailed) { | 267 if (status == MediaInfoLoader::kFailed) { |
| 332 info_loader_.reset(); | 268 info_loader_.reset(); |
| 333 UpdateNetworkState(WebMediaPlayer::NetworkStateNetworkError); | 269 UpdateNetworkState(WebMediaPlayer::NetworkStateNetworkError); |
| 334 return; | 270 return; |
| 335 } | 271 } |
| 336 redirected_url_ = redirected_url; | 272 redirected_url_ = redirected_url; |
| 337 InitializePlayer( | 273 InitializePlayer(redirected_url, first_party_for_cookies, |
| 338 redirected_url, first_party_for_cookies, allow_stored_credentials, 0); | 274 allow_stored_credentials); |
| 339 | 275 |
| 340 UpdateNetworkState(WebMediaPlayer::NetworkStateIdle); | 276 UpdateNetworkState(WebMediaPlayer::NetworkStateIdle); |
| 341 } | 277 } |
| 342 | 278 |
| 343 bool WebMediaPlayerAndroid::IsLocalResource() { | 279 bool WebMediaPlayerAndroid::IsLocalResource() { |
| 344 if (url_.SchemeIsFile() || url_.SchemeIsBlob()) | 280 if (url_.SchemeIsFile() || url_.SchemeIsBlob()) |
| 345 return true; | 281 return true; |
| 346 | 282 |
| 347 std::string host = url_.host(); | 283 std::string host = url_.host(); |
| 348 if (!host.compare("localhost") || !host.compare("127.0.0.1") || | 284 if (!host.compare("localhost") || !host.compare("127.0.0.1") || |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 402 | 338 |
| 403 void WebMediaPlayerAndroid::seek(double seconds) { | 339 void WebMediaPlayerAndroid::seek(double seconds) { |
| 404 DCHECK(main_thread_checker_.CalledOnValidThread()); | 340 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 405 DVLOG(1) << __FUNCTION__ << "(" << seconds << ")"; | 341 DVLOG(1) << __FUNCTION__ << "(" << seconds << ")"; |
| 406 | 342 |
| 407 playback_completed_ = false; | 343 playback_completed_ = false; |
| 408 base::TimeDelta new_seek_time = base::TimeDelta::FromSecondsD(seconds); | 344 base::TimeDelta new_seek_time = base::TimeDelta::FromSecondsD(seconds); |
| 409 | 345 |
| 410 if (seeking_) { | 346 if (seeking_) { |
| 411 if (new_seek_time == seek_time_) { | 347 if (new_seek_time == seek_time_) { |
| 412 if (media_source_delegate_) { | 348 pending_seek_ = false; |
| 413 // Don't suppress any redundant in-progress MSE seek. There could have | 349 return; |
| 414 // been changes to the underlying buffers after seeking the demuxer and | |
| 415 // before receiving OnSeekComplete() for the currently in-progress seek. | |
| 416 MEDIA_LOG(DEBUG, media_log_) | |
| 417 << "Detected MediaSource seek to same time as in-progress seek to " | |
| 418 << seek_time_ << "."; | |
| 419 } else { | |
| 420 // Suppress all redundant seeks if unrestricted by media source | |
| 421 // demuxer API. | |
| 422 pending_seek_ = false; | |
| 423 return; | |
| 424 } | |
| 425 } | 350 } |
| 426 | 351 |
| 427 pending_seek_ = true; | 352 pending_seek_ = true; |
| 428 pending_seek_time_ = new_seek_time; | 353 pending_seek_time_ = new_seek_time; |
| 429 | 354 |
| 430 if (media_source_delegate_) | |
| 431 media_source_delegate_->CancelPendingSeek(pending_seek_time_); | |
| 432 | |
| 433 // Later, OnSeekComplete will trigger the pending seek. | 355 // Later, OnSeekComplete will trigger the pending seek. |
| 434 return; | 356 return; |
| 435 } | 357 } |
| 436 | 358 |
| 437 seeking_ = true; | 359 seeking_ = true; |
| 438 seek_time_ = new_seek_time; | 360 seek_time_ = new_seek_time; |
| 439 | 361 |
| 440 if (media_source_delegate_) | |
| 441 media_source_delegate_->StartWaitingForSeek(seek_time_); | |
| 442 | |
| 443 // Kick off the asynchronous seek! | 362 // Kick off the asynchronous seek! |
| 444 player_manager_->Seek(player_id_, seek_time_); | 363 player_manager_->Seek(player_id_, seek_time_); |
| 445 } | 364 } |
| 446 | 365 |
| 447 bool WebMediaPlayerAndroid::supportsSave() const { | 366 bool WebMediaPlayerAndroid::supportsSave() const { |
| 448 return false; | 367 return false; |
| 449 } | 368 } |
| 450 | 369 |
| 451 void WebMediaPlayerAndroid::setRate(double rate) {} | 370 void WebMediaPlayerAndroid::setRate(double rate) {} |
| 452 | 371 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 520 DCHECK(main_thread_checker_.CalledOnValidThread()); | 439 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 521 if (duration_ == media::kInfiniteDuration) | 440 if (duration_ == media::kInfiniteDuration) |
| 522 return std::numeric_limits<double>::infinity(); | 441 return std::numeric_limits<double>::infinity(); |
| 523 | 442 |
| 524 return duration_.InSecondsF(); | 443 return duration_.InSecondsF(); |
| 525 } | 444 } |
| 526 | 445 |
| 527 double WebMediaPlayerAndroid::timelineOffset() const { | 446 double WebMediaPlayerAndroid::timelineOffset() const { |
| 528 DCHECK(main_thread_checker_.CalledOnValidThread()); | 447 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 529 base::Time timeline_offset; | 448 base::Time timeline_offset; |
| 530 if (media_source_delegate_) | |
| 531 timeline_offset = media_source_delegate_->GetTimelineOffset(); | |
| 532 | |
| 533 if (timeline_offset.is_null()) | 449 if (timeline_offset.is_null()) |
| 534 return std::numeric_limits<double>::quiet_NaN(); | 450 return std::numeric_limits<double>::quiet_NaN(); |
| 535 | 451 |
| 536 return timeline_offset.ToJsTime(); | 452 return timeline_offset.ToJsTime(); |
| 537 } | 453 } |
| 538 | 454 |
| 539 double WebMediaPlayerAndroid::currentTime() const { | 455 double WebMediaPlayerAndroid::currentTime() const { |
| 540 DCHECK(main_thread_checker_.CalledOnValidThread()); | 456 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 541 // If the player is processing a seek, return the seek time. | 457 // If the player is processing a seek, return the seek time. |
| 542 // Blink may still query us if updatePlaybackState() occurs while seeking. | 458 // Blink may still query us if updatePlaybackState() occurs while seeking. |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 560 | 476 |
| 561 WebMediaPlayer::ReadyState WebMediaPlayerAndroid::getReadyState() const { | 477 WebMediaPlayer::ReadyState WebMediaPlayerAndroid::getReadyState() const { |
| 562 return ready_state_; | 478 return ready_state_; |
| 563 } | 479 } |
| 564 | 480 |
| 565 blink::WebString WebMediaPlayerAndroid::getErrorMessage() { | 481 blink::WebString WebMediaPlayerAndroid::getErrorMessage() { |
| 566 return blink::WebString::fromUTF8(media_log_->GetLastErrorMessage()); | 482 return blink::WebString::fromUTF8(media_log_->GetLastErrorMessage()); |
| 567 } | 483 } |
| 568 | 484 |
| 569 blink::WebTimeRanges WebMediaPlayerAndroid::buffered() const { | 485 blink::WebTimeRanges WebMediaPlayerAndroid::buffered() const { |
| 570 if (media_source_delegate_) | |
| 571 return media_source_delegate_->Buffered(); | |
| 572 return buffered_; | 486 return buffered_; |
| 573 } | 487 } |
| 574 | 488 |
| 575 blink::WebTimeRanges WebMediaPlayerAndroid::seekable() const { | 489 blink::WebTimeRanges WebMediaPlayerAndroid::seekable() const { |
| 576 if (ready_state_ < WebMediaPlayer::ReadyStateHaveMetadata) | 490 if (ready_state_ < WebMediaPlayer::ReadyStateHaveMetadata) |
| 577 return blink::WebTimeRanges(); | 491 return blink::WebTimeRanges(); |
| 578 | 492 |
| 579 // TODO(dalecurtis): Technically this allows seeking on media which return an | 493 // TODO(dalecurtis): Technically this allows seeking on media which return an |
| 580 // infinite duration. While not expected, disabling this breaks semi-live | 494 // infinite duration. While not expected, disabling this breaks semi-live |
| 581 // players, http://crbug.com/427412. | 495 // players, http://crbug.com/427412. |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 734 if (info_loader_) | 648 if (info_loader_) |
| 735 return info_loader_->DidPassCORSAccessCheck(); | 649 return info_loader_->DidPassCORSAccessCheck(); |
| 736 return false; | 650 return false; |
| 737 } | 651 } |
| 738 | 652 |
| 739 double WebMediaPlayerAndroid::mediaTimeForTimeValue(double timeValue) const { | 653 double WebMediaPlayerAndroid::mediaTimeForTimeValue(double timeValue) const { |
| 740 return base::TimeDelta::FromSecondsD(timeValue).InSecondsF(); | 654 return base::TimeDelta::FromSecondsD(timeValue).InSecondsF(); |
| 741 } | 655 } |
| 742 | 656 |
| 743 unsigned WebMediaPlayerAndroid::decodedFrameCount() const { | 657 unsigned WebMediaPlayerAndroid::decodedFrameCount() const { |
| 744 if (media_source_delegate_) | |
| 745 return media_source_delegate_->DecodedFrameCount(); | |
| 746 NOTIMPLEMENTED(); | 658 NOTIMPLEMENTED(); |
| 747 return 0; | 659 return 0; |
| 748 } | 660 } |
| 749 | 661 |
| 750 unsigned WebMediaPlayerAndroid::droppedFrameCount() const { | 662 unsigned WebMediaPlayerAndroid::droppedFrameCount() const { |
| 751 if (media_source_delegate_) | |
| 752 return media_source_delegate_->DroppedFrameCount(); | |
| 753 NOTIMPLEMENTED(); | 663 NOTIMPLEMENTED(); |
| 754 return 0; | 664 return 0; |
| 755 } | 665 } |
| 756 | 666 |
| 757 size_t WebMediaPlayerAndroid::audioDecodedByteCount() const { | 667 size_t WebMediaPlayerAndroid::audioDecodedByteCount() const { |
| 758 if (media_source_delegate_) | |
| 759 return media_source_delegate_->AudioDecodedByteCount(); | |
| 760 NOTIMPLEMENTED(); | 668 NOTIMPLEMENTED(); |
| 761 return 0; | 669 return 0; |
| 762 } | 670 } |
| 763 | 671 |
| 764 size_t WebMediaPlayerAndroid::videoDecodedByteCount() const { | 672 size_t WebMediaPlayerAndroid::videoDecodedByteCount() const { |
| 765 if (media_source_delegate_) | |
| 766 return media_source_delegate_->VideoDecodedByteCount(); | |
| 767 NOTIMPLEMENTED(); | 673 NOTIMPLEMENTED(); |
| 768 return 0; | 674 return 0; |
| 769 } | 675 } |
| 770 | 676 |
| 771 void WebMediaPlayerAndroid::OnMediaMetadataChanged( | 677 void WebMediaPlayerAndroid::OnMediaMetadataChanged( |
| 772 base::TimeDelta duration, int width, int height, bool success) { | 678 base::TimeDelta duration, int width, int height, bool success) { |
| 773 DCHECK(main_thread_checker_.CalledOnValidThread()); | 679 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 774 bool need_to_signal_duration_changed = false; | 680 bool need_to_signal_duration_changed = false; |
| 775 | 681 |
| 776 if (is_local_resource_) | 682 if (is_local_resource_) |
| 777 UpdateNetworkState(WebMediaPlayer::NetworkStateLoaded); | 683 UpdateNetworkState(WebMediaPlayer::NetworkStateLoaded); |
| 778 | 684 |
| 779 // For HLS streams, the reported duration may be zero for infinite streams. | 685 // For HLS streams, the reported duration may be zero for infinite streams. |
| 780 // See http://crbug.com/501213. | 686 // See http://crbug.com/501213. |
| 781 if (duration.is_zero() && IsHLSStream()) | 687 if (duration.is_zero() && IsHLSStream()) |
| 782 duration = media::kInfiniteDuration; | 688 duration = media::kInfiniteDuration; |
| 783 | 689 |
| 784 // Update duration, if necessary, prior to ready state updates that may | 690 // Update duration, if necessary, prior to ready state updates that may |
| 785 // cause duration() query. | 691 // cause duration() query. |
| 786 if (!ignore_metadata_duration_change_ && duration_ != duration) { | 692 if (!ignore_metadata_duration_change_ && duration_ != duration) { |
| 787 duration_ = duration; | 693 duration_ = duration; |
| 788 if (is_local_resource_) | 694 if (is_local_resource_) |
| 789 buffered_[0].end = duration_.InSecondsF(); | 695 buffered_[0].end = duration_.InSecondsF(); |
| 790 // Client readyState transition from HAVE_NOTHING to HAVE_METADATA | 696 // Client readyState transition from HAVE_NOTHING to HAVE_METADATA |
| 791 // already triggers a durationchanged event. If this is a different | 697 // already triggers a durationchanged event. If this is a different |
| 792 // transition, remember to signal durationchanged. | 698 // transition, remember to signal durationchanged. |
| 793 // Do not ever signal durationchanged on metadata change in MSE case | 699 if (ready_state_ > WebMediaPlayer::ReadyStateHaveNothing) |
| 794 // because OnDurationChanged() handles this. | |
| 795 if (ready_state_ > WebMediaPlayer::ReadyStateHaveNothing && | |
| 796 player_type_ != MEDIA_PLAYER_TYPE_MEDIA_SOURCE) { | |
| 797 need_to_signal_duration_changed = true; | 700 need_to_signal_duration_changed = true; |
| 798 } | |
| 799 } | 701 } |
| 800 | 702 |
| 801 if (ready_state_ != WebMediaPlayer::ReadyStateHaveEnoughData) { | 703 if (ready_state_ != WebMediaPlayer::ReadyStateHaveEnoughData) { |
| 802 UpdateReadyState(WebMediaPlayer::ReadyStateHaveMetadata); | 704 UpdateReadyState(WebMediaPlayer::ReadyStateHaveMetadata); |
| 803 UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); | 705 UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); |
| 804 } | 706 } |
| 805 | 707 |
| 806 // TODO(wolenetz): Should we just abort early and set network state to an | 708 // TODO(wolenetz): Should we just abort early and set network state to an |
| 807 // error if success == false? See http://crbug.com/248399 | 709 // error if success == false? See http://crbug.com/248399 |
| 808 if (success) | 710 if (success) |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1008 void WebMediaPlayerAndroid::OnMediaPlayerPause() { | 910 void WebMediaPlayerAndroid::OnMediaPlayerPause() { |
| 1009 UpdatePlayingState(false); | 911 UpdatePlayingState(false); |
| 1010 client_->playbackStateChanged(); | 912 client_->playbackStateChanged(); |
| 1011 } | 913 } |
| 1012 | 914 |
| 1013 void WebMediaPlayerAndroid::OnRemoteRouteAvailabilityChanged( | 915 void WebMediaPlayerAndroid::OnRemoteRouteAvailabilityChanged( |
| 1014 bool routes_available) { | 916 bool routes_available) { |
| 1015 client_->remoteRouteAvailabilityChanged(routes_available); | 917 client_->remoteRouteAvailabilityChanged(routes_available); |
| 1016 } | 918 } |
| 1017 | 919 |
| 1018 void WebMediaPlayerAndroid::OnDurationChanged(const base::TimeDelta& duration) { | |
| 1019 DCHECK(main_thread_checker_.CalledOnValidThread()); | |
| 1020 // Only MSE |player_type_| registers this callback. | |
| 1021 DCHECK_EQ(player_type_, MEDIA_PLAYER_TYPE_MEDIA_SOURCE); | |
| 1022 | |
| 1023 // Cache the new duration value and trust it over any subsequent duration | |
| 1024 // values received in OnMediaMetadataChanged(). | |
| 1025 duration_ = duration; | |
| 1026 ignore_metadata_duration_change_ = true; | |
| 1027 | |
| 1028 // Notify MediaPlayerClient that duration has changed, if > HAVE_NOTHING. | |
| 1029 if (ready_state_ > WebMediaPlayer::ReadyStateHaveNothing) | |
| 1030 client_->durationChanged(); | |
| 1031 } | |
| 1032 | |
| 1033 void WebMediaPlayerAndroid::UpdateNetworkState( | 920 void WebMediaPlayerAndroid::UpdateNetworkState( |
| 1034 WebMediaPlayer::NetworkState state) { | 921 WebMediaPlayer::NetworkState state) { |
| 1035 DCHECK(main_thread_checker_.CalledOnValidThread()); | 922 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 1036 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing && | 923 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing && |
| 1037 (state == WebMediaPlayer::NetworkStateNetworkError || | 924 (state == WebMediaPlayer::NetworkStateNetworkError || |
| 1038 state == WebMediaPlayer::NetworkStateDecodeError)) { | 925 state == WebMediaPlayer::NetworkStateDecodeError)) { |
| 1039 // Any error that occurs before reaching ReadyStateHaveMetadata should | 926 // Any error that occurs before reaching ReadyStateHaveMetadata should |
| 1040 // be considered a format error. | 927 // be considered a format error. |
| 1041 network_state_ = WebMediaPlayer::NetworkStateFormatError; | 928 network_state_ = WebMediaPlayer::NetworkStateFormatError; |
| 1042 } else { | 929 } else { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1082 case WebMediaPlayer::NetworkStateDecodeError: | 969 case WebMediaPlayer::NetworkStateDecodeError: |
| 1083 break; | 970 break; |
| 1084 } | 971 } |
| 1085 player_manager_->SuspendAndReleaseResources(player_id_); | 972 player_manager_->SuspendAndReleaseResources(player_id_); |
| 1086 SetNeedsEstablishPeer(true); | 973 SetNeedsEstablishPeer(true); |
| 1087 } | 974 } |
| 1088 | 975 |
| 1089 void WebMediaPlayerAndroid::InitializePlayer( | 976 void WebMediaPlayerAndroid::InitializePlayer( |
| 1090 const GURL& url, | 977 const GURL& url, |
| 1091 const GURL& first_party_for_cookies, | 978 const GURL& first_party_for_cookies, |
| 1092 bool allow_stored_credentials, | 979 bool allow_stored_credentials) { |
| 1093 int demuxer_client_id) { | |
| 1094 ReportHLSMetrics(); | 980 ReportHLSMetrics(); |
| 1095 | 981 |
| 1096 allow_stored_credentials_ = allow_stored_credentials; | 982 allow_stored_credentials_ = allow_stored_credentials; |
| 1097 player_manager_->Initialize( | 983 player_manager_->Initialize(player_type_, player_id_, url, |
| 1098 player_type_, player_id_, url, first_party_for_cookies, demuxer_client_id, | 984 first_party_for_cookies, frame_->document().url(), |
| 1099 frame_->document().url(), allow_stored_credentials, delegate_id_); | 985 allow_stored_credentials, delegate_id_); |
| 1100 is_player_initialized_ = true; | 986 is_player_initialized_ = true; |
| 1101 | 987 |
| 1102 if (is_fullscreen_) | 988 if (is_fullscreen_) |
| 1103 player_manager_->EnterFullscreen(player_id_); | 989 player_manager_->EnterFullscreen(player_id_); |
| 1104 | |
| 1105 if (cdm_context_) | |
| 1106 SetCdmInternal(base::Bind(&media::IgnoreCdmAttached)); | |
| 1107 } | 990 } |
| 1108 | 991 |
| 1109 void WebMediaPlayerAndroid::Pause(bool is_media_related_action) { | 992 void WebMediaPlayerAndroid::Pause(bool is_media_related_action) { |
| 1110 player_manager_->Pause(player_id_, is_media_related_action); | 993 player_manager_->Pause(player_id_, is_media_related_action); |
| 1111 UpdatePlayingState(false); | 994 UpdatePlayingState(false); |
| 1112 } | 995 } |
| 1113 | 996 |
| 1114 void WebMediaPlayerAndroid::DrawRemotePlaybackText( | 997 void WebMediaPlayerAndroid::DrawRemotePlaybackText( |
| 1115 const std::string& remote_playback_message) { | 998 const std::string& remote_playback_message) { |
| 1116 DCHECK(main_thread_checker_.CalledOnValidThread()); | 999 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1346 playback_completed_ || currentTime() >= duration()); | 1229 playback_completed_ || currentTime() >= duration()); |
| 1347 } | 1230 } |
| 1348 } | 1231 } |
| 1349 } | 1232 } |
| 1350 | 1233 |
| 1351 void WebMediaPlayerAndroid::setContentDecryptionModule( | 1234 void WebMediaPlayerAndroid::setContentDecryptionModule( |
| 1352 blink::WebContentDecryptionModule* cdm, | 1235 blink::WebContentDecryptionModule* cdm, |
| 1353 blink::WebContentDecryptionModuleResult result) { | 1236 blink::WebContentDecryptionModuleResult result) { |
| 1354 DCHECK(main_thread_checker_.CalledOnValidThread()); | 1237 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 1355 | 1238 |
| 1356 // Once the CDM is set it can't be cleared as there may be frames being | |
| 1357 // decrypted on other threads. So fail this request. | |
| 1358 // http://crbug.com/462365#c7. | |
| 1359 if (!cdm) { | |
| 1360 result.completeWithError( | |
| 1361 blink::WebContentDecryptionModuleExceptionInvalidStateError, 0, | |
| 1362 "The existing MediaKeys object cannot be removed at this time."); | |
| 1363 return; | |
| 1364 } | |
| 1365 | |
| 1366 cdm_context_ = media::ToWebContentDecryptionModuleImpl(cdm)->GetCdmContext(); | |
| 1367 | |
| 1368 if (is_player_initialized_) { | |
| 1369 SetCdmInternal( | |
| 1370 base::Bind(&WebMediaPlayerAndroid::ContentDecryptionModuleAttached, | |
| 1371 weak_factory_.GetWeakPtr(), result)); | |
| 1372 } else { | |
| 1373 // No pipeline/decoder connected, so resolve the promise. When something | |
| 1374 // is connected, setting the CDM will happen in SetCdmReadyCB(). | |
| 1375 ContentDecryptionModuleAttached(result, true); | |
| 1376 } | |
| 1377 } | |
| 1378 | |
| 1379 void WebMediaPlayerAndroid::ContentDecryptionModuleAttached( | |
| 1380 blink::WebContentDecryptionModuleResult result, | |
| 1381 bool success) { | |
| 1382 if (success) { | |
| 1383 result.complete(); | |
| 1384 return; | |
| 1385 } | |
| 1386 | |
| 1387 result.completeWithError( | 1239 result.completeWithError( |
| 1388 blink::WebContentDecryptionModuleExceptionNotSupportedError, | 1240 blink::WebContentDecryptionModuleExceptionInvalidStateError, 0, |
|
wolenetz
2016/09/30 23:23:24
nit: blink::WebContentDecryptionModuleExceptionNot
DaleCurtis
2016/09/30 23:34:24
Deleted.
| |
| 1389 0, | 1241 "EME is not supported for this playback."); |
| 1390 "Unable to set MediaKeys object"); | |
| 1391 } | |
| 1392 | |
| 1393 void WebMediaPlayerAndroid::OnMediaSourceOpened( | |
| 1394 blink::WebMediaSource* web_media_source) { | |
| 1395 client_->mediaSourceOpened(web_media_source); | |
| 1396 } | |
| 1397 | |
| 1398 void WebMediaPlayerAndroid::OnEncryptedMediaInitData( | |
| 1399 media::EmeInitDataType init_data_type, | |
| 1400 const std::vector<uint8_t>& init_data) { | |
| 1401 DCHECK(main_thread_checker_.CalledOnValidThread()); | |
| 1402 | |
| 1403 // TODO(xhwang): Update this UMA name. https://crbug.com/589251 | |
| 1404 UMA_HISTOGRAM_COUNTS("Media.EME.NeedKey", 1); | |
| 1405 | |
| 1406 DCHECK(init_data_type != media::EmeInitDataType::UNKNOWN); | |
| 1407 | |
| 1408 encrypted_client_->encrypted(ConvertToWebInitDataType(init_data_type), | |
| 1409 init_data.data(), init_data.size()); | |
| 1410 } | |
| 1411 | |
| 1412 void WebMediaPlayerAndroid::OnWaitingForDecryptionKey() { | |
| 1413 encrypted_client_->didBlockPlaybackWaitingForKey(); | |
| 1414 | |
| 1415 // TODO(jrummell): didResumePlaybackBlockedForKey() should only be called | |
| 1416 // when a key has been successfully added (e.g. OnSessionKeysChange() with | |
| 1417 // |has_additional_usable_key| = true). http://crbug.com/461903 | |
| 1418 encrypted_client_->didResumePlaybackBlockedForKey(); | |
| 1419 } | 1242 } |
| 1420 | 1243 |
| 1421 void WebMediaPlayerAndroid::OnHidden() { | 1244 void WebMediaPlayerAndroid::OnHidden() { |
| 1422 // Pause audible video preserving its session. | 1245 // Pause audible video preserving its session. |
| 1423 if (hasVideo() && IsBackgroundVideoCandidate() && !paused()) { | 1246 if (hasVideo() && IsBackgroundVideoCandidate() && !paused()) { |
| 1424 Pause(false); | 1247 Pause(false); |
| 1425 is_play_pending_ = true; | 1248 is_play_pending_ = true; |
| 1426 return; | 1249 return; |
| 1427 } | 1250 } |
| 1428 | 1251 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1457 void WebMediaPlayerAndroid::OnPause() { | 1280 void WebMediaPlayerAndroid::OnPause() { |
| 1458 pause(); | 1281 pause(); |
| 1459 client_->playbackStateChanged(); | 1282 client_->playbackStateChanged(); |
| 1460 } | 1283 } |
| 1461 | 1284 |
| 1462 void WebMediaPlayerAndroid::OnVolumeMultiplierUpdate(double multiplier) { | 1285 void WebMediaPlayerAndroid::OnVolumeMultiplierUpdate(double multiplier) { |
| 1463 volume_multiplier_ = multiplier; | 1286 volume_multiplier_ = multiplier; |
| 1464 setVolume(volume_); | 1287 setVolume(volume_); |
| 1465 } | 1288 } |
| 1466 | 1289 |
| 1467 void WebMediaPlayerAndroid::OnCdmContextReady(media::CdmContext* cdm_context) { | |
| 1468 DCHECK(!cdm_context_); | |
| 1469 | |
| 1470 if (!cdm_context) { | |
| 1471 LOG(ERROR) << "CdmContext not available (e.g. CDM creation failed)."; | |
| 1472 return; | |
| 1473 } | |
| 1474 | |
| 1475 cdm_context_ = cdm_context; | |
| 1476 | |
| 1477 if (is_player_initialized_) | |
| 1478 SetCdmInternal(base::Bind(&media::IgnoreCdmAttached)); | |
| 1479 } | |
| 1480 | |
| 1481 void WebMediaPlayerAndroid::SetCdmInternal( | |
| 1482 const media::CdmAttachedCB& cdm_attached_cb) { | |
| 1483 DCHECK(main_thread_checker_.CalledOnValidThread()); | |
| 1484 DCHECK(cdm_context_ && is_player_initialized_); | |
| 1485 DCHECK(cdm_context_->GetDecryptor() || | |
| 1486 cdm_context_->GetCdmId() != media::CdmContext::kInvalidCdmId) | |
| 1487 << "CDM should support either a Decryptor or a CDM ID."; | |
| 1488 | |
| 1489 if (cdm_ready_cb_.is_null()) { | |
| 1490 cdm_attached_cb.Run(true); | |
| 1491 return; | |
| 1492 } | |
| 1493 | |
| 1494 // Satisfy |cdm_ready_cb_|. Use BindToCurrentLoop() since the callback could | |
| 1495 // be fired on other threads. | |
| 1496 base::ResetAndReturn(&cdm_ready_cb_) | |
| 1497 .Run(cdm_context_, media::BindToCurrentLoop(base::Bind( | |
| 1498 &WebMediaPlayerAndroid::OnCdmAttached, | |
| 1499 weak_factory_.GetWeakPtr(), cdm_attached_cb))); | |
| 1500 } | |
| 1501 | |
| 1502 void WebMediaPlayerAndroid::OnCdmAttached( | |
| 1503 const media::CdmAttachedCB& cdm_attached_cb, | |
| 1504 bool success) { | |
| 1505 DVLOG(1) << __FUNCTION__ << ": success: " << success; | |
| 1506 DCHECK(main_thread_checker_.CalledOnValidThread()); | |
| 1507 | |
| 1508 if (!success) { | |
| 1509 if (cdm_context_->GetCdmId() == media::CdmContext::kInvalidCdmId) { | |
| 1510 NOTREACHED() << "CDM cannot be attached to media player."; | |
| 1511 cdm_attached_cb.Run(false); | |
| 1512 return; | |
| 1513 } | |
| 1514 | |
| 1515 // If the CDM is not attached (e.g. the CDM does not support a Decryptor), | |
| 1516 // MediaSourceDelegate will fall back to use a browser side (IPC-based) CDM. | |
| 1517 player_manager_->SetCdm(player_id_, cdm_context_->GetCdmId()); | |
| 1518 } | |
| 1519 | |
| 1520 cdm_attached_cb.Run(true); | |
| 1521 } | |
| 1522 | |
| 1523 void WebMediaPlayerAndroid::SetCdmReadyCB( | |
| 1524 const MediaSourceDelegate::CdmReadyCB& cdm_ready_cb) { | |
| 1525 DCHECK(main_thread_checker_.CalledOnValidThread()); | |
| 1526 DCHECK(is_player_initialized_); | |
| 1527 | |
| 1528 // Cancels the previous CDM request. | |
| 1529 if (cdm_ready_cb.is_null()) { | |
| 1530 if (!cdm_ready_cb_.is_null()) { | |
| 1531 base::ResetAndReturn(&cdm_ready_cb_) | |
| 1532 .Run(nullptr, base::Bind(&media::IgnoreCdmAttached)); | |
| 1533 } | |
| 1534 return; | |
| 1535 } | |
| 1536 | |
| 1537 // TODO(xhwang): Support multiple CDM notification request (e.g. from | |
| 1538 // video and audio). The current implementation is okay for the current | |
| 1539 // media pipeline since we initialize audio and video decoders in sequence. | |
| 1540 // But WebMediaPlayerAndroid should not depend on media pipeline's | |
| 1541 // implementation detail. | |
| 1542 DCHECK(cdm_ready_cb_.is_null()); | |
| 1543 cdm_ready_cb_ = cdm_ready_cb; | |
| 1544 | |
| 1545 if (cdm_context_) | |
| 1546 SetCdmInternal(base::Bind(&media::IgnoreCdmAttached)); | |
| 1547 } | |
| 1548 | |
| 1549 bool WebMediaPlayerAndroid::supportsOverlayFullscreenVideo() { | 1290 bool WebMediaPlayerAndroid::supportsOverlayFullscreenVideo() { |
| 1550 return true; | 1291 return true; |
| 1551 } | 1292 } |
| 1552 | 1293 |
| 1553 void WebMediaPlayerAndroid::enteredFullscreen() { | 1294 void WebMediaPlayerAndroid::enteredFullscreen() { |
| 1554 if (is_player_initialized_) | 1295 if (is_player_initialized_) |
| 1555 player_manager_->EnterFullscreen(player_id_); | 1296 player_manager_->EnterFullscreen(player_id_); |
| 1556 SetNeedsEstablishPeer(false); | 1297 SetNeedsEstablishPeer(false); |
| 1557 is_fullscreen_ = true; | 1298 is_fullscreen_ = true; |
| 1558 suppress_deleting_texture_ = false; | 1299 suppress_deleting_texture_ = false; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1606 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 1347 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 1607 switches::kDisableMediaSuspend)) { | 1348 switches::kDisableMediaSuspend)) { |
| 1608 return false; | 1349 return false; |
| 1609 } | 1350 } |
| 1610 | 1351 |
| 1611 return base::FeatureList::IsEnabled(media::kResumeBackgroundVideo) && | 1352 return base::FeatureList::IsEnabled(media::kResumeBackgroundVideo) && |
| 1612 hasAudio() && !isRemote() && delegate_ && delegate_->IsHidden(); | 1353 hasAudio() && !isRemote() && delegate_ && delegate_->IsHidden(); |
| 1613 } | 1354 } |
| 1614 | 1355 |
| 1615 } // namespace content | 1356 } // namespace content |
| OLD | NEW |