Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(587)

Side by Side Diff: content/browser/media/android/browser_media_player_manager.cc

Issue 1372203002: Throttle media decoding after excessive Android media server crashes (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: addressing comments Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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::OnDecorderResourcesReleased,
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::OnDecorderResourcesReleased,
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::OnDecorderResourcesReleased,
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
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
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
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
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
638 int BrowserMediaPlayerManager::RoutingID() { 658 int BrowserMediaPlayerManager::RoutingID() {
639 return render_frame_host_->GetRoutingID(); 659 return render_frame_host_->GetRoutingID();
640 } 660 }
641 661
642 bool BrowserMediaPlayerManager::Send(IPC::Message* msg) { 662 bool BrowserMediaPlayerManager::Send(IPC::Message* msg) {
643 return render_frame_host_->Send(msg); 663 return render_frame_host_->Send(msg);
644 } 664 }
645 665
646 void BrowserMediaPlayerManager::ReleaseFullscreenPlayer( 666 void BrowserMediaPlayerManager::ReleaseFullscreenPlayer(
647 MediaPlayerAndroid* player) { 667 MediaPlayerAndroid* player) {
648 ReleasePlayer(player); 668 ReleasePlayer(player);
649 } 669 }
650 670
651 void BrowserMediaPlayerManager::OnMediaResourcesRequested(int player_id) { 671 bool BrowserMediaPlayerManager::RequestDecoderResources(
652 int num_active_player = 0; 672 int player_id, bool temporary) {
653 ScopedVector<MediaPlayerAndroid>::iterator it; 673 if (!MediaThrottler::GetInstance()->RequestDecoderResources())
654 for (it = players_.begin(); it != players_.end(); ++it) { 674 return false;
655 if (!(*it)->IsPlayerReady())
656 continue;
657 675
658 // The player is already active, ignore it. 676 ActivePlayerMap::iterator it;
659 if ((*it)->player_id() == player_id) 677 // The player is already active, ignore it. A long running player should not
660 return; 678 // request temporary permissions.
661 else 679 if ((it = active_players_.find(player_id)) != active_players_.end()) {
662 num_active_player++; 680 DCHECK(!temporary || it->second);
681 return true;
663 } 682 }
664 683
665 // Number of active players are less than the threshold, do nothing. 684 if (!temporary) {
666 if (num_active_player < kMediaPlayerThreshold) 685 int long_running_player = 0;
686 for (it = active_players_.begin(); it != active_players_.end(); ++it) {
687 if (!it->second)
688 long_running_player++;
689 }
690
691 // Number of active players are less than the threshold, do nothing.
692 if (long_running_player < kMediaPlayerThreshold)
693 return true;
694
695 for (it = active_players_.begin(); it != active_players_.end(); ++it) {
696 if (!it->second && !GetPlayer(it->first)->IsPlaying() &&
697 fullscreen_player_id_ != it->first) {
698 ReleasePlayer(GetPlayer(it->first));
699 Send(new MediaPlayerMsg_MediaPlayerReleased(RoutingID(),
700 (it->first)));
701 }
702 }
703 }
704
705 active_players_[player_id] = temporary;
706 return true;
707 }
708
709 void BrowserMediaPlayerManager::OnDecorderResourcesReleased(int player_id) {
710 if (active_players_.find(player_id) == active_players_.end())
667 return; 711 return;
668 712
669 for (it = players_.begin(); it != players_.end(); ++it) { 713 active_players_.erase(player_id);
670 if ((*it)->IsPlayerReady() && !(*it)->IsPlaying() && 714 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 } 715 }
685 716
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698