webmediaplayer_ms.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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.
4
5#include "content/renderer/media/webmediaplayer_ms.h"
6
7#include <limits>
8
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/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 "content/renderer/render_frame_impl.h"
20#include "media/base/media_log.h"
21#include "media/base/video_frame.h"
22#include "third_party/WebKit/public/platform/WebMediaPlayerClient.h"
23#include "third_party/WebKit/public/platform/WebRect.h"
24#include "third_party/WebKit/public/platform/WebSize.h"
25#include "third_party/WebKit/public/platform/WebURL.h"
26#include "third_party/WebKit/public/web/WebFrame.h"
27#include "third_party/WebKit/public/web/WebView.h"
28#include "webkit/renderer/compositor_bindings/web_layer_impl.h"
29
30using blink::WebCanvas;
31using blink::WebMediaPlayer;
32using blink::WebRect;
33using blink::WebSize;
34
35namespace content {
36
37WebMediaPlayerMS::WebMediaPlayerMS(
38    blink::WebFrame* frame,
39    blink::WebMediaPlayerClient* client,
40    base::WeakPtr<WebMediaPlayerDelegate> delegate,
41    MediaStreamClient* media_stream_client,
42    media::MediaLog* media_log)
43    : frame_(frame),
44      network_state_(WebMediaPlayer::NetworkStateEmpty),
45      ready_state_(WebMediaPlayer::ReadyStateHaveNothing),
46      buffered_(static_cast<size_t>(1)),
47      client_(client),
48      delegate_(delegate),
49      media_stream_client_(media_stream_client),
50      paused_(true),
51      current_frame_used_(false),
52      pending_repaint_(false),
53      video_frame_provider_client_(NULL),
54      received_first_frame_(false),
55      sequence_started_(false),
56      total_frame_count_(0),
57      dropped_frame_count_(0),
58      media_log_(media_log) {
59  DVLOG(1) << "WebMediaPlayerMS::ctor";
60  DCHECK(media_stream_client);
61  media_log_->AddEvent(
62      media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED));
63}
64
65WebMediaPlayerMS::~WebMediaPlayerMS() {
66  DVLOG(1) << "WebMediaPlayerMS::dtor";
67  DCHECK(thread_checker_.CalledOnValidThread());
68
69  SetVideoFrameProviderClient(NULL);
70  GetClient()->setWebLayer(NULL);
71
72  if (video_frame_provider_.get())
73    video_frame_provider_->Stop();
74
75  if (audio_renderer_.get())
76    audio_renderer_->Stop();
77
78  media_log_->AddEvent(
79      media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED));
80
81  if (delegate_.get())
82    delegate_->PlayerGone(this);
83}
84
85void WebMediaPlayerMS::load(LoadType load_type,
86                            const blink::WebURL& url,
87                            CORSMode cors_mode) {
88  DVLOG(1) << "WebMediaPlayerMS::load";
89  DCHECK(thread_checker_.CalledOnValidThread());
90
91  // TODO(acolwell): Change this to DCHECK_EQ(load_type,
92  // LoadTypeMediaStream) once Blink-side changes land.
93  DCHECK_NE(load_type, LoadTypeMediaSource);
94
95  GURL gurl(url);
96
97  setVolume(GetClient()->volume());
98  SetNetworkState(WebMediaPlayer::NetworkStateLoading);
99  SetReadyState(WebMediaPlayer::ReadyStateHaveNothing);
100  media_log_->AddEvent(media_log_->CreateLoadEvent(url.spec()));
101
102  // Check if this url is media stream.
103  video_frame_provider_ = media_stream_client_->GetVideoFrameProvider(
104      url,
105      base::Bind(&WebMediaPlayerMS::OnSourceError, AsWeakPtr()),
106      base::Bind(&WebMediaPlayerMS::OnFrameAvailable, AsWeakPtr()));
107
108  audio_renderer_ = media_stream_client_->GetAudioRenderer(
109    url,
110    RenderFrame::FromWebFrame(frame_)->GetRoutingID());
111
112  if (video_frame_provider_.get() || audio_renderer_.get()) {
113    GetClient()->setOpaque(true);
114    if (audio_renderer_.get())
115      audio_renderer_->Start();
116
117    if (video_frame_provider_.get()) {
118      video_frame_provider_->Start();
119    } else {
120      // This is audio-only mode.
121      DCHECK(audio_renderer_.get());
122      SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata);
123      SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
124    }
125  } else {
126    SetNetworkState(WebMediaPlayer::NetworkStateNetworkError);
127  }
128}
129
130void WebMediaPlayerMS::play() {
131  DVLOG(1) << "WebMediaPlayerMS::play";
132  DCHECK(thread_checker_.CalledOnValidThread());
133
134  if (paused_) {
135    if (video_frame_provider_.get())
136      video_frame_provider_->Play();
137
138    if (audio_renderer_.get())
139      audio_renderer_->Play();
140
141    if (delegate_.get())
142      delegate_->DidPlay(this);
143  }
144
145  paused_ = false;
146
147  media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PLAY));
148}
149
150void WebMediaPlayerMS::pause() {
151  DVLOG(1) << "WebMediaPlayerMS::pause";
152  DCHECK(thread_checker_.CalledOnValidThread());
153
154  if (video_frame_provider_.get())
155    video_frame_provider_->Pause();
156
157  if (!paused_) {
158    if (audio_renderer_.get())
159      audio_renderer_->Pause();
160
161    if (delegate_.get())
162      delegate_->DidPause(this);
163  }
164
165  paused_ = true;
166
167  media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PAUSE));
168}
169
170bool WebMediaPlayerMS::supportsSave() const {
171  DCHECK(thread_checker_.CalledOnValidThread());
172  return false;
173}
174
175void WebMediaPlayerMS::seek(double seconds) {
176  DCHECK(thread_checker_.CalledOnValidThread());
177}
178
179void WebMediaPlayerMS::setRate(double rate) {
180  DCHECK(thread_checker_.CalledOnValidThread());
181}
182
183void WebMediaPlayerMS::setVolume(double volume) {
184  DCHECK(thread_checker_.CalledOnValidThread());
185  if (!audio_renderer_.get())
186    return;
187  DVLOG(1) << "WebMediaPlayerMS::setVolume(volume=" << volume << ")";
188  audio_renderer_->SetVolume(volume);
189}
190
191void WebMediaPlayerMS::setPreload(WebMediaPlayer::Preload preload) {
192  DCHECK(thread_checker_.CalledOnValidThread());
193}
194
195bool WebMediaPlayerMS::hasVideo() const {
196  DCHECK(thread_checker_.CalledOnValidThread());
197  return (video_frame_provider_.get() != NULL);
198}
199
200bool WebMediaPlayerMS::hasAudio() const {
201  DCHECK(thread_checker_.CalledOnValidThread());
202  return (audio_renderer_.get() != NULL);
203}
204
205blink::WebSize WebMediaPlayerMS::naturalSize() const {
206  DCHECK(thread_checker_.CalledOnValidThread());
207
208  gfx::Size size;
209  if (current_frame_.get())
210    size = current_frame_->natural_size();
211  DVLOG(3) << "WebMediaPlayerMS::naturalSize, " << size.ToString();
212  return blink::WebSize(size);
213}
214
215bool WebMediaPlayerMS::paused() const {
216  DCHECK(thread_checker_.CalledOnValidThread());
217  return paused_;
218}
219
220bool WebMediaPlayerMS::seeking() const {
221  DCHECK(thread_checker_.CalledOnValidThread());
222  return false;
223}
224
225double WebMediaPlayerMS::duration() const {
226  DCHECK(thread_checker_.CalledOnValidThread());
227  return std::numeric_limits<double>::infinity();
228}
229
230double WebMediaPlayerMS::currentTime() const {
231  DCHECK(thread_checker_.CalledOnValidThread());
232  if (current_frame_.get()) {
233    return current_frame_->GetTimestamp().InSecondsF();
234  } else if (audio_renderer_.get()) {
235    return audio_renderer_->GetCurrentRenderTime().InSecondsF();
236  }
237  return 0.0;
238}
239
240WebMediaPlayer::NetworkState WebMediaPlayerMS::networkState() const {
241  DCHECK(thread_checker_.CalledOnValidThread());
242  DVLOG(1) << "WebMediaPlayerMS::networkState, state:" << network_state_;
243  return network_state_;
244}
245
246WebMediaPlayer::ReadyState WebMediaPlayerMS::readyState() const {
247  DCHECK(thread_checker_.CalledOnValidThread());
248  DVLOG(1) << "WebMediaPlayerMS::readyState, state:" << ready_state_;
249  return ready_state_;
250}
251
252const blink::WebTimeRanges& WebMediaPlayerMS::buffered() {
253  DCHECK(thread_checker_.CalledOnValidThread());
254  return buffered_;
255}
256
257double WebMediaPlayerMS::maxTimeSeekable() const {
258  DCHECK(thread_checker_.CalledOnValidThread());
259  return 0.0;
260}
261
262bool WebMediaPlayerMS::didLoadingProgress() const {
263  DCHECK(thread_checker_.CalledOnValidThread());
264  return true;
265}
266
267void WebMediaPlayerMS::paint(WebCanvas* canvas,
268                             const WebRect& rect,
269                             unsigned char alpha) {
270  DVLOG(3) << "WebMediaPlayerMS::paint";
271  DCHECK(thread_checker_.CalledOnValidThread());
272
273  gfx::RectF dest_rect(rect.x, rect.y, rect.width, rect.height);
274  video_renderer_.Paint(current_frame_.get(), canvas, dest_rect, alpha);
275
276  {
277    base::AutoLock auto_lock(current_frame_lock_);
278    if (current_frame_.get())
279      current_frame_used_ = true;
280  }
281}
282
283bool WebMediaPlayerMS::hasSingleSecurityOrigin() const {
284  DCHECK(thread_checker_.CalledOnValidThread());
285  return true;
286}
287
288bool WebMediaPlayerMS::didPassCORSAccessCheck() const {
289  DCHECK(thread_checker_.CalledOnValidThread());
290  return true;
291}
292
293double WebMediaPlayerMS::mediaTimeForTimeValue(double timeValue) const {
294  return ConvertSecondsToTimestamp(timeValue).InSecondsF();
295}
296
297unsigned WebMediaPlayerMS::decodedFrameCount() const {
298  DCHECK(thread_checker_.CalledOnValidThread());
299  DVLOG(1) << "WebMediaPlayerMS::decodedFrameCount, " << total_frame_count_;
300  return total_frame_count_;
301}
302
303unsigned WebMediaPlayerMS::droppedFrameCount() const {
304  DCHECK(thread_checker_.CalledOnValidThread());
305  DVLOG(1) << "WebMediaPlayerMS::droppedFrameCount, " << dropped_frame_count_;
306  return dropped_frame_count_;
307}
308
309unsigned WebMediaPlayerMS::audioDecodedByteCount() const {
310  DCHECK(thread_checker_.CalledOnValidThread());
311  NOTIMPLEMENTED();
312  return 0;
313}
314
315unsigned WebMediaPlayerMS::videoDecodedByteCount() const {
316  DCHECK(thread_checker_.CalledOnValidThread());
317  NOTIMPLEMENTED();
318  return 0;
319}
320
321void WebMediaPlayerMS::SetVideoFrameProviderClient(
322    cc::VideoFrameProvider::Client* client) {
323  // This is called from both the main renderer thread and the compositor
324  // thread (when the main thread is blocked).
325  if (video_frame_provider_client_)
326    video_frame_provider_client_->StopUsingProvider();
327  video_frame_provider_client_ = client;
328}
329
330scoped_refptr<media::VideoFrame> WebMediaPlayerMS::GetCurrentFrame() {
331  DVLOG(3) << "WebMediaPlayerMS::GetCurrentFrame";
332  base::AutoLock auto_lock(current_frame_lock_);
333  DCHECK(!pending_repaint_);
334  if (!current_frame_.get())
335    return NULL;
336  pending_repaint_ = true;
337  current_frame_used_ = true;
338  return current_frame_;
339}
340
341void WebMediaPlayerMS::PutCurrentFrame(
342    const scoped_refptr<media::VideoFrame>& frame) {
343  DVLOG(3) << "WebMediaPlayerMS::PutCurrentFrame";
344  DCHECK(pending_repaint_);
345  pending_repaint_ = false;
346}
347
348void WebMediaPlayerMS::OnFrameAvailable(
349    const scoped_refptr<media::VideoFrame>& frame) {
350  DVLOG(3) << "WebMediaPlayerMS::OnFrameAvailable";
351  DCHECK(thread_checker_.CalledOnValidThread());
352  ++total_frame_count_;
353  if (!received_first_frame_) {
354    received_first_frame_ = true;
355    {
356      base::AutoLock auto_lock(current_frame_lock_);
357      DCHECK(!current_frame_used_);
358      current_frame_ = frame;
359    }
360    SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata);
361    SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
362    GetClient()->sizeChanged();
363
364    if (video_frame_provider_.get() && GetClient()->needsWebLayerForVideo()) {
365      video_weblayer_.reset(
366          new webkit::WebLayerImpl(cc::VideoLayer::Create(this)));
367      GetClient()->setWebLayer(video_weblayer_.get());
368    }
369  }
370
371  // Do not update |current_frame_| when paused.
372  if (paused_)
373    return;
374
375  if (!sequence_started_) {
376    sequence_started_ = true;
377    start_time_ = frame->GetTimestamp();
378  }
379  bool size_changed = !current_frame_.get() ||
380                      current_frame_->natural_size() != frame->natural_size();
381
382  {
383    base::AutoLock auto_lock(current_frame_lock_);
384    if (!current_frame_used_ && current_frame_.get())
385      ++dropped_frame_count_;
386    current_frame_ = frame;
387    current_frame_->SetTimestamp(frame->GetTimestamp() - start_time_);
388    current_frame_used_ = false;
389  }
390
391  if (size_changed)
392    GetClient()->sizeChanged();
393
394  GetClient()->repaint();
395}
396
397void WebMediaPlayerMS::RepaintInternal() {
398  DVLOG(1) << "WebMediaPlayerMS::RepaintInternal";
399  DCHECK(thread_checker_.CalledOnValidThread());
400  GetClient()->repaint();
401}
402
403void WebMediaPlayerMS::OnSourceError() {
404  DVLOG(1) << "WebMediaPlayerMS::OnSourceError";
405  DCHECK(thread_checker_.CalledOnValidThread());
406  SetNetworkState(WebMediaPlayer::NetworkStateFormatError);
407  RepaintInternal();
408}
409
410void WebMediaPlayerMS::SetNetworkState(WebMediaPlayer::NetworkState state) {
411  DCHECK(thread_checker_.CalledOnValidThread());
412  network_state_ = state;
413  // Always notify to ensure client has the latest value.
414  GetClient()->networkStateChanged();
415}
416
417void WebMediaPlayerMS::SetReadyState(WebMediaPlayer::ReadyState state) {
418  DCHECK(thread_checker_.CalledOnValidThread());
419  ready_state_ = state;
420  // Always notify to ensure client has the latest value.
421  GetClient()->readyStateChanged();
422}
423
424blink::WebMediaPlayerClient* WebMediaPlayerMS::GetClient() {
425  DCHECK(thread_checker_.CalledOnValidThread());
426  DCHECK(client_);
427  return client_;
428}
429
430}  // namespace content
431