Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / content / renderer / media / android / webmediaplayer_android.cc
index 159fa34..eae9714 100644 (file)
 #include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
+#include "base/message_loop/message_loop.h"
 #include "base/metrics/histogram.h"
 #include "base/strings/string_number_conversions.h"
 #include "cc/layers/video_layer.h"
 #include "content/public/common/content_client.h"
+#include "content/public/renderer/render_frame.h"
 #include "content/renderer/media/android/proxy_media_keys.h"
 #include "content/renderer/media/android/renderer_demuxer_android.h"
 #include "content/renderer/media/android/renderer_media_player_manager.h"
@@ -26,6 +28,7 @@
 #include "content/renderer/render_thread_impl.h"
 #include "gpu/GLES2/gl2extchromium.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/command_buffer/common/mailbox_holder.h"
 #include "grit/content_resources.h"
 #include "media/base/android/media_player_android.h"
 #include "media/base/bind_to_current_loop.h"
@@ -34,6 +37,7 @@
 #include "net/base/mime_util.h"
 #include "third_party/WebKit/public/platform/WebMediaPlayerClient.h"
 #include "third_party/WebKit/public/platform/WebString.h"
+#include "third_party/WebKit/public/platform/WebURL.h"
 #include "third_party/WebKit/public/web/WebDocument.h"
 #include "third_party/WebKit/public/web/WebFrame.h"
 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
