| 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/browser/media/android/browser_media_player_manager.h" | 5 #include "content/browser/media/android/browser_media_player_manager.h" |
| 6 | 6 |
| 7 #include "base/android/scoped_java_ref.h" | 7 #include "base/android/scoped_java_ref.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "content/browser/android/content_view_core_impl.h" | 9 #include "content/browser/android/content_view_core_impl.h" |
| 10 #include "content/browser/media/android/browser_demuxer_android.h" | 10 #include "content/browser/media/android/browser_demuxer_android.h" |
| 11 #include "content/browser/media/android/media_resource_getter_impl.h" | 11 #include "content/browser/media/android/media_resource_getter_impl.h" |
| 12 #include "content/browser/media/android/media_session.h" | 12 #include "content/browser/media/android/media_session.h" |
| 13 #include "content/browser/media/android/media_throttler.h" |
| 13 #include "content/browser/media/media_web_contents_observer.h" | 14 #include "content/browser/media/media_web_contents_observer.h" |
| 14 #include "content/browser/renderer_host/render_view_host_impl.h" | 15 #include "content/browser/renderer_host/render_view_host_impl.h" |
| 15 #include "content/browser/web_contents/web_contents_view_android.h" | 16 #include "content/browser/web_contents/web_contents_view_android.h" |
| 16 #include "content/common/media/media_player_messages_android.h" | 17 #include "content/common/media/media_player_messages_android.h" |
| 17 #include "content/public/browser/android/content_view_core.h" | 18 #include "content/public/browser/android/content_view_core.h" |
| 18 #include "content/public/browser/android/external_video_surface_container.h" | 19 #include "content/public/browser/android/external_video_surface_container.h" |
| 19 #include "content/public/browser/browser_context.h" | 20 #include "content/public/browser/browser_context.h" |
| 20 #include "content/public/browser/browser_thread.h" | 21 #include "content/public/browser/browser_thread.h" |
| 21 #include "content/public/browser/content_browser_client.h" | 22 #include "content/public/browser/content_browser_client.h" |
| 22 #include "content/public/browser/render_frame_host.h" | 23 #include "content/public/browser/render_frame_host.h" |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 switch (media_player_params.type) { | 138 switch (media_player_params.type) { |
| 138 case MEDIA_PLAYER_TYPE_URL: { | 139 case MEDIA_PLAYER_TYPE_URL: { |
| 139 const std::string user_agent = GetContentClient()->GetUserAgent(); | 140 const std::string user_agent = GetContentClient()->GetUserAgent(); |
| 140 MediaPlayerBridge* media_player_bridge = new MediaPlayerBridge( | 141 MediaPlayerBridge* media_player_bridge = new MediaPlayerBridge( |
| 141 media_player_params.player_id, | 142 media_player_params.player_id, |
| 142 media_player_params.url, | 143 media_player_params.url, |
| 143 media_player_params.first_party_for_cookies, | 144 media_player_params.first_party_for_cookies, |
| 144 user_agent, | 145 user_agent, |
| 145 hide_url_log, | 146 hide_url_log, |
| 146 this, | 147 this, |
| 147 base::Bind(&BrowserMediaPlayerManager::OnMediaResourcesRequested, | 148 base::Bind(&BrowserMediaPlayerManager::OnDecoderResourcesReleased, |
| 148 weak_ptr_factory_.GetWeakPtr()), | 149 weak_ptr_factory_.GetWeakPtr()), |
| 149 media_player_params.frame_url, | 150 media_player_params.frame_url, |
| 150 media_player_params.allow_credentials); | 151 media_player_params.allow_credentials); |
| 151 ContentViewCoreImpl* content_view_core_impl = | 152 ContentViewCoreImpl* content_view_core_impl = |
| 152 static_cast<ContentViewCoreImpl*>(ContentViewCore::FromWebContents( | 153 static_cast<ContentViewCoreImpl*>(ContentViewCore::FromWebContents( |
| 153 web_contents_)); | 154 web_contents_)); |
| 154 if (!content_view_core_impl) { | 155 if (!content_view_core_impl |
| 155 // May reach here due to prerendering. Don't extract the metadata | 156 // Initialize the player will cause MediaMetadataExtractor to decode |
| 156 // since it is expensive. | 157 // small chunks of data. |
| 158 || !RequestDecoderResources(media_player_params.player_id, true)) { |
| 159 // May reach here due to prerendering or throttling. Don't extract the |
| 160 // metadata since it is expensive. |
| 157 // TODO(qinmin): extract the metadata once the user decided to load | 161 // TODO(qinmin): extract the metadata once the user decided to load |
| 158 // the page. | 162 // the page. |
| 159 OnMediaMetadataChanged( | 163 OnMediaMetadataChanged( |
| 160 media_player_params.player_id, base::TimeDelta(), 0, 0, false); | 164 media_player_params.player_id, base::TimeDelta(), 0, 0, false); |
| 161 } else if (!content_view_core_impl->ShouldBlockMediaRequest( | 165 } else if (!content_view_core_impl->ShouldBlockMediaRequest( |
| 162 media_player_params.url)) { | 166 media_player_params.url)) { |
| 163 media_player_bridge->Initialize(); | 167 media_player_bridge->Initialize(); |
| 164 } | 168 } |
| 165 return media_player_bridge; | 169 return media_player_bridge; |
| 166 } | 170 } |
| 167 | 171 |
| 168 case MEDIA_PLAYER_TYPE_MEDIA_SOURCE: { | 172 case MEDIA_PLAYER_TYPE_MEDIA_SOURCE: { |
| 169 if (base::CommandLine::ForCurrentProcess()-> | 173 if (base::CommandLine::ForCurrentProcess()-> |
| 170 HasSwitch(switches::kEnableMediaThreadForMediaPlayback)) { | 174 HasSwitch(switches::kEnableMediaThreadForMediaPlayback)) { |
| 171 return new MediaCodecPlayer( | 175 return new MediaCodecPlayer( |
| 172 media_player_params.player_id, | 176 media_player_params.player_id, |
| 173 weak_ptr_factory_.GetWeakPtr(), | 177 weak_ptr_factory_.GetWeakPtr(), |
| 174 base::Bind(&BrowserMediaPlayerManager::OnMediaResourcesRequested, | 178 base::Bind(&BrowserMediaPlayerManager::OnDecoderResourcesReleased, |
| 175 weak_ptr_factory_.GetWeakPtr()), | 179 weak_ptr_factory_.GetWeakPtr()), |
| 176 demuxer->CreateDemuxer(media_player_params.demuxer_client_id), | 180 demuxer->CreateDemuxer(media_player_params.demuxer_client_id), |
| 177 media_player_params.frame_url); | 181 media_player_params.frame_url); |
| 178 } else { | 182 } else { |
| 179 return new MediaSourcePlayer( | 183 return new MediaSourcePlayer( |
| 180 media_player_params.player_id, | 184 media_player_params.player_id, |
| 181 this, | 185 this, |
| 182 base::Bind(&BrowserMediaPlayerManager::OnMediaResourcesRequested, | 186 base::Bind(&BrowserMediaPlayerManager::OnDecoderResourcesReleased, |
| 183 weak_ptr_factory_.GetWeakPtr()), | 187 weak_ptr_factory_.GetWeakPtr()), |
| 184 demuxer->CreateDemuxer(media_player_params.demuxer_client_id), | 188 demuxer->CreateDemuxer(media_player_params.demuxer_client_id), |
| 185 media_player_params.frame_url); | 189 media_player_params.frame_url); |
| 186 } | 190 } |
| 187 } | 191 } |
| 188 } | 192 } |
| 189 | 193 |
| 190 NOTREACHED(); | 194 NOTREACHED(); |
| 191 return NULL; | 195 return NULL; |
| 192 } | 196 } |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 } | 318 } |
| 315 | 319 |
| 316 void BrowserMediaPlayerManager::OnSeekComplete( | 320 void BrowserMediaPlayerManager::OnSeekComplete( |
| 317 int player_id, | 321 int player_id, |
| 318 const base::TimeDelta& current_time) { | 322 const base::TimeDelta& current_time) { |
| 319 Send(new MediaPlayerMsg_SeekCompleted(RoutingID(), player_id, current_time)); | 323 Send(new MediaPlayerMsg_SeekCompleted(RoutingID(), player_id, current_time)); |
| 320 } | 324 } |
| 321 | 325 |
| 322 void BrowserMediaPlayerManager::OnError(int player_id, int error) { | 326 void BrowserMediaPlayerManager::OnError(int player_id, int error) { |
| 323 Send(new MediaPlayerMsg_MediaError(RoutingID(), player_id, error)); | 327 Send(new MediaPlayerMsg_MediaError(RoutingID(), player_id, error)); |
| 324 if (fullscreen_player_id_ == player_id) | 328 if (fullscreen_player_id_ == player_id && |
| 329 error != MediaPlayerAndroid::MEDIA_ERROR_INVALID_CODE) { |
| 325 video_view_->OnMediaPlayerError(error); | 330 video_view_->OnMediaPlayerError(error); |
| 331 } |
| 326 } | 332 } |
| 327 | 333 |
| 328 void BrowserMediaPlayerManager::OnVideoSizeChanged( | 334 void BrowserMediaPlayerManager::OnVideoSizeChanged( |
| 329 int player_id, int width, int height) { | 335 int player_id, int width, int height) { |
| 330 Send(new MediaPlayerMsg_MediaVideoSizeChanged(RoutingID(), player_id, | 336 Send(new MediaPlayerMsg_MediaVideoSizeChanged(RoutingID(), player_id, |
| 331 width, height)); | 337 width, height)); |
| 332 if (fullscreen_player_id_ == player_id) | 338 if (fullscreen_player_id_ == player_id) |
| 333 video_view_->OnVideoSizeChanged(width, height); | 339 video_view_->OnVideoSizeChanged(width, height); |
| 334 } | 340 } |
| 335 | 341 |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 471 // In case we're stealing the external surface from another player. | 477 // In case we're stealing the external surface from another player. |
| 472 ReleasePlayerOfExternalVideoSurfaceIfNeeded(player_id); | 478 ReleasePlayerOfExternalVideoSurfaceIfNeeded(player_id); |
| 473 external_video_surface_container_->RequestExternalVideoSurface( | 479 external_video_surface_container_->RequestExternalVideoSurface( |
| 474 player_id, | 480 player_id, |
| 475 base::Bind(&BrowserMediaPlayerManager::AttachExternalVideoSurface, | 481 base::Bind(&BrowserMediaPlayerManager::AttachExternalVideoSurface, |
| 476 base::Unretained(this)), | 482 base::Unretained(this)), |
| 477 base::Bind(&BrowserMediaPlayerManager::DetachExternalVideoSurface, | 483 base::Bind(&BrowserMediaPlayerManager::DetachExternalVideoSurface, |
| 478 base::Unretained(this))); | 484 base::Unretained(this))); |
| 479 } | 485 } |
| 480 } | 486 } |
| 487 |
| 488 void BrowserMediaPlayerManager::ReleaseExternalSurface(int player_id) { |
| 489 if (external_video_surface_container_) |
| 490 external_video_surface_container_->ReleaseExternalVideoSurface(player_id); |
| 491 } |
| 481 #endif // defined(VIDEO_HOLE) | 492 #endif // defined(VIDEO_HOLE) |
| 482 | 493 |
| 483 void BrowserMediaPlayerManager::OnEnterFullscreen(int player_id) { | 494 void BrowserMediaPlayerManager::OnEnterFullscreen(int player_id) { |
| 484 DCHECK_EQ(fullscreen_player_id_, kInvalidMediaPlayerId); | 495 DCHECK_EQ(fullscreen_player_id_, kInvalidMediaPlayerId); |
| 485 #if defined(VIDEO_HOLE) | 496 #if defined(VIDEO_HOLE) |
| 486 // If this fullscreen player is started when another player | 497 // If this fullscreen player is started when another player |
| 487 // uses the external surface, release that other player. | 498 // uses the external surface, release that other player. |
| 488 ReleasePlayerOfExternalVideoSurfaceIfNeeded(player_id); | 499 ReleasePlayerOfExternalVideoSurfaceIfNeeded(player_id); |
| 489 if (external_video_surface_container_) | 500 if (external_video_surface_container_) |
| 490 external_video_surface_container_->ReleaseExternalVideoSurface(player_id); | 501 external_video_surface_container_->ReleaseExternalVideoSurface(player_id); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 if (!player) | 540 if (!player) |
| 530 return; | 541 return; |
| 531 | 542 |
| 532 AddPlayer(player); | 543 AddPlayer(player); |
| 533 } | 544 } |
| 534 | 545 |
| 535 void BrowserMediaPlayerManager::OnStart(int player_id) { | 546 void BrowserMediaPlayerManager::OnStart(int player_id) { |
| 536 MediaPlayerAndroid* player = GetPlayer(player_id); | 547 MediaPlayerAndroid* player = GetPlayer(player_id); |
| 537 if (!player) | 548 if (!player) |
| 538 return; | 549 return; |
| 539 player->Start(); | 550 |
| 540 if (fullscreen_player_id_ == player_id && fullscreen_player_is_released_) { | 551 if (RequestDecoderResources(player_id, false)) { |
| 541 video_view_->OpenVideo(); | 552 StartInternal(player_id); |
| 542 fullscreen_player_is_released_ = false; | 553 } else if (WebContentsDelegate* delegate = web_contents_->GetDelegate()){ |
| 554 delegate->RequestMediaDecodePermission( |
| 555 web_contents_, |
| 556 base::Bind(&BrowserMediaPlayerManager::OnPlaybackPermissionGranted, |
| 557 weak_ptr_factory_.GetWeakPtr(), player_id)); |
| 543 } | 558 } |
| 544 } | 559 } |
| 545 | 560 |
| 546 void BrowserMediaPlayerManager::OnSeek( | 561 void BrowserMediaPlayerManager::OnSeek( |
| 547 int player_id, | 562 int player_id, |
| 548 const base::TimeDelta& time) { | 563 const base::TimeDelta& time) { |
| 549 MediaPlayerAndroid* player = GetPlayer(player_id); | 564 MediaPlayerAndroid* player = GetPlayer(player_id); |
| 550 if (player) | 565 if (player) |
| 551 player->SeekTo(time); | 566 player->SeekTo(time); |
| 552 } | 567 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 603 | 618 |
| 604 void BrowserMediaPlayerManager::AddPlayer(MediaPlayerAndroid* player) { | 619 void BrowserMediaPlayerManager::AddPlayer(MediaPlayerAndroid* player) { |
| 605 DCHECK(!GetPlayer(player->player_id())); | 620 DCHECK(!GetPlayer(player->player_id())); |
| 606 players_.push_back(player); | 621 players_.push_back(player); |
| 607 } | 622 } |
| 608 | 623 |
| 609 void BrowserMediaPlayerManager::RemovePlayer(int player_id) { | 624 void BrowserMediaPlayerManager::RemovePlayer(int player_id) { |
| 610 for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin(); | 625 for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin(); |
| 611 it != players_.end(); ++it) { | 626 it != players_.end(); ++it) { |
| 612 if ((*it)->player_id() == player_id) { | 627 if ((*it)->player_id() == player_id) { |
| 613 ReleaseMediaResources(player_id); | 628 #if defined(VIDEO_HOLE) |
| 629 ReleaseExternalSurface(player_id); |
| 630 #endif |
| 614 (*it)->DeleteOnCorrectThread(); | 631 (*it)->DeleteOnCorrectThread(); |
| 615 players_.weak_erase(it); | 632 players_.weak_erase(it); |
| 616 MediaSession::Get(web_contents())->RemovePlayer(this, player_id); | 633 MediaSession::Get(web_contents())->RemovePlayer(this, player_id); |
| 617 break; | 634 break; |
| 618 } | 635 } |
| 619 } | 636 } |
| 637 active_players_.erase(player_id); |
| 620 } | 638 } |
| 621 | 639 |
| 622 scoped_ptr<media::MediaPlayerAndroid> BrowserMediaPlayerManager::SwapPlayer( | 640 scoped_ptr<media::MediaPlayerAndroid> BrowserMediaPlayerManager::SwapPlayer( |
| 623 int player_id, media::MediaPlayerAndroid* player) { | 641 int player_id, media::MediaPlayerAndroid* player) { |
| 624 media::MediaPlayerAndroid* previous_player = NULL; | 642 media::MediaPlayerAndroid* previous_player = NULL; |
| 625 for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin(); | 643 for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin(); |
| 626 it != players_.end(); ++it) { | 644 it != players_.end(); ++it) { |
| 627 if ((*it)->player_id() == player_id) { | 645 if ((*it)->player_id() == player_id) { |
| 628 previous_player = *it; | 646 previous_player = *it; |
| 629 ReleaseMediaResources(player_id); | 647 #if defined(VIDEO_HOLE) |
| 648 ReleaseExternalSurface(player_id); |
| 649 #endif |
| 630 players_.weak_erase(it); | 650 players_.weak_erase(it); |
| 631 players_.push_back(player); | 651 players_.push_back(player); |
| 632 break; | 652 break; |
| 633 } | 653 } |
| 634 } | 654 } |
| 635 return scoped_ptr<media::MediaPlayerAndroid>(previous_player); | 655 return scoped_ptr<media::MediaPlayerAndroid>(previous_player); |
| 636 } | 656 } |
| 637 | 657 |
| 658 bool BrowserMediaPlayerManager::RequestDecoderResources( |
| 659 int player_id, bool temporary) { |
| 660 if (!MediaThrottler::GetInstance()->RequestDecoderResources()) |
| 661 return false; |
| 662 |
| 663 ActivePlayerMap::iterator it; |
| 664 // The player is already active, ignore it. A long running player should not |
| 665 // request temporary permissions. |
| 666 if ((it = active_players_.find(player_id)) != active_players_.end()) { |
| 667 DCHECK(!temporary || it->second); |
| 668 return true; |
| 669 } |
| 670 |
| 671 if (!temporary) { |
| 672 int long_running_player = 0; |
| 673 for (it = active_players_.begin(); it != active_players_.end(); ++it) { |
| 674 if (!it->second) |
| 675 long_running_player++; |
| 676 } |
| 677 |
| 678 // Number of active players are less than the threshold, do nothing. |
| 679 if (long_running_player < kMediaPlayerThreshold) |
| 680 return true; |
| 681 |
| 682 for (it = active_players_.begin(); it != active_players_.end(); ++it) { |
| 683 if (!it->second && !GetPlayer(it->first)->IsPlaying() && |
| 684 fullscreen_player_id_ != it->first) { |
| 685 ReleasePlayer(GetPlayer(it->first)); |
| 686 Send(new MediaPlayerMsg_MediaPlayerReleased(RoutingID(), |
| 687 (it->first))); |
| 688 } |
| 689 } |
| 690 } |
| 691 |
| 692 active_players_[player_id] = temporary; |
| 693 return true; |
| 694 } |
| 695 |
| 696 void BrowserMediaPlayerManager::OnDecoderResourcesReleased(int player_id) { |
| 697 if (active_players_.find(player_id) == active_players_.end()) |
| 698 return; |
| 699 |
| 700 active_players_.erase(player_id); |
| 701 MediaThrottler::GetInstance()->OnDecodeRequestFinished(); |
| 702 } |
| 703 |
| 638 int BrowserMediaPlayerManager::RoutingID() { | 704 int BrowserMediaPlayerManager::RoutingID() { |
| 639 return render_frame_host_->GetRoutingID(); | 705 return render_frame_host_->GetRoutingID(); |
| 640 } | 706 } |
| 641 | 707 |
| 642 bool BrowserMediaPlayerManager::Send(IPC::Message* msg) { | 708 bool BrowserMediaPlayerManager::Send(IPC::Message* msg) { |
| 643 return render_frame_host_->Send(msg); | 709 return render_frame_host_->Send(msg); |
| 644 } | 710 } |
| 645 | 711 |
| 646 void BrowserMediaPlayerManager::ReleaseFullscreenPlayer( | 712 void BrowserMediaPlayerManager::ReleaseFullscreenPlayer( |
| 647 MediaPlayerAndroid* player) { | 713 MediaPlayerAndroid* player) { |
| 648 ReleasePlayer(player); | 714 ReleasePlayer(player); |
| 649 } | 715 } |
| 650 | 716 |
| 651 void BrowserMediaPlayerManager::OnMediaResourcesRequested(int player_id) { | |
| 652 int num_active_player = 0; | |
| 653 ScopedVector<MediaPlayerAndroid>::iterator it; | |
| 654 for (it = players_.begin(); it != players_.end(); ++it) { | |
| 655 if (!(*it)->IsPlayerReady()) | |
| 656 continue; | |
| 657 | |
| 658 // The player is already active, ignore it. | |
| 659 if ((*it)->player_id() == player_id) | |
| 660 return; | |
| 661 else | |
| 662 num_active_player++; | |
| 663 } | |
| 664 | |
| 665 // Number of active players are less than the threshold, do nothing. | |
| 666 if (num_active_player < kMediaPlayerThreshold) | |
| 667 return; | |
| 668 | |
| 669 for (it = players_.begin(); it != players_.end(); ++it) { | |
| 670 if ((*it)->IsPlayerReady() && !(*it)->IsPlaying() && | |
| 671 fullscreen_player_id_ != (*it)->player_id()) { | |
| 672 ReleasePlayer(*it); | |
| 673 Send(new MediaPlayerMsg_MediaPlayerReleased(RoutingID(), | |
| 674 (*it)->player_id())); | |
| 675 } | |
| 676 } | |
| 677 } | |
| 678 | |
| 679 void BrowserMediaPlayerManager::ReleaseMediaResources(int player_id) { | |
| 680 #if defined(VIDEO_HOLE) | |
| 681 if (external_video_surface_container_) | |
| 682 external_video_surface_container_->ReleaseExternalVideoSurface(player_id); | |
| 683 #endif // defined(VIDEO_HOLE) | |
| 684 } | |
| 685 | |
| 686 void BrowserMediaPlayerManager::ReleasePlayer(MediaPlayerAndroid* player) { | 717 void BrowserMediaPlayerManager::ReleasePlayer(MediaPlayerAndroid* player) { |
| 687 player->Release(); | 718 player->Release(); |
| 688 ReleaseMediaResources(player->player_id()); | 719 #if defined(VIDEO_HOLE) |
| 720 ReleaseExternalSurface(player->player_id()); |
| 721 #endif |
| 722 } |
| 723 |
| 724 void BrowserMediaPlayerManager::OnPlaybackPermissionGranted( |
| 725 int player_id, bool granted) { |
| 726 if (!granted) |
| 727 return; |
| 728 |
| 729 MediaThrottler::GetInstance()->Reset(); |
| 730 StartInternal(player_id); |
| 731 } |
| 732 |
| 733 void BrowserMediaPlayerManager::StartInternal(int player_id) { |
| 734 MediaPlayerAndroid* player = GetPlayer(player_id); |
| 735 if (!player) |
| 736 return; |
| 737 player->Start(); |
| 738 if (fullscreen_player_id_ == player_id && fullscreen_player_is_released_) { |
| 739 video_view_->OpenVideo(); |
| 740 fullscreen_player_is_released_ = false; |
| 741 } |
| 689 } | 742 } |
| 690 | 743 |
| 691 } // namespace content | 744 } // namespace content |
| OLD | NEW |