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