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
WebMediaPlayerMS(blink::WebFrame * frame,blink::WebMediaPlayerClient * client,base::WeakPtr<WebMediaPlayerDelegate> delegate,MediaStreamClient * media_stream_client,media::MediaLog * media_log)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
~WebMediaPlayerMS()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
load(LoadType load_type,const blink::WebURL & url,CORSMode cors_mode)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
play()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
pause()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
supportsFullscreen() const167 bool WebMediaPlayerMS::supportsFullscreen() const {
168 DCHECK(thread_checker_.CalledOnValidThread());
169 return true;
170 }
171
supportsSave() const172 bool WebMediaPlayerMS::supportsSave() const {
173 DCHECK(thread_checker_.CalledOnValidThread());
174 return false;
175 }
176
seek(double seconds)177 void WebMediaPlayerMS::seek(double seconds) {
178 DCHECK(thread_checker_.CalledOnValidThread());
179 }
180
setRate(double rate)181 void WebMediaPlayerMS::setRate(double rate) {
182 DCHECK(thread_checker_.CalledOnValidThread());
183 }
184
setVolume(double volume)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
setPreload(WebMediaPlayer::Preload preload)193 void WebMediaPlayerMS::setPreload(WebMediaPlayer::Preload preload) {
194 DCHECK(thread_checker_.CalledOnValidThread());
195 }
196
hasVideo() const197 bool WebMediaPlayerMS::hasVideo() const {
198 DCHECK(thread_checker_.CalledOnValidThread());
199 return (video_frame_provider_.get() != NULL);
200 }
201
hasAudio() const202 bool WebMediaPlayerMS::hasAudio() const {
203 DCHECK(thread_checker_.CalledOnValidThread());
204 return (audio_renderer_.get() != NULL);
205 }
206
naturalSize() const207 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
paused() const217 bool WebMediaPlayerMS::paused() const {
218 DCHECK(thread_checker_.CalledOnValidThread());
219 return paused_;
220 }
221
seeking() const222 bool WebMediaPlayerMS::seeking() const {
223 DCHECK(thread_checker_.CalledOnValidThread());
224 return false;
225 }
226
duration() const227 double WebMediaPlayerMS::duration() const {
228 DCHECK(thread_checker_.CalledOnValidThread());
229 return std::numeric_limits<double>::infinity();
230 }
231
currentTime() const232 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
networkState() const242 WebMediaPlayer::NetworkState WebMediaPlayerMS::networkState() const {
243 DCHECK(thread_checker_.CalledOnValidThread());
244 DVLOG(1) << "WebMediaPlayerMS::networkState, state:" << network_state_;
245 return network_state_;
246 }
247
readyState() const248 WebMediaPlayer::ReadyState WebMediaPlayerMS::readyState() const {
249 DCHECK(thread_checker_.CalledOnValidThread());
250 DVLOG(1) << "WebMediaPlayerMS::readyState, state:" << ready_state_;
251 return ready_state_;
252 }
253
buffered()254 const blink::WebTimeRanges& WebMediaPlayerMS::buffered() {
255 DCHECK(thread_checker_.CalledOnValidThread());
256 return buffered_;
257 }
258
maxTimeSeekable() const259 double WebMediaPlayerMS::maxTimeSeekable() const {
260 DCHECK(thread_checker_.CalledOnValidThread());
261 return 0.0;
262 }
263
didLoadingProgress() const264 bool WebMediaPlayerMS::didLoadingProgress() const {
265 DCHECK(thread_checker_.CalledOnValidThread());
266 return true;
267 }
268
paint(WebCanvas * canvas,const WebRect & rect,unsigned char alpha)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
hasSingleSecurityOrigin() const285 bool WebMediaPlayerMS::hasSingleSecurityOrigin() const {
286 DCHECK(thread_checker_.CalledOnValidThread());
287 return true;
288 }
289
didPassCORSAccessCheck() const290 bool WebMediaPlayerMS::didPassCORSAccessCheck() const {
291 DCHECK(thread_checker_.CalledOnValidThread());
292 return true;
293 }
294
mediaTimeForTimeValue(double timeValue) const295 double WebMediaPlayerMS::mediaTimeForTimeValue(double timeValue) const {
296 return ConvertSecondsToTimestamp(timeValue).InSecondsF();
297 }
298
decodedFrameCount() const299 unsigned WebMediaPlayerMS::decodedFrameCount() const {
300 DCHECK(thread_checker_.CalledOnValidThread());
301 DVLOG(1) << "WebMediaPlayerMS::decodedFrameCount, " << total_frame_count_;
302 return total_frame_count_;
303 }
304
droppedFrameCount() const305 unsigned WebMediaPlayerMS::droppedFrameCount() const {
306 DCHECK(thread_checker_.CalledOnValidThread());
307 DVLOG(1) << "WebMediaPlayerMS::droppedFrameCount, " << dropped_frame_count_;
308 return dropped_frame_count_;
309 }
310
audioDecodedByteCount() const311 unsigned WebMediaPlayerMS::audioDecodedByteCount() const {
312 DCHECK(thread_checker_.CalledOnValidThread());
313 NOTIMPLEMENTED();
314 return 0;
315 }
316
videoDecodedByteCount() const317 unsigned WebMediaPlayerMS::videoDecodedByteCount() const {
318 DCHECK(thread_checker_.CalledOnValidThread());
319 NOTIMPLEMENTED();
320 return 0;
321 }
322
SetVideoFrameProviderClient(cc::VideoFrameProvider::Client * client)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
GetCurrentFrame()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
PutCurrentFrame(const scoped_refptr<media::VideoFrame> & 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;
348 }
349
OnFrameAvailable(const scoped_refptr<media::VideoFrame> & frame)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
RepaintInternal()399 void WebMediaPlayerMS::RepaintInternal() {
400 DVLOG(1) << "WebMediaPlayerMS::RepaintInternal";
401 DCHECK(thread_checker_.CalledOnValidThread());
402 GetClient()->repaint();
403 }
404
OnSourceError()405 void WebMediaPlayerMS::OnSourceError() {
406 DVLOG(1) << "WebMediaPlayerMS::OnSourceError";
407 DCHECK(thread_checker_.CalledOnValidThread());
408 SetNetworkState(WebMediaPlayer::NetworkStateFormatError);
409 RepaintInternal();
410 }
411
SetNetworkState(WebMediaPlayer::NetworkState state)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
SetReadyState(WebMediaPlayer::ReadyState state)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
GetClient()426 blink::WebMediaPlayerClient* WebMediaPlayerMS::GetClient() {
427 DCHECK(thread_checker_.CalledOnValidThread());
428 DCHECK(client_);
429 return client_;
430 }
431
432 } // namespace content
433