blob: 76e6437883efb3f8361c3c2d2af348070c4fdb69 [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>
[email protected]d82b18ae2011-03-23 21:28:598#include <string>
[email protected]47b06ceb2010-08-04 22:41:119
[email protected]08273c7b2011-09-17 00:33:5110#include "base/bind.h"
[email protected]2041cf342010-02-19 03:15:5911#include "base/callback.h"
[email protected]963ab912010-01-22 19:56:1412#include "base/command_line.h"
[email protected]b6c29552011-03-14 15:56:2913#include "media/base/composite_data_source_factory.h"
[email protected]f8db8132010-12-03 00:27:4914#include "media/base/filter_collection.h"
[email protected]32da1002010-03-03 21:57:3515#include "media/base/limits.h"
[email protected]090f7312011-08-05 23:26:4016#include "media/base/media_log.h"
[email protected]963ab912010-01-22 19:56:1417#include "media/base/media_switches.h"
[email protected]583634b2010-11-11 17:47:1518#include "media/base/pipeline_impl.h"
[email protected]e81283bb2010-08-31 18:01:2119#include "media/base/video_frame.h"
[email protected]4af58de2011-03-30 20:28:5020#include "media/filters/adaptive_demuxer.h"
[email protected]81bb3322011-07-21 15:55:5021#include "media/filters/chunk_demuxer_factory.h"
[email protected]08107faa2011-08-24 16:49:0122#include "media/filters/dummy_demuxer_factory.h"
[email protected]4c616fa52009-03-30 20:10:0723#include "media/filters/ffmpeg_audio_decoder.h"
[email protected]c88c7c22011-03-14 19:44:2224#include "media/filters/ffmpeg_demuxer_factory.h"
[email protected]720ac732009-04-02 23:55:4425#include "media/filters/ffmpeg_video_decoder.h"
[email protected]891acc92009-04-27 19:56:4126#include "media/filters/null_audio_renderer.h"
[email protected]c1d9cdc2011-01-17 06:50:0127#include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h"
28#include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h"
29#include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h"
30#include "third_party/WebKit/Source/WebKit/chromium/public/WebVideoFrame.h"
[email protected]38aefc312011-09-20 05:06:3731#include "v8/include/v8.h"
[email protected]5b5bb9d2010-10-22 19:57:3632#include "webkit/glue/media/buffered_data_source.h"
[email protected]5b5bb9d2010-10-22 19:57:3633#include "webkit/glue/media/simple_data_source.h"
[email protected]ab2c4732011-07-20 19:57:4034#include "webkit/glue/media/media_stream_client.h"
[email protected]add51772009-06-11 18:25:1735#include "webkit/glue/media/video_renderer_impl.h"
[email protected]8400e032010-02-26 18:50:1136#include "webkit/glue/media/web_video_renderer.h"
[email protected]a23306102011-08-09 22:50:2637#include "webkit/glue/webmediaplayer_proxy.h"
[email protected]e81283bb2010-08-31 18:01:2138#include "webkit/glue/webvideoframe_impl.h"
[email protected]b3f2b912009-04-09 16:18:5239
[email protected]df143bdc2009-06-16 17:34:1940using WebKit::WebCanvas;
[email protected]b3f2b912009-04-09 16:18:5241using WebKit::WebRect;
42using WebKit::WebSize;
[email protected]a9590c22011-03-16 16:57:0243using media::PipelineStatus;
[email protected]ec9212f2008-12-18 21:40:3644
[email protected]8931c41a2009-07-07 17:31:4945namespace {
46
[email protected]38aefc312011-09-20 05:06:3747// Amount of extra memory used by each player instance reported to V8.
48// It is not exact number -- first, it differs on different platforms,
49// and second, it is very hard to calculate. Instead, use some arbitrary
50// value that will cause garbage collection from time to time. We don't want
51// it to happen on every allocation, but don't want 5k players to sit in memory
52// either. Looks that chosen constant achieves both goals, at least for audio
53// objects. (Do not worry about video objects yet, JS programs do not create
54// thousands of them...)
55const int kPlayerExtraMemory = 1024 * 1024;
56
[email protected]378f0b72009-08-11 17:11:4257// Limits the range of playback rate.
58//
59// TODO(kylep): Revisit these.
60//
61// Vista has substantially lower performance than XP or Windows7. If you speed
62// up a video too much, it can't keep up, and rendering stops updating except on
63// the time bar. For really high speeds, audio becomes a bottleneck and we just
64// use up the data we have, which may not achieve the speed requested, but will
65// not crash the tab.
66//
67// A very slow speed, ie 0.00000001x, causes the machine to lock up. (It seems
68// like a busy loop). It gets unresponsive, although its not completely dead.
69//
70// Also our timers are not very accurate (especially for ogg), which becomes
71// evident at low speeds and on Vista. Since other speeds are risky and outside
72// the norms, we think 1/16x to 16x is a safe and useful range for now.
73const float kMinRate = 0.0625f;
74const float kMaxRate = 16.0f;
75
[email protected]b781e772011-02-04 20:27:5176// Platform independent method for converting and rounding floating point
77// seconds to an int64 timestamp.
78//
79// Refer to https://bugs.webkit.org/show_bug.cgi?id=52697 for details.
80base::TimeDelta ConvertSecondsToTimestamp(float seconds) {
81 float microseconds = seconds * base::Time::kMicrosecondsPerSecond;
82 float integer = ceilf(microseconds);
83 float difference = integer - microseconds;
84
85 // Round down if difference is large enough.
86 if ((microseconds > 0 && difference > 0.5f) ||
87 (microseconds <= 0 && difference >= 0.5f)) {
88 integer -= 1.0f;
89 }
90
91 // Now we can safely cast to int64 microseconds.
92 return base::TimeDelta::FromMicroseconds(static_cast<int64>(integer));
93}
94
[email protected]8931c41a2009-07-07 17:31:4995} // namespace
96
[email protected]add51772009-06-11 18:25:1797namespace webkit_glue {
98
[email protected]5b5bb9d2010-10-22 19:57:3699WebMediaPlayerImpl::WebMediaPlayerImpl(
100 WebKit::WebMediaPlayerClient* client,
[email protected]f78d1dfc2011-01-15 07:09:27101 media::FilterCollection* collection,
[email protected]ab2c4732011-07-20 19:57:40102 media::MessageLoopFactory* message_loop_factory,
[email protected]090f7312011-08-05 23:26:40103 MediaStreamClient* media_stream_client,
104 media::MediaLog* media_log)
[email protected]4e6be3f2009-05-07 02:24:44105 : network_state_(WebKit::WebMediaPlayer::Empty),
106 ready_state_(WebKit::WebMediaPlayer::HaveNothing),
[email protected]d43ed912009-02-03 04:52:53107 main_loop_(NULL),
[email protected]457d8342010-10-23 01:20:37108 filter_collection_(collection),
[email protected]a8e24d522010-12-01 07:13:58109 pipeline_(NULL),
[email protected]f78d1dfc2011-01-15 07:09:27110 message_loop_factory_(message_loop_factory),
[email protected]49480902009-07-14 20:23:43111 paused_(true),
[email protected]b3766a22010-12-22 17:34:13112 seeking_(false),
[email protected]49480902009-07-14 20:23:43113 playback_rate_(0.0f),
[email protected]5d11eff2011-09-15 00:06:06114 pending_seek_(false),
[email protected]5badb082010-06-11 17:40:15115 client_(client),
[email protected]ab2c4732011-07-20 19:57:40116 proxy_(NULL),
[email protected]090f7312011-08-05 23:26:40117 media_stream_client_(media_stream_client),
118 media_log_(media_log) {
[email protected]4e6be3f2009-05-07 02:24:44119 // Saves the current message loop.
120 DCHECK(!main_loop_);
121 main_loop_ = MessageLoop::current();
[email protected]c93eb0a62011-08-09 22:47:24122 media_log_->AddEvent(
123 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED));
[email protected]a8e24d522010-12-01 07:13:58124}
[email protected]4e6be3f2009-05-07 02:24:44125
[email protected]a8e24d522010-12-01 07:13:58126bool WebMediaPlayerImpl::Initialize(
[email protected]79684282010-12-06 21:15:46127 WebKit::WebFrame* frame,
[email protected]a8e24d522010-12-01 07:13:58128 bool use_simple_data_source,
129 scoped_refptr<WebVideoRenderer> web_video_renderer) {
[email protected]f78d1dfc2011-01-15 07:09:27130 MessageLoop* pipeline_message_loop =
131 message_loop_factory_->GetMessageLoop("PipelineThread");
132 if (!pipeline_message_loop) {
[email protected]3b4cbbf2009-07-11 00:16:19133 NOTREACHED() << "Could not start PipelineThread";
[email protected]a8e24d522010-12-01 07:13:58134 return false;
[email protected]3b4cbbf2009-07-11 00:16:19135 }
136
[email protected]38aefc312011-09-20 05:06:37137 // Let V8 know we started new thread if we did not did it yet.
138 // Made separate task to avoid deletion of player currently being created.
139 // Also, delaying GC until after player starts gets rid of starting lag --
140 // collection happens in parallel with playing.
141 // TODO(enal): remove when we get rid of per-audio-stream thread.
142 if (destructor_or_task_had_run_.get() == NULL) {
143 destructor_or_task_had_run_ = new DestructorOrTaskHadRun();
144 main_loop_->PostTask(
145 FROM_HERE,
146 NewRunnableFunction(WebMediaPlayerImpl::UsesExtraMemoryTask,
147 destructor_or_task_had_run_));
148 }
149
[email protected]c93eb0a62011-08-09 22:47:24150 pipeline_ = new media::PipelineImpl(pipeline_message_loop, media_log_);
[email protected]db190487d2009-07-30 18:51:52151
[email protected]4e6be3f2009-05-07 02:24:44152 // Also we want to be notified of |main_loop_| destruction.
153 main_loop_->AddDestructionObserver(this);
[email protected]8931c41a2009-07-07 17:31:49154
155 // Creates the proxy.
[email protected]a23306102011-08-09 22:50:26156 proxy_ = new WebMediaPlayerProxy(main_loop_, this);
157 web_video_renderer->SetWebMediaPlayerProxy(proxy_);
[email protected]457d8342010-10-23 01:20:37158 proxy_->SetVideoRenderer(web_video_renderer);
[email protected]8931c41a2009-07-07 17:31:49159
[email protected]576537842009-08-12 23:52:05160 // Set our pipeline callbacks.
[email protected]583634b2010-11-11 17:47:15161 pipeline_->Init(
[email protected]460e5712011-08-09 23:25:53162 base::Bind(&WebMediaPlayerProxy::PipelineEndedCallback,
163 proxy_.get()),
164 base::Bind(&WebMediaPlayerProxy::PipelineErrorCallback,
165 proxy_.get()),
166 base::Bind(&WebMediaPlayerProxy::NetworkEventCallback,
167 proxy_.get()));
[email protected]db190487d2009-07-30 18:51:52168
[email protected]5b5bb9d2010-10-22 19:57:36169 // A simple data source that keeps all data in memory.
[email protected]b6c29552011-03-14 15:56:29170 scoped_ptr<media::DataSourceFactory> simple_data_source_factory(
171 SimpleDataSource::CreateFactory(MessageLoop::current(), frame,
[email protected]24d75c72011-08-09 17:53:45172 media_log_,
[email protected]b6c29552011-03-14 15:56:29173 proxy_->GetBuildObserver()));
[email protected]457d8342010-10-23 01:20:37174
[email protected]5b5bb9d2010-10-22 19:57:36175 // A sophisticated data source that does memory caching.
[email protected]b6c29552011-03-14 15:56:29176 scoped_ptr<media::DataSourceFactory> buffered_data_source_factory(
177 BufferedDataSource::CreateFactory(MessageLoop::current(), frame,
[email protected]24d75c72011-08-09 17:53:45178 media_log_,
[email protected]b6c29552011-03-14 15:56:29179 proxy_->GetBuildObserver()));
180
181 scoped_ptr<media::CompositeDataSourceFactory> data_source_factory(
182 new media::CompositeDataSourceFactory());
[email protected]457d8342010-10-23 01:20:37183
[email protected]5b5bb9d2010-10-22 19:57:36184 if (use_simple_data_source) {
[email protected]b6c29552011-03-14 15:56:29185 data_source_factory->AddFactory(simple_data_source_factory.release());
186 data_source_factory->AddFactory(buffered_data_source_factory.release());
[email protected]5b5bb9d2010-10-22 19:57:36187 } else {
[email protected]b6c29552011-03-14 15:56:29188 data_source_factory->AddFactory(buffered_data_source_factory.release());
189 data_source_factory->AddFactory(simple_data_source_factory.release());
[email protected]5b5bb9d2010-10-22 19:57:36190 }
191
[email protected]c88c7c22011-03-14 19:44:22192 scoped_ptr<media::DemuxerFactory> demuxer_factory(
193 new media::FFmpegDemuxerFactory(data_source_factory.release(),
194 pipeline_message_loop));
[email protected]4af58de2011-03-30 20:28:50195 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableAdaptive)) {
196 demuxer_factory.reset(new media::AdaptiveDemuxerFactory(
197 demuxer_factory.release()));
[email protected]81bb3322011-07-21 15:55:50198
199 std::string sourceUrl;
200
201 // TODO(acolwell): Uncomment once WebKit changes are checked in.
202 // https://bugs.webkit.org/show_bug.cgi?id=64731
203 //sourceUrl = GetClient()->sourceURL().spec();
204
205 if (!sourceUrl.empty()) {
206 demuxer_factory.reset(
207 new media::ChunkDemuxerFactory(sourceUrl,
208 demuxer_factory.release(),
209 proxy_));
210 }
[email protected]4af58de2011-03-30 20:28:50211 }
[email protected]c88c7c22011-03-14 19:44:22212 filter_collection_->SetDemuxerFactory(demuxer_factory.release());
[email protected]b6c29552011-03-14 15:56:29213
[email protected]8931c41a2009-07-07 17:31:49214 // Add in the default filter factories.
[email protected]f78d1dfc2011-01-15 07:09:27215 filter_collection_->AddAudioDecoder(new media::FFmpegAudioDecoder(
216 message_loop_factory_->GetMessageLoop("AudioDecoderThread")));
217 filter_collection_->AddVideoDecoder(new media::FFmpegVideoDecoder(
218 message_loop_factory_->GetMessageLoop("VideoDecoderThread"), NULL));
[email protected]b7ba5b52010-11-15 22:04:49219 filter_collection_->AddAudioRenderer(new media::NullAudioRenderer());
[email protected]a8e24d522010-12-01 07:13:58220
221 return true;
[email protected]ec9212f2008-12-18 21:40:36222}
223
[email protected]4e6be3f2009-05-07 02:24:44224WebMediaPlayerImpl::~WebMediaPlayerImpl() {
[email protected]8931c41a2009-07-07 17:31:49225 Destroy();
[email protected]c93eb0a62011-08-09 22:47:24226 media_log_->AddEvent(
227 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED));
[email protected]d43ed912009-02-03 04:52:53228
[email protected]4e6be3f2009-05-07 02:24:44229 // Finally tell the |main_loop_| we don't want to be notified of destruction
[email protected]d43ed912009-02-03 04:52:53230 // event.
231 if (main_loop_) {
232 main_loop_->RemoveDestructionObserver(this);
233 }
[email protected]ec9212f2008-12-18 21:40:36234}
235
[email protected]4e6be3f2009-05-07 02:24:44236void WebMediaPlayerImpl::load(const WebKit::WebURL& url) {
[email protected]8931c41a2009-07-07 17:31:49237 DCHECK(MessageLoop::current() == main_loop_);
238 DCHECK(proxy_);
[email protected]d43ed912009-02-03 04:52:53239
[email protected]ab2c4732011-07-20 19:57:40240 if (media_stream_client_) {
[email protected]08107faa2011-08-24 16:49:01241 bool has_video = false;
242 bool has_audio = false;
[email protected]ab2c4732011-07-20 19:57:40243 scoped_refptr<media::VideoDecoder> new_decoder =
244 media_stream_client_->GetVideoDecoder(url, message_loop_factory_.get());
245 if (new_decoder.get()) {
246 // Remove the default decoder.
247 scoped_refptr<media::VideoDecoder> old_videodecoder;
248 filter_collection_->SelectVideoDecoder(&old_videodecoder);
249 filter_collection_->AddVideoDecoder(new_decoder.get());
[email protected]08107faa2011-08-24 16:49:01250 has_video = true;
[email protected]ab2c4732011-07-20 19:57:40251 }
[email protected]08107faa2011-08-24 16:49:01252
253 // TODO(wjia): add audio decoder handling when it's available.
254 if (has_video || has_audio)
255 filter_collection_->SetDemuxerFactory(
256 new media::DummyDemuxerFactory(has_video, has_audio));
[email protected]ab2c4732011-07-20 19:57:40257 }
258
[email protected]835070f2010-05-18 23:48:29259 // Handle any volume changes that occured before load().
260 setVolume(GetClient()->volume());
[email protected]23a8b1d82011-04-05 16:28:20261 // Get the preload value.
262 setPreload(GetClient()->preload());
[email protected]835070f2010-05-18 23:48:29263
[email protected]a7281022009-06-17 17:58:04264 // Initialize the pipeline.
[email protected]8931c41a2009-07-07 17:31:49265 SetNetworkState(WebKit::WebMediaPlayer::Loading);
266 SetReadyState(WebKit::WebMediaPlayer::HaveNothing);
[email protected]3b4cbbf2009-07-11 00:16:19267 pipeline_->Start(
[email protected]9e166972010-11-03 05:40:13268 filter_collection_.release(),
[email protected]8931c41a2009-07-07 17:31:49269 url.spec(),
[email protected]460e5712011-08-09 23:25:53270 base::Bind(&WebMediaPlayerProxy::PipelineInitializationCallback,
271 proxy_.get()));
272
[email protected]24d75c72011-08-09 17:53:45273 media_log_->AddEvent(media_log_->CreateLoadEvent(url.spec()));
[email protected]ec9212f2008-12-18 21:40:36274}
275
[email protected]4e6be3f2009-05-07 02:24:44276void WebMediaPlayerImpl::cancelLoad() {
[email protected]8931c41a2009-07-07 17:31:49277 DCHECK(MessageLoop::current() == main_loop_);
[email protected]ec9212f2008-12-18 21:40:36278}
279
[email protected]4e6be3f2009-05-07 02:24:44280void WebMediaPlayerImpl::play() {
[email protected]8931c41a2009-07-07 17:31:49281 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53282
[email protected]49480902009-07-14 20:23:43283 paused_ = false;
284 pipeline_->SetPlaybackRate(playback_rate_);
[email protected]090f7312011-08-05 23:26:40285
[email protected]24d75c72011-08-09 17:53:45286 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PLAY));
[email protected]ec9212f2008-12-18 21:40:36287}
288
[email protected]4e6be3f2009-05-07 02:24:44289void WebMediaPlayerImpl::pause() {
[email protected]8931c41a2009-07-07 17:31:49290 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53291
[email protected]49480902009-07-14 20:23:43292 paused_ = true;
[email protected]3b4cbbf2009-07-11 00:16:19293 pipeline_->SetPlaybackRate(0.0f);
[email protected]f467d032009-10-23 00:56:24294 paused_time_ = pipeline_->GetCurrentTime();
[email protected]090f7312011-08-05 23:26:40295
[email protected]24d75c72011-08-09 17:53:45296 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PAUSE));
[email protected]ec9212f2008-12-18 21:40:36297}
298
[email protected]574a1d62009-07-17 03:23:46299bool WebMediaPlayerImpl::supportsFullscreen() const {
300 DCHECK(MessageLoop::current() == main_loop_);
301 return true;
302}
303
304bool WebMediaPlayerImpl::supportsSave() const {
305 DCHECK(MessageLoop::current() == main_loop_);
306 return true;
307}
308
[email protected]4e6be3f2009-05-07 02:24:44309void WebMediaPlayerImpl::seek(float seconds) {
[email protected]8931c41a2009-07-07 17:31:49310 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53311
[email protected]2a6c25692009-08-18 00:25:55312 // WebKit fires a seek(0) at the very start, however pipeline already does a
313 // seek(0) internally. Avoid doing seek(0) the second time because this will
314 // cause extra pre-rolling and will break servers without range request
315 // support.
[email protected]d8840af42009-08-25 21:27:56316 //
317 // We still have to notify WebKit that time has changed otherwise
318 // HTMLMediaElement gets into an inconsistent state.
[email protected]2a6c25692009-08-18 00:25:55319 if (pipeline_->GetCurrentTime().ToInternalValue() == 0 && seconds == 0) {
[email protected]d8840af42009-08-25 21:27:56320 GetClient()->timeChanged();
[email protected]2a6c25692009-08-18 00:25:55321 return;
322 }
[email protected]576537842009-08-12 23:52:05323
[email protected]5d11eff2011-09-15 00:06:06324 if (seeking_) {
325 pending_seek_ = true;
326 pending_seek_seconds_ = seconds;
327 return;
328 }
329
[email protected]c93eb0a62011-08-09 22:47:24330 media_log_->AddEvent(media_log_->CreateSeekEvent(seconds));
331
[email protected]b781e772011-02-04 20:27:51332 base::TimeDelta seek_time = ConvertSecondsToTimestamp(seconds);
[email protected]44ff37c02009-10-24 01:03:03333
334 // Update our paused time.
335 if (paused_) {
336 paused_time_ = seek_time;
337 }
338
[email protected]b3766a22010-12-22 17:34:13339 seeking_ = true;
340
[email protected]81bb3322011-07-21 15:55:50341 proxy_->DemuxerFlush();
[email protected]020fba32011-06-29 16:37:46342
[email protected]44ff37c02009-10-24 01:03:03343 // Kick off the asynchronous seek!
[email protected]3b4cbbf2009-07-11 00:16:19344 pipeline_->Seek(
[email protected]44ff37c02009-10-24 01:03:03345 seek_time,
[email protected]460e5712011-08-09 23:25:53346 base::Bind(&WebMediaPlayerProxy::PipelineSeekCallback,
347 proxy_.get()));
[email protected]ec9212f2008-12-18 21:40:36348}
349
[email protected]4e6be3f2009-05-07 02:24:44350void WebMediaPlayerImpl::setEndTime(float seconds) {
[email protected]8931c41a2009-07-07 17:31:49351 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53352
353 // TODO(hclam): add method call when it has been implemented.
354 return;
[email protected]ec9212f2008-12-18 21:40:36355}
[email protected]d43ed912009-02-03 04:52:53356
[email protected]4e6be3f2009-05-07 02:24:44357void WebMediaPlayerImpl::setRate(float rate) {
[email protected]8931c41a2009-07-07 17:31:49358 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53359
[email protected]378f0b72009-08-11 17:11:42360 // TODO(kylep): Remove when support for negatives is added. Also, modify the
361 // following checks so rewind uses reasonable values also.
362 if (rate < 0.0f)
363 return;
364
365 // Limit rates to reasonable values by clamping.
366 if (rate != 0.0f) {
367 if (rate < kMinRate)
368 rate = kMinRate;
369 else if (rate > kMaxRate)
370 rate = kMaxRate;
371 }
372
[email protected]49480902009-07-14 20:23:43373 playback_rate_ = rate;
374 if (!paused_) {
375 pipeline_->SetPlaybackRate(rate);
376 }
[email protected]ec9212f2008-12-18 21:40:36377}
378
[email protected]4e6be3f2009-05-07 02:24:44379void WebMediaPlayerImpl::setVolume(float volume) {
[email protected]8931c41a2009-07-07 17:31:49380 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53381
[email protected]3b4cbbf2009-07-11 00:16:19382 pipeline_->SetVolume(volume);
[email protected]ec9212f2008-12-18 21:40:36383}
[email protected]f0a51fb52009-03-05 12:46:38384
[email protected]4e6be3f2009-05-07 02:24:44385void WebMediaPlayerImpl::setVisible(bool visible) {
[email protected]8931c41a2009-07-07 17:31:49386 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53387
388 // TODO(hclam): add appropriate method call when pipeline has it implemented.
389 return;
[email protected]ec9212f2008-12-18 21:40:36390}
[email protected]d43ed912009-02-03 04:52:53391
[email protected]23a8b1d82011-04-05 16:28:20392#define COMPILE_ASSERT_MATCHING_ENUM(webkit_name, chromium_name) \
[email protected]474c37a2011-08-23 20:24:52393 COMPILE_ASSERT(static_cast<int>(WebKit::WebMediaPlayer::webkit_name) == \
394 static_cast<int>(media::chromium_name), \
395 mismatching_enums)
[email protected]23a8b1d82011-04-05 16:28:20396COMPILE_ASSERT_MATCHING_ENUM(None, NONE);
397COMPILE_ASSERT_MATCHING_ENUM(MetaData, METADATA);
398COMPILE_ASSERT_MATCHING_ENUM(Auto, AUTO);
399
400void WebMediaPlayerImpl::setPreload(WebKit::WebMediaPlayer::Preload preload) {
[email protected]8931c41a2009-07-07 17:31:49401 DCHECK(MessageLoop::current() == main_loop_);
[email protected]4e6be3f2009-05-07 02:24:44402
[email protected]23a8b1d82011-04-05 16:28:20403 pipeline_->SetPreload(static_cast<media::Preload>(preload));
[email protected]4e6be3f2009-05-07 02:24:44404}
405
406bool WebMediaPlayerImpl::totalBytesKnown() {
[email protected]8931c41a2009-07-07 17:31:49407 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53408
[email protected]3b4cbbf2009-07-11 00:16:19409 return pipeline_->GetTotalBytes() != 0;
[email protected]d43ed912009-02-03 04:52:53410}
411
[email protected]4e6be3f2009-05-07 02:24:44412bool WebMediaPlayerImpl::hasVideo() const {
[email protected]8931c41a2009-07-07 17:31:49413 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53414
[email protected]cee32342011-03-09 15:58:16415 return pipeline_->HasVideo();
[email protected]d43ed912009-02-03 04:52:53416}
417
[email protected]fc367af2009-08-14 23:06:35418bool WebMediaPlayerImpl::hasAudio() const {
419 DCHECK(MessageLoop::current() == main_loop_);
420
[email protected]cee32342011-03-09 15:58:16421 return pipeline_->HasAudio();
[email protected]fc367af2009-08-14 23:06:35422}
423
[email protected]4e6be3f2009-05-07 02:24:44424WebKit::WebSize WebMediaPlayerImpl::naturalSize() const {
[email protected]8931c41a2009-07-07 17:31:49425 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53426
[email protected]2975fa532011-09-19 20:18:33427 gfx::Size size;
428 pipeline_->GetNaturalVideoSize(&size);
429 return WebKit::WebSize(size);
[email protected]d43ed912009-02-03 04:52:53430}
431
[email protected]4e6be3f2009-05-07 02:24:44432bool WebMediaPlayerImpl::paused() const {
[email protected]8931c41a2009-07-07 17:31:49433 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53434
[email protected]3b4cbbf2009-07-11 00:16:19435 return pipeline_->GetPlaybackRate() == 0.0f;
[email protected]d43ed912009-02-03 04:52:53436}
437
[email protected]4e6be3f2009-05-07 02:24:44438bool WebMediaPlayerImpl::seeking() const {
[email protected]8931c41a2009-07-07 17:31:49439 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53440
[email protected]0acebfa2009-08-21 22:45:40441 if (ready_state_ == WebKit::WebMediaPlayer::HaveNothing)
442 return false;
[email protected]67cd5052009-09-10 21:53:22443
[email protected]b3766a22010-12-22 17:34:13444 return seeking_;
[email protected]ec9212f2008-12-18 21:40:36445}
446
[email protected]4e6be3f2009-05-07 02:24:44447float WebMediaPlayerImpl::duration() const {
[email protected]8931c41a2009-07-07 17:31:49448 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53449
[email protected]47b06ceb2010-08-04 22:41:11450 base::TimeDelta duration = pipeline_->GetMediaDuration();
451 if (duration.InMicroseconds() == media::Limits::kMaxTimeInMicroseconds)
452 return std::numeric_limits<float>::infinity();
453 return static_cast<float>(duration.InSecondsF());
[email protected]d43ed912009-02-03 04:52:53454}
455
[email protected]4e6be3f2009-05-07 02:24:44456float WebMediaPlayerImpl::currentTime() const {
[email protected]8931c41a2009-07-07 17:31:49457 DCHECK(MessageLoop::current() == main_loop_);
[email protected]f467d032009-10-23 00:56:24458 if (paused_) {
459 return static_cast<float>(paused_time_.InSecondsF());
460 }
[email protected]128740b2009-07-17 22:09:28461 return static_cast<float>(pipeline_->GetCurrentTime().InSecondsF());
[email protected]d43ed912009-02-03 04:52:53462}
463
[email protected]4e6be3f2009-05-07 02:24:44464int WebMediaPlayerImpl::dataRate() const {
[email protected]8931c41a2009-07-07 17:31:49465 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53466
467 // TODO(hclam): Add this method call if pipeline has it in the interface.
468 return 0;
469}
470
[email protected]ddb1e5a2010-12-13 20:10:45471WebKit::WebMediaPlayer::NetworkState WebMediaPlayerImpl::networkState() const {
472 return network_state_;
473}
474
475WebKit::WebMediaPlayer::ReadyState WebMediaPlayerImpl::readyState() const {
476 return ready_state_;
477}
478
[email protected]f70f8e12010-05-25 21:30:39479const WebKit::WebTimeRanges& WebMediaPlayerImpl::buffered() {
480 DCHECK(MessageLoop::current() == main_loop_);
481
482 // Update buffered_ with the most recent buffered time.
[email protected]69a83852010-06-12 01:12:13483 if (buffered_.size() > 0) {
484 float buffered_time = static_cast<float>(
485 pipeline_->GetBufferedTime().InSecondsF());
486 if (buffered_time >= buffered_[0].start)
487 buffered_[0].end = buffered_time;
488 }
[email protected]f70f8e12010-05-25 21:30:39489
490 return buffered_;
491}
492
[email protected]4e6be3f2009-05-07 02:24:44493float WebMediaPlayerImpl::maxTimeSeekable() const {
[email protected]8931c41a2009-07-07 17:31:49494 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53495
[email protected]38259a7a82009-07-29 21:49:49496 // If we are performing streaming, we report that we cannot seek at all.
497 // We are using this flag to indicate if the data source supports seeking
498 // or not. We should be able to seek even if we are performing streaming.
499 // TODO(hclam): We need to update this when we have better caching.
500 if (pipeline_->IsStreaming())
[email protected]73293602009-04-29 00:30:22501 return 0.0f;
[email protected]fd286f22010-04-20 23:45:15502 return static_cast<float>(pipeline_->GetMediaDuration().InSecondsF());
[email protected]ec9212f2008-12-18 21:40:36503}
504
[email protected]4e6be3f2009-05-07 02:24:44505unsigned long long WebMediaPlayerImpl::bytesLoaded() const {
[email protected]8931c41a2009-07-07 17:31:49506 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53507
[email protected]3b4cbbf2009-07-11 00:16:19508 return pipeline_->GetBufferedBytes();
[email protected]d43ed912009-02-03 04:52:53509}
510
[email protected]4e6be3f2009-05-07 02:24:44511unsigned long long WebMediaPlayerImpl::totalBytes() const {
[email protected]8931c41a2009-07-07 17:31:49512 DCHECK(MessageLoop::current() == main_loop_);
[email protected]d43ed912009-02-03 04:52:53513
[email protected]3b4cbbf2009-07-11 00:16:19514 return pipeline_->GetTotalBytes();
[email protected]d43ed912009-02-03 04:52:53515}
516
[email protected]4e6be3f2009-05-07 02:24:44517void WebMediaPlayerImpl::setSize(const WebSize& size) {
[email protected]8931c41a2009-07-07 17:31:49518 DCHECK(MessageLoop::current() == main_loop_);
519 DCHECK(proxy_);
[email protected]d43ed912009-02-03 04:52:53520
[email protected]8931c41a2009-07-07 17:31:49521 proxy_->SetSize(gfx::Rect(0, 0, size.width, size.height));
[email protected]ec9212f2008-12-18 21:40:36522}
523
[email protected]df143bdc2009-06-16 17:34:19524void WebMediaPlayerImpl::paint(WebCanvas* canvas,
[email protected]4e6be3f2009-05-07 02:24:44525 const WebRect& rect) {
[email protected]8931c41a2009-07-07 17:31:49526 DCHECK(MessageLoop::current() == main_loop_);
527 DCHECK(proxy_);
[email protected]4e6be3f2009-05-07 02:24:44528
[email protected]8c89e7792009-08-19 21:18:34529#if WEBKIT_USING_SKIA
[email protected]8931c41a2009-07-07 17:31:49530 proxy_->Paint(canvas, rect);
[email protected]776775e2009-09-21 15:21:29531#elif WEBKIT_USING_CG
[email protected]32da1002010-03-03 21:57:35532 // Get the current scaling in X and Y.
533 CGAffineTransform mat = CGContextGetCTM(canvas);
534 float scale_x = sqrt(mat.a * mat.a + mat.b * mat.b);
535 float scale_y = sqrt(mat.c * mat.c + mat.d * mat.d);
536 float inverse_scale_x = SkScalarNearlyZero(scale_x) ? 0.0f : 1.0f / scale_x;
537 float inverse_scale_y = SkScalarNearlyZero(scale_y) ? 0.0f : 1.0f / scale_y;
538 int scaled_width = static_cast<int>(rect.width * fabs(scale_x));
539 int scaled_height = static_cast<int>(rect.height * fabs(scale_y));
540
541 // Make sure we don't create a huge canvas.
542 // TODO(hclam): Respect the aspect ratio.
543 if (scaled_width > static_cast<int>(media::Limits::kMaxCanvas))
544 scaled_width = media::Limits::kMaxCanvas;
545 if (scaled_height > static_cast<int>(media::Limits::kMaxCanvas))
546 scaled_height = media::Limits::kMaxCanvas;
547
[email protected]776775e2009-09-21 15:21:29548 // If there is no preexisting platform canvas, or if the size has
549 // changed, recreate the canvas. This is to avoid recreating the bitmap
550 // buffer over and over for each frame of video.
551 if (!skia_canvas_.get() ||
[email protected]32da1002010-03-03 21:57:35552 skia_canvas_->getDevice()->width() != scaled_width ||
553 skia_canvas_->getDevice()->height() != scaled_height) {
554 skia_canvas_.reset(
555 new skia::PlatformCanvas(scaled_width, scaled_height, true));
[email protected]776775e2009-09-21 15:21:29556 }
557
558 // Draw to our temporary skia canvas.
[email protected]32da1002010-03-03 21:57:35559 gfx::Rect normalized_rect(scaled_width, scaled_height);
[email protected]776775e2009-09-21 15:21:29560 proxy_->Paint(skia_canvas_.get(), normalized_rect);
561
562 // The mac coordinate system is flipped vertical from the normal skia
563 // coordinates. During painting of the frame, flip the coordinates
564 // system and, for simplicity, also translate the clip rectangle to
565 // start at 0,0.
566 CGContextSaveGState(canvas);
567 CGContextTranslateCTM(canvas, rect.x, rect.height + rect.y);
[email protected]32da1002010-03-03 21:57:35568 CGContextScaleCTM(canvas, inverse_scale_x, -inverse_scale_y);
[email protected]776775e2009-09-21 15:21:29569
570 // We need a local variable CGRect version for DrawToContext.
571 CGRect normalized_cgrect =
572 CGRectMake(normalized_rect.x(), normalized_rect.y(),
573 normalized_rect.width(), normalized_rect.height());
574
575 // Copy the frame rendered to our temporary skia canvas onto the passed in
576 // canvas.
[email protected]62f2e802011-05-26 14:28:35577 skia::DrawToNativeContext(skia_canvas_.get(), canvas, 0, 0,
578 &normalized_cgrect);
[email protected]776775e2009-09-21 15:21:29579
580 CGContextRestoreGState(canvas);
[email protected]8c89e7792009-08-19 21:18:34581#else
[email protected]776775e2009-09-21 15:21:29582 NOTIMPLEMENTED() << "We only support rendering to skia or CG";
[email protected]8c89e7792009-08-19 21:18:34583#endif
[email protected]ec9212f2008-12-18 21:40:36584}
[email protected]5df51652009-01-17 00:03:00585
[email protected]38259a7a82009-07-29 21:49:49586bool WebMediaPlayerImpl::hasSingleSecurityOrigin() const {
[email protected]cf31d6f2010-10-26 02:23:47587 if (proxy_)
588 return proxy_->HasSingleOrigin();
[email protected]fcdb7462009-10-21 21:05:11589 return true;
[email protected]38259a7a82009-07-29 21:49:49590}
591
592WebKit::WebMediaPlayer::MovieLoadType
593 WebMediaPlayerImpl::movieLoadType() const {
594 DCHECK(MessageLoop::current() == main_loop_);
595
596 // TODO(hclam): If the pipeline is performing streaming, we say that this is
597 // a live stream. But instead it should be a StoredStream if we have proper
598 // caching.
599 if (pipeline_->IsStreaming())
600 return WebKit::WebMediaPlayer::LiveStream;
601 return WebKit::WebMediaPlayer::Unknown;
602}
603
[email protected]e06e16d82011-05-26 22:13:33604float WebMediaPlayerImpl::mediaTimeForTimeValue(float timeValue) const {
605 return ConvertSecondsToTimestamp(timeValue).InSecondsF();
606}
607
[email protected]d82b18ae2011-03-23 21:28:59608unsigned WebMediaPlayerImpl::decodedFrameCount() const {
[email protected]4c51bc662011-02-16 02:03:16609 DCHECK(MessageLoop::current() == main_loop_);
610
611 media::PipelineStatistics stats = pipeline_->GetStatistics();
612 return stats.video_frames_decoded;
613}
614
[email protected]d82b18ae2011-03-23 21:28:59615unsigned WebMediaPlayerImpl::droppedFrameCount() const {
[email protected]4c51bc662011-02-16 02:03:16616 DCHECK(MessageLoop::current() == main_loop_);
617
618 media::PipelineStatistics stats = pipeline_->GetStatistics();
619 return stats.video_frames_dropped;
620}
621
[email protected]d82b18ae2011-03-23 21:28:59622unsigned WebMediaPlayerImpl::audioDecodedByteCount() const {
[email protected]4c51bc662011-02-16 02:03:16623 DCHECK(MessageLoop::current() == main_loop_);
624
625 media::PipelineStatistics stats = pipeline_->GetStatistics();
626 return stats.audio_bytes_decoded;
627}
628
[email protected]d82b18ae2011-03-23 21:28:59629unsigned WebMediaPlayerImpl::videoDecodedByteCount() const {
[email protected]4c51bc662011-02-16 02:03:16630 DCHECK(MessageLoop::current() == main_loop_);
631
632 media::PipelineStatistics stats = pipeline_->GetStatistics();
633 return stats.video_bytes_decoded;
634}
635
[email protected]e81283bb2010-08-31 18:01:21636WebKit::WebVideoFrame* WebMediaPlayerImpl::getCurrentFrame() {
637 scoped_refptr<media::VideoFrame> video_frame;
638 proxy_->GetCurrentFrame(&video_frame);
639 if (video_frame.get())
640 return new WebVideoFrameImpl(video_frame);
641 return NULL;
642}
643
644void WebMediaPlayerImpl::putCurrentFrame(
645 WebKit::WebVideoFrame* web_video_frame) {
646 if (web_video_frame) {
[email protected]ad8e04a2010-11-01 04:16:27647 scoped_refptr<media::VideoFrame> video_frame(
648 WebVideoFrameImpl::toVideoFrame(web_video_frame));
[email protected]e81283bb2010-08-31 18:01:21649 proxy_->PutCurrentFrame(video_frame);
650 delete web_video_frame;
651 }
652}
653
[email protected]81bb3322011-07-21 15:55:50654// TODO(acolwell): Uncomment once WebKit changes are checked in.
655// https://bugs.webkit.org/show_bug.cgi?id=64731
656/*
657bool WebMediaPlayerImpl::sourceAppend(const unsigned char* data,
658 unsigned length) {
659 DCHECK(MessageLoop::current() == main_loop_);
660 return proxy_->DemuxerAppend(data, length);
661}
662
663void WebMediaPlayerImpl::sourceEndOfStream(
664 WebKit::WebMediaPlayer::EndOfStreamStatus status) {
665 DCHECK(MessageLoop::current() == main_loop_);
666 media::PipelineStatus pipeline_status = media::PIPELINE_OK;
667
668 switch(status) {
[email protected]e4064fd2011-08-04 16:15:51669 case WebKit::WebMediaPlayer::EosNoError:
670 break;
[email protected]81bb3322011-07-21 15:55:50671 case WebKit::WebMediaPlayer::EosNetworkError:
672 pipeline_status = media::PIPELINE_ERROR_NETWORK;
673 break;
674 case WebKit::WebMediaPlayer::EosDecodeError:
675 pipeline_status = media::PIPELINE_ERROR_DECODE;
676 break;
677 default:
678 NOTIMPLEMENTED();
679 }
680
681 proxy_->DemuxerEndOfStream(pipeline_status);
682}
683*/
684
[email protected]4e6be3f2009-05-07 02:24:44685void WebMediaPlayerImpl::WillDestroyCurrentMessageLoop() {
[email protected]8931c41a2009-07-07 17:31:49686 Destroy();
687 main_loop_ = NULL;
688}
689
690void WebMediaPlayerImpl::Repaint() {
691 DCHECK(MessageLoop::current() == main_loop_);
692 GetClient()->repaint();
693}
694
[email protected]a9590c22011-03-16 16:57:02695void WebMediaPlayerImpl::OnPipelineInitialize(PipelineStatus status) {
[email protected]8931c41a2009-07-07 17:31:49696 DCHECK(MessageLoop::current() == main_loop_);
[email protected]a9590c22011-03-16 16:57:02697 if (status == media::PIPELINE_OK) {
[email protected]67cd5052009-09-10 21:53:22698 // Only keep one time range starting from 0.
[email protected]c8ca48ea2009-10-16 01:59:17699 WebKit::WebTimeRanges new_buffered(static_cast<size_t>(1));
[email protected]747ca432009-10-09 22:44:48700 new_buffered[0].start = 0.0f;
701 new_buffered[0].end =
[email protected]fd286f22010-04-20 23:45:15702 static_cast<float>(pipeline_->GetMediaDuration().InSecondsF());
[email protected]747ca432009-10-09 22:44:48703 buffered_.swap(new_buffered);
[email protected]67cd5052009-09-10 21:53:22704
[email protected]65bdef09c2011-05-20 05:41:27705 if (pipeline_->IsLoaded()) {
706 SetNetworkState(WebKit::WebMediaPlayer::Loaded);
707 }
708
[email protected]64d3d792010-04-02 03:03:07709 // Since we have initialized the pipeline, say we have everything otherwise
710 // we'll remain either loading/idle.
[email protected]96706912009-07-15 17:18:05711 // TODO(hclam): change this to report the correct status.
712 SetReadyState(WebKit::WebMediaPlayer::HaveMetadata);
713 SetReadyState(WebKit::WebMediaPlayer::HaveEnoughData);
[email protected]96706912009-07-15 17:18:05714 } else {
[email protected]a9590c22011-03-16 16:57:02715 // TODO(hclam): should use |status| to determine the state
[email protected]96706912009-07-15 17:18:05716 // properly and reports error using MediaError.
717 // WebKit uses FormatError to indicate an error for bogus URL or bad file.
718 // Since we are at the initialization stage we can safely treat every error
719 // as format error. Should post a task to call to |webmediaplayer_|.
720 SetNetworkState(WebKit::WebMediaPlayer::FormatError);
721 }
[email protected]83f2a8a2009-08-18 22:42:15722
723 // Repaint to trigger UI update.
724 Repaint();
[email protected]96706912009-07-15 17:18:05725}
726
[email protected]a9590c22011-03-16 16:57:02727void WebMediaPlayerImpl::OnPipelineSeek(PipelineStatus status) {
[email protected]96706912009-07-15 17:18:05728 DCHECK(MessageLoop::current() == main_loop_);
[email protected]5d11eff2011-09-15 00:06:06729 seeking_ = false;
730 if (pending_seek_) {
731 pending_seek_ = false;
732 seek(pending_seek_seconds_);
733 return;
734 }
735
[email protected]a9590c22011-03-16 16:57:02736 if (status == media::PIPELINE_OK) {
[email protected]44ff37c02009-10-24 01:03:03737 // Update our paused time.
738 if (paused_) {
739 paused_time_ = pipeline_->GetCurrentTime();
740 }
741
[email protected]0acebfa2009-08-21 22:45:40742 SetReadyState(WebKit::WebMediaPlayer::HaveEnoughData);
[email protected]96706912009-07-15 17:18:05743 GetClient()->timeChanged();
744 }
[email protected]8931c41a2009-07-07 17:31:49745}
746
[email protected]a9590c22011-03-16 16:57:02747void WebMediaPlayerImpl::OnPipelineEnded(PipelineStatus status) {
[email protected]576537842009-08-12 23:52:05748 DCHECK(MessageLoop::current() == main_loop_);
[email protected]a9590c22011-03-16 16:57:02749 if (status == media::PIPELINE_OK) {
[email protected]576537842009-08-12 23:52:05750 GetClient()->timeChanged();
751 }
752}
753
[email protected]a9590c22011-03-16 16:57:02754void WebMediaPlayerImpl::OnPipelineError(PipelineStatus error) {
[email protected]db190487d2009-07-30 18:51:52755 DCHECK(MessageLoop::current() == main_loop_);
[email protected]a9590c22011-03-16 16:57:02756 switch (error) {
[email protected]db190487d2009-07-30 18:51:52757 case media::PIPELINE_OK:
[email protected]a9590c22011-03-16 16:57:02758 LOG(DFATAL) << "PIPELINE_OK isn't an error!";
759 break;
760
[email protected]e4064fd2011-08-04 16:15:51761 case media::PIPELINE_ERROR_NETWORK:
762 SetNetworkState(WebMediaPlayer::NetworkError);
763 break;
764
[email protected]db190487d2009-07-30 18:51:52765 case media::PIPELINE_ERROR_INITIALIZATION_FAILED:
766 case media::PIPELINE_ERROR_REQUIRED_FILTER_MISSING:
767 case media::PIPELINE_ERROR_COULD_NOT_RENDER:
[email protected]db190487d2009-07-30 18:51:52768 case media::PIPELINE_ERROR_URL_NOT_FOUND:
[email protected]db190487d2009-07-30 18:51:52769 case media::PIPELINE_ERROR_READ:
[email protected]db190487d2009-07-30 18:51:52770 case media::DEMUXER_ERROR_COULD_NOT_OPEN:
771 case media::DEMUXER_ERROR_COULD_NOT_PARSE:
772 case media::DEMUXER_ERROR_NO_SUPPORTED_STREAMS:
773 case media::DEMUXER_ERROR_COULD_NOT_CREATE_THREAD:
[email protected]b6c29552011-03-14 15:56:29774 case media::DATASOURCE_ERROR_URL_NOT_SUPPORTED:
[email protected]9c4e77ab2009-07-31 00:17:08775 // Format error.
776 SetNetworkState(WebMediaPlayer::FormatError);
777 break;
778
779 case media::PIPELINE_ERROR_DECODE:
780 case media::PIPELINE_ERROR_ABORT:
781 case media::PIPELINE_ERROR_OUT_OF_MEMORY:
782 case media::PIPELINE_ERROR_AUDIO_HARDWARE:
[email protected]641c9abc2011-01-05 18:44:10783 case media::PIPELINE_ERROR_OPERATION_PENDING:
784 case media::PIPELINE_ERROR_INVALID_STATE:
[email protected]db190487d2009-07-30 18:51:52785 // Decode error.
786 SetNetworkState(WebMediaPlayer::DecodeError);
787 break;
788 }
[email protected]bb2c1f32009-08-14 04:14:50789
790 // Repaint to trigger UI update.
791 Repaint();
[email protected]db190487d2009-07-30 18:51:52792}
793
[email protected]a9590c22011-03-16 16:57:02794void WebMediaPlayerImpl::OnNetworkEvent(PipelineStatus status) {
[email protected]4f92fbc2009-10-16 01:29:50795 DCHECK(MessageLoop::current() == main_loop_);
[email protected]a9590c22011-03-16 16:57:02796 if (status == media::PIPELINE_OK) {
[email protected]7b5ce7d6d2011-08-17 14:07:47797 if (pipeline_->IsNetworkActive())
[email protected]4f92fbc2009-10-16 01:29:50798 SetNetworkState(WebKit::WebMediaPlayer::Loading);
[email protected]7b5ce7d6d2011-08-17 14:07:47799 else
[email protected]4f92fbc2009-10-16 01:29:50800 SetNetworkState(WebKit::WebMediaPlayer::Idle);
801 }
802}
803
[email protected]81bb3322011-07-21 15:55:50804void WebMediaPlayerImpl::OnDemuxerOpened() {
805 DCHECK(MessageLoop::current() == main_loop_);
806
807 // TODO(acolwell): Uncomment once WebKit changes are checked in.
808 // https://bugs.webkit.org/show_bug.cgi?id=64731
809 //GetClient()->sourceOpened();
810}
811
[email protected]8931c41a2009-07-07 17:31:49812void WebMediaPlayerImpl::SetNetworkState(
813 WebKit::WebMediaPlayer::NetworkState state) {
814 DCHECK(MessageLoop::current() == main_loop_);
[email protected]867e59272009-08-25 18:08:16815 // Always notify to ensure client has the latest value.
816 network_state_ = state;
817 GetClient()->networkStateChanged();
[email protected]8931c41a2009-07-07 17:31:49818}
819
820void WebMediaPlayerImpl::SetReadyState(
821 WebKit::WebMediaPlayer::ReadyState state) {
822 DCHECK(MessageLoop::current() == main_loop_);
[email protected]867e59272009-08-25 18:08:16823 // Always notify to ensure client has the latest value.
824 ready_state_ = state;
825 GetClient()->readyStateChanged();
[email protected]8931c41a2009-07-07 17:31:49826}
827
828void WebMediaPlayerImpl::Destroy() {
829 DCHECK(MessageLoop::current() == main_loop_);
830
[email protected]5b5bb9d2010-10-22 19:57:36831 // Tell the data source to abort any pending reads so that the pipeline is
832 // not blocked when issuing stop commands to the other filters.
[email protected]81bb3322011-07-21 15:55:50833 if (proxy_) {
[email protected]f63760a2011-02-16 04:59:10834 proxy_->AbortDataSources();
[email protected]81bb3322011-07-21 15:55:50835 proxy_->DemuxerShutdown();
836 }
[email protected]020fba32011-06-29 16:37:46837
[email protected]8931c41a2009-07-07 17:31:49838 // Make sure to kill the pipeline so there's no more media threads running.
[email protected]5badb082010-06-11 17:40:15839 // Note: stopping the pipeline might block for a long time.
[email protected]a8e24d522010-12-01 07:13:58840 if (pipeline_) {
[email protected]ea431e52011-03-17 22:03:12841 media::PipelineStatusNotification note;
842 pipeline_->Stop(note.Callback());
843 note.Wait();
[email protected]38aefc312011-09-20 05:06:37844
845 // Let V8 know we are not using extra resources anymore.
846 if (destructor_or_task_had_run_.get() != NULL) {
847 if (destructor_or_task_had_run_->value())
848 v8::V8::AdjustAmountOfExternalAllocatedMemory(-kPlayerExtraMemory);
849 else
850 destructor_or_task_had_run_->set_value(true);
851 }
852 destructor_or_task_had_run_ = NULL;
[email protected]a8e24d522010-12-01 07:13:58853 }
[email protected]5df51652009-01-17 00:03:00854
[email protected]f78d1dfc2011-01-15 07:09:27855 message_loop_factory_.reset();
856
[email protected]8931c41a2009-07-07 17:31:49857 // And then detach the proxy, it may live on the render thread for a little
858 // longer until all the tasks are finished.
859 if (proxy_) {
860 proxy_->Detach();
861 proxy_ = NULL;
[email protected]a7281022009-06-17 17:58:04862 }
[email protected]5df51652009-01-17 00:03:00863}
864
[email protected]8931c41a2009-07-07 17:31:49865WebKit::WebMediaPlayerClient* WebMediaPlayerImpl::GetClient() {
866 DCHECK(MessageLoop::current() == main_loop_);
867 DCHECK(client_);
868 return client_;
[email protected]5df51652009-01-17 00:03:00869}
[email protected]add51772009-06-11 18:25:17870
[email protected]38aefc312011-09-20 05:06:37871void WebMediaPlayerImpl::UsesExtraMemoryTask(
872 scoped_refptr<DestructorOrTaskHadRun> destructor_or_task_had_run) {
873 if (!destructor_or_task_had_run->value()) {
874 v8::V8::AdjustAmountOfExternalAllocatedMemory(kPlayerExtraMemory);
875 destructor_or_task_had_run->set_value(true);
876 }
877}
878
[email protected]add51772009-06-11 18:25:17879} // namespace webkit_glue