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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "webkit/media/android/webmediaplayer_android.h" 5 #include "webkit/media/android/webmediaplayer_android.h"
6 6
7 #include <string>
8
9 #include "base/bind.h"
10 #include "base/command_line.h"
11 #include "base/file_path.h" 7 #include "base/file_path.h"
12 #include "base/logging.h" 8 #include "base/logging.h"
13 #include "base/utf_string_conversions.h"
14 #include "media/base/android/media_player_bridge.h" 9 #include "media/base/android/media_player_bridge.h"
15 #include "net/base/mime_util.h" 10 #include "net/base/mime_util.h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerClient. h" 11 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerClient. h"
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
20 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCookieJar .h"
21 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h"
22 #include "webkit/media/android/stream_texture_factory_android.h" 12 #include "webkit/media/android/stream_texture_factory_android.h"
23 #include "webkit/media/android/webmediaplayer_manager_android.h" 13 #include "webkit/media/android/webmediaplayer_manager_android.h"
24 #include "webkit/media/android/webmediaplayer_proxy_android.h"
25 #include "webkit/media/webmediaplayer_util.h" 14 #include "webkit/media/webmediaplayer_util.h"
26 #include "webkit/media/webvideoframe_impl.h" 15 #include "webkit/media/webvideoframe_impl.h"
27 16
28 using WebKit::WebCanvas; 17 static const uint32 kGLTextureExternalOES = 0x8D65;
29 using WebKit::WebMediaPlayerClient; 18
30 using WebKit::WebMediaPlayer; 19 using WebKit::WebMediaPlayer;
31 using WebKit::WebRect;
32 using WebKit::WebSize; 20 using WebKit::WebSize;
33 using WebKit::WebTimeRanges; 21 using WebKit::WebTimeRanges;
34 using WebKit::WebURL; 22 using WebKit::WebURL;
35 using WebKit::WebVideoFrame; 23 using WebKit::WebVideoFrame;
36 using media::MediaPlayerBridge; 24 using media::MediaPlayerBridge;
37 using media::VideoFrame; 25 using media::VideoFrame;
38 using webkit_media::WebVideoFrameImpl;
39
40 // TODO(qinmin): Figure out where we should define this more appropriately
41 static const uint32 kGLTextureExternalOES = 0x8D65;
42 26
43 namespace webkit_media { 27 namespace webkit_media {
44 28
45 // Because we create the media player lazily on android, the duration of the
46 // media is initially unknown to us. This makes the user unable to perform
47 // seek. To solve this problem, we use a temporary duration of 100 seconds when
48 // the duration is unknown. And we scale the seek position later when duration
49 // is available.
50 // TODO(qinmin): create a thread and use android MediaMetadataRetriever
51 // class to extract the duration.
52 static const float kTemporaryDuration = 100.0f;
53
54 bool WebMediaPlayerAndroid::incognito_mode_ = false;
55
56 WebMediaPlayerAndroid::WebMediaPlayerAndroid( 29 WebMediaPlayerAndroid::WebMediaPlayerAndroid(
57 WebKit::WebFrame* frame, 30 WebKit::WebMediaPlayerClient* client,
58 WebMediaPlayerClient* client, 31 WebMediaPlayerManagerAndroid* manager,
59 WebKit::WebCookieJar* cookie_jar, 32 StreamTextureFactory* factory)
60 webkit_media::WebMediaPlayerManagerAndroid* manager, 33 : client_(client),
61 webkit_media::StreamTextureFactory* factory)
62 : frame_(frame),
63 client_(client),
64 buffered_(1u), 34 buffered_(1u),
65 video_frame_(new WebVideoFrameImpl(VideoFrame::CreateEmptyFrame())), 35 video_frame_(new WebVideoFrameImpl(VideoFrame::CreateEmptyFrame())),
66 main_loop_(MessageLoop::current()), 36 main_loop_(MessageLoop::current()),
67 proxy_(new WebMediaPlayerProxyAndroid(main_loop_->message_loop_proxy(),
68 AsWeakPtr())),
69 prepared_(false),
70 duration_(0),
71 pending_seek_(0), 37 pending_seek_(0),
72 seeking_(false), 38 seeking_(false),
73 playback_completed_(false),
74 did_loading_progress_(false), 39 did_loading_progress_(false),
75 cookie_jar_(cookie_jar),
76 manager_(manager), 40 manager_(manager),
77 pending_play_event_(false),
78 network_state_(WebMediaPlayer::NetworkStateEmpty), 41 network_state_(WebMediaPlayer::NetworkStateEmpty),
79 ready_state_(WebMediaPlayer::ReadyStateHaveNothing), 42 ready_state_(WebMediaPlayer::ReadyStateHaveNothing),
80 texture_id_(0), 43 is_playing_(false),
81 stream_id_(0),
82 needs_establish_peer_(true), 44 needs_establish_peer_(true),
83 stream_texture_factory_(factory) { 45 stream_texture_factory_(factory) {
84 main_loop_->AddDestructionObserver(this); 46 main_loop_->AddDestructionObserver(this);
85 if (manager_) 47 if (manager_)
86 player_id_ = manager_->RegisterMediaPlayer(this); 48 player_id_ = manager_->RegisterMediaPlayer(this);
49
87 if (stream_texture_factory_.get()) { 50 if (stream_texture_factory_.get()) {
88 stream_texture_proxy_.reset(stream_texture_factory_->CreateProxy()); 51 stream_texture_proxy_.reset(stream_texture_factory_->CreateProxy());
89 stream_id_ = stream_texture_factory_->CreateStreamTexture(&texture_id_); 52 stream_id_ = stream_texture_factory_->CreateStreamTexture(&texture_id_);
90 } 53 }
91 } 54 }
92 55
93 WebMediaPlayerAndroid::~WebMediaPlayerAndroid() { 56 WebMediaPlayerAndroid::~WebMediaPlayerAndroid() {
94 if (manager_) 57 Destroy();
95 manager_->UnregisterMediaPlayer(player_id_);
96 58
97 if (stream_id_) 59 if (stream_id_)
98 stream_texture_factory_->DestroyStreamTexture(texture_id_); 60 stream_texture_factory_->DestroyStreamTexture(texture_id_);
99 61
62 if (manager_)
63 manager_->UnregisterMediaPlayer(player_id_);
64
100 if (main_loop_) 65 if (main_loop_)
101 main_loop_->RemoveDestructionObserver(this); 66 main_loop_->RemoveDestructionObserver(this);
102 } 67 }
103 68
104 void WebMediaPlayerAndroid::InitIncognito(bool incognito_mode) {
105 incognito_mode_ = incognito_mode;
106 }
107
108 void WebMediaPlayerAndroid::load(const WebURL& url, CORSMode cors_mode) { 69 void WebMediaPlayerAndroid::load(const WebURL& url, CORSMode cors_mode) {
109 if (cors_mode != CORSModeUnspecified) 70 if (cors_mode != CORSModeUnspecified)
110 NOTIMPLEMENTED() << "No CORS support"; 71 NOTIMPLEMENTED() << "No CORS support";
111 72
112 url_ = url; 73 url_ = url;
113 74
114 UpdateNetworkState(WebMediaPlayer::NetworkStateLoading); 75 InitializeMediaPlayer(url_);
115 UpdateReadyState(WebMediaPlayer::ReadyStateHaveNothing);
116
117 // Calling InitializeMediaPlayer() will cause android mediaplayer to start
118 // buffering and decoding the data. On mobile devices, this costs a lot of
119 // data usage and could even introduce performance issues. So we don't
120 // initialize the player unless it is a local file. We will start loading
121 // the media only when play/seek/fullsceen button is clicked.
122 if (url_.SchemeIs("file")) {
123 InitializeMediaPlayer();
124 return;
125 }
126
127 // TODO(qinmin): we need a method to calculate the duration of the media.
128 // Android does not provide any function to do that.
129 // Set the initial duration value to kTemporaryDuration so that user can
130 // touch the seek bar to perform seek. We will scale the seek position later
131 // when we got the actual duration.
132 duration_ = kTemporaryDuration;
133
134 // Pretend everything has been loaded so that webkit can
135 // still call play() and seek().
136 UpdateReadyState(WebMediaPlayer::ReadyStateHaveMetadata);
137 UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
138 } 76 }
139 77
140 void WebMediaPlayerAndroid::cancelLoad() { 78 void WebMediaPlayerAndroid::cancelLoad() {
141 NOTIMPLEMENTED(); 79 NOTIMPLEMENTED();
142 } 80 }
143 81
144 void WebMediaPlayerAndroid::play() { 82 void WebMediaPlayerAndroid::play() {
145 if (media_player_.get()) { 83 if (hasVideo() && needs_establish_peer_)
146 if (!prepared_) 84 EstablishSurfaceTexturePeer();
147 pending_play_event_ = true; 85
148 else 86 PlayInternal();
149 PlayInternal(); 87 is_playing_ = true;
150 } else {
151 pending_play_event_ = true;
152 InitializeMediaPlayer();
153 }
154 } 88 }
155 89
156 void WebMediaPlayerAndroid::pause() { 90 void WebMediaPlayerAndroid::pause() {
157 if (media_player_.get()) { 91 PauseInternal();
158 if (!prepared_) 92 is_playing_ = false;
159 pending_play_event_ = false;
160 else
161 PauseInternal();
162 } else {
163 // We don't need to load media if pause() is called.
164 pending_play_event_ = false;
165 }
166 } 93 }
167 94
168 void WebMediaPlayerAndroid::seek(float seconds) { 95 void WebMediaPlayerAndroid::seek(float seconds) {
169 // Record the time to seek when OnMediaPrepared() is called.
170 pending_seek_ = seconds; 96 pending_seek_ = seconds;
97 seeking_ = true;
171 98
172 // Reset |playback_completed_| so that we return the correct current time. 99 SeekInternal(ConvertSecondsToTimestamp(seconds));
173 playback_completed_ = false;
174
175 if (media_player_.get()) {
176 if (prepared_)
177 SeekInternal(seconds);
178 } else {
179 InitializeMediaPlayer();
180 }
181 } 100 }
182 101
183 bool WebMediaPlayerAndroid::supportsFullscreen() const { 102 bool WebMediaPlayerAndroid::supportsFullscreen() const {
184 return true; 103 return true;
185 } 104 }
186 105
187 bool WebMediaPlayerAndroid::supportsSave() const { 106 bool WebMediaPlayerAndroid::supportsSave() const {
188 return false; 107 return false;
189 } 108 }
190 109
191 void WebMediaPlayerAndroid::setEndTime(float seconds) { 110 void WebMediaPlayerAndroid::setEndTime(float seconds) {
192 // Deprecated. 111 // Deprecated.
193 // TODO(qinmin): Remove this from WebKit::WebMediaPlayer as it is never used. 112 // TODO(qinmin): Remove this from WebKit::WebMediaPlayer as it is never used.
194 } 113 }
195 114
196 void WebMediaPlayerAndroid::setRate(float rate) { 115 void WebMediaPlayerAndroid::setRate(float rate) {
197 NOTIMPLEMENTED(); 116 NOTIMPLEMENTED();
198 } 117 }
199 118
200 void WebMediaPlayerAndroid::setVolume(float volume) { 119 void WebMediaPlayerAndroid::setVolume(float volume) {
201 if (media_player_.get()) 120 NOTIMPLEMENTED();
202 media_player_->SetVolume(volume, volume);
203 } 121 }
204 122
205 void WebMediaPlayerAndroid::setVisible(bool visible) { 123 void WebMediaPlayerAndroid::setVisible(bool visible) {
206 // Deprecated. 124 // Deprecated.
207 // TODO(qinmin): Remove this from WebKit::WebMediaPlayer as it is never used. 125 // TODO(qinmin): Remove this from WebKit::WebMediaPlayer as it is never used.
208 } 126 }
209 127
210 bool WebMediaPlayerAndroid::totalBytesKnown() { 128 bool WebMediaPlayerAndroid::totalBytesKnown() {
211 NOTIMPLEMENTED(); 129 NOTIMPLEMENTED();
212 return false; 130 return false;
213 } 131 }
214 132
215 bool WebMediaPlayerAndroid::hasVideo() const { 133 bool WebMediaPlayerAndroid::hasVideo() const {
134 // If we have obtained video size information before, use it.
135 if (!natural_size_.isEmpty())
136 return true;
137
216 // TODO(qinmin): need a better method to determine whether the current media 138 // TODO(qinmin): need a better method to determine whether the current media
217 // content contains video. Android does not provide any function to do 139 // content contains video. Android does not provide any function to do
218 // this. 140 // this.
219 // We don't know whether the current media content has video unless 141 // We don't know whether the current media content has video unless
220 // the player is prepared. If the player is not prepared, we fall back 142 // the player is prepared. If the player is not prepared, we fall back
221 // to the mime-type. There may be no mime-type on a redirect URL. 143 // to the mime-type. There may be no mime-type on a redirect URL.
222 // In that case, we conservatively assume it contains video so that 144 // In that case, we conservatively assume it contains video so that
223 // enterfullscreen call will not fail. 145 // enterfullscreen call will not fail.
224 if (!prepared_) { 146 if (!url_.has_path())
225 if (!url_.has_path()) 147 return false;
226 return false; 148 std::string mime;
227 std::string mime; 149 if(!net::GetMimeTypeFromFile(FilePath(url_.path()), &mime))
228 if(!net::GetMimeTypeFromFile(FilePath(url_.path()), &mime)) 150 return true;
229 return true; 151 return mime.find("audio/") == std::string::npos;
230 return mime.find("audio/") == std::string::npos;
231 }
232
233 return !natural_size_.isEmpty();
234 } 152 }
235 153
236 bool WebMediaPlayerAndroid::hasAudio() const { 154 bool WebMediaPlayerAndroid::hasAudio() const {
237 // TODO(hclam): Query status of audio and return the actual value. 155 // TODO(hclam): Query status of audio and return the actual value.
238 return true; 156 return true;
239 } 157 }
240 158
241 bool WebMediaPlayerAndroid::paused() const { 159 bool WebMediaPlayerAndroid::paused() const {
242 if (!prepared_) 160 return !is_playing_;
243 return !pending_play_event_;
244 return !media_player_->IsPlaying();
245 } 161 }
246 162
247 bool WebMediaPlayerAndroid::seeking() const { 163 bool WebMediaPlayerAndroid::seeking() const {
248 return seeking_; 164 return seeking_;
249 } 165 }
250 166
251 float WebMediaPlayerAndroid::duration() const { 167 float WebMediaPlayerAndroid::duration() const {
252 return duration_; 168 return static_cast<float>(duration_.InSecondsF());
253 } 169 }
254 170
255 float WebMediaPlayerAndroid::currentTime() const { 171 float WebMediaPlayerAndroid::currentTime() const {
256 // If the player is pending for a seek, return the seek time. 172 // If the player is pending for a seek, return the seek time.
257 if (!prepared_ || seeking()) 173 if (seeking())
258 return pending_seek_; 174 return pending_seek_;
259 175
260 // When playback is about to finish, android media player often stops 176 return GetCurrentTimeInternal();
261 // at a time which is smaller than the duration. This makes webkit never
262 // know that the playback has finished. To solve this, we set the
263 // current time to media duration when OnPlaybackComplete() get called.
264 // And return the greater of the two values so that the current
265 // time is most updated.
266 if (playback_completed_)
267 return duration();
268 return static_cast<float>(media_player_->GetCurrentTime().InSecondsF());
269 } 177 }
270 178
271 int WebMediaPlayerAndroid::dataRate() const { 179 int WebMediaPlayerAndroid::dataRate() const {
272 // Deprecated. 180 // Deprecated.
273 // TODO(qinmin): Remove this from WebKit::WebMediaPlayer as it is never used. 181 // TODO(qinmin): Remove this from WebKit::WebMediaPlayer as it is never used.
274 return 0; 182 return 0;
275 } 183 }
276 184
277 WebSize WebMediaPlayerAndroid::naturalSize() const { 185 WebSize WebMediaPlayerAndroid::naturalSize() const {
278 return natural_size_; 186 return natural_size_;
(...skipping 21 matching lines...) Expand all
300 did_loading_progress_ = false; 208 did_loading_progress_ = false;
301 return ret; 209 return ret;
302 } 210 }
303 211
304 unsigned long long WebMediaPlayerAndroid::totalBytes() const { 212 unsigned long long WebMediaPlayerAndroid::totalBytes() const {
305 // Deprecated. 213 // Deprecated.
306 // TODO(qinmin): Remove this from WebKit::WebMediaPlayer as it is never used. 214 // TODO(qinmin): Remove this from WebKit::WebMediaPlayer as it is never used.
307 return 0; 215 return 0;
308 } 216 }
309 217
310 void WebMediaPlayerAndroid::setSize(const WebSize& size) { 218 void WebMediaPlayerAndroid::setSize(const WebKit::WebSize& size) {
311 texture_size_ = size;
312 } 219 }
313 220
314 void WebMediaPlayerAndroid::paint(WebKit::WebCanvas* canvas, 221 void WebMediaPlayerAndroid::paint(WebKit::WebCanvas* canvas,
315 const WebKit::WebRect& rect, 222 const WebKit::WebRect& rect,
316 uint8_t alpha) { 223 uint8_t alpha) {
317 NOTIMPLEMENTED(); 224 NOTIMPLEMENTED();
318 } 225 }
319 226
320 bool WebMediaPlayerAndroid::hasSingleSecurityOrigin() const { 227 bool WebMediaPlayerAndroid::hasSingleSecurityOrigin() const {
321 return false; 228 return false;
322 } 229 }
323 230
324 bool WebMediaPlayerAndroid::didPassCORSAccessCheck() const { 231 bool WebMediaPlayerAndroid::didPassCORSAccessCheck() const {
325 return false; 232 return false;
326 } 233 }
327 234
328 WebMediaPlayer::MovieLoadType 235 WebMediaPlayer::MovieLoadType WebMediaPlayerAndroid::movieLoadType() const {
329 WebMediaPlayerAndroid::movieLoadType() const {
330 // Deprecated. 236 // Deprecated.
331 // TODO(qinmin): Remove this from WebKit::WebMediaPlayer as it is never used. 237 // TODO(qinmin): Remove this from WebKit::WebMediaPlayer as it is never used.
332 return WebMediaPlayer::MovieLoadTypeUnknown; 238 return WebMediaPlayer::MovieLoadTypeUnknown;
333 } 239 }
334 240
335 float WebMediaPlayerAndroid::mediaTimeForTimeValue(float timeValue) const { 241 float WebMediaPlayerAndroid::mediaTimeForTimeValue(float timeValue) const {
336 return ConvertSecondsToTimestamp(timeValue).InSecondsF(); 242 return ConvertSecondsToTimestamp(timeValue).InSecondsF();
337 } 243 }
338 244
339 unsigned WebMediaPlayerAndroid::decodedFrameCount() const { 245 unsigned WebMediaPlayerAndroid::decodedFrameCount() const {
340 NOTIMPLEMENTED(); 246 NOTIMPLEMENTED();
341 return 0; 247 return 0;
342 } 248 }
343 249
344 unsigned WebMediaPlayerAndroid::droppedFrameCount() const { 250 unsigned WebMediaPlayerAndroid::droppedFrameCount() const {
345 NOTIMPLEMENTED(); 251 NOTIMPLEMENTED();
346 return 0; 252 return 0;
347 } 253 }
348 254
349 unsigned WebMediaPlayerAndroid::audioDecodedByteCount() const { 255 unsigned WebMediaPlayerAndroid::audioDecodedByteCount() const {
350 NOTIMPLEMENTED(); 256 NOTIMPLEMENTED();
351 return 0; 257 return 0;
352 } 258 }
353 259
354 unsigned WebMediaPlayerAndroid::videoDecodedByteCount() const { 260 unsigned WebMediaPlayerAndroid::videoDecodedByteCount() const {
355 NOTIMPLEMENTED(); 261 NOTIMPLEMENTED();
356 return 0; 262 return 0;
357 } 263 }
358 264
359 void WebMediaPlayerAndroid::OnMediaPrepared() { 265 void WebMediaPlayerAndroid::OnMediaPrepared(base::TimeDelta duration) {
360 if (!media_player_.get())
361 return;
362
363 prepared_ = true;
364
365 // Update the media duration first so that webkit will get the correct
366 // duration when UpdateReadyState is called.
367 float dur = duration_;
368 duration_ = media_player_->GetDuration().InSecondsF();
369
370 if (url_.SchemeIs("file")) 266 if (url_.SchemeIs("file"))
371 UpdateNetworkState(WebMediaPlayer::NetworkStateLoaded); 267 UpdateNetworkState(WebMediaPlayer::NetworkStateLoaded);
372 268
373 if (ready_state_ != WebMediaPlayer::ReadyStateHaveEnoughData) { 269 if (ready_state_ != WebMediaPlayer::ReadyStateHaveEnoughData) {
374 UpdateReadyState(WebMediaPlayer::ReadyStateHaveMetadata); 270 UpdateReadyState(WebMediaPlayer::ReadyStateHaveMetadata);
375 UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); 271 UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
376 } else { 272 } else {
377 // If the status is already set to ReadyStateHaveEnoughData, set it again 273 // If the status is already set to ReadyStateHaveEnoughData, set it again
378 // to make sure that Videolayerchromium will get created. 274 // to make sure that Videolayerchromium will get created.
379 UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); 275 UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
380 } 276 }
381 277
382 if (!url_.SchemeIs("file")) { 278 // In we have skipped loading, we have to update webkit about the new
383 // In we have skipped loading, the duration was preset to 279 // duration.
384 // kTemporaryDuration. We have to update webkit about the new duration. 280 if (duration_ != duration) {
385 if (duration_ != dur) { 281 duration_ = duration;
386 // Scale the |pending_seek_| according to the new duration. 282 client_->durationChanged();
387 pending_seek_ = pending_seek_ * duration_ / kTemporaryDuration;
388 client_->durationChanged();
389 }
390 } 283 }
391
392 // If media player was recovered from a saved state, consume all the pending
393 // events.
394 seek(pending_seek_);
395
396 if (pending_play_event_)
397 PlayInternal();
398
399 pending_play_event_ = false;
400 } 284 }
401 285
402 void WebMediaPlayerAndroid::OnPlaybackComplete() { 286 void WebMediaPlayerAndroid::OnPlaybackComplete() {
403 // Set the current time equal to duration to let webkit know that play back 287 // When playback is about to finish, android media player often stops
404 // is completed. 288 // at a time which is smaller than the duration. This makes webkit never
405 playback_completed_ = true; 289 // know that the playback has finished. To solve this, we set the
290 // current time to media duration when OnPlaybackComplete() get called.
291 OnTimeUpdate(duration_);
406 client_->timeChanged(); 292 client_->timeChanged();
407 } 293 }
408 294
409 void WebMediaPlayerAndroid::OnBufferingUpdate(int percentage) { 295 void WebMediaPlayerAndroid::OnBufferingUpdate(int percentage) {
410 buffered_[0].end = duration() * percentage / 100; 296 buffered_[0].end = duration() * percentage / 100;
411 did_loading_progress_ = true; 297 did_loading_progress_ = true;
412 } 298 }
413 299
414 void WebMediaPlayerAndroid::OnSeekComplete() { 300 void WebMediaPlayerAndroid::OnSeekComplete(base::TimeDelta current_time) {
415 seeking_ = false; 301 seeking_ = false;
416 302
303 OnTimeUpdate(current_time);
304
417 UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); 305 UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
418 306
419 client_->timeChanged(); 307 client_->timeChanged();
420 } 308 }
421 309
422 void WebMediaPlayerAndroid::OnMediaError(int error_type) { 310 void WebMediaPlayerAndroid::OnMediaError(int error_type) {
423 switch (error_type) { 311 switch (error_type) {
424 case MediaPlayerBridge::MEDIA_ERROR_UNKNOWN: 312 case MediaPlayerBridge::MEDIA_ERROR_UNKNOWN:
425 // When playing an bogus URL or bad file we fire a MEDIA_ERROR_UNKNOWN. 313 // When playing an bogus URL or bad file we fire a MEDIA_ERROR_UNKNOWN.
426 // As WebKit uses FormatError to indicate an error for bogus URL or bad 314 // As WebKit uses FormatError to indicate an error for bogus URL or bad
427 // file we default a MEDIA_ERROR_UNKNOWN to NetworkStateFormatError. 315 // file we default a MEDIA_ERROR_UNKNOWN to NetworkStateFormatError.
428 UpdateNetworkState(WebMediaPlayer::NetworkStateFormatError); 316 UpdateNetworkState(WebMediaPlayer::NetworkStateFormatError);
429 break; 317 break;
430 case MediaPlayerBridge::MEDIA_ERROR_SERVER_DIED: 318 case MediaPlayerBridge::MEDIA_ERROR_SERVER_DIED:
431 // TODO(zhenghao): Media server died. In this case, the application must 319 // TODO(zhenghao): Media server died. In this case, the application must
432 // release the MediaPlayer object and instantiate a new one. 320 // release the MediaPlayer object and instantiate a new one.
433 UpdateNetworkState(WebMediaPlayer::NetworkStateDecodeError); 321 UpdateNetworkState(WebMediaPlayer::NetworkStateDecodeError);
434 break; 322 break;
435 case MediaPlayerBridge::MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK: 323 case MediaPlayerBridge::MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
436 UpdateNetworkState(WebMediaPlayer::NetworkStateFormatError); 324 UpdateNetworkState(WebMediaPlayer::NetworkStateFormatError);
437 break; 325 break;
438 case MediaPlayerBridge::MEDIA_ERROR_INVALID_CODE: 326 case MediaPlayerBridge::MEDIA_ERROR_INVALID_CODE:
439 break; 327 break;
440 } 328 }
441 client_->repaint(); 329 client_->repaint();
442 } 330 }
443 331
444 void WebMediaPlayerAndroid::OnMediaInfo(int info_type) {
445 NOTIMPLEMENTED();
446 }
447
448 void WebMediaPlayerAndroid::OnVideoSizeChanged(int width, int height) { 332 void WebMediaPlayerAndroid::OnVideoSizeChanged(int width, int height) {
449 if (natural_size_.width == width && natural_size_.height == height) 333 if (natural_size_.width == width && natural_size_.height == height)
450 return; 334 return;
451 335
452 natural_size_.width = width; 336 natural_size_.width = width;
453 natural_size_.height = height; 337 natural_size_.height = height;
454 if (texture_id_) { 338 if (texture_id_) {
455 video_frame_.reset(new WebVideoFrameImpl(VideoFrame::WrapNativeTexture( 339 video_frame_.reset(new WebVideoFrameImpl(VideoFrame::WrapNativeTexture(
456 texture_id_, kGLTextureExternalOES, natural_size_, natural_size_, 340 texture_id_, kGLTextureExternalOES, natural_size_, natural_size_,
457 base::TimeDelta(), 341 base::TimeDelta(),
(...skipping 10 matching lines...) Expand all
468 void WebMediaPlayerAndroid::UpdateReadyState( 352 void WebMediaPlayerAndroid::UpdateReadyState(
469 WebMediaPlayer::ReadyState state) { 353 WebMediaPlayer::ReadyState state) {
470 ready_state_ = state; 354 ready_state_ = state;
471 client_->readyStateChanged(); 355 client_->readyStateChanged();
472 } 356 }
473 357
474 void WebMediaPlayerAndroid::ReleaseMediaResources() { 358 void WebMediaPlayerAndroid::ReleaseMediaResources() {
475 // Pause the media player first. 359 // Pause the media player first.
476 pause(); 360 pause();
477 client_->playbackStateChanged(); 361 client_->playbackStateChanged();
362 needs_establish_peer_ = true;
478 363
479 if (media_player_.get()) { 364 ReleaseResourcesInternal();
480 // Save the current media player status.
481 pending_seek_ = currentTime();
482 duration_ = duration();
483
484 media_player_.reset();
485 needs_establish_peer_ = true;
486 }
487 prepared_ = false;
488 }
489
490 bool WebMediaPlayerAndroid::IsInitialized() const {
491 return (media_player_ != NULL);
492 }
493
494 void WebMediaPlayerAndroid::InitializeMediaPlayer() {
495 CHECK(!media_player_.get());
496 prepared_ = false;
497 media_player_.reset(new MediaPlayerBridge());
498 media_player_->SetStayAwakeWhilePlaying();
499
500 std::string cookies;
501 if (cookie_jar_ != NULL) {
502 WebURL first_party_url(frame_->document().firstPartyForCookies());
503 cookies = UTF16ToUTF8(cookie_jar_->cookies(url_, first_party_url));
504 }
505 media_player_->SetDataSource(url_.spec(), cookies, incognito_mode_);
506
507 if (manager_)
508 manager_->RequestMediaResources(player_id_);
509
510 media_player_->Prepare(
511 base::Bind(&WebMediaPlayerProxyAndroid::MediaInfoCallback, proxy_),
512 base::Bind(&WebMediaPlayerProxyAndroid::MediaErrorCallback, proxy_),
513 base::Bind(&WebMediaPlayerProxyAndroid::VideoSizeChangedCallback, proxy_),
514 base::Bind(&WebMediaPlayerProxyAndroid::BufferingUpdateCallback, proxy_),
515 base::Bind(&WebMediaPlayerProxyAndroid::MediaPreparedCallback, proxy_));
516 }
517
518 void WebMediaPlayerAndroid::PlayInternal() {
519 CHECK(prepared_);
520
521 if (hasVideo() && stream_texture_factory_.get()) {
522 if (needs_establish_peer_) {
523 stream_texture_factory_->EstablishPeer(stream_id_, player_id_);
524 needs_establish_peer_ = false;
525 }
526 }
527
528 if (paused())
529 media_player_->Start(base::Bind(
530 &WebMediaPlayerProxyAndroid::PlaybackCompleteCallback, proxy_));
531 }
532
533 void WebMediaPlayerAndroid::PauseInternal() {
534 CHECK(prepared_);
535 media_player_->Pause();
536 }
537
538 void WebMediaPlayerAndroid::SeekInternal(float seconds) {
539 CHECK(prepared_);
540 seeking_ = true;
541 media_player_->SeekTo(ConvertSecondsToTimestamp(seconds), base::Bind(
542 &WebMediaPlayerProxyAndroid::SeekCompleteCallback, proxy_));
543 } 365 }
544 366
545 void WebMediaPlayerAndroid::WillDestroyCurrentMessageLoop() { 367 void WebMediaPlayerAndroid::WillDestroyCurrentMessageLoop() {
368 Destroy();
369
370 if (stream_id_) {
371 stream_texture_factory_->DestroyStreamTexture(texture_id_);
372 stream_id_ = 0;
373 }
374
375 video_frame_.reset(new WebVideoFrameImpl(VideoFrame::CreateEmptyFrame()));
376
377 if (manager_)
378 manager_->UnregisterMediaPlayer(player_id_);
379
546 manager_ = NULL; 380 manager_ = NULL;
547 main_loop_ = NULL; 381 main_loop_ = NULL;
548 } 382 }
549 383
550 WebVideoFrame* WebMediaPlayerAndroid::getCurrentFrame() { 384 WebVideoFrame* WebMediaPlayerAndroid::getCurrentFrame() {
551 if (!stream_texture_proxy_->IsInitialized() && stream_id_) { 385 if (stream_texture_proxy_.get() && !stream_texture_proxy_->IsInitialized()
386 && stream_id_) {
552 stream_texture_proxy_->Initialize( 387 stream_texture_proxy_->Initialize(
553 stream_id_, video_frame_->width(), video_frame_->height()); 388 stream_id_, video_frame_->width(), video_frame_->height());
554 } 389 }
555 390
556 return video_frame_.get(); 391 return video_frame_.get();
557 } 392 }
558 393
559 void WebMediaPlayerAndroid::putCurrentFrame( 394 void WebMediaPlayerAndroid::putCurrentFrame(
560 WebVideoFrame* web_video_frame) { 395 WebVideoFrame* web_video_frame) {
561 } 396 }
562 397
563 // This gets called both on compositor and main thread.
564 void WebMediaPlayerAndroid::setStreamTextureClient( 398 void WebMediaPlayerAndroid::setStreamTextureClient(
565 WebKit::WebStreamTextureClient* client) { 399 WebKit::WebStreamTextureClient* client) {
566 if (stream_texture_proxy_.get()) 400 if (stream_texture_proxy_.get())
567 stream_texture_proxy_->SetClient(client); 401 stream_texture_proxy_->SetClient(client);
568 } 402 }
569 403
404 void WebMediaPlayerAndroid::EstablishSurfaceTexturePeer() {
405 if (stream_texture_factory_.get() && stream_id_)
406 stream_texture_factory_->EstablishPeer(stream_id_, player_id_);
407 needs_establish_peer_ = false;
408 }
409
410 void WebMediaPlayerAndroid::UpdatePlayingState(bool is_playing) {
411 is_playing_ = is_playing;
412 }
413
570 } // namespace webkit_media 414 } // namespace webkit_media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698