Commit e45912ef authored by qinmin@chromium.org's avatar qinmin@chromium.org

Upstream WebMediaPlayerAndroid as WebKit::WebMediaPlayer implementation on android.

I've seperated the WebMediaPlayerAndroid into several changes so that each change will be easier to understand.
This is the first change in the series. It implements the basic functionalities needed for WebMediaPlayer on android.

Here are the things that are missing and will be addressed in future changes:
1. Only audio is working after this change (for video, you can only hear audio now). Video will be in the next change.
2. Fullscreen implementation is missing in this change, it will come after the video change.

BUG=
TEST=


Review URL: http://codereview.chromium.org/10073016

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@133971 0039d316-1c4b-4281-b951-d872f2087c98
parent b880b2d8
This diff is collapsed.
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef WEBKIT_MEDIA_ANDROID_WEBMEDIAPLAYER_ANDROID_H_
#define WEBKIT_MEDIA_ANDROID_WEBMEDIAPLAYER_ANDROID_H_
#include <jni.h>
#include "base/basictypes.h"
#include "base/message_loop_proxy.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayer.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebVideoFrame.h"
namespace WebKit {
class WebCookieJar;
}
namespace media {
class MediaPlayerBridge;
}
namespace webkit_media {
class WebMediaPlayerProxyAndroid;
// This class serves as the android implementation of WebKit::WebMediaPlayer.
// It implements all the playback functions by forwarding calls to android
// media player, and reports player state changes to the webkit.
class WebMediaPlayerAndroid :
public WebKit::WebMediaPlayer,
public base::SupportsWeakPtr<WebMediaPlayerAndroid> {
public:
WebMediaPlayerAndroid(WebKit::WebMediaPlayerClient* client,
WebKit::WebCookieJar* cookie_jar);
virtual ~WebMediaPlayerAndroid() OVERRIDE;
// Set |incognito_mode_| to true if in incognito mode.
static void InitIncognito(bool incognito_mode);
// Resource loading.
virtual void load(const WebKit::WebURL& url) OVERRIDE;
virtual void cancelLoad() OVERRIDE;
// Playback controls.
virtual void play() OVERRIDE;
virtual void pause() OVERRIDE;
virtual void seek(float seconds) OVERRIDE;
virtual bool supportsFullscreen() const OVERRIDE;
virtual bool supportsSave() const OVERRIDE;
virtual void setEndTime(float seconds) OVERRIDE;
virtual void setRate(float rate) OVERRIDE;
virtual void setVolume(float volume) OVERRIDE;
virtual void setVisible(bool visible) OVERRIDE;
virtual bool totalBytesKnown() OVERRIDE;
virtual const WebKit::WebTimeRanges& buffered() OVERRIDE;
virtual float maxTimeSeekable() const OVERRIDE;
// Methods for painting.
virtual void setSize(const WebKit::WebSize& size) OVERRIDE;
virtual void paint(WebKit::WebCanvas* canvas,
const WebKit::WebRect& rect,
uint8_t alpha) OVERRIDE;
// True if the loaded media has a playable video/audio track.
virtual bool hasVideo() const OVERRIDE;
virtual bool hasAudio() const OVERRIDE;
// Dimensions of the video.
virtual WebKit::WebSize naturalSize() const OVERRIDE;
// Getters of playback state.
virtual bool paused() const OVERRIDE;
virtual bool seeking() const OVERRIDE;
virtual float duration() const OVERRIDE;
virtual float currentTime() const OVERRIDE;
// Get rate of loading the resource.
virtual int32 dataRate() const OVERRIDE;
virtual unsigned long long bytesLoaded() const OVERRIDE;
virtual unsigned long long totalBytes() const OVERRIDE;
// Internal states of loading and network.
virtual WebKit::WebMediaPlayer::NetworkState networkState() const OVERRIDE;
virtual WebKit::WebMediaPlayer::ReadyState readyState() const OVERRIDE;
virtual bool hasSingleSecurityOrigin() const OVERRIDE;
virtual WebKit::WebMediaPlayer::MovieLoadType movieLoadType() const OVERRIDE;
virtual float mediaTimeForTimeValue(float timeValue) const OVERRIDE;
// Provide statistics.
virtual unsigned decodedFrameCount() const OVERRIDE;
virtual unsigned droppedFrameCount() const OVERRIDE;
virtual unsigned audioDecodedByteCount() const OVERRIDE;
virtual unsigned videoDecodedByteCount() const OVERRIDE;
// Methods called from VideoLayerChromium. These methods are running on the
// compositor thread.
virtual WebKit::WebVideoFrame* getCurrentFrame() OVERRIDE;
virtual void putCurrentFrame(WebKit::WebVideoFrame*) OVERRIDE;
// Media player callback handlers.
void OnMediaPrepared();
void OnPlaybackComplete();
void OnBufferingUpdate(int percentage);
void OnSeekComplete();
void OnMediaError(int error_type);
void OnMediaInfo(int info_type);
void OnVideoSizeChanged(int width, int height);
// Method to set the video surface for android media player.
void SetVideoSurface(jobject j_surface);
private:
// Create a media player to load the |url_| and prepare for playback.
// Because of limited decoding resources on mobile devices, idle media players
// could get released. In that case, we call this function to get a new media
// player when needed.
void InitializeMediaPlayer();
// Functions that implements media player control.
void PlayInternal();
void PauseInternal();
void SeekInternal(float seconds);
// Helper methods for posting task for setting states and update WebKit.
void UpdateNetworkState(WebKit::WebMediaPlayer::NetworkState state);
void UpdateReadyState(WebKit::WebMediaPlayer::ReadyState state);
// whether the current process is incognito mode
static bool incognito_mode_;
WebKit::WebMediaPlayerClient* const client_;
// Save the list of buffered time ranges.
WebKit::WebTimeRanges buffered_;
// Bridge to the android media player.
scoped_ptr<media::MediaPlayerBridge> media_player_;
// Size of the media element.
WebKit::WebSize texture_size_;
// Size of the video.
WebKit::WebSize natural_size_;
// The video frame object used for renderering by WebKit.
scoped_ptr<WebKit::WebVideoFrame> video_frame_;
// Proxy object that delegates method calls on Render Thread.
// This object is created on the Render Thread and is only called in the
// destructor.
scoped_refptr<WebMediaPlayerProxyAndroid> proxy_;
// If this is set to true, prepare of the media player is done.
bool prepared_;
// URL of the media file to be fetched.
GURL url_;
// Media duration.
float duration_;
// When switching tabs, we release the media player. This variable keeps
// track of the current playback time so that a seek will be performed
// next time the media player gets recreated.
float pending_seek_;
// Internal seek state.
bool seeking_;
// Whether playback has completed.
float playback_completed_;
// Fake it by self increasing on every OnBufferingUpdate event.
int64 buffered_bytes_;
// Pointer to the cookie jar to get the cookie for the media url.
WebKit::WebCookieJar* cookie_jar_;
// Whether the user has clicked the play button while media player
// is preparing.
bool pending_play_event_;
// Current player states.
WebKit::WebMediaPlayer::NetworkState network_state_;
WebKit::WebMediaPlayer::ReadyState ready_state_;
DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerAndroid);
};
} // namespace webkit_media
#endif // WEBKIT_MEDIA_ANDROID_WEBMEDIAPLAYER_ANDROID_H_
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "webkit/media/android/webmediaplayer_proxy_android.h"
#include "base/bind.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/message_loop_proxy.h"
#include "webkit/media/android/webmediaplayer_android.h"
namespace webkit_media {
WebMediaPlayerProxyAndroid::WebMediaPlayerProxyAndroid(
const scoped_refptr<base::MessageLoopProxy>& render_loop,
base::WeakPtr<WebMediaPlayerAndroid> webmediaplayer)
: render_loop_(render_loop),
webmediaplayer_(webmediaplayer) {
DCHECK(render_loop_);
DCHECK(webmediaplayer_);
}
WebMediaPlayerProxyAndroid::~WebMediaPlayerProxyAndroid() {
}
void WebMediaPlayerProxyAndroid::MediaErrorCallback(int error_type) {
render_loop_->PostTask(FROM_HERE, base::Bind(
&WebMediaPlayerAndroid::OnMediaError, webmediaplayer_, error_type));
}
void WebMediaPlayerProxyAndroid::MediaInfoCallback(int info_type) {
render_loop_->PostTask(FROM_HERE, base::Bind(
&WebMediaPlayerAndroid::OnMediaInfo, webmediaplayer_, info_type));
}
void WebMediaPlayerProxyAndroid::VideoSizeChangedCallback(
int width, int height) {
render_loop_->PostTask(FROM_HERE, base::Bind(
&WebMediaPlayerAndroid::OnVideoSizeChanged, webmediaplayer_,
width, height));
}
void WebMediaPlayerProxyAndroid::BufferingUpdateCallback(int percent) {
render_loop_->PostTask(FROM_HERE, base::Bind(
&WebMediaPlayerAndroid::OnBufferingUpdate, webmediaplayer_, percent));
}
void WebMediaPlayerProxyAndroid::PlaybackCompleteCallback() {
render_loop_->PostTask(FROM_HERE, base::Bind(
&WebMediaPlayerAndroid::OnPlaybackComplete, webmediaplayer_));
}
void WebMediaPlayerProxyAndroid::SeekCompleteCallback() {
render_loop_->PostTask(FROM_HERE, base::Bind(
&WebMediaPlayerAndroid::OnSeekComplete, webmediaplayer_));
}
void WebMediaPlayerProxyAndroid::MediaPreparedCallback() {
render_loop_->PostTask(FROM_HERE, base::Bind(
&WebMediaPlayerAndroid::OnMediaPrepared, webmediaplayer_));
}
} // namespace webkit_media
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef WEBKIT_MEDIA_ANDROID_WEBMEDIAPLAYER_PROXY_ANDROID_H_
#define WEBKIT_MEDIA_ANDROID_WEBMEDIAPLAYER_PROXY_ANDROID_H_
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
namespace base {
class MessageLoopProxy;
}
namespace webkit_media {
class WebMediaPlayerAndroid;
// Acts as a thread proxy between media::MediaPlayerBridge and
// WebMediaPlayerAndroid so that callbacks are posted onto the render thread.
class WebMediaPlayerProxyAndroid
: public base::RefCountedThreadSafe<WebMediaPlayerProxyAndroid> {
public:
WebMediaPlayerProxyAndroid(
const scoped_refptr<base::MessageLoopProxy>& render_loop,
base::WeakPtr<WebMediaPlayerAndroid> webmediaplayer);
// Callbacks from media::MediaPlayerBridge to WebMediaPlayerAndroid.
void MediaErrorCallback(int error_type);
void MediaInfoCallback(int info_type);
void VideoSizeChangedCallback(int width, int height);
void BufferingUpdateCallback(int percent);
void PlaybackCompleteCallback();
void SeekCompleteCallback();
void MediaPreparedCallback();
private:
friend class base::RefCountedThreadSafe<WebMediaPlayerProxyAndroid>;
virtual ~WebMediaPlayerProxyAndroid();
// Notify |webmediaplayer_| that an error has occured.
void MediaErrorTask(int error_type);
// Notify |webmediaplayer_| that some info has been received from
// media::MediaPlayerBridge.
void MediaInfoTask(int info_type);
// Notify |webmediaplayer_| that the video size has changed.
void VideoSizeChangedTask(int width, int height);
// Notify |webmediaplayer_| that an update in buffering has occured.
void BufferingUpdateTask(int percent);
// Notify |webmediaplayer_| that playback has completed.
void PlaybackCompleteTask();
// Notify |webmediaplayer_| that seek has completed.
void SeekCompleteTask();
// Notify |webmediaplayer_| that media has been prepared successfully.
void MediaPreparedTask();
// The render message loop where WebKit lives.
scoped_refptr<base::MessageLoopProxy> render_loop_;
// The WebMediaPlayerAndroid object all the callbacks should be send to.
base::WeakPtr<WebMediaPlayerAndroid> webmediaplayer_;
DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerProxyAndroid);
};
} // namespace webkit_media
#endif // WEBKIT_MEDIA_ANDROID_WEBMEDIAPLAYER_PROXY_ANDROID_H_
......@@ -15,6 +15,10 @@
],
'sources': [
'android/audio_decoder_android.cc',
'android/webmediaplayer_android.cc',
'android/webmediaplayer_android.h',
'android/webmediaplayer_proxy_android.cc',
'android/webmediaplayer_proxy_android.h',
'active_loader.cc',
'active_loader.h',
'audio_decoder.cc',
......@@ -36,6 +40,8 @@
'webmediaplayer_impl.h',
'webmediaplayer_proxy.cc',
'webmediaplayer_proxy.h',
'webmediaplayer_util.cc',
'webmediaplayer_util.h',
'webvideoframe_impl.cc',
'webvideoframe_impl.h',
],
......@@ -45,12 +51,19 @@
'<(DEPTH)/webkit/support/setup_third_party.gyp:third_party_headers',
],
}],
['OS=="android"', {
['OS == "android"', {
'sources!': [
'audio_decoder.cc',
'webmediaplayer_impl.cc',
'webmediaplayer_impl.h',
],
'dependencies': [
'<(DEPTH)/media/media.gyp:player_android',
],
}, { # OS != "android"'
'sources/': [
['exclude', '^android/'],
],
}],
],
},
......
......@@ -35,6 +35,7 @@
#include "webkit/media/key_systems.h"
#include "webkit/media/webmediaplayer_delegate.h"
#include "webkit/media/webmediaplayer_proxy.h"
#include "webkit/media/webmediaplayer_util.h"
#include "webkit/media/webvideoframe_impl.h"
using WebKit::WebCanvas;
......@@ -76,25 +77,6 @@ const int kPlayerExtraMemory = 1024 * 1024;
const float kMinRate = 0.0625f;
const float kMaxRate = 16.0f;
// Platform independent method for converting and rounding floating point
// seconds to an int64 timestamp.
//
// Refer to https://bugs.webkit.org/show_bug.cgi?id=52697 for details.
base::TimeDelta ConvertSecondsToTimestamp(float seconds) {
float microseconds = seconds * base::Time::kMicrosecondsPerSecond;
float integer = ceilf(microseconds);
float difference = integer - microseconds;
// Round down if difference is large enough.
if ((microseconds > 0 && difference > 0.5f) ||
(microseconds <= 0 && difference >= 0.5f)) {
integer -= 1.0f;
}
// Now we can safely cast to int64 microseconds.
return base::TimeDelta::FromMicroseconds(static_cast<int64>(integer));
}
} // namespace
namespace webkit_media {
......
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "webkit/media/webmediaplayer_util.h"
#include <math.h>
namespace webkit_media {
base::TimeDelta ConvertSecondsToTimestamp(float seconds) {
float microseconds = seconds * base::Time::kMicrosecondsPerSecond;
float integer = ceilf(microseconds);
float difference = integer - microseconds;
// Round down if difference is large enough.
if ((microseconds > 0 && difference > 0.5f) ||
(microseconds <= 0 && difference >= 0.5f)) {
integer -= 1.0f;
}
// Now we can safely cast to int64 microseconds.
return base::TimeDelta::FromMicroseconds(static_cast<int64>(integer));
}
} // namespace webkit_media
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef WEBKIT_MEDIA_WEBMEDIAPLAYER_UTIL_H_
#define WEBKIT_MEDIA_WEBMEDIAPLAYER_UTIL_H_
#include "base/time.h"
namespace webkit_media {
// Platform independent method for converting and rounding floating point
// seconds to an int64 timestamp.
//
// Refer to https://bugs.webkit.org/show_bug.cgi?id=52697 for details.
base::TimeDelta ConvertSecondsToTimestamp(float seconds);
} // namespace webkit_media
#endif // WEBKIT_MEDIA_WEBMEDIAPLAYER_UTIL_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment