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 |