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