Chromium Code Reviews| Index: webkit/media/android/webmediaplayer_android.cc |
| diff --git a/webkit/media/android/webmediaplayer_android.cc b/webkit/media/android/webmediaplayer_android.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..30a1b2c8ea2ea71094a479d05332531a8b6b8809 |
| --- /dev/null |
| +++ b/webkit/media/android/webmediaplayer_android.cc |
| @@ -0,0 +1,520 @@ |
| +// 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_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/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/webmediaplayer_proxy_android.h" |
| +#include "webkit/media/webvideoframe_impl.h" |
| + |
| +using WebKit::WebCanvas; |
| +using WebKit::WebFrame; |
| +using WebKit::WebMediaPlayerClient; |
| +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; |
| + |
| +namespace { |
| + |
| +// 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) { |
|
scherkus (not reviewing)
2012/04/17 03:57:31
this code is duplicated
qinmin
2012/04/18 20:06:30
move the function to webmediaplayer_util.h, and al
|
| + 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 { |
| + |
| +bool WebMediaPlayerAndroid::incognito_mode_ = false; |
| + |
| +WebMediaPlayerAndroid::WebMediaPlayerAndroid( |
| + WebFrame* frame, |
| + WebMediaPlayerClient* client, |
| + WebKit::WebCookieJar* cookie_jar) |
| + : frame_(frame), |
|
scherkus (not reviewing)
2012/04/17 03:57:31
WMPA doesn't use this
qinmin
2012/04/18 20:06:30
This will be used by the fullscreen view code to g
|
| + client_(client), |
| + render_message_loop_(base::MessageLoopProxy::current()), |
|
scherkus (not reviewing)
2012/04/17 03:57:31
WMPA doesn't use this
qinmin
2012/04/18 20:06:30
Done.
|
| + media_player_(NULL), |
|
scherkus (not reviewing)
2012/04/17 03:57:31
for scoped_ptr/scoped_refptr we typically leave th
qinmin
2012/04/18 20:06:30
Done.
|
| + natural_size_(WebSize(0,0)), |
|
scherkus (not reviewing)
2012/04/17 03:57:31
this is handles by default ctor -- no need to have
qinmin
2012/04/18 20:06:30
Done.
|
| + proxy_(new WebMediaPlayerProxyAndroid(render_message_loop_)), |
| + prepared_(false), |
| + duration_(0), |
| + time_to_seek_(0), |
| + seeking_(false), |
| + current_time_(0), |
| + buffered_bytes_(0), |
| + cookie_jar_(cookie_jar), |
| + pending_play_event_(false), |
| + skip_loading_(false), |
| + network_state_(WebMediaPlayer::Empty), |
| + ready_state_(WebMediaPlayer::HaveNothing) { |
| + video_frame_.reset(new WebVideoFrameImpl(VideoFrame::CreateEmptyFrame())); |
| +} |
| + |
| +WebMediaPlayerAndroid::~WebMediaPlayerAndroid() { |
| + proxy_->SetWebMediaPlayer(NULL); |
| + |
| + if (media_player_.get()) { |
| + media_player_->Stop(); |
| + media_player_.reset(NULL); |
|
scherkus (not reviewing)
2012/04/17 03:57:31
do you need this line? the dtor should call this a
qinmin
2012/04/18 20:06:30
Done.
|
| + } |
| + |
| + video_frame_.reset(NULL); |
|
scherkus (not reviewing)
2012/04/17 03:57:31
ditto
qinmin
2012/04/18 20:06:30
Done.
|
| +} |
| + |
| +void WebMediaPlayerAndroid::InitIncognito(bool incognito_mode) { |
| + incognito_mode_ = incognito_mode; |
|
scherkus (not reviewing)
2012/04/17 03:57:31
when is this called? is it guaranteed this will ge
qinmin
2012/04/18 20:06:30
This will be called by chrome/browser/chrome_conte
scherkus (not reviewing)
2012/04/21 03:02:05
What you describe are all implementation details o
|
| +} |
| + |
| +void WebMediaPlayerAndroid::load(const WebURL& url) { |
| + url_ = url; |
|
scherkus (not reviewing)
2012/04/17 03:57:31
most of your url_ usage involves immediately conve
qinmin
2012/04/18 20:06:30
Done.
|
| + GURL gurl(url_); |
| + |
| + // Calling LoadUrl 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 load the url |
| + // unless it is a local file. We will start loading the media only when |
| + // play/seek/fullsceen button is clicked. |
|
scherkus (not reviewing)
2012/04/17 03:57:31
as a web page author can't I work around this by h
qinmin
2012/04/18 20:06:30
No, calling play() will not work as there are gest
scherkus (not reviewing)
2012/04/21 03:02:05
Thanks for the explanation!
On 2012/04/18 20:06:3
|
| + if (gurl.SchemeIs("file")) |
| + LoadUrl(url_); |
| + else |
| + skip_loading_ = true; |
| + |
| + UpdateNetworkState(WebMediaPlayer::Loading); |
| + UpdateReadyState(WebMediaPlayer::HaveNothing); |
| + |
| + if (skip_loading_) { |
|
scherkus (not reviewing)
2012/04/17 03:57:31
you can replace skip_loading_ with a check for med
qinmin
2012/04/18 20:06:30
rewrite the handle to file:// case
On 2012/04/17 0
|
| + // FIXME(qinmin): we need a method to calculate the duration of the media. |
|
scherkus (not reviewing)
2012/04/17 03:57:31
s/FIXME/TODO
qinmin
2012/04/18 20:06:30
Done.
|
| + // Android does not provide any function to do that. |
| + // Set the initial duration value to 100 seconds 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_ = 100; |
|
scherkus (not reviewing)
2012/04/17 03:57:31
you shouldn't need a duration_ parameter at all
i
qinmin
2012/04/18 20:06:30
We need the duration_ for many reasons:
1. MediaPl
|
| + |
| + // Pretend everything has been loaded so that webkit can |
| + // still call play() and seek(). |
| + UpdateReadyState(WebMediaPlayer::HaveMetadata); |
| + UpdateReadyState(WebMediaPlayer::HaveEnoughData); |
| + } |
| +} |
| + |
| +void WebMediaPlayerAndroid::cancelLoad() { |
| + NOTIMPLEMENTED(); |
| +} |
| + |
| +void WebMediaPlayerAndroid::play() { |
| + if (media_player_.get()) { |
| + if (!prepared_) |
| + pending_play_event_ = true; |
| + else |
| + PlayInternal(); |
| + } else { |
| + pending_play_event_ = true; |
| + LoadUrl(url_); |
| + } |
| +} |
| + |
| +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(). |
|
scherkus (not reviewing)
2012/04/17 03:57:31
pause() instead of called()?
qinmin
2012/04/18 20:06:30
Done.
|
| + pending_play_event_ = false; |
| + } |
| +} |
| + |
| +void WebMediaPlayerAndroid::seek(float seconds) { |
| + // Record the time to seek when OnMediaPrepared() is called. |
| + time_to_seek_ = seconds; |
|
scherkus (not reviewing)
2012/04/17 03:57:31
perhaps a better variable name is "pending_seek_"
qinmin
2012/04/18 20:06:30
Done.
|
| + if (media_player_.get()) { |
| + if (prepared_) |
| + SeekInternal(seconds); |
| + } else |
| + LoadUrl(url_); |
|
scherkus (not reviewing)
2012/04/17 03:57:31
curly braces please
qinmin
2012/04/18 20:06:30
Done.
|
| +} |
| + |
| +bool WebMediaPlayerAndroid::supportsFullscreen() const { |
| + return true; |
| +} |
| + |
| +bool WebMediaPlayerAndroid::supportsSave() const { |
| + return false; |
| +} |
| + |
| +void WebMediaPlayerAndroid::setEndTime(float seconds) { |
| + // Deprecated. |
|
scherkus (not reviewing)
2012/04/17 03:57:31
for these and others: if they're deprecated are th
qinmin
2012/04/18 20:06:30
No, there are no bugs filed. Added a todo for this
|
| +} |
| + |
| +void WebMediaPlayerAndroid::setRate(float rate) { |
| + NOTIMPLEMENTED(); |
| +} |
| + |
| +void WebMediaPlayerAndroid::setVolume(float volume) { |
| + media_player_->SetVolume(volume, volume); |
| +} |
| + |
| +void WebMediaPlayerAndroid::setVisible(bool visible) { |
| + // Deprecated. |
| +} |
| + |
| +bool WebMediaPlayerAndroid::totalBytesKnown() { |
| + NOTIMPLEMENTED(); |
| + return false; |
| +} |
| + |
| +bool WebMediaPlayerAndroid::hasVideo() const { |
| + // FIXME(qinmin): need a better method to determine whether the current media |
| + // content contains video. Android does not provide any function to do |
| + // this. |
| + // We don't know whether the current media content has video unless |
| + // the player is prepared. If the player is not prepared, we fall back |
| + // 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_) { |
| + GURL gurl(url_); |
| + if(!gurl.has_path()) |
|
scherkus (not reviewing)
2012/04/17 03:57:31
space between if and (
qinmin
2012/04/18 20:06:30
Done.
|
| + return false; |
| + std::string mime; |
| + if(!net::GetMimeTypeFromFile(FilePath(gurl.path()), &mime)) |
| + return true; |
| + return mime.find("audio") == std::string::npos; |
|
scherkus (not reviewing)
2012/04/17 03:57:31
should this be "audio/"?
qinmin
2012/04/18 20:06:30
Done, but should have the same effect for all curr
|
| + } |
| + |
| + return natural_size_.width != 0 && natural_size_.height != 0; |
|
scherkus (not reviewing)
2012/04/17 03:57:31
how about !natural_size_.isEmpty() instead?
qinmin
2012/04/18 20:06:30
Done.
|
| +} |
| + |
| +bool WebMediaPlayerAndroid::hasAudio() const { |
| + // TODO(hclam): Query status of audio and return the actual value. |
| + return true; |
| +} |
| + |
| +bool WebMediaPlayerAndroid::paused() const { |
| + if (!prepared_) |
| + return !pending_play_event_; |
| + return !media_player_->IsPlaying(); |
| +} |
| + |
| +bool WebMediaPlayerAndroid::seeking() const { |
| + return seeking_; |
| +} |
| + |
| +float WebMediaPlayerAndroid::duration() const { |
| + return duration_; |
| +} |
| + |
| +float WebMediaPlayerAndroid::currentTime() const { |
| + // If the player is pending for a seek, return the seek time. |
| + if (!prepared_ || seeking()) |
| + return time_to_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 PLAYBACK_COMPLETE message is |
|
scherkus (not reviewing)
2012/04/17 03:57:31
by "PLAYBACK_COMPLETE message" do you mean OnPlayb
qinmin
2012/04/18 20:06:30
Done.
|
| + // received. And return the greater of the two values so that the current |
| + // time is most updated. |
| + return std::max(current_time_, |
|
scherkus (not reviewing)
2012/04/17 03:57:31
current_time_ is completely misleading as it's eit
qinmin
2012/04/18 20:06:30
current_time was used to send the current time inf
|
| + (float) media_player_->GetCurrentTime().InSecondsF()); |
|
scherkus (not reviewing)
2012/04/17 03:57:31
static_cast<>
qinmin
2012/04/18 20:06:30
Done.
|
| +} |
| + |
| +int WebMediaPlayerAndroid::dataRate() const { |
| + // Deprecated. |
| + return 0; |
| +} |
| + |
| +WebSize WebMediaPlayerAndroid::naturalSize() const { |
| + return natural_size_; |
| +} |
| + |
| +WebMediaPlayer::NetworkState WebMediaPlayerAndroid::networkState() const { |
| + return network_state_; |
| +} |
| + |
| +WebMediaPlayer::ReadyState WebMediaPlayerAndroid::readyState() const { |
| + return ready_state_; |
| +} |
| + |
| +const WebTimeRanges& WebMediaPlayerAndroid::buffered() { |
| + return time_ranges_; |
| +} |
| + |
| +float WebMediaPlayerAndroid::maxTimeSeekable() const { |
| + // TODO(hclam): If this stream is not seekable this should return 0. |
| + return duration(); |
| +} |
| + |
| +unsigned long long WebMediaPlayerAndroid::bytesLoaded() const { |
| + return buffered_bytes_; |
| +} |
| + |
| +unsigned long long WebMediaPlayerAndroid::totalBytes() const { |
| + // Deprecated. |
| + return 0; |
| +} |
| + |
| +void WebMediaPlayerAndroid::setSize(const WebSize& size) { |
| + texture_size_ = size; |
| +} |
| + |
| +void WebMediaPlayerAndroid::paint(WebCanvas* canvas, const WebRect& rect) { |
| + NOTIMPLEMENTED(); |
| +} |
| + |
| +bool WebMediaPlayerAndroid::hasSingleSecurityOrigin() const { |
| + return false; |
| +} |
| + |
| +WebMediaPlayer::MovieLoadType |
| + WebMediaPlayerAndroid::movieLoadType() const { |
| + // Deprecated. |
| + return WebMediaPlayer::Unknown; |
| +} |
| + |
| +float WebMediaPlayerAndroid::mediaTimeForTimeValue(float timeValue) const { |
| + return ConvertSecondsToTimestamp(timeValue).InSecondsF(); |
| +} |
| + |
| +unsigned WebMediaPlayerAndroid::decodedFrameCount() const { |
| + NOTIMPLEMENTED(); |
| + return 0; |
| +} |
| + |
| +unsigned WebMediaPlayerAndroid::droppedFrameCount() const { |
| + NOTIMPLEMENTED(); |
| + return 0; |
| +} |
| + |
| +unsigned WebMediaPlayerAndroid::audioDecodedByteCount() const { |
| + NOTIMPLEMENTED(); |
| + return 0; |
| +} |
| + |
| +unsigned WebMediaPlayerAndroid::videoDecodedByteCount() const { |
| + NOTIMPLEMENTED(); |
| + return 0; |
| +} |
| + |
| +void WebMediaPlayerAndroid::OnMediaPrepared() { |
| + WebKit::WebTimeRanges new_buffered(static_cast<size_t>(1)); |
| + new_buffered[0].start = 0.0f; |
|
scherkus (not reviewing)
2012/04/17 03:57:31
WebTimeRanges's default ctor initializes to 0
qinmin
2012/04/18 20:06:30
Done.
|
| + new_buffered[0].end = 0.0f; |
| + time_ranges_.swap(new_buffered); |
|
scherkus (not reviewing)
2012/04/17 03:57:31
why the swap? how often is OnMediaPrepared() calle
qinmin
2012/04/18 20:06:30
This could be called many times as MediaPlayer cou
|
| + 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(); |
| + |
| + GURL gurl(url_); |
| + if (gurl.SchemeIs("file")) |
| + UpdateNetworkState(WebMediaPlayer::Loaded); |
| + |
| + if (ready_state_ != WebMediaPlayer::HaveEnoughData) { |
| + UpdateReadyState(WebMediaPlayer::HaveMetadata); |
| + UpdateReadyState(WebMediaPlayer::HaveEnoughData); |
| + } else { |
| + // If the status is already set to HaveEnoughData, set it again to make sure |
| + // that Videolayerchromium will get created. |
| + UpdateReadyState(WebMediaPlayer::HaveEnoughData); |
| + } |
| + |
| + if (skip_loading_) { |
| + // In we have skipped loading, the duration was preset to 100 sec. |
| + // We have to update webkit about the new duration. |
|
scherkus (not reviewing)
2012/04/17 03:57:31
even in the file:// case isn't the duration also u
qinmin
2012/04/18 20:06:30
So here is what happens:
WebKit will call duration
|
| + if (duration_ != dur) { |
| + // Scale the time_to_seek_ according to the new duration. |
| + time_to_seek_ = time_to_seek_ * duration_ / 100.0f; |
| + client_->durationChanged(); |
| + } |
| + } |
| + |
| + // If media player was recovered from a saved state, consume all the pending |
| + // events. |
| + seek(time_to_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. |
| + current_time_ = duration(); |
| + client_->timeChanged(); |
| +} |
| + |
| +void WebMediaPlayerAndroid::OnBufferingUpdate(int percentage) { |
| + if (time_ranges_.size() > 0) { |
|
scherkus (not reviewing)
2012/04/17 03:57:31
would OnBufferingUpdate() ever get called before O
qinmin
2012/04/18 20:06:30
Yes, that could happen as mediaplayer could get de
scherkus (not reviewing)
2012/04/21 03:02:05
But time_ranges_ is never reset back to size 0 and
|
| + time_ranges_[0].end = duration() * percentage / 100; |
| + // Implement a trick here to fake progress event, as WebKit checks |
| + // consecutive bytesLoaded() to see if any progress made. |
| + // See HTMLMediaElement::progressEventTimerFired. |
| + buffered_bytes_++; |
|
scherkus (not reviewing)
2012/04/17 03:57:31
FYI this is a pretty horrible trick!
can you at l
qinmin
2012/04/18 20:06:30
TODO added, android mediaplayer does not provide u
scherkus (not reviewing)
2012/04/21 03:02:05
You should send a patch to WebKit :)
In fact in r
|
| + } |
| +} |
| + |
| +void WebMediaPlayerAndroid::OnSeekComplete() { |
| + seeking_ = false; |
| + |
| + UpdateReadyState(WebMediaPlayer::HaveEnoughData); |
| + |
| + client_->timeChanged(); |
| +} |
| + |
| +void WebMediaPlayerAndroid::OnMediaError(int error_type) { |
| + switch (error_type) { |
| + case MediaPlayerBridge::MEDIA_ERROR_UNKNOWN: |
| + // When playing an bogus URL or bad file, we fire an MEDIA_ERROR_UNKNOWN. |
|
scherkus (not reviewing)
2012/04/17 03:57:31
s/an/a
s/,//
qinmin
2012/04/18 20:06:30
Done.
|
| + // As WebKit uses FormatError to indicate an error for bogus URL or bad |
| + // file, we default an MEDIA_ERROR_UNKNOWN to FormatError. |
|
scherkus (not reviewing)
2012/04/17 03:57:31
s/an/a
s/,//
qinmin
2012/04/18 20:06:30
Done.
|
| + UpdateNetworkState(WebMediaPlayer::FormatError); |
| + break; |
| + case MediaPlayerBridge::MEDIA_ERROR_SERVER_DIED: |
| + // TODO(zhenghao): Media server died. In this case, the application must |
| + // release the MediaPlayer object and instantiate a new one. |
| + UpdateNetworkState(WebMediaPlayer::DecodeError); |
| + break; |
| + case MediaPlayerBridge::MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK: |
| + UpdateNetworkState(WebMediaPlayer::FormatError); |
| + break; |
| + case MediaPlayerBridge::MEDIA_ERROR_INVALID_CODE: |
| + break; |
| + } |
| + client_->repaint(); |
| +} |
| + |
| +void WebMediaPlayerAndroid::OnMediaInfo(int info_type) { |
| + NOTIMPLEMENTED(); |
| +} |
| + |
| +void WebMediaPlayerAndroid::OnVideoSizeChanged(int width, int height) { |
| + natural_size_.width = width; |
| + natural_size_.height = height; |
| +} |
| + |
| +void WebMediaPlayerAndroid::UpdateNetworkState( |
| + WebMediaPlayer::NetworkState state) { |
| + network_state_ = state; |
| + client_->networkStateChanged(); |
| +} |
| + |
| +void WebMediaPlayerAndroid::UpdateReadyState( |
| + WebMediaPlayer::ReadyState state) { |
| + ready_state_ = state; |
| + client_->readyStateChanged(); |
| +} |
| + |
| +void WebMediaPlayerAndroid::SetVideoSurface( |
|
scherkus (not reviewing)
2012/04/17 03:57:31
nit: this can fit on single line
qinmin
2012/04/18 20:06:30
Done.
|
| + jobject j_surface) { |
| + if (media_player_.get()) |
| + media_player_->SetVideoSurface(j_surface); |
| +} |
| + |
| +void WebMediaPlayerAndroid::InitializeMediaPlayer() { |
| + if (!media_player_.get()) { |
|
scherkus (not reviewing)
2012/04/17 03:57:31
this check isn't needed -- you only call this meth
qinmin
2012/04/18 20:06:30
Changed it to a CHECK instead.
On 2012/04/17 03:5
|
| + prepared_ = false; |
| + media_player_.reset(new MediaPlayerBridge()); |
| + media_player_->SetStayAwakeWhilePlaying(); |
| + proxy_->SetWebMediaPlayer(this); |
| + } |
| +} |
| + |
| +void WebMediaPlayerAndroid::LoadUrl(WebURL url) { |
|
scherkus (not reviewing)
2012/04/17 03:57:31
AFAIK this only gets called once during the lifeti
qinmin
2012/04/18 20:06:30
This could get called many times since we will rel
|
| + if (!media_player_.get()) |
| + InitializeMediaPlayer(); |
| + |
| + media_player_->Reset(); |
|
scherkus (not reviewing)
2012/04/17 03:57:31
not needed since LoadUrl() should only get called
qinmin
2012/04/18 20:06:30
Done.
|
| + |
| + std::string cookies; |
| + if (cookie_jar_ != NULL) |
|
scherkus (not reviewing)
2012/04/17 03:57:31
is it valid to pass in a NULL cookie_jar to this c
qinmin
2012/04/18 20:06:30
Yes, for DRT case.
On 2012/04/17 03:57:31, scherk
scherkus (not reviewing)
2012/04/21 03:02:05
There's no DRT-specific cookie jar implementation
|
| + cookies = UTF16ToUTF8(cookie_jar_->cookies(url, url)); |
| + media_player_->SetDataSource(url.spec(), cookies, incognito_mode_); |
| + |
| + 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_)); |
| + |
|
scherkus (not reviewing)
2012/04/17 03:57:31
nit: remove blank line
qinmin
2012/04/18 20:06:30
Done.
|
| +} |
| + |
| +void WebMediaPlayerAndroid::PlayInternal() { |
| + CHECK(prepared_); |
| + |
| + if (paused()) |
| + media_player_->Start(base::Bind( |
| + &WebMediaPlayerProxyAndroid::PlaybackCompleteCallback, proxy_)); |
| +} |
| + |
| +void WebMediaPlayerAndroid::PauseInternal() { |
| + CHECK(prepared_); |
| + media_player_->Pause(); |
| +} |
| + |
| +void WebMediaPlayerAndroid::SeekInternal(float seconds) { |
| + CHECK(prepared_); |
| + if (seconds == 0.0f && currentTime() == 0.0f) { |
|
scherkus (not reviewing)
2012/04/17 03:57:31
what's this for?
qinmin
2012/04/18 20:06:30
This is just to save some unnecessary calls to the
|
| + client_->timeChanged(); |
| + return; |
| + } |
| + seeking_ = true; |
| + media_player_->SeekTo(ConvertSecondsToTimestamp(seconds), base::Bind( |
| + &WebMediaPlayerProxyAndroid::SeekCompleteCallback, proxy_)); |
| +} |
| + |
| +// ------------------------------------------------------------------------- |
| +// Methods that are called on the compositor thread if useThreadedCompositor |
| +// flag is set. |
|
scherkus (not reviewing)
2012/04/17 03:57:31
you've already covered this in the .h -- I'd remov
qinmin
2012/04/18 20:06:30
Done.
|
| +WebVideoFrame* WebMediaPlayerAndroid::getCurrentFrame() { |
| + return video_frame_.get(); |
| +} |
| + |
| +void WebMediaPlayerAndroid::putCurrentFrame( |
| + WebVideoFrame* web_video_frame) { |
| +} |
| + |
| +// ------------------------------------------------------------------------- |
| + |
| +} // namespace webkit_media |