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