| 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 "media/blink/webmediaplayer_impl.h" | 5 #include "media/blink/webmediaplayer_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <limits> | 9 #include <limits> |
| 10 #include <string> | 10 #include <string> |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 suspend_enabled_(params.allow_suspend()), | 234 suspend_enabled_(params.allow_suspend()), |
| 235 use_fallback_path_(false), | 235 use_fallback_path_(false), |
| 236 is_encrypted_(false), | 236 is_encrypted_(false), |
| 237 underflow_count_(0), | 237 underflow_count_(0), |
| 238 preroll_attempt_pending_(false), | 238 preroll_attempt_pending_(false), |
| 239 observer_(params.media_observer()), | 239 observer_(params.media_observer()), |
| 240 max_keyframe_distance_to_disable_background_video_( | 240 max_keyframe_distance_to_disable_background_video_( |
| 241 params.max_keyframe_distance_to_disable_background_video()), | 241 params.max_keyframe_distance_to_disable_background_video()), |
| 242 enable_instant_source_buffer_gc_( | 242 enable_instant_source_buffer_gc_( |
| 243 params.enable_instant_source_buffer_gc()) { | 243 params.enable_instant_source_buffer_gc()) { |
| 244 DVLOG(1) << __func__; |
| 244 DCHECK(!adjust_allocated_memory_cb_.is_null()); | 245 DCHECK(!adjust_allocated_memory_cb_.is_null()); |
| 245 DCHECK(renderer_factory_); | 246 DCHECK(renderer_factory_); |
| 246 DCHECK(client_); | 247 DCHECK(client_); |
| 247 DCHECK(delegate_); | 248 DCHECK(delegate_); |
| 248 | 249 |
| 249 tick_clock_.reset(new base::DefaultTickClock()); | 250 tick_clock_.reset(new base::DefaultTickClock()); |
| 250 | 251 |
| 251 force_video_overlays_ = base::CommandLine::ForCurrentProcess()->HasSwitch( | 252 force_video_overlays_ = base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 252 switches::kForceVideoOverlays); | 253 switches::kForceVideoOverlays); |
| 253 | 254 |
| 254 enable_fullscreen_video_overlays_ = | 255 enable_fullscreen_video_overlays_ = |
| 255 base::FeatureList::IsEnabled(media::kOverlayFullscreenVideo); | 256 base::FeatureList::IsEnabled(media::kOverlayFullscreenVideo); |
| 256 | 257 |
| 257 delegate_id_ = delegate_->AddObserver(this); | 258 delegate_id_ = delegate_->AddObserver(this); |
| 258 delegate_->SetIdle(delegate_id_, true); | 259 delegate_->SetIdle(delegate_id_, true); |
| 259 | 260 |
| 260 media_log_->AddEvent( | 261 media_log_->AddEvent( |
| 261 media_log_->CreateEvent(MediaLogEvent::WEBMEDIAPLAYER_CREATED)); | 262 media_log_->CreateEvent(MediaLogEvent::WEBMEDIAPLAYER_CREATED)); |
| 262 | 263 |
| 263 if (params.initial_cdm()) | 264 if (params.initial_cdm()) |
| 264 SetCdm(params.initial_cdm()); | 265 SetCdm(params.initial_cdm()); |
| 265 | 266 |
| 266 // TODO(xhwang): When we use an external Renderer, many methods won't work, | 267 // TODO(xhwang): When we use an external Renderer, many methods won't work, |
| 267 // e.g. GetCurrentFrameFromCompositor(). See http://crbug.com/434861 | 268 // e.g. GetCurrentFrameFromCompositor(). See http://crbug.com/434861 |
| 268 audio_source_provider_ = | 269 audio_source_provider_ = |
| 269 new WebAudioSourceProviderImpl(params.audio_renderer_sink(), media_log_); | 270 new WebAudioSourceProviderImpl(params.audio_renderer_sink(), media_log_); |
| 270 } | 271 } |
| 271 | 272 |
| 272 WebMediaPlayerImpl::~WebMediaPlayerImpl() { | 273 WebMediaPlayerImpl::~WebMediaPlayerImpl() { |
| 274 DVLOG(1) << __func__; |
| 273 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 275 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 274 | 276 |
| 277 if (set_cdm_result_) { |
| 278 DVLOG(2) << "Resolve pending SetCdm() when media player is destroyed."; |
| 279 set_cdm_result_->complete(); |
| 280 set_cdm_result_.reset(); |
| 281 } |
| 282 |
| 275 suppress_destruction_errors_ = true; | 283 suppress_destruction_errors_ = true; |
| 276 | 284 |
| 277 delegate_->PlayerGone(delegate_id_); | 285 delegate_->PlayerGone(delegate_id_); |
| 278 delegate_->RemoveObserver(delegate_id_); | 286 delegate_->RemoveObserver(delegate_id_); |
| 279 | 287 |
| 280 // Finalize any watch time metrics before destroying the pipeline. | 288 // Finalize any watch time metrics before destroying the pipeline. |
| 281 watch_time_reporter_.reset(); | 289 watch_time_reporter_.reset(); |
| 282 | 290 |
| 283 // Pipeline must be stopped before it is destroyed. | 291 // Pipeline must be stopped before it is destroyed. |
| 284 pipeline_.Stop(); | 292 pipeline_.Stop(); |
| 285 | 293 |
| 286 if (last_reported_memory_usage_) | 294 if (last_reported_memory_usage_) |
| 287 adjust_allocated_memory_cb_.Run(-last_reported_memory_usage_); | 295 adjust_allocated_memory_cb_.Run(-last_reported_memory_usage_); |
| 288 | 296 |
| 289 // Destruct compositor resources in the proper order. | 297 // Destruct compositor resources in the proper order. |
| 290 client_->setWebLayer(nullptr); | 298 client_->setWebLayer(nullptr); |
| 291 if (video_weblayer_) | 299 if (video_weblayer_) |
| 292 static_cast<cc::VideoLayer*>(video_weblayer_->layer())->StopUsingProvider(); | 300 static_cast<cc::VideoLayer*>(video_weblayer_->layer())->StopUsingProvider(); |
| 293 compositor_task_runner_->DeleteSoon(FROM_HERE, compositor_); | 301 compositor_task_runner_->DeleteSoon(FROM_HERE, compositor_); |
| 294 | 302 |
| 295 media_log_->AddEvent( | 303 media_log_->AddEvent( |
| 296 media_log_->CreateEvent(MediaLogEvent::WEBMEDIAPLAYER_DESTROYED)); | 304 media_log_->CreateEvent(MediaLogEvent::WEBMEDIAPLAYER_DESTROYED)); |
| 297 } | 305 } |
| 298 | 306 |
| 299 void WebMediaPlayerImpl::load(LoadType load_type, | 307 void WebMediaPlayerImpl::load(LoadType load_type, |
| 300 const blink::WebMediaPlayerSource& source, | 308 const blink::WebMediaPlayerSource& source, |
| 301 CORSMode cors_mode) { | 309 CORSMode cors_mode) { |
| 310 DVLOG(1) << __func__; |
| 302 // Only URL or MSE blob URL is supported. | 311 // Only URL or MSE blob URL is supported. |
| 303 DCHECK(source.isURL()); | 312 DCHECK(source.isURL()); |
| 304 blink::WebURL url = source.getAsURL(); | 313 blink::WebURL url = source.getAsURL(); |
| 305 DVLOG(1) << __func__ << "(" << load_type << ", " << url << ", " << cors_mode | 314 DVLOG(1) << __func__ << "(" << load_type << ", " << url << ", " << cors_mode |
| 306 << ")"; | 315 << ")"; |
| 307 if (!defer_load_cb_.is_null()) { | 316 if (!defer_load_cb_.is_null()) { |
| 308 defer_load_cb_.Run(base::Bind( | 317 defer_load_cb_.Run(base::Bind( |
| 309 &WebMediaPlayerImpl::DoLoad, AsWeakPtr(), load_type, url, cors_mode)); | 318 &WebMediaPlayerImpl::DoLoad, AsWeakPtr(), load_type, url, cors_mode)); |
| 310 return; | 319 return; |
| 311 } | 320 } |
| (...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 951 Context3D context_3d; | 960 Context3D context_3d; |
| 952 if (!context_3d_cb_.is_null()) | 961 if (!context_3d_cb_.is_null()) |
| 953 context_3d = context_3d_cb_.Run(); | 962 context_3d = context_3d_cb_.Run(); |
| 954 return skcanvas_video_renderer_.CopyVideoFrameTexturesToGLTexture( | 963 return skcanvas_video_renderer_.CopyVideoFrameTexturesToGLTexture( |
| 955 context_3d, gl, video_frame.get(), texture, premultiply_alpha, flip_y); | 964 context_3d, gl, video_frame.get(), texture, premultiply_alpha, flip_y); |
| 956 } | 965 } |
| 957 | 966 |
| 958 void WebMediaPlayerImpl::setContentDecryptionModule( | 967 void WebMediaPlayerImpl::setContentDecryptionModule( |
| 959 blink::WebContentDecryptionModule* cdm, | 968 blink::WebContentDecryptionModule* cdm, |
| 960 blink::WebContentDecryptionModuleResult result) { | 969 blink::WebContentDecryptionModuleResult result) { |
| 970 DVLOG(1) << __func__ << ": cdm = " << cdm; |
| 961 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 971 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 962 | 972 |
| 963 // Once the CDM is set it can't be cleared as there may be frames being | 973 // Once the CDM is set it can't be cleared as there may be frames being |
| 964 // decrypted on other threads. So fail this request. | 974 // decrypted on other threads. So fail this request. |
| 965 // http://crbug.com/462365#c7. | 975 // http://crbug.com/462365#c7. |
| 966 if (!cdm) { | 976 if (!cdm) { |
| 967 result.completeWithError( | 977 result.completeWithError( |
| 968 blink::WebContentDecryptionModuleExceptionInvalidStateError, 0, | 978 blink::WebContentDecryptionModuleExceptionInvalidStateError, 0, |
| 969 "The existing ContentDecryptionModule object cannot be removed at this " | 979 "The existing ContentDecryptionModule object cannot be removed at this " |
| 970 "time."); | 980 "time."); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1055 observer_->OnSetCdm(cdm_context); | 1065 observer_->OnSetCdm(cdm_context); |
| 1056 | 1066 |
| 1057 // Keep the reference to the CDM, as it shouldn't be destroyed until | 1067 // Keep the reference to the CDM, as it shouldn't be destroyed until |
| 1058 // after the pipeline is done with the |cdm_context|. | 1068 // after the pipeline is done with the |cdm_context|. |
| 1059 pending_cdm_ = std::move(cdm_reference); | 1069 pending_cdm_ = std::move(cdm_reference); |
| 1060 pipeline_.SetCdm(cdm_context, | 1070 pipeline_.SetCdm(cdm_context, |
| 1061 base::Bind(&WebMediaPlayerImpl::OnCdmAttached, AsWeakPtr())); | 1071 base::Bind(&WebMediaPlayerImpl::OnCdmAttached, AsWeakPtr())); |
| 1062 } | 1072 } |
| 1063 | 1073 |
| 1064 void WebMediaPlayerImpl::OnCdmAttached(bool success) { | 1074 void WebMediaPlayerImpl::OnCdmAttached(bool success) { |
| 1075 DVLOG(1) << __func__ << ": success = " << success; |
| 1065 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1076 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1066 DCHECK(pending_cdm_); | 1077 DCHECK(pending_cdm_); |
| 1067 | 1078 |
| 1068 // If the CDM is set from the constructor there is no promise | 1079 // If the CDM is set from the constructor there is no promise |
| 1069 // (|set_cdm_result_|) to fulfill. | 1080 // (|set_cdm_result_|) to fulfill. |
| 1070 if (success) { | 1081 if (success) { |
| 1071 // This will release the previously attached CDM (if any). | 1082 // This will release the previously attached CDM (if any). |
| 1072 cdm_ = std::move(pending_cdm_); | 1083 cdm_ = std::move(pending_cdm_); |
| 1073 if (set_cdm_result_) { | 1084 if (set_cdm_result_) { |
| 1074 set_cdm_result_->complete(); | 1085 set_cdm_result_->complete(); |
| (...skipping 1210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2285 UMA_HISTOGRAM_TIMES( | 2296 UMA_HISTOGRAM_TIMES( |
| 2286 "Media.Video.TimeFromForegroundToFirstFrame.DisableTrack", | 2297 "Media.Video.TimeFromForegroundToFirstFrame.DisableTrack", |
| 2287 time_to_first_frame); | 2298 time_to_first_frame); |
| 2288 } else { | 2299 } else { |
| 2289 UMA_HISTOGRAM_TIMES("Media.Video.TimeFromForegroundToFirstFrame.Paused", | 2300 UMA_HISTOGRAM_TIMES("Media.Video.TimeFromForegroundToFirstFrame.Paused", |
| 2290 time_to_first_frame); | 2301 time_to_first_frame); |
| 2291 } | 2302 } |
| 2292 } | 2303 } |
| 2293 | 2304 |
| 2294 } // namespace media | 2305 } // namespace media |
| OLD | NEW |