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

Unified Diff: webkit/media/android/webmediaplayer_android.cc

Issue 10919075: Move android mediaplayer from render process to browser process. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: addressing comments Created 8 years, 3 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: webkit/media/android/webmediaplayer_android.cc
diff --git a/webkit/media/android/webmediaplayer_android.cc b/webkit/media/android/webmediaplayer_android.cc
index 8032a8cea779b0ae778d20b3fdb19a50221f8348..fae25d6ffd800c028354feb528cefc1960a7c526 100644
--- a/webkit/media/android/webmediaplayer_android.cc
+++ b/webkit/media/android/webmediaplayer_android.cc
@@ -4,86 +4,49 @@
#include "webkit/media/android/webmediaplayer_android.h"
-#include <string>
-
-#include "base/bind.h"
-#include "base/command_line.h"
#include "base/file_path.h"
#include "base/logging.h"
-#include "base/utf_string_conversions.h"
#include "media/base/android/media_player_bridge.h"
#include "net/base/mime_util.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerClient.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCookieJar.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h"
#include "webkit/media/android/stream_texture_factory_android.h"
#include "webkit/media/android/webmediaplayer_manager_android.h"
-#include "webkit/media/android/webmediaplayer_proxy_android.h"
#include "webkit/media/webmediaplayer_util.h"
#include "webkit/media/webvideoframe_impl.h"
-using WebKit::WebCanvas;
-using WebKit::WebMediaPlayerClient;
+static const uint32 kGLTextureExternalOES = 0x8D65;
+
using WebKit::WebMediaPlayer;
-using WebKit::WebRect;
using WebKit::WebSize;
using WebKit::WebTimeRanges;
using WebKit::WebURL;
using WebKit::WebVideoFrame;
using media::MediaPlayerBridge;
using media::VideoFrame;
-using webkit_media::WebVideoFrameImpl;
-
-// TODO(qinmin): Figure out where we should define this more appropriately
-static const uint32 kGLTextureExternalOES = 0x8D65;
namespace webkit_media {
-// Because we create the media player lazily on android, the duration of the
-// media is initially unknown to us. This makes the user unable to perform
-// seek. To solve this problem, we use a temporary duration of 100 seconds when
-// the duration is unknown. And we scale the seek position later when duration
-// is available.
-// TODO(qinmin): create a thread and use android MediaMetadataRetriever
-// class to extract the duration.
-static const float kTemporaryDuration = 100.0f;
-
-bool WebMediaPlayerAndroid::incognito_mode_ = false;
-
WebMediaPlayerAndroid::WebMediaPlayerAndroid(
- WebKit::WebFrame* frame,
- WebMediaPlayerClient* client,
- WebKit::WebCookieJar* cookie_jar,
- webkit_media::WebMediaPlayerManagerAndroid* manager,
- webkit_media::StreamTextureFactory* factory)
- : frame_(frame),
- client_(client),
+ WebKit::WebMediaPlayerClient* client,
+ WebMediaPlayerManagerAndroid* manager,
+ StreamTextureFactory* factory)
+ : client_(client),
buffered_(1u),
video_frame_(new WebVideoFrameImpl(VideoFrame::CreateEmptyFrame())),
main_loop_(MessageLoop::current()),
- proxy_(new WebMediaPlayerProxyAndroid(main_loop_->message_loop_proxy(),
- AsWeakPtr())),
- prepared_(false),
- duration_(0),
pending_seek_(0),
seeking_(false),
- playback_completed_(false),
did_loading_progress_(false),
- cookie_jar_(cookie_jar),
manager_(manager),
- pending_play_event_(false),
network_state_(WebMediaPlayer::NetworkStateEmpty),
ready_state_(WebMediaPlayer::ReadyStateHaveNothing),
- texture_id_(0),
- stream_id_(0),
+ is_playing_(false),
needs_establish_peer_(true),
stream_texture_factory_(factory) {
main_loop_->AddDestructionObserver(this);
if (manager_)
player_id_ = manager_->RegisterMediaPlayer(this);
+
if (stream_texture_factory_.get()) {
stream_texture_proxy_.reset(stream_texture_factory_->CreateProxy());
stream_id_ = stream_texture_factory_->CreateStreamTexture(&texture_id_);
@@ -91,50 +54,23 @@ WebMediaPlayerAndroid::WebMediaPlayerAndroid(
}
WebMediaPlayerAndroid::~WebMediaPlayerAndroid() {
- if (manager_)
- manager_->UnregisterMediaPlayer(player_id_);
-
if (stream_id_)
stream_texture_factory_->DestroyStreamTexture(texture_id_);
+ if (manager_)
+ manager_->UnregisterMediaPlayer(player_id_);
+
if (main_loop_)
main_loop_->RemoveDestructionObserver(this);
}
-void WebMediaPlayerAndroid::InitIncognito(bool incognito_mode) {
- incognito_mode_ = incognito_mode;
-}
-
void WebMediaPlayerAndroid::load(const WebURL& url, CORSMode cors_mode) {
if (cors_mode != CORSModeUnspecified)
NOTIMPLEMENTED() << "No CORS support";
url_ = url;
- UpdateNetworkState(WebMediaPlayer::NetworkStateLoading);
- UpdateReadyState(WebMediaPlayer::ReadyStateHaveNothing);
-
- // Calling InitializeMediaPlayer() will cause android mediaplayer to start
- // buffering and decoding the data. On mobile devices, this costs a lot of
- // data usage and could even introduce performance issues. So we don't
- // initialize the player unless it is a local file. We will start loading
- // the media only when play/seek/fullsceen button is clicked.
- if (url_.SchemeIs("file")) {
- InitializeMediaPlayer();
- return;
- }
-
- // TODO(qinmin): we need a method to calculate the duration of the media.
- // Android does not provide any function to do that.
- // Set the initial duration value to kTemporaryDuration so that user can
- // touch the seek bar to perform seek. We will scale the seek position later
- // when we got the actual duration.
- duration_ = kTemporaryDuration;
-
- // Pretend everything has been loaded so that webkit can
- // still call play() and seek().
- UpdateReadyState(WebMediaPlayer::ReadyStateHaveMetadata);
- UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
+ InitializeMediaPlayer(url_);
}
void WebMediaPlayerAndroid::cancelLoad() {
@@ -142,42 +78,23 @@ void WebMediaPlayerAndroid::cancelLoad() {
}
void WebMediaPlayerAndroid::play() {
- if (media_player_.get()) {
- if (!prepared_)
- pending_play_event_ = true;
- else
- PlayInternal();
- } else {
- pending_play_event_ = true;
- InitializeMediaPlayer();
- }
+ if (hasVideo() && needs_establish_peer_)
+ EstablishSurfaceTexturePeer();
+
+ PlayInternal();
+ is_playing_ = true;
}
void WebMediaPlayerAndroid::pause() {
- if (media_player_.get()) {
- if (!prepared_)
- pending_play_event_ = false;
- else
- PauseInternal();
- } else {
- // We don't need to load media if pause() is called.
- pending_play_event_ = false;
- }
+ PauseInternal();
+ is_playing_ = false;
}
void WebMediaPlayerAndroid::seek(float seconds) {
- // Record the time to seek when OnMediaPrepared() is called.
pending_seek_ = seconds;
+ seeking_ = true;
- // Reset |playback_completed_| so that we return the correct current time.
- playback_completed_ = false;
-
- if (media_player_.get()) {
- if (prepared_)
- SeekInternal(seconds);
- } else {
- InitializeMediaPlayer();
- }
+ SeekInternal(ConvertSecondsToTimestamp(seconds));
}
bool WebMediaPlayerAndroid::supportsFullscreen() const {
@@ -198,8 +115,7 @@ void WebMediaPlayerAndroid::setRate(float rate) {
}
void WebMediaPlayerAndroid::setVolume(float volume) {
- if (media_player_.get())
- media_player_->SetVolume(volume, volume);
+ NOTIMPLEMENTED();
}
void WebMediaPlayerAndroid::setVisible(bool visible) {
@@ -213,6 +129,10 @@ bool WebMediaPlayerAndroid::totalBytesKnown() {
}
bool WebMediaPlayerAndroid::hasVideo() const {
+ // If we have obtained video size information before, use it.
+ if (!natural_size_.isEmpty())
+ return true;
+
// TODO(qinmin): need a better method to determine whether the current media
// content contains video. Android does not provide any function to do
// this.
@@ -221,16 +141,12 @@ bool WebMediaPlayerAndroid::hasVideo() const {
// to the mime-type. There may be no mime-type on a redirect URL.
// In that case, we conservatively assume it contains video so that
// enterfullscreen call will not fail.
- if (!prepared_) {
- if (!url_.has_path())
- return false;
- std::string mime;
- if(!net::GetMimeTypeFromFile(FilePath(url_.path()), &mime))
- return true;
- return mime.find("audio/") == std::string::npos;
- }
-
- return !natural_size_.isEmpty();
+ if (!url_.has_path())
+ return false;
+ std::string mime;
+ if(!net::GetMimeTypeFromFile(FilePath(url_.path()), &mime))
+ return true;
+ return mime.find("audio/") == std::string::npos;
}
bool WebMediaPlayerAndroid::hasAudio() const {
@@ -239,9 +155,7 @@ bool WebMediaPlayerAndroid::hasAudio() const {
}
bool WebMediaPlayerAndroid::paused() const {
- if (!prepared_)
- return !pending_play_event_;
- return !media_player_->IsPlaying();
+ return !is_playing_;
}
bool WebMediaPlayerAndroid::seeking() const {
@@ -249,23 +163,15 @@ bool WebMediaPlayerAndroid::seeking() const {
}
float WebMediaPlayerAndroid::duration() const {
- return duration_;
+ return static_cast<float>(duration_.InSecondsF());
}
float WebMediaPlayerAndroid::currentTime() const {
// If the player is pending for a seek, return the seek time.
- if (!prepared_ || seeking())
+ if (seeking())
return pending_seek_;
- // When playback is about to finish, android media player often stops
- // at a time which is smaller than the duration. This makes webkit never
- // know that the playback has finished. To solve this, we set the
- // current time to media duration when OnPlaybackComplete() get called.
- // And return the greater of the two values so that the current
- // time is most updated.
- if (playback_completed_)
- return duration();
- return static_cast<float>(media_player_->GetCurrentTime().InSecondsF());
+ return GetCurrentTimeInternal();
}
int WebMediaPlayerAndroid::dataRate() const {
@@ -307,8 +213,7 @@ unsigned long long WebMediaPlayerAndroid::totalBytes() const {
return 0;
}
-void WebMediaPlayerAndroid::setSize(const WebSize& size) {
- texture_size_ = size;
+void WebMediaPlayerAndroid::setSize(const WebKit::WebSize& size) {
}
void WebMediaPlayerAndroid::paint(WebKit::WebCanvas* canvas,
@@ -325,8 +230,7 @@ bool WebMediaPlayerAndroid::didPassCORSAccessCheck() const {
return false;
}
-WebMediaPlayer::MovieLoadType
- WebMediaPlayerAndroid::movieLoadType() const {
+WebMediaPlayer::MovieLoadType WebMediaPlayerAndroid::movieLoadType() const {
// Deprecated.
// TODO(qinmin): Remove this from WebKit::WebMediaPlayer as it is never used.
return WebMediaPlayer::MovieLoadTypeUnknown;
@@ -356,17 +260,7 @@ unsigned WebMediaPlayerAndroid::videoDecodedByteCount() const {
return 0;
}
-void WebMediaPlayerAndroid::OnMediaPrepared() {
- if (!media_player_.get())
- return;
-
- prepared_ = true;
-
- // Update the media duration first so that webkit will get the correct
- // duration when UpdateReadyState is called.
- float dur = duration_;
- duration_ = media_player_->GetDuration().InSecondsF();
-
+void WebMediaPlayerAndroid::OnMediaPrepared(base::TimeDelta duration) {
if (url_.SchemeIs("file"))
UpdateNetworkState(WebMediaPlayer::NetworkStateLoaded);
@@ -379,30 +273,20 @@ void WebMediaPlayerAndroid::OnMediaPrepared() {
UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
}
- if (!url_.SchemeIs("file")) {
- // In we have skipped loading, the duration was preset to
- // kTemporaryDuration. We have to update webkit about the new duration.
- if (duration_ != dur) {
- // Scale the |pending_seek_| according to the new duration.
- pending_seek_ = pending_seek_ * duration_ / kTemporaryDuration;
- client_->durationChanged();
- }
+ // In we have skipped loading, we have to update webkit about the new
+ // duration.
+ if (duration_ != duration) {
+ duration_ = duration;
+ client_->durationChanged();
}
-
- // If media player was recovered from a saved state, consume all the pending
- // events.
- seek(pending_seek_);
-
- if (pending_play_event_)
- PlayInternal();
-
- pending_play_event_ = false;
}
void WebMediaPlayerAndroid::OnPlaybackComplete() {
- // Set the current time equal to duration to let webkit know that play back
- // is completed.
- playback_completed_ = true;
+ // When playback is about to finish, android media player often stops
+ // at a time which is smaller than the duration. This makes webkit never
+ // know that the playback has finished. To solve this, we set the
+ // current time to media duration when OnPlaybackComplete() get called.
+ OnTimeUpdate(duration_);
client_->timeChanged();
}
@@ -411,9 +295,11 @@ void WebMediaPlayerAndroid::OnBufferingUpdate(int percentage) {
did_loading_progress_ = true;
}
-void WebMediaPlayerAndroid::OnSeekComplete() {
+void WebMediaPlayerAndroid::OnSeekComplete(base::TimeDelta current_time) {
seeking_ = false;
+ OnTimeUpdate(current_time);
+
UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
client_->timeChanged();
@@ -441,10 +327,6 @@ void WebMediaPlayerAndroid::OnMediaError(int error_type) {
client_->repaint();
}
-void WebMediaPlayerAndroid::OnMediaInfo(int info_type) {
- NOTIMPLEMENTED();
-}
-
void WebMediaPlayerAndroid::OnVideoSizeChanged(int width, int height) {
if (natural_size_.width == width && natural_size_.height == height)
return;
@@ -471,84 +353,39 @@ void WebMediaPlayerAndroid::UpdateReadyState(
client_->readyStateChanged();
}
+void WebMediaPlayerAndroid::OnPlayerReleased() {
+ needs_establish_peer_ = true;
+}
+
void WebMediaPlayerAndroid::ReleaseMediaResources() {
// Pause the media player first.
pause();
client_->playbackStateChanged();
- if (media_player_.get()) {
- // Save the current media player status.
- pending_seek_ = currentTime();
- duration_ = duration();
-
- media_player_.reset();
- needs_establish_peer_ = true;
- }
- prepared_ = false;
-}
-
-bool WebMediaPlayerAndroid::IsInitialized() const {
- return (media_player_ != NULL);
-}
-
-void WebMediaPlayerAndroid::InitializeMediaPlayer() {
- CHECK(!media_player_.get());
- prepared_ = false;
- media_player_.reset(new MediaPlayerBridge());
- media_player_->SetStayAwakeWhilePlaying();
-
- std::string cookies;
- if (cookie_jar_ != NULL) {
- WebURL first_party_url(frame_->document().firstPartyForCookies());
- cookies = UTF16ToUTF8(cookie_jar_->cookies(url_, first_party_url));
- }
- media_player_->SetDataSource(url_.spec(), cookies, incognito_mode_);
-
- if (manager_)
- manager_->RequestMediaResources(player_id_);
-
- media_player_->Prepare(
- base::Bind(&WebMediaPlayerProxyAndroid::MediaInfoCallback, proxy_),
- base::Bind(&WebMediaPlayerProxyAndroid::MediaErrorCallback, proxy_),
- base::Bind(&WebMediaPlayerProxyAndroid::VideoSizeChangedCallback, proxy_),
- base::Bind(&WebMediaPlayerProxyAndroid::BufferingUpdateCallback, proxy_),
- base::Bind(&WebMediaPlayerProxyAndroid::MediaPreparedCallback, proxy_));
+ ReleaseResourcesInternal();
+ OnPlayerReleased();
}
-void WebMediaPlayerAndroid::PlayInternal() {
- CHECK(prepared_);
+void WebMediaPlayerAndroid::WillDestroyCurrentMessageLoop() {
+ Destroy();
- if (hasVideo() && stream_texture_factory_.get()) {
- if (needs_establish_peer_) {
- stream_texture_factory_->EstablishPeer(stream_id_, player_id_);
- needs_establish_peer_ = false;
- }
+ if (stream_id_) {
+ stream_texture_factory_->DestroyStreamTexture(texture_id_);
+ stream_id_ = 0;
}
- if (paused())
- media_player_->Start(base::Bind(
- &WebMediaPlayerProxyAndroid::PlaybackCompleteCallback, proxy_));
-}
-
-void WebMediaPlayerAndroid::PauseInternal() {
- CHECK(prepared_);
- media_player_->Pause();
-}
+ video_frame_.reset(new WebVideoFrameImpl(VideoFrame::CreateEmptyFrame()));
-void WebMediaPlayerAndroid::SeekInternal(float seconds) {
- CHECK(prepared_);
- seeking_ = true;
- media_player_->SeekTo(ConvertSecondsToTimestamp(seconds), base::Bind(
- &WebMediaPlayerProxyAndroid::SeekCompleteCallback, proxy_));
-}
+ if (manager_)
+ manager_->UnregisterMediaPlayer(player_id_);
-void WebMediaPlayerAndroid::WillDestroyCurrentMessageLoop() {
manager_ = NULL;
main_loop_ = NULL;
}
WebVideoFrame* WebMediaPlayerAndroid::getCurrentFrame() {
- if (!stream_texture_proxy_->IsInitialized() && stream_id_) {
+ if (stream_texture_proxy_.get() && !stream_texture_proxy_->IsInitialized()
+ && stream_id_) {
stream_texture_proxy_->Initialize(
stream_id_, video_frame_->width(), video_frame_->height());
}
@@ -560,11 +397,20 @@ void WebMediaPlayerAndroid::putCurrentFrame(
WebVideoFrame* web_video_frame) {
}
-// This gets called both on compositor and main thread.
void WebMediaPlayerAndroid::setStreamTextureClient(
WebKit::WebStreamTextureClient* client) {
if (stream_texture_proxy_.get())
stream_texture_proxy_->SetClient(client);
}
+void WebMediaPlayerAndroid::EstablishSurfaceTexturePeer() {
+ if (stream_texture_factory_.get() && stream_id_)
+ stream_texture_factory_->EstablishPeer(stream_id_, player_id_);
+ needs_establish_peer_ = false;
+}
+
+void WebMediaPlayerAndroid::UpdatePlayingState(bool is_playing) {
+ is_playing_ = is_playing;
+}
+
} // namespace webkit_media

Powered by Google App Engine
This is Rietveld 408576698