Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/WebDocument.h" | |
| 17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | |
| 16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerClient. h" | 18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerClient. h" |
| 17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" | 19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" |
| 18 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCookieJar .h" | 20 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCookieJar .h" |
| 19 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h" | 21 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h" |
| 22 #include "webkit/media/android/stream_texture_factory_android.h" | |
| 23 #include "webkit/media/android/webmediaplayer_manager_android.h" | |
| 20 #include "webkit/media/android/webmediaplayer_proxy_android.h" | 24 #include "webkit/media/android/webmediaplayer_proxy_android.h" |
| 21 #include "webkit/media/webmediaplayer_util.h" | 25 #include "webkit/media/webmediaplayer_util.h" |
| 22 #include "webkit/media/webvideoframe_impl.h" | 26 #include "webkit/media/webvideoframe_impl.h" |
| 23 | 27 |
| 24 using WebKit::WebCanvas; | 28 using WebKit::WebCanvas; |
| 25 using WebKit::WebMediaPlayerClient; | 29 using WebKit::WebMediaPlayerClient; |
| 26 using WebKit::WebMediaPlayer; | 30 using WebKit::WebMediaPlayer; |
| 27 using WebKit::WebRect; | 31 using WebKit::WebRect; |
| 28 using WebKit::WebSize; | 32 using WebKit::WebSize; |
| 29 using WebKit::WebTimeRanges; | 33 using WebKit::WebTimeRanges; |
| 30 using WebKit::WebURL; | 34 using WebKit::WebURL; |
| 31 using WebKit::WebVideoFrame; | 35 using WebKit::WebVideoFrame; |
| 32 using media::MediaPlayerBridge; | 36 using media::MediaPlayerBridge; |
| 33 using media::VideoFrame; | 37 using media::VideoFrame; |
| 34 using webkit_media::WebVideoFrameImpl; | 38 using webkit_media::WebVideoFrameImpl; |
| 35 | 39 |
| 40 // TODO(qinmin): Figure out where we should define this more appropriately | |
| 41 static const uint32 kGLTextureExternalOES = 0x8D65; | |
| 42 | |
| 36 namespace webkit_media { | 43 namespace webkit_media { |
| 37 | 44 |
| 38 // Because we create the media player lazily on android, the duration of the | 45 // 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 | 46 // 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 | 47 // 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 | 48 // the duration is unknown. And we scale the seek position later when duration |
| 42 // is available. | 49 // is available. |
| 43 // TODO(qinmin): create a thread and use android MediaMetadataRetriever | 50 // TODO(qinmin): create a thread and use android MediaMetadataRetriever |
| 44 // class to extract the duration. | 51 // class to extract the duration. |
| 45 static const float kTemporaryDuration = 100.0f; | 52 static const float kTemporaryDuration = 100.0f; |
| 46 | 53 |
| 47 bool WebMediaPlayerAndroid::incognito_mode_ = false; | 54 bool WebMediaPlayerAndroid::incognito_mode_ = false; |
| 48 | 55 |
| 49 WebMediaPlayerAndroid::WebMediaPlayerAndroid( | 56 WebMediaPlayerAndroid::WebMediaPlayerAndroid( |
| 57 WebKit::WebFrame* frame, | |
| 50 WebMediaPlayerClient* client, | 58 WebMediaPlayerClient* client, |
| 51 WebKit::WebCookieJar* cookie_jar) | 59 WebKit::WebCookieJar* cookie_jar, |
| 52 : client_(client), | 60 webkit_media::WebMediaPlayerManagerAndroid* manager, |
| 61 webkit_media::StreamTextureFactory* factory) | |
| 62 : frame_(frame), | |
| 63 client_(client), | |
| 53 buffered_(1u), | 64 buffered_(1u), |
| 54 video_frame_(new WebVideoFrameImpl(VideoFrame::CreateEmptyFrame())), | 65 video_frame_(new WebVideoFrameImpl(VideoFrame::CreateEmptyFrame())), |
| 55 proxy_(new WebMediaPlayerProxyAndroid(base::MessageLoopProxy::current(), | 66 proxy_(new WebMediaPlayerProxyAndroid(base::MessageLoopProxy::current(), |
| 56 AsWeakPtr())), | 67 AsWeakPtr())), |
| 57 prepared_(false), | 68 prepared_(false), |
| 58 duration_(0), | 69 duration_(0), |
| 59 pending_seek_(0), | 70 pending_seek_(0), |
| 60 seeking_(false), | 71 seeking_(false), |
| 61 playback_completed_(false), | 72 playback_completed_(false), |
| 62 buffered_bytes_(0), | 73 buffered_bytes_(0), |
| 63 cookie_jar_(cookie_jar), | 74 cookie_jar_(cookie_jar), |
| 75 manager_(manager), | |
| 64 pending_play_event_(false), | 76 pending_play_event_(false), |
| 65 network_state_(WebMediaPlayer::NetworkStateEmpty), | 77 network_state_(WebMediaPlayer::NetworkStateEmpty), |
| 66 ready_state_(WebMediaPlayer::ReadyStateHaveNothing) { | 78 ready_state_(WebMediaPlayer::ReadyStateHaveNothing), |
| 67 video_frame_.reset(new WebVideoFrameImpl(VideoFrame::CreateEmptyFrame())); | 79 texture_id_(0), |
| 80 stream_id_(0), | |
| 81 needs_establish_peer_(true), | |
| 82 stream_texture_factory_(factory) { | |
| 83 player_id_ = manager_->RegisterMediaPlayer(this); | |
| 84 if (stream_texture_factory_.get()) | |
| 85 stream_texture_proxy_.reset(stream_texture_factory_->CreateProxy()); | |
| 68 } | 86 } |
| 69 | 87 |
| 70 WebMediaPlayerAndroid::~WebMediaPlayerAndroid() { | 88 WebMediaPlayerAndroid::~WebMediaPlayerAndroid() { |
| 71 if (media_player_.get()) { | 89 if (media_player_.get()) { |
| 72 media_player_->Stop(); | 90 media_player_->Stop(); |
| 73 } | 91 } |
| 92 | |
| 93 manager_->UnregisterMediaPlayer(player_id_); | |
| 74 } | 94 } |
| 75 | 95 |
| 76 void WebMediaPlayerAndroid::InitIncognito(bool incognito_mode) { | 96 void WebMediaPlayerAndroid::InitIncognito(bool incognito_mode) { |
| 77 incognito_mode_ = incognito_mode; | 97 incognito_mode_ = incognito_mode; |
| 78 } | 98 } |
| 79 | 99 |
| 80 void WebMediaPlayerAndroid::load(const WebURL& url) { | 100 void WebMediaPlayerAndroid::load(const WebURL& url) { |
| 81 url_ = url; | 101 url_ = url; |
| 82 | 102 |
| 83 UpdateNetworkState(WebMediaPlayer::NetworkStateLoading); | 103 UpdateNetworkState(WebMediaPlayer::NetworkStateLoading); |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 422 network_state_ = state; | 442 network_state_ = state; |
| 423 client_->networkStateChanged(); | 443 client_->networkStateChanged(); |
| 424 } | 444 } |
| 425 | 445 |
| 426 void WebMediaPlayerAndroid::UpdateReadyState( | 446 void WebMediaPlayerAndroid::UpdateReadyState( |
| 427 WebMediaPlayer::ReadyState state) { | 447 WebMediaPlayer::ReadyState state) { |
| 428 ready_state_ = state; | 448 ready_state_ = state; |
| 429 client_->readyStateChanged(); | 449 client_->readyStateChanged(); |
| 430 } | 450 } |
| 431 | 451 |
| 432 void WebMediaPlayerAndroid::SetVideoSurface(jobject j_surface) { | 452 void WebMediaPlayerAndroid::ReleaseMediaResources() { |
| 433 if (media_player_.get()) | 453 // Pause the media player first. |
| 434 media_player_->SetVideoSurface(j_surface); | 454 pause(); |
| 455 client_->playbackStateChanged(); | |
| 456 | |
| 457 if (media_player_.get()) { | |
| 458 // Save the current media player status. | |
| 459 pending_seek_ = currentTime(); | |
| 460 duration_ = duration(); | |
| 461 | |
| 462 media_player_.reset(); | |
| 463 needs_establish_peer_ = true; | |
| 464 } | |
| 465 prepared_ = false; | |
| 435 } | 466 } |
| 436 | 467 |
| 437 void WebMediaPlayerAndroid::InitializeMediaPlayer() { | 468 void WebMediaPlayerAndroid::InitializeMediaPlayer() { |
| 438 CHECK(!media_player_.get()); | 469 CHECK(!media_player_.get()); |
| 439 prepared_ = false; | 470 prepared_ = false; |
| 440 media_player_.reset(new MediaPlayerBridge()); | 471 media_player_.reset(new MediaPlayerBridge()); |
| 441 media_player_->SetStayAwakeWhilePlaying(); | 472 media_player_->SetStayAwakeWhilePlaying(); |
| 442 | 473 |
| 443 std::string cookies; | 474 std::string cookies; |
| 444 if (cookie_jar_ != NULL) { | 475 if (cookie_jar_ != NULL) { |
| 445 WebURL url(url_); | 476 WebURL url(frame_->document().firstPartyForCookies()); |
|
jochen (gone - plz use gerrit)
2012/05/30 08:41:37
I'd name this "first_party_url", and then
qinmin
2012/05/30 17:06:51
Done.
| |
| 446 cookies = UTF16ToUTF8(cookie_jar_->cookies(url, url)); | 477 cookies = UTF16ToUTF8(cookie_jar_->cookies(url, url)); |
|
jochen (gone - plz use gerrit)
2012/05/30 08:41:37
it should be cookies(url_, first_party_url)
qinmin
2012/05/30 17:06:51
Done.
| |
| 447 } | 478 } |
| 448 media_player_->SetDataSource(url_.spec(), cookies, incognito_mode_); | 479 media_player_->SetDataSource(url_.spec(), cookies, incognito_mode_); |
| 449 | 480 |
| 450 media_player_->Prepare( | 481 media_player_->Prepare( |
| 451 base::Bind(&WebMediaPlayerProxyAndroid::MediaInfoCallback, proxy_), | 482 base::Bind(&WebMediaPlayerProxyAndroid::MediaInfoCallback, proxy_), |
| 452 base::Bind(&WebMediaPlayerProxyAndroid::MediaErrorCallback, proxy_), | 483 base::Bind(&WebMediaPlayerProxyAndroid::MediaErrorCallback, proxy_), |
| 453 base::Bind(&WebMediaPlayerProxyAndroid::VideoSizeChangedCallback, proxy_), | 484 base::Bind(&WebMediaPlayerProxyAndroid::VideoSizeChangedCallback, proxy_), |
| 454 base::Bind(&WebMediaPlayerProxyAndroid::BufferingUpdateCallback, proxy_), | 485 base::Bind(&WebMediaPlayerProxyAndroid::BufferingUpdateCallback, proxy_), |
| 455 base::Bind(&WebMediaPlayerProxyAndroid::MediaPreparedCallback, proxy_)); | 486 base::Bind(&WebMediaPlayerProxyAndroid::MediaPreparedCallback, proxy_)); |
| 456 } | 487 } |
| 457 | 488 |
| 458 void WebMediaPlayerAndroid::PlayInternal() { | 489 void WebMediaPlayerAndroid::PlayInternal() { |
| 459 CHECK(prepared_); | 490 CHECK(prepared_); |
| 460 | 491 |
| 492 if (hasVideo() && stream_texture_factory_.get()) { | |
| 493 if (!stream_id_) | |
| 494 CreateStreamTexture(); | |
| 495 | |
| 496 if (needs_establish_peer_) { | |
| 497 stream_texture_factory_->EstablishPeer(stream_id_, player_id_); | |
| 498 needs_establish_peer_ = false; | |
| 499 } | |
| 500 } | |
| 501 | |
| 461 if (paused()) | 502 if (paused()) |
| 462 media_player_->Start(base::Bind( | 503 media_player_->Start(base::Bind( |
| 463 &WebMediaPlayerProxyAndroid::PlaybackCompleteCallback, proxy_)); | 504 &WebMediaPlayerProxyAndroid::PlaybackCompleteCallback, proxy_)); |
| 464 } | 505 } |
| 465 | 506 |
| 466 void WebMediaPlayerAndroid::PauseInternal() { | 507 void WebMediaPlayerAndroid::PauseInternal() { |
| 467 CHECK(prepared_); | 508 CHECK(prepared_); |
| 468 media_player_->Pause(); | 509 media_player_->Pause(); |
| 469 } | 510 } |
| 470 | 511 |
| 471 void WebMediaPlayerAndroid::SeekInternal(float seconds) { | 512 void WebMediaPlayerAndroid::SeekInternal(float seconds) { |
| 472 CHECK(prepared_); | 513 CHECK(prepared_); |
| 473 seeking_ = true; | 514 seeking_ = true; |
| 474 media_player_->SeekTo(ConvertSecondsToTimestamp(seconds), base::Bind( | 515 media_player_->SeekTo(ConvertSecondsToTimestamp(seconds), base::Bind( |
| 475 &WebMediaPlayerProxyAndroid::SeekCompleteCallback, proxy_)); | 516 &WebMediaPlayerProxyAndroid::SeekCompleteCallback, proxy_)); |
| 476 } | 517 } |
| 477 | 518 |
| 519 void WebMediaPlayerAndroid::CreateStreamTexture() { | |
| 520 DCHECK(!stream_id_); | |
| 521 DCHECK(!texture_id_); | |
| 522 stream_id_ = stream_texture_factory_->CreateStreamTexture(&texture_id_); | |
| 523 if (texture_id_) | |
| 524 video_frame_.reset(new WebVideoFrameImpl(VideoFrame::WrapNativeTexture( | |
| 525 texture_id_, | |
| 526 kGLTextureExternalOES, | |
| 527 texture_size_.width, | |
| 528 texture_size_.height, | |
| 529 base::TimeDelta(), | |
| 530 base::TimeDelta(), | |
| 531 base::Bind(&WebMediaPlayerAndroid::DestroyStreamTexture, | |
| 532 base::Unretained(this))))); | |
| 533 } | |
| 534 | |
| 535 void WebMediaPlayerAndroid::DestroyStreamTexture() { | |
| 536 DCHECK(stream_id_); | |
| 537 DCHECK(texture_id_); | |
| 538 stream_texture_factory_->DestroyStreamTexture(texture_id_); | |
| 539 texture_id_ = 0; | |
| 540 stream_id_ = 0; | |
| 541 } | |
| 542 | |
| 478 WebVideoFrame* WebMediaPlayerAndroid::getCurrentFrame() { | 543 WebVideoFrame* WebMediaPlayerAndroid::getCurrentFrame() { |
| 544 if (!stream_texture_proxy_->IsInitialized() && stream_id_) { | |
| 545 stream_texture_proxy_->Initialize( | |
| 546 stream_id_, video_frame_->width(), video_frame_->height()); | |
| 547 } | |
| 548 | |
| 479 return video_frame_.get(); | 549 return video_frame_.get(); |
| 480 } | 550 } |
| 481 | 551 |
| 482 void WebMediaPlayerAndroid::putCurrentFrame( | 552 void WebMediaPlayerAndroid::putCurrentFrame( |
| 483 WebVideoFrame* web_video_frame) { | 553 WebVideoFrame* web_video_frame) { |
| 484 } | 554 } |
| 485 | 555 |
| 556 // This gets called both on compositor and main thread. | |
| 557 void WebMediaPlayerAndroid::setStreamTextureClient( | |
| 558 WebKit::WebStreamTextureClient* client) { | |
| 559 if (stream_texture_proxy_.get()) | |
| 560 stream_texture_proxy_->SetClient(client); | |
| 561 } | |
| 562 | |
| 486 } // namespace webkit_media | 563 } // namespace webkit_media |
| OLD | NEW |