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

Unified 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: new infobar text per UI review 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/media/android/browser_media_player_manager.cc
diff --git a/content/browser/media/android/browser_media_player_manager.cc b/content/browser/media/android/browser_media_player_manager.cc
index 76c22c19c0ff1998286c16474cceab4231b4b854..37e112096e2e547ae677a9a9fbbd9eda28013daa 100644
--- a/content/browser/media/android/browser_media_player_manager.cc
+++ b/content/browser/media/android/browser_media_player_manager.cc
@@ -9,6 +9,7 @@
#include "content/browser/media/android/browser_demuxer_android.h"
#include "content/browser/media/android/media_resource_getter_impl.h"
#include "content/browser/media/android/media_session.h"
+#include "content/browser/media/android/media_throttler.h"
#include "content/browser/media/media_web_contents_observer.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_view_android.h"
@@ -143,16 +144,19 @@ MediaPlayerAndroid* BrowserMediaPlayerManager::CreateMediaPlayer(
user_agent,
hide_url_log,
this,
- base::Bind(&BrowserMediaPlayerManager::OnMediaResourcesRequested,
+ base::Bind(&BrowserMediaPlayerManager::OnDecoderResourcesReleased,
weak_ptr_factory_.GetWeakPtr()),
media_player_params.frame_url,
media_player_params.allow_credentials);
ContentViewCoreImpl* content_view_core_impl =
static_cast<ContentViewCoreImpl*>(ContentViewCore::FromWebContents(
web_contents_));
- if (!content_view_core_impl) {
- // May reach here due to prerendering. Don't extract the metadata
- // since it is expensive.
+ if (!content_view_core_impl
+ // Initialize the player will cause MediaMetadataExtractor to decode
+ // small chunks of data.
+ || !RequestDecoderResources(media_player_params.player_id, true)) {
+ // May reach here due to prerendering or throttling. Don't extract the
+ // metadata since it is expensive.
// TODO(qinmin): extract the metadata once the user decided to load
// the page.
OnMediaMetadataChanged(
@@ -169,7 +173,7 @@ MediaPlayerAndroid* BrowserMediaPlayerManager::CreateMediaPlayer(
return new MediaCodecPlayer(
media_player_params.player_id,
weak_ptr_factory_.GetWeakPtr(),
- base::Bind(&BrowserMediaPlayerManager::OnMediaResourcesRequested,
+ base::Bind(&BrowserMediaPlayerManager::OnDecoderResourcesReleased,
weak_ptr_factory_.GetWeakPtr()),
demuxer->CreateDemuxer(media_player_params.demuxer_client_id),
media_player_params.frame_url);
@@ -177,7 +181,7 @@ MediaPlayerAndroid* BrowserMediaPlayerManager::CreateMediaPlayer(
return new MediaSourcePlayer(
media_player_params.player_id,
this,
- base::Bind(&BrowserMediaPlayerManager::OnMediaResourcesRequested,
+ base::Bind(&BrowserMediaPlayerManager::OnDecoderResourcesReleased,
weak_ptr_factory_.GetWeakPtr()),
demuxer->CreateDemuxer(media_player_params.demuxer_client_id),
media_player_params.frame_url);
@@ -319,8 +323,10 @@ void BrowserMediaPlayerManager::OnSeekComplete(
void BrowserMediaPlayerManager::OnError(int player_id, int error) {
Send(new MediaPlayerMsg_MediaError(RoutingID(), player_id, error));
- if (fullscreen_player_id_ == player_id)
+ if (fullscreen_player_id_ == player_id &&
+ error != MediaPlayerAndroid::MEDIA_ERROR_INVALID_CODE) {
video_view_->OnMediaPlayerError(error);
+ }
}
void BrowserMediaPlayerManager::OnVideoSizeChanged(
@@ -475,6 +481,11 @@ void BrowserMediaPlayerManager::OnRequestExternalSurface(
base::Unretained(this)));
}
}
+
+void BrowserMediaPlayerManager::ReleaseExternalSurface(int player_id) {
+ if (external_video_surface_container_)
+ external_video_surface_container_->ReleaseExternalVideoSurface(player_id);
+}
#endif // defined(VIDEO_HOLE)
void BrowserMediaPlayerManager::OnEnterFullscreen(int player_id) {
@@ -533,10 +544,14 @@ void BrowserMediaPlayerManager::OnStart(int player_id) {
MediaPlayerAndroid* player = GetPlayer(player_id);
if (!player)
return;
- player->Start();
- if (fullscreen_player_id_ == player_id && fullscreen_player_is_released_) {
- video_view_->OpenVideo();
- fullscreen_player_is_released_ = false;
+
+ if (RequestDecoderResources(player_id, false)) {
+ StartInternal(player_id);
+ } else if (WebContentsDelegate* delegate = web_contents_->GetDelegate()){
+ delegate->RequestMediaDecodePermission(
+ web_contents_,
+ base::Bind(&BrowserMediaPlayerManager::OnPlaybackPermissionGranted,
+ weak_ptr_factory_.GetWeakPtr(), player_id));
}
}
@@ -607,13 +622,16 @@ void BrowserMediaPlayerManager::RemovePlayer(int player_id) {
for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin();
it != players_.end(); ++it) {
if ((*it)->player_id() == player_id) {
- ReleaseMediaResources(player_id);
+#if defined(VIDEO_HOLE)
+ ReleaseExternalSurface(player_id);
+#endif
(*it)->DeleteOnCorrectThread();
players_.weak_erase(it);
MediaSession::Get(web_contents())->RemovePlayer(this, player_id);
break;
}
}
+ active_players_.erase(player_id);
}
scoped_ptr<media::MediaPlayerAndroid> BrowserMediaPlayerManager::SwapPlayer(
@@ -623,7 +641,9 @@ scoped_ptr<media::MediaPlayerAndroid> BrowserMediaPlayerManager::SwapPlayer(
it != players_.end(); ++it) {
if ((*it)->player_id() == player_id) {
previous_player = *it;
- ReleaseMediaResources(player_id);
+#if defined(VIDEO_HOLE)
+ ReleaseExternalSurface(player_id);
+#endif
players_.weak_erase(it);
players_.push_back(player);
break;
@@ -632,6 +652,52 @@ scoped_ptr<media::MediaPlayerAndroid> BrowserMediaPlayerManager::SwapPlayer(
return scoped_ptr<media::MediaPlayerAndroid>(previous_player);
}
+bool BrowserMediaPlayerManager::RequestDecoderResources(
+ int player_id, bool temporary) {
+ if (!MediaThrottler::GetInstance()->RequestDecoderResources())
+ return false;
+
+ ActivePlayerMap::iterator it;
+ // The player is already active, ignore it. A long running player should not
+ // request temporary permissions.
+ if ((it = active_players_.find(player_id)) != active_players_.end()) {
+ DCHECK(!temporary || it->second);
+ return true;
+ }
+
+ if (!temporary) {
+ int long_running_player = 0;
+ for (it = active_players_.begin(); it != active_players_.end(); ++it) {
+ if (!it->second)
+ long_running_player++;
+ }
+
+ // Number of active players are less than the threshold, do nothing.
+ if (long_running_player < kMediaPlayerThreshold)
+ return true;
+
+ for (it = active_players_.begin(); it != active_players_.end(); ++it) {
+ if (!it->second && !GetPlayer(it->first)->IsPlaying() &&
+ fullscreen_player_id_ != it->first) {
+ ReleasePlayer(GetPlayer(it->first));
+ Send(new MediaPlayerMsg_MediaPlayerReleased(RoutingID(),
+ (it->first)));
+ }
+ }
+ }
+
+ active_players_[player_id] = temporary;
+ return true;
+}
+
+void BrowserMediaPlayerManager::OnDecoderResourcesReleased(int player_id) {
+ if (active_players_.find(player_id) == active_players_.end())
+ return;
+
+ active_players_.erase(player_id);
+ MediaThrottler::GetInstance()->OnDecodeRequestFinished();
+}
+
int BrowserMediaPlayerManager::RoutingID() {
return render_frame_host_->GetRoutingID();
}
@@ -645,44 +711,31 @@ void BrowserMediaPlayerManager::ReleaseFullscreenPlayer(
ReleasePlayer(player);
}
-void BrowserMediaPlayerManager::OnMediaResourcesRequested(int player_id) {
- int num_active_player = 0;
- ScopedVector<MediaPlayerAndroid>::iterator it;
- for (it = players_.begin(); it != players_.end(); ++it) {
- if (!(*it)->IsPlayerReady())
- continue;
-
- // The player is already active, ignore it.
- if ((*it)->player_id() == player_id)
- return;
- else
- num_active_player++;
- }
+void BrowserMediaPlayerManager::ReleasePlayer(MediaPlayerAndroid* player) {
+ player->Release();
+#if defined(VIDEO_HOLE)
+ ReleaseExternalSurface(player->player_id());
+#endif
+}
- // Number of active players are less than the threshold, do nothing.
- if (num_active_player < kMediaPlayerThreshold)
+void BrowserMediaPlayerManager::OnPlaybackPermissionGranted(
+ int player_id, bool granted) {
+ if (!granted)
return;
- for (it = players_.begin(); it != players_.end(); ++it) {
- if ((*it)->IsPlayerReady() && !(*it)->IsPlaying() &&
- fullscreen_player_id_ != (*it)->player_id()) {
- ReleasePlayer(*it);
- Send(new MediaPlayerMsg_MediaPlayerReleased(RoutingID(),
- (*it)->player_id()));
- }
- }
+ MediaThrottler::GetInstance()->Reset();
+ StartInternal(player_id);
}
-void BrowserMediaPlayerManager::ReleaseMediaResources(int player_id) {
-#if defined(VIDEO_HOLE)
- if (external_video_surface_container_)
- external_video_surface_container_->ReleaseExternalVideoSurface(player_id);
-#endif // defined(VIDEO_HOLE)
-}
-
-void BrowserMediaPlayerManager::ReleasePlayer(MediaPlayerAndroid* player) {
- player->Release();
- ReleaseMediaResources(player->player_id());
+void BrowserMediaPlayerManager::StartInternal(int player_id) {
+ MediaPlayerAndroid* player = GetPlayer(player_id);
+ if (!player)
+ return;
+ player->Start();
+ if (fullscreen_player_id_ == player_id && fullscreen_player_is_released_) {
+ video_view_->OpenVideo();
+ fullscreen_player_is_released_ = false;
+ }
}
} // namespace content
« no previous file with comments | « content/browser/media/android/browser_media_player_manager.h ('k') | content/browser/media/android/media_throttler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698