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 did_loading_progress_(false), | 74 did_loading_progress_(false), |
64 cookie_jar_(cookie_jar), | 75 cookie_jar_(cookie_jar), |
| 76 manager_(manager), |
65 pending_play_event_(false), | 77 pending_play_event_(false), |
66 network_state_(WebMediaPlayer::NetworkStateEmpty), | 78 network_state_(WebMediaPlayer::NetworkStateEmpty), |
67 ready_state_(WebMediaPlayer::ReadyStateHaveNothing) { | 79 ready_state_(WebMediaPlayer::ReadyStateHaveNothing), |
68 video_frame_.reset(new WebVideoFrameImpl(VideoFrame::CreateEmptyFrame())); | 80 texture_id_(0), |
| 81 stream_id_(0), |
| 82 needs_establish_peer_(true), |
| 83 stream_texture_factory_(factory) { |
| 84 player_id_ = manager_->RegisterMediaPlayer(this); |
| 85 if (stream_texture_factory_.get()) |
| 86 stream_texture_proxy_.reset(stream_texture_factory_->CreateProxy()); |
69 } | 87 } |
70 | 88 |
71 WebMediaPlayerAndroid::~WebMediaPlayerAndroid() { | 89 WebMediaPlayerAndroid::~WebMediaPlayerAndroid() { |
72 if (media_player_.get()) { | 90 if (media_player_.get()) { |
73 media_player_->Stop(); | 91 media_player_->Stop(); |
74 } | 92 } |
| 93 |
| 94 manager_->UnregisterMediaPlayer(player_id_); |
75 } | 95 } |
76 | 96 |
77 void WebMediaPlayerAndroid::InitIncognito(bool incognito_mode) { | 97 void WebMediaPlayerAndroid::InitIncognito(bool incognito_mode) { |
78 incognito_mode_ = incognito_mode; | 98 incognito_mode_ = incognito_mode; |
79 } | 99 } |
80 | 100 |
81 void WebMediaPlayerAndroid::load(const WebURL& url) { | 101 void WebMediaPlayerAndroid::load(const WebURL& url) { |
82 url_ = url; | 102 url_ = url; |
83 | 103 |
84 UpdateNetworkState(WebMediaPlayer::NetworkStateLoading); | 104 UpdateNetworkState(WebMediaPlayer::NetworkStateLoading); |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 network_state_ = state; | 450 network_state_ = state; |
431 client_->networkStateChanged(); | 451 client_->networkStateChanged(); |
432 } | 452 } |
433 | 453 |
434 void WebMediaPlayerAndroid::UpdateReadyState( | 454 void WebMediaPlayerAndroid::UpdateReadyState( |
435 WebMediaPlayer::ReadyState state) { | 455 WebMediaPlayer::ReadyState state) { |
436 ready_state_ = state; | 456 ready_state_ = state; |
437 client_->readyStateChanged(); | 457 client_->readyStateChanged(); |
438 } | 458 } |
439 | 459 |
440 void WebMediaPlayerAndroid::SetVideoSurface(jobject j_surface) { | 460 void WebMediaPlayerAndroid::ReleaseMediaResources() { |
441 if (media_player_.get()) | 461 // Pause the media player first. |
442 media_player_->SetVideoSurface(j_surface); | 462 pause(); |
| 463 client_->playbackStateChanged(); |
| 464 |
| 465 if (media_player_.get()) { |
| 466 // Save the current media player status. |
| 467 pending_seek_ = currentTime(); |
| 468 duration_ = duration(); |
| 469 |
| 470 media_player_.reset(); |
| 471 needs_establish_peer_ = true; |
| 472 } |
| 473 prepared_ = false; |
443 } | 474 } |
444 | 475 |
445 void WebMediaPlayerAndroid::InitializeMediaPlayer() { | 476 void WebMediaPlayerAndroid::InitializeMediaPlayer() { |
446 CHECK(!media_player_.get()); | 477 CHECK(!media_player_.get()); |
447 prepared_ = false; | 478 prepared_ = false; |
448 media_player_.reset(new MediaPlayerBridge()); | 479 media_player_.reset(new MediaPlayerBridge()); |
449 media_player_->SetStayAwakeWhilePlaying(); | 480 media_player_->SetStayAwakeWhilePlaying(); |
450 | 481 |
451 std::string cookies; | 482 std::string cookies; |
452 if (cookie_jar_ != NULL) { | 483 if (cookie_jar_ != NULL) { |
453 WebURL url(url_); | 484 WebURL first_party_url(frame_->document().firstPartyForCookies()); |
454 cookies = UTF16ToUTF8(cookie_jar_->cookies(url, url)); | 485 cookies = UTF16ToUTF8(cookie_jar_->cookies(url_, first_party_url)); |
455 } | 486 } |
456 media_player_->SetDataSource(url_.spec(), cookies, incognito_mode_); | 487 media_player_->SetDataSource(url_.spec(), cookies, incognito_mode_); |
457 | 488 |
458 media_player_->Prepare( | 489 media_player_->Prepare( |
459 base::Bind(&WebMediaPlayerProxyAndroid::MediaInfoCallback, proxy_), | 490 base::Bind(&WebMediaPlayerProxyAndroid::MediaInfoCallback, proxy_), |
460 base::Bind(&WebMediaPlayerProxyAndroid::MediaErrorCallback, proxy_), | 491 base::Bind(&WebMediaPlayerProxyAndroid::MediaErrorCallback, proxy_), |
461 base::Bind(&WebMediaPlayerProxyAndroid::VideoSizeChangedCallback, proxy_), | 492 base::Bind(&WebMediaPlayerProxyAndroid::VideoSizeChangedCallback, proxy_), |
462 base::Bind(&WebMediaPlayerProxyAndroid::BufferingUpdateCallback, proxy_), | 493 base::Bind(&WebMediaPlayerProxyAndroid::BufferingUpdateCallback, proxy_), |
463 base::Bind(&WebMediaPlayerProxyAndroid::MediaPreparedCallback, proxy_)); | 494 base::Bind(&WebMediaPlayerProxyAndroid::MediaPreparedCallback, proxy_)); |
464 } | 495 } |
465 | 496 |
466 void WebMediaPlayerAndroid::PlayInternal() { | 497 void WebMediaPlayerAndroid::PlayInternal() { |
467 CHECK(prepared_); | 498 CHECK(prepared_); |
468 | 499 |
| 500 if (hasVideo() && stream_texture_factory_.get()) { |
| 501 if (!stream_id_) |
| 502 CreateStreamTexture(); |
| 503 |
| 504 if (needs_establish_peer_) { |
| 505 stream_texture_factory_->EstablishPeer(stream_id_, player_id_); |
| 506 needs_establish_peer_ = false; |
| 507 } |
| 508 } |
| 509 |
469 if (paused()) | 510 if (paused()) |
470 media_player_->Start(base::Bind( | 511 media_player_->Start(base::Bind( |
471 &WebMediaPlayerProxyAndroid::PlaybackCompleteCallback, proxy_)); | 512 &WebMediaPlayerProxyAndroid::PlaybackCompleteCallback, proxy_)); |
472 } | 513 } |
473 | 514 |
474 void WebMediaPlayerAndroid::PauseInternal() { | 515 void WebMediaPlayerAndroid::PauseInternal() { |
475 CHECK(prepared_); | 516 CHECK(prepared_); |
476 media_player_->Pause(); | 517 media_player_->Pause(); |
477 } | 518 } |
478 | 519 |
479 void WebMediaPlayerAndroid::SeekInternal(float seconds) { | 520 void WebMediaPlayerAndroid::SeekInternal(float seconds) { |
480 CHECK(prepared_); | 521 CHECK(prepared_); |
481 seeking_ = true; | 522 seeking_ = true; |
482 media_player_->SeekTo(ConvertSecondsToTimestamp(seconds), base::Bind( | 523 media_player_->SeekTo(ConvertSecondsToTimestamp(seconds), base::Bind( |
483 &WebMediaPlayerProxyAndroid::SeekCompleteCallback, proxy_)); | 524 &WebMediaPlayerProxyAndroid::SeekCompleteCallback, proxy_)); |
484 } | 525 } |
485 | 526 |
| 527 void WebMediaPlayerAndroid::CreateStreamTexture() { |
| 528 DCHECK(!stream_id_); |
| 529 DCHECK(!texture_id_); |
| 530 stream_id_ = stream_texture_factory_->CreateStreamTexture(&texture_id_); |
| 531 if (texture_id_) |
| 532 video_frame_.reset(new WebVideoFrameImpl(VideoFrame::WrapNativeTexture( |
| 533 texture_id_, |
| 534 kGLTextureExternalOES, |
| 535 texture_size_.width, |
| 536 texture_size_.height, |
| 537 base::TimeDelta(), |
| 538 base::TimeDelta(), |
| 539 base::Bind(&WebMediaPlayerAndroid::DestroyStreamTexture, |
| 540 base::Unretained(this))))); |
| 541 } |
| 542 |
| 543 void WebMediaPlayerAndroid::DestroyStreamTexture() { |
| 544 DCHECK(stream_id_); |
| 545 DCHECK(texture_id_); |
| 546 stream_texture_factory_->DestroyStreamTexture(texture_id_); |
| 547 texture_id_ = 0; |
| 548 stream_id_ = 0; |
| 549 } |
| 550 |
486 WebVideoFrame* WebMediaPlayerAndroid::getCurrentFrame() { | 551 WebVideoFrame* WebMediaPlayerAndroid::getCurrentFrame() { |
| 552 if (!stream_texture_proxy_->IsInitialized() && stream_id_) { |
| 553 stream_texture_proxy_->Initialize( |
| 554 stream_id_, video_frame_->width(), video_frame_->height()); |
| 555 } |
| 556 |
487 return video_frame_.get(); | 557 return video_frame_.get(); |
488 } | 558 } |
489 | 559 |
490 void WebMediaPlayerAndroid::putCurrentFrame( | 560 void WebMediaPlayerAndroid::putCurrentFrame( |
491 WebVideoFrame* web_video_frame) { | 561 WebVideoFrame* web_video_frame) { |
492 } | 562 } |
493 | 563 |
| 564 // This gets called both on compositor and main thread. |
| 565 void WebMediaPlayerAndroid::setStreamTextureClient( |
| 566 WebKit::WebStreamTextureClient* client) { |
| 567 if (stream_texture_proxy_.get()) |
| 568 stream_texture_proxy_->SetClient(client); |
| 569 } |
| 570 |
494 } // namespace webkit_media | 571 } // namespace webkit_media |
OLD | NEW |