Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1189)

Side by Side Diff: webkit/media/webmediaplayer_ms.cc

Issue 10918052: create a separate WebMediaPlayer for URL derived from media stream (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: code review Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 "webkit/media/webmediaplayer_ms.h"
6
7 #include <limits>
8
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/message_loop.h"
12 #include "base/metrics/histogram.h"
13 #include "media/base/media_log.h"
14 #include "media/base/video_frame.h"
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerClient. h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebVideoFrame.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
19 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h"
20 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h"
21 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h"
22 #include "v8/include/v8.h"
23 #include "webkit/media/media_stream_client.h"
24 #include "webkit/media/video_frame_provider.h"
25 #include "webkit/media/webmediaplayer_delegate.h"
26 #include "webkit/media/webmediaplayer_util.h"
27 #include "webkit/media/webvideoframe_impl.h"
28
29 using WebKit::WebCanvas;
30 using WebKit::WebMediaPlayer;
31 using WebKit::WebRect;
32 using WebKit::WebSize;
33
34 namespace {
35
36 // Amount of extra memory used by each player instance reported to V8.
37 // It is not exact number -- first, it differs on different platforms,
38 // and second, it is very hard to calculate. Instead, use some arbitrary
39 // value that will cause garbage collection from time to time. We don't want
40 // it to happen on every allocation, but don't want 5k players to sit in memory
41 // either. Looks that chosen constant achieves both goals, at least for audio
42 // objects. (Do not worry about video objects yet, JS programs do not create
43 // thousands of them...)
44 const int kPlayerExtraMemory = 1024 * 1024;
45
46 } // namespace
47
48 namespace webkit_media {
49
50 WebMediaPlayerMS::WebMediaPlayerMS(
51 WebKit::WebFrame* frame,
52 WebKit::WebMediaPlayerClient* client,
53 base::WeakPtr<WebMediaPlayerDelegate> delegate,
54 MediaStreamClient* media_stream_client,
55 media::MediaLog* media_log)
56 : frame_(frame),
57 network_state_(WebMediaPlayer::NetworkStateEmpty),
58 ready_state_(WebMediaPlayer::ReadyStateHaveNothing),
59 buffered_(static_cast<size_t>(1)),
60 client_(client),
61 delegate_(delegate),
62 media_stream_client_(media_stream_client),
63 video_frame_provider_started_(false),
64 paused_(true),
65 pending_repaint_(false),
66 got_first_frame_(false),
67 total_frame_count_(0),
68 dropped_frame_count_(0),
69 media_log_(media_log),
70 incremented_externally_allocated_memory_(false) {
71 DVLOG(1) << "WebMediaPlayerMS::ctor";
72 DCHECK(media_stream_client);
73 media_log_->AddEvent(
74 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED));
75
76 // Let V8 know we started new thread if we did not did it yet.
77 // Made separate task to avoid deletion of player currently being created.
78 // Also, delaying GC until after player starts gets rid of starting lag --
79 // collection happens in parallel with playing.
80 //
81 // TODO(enal): remove when we get rid of per-audio-stream thread.
82 MessageLoop::current()->PostTask(
83 FROM_HERE,
84 base::Bind(&WebMediaPlayerMS::IncrementExternallyAllocatedMemory,
85 AsWeakPtr()));
86 }
87
88 WebMediaPlayerMS::~WebMediaPlayerMS() {
89 DVLOG(1) << "WebMediaPlayerMS::dtor";
90 DCHECK(thread_checker_.CalledOnValidThread());
91 if (video_frame_provider_) {
92 video_frame_provider_->Stop();
93 }
94
95 // Let V8 know we are not using extra resources anymore.
96 if (incremented_externally_allocated_memory_) {
scherkus (not reviewing) 2012/09/13 10:22:43 remove all this incremented memory / V8 stuff -- y
wjia(left Chromium) 2012/09/19 03:22:06 Done.
97 v8::V8::AdjustAmountOfExternalAllocatedMemory(-kPlayerExtraMemory);
98 incremented_externally_allocated_memory_ = false;
99 }
100
101 media_log_->AddEvent(
102 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED));
103
104 if (delegate_)
105 delegate_->PlayerGone(this);
106 }
107
108 void WebMediaPlayerMS::load(const WebKit::WebURL& url, CORSMode cors_mode) {
109 DVLOG(1) << "WebMediaPlayerMS::load";
110 DCHECK(thread_checker_.CalledOnValidThread());
111
112 GURL gurl(url);
113
114 setVolume(GetClient()->volume());
115 SetNetworkState(WebMediaPlayer::NetworkStateLoading);
116 SetReadyState(WebMediaPlayer::ReadyStateHaveNothing);
117 media_log_->AddEvent(media_log_->CreateLoadEvent(url.spec()));
118
119 // Check if this url is media stream.
120 video_frame_provider_ = media_stream_client_->GetVideoFrameProvider(
121 url,
122 base::Bind(&WebMediaPlayerMS::OnSourceError, AsWeakPtr()),
123 base::Bind(&WebMediaPlayerMS::OnFrameAvailable, AsWeakPtr()));
124 if (video_frame_provider_) {
125 SetNetworkState(WebMediaPlayer::NetworkStateLoaded);
126 GetClient()->sourceOpened();
127 GetClient()->setOpaque(true);
128 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata);
129 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
130 RepaintInternal();
131 } else {
132 SetNetworkState(WebMediaPlayer::NetworkStateNetworkError);
133 }
134 }
135
136 void WebMediaPlayerMS::cancelLoad() {
137 DCHECK(thread_checker_.CalledOnValidThread());
138 }
139
140 void WebMediaPlayerMS::play() {
141 DVLOG(1) << "WebMediaPlayerMS::play";
142 DCHECK(thread_checker_.CalledOnValidThread());
143
144 paused_ = false;
145 if (video_frame_provider_) {
146 if (video_frame_provider_started_) {
147 video_frame_provider_->Play();
148 } else {
149 video_frame_provider_started_ = true;
150 video_frame_provider_->Start();
151 }
152 }
153 // TODO(wjia): add audio.
scherkus (not reviewing) 2012/09/13 10:22:43 can you reference the bug in the TODO?
wjia(left Chromium) 2012/09/19 03:22:06 Done.
154
155 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PLAY));
156
157 if (delegate_)
158 delegate_->DidPlay(this);
159 }
160
161 void WebMediaPlayerMS::pause() {
162 DVLOG(1) << "WebMediaPlayerMS::pause";
163 DCHECK(thread_checker_.CalledOnValidThread());
164
165 if (video_frame_provider_)
166 video_frame_provider_->Pause();
167 // TODO(wjia): add audio.
scherkus (not reviewing) 2012/09/13 10:22:43 can you reference the bug in the TODO?
wjia(left Chromium) 2012/09/19 03:22:06 Done.
168 paused_ = true;
169
170 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PAUSE));
171
172 if (delegate_)
173 delegate_->DidPause(this);
174 }
175
176 bool WebMediaPlayerMS::supportsFullscreen() const {
177 DCHECK(thread_checker_.CalledOnValidThread());
178 return true;
179 }
180
181 bool WebMediaPlayerMS::supportsSave() const {
182 DCHECK(thread_checker_.CalledOnValidThread());
183 return false;
184 }
185
186 void WebMediaPlayerMS::seek(float seconds) {
187 DCHECK(thread_checker_.CalledOnValidThread());
188 }
189
190 void WebMediaPlayerMS::setEndTime(float seconds) {
191 DCHECK(thread_checker_.CalledOnValidThread());
192 }
193
194 void WebMediaPlayerMS::setRate(float rate) {
195 DCHECK(thread_checker_.CalledOnValidThread());
196 }
197
198 void WebMediaPlayerMS::setVolume(float volume) {
199 DCHECK(thread_checker_.CalledOnValidThread());
200 // TODO(wjia): set audio volume.
scherkus (not reviewing) 2012/09/13 10:22:43 can you reference the bug in the TODO?
wjia(left Chromium) 2012/09/19 03:22:06 Done.
201 NOTIMPLEMENTED();
202 }
203
204 void WebMediaPlayerMS::setVisible(bool visible) {
205 DCHECK(thread_checker_.CalledOnValidThread());
206 }
207
208 void WebMediaPlayerMS::setPreload(WebMediaPlayer::Preload preload) {
209 DCHECK(thread_checker_.CalledOnValidThread());
210 }
211
212 bool WebMediaPlayerMS::totalBytesKnown() {
213 DCHECK(thread_checker_.CalledOnValidThread());
214 return false;
215 }
216
217 bool WebMediaPlayerMS::hasVideo() const {
218 DCHECK(thread_checker_.CalledOnValidThread());
219 return (video_frame_provider_ != NULL);
220 }
221
222 bool WebMediaPlayerMS::hasAudio() const {
223 DCHECK(thread_checker_.CalledOnValidThread());
224 // TODO(wjia): add audio support.
scherkus (not reviewing) 2012/09/13 10:22:43 can you reference the bug in the TODO?
wjia(left Chromium) 2012/09/19 03:22:06 Done.
225 return false;
226 }
227
228 WebKit::WebSize WebMediaPlayerMS::naturalSize() const {
229 DCHECK(thread_checker_.CalledOnValidThread());
230
231 gfx::Size size;
232 if (current_frame_)
233 size = current_frame_->natural_size();
234 DVLOG(1) << "WebMediaPlayerMS::naturalSize, " << size.ToString();
235 return WebKit::WebSize(size);
236 }
237
238 bool WebMediaPlayerMS::paused() const {
239 DCHECK(thread_checker_.CalledOnValidThread());
240 return paused_;
241 }
242
243 bool WebMediaPlayerMS::seeking() const {
244 DCHECK(thread_checker_.CalledOnValidThread());
245 return false;
246 }
247
248 float WebMediaPlayerMS::duration() const {
249 DCHECK(thread_checker_.CalledOnValidThread());
250 return std::numeric_limits<float>::infinity();
251 }
252
253 float WebMediaPlayerMS::currentTime() const {
254 DCHECK(thread_checker_.CalledOnValidThread());
255 if (current_frame_.get()) {
256 return current_frame_->GetTimestamp().InSecondsF();
257 }
258 return 0.0f;
259 }
260
261 int WebMediaPlayerMS::dataRate() const {
262 DCHECK(thread_checker_.CalledOnValidThread());
263 return 0;
264 }
265
266 WebMediaPlayer::NetworkState WebMediaPlayerMS::networkState() const {
267 DCHECK(thread_checker_.CalledOnValidThread());
268 DVLOG(1) << "WebMediaPlayerMS::networkState, state:" << network_state_;
269 return network_state_;
270 }
271
272 WebMediaPlayer::ReadyState WebMediaPlayerMS::readyState() const {
273 DCHECK(thread_checker_.CalledOnValidThread());
274 DVLOG(1) << "WebMediaPlayerMS::readyState, state:" << ready_state_;
275 return ready_state_;
276 }
277
278 const WebKit::WebTimeRanges& WebMediaPlayerMS::buffered() {
279 DCHECK(thread_checker_.CalledOnValidThread());
280 return buffered_;
281 }
282
283 float WebMediaPlayerMS::maxTimeSeekable() const {
284 DCHECK(thread_checker_.CalledOnValidThread());
285 return 0.0f;
286 }
287
288 bool WebMediaPlayerMS::didLoadingProgress() const {
289 DCHECK(thread_checker_.CalledOnValidThread());
290 return false;
291 }
292
293 unsigned long long WebMediaPlayerMS::totalBytes() const {
294 DCHECK(thread_checker_.CalledOnValidThread());
295 return 0;
296 }
297
298 void WebMediaPlayerMS::setSize(const WebSize& size) {
299 DCHECK(thread_checker_.CalledOnValidThread());
300 // Don't need to do anything as we use the dimensions passed in via paint().
301 }
302
303 void WebMediaPlayerMS::paint(WebCanvas* canvas,
304 const WebRect& rect,
305 uint8_t alpha) {
306 DVLOG(1) << "WebMediaPlayerMS::paint";
307 DCHECK(thread_checker_.CalledOnValidThread());
308
309 video_renderer_.Paint(current_frame_, canvas, rect, alpha);
310 }
311
312 bool WebMediaPlayerMS::hasSingleSecurityOrigin() const {
313 DCHECK(thread_checker_.CalledOnValidThread());
314 return true;
315 }
316
317 bool WebMediaPlayerMS::didPassCORSAccessCheck() const {
318 DCHECK(thread_checker_.CalledOnValidThread());
319 return true;
320 }
321
322 WebMediaPlayer::MovieLoadType WebMediaPlayerMS::movieLoadType() const {
323 DCHECK(thread_checker_.CalledOnValidThread());
324 return WebMediaPlayer::MovieLoadTypeUnknown;
325 }
326
327 float WebMediaPlayerMS::mediaTimeForTimeValue(float timeValue) const {
328 return ConvertSecondsToTimestamp(timeValue).InSecondsF();
329 }
330
331 unsigned WebMediaPlayerMS::decodedFrameCount() const {
332 DCHECK(thread_checker_.CalledOnValidThread());
333 DVLOG(1) << "WebMediaPlayerMS::decodedFrameCount, " << total_frame_count_;
334 return total_frame_count_;
335 }
336
337 unsigned WebMediaPlayerMS::droppedFrameCount() const {
338 DCHECK(thread_checker_.CalledOnValidThread());
339 DVLOG(1) << "WebMediaPlayerMS::droppedFrameCount, " << dropped_frame_count_;
340 return dropped_frame_count_;
341 }
342
343 unsigned WebMediaPlayerMS::audioDecodedByteCount() const {
344 DCHECK(thread_checker_.CalledOnValidThread());
345 NOTIMPLEMENTED();
346 return 0;
347 }
348
349 unsigned WebMediaPlayerMS::videoDecodedByteCount() const {
350 DCHECK(thread_checker_.CalledOnValidThread());
351 NOTIMPLEMENTED();
352 return 0;
353 }
354
355 WebKit::WebVideoFrame* WebMediaPlayerMS::getCurrentFrame() {
356 DVLOG(1) << "WebMediaPlayerMS::getCurrentFrame";
357 DCHECK(thread_checker_.CalledOnValidThread());
358 DCHECK(!pending_repaint_);
359 pending_repaint_ = true;
360 if (current_frame_.get())
361 return new webkit_media::WebVideoFrameImpl(current_frame_);
362 return NULL;
363 }
364
365 void WebMediaPlayerMS::putCurrentFrame(
366 WebKit::WebVideoFrame* web_video_frame) {
367 DVLOG(1) << "WebMediaPlayerMS::putCurrentFrame";
368 DCHECK(thread_checker_.CalledOnValidThread());
369 DCHECK(pending_repaint_);
370 pending_repaint_ = false;
371 if (web_video_frame) {
372 delete web_video_frame;
373 }
374 }
375
376 void WebMediaPlayerMS::OnFrameAvailable(
377 const scoped_refptr<media::VideoFrame>& frame) {
378 DVLOG(1) << "WebMediaPlayerMS::OnFrameAvailable";
379 DCHECK(thread_checker_.CalledOnValidThread());
380 ++total_frame_count_;
381 if (!got_first_frame_) {
382 got_first_frame_ = true;
383 start_time_ = frame->GetTimestamp();
384 }
385 current_frame_ = frame;
386 current_frame_->SetTimestamp(frame->GetTimestamp() - start_time_);
387 if (pending_repaint_) {
388 // TODO(wjia): Figure out how to calculate dropped frame count for
389 // both S/W and H/W compositing.
390 // ++dropped_frame_count_;
391 } else {
392 GetClient()->repaint();
393 }
394 }
395
396 void WebMediaPlayerMS::RepaintInternal() {
397 DVLOG(1) << "WebMediaPlayerMS::RepaintInternal";
398 DCHECK(thread_checker_.CalledOnValidThread());
399 if (!pending_repaint_) {
400 GetClient()->repaint();
401 }
402 }
403
404 void WebMediaPlayerMS::OnSourceError() {
405 DVLOG(1) << "WebMediaPlayerMS::OnSourceError";
406 DCHECK(thread_checker_.CalledOnValidThread());
407 SetNetworkState(WebMediaPlayer::NetworkStateFormatError);
408 RepaintInternal();
409 }
410
411 void WebMediaPlayerMS::SetNetworkState(WebMediaPlayer::NetworkState state) {
412 DCHECK(thread_checker_.CalledOnValidThread());
413 network_state_ = state;
414 // Always notify to ensure client has the latest value.
415 GetClient()->networkStateChanged();
416 }
417
418 void WebMediaPlayerMS::SetReadyState(WebMediaPlayer::ReadyState state) {
419 DCHECK(thread_checker_.CalledOnValidThread());
420 ready_state_ = state;
421 // Always notify to ensure client has the latest value.
422 GetClient()->readyStateChanged();
423 }
424
425 WebKit::WebMediaPlayerClient* WebMediaPlayerMS::GetClient() {
426 DCHECK(thread_checker_.CalledOnValidThread());
427 DCHECK(client_);
428 return client_;
429 }
430
431 void WebMediaPlayerMS::IncrementExternallyAllocatedMemory() {
432 DCHECK(thread_checker_.CalledOnValidThread());
433 incremented_externally_allocated_memory_ = true;
434 v8::V8::AdjustAmountOfExternalAllocatedMemory(kPlayerExtraMemory);
435 }
436
437 } // namespace webkit_media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698