blob: 3801406777c7b229fb93ccec194852379e239102 [file] [log] [blame]
[email protected]b781e772011-02-04 20:27:511// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]891acc92009-04-27 19:56:412// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
[email protected]ec9212f2008-12-18 21:40:364
[email protected]8931c41a2009-07-07 17:31:495#include "webkit/glue/webmediaplayer_impl.h"
6
[email protected]47b06ceb2010-08-04 22:41:117#include <limits>
8
[email protected]2041cf342010-02-19 03:15:599#include "base/callback.h"
[email protected]963ab912010-01-22 19:56:1410#include "base/command_line.h"
[email protected]f8db8132010-12-03 00:27:4911#include "media/base/filter_collection.h"
[email protected]32da1002010-03-03 21:57:3512#include "media/base/limits.h"
[email protected]38259a7a82009-07-29 21:49:4913#include "media/base/media_format.h"
[email protected]963ab912010-01-22 19:56:1414#include "media/base/media_switches.h"
[email protected]583634b2010-11-11 17:47:1515#include "media/base/pipeline_impl.h"
[email protected]e81283bb2010-08-31 18:01:2116#include "media/base/video_frame.h"
[email protected]4c616fa52009-03-30 20:10:0717#include "media/filters/ffmpeg_audio_decoder.h"
[email protected]3f06d0ef2009-03-19 01:35:3618#include "media/filters/ffmpeg_demuxer.h"
[email protected]720ac732009-04-02 23:55:4419#include "media/filters/ffmpeg_video_decoder.h"
[email protected]891acc92009-04-27 19:56:4120#include "media/filters/null_audio_renderer.h"
[email protected]776775e2009-09-21 15:21:2921#include "skia/ext/platform_canvas.h"
[email protected]c1d9cdc2011-01-17 06:50:0122#include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h"
23#include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h"
24#include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h"
25#include "third_party/WebKit/Source/WebKit/chromium/public/WebVideoFrame.h"
[email protected]5b5bb9d2010-10-22 19:57:3626#include "webkit/glue/media/buffered_data_source.h"
[email protected]5b5bb9d2010-10-22 19:57:3627#include "webkit/glue/media/simple_data_source.h"
[email protected]add51772009-06-11 18:25:1728#include "webkit/glue/media/video_renderer_impl.h"
[email protected]8400e032010-02-26 18:50:1129#include "webkit/glue/media/web_video_renderer.h"
[email protected]e81283bb2010-08-31 18:01:2130#include "webkit/glue/webvideoframe_impl.h"
[email protected]b3f2b912009-04-09 16:18:5231
[email protected]df143bdc2009-06-16 17:34:1932using WebKit::WebCanvas;
[email protected]b3f2b912009-04-09 16:18:5233using WebKit::WebRect;
34using WebKit::WebSize;
[email protected]ec9212f2008-12-18 21:40:3635
[email protected]8931c41a2009-07-07 17:31:4936namespace {
37
38// Limits the maximum outstanding repaints posted on render thread.
39// This number of 50 is a guess, it does not take too much memory on the task
40// queue but gives up a pretty good latency on repaint.
41const int kMaxOutstandingRepaints = 50;
42
[email protected]378f0b72009-08-11 17:11:4243// Limits the range of playback rate.
44//
45// TODO(kylep): Revisit these.
46//
47// Vista has substantially lower performance than XP or Windows7. If you speed
48// up a video too much, it can't keep up, and rendering stops updating except on
49// the time bar. For really high speeds, audio becomes a bottleneck and we just
50// use up the data we have, which may not achieve the speed requested, but will
51// not crash the tab.
52//
53// A very slow speed, ie 0.00000001x, causes the machine to lock up. (It seems
54// like a busy loop). It gets unresponsive, although its not completely dead.
55//
56// Also our timers are not very accurate (especially for ogg), which becomes
57// evident at low speeds and on Vista. Since other speeds are risky and outside
58// the norms, we think 1/16x to 16x is a safe and useful range for now.
59const float kMinRate = 0.0625f;
60const float kMaxRate = 16.0f;
61
[email protected]b781e772011-02-04 20:27:5162// Platform independent method for converting and rounding floating point
63// seconds to an int64 timestamp.
64//
65// Refer to https://bugs.webkit.org/show_bug.cgi?id=52697 for details.
66base::TimeDelta ConvertSecondsToTimestamp(float seconds) {
67 float microseconds = seconds * base::Time::kMicrosecondsPerSecond;
68 float integer = ceilf(microseconds);
69 float difference = integer - microseconds;
70
71 // Round down if difference is large enough.
72 if ((microseconds > 0 && difference > 0.5f) ||
73 (microseconds <= 0 && difference >= 0.5f)) {
74 integer -= 1.0f;
75 }
76
77 // Now we can safely cast to int64 microseconds.
78 return base::TimeDelta::FromMicroseconds(static_cast<int64>(integer));
79}
80
[email protected]8931c41a2009-07-07 17:31:4981} // namespace
82
[email protected]add51772009-06-11 18:25:1783namespace webkit_glue {
84
[email protected]d43ed912009-02-03 04:52:5385/////////////////////////////////////////////////////////////////////////////
[email protected]8931c41a2009-07-07 17:31:4986// WebMediaPlayerImpl::Proxy implementation
[email protected]d43ed912009-02-03 04:52:5387
[email protected]8931c41a2009-07-07 17:31:4988WebMediaPlayerImpl::Proxy::Proxy(MessageLoop* render_loop,
89 WebMediaPlayerImpl* webmediaplayer)
90 : render_loop_(render_loop),
91 webmediaplayer_(webmediaplayer),
92 outstanding_repaints_(0) {
93 DCHECK(render_loop_);
94 DCHECK(webmediaplayer_);
95}
[email protected]d43ed912009-02-03 04:52:5396
[email protected]8931c41a2009-07-07 17:31:4997WebMediaPlayerImpl::Proxy::~Proxy() {
98 Detach();
99}
100
101void WebMediaPlayerImpl::Proxy::Repaint() {
[email protected]20305ec2011-01-21 04:55:52102 base::AutoLock auto_lock(lock_);
[email protected]8931c41a2009-07-07 17:31:49103 if (outstanding_repaints_ < kMaxOutstandingRepaints) {
104 ++outstanding_repaints_;
105
106 render_loop_->PostTask(FROM_HERE,
107 NewRunnableMethod(this, &WebMediaPlayerImpl::Proxy::RepaintTask));
[email protected]d43ed912009-02-03 04:52:53108 }
[email protected]8931c41a2009-07-07 17:31:49109}
[email protected]d43ed912009-02-03 04:52:53110
[email protected]8931c41a2009-07-07 17:31:49111void WebMediaPlayerImpl::Proxy::SetVideoRenderer(
[email protected]457d8342010-10-23 01:20:37112 scoped_refptr<WebVideoRenderer> video_renderer) {
[email protected]8931c41a2009-07-07 17:31:49113 video_renderer_ = video_renderer;
114}
115
[email protected]f63760a2011-02-16 04:59:10116void WebMediaPlayerImpl::Proxy::AddDataSource(
[email protected]cf31d6f2010-10-26 02:23:47117 scoped_refptr<WebDataSource> data_source) {
[email protected]f63760a2011-02-16 04:59:10118 base::AutoLock auto_lock(data_sources_lock_);
119 data_sources_.push_back(data_source);
[email protected]cf31d6f2010-10-26 02:23:47120}
121
[email protected]8931c41a2009-07-07 17:31:49122void WebMediaPlayerImpl::Proxy::Paint(skia::PlatformCanvas* canvas,
123 const gfx::Rect& dest_rect) {
124 DCHECK(MessageLoop::current() == render_loop_);
125 if (video_renderer_) {
126 video_renderer_->Paint(canvas, dest_rect);
127 }
128}
129
130void WebMediaPlayerImpl::Proxy::SetSize(const gfx::Rect& rect) {
131 DCHECK(MessageLoop::current() == render_loop_);
132 if (video_renderer_) {
133 video_renderer_->SetRect(rect);
134 }
135}
136
[email protected]cf31d6f2010-10-26 02:23:47137bool WebMediaPlayerImpl::Proxy::HasSingleOrigin() {
138 DCHECK(MessageLoop::current() == render_loop_);
[email protected]f63760a2011-02-16 04:59:10139
140 base::AutoLock auto_lock(data_sources_lock_);
141
142 for (DataSourceList::iterator itr = data_sources_.begin();
143 itr != data_sources_.end();
144 itr++) {
145 if (!(*itr)->HasSingleOrigin())
146 return false;
[email protected]cf31d6f2010-10-26 02:23:47147 }
148 return true;
149}
150
[email protected]f63760a2011-02-16 04:59:10151void WebMediaPlayerImpl::Proxy::AbortDataSources() {
[email protected]5b5bb9d2010-10-22 19:57:36152 DCHECK(MessageLoop::current() == render_loop_);
[email protected]f63760a2011-02-16 04:59:10153 base::AutoLock auto_lock(data_sources_lock_);
154
155 for (DataSourceList::iterator itr = data_sources_.begin();
156 itr != data_sources_.end();
157 itr++) {
158 (*itr)->Abort();
[email protected]5b5bb9d2010-10-22 19:57:36159 }
160}
161
[email protected]8931c41a2009-07-07 17:31:49162void WebMediaPlayerImpl::Proxy::Detach() {
163 DCHECK(MessageLoop::current() == render_loop_);
164 webmediaplayer_ = NULL;
165 video_renderer_ = NULL;
[email protected]f63760a2011-02-16 04:59:10166
167 {
168 base::AutoLock auto_lock(data_sources_lock_);
169 data_sources_.clear();
170 }
[email protected]8931c41a2009-07-07 17:31:49171}
172
[email protected]96706912009-07-15 17:18:05173void WebMediaPlayerImpl::Proxy::PipelineInitializationCallback() {
174 render_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
175 &WebMediaPlayerImpl::Proxy::PipelineInitializationTask));
176}
177
178void WebMediaPlayerImpl::Proxy::PipelineSeekCallback() {
179 render_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
180 &WebMediaPlayerImpl::Proxy::PipelineSeekTask));
181}
182
[email protected]576537842009-08-12 23:52:05183void WebMediaPlayerImpl::Proxy::PipelineEndedCallback() {
184 render_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
185 &WebMediaPlayerImpl::Proxy::PipelineEndedTask));
186}
187
[email protected]db190487d2009-07-30 18:51:52188void WebMediaPlayerImpl::Proxy::PipelineErrorCallback() {
189 render_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
190 &WebMediaPlayerImpl::Proxy::PipelineErrorTask));
191}
192
[email protected]4f92fbc2009-10-16 01:29:50193void WebMediaPlayerImpl::Proxy::NetworkEventCallback() {
194 render_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
195 &WebMediaPlayerImpl::Proxy::NetworkEventTask));
196}
197
[email protected]96706912009-07-15 17:18:05198void WebMediaPlayerImpl::Proxy::RepaintTask() {
199 DCHECK(MessageLoop::current() == render_loop_);
200 {
[email protected]20305ec2011-01-21 04:55:52201 base::AutoLock auto_lock(lock_);
[email protected]96706912009-07-15 17:18:05202 --outstanding_repaints_;
203 DCHECK_GE(outstanding_repaints_, 0);
204 }
205 if (webmediaplayer_) {
206 webmediaplayer_->Repaint();
[email protected]8931c41a2009-07-07 17:31:49207 }
208}
209
[email protected]96706912009-07-15 17:18:05210void WebMediaPlayerImpl::Proxy::PipelineInitializationTask() {
211 DCHECK(MessageLoop::current() == render_loop_);
212 if (webmediaplayer_) {
213 webmediaplayer_->OnPipelineInitialize();
214 }
215}
216
217void WebMediaPlayerImpl::Proxy::PipelineSeekTask() {
218 DCHECK(MessageLoop::current() == render_loop_);
219 if (webmediaplayer_) {
220 webmediaplayer_->OnPipelineSeek();
221 }
[email protected]8931c41a2009-07-07 17:31:49222}
[email protected]d43ed912009-02-03 04:52:53223
[email protected]576537842009-08-12 23:52:05224void WebMediaPlayerImpl::Proxy::PipelineEndedTask() {
225 DCHECK(MessageLoop::current() == render_loop_);
226 if (webmediaplayer_) {
227 webmediaplayer_->OnPipelineEnded();
228 }
229}
230
[email protected]db190487d2009-07-30 18:51:52231void WebMediaPlayerImpl::Proxy::PipelineErrorTask() {
232 DCHECK(MessageLoop::current() == render_loop_);
233 if (webmediaplayer_) {
234 webmediaplayer_->OnPipelineError();
235 }
236}
237
[email protected]4f92fbc2009-10-16 01:29:50238void WebMediaPlayerImpl::Proxy::NetworkEventTask() {
239 DCHECK(MessageLoop::current() == render_loop_);
240 if (webmediaplayer_) {
241 webmediaplayer_->OnNetworkEvent();
242 }
243}
244
[email protected]e81283bb2010-08-31 18:01:21245void WebMediaPlayerImpl::Proxy::GetCurrentFrame(
246 scoped_refptr<media::VideoFrame>* frame_out) {
247 if (video_renderer_)
248 video_renderer_->GetCurrentFrame(frame_out);
249}
250
251void WebMediaPlayerImpl::Proxy::PutCurrentFrame(
252 scoped_refptr<media::VideoFrame> frame) {
253 if (video_renderer_)
254 video_renderer_->PutCurrentFrame(frame);
255}
256
[email protected]d43ed912009-02-03 04:52:53257/////////////////////////////////////////////////////////////////////////////
[email protected]4e6be3f2009-05-07 02:24:44258// WebMediaPlayerImpl implementation
[email protected]d43ed912009-02-03 04:52:53259
[email protected]5b5bb9d2010-10-22 19:57:36260WebMediaPlayerImpl::WebMediaPlayerImpl(
261 WebKit::WebMediaPlayerClient* client,
[email protected]f78d1dfc2011-01-15 07:09:27262 media::FilterCollection* collection,
263 media::MessageLoopFactory* message_loop_factory)
[email protected]4e6be3f2009-05-07 02:24:44264 : network_state_(WebKit::WebMediaPlayer::Empty),
265 ready_state_(WebKit::WebMediaPlayer::HaveNothing),
[email protected]d43ed912009-02-03 04:52:53266 main_loop_(NULL),
[email protected]457d8342010-10-23 01:20:37267 filter_collection_(collection),
[email protected]a8e24d522010-12-01 07:13:58268 pipeline_(NULL),
[email protected]f78d1dfc2011-01-15 07:09:27269 message_loop_factory_(message_loop_factory),
[email protected]49480902009-07-14 20:23:43270 paused_(true),
[email protected]b3766a22010-12-22 17:34:13271 seeking_(false),
[email protected]49480902009-07-14 20:23:43272 playback_rate_(0.0f),
[email protected]5badb082010-06-11 17:40:15273 client_(client),
[email protected]a8e24d522010-12-01 07:13:58274 proxy_(NULL),
[email protected]5badb082010-06-11 17:40:15275 pipeline_stopped_(false, false) {
[email protected]4e6be3f2009-05-07 02:24:44276 // Saves the current message loop.
277 DCHECK(!main_loop_);
278 main_loop_ = MessageLoop::current();
[email protected]a8e24d522010-12-01 07:13:58279}
[email protected]4e6be3f2009-05-07 02:24:44280
[email protected]a8e24d522010-12-01 07:13:58281bool WebMediaPlayerImpl::Initialize(
[email protected]79684282010-12-06 21:15:46282 WebKit::WebFrame* frame,
[email protected]a8e24d522010-12-01 07:13:58283 bool use_simple_data_source,
284 scoped_refptr<WebVideoRenderer> web_video_renderer) {
[email protected]f78d1dfc2011-01-15 07:09:27285 MessageLoop* pipeline_message_loop =
286 message_loop_factory_->GetMessageLoop("PipelineThread");
287 if (!pipeline_message_loop) {
[email protected]3b4cbbf2009-07-11 00:16:19288 NOTREACHED() << "Could not start PipelineThread";
[email protected]a8e24d522010-12-01 07:13:58289 return false;
[email protected]3b4cbbf2009-07-11 00:16:19290 }
291
[email protected]f78d1dfc2011-01-15 07:09:27292 pipeline_ = new media::PipelineImpl(pipeline_message_loop);
[email protected]db190487d2009-07-30 18:51:52293
[email protected]4e6be3f2009-05-07 02:24:44294 // Also we want to be notified of |main_loop_| destruction.
295 main_loop_->AddDestructionObserver(this);
[email protected]8931c41a2009-07-07 17:31:49296
297 // Creates the proxy.
298 proxy_ = new Proxy(main_loop_, this);
[email protected]457d8342010-10-23 01:20:37299 web_video_renderer->SetWebMediaPlayerImplProxy(proxy_);
300 proxy_->SetVideoRenderer(web_video_renderer);
[email protected]8931c41a2009-07-07 17:31:49301
[email protected]576537842009-08-12 23:52:05302 // Set our pipeline callbacks.
[email protected]583634b2010-11-11 17:47:15303 pipeline_->Init(
304 NewCallback(proxy_.get(),
305 &WebMediaPlayerImpl::Proxy::PipelineEndedCallback),
306 NewCallback(proxy_.get(),
307 &WebMediaPlayerImpl::Proxy::PipelineErrorCallback),
308 NewCallback(proxy_.get(),
309 &WebMediaPlayerImpl::Proxy::NetworkEventCallback));
[email protected]db190487d2009-07-30 18:51:52310
[email protected]5b5bb9d2010-10-22 19:57:36311 // A simple data source that keeps all data in memory.
[email protected]ad8e04a2010-11-01 04:16:27312 scoped_refptr<SimpleDataSource> simple_data_source(
[email protected]79684282010-12-06 21:15:46313 new SimpleDataSource(MessageLoop::current(), frame));
[email protected]457d8342010-10-23 01:20:37314
[email protected]5b5bb9d2010-10-22 19:57:36315 // A sophisticated data source that does memory caching.
[email protected]ad8e04a2010-11-01 04:16:27316 scoped_refptr<BufferedDataSource> buffered_data_source(
[email protected]79684282010-12-06 21:15:46317 new BufferedDataSource(MessageLoop::current(), frame));
[email protected]f63760a2011-02-16 04:59:10318 proxy_->AddDataSource(buffered_data_source);
[email protected]457d8342010-10-23 01:20:37319
[email protected]5b5bb9d2010-10-22 19:57:36320 if (use_simple_data_source) {
[email protected]b7ba5b52010-11-15 22:04:49321 filter_collection_->AddDataSource(simple_data_source);
322 filter_collection_->AddDataSource(buffered_data_source);
[email protected]5b5bb9d2010-10-22 19:57:36323 } else {
[email protected]b7ba5b52010-11-15 22:04:49324 filter_collection_->AddDataSource(buffered_data_source);
325 filter_collection_->AddDataSource(simple_data_source);
[email protected]5b5bb9d2010-10-22 19:57:36326 }
327
[email protected]8931c41a2009-07-07 17:31:49328 // Add in the default filter factories.
[email protected]f78d1dfc2011-01-15 07:09:27329 filter_collection_->AddDemuxer(new media::FFmpegDemuxer(
330 message_loop_factory_->GetMessageLoop("DemuxThread")));
331 filter_collection_->AddAudioDecoder(new media::FFmpegAudioDecoder(
332 message_loop_factory_->GetMessageLoop("AudioDecoderThread")));
333 filter_collection_->AddVideoDecoder(new media::FFmpegVideoDecoder(
334 message_loop_factory_->GetMessageLoop("VideoDecoderThread"), NULL));
[email protected]b7ba5b52010-11-15 22:04:49335 filter_collection_->AddAudioRenderer(new media::NullAudioRenderer());
[email protected]a8e24d522010-12-01 07:13:58336
337 return true;
[email protected]ec9212f2008-12-18 21:40:36338}
339
[email protected]4e6be3f2009-05-07 02:24:44340WebMediaPlayerImpl::~WebMediaPlayerImpl() {
[email protected]8931c41a2009-07-07 17:31:49341 Destroy();
[email protected]d43ed912009-02-03 04:52:53342
[email protected]4e6be3f2009-05-07 02:24:44343 // Finally tell the |main_loop_| we don't want to be notified of destruction
[email protected]d43ed912009-02-03 04:52:53344 // event.
345 if (main_loop_) {
346 main_loop_->RemoveDestructionObserver(this);
347 }
[email protected]ec9212f2008-12-18 21:40:36348}
349
[email protected]4e6be3f2009-05-07 02:24:44350void WebMediaPlayerImpl::load(const WebKit::WebURL& url) {
[email protected]8931c41a2009-07-07 17:31:49351 DCHECK(MessageLoop::current() == main_loop_);
352 DCHECK(proxy_);
[email protected]d43ed912009-02-03 04:52:53353
[email protected]835070f2010-05-18 23:48:29354 // Handle any volume changes that occured before load().
355 setVolume(GetClient()->volume());
356
[email protected]a7281022009-06-17 17:58:04357 // Initialize the pipeline.
[email protected]8931c41a2009-07-07 17:31:49358 SetNetworkState(WebKit::WebMediaPlayer::Loading);
359 SetReadyState(WebKit::WebMediaPlayer::HaveNothing);
[email protected]3b4cbbf2009-07-11 00:16:19360 pipeline_->Start(
[email protected]9e166972010-11-03 05:40:13361 filter_collection_.release(),
[email protected]8931c41a2009-07-07 17:31:49362 url.spec(),
363 NewCallback(proxy_.get(),
364 &WebMediaPlayerImpl::Proxy::PipelineInitializationCallback));
[email protected]ec9212f2008-12-18 21:40:36365}
366
[email protected]4e6be3f2009-05-07 02:24:44367void WebMediaPlayerImpl::cancelLoad() {
[email protected]8931c41a2009-07-07 17:31:49368 DCHECK(MessageLoop::current() == main_loop_);
[email protected]ec9212f2008-12-18 21:40:36369}
370
[email protected]4e6be3f2009-05-07 02:24:44371void WebMediaPlayerImpl::play() {
[email protected]8931c41a2009-07-07 17:31:49372 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53373
[email protected]49480902009-07-14 20:23:43374 paused_ = false;
375 pipeline_->SetPlaybackRate(playback_rate_);
[email protected]ec9212f2008-12-18 21:40:36376}
377
[email protected]4e6be3f2009-05-07 02:24:44378void WebMediaPlayerImpl::pause() {
[email protected]8931c41a2009-07-07 17:31:49379 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53380
[email protected]49480902009-07-14 20:23:43381 paused_ = true;
[email protected]3b4cbbf2009-07-11 00:16:19382 pipeline_->SetPlaybackRate(0.0f);
[email protected]f467d032009-10-23 00:56:24383 paused_time_ = pipeline_->GetCurrentTime();
[email protected]ec9212f2008-12-18 21:40:36384}
385
[email protected]574a1d62009-07-17 03:23:46386bool WebMediaPlayerImpl::supportsFullscreen() const {
387 DCHECK(MessageLoop::current() == main_loop_);
388 return true;
389}
390
391bool WebMediaPlayerImpl::supportsSave() const {
392 DCHECK(MessageLoop::current() == main_loop_);
393 return true;
394}
395
[email protected]4e6be3f2009-05-07 02:24:44396void WebMediaPlayerImpl::seek(float seconds) {
[email protected]8931c41a2009-07-07 17:31:49397 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53398
[email protected]2a6c25692009-08-18 00:25:55399 // WebKit fires a seek(0) at the very start, however pipeline already does a
400 // seek(0) internally. Avoid doing seek(0) the second time because this will
401 // cause extra pre-rolling and will break servers without range request
402 // support.
[email protected]d8840af42009-08-25 21:27:56403 //
404 // We still have to notify WebKit that time has changed otherwise
405 // HTMLMediaElement gets into an inconsistent state.
[email protected]2a6c25692009-08-18 00:25:55406 if (pipeline_->GetCurrentTime().ToInternalValue() == 0 && seconds == 0) {
[email protected]d8840af42009-08-25 21:27:56407 GetClient()->timeChanged();
[email protected]2a6c25692009-08-18 00:25:55408 return;
409 }
[email protected]576537842009-08-12 23:52:05410
[email protected]b781e772011-02-04 20:27:51411 base::TimeDelta seek_time = ConvertSecondsToTimestamp(seconds);
[email protected]44ff37c02009-10-24 01:03:03412
413 // Update our paused time.
414 if (paused_) {
415 paused_time_ = seek_time;
416 }
417
[email protected]b3766a22010-12-22 17:34:13418 seeking_ = true;
419
[email protected]44ff37c02009-10-24 01:03:03420 // Kick off the asynchronous seek!
[email protected]3b4cbbf2009-07-11 00:16:19421 pipeline_->Seek(
[email protected]44ff37c02009-10-24 01:03:03422 seek_time,
[email protected]8931c41a2009-07-07 17:31:49423 NewCallback(proxy_.get(),
424 &WebMediaPlayerImpl::Proxy::PipelineSeekCallback));
[email protected]ec9212f2008-12-18 21:40:36425}
426
[email protected]4e6be3f2009-05-07 02:24:44427void WebMediaPlayerImpl::setEndTime(float seconds) {
[email protected]8931c41a2009-07-07 17:31:49428 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53429
430 // TODO(hclam): add method call when it has been implemented.
431 return;
[email protected]ec9212f2008-12-18 21:40:36432}
[email protected]d43ed912009-02-03 04:52:53433
[email protected]4e6be3f2009-05-07 02:24:44434void WebMediaPlayerImpl::setRate(float rate) {
[email protected]8931c41a2009-07-07 17:31:49435 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53436
[email protected]378f0b72009-08-11 17:11:42437 // TODO(kylep): Remove when support for negatives is added. Also, modify the
438 // following checks so rewind uses reasonable values also.
439 if (rate < 0.0f)
440 return;
441
442 // Limit rates to reasonable values by clamping.
443 if (rate != 0.0f) {
444 if (rate < kMinRate)
445 rate = kMinRate;
446 else if (rate > kMaxRate)
447 rate = kMaxRate;
448 }
449
[email protected]49480902009-07-14 20:23:43450 playback_rate_ = rate;
451 if (!paused_) {
452 pipeline_->SetPlaybackRate(rate);
453 }
[email protected]ec9212f2008-12-18 21:40:36454}
455
[email protected]4e6be3f2009-05-07 02:24:44456void WebMediaPlayerImpl::setVolume(float volume) {
[email protected]8931c41a2009-07-07 17:31:49457 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53458
[email protected]3b4cbbf2009-07-11 00:16:19459 pipeline_->SetVolume(volume);
[email protected]ec9212f2008-12-18 21:40:36460}
[email protected]f0a51fb52009-03-05 12:46:38461
[email protected]4e6be3f2009-05-07 02:24:44462void WebMediaPlayerImpl::setVisible(bool visible) {
[email protected]8931c41a2009-07-07 17:31:49463 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53464
465 // TODO(hclam): add appropriate method call when pipeline has it implemented.
466 return;
[email protected]ec9212f2008-12-18 21:40:36467}
[email protected]d43ed912009-02-03 04:52:53468
[email protected]4e6be3f2009-05-07 02:24:44469bool WebMediaPlayerImpl::setAutoBuffer(bool autoBuffer) {
[email protected]8931c41a2009-07-07 17:31:49470 DCHECK(MessageLoop::current() == main_loop_);
[email protected]4e6be3f2009-05-07 02:24:44471
472 return false;
473}
474
475bool WebMediaPlayerImpl::totalBytesKnown() {
[email protected]8931c41a2009-07-07 17:31:49476 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53477
[email protected]3b4cbbf2009-07-11 00:16:19478 return pipeline_->GetTotalBytes() != 0;
[email protected]d43ed912009-02-03 04:52:53479}
480
[email protected]4e6be3f2009-05-07 02:24:44481bool WebMediaPlayerImpl::hasVideo() const {
[email protected]8931c41a2009-07-07 17:31:49482 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53483
[email protected]cee32342011-03-09 15:58:16484 return pipeline_->HasVideo();
[email protected]d43ed912009-02-03 04:52:53485}
486
[email protected]fc367af2009-08-14 23:06:35487bool WebMediaPlayerImpl::hasAudio() const {
488 DCHECK(MessageLoop::current() == main_loop_);
489
[email protected]cee32342011-03-09 15:58:16490 return pipeline_->HasAudio();
[email protected]fc367af2009-08-14 23:06:35491}
492
[email protected]4e6be3f2009-05-07 02:24:44493WebKit::WebSize WebMediaPlayerImpl::naturalSize() const {
[email protected]8931c41a2009-07-07 17:31:49494 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53495
496 size_t width, height;
[email protected]3b4cbbf2009-07-11 00:16:19497 pipeline_->GetVideoSize(&width, &height);
[email protected]4e6be3f2009-05-07 02:24:44498 return WebKit::WebSize(width, height);
[email protected]d43ed912009-02-03 04:52:53499}
500
[email protected]4e6be3f2009-05-07 02:24:44501bool WebMediaPlayerImpl::paused() const {
[email protected]8931c41a2009-07-07 17:31:49502 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53503
[email protected]3b4cbbf2009-07-11 00:16:19504 return pipeline_->GetPlaybackRate() == 0.0f;
[email protected]d43ed912009-02-03 04:52:53505}
506
[email protected]4e6be3f2009-05-07 02:24:44507bool WebMediaPlayerImpl::seeking() const {
[email protected]8931c41a2009-07-07 17:31:49508 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53509
[email protected]0acebfa2009-08-21 22:45:40510 if (ready_state_ == WebKit::WebMediaPlayer::HaveNothing)
511 return false;
[email protected]67cd5052009-09-10 21:53:22512
[email protected]b3766a22010-12-22 17:34:13513 return seeking_;
[email protected]ec9212f2008-12-18 21:40:36514}
515
[email protected]4e6be3f2009-05-07 02:24:44516float WebMediaPlayerImpl::duration() const {
[email protected]8931c41a2009-07-07 17:31:49517 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53518
[email protected]47b06ceb2010-08-04 22:41:11519 base::TimeDelta duration = pipeline_->GetMediaDuration();
520 if (duration.InMicroseconds() == media::Limits::kMaxTimeInMicroseconds)
521 return std::numeric_limits<float>::infinity();
522 return static_cast<float>(duration.InSecondsF());
[email protected]d43ed912009-02-03 04:52:53523}
524
[email protected]4e6be3f2009-05-07 02:24:44525float WebMediaPlayerImpl::currentTime() const {
[email protected]8931c41a2009-07-07 17:31:49526 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53527
[email protected]f467d032009-10-23 00:56:24528 if (paused_) {
529 return static_cast<float>(paused_time_.InSecondsF());
530 }
[email protected]128740b2009-07-17 22:09:28531 return static_cast<float>(pipeline_->GetCurrentTime().InSecondsF());
[email protected]d43ed912009-02-03 04:52:53532}
533
[email protected]4e6be3f2009-05-07 02:24:44534int WebMediaPlayerImpl::dataRate() const {
[email protected]8931c41a2009-07-07 17:31:49535 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53536
537 // TODO(hclam): Add this method call if pipeline has it in the interface.
538 return 0;
539}
540
[email protected]ddb1e5a2010-12-13 20:10:45541WebKit::WebMediaPlayer::NetworkState WebMediaPlayerImpl::networkState() const {
542 return network_state_;
543}
544
545WebKit::WebMediaPlayer::ReadyState WebMediaPlayerImpl::readyState() const {
546 return ready_state_;
547}
548
[email protected]f70f8e12010-05-25 21:30:39549const WebKit::WebTimeRanges& WebMediaPlayerImpl::buffered() {
550 DCHECK(MessageLoop::current() == main_loop_);
551
552 // Update buffered_ with the most recent buffered time.
[email protected]69a83852010-06-12 01:12:13553 if (buffered_.size() > 0) {
554 float buffered_time = static_cast<float>(
555 pipeline_->GetBufferedTime().InSecondsF());
556 if (buffered_time >= buffered_[0].start)
557 buffered_[0].end = buffered_time;
558 }
[email protected]f70f8e12010-05-25 21:30:39559
560 return buffered_;
561}
562
[email protected]4e6be3f2009-05-07 02:24:44563float WebMediaPlayerImpl::maxTimeSeekable() const {
[email protected]8931c41a2009-07-07 17:31:49564 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53565
[email protected]38259a7a82009-07-29 21:49:49566 // If we are performing streaming, we report that we cannot seek at all.
567 // We are using this flag to indicate if the data source supports seeking
568 // or not. We should be able to seek even if we are performing streaming.
569 // TODO(hclam): We need to update this when we have better caching.
570 if (pipeline_->IsStreaming())
[email protected]73293602009-04-29 00:30:22571 return 0.0f;
[email protected]fd286f22010-04-20 23:45:15572 return static_cast<float>(pipeline_->GetMediaDuration().InSecondsF());
[email protected]ec9212f2008-12-18 21:40:36573}
574
[email protected]4e6be3f2009-05-07 02:24:44575unsigned long long WebMediaPlayerImpl::bytesLoaded() const {
[email protected]8931c41a2009-07-07 17:31:49576 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53577
[email protected]3b4cbbf2009-07-11 00:16:19578 return pipeline_->GetBufferedBytes();
[email protected]d43ed912009-02-03 04:52:53579}
580
[email protected]4e6be3f2009-05-07 02:24:44581unsigned long long WebMediaPlayerImpl::totalBytes() const {
[email protected]8931c41a2009-07-07 17:31:49582 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53583
[email protected]3b4cbbf2009-07-11 00:16:19584 return pipeline_->GetTotalBytes();
[email protected]d43ed912009-02-03 04:52:53585}
586
[email protected]4e6be3f2009-05-07 02:24:44587void WebMediaPlayerImpl::setSize(const WebSize& size) {
[email protected]8931c41a2009-07-07 17:31:49588 DCHECK(MessageLoop::current() == main_loop_);
589 DCHECK(proxy_);
[email protected]d43ed912009-02-03 04:52:53590
[email protected]8931c41a2009-07-07 17:31:49591 proxy_->SetSize(gfx::Rect(0, 0, size.width, size.height));
[email protected]ec9212f2008-12-18 21:40:36592}
593
[email protected]df143bdc2009-06-16 17:34:19594void WebMediaPlayerImpl::paint(WebCanvas* canvas,
[email protected]4e6be3f2009-05-07 02:24:44595 const WebRect& rect) {
[email protected]8931c41a2009-07-07 17:31:49596 DCHECK(MessageLoop::current() == main_loop_);
597 DCHECK(proxy_);
[email protected]4e6be3f2009-05-07 02:24:44598
[email protected]8c89e7792009-08-19 21:18:34599#if WEBKIT_USING_SKIA
[email protected]8931c41a2009-07-07 17:31:49600 proxy_->Paint(canvas, rect);
[email protected]776775e2009-09-21 15:21:29601#elif WEBKIT_USING_CG
[email protected]32da1002010-03-03 21:57:35602 // Get the current scaling in X and Y.
603 CGAffineTransform mat = CGContextGetCTM(canvas);
604 float scale_x = sqrt(mat.a * mat.a + mat.b * mat.b);
605 float scale_y = sqrt(mat.c * mat.c + mat.d * mat.d);
606 float inverse_scale_x = SkScalarNearlyZero(scale_x) ? 0.0f : 1.0f / scale_x;
607 float inverse_scale_y = SkScalarNearlyZero(scale_y) ? 0.0f : 1.0f / scale_y;
608 int scaled_width = static_cast<int>(rect.width * fabs(scale_x));
609 int scaled_height = static_cast<int>(rect.height * fabs(scale_y));
610
611 // Make sure we don't create a huge canvas.
612 // TODO(hclam): Respect the aspect ratio.
613 if (scaled_width > static_cast<int>(media::Limits::kMaxCanvas))
614 scaled_width = media::Limits::kMaxCanvas;
615 if (scaled_height > static_cast<int>(media::Limits::kMaxCanvas))
616 scaled_height = media::Limits::kMaxCanvas;
617
[email protected]776775e2009-09-21 15:21:29618 // If there is no preexisting platform canvas, or if the size has
619 // changed, recreate the canvas. This is to avoid recreating the bitmap
620 // buffer over and over for each frame of video.
621 if (!skia_canvas_.get() ||
[email protected]32da1002010-03-03 21:57:35622 skia_canvas_->getDevice()->width() != scaled_width ||
623 skia_canvas_->getDevice()->height() != scaled_height) {
624 skia_canvas_.reset(
625 new skia::PlatformCanvas(scaled_width, scaled_height, true));
[email protected]776775e2009-09-21 15:21:29626 }
627
628 // Draw to our temporary skia canvas.
[email protected]32da1002010-03-03 21:57:35629 gfx::Rect normalized_rect(scaled_width, scaled_height);
[email protected]776775e2009-09-21 15:21:29630 proxy_->Paint(skia_canvas_.get(), normalized_rect);
631
632 // The mac coordinate system is flipped vertical from the normal skia
633 // coordinates. During painting of the frame, flip the coordinates
634 // system and, for simplicity, also translate the clip rectangle to
635 // start at 0,0.
636 CGContextSaveGState(canvas);
637 CGContextTranslateCTM(canvas, rect.x, rect.height + rect.y);
[email protected]32da1002010-03-03 21:57:35638 CGContextScaleCTM(canvas, inverse_scale_x, -inverse_scale_y);
[email protected]776775e2009-09-21 15:21:29639
640 // We need a local variable CGRect version for DrawToContext.
641 CGRect normalized_cgrect =
642 CGRectMake(normalized_rect.x(), normalized_rect.y(),
643 normalized_rect.width(), normalized_rect.height());
644
645 // Copy the frame rendered to our temporary skia canvas onto the passed in
646 // canvas.
647 skia_canvas_->getTopPlatformDevice().DrawToContext(canvas, 0, 0,
648 &normalized_cgrect);
649
650 CGContextRestoreGState(canvas);
[email protected]8c89e7792009-08-19 21:18:34651#else
[email protected]776775e2009-09-21 15:21:29652 NOTIMPLEMENTED() << "We only support rendering to skia or CG";
[email protected]8c89e7792009-08-19 21:18:34653#endif
[email protected]ec9212f2008-12-18 21:40:36654}
[email protected]5df51652009-01-17 00:03:00655
[email protected]38259a7a82009-07-29 21:49:49656bool WebMediaPlayerImpl::hasSingleSecurityOrigin() const {
[email protected]cf31d6f2010-10-26 02:23:47657 if (proxy_)
658 return proxy_->HasSingleOrigin();
[email protected]fcdb7462009-10-21 21:05:11659 return true;
[email protected]38259a7a82009-07-29 21:49:49660}
661
662WebKit::WebMediaPlayer::MovieLoadType
663 WebMediaPlayerImpl::movieLoadType() const {
664 DCHECK(MessageLoop::current() == main_loop_);
665
666 // TODO(hclam): If the pipeline is performing streaming, we say that this is
667 // a live stream. But instead it should be a StoredStream if we have proper
668 // caching.
669 if (pipeline_->IsStreaming())
670 return WebKit::WebMediaPlayer::LiveStream;
671 return WebKit::WebMediaPlayer::Unknown;
672}
673
[email protected]dc2479d2011-02-25 20:18:38674unsigned WebMediaPlayerImpl::decodedFrameCount() const
[email protected]4c51bc662011-02-16 02:03:16675{
676 DCHECK(MessageLoop::current() == main_loop_);
677
678 media::PipelineStatistics stats = pipeline_->GetStatistics();
679 return stats.video_frames_decoded;
680}
681
[email protected]dc2479d2011-02-25 20:18:38682unsigned WebMediaPlayerImpl::droppedFrameCount() const
[email protected]4c51bc662011-02-16 02:03:16683{
684 DCHECK(MessageLoop::current() == main_loop_);
685
686 media::PipelineStatistics stats = pipeline_->GetStatistics();
687 return stats.video_frames_dropped;
688}
689
[email protected]dc2479d2011-02-25 20:18:38690unsigned WebMediaPlayerImpl::audioDecodedByteCount() const
[email protected]4c51bc662011-02-16 02:03:16691{
692 DCHECK(MessageLoop::current() == main_loop_);
693
694 media::PipelineStatistics stats = pipeline_->GetStatistics();
695 return stats.audio_bytes_decoded;
696}
697
[email protected]dc2479d2011-02-25 20:18:38698unsigned WebMediaPlayerImpl::videoDecodedByteCount() const
[email protected]4c51bc662011-02-16 02:03:16699{
700 DCHECK(MessageLoop::current() == main_loop_);
701
702 media::PipelineStatistics stats = pipeline_->GetStatistics();
703 return stats.video_bytes_decoded;
704}
705
[email protected]e81283bb2010-08-31 18:01:21706WebKit::WebVideoFrame* WebMediaPlayerImpl::getCurrentFrame() {
707 scoped_refptr<media::VideoFrame> video_frame;
708 proxy_->GetCurrentFrame(&video_frame);
709 if (video_frame.get())
710 return new WebVideoFrameImpl(video_frame);
711 return NULL;
712}
713
714void WebMediaPlayerImpl::putCurrentFrame(
715 WebKit::WebVideoFrame* web_video_frame) {
716 if (web_video_frame) {
[email protected]ad8e04a2010-11-01 04:16:27717 scoped_refptr<media::VideoFrame> video_frame(
718 WebVideoFrameImpl::toVideoFrame(web_video_frame));
[email protected]e81283bb2010-08-31 18:01:21719 proxy_->PutCurrentFrame(video_frame);
720 delete web_video_frame;
721 }
722}
723
[email protected]4e6be3f2009-05-07 02:24:44724void WebMediaPlayerImpl::WillDestroyCurrentMessageLoop() {
[email protected]8931c41a2009-07-07 17:31:49725 Destroy();
726 main_loop_ = NULL;
727}
728
729void WebMediaPlayerImpl::Repaint() {
730 DCHECK(MessageLoop::current() == main_loop_);
731 GetClient()->repaint();
732}
733
[email protected]96706912009-07-15 17:18:05734void WebMediaPlayerImpl::OnPipelineInitialize() {
[email protected]8931c41a2009-07-07 17:31:49735 DCHECK(MessageLoop::current() == main_loop_);
[email protected]96706912009-07-15 17:18:05736 if (pipeline_->GetError() == media::PIPELINE_OK) {
[email protected]67cd5052009-09-10 21:53:22737 // Only keep one time range starting from 0.
[email protected]c8ca48ea2009-10-16 01:59:17738 WebKit::WebTimeRanges new_buffered(static_cast<size_t>(1));
[email protected]747ca432009-10-09 22:44:48739 new_buffered[0].start = 0.0f;
740 new_buffered[0].end =
[email protected]fd286f22010-04-20 23:45:15741 static_cast<float>(pipeline_->GetMediaDuration().InSecondsF());
[email protected]747ca432009-10-09 22:44:48742 buffered_.swap(new_buffered);
[email protected]67cd5052009-09-10 21:53:22743
[email protected]64d3d792010-04-02 03:03:07744 // Since we have initialized the pipeline, say we have everything otherwise
745 // we'll remain either loading/idle.
[email protected]96706912009-07-15 17:18:05746 // TODO(hclam): change this to report the correct status.
747 SetReadyState(WebKit::WebMediaPlayer::HaveMetadata);
748 SetReadyState(WebKit::WebMediaPlayer::HaveEnoughData);
[email protected]0acebfa2009-08-21 22:45:40749 if (pipeline_->IsLoaded()) {
750 SetNetworkState(WebKit::WebMediaPlayer::Loaded);
[email protected]0acebfa2009-08-21 22:45:40751 }
[email protected]96706912009-07-15 17:18:05752 } else {
753 // TODO(hclam): should use pipeline_->GetError() to determine the state
754 // properly and reports error using MediaError.
755 // WebKit uses FormatError to indicate an error for bogus URL or bad file.
756 // Since we are at the initialization stage we can safely treat every error
757 // as format error. Should post a task to call to |webmediaplayer_|.
758 SetNetworkState(WebKit::WebMediaPlayer::FormatError);
759 }
[email protected]83f2a8a2009-08-18 22:42:15760
761 // Repaint to trigger UI update.
762 Repaint();
[email protected]96706912009-07-15 17:18:05763}
764
765void WebMediaPlayerImpl::OnPipelineSeek() {
766 DCHECK(MessageLoop::current() == main_loop_);
767 if (pipeline_->GetError() == media::PIPELINE_OK) {
[email protected]44ff37c02009-10-24 01:03:03768 // Update our paused time.
769 if (paused_) {
770 paused_time_ = pipeline_->GetCurrentTime();
771 }
772
[email protected]0acebfa2009-08-21 22:45:40773 SetReadyState(WebKit::WebMediaPlayer::HaveEnoughData);
[email protected]b3766a22010-12-22 17:34:13774 seeking_ = false;
[email protected]96706912009-07-15 17:18:05775 GetClient()->timeChanged();
776 }
[email protected]8931c41a2009-07-07 17:31:49777}
778
[email protected]576537842009-08-12 23:52:05779void WebMediaPlayerImpl::OnPipelineEnded() {
780 DCHECK(MessageLoop::current() == main_loop_);
781 if (pipeline_->GetError() == media::PIPELINE_OK) {
782 GetClient()->timeChanged();
783 }
784}
785
[email protected]db190487d2009-07-30 18:51:52786void WebMediaPlayerImpl::OnPipelineError() {
787 DCHECK(MessageLoop::current() == main_loop_);
788 switch (pipeline_->GetError()) {
789 case media::PIPELINE_OK:
[email protected]db190487d2009-07-30 18:51:52790 case media::PIPELINE_ERROR_INITIALIZATION_FAILED:
791 case media::PIPELINE_ERROR_REQUIRED_FILTER_MISSING:
792 case media::PIPELINE_ERROR_COULD_NOT_RENDER:
[email protected]db190487d2009-07-30 18:51:52793 case media::PIPELINE_ERROR_URL_NOT_FOUND:
794 case media::PIPELINE_ERROR_NETWORK:
[email protected]db190487d2009-07-30 18:51:52795 case media::PIPELINE_ERROR_READ:
[email protected]db190487d2009-07-30 18:51:52796 case media::DEMUXER_ERROR_COULD_NOT_OPEN:
797 case media::DEMUXER_ERROR_COULD_NOT_PARSE:
798 case media::DEMUXER_ERROR_NO_SUPPORTED_STREAMS:
799 case media::DEMUXER_ERROR_COULD_NOT_CREATE_THREAD:
[email protected]9c4e77ab2009-07-31 00:17:08800 // Format error.
801 SetNetworkState(WebMediaPlayer::FormatError);
802 break;
803
804 case media::PIPELINE_ERROR_DECODE:
805 case media::PIPELINE_ERROR_ABORT:
806 case media::PIPELINE_ERROR_OUT_OF_MEMORY:
807 case media::PIPELINE_ERROR_AUDIO_HARDWARE:
[email protected]641c9abc2011-01-05 18:44:10808 case media::PIPELINE_ERROR_OPERATION_PENDING:
809 case media::PIPELINE_ERROR_INVALID_STATE:
[email protected]db190487d2009-07-30 18:51:52810 // Decode error.
811 SetNetworkState(WebMediaPlayer::DecodeError);
812 break;
813 }
[email protected]bb2c1f32009-08-14 04:14:50814
815 // Repaint to trigger UI update.
816 Repaint();
[email protected]db190487d2009-07-30 18:51:52817}
818
[email protected]4f92fbc2009-10-16 01:29:50819void WebMediaPlayerImpl::OnNetworkEvent() {
820 DCHECK(MessageLoop::current() == main_loop_);
821 if (pipeline_->GetError() == media::PIPELINE_OK) {
[email protected]c5c80722010-07-26 19:11:06822 if (pipeline_->IsNetworkActive()) {
[email protected]4f92fbc2009-10-16 01:29:50823 SetNetworkState(WebKit::WebMediaPlayer::Loading);
[email protected]c5c80722010-07-26 19:11:06824 } else {
825 // If we are inactive because we just finished receiving all the data,
826 // do one final repaint to show final progress.
827 if (bytesLoaded() == totalBytes() &&
[email protected]25544312011-02-24 23:12:23828 network_state_ != WebKit::WebMediaPlayer::Idle) {
[email protected]c5c80722010-07-26 19:11:06829 Repaint();
[email protected]25544312011-02-24 23:12:23830
831 SetNetworkState(WebKit::WebMediaPlayer::Loaded);
832 }
833
[email protected]4f92fbc2009-10-16 01:29:50834 SetNetworkState(WebKit::WebMediaPlayer::Idle);
[email protected]c5c80722010-07-26 19:11:06835 }
[email protected]4f92fbc2009-10-16 01:29:50836 }
837}
838
[email protected]8931c41a2009-07-07 17:31:49839void WebMediaPlayerImpl::SetNetworkState(
840 WebKit::WebMediaPlayer::NetworkState state) {
841 DCHECK(MessageLoop::current() == main_loop_);
[email protected]867e59272009-08-25 18:08:16842 // Always notify to ensure client has the latest value.
843 network_state_ = state;
844 GetClient()->networkStateChanged();
[email protected]8931c41a2009-07-07 17:31:49845}
846
847void WebMediaPlayerImpl::SetReadyState(
848 WebKit::WebMediaPlayer::ReadyState state) {
849 DCHECK(MessageLoop::current() == main_loop_);
[email protected]867e59272009-08-25 18:08:16850 // Always notify to ensure client has the latest value.
851 ready_state_ = state;
852 GetClient()->readyStateChanged();
[email protected]8931c41a2009-07-07 17:31:49853}
854
855void WebMediaPlayerImpl::Destroy() {
856 DCHECK(MessageLoop::current() == main_loop_);
857
[email protected]5b5bb9d2010-10-22 19:57:36858 // Tell the data source to abort any pending reads so that the pipeline is
859 // not blocked when issuing stop commands to the other filters.
860 if (proxy_)
[email protected]f63760a2011-02-16 04:59:10861 proxy_->AbortDataSources();
[email protected]5b5bb9d2010-10-22 19:57:36862
[email protected]8931c41a2009-07-07 17:31:49863 // Make sure to kill the pipeline so there's no more media threads running.
[email protected]5badb082010-06-11 17:40:15864 // Note: stopping the pipeline might block for a long time.
[email protected]a8e24d522010-12-01 07:13:58865 if (pipeline_) {
866 pipeline_->Stop(NewCallback(this,
867 &WebMediaPlayerImpl::PipelineStoppedCallback));
868 pipeline_stopped_.Wait();
[email protected]a8e24d522010-12-01 07:13:58869 }
[email protected]5df51652009-01-17 00:03:00870
[email protected]f78d1dfc2011-01-15 07:09:27871 message_loop_factory_.reset();
872
[email protected]8931c41a2009-07-07 17:31:49873 // And then detach the proxy, it may live on the render thread for a little
874 // longer until all the tasks are finished.
875 if (proxy_) {
876 proxy_->Detach();
877 proxy_ = NULL;
[email protected]a7281022009-06-17 17:58:04878 }
[email protected]5df51652009-01-17 00:03:00879}
880
[email protected]5badb082010-06-11 17:40:15881void WebMediaPlayerImpl::PipelineStoppedCallback() {
882 pipeline_stopped_.Signal();
883}
884
[email protected]8931c41a2009-07-07 17:31:49885WebKit::WebMediaPlayerClient* WebMediaPlayerImpl::GetClient() {
886 DCHECK(MessageLoop::current() == main_loop_);
887 DCHECK(client_);
888 return client_;
[email protected]5df51652009-01-17 00:03:00889}
[email protected]add51772009-06-11 18:25:17890
891} // namespace webkit_glue