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