| 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 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 encrypted_media_support_(cdm_factory, | 179 encrypted_media_support_(cdm_factory, |
| 180 encrypted_client, | 180 encrypted_client, |
| 181 params.media_permission(), | 181 params.media_permission(), |
| 182 base::Bind(&WebMediaPlayerImpl::SetCdm, | 182 base::Bind(&WebMediaPlayerImpl::SetCdm, |
| 183 AsWeakPtr(), | 183 AsWeakPtr(), |
| 184 base::Bind(&IgnoreCdmAttached))), | 184 base::Bind(&IgnoreCdmAttached))), |
| 185 is_cdm_attached_(false), | 185 is_cdm_attached_(false), |
| 186 #if defined(OS_ANDROID) // WMPI_CAST | 186 #if defined(OS_ANDROID) // WMPI_CAST |
| 187 cast_impl_(this, client_, params.context_3d_cb(), delegate), | 187 cast_impl_(this, client_, params.context_3d_cb(), delegate), |
| 188 #endif | 188 #endif |
| 189 volume_(1.0), |
| 190 volume_multiplier_(1.0), |
| 189 renderer_factory_(std::move(renderer_factory)) { | 191 renderer_factory_(std::move(renderer_factory)) { |
| 190 DCHECK(!adjust_allocated_memory_cb_.is_null()); | 192 DCHECK(!adjust_allocated_memory_cb_.is_null()); |
| 191 DCHECK(renderer_factory_); | 193 DCHECK(renderer_factory_); |
| 192 | 194 |
| 193 if (delegate) | 195 if (delegate) |
| 194 delegate->AddObserver(this); | 196 delegate->AddObserver(this); |
| 195 | 197 |
| 196 media_log_->AddEvent( | 198 media_log_->AddEvent( |
| 197 media_log_->CreateEvent(MediaLogEvent::WEBMEDIAPLAYER_CREATED)); | 199 media_log_->CreateEvent(MediaLogEvent::WEBMEDIAPLAYER_CREATED)); |
| 198 | 200 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 211 ? params.audio_renderer_sink() | 213 ? params.audio_renderer_sink() |
| 212 : new NullAudioSink(media_task_runner_)); | 214 : new NullAudioSink(media_task_runner_)); |
| 213 } | 215 } |
| 214 | 216 |
| 215 WebMediaPlayerImpl::~WebMediaPlayerImpl() { | 217 WebMediaPlayerImpl::~WebMediaPlayerImpl() { |
| 216 client_->setWebLayer(NULL); | 218 client_->setWebLayer(NULL); |
| 217 | 219 |
| 218 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 220 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 219 | 221 |
| 220 if (delegate_) { | 222 if (delegate_) { |
| 223 delegate_->PlayerGone(this); |
| 221 delegate_->RemoveObserver(this); | 224 delegate_->RemoveObserver(this); |
| 222 delegate_->PlayerGone(this); | |
| 223 } | 225 } |
| 224 | 226 |
| 225 // Abort any pending IO so stopping the pipeline doesn't get blocked. | 227 // Abort any pending IO so stopping the pipeline doesn't get blocked. |
| 226 if (data_source_) | 228 if (data_source_) |
| 227 data_source_->Abort(); | 229 data_source_->Abort(); |
| 228 if (chunk_demuxer_) { | 230 if (chunk_demuxer_) { |
| 229 chunk_demuxer_->Shutdown(); | 231 chunk_demuxer_->Shutdown(); |
| 230 chunk_demuxer_ = NULL; | 232 chunk_demuxer_ = NULL; |
| 231 } | 233 } |
| 232 | 234 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 #endif | 327 #endif |
| 326 | 328 |
| 327 paused_ = false; | 329 paused_ = false; |
| 328 | 330 |
| 329 pipeline_.SetPlaybackRate(playback_rate_); | 331 pipeline_.SetPlaybackRate(playback_rate_); |
| 330 if (data_source_) | 332 if (data_source_) |
| 331 data_source_->MediaIsPlaying(); | 333 data_source_->MediaIsPlaying(); |
| 332 | 334 |
| 333 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::PLAY)); | 335 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::PLAY)); |
| 334 | 336 |
| 335 if (delegate_ && playback_rate_ > 0) | 337 if (playback_rate_ > 0) |
| 336 NotifyPlaybackStarted(); | 338 NotifyPlaybackStarted(); |
| 337 } | 339 } |
| 338 | 340 |
| 339 void WebMediaPlayerImpl::pause() { | 341 void WebMediaPlayerImpl::pause() { |
| 340 DVLOG(1) << __FUNCTION__; | 342 DVLOG(1) << __FUNCTION__; |
| 341 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 343 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 342 | 344 |
| 343 const bool was_already_paused = paused_ || playback_rate_ == 0; | 345 const bool was_already_paused = paused_ || playback_rate_ == 0; |
| 344 paused_ = true; | 346 paused_ = true; |
| 345 | 347 |
| 346 #if defined(OS_ANDROID) // WMPI_CAST | 348 #if defined(OS_ANDROID) // WMPI_CAST |
| 347 if (isRemote()) { | 349 if (isRemote()) { |
| 348 cast_impl_.pause(); | 350 cast_impl_.pause(); |
| 349 return; | 351 return; |
| 350 } | 352 } |
| 351 #endif | 353 #endif |
| 352 | 354 |
| 353 pipeline_.SetPlaybackRate(0.0); | 355 pipeline_.SetPlaybackRate(0.0); |
| 354 UpdatePausedTime(); | 356 UpdatePausedTime(); |
| 355 | 357 |
| 356 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::PAUSE)); | 358 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::PAUSE)); |
| 357 | 359 |
| 358 if (!was_already_paused && delegate_) | 360 if (!was_already_paused) |
| 359 NotifyPlaybackPaused(); | 361 NotifyPlaybackPaused(); |
| 360 } | 362 } |
| 361 | 363 |
| 362 bool WebMediaPlayerImpl::supportsSave() const { | 364 bool WebMediaPlayerImpl::supportsSave() const { |
| 363 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 365 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 364 return supports_save_; | 366 return supports_save_; |
| 365 } | 367 } |
| 366 | 368 |
| 367 void WebMediaPlayerImpl::seek(double seconds) { | 369 void WebMediaPlayerImpl::seek(double seconds) { |
| 368 DVLOG(1) << __FUNCTION__ << "(" << seconds << "s)"; | 370 DVLOG(1) << __FUNCTION__ << "(" << seconds << "s)"; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 // following checks so rewind uses reasonable values also. | 470 // following checks so rewind uses reasonable values also. |
| 469 if (rate < 0.0) | 471 if (rate < 0.0) |
| 470 return; | 472 return; |
| 471 | 473 |
| 472 // Limit rates to reasonable values by clamping. | 474 // Limit rates to reasonable values by clamping. |
| 473 if (rate != 0.0) { | 475 if (rate != 0.0) { |
| 474 if (rate < kMinRate) | 476 if (rate < kMinRate) |
| 475 rate = kMinRate; | 477 rate = kMinRate; |
| 476 else if (rate > kMaxRate) | 478 else if (rate > kMaxRate) |
| 477 rate = kMaxRate; | 479 rate = kMaxRate; |
| 478 if (playback_rate_ == 0 && !paused_ && delegate_) | 480 if (playback_rate_ == 0 && !paused_) |
| 479 NotifyPlaybackStarted(); | 481 NotifyPlaybackStarted(); |
| 480 } else if (playback_rate_ != 0 && !paused_ && delegate_) { | 482 } else if (playback_rate_ != 0 && !paused_) { |
| 481 NotifyPlaybackPaused(); | 483 NotifyPlaybackPaused(); |
| 482 } | 484 } |
| 483 | 485 |
| 484 playback_rate_ = rate; | 486 playback_rate_ = rate; |
| 485 if (!paused_) { | 487 if (!paused_) { |
| 486 pipeline_.SetPlaybackRate(rate); | 488 pipeline_.SetPlaybackRate(rate); |
| 487 if (data_source_) | 489 if (data_source_) |
| 488 data_source_->MediaPlaybackRateChanged(rate); | 490 data_source_->MediaPlaybackRateChanged(rate); |
| 489 } | 491 } |
| 490 } | 492 } |
| 491 | 493 |
| 492 void WebMediaPlayerImpl::setVolume(double volume) { | 494 void WebMediaPlayerImpl::setVolume(double volume) { |
| 493 DVLOG(1) << __FUNCTION__ << "(" << volume << ")"; | 495 DVLOG(1) << __FUNCTION__ << "(" << volume << ")"; |
| 494 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 496 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 495 | 497 volume_ = volume; |
| 496 pipeline_.SetVolume(volume); | 498 pipeline_.SetVolume(volume_ * volume_multiplier_); |
| 497 } | 499 } |
| 498 | 500 |
| 499 void WebMediaPlayerImpl::setSinkId( | 501 void WebMediaPlayerImpl::setSinkId( |
| 500 const blink::WebString& sink_id, | 502 const blink::WebString& sink_id, |
| 501 const blink::WebSecurityOrigin& security_origin, | 503 const blink::WebSecurityOrigin& security_origin, |
| 502 blink::WebSetSinkIdCallbacks* web_callback) { | 504 blink::WebSetSinkIdCallbacks* web_callback) { |
| 503 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 505 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 504 DVLOG(1) << __FUNCTION__; | 506 DVLOG(1) << __FUNCTION__; |
| 505 | 507 |
| 506 media::SwitchOutputDeviceCB callback = | 508 media::SwitchOutputDeviceCB callback = |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 908 void WebMediaPlayerImpl::OnPipelineSeeked(bool time_changed, | 910 void WebMediaPlayerImpl::OnPipelineSeeked(bool time_changed, |
| 909 PipelineStatus status) { | 911 PipelineStatus status) { |
| 910 DVLOG(1) << __FUNCTION__ << "(" << time_changed << ", " << status << ")"; | 912 DVLOG(1) << __FUNCTION__ << "(" << time_changed << ", " << status << ")"; |
| 911 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 913 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 912 | 914 |
| 913 if (status != PIPELINE_OK) { | 915 if (status != PIPELINE_OK) { |
| 914 OnPipelineError(status); | 916 OnPipelineError(status); |
| 915 return; | 917 return; |
| 916 } | 918 } |
| 917 | 919 |
| 920 // If we we're resuming into the playing state, notify the delegate. |
| 921 if (resuming_ && playback_rate_ > 0 && !paused_) |
| 922 NotifyPlaybackStarted(); |
| 923 |
| 918 // Whether or not the seek was caused by a resume, we're not suspended now. | 924 // Whether or not the seek was caused by a resume, we're not suspended now. |
| 919 resuming_ = false; | 925 resuming_ = false; |
| 920 suspended_ = false; | 926 suspended_ = false; |
| 921 | 927 |
| 922 // If there is a pending suspend, the seek does not complete until after the | 928 // If there is a pending suspend, the seek does not complete until after the |
| 923 // next resume. | 929 // next resume. |
| 924 if (pending_suspend_) { | 930 if (pending_suspend_) { |
| 925 pending_suspend_ = false; | 931 pending_suspend_ = false; |
| 926 pending_time_change_ = time_changed; | 932 pending_time_change_ = time_changed; |
| 927 Suspend(); | 933 Suspend(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 952 void WebMediaPlayerImpl::OnPipelineSuspended(PipelineStatus status) { | 958 void WebMediaPlayerImpl::OnPipelineSuspended(PipelineStatus status) { |
| 953 DVLOG(1) << __FUNCTION__ << "(" << status << ")"; | 959 DVLOG(1) << __FUNCTION__ << "(" << status << ")"; |
| 954 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 960 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 955 | 961 |
| 956 if (status != PIPELINE_OK) { | 962 if (status != PIPELINE_OK) { |
| 957 OnPipelineError(status); | 963 OnPipelineError(status); |
| 958 return; | 964 return; |
| 959 } | 965 } |
| 960 | 966 |
| 961 suspending_ = false; | 967 suspending_ = false; |
| 968 if (delegate_) |
| 969 delegate_->PlayerGone(this); |
| 962 | 970 |
| 963 #if defined(OS_ANDROID) | 971 #if defined(OS_ANDROID) |
| 964 if (isRemote()) { | 972 if (isRemote()) { |
| 965 scoped_refptr<VideoFrame> frame = cast_impl_.GetCastingBanner(); | 973 scoped_refptr<VideoFrame> frame = cast_impl_.GetCastingBanner(); |
| 966 if (frame) { | 974 if (frame) { |
| 967 compositor_->PaintFrameUsingOldRenderingPath(frame); | 975 compositor_->PaintFrameUsingOldRenderingPath(frame); |
| 968 } | 976 } |
| 969 } | 977 } |
| 970 #endif | 978 #endif |
| 971 | 979 |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1181 if (pending_suspend_) { | 1189 if (pending_suspend_) { |
| 1182 pending_suspend_ = false; | 1190 pending_suspend_ = false; |
| 1183 return; | 1191 return; |
| 1184 } | 1192 } |
| 1185 | 1193 |
| 1186 // Might already be resuming iff we came back from remote playback recently. | 1194 // Might already be resuming iff we came back from remote playback recently. |
| 1187 if (suspended_ && !resuming_) | 1195 if (suspended_ && !resuming_) |
| 1188 Resume(); | 1196 Resume(); |
| 1189 } | 1197 } |
| 1190 | 1198 |
| 1199 void WebMediaPlayerImpl::OnPlay() { |
| 1200 play(); |
| 1201 client_->playbackStateChanged(); |
| 1202 } |
| 1203 |
| 1204 void WebMediaPlayerImpl::OnPause() { |
| 1205 pause(); |
| 1206 client_->playbackStateChanged(); |
| 1207 } |
| 1208 |
| 1209 void WebMediaPlayerImpl::OnVolumeMultiplierUpdate(double multiplier) { |
| 1210 volume_multiplier_ = multiplier; |
| 1211 setVolume(volume_); |
| 1212 } |
| 1213 |
| 1191 void WebMediaPlayerImpl::Resume() { | 1214 void WebMediaPlayerImpl::Resume() { |
| 1192 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1215 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1193 CHECK(suspended_); | 1216 CHECK(suspended_); |
| 1194 CHECK(!resuming_); | 1217 CHECK(!resuming_); |
| 1195 | 1218 |
| 1196 // If there was a time change pending when we suspended (which can happen when | 1219 // If there was a time change pending when we suspended (which can happen when |
| 1197 // we suspend immediately after a seek), surface it after resuming. | 1220 // we suspend immediately after a seek), surface it after resuming. |
| 1198 bool time_changed = pending_time_change_; | 1221 bool time_changed = pending_time_change_; |
| 1199 pending_time_change_ = false; | 1222 pending_time_change_ = false; |
| 1200 | 1223 |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1465 ended_ ? pipeline_.GetMediaDuration() : pipeline_.GetMediaTime(); | 1488 ended_ ? pipeline_.GetMediaDuration() : pipeline_.GetMediaTime(); |
| 1466 } | 1489 } |
| 1467 | 1490 |
| 1468 void WebMediaPlayerImpl::NotifyPlaybackStarted() { | 1491 void WebMediaPlayerImpl::NotifyPlaybackStarted() { |
| 1469 #if defined(OS_ANDROID) // WMPI_CAST | 1492 #if defined(OS_ANDROID) // WMPI_CAST |
| 1470 // We do not tell our delegates about remote playback, becuase that would | 1493 // We do not tell our delegates about remote playback, becuase that would |
| 1471 // keep the device awake, which is not what we want. | 1494 // keep the device awake, which is not what we want. |
| 1472 if (isRemote()) | 1495 if (isRemote()) |
| 1473 return; | 1496 return; |
| 1474 #endif | 1497 #endif |
| 1475 if (delegate_) | 1498 if (delegate_) { |
| 1476 delegate_->DidPlay(this); | 1499 delegate_->DidPlay(this, hasVideo(), hasAudio(), false, |
| 1500 pipeline_.GetMediaDuration()); |
| 1501 } |
| 1477 if (!memory_usage_reporting_timer_.IsRunning()) { | 1502 if (!memory_usage_reporting_timer_.IsRunning()) { |
| 1478 memory_usage_reporting_timer_.Start(FROM_HERE, | 1503 memory_usage_reporting_timer_.Start(FROM_HERE, |
| 1479 base::TimeDelta::FromSeconds(2), this, | 1504 base::TimeDelta::FromSeconds(2), this, |
| 1480 &WebMediaPlayerImpl::ReportMemoryUsage); | 1505 &WebMediaPlayerImpl::ReportMemoryUsage); |
| 1481 } | 1506 } |
| 1482 } | 1507 } |
| 1483 | 1508 |
| 1484 void WebMediaPlayerImpl::NotifyPlaybackPaused() { | 1509 void WebMediaPlayerImpl::NotifyPlaybackPaused() { |
| 1485 #if defined(OS_ANDROID) // WMPI_CAST | 1510 #if defined(OS_ANDROID) // WMPI_CAST |
| 1486 if (isRemote()) | 1511 if (isRemote()) |
| 1487 return; | 1512 return; |
| 1488 #endif | 1513 #endif |
| 1489 if (delegate_) | 1514 if (delegate_) |
| 1490 delegate_->DidPause(this); | 1515 delegate_->DidPause(this, ended_); |
| 1491 memory_usage_reporting_timer_.Stop(); | 1516 memory_usage_reporting_timer_.Stop(); |
| 1492 ReportMemoryUsage(); | 1517 ReportMemoryUsage(); |
| 1493 } | 1518 } |
| 1494 | 1519 |
| 1495 void WebMediaPlayerImpl::ReportMemoryUsage() { | 1520 void WebMediaPlayerImpl::ReportMemoryUsage() { |
| 1496 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1521 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1497 | 1522 |
| 1498 // About base::Unretained() usage below: We destroy |demuxer_| on the main | 1523 // About base::Unretained() usage below: We destroy |demuxer_| on the main |
| 1499 // thread. Before that, however, ~WebMediaPlayerImpl() posts a task to the | 1524 // thread. Before that, however, ~WebMediaPlayerImpl() posts a task to the |
| 1500 // media thread and waits for it to finish. Hence, the GetMemoryUsage() task | 1525 // media thread and waits for it to finish. Hence, the GetMemoryUsage() task |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1523 << ", Video: " << stats.video_memory_usage << ", DataSource: " | 1548 << ", Video: " << stats.video_memory_usage << ", DataSource: " |
| 1524 << (data_source_ ? data_source_->GetMemoryUsage() : 0) | 1549 << (data_source_ ? data_source_->GetMemoryUsage() : 0) |
| 1525 << ", Demuxer: " << demuxer_memory_usage; | 1550 << ", Demuxer: " << demuxer_memory_usage; |
| 1526 | 1551 |
| 1527 const int64_t delta = current_memory_usage - last_reported_memory_usage_; | 1552 const int64_t delta = current_memory_usage - last_reported_memory_usage_; |
| 1528 last_reported_memory_usage_ = current_memory_usage; | 1553 last_reported_memory_usage_ = current_memory_usage; |
| 1529 adjust_allocated_memory_cb_.Run(delta); | 1554 adjust_allocated_memory_cb_.Run(delta); |
| 1530 } | 1555 } |
| 1531 | 1556 |
| 1532 } // namespace media | 1557 } // namespace media |
| OLD | NEW |