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

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 and resolving merge conflicts 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() {
57 if (stream_id_)
58 stream_texture_factory_->DestroyStreamTexture(texture_id_);
59
94 if (manager_) 60 if (manager_)
95 manager_->UnregisterMediaPlayer(player_id_); 61 manager_->UnregisterMediaPlayer(player_id_);
96 62
97 if (stream_id_)
98 stream_texture_factory_->DestroyStreamTexture(texture_id_);
99
100 if (main_loop_) 63 if (main_loop_)
101 main_loop_->RemoveDestructionObserver(this); 64 main_loop_->RemoveDestructionObserver(this);
102 } 65 }
103 66
104 void WebMediaPlayerAndroid::InitIncognito(bool incognito_mode) {
105 incognito_mode_ = incognito_mode;
106 }
107
108 void WebMediaPlayerAndroid::load(const WebURL& url, CORSMode cors_mode) { 67 void WebMediaPlayerAndroid::load(const WebURL& url, CORSMode cors_mode) {
109 if (cors_mode != CORSModeUnspecified) 68 if (cors_mode != CORSModeUnspecified)
110 NOTIMPLEMENTED() << "No CORS support"; 69 NOTIMPLEMENTED() << "No CORS support";
111 70
112 url_ = url; 71 url_ = url;
113 72
114 UpdateNetworkState(WebMediaPlayer::NetworkStateLoading); 73 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 } 74 }
139 75
140 void WebMediaPlayerAndroid::cancelLoad() { 76 void WebMediaPlayerAndroid::cancelLoad() {
141 NOTIMPLEMENTED(); 77 NOTIMPLEMENTED();
142 } 78 }
143 79
144 void WebMediaPlayerAndroid::play() { 80 void WebMediaPlayerAndroid::play() {
145 if (media_player_.get()) { 81 if (hasVideo() && needs_establish_peer_)
146 if (!prepared_) 82 EstablishSurfaceTexturePeer();
147 pending_play_event_ = true; 83
148 else 84 PlayInternal();
149 PlayInternal(); 85 is_playing_ = true;
150 } else {
151 pending_play_event_ = true;
152 InitializeMediaPlayer();
153 }
154 } 86 }
155 87
156 void WebMediaPlayerAndroid::pause() { 88 void WebMediaPlayerAndroid::pause() {
157 if (media_player_.get()) { 89 PauseInternal();
158 if (!prepared_) 90 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 } 91 }
167 92
168 void WebMediaPlayerAndroid::seek(float seconds) { 93 void WebMediaPlayerAndroid::seek(float seconds) {
169 // Record the time to seek when OnMediaPrepared() is called.
170 pending_seek_ = seconds; 94 pending_seek_ = seconds;
95 seeking_ = true;
171 96
172 // Reset |playback_completed_| so that we return the correct current time. 97 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 } 98 }
182 99
183 bool WebMediaPlayerAndroid::supportsFullscreen() const { 100 bool WebMediaPlayerAndroid::supportsFullscreen() const {
184 return true; 101 return true;
185 } 102 }
186 103
187 bool WebMediaPlayerAndroid::supportsSave() const { 104 bool WebMediaPlayerAndroid::supportsSave() const {
188 return false; 105 return false;
189 } 106 }
190 107
191 void WebMediaPlayerAndroid::setEndTime(float seconds) { 108 void WebMediaPlayerAndroid::setEndTime(float seconds) {
192 // Deprecated. 109 // Deprecated.
193 // TODO(qinmin): Remove this from WebKit::WebMediaPlayer as it is never used. 110 // TODO(qinmin): Remove this from WebKit::WebMediaPlayer as it is never used.
194 } 111 }
195 112
196 void WebMediaPlayerAndroid::setRate(float rate) { 113 void WebMediaPlayerAndroid::setRate(float rate) {
197 NOTIMPLEMENTED(); 114 NOTIMPLEMENTED();
198 } 115 }
199 116
200 void WebMediaPlayerAndroid::setVolume(float volume) { 117 void WebMediaPlayerAndroid::setVolume(float volume) {
201 if (media_player_.get()) 118 NOTIMPLEMENTED();
202 media_player_->SetVolume(volume, volume);
203 } 119 }
204 120
205 void WebMediaPlayerAndroid::setVisible(bool visible) { 121 void WebMediaPlayerAndroid::setVisible(bool visible) {
206 // Deprecated. 122 // Deprecated.
207 // TODO(qinmin): Remove this from WebKit::WebMediaPlayer as it is never used. 123 // TODO(qinmin): Remove this from WebKit::WebMediaPlayer as it is never used.
208 } 124 }
209 125
210 bool WebMediaPlayerAndroid::totalBytesKnown() { 126 bool WebMediaPlayerAndroid::totalBytesKnown() {
211 NOTIMPLEMENTED(); 127 NOTIMPLEMENTED();
212 return false; 128 return false;
213 } 129 }
214 130
215 bool WebMediaPlayerAndroid::hasVideo() const { 131 bool WebMediaPlayerAndroid::hasVideo() const {
132 // If we have obtained video size information before, use it.
133 if (!natural_size_.isEmpty())
134 return true;
135
216 // TODO(qinmin): need a better method to determine whether the current media 136 // TODO(qinmin): need a better method to determine whether the current media
217 // content contains video. Android does not provide any function to do 137 // content contains video. Android does not provide any function to do
218 // this. 138 // this.
219 // We don't know whether the current media content has video unless 139 // 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 140 // 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. 141 // 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 142 // In that case, we conservatively assume it contains video so that
223 // enterfullscreen call will not fail. 143 // enterfullscreen call will not fail.
224 if (!prepared_) { 144 if (!url_.has_path())
225 if (!url_.has_path()) 145 return false;
226 return false; 146 std::string mime;
227 std::string mime; 147 if(!net::GetMimeTypeFromFile(FilePath(url_.path()), &mime))
228 if(!net::GetMimeTypeFromFile(FilePath(url_.path()), &mime)) 148 return true;
229 return true; 149 return mime.find("audio/") == std::string::npos;
230 return mime.find("audio/") == std::string::npos;
231 }
232
233 return !natural_size_.isEmpty();
234 } 150 }
235 151
236 bool WebMediaPlayerAndroid::hasAudio() const { 152 bool WebMediaPlayerAndroid::hasAudio() const {
237 // TODO(hclam): Query status of audio and return the actual value. 153 // TODO(hclam): Query status of audio and return the actual value.
238 return true; 154 return true;
239 } 155 }
240 156
241 bool WebMediaPlayerAndroid::paused() const { 157 bool WebMediaPlayerAndroid::paused() const {
242 if (!prepared_) 158 return !is_playing_;
243 return !pending_play_event_;
244 return !media_player_->IsPlaying();
245 } 159 }
246 160
247 bool WebMediaPlayerAndroid::seeking() const { 161 bool WebMediaPlayerAndroid::seeking() const {
248 return seeking_; 162 return seeking_;
249 } 163 }
250 164
251 float WebMediaPlayerAndroid::duration() const { 165 float WebMediaPlayerAndroid::duration() const {
252 return duration_; 166 return static_cast<float>(duration_.InSecondsF());
253 } 167 }
254 168
255 float WebMediaPlayerAndroid::currentTime() const { 169 float WebMediaPlayerAndroid::currentTime() const {
256 // If the player is pending for a seek, return the seek time. 170 // If the player is pending for a seek, return the seek time.
257 if (!prepared_ || seeking()) 171 if (seeking())
258 return pending_seek_; 172 return pending_seek_;
259 173
260 // When playback is about to finish, android media player often stops 174 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 } 175 }
270 176
271 int WebMediaPlayerAndroid::dataRate() const { 177 int WebMediaPlayerAndroid::dataRate() const {
272 // Deprecated. 178 // Deprecated.
273 // TODO(qinmin): Remove this from WebKit::WebMediaPlayer as it is never used. 179 // TODO(qinmin): Remove this from WebKit::WebMediaPlayer as it is never used.
274 return 0; 180 return 0;
275 } 181 }
276 182
277 WebSize WebMediaPlayerAndroid::naturalSize() const { 183 WebSize WebMediaPlayerAndroid::naturalSize() const {
278 return natural_size_; 184 return natural_size_;
(...skipping 21 matching lines...) Expand all
300 did_loading_progress_ = false; 206 did_loading_progress_ = false;
301 return ret; 207 return ret;
302 } 208 }
303 209
304 unsigned long long WebMediaPlayerAndroid::totalBytes() const { 210 unsigned long long WebMediaPlayerAndroid::totalBytes() const {
305 // Deprecated. 211 // Deprecated.
306 // TODO(qinmin): Remove this from WebKit::WebMediaPlayer as it is never used. 212 // TODO(qinmin): Remove this from WebKit::WebMediaPlayer as it is never used.
307 return 0; 213 return 0;
308 } 214 }
309 215
310 void WebMediaPlayerAndroid::setSize(const WebSize& size) { 216 void WebMediaPlayerAndroid::setSize(const WebKit::WebSize& size) {
311 texture_size_ = size;
312 } 217 }
313 218
314 void WebMediaPlayerAndroid::paint(WebKit::WebCanvas* canvas, 219 void WebMediaPlayerAndroid::paint(WebKit::WebCanvas* canvas,
315 const WebKit::WebRect& rect, 220 const WebKit::WebRect& rect,
316 uint8_t alpha) { 221 uint8_t alpha) {
317 NOTIMPLEMENTED(); 222 NOTIMPLEMENTED();
318 } 223 }
319 224
320 bool WebMediaPlayerAndroid::hasSingleSecurityOrigin() const { 225 bool WebMediaPlayerAndroid::hasSingleSecurityOrigin() const {
321 return false; 226 return false;
322 } 227 }
323 228
324 bool WebMediaPlayerAndroid::didPassCORSAccessCheck() const { 229 bool WebMediaPlayerAndroid::didPassCORSAccessCheck() const {
325 return false; 230 return false;
326 } 231 }
327 232
328 WebMediaPlayer::MovieLoadType 233 WebMediaPlayer::MovieLoadType WebMediaPlayerAndroid::movieLoadType() const {
329 WebMediaPlayerAndroid::movieLoadType() const {
330 // Deprecated. 234 // Deprecated.
331 // TODO(qinmin): Remove this from WebKit::WebMediaPlayer as it is never used. 235 // TODO(qinmin): Remove this from WebKit::WebMediaPlayer as it is never used.
332 return WebMediaPlayer::MovieLoadTypeUnknown; 236 return WebMediaPlayer::MovieLoadTypeUnknown;
333 } 237 }
334 238
335 float WebMediaPlayerAndroid::mediaTimeForTimeValue(float timeValue) const { 239 float WebMediaPlayerAndroid::mediaTimeForTimeValue(float timeValue) const {
336 return ConvertSecondsToTimestamp(timeValue).InSecondsF(); 240 return ConvertSecondsToTimestamp(timeValue).InSecondsF();
337 } 241 }
338 242
339 unsigned WebMediaPlayerAndroid::decodedFrameCount() const { 243 unsigned WebMediaPlayerAndroid::decodedFrameCount() const {
340 NOTIMPLEMENTED(); 244 NOTIMPLEMENTED();
341 return 0; 245 return 0;
342 } 246 }
343 247
344 unsigned WebMediaPlayerAndroid::droppedFrameCount() const { 248 unsigned WebMediaPlayerAndroid::droppedFrameCount() const {
345 NOTIMPLEMENTED(); 249 NOTIMPLEMENTED();
346 return 0; 250 return 0;
347 } 251 }
348 252
349 unsigned WebMediaPlayerAndroid::audioDecodedByteCount() const { 253 unsigned WebMediaPlayerAndroid::audioDecodedByteCount() const {
350 NOTIMPLEMENTED(); 254 NOTIMPLEMENTED();
351 return 0; 255 return 0;
352 } 256 }
353 257
354 unsigned WebMediaPlayerAndroid::videoDecodedByteCount() const { 258 unsigned WebMediaPlayerAndroid::videoDecodedByteCount() const {
355 NOTIMPLEMENTED(); 259 NOTIMPLEMENTED();
356 return 0; 260 return 0;
357 } 261 }
358 262
359 void WebMediaPlayerAndroid::OnMediaPrepared() { 263 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")) 264 if (url_.SchemeIs("file"))
371 UpdateNetworkState(WebMediaPlayer::NetworkStateLoaded); 265 UpdateNetworkState(WebMediaPlayer::NetworkStateLoaded);
372 266
373 if (ready_state_ != WebMediaPlayer::ReadyStateHaveEnoughData) { 267 if (ready_state_ != WebMediaPlayer::ReadyStateHaveEnoughData) {
374 UpdateReadyState(WebMediaPlayer::ReadyStateHaveMetadata); 268 UpdateReadyState(WebMediaPlayer::ReadyStateHaveMetadata);
375 UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); 269 UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
376 } else { 270 } else {
377 // If the status is already set to ReadyStateHaveEnoughData, set it again 271 // If the status is already set to ReadyStateHaveEnoughData, set it again
378 // to make sure that Videolayerchromium will get created. 272 // to make sure that Videolayerchromium will get created.
379 UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); 273 UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
380 } 274 }
381 275
382 if (!url_.SchemeIs("file")) { 276 // In we have skipped loading, we have to update webkit about the new
383 // In we have skipped loading, the duration was preset to 277 // duration.
384 // kTemporaryDuration. We have to update webkit about the new duration. 278 if (duration_ != duration) {
385 if (duration_ != dur) { 279 duration_ = duration;
386 // Scale the |pending_seek_| according to the new duration. 280 client_->durationChanged();
387 pending_seek_ = pending_seek_ * duration_ / kTemporaryDuration;
388 client_->durationChanged();
389 }
390 } 281 }
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 } 282 }
401 283
402 void WebMediaPlayerAndroid::OnPlaybackComplete() { 284 void WebMediaPlayerAndroid::OnPlaybackComplete() {
403 // Set the current time equal to duration to let webkit know that play back 285 // When playback is about to finish, android media player often stops
404 // is completed. 286 // at a time which is smaller than the duration. This makes webkit never
405 playback_completed_ = true; 287 // know that the playback has finished. To solve this, we set the
288 // current time to media duration when OnPlaybackComplete() get called.
289 OnTimeUpdate(duration_);
406 client_->timeChanged(); 290 client_->timeChanged();
407 } 291 }
408 292
409 void WebMediaPlayerAndroid::OnBufferingUpdate(int percentage) { 293 void WebMediaPlayerAndroid::OnBufferingUpdate(int percentage) {
410 buffered_[0].end = duration() * percentage / 100; 294 buffered_[0].end = duration() * percentage / 100;
411 did_loading_progress_ = true; 295 did_loading_progress_ = true;
412 } 296 }
413 297
414 void WebMediaPlayerAndroid::OnSeekComplete() { 298 void WebMediaPlayerAndroid::OnSeekComplete(base::TimeDelta current_time) {
415 seeking_ = false; 299 seeking_ = false;
416 300
301 OnTimeUpdate(current_time);
302
417 UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); 303 UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
418 304
419 client_->timeChanged(); 305 client_->timeChanged();
420 } 306 }
421 307
422 void WebMediaPlayerAndroid::OnMediaError(int error_type) { 308 void WebMediaPlayerAndroid::OnMediaError(int error_type) {
423 switch (error_type) { 309 switch (error_type) {
424 case MediaPlayerBridge::MEDIA_ERROR_UNKNOWN: 310 case MediaPlayerBridge::MEDIA_ERROR_UNKNOWN:
425 // When playing an bogus URL or bad file we fire a MEDIA_ERROR_UNKNOWN. 311 // 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 312 // As WebKit uses FormatError to indicate an error for bogus URL or bad
427 // file we default a MEDIA_ERROR_UNKNOWN to NetworkStateFormatError. 313 // file we default a MEDIA_ERROR_UNKNOWN to NetworkStateFormatError.
428 UpdateNetworkState(WebMediaPlayer::NetworkStateFormatError); 314 UpdateNetworkState(WebMediaPlayer::NetworkStateFormatError);
429 break; 315 break;
430 case MediaPlayerBridge::MEDIA_ERROR_SERVER_DIED: 316 case MediaPlayerBridge::MEDIA_ERROR_SERVER_DIED:
431 // TODO(zhenghao): Media server died. In this case, the application must 317 // TODO(zhenghao): Media server died. In this case, the application must
432 // release the MediaPlayer object and instantiate a new one. 318 // release the MediaPlayer object and instantiate a new one.
433 UpdateNetworkState(WebMediaPlayer::NetworkStateDecodeError); 319 UpdateNetworkState(WebMediaPlayer::NetworkStateDecodeError);
434 break; 320 break;
435 case MediaPlayerBridge::MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK: 321 case MediaPlayerBridge::MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
436 UpdateNetworkState(WebMediaPlayer::NetworkStateFormatError); 322 UpdateNetworkState(WebMediaPlayer::NetworkStateFormatError);
437 break; 323 break;
438 case MediaPlayerBridge::MEDIA_ERROR_INVALID_CODE: 324 case MediaPlayerBridge::MEDIA_ERROR_INVALID_CODE:
439 break; 325 break;
440 } 326 }
441 client_->repaint(); 327 client_->repaint();
442 } 328 }
443 329
444 void WebMediaPlayerAndroid::OnMediaInfo(int info_type) {
445 NOTIMPLEMENTED();
446 }
447
448 void WebMediaPlayerAndroid::OnVideoSizeChanged(int width, int height) { 330 void WebMediaPlayerAndroid::OnVideoSizeChanged(int width, int height) {
449 if (natural_size_.width == width && natural_size_.height == height) 331 if (natural_size_.width == width && natural_size_.height == height)
450 return; 332 return;
451 333
452 natural_size_.width = width; 334 natural_size_.width = width;
453 natural_size_.height = height; 335 natural_size_.height = height;
454 if (texture_id_) { 336 if (texture_id_) {
455 video_frame_.reset(new WebVideoFrameImpl(VideoFrame::WrapNativeTexture( 337 video_frame_.reset(new WebVideoFrameImpl(VideoFrame::WrapNativeTexture(
456 texture_id_, kGLTextureExternalOES, natural_size_, natural_size_, 338 texture_id_, kGLTextureExternalOES, natural_size_, natural_size_,
457 base::TimeDelta(), 339 base::TimeDelta(),
458 base::Closure()))); 340 base::Closure())));
459 } 341 }
460 } 342 }
461 343
462 void WebMediaPlayerAndroid::UpdateNetworkState( 344 void WebMediaPlayerAndroid::UpdateNetworkState(
463 WebMediaPlayer::NetworkState state) { 345 WebMediaPlayer::NetworkState state) {
464 network_state_ = state; 346 network_state_ = state;
465 client_->networkStateChanged(); 347 client_->networkStateChanged();
466 } 348 }
467 349
468 void WebMediaPlayerAndroid::UpdateReadyState( 350 void WebMediaPlayerAndroid::UpdateReadyState(
469 WebMediaPlayer::ReadyState state) { 351 WebMediaPlayer::ReadyState state) {
470 ready_state_ = state; 352 ready_state_ = state;
471 client_->readyStateChanged(); 353 client_->readyStateChanged();
472 } 354 }
473 355
356 void WebMediaPlayerAndroid::OnPlayerReleased() {
357 needs_establish_peer_ = true;
358 }
359
474 void WebMediaPlayerAndroid::ReleaseMediaResources() { 360 void WebMediaPlayerAndroid::ReleaseMediaResources() {
475 // Pause the media player first. 361 // Pause the media player first.
476 pause(); 362 pause();
477 client_->playbackStateChanged(); 363 client_->playbackStateChanged();
478 364
479 if (media_player_.get()) { 365 ReleaseResourcesInternal();
480 // Save the current media player status. 366 OnPlayerReleased();
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 } 367 }
544 368
545 void WebMediaPlayerAndroid::WillDestroyCurrentMessageLoop() { 369 void WebMediaPlayerAndroid::WillDestroyCurrentMessageLoop() {
370 Destroy();
371
372 if (stream_id_) {
373 stream_texture_factory_->DestroyStreamTexture(texture_id_);
374 stream_id_ = 0;
375 }
376
377 video_frame_.reset(new WebVideoFrameImpl(VideoFrame::CreateEmptyFrame()));
378
379 if (manager_)
380 manager_->UnregisterMediaPlayer(player_id_);
381
546 manager_ = NULL; 382 manager_ = NULL;
547 main_loop_ = NULL; 383 main_loop_ = NULL;
548 } 384 }
549 385
550 WebVideoFrame* WebMediaPlayerAndroid::getCurrentFrame() { 386 WebVideoFrame* WebMediaPlayerAndroid::getCurrentFrame() {
551 if (!stream_texture_proxy_->IsInitialized() && stream_id_) { 387 if (stream_texture_proxy_.get() && !stream_texture_proxy_->IsInitialized()
388 && stream_id_) {
552 stream_texture_proxy_->Initialize( 389 stream_texture_proxy_->Initialize(
553 stream_id_, video_frame_->width(), video_frame_->height()); 390 stream_id_, video_frame_->width(), video_frame_->height());
554 } 391 }
555 392
556 return video_frame_.get(); 393 return video_frame_.get();
557 } 394 }
558 395
559 void WebMediaPlayerAndroid::putCurrentFrame( 396 void WebMediaPlayerAndroid::putCurrentFrame(
560 WebVideoFrame* web_video_frame) { 397 WebVideoFrame* web_video_frame) {
561 } 398 }
562 399
563 // This gets called both on compositor and main thread.
564 void WebMediaPlayerAndroid::setStreamTextureClient( 400 void WebMediaPlayerAndroid::setStreamTextureClient(
565 WebKit::WebStreamTextureClient* client) { 401 WebKit::WebStreamTextureClient* client) {
566 if (stream_texture_proxy_.get()) 402 if (stream_texture_proxy_.get())
567 stream_texture_proxy_->SetClient(client); 403 stream_texture_proxy_->SetClient(client);
568 } 404 }
569 405
406 void WebMediaPlayerAndroid::EstablishSurfaceTexturePeer() {
407 if (stream_texture_factory_.get() && stream_id_)
408 stream_texture_factory_->EstablishPeer(stream_id_, player_id_);
409 needs_establish_peer_ = false;
410 }
411
412 void WebMediaPlayerAndroid::UpdatePlayingState(bool is_playing) {
413 is_playing_ = is_playing;
414 }
415
570 } // namespace webkit_media 416 } // namespace webkit_media
OLDNEW
« no previous file with comments | « webkit/media/android/webmediaplayer_android.h ('k') | webkit/media/android/webmediaplayer_impl_android.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698