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::OnPlayerReleased, |
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 || !RequestDecoderResources(media_player_params.player_id, true)) { |
Ted C
2015/09/28 22:42:29
why is this temporary? maybe my question from the
qinmin
2015/09/29 23:16:22
This is because calling Initialize() will decode a
| |
156 // since it is expensive. | 157 // May reach here due to prerendering or throttling. Don't extract the |
158 // metadata since it is expensive. | |
157 // TODO(qinmin): extract the metadata once the user decided to load | 159 // TODO(qinmin): extract the metadata once the user decided to load |
158 // the page. | 160 // the page. |
159 OnMediaMetadataChanged( | 161 OnMediaMetadataChanged( |
160 media_player_params.player_id, base::TimeDelta(), 0, 0, false); | 162 media_player_params.player_id, base::TimeDelta(), 0, 0, false); |
161 } else if (!content_view_core_impl->ShouldBlockMediaRequest( | 163 } else if (!content_view_core_impl->ShouldBlockMediaRequest( |
162 media_player_params.url)) { | 164 media_player_params.url)) { |
163 media_player_bridge->Initialize(); | 165 media_player_bridge->Initialize(); |
164 } | 166 } |
165 return media_player_bridge; | 167 return media_player_bridge; |
166 } | 168 } |
167 | 169 |
168 case MEDIA_PLAYER_TYPE_MEDIA_SOURCE: { | 170 case MEDIA_PLAYER_TYPE_MEDIA_SOURCE: { |
169 if (base::CommandLine::ForCurrentProcess()-> | 171 if (base::CommandLine::ForCurrentProcess()-> |
170 HasSwitch(switches::kEnableMediaThreadForMediaPlayback)) { | 172 HasSwitch(switches::kEnableMediaThreadForMediaPlayback)) { |
171 return new MediaCodecPlayer( | 173 return new MediaCodecPlayer( |
172 media_player_params.player_id, | 174 media_player_params.player_id, |
173 weak_ptr_factory_.GetWeakPtr(), | 175 weak_ptr_factory_.GetWeakPtr(), |
174 base::Bind(&BrowserMediaPlayerManager::OnMediaResourcesRequested, | 176 base::Bind(&BrowserMediaPlayerManager::OnPlayerReleased, |
175 weak_ptr_factory_.GetWeakPtr()), | 177 weak_ptr_factory_.GetWeakPtr()), |
176 demuxer->CreateDemuxer(media_player_params.demuxer_client_id), | 178 demuxer->CreateDemuxer(media_player_params.demuxer_client_id), |
177 media_player_params.frame_url); | 179 media_player_params.frame_url); |
178 } else { | 180 } else { |
179 return new MediaSourcePlayer( | 181 return new MediaSourcePlayer( |
180 media_player_params.player_id, | 182 media_player_params.player_id, |
181 this, | 183 this, |
182 base::Bind(&BrowserMediaPlayerManager::OnMediaResourcesRequested, | 184 base::Bind(&BrowserMediaPlayerManager::OnPlayerReleased, |
183 weak_ptr_factory_.GetWeakPtr()), | 185 weak_ptr_factory_.GetWeakPtr()), |
184 demuxer->CreateDemuxer(media_player_params.demuxer_client_id), | 186 demuxer->CreateDemuxer(media_player_params.demuxer_client_id), |
185 media_player_params.frame_url); | 187 media_player_params.frame_url); |
186 } | 188 } |
187 } | 189 } |
188 } | 190 } |
189 | 191 |
190 NOTREACHED(); | 192 NOTREACHED(); |
191 return NULL; | 193 return NULL; |
192 } | 194 } |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
314 } | 316 } |
315 | 317 |
316 void BrowserMediaPlayerManager::OnSeekComplete( | 318 void BrowserMediaPlayerManager::OnSeekComplete( |
317 int player_id, | 319 int player_id, |
318 const base::TimeDelta& current_time) { | 320 const base::TimeDelta& current_time) { |
319 Send(new MediaPlayerMsg_SeekCompleted(RoutingID(), player_id, current_time)); | 321 Send(new MediaPlayerMsg_SeekCompleted(RoutingID(), player_id, current_time)); |
320 } | 322 } |
321 | 323 |
322 void BrowserMediaPlayerManager::OnError(int player_id, int error) { | 324 void BrowserMediaPlayerManager::OnError(int player_id, int error) { |
323 Send(new MediaPlayerMsg_MediaError(RoutingID(), player_id, error)); | 325 Send(new MediaPlayerMsg_MediaError(RoutingID(), player_id, error)); |
324 if (fullscreen_player_id_ == player_id) | 326 if (fullscreen_player_id_ == player_id && |
327 error != MediaPlayerAndroid::MEDIA_ERROR_INVALID_CODE) { | |
325 video_view_->OnMediaPlayerError(error); | 328 video_view_->OnMediaPlayerError(error); |
329 } | |
326 } | 330 } |
327 | 331 |
328 void BrowserMediaPlayerManager::OnVideoSizeChanged( | 332 void BrowserMediaPlayerManager::OnVideoSizeChanged( |
329 int player_id, int width, int height) { | 333 int player_id, int width, int height) { |
330 Send(new MediaPlayerMsg_MediaVideoSizeChanged(RoutingID(), player_id, | 334 Send(new MediaPlayerMsg_MediaVideoSizeChanged(RoutingID(), player_id, |
331 width, height)); | 335 width, height)); |
332 if (fullscreen_player_id_ == player_id) | 336 if (fullscreen_player_id_ == player_id) |
333 video_view_->OnVideoSizeChanged(width, height); | 337 video_view_->OnVideoSizeChanged(width, height); |
334 } | 338 } |
335 | 339 |
(...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. | 475 // In case we're stealing the external surface from another player. |
472 ReleasePlayerOfExternalVideoSurfaceIfNeeded(player_id); | 476 ReleasePlayerOfExternalVideoSurfaceIfNeeded(player_id); |
473 external_video_surface_container_->RequestExternalVideoSurface( | 477 external_video_surface_container_->RequestExternalVideoSurface( |
474 player_id, | 478 player_id, |
475 base::Bind(&BrowserMediaPlayerManager::AttachExternalVideoSurface, | 479 base::Bind(&BrowserMediaPlayerManager::AttachExternalVideoSurface, |
476 base::Unretained(this)), | 480 base::Unretained(this)), |
477 base::Bind(&BrowserMediaPlayerManager::DetachExternalVideoSurface, | 481 base::Bind(&BrowserMediaPlayerManager::DetachExternalVideoSurface, |
478 base::Unretained(this))); | 482 base::Unretained(this))); |
479 } | 483 } |
480 } | 484 } |
485 | |
486 void BrowserMediaPlayerManager::ReleaseExternalSurface(int player_id) { | |
487 if (external_video_surface_container_) | |
488 external_video_surface_container_->ReleaseExternalVideoSurface(player_id); | |
489 } | |
481 #endif // defined(VIDEO_HOLE) | 490 #endif // defined(VIDEO_HOLE) |
482 | 491 |
483 void BrowserMediaPlayerManager::OnEnterFullscreen(int player_id) { | 492 void BrowserMediaPlayerManager::OnEnterFullscreen(int player_id) { |
484 DCHECK_EQ(fullscreen_player_id_, kInvalidMediaPlayerId); | 493 DCHECK_EQ(fullscreen_player_id_, kInvalidMediaPlayerId); |
485 #if defined(VIDEO_HOLE) | 494 #if defined(VIDEO_HOLE) |
486 // If this fullscreen player is started when another player | 495 // If this fullscreen player is started when another player |
487 // uses the external surface, release that other player. | 496 // uses the external surface, release that other player. |
488 ReleasePlayerOfExternalVideoSurfaceIfNeeded(player_id); | 497 ReleasePlayerOfExternalVideoSurfaceIfNeeded(player_id); |
489 if (external_video_surface_container_) | 498 if (external_video_surface_container_) |
490 external_video_surface_container_->ReleaseExternalVideoSurface(player_id); | 499 external_video_surface_container_->ReleaseExternalVideoSurface(player_id); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
526 host->GetBrowserContext()->IsOffTheRecord(), | 535 host->GetBrowserContext()->IsOffTheRecord(), |
527 host->browser_demuxer_android().get()); | 536 host->browser_demuxer_android().get()); |
528 | 537 |
529 if (!player) | 538 if (!player) |
530 return; | 539 return; |
531 | 540 |
532 AddPlayer(player); | 541 AddPlayer(player); |
533 } | 542 } |
534 | 543 |
535 void BrowserMediaPlayerManager::OnStart(int player_id) { | 544 void BrowserMediaPlayerManager::OnStart(int player_id) { |
536 MediaPlayerAndroid* player = GetPlayer(player_id); | 545 MediaPlayerAndroid* player = GetPlayer(player_id); |
Tima Vaisburd
2015/09/28 22:09:12
Do you need to get the |player| here and at the be
qinmin
2015/09/29 23:16:22
Yes, both places.
Here we will show the infobar, b
| |
537 if (!player) | 546 if (!player) |
538 return; | 547 return; |
539 player->Start(); | 548 |
540 if (fullscreen_player_id_ == player_id && fullscreen_player_is_released_) { | 549 if (RequestDecoderResources(player_id, false)) { |
541 video_view_->OpenVideo(); | 550 StartInternal(player_id); |
542 fullscreen_player_is_released_ = false; | 551 } else if (WebContentsDelegate* delegate = web_contents_->GetDelegate()){ |
552 delegate->RequestMediaDecodePermission( | |
553 web_contents_, | |
554 base::Bind(&BrowserMediaPlayerManager::OnPlaybackPermissionGranted, | |
555 weak_ptr_factory_.GetWeakPtr(), player_id)); | |
543 } | 556 } |
544 } | 557 } |
545 | 558 |
546 void BrowserMediaPlayerManager::OnSeek( | 559 void BrowserMediaPlayerManager::OnSeek( |
547 int player_id, | 560 int player_id, |
548 const base::TimeDelta& time) { | 561 const base::TimeDelta& time) { |
549 MediaPlayerAndroid* player = GetPlayer(player_id); | 562 MediaPlayerAndroid* player = GetPlayer(player_id); |
550 if (player) | 563 if (player) |
551 player->SeekTo(time); | 564 player->SeekTo(time); |
552 } | 565 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
603 | 616 |
604 void BrowserMediaPlayerManager::AddPlayer(MediaPlayerAndroid* player) { | 617 void BrowserMediaPlayerManager::AddPlayer(MediaPlayerAndroid* player) { |
605 DCHECK(!GetPlayer(player->player_id())); | 618 DCHECK(!GetPlayer(player->player_id())); |
606 players_.push_back(player); | 619 players_.push_back(player); |
607 } | 620 } |
608 | 621 |
609 void BrowserMediaPlayerManager::RemovePlayer(int player_id) { | 622 void BrowserMediaPlayerManager::RemovePlayer(int player_id) { |
610 for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin(); | 623 for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin(); |
611 it != players_.end(); ++it) { | 624 it != players_.end(); ++it) { |
612 if ((*it)->player_id() == player_id) { | 625 if ((*it)->player_id() == player_id) { |
613 ReleaseMediaResources(player_id); | 626 #if defined(VIDEO_HOLE) |
627 ReleaseExternalSurface(player_id); | |
628 #endif | |
614 (*it)->DeleteOnCorrectThread(); | 629 (*it)->DeleteOnCorrectThread(); |
615 players_.weak_erase(it); | 630 players_.weak_erase(it); |
616 MediaSession::Get(web_contents())->RemovePlayer(this, player_id); | 631 MediaSession::Get(web_contents())->RemovePlayer(this, player_id); |
617 break; | 632 break; |
618 } | 633 } |
619 } | 634 } |
635 active_players_.erase(player_id); | |
620 } | 636 } |
621 | 637 |
622 scoped_ptr<media::MediaPlayerAndroid> BrowserMediaPlayerManager::SwapPlayer( | 638 scoped_ptr<media::MediaPlayerAndroid> BrowserMediaPlayerManager::SwapPlayer( |
623 int player_id, media::MediaPlayerAndroid* player) { | 639 int player_id, media::MediaPlayerAndroid* player) { |
624 media::MediaPlayerAndroid* previous_player = NULL; | 640 media::MediaPlayerAndroid* previous_player = NULL; |
625 for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin(); | 641 for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin(); |
626 it != players_.end(); ++it) { | 642 it != players_.end(); ++it) { |
627 if ((*it)->player_id() == player_id) { | 643 if ((*it)->player_id() == player_id) { |
628 previous_player = *it; | 644 previous_player = *it; |
629 ReleaseMediaResources(player_id); | 645 #if defined(VIDEO_HOLE) |
646 ReleaseExternalSurface(player_id); | |
647 #endif | |
630 players_.weak_erase(it); | 648 players_.weak_erase(it); |
631 players_.push_back(player); | 649 players_.push_back(player); |
632 break; | 650 break; |
633 } | 651 } |
634 } | 652 } |
635 return scoped_ptr<media::MediaPlayerAndroid>(previous_player); | 653 return scoped_ptr<media::MediaPlayerAndroid>(previous_player); |
636 } | 654 } |
637 | 655 |
638 int BrowserMediaPlayerManager::RoutingID() { | 656 int BrowserMediaPlayerManager::RoutingID() { |
639 return render_frame_host_->GetRoutingID(); | 657 return render_frame_host_->GetRoutingID(); |
640 } | 658 } |
641 | 659 |
642 bool BrowserMediaPlayerManager::Send(IPC::Message* msg) { | 660 bool BrowserMediaPlayerManager::Send(IPC::Message* msg) { |
643 return render_frame_host_->Send(msg); | 661 return render_frame_host_->Send(msg); |
644 } | 662 } |
645 | 663 |
646 void BrowserMediaPlayerManager::ReleaseFullscreenPlayer( | 664 void BrowserMediaPlayerManager::ReleaseFullscreenPlayer( |
647 MediaPlayerAndroid* player) { | 665 MediaPlayerAndroid* player) { |
648 ReleasePlayer(player); | 666 ReleasePlayer(player); |
649 } | 667 } |
650 | 668 |
651 void BrowserMediaPlayerManager::OnMediaResourcesRequested(int player_id) { | 669 bool BrowserMediaPlayerManager::RequestDecoderResources( |
652 int num_active_player = 0; | 670 int player_id, bool temporary) { |
653 ScopedVector<MediaPlayerAndroid>::iterator it; | 671 if (!MediaThrottler::GetInstance()->RequestToDecodeData()) |
654 for (it = players_.begin(); it != players_.end(); ++it) { | 672 return false; |
655 if (!(*it)->IsPlayerReady()) | |
656 continue; | |
657 | 673 |
658 // The player is already active, ignore it. | 674 // The player is already active, ignore it. A long running player should not |
659 if ((*it)->player_id() == player_id) | 675 // request temporary permissions. |
Ted C
2015/09/28 22:42:29
should there be an assert about that?
qinmin
2015/09/29 23:16:22
Done.
| |
660 return; | 676 if (active_players_.find(player_id) != active_players_.end()) |
661 else | 677 return true; |
662 num_active_player++; | 678 |
679 if (!temporary) { | |
680 int long_running_player = 0; | |
681 ActivePlayerMap::iterator it; | |
682 for (it = active_players_.begin(); it != active_players_.end(); ++it) { | |
683 if (!it->second) | |
684 long_running_player++; | |
685 } | |
686 | |
687 // Number of active players are less than the threshold, do nothing. | |
688 if (long_running_player < kMediaPlayerThreshold) | |
689 return true; | |
690 | |
691 for (it = active_players_.begin(); it != active_players_.end(); ++it) { | |
692 if (!it->second && !GetPlayer(it->first)->IsPlaying() && | |
693 fullscreen_player_id_ != it->first) { | |
694 ReleasePlayer(GetPlayer(it->first)); | |
695 Send(new MediaPlayerMsg_MediaPlayerReleased(RoutingID(), | |
696 (it->first))); | |
697 } | |
698 } | |
663 } | 699 } |
664 | 700 |
665 // Number of active players are less than the threshold, do nothing. | 701 active_players_[player_id] = temporary; |
666 if (num_active_player < kMediaPlayerThreshold) | 702 return true; |
703 } | |
704 | |
705 void BrowserMediaPlayerManager::OnPlayerReleased(int player_id) { | |
706 if (active_players_.find(player_id) == active_players_.end()) | |
667 return; | 707 return; |
668 | 708 |
669 for (it = players_.begin(); it != players_.end(); ++it) { | 709 active_players_.erase(player_id); |
670 if ((*it)->IsPlayerReady() && !(*it)->IsPlaying() && | 710 MediaThrottler::GetInstance()->OnDecodeRequestFinished(); |
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 } | 711 } |
685 | 712 |
686 void BrowserMediaPlayerManager::ReleasePlayer(MediaPlayerAndroid* player) { | 713 void BrowserMediaPlayerManager::ReleasePlayer(MediaPlayerAndroid* player) { |
687 player->Release(); | 714 player->Release(); |
688 ReleaseMediaResources(player->player_id()); | 715 #if defined(VIDEO_HOLE) |
716 ReleaseExternalSurface(player->player_id()); | |
717 #endif | |
718 } | |
719 | |
720 void BrowserMediaPlayerManager::OnPlaybackPermissionGranted( | |
721 int player_id, bool granted) { | |
722 if (!granted) | |
723 return; | |
Ted C
2015/09/28 22:42:29
is there any cleanup to be done here?
qinmin
2015/09/29 23:16:22
not needed, the player has to acquire permission f
| |
724 | |
725 MediaThrottler::GetInstance()->Reset(); | |
726 StartInternal(player_id); | |
727 } | |
728 | |
729 void BrowserMediaPlayerManager::StartInternal(int player_id) { | |
730 MediaPlayerAndroid* player = GetPlayer(player_id); | |
731 if (!player) | |
732 return; | |
733 player->Start(); | |
734 if (fullscreen_player_id_ == player_id && fullscreen_player_is_released_) { | |
735 video_view_->OpenVideo(); | |
736 fullscreen_player_is_released_ = false; | |
737 } | |
689 } | 738 } |
690 | 739 |
691 } // namespace content | 740 } // namespace content |
OLD | NEW |