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

Side by Side Diff: webkit/glue/webmediaplayer_impl.cc

Issue 147225: Refactoring to introduce refcount to WebMediaPlayerImpl... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « webkit/glue/webmediaplayer_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2008-2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2008-2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "webkit/glue/webmediaplayer_impl.h"
6
5 #include "base/command_line.h" 7 #include "base/command_line.h"
6 #include "googleurl/src/gurl.h" 8 #include "googleurl/src/gurl.h"
7 #include "media/filters/ffmpeg_audio_decoder.h" 9 #include "media/filters/ffmpeg_audio_decoder.h"
8 #include "media/filters/ffmpeg_demuxer.h" 10 #include "media/filters/ffmpeg_demuxer.h"
9 #include "media/filters/ffmpeg_video_decoder.h" 11 #include "media/filters/ffmpeg_video_decoder.h"
10 #include "media/filters/null_audio_renderer.h" 12 #include "media/filters/null_audio_renderer.h"
11 #include "webkit/api/public/WebRect.h" 13 #include "webkit/api/public/WebRect.h"
12 #include "webkit/api/public/WebSize.h" 14 #include "webkit/api/public/WebSize.h"
13 #include "webkit/api/public/WebURL.h" 15 #include "webkit/api/public/WebURL.h"
14 #include "webkit/glue/media/video_renderer_impl.h" 16 #include "webkit/glue/media/video_renderer_impl.h"
15 #include "webkit/glue/webmediaplayer_impl.h"
16 17
17 using WebKit::WebCanvas; 18 using WebKit::WebCanvas;
18 using WebKit::WebRect; 19 using WebKit::WebRect;
19 using WebKit::WebSize; 20 using WebKit::WebSize;
20 21
22 namespace {
23
24 // Limits the maximum outstanding repaints posted on render thread.
25 // This number of 50 is a guess, it does not take too much memory on the task
26 // queue but gives up a pretty good latency on repaint.
27 const int kMaxOutstandingRepaints = 50;
28
29 } // namespace
30
21 namespace webkit_glue { 31 namespace webkit_glue {
22 32
23 ///////////////////////////////////////////////////////////////////////////// 33 /////////////////////////////////////////////////////////////////////////////
24 // Task to be posted on main thread that fire WebMediaPlayerClient methods. 34 // WebMediaPlayerImpl::Proxy implementation
25 35
26 class NotifyWebMediaPlayerClientTask : public CancelableTask { 36 WebMediaPlayerImpl::Proxy::Proxy(MessageLoop* render_loop,
27 public: 37 WebMediaPlayerImpl* webmediaplayer)
28 NotifyWebMediaPlayerClientTask(WebMediaPlayerImpl* media_player, 38 : render_loop_(render_loop),
29 WebMediaPlayerClientMethod method) 39 webmediaplayer_(webmediaplayer),
30 : media_player_(media_player), 40 outstanding_repaints_(0) {
31 method_(method) {} 41 DCHECK(render_loop_);
42 DCHECK(webmediaplayer_);
43 }
32 44
33 virtual void Run() { 45 WebMediaPlayerImpl::Proxy::~Proxy() {
34 if (media_player_) { 46 Detach();
35 (media_player_->client()->*(method_))(); 47 }
36 media_player_->DidTask(this); 48
37 } 49 void WebMediaPlayerImpl::Proxy::Repaint() {
50 AutoLock auto_lock(lock_);
51 if (outstanding_repaints_ < kMaxOutstandingRepaints) {
52 ++outstanding_repaints_;
53
54 render_loop_->PostTask(FROM_HERE,
55 NewRunnableMethod(this, &WebMediaPlayerImpl::Proxy::RepaintTask));
38 } 56 }
57 }
39 58
40 virtual void Cancel() { 59 void WebMediaPlayerImpl::Proxy::TimeChanged() {
41 media_player_ = NULL; 60 render_loop_->PostTask(FROM_HERE,
61 NewRunnableMethod(this, &WebMediaPlayerImpl::Proxy::TimeChangedTask));
62 }
63
64 void WebMediaPlayerImpl::Proxy::NetworkStateChanged(
65 WebKit::WebMediaPlayer::NetworkState state) {
66 render_loop_->PostTask(FROM_HERE,
67 NewRunnableMethod(this,
68 &WebMediaPlayerImpl::Proxy::NetworkStateChangedTask,
69 state));
70 }
71
72 void WebMediaPlayerImpl::Proxy::ReadyStateChanged(
73 WebKit::WebMediaPlayer::ReadyState state) {
74 render_loop_->PostTask(FROM_HERE,
75 NewRunnableMethod(this,
76 &WebMediaPlayerImpl::Proxy::ReadyStateChangedTask,
77 state));
78 }
79
80 void WebMediaPlayerImpl::Proxy::RepaintTask() {
81 DCHECK(MessageLoop::current() == render_loop_);
82 {
83 AutoLock auto_lock(lock_);
84 --outstanding_repaints_;
85 DCHECK_GE(outstanding_repaints_, 0);
42 } 86 }
87 if (webmediaplayer_)
88 webmediaplayer_->Repaint();
89 }
43 90
44 private: 91 void WebMediaPlayerImpl::Proxy::TimeChangedTask() {
45 WebMediaPlayerImpl* media_player_; 92 DCHECK(MessageLoop::current() == render_loop_);
46 WebMediaPlayerClientMethod method_; 93 if (webmediaplayer_)
94 webmediaplayer_->TimeChanged();
95 }
47 96
48 DISALLOW_COPY_AND_ASSIGN(NotifyWebMediaPlayerClientTask); 97 void WebMediaPlayerImpl::Proxy::NetworkStateChangedTask(
49 }; 98 WebKit::WebMediaPlayer::NetworkState state) {
99 DCHECK(MessageLoop::current() == render_loop_);
100 if (webmediaplayer_)
101 webmediaplayer_->SetNetworkState(state);
102 }
103
104 void WebMediaPlayerImpl::Proxy::ReadyStateChangedTask(
105 WebKit::WebMediaPlayer::ReadyState state) {
106 DCHECK(MessageLoop::current() == render_loop_);
107 if (webmediaplayer_)
108 webmediaplayer_->SetReadyState(state);
109 }
110
111 void WebMediaPlayerImpl::Proxy::SetVideoRenderer(
112 VideoRendererImpl* video_renderer) {
113 video_renderer_ = video_renderer;
114 }
115
116 void WebMediaPlayerImpl::Proxy::Paint(skia::PlatformCanvas* canvas,
117 const gfx::Rect& dest_rect) {
118 DCHECK(MessageLoop::current() == render_loop_);
119 if (video_renderer_) {
120 video_renderer_->Paint(canvas, dest_rect);
121 }
122 }
123
124 void WebMediaPlayerImpl::Proxy::SetSize(const gfx::Rect& rect) {
125 DCHECK(MessageLoop::current() == render_loop_);
126 if (video_renderer_) {
127 video_renderer_->SetRect(rect);
128 }
129 }
130
131 void WebMediaPlayerImpl::Proxy::Detach() {
132 DCHECK(MessageLoop::current() == render_loop_);
133 webmediaplayer_ = NULL;
134 video_renderer_ = NULL;
135 }
136
137 void WebMediaPlayerImpl::Proxy::PipelineInitializationCallback(bool success) {
138 if (success) {
139 // Since we have initialized the pipeline, say we have everything.
140 // TODO(hclam): change this to report the correct status. Should also post
141 // a task to call to |webmediaplayer_|.
142 ReadyStateChanged(WebKit::WebMediaPlayer::HaveMetadata);
143 ReadyStateChanged(WebKit::WebMediaPlayer::HaveEnoughData);
144 NetworkStateChanged(WebKit::WebMediaPlayer::Loaded);
145 } else {
146 // TODO(hclam): should use pipeline_.GetError() to determine the state
147 // properly and reports error using MediaError.
148 // WebKit uses FormatError to indicate an error for bogus URL or bad file.
149 // Since we are at the initialization stage we can safely treat every error
150 // as format error. Should post a task to call to |webmediaplayer_|.
151 NetworkStateChanged(WebKit::WebMediaPlayer::FormatError);
152 }
153 }
154
155 void WebMediaPlayerImpl::Proxy::PipelineSeekCallback(bool success) {
156 if (success)
157 TimeChanged();
158 }
50 159
51 ///////////////////////////////////////////////////////////////////////////// 160 /////////////////////////////////////////////////////////////////////////////
52 // WebMediaPlayerImpl implementation 161 // WebMediaPlayerImpl implementation
53 162
54 WebMediaPlayerImpl::WebMediaPlayerImpl(WebKit::WebMediaPlayerClient* client, 163 WebMediaPlayerImpl::WebMediaPlayerImpl(WebKit::WebMediaPlayerClient* client,
55 media::FilterFactoryCollection* factory) 164 media::FilterFactoryCollection* factory)
56 : network_state_(WebKit::WebMediaPlayer::Empty), 165 : network_state_(WebKit::WebMediaPlayer::Empty),
57 ready_state_(WebKit::WebMediaPlayer::HaveNothing), 166 ready_state_(WebKit::WebMediaPlayer::HaveNothing),
58 main_loop_(NULL), 167 main_loop_(NULL),
59 filter_factory_(factory), 168 filter_factory_(factory),
60 video_renderer_(NULL), 169 client_(client) {
61 client_(client),
62 tasks_(kLastTaskIndex) {
63 // Add in the default filter factories.
64 filter_factory_->AddFactory(media::FFmpegDemuxer::CreateFilterFactory());
65 filter_factory_->AddFactory(media::FFmpegAudioDecoder::CreateFactory());
66 filter_factory_->AddFactory(media::FFmpegVideoDecoder::CreateFactory());
67 filter_factory_->AddFactory(media::NullAudioRenderer::CreateFilterFactory());
68 filter_factory_->AddFactory(VideoRendererImpl::CreateFactory(this));
69
70 DCHECK(client_);
71
72 // Saves the current message loop. 170 // Saves the current message loop.
73 DCHECK(!main_loop_); 171 DCHECK(!main_loop_);
74 main_loop_ = MessageLoop::current(); 172 main_loop_ = MessageLoop::current();
75 173
76 // Also we want to be notified of |main_loop_| destruction. 174 // Also we want to be notified of |main_loop_| destruction.
77 main_loop_->AddDestructionObserver(this); 175 main_loop_->AddDestructionObserver(this);
176
177 // Creates the proxy.
178 proxy_ = new Proxy(main_loop_, this);
179
180 // Add in the default filter factories.
181 filter_factory_->AddFactory(media::FFmpegDemuxer::CreateFilterFactory());
182 filter_factory_->AddFactory(media::FFmpegAudioDecoder::CreateFactory());
183 filter_factory_->AddFactory(media::FFmpegVideoDecoder::CreateFactory());
184 filter_factory_->AddFactory(media::NullAudioRenderer::CreateFilterFactory());
185 filter_factory_->AddFactory(VideoRendererImpl::CreateFactory(proxy_));
78 } 186 }
79 187
80 WebMediaPlayerImpl::~WebMediaPlayerImpl() { 188 WebMediaPlayerImpl::~WebMediaPlayerImpl() {
81 pipeline_.Stop(); 189 Destroy();
82
83 // Cancel all tasks posted on the |main_loop_|.
84 CancelAllTasks();
85 190
86 // Finally tell the |main_loop_| we don't want to be notified of destruction 191 // Finally tell the |main_loop_| we don't want to be notified of destruction
87 // event. 192 // event.
88 if (main_loop_) { 193 if (main_loop_) {
89 main_loop_->RemoveDestructionObserver(this); 194 main_loop_->RemoveDestructionObserver(this);
90 } 195 }
91 } 196 }
92 197
93 void WebMediaPlayerImpl::load(const WebKit::WebURL& url) { 198 void WebMediaPlayerImpl::load(const WebKit::WebURL& url) {
94 DCHECK(main_loop_ && MessageLoop::current() == main_loop_); 199 DCHECK(MessageLoop::current() == main_loop_);
200 DCHECK(proxy_);
95 201
96 // Initialize the pipeline. 202 // Initialize the pipeline.
97 if (network_state_ != WebKit::WebMediaPlayer::Loading) { 203 SetNetworkState(WebKit::WebMediaPlayer::Loading);
98 network_state_ = WebKit::WebMediaPlayer::Loading; 204 SetReadyState(WebKit::WebMediaPlayer::HaveNothing);
99 client_->networkStateChanged(); 205 pipeline_.Start(
100 } 206 filter_factory_.get(),
101 if (ready_state_ != WebKit::WebMediaPlayer::HaveNothing) { 207 url.spec(),
102 ready_state_ = WebKit::WebMediaPlayer::HaveNothing; 208 NewCallback(proxy_.get(),
103 client_->readyStateChanged(); 209 &WebMediaPlayerImpl::Proxy::PipelineInitializationCallback));
104 }
105 pipeline_.Start(filter_factory_.get(), url.spec(),
106 NewCallback(this, &WebMediaPlayerImpl::OnPipelineInitialize));
107 } 210 }
108 211
109 void WebMediaPlayerImpl::cancelLoad() { 212 void WebMediaPlayerImpl::cancelLoad() {
110 DCHECK(main_loop_ && MessageLoop::current() == main_loop_); 213 DCHECK(MessageLoop::current() == main_loop_);
111
112 // TODO(hclam): Calls to render_view_ to stop resource load
113 } 214 }
114 215
115 void WebMediaPlayerImpl::play() { 216 void WebMediaPlayerImpl::play() {
116 DCHECK(main_loop_ && MessageLoop::current() == main_loop_); 217 DCHECK(MessageLoop::current() == main_loop_);
117 218
118 // TODO(hclam): We should restore the previous playback rate rather than 219 // TODO(hclam): We should restore the previous playback rate rather than
119 // having it at 1.0. 220 // having it at 1.0.
120 pipeline_.SetPlaybackRate(1.0f); 221 pipeline_.SetPlaybackRate(1.0f);
121 } 222 }
122 223
123 void WebMediaPlayerImpl::pause() { 224 void WebMediaPlayerImpl::pause() {
124 DCHECK(main_loop_ && MessageLoop::current() == main_loop_); 225 DCHECK(MessageLoop::current() == main_loop_);
125 226
126 pipeline_.SetPlaybackRate(0.0f); 227 pipeline_.SetPlaybackRate(0.0f);
127 } 228 }
128 229
129 void WebMediaPlayerImpl::stop() {
130 DCHECK(main_loop_ && MessageLoop::current() == main_loop_);
131
132 // We can fire Stop() multiple times.
133 pipeline_.Stop();
134 }
135
136 void WebMediaPlayerImpl::seek(float seconds) { 230 void WebMediaPlayerImpl::seek(float seconds) {
137 DCHECK(main_loop_ && MessageLoop::current() == main_loop_); 231 DCHECK(MessageLoop::current() == main_loop_);
138 232
139 // Try to preserve as much accuracy as possible. 233 // Try to preserve as much accuracy as possible.
140 float microseconds = seconds * base::Time::kMicrosecondsPerSecond; 234 float microseconds = seconds * base::Time::kMicrosecondsPerSecond;
141 if (seconds != 0) 235 if (seconds != 0)
142 pipeline_.Seek( 236 pipeline_.Seek(
143 base::TimeDelta::FromMicroseconds(static_cast<int64>(microseconds)), 237 base::TimeDelta::FromMicroseconds(static_cast<int64>(microseconds)),
144 NewCallback(this, &WebMediaPlayerImpl::OnPipelineSeek)); 238 NewCallback(proxy_.get(),
239 &WebMediaPlayerImpl::Proxy::PipelineSeekCallback));
145 } 240 }
146 241
147 void WebMediaPlayerImpl::setEndTime(float seconds) { 242 void WebMediaPlayerImpl::setEndTime(float seconds) {
148 DCHECK(main_loop_ && MessageLoop::current() == main_loop_); 243 DCHECK(MessageLoop::current() == main_loop_);
149 244
150 // TODO(hclam): add method call when it has been implemented. 245 // TODO(hclam): add method call when it has been implemented.
151 return; 246 return;
152 } 247 }
153 248
154 void WebMediaPlayerImpl::setRate(float rate) { 249 void WebMediaPlayerImpl::setRate(float rate) {
155 DCHECK(main_loop_ && MessageLoop::current() == main_loop_); 250 DCHECK(MessageLoop::current() == main_loop_);
156 251
157 pipeline_.SetPlaybackRate(rate); 252 pipeline_.SetPlaybackRate(rate);
158 } 253 }
159 254
160 void WebMediaPlayerImpl::setVolume(float volume) { 255 void WebMediaPlayerImpl::setVolume(float volume) {
161 DCHECK(main_loop_ && MessageLoop::current() == main_loop_); 256 DCHECK(MessageLoop::current() == main_loop_);
162 257
163 pipeline_.SetVolume(volume); 258 pipeline_.SetVolume(volume);
164 } 259 }
165 260
166 void WebMediaPlayerImpl::setVisible(bool visible) { 261 void WebMediaPlayerImpl::setVisible(bool visible) {
167 DCHECK(main_loop_ && MessageLoop::current() == main_loop_); 262 DCHECK(MessageLoop::current() == main_loop_);
168 263
169 // TODO(hclam): add appropriate method call when pipeline has it implemented. 264 // TODO(hclam): add appropriate method call when pipeline has it implemented.
170 return; 265 return;
171 } 266 }
172 267
173 bool WebMediaPlayerImpl::setAutoBuffer(bool autoBuffer) { 268 bool WebMediaPlayerImpl::setAutoBuffer(bool autoBuffer) {
174 DCHECK(main_loop_ && MessageLoop::current() == main_loop_); 269 DCHECK(MessageLoop::current() == main_loop_);
175 270
176 return false; 271 return false;
177 } 272 }
178 273
179 bool WebMediaPlayerImpl::totalBytesKnown() { 274 bool WebMediaPlayerImpl::totalBytesKnown() {
180 DCHECK(main_loop_ && MessageLoop::current() == main_loop_); 275 DCHECK(MessageLoop::current() == main_loop_);
181 276
182 return pipeline_.GetTotalBytes() != 0; 277 return pipeline_.GetTotalBytes() != 0;
183 } 278 }
184 279
185 bool WebMediaPlayerImpl::hasVideo() const { 280 bool WebMediaPlayerImpl::hasVideo() const {
186 DCHECK(main_loop_ && MessageLoop::current() == main_loop_); 281 DCHECK(MessageLoop::current() == main_loop_);
187 282
188 size_t width, height; 283 size_t width, height;
189 pipeline_.GetVideoSize(&width, &height); 284 pipeline_.GetVideoSize(&width, &height);
190 return width != 0 && height != 0; 285 return width != 0 && height != 0;
191 } 286 }
192 287
193 WebKit::WebSize WebMediaPlayerImpl::naturalSize() const { 288 WebKit::WebSize WebMediaPlayerImpl::naturalSize() const {
194 DCHECK(main_loop_ && MessageLoop::current() == main_loop_); 289 DCHECK(MessageLoop::current() == main_loop_);
195 290
196 size_t width, height; 291 size_t width, height;
197 pipeline_.GetVideoSize(&width, &height); 292 pipeline_.GetVideoSize(&width, &height);
198 return WebKit::WebSize(width, height); 293 return WebKit::WebSize(width, height);
199 } 294 }
200 295
201 bool WebMediaPlayerImpl::paused() const { 296 bool WebMediaPlayerImpl::paused() const {
202 DCHECK(main_loop_ && MessageLoop::current() == main_loop_); 297 DCHECK(MessageLoop::current() == main_loop_);
203 298
204 return pipeline_.GetPlaybackRate() == 0.0f; 299 return pipeline_.GetPlaybackRate() == 0.0f;
205 } 300 }
206 301
207 bool WebMediaPlayerImpl::seeking() const { 302 bool WebMediaPlayerImpl::seeking() const {
208 DCHECK(main_loop_ && MessageLoop::current() == main_loop_); 303 DCHECK(MessageLoop::current() == main_loop_);
209 304
210 return tasks_[kTimeChangedTaskIndex] != NULL; 305 return false;
211 } 306 }
212 307
213 float WebMediaPlayerImpl::duration() const { 308 float WebMediaPlayerImpl::duration() const {
214 DCHECK(main_loop_ && MessageLoop::current() == main_loop_); 309 DCHECK(MessageLoop::current() == main_loop_);
215 310
216 return static_cast<float>(pipeline_.GetDuration().InSecondsF()); 311 return static_cast<float>(pipeline_.GetDuration().InSecondsF());
217 } 312 }
218 313
219 float WebMediaPlayerImpl::currentTime() const { 314 float WebMediaPlayerImpl::currentTime() const {
220 DCHECK(main_loop_ && MessageLoop::current() == main_loop_); 315 DCHECK(MessageLoop::current() == main_loop_);
221 316
222 return static_cast<float>(pipeline_.GetTime().InSecondsF()); 317 return static_cast<float>(pipeline_.GetTime().InSecondsF());
223 } 318 }
224 319
225 int WebMediaPlayerImpl::dataRate() const { 320 int WebMediaPlayerImpl::dataRate() const {
226 DCHECK(main_loop_ && MessageLoop::current() == main_loop_); 321 DCHECK(MessageLoop::current() == main_loop_);
227 322
228 // TODO(hclam): Add this method call if pipeline has it in the interface. 323 // TODO(hclam): Add this method call if pipeline has it in the interface.
229 return 0; 324 return 0;
230 } 325 }
231 326
232 float WebMediaPlayerImpl::maxTimeBuffered() const { 327 float WebMediaPlayerImpl::maxTimeBuffered() const {
233 DCHECK(main_loop_ && MessageLoop::current() == main_loop_); 328 DCHECK(MessageLoop::current() == main_loop_);
234 329
235 return static_cast<float>(pipeline_.GetBufferedTime().InSecondsF()); 330 return static_cast<float>(pipeline_.GetBufferedTime().InSecondsF());
236 } 331 }
237 332
238 float WebMediaPlayerImpl::maxTimeSeekable() const { 333 float WebMediaPlayerImpl::maxTimeSeekable() const {
239 DCHECK(main_loop_ && MessageLoop::current() == main_loop_); 334 DCHECK(MessageLoop::current() == main_loop_);
240 335
241 // TODO(scherkus): move this logic down into the pipeline. 336 // TODO(scherkus): move this logic down into the pipeline.
242 if (pipeline_.GetTotalBytes() == 0) { 337 if (pipeline_.GetTotalBytes() == 0) {
243 return 0.0f; 338 return 0.0f;
244 } 339 }
245 double total_bytes = static_cast<double>(pipeline_.GetTotalBytes()); 340 double total_bytes = static_cast<double>(pipeline_.GetTotalBytes());
246 double buffered_bytes = static_cast<double>(pipeline_.GetBufferedBytes()); 341 double buffered_bytes = static_cast<double>(pipeline_.GetBufferedBytes());
247 double duration = static_cast<double>(pipeline_.GetDuration().InSecondsF()); 342 double duration = static_cast<double>(pipeline_.GetDuration().InSecondsF());
248 return static_cast<float>(duration * (buffered_bytes / total_bytes)); 343 return static_cast<float>(duration * (buffered_bytes / total_bytes));
249 } 344 }
250 345
251 unsigned long long WebMediaPlayerImpl::bytesLoaded() const { 346 unsigned long long WebMediaPlayerImpl::bytesLoaded() const {
252 DCHECK(main_loop_ && MessageLoop::current() == main_loop_); 347 DCHECK(MessageLoop::current() == main_loop_);
253 348
254 return pipeline_.GetBufferedBytes(); 349 return pipeline_.GetBufferedBytes();
255 } 350 }
256 351
257 unsigned long long WebMediaPlayerImpl::totalBytes() const { 352 unsigned long long WebMediaPlayerImpl::totalBytes() const {
258 DCHECK(main_loop_ && MessageLoop::current() == main_loop_); 353 DCHECK(MessageLoop::current() == main_loop_);
259 354
260 return pipeline_.GetTotalBytes(); 355 return pipeline_.GetTotalBytes();
261 } 356 }
262 357
263 void WebMediaPlayerImpl::setSize(const WebSize& size) { 358 void WebMediaPlayerImpl::setSize(const WebSize& size) {
264 DCHECK(main_loop_ && MessageLoop::current() == main_loop_); 359 DCHECK(MessageLoop::current() == main_loop_);
360 DCHECK(proxy_);
265 361
266 if (video_renderer_) { 362 proxy_->SetSize(gfx::Rect(0, 0, size.width, size.height));
267 // TODO(scherkus): Change API to use SetSize().
268 video_renderer_->SetRect(gfx::Rect(0, 0, size.width, size.height));
269 }
270 } 363 }
271 364
272 void WebMediaPlayerImpl::paint(WebCanvas* canvas, 365 void WebMediaPlayerImpl::paint(WebCanvas* canvas,
273 const WebRect& rect) { 366 const WebRect& rect) {
274 DCHECK(main_loop_ && MessageLoop::current() == main_loop_); 367 DCHECK(MessageLoop::current() == main_loop_);
368 DCHECK(proxy_);
275 369
276 if (video_renderer_) { 370 proxy_->Paint(canvas, rect);
277 video_renderer_->Paint(canvas, rect); 371 }
372
373 void WebMediaPlayerImpl::WillDestroyCurrentMessageLoop() {
374 Destroy();
375 main_loop_ = NULL;
376 }
377
378 void WebMediaPlayerImpl::Repaint() {
379 DCHECK(MessageLoop::current() == main_loop_);
380 GetClient()->repaint();
381 }
382
383 void WebMediaPlayerImpl::TimeChanged() {
384 DCHECK(MessageLoop::current() == main_loop_);
385 GetClient()->timeChanged();
386 }
387
388 void WebMediaPlayerImpl::SetNetworkState(
389 WebKit::WebMediaPlayer::NetworkState state) {
390 DCHECK(MessageLoop::current() == main_loop_);
391 if (network_state_ != state) {
392 network_state_ = state;
393 GetClient()->networkStateChanged();
278 } 394 }
279 } 395 }
280 396
281 void WebMediaPlayerImpl::WillDestroyCurrentMessageLoop() { 397 void WebMediaPlayerImpl::SetReadyState(
282 pipeline_.Stop(); 398 WebKit::WebMediaPlayer::ReadyState state) {
283 } 399 DCHECK(MessageLoop::current() == main_loop_);
284 400 if (ready_state_ != state) {
285 void WebMediaPlayerImpl::OnPipelineInitialize(bool successful) { 401 ready_state_ = state;
286 WebKit::WebMediaPlayer::ReadyState old_ready_state = ready_state_; 402 GetClient()->readyStateChanged();
287 WebKit::WebMediaPlayer::NetworkState old_network_state = network_state_;
288 if (successful) {
289 // Since we have initialized the pipeline, say we have everything.
290 // TODO(hclam): change this to report the correct status.
291 ready_state_ = WebKit::WebMediaPlayer::HaveEnoughData;
292 network_state_ = WebKit::WebMediaPlayer::Loaded;
293 } else {
294 // TODO(hclam): should use pipeline_.GetError() to determine the state
295 // properly and reports error using MediaError.
296 // WebKit uses FormatError to indicate an error for bogus URL or bad file.
297 // Since we are at the initialization stage we can safely treat every error
298 // as format error.
299 network_state_ = WebKit::WebMediaPlayer::FormatError;
300 }
301
302 if (network_state_ != old_network_state) {
303 PostTask(kNetworkStateTaskIndex,
304 &WebKit::WebMediaPlayerClient::networkStateChanged);
305 }
306 if (ready_state_ != old_ready_state) {
307 PostTask(kReadyStateTaskIndex,
308 &WebKit::WebMediaPlayerClient::readyStateChanged);
309 } 403 }
310 } 404 }
311 405
312 void WebMediaPlayerImpl::OnPipelineSeek(bool successful) { 406 void WebMediaPlayerImpl::Destroy() {
313 PostTask(kTimeChangedTaskIndex, 407 DCHECK(MessageLoop::current() == main_loop_);
314 &WebKit::WebMediaPlayerClient::timeChanged);
315 }
316 408
317 void WebMediaPlayerImpl::SetVideoRenderer(VideoRendererImpl* video_renderer) { 409 // Make sure to kill the pipeline so there's no more media threads running.
318 video_renderer_ = video_renderer; 410 // TODO(hclam): stopping the pipeline is synchronous so it might block
319 } 411 // stopping for a long time.
412 pipeline_.Stop();
320 413
321 void WebMediaPlayerImpl::DidTask(CancelableTask* task) { 414 // And then detach the proxy, it may live on the render thread for a little
322 AutoLock auto_lock(task_lock_); 415 // longer until all the tasks are finished.
323 416 if (proxy_) {
324 for (size_t i = 0; i < tasks_.size(); ++i) { 417 proxy_->Detach();
325 if (tasks_[i] == task) { 418 proxy_ = NULL;
326 tasks_[i] = NULL;
327 return;
328 }
329 }
330 NOTREACHED();
331 }
332
333 void WebMediaPlayerImpl::CancelAllTasks() {
334 AutoLock auto_lock(task_lock_);
335 // Loop through the list of tasks and cancel tasks that are still alive.
336 for (size_t i = 0; i < tasks_.size(); ++i) {
337 if (tasks_[i])
338 tasks_[i]->Cancel();
339 } 419 }
340 } 420 }
341 421
342 void WebMediaPlayerImpl::PostTask(int index, 422 WebKit::WebMediaPlayerClient* WebMediaPlayerImpl::GetClient() {
343 WebMediaPlayerClientMethod method) { 423 DCHECK(MessageLoop::current() == main_loop_);
344 DCHECK(main_loop_); 424 DCHECK(client_);
345 425 return client_;
346 AutoLock auto_lock(task_lock_);
347 if (!tasks_[index]) {
348 CancelableTask* task = new NotifyWebMediaPlayerClientTask(this, method);
349 tasks_[index] = task;
350 main_loop_->PostTask(FROM_HERE, task);
351 }
352 }
353
354 void WebMediaPlayerImpl::PostRepaintTask() {
355 PostTask(kRepaintTaskIndex, &WebKit::WebMediaPlayerClient::repaint);
356 } 426 }
357 427
358 } // namespace webkit_glue 428 } // namespace webkit_glue
OLDNEW
« no previous file with comments | « webkit/glue/webmediaplayer_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698