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

Unified Diff: webkit/renderer/media/android/webmediaplayer_android.cc

Issue 17502007: Move webkit/renderer/media/android/ to content/renderer/media/android/. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix shared lib Created 7 years, 6 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 side-by-side diff with in-line comments
Download patch
Index: webkit/renderer/media/android/webmediaplayer_android.cc
diff --git a/webkit/renderer/media/android/webmediaplayer_android.cc b/webkit/renderer/media/android/webmediaplayer_android.cc
deleted file mode 100644
index 31e9fa4be69a0c7b81bd18fca0bf998afa197741..0000000000000000000000000000000000000000
--- a/webkit/renderer/media/android/webmediaplayer_android.cc
+++ /dev/null
@@ -1,1113 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "webkit/renderer/media/android/webmediaplayer_android.h"
-
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/files/file_path.h"
-#include "base/logging.h"
-#include "base/metrics/histogram.h"
-#include "base/strings/string_number_conversions.h"
-#include "cc/layers/video_layer.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "media/base/android/media_player_android.h"
-#include "media/base/bind_to_loop.h"
-#include "media/base/media_switches.h"
-#include "media/base/video_frame.h"
-#include "net/base/mime_util.h"
-#include "third_party/WebKit/public/platform/WebString.h"
-#include "third_party/WebKit/public/web/WebDocument.h"
-#include "third_party/WebKit/public/web/WebFrame.h"
-#include "third_party/WebKit/public/web/WebMediaPlayerClient.h"
-#include "third_party/WebKit/public/web/WebMediaSource.h"
-#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
-#include "third_party/WebKit/public/web/WebView.h"
-#include "webkit/renderer/compositor_bindings/web_layer_impl.h"
-#include "webkit/renderer/media/android/webmediaplayer_manager_android.h"
-#include "webkit/renderer/media/android/webmediaplayer_proxy_android.h"
-#include "webkit/renderer/media/crypto/key_systems.h"
-#include "webkit/renderer/media/webmediaplayer_delegate.h"
-#include "webkit/renderer/media/webmediaplayer_util.h"
-
-#if defined(GOOGLE_TV)
-#include "webkit/renderer/media/media_stream_audio_renderer.h"
-#include "webkit/renderer/media/media_stream_client.h"
-#endif
-
-static const uint32 kGLTextureExternalOES = 0x8D65;
-
-using WebKit::WebMediaPlayer;
-using WebKit::WebMediaSource;
-using WebKit::WebSize;
-using WebKit::WebString;
-using WebKit::WebTimeRanges;
-using WebKit::WebURL;
-using media::MediaPlayerAndroid;
-using media::VideoFrame;
-
-namespace {
-// Prefix for histograms related to Encrypted Media Extensions.
-const char* kMediaEme = "Media.EME.";
-} // namespace
-
-namespace webkit_media {
-
-#define BIND_TO_RENDER_LOOP(function) \
- media::BindToLoop(main_loop_, base::Bind(function, AsWeakPtr()))
-
-WebMediaPlayerAndroid::WebMediaPlayerAndroid(
- WebKit::WebFrame* frame,
- WebKit::WebMediaPlayerClient* client,
- base::WeakPtr<WebMediaPlayerDelegate> delegate,
- WebMediaPlayerManagerAndroid* manager,
- WebMediaPlayerProxyAndroid* proxy,
- StreamTextureFactory* factory,
- media::MediaLog* media_log)
- : frame_(frame),
- client_(client),
- delegate_(delegate),
- buffered_(1u),
- main_loop_(base::MessageLoopProxy::current()),
- ignore_metadata_duration_change_(false),
- pending_seek_(0),
- seeking_(false),
- did_loading_progress_(false),
- manager_(manager),
- network_state_(WebMediaPlayer::NetworkStateEmpty),
- ready_state_(WebMediaPlayer::ReadyStateHaveNothing),
- is_playing_(false),
- needs_establish_peer_(true),
- stream_texture_proxy_initialized_(false),
- has_size_info_(false),
- has_media_metadata_(false),
- has_media_info_(false),
- stream_texture_factory_(factory),
- needs_external_surface_(false),
- video_frame_provider_client_(NULL),
-#if defined(GOOGLE_TV)
- demuxer_(NULL),
-#endif // defined(GOOGLE_TV)
- source_type_(MediaPlayerAndroid::SOURCE_TYPE_URL),
- proxy_(proxy),
- current_time_(0),
- media_log_(media_log),
- media_stream_client_(NULL) {
- DCHECK(proxy_);
- DCHECK(manager_);
-
- // We want to be notified of |main_loop_| destruction.
- base::MessageLoop::current()->AddDestructionObserver(this);
-
- player_id_ = manager_->RegisterMediaPlayer(this);
-
- if (stream_texture_factory_) {
- stream_texture_proxy_.reset(stream_texture_factory_->CreateProxy());
- stream_id_ = stream_texture_factory_->CreateStreamTexture(&texture_id_);
- ReallocateVideoFrame();
- }
-
- if (WebKit::WebRuntimeFeatures::isLegacyEncryptedMediaEnabled()) {
- // |decryptor_| is owned, so Unretained() is safe here.
- decryptor_.reset(new ProxyDecryptor(
-#if defined(ENABLE_PEPPER_CDMS)
- client,
- frame,
-#endif // defined(ENABLE_PEPPER_CDMS)
-#if defined(OS_ANDROID) && !defined(GOOGLE_TV)
- proxy_,
- player_id_, // TODO(xhwang): Use media_keys_id when MediaKeys are
- // separated from WebMediaPlayer.
-#endif // defined(OS_ANDROID) && !defined(GOOGLE_TV)
- base::Bind(&WebMediaPlayerAndroid::OnKeyAdded, base::Unretained(this)),
- base::Bind(&WebMediaPlayerAndroid::OnKeyError, base::Unretained(this)),
- base::Bind(&WebMediaPlayerAndroid::OnKeyMessage,
- base::Unretained(this))));
- }
-}
-
-WebMediaPlayerAndroid::~WebMediaPlayerAndroid() {
- SetVideoFrameProviderClient(NULL);
- client_->setWebLayer(NULL);
-
- if (proxy_)
- proxy_->DestroyPlayer(player_id_);
-
- if (stream_id_)
- stream_texture_factory_->DestroyStreamTexture(texture_id_);
-
- if (manager_)
- manager_->UnregisterMediaPlayer(player_id_);
-
- if (base::MessageLoop::current())
- base::MessageLoop::current()->RemoveDestructionObserver(this);
-
- if (source_type_ == MediaPlayerAndroid::SOURCE_TYPE_MSE && delegate_)
- delegate_->PlayerGone(this);
-
-#if defined(GOOGLE_TV)
- if (audio_renderer_) {
- if (audio_renderer_->IsLocalRenderer()) {
- audio_renderer_->Stop();
- } else if (!paused()) {
- // The |audio_renderer_| can be shared by multiple remote streams, and
- // it will be stopped when WebRtcAudioDeviceImpl goes away. So we simply
- // pause the |audio_renderer_| here to avoid re-creating the
- // |audio_renderer_|.
- audio_renderer_->Pause();
- }
- }
- if (demuxer_ && !destroy_demuxer_cb_.is_null()) {
- media_source_delegate_.reset();
- destroy_demuxer_cb_.Run();
- }
-#endif
-}
-
-void WebMediaPlayerAndroid::load(const WebURL& url, CORSMode cors_mode) {
- load(url, NULL, cors_mode);
-}
-
-void WebMediaPlayerAndroid::load(const WebURL& url,
- WebMediaSource* media_source,
- CORSMode cors_mode) {
- source_type_ = MediaPlayerAndroid::SOURCE_TYPE_URL;
- has_media_metadata_ = false;
- has_media_info_ = false;
-
- if (media_source)
- source_type_ = MediaPlayerAndroid::SOURCE_TYPE_MSE;
-#if defined(GOOGLE_TV)
- if (media_stream_client_) {
- DCHECK(!media_source);
- source_type_ = MediaPlayerAndroid::SOURCE_TYPE_STREAM;
- }
-#endif
-
- if (source_type_ != MediaPlayerAndroid::SOURCE_TYPE_URL) {
- has_media_info_ = true;
- media_source_delegate_.reset(
- new MediaSourceDelegate(proxy_, player_id_, media_log_));
- // |media_source_delegate_| is owned, so Unretained() is safe here.
- if (source_type_ == MediaPlayerAndroid::SOURCE_TYPE_MSE) {
- media_source_delegate_->InitializeMediaSource(
- media_source,
- base::Bind(&WebMediaPlayerAndroid::OnNeedKey, base::Unretained(this)),
- base::Bind(&WebMediaPlayerAndroid::UpdateNetworkState,
- base::Unretained(this)),
- BIND_TO_RENDER_LOOP(&WebMediaPlayerAndroid::OnDurationChange));
- }
-#if defined(GOOGLE_TV)
- if (source_type_ == MediaPlayerAndroid::SOURCE_TYPE_STREAM) {
- media_source_delegate_->InitializeMediaStream(
- demuxer_,
- base::Bind(&WebMediaPlayerAndroid::UpdateNetworkState,
- base::Unretained(this)));
- audio_renderer_ = media_stream_client_->GetAudioRenderer(url);
- if (audio_renderer_)
- audio_renderer_->Start();
- }
-#endif
- } else {
- info_loader_.reset(
- new MediaInfoLoader(
- url,
- cors_mode,
- base::Bind(&WebMediaPlayerAndroid::DidLoadMediaInfo,
- base::Unretained(this))));
- info_loader_->Start(frame_);
- }
-
- InitializeMediaPlayer(url);
-}
-
-void WebMediaPlayerAndroid::InitializeMediaPlayer(const WebURL& url) {
- url_ = url;
- GURL first_party_url = frame_->document().firstPartyForCookies();
- proxy_->Initialize(player_id_, url, source_type_, first_party_url);
- if (manager_->IsInFullscreen(frame_))
- proxy_->EnterFullscreen(player_id_);
-
- UpdateNetworkState(WebMediaPlayer::NetworkStateLoading);
- UpdateReadyState(WebMediaPlayer::ReadyStateHaveNothing);
-}
-
-void WebMediaPlayerAndroid::DidLoadMediaInfo(
- MediaInfoLoader::Status status) {
- DCHECK(!media_source_delegate_);
- if (status == MediaInfoLoader::kFailed) {
- info_loader_.reset();
- UpdateNetworkState(WebMediaPlayer::NetworkStateNetworkError);
- return;
- }
-
- has_media_info_ = true;
- if (has_media_metadata_ &&
- ready_state_ != WebMediaPlayer::ReadyStateHaveEnoughData) {
- UpdateReadyState(WebMediaPlayer::ReadyStateHaveMetadata);
- UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
- }
-}
-
-void WebMediaPlayerAndroid::play() {
-#if defined(GOOGLE_TV)
- if (hasVideo() && needs_external_surface_) {
- DCHECK(!needs_establish_peer_);
- proxy_->RequestExternalSurface(player_id_, last_computed_rect_);
- }
- if (audio_renderer_ && paused())
- audio_renderer_->Play();
-#endif
- if (hasVideo() && needs_establish_peer_)
- EstablishSurfaceTexturePeer();
-
- if (paused())
- proxy_->Start(player_id_);
- UpdatePlayingState(true);
-}
-
-void WebMediaPlayerAndroid::pause() {
-#if defined(GOOGLE_TV)
- if (audio_renderer_ && !paused())
- audio_renderer_->Pause();
-#endif
- proxy_->Pause(player_id_);
- UpdatePlayingState(false);
-}
-
-void WebMediaPlayerAndroid::seek(double seconds) {
- pending_seek_ = seconds;
- if (seeking_ && media_source_delegate_)
- media_source_delegate_->CancelPendingSeek();
- seeking_ = true;
-
- base::TimeDelta seek_time = ConvertSecondsToTimestamp(seconds);
-#if defined(GOOGLE_TV)
- // TODO(qinmin): check if GTV can also defer the seek until the browser side
- // player is ready.
- if (media_source_delegate_)
- media_source_delegate_->Seek(seek_time);
-#endif
- proxy_->Seek(player_id_, seek_time);
-}
-
-bool WebMediaPlayerAndroid::supportsFullscreen() const {
- return true;
-}
-
-bool WebMediaPlayerAndroid::supportsSave() const {
- return false;
-}
-
-void WebMediaPlayerAndroid::setRate(double rate) {
- NOTIMPLEMENTED();
-}
-
-void WebMediaPlayerAndroid::setVolume(double volume) {
- NOTIMPLEMENTED();
-}
-
-bool WebMediaPlayerAndroid::hasVideo() const {
- // If we have obtained video size information before, use it.
- if (has_size_info_)
- return !natural_size_.isEmpty();
-
- // TODO(qinmin): need a better method to determine whether the current media
- // content contains video. Android does not provide any function to do
- // this.
- // We don't know whether the current media content has video unless
- // the player is prepared. If the player is not prepared, we fall back
- // to the mime-type. There may be no mime-type on a redirect URL.
- // In that case, we conservatively assume it contains video so that
- // enterfullscreen call will not fail.
- if (!url_.has_path())
- return false;
- std::string mime;
- if(!net::GetMimeTypeFromFile(base::FilePath(url_.path()), &mime))
- return true;
- return mime.find("audio/") == std::string::npos;
-}
-
-bool WebMediaPlayerAndroid::hasAudio() const {
- // TODO(hclam): Query status of audio and return the actual value.
- return true;
-}
-
-bool WebMediaPlayerAndroid::paused() const {
- return !is_playing_;
-}
-
-bool WebMediaPlayerAndroid::seeking() const {
- return seeking_;
-}
-
-double WebMediaPlayerAndroid::duration() const {
- // HTML5 spec requires duration to be NaN if readyState is HAVE_NOTHING
- if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing)
- return std::numeric_limits<double>::quiet_NaN();
-
- // TODO(wolenetz): Correctly handle durations that MediaSourcePlayer
- // considers unseekable, including kInfiniteDuration().
- // See http://crbug.com/248396
- return duration_.InSecondsF();
-}
-
-double WebMediaPlayerAndroid::currentTime() const {
- // If the player is pending for a seek, return the seek time.
- if (seeking())
- return pending_seek_;
- return current_time_;
-}
-
-WebSize WebMediaPlayerAndroid::naturalSize() const {
- return natural_size_;
-}
-
-WebMediaPlayer::NetworkState WebMediaPlayerAndroid::networkState() const {
- return network_state_;
-}
-
-WebMediaPlayer::ReadyState WebMediaPlayerAndroid::readyState() const {
- return ready_state_;
-}
-
-const WebTimeRanges& WebMediaPlayerAndroid::buffered() {
- if (media_source_delegate_)
- return media_source_delegate_->Buffered();
- return buffered_;
-}
-
-double WebMediaPlayerAndroid::maxTimeSeekable() const {
- // If we haven't even gotten to ReadyStateHaveMetadata yet then just
- // return 0 so that the seekable range is empty.
- if (ready_state_ < WebMediaPlayer::ReadyStateHaveMetadata)
- return 0.0;
-
- // TODO(hclam): If this stream is not seekable this should return 0.
- return duration();
-}
-
-bool WebMediaPlayerAndroid::didLoadingProgress() const {
- bool ret = did_loading_progress_;
- did_loading_progress_ = false;
- return ret;
-}
-
-void WebMediaPlayerAndroid::paint(WebKit::WebCanvas* canvas,
- const WebKit::WebRect& rect,
- unsigned char alpha) {
- NOTIMPLEMENTED();
-}
-
-bool WebMediaPlayerAndroid::copyVideoTextureToPlatformTexture(
- WebKit::WebGraphicsContext3D* web_graphics_context,
- unsigned int texture,
- unsigned int level,
- unsigned int internal_format,
- unsigned int type,
- bool premultiply_alpha,
- bool flip_y) {
- if (!texture_id_)
- return false;
-
- // The video is stored in an unmultiplied format, so premultiply if
- // necessary.
- web_graphics_context->pixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM,
- premultiply_alpha);
-
- // Application itself needs to take care of setting the right flip_y
- // value down to get the expected result.
- // flip_y==true means to reverse the video orientation while
- // flip_y==false means to keep the intrinsic orientation.
- web_graphics_context->pixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, flip_y);
- web_graphics_context->copyTextureCHROMIUM(GL_TEXTURE_2D, texture_id_,
- texture, level, internal_format,
- type);
- web_graphics_context->pixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, false);
- web_graphics_context->pixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM,
- false);
- return true;
-}
-
-bool WebMediaPlayerAndroid::hasSingleSecurityOrigin() const {
- if (info_loader_)
- return info_loader_->HasSingleOrigin();
- // The info loader may have failed.
- if (source_type_ == MediaPlayerAndroid::SOURCE_TYPE_URL)
- return false;
- return true;
-}
-
-bool WebMediaPlayerAndroid::didPassCORSAccessCheck() const {
- if (info_loader_)
- return info_loader_->DidPassCORSAccessCheck();
- return false;
-}
-
-double WebMediaPlayerAndroid::mediaTimeForTimeValue(double timeValue) const {
- return ConvertSecondsToTimestamp(timeValue).InSecondsF();
-}
-
-unsigned WebMediaPlayerAndroid::decodedFrameCount() const {
- if (media_source_delegate_)
- return media_source_delegate_->DecodedFrameCount();
- NOTIMPLEMENTED();
- return 0;
-}
-
-unsigned WebMediaPlayerAndroid::droppedFrameCount() const {
- if (media_source_delegate_)
- return media_source_delegate_->DroppedFrameCount();
- NOTIMPLEMENTED();
- return 0;
-}
-
-unsigned WebMediaPlayerAndroid::audioDecodedByteCount() const {
- if (media_source_delegate_)
- return media_source_delegate_->AudioDecodedByteCount();
- NOTIMPLEMENTED();
- return 0;
-}
-
-unsigned WebMediaPlayerAndroid::videoDecodedByteCount() const {
- if (media_source_delegate_)
- return media_source_delegate_->VideoDecodedByteCount();
- NOTIMPLEMENTED();
- return 0;
-}
-
-void WebMediaPlayerAndroid::OnMediaMetadataChanged(
- base::TimeDelta duration, int width, int height, bool success) {
- bool need_to_signal_duration_changed = false;
-
- if (url_.SchemeIs("file"))
- UpdateNetworkState(WebMediaPlayer::NetworkStateLoaded);
-
- // Update duration, if necessary, prior to ready state updates that may
- // cause duration() query.
- // TODO(wolenetz): Correctly handle durations that MediaSourcePlayer
- // considers unseekable, including kInfiniteDuration().
- // See http://crbug.com/248396
- if (!ignore_metadata_duration_change_ && duration_ != duration) {
- duration_ = duration;
-
- // Client readyState transition from HAVE_NOTHING to HAVE_METADATA
- // already triggers a durationchanged event. If this is a different
- // transition, remember to signal durationchanged.
- // Do not ever signal durationchanged on metadata change in MSE case
- // because OnDurationChange() handles this.
- if (ready_state_ > WebMediaPlayer::ReadyStateHaveNothing &&
- source_type_ != MediaPlayerAndroid::SOURCE_TYPE_MSE) {
- need_to_signal_duration_changed = true;
- }
- }
-
- has_media_metadata_ = true;
- if (has_media_info_ &&
- ready_state_ != WebMediaPlayer::ReadyStateHaveEnoughData) {
- UpdateReadyState(WebMediaPlayer::ReadyStateHaveMetadata);
- UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
- }
-
- // TODO(wolenetz): Should we just abort early and set network state to an
- // error if success == false? See http://crbug.com/248399
- if (success)
- OnVideoSizeChanged(width, height);
-
- if (hasVideo() && !video_weblayer_ && client_->needsWebLayerForVideo()) {
- video_weblayer_.reset(
- new webkit::WebLayerImpl(cc::VideoLayer::Create(this)));
- client_->setWebLayer(video_weblayer_.get());
- }
-
- if (need_to_signal_duration_changed)
- client_->durationChanged();
-}
-
-void WebMediaPlayerAndroid::OnPlaybackComplete() {
- // When playback is about to finish, android media player often stops
- // at a time which is smaller than the duration. This makes webkit never
- // know that the playback has finished. To solve this, we set the
- // current time to media duration when OnPlaybackComplete() get called.
- OnTimeUpdate(duration_);
- client_->timeChanged();
-}
-
-void WebMediaPlayerAndroid::OnBufferingUpdate(int percentage) {
- buffered_[0].end = duration() * percentage / 100;
- did_loading_progress_ = true;
-}
-
-void WebMediaPlayerAndroid::OnSeekComplete(base::TimeDelta current_time) {
- seeking_ = false;
-
- OnTimeUpdate(current_time);
-
- UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
-
- client_->timeChanged();
-}
-
-void WebMediaPlayerAndroid::OnMediaError(int error_type) {
- switch (error_type) {
- case MediaPlayerAndroid::MEDIA_ERROR_FORMAT:
- UpdateNetworkState(WebMediaPlayer::NetworkStateFormatError);
- break;
- case MediaPlayerAndroid::MEDIA_ERROR_DECODE:
- UpdateNetworkState(WebMediaPlayer::NetworkStateDecodeError);
- break;
- case MediaPlayerAndroid::MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
- UpdateNetworkState(WebMediaPlayer::NetworkStateFormatError);
- break;
- case MediaPlayerAndroid::MEDIA_ERROR_INVALID_CODE:
- break;
- }
- client_->repaint();
-}
-
-void WebMediaPlayerAndroid::OnVideoSizeChanged(int width, int height) {
- has_size_info_ = true;
- if (natural_size_.width == width && natural_size_.height == height)
- return;
-
-#if defined(GOOGLE_TV)
- static bool has_switch = CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kUseExternalVideoSurfaceThresholdInPixels);
- static int threshold = 0;
- static bool parsed_arg =
- has_switch &&
- base::StringToInt(
- CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
- switches::kUseExternalVideoSurfaceThresholdInPixels),
- &threshold);
-
- if ((parsed_arg && threshold <= width * height) ||
- // Use H/W surface for MSE as the content is protected.
- media_source_delegate_) {
- if (stream_texture_factory_) {
- stream_texture_factory_->DestroyStreamTexture(texture_id_);
- stream_id_ = 0;
- texture_id_ = 0;
- }
- needs_external_surface_ = true;
- SetNeedsEstablishPeer(false);
- if (!paused())
- proxy_->RequestExternalSurface(player_id_, last_computed_rect_);
- }
-#endif
-
- natural_size_.width = width;
- natural_size_.height = height;
- ReallocateVideoFrame();
-}
-
-void WebMediaPlayerAndroid::OnTimeUpdate(base::TimeDelta current_time) {
- current_time_ = current_time.InSecondsF();
-}
-
-void WebMediaPlayerAndroid::OnDidEnterFullscreen() {
- if (!manager_->IsInFullscreen(frame_)) {
- frame_->view()->willEnterFullScreen();
- frame_->view()->didEnterFullScreen();
- manager_->DidEnterFullscreen(frame_);
- }
-}
-
-void WebMediaPlayerAndroid::OnDidExitFullscreen() {
- // |needs_external_surface_| is always false on non-TV devices.
- if (!needs_external_surface_)
- SetNeedsEstablishPeer(true);
- // We had the fullscreen surface connected to Android MediaPlayer,
- // so reconnect our surface texture for embedded playback.
- if (!paused())
- EstablishSurfaceTexturePeer();
-
- frame_->view()->willExitFullScreen();
- frame_->view()->didExitFullScreen();
- manager_->DidExitFullscreen();
- client_->repaint();
-}
-
-void WebMediaPlayerAndroid::OnMediaPlayerPlay() {
- UpdatePlayingState(true);
- client_->playbackStateChanged();
-}
-
-void WebMediaPlayerAndroid::OnMediaPlayerPause() {
- UpdatePlayingState(false);
- client_->playbackStateChanged();
-}
-
-void WebMediaPlayerAndroid::OnMediaSeekRequest(base::TimeDelta time_to_seek) {
- if (!media_source_delegate_)
- return;
-
- if (!seeking_)
- media_source_delegate_->CancelPendingSeek();
- media_source_delegate_->Seek(time_to_seek);
- OnTimeUpdate(time_to_seek);
-}
-
-void WebMediaPlayerAndroid::OnMediaConfigRequest() {
- if (!media_source_delegate_)
- return;
-
- media_source_delegate_->OnMediaConfigRequest();
-}
-
-void WebMediaPlayerAndroid::OnDurationChange(const base::TimeDelta& duration) {
- // Only MSE |source_type_| registers this callback.
- DCHECK(source_type_ == MediaPlayerAndroid::SOURCE_TYPE_MSE);
-
- // Cache the new duration value and trust it over any subsequent duration
- // values received in OnMediaMetadataChanged().
- // TODO(wolenetz): Correctly handle durations that MediaSourcePlayer
- // considers unseekable, including kInfiniteDuration().
- // See http://crbug.com/248396
- duration_ = duration;
- ignore_metadata_duration_change_ = true;
-
- // Send message to Android MediaSourcePlayer to update duration.
- if (proxy_)
- proxy_->DurationChanged(player_id_, duration_);
-
- // Notify MediaPlayerClient that duration has changed, if > HAVE_NOTHING.
- if (ready_state_ > WebMediaPlayer::ReadyStateHaveNothing)
- client_->durationChanged();
-}
-
-void WebMediaPlayerAndroid::UpdateNetworkState(
- WebMediaPlayer::NetworkState state) {
- if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing &&
- (state == WebMediaPlayer::NetworkStateNetworkError ||
- state == WebMediaPlayer::NetworkStateDecodeError)) {
- // Any error that occurs before reaching ReadyStateHaveMetadata should
- // be considered a format error.
- network_state_ = WebMediaPlayer::NetworkStateFormatError;
- } else {
- network_state_ = state;
- }
- client_->networkStateChanged();
-}
-
-void WebMediaPlayerAndroid::UpdateReadyState(
- WebMediaPlayer::ReadyState state) {
- ready_state_ = state;
- client_->readyStateChanged();
-}
-
-void WebMediaPlayerAndroid::OnPlayerReleased() {
- // |needs_external_surface_| is always false on non-TV devices.
- if (!needs_external_surface_)
- needs_establish_peer_ = true;
-}
-
-void WebMediaPlayerAndroid::ReleaseMediaResources() {
- switch (network_state_) {
- // Pause the media player and inform WebKit if the player is in a good
- // shape.
- case WebMediaPlayer::NetworkStateIdle:
- case WebMediaPlayer::NetworkStateLoading:
- case WebMediaPlayer::NetworkStateLoaded:
- pause();
- client_->playbackStateChanged();
- break;
- // If a WebMediaPlayer instance has entered into one of these states,
- // the internal network state in HTMLMediaElement could be set to empty.
- // And calling playbackStateChanged() could get this object deleted.
- case WebMediaPlayer::NetworkStateEmpty:
- case WebMediaPlayer::NetworkStateFormatError:
- case WebMediaPlayer::NetworkStateNetworkError:
- case WebMediaPlayer::NetworkStateDecodeError:
- break;
- }
- proxy_->ReleaseResources(player_id_);
- OnPlayerReleased();
-}
-
-void WebMediaPlayerAndroid::WillDestroyCurrentMessageLoop() {
- if (manager_)
- manager_->UnregisterMediaPlayer(player_id_);
- Detach();
-}
-
-void WebMediaPlayerAndroid::Detach() {
- if (stream_id_) {
- stream_texture_factory_->DestroyStreamTexture(texture_id_);
- stream_id_ = 0;
- }
-
- media_source_delegate_.reset();
- current_frame_ = NULL;
- manager_ = NULL;
- proxy_ = NULL;
-}
-
-void WebMediaPlayerAndroid::ReallocateVideoFrame() {
- if (needs_external_surface_) {
- // VideoFrame::CreateHoleFrame is only defined under GOOGLE_TV.
-#if defined(GOOGLE_TV)
- if (!natural_size_.isEmpty()) {
- current_frame_ = VideoFrame::CreateHoleFrame(natural_size_);
- // Force the client to grab the hole frame.
- client_->repaint();
- }
-#else
- NOTIMPLEMENTED() << "Hole punching not supported outside of Google TV";
-#endif
- } else if (texture_id_) {
- current_frame_ = VideoFrame::WrapNativeTexture(
- texture_id_, kGLTextureExternalOES, natural_size_,
- gfx::Rect(natural_size_), natural_size_, base::TimeDelta(),
- VideoFrame::ReadPixelsCB(),
- base::Closure());
- }
-}
-
-void WebMediaPlayerAndroid::SetVideoFrameProviderClient(
- cc::VideoFrameProvider::Client* client) {
- // This is called from both the main renderer thread and the compositor
- // thread (when the main thread is blocked).
- if (video_frame_provider_client_)
- video_frame_provider_client_->StopUsingProvider();
- video_frame_provider_client_ = client;
-
- // Set the callback target when a frame is produced.
- if (stream_texture_proxy_)
- stream_texture_proxy_->SetClient(client);
-}
-
-scoped_refptr<media::VideoFrame> WebMediaPlayerAndroid::GetCurrentFrame() {
- if (!stream_texture_proxy_initialized_ && stream_texture_proxy_ &&
- stream_id_ && !needs_external_surface_) {
- gfx::Size natural_size = current_frame_->natural_size();
- stream_texture_proxy_->BindToCurrentThread(
- stream_id_, natural_size.width(), natural_size.height());
- stream_texture_proxy_initialized_ = true;
- }
- return current_frame_;
-}
-
-void WebMediaPlayerAndroid::PutCurrentFrame(
- const scoped_refptr<media::VideoFrame>& frame) {
-}
-
-void WebMediaPlayerAndroid::EstablishSurfaceTexturePeer() {
- if (media_source_delegate_ && stream_texture_factory_) {
- // MediaCodec will release the old surface when it goes away, we need to
- // recreate a new one each time this is called.
- stream_texture_factory_->DestroyStreamTexture(texture_id_);
- stream_id_ = 0;
- texture_id_ = 0;
- stream_id_ = stream_texture_factory_->CreateStreamTexture(&texture_id_);
- ReallocateVideoFrame();
- stream_texture_proxy_initialized_ = false;
- }
- if (stream_texture_factory_.get() && stream_id_)
- stream_texture_factory_->EstablishPeer(stream_id_, player_id_);
- needs_establish_peer_ = false;
-}
-
-void WebMediaPlayerAndroid::SetNeedsEstablishPeer(bool needs_establish_peer) {
- needs_establish_peer_ = needs_establish_peer;
-}
-
-void WebMediaPlayerAndroid::UpdatePlayingState(bool is_playing) {
- is_playing_ = is_playing;
- if (source_type_ != MediaPlayerAndroid::SOURCE_TYPE_MSE || !delegate_)
- return;
- if (is_playing)
- delegate_->DidPlay(this);
- else
- delegate_->DidPause(this);
-}
-
-#if defined(GOOGLE_TV)
-bool WebMediaPlayerAndroid::RetrieveGeometryChange(gfx::RectF* rect) {
- if (!video_weblayer_)
- return false;
-
- // Compute the geometry of video frame layer.
- cc::Layer* layer = video_weblayer_->layer();
- rect->set_size(layer->bounds());
- while (layer) {
- rect->Offset(layer->position().OffsetFromOrigin());
- layer = layer->parent();
- }
-
- // Return false when the geometry hasn't been changed from the last time.
- if (last_computed_rect_ == *rect)
- return false;
-
- // Store the changed geometry information when it is actually changed.
- last_computed_rect_ = *rect;
- return true;
-}
-#endif
-
-// The following EME related code is copied from WebMediaPlayerImpl.
-// TODO(xhwang): Remove duplicate code between WebMediaPlayerAndroid and
-// WebMediaPlayerImpl.
-// TODO(kjyoun): Update Google TV EME implementation to use IPC.
-
-// Helper functions to report media EME related stats to UMA. They follow the
-// convention of more commonly used macros UMA_HISTOGRAM_ENUMERATION and
-// UMA_HISTOGRAM_COUNTS. The reason that we cannot use those macros directly is
-// that UMA_* macros require the names to be constant throughout the process'
-// lifetime.
-static void EmeUMAHistogramEnumeration(const std::string& key_system,
- const std::string& method,
- int sample,
- int boundary_value) {
- base::LinearHistogram::FactoryGet(
- kMediaEme + KeySystemNameForUMA(key_system) + "." + method,
- 1, boundary_value, boundary_value + 1,
- base::Histogram::kUmaTargetedHistogramFlag)->Add(sample);
-}
-
-static void EmeUMAHistogramCounts(const std::string& key_system,
- const std::string& method,
- int sample) {
- // Use the same parameters as UMA_HISTOGRAM_COUNTS.
- base::Histogram::FactoryGet(
- kMediaEme + KeySystemNameForUMA(key_system) + "." + method,
- 1, 1000000, 50, base::Histogram::kUmaTargetedHistogramFlag)->Add(sample);
-}
-
-// Helper enum for reporting generateKeyRequest/addKey histograms.
-enum MediaKeyException {
- kUnknownResultId,
- kSuccess,
- kKeySystemNotSupported,
- kInvalidPlayerState,
- kMaxMediaKeyException
-};
-
-static MediaKeyException MediaKeyExceptionForUMA(
- WebMediaPlayer::MediaKeyException e) {
- switch (e) {
- case WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported:
- return kKeySystemNotSupported;
- case WebMediaPlayer::MediaKeyExceptionInvalidPlayerState:
- return kInvalidPlayerState;
- case WebMediaPlayer::MediaKeyExceptionNoError:
- return kSuccess;
- default:
- return kUnknownResultId;
- }
-}
-
-// Helper for converting |key_system| name and exception |e| to a pair of enum
-// values from above, for reporting to UMA.
-static void ReportMediaKeyExceptionToUMA(
- const std::string& method,
- const WebString& key_system,
- WebMediaPlayer::MediaKeyException e) {
- MediaKeyException result_id = MediaKeyExceptionForUMA(e);
- DCHECK_NE(result_id, kUnknownResultId) << e;
- EmeUMAHistogramEnumeration(
- key_system.utf8(), method, result_id, kMaxMediaKeyException);
-}
-
-WebMediaPlayer::MediaKeyException WebMediaPlayerAndroid::generateKeyRequest(
- const WebString& key_system,
- const unsigned char* init_data,
- unsigned init_data_length) {
- WebMediaPlayer::MediaKeyException e =
- GenerateKeyRequestInternal(key_system, init_data, init_data_length);
- ReportMediaKeyExceptionToUMA("generateKeyRequest", key_system, e);
- return e;
-}
-
-WebMediaPlayer::MediaKeyException
-WebMediaPlayerAndroid::GenerateKeyRequestInternal(
- const WebString& key_system,
- const unsigned char* init_data,
- unsigned init_data_length) {
- DVLOG(1) << "generateKeyRequest: " << key_system.utf8().data() << ": "
- << std::string(reinterpret_cast<const char*>(init_data),
- static_cast<size_t>(init_data_length));
-
- if (!IsSupportedKeySystem(key_system))
- return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
-
- // We do not support run-time switching between key systems for now.
- if (current_key_system_.isEmpty()) {
- if (!decryptor_->InitializeCDM(key_system.utf8()))
- return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
- current_key_system_ = key_system;
- } else if (key_system != current_key_system_) {
- return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
- }
-
- // TODO(xhwang): We assume all streams are from the same container (thus have
- // the same "type") for now. In the future, the "type" should be passed down
- // from the application.
- if (!decryptor_->GenerateKeyRequest(init_data_type_,
- init_data, init_data_length)) {
- current_key_system_.reset();
- return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
- }
-
- return WebMediaPlayer::MediaKeyExceptionNoError;
-}
-
-WebMediaPlayer::MediaKeyException WebMediaPlayerAndroid::addKey(
- const WebString& key_system,
- const unsigned char* key,
- unsigned key_length,
- const unsigned char* init_data,
- unsigned init_data_length,
- const WebString& session_id) {
- WebMediaPlayer::MediaKeyException e = AddKeyInternal(
- key_system, key, key_length, init_data, init_data_length, session_id);
- ReportMediaKeyExceptionToUMA("addKey", key_system, e);
- return e;
-}
-
-WebMediaPlayer::MediaKeyException WebMediaPlayerAndroid::AddKeyInternal(
- const WebString& key_system,
- const unsigned char* key,
- unsigned key_length,
- const unsigned char* init_data,
- unsigned init_data_length,
- const WebString& session_id) {
- DCHECK(key);
- DCHECK_GT(key_length, 0u);
- DVLOG(1) << "addKey: " << key_system.utf8().data() << ": "
- << std::string(reinterpret_cast<const char*>(key),
- static_cast<size_t>(key_length)) << ", "
- << std::string(reinterpret_cast<const char*>(init_data),
- static_cast<size_t>(init_data_length))
- << " [" << session_id.utf8().data() << "]";
-
- if (!IsSupportedKeySystem(key_system))
- return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
-
- if (current_key_system_.isEmpty() || key_system != current_key_system_)
- return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
-
- decryptor_->AddKey(key, key_length, init_data, init_data_length,
- session_id.utf8());
- return WebMediaPlayer::MediaKeyExceptionNoError;
-}
-
-WebMediaPlayer::MediaKeyException WebMediaPlayerAndroid::cancelKeyRequest(
- const WebString& key_system,
- const WebString& session_id) {
- WebMediaPlayer::MediaKeyException e =
- CancelKeyRequestInternal(key_system, session_id);
- ReportMediaKeyExceptionToUMA("cancelKeyRequest", key_system, e);
- return e;
-}
-
-WebMediaPlayer::MediaKeyException
-WebMediaPlayerAndroid::CancelKeyRequestInternal(
- const WebString& key_system,
- const WebString& session_id) {
- if (!IsSupportedKeySystem(key_system))
- return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
-
- if (current_key_system_.isEmpty() || key_system != current_key_system_)
- return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
-
- decryptor_->CancelKeyRequest(session_id.utf8());
- return WebMediaPlayer::MediaKeyExceptionNoError;
-}
-
-void WebMediaPlayerAndroid::OnKeyAdded(const std::string& session_id) {
- EmeUMAHistogramCounts(current_key_system_.utf8(), "KeyAdded", 1);
-
- if (media_source_delegate_)
- media_source_delegate_->NotifyKeyAdded(current_key_system_.utf8());
-
- client_->keyAdded(current_key_system_, WebString::fromUTF8(session_id));
-}
-
-void WebMediaPlayerAndroid::OnKeyError(const std::string& session_id,
- media::MediaKeys::KeyError error_code,
- int system_code) {
- EmeUMAHistogramEnumeration(current_key_system_.utf8(), "KeyError",
- error_code, media::MediaKeys::kMaxKeyError);
-
- client_->keyError(
- current_key_system_,
- WebString::fromUTF8(session_id),
- static_cast<WebKit::WebMediaPlayerClient::MediaKeyErrorCode>(error_code),
- system_code);
-}
-
-void WebMediaPlayerAndroid::OnKeyMessage(const std::string& session_id,
- const std::string& message,
- const std::string& destination_url) {
- const GURL destination_url_gurl(destination_url);
- DLOG_IF(WARNING, !destination_url.empty() && !destination_url_gurl.is_valid())
- << "Invalid URL in destination_url: " << destination_url;
-
- client_->keyMessage(current_key_system_,
- WebString::fromUTF8(session_id),
- reinterpret_cast<const uint8*>(message.data()),
- message.size(),
- destination_url_gurl);
-}
-
-void WebMediaPlayerAndroid::OnNeedKey(const std::string& session_id,
- const std::string& type,
- scoped_ptr<uint8[]> init_data,
- int init_data_size) {
- // Do not fire NeedKey event if encrypted media is not enabled.
- if (!WebKit::WebRuntimeFeatures::isEncryptedMediaEnabled() &&
- !WebKit::WebRuntimeFeatures::isLegacyEncryptedMediaEnabled()) {
- return;
- }
-
- UMA_HISTOGRAM_COUNTS(kMediaEme + std::string("NeedKey"), 1);
-
- DCHECK(init_data_type_.empty() || type.empty() || type == init_data_type_);
- if (init_data_type_.empty())
- init_data_type_ = type;
-
- client_->keyNeeded(WebString(),
- WebString::fromUTF8(session_id),
- init_data.get(),
- init_data_size);
-}
-
-#if defined(GOOGLE_TV)
-bool WebMediaPlayerAndroid::InjectMediaStream(
- MediaStreamClient* media_stream_client,
- media::Demuxer* demuxer,
- const base::Closure& destroy_demuxer_cb) {
- DCHECK(!demuxer);
- media_stream_client_ = media_stream_client;
- demuxer_ = demuxer;
- destroy_demuxer_cb_ = destroy_demuxer_cb;
- return true;
-}
-#endif
-
-void WebMediaPlayerAndroid::OnReadFromDemuxer(
- media::DemuxerStream::Type type, bool seek_done) {
- if (media_source_delegate_)
- media_source_delegate_->OnReadFromDemuxer(type, seek_done);
- else
- NOTIMPLEMENTED();
-}
-
-void WebMediaPlayerAndroid::enterFullscreen() {
- if (manager_->CanEnterFullscreen(frame_)) {
- proxy_->EnterFullscreen(player_id_);
- SetNeedsEstablishPeer(false);
- }
-}
-
-void WebMediaPlayerAndroid::exitFullscreen() {
- proxy_->ExitFullscreen(player_id_);
-}
-
-bool WebMediaPlayerAndroid::canEnterFullscreen() const {
- return manager_->CanEnterFullscreen(frame_);
-}
-
-} // namespace webkit_media
« no previous file with comments | « webkit/renderer/media/android/webmediaplayer_android.h ('k') | webkit/renderer/media/android/webmediaplayer_manager_android.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698