Separate Simple Backend creation from initialization.
[chromium-blink-merge.git] / webkit / media / webmediaplayer_ms.cc
blob23bc638e7340ceb4ff39ac1919bbf609d7b311c7
1 // Copyright (c) 2012 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 "webkit/media/webmediaplayer_ms.h"
7 #include <limits>
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/message_loop.h"
12 #include "base/metrics/histogram.h"
13 #include "cc/layers/video_layer.h"
14 #include "media/base/media_log.h"
15 #include "media/base/video_frame.h"
16 #include "third_party/WebKit/Source/Platform/chromium/public/WebRect.h"
17 #include "third_party/WebKit/Source/Platform/chromium/public/WebSize.h"
18 #include "third_party/WebKit/Source/Platform/chromium/public/WebURL.h"
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerClient.h"
21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
22 #include "webkit/compositor_bindings/web_layer_impl.h"
23 #include "webkit/media/media_stream_audio_renderer.h"
24 #include "webkit/media/media_stream_client.h"
25 #include "webkit/media/video_frame_provider.h"
26 #include "webkit/media/webmediaplayer_delegate.h"
27 #include "webkit/media/webmediaplayer_util.h"
29 using WebKit::WebCanvas;
30 using WebKit::WebMediaPlayer;
31 using WebKit::WebRect;
32 using WebKit::WebSize;
34 namespace webkit_media {
36 WebMediaPlayerMS::WebMediaPlayerMS(
37 WebKit::WebFrame* frame,
38 WebKit::WebMediaPlayerClient* client,
39 base::WeakPtr<WebMediaPlayerDelegate> delegate,
40 MediaStreamClient* media_stream_client,
41 media::MediaLog* media_log)
42 : frame_(frame),
43 network_state_(WebMediaPlayer::NetworkStateEmpty),
44 ready_state_(WebMediaPlayer::ReadyStateHaveNothing),
45 buffered_(static_cast<size_t>(1)),
46 client_(client),
47 delegate_(delegate),
48 media_stream_client_(media_stream_client),
49 paused_(true),
50 current_frame_used_(false),
51 pending_repaint_(false),
52 video_frame_provider_client_(NULL),
53 received_first_frame_(false),
54 sequence_started_(false),
55 total_frame_count_(0),
56 dropped_frame_count_(0),
57 media_log_(media_log) {
58 DVLOG(1) << "WebMediaPlayerMS::ctor";
59 DCHECK(media_stream_client);
60 media_log_->AddEvent(
61 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED));
64 WebMediaPlayerMS::~WebMediaPlayerMS() {
65 DVLOG(1) << "WebMediaPlayerMS::dtor";
66 DCHECK(thread_checker_.CalledOnValidThread());
68 SetVideoFrameProviderClient(NULL);
69 GetClient()->setWebLayer(NULL);
71 if (video_frame_provider_) {
72 video_frame_provider_->Stop();
75 if (audio_renderer_) {
76 if (audio_renderer_->IsLocalRenderer()) {
77 audio_renderer_->Stop();
78 } else if (!paused_) {
79 // The |audio_renderer_| can be shared by multiple remote streams, and
80 // it will be stopped when WebRtcAudioDeviceImpl goes away. So we simply
81 // pause the |audio_renderer_| here to avoid re-creating the
82 // |audio_renderer_|.
83 audio_renderer_->Pause();
87 media_log_->AddEvent(
88 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED));
90 if (delegate_)
91 delegate_->PlayerGone(this);
94 void WebMediaPlayerMS::load(const WebKit::WebURL& url, CORSMode cors_mode) {
95 DVLOG(1) << "WebMediaPlayerMS::load";
96 DCHECK(thread_checker_.CalledOnValidThread());
98 GURL gurl(url);
100 setVolume(GetClient()->volume());
101 SetNetworkState(WebMediaPlayer::NetworkStateLoading);
102 SetReadyState(WebMediaPlayer::ReadyStateHaveNothing);
103 media_log_->AddEvent(media_log_->CreateLoadEvent(url.spec()));
105 // Check if this url is media stream.
106 video_frame_provider_ = media_stream_client_->GetVideoFrameProvider(
107 url,
108 base::Bind(&WebMediaPlayerMS::OnSourceError, AsWeakPtr()),
109 base::Bind(&WebMediaPlayerMS::OnFrameAvailable, AsWeakPtr()));
111 audio_renderer_ = media_stream_client_->GetAudioRenderer(url);
113 if (video_frame_provider_ || audio_renderer_) {
114 GetClient()->setOpaque(true);
115 if (audio_renderer_)
116 audio_renderer_->Start();
118 if (video_frame_provider_) {
119 video_frame_provider_->Start();
120 } else {
121 // This is audio-only mode.
122 DCHECK(audio_renderer_);
123 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata);
124 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
126 } else {
127 SetNetworkState(WebMediaPlayer::NetworkStateNetworkError);
131 void WebMediaPlayerMS::load(const WebKit::WebURL& url,
132 WebKit::WebMediaSource* media_source,
133 CORSMode cors_mode) {
134 NOTIMPLEMENTED();
137 void WebMediaPlayerMS::cancelLoad() {
138 DCHECK(thread_checker_.CalledOnValidThread());
141 void WebMediaPlayerMS::play() {
142 DVLOG(1) << "WebMediaPlayerMS::play";
143 DCHECK(thread_checker_.CalledOnValidThread());
145 if (video_frame_provider_ && paused_)
146 video_frame_provider_->Play();
148 if (audio_renderer_ && paused_)
149 audio_renderer_->Play();
151 paused_ = false;
153 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PLAY));
155 if (delegate_)
156 delegate_->DidPlay(this);
159 void WebMediaPlayerMS::pause() {
160 DVLOG(1) << "WebMediaPlayerMS::pause";
161 DCHECK(thread_checker_.CalledOnValidThread());
163 if (video_frame_provider_)
164 video_frame_provider_->Pause();
166 if (audio_renderer_ && !paused_)
167 audio_renderer_->Pause();
169 paused_ = true;
171 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PAUSE));
173 if (delegate_)
174 delegate_->DidPause(this);
177 bool WebMediaPlayerMS::supportsFullscreen() const {
178 DCHECK(thread_checker_.CalledOnValidThread());
179 return true;
182 bool WebMediaPlayerMS::supportsSave() const {
183 DCHECK(thread_checker_.CalledOnValidThread());
184 return false;
187 void WebMediaPlayerMS::seekFloat(float seconds) {
188 seek(seconds);
191 void WebMediaPlayerMS::seek(float seconds) {
192 DCHECK(thread_checker_.CalledOnValidThread());
195 void WebMediaPlayerMS::setEndTimeFloat(float seconds) {
196 setEndTime(seconds);
199 void WebMediaPlayerMS::setEndTime(float seconds) {
200 DCHECK(thread_checker_.CalledOnValidThread());
203 void WebMediaPlayerMS::setRateFloat(float rate) {
204 setRate(rate);
207 void WebMediaPlayerMS::setRate(float rate) {
208 DCHECK(thread_checker_.CalledOnValidThread());
211 void WebMediaPlayerMS::setVolumeFloat(float volume) {
212 setVolume(volume);
215 void WebMediaPlayerMS::setVolume(float volume) {
216 DCHECK(thread_checker_.CalledOnValidThread());
217 if (!audio_renderer_)
218 return;
219 DVLOG(1) << "WebMediaPlayerMS::setVolume(volume=" << volume << ")";
220 audio_renderer_->SetVolume(volume);
223 void WebMediaPlayerMS::setVisible(bool visible) {
224 DCHECK(thread_checker_.CalledOnValidThread());
227 void WebMediaPlayerMS::setPreload(WebMediaPlayer::Preload preload) {
228 DCHECK(thread_checker_.CalledOnValidThread());
231 bool WebMediaPlayerMS::totalBytesKnown() {
232 DCHECK(thread_checker_.CalledOnValidThread());
233 return false;
236 bool WebMediaPlayerMS::hasVideo() const {
237 DCHECK(thread_checker_.CalledOnValidThread());
238 return (video_frame_provider_ != NULL);
241 bool WebMediaPlayerMS::hasAudio() const {
242 DCHECK(thread_checker_.CalledOnValidThread());
243 return (audio_renderer_ != NULL);
246 WebKit::WebSize WebMediaPlayerMS::naturalSize() const {
247 DCHECK(thread_checker_.CalledOnValidThread());
249 gfx::Size size;
250 if (current_frame_)
251 size = current_frame_->natural_size();
252 DVLOG(3) << "WebMediaPlayerMS::naturalSize, " << size.ToString();
253 return WebKit::WebSize(size);
256 bool WebMediaPlayerMS::paused() const {
257 DCHECK(thread_checker_.CalledOnValidThread());
258 return paused_;
261 bool WebMediaPlayerMS::seeking() const {
262 DCHECK(thread_checker_.CalledOnValidThread());
263 return false;
266 float WebMediaPlayerMS::durationFloat() const {
267 return duration();
270 float WebMediaPlayerMS::duration() const {
271 DCHECK(thread_checker_.CalledOnValidThread());
272 return std::numeric_limits<float>::infinity();
275 float WebMediaPlayerMS::currentTimeFloat() const {
276 return currentTime();
279 float WebMediaPlayerMS::currentTime() const {
280 DCHECK(thread_checker_.CalledOnValidThread());
281 if (current_frame_.get()) {
282 return current_frame_->GetTimestamp().InSecondsF();
283 } else if (audio_renderer_) {
284 return audio_renderer_->GetCurrentRenderTime().InSecondsF();
286 return 0.0f;
289 int WebMediaPlayerMS::dataRate() const {
290 DCHECK(thread_checker_.CalledOnValidThread());
291 return 0;
294 WebMediaPlayer::NetworkState WebMediaPlayerMS::networkState() const {
295 DCHECK(thread_checker_.CalledOnValidThread());
296 DVLOG(1) << "WebMediaPlayerMS::networkState, state:" << network_state_;
297 return network_state_;
300 WebMediaPlayer::ReadyState WebMediaPlayerMS::readyState() const {
301 DCHECK(thread_checker_.CalledOnValidThread());
302 DVLOG(1) << "WebMediaPlayerMS::readyState, state:" << ready_state_;
303 return ready_state_;
306 const WebKit::WebTimeRanges& WebMediaPlayerMS::buffered() {
307 DCHECK(thread_checker_.CalledOnValidThread());
308 return buffered_;
311 float WebMediaPlayerMS::maxTimeSeekableFloat() const {
312 return maxTimeSeekable();
315 float WebMediaPlayerMS::maxTimeSeekable() const {
316 DCHECK(thread_checker_.CalledOnValidThread());
317 return 0.0f;
320 bool WebMediaPlayerMS::didLoadingProgress() const {
321 DCHECK(thread_checker_.CalledOnValidThread());
322 return true;
325 unsigned long long WebMediaPlayerMS::totalBytes() const {
326 DCHECK(thread_checker_.CalledOnValidThread());
327 return 0;
330 void WebMediaPlayerMS::setSize(const WebSize& size) {
331 DCHECK(thread_checker_.CalledOnValidThread());
332 // Don't need to do anything as we use the dimensions passed in via paint().
335 void WebMediaPlayerMS::paint(WebCanvas* canvas,
336 const WebRect& rect,
337 uint8_t alpha) {
338 DVLOG(3) << "WebMediaPlayerMS::paint";
339 DCHECK(thread_checker_.CalledOnValidThread());
341 gfx::RectF dest_rect(rect.x, rect.y, rect.width, rect.height);
342 video_renderer_.Paint(current_frame_, canvas, dest_rect, alpha);
345 base::AutoLock auto_lock(current_frame_lock_);
346 if (current_frame_.get())
347 current_frame_used_ = true;
351 bool WebMediaPlayerMS::hasSingleSecurityOrigin() const {
352 DCHECK(thread_checker_.CalledOnValidThread());
353 return true;
356 bool WebMediaPlayerMS::didPassCORSAccessCheck() const {
357 DCHECK(thread_checker_.CalledOnValidThread());
358 return true;
361 WebMediaPlayer::MovieLoadType WebMediaPlayerMS::movieLoadType() const {
362 DCHECK(thread_checker_.CalledOnValidThread());
363 return WebMediaPlayer::MovieLoadTypeUnknown;
366 float WebMediaPlayerMS::mediaTimeForTimeValueFloat(float timeValue) const {
367 return mediaTimeForTimeValue(timeValue);
370 float WebMediaPlayerMS::mediaTimeForTimeValue(float timeValue) const {
371 return ConvertSecondsToTimestamp(timeValue).InSecondsF();
374 unsigned WebMediaPlayerMS::decodedFrameCount() const {
375 DCHECK(thread_checker_.CalledOnValidThread());
376 DVLOG(1) << "WebMediaPlayerMS::decodedFrameCount, " << total_frame_count_;
377 return total_frame_count_;
380 unsigned WebMediaPlayerMS::droppedFrameCount() const {
381 DCHECK(thread_checker_.CalledOnValidThread());
382 DVLOG(1) << "WebMediaPlayerMS::droppedFrameCount, " << dropped_frame_count_;
383 return dropped_frame_count_;
386 unsigned WebMediaPlayerMS::audioDecodedByteCount() const {
387 DCHECK(thread_checker_.CalledOnValidThread());
388 NOTIMPLEMENTED();
389 return 0;
392 unsigned WebMediaPlayerMS::videoDecodedByteCount() const {
393 DCHECK(thread_checker_.CalledOnValidThread());
394 NOTIMPLEMENTED();
395 return 0;
398 void WebMediaPlayerMS::SetVideoFrameProviderClient(
399 cc::VideoFrameProvider::Client* client) {
400 // This is called from both the main renderer thread and the compositor
401 // thread (when the main thread is blocked).
402 if (video_frame_provider_client_)
403 video_frame_provider_client_->StopUsingProvider();
404 video_frame_provider_client_ = client;
407 scoped_refptr<media::VideoFrame> WebMediaPlayerMS::GetCurrentFrame() {
408 DVLOG(3) << "WebMediaPlayerMS::GetCurrentFrame";
409 base::AutoLock auto_lock(current_frame_lock_);
410 DCHECK(!pending_repaint_);
411 if (!current_frame_)
412 return NULL;
413 pending_repaint_ = true;
414 current_frame_used_ = true;
415 return current_frame_;
418 void WebMediaPlayerMS::PutCurrentFrame(
419 const scoped_refptr<media::VideoFrame>& frame) {
420 DVLOG(3) << "WebMediaPlayerMS::PutCurrentFrame";
421 DCHECK(pending_repaint_);
422 pending_repaint_ = false;
425 void WebMediaPlayerMS::OnFrameAvailable(
426 const scoped_refptr<media::VideoFrame>& frame) {
427 DVLOG(3) << "WebMediaPlayerMS::OnFrameAvailable";
428 DCHECK(thread_checker_.CalledOnValidThread());
429 ++total_frame_count_;
430 if (!received_first_frame_) {
431 received_first_frame_ = true;
433 base::AutoLock auto_lock(current_frame_lock_);
434 DCHECK(!current_frame_used_);
435 current_frame_ =
436 media::VideoFrame::CreateBlackFrame(frame->natural_size());
438 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata);
439 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
440 GetClient()->sizeChanged();
442 if (video_frame_provider_ && GetClient()->needsWebLayerForVideo()) {
443 video_weblayer_.reset(
444 new webkit::WebLayerImpl(cc::VideoLayer::Create(this)));
445 GetClient()->setWebLayer(video_weblayer_.get());
449 // Do not update |current_frame_| when paused.
450 if (paused_)
451 return;
453 if (!sequence_started_) {
454 sequence_started_ = true;
455 start_time_ = frame->GetTimestamp();
457 bool size_changed = !current_frame_ ||
458 current_frame_->natural_size() != frame->natural_size();
461 base::AutoLock auto_lock(current_frame_lock_);
462 if (!current_frame_used_ && current_frame_.get())
463 ++dropped_frame_count_;
464 current_frame_ = frame;
465 current_frame_->SetTimestamp(frame->GetTimestamp() - start_time_);
466 current_frame_used_ = false;
469 if (size_changed)
470 GetClient()->sizeChanged();
472 GetClient()->repaint();
475 void WebMediaPlayerMS::RepaintInternal() {
476 DVLOG(1) << "WebMediaPlayerMS::RepaintInternal";
477 DCHECK(thread_checker_.CalledOnValidThread());
478 GetClient()->repaint();
481 void WebMediaPlayerMS::OnSourceError() {
482 DVLOG(1) << "WebMediaPlayerMS::OnSourceError";
483 DCHECK(thread_checker_.CalledOnValidThread());
484 SetNetworkState(WebMediaPlayer::NetworkStateFormatError);
485 RepaintInternal();
488 void WebMediaPlayerMS::SetNetworkState(WebMediaPlayer::NetworkState state) {
489 DCHECK(thread_checker_.CalledOnValidThread());
490 network_state_ = state;
491 // Always notify to ensure client has the latest value.
492 GetClient()->networkStateChanged();
495 void WebMediaPlayerMS::SetReadyState(WebMediaPlayer::ReadyState state) {
496 DCHECK(thread_checker_.CalledOnValidThread());
497 ready_state_ = state;
498 // Always notify to ensure client has the latest value.
499 GetClient()->readyStateChanged();
502 WebKit::WebMediaPlayerClient* WebMediaPlayerMS::GetClient() {
503 DCHECK(thread_checker_.CalledOnValidThread());
504 DCHECK(client_);
505 return client_;
508 } // namespace webkit_media