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 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 opaque_(false), | 148 opaque_(false), |
149 playback_rate_(0.0), | 149 playback_rate_(0.0), |
150 paused_(true), | 150 paused_(true), |
151 seeking_(false), | 151 seeking_(false), |
152 pending_suspend_(false), | 152 pending_suspend_(false), |
153 pending_time_change_(false), | 153 pending_time_change_(false), |
154 pending_resume_(false), | 154 pending_resume_(false), |
155 suspending_(false), | 155 suspending_(false), |
156 suspended_(false), | 156 suspended_(false), |
157 resuming_(false), | 157 resuming_(false), |
| 158 pending_suspend_resume_cycle_(false), |
158 ended_(false), | 159 ended_(false), |
159 pending_seek_(false), | 160 pending_seek_(false), |
160 should_notify_time_changed_(false), | 161 should_notify_time_changed_(false), |
| 162 fullscreen_(false), |
| 163 decoder_requires_restart_for_fullscreen_(false), |
161 client_(client), | 164 client_(client), |
162 encrypted_client_(encrypted_client), | 165 encrypted_client_(encrypted_client), |
163 delegate_(delegate), | 166 delegate_(delegate), |
164 delegate_id_(0), | 167 delegate_id_(0), |
165 defer_load_cb_(params.defer_load_cb()), | 168 defer_load_cb_(params.defer_load_cb()), |
166 context_3d_cb_(params.context_3d_cb()), | 169 context_3d_cb_(params.context_3d_cb()), |
167 adjust_allocated_memory_cb_(params.adjust_allocated_memory_cb()), | 170 adjust_allocated_memory_cb_(params.adjust_allocated_memory_cb()), |
168 last_reported_memory_usage_(0), | 171 last_reported_memory_usage_(0), |
169 supports_save_(true), | 172 supports_save_(true), |
170 chunk_demuxer_(NULL), | 173 chunk_demuxer_(NULL), |
(...skipping 12 matching lines...) Expand all Loading... |
183 params.media_permission(), | 186 params.media_permission(), |
184 base::Bind(&WebMediaPlayerImpl::SetCdm, | 187 base::Bind(&WebMediaPlayerImpl::SetCdm, |
185 AsWeakPtr(), | 188 AsWeakPtr(), |
186 base::Bind(&IgnoreCdmAttached))), | 189 base::Bind(&IgnoreCdmAttached))), |
187 is_cdm_attached_(false), | 190 is_cdm_attached_(false), |
188 #if defined(OS_ANDROID) // WMPI_CAST | 191 #if defined(OS_ANDROID) // WMPI_CAST |
189 cast_impl_(this, client_, params.context_3d_cb()), | 192 cast_impl_(this, client_, params.context_3d_cb()), |
190 #endif | 193 #endif |
191 volume_(1.0), | 194 volume_(1.0), |
192 volume_multiplier_(1.0), | 195 volume_multiplier_(1.0), |
193 renderer_factory_(std::move(renderer_factory)) { | 196 renderer_factory_(std::move(renderer_factory)), |
| 197 surface_manager_(params.surface_manager()) { |
194 DCHECK(!adjust_allocated_memory_cb_.is_null()); | 198 DCHECK(!adjust_allocated_memory_cb_.is_null()); |
195 DCHECK(renderer_factory_); | 199 DCHECK(renderer_factory_); |
196 | 200 |
197 if (delegate_) | 201 if (delegate_) |
198 delegate_id_ = delegate_->AddObserver(this); | 202 delegate_id_ = delegate_->AddObserver(this); |
199 | 203 |
200 media_log_->AddEvent( | 204 media_log_->AddEvent( |
201 media_log_->CreateEvent(MediaLogEvent::WEBMEDIAPLAYER_CREATED)); | 205 media_log_->CreateEvent(MediaLogEvent::WEBMEDIAPLAYER_CREATED)); |
202 | 206 |
203 if (params.initial_cdm()) { | 207 if (params.initial_cdm()) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 DVLOG(1) << __FUNCTION__ << "(" << load_type << ", " << url << ", " | 261 DVLOG(1) << __FUNCTION__ << "(" << load_type << ", " << url << ", " |
258 << cors_mode << ")"; | 262 << cors_mode << ")"; |
259 if (!defer_load_cb_.is_null()) { | 263 if (!defer_load_cb_.is_null()) { |
260 defer_load_cb_.Run(base::Bind( | 264 defer_load_cb_.Run(base::Bind( |
261 &WebMediaPlayerImpl::DoLoad, AsWeakPtr(), load_type, url, cors_mode)); | 265 &WebMediaPlayerImpl::DoLoad, AsWeakPtr(), load_type, url, cors_mode)); |
262 return; | 266 return; |
263 } | 267 } |
264 DoLoad(load_type, url, cors_mode); | 268 DoLoad(load_type, url, cors_mode); |
265 } | 269 } |
266 | 270 |
| 271 void WebMediaPlayerImpl::enteredFullscreen() { |
| 272 fullscreen_ = true; |
| 273 if (decoder_requires_restart_for_fullscreen_) |
| 274 ScheduleRestart(); |
| 275 } |
| 276 |
| 277 void WebMediaPlayerImpl::exitedFullscreen() { |
| 278 fullscreen_ = false; |
| 279 if (decoder_requires_restart_for_fullscreen_) |
| 280 ScheduleRestart(); |
| 281 } |
| 282 |
267 void WebMediaPlayerImpl::DoLoad(LoadType load_type, | 283 void WebMediaPlayerImpl::DoLoad(LoadType load_type, |
268 const blink::WebURL& url, | 284 const blink::WebURL& url, |
269 CORSMode cors_mode) { | 285 CORSMode cors_mode) { |
270 DVLOG(1) << __FUNCTION__; | 286 DVLOG(1) << __FUNCTION__; |
271 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 287 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
272 | 288 |
273 GURL gurl(url); | 289 GURL gurl(url); |
274 ReportMetrics( | 290 ReportMetrics( |
275 load_type, gurl, | 291 load_type, gurl, |
276 blink::WebStringToGURL(frame_->document().securityOrigin().toString())); | 292 blink::WebStringToGURL(frame_->document().securityOrigin().toString())); |
(...skipping 688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
965 | 981 |
966 #if defined(OS_ANDROID) | 982 #if defined(OS_ANDROID) |
967 if (isRemote()) { | 983 if (isRemote()) { |
968 scoped_refptr<VideoFrame> frame = cast_impl_.GetCastingBanner(); | 984 scoped_refptr<VideoFrame> frame = cast_impl_.GetCastingBanner(); |
969 if (frame) { | 985 if (frame) { |
970 compositor_->PaintFrameUsingOldRenderingPath(frame); | 986 compositor_->PaintFrameUsingOldRenderingPath(frame); |
971 } | 987 } |
972 } | 988 } |
973 #endif | 989 #endif |
974 | 990 |
975 if (pending_resume_) { | 991 if (pending_resume_ || pending_suspend_resume_cycle_) { |
976 pending_resume_ = false; | 992 pending_resume_ = false; |
| 993 pending_suspend_resume_cycle_ = false; |
977 Resume(); | 994 Resume(); |
978 return; | 995 return; |
979 } | 996 } |
980 } | 997 } |
981 | 998 |
982 void WebMediaPlayerImpl::OnPipelineEnded() { | 999 void WebMediaPlayerImpl::OnPipelineEnded() { |
983 DVLOG(1) << __FUNCTION__; | 1000 DVLOG(1) << __FUNCTION__; |
984 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1001 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
985 | 1002 |
986 // Ignore state changes until we've completed all outstanding seeks. | 1003 // Ignore state changes until we've completed all outstanding seeks. |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1239 | 1256 |
1240 if (chunk_demuxer_) | 1257 if (chunk_demuxer_) |
1241 chunk_demuxer_->StartWaitingForSeek(seek_time_); | 1258 chunk_demuxer_->StartWaitingForSeek(seek_time_); |
1242 | 1259 |
1243 resuming_ = true; | 1260 resuming_ = true; |
1244 pipeline_.Resume(CreateRenderer(), seek_time_, | 1261 pipeline_.Resume(CreateRenderer(), seek_time_, |
1245 BIND_TO_RENDER_LOOP1(&WebMediaPlayerImpl::OnPipelineSeeked, | 1262 BIND_TO_RENDER_LOOP1(&WebMediaPlayerImpl::OnPipelineSeeked, |
1246 time_changed)); | 1263 time_changed)); |
1247 } | 1264 } |
1248 | 1265 |
| 1266 void WebMediaPlayerImpl::ScheduleRestart() { |
| 1267 // If we're suspended but not resuming there is no need to restart because |
| 1268 // there is no renderer to kill. |
| 1269 if (!suspended_ || resuming_) { |
| 1270 pending_suspend_resume_cycle_ = true; |
| 1271 ScheduleSuspend(); |
| 1272 } |
| 1273 } |
| 1274 |
1249 #if defined(OS_ANDROID) // WMPI_CAST | 1275 #if defined(OS_ANDROID) // WMPI_CAST |
1250 | 1276 |
1251 bool WebMediaPlayerImpl::isRemote() const { | 1277 bool WebMediaPlayerImpl::isRemote() const { |
1252 return cast_impl_.isRemote(); | 1278 return cast_impl_.isRemote(); |
1253 } | 1279 } |
1254 | 1280 |
1255 void WebMediaPlayerImpl::SetMediaPlayerManager( | 1281 void WebMediaPlayerImpl::SetMediaPlayerManager( |
1256 RendererMediaPlayerManagerInterface* media_player_manager) { | 1282 RendererMediaPlayerManagerInterface* media_player_manager) { |
1257 cast_impl_.SetMediaPlayerManager(media_player_manager); | 1283 cast_impl_.SetMediaPlayerManager(media_player_manager); |
1258 } | 1284 } |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1327 if (!is_downloading && network_state_ == WebMediaPlayer::NetworkStateLoading) | 1353 if (!is_downloading && network_state_ == WebMediaPlayer::NetworkStateLoading) |
1328 SetNetworkState(WebMediaPlayer::NetworkStateIdle); | 1354 SetNetworkState(WebMediaPlayer::NetworkStateIdle); |
1329 else if (is_downloading && network_state_ == WebMediaPlayer::NetworkStateIdle) | 1355 else if (is_downloading && network_state_ == WebMediaPlayer::NetworkStateIdle) |
1330 SetNetworkState(WebMediaPlayer::NetworkStateLoading); | 1356 SetNetworkState(WebMediaPlayer::NetworkStateLoading); |
1331 media_log_->AddEvent( | 1357 media_log_->AddEvent( |
1332 media_log_->CreateBooleanEvent( | 1358 media_log_->CreateBooleanEvent( |
1333 MediaLogEvent::NETWORK_ACTIVITY_SET, | 1359 MediaLogEvent::NETWORK_ACTIVITY_SET, |
1334 "is_downloading_data", is_downloading)); | 1360 "is_downloading_data", is_downloading)); |
1335 } | 1361 } |
1336 | 1362 |
| 1363 // TODO(watk): Move this state management out of WMPI. |
| 1364 void WebMediaPlayerImpl::OnSurfaceRequested( |
| 1365 const SurfaceCreatedCB& surface_created_cb) { |
| 1366 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1367 DCHECK(surface_manager_); |
| 1368 |
| 1369 // A null callback indicates that the decoder is going away. |
| 1370 if (surface_created_cb.is_null()) { |
| 1371 decoder_requires_restart_for_fullscreen_ = false; |
| 1372 return; |
| 1373 } |
| 1374 |
| 1375 // If we're getting a surface request it means GVD is initializing, so until |
| 1376 // we get a null surface request, GVD is the active decoder. While that's the |
| 1377 // case we should restart the pipeline on fullscreen transitions so that when |
| 1378 // we create a new GVD it will request a surface again and get the right kind |
| 1379 // of surface for the fullscreen state. |
| 1380 // TODO(watk): Don't require a pipeline restart to switch surfaces for |
| 1381 // cases where it isn't necessary. |
| 1382 decoder_requires_restart_for_fullscreen_ = true; |
| 1383 if (fullscreen_) { |
| 1384 surface_manager_->CreateFullscreenSurface(pipeline_metadata_.natural_size, |
| 1385 surface_created_cb); |
| 1386 } else { |
| 1387 // Tell the decoder to create its own surface. |
| 1388 surface_created_cb.Run(SurfaceManager::kNoSurfaceID); |
| 1389 } |
| 1390 } |
| 1391 |
1337 scoped_ptr<Renderer> WebMediaPlayerImpl::CreateRenderer() { | 1392 scoped_ptr<Renderer> WebMediaPlayerImpl::CreateRenderer() { |
| 1393 RequestSurfaceCB request_surface_cb; |
| 1394 #if defined(OS_ANDROID) |
| 1395 request_surface_cb = |
| 1396 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnSurfaceRequested); |
| 1397 #endif |
1338 return renderer_factory_->CreateRenderer( | 1398 return renderer_factory_->CreateRenderer( |
1339 media_task_runner_, worker_task_runner_, audio_source_provider_.get(), | 1399 media_task_runner_, worker_task_runner_, audio_source_provider_.get(), |
1340 compositor_); | 1400 compositor_, request_surface_cb); |
1341 } | 1401 } |
1342 | 1402 |
1343 void WebMediaPlayerImpl::StartPipeline() { | 1403 void WebMediaPlayerImpl::StartPipeline() { |
1344 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1404 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1345 | 1405 |
1346 Demuxer::EncryptedMediaInitDataCB encrypted_media_init_data_cb = | 1406 Demuxer::EncryptedMediaInitDataCB encrypted_media_init_data_cb = |
1347 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnEncryptedMediaInitData); | 1407 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnEncryptedMediaInitData); |
1348 | 1408 |
1349 // Figure out which demuxer to use. | 1409 // Figure out which demuxer to use. |
1350 if (load_type_ != LoadTypeMediaSource) { | 1410 if (load_type_ != LoadTypeMediaSource) { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1428 client_->durationChanged(); | 1488 client_->durationChanged(); |
1429 } | 1489 } |
1430 | 1490 |
1431 void WebMediaPlayerImpl::OnNaturalSizeChanged(gfx::Size size) { | 1491 void WebMediaPlayerImpl::OnNaturalSizeChanged(gfx::Size size) { |
1432 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1492 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1433 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); | 1493 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); |
1434 TRACE_EVENT0("media", "WebMediaPlayerImpl::OnNaturalSizeChanged"); | 1494 TRACE_EVENT0("media", "WebMediaPlayerImpl::OnNaturalSizeChanged"); |
1435 | 1495 |
1436 media_log_->AddEvent( | 1496 media_log_->AddEvent( |
1437 media_log_->CreateVideoSizeSetEvent(size.width(), size.height())); | 1497 media_log_->CreateVideoSizeSetEvent(size.width(), size.height())); |
| 1498 |
| 1499 if (fullscreen_ && surface_manager_ && |
| 1500 pipeline_metadata_.natural_size != size) { |
| 1501 surface_manager_->NaturalSizeChanged(size); |
| 1502 } |
| 1503 |
1438 pipeline_metadata_.natural_size = size; | 1504 pipeline_metadata_.natural_size = size; |
1439 | |
1440 client_->sizeChanged(); | 1505 client_->sizeChanged(); |
1441 } | 1506 } |
1442 | 1507 |
1443 void WebMediaPlayerImpl::OnOpacityChanged(bool opaque) { | 1508 void WebMediaPlayerImpl::OnOpacityChanged(bool opaque) { |
1444 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1509 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1445 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); | 1510 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); |
1446 | 1511 |
1447 opaque_ = opaque; | 1512 opaque_ = opaque; |
1448 // Modify content opaqueness of cc::Layer directly so that | 1513 // Modify content opaqueness of cc::Layer directly so that |
1449 // SetContentsOpaqueIsFixed is ignored. | 1514 // SetContentsOpaqueIsFixed is ignored. |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1550 << ", Video: " << stats.video_memory_usage << ", DataSource: " | 1615 << ", Video: " << stats.video_memory_usage << ", DataSource: " |
1551 << (data_source_ ? data_source_->GetMemoryUsage() : 0) | 1616 << (data_source_ ? data_source_->GetMemoryUsage() : 0) |
1552 << ", Demuxer: " << demuxer_memory_usage; | 1617 << ", Demuxer: " << demuxer_memory_usage; |
1553 | 1618 |
1554 const int64_t delta = current_memory_usage - last_reported_memory_usage_; | 1619 const int64_t delta = current_memory_usage - last_reported_memory_usage_; |
1555 last_reported_memory_usage_ = current_memory_usage; | 1620 last_reported_memory_usage_ = current_memory_usage; |
1556 adjust_allocated_memory_cb_.Run(delta); | 1621 adjust_allocated_memory_cb_.Run(delta); |
1557 } | 1622 } |
1558 | 1623 |
1559 } // namespace media | 1624 } // namespace media |
OLD | NEW |