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"
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/renderer/media/media_stream_audio_renderer.h"
15 #include "content/renderer/media/media_stream_client.h"
16 #include "content/renderer/media/video_frame_provider.h"
17 #include "content/renderer/media/webmediaplayer_delegate.h"
18 #include "content/renderer/media/webmediaplayer_util.h"
19 #include "media/base/media_log.h"
20 #include "media/base/video_frame.h"
21 #include "third_party/WebKit/public/platform/WebRect.h"
22 #include "third_party/WebKit/public/platform/WebSize.h"
23 #include "third_party/WebKit/public/platform/WebURL.h"
24 #include "third_party/WebKit/public/web/WebFrame.h"
25 #include "third_party/WebKit/public/web/WebMediaPlayerClient.h"
26 #include "third_party/WebKit/public/web/WebView.h"
27 #include "webkit/renderer/compositor_bindings/web_layer_impl.h"
29 using WebKit::WebCanvas;
30 using WebKit::WebMediaPlayer;
31 using WebKit::WebRect;
32 using WebKit::WebSize;
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)
43 network_state_(WebMediaPlayer::NetworkStateEmpty),
44 ready_state_(WebMediaPlayer::ReadyStateHaveNothing),
45 buffered_(static_cast<size_t>(1)),
48 media_stream_client_(media_stream_client),
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);
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_.get())
72 video_frame_provider_->Stop();
74 if (audio_renderer_.get())
75 audio_renderer_->Stop();
78 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED));
81 delegate_->PlayerGone(this);
84 void WebMediaPlayerMS::load(LoadType load_type,
85 const WebKit::WebURL& url,
87 DVLOG(1) << "WebMediaPlayerMS::load";
88 DCHECK(thread_checker_.CalledOnValidThread());
90 // TODO(acolwell): Change this to DCHECK_EQ(load_type,
91 // LoadTypeMediaStream) once Blink-side changes land.
92 DCHECK_NE(load_type, LoadTypeMediaSource);
96 setVolume(GetClient()->volume());
97 SetNetworkState(WebMediaPlayer::NetworkStateLoading);
98 SetReadyState(WebMediaPlayer::ReadyStateHaveNothing);
99 media_log_->AddEvent(media_log_->CreateLoadEvent(url.spec()));
101 // Check if this url is media stream.
102 video_frame_provider_ = media_stream_client_->GetVideoFrameProvider(
104 base::Bind(&WebMediaPlayerMS::OnSourceError, AsWeakPtr()),
105 base::Bind(&WebMediaPlayerMS::OnFrameAvailable, AsWeakPtr()));
107 audio_renderer_ = media_stream_client_->GetAudioRenderer(url);
109 if (video_frame_provider_.get() || audio_renderer_.get()) {
110 GetClient()->setOpaque(true);
111 if (audio_renderer_.get())
112 audio_renderer_->Start();
114 if (video_frame_provider_.get()) {
115 video_frame_provider_->Start();
117 // This is audio-only mode.
118 DCHECK(audio_renderer_.get());
119 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata);
120 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
123 SetNetworkState(WebMediaPlayer::NetworkStateNetworkError);
127 void WebMediaPlayerMS::play() {
128 DVLOG(1) << "WebMediaPlayerMS::play";
129 DCHECK(thread_checker_.CalledOnValidThread());
132 if (video_frame_provider_.get())
133 video_frame_provider_->Play();
135 if (audio_renderer_.get())
136 audio_renderer_->Play();
139 delegate_->DidPlay(this);
144 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PLAY));
147 void WebMediaPlayerMS::pause() {
148 DVLOG(1) << "WebMediaPlayerMS::pause";
149 DCHECK(thread_checker_.CalledOnValidThread());
151 if (video_frame_provider_.get())
152 video_frame_provider_->Pause();
155 if (audio_renderer_.get())
156 audio_renderer_->Pause();
159 delegate_->DidPause(this);
164 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PAUSE));
167 bool WebMediaPlayerMS::supportsFullscreen() const {
168 DCHECK(thread_checker_.CalledOnValidThread());
172 bool WebMediaPlayerMS::supportsSave() const {
173 DCHECK(thread_checker_.CalledOnValidThread());
177 void WebMediaPlayerMS::seek(double seconds) {
178 DCHECK(thread_checker_.CalledOnValidThread());
181 void WebMediaPlayerMS::setRate(double rate) {
182 DCHECK(thread_checker_.CalledOnValidThread());
185 void WebMediaPlayerMS::setVolume(double volume) {
186 DCHECK(thread_checker_.CalledOnValidThread());
187 if (!audio_renderer_.get())
189 DVLOG(1) << "WebMediaPlayerMS::setVolume(volume=" << volume << ")";
190 audio_renderer_->SetVolume(volume);
193 void WebMediaPlayerMS::setPreload(WebMediaPlayer::Preload preload) {
194 DCHECK(thread_checker_.CalledOnValidThread());
197 bool WebMediaPlayerMS::hasVideo() const {
198 DCHECK(thread_checker_.CalledOnValidThread());
199 return (video_frame_provider_.get() != NULL);
202 bool WebMediaPlayerMS::hasAudio() const {
203 DCHECK(thread_checker_.CalledOnValidThread());
204 return (audio_renderer_.get() != NULL);
207 WebKit::WebSize WebMediaPlayerMS::naturalSize() const {
208 DCHECK(thread_checker_.CalledOnValidThread());
211 if (current_frame_.get())
212 size = current_frame_->natural_size();
213 DVLOG(3) << "WebMediaPlayerMS::naturalSize, " << size.ToString();
214 return WebKit::WebSize(size);
217 bool WebMediaPlayerMS::paused() const {
218 DCHECK(thread_checker_.CalledOnValidThread());
222 bool WebMediaPlayerMS::seeking() const {
223 DCHECK(thread_checker_.CalledOnValidThread());
227 double WebMediaPlayerMS::duration() const {
228 DCHECK(thread_checker_.CalledOnValidThread());
229 return std::numeric_limits<double>::infinity();
232 double WebMediaPlayerMS::currentTime() const {
233 DCHECK(thread_checker_.CalledOnValidThread());
234 if (current_frame_.get()) {
235 return current_frame_->GetTimestamp().InSecondsF();
236 } else if (audio_renderer_.get()) {
237 return audio_renderer_->GetCurrentRenderTime().InSecondsF();
242 WebMediaPlayer::NetworkState WebMediaPlayerMS::networkState() const {
243 DCHECK(thread_checker_.CalledOnValidThread());
244 DVLOG(1) << "WebMediaPlayerMS::networkState, state:" << network_state_;
245 return network_state_;
248 WebMediaPlayer::ReadyState WebMediaPlayerMS::readyState() const {
249 DCHECK(thread_checker_.CalledOnValidThread());
250 DVLOG(1) << "WebMediaPlayerMS::readyState, state:" << ready_state_;
254 const WebKit::WebTimeRanges& WebMediaPlayerMS::buffered() {
255 DCHECK(thread_checker_.CalledOnValidThread());
259 double WebMediaPlayerMS::maxTimeSeekable() const {
260 DCHECK(thread_checker_.CalledOnValidThread());
264 bool WebMediaPlayerMS::didLoadingProgress() const {
265 DCHECK(thread_checker_.CalledOnValidThread());
269 void WebMediaPlayerMS::paint(WebCanvas* canvas,
271 unsigned char alpha) {
272 DVLOG(3) << "WebMediaPlayerMS::paint";
273 DCHECK(thread_checker_.CalledOnValidThread());
275 gfx::RectF dest_rect(rect.x, rect.y, rect.width, rect.height);
276 video_renderer_.Paint(current_frame_.get(), canvas, dest_rect, alpha);
279 base::AutoLock auto_lock(current_frame_lock_);
280 if (current_frame_.get())
281 current_frame_used_ = true;
285 bool WebMediaPlayerMS::hasSingleSecurityOrigin() const {
286 DCHECK(thread_checker_.CalledOnValidThread());
290 bool WebMediaPlayerMS::didPassCORSAccessCheck() const {
291 DCHECK(thread_checker_.CalledOnValidThread());
295 double WebMediaPlayerMS::mediaTimeForTimeValue(double timeValue) const {
296 return ConvertSecondsToTimestamp(timeValue).InSecondsF();
299 unsigned WebMediaPlayerMS::decodedFrameCount() const {
300 DCHECK(thread_checker_.CalledOnValidThread());
301 DVLOG(1) << "WebMediaPlayerMS::decodedFrameCount, " << total_frame_count_;
302 return total_frame_count_;
305 unsigned WebMediaPlayerMS::droppedFrameCount() const {
306 DCHECK(thread_checker_.CalledOnValidThread());
307 DVLOG(1) << "WebMediaPlayerMS::droppedFrameCount, " << dropped_frame_count_;
308 return dropped_frame_count_;
311 unsigned WebMediaPlayerMS::audioDecodedByteCount() const {
312 DCHECK(thread_checker_.CalledOnValidThread());
317 unsigned WebMediaPlayerMS::videoDecodedByteCount() const {
318 DCHECK(thread_checker_.CalledOnValidThread());
323 void WebMediaPlayerMS::SetVideoFrameProviderClient(
324 cc::VideoFrameProvider::Client* client) {
325 // This is called from both the main renderer thread and the compositor
326 // thread (when the main thread is blocked).
327 if (video_frame_provider_client_)
328 video_frame_provider_client_->StopUsingProvider();
329 video_frame_provider_client_ = client;
332 scoped_refptr<media::VideoFrame> WebMediaPlayerMS::GetCurrentFrame() {
333 DVLOG(3) << "WebMediaPlayerMS::GetCurrentFrame";
334 base::AutoLock auto_lock(current_frame_lock_);
335 DCHECK(!pending_repaint_);
336 if (!current_frame_.get())
338 pending_repaint_ = true;
339 current_frame_used_ = true;
340 return current_frame_;
343 void WebMediaPlayerMS::PutCurrentFrame(
344 const scoped_refptr<media::VideoFrame>& frame) {
345 DVLOG(3) << "WebMediaPlayerMS::PutCurrentFrame";
346 DCHECK(pending_repaint_);
347 pending_repaint_ = false;
350 void WebMediaPlayerMS::OnFrameAvailable(
351 const scoped_refptr<media::VideoFrame>& frame) {
352 DVLOG(3) << "WebMediaPlayerMS::OnFrameAvailable";
353 DCHECK(thread_checker_.CalledOnValidThread());
354 ++total_frame_count_;
355 if (!received_first_frame_) {
356 received_first_frame_ = true;
358 base::AutoLock auto_lock(current_frame_lock_);
359 DCHECK(!current_frame_used_);
360 current_frame_ = frame;
362 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata);
363 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
364 GetClient()->sizeChanged();
366 if (video_frame_provider_.get() && GetClient()->needsWebLayerForVideo()) {
367 video_weblayer_.reset(
368 new webkit::WebLayerImpl(cc::VideoLayer::Create(this)));
369 GetClient()->setWebLayer(video_weblayer_.get());
373 // Do not update |current_frame_| when paused.
377 if (!sequence_started_) {
378 sequence_started_ = true;
379 start_time_ = frame->GetTimestamp();
381 bool size_changed = !current_frame_.get() ||
382 current_frame_->natural_size() != frame->natural_size();
385 base::AutoLock auto_lock(current_frame_lock_);
386 if (!current_frame_used_ && current_frame_.get())
387 ++dropped_frame_count_;
388 current_frame_ = frame;
389 current_frame_->SetTimestamp(frame->GetTimestamp() - start_time_);
390 current_frame_used_ = false;
394 GetClient()->sizeChanged();
396 GetClient()->repaint();
399 void WebMediaPlayerMS::RepaintInternal() {
400 DVLOG(1) << "WebMediaPlayerMS::RepaintInternal";
401 DCHECK(thread_checker_.CalledOnValidThread());
402 GetClient()->repaint();
405 void WebMediaPlayerMS::OnSourceError() {
406 DVLOG(1) << "WebMediaPlayerMS::OnSourceError";
407 DCHECK(thread_checker_.CalledOnValidThread());
408 SetNetworkState(WebMediaPlayer::NetworkStateFormatError);
412 void WebMediaPlayerMS::SetNetworkState(WebMediaPlayer::NetworkState state) {
413 DCHECK(thread_checker_.CalledOnValidThread());
414 network_state_ = state;
415 // Always notify to ensure client has the latest value.
416 GetClient()->networkStateChanged();
419 void WebMediaPlayerMS::SetReadyState(WebMediaPlayer::ReadyState state) {
420 DCHECK(thread_checker_.CalledOnValidThread());
421 ready_state_ = state;
422 // Always notify to ensure client has the latest value.
423 GetClient()->readyStateChanged();
426 WebKit::WebMediaPlayerClient* WebMediaPlayerMS::GetClient() {
427 DCHECK(thread_checker_.CalledOnValidThread());
432 } // namespace content