Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "webkit/media/android/webmediaplayer_android.h" | |
| 6 | |
| 7 #include <string> | |
| 8 | |
| 9 #include "base/bind.h" | |
| 10 #include "base/command_line.h" | |
| 11 #include "base/file_path.h" | |
| 12 #include "base/logging.h" | |
| 13 #include "base/utf_string_conversions.h" | |
| 14 #include "media/base/android/media_player_bridge.h" | |
| 15 #include "net/base/mime_util.h" | |
| 16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | |
| 17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerClient. h" | |
| 18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" | |
| 19 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCookieJar .h" | |
| 20 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h" | |
| 21 #include "webkit/media/android/webmediaplayer_proxy_android.h" | |
| 22 #include "webkit/media/webvideoframe_impl.h" | |
| 23 | |
| 24 using WebKit::WebCanvas; | |
| 25 using WebKit::WebFrame; | |
| 26 using WebKit::WebMediaPlayerClient; | |
| 27 using WebKit::WebMediaPlayer; | |
| 28 using WebKit::WebRect; | |
| 29 using WebKit::WebSize; | |
| 30 using WebKit::WebTimeRanges; | |
| 31 using WebKit::WebURL; | |
| 32 using WebKit::WebVideoFrame; | |
| 33 using media::MediaPlayerBridge; | |
| 34 using media::VideoFrame; | |
| 35 using webkit_media::WebVideoFrameImpl; | |
| 36 | |
| 37 namespace { | |
| 38 | |
| 39 // Platform independent method for converting and rounding floating point | |
| 40 // seconds to an int64 timestamp. | |
| 41 // | |
| 42 // Refer to https://bugs.webkit.org/show_bug.cgi?id=52697 for details. | |
| 43 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
| |
| 44 float microseconds = seconds * base::Time::kMicrosecondsPerSecond; | |
| 45 float integer = ceilf(microseconds); | |
| 46 float difference = integer - microseconds; | |
| 47 | |
| 48 // Round down if difference is large enough. | |
| 49 if ((microseconds > 0 && difference > 0.5f) || | |
| 50 (microseconds <= 0 && difference >= 0.5f)) { | |
| 51 integer -= 1.0f; | |
| 52 } | |
| 53 | |
| 54 // Now we can safely cast to int64 microseconds. | |
| 55 return base::TimeDelta::FromMicroseconds(static_cast<int64>(integer)); | |
| 56 } | |
| 57 | |
| 58 } // namespace | |
| 59 | |
| 60 namespace webkit_media { | |
| 61 | |
| 62 bool WebMediaPlayerAndroid::incognito_mode_ = false; | |
| 63 | |
| 64 WebMediaPlayerAndroid::WebMediaPlayerAndroid( | |
| 65 WebFrame* frame, | |
| 66 WebMediaPlayerClient* client, | |
| 67 WebKit::WebCookieJar* cookie_jar) | |
| 68 : 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
| |
| 69 client_(client), | |
| 70 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.
| |
| 71 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.
| |
| 72 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.
| |
| 73 proxy_(new WebMediaPlayerProxyAndroid(render_message_loop_)), | |
| 74 prepared_(false), | |
| 75 duration_(0), | |
| 76 time_to_seek_(0), | |
| 77 seeking_(false), | |
| 78 current_time_(0), | |
| 79 buffered_bytes_(0), | |
| 80 cookie_jar_(cookie_jar), | |
| 81 pending_play_event_(false), | |
| 82 skip_loading_(false), | |
| 83 network_state_(WebMediaPlayer::Empty), | |
| 84 ready_state_(WebMediaPlayer::HaveNothing) { | |
| 85 video_frame_.reset(new WebVideoFrameImpl(VideoFrame::CreateEmptyFrame())); | |
| 86 } | |
| 87 | |
| 88 WebMediaPlayerAndroid::~WebMediaPlayerAndroid() { | |
| 89 proxy_->SetWebMediaPlayer(NULL); | |
| 90 | |
| 91 if (media_player_.get()) { | |
| 92 media_player_->Stop(); | |
| 93 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.
| |
| 94 } | |
| 95 | |
| 96 video_frame_.reset(NULL); | |
|
scherkus (not reviewing)
2012/04/17 03:57:31
ditto
qinmin
2012/04/18 20:06:30
Done.
| |
| 97 } | |
| 98 | |
| 99 void WebMediaPlayerAndroid::InitIncognito(bool incognito_mode) { | |
| 100 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
| |
| 101 } | |
| 102 | |
| 103 void WebMediaPlayerAndroid::load(const WebURL& url) { | |
| 104 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.
| |
| 105 GURL gurl(url_); | |
| 106 | |
| 107 // Calling LoadUrl will cause android mediaplayer to start buffering and | |
| 108 // decoding the data. On mobile devices, this costs a lot of data usage | |
| 109 // and could even introduce performance issues. So we don't load the url | |
| 110 // unless it is a local file. We will start loading the media only when | |
| 111 // 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
| |
| 112 if (gurl.SchemeIs("file")) | |
| 113 LoadUrl(url_); | |
| 114 else | |
| 115 skip_loading_ = true; | |
| 116 | |
| 117 UpdateNetworkState(WebMediaPlayer::Loading); | |
| 118 UpdateReadyState(WebMediaPlayer::HaveNothing); | |
| 119 | |
| 120 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
| |
| 121 // 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.
| |
| 122 // Android does not provide any function to do that. | |
| 123 // Set the initial duration value to 100 seconds so that user can touch | |
| 124 // the seek bar to perform seek. We will scale the seek position later | |
| 125 // when we got the actual duration. | |
| 126 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
| |
| 127 | |
| 128 // Pretend everything has been loaded so that webkit can | |
| 129 // still call play() and seek(). | |
| 130 UpdateReadyState(WebMediaPlayer::HaveMetadata); | |
| 131 UpdateReadyState(WebMediaPlayer::HaveEnoughData); | |
| 132 } | |
| 133 } | |
| 134 | |
| 135 void WebMediaPlayerAndroid::cancelLoad() { | |
| 136 NOTIMPLEMENTED(); | |
| 137 } | |
| 138 | |
| 139 void WebMediaPlayerAndroid::play() { | |
| 140 if (media_player_.get()) { | |
| 141 if (!prepared_) | |
| 142 pending_play_event_ = true; | |
| 143 else | |
| 144 PlayInternal(); | |
| 145 } else { | |
| 146 pending_play_event_ = true; | |
| 147 LoadUrl(url_); | |
| 148 } | |
| 149 } | |
| 150 | |
| 151 void WebMediaPlayerAndroid::pause() { | |
| 152 if (media_player_.get()) { | |
| 153 if (!prepared_) | |
| 154 pending_play_event_ = false; | |
| 155 else | |
| 156 PauseInternal(); | |
| 157 } else { | |
| 158 // 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.
| |
| 159 pending_play_event_ = false; | |
| 160 } | |
| 161 } | |
| 162 | |
| 163 void WebMediaPlayerAndroid::seek(float seconds) { | |
| 164 // Record the time to seek when OnMediaPrepared() is called. | |
| 165 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.
| |
| 166 if (media_player_.get()) { | |
| 167 if (prepared_) | |
| 168 SeekInternal(seconds); | |
| 169 } else | |
| 170 LoadUrl(url_); | |
|
scherkus (not reviewing)
2012/04/17 03:57:31
curly braces please
qinmin
2012/04/18 20:06:30
Done.
| |
| 171 } | |
| 172 | |
| 173 bool WebMediaPlayerAndroid::supportsFullscreen() const { | |
| 174 return true; | |
| 175 } | |
| 176 | |
| 177 bool WebMediaPlayerAndroid::supportsSave() const { | |
| 178 return false; | |
| 179 } | |
| 180 | |
| 181 void WebMediaPlayerAndroid::setEndTime(float seconds) { | |
| 182 // 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
| |
| 183 } | |
| 184 | |
| 185 void WebMediaPlayerAndroid::setRate(float rate) { | |
| 186 NOTIMPLEMENTED(); | |
| 187 } | |
| 188 | |
| 189 void WebMediaPlayerAndroid::setVolume(float volume) { | |
| 190 media_player_->SetVolume(volume, volume); | |
| 191 } | |
| 192 | |
| 193 void WebMediaPlayerAndroid::setVisible(bool visible) { | |
| 194 // Deprecated. | |
| 195 } | |
| 196 | |
| 197 bool WebMediaPlayerAndroid::totalBytesKnown() { | |
| 198 NOTIMPLEMENTED(); | |
| 199 return false; | |
| 200 } | |
| 201 | |
| 202 bool WebMediaPlayerAndroid::hasVideo() const { | |
| 203 // FIXME(qinmin): need a better method to determine whether the current media | |
| 204 // content contains video. Android does not provide any function to do | |
| 205 // this. | |
| 206 // We don't know whether the current media content has video unless | |
| 207 // the player is prepared. If the player is not prepared, we fall back | |
| 208 // to the mime-type. There may be no mime-type on a redirect URL. | |
| 209 // In that case, we conservatively assume it contains video so that | |
| 210 // enterfullscreen call will not fail. | |
| 211 if (!prepared_) { | |
| 212 GURL gurl(url_); | |
| 213 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.
| |
| 214 return false; | |
| 215 std::string mime; | |
| 216 if(!net::GetMimeTypeFromFile(FilePath(gurl.path()), &mime)) | |
| 217 return true; | |
| 218 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
| |
| 219 } | |
| 220 | |
| 221 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.
| |
| 222 } | |
| 223 | |
| 224 bool WebMediaPlayerAndroid::hasAudio() const { | |
| 225 // TODO(hclam): Query status of audio and return the actual value. | |
| 226 return true; | |
| 227 } | |
| 228 | |
| 229 bool WebMediaPlayerAndroid::paused() const { | |
| 230 if (!prepared_) | |
| 231 return !pending_play_event_; | |
| 232 return !media_player_->IsPlaying(); | |
| 233 } | |
| 234 | |
| 235 bool WebMediaPlayerAndroid::seeking() const { | |
| 236 return seeking_; | |
| 237 } | |
| 238 | |
| 239 float WebMediaPlayerAndroid::duration() const { | |
| 240 return duration_; | |
| 241 } | |
| 242 | |
| 243 float WebMediaPlayerAndroid::currentTime() const { | |
| 244 // If the player is pending for a seek, return the seek time. | |
| 245 if (!prepared_ || seeking()) | |
| 246 return time_to_seek_; | |
| 247 | |
| 248 // When playback is about to finish, android media player often stops | |
| 249 // at a time which is smaller than the duration. This makes webkit never | |
| 250 // know that the playback has finished. To solve this, we set the | |
| 251 // 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.
| |
| 252 // received. And return the greater of the two values so that the current | |
| 253 // time is most updated. | |
| 254 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
| |
| 255 (float) media_player_->GetCurrentTime().InSecondsF()); | |
|
scherkus (not reviewing)
2012/04/17 03:57:31
static_cast<>
qinmin
2012/04/18 20:06:30
Done.
| |
| 256 } | |
| 257 | |
| 258 int WebMediaPlayerAndroid::dataRate() const { | |
| 259 // Deprecated. | |
| 260 return 0; | |
| 261 } | |
| 262 | |
| 263 WebSize WebMediaPlayerAndroid::naturalSize() const { | |
| 264 return natural_size_; | |
| 265 } | |
| 266 | |
| 267 WebMediaPlayer::NetworkState WebMediaPlayerAndroid::networkState() const { | |
| 268 return network_state_; | |
| 269 } | |
| 270 | |
| 271 WebMediaPlayer::ReadyState WebMediaPlayerAndroid::readyState() const { | |
| 272 return ready_state_; | |
| 273 } | |
| 274 | |
| 275 const WebTimeRanges& WebMediaPlayerAndroid::buffered() { | |
| 276 return time_ranges_; | |
| 277 } | |
| 278 | |
| 279 float WebMediaPlayerAndroid::maxTimeSeekable() const { | |
| 280 // TODO(hclam): If this stream is not seekable this should return 0. | |
| 281 return duration(); | |
| 282 } | |
| 283 | |
| 284 unsigned long long WebMediaPlayerAndroid::bytesLoaded() const { | |
| 285 return buffered_bytes_; | |
| 286 } | |
| 287 | |
| 288 unsigned long long WebMediaPlayerAndroid::totalBytes() const { | |
| 289 // Deprecated. | |
| 290 return 0; | |
| 291 } | |
| 292 | |
| 293 void WebMediaPlayerAndroid::setSize(const WebSize& size) { | |
| 294 texture_size_ = size; | |
| 295 } | |
| 296 | |
| 297 void WebMediaPlayerAndroid::paint(WebCanvas* canvas, const WebRect& rect) { | |
| 298 NOTIMPLEMENTED(); | |
| 299 } | |
| 300 | |
| 301 bool WebMediaPlayerAndroid::hasSingleSecurityOrigin() const { | |
| 302 return false; | |
| 303 } | |
| 304 | |
| 305 WebMediaPlayer::MovieLoadType | |
| 306 WebMediaPlayerAndroid::movieLoadType() const { | |
| 307 // Deprecated. | |
| 308 return WebMediaPlayer::Unknown; | |
| 309 } | |
| 310 | |
| 311 float WebMediaPlayerAndroid::mediaTimeForTimeValue(float timeValue) const { | |
| 312 return ConvertSecondsToTimestamp(timeValue).InSecondsF(); | |
| 313 } | |
| 314 | |
| 315 unsigned WebMediaPlayerAndroid::decodedFrameCount() const { | |
| 316 NOTIMPLEMENTED(); | |
| 317 return 0; | |
| 318 } | |
| 319 | |
| 320 unsigned WebMediaPlayerAndroid::droppedFrameCount() const { | |
| 321 NOTIMPLEMENTED(); | |
| 322 return 0; | |
| 323 } | |
| 324 | |
| 325 unsigned WebMediaPlayerAndroid::audioDecodedByteCount() const { | |
| 326 NOTIMPLEMENTED(); | |
| 327 return 0; | |
| 328 } | |
| 329 | |
| 330 unsigned WebMediaPlayerAndroid::videoDecodedByteCount() const { | |
| 331 NOTIMPLEMENTED(); | |
| 332 return 0; | |
| 333 } | |
| 334 | |
| 335 void WebMediaPlayerAndroid::OnMediaPrepared() { | |
| 336 WebKit::WebTimeRanges new_buffered(static_cast<size_t>(1)); | |
| 337 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.
| |
| 338 new_buffered[0].end = 0.0f; | |
| 339 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
| |
| 340 prepared_ = true; | |
| 341 | |
| 342 // Update the media duration first so that webkit will get the correct | |
| 343 // duration when UpdateReadyState is called. | |
| 344 float dur = duration_; | |
| 345 duration_ = media_player_->GetDuration().InSecondsF(); | |
| 346 | |
| 347 GURL gurl(url_); | |
| 348 if (gurl.SchemeIs("file")) | |
| 349 UpdateNetworkState(WebMediaPlayer::Loaded); | |
| 350 | |
| 351 if (ready_state_ != WebMediaPlayer::HaveEnoughData) { | |
| 352 UpdateReadyState(WebMediaPlayer::HaveMetadata); | |
| 353 UpdateReadyState(WebMediaPlayer::HaveEnoughData); | |
| 354 } else { | |
| 355 // If the status is already set to HaveEnoughData, set it again to make sure | |
| 356 // that Videolayerchromium will get created. | |
| 357 UpdateReadyState(WebMediaPlayer::HaveEnoughData); | |
| 358 } | |
| 359 | |
| 360 if (skip_loading_) { | |
| 361 // In we have skipped loading, the duration was preset to 100 sec. | |
| 362 // 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
| |
| 363 if (duration_ != dur) { | |
| 364 // Scale the time_to_seek_ according to the new duration. | |
| 365 time_to_seek_ = time_to_seek_ * duration_ / 100.0f; | |
| 366 client_->durationChanged(); | |
| 367 } | |
| 368 } | |
| 369 | |
| 370 // If media player was recovered from a saved state, consume all the pending | |
| 371 // events. | |
| 372 seek(time_to_seek_); | |
| 373 | |
| 374 if (pending_play_event_) | |
| 375 PlayInternal(); | |
| 376 | |
| 377 pending_play_event_ = false; | |
| 378 } | |
| 379 | |
| 380 void WebMediaPlayerAndroid::OnPlaybackComplete() { | |
| 381 // Set the current time equal to duration to let webkit know that play back | |
| 382 // is completed. | |
| 383 current_time_ = duration(); | |
| 384 client_->timeChanged(); | |
| 385 } | |
| 386 | |
| 387 void WebMediaPlayerAndroid::OnBufferingUpdate(int percentage) { | |
| 388 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
| |
| 389 time_ranges_[0].end = duration() * percentage / 100; | |
| 390 // Implement a trick here to fake progress event, as WebKit checks | |
| 391 // consecutive bytesLoaded() to see if any progress made. | |
| 392 // See HTMLMediaElement::progressEventTimerFired. | |
| 393 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
| |
| 394 } | |
| 395 } | |
| 396 | |
| 397 void WebMediaPlayerAndroid::OnSeekComplete() { | |
| 398 seeking_ = false; | |
| 399 | |
| 400 UpdateReadyState(WebMediaPlayer::HaveEnoughData); | |
| 401 | |
| 402 client_->timeChanged(); | |
| 403 } | |
| 404 | |
| 405 void WebMediaPlayerAndroid::OnMediaError(int error_type) { | |
| 406 switch (error_type) { | |
| 407 case MediaPlayerBridge::MEDIA_ERROR_UNKNOWN: | |
| 408 // 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.
| |
| 409 // As WebKit uses FormatError to indicate an error for bogus URL or bad | |
| 410 // 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.
| |
| 411 UpdateNetworkState(WebMediaPlayer::FormatError); | |
| 412 break; | |
| 413 case MediaPlayerBridge::MEDIA_ERROR_SERVER_DIED: | |
| 414 // TODO(zhenghao): Media server died. In this case, the application must | |
| 415 // release the MediaPlayer object and instantiate a new one. | |
| 416 UpdateNetworkState(WebMediaPlayer::DecodeError); | |
| 417 break; | |
| 418 case MediaPlayerBridge::MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK: | |
| 419 UpdateNetworkState(WebMediaPlayer::FormatError); | |
| 420 break; | |
| 421 case MediaPlayerBridge::MEDIA_ERROR_INVALID_CODE: | |
| 422 break; | |
| 423 } | |
| 424 client_->repaint(); | |
| 425 } | |
| 426 | |
| 427 void WebMediaPlayerAndroid::OnMediaInfo(int info_type) { | |
| 428 NOTIMPLEMENTED(); | |
| 429 } | |
| 430 | |
| 431 void WebMediaPlayerAndroid::OnVideoSizeChanged(int width, int height) { | |
| 432 natural_size_.width = width; | |
| 433 natural_size_.height = height; | |
| 434 } | |
| 435 | |
| 436 void WebMediaPlayerAndroid::UpdateNetworkState( | |
| 437 WebMediaPlayer::NetworkState state) { | |
| 438 network_state_ = state; | |
| 439 client_->networkStateChanged(); | |
| 440 } | |
| 441 | |
| 442 void WebMediaPlayerAndroid::UpdateReadyState( | |
| 443 WebMediaPlayer::ReadyState state) { | |
| 444 ready_state_ = state; | |
| 445 client_->readyStateChanged(); | |
| 446 } | |
| 447 | |
| 448 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.
| |
| 449 jobject j_surface) { | |
| 450 if (media_player_.get()) | |
| 451 media_player_->SetVideoSurface(j_surface); | |
| 452 } | |
| 453 | |
| 454 void WebMediaPlayerAndroid::InitializeMediaPlayer() { | |
| 455 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
| |
| 456 prepared_ = false; | |
| 457 media_player_.reset(new MediaPlayerBridge()); | |
| 458 media_player_->SetStayAwakeWhilePlaying(); | |
| 459 proxy_->SetWebMediaPlayer(this); | |
| 460 } | |
| 461 } | |
| 462 | |
| 463 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
| |
| 464 if (!media_player_.get()) | |
| 465 InitializeMediaPlayer(); | |
| 466 | |
| 467 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.
| |
| 468 | |
| 469 std::string cookies; | |
| 470 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
| |
| 471 cookies = UTF16ToUTF8(cookie_jar_->cookies(url, url)); | |
| 472 media_player_->SetDataSource(url.spec(), cookies, incognito_mode_); | |
| 473 | |
| 474 media_player_->Prepare( | |
| 475 base::Bind(&WebMediaPlayerProxyAndroid::MediaInfoCallback, proxy_), | |
| 476 base::Bind(&WebMediaPlayerProxyAndroid::MediaErrorCallback, proxy_), | |
| 477 base::Bind(&WebMediaPlayerProxyAndroid::VideoSizeChangedCallback, proxy_), | |
| 478 base::Bind(&WebMediaPlayerProxyAndroid::BufferingUpdateCallback, proxy_), | |
| 479 base::Bind(&WebMediaPlayerProxyAndroid::MediaPreparedCallback, proxy_)); | |
| 480 | |
|
scherkus (not reviewing)
2012/04/17 03:57:31
nit: remove blank line
qinmin
2012/04/18 20:06:30
Done.
| |
| 481 } | |
| 482 | |
| 483 void WebMediaPlayerAndroid::PlayInternal() { | |
| 484 CHECK(prepared_); | |
| 485 | |
| 486 if (paused()) | |
| 487 media_player_->Start(base::Bind( | |
| 488 &WebMediaPlayerProxyAndroid::PlaybackCompleteCallback, proxy_)); | |
| 489 } | |
| 490 | |
| 491 void WebMediaPlayerAndroid::PauseInternal() { | |
| 492 CHECK(prepared_); | |
| 493 media_player_->Pause(); | |
| 494 } | |
| 495 | |
| 496 void WebMediaPlayerAndroid::SeekInternal(float seconds) { | |
| 497 CHECK(prepared_); | |
| 498 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
| |
| 499 client_->timeChanged(); | |
| 500 return; | |
| 501 } | |
| 502 seeking_ = true; | |
| 503 media_player_->SeekTo(ConvertSecondsToTimestamp(seconds), base::Bind( | |
| 504 &WebMediaPlayerProxyAndroid::SeekCompleteCallback, proxy_)); | |
| 505 } | |
| 506 | |
| 507 // ------------------------------------------------------------------------- | |
| 508 // Methods that are called on the compositor thread if useThreadedCompositor | |
| 509 // 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.
| |
| 510 WebVideoFrame* WebMediaPlayerAndroid::getCurrentFrame() { | |
| 511 return video_frame_.get(); | |
| 512 } | |
| 513 | |
| 514 void WebMediaPlayerAndroid::putCurrentFrame( | |
| 515 WebVideoFrame* web_video_frame) { | |
| 516 } | |
| 517 | |
| 518 // ------------------------------------------------------------------------- | |
| 519 | |
| 520 } // namespace webkit_media | |
| OLD | NEW |