@@ -66,12 +70,12 @@ namespace content {
 void WebMediaPlayerAndroid::OnReleaseRemotePlaybackTexture(
     const scoped_refptr<base::MessageLoopProxy>& main_loop,
     const base::WeakPtr<WebMediaPlayerAndroid>& player,
-    uint32 sync_point) {
+    scoped_ptr<gpu::MailboxHolder> mailbox_holder) {
   main_loop->PostTask(
       FROM_HERE,
       base::Bind(&WebMediaPlayerAndroid::DoReleaseRemotePlaybackTexture,
                  player,
-                 sync_point));
+                 mailbox_holder->sync_point));
 }
 
 WebMediaPlayerAndroid::WebMediaPlayerAndroid(
@@ -82,7 +86,8 @@ WebMediaPlayerAndroid::WebMediaPlayerAndroid(
     StreamTextureFactory* factory,
     const scoped_refptr<base::MessageLoopProxy>& media_loop,
     media::MediaLog* media_log)
-    : frame_(frame),
+    : RenderFrameObserver(RenderFrame::FromWebFrame(frame)),
+      frame_(frame),
       client_(client),
       delegate_(delegate),
       buffered_(1u),
@@ -119,9 +124,6 @@ WebMediaPlayerAndroid::WebMediaPlayerAndroid(
 
   DCHECK(main_thread_checker_.CalledOnValidThread());
 
-  // We want to be notified of |main_loop_| destruction.
-  base::MessageLoop::current()->AddDestructionObserver(this);
-
   player_id_ = manager_->RegisterMediaPlayer(this);
 
 #if defined(VIDEO_HOLE)
@@ -149,9 +151,6 @@ WebMediaPlayerAndroid::~WebMediaPlayerAndroid() {
         DeleteTextures(1, &remote_playback_texture_id_);
   }
 
-  if (base::MessageLoop::current())
-    base::MessageLoop::current()->RemoveDestructionObserver(this);
-
   if (player_type_ == MEDIA_PLAYER_TYPE_MEDIA_SOURCE && delegate_)
     delegate_->PlayerGone(this);
 }
@@ -220,8 +219,8 @@ void WebMediaPlayerAndroid::load(LoadType load_type,
   manager_->Initialize(
       player_type_, player_id_, url, first_party_url, demuxer_client_id);
 
-  if (manager_->IsInFullscreen(frame_))
-    manager_->EnterFullscreen(player_id_);
+  if (manager_->ShouldEnterFullscreen(frame_))
+    manager_->EnterFullscreen(player_id_, frame_);
 
   UpdateNetworkState(WebMediaPlayer::NetworkStateLoading);
   UpdateReadyState(WebMediaPlayer::ReadyStateHaveNothing);
@@ -563,12 +562,6 @@ void WebMediaPlayerAndroid::OnMediaMetadataChanged(
   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();
 }
@@ -674,6 +667,11 @@ void WebMediaPlayerAndroid::OnVideoSizeChanged(int width, int height) {
   natural_size_.width = width;
   natural_size_.height = height;
   ReallocateVideoFrame();
+  CreateWebLayerIfNeeded();
+  // TODO(qinmin): This is a hack. We need the media element to stop showing the
+  // poster image by forcing it to call setDisplayMode(video). Should move the
+  // logic into HTMLMediaElement.cpp.
+  client_->timeChanged();
 }
 
 void WebMediaPlayerAndroid::OnTimeUpdate(const base::TimeDelta& current_time) {
@@ -813,7 +811,7 @@ void WebMediaPlayerAndroid::ReleaseMediaResources() {
   OnPlayerReleased();
 }
 
-void WebMediaPlayerAndroid::WillDestroyCurrentMessageLoop() {
+void WebMediaPlayerAndroid::OnDestruct() {
   if (manager_)
     manager_->UnregisterMediaPlayer(player_id_);
   Detach();
@@ -866,7 +864,7 @@ void WebMediaPlayerAndroid::DrawRemotePlaybackIcon() {
   paint.setAntiAlias(true);
   paint.setFilterLevel(SkPaint::kHigh_FilterLevel);
   const SkBitmap* icon_bitmap =
-      content::GetContentClient()
+      GetContentClient()
           ->GetNativeImageNamed(IDR_MEDIAPLAYER_REMOTE_PLAYBACK_ICON)
           .ToSkBitmap();
   // In order to get a reasonable margin around the icon:
@@ -920,19 +918,16 @@ void WebMediaPlayerAndroid::DrawRemotePlaybackIcon() {
   GLuint texture_mailbox_sync_point = gl->InsertSyncPointCHROMIUM();
 
   scoped_refptr<VideoFrame> new_frame = VideoFrame::WrapNativeTexture(
-      make_scoped_ptr(new VideoFrame::MailboxHolder(
-          texture_mailbox,
-          texture_mailbox_sync_point,
-          base::Bind(&WebMediaPlayerAndroid::OnReleaseRemotePlaybackTexture,
-                     main_loop_,
-                     weak_factory_.GetWeakPtr()))),
-      texture_target,
+      make_scoped_ptr(new gpu::MailboxHolder(
+          texture_mailbox, texture_target, texture_mailbox_sync_point)),
+      base::Bind(&WebMediaPlayerAndroid::OnReleaseRemotePlaybackTexture,
+                 main_loop_,
+                 weak_factory_.GetWeakPtr()),
       canvas_size /* coded_size */,
       gfx::Rect(canvas_size) /* visible_rect */,
       canvas_size /* natural_size */,
       base::TimeDelta() /* timestamp */,
-      VideoFrame::ReadPixelsCB(),
-      base::Closure() /* no_longer_needed_cb */);
+      VideoFrame::ReadPixelsCB());
   SetCurrentFrameInternal(new_frame);
 }
 
@@ -952,21 +947,26 @@ void WebMediaPlayerAndroid::ReallocateVideoFrame() {
 #endif  // defined(VIDEO_HOLE)
   } else if (!is_remote_ && texture_id_) {
     scoped_refptr<VideoFrame> new_frame = VideoFrame::WrapNativeTexture(
-        make_scoped_ptr(new VideoFrame::MailboxHolder(
-            texture_mailbox_,
-            texture_mailbox_sync_point_,
-            VideoFrame::MailboxHolder::TextureNoLongerNeededCallback())),
-        kGLTextureExternalOES,
+        make_scoped_ptr(new gpu::MailboxHolder(texture_mailbox_,
+                                               kGLTextureExternalOES,
+                                               texture_mailbox_sync_point_)),
+        media::VideoFrame::ReleaseMailboxCB(),
         natural_size_,
         gfx::Rect(natural_size_),
         natural_size_,
         base::TimeDelta(),
-        VideoFrame::ReadPixelsCB(),
-        base::Closure());
+        VideoFrame::ReadPixelsCB());
     SetCurrentFrameInternal(new_frame);
   }
 }
 
+void WebMediaPlayerAndroid::CreateWebLayerIfNeeded() {
+  if (!hasVideo() || video_weblayer_ || !client_->needsWebLayerForVideo())
+    return;
+  video_weblayer_.reset(new webkit::WebLayerImpl(cc::VideoLayer::Create(this)));
+  client_->setWebLayer(video_weblayer_.get());
+}
+
 void WebMediaPlayerAndroid::SetVideoFrameProviderClient(
     cc::VideoFrameProvider::Client* client) {
   // This is called from both the main renderer thread and the compositor
@@ -1033,18 +1033,6 @@ void WebMediaPlayerAndroid::EstablishSurfaceTexturePeer() {
   if (!stream_texture_proxy_)
     return;
 
-  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;
-    texture_mailbox_ = gpu::Mailbox();
-    texture_mailbox_sync_point_ = 0;
-    DoCreateStreamTexture();
-    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;
@@ -1065,6 +1053,10 @@ void WebMediaPlayerAndroid::SetNeedsEstablishPeer(bool needs_establish_peer) {
   needs_establish_peer_ = needs_establish_peer;
 }
 
+void WebMediaPlayerAndroid::setPoster(const blink::WebURL& poster) {
+  manager_->SetPoster(player_id_, poster);
+}
+
 void WebMediaPlayerAndroid::UpdatePlayingState(bool is_playing) {
   is_playing_ = is_playing;
   if (!delegate_)
@@ -1076,26 +1068,30 @@ void WebMediaPlayerAndroid::UpdatePlayingState(bool is_playing) {
 }
 
 #if defined(VIDEO_HOLE)
-bool WebMediaPlayerAndroid::RetrieveGeometryChange(gfx::RectF* rect) {
+bool WebMediaPlayerAndroid::UpdateBoundaryRectangle() {
   if (!video_weblayer_)
     return false;
 
   // Compute the geometry of video frame layer.
   cc::Layer* layer = video_weblayer_->layer();
-  rect->set_size(layer->bounds());
+  gfx::RectF rect(layer->bounds());
   while (layer) {
-    rect->Offset(layer->position().OffsetFromOrigin());
+    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)
+  if (last_computed_rect_ == rect)
     return false;
 
   // Store the changed geometry information when it is actually changed.
-  last_computed_rect_ = *rect;
+  last_computed_rect_ = rect;
   return true;
 }
+
+const gfx::RectF WebMediaPlayerAndroid::GetBoundaryRectangle() {
+  return last_computed_rect_;
+}
 #endif
 
 // The following EME related code is copied from WebMediaPlayerImpl.
@@ -1405,7 +1401,7 @@ void WebMediaPlayerAndroid::DoReleaseRemotePlaybackTexture(uint32 sync_point) {
 
 void WebMediaPlayerAndroid::enterFullscreen() {
   if (manager_->CanEnterFullscreen(frame_)) {
-    manager_->EnterFullscreen(player_id_);
+    manager_->EnterFullscreen(player_id_, frame_);
     SetNeedsEstablishPeer(false);
   }
 }