| 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 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 base::Bind(&WebMediaPlayerImpl::OnPipelineSuspended, AsWeakPtr()), | 172 base::Bind(&WebMediaPlayerImpl::OnPipelineSuspended, AsWeakPtr()), |
| 173 base::Bind(&WebMediaPlayerImpl::OnError, AsWeakPtr())), | 173 base::Bind(&WebMediaPlayerImpl::OnError, AsWeakPtr())), |
| 174 load_type_(LoadTypeURL), | 174 load_type_(LoadTypeURL), |
| 175 opaque_(false), | 175 opaque_(false), |
| 176 playback_rate_(0.0), | 176 playback_rate_(0.0), |
| 177 paused_(true), | 177 paused_(true), |
| 178 seeking_(false), | 178 seeking_(false), |
| 179 pending_suspend_resume_cycle_(false), | 179 pending_suspend_resume_cycle_(false), |
| 180 ended_(false), | 180 ended_(false), |
| 181 should_notify_time_changed_(false), | 181 should_notify_time_changed_(false), |
| 182 fullscreen_(false), | 182 overlay_enabled_(false), |
| 183 decoder_requires_restart_for_fullscreen_(false), | 183 decoder_requires_restart_for_overlay_(false), |
| 184 client_(client), | 184 client_(client), |
| 185 encrypted_client_(encrypted_client), | 185 encrypted_client_(encrypted_client), |
| 186 delegate_(delegate), | 186 delegate_(delegate), |
| 187 delegate_id_(0), | 187 delegate_id_(0), |
| 188 defer_load_cb_(params.defer_load_cb()), | 188 defer_load_cb_(params.defer_load_cb()), |
| 189 context_3d_cb_(params.context_3d_cb()), | 189 context_3d_cb_(params.context_3d_cb()), |
| 190 adjust_allocated_memory_cb_(params.adjust_allocated_memory_cb()), | 190 adjust_allocated_memory_cb_(params.adjust_allocated_memory_cb()), |
| 191 last_reported_memory_usage_(0), | 191 last_reported_memory_usage_(0), |
| 192 supports_save_(true), | 192 supports_save_(true), |
| 193 chunk_demuxer_(NULL), | 193 chunk_demuxer_(NULL), |
| 194 url_index_(url_index), | 194 url_index_(url_index), |
| 195 // Threaded compositing isn't enabled universally yet. | 195 // Threaded compositing isn't enabled universally yet. |
| 196 compositor_task_runner_(params.compositor_task_runner() | 196 compositor_task_runner_(params.compositor_task_runner() |
| 197 ? params.compositor_task_runner() | 197 ? params.compositor_task_runner() |
| 198 : base::ThreadTaskRunnerHandle::Get()), | 198 : base::ThreadTaskRunnerHandle::Get()), |
| 199 compositor_(new VideoFrameCompositor(compositor_task_runner_)), | 199 compositor_(new VideoFrameCompositor(compositor_task_runner_)), |
| 200 is_cdm_attached_(false), | 200 is_cdm_attached_(false), |
| 201 #if defined(OS_ANDROID) // WMPI_CAST | 201 #if defined(OS_ANDROID) // WMPI_CAST |
| 202 cast_impl_(this, client_, params.context_3d_cb()), | 202 cast_impl_(this, client_, params.context_3d_cb()), |
| 203 #endif | 203 #endif |
| 204 volume_(1.0), | 204 volume_(1.0), |
| 205 volume_multiplier_(1.0), | 205 volume_multiplier_(1.0), |
| 206 renderer_factory_(std::move(renderer_factory)), | 206 renderer_factory_(std::move(renderer_factory)), |
| 207 surface_manager_(params.surface_manager()), | 207 surface_manager_(params.surface_manager()), |
| 208 fullscreen_surface_id_(SurfaceManager::kNoSurfaceID), | 208 overlay_surface_id_(SurfaceManager::kNoSurfaceID), |
| 209 suppress_destruction_errors_(false), | 209 suppress_destruction_errors_(false), |
| 210 can_suspend_state_(CanSuspendState::UNKNOWN) { | 210 can_suspend_state_(CanSuspendState::UNKNOWN) { |
| 211 DCHECK(!adjust_allocated_memory_cb_.is_null()); | 211 DCHECK(!adjust_allocated_memory_cb_.is_null()); |
| 212 DCHECK(renderer_factory_); | 212 DCHECK(renderer_factory_); |
| 213 DCHECK(client_); | 213 DCHECK(client_); |
| 214 | 214 |
| 215 force_video_overlays_ = base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 216 switches::kForceVideoOverlays); |
| 217 |
| 215 if (delegate_) | 218 if (delegate_) |
| 216 delegate_id_ = delegate_->AddObserver(this); | 219 delegate_id_ = delegate_->AddObserver(this); |
| 217 | 220 |
| 218 media_log_->AddEvent( | 221 media_log_->AddEvent( |
| 219 media_log_->CreateEvent(MediaLogEvent::WEBMEDIAPLAYER_CREATED)); | 222 media_log_->CreateEvent(MediaLogEvent::WEBMEDIAPLAYER_CREATED)); |
| 220 | 223 |
| 221 if (params.initial_cdm()) { | 224 if (params.initial_cdm()) { |
| 222 SetCdm(base::Bind(&IgnoreCdmAttached), | 225 SetCdm(base::Bind(&IgnoreCdmAttached), |
| 223 ToWebContentDecryptionModuleImpl(params.initial_cdm()) | 226 ToWebContentDecryptionModuleImpl(params.initial_cdm()) |
| 224 ->GetCdmContext()); | 227 ->GetCdmContext()); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 } | 279 } |
| 277 | 280 |
| 278 bool WebMediaPlayerImpl::supportsOverlayFullscreenVideo() { | 281 bool WebMediaPlayerImpl::supportsOverlayFullscreenVideo() { |
| 279 #if defined(OS_ANDROID) | 282 #if defined(OS_ANDROID) |
| 280 return true; | 283 return true; |
| 281 #else | 284 #else |
| 282 return false; | 285 return false; |
| 283 #endif | 286 #endif |
| 284 } | 287 } |
| 285 | 288 |
| 286 void WebMediaPlayerImpl::enteredFullscreen() { | 289 void WebMediaPlayerImpl::EnableOverlay() { |
| 287 fullscreen_ = true; | 290 overlay_enabled_ = true; |
| 288 if (surface_manager_) { | 291 if (surface_manager_) { |
| 289 surface_created_cb_.Reset( | 292 surface_created_cb_.Reset( |
| 290 base::Bind(&WebMediaPlayerImpl::OnSurfaceCreated, AsWeakPtr())); | 293 base::Bind(&WebMediaPlayerImpl::OnSurfaceCreated, AsWeakPtr())); |
| 291 surface_manager_->CreateFullscreenSurface(pipeline_metadata_.natural_size, | 294 surface_manager_->CreateFullscreenSurface(pipeline_metadata_.natural_size, |
| 292 surface_created_cb_.callback()); | 295 surface_created_cb_.callback()); |
| 293 } | 296 } |
| 294 if (decoder_requires_restart_for_fullscreen_) | 297 |
| 298 if (decoder_requires_restart_for_overlay_) |
| 295 ScheduleRestart(); | 299 ScheduleRestart(); |
| 296 } | 300 } |
| 297 | 301 |
| 302 void WebMediaPlayerImpl::DisableOverlay() { |
| 303 DCHECK(overlay_enabled_); |
| 304 |
| 305 overlay_enabled_ = false; |
| 306 surface_created_cb_.Cancel(); |
| 307 overlay_surface_id_ = SurfaceManager::kNoSurfaceID; |
| 308 |
| 309 if (decoder_requires_restart_for_overlay_) |
| 310 ScheduleRestart(); |
| 311 } |
| 312 |
| 313 void WebMediaPlayerImpl::enteredFullscreen() { |
| 314 if (!force_video_overlays_) |
| 315 EnableOverlay(); |
| 316 } |
| 317 |
| 298 void WebMediaPlayerImpl::exitedFullscreen() { | 318 void WebMediaPlayerImpl::exitedFullscreen() { |
| 299 fullscreen_ = false; | 319 if (!force_video_overlays_) |
| 300 surface_created_cb_.Cancel(); | 320 DisableOverlay(); |
| 301 fullscreen_surface_id_ = SurfaceManager::kNoSurfaceID; | |
| 302 if (decoder_requires_restart_for_fullscreen_) | |
| 303 ScheduleRestart(); | |
| 304 } | 321 } |
| 305 | 322 |
| 306 void WebMediaPlayerImpl::DoLoad(LoadType load_type, | 323 void WebMediaPlayerImpl::DoLoad(LoadType load_type, |
| 307 const blink::WebURL& url, | 324 const blink::WebURL& url, |
| 308 CORSMode cors_mode) { | 325 CORSMode cors_mode) { |
| 309 DVLOG(1) << __FUNCTION__; | 326 DVLOG(1) << __FUNCTION__; |
| 310 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 327 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 311 | 328 |
| 312 GURL gurl(url); | 329 GURL gurl(url); |
| 313 ReportMetrics(load_type, gurl, frame_->getSecurityOrigin()); | 330 ReportMetrics(load_type, gurl, frame_->getSecurityOrigin()); |
| (...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1005 VIDEO_ROTATION_MAX + 1); | 1022 VIDEO_ROTATION_MAX + 1); |
| 1006 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); | 1023 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); |
| 1007 | 1024 |
| 1008 if (hasVideo()) { | 1025 if (hasVideo()) { |
| 1009 if (pipeline_metadata_.video_rotation == VIDEO_ROTATION_90 || | 1026 if (pipeline_metadata_.video_rotation == VIDEO_ROTATION_90 || |
| 1010 pipeline_metadata_.video_rotation == VIDEO_ROTATION_270) { | 1027 pipeline_metadata_.video_rotation == VIDEO_ROTATION_270) { |
| 1011 gfx::Size size = pipeline_metadata_.natural_size; | 1028 gfx::Size size = pipeline_metadata_.natural_size; |
| 1012 pipeline_metadata_.natural_size = gfx::Size(size.height(), size.width()); | 1029 pipeline_metadata_.natural_size = gfx::Size(size.height(), size.width()); |
| 1013 } | 1030 } |
| 1014 | 1031 |
| 1015 if (fullscreen_ && surface_manager_) | 1032 if (overlay_enabled_ && surface_manager_) |
| 1016 surface_manager_->NaturalSizeChanged(pipeline_metadata_.natural_size); | 1033 surface_manager_->NaturalSizeChanged(pipeline_metadata_.natural_size); |
| 1017 | 1034 |
| 1018 DCHECK(!video_weblayer_); | 1035 DCHECK(!video_weblayer_); |
| 1019 video_weblayer_.reset(new cc_blink::WebLayerImpl(cc::VideoLayer::Create( | 1036 video_weblayer_.reset(new cc_blink::WebLayerImpl(cc::VideoLayer::Create( |
| 1020 compositor_, pipeline_metadata_.video_rotation))); | 1037 compositor_, pipeline_metadata_.video_rotation))); |
| 1021 video_weblayer_->layer()->SetContentsOpaque(opaque_); | 1038 video_weblayer_->layer()->SetContentsOpaque(opaque_); |
| 1022 video_weblayer_->SetContentsOpaqueIsFixed(true); | 1039 video_weblayer_->SetContentsOpaqueIsFixed(true); |
| 1023 client_->setWebLayer(video_weblayer_.get()); | 1040 client_->setWebLayer(video_weblayer_.get()); |
| 1024 } | 1041 } |
| 1025 | 1042 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1111 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1128 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1112 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); | 1129 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); |
| 1113 | 1130 |
| 1114 if (size == pipeline_metadata_.natural_size) | 1131 if (size == pipeline_metadata_.natural_size) |
| 1115 return; | 1132 return; |
| 1116 | 1133 |
| 1117 TRACE_EVENT0("media", "WebMediaPlayerImpl::OnNaturalSizeChanged"); | 1134 TRACE_EVENT0("media", "WebMediaPlayerImpl::OnNaturalSizeChanged"); |
| 1118 media_log_->AddEvent( | 1135 media_log_->AddEvent( |
| 1119 media_log_->CreateVideoSizeSetEvent(size.width(), size.height())); | 1136 media_log_->CreateVideoSizeSetEvent(size.width(), size.height())); |
| 1120 | 1137 |
| 1121 if (fullscreen_ && surface_manager_) | 1138 if (overlay_enabled_ && surface_manager_) |
| 1122 surface_manager_->NaturalSizeChanged(size); | 1139 surface_manager_->NaturalSizeChanged(size); |
| 1123 | 1140 |
| 1124 pipeline_metadata_.natural_size = size; | 1141 pipeline_metadata_.natural_size = size; |
| 1125 client_->sizeChanged(); | 1142 client_->sizeChanged(); |
| 1126 } | 1143 } |
| 1127 | 1144 |
| 1128 void WebMediaPlayerImpl::OnVideoOpacityChange(bool opaque) { | 1145 void WebMediaPlayerImpl::OnVideoOpacityChange(bool opaque) { |
| 1129 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1146 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1130 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); | 1147 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); |
| 1131 | 1148 |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1292 SetNetworkState(WebMediaPlayer::NetworkStateIdle); | 1309 SetNetworkState(WebMediaPlayer::NetworkStateIdle); |
| 1293 else if (is_downloading && network_state_ == WebMediaPlayer::NetworkStateIdle) | 1310 else if (is_downloading && network_state_ == WebMediaPlayer::NetworkStateIdle) |
| 1294 SetNetworkState(WebMediaPlayer::NetworkStateLoading); | 1311 SetNetworkState(WebMediaPlayer::NetworkStateLoading); |
| 1295 media_log_->AddEvent( | 1312 media_log_->AddEvent( |
| 1296 media_log_->CreateBooleanEvent( | 1313 media_log_->CreateBooleanEvent( |
| 1297 MediaLogEvent::NETWORK_ACTIVITY_SET, | 1314 MediaLogEvent::NETWORK_ACTIVITY_SET, |
| 1298 "is_downloading_data", is_downloading)); | 1315 "is_downloading_data", is_downloading)); |
| 1299 } | 1316 } |
| 1300 | 1317 |
| 1301 void WebMediaPlayerImpl::OnSurfaceCreated(int surface_id) { | 1318 void WebMediaPlayerImpl::OnSurfaceCreated(int surface_id) { |
| 1302 fullscreen_surface_id_ = surface_id; | 1319 if (force_video_overlays_ && surface_id == SurfaceManager::kNoSurfaceID) |
| 1320 LOG(ERROR) << "Create surface failed."; |
| 1321 |
| 1322 overlay_surface_id_ = surface_id; |
| 1303 if (!pending_surface_request_cb_.is_null()) | 1323 if (!pending_surface_request_cb_.is_null()) |
| 1304 base::ResetAndReturn(&pending_surface_request_cb_).Run(surface_id); | 1324 base::ResetAndReturn(&pending_surface_request_cb_).Run(surface_id); |
| 1305 } | 1325 } |
| 1306 | 1326 |
| 1307 // TODO(watk): Move this state management out of WMPI. | 1327 // TODO(watk): Move this state management out of WMPI. |
| 1308 void WebMediaPlayerImpl::OnSurfaceRequested( | 1328 void WebMediaPlayerImpl::OnSurfaceRequested( |
| 1309 const SurfaceCreatedCB& surface_created_cb) { | 1329 const SurfaceCreatedCB& surface_created_cb) { |
| 1310 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1330 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1311 DCHECK(surface_manager_); | 1331 DCHECK(surface_manager_); |
| 1312 | 1332 |
| 1313 // A null callback indicates that the decoder is going away. | 1333 // A null callback indicates that the decoder is going away. |
| 1314 if (surface_created_cb.is_null()) { | 1334 if (surface_created_cb.is_null()) { |
| 1315 decoder_requires_restart_for_fullscreen_ = false; | 1335 decoder_requires_restart_for_overlay_ = false; |
| 1316 pending_surface_request_cb_.Reset(); | 1336 pending_surface_request_cb_.Reset(); |
| 1317 return; | 1337 return; |
| 1318 } | 1338 } |
| 1319 | 1339 |
| 1320 // If we're getting a surface request it means GVD is initializing, so until | 1340 // If we're getting a surface request it means GVD is initializing, so until |
| 1321 // we get a null surface request, GVD is the active decoder. While that's the | 1341 // we get a null surface request, GVD is the active decoder. While that's the |
| 1322 // case we should restart the pipeline on fullscreen transitions so that when | 1342 // case we should restart the pipeline on fullscreen transitions so that when |
| 1323 // we create a new GVD it will request a surface again and get the right kind | 1343 // we create a new GVD it will request a surface again and get the right kind |
| 1324 // of surface for the fullscreen state. | 1344 // of surface for the fullscreen state. |
| 1325 // TODO(watk): Don't require a pipeline restart to switch surfaces for | 1345 // TODO(watk): Don't require a pipeline restart to switch surfaces for |
| 1326 // cases where it isn't necessary. | 1346 // cases where it isn't necessary. |
| 1327 decoder_requires_restart_for_fullscreen_ = true; | 1347 decoder_requires_restart_for_overlay_ = true; |
| 1328 if (fullscreen_) { | 1348 if (overlay_enabled_) { |
| 1329 if (fullscreen_surface_id_ != SurfaceManager::kNoSurfaceID) | 1349 if (overlay_surface_id_ != SurfaceManager::kNoSurfaceID) |
| 1330 surface_created_cb.Run(fullscreen_surface_id_); | 1350 surface_created_cb.Run(overlay_surface_id_); |
| 1331 else | 1351 else |
| 1332 pending_surface_request_cb_ = surface_created_cb; | 1352 pending_surface_request_cb_ = surface_created_cb; |
| 1333 } else { | 1353 } else { |
| 1334 // Tell the decoder to create its own surface. | 1354 // Tell the decoder to create its own surface. |
| 1335 surface_created_cb.Run(SurfaceManager::kNoSurfaceID); | 1355 surface_created_cb.Run(SurfaceManager::kNoSurfaceID); |
| 1336 } | 1356 } |
| 1337 } | 1357 } |
| 1338 | 1358 |
| 1339 std::unique_ptr<Renderer> WebMediaPlayerImpl::CreateRenderer() { | 1359 std::unique_ptr<Renderer> WebMediaPlayerImpl::CreateRenderer() { |
| 1360 if (force_video_overlays_) |
| 1361 EnableOverlay(); |
| 1362 |
| 1340 RequestSurfaceCB request_surface_cb; | 1363 RequestSurfaceCB request_surface_cb; |
| 1341 #if defined(OS_ANDROID) | 1364 #if defined(OS_ANDROID) |
| 1342 request_surface_cb = | 1365 request_surface_cb = |
| 1343 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnSurfaceRequested); | 1366 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnSurfaceRequested); |
| 1344 #endif | 1367 #endif |
| 1345 return renderer_factory_->CreateRenderer( | 1368 return renderer_factory_->CreateRenderer( |
| 1346 media_task_runner_, worker_task_runner_, audio_source_provider_.get(), | 1369 media_task_runner_, worker_task_runner_, audio_source_provider_.get(), |
| 1347 compositor_, request_surface_cb); | 1370 compositor_, request_surface_cb); |
| 1348 } | 1371 } |
| 1349 | 1372 |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1620 // correctly configure the session. | 1643 // correctly configure the session. |
| 1621 // | 1644 // |
| 1622 // TODO(sandersd): If Blink told us the paused state sooner, we could create | 1645 // TODO(sandersd): If Blink told us the paused state sooner, we could create |
| 1623 // the media session sooner. | 1646 // the media session sooner. |
| 1624 bool can_play = !has_error && !is_remote && have_future_data; | 1647 bool can_play = !has_error && !is_remote && have_future_data; |
| 1625 bool has_session = can_play && !must_suspend_ && !background_suspended; | 1648 bool has_session = can_play && !must_suspend_ && !background_suspended; |
| 1626 | 1649 |
| 1627 if (!has_session) { | 1650 if (!has_session) { |
| 1628 result.delegate_state = DelegateState::GONE; | 1651 result.delegate_state = DelegateState::GONE; |
| 1629 } else if (paused_) { | 1652 } else if (paused_) { |
| 1630 if (seeking() || fullscreen_) { | 1653 if (seeking() || overlay_enabled_) { |
| 1631 result.delegate_state = DelegateState::PAUSED_BUT_NOT_IDLE; | 1654 result.delegate_state = DelegateState::PAUSED_BUT_NOT_IDLE; |
| 1632 } else if (ended_) { | 1655 } else if (ended_) { |
| 1633 result.delegate_state = DelegateState::ENDED; | 1656 result.delegate_state = DelegateState::ENDED; |
| 1634 } else { | 1657 } else { |
| 1635 result.delegate_state = DelegateState::PAUSED; | 1658 result.delegate_state = DelegateState::PAUSED; |
| 1636 } | 1659 } |
| 1637 } else { | 1660 } else { |
| 1638 result.delegate_state = DelegateState::PLAYING; | 1661 result.delegate_state = DelegateState::PLAYING; |
| 1639 } | 1662 } |
| 1640 | 1663 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1698 if (isRemote()) | 1721 if (isRemote()) |
| 1699 return; | 1722 return; |
| 1700 #endif | 1723 #endif |
| 1701 | 1724 |
| 1702 // Idle timeout chosen arbitrarily. | 1725 // Idle timeout chosen arbitrarily. |
| 1703 background_pause_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(5), | 1726 background_pause_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(5), |
| 1704 this, &WebMediaPlayerImpl::OnPause); | 1727 this, &WebMediaPlayerImpl::OnPause); |
| 1705 } | 1728 } |
| 1706 | 1729 |
| 1707 } // namespace media | 1730 } // namespace media |
| OLD | NEW |