summaryrefslogtreecommitdiffstats
path: root/chromium/content/renderer/media/webmediaplayer_ms.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/renderer/media/webmediaplayer_ms.cc')
-rw-r--r--chromium/content/renderer/media/webmediaplayer_ms.cc102
1 files changed, 74 insertions, 28 deletions
diff --git a/chromium/content/renderer/media/webmediaplayer_ms.cc b/chromium/content/renderer/media/webmediaplayer_ms.cc
index 3f64ff150ef..b466d3168aa 100644
--- a/chromium/content/renderer/media/webmediaplayer_ms.cc
+++ b/chromium/content/renderer/media/webmediaplayer_ms.cc
@@ -11,52 +11,94 @@
#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
#include "cc/layers/video_layer.h"
+#include "content/public/renderer/render_view.h"
+#include "content/renderer/compositor_bindings/web_layer_impl.h"
#include "content/renderer/media/media_stream_audio_renderer.h"
-#include "content/renderer/media/media_stream_client.h"
+#include "content/renderer/media/media_stream_renderer_factory.h"
#include "content/renderer/media/video_frame_provider.h"
#include "content/renderer/media/webmediaplayer_delegate.h"
#include "content/renderer/media/webmediaplayer_util.h"
+#include "content/renderer/render_frame_impl.h"
#include "media/base/media_log.h"
#include "media/base/video_frame.h"
+#include "media/base/video_util.h"
#include "third_party/WebKit/public/platform/WebMediaPlayerClient.h"
#include "third_party/WebKit/public/platform/WebRect.h"
#include "third_party/WebKit/public/platform/WebSize.h"
#include "third_party/WebKit/public/platform/WebURL.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "third_party/WebKit/public/web/WebView.h"
-#include "webkit/renderer/compositor_bindings/web_layer_impl.h"
+#include "third_party/skia/include/core/SkBitmap.h"
using blink::WebCanvas;
using blink::WebMediaPlayer;
using blink::WebRect;
using blink::WebSize;
+namespace {
+
+// This function copies a YV12 or NATIVE_TEXTURE to a new YV12
+// media::VideoFrame.
+scoped_refptr<media::VideoFrame> CopyFrameToYV12(
+ const scoped_refptr<media::VideoFrame>& frame) {
+ DCHECK(frame->format() == media::VideoFrame::YV12 ||
+ frame->format() == media::VideoFrame::I420 ||
+ frame->format() == media::VideoFrame::NATIVE_TEXTURE);
+ scoped_refptr<media::VideoFrame> new_frame =
+ media::VideoFrame::CreateFrame(media::VideoFrame::YV12,
+ frame->coded_size(),
+ frame->visible_rect(),
+ frame->natural_size(),
+ frame->timestamp());
+
+ if (frame->format() == media::VideoFrame::NATIVE_TEXTURE) {
+ SkBitmap bitmap;
+ bitmap.allocN32Pixels(frame->visible_rect().width(),
+ frame->visible_rect().height());
+ frame->ReadPixelsFromNativeTexture(bitmap);
+
+ media::CopyRGBToVideoFrame(
+ reinterpret_cast<uint8*>(bitmap.getPixels()),
+ bitmap.rowBytes(),
+ frame->visible_rect(),
+ new_frame.get());
+ } else {
+ size_t number_of_planes =
+ media::VideoFrame::NumPlanes(frame->format());
+ for (size_t i = 0; i < number_of_planes; ++i) {
+ media::CopyPlane(i, frame->data(i), frame->stride(i),
+ frame->rows(i), new_frame.get());
+ }
+ }
+ return new_frame;
+}
+
+} // anonymous namespace
+
namespace content {
WebMediaPlayerMS::WebMediaPlayerMS(
blink::WebFrame* frame,
blink::WebMediaPlayerClient* client,
base::WeakPtr<WebMediaPlayerDelegate> delegate,
- MediaStreamClient* media_stream_client,
- media::MediaLog* media_log)
+ media::MediaLog* media_log,
+ scoped_ptr<MediaStreamRendererFactory> factory)
: frame_(frame),
network_state_(WebMediaPlayer::NetworkStateEmpty),
ready_state_(WebMediaPlayer::ReadyStateHaveNothing),
buffered_(static_cast<size_t>(1)),
client_(client),
delegate_(delegate),
- media_stream_client_(media_stream_client),
paused_(true),
current_frame_used_(false),
pending_repaint_(false),
video_frame_provider_client_(NULL),
received_first_frame_(false),
- sequence_started_(false),
total_frame_count_(0),
dropped_frame_count_(0),
- media_log_(media_log) {
+ media_log_(media_log),
+ renderer_factory_(factory.Pass()) {
DVLOG(1) << "WebMediaPlayerMS::ctor";
- DCHECK(media_stream_client);
media_log_->AddEvent(
media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED));
}
@@ -98,16 +140,18 @@ void WebMediaPlayerMS::load(LoadType load_type,
SetReadyState(WebMediaPlayer::ReadyStateHaveNothing);
media_log_->AddEvent(media_log_->CreateLoadEvent(url.spec()));
- // Check if this url is media stream.
- video_frame_provider_ = media_stream_client_->GetVideoFrameProvider(
+ video_frame_provider_ = renderer_factory_->GetVideoFrameProvider(
url,
base::Bind(&WebMediaPlayerMS::OnSourceError, AsWeakPtr()),
base::Bind(&WebMediaPlayerMS::OnFrameAvailable, AsWeakPtr()));
- audio_renderer_ = media_stream_client_->GetAudioRenderer(url);
+ RenderFrame* frame = RenderFrame::FromWebFrame(frame_);
+ audio_renderer_ = renderer_factory_->GetAudioRenderer(
+ url,
+ frame->GetRenderView()->GetRoutingID(),
+ frame->GetRoutingID());
if (video_frame_provider_.get() || audio_renderer_.get()) {
- GetClient()->setOpaque(true);
if (audio_renderer_.get())
audio_renderer_->Start();
@@ -162,11 +206,17 @@ void WebMediaPlayerMS::pause() {
paused_ = true;
media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PAUSE));
-}
-bool WebMediaPlayerMS::supportsFullscreen() const {
- DCHECK(thread_checker_.CalledOnValidThread());
- return true;
+ if (!current_frame_)
+ return;
+
+ // Copy the frame so that rendering can show the last received frame.
+ // The original frame must not be referenced when the player is paused since
+ // there might be a finite number of available buffers. E.g, video that
+ // originates from a video camera.
+ scoped_refptr<media::VideoFrame> new_frame = CopyFrameToYV12(current_frame_);
+ base::AutoLock auto_lock(current_frame_lock_);
+ current_frame_ = new_frame;
}
bool WebMediaPlayerMS::supportsSave() const {
@@ -231,8 +281,8 @@ double WebMediaPlayerMS::duration() const {
double WebMediaPlayerMS::currentTime() const {
DCHECK(thread_checker_.CalledOnValidThread());
- if (current_frame_.get()) {
- return current_frame_->GetTimestamp().InSecondsF();
+ if (current_time_.ToInternalValue() != 0) {
+ return current_time_.InSecondsF();
} else if (audio_renderer_.get()) {
return audio_renderer_->GetCurrentRenderTime().InSecondsF();
}
@@ -251,7 +301,7 @@ WebMediaPlayer::ReadyState WebMediaPlayerMS::readyState() const {
return ready_state_;
}
-const blink::WebTimeRanges& WebMediaPlayerMS::buffered() {
+blink::WebTimeRanges WebMediaPlayerMS::buffered() const {
DCHECK(thread_checker_.CalledOnValidThread());
return buffered_;
}
@@ -261,7 +311,7 @@ double WebMediaPlayerMS::maxTimeSeekable() const {
return 0.0;
}
-bool WebMediaPlayerMS::didLoadingProgress() const {
+bool WebMediaPlayerMS::didLoadingProgress() {
DCHECK(thread_checker_.CalledOnValidThread());
return true;
}
@@ -363,9 +413,9 @@ void WebMediaPlayerMS::OnFrameAvailable(
SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
GetClient()->sizeChanged();
- if (video_frame_provider_.get() && GetClient()->needsWebLayerForVideo()) {
- video_weblayer_.reset(
- new webkit::WebLayerImpl(cc::VideoLayer::Create(this)));
+ if (video_frame_provider_) {
+ video_weblayer_.reset(new WebLayerImpl(cc::VideoLayer::Create(this)));
+ video_weblayer_->setOpaque(true);
GetClient()->setWebLayer(video_weblayer_.get());
}
}
@@ -374,10 +424,6 @@ void WebMediaPlayerMS::OnFrameAvailable(
if (paused_)
return;
- if (!sequence_started_) {
- sequence_started_ = true;
- start_time_ = frame->GetTimestamp();
- }
bool size_changed = !current_frame_.get() ||
current_frame_->natural_size() != frame->natural_size();
@@ -386,7 +432,7 @@ void WebMediaPlayerMS::OnFrameAvailable(
if (!current_frame_used_ && current_frame_.get())
++dropped_frame_count_;
current_frame_ = frame;
- current_frame_->SetTimestamp(frame->GetTimestamp() - start_time_);
+ current_time_ = frame->timestamp();
current_frame_used_ = false;
}