chrome.bluetoothSocket: clean-up Listen functions
[chromium-blink-merge.git] / content / renderer / media / webmediaplayer_ms.cc
blobfe8d7a5a871d5f63f127ad44b161b527e3117a74
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/renderer/media/webmediaplayer_ms.h"
7 #include <limits>
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/metrics/histogram.h"
13 #include "cc/layers/video_layer.h"
14 #include "content/public/renderer/render_view.h"
15 #include "content/renderer/media/media_stream_audio_renderer.h"
16 #include "content/renderer/media/media_stream_renderer_factory.h"
17 #include "content/renderer/media/video_frame_provider.h"
18 #include "content/renderer/media/webmediaplayer_delegate.h"
19 #include "content/renderer/media/webmediaplayer_util.h"
20 #include "content/renderer/render_frame_impl.h"
21 #include "media/base/media_log.h"
22 #include "media/base/video_frame.h"
23 #include "media/base/video_util.h"
24 #include "third_party/WebKit/public/platform/WebMediaPlayerClient.h"
25 #include "third_party/WebKit/public/platform/WebRect.h"
26 #include "third_party/WebKit/public/platform/WebSize.h"
27 #include "third_party/WebKit/public/platform/WebURL.h"
28 #include "third_party/WebKit/public/web/WebFrame.h"
29 #include "third_party/WebKit/public/web/WebView.h"
30 #include "third_party/skia/include/core/SkBitmap.h"
31 #include "webkit/renderer/compositor_bindings/web_layer_impl.h"
33 using blink::WebCanvas;
34 using blink::WebMediaPlayer;
35 using blink::WebRect;
36 using blink::WebSize;
38 namespace {
40 // This function copies a YV12 or NATIVE_TEXTURE to a new YV12
41 // media::VideoFrame.
42 scoped_refptr<media::VideoFrame> CopyFrameToYV12(
43 const scoped_refptr<media::VideoFrame>& frame) {
44 DCHECK(frame->format() == media::VideoFrame::YV12 ||
45 frame->format() == media::VideoFrame::I420 ||
46 frame->format() == media::VideoFrame::NATIVE_TEXTURE);
47 scoped_refptr<media::VideoFrame> new_frame =
48 media::VideoFrame::CreateFrame(media::VideoFrame::YV12,
49 frame->coded_size(),
50 frame->visible_rect(),
51 frame->natural_size(),
52 frame->timestamp());
54 if (frame->format() == media::VideoFrame::NATIVE_TEXTURE) {
55 SkBitmap bitmap;
56 bitmap.allocN32Pixels(frame->visible_rect().width(),
57 frame->visible_rect().height());
58 frame->ReadPixelsFromNativeTexture(bitmap);
60 media::CopyRGBToVideoFrame(
61 reinterpret_cast<uint8*>(bitmap.getPixels()),
62 bitmap.rowBytes(),
63 frame->visible_rect(),
64 new_frame.get());
65 } else {
66 size_t number_of_planes =
67 media::VideoFrame::NumPlanes(frame->format());
68 for (size_t i = 0; i < number_of_planes; ++i) {
69 media::CopyPlane(i, frame->data(i), frame->stride(i),
70 frame->rows(i), new_frame.get());
73 return new_frame;
76 } // anonymous namespace
78 namespace content {
80 WebMediaPlayerMS::WebMediaPlayerMS(
81 blink::WebFrame* frame,
82 blink::WebMediaPlayerClient* client,
83 base::WeakPtr<WebMediaPlayerDelegate> delegate,
84 media::MediaLog* media_log,
85 scoped_ptr<MediaStreamRendererFactory> factory)
86 : frame_(frame),
87 network_state_(WebMediaPlayer::NetworkStateEmpty),
88 ready_state_(WebMediaPlayer::ReadyStateHaveNothing),
89 buffered_(static_cast<size_t>(1)),
90 client_(client),
91 delegate_(delegate),
92 paused_(true),
93 current_frame_used_(false),
94 pending_repaint_(false),
95 video_frame_provider_client_(NULL),
96 received_first_frame_(false),
97 total_frame_count_(0),
98 dropped_frame_count_(0),
99 media_log_(media_log),
100 renderer_factory_(factory.Pass()) {
101 DVLOG(1) << "WebMediaPlayerMS::ctor";
102 media_log_->AddEvent(
103 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED));
106 WebMediaPlayerMS::~WebMediaPlayerMS() {
107 DVLOG(1) << "WebMediaPlayerMS::dtor";
108 DCHECK(thread_checker_.CalledOnValidThread());
110 SetVideoFrameProviderClient(NULL);
111 GetClient()->setWebLayer(NULL);
113 if (video_frame_provider_.get())
114 video_frame_provider_->Stop();
116 if (audio_renderer_.get())
117 audio_renderer_->Stop();
119 media_log_->AddEvent(
120 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED));
122 if (delegate_.get())
123 delegate_->PlayerGone(this);
126 void WebMediaPlayerMS::load(LoadType load_type,
127 const blink::WebURL& url,
128 CORSMode cors_mode) {
129 DVLOG(1) << "WebMediaPlayerMS::load";
130 DCHECK(thread_checker_.CalledOnValidThread());
132 // TODO(acolwell): Change this to DCHECK_EQ(load_type,
133 // LoadTypeMediaStream) once Blink-side changes land.
134 DCHECK_NE(load_type, LoadTypeMediaSource);
136 GURL gurl(url);
138 setVolume(GetClient()->volume());
139 SetNetworkState(WebMediaPlayer::NetworkStateLoading);
140 SetReadyState(WebMediaPlayer::ReadyStateHaveNothing);
141 media_log_->AddEvent(media_log_->CreateLoadEvent(url.spec()));
143 video_frame_provider_ = renderer_factory_->GetVideoFrameProvider(
144 url,
145 base::Bind(&WebMediaPlayerMS::OnSourceError, AsWeakPtr()),
146 base::Bind(&WebMediaPlayerMS::OnFrameAvailable, AsWeakPtr()));
148 RenderFrame* frame = RenderFrame::FromWebFrame(frame_);
149 audio_renderer_ = renderer_factory_->GetAudioRenderer(
150 url,
151 frame->GetRenderView()->GetRoutingID(),
152 frame->GetRoutingID());
154 if (video_frame_provider_.get() || audio_renderer_.get()) {
155 if (audio_renderer_.get())
156 audio_renderer_->Start();
158 if (video_frame_provider_.get()) {
159 video_frame_provider_->Start();
160 } else {
161 // This is audio-only mode.
162 DCHECK(audio_renderer_.get());
163 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata);
164 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
166 } else {
167 SetNetworkState(WebMediaPlayer::NetworkStateNetworkError);
171 void WebMediaPlayerMS::play() {
172 DVLOG(1) << "WebMediaPlayerMS::play";
173 DCHECK(thread_checker_.CalledOnValidThread());
175 if (paused_) {
176 if (video_frame_provider_.get())
177 video_frame_provider_->Play();
179 if (audio_renderer_.get())
180 audio_renderer_->Play();
182 if (delegate_.get())
183 delegate_->DidPlay(this);
186 paused_ = false;
188 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PLAY));
191 void WebMediaPlayerMS::pause() {
192 DVLOG(1) << "WebMediaPlayerMS::pause";
193 DCHECK(thread_checker_.CalledOnValidThread());
195 if (video_frame_provider_.get())
196 video_frame_provider_->Pause();
198 if (!paused_) {
199 if (audio_renderer_.get())
200 audio_renderer_->Pause();
202 if (delegate_.get())
203 delegate_->DidPause(this);
206 paused_ = true;
208 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PAUSE));
210 if (!current_frame_)
211 return;
213 // Copy the frame so that rendering can show the last received frame.
214 // The original frame must not be referenced when the player is paused since
215 // there might be a finite number of available buffers. E.g, video that
216 // originates from a video camera.
217 scoped_refptr<media::VideoFrame> new_frame = CopyFrameToYV12(current_frame_);
218 base::AutoLock auto_lock(current_frame_lock_);
219 current_frame_ = new_frame;
222 bool WebMediaPlayerMS::supportsSave() const {
223 DCHECK(thread_checker_.CalledOnValidThread());
224 return false;
227 void WebMediaPlayerMS::seek(double seconds) {
228 DCHECK(thread_checker_.CalledOnValidThread());
231 void WebMediaPlayerMS::setRate(double rate) {
232 DCHECK(thread_checker_.CalledOnValidThread());
235 void WebMediaPlayerMS::setVolume(double volume) {
236 DCHECK(thread_checker_.CalledOnValidThread());
237 if (!audio_renderer_.get())
238 return;
239 DVLOG(1) << "WebMediaPlayerMS::setVolume(volume=" << volume << ")";
240 audio_renderer_->SetVolume(volume);
243 void WebMediaPlayerMS::setPreload(WebMediaPlayer::Preload preload) {
244 DCHECK(thread_checker_.CalledOnValidThread());
247 bool WebMediaPlayerMS::hasVideo() const {
248 DCHECK(thread_checker_.CalledOnValidThread());
249 return (video_frame_provider_.get() != NULL);
252 bool WebMediaPlayerMS::hasAudio() const {
253 DCHECK(thread_checker_.CalledOnValidThread());
254 return (audio_renderer_.get() != NULL);
257 blink::WebSize WebMediaPlayerMS::naturalSize() const {
258 DCHECK(thread_checker_.CalledOnValidThread());
260 gfx::Size size;
261 if (current_frame_.get())
262 size = current_frame_->natural_size();
263 DVLOG(3) << "WebMediaPlayerMS::naturalSize, " << size.ToString();
264 return blink::WebSize(size);
267 bool WebMediaPlayerMS::paused() const {
268 DCHECK(thread_checker_.CalledOnValidThread());
269 return paused_;
272 bool WebMediaPlayerMS::seeking() const {
273 DCHECK(thread_checker_.CalledOnValidThread());
274 return false;
277 double WebMediaPlayerMS::duration() const {
278 DCHECK(thread_checker_.CalledOnValidThread());
279 return std::numeric_limits<double>::infinity();
282 double WebMediaPlayerMS::currentTime() const {
283 DCHECK(thread_checker_.CalledOnValidThread());
284 if (current_time_.ToInternalValue() != 0) {
285 return current_time_.InSecondsF();
286 } else if (audio_renderer_.get()) {
287 return audio_renderer_->GetCurrentRenderTime().InSecondsF();
289 return 0.0;
292 WebMediaPlayer::NetworkState WebMediaPlayerMS::networkState() const {
293 DCHECK(thread_checker_.CalledOnValidThread());
294 DVLOG(1) << "WebMediaPlayerMS::networkState, state:" << network_state_;
295 return network_state_;
298 WebMediaPlayer::ReadyState WebMediaPlayerMS::readyState() const {
299 DCHECK(thread_checker_.CalledOnValidThread());
300 DVLOG(1) << "WebMediaPlayerMS::readyState, state:" << ready_state_;
301 return ready_state_;
304 blink::WebTimeRanges WebMediaPlayerMS::buffered() const {
305 DCHECK(thread_checker_.CalledOnValidThread());
306 return buffered_;
309 double WebMediaPlayerMS::maxTimeSeekable() const {
310 DCHECK(thread_checker_.CalledOnValidThread());
311 return 0.0;
314 bool WebMediaPlayerMS::didLoadingProgress() {
315 DCHECK(thread_checker_.CalledOnValidThread());
316 return true;
319 void WebMediaPlayerMS::paint(WebCanvas* canvas,
320 const WebRect& rect,
321 unsigned char alpha) {
322 DVLOG(3) << "WebMediaPlayerMS::paint";
323 DCHECK(thread_checker_.CalledOnValidThread());
325 gfx::RectF dest_rect(rect.x, rect.y, rect.width, rect.height);
326 video_renderer_.Paint(current_frame_.get(), canvas, dest_rect, alpha);
329 base::AutoLock auto_lock(current_frame_lock_);
330 if (current_frame_.get())
331 current_frame_used_ = true;
335 bool WebMediaPlayerMS::hasSingleSecurityOrigin() const {
336 DCHECK(thread_checker_.CalledOnValidThread());
337 return true;
340 bool WebMediaPlayerMS::didPassCORSAccessCheck() const {
341 DCHECK(thread_checker_.CalledOnValidThread());
342 return true;
345 double WebMediaPlayerMS::mediaTimeForTimeValue(double timeValue) const {
346 return ConvertSecondsToTimestamp(timeValue).InSecondsF();
349 unsigned WebMediaPlayerMS::decodedFrameCount() const {
350 DCHECK(thread_checker_.CalledOnValidThread());
351 DVLOG(1) << "WebMediaPlayerMS::decodedFrameCount, " << total_frame_count_;
352 return total_frame_count_;
355 unsigned WebMediaPlayerMS::droppedFrameCount() const {
356 DCHECK(thread_checker_.CalledOnValidThread());
357 DVLOG(1) << "WebMediaPlayerMS::droppedFrameCount, " << dropped_frame_count_;
358 return dropped_frame_count_;
361 unsigned WebMediaPlayerMS::audioDecodedByteCount() const {
362 DCHECK(thread_checker_.CalledOnValidThread());
363 NOTIMPLEMENTED();
364 return 0;
367 unsigned WebMediaPlayerMS::videoDecodedByteCount() const {
368 DCHECK(thread_checker_.CalledOnValidThread());
369 NOTIMPLEMENTED();
370 return 0;
373 void WebMediaPlayerMS::SetVideoFrameProviderClient(
374 cc::VideoFrameProvider::Client* client) {
375 // This is called from both the main renderer thread and the compositor
376 // thread (when the main thread is blocked).
377 if (video_frame_provider_client_)
378 video_frame_provider_client_->StopUsingProvider();
379 video_frame_provider_client_ = client;
382 scoped_refptr<media::VideoFrame> WebMediaPlayerMS::GetCurrentFrame() {
383 DVLOG(3) << "WebMediaPlayerMS::GetCurrentFrame";
384 base::AutoLock auto_lock(current_frame_lock_);
385 DCHECK(!pending_repaint_);
386 if (!current_frame_.get())
387 return NULL;
388 pending_repaint_ = true;
389 current_frame_used_ = true;
390 return current_frame_;
393 void WebMediaPlayerMS::PutCurrentFrame(
394 const scoped_refptr<media::VideoFrame>& frame) {
395 DVLOG(3) << "WebMediaPlayerMS::PutCurrentFrame";
396 DCHECK(pending_repaint_);
397 pending_repaint_ = false;
400 void WebMediaPlayerMS::OnFrameAvailable(
401 const scoped_refptr<media::VideoFrame>& frame) {
402 DVLOG(3) << "WebMediaPlayerMS::OnFrameAvailable";
403 DCHECK(thread_checker_.CalledOnValidThread());
404 ++total_frame_count_;
405 if (!received_first_frame_) {
406 received_first_frame_ = true;
408 base::AutoLock auto_lock(current_frame_lock_);
409 DCHECK(!current_frame_used_);
410 current_frame_ = frame;
412 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata);
413 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
414 GetClient()->sizeChanged();
416 if (video_frame_provider_) {
417 video_weblayer_.reset(
418 new webkit::WebLayerImpl(cc::VideoLayer::Create(this)));
419 video_weblayer_->setOpaque(true);
420 GetClient()->setWebLayer(video_weblayer_.get());
424 // Do not update |current_frame_| when paused.
425 if (paused_)
426 return;
428 bool size_changed = !current_frame_.get() ||
429 current_frame_->natural_size() != frame->natural_size();
432 base::AutoLock auto_lock(current_frame_lock_);
433 if (!current_frame_used_ && current_frame_.get())
434 ++dropped_frame_count_;
435 current_frame_ = frame;
436 current_time_ = frame->timestamp();
437 current_frame_used_ = false;
440 if (size_changed)
441 GetClient()->sizeChanged();
443 GetClient()->repaint();
446 void WebMediaPlayerMS::RepaintInternal() {
447 DVLOG(1) << "WebMediaPlayerMS::RepaintInternal";
448 DCHECK(thread_checker_.CalledOnValidThread());
449 GetClient()->repaint();
452 void WebMediaPlayerMS::OnSourceError() {
453 DVLOG(1) << "WebMediaPlayerMS::OnSourceError";
454 DCHECK(thread_checker_.CalledOnValidThread());
455 SetNetworkState(WebMediaPlayer::NetworkStateFormatError);
456 RepaintInternal();
459 void WebMediaPlayerMS::SetNetworkState(WebMediaPlayer::NetworkState state) {
460 DCHECK(thread_checker_.CalledOnValidThread());
461 network_state_ = state;
462 // Always notify to ensure client has the latest value.
463 GetClient()->networkStateChanged();
466 void WebMediaPlayerMS::SetReadyState(WebMediaPlayer::ReadyState state) {
467 DCHECK(thread_checker_.CalledOnValidThread());
468 ready_state_ = state;
469 // Always notify to ensure client has the latest value.
470 GetClient()->readyStateChanged();
473 blink::WebMediaPlayerClient* WebMediaPlayerMS::GetClient() {
474 DCHECK(thread_checker_.CalledOnValidThread());
475 DCHECK(client_);
476 return client_;
479 } // namespace content