- add sources.
[platform/framework/web/crosswalk.git] / src / content / renderer / media / webmediaplayer_ms.cc
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/WebRect.h"
22 #include "third_party/WebKit/public/platform/WebSize.h"
23 #include "third_party/WebKit/public/platform/WebURL.h"
24 #include "third_party/WebKit/public/web/WebFrame.h"
25 #include "third_party/WebKit/public/web/WebMediaPlayerClient.h"
26 #include "third_party/WebKit/public/web/WebView.h"
27 #include "webkit/renderer/compositor_bindings/web_layer_impl.h"
28
29 using WebKit::WebCanvas;
30 using WebKit::WebMediaPlayer;
31 using WebKit::WebRect;
32 using WebKit::WebSize;
33
34 namespace content {
35
36 WebMediaPlayerMS::WebMediaPlayerMS(
37     WebKit::WebFrame* frame,
38     WebKit::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 WebKit::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 WebKit::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 WebKit::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 WebKit::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 WebKit::WebMediaPlayerClient* WebMediaPlayerMS::GetClient() {
427   DCHECK(thread_checker_.CalledOnValidThread());
428   DCHECK(client_);
429   return client_;
430 }
431
432 }  // namespace content