#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"
#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"
#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"
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(
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),
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)
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);
}
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);
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();
}
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) {
OnPlayerReleased();
}
-void WebMediaPlayerAndroid::WillDestroyCurrentMessageLoop() {
+void WebMediaPlayerAndroid::OnDestruct() {
if (manager_)
manager_->UnregisterMediaPlayer(player_id_);
Detach();
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:
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);
}
#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
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;
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_)
}
#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.
void WebMediaPlayerAndroid::enterFullscreen() {
if (manager_->CanEnterFullscreen(frame_)) {
- manager_->EnterFullscreen(player_id_);
+ manager_->EnterFullscreen(player_id_, frame_);
SetNeedsEstablishPeer(false);
}
}