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/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 Loading... | |
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 |
OLD | NEW |