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

Side by Side Diff: webkit/media/android/webmediaplayer_android.cc

Issue 10413015: Upstream implementation for embedded video for WebMediaPlayerAndroid (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: addressing feedbacks Created 8 years, 7 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> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/file_path.h" 11 #include "base/file_path.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/utf_string_conversions.h" 13 #include "base/utf_string_conversions.h"
14 #include "media/base/android/media_player_bridge.h" 14 #include "media/base/android/media_player_bridge.h"
15 #include "net/base/mime_util.h" 15 #include "net/base/mime_util.h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerClient. h" 16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerClient. h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" 17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCookieJar .h" 18 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCookieJar .h"
19 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h" 19 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h"
20 #include "webkit/media/android/stream_texture_factory_android.h"
21 #include "webkit/media/android/webmediaplayer_manager_android.h"
20 #include "webkit/media/android/webmediaplayer_proxy_android.h" 22 #include "webkit/media/android/webmediaplayer_proxy_android.h"
21 #include "webkit/media/webmediaplayer_util.h" 23 #include "webkit/media/webmediaplayer_util.h"
22 #include "webkit/media/webvideoframe_impl.h" 24 #include "webkit/media/webvideoframe_impl.h"
23 25
24 using WebKit::WebCanvas; 26 using WebKit::WebCanvas;
25 using WebKit::WebMediaPlayerClient; 27 using WebKit::WebMediaPlayerClient;
26 using WebKit::WebMediaPlayer; 28 using WebKit::WebMediaPlayer;
27 using WebKit::WebRect; 29 using WebKit::WebRect;
28 using WebKit::WebSize; 30 using WebKit::WebSize;
29 using WebKit::WebTimeRanges; 31 using WebKit::WebTimeRanges;
30 using WebKit::WebURL; 32 using WebKit::WebURL;
31 using WebKit::WebVideoFrame; 33 using WebKit::WebVideoFrame;
32 using media::MediaPlayerBridge; 34 using media::MediaPlayerBridge;
33 using media::VideoFrame; 35 using media::VideoFrame;
34 using webkit_media::WebVideoFrameImpl; 36 using webkit_media::WebVideoFrameImpl;
35 37
38 // TODO(qinmin): Figure out where we should define this more appropriately
39 #define GL_TEXTURE_EXTERNAL_OES 0x8D65
40
36 namespace webkit_media { 41 namespace webkit_media {
37 42
38 // Because we create the media player lazily on android, the duration of the 43 // Because we create the media player lazily on android, the duration of the
39 // media is initially unknown to us. This makes the user unable to perform 44 // media is initially unknown to us. This makes the user unable to perform
40 // seek. To solve this problem, we use a temporary duration of 100 seconds when 45 // seek. To solve this problem, we use a temporary duration of 100 seconds when
41 // the duration is unknown. And we scale the seek position later when duration 46 // the duration is unknown. And we scale the seek position later when duration
42 // is available. 47 // is available.
43 // TODO(qinmin): create a thread and use android MediaMetadataRetriever 48 // TODO(qinmin): create a thread and use android MediaMetadataRetriever
44 // class to extract the duration. 49 // class to extract the duration.
45 static const float kTemporaryDuration = 100.0f; 50 static const float kTemporaryDuration = 100.0f;
46 51
47 bool WebMediaPlayerAndroid::incognito_mode_ = false; 52 bool WebMediaPlayerAndroid::incognito_mode_ = false;
48 53
49 WebMediaPlayerAndroid::WebMediaPlayerAndroid( 54 WebMediaPlayerAndroid::WebMediaPlayerAndroid(
50 WebMediaPlayerClient* client, 55 WebMediaPlayerClient* client,
51 WebKit::WebCookieJar* cookie_jar) 56 WebKit::WebCookieJar* cookie_jar,
57 webkit_media::WebMediaPlayerManagerAndroid* manager,
58 webkit_media::StreamTextureFactory* factory)
52 : client_(client), 59 : client_(client),
53 buffered_(1u), 60 buffered_(1u),
54 video_frame_(new WebVideoFrameImpl(VideoFrame::CreateEmptyFrame())), 61 video_frame_(new WebVideoFrameImpl(VideoFrame::CreateEmptyFrame())),
55 proxy_(new WebMediaPlayerProxyAndroid(base::MessageLoopProxy::current(), 62 proxy_(new WebMediaPlayerProxyAndroid(base::MessageLoopProxy::current(),
56 AsWeakPtr())), 63 AsWeakPtr())),
57 prepared_(false), 64 prepared_(false),
58 duration_(0), 65 duration_(0),
59 pending_seek_(0), 66 pending_seek_(0),
60 seeking_(false), 67 seeking_(false),
61 playback_completed_(false), 68 playback_completed_(false),
62 buffered_bytes_(0), 69 buffered_bytes_(0),
63 cookie_jar_(cookie_jar), 70 cookie_jar_(cookie_jar),
71 manager_(manager),
64 pending_play_event_(false), 72 pending_play_event_(false),
65 network_state_(WebMediaPlayer::NetworkStateEmpty), 73 network_state_(WebMediaPlayer::NetworkStateEmpty),
66 ready_state_(WebMediaPlayer::ReadyStateHaveNothing) { 74 ready_state_(WebMediaPlayer::ReadyStateHaveNothing),
67 video_frame_.reset(new WebVideoFrameImpl(VideoFrame::CreateEmptyFrame())); 75 texture_id_(0),
76 stream_id_(0),
77 needs_establish_peer_(true),
78 stream_texture_proxy_initialized_(false),
79 stream_texture_factory_(factory) {
80 player_id_ = manager_->RegisterMediaPlayer(this);
81 if (stream_texture_factory_.get())
scherkus (not reviewing) 2012/05/24 21:36:32 so right now this is NULL but what about after you
qinmin 2012/05/25 01:04:21 Yes, eventually when StreamTextureProxy implementa
82 stream_texture_proxy_.reset(stream_texture_factory_->CreateProxy());
68 } 83 }
69 84
70 WebMediaPlayerAndroid::~WebMediaPlayerAndroid() { 85 WebMediaPlayerAndroid::~WebMediaPlayerAndroid() {
71 if (media_player_.get()) { 86 if (media_player_.get()) {
72 media_player_->Stop(); 87 media_player_->Stop();
88 media_player_->SetVideoSurface(0);
scherkus (not reviewing) 2012/05/24 21:36:32 should this also be NULL? OOC do these methods ne
qinmin 2012/05/25 01:04:21 Changed to NULL. If we don't call it, the surface
73 } 89 }
90
91 manager_->UnRegisterMediaPlayer(player_id_);
74 } 92 }
75 93
76 void WebMediaPlayerAndroid::InitIncognito(bool incognito_mode) { 94 void WebMediaPlayerAndroid::InitIncognito(bool incognito_mode) {
77 incognito_mode_ = incognito_mode; 95 incognito_mode_ = incognito_mode;
78 } 96 }
79 97
80 void WebMediaPlayerAndroid::load(const WebURL& url) { 98 void WebMediaPlayerAndroid::load(const WebURL& url) {
81 url_ = url; 99 url_ = url;
82 100
83 UpdateNetworkState(WebMediaPlayer::NetworkStateLoading); 101 UpdateNetworkState(WebMediaPlayer::NetworkStateLoading);
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 network_state_ = state; 440 network_state_ = state;
423 client_->networkStateChanged(); 441 client_->networkStateChanged();
424 } 442 }
425 443
426 void WebMediaPlayerAndroid::UpdateReadyState( 444 void WebMediaPlayerAndroid::UpdateReadyState(
427 WebMediaPlayer::ReadyState state) { 445 WebMediaPlayer::ReadyState state) {
428 ready_state_ = state; 446 ready_state_ = state;
429 client_->readyStateChanged(); 447 client_->readyStateChanged();
430 } 448 }
431 449
450 void WebMediaPlayerAndroid::ReleaseMediaResources() {
451 // Pause the media player first.
452 pause();
453 client_->playbackStateChanged();
454
455 if (media_player_.get()) {
456 // Save the current media player status.
457 pending_seek_ = currentTime();
458 duration_ = duration();
459
460 // Disconnecting the Surface from the producer side allows
461 // all buffers but the one current (to the client) to be freed.
462 // We intentionally keep the current texture so we have something
463 // to show in the video layer.
464 // At the same time we happily avoid recreating the SurfaceTexture to
scherkus (not reviewing) 2012/05/24 21:36:32 s/SurfaceTexture/Surface
qinmin 2012/05/25 01:04:21 Done.
465 // not have to deal with rewiring any proxies receiving notifications.
466 media_player_->SetVideoSurface(NULL);
scherkus (not reviewing) 2012/05/24 21:36:32 we delete the media player on the next line -- wha
qinmin 2012/05/25 01:04:21 Just as the reason above, deleting media_player_ w
467 media_player_.reset(NULL);
scherkus (not reviewing) 2012/05/24 21:36:32 nit: s/reset(NULL)/reset()/
qinmin 2012/05/25 01:04:21 Done.
468 needs_establish_peer_ = true;
scherkus (not reviewing) 2012/05/24 21:36:32 requiring a peer seems roughly correlated with hav
qinmin 2012/05/25 01:04:21 need_establish_peer_ does not always correlate to
469 }
470 prepared_ = false;
471 }
472
432 void WebMediaPlayerAndroid::SetVideoSurface(jobject j_surface) { 473 void WebMediaPlayerAndroid::SetVideoSurface(jobject j_surface) {
433 if (media_player_.get()) 474 if (media_player_.get())
434 media_player_->SetVideoSurface(j_surface); 475 media_player_->SetVideoSurface(j_surface);
435 } 476 }
436 477
437 void WebMediaPlayerAndroid::InitializeMediaPlayer() { 478 void WebMediaPlayerAndroid::InitializeMediaPlayer() {
438 CHECK(!media_player_.get()); 479 CHECK(!media_player_.get());
439 prepared_ = false; 480 prepared_ = false;
440 media_player_.reset(new MediaPlayerBridge()); 481 media_player_.reset(new MediaPlayerBridge());
441 media_player_->SetStayAwakeWhilePlaying(); 482 media_player_->SetStayAwakeWhilePlaying();
442 483
443 std::string cookies; 484 std::string cookies;
444 if (cookie_jar_ != NULL) { 485 if (cookie_jar_ != NULL) {
445 WebURL url(url_); 486 WebURL url(url_);
446 cookies = UTF16ToUTF8(cookie_jar_->cookies(url, url)); 487 cookies = UTF16ToUTF8(cookie_jar_->cookies(url, url));
447 } 488 }
448 media_player_->SetDataSource(url_.spec(), cookies, incognito_mode_); 489 media_player_->SetDataSource(url_.spec(), cookies, incognito_mode_);
449 490
450 media_player_->Prepare( 491 media_player_->Prepare(
451 base::Bind(&WebMediaPlayerProxyAndroid::MediaInfoCallback, proxy_), 492 base::Bind(&WebMediaPlayerProxyAndroid::MediaInfoCallback, proxy_),
452 base::Bind(&WebMediaPlayerProxyAndroid::MediaErrorCallback, proxy_), 493 base::Bind(&WebMediaPlayerProxyAndroid::MediaErrorCallback, proxy_),
453 base::Bind(&WebMediaPlayerProxyAndroid::VideoSizeChangedCallback, proxy_), 494 base::Bind(&WebMediaPlayerProxyAndroid::VideoSizeChangedCallback, proxy_),
454 base::Bind(&WebMediaPlayerProxyAndroid::BufferingUpdateCallback, proxy_), 495 base::Bind(&WebMediaPlayerProxyAndroid::BufferingUpdateCallback, proxy_),
455 base::Bind(&WebMediaPlayerProxyAndroid::MediaPreparedCallback, proxy_)); 496 base::Bind(&WebMediaPlayerProxyAndroid::MediaPreparedCallback, proxy_));
456 } 497 }
457 498
458 void WebMediaPlayerAndroid::PlayInternal() { 499 void WebMediaPlayerAndroid::PlayInternal() {
459 CHECK(prepared_); 500 CHECK(prepared_);
460 501
502 if (hasVideo() && stream_texture_factory_.get()) {
503 if (!stream_id_)
504 CreateStreamTexture();
505
506 if (needs_establish_peer_) {
507 stream_texture_factory_->EstablishPeer(stream_id_, player_id_);
508 needs_establish_peer_ = false;
509 }
510 }
511
461 if (paused()) 512 if (paused())
462 media_player_->Start(base::Bind( 513 media_player_->Start(base::Bind(
463 &WebMediaPlayerProxyAndroid::PlaybackCompleteCallback, proxy_)); 514 &WebMediaPlayerProxyAndroid::PlaybackCompleteCallback, proxy_));
464 } 515 }
465 516
466 void WebMediaPlayerAndroid::PauseInternal() { 517 void WebMediaPlayerAndroid::PauseInternal() {
467 CHECK(prepared_); 518 CHECK(prepared_);
468 media_player_->Pause(); 519 media_player_->Pause();
469 } 520 }
470 521
471 void WebMediaPlayerAndroid::SeekInternal(float seconds) { 522 void WebMediaPlayerAndroid::SeekInternal(float seconds) {
472 CHECK(prepared_); 523 CHECK(prepared_);
473 seeking_ = true; 524 seeking_ = true;
474 media_player_->SeekTo(ConvertSecondsToTimestamp(seconds), base::Bind( 525 media_player_->SeekTo(ConvertSecondsToTimestamp(seconds), base::Bind(
475 &WebMediaPlayerProxyAndroid::SeekCompleteCallback, proxy_)); 526 &WebMediaPlayerProxyAndroid::SeekCompleteCallback, proxy_));
476 } 527 }
477 528
529 void WebMediaPlayerAndroid::CreateStreamTexture() {
530 DCHECK(!stream_id_);
531 DCHECK(!texture_id_);
532 stream_id_ = stream_texture_factory_->CreateStreamTexture(&texture_id_);
scherkus (not reviewing) 2012/05/24 21:36:32 isn't this NULL right now? is CreateStreamTexture
qinmin 2012/05/25 01:04:21 This function will not get called if stream_textur
533 if (texture_id_)
534 video_frame_.reset(new WebVideoFrameImpl(VideoFrame::WrapNativeTexture(
535 texture_id_,
536 GL_TEXTURE_EXTERNAL_OES,
537 texture_size_.width,
538 texture_size_.height,
539 base::TimeDelta(),
540 base::TimeDelta(),
541 base::Bind(&WebMediaPlayerAndroid::DestroyStreamTexture,
542 base::Unretained(this)))));
543 }
544
545 void WebMediaPlayerAndroid::DestroyStreamTexture() {
546 DCHECK(stream_id_);
547 DCHECK(texture_id_);
548 stream_texture_factory_->DestroyStreamTexture(texture_id_);
549 texture_id_ = 0;
550 stream_id_ = 0;
551 }
552
478 WebVideoFrame* WebMediaPlayerAndroid::getCurrentFrame() { 553 WebVideoFrame* WebMediaPlayerAndroid::getCurrentFrame() {
554 if (!stream_texture_proxy_initialized_ && stream_id_) {
scherkus (not reviewing) 2012/05/24 21:36:32 would stream_texture_proxy_initialized_ be better
qinmin 2012/05/25 01:04:21 Done.
555 stream_texture_proxy_->Initialize(
556 stream_id_, video_frame_->width(), video_frame_->height());
557 stream_texture_proxy_initialized_ = true;
558 }
559
479 return video_frame_.get(); 560 return video_frame_.get();
480 } 561 }
481 562
482 void WebMediaPlayerAndroid::putCurrentFrame( 563 void WebMediaPlayerAndroid::putCurrentFrame(
483 WebVideoFrame* web_video_frame) { 564 WebVideoFrame* web_video_frame) {
484 } 565 }
485 566
567 // This gets called both on impl and main thread.
scherkus (not reviewing) 2012/05/24 21:36:32 s/impl/compositor
scherkus (not reviewing) 2012/05/24 21:36:32 who is calling it on the main thread and for what
qinmin 2012/05/25 01:04:21 Done.
qinmin 2012/05/25 01:04:21 It is called in WebMediaPlayerClientImpl::~WebMedi
568 void WebMediaPlayerAndroid::setStreamTextureClient(
569 WebKit::WebStreamTextureClient* client) {
570 if (stream_texture_proxy_.get())
571 stream_texture_proxy_->SetClient(client);
572 }
573
486 } // namespace webkit_media 574 } // namespace webkit_media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698