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

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_factory_(factory) {
79 player_id_ = manager_->RegisterMediaPlayer(this);
80 if (stream_texture_factory_.get())
81 stream_texture_proxy_.reset(stream_texture_factory_->CreateProxy());
68 } 82 }
69 83
70 WebMediaPlayerAndroid::~WebMediaPlayerAndroid() { 84 WebMediaPlayerAndroid::~WebMediaPlayerAndroid() {
71 if (media_player_.get()) { 85 if (media_player_.get()) {
72 media_player_->Stop(); 86 media_player_->Stop();
87 media_player_->SetVideoSurface(NULL);
73 } 88 }
89
90 manager_->UnregisterMediaPlayer(player_id_);
74 } 91 }
75 92
76 void WebMediaPlayerAndroid::InitIncognito(bool incognito_mode) { 93 void WebMediaPlayerAndroid::InitIncognito(bool incognito_mode) {
77 incognito_mode_ = incognito_mode; 94 incognito_mode_ = incognito_mode;
78 } 95 }
79 96
80 void WebMediaPlayerAndroid::load(const WebURL& url) { 97 void WebMediaPlayerAndroid::load(const WebURL& url) {
81 url_ = url; 98 url_ = url;
82 99
83 UpdateNetworkState(WebMediaPlayer::NetworkStateLoading); 100 UpdateNetworkState(WebMediaPlayer::NetworkStateLoading);
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 network_state_ = state; 439 network_state_ = state;
423 client_->networkStateChanged(); 440 client_->networkStateChanged();
424 } 441 }
425 442
426 void WebMediaPlayerAndroid::UpdateReadyState( 443 void WebMediaPlayerAndroid::UpdateReadyState(
427 WebMediaPlayer::ReadyState state) { 444 WebMediaPlayer::ReadyState state) {
428 ready_state_ = state; 445 ready_state_ = state;
429 client_->readyStateChanged(); 446 client_->readyStateChanged();
430 } 447 }
431 448
449 void WebMediaPlayerAndroid::ReleaseMediaResources() {
450 // Pause the media player first.
451 pause();
452 client_->playbackStateChanged();
453
454 if (media_player_.get()) {
455 // Save the current media player status.
456 pending_seek_ = currentTime();
457 duration_ = duration();
458
459 // Disconnecting the Surface from the producer side allows
460 // all buffers but the one current (to the client) to be freed.
461 // We intentionally keep the current texture so we have something
462 // to show in the video layer.
463 // At the same time we happily avoid recreating the Surface to
464 // not have to deal with rewiring any proxies receiving notifications.
465 media_player_->SetVideoSurface(NULL);
466 media_player_.reset();
467 needs_establish_peer_ = true;
468 }
469 prepared_ = false;
470 }
471
432 void WebMediaPlayerAndroid::SetVideoSurface(jobject j_surface) { 472 void WebMediaPlayerAndroid::SetVideoSurface(jobject j_surface) {
433 if (media_player_.get()) 473 if (media_player_.get())
434 media_player_->SetVideoSurface(j_surface); 474 media_player_->SetVideoSurface(j_surface);
435 } 475 }
436 476
437 void WebMediaPlayerAndroid::InitializeMediaPlayer() { 477 void WebMediaPlayerAndroid::InitializeMediaPlayer() {
438 CHECK(!media_player_.get()); 478 CHECK(!media_player_.get());
439 prepared_ = false; 479 prepared_ = false;
440 media_player_.reset(new MediaPlayerBridge()); 480 media_player_.reset(new MediaPlayerBridge());
scherkus (not reviewing) 2012/05/25 22:01:46 if a media_player_ existed... would we want to cal
qinmin 2012/05/26 00:37:42 Moved SetVideoSurface(NULL) to MediaPlayerBridge d
441 media_player_->SetStayAwakeWhilePlaying(); 481 media_player_->SetStayAwakeWhilePlaying();
442 482
443 std::string cookies; 483 std::string cookies;
444 if (cookie_jar_ != NULL) { 484 if (cookie_jar_ != NULL) {
445 WebURL url(url_); 485 WebURL url(url_);
446 cookies = UTF16ToUTF8(cookie_jar_->cookies(url, url)); 486 cookies = UTF16ToUTF8(cookie_jar_->cookies(url, url));
447 } 487 }
448 media_player_->SetDataSource(url_.spec(), cookies, incognito_mode_); 488 media_player_->SetDataSource(url_.spec(), cookies, incognito_mode_);
449 489
450 media_player_->Prepare( 490 media_player_->Prepare(
451 base::Bind(&WebMediaPlayerProxyAndroid::MediaInfoCallback, proxy_), 491 base::Bind(&WebMediaPlayerProxyAndroid::MediaInfoCallback, proxy_),
452 base::Bind(&WebMediaPlayerProxyAndroid::MediaErrorCallback, proxy_), 492 base::Bind(&WebMediaPlayerProxyAndroid::MediaErrorCallback, proxy_),
453 base::Bind(&WebMediaPlayerProxyAndroid::VideoSizeChangedCallback, proxy_), 493 base::Bind(&WebMediaPlayerProxyAndroid::VideoSizeChangedCallback, proxy_),
454 base::Bind(&WebMediaPlayerProxyAndroid::BufferingUpdateCallback, proxy_), 494 base::Bind(&WebMediaPlayerProxyAndroid::BufferingUpdateCallback, proxy_),
455 base::Bind(&WebMediaPlayerProxyAndroid::MediaPreparedCallback, proxy_)); 495 base::Bind(&WebMediaPlayerProxyAndroid::MediaPreparedCallback, proxy_));
456 } 496 }
457 497
458 void WebMediaPlayerAndroid::PlayInternal() { 498 void WebMediaPlayerAndroid::PlayInternal() {
459 CHECK(prepared_); 499 CHECK(prepared_);
460 500
501 if (hasVideo() && stream_texture_factory_.get()) {
502 if (!stream_id_)
503 CreateStreamTexture();
504
505 if (needs_establish_peer_) {
506 stream_texture_factory_->EstablishPeer(stream_id_, player_id_);
507 needs_establish_peer_ = false;
508 }
509 }
510
461 if (paused()) 511 if (paused())
462 media_player_->Start(base::Bind( 512 media_player_->Start(base::Bind(
463 &WebMediaPlayerProxyAndroid::PlaybackCompleteCallback, proxy_)); 513 &WebMediaPlayerProxyAndroid::PlaybackCompleteCallback, proxy_));
464 } 514 }
465 515
466 void WebMediaPlayerAndroid::PauseInternal() { 516 void WebMediaPlayerAndroid::PauseInternal() {
467 CHECK(prepared_); 517 CHECK(prepared_);
468 media_player_->Pause(); 518 media_player_->Pause();
469 } 519 }
470 520
471 void WebMediaPlayerAndroid::SeekInternal(float seconds) { 521 void WebMediaPlayerAndroid::SeekInternal(float seconds) {
472 CHECK(prepared_); 522 CHECK(prepared_);
473 seeking_ = true; 523 seeking_ = true;
474 media_player_->SeekTo(ConvertSecondsToTimestamp(seconds), base::Bind( 524 media_player_->SeekTo(ConvertSecondsToTimestamp(seconds), base::Bind(
475 &WebMediaPlayerProxyAndroid::SeekCompleteCallback, proxy_)); 525 &WebMediaPlayerProxyAndroid::SeekCompleteCallback, proxy_));
476 } 526 }
477 527
528 void WebMediaPlayerAndroid::CreateStreamTexture() {
529 DCHECK(!stream_id_);
530 DCHECK(!texture_id_);
531 stream_id_ = stream_texture_factory_->CreateStreamTexture(&texture_id_);
532 if (texture_id_)
533 video_frame_.reset(new WebVideoFrameImpl(VideoFrame::WrapNativeTexture(
534 texture_id_,
535 GL_TEXTURE_EXTERNAL_OES,
536 texture_size_.width,
537 texture_size_.height,
538 base::TimeDelta(),
539 base::TimeDelta(),
540 base::Bind(&WebMediaPlayerAndroid::DestroyStreamTexture,
541 base::Unretained(this)))));
542 }
543
544 void WebMediaPlayerAndroid::DestroyStreamTexture() {
545 DCHECK(stream_id_);
546 DCHECK(texture_id_);
547 stream_texture_factory_->DestroyStreamTexture(texture_id_);
548 texture_id_ = 0;
549 stream_id_ = 0;
550 }
551
478 WebVideoFrame* WebMediaPlayerAndroid::getCurrentFrame() { 552 WebVideoFrame* WebMediaPlayerAndroid::getCurrentFrame() {
553 if (!stream_texture_proxy_->IsInitialized() && stream_id_) {
554 stream_texture_proxy_->Initialize(
555 stream_id_, video_frame_->width(), video_frame_->height());
556 }
557
479 return video_frame_.get(); 558 return video_frame_.get();
480 } 559 }
481 560
482 void WebMediaPlayerAndroid::putCurrentFrame( 561 void WebMediaPlayerAndroid::putCurrentFrame(
483 WebVideoFrame* web_video_frame) { 562 WebVideoFrame* web_video_frame) {
484 } 563 }
485 564
565 // This gets called both on compositor and main thread.
566 void WebMediaPlayerAndroid::setStreamTextureClient(
567 WebKit::WebStreamTextureClient* client) {
568 if (stream_texture_proxy_.get())
569 stream_texture_proxy_->SetClient(client);
570 }
571
486 } // namespace webkit_media 572 } // namespace webkit_media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698