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

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

Issue 7493030: Split WebMediaPlayerImpl::Proxy into its own class. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src
Patch Set: rebase Created 9 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
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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" 5 #include "webkit/glue/webmediaplayer_impl.h"
6 6
7 #include <limits> 7 #include <limits>
8 #include <string> 8 #include <string>
9 9
10 #include "base/callback.h" 10 #include "base/callback.h"
(...skipping 12 matching lines...) Expand all
23 #include "media/filters/null_audio_renderer.h" 23 #include "media/filters/null_audio_renderer.h"
24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h" 24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h"
25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h" 25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h"
26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h" 26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h"
27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebVideoFrame.h" 27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebVideoFrame.h"
28 #include "webkit/glue/media/buffered_data_source.h" 28 #include "webkit/glue/media/buffered_data_source.h"
29 #include "webkit/glue/media/simple_data_source.h" 29 #include "webkit/glue/media/simple_data_source.h"
30 #include "webkit/glue/media/media_stream_client.h" 30 #include "webkit/glue/media/media_stream_client.h"
31 #include "webkit/glue/media/video_renderer_impl.h" 31 #include "webkit/glue/media/video_renderer_impl.h"
32 #include "webkit/glue/media/web_video_renderer.h" 32 #include "webkit/glue/media/web_video_renderer.h"
33 #include "webkit/glue/webmediaplayer_proxy.h"
33 #include "webkit/glue/webvideoframe_impl.h" 34 #include "webkit/glue/webvideoframe_impl.h"
34 35
35 using WebKit::WebCanvas; 36 using WebKit::WebCanvas;
36 using WebKit::WebRect; 37 using WebKit::WebRect;
37 using WebKit::WebSize; 38 using WebKit::WebSize;
38 using media::PipelineStatus; 39 using media::PipelineStatus;
39 40
40 namespace { 41 namespace {
41 42
42 // Limits the maximum outstanding repaints posted on render thread.
43 // This number of 50 is a guess, it does not take too much memory on the task
44 // queue but gives up a pretty good latency on repaint.
45 const int kMaxOutstandingRepaints = 50;
46
47 // Limits the range of playback rate. 43 // Limits the range of playback rate.
48 // 44 //
49 // TODO(kylep): Revisit these. 45 // TODO(kylep): Revisit these.
50 // 46 //
51 // Vista has substantially lower performance than XP or Windows7. If you speed 47 // Vista has substantially lower performance than XP or Windows7. If you speed
52 // up a video too much, it can't keep up, and rendering stops updating except on 48 // up a video too much, it can't keep up, and rendering stops updating except on
53 // the time bar. For really high speeds, audio becomes a bottleneck and we just 49 // the time bar. For really high speeds, audio becomes a bottleneck and we just
54 // use up the data we have, which may not achieve the speed requested, but will 50 // use up the data we have, which may not achieve the speed requested, but will
55 // not crash the tab. 51 // not crash the tab.
56 // 52 //
(...skipping 22 matching lines...) Expand all
79 } 75 }
80 76
81 // Now we can safely cast to int64 microseconds. 77 // Now we can safely cast to int64 microseconds.
82 return base::TimeDelta::FromMicroseconds(static_cast<int64>(integer)); 78 return base::TimeDelta::FromMicroseconds(static_cast<int64>(integer));
83 } 79 }
84 80
85 } // namespace 81 } // namespace
86 82
87 namespace webkit_glue { 83 namespace webkit_glue {
88 84
89 /////////////////////////////////////////////////////////////////////////////
90 // WebMediaPlayerImpl::Proxy implementation
91
92 WebMediaPlayerImpl::Proxy::Proxy(MessageLoop* render_loop,
93 WebMediaPlayerImpl* webmediaplayer)
94 : render_loop_(render_loop),
95 webmediaplayer_(webmediaplayer),
96 outstanding_repaints_(0) {
97 DCHECK(render_loop_);
98 DCHECK(webmediaplayer_);
99 }
100
101 WebMediaPlayerImpl::Proxy::~Proxy() {
102 Detach();
103 }
104
105 void WebMediaPlayerImpl::Proxy::Repaint() {
106 base::AutoLock auto_lock(lock_);
107 if (outstanding_repaints_ < kMaxOutstandingRepaints) {
108 ++outstanding_repaints_;
109
110 render_loop_->PostTask(FROM_HERE,
111 NewRunnableMethod(this, &WebMediaPlayerImpl::Proxy::RepaintTask));
112 }
113 }
114
115 void WebMediaPlayerImpl::Proxy::SetVideoRenderer(
116 scoped_refptr<WebVideoRenderer> video_renderer) {
117 video_renderer_ = video_renderer;
118 }
119
120 WebDataSourceBuildObserverHack* WebMediaPlayerImpl::Proxy::GetBuildObserver() {
121 if (!build_observer_.get())
122 build_observer_.reset(NewCallback(this, &Proxy::AddDataSource));
123 return build_observer_.get();
124 }
125
126 void WebMediaPlayerImpl::Proxy::Paint(SkCanvas* canvas,
127 const gfx::Rect& dest_rect) {
128 DCHECK(MessageLoop::current() == render_loop_);
129 if (video_renderer_) {
130 video_renderer_->Paint(canvas, dest_rect);
131 }
132 }
133
134 void WebMediaPlayerImpl::Proxy::SetSize(const gfx::Rect& rect) {
135 DCHECK(MessageLoop::current() == render_loop_);
136 if (video_renderer_) {
137 video_renderer_->SetRect(rect);
138 }
139 }
140
141 bool WebMediaPlayerImpl::Proxy::HasSingleOrigin() {
142 DCHECK(MessageLoop::current() == render_loop_);
143
144 base::AutoLock auto_lock(data_sources_lock_);
145
146 for (DataSourceList::iterator itr = data_sources_.begin();
147 itr != data_sources_.end();
148 itr++) {
149 if (!(*itr)->HasSingleOrigin())
150 return false;
151 }
152 return true;
153 }
154
155 void WebMediaPlayerImpl::Proxy::AbortDataSources() {
156 DCHECK(MessageLoop::current() == render_loop_);
157 base::AutoLock auto_lock(data_sources_lock_);
158
159 for (DataSourceList::iterator itr = data_sources_.begin();
160 itr != data_sources_.end();
161 itr++) {
162 (*itr)->Abort();
163 }
164 }
165
166 void WebMediaPlayerImpl::Proxy::Detach() {
167 DCHECK(MessageLoop::current() == render_loop_);
168 webmediaplayer_ = NULL;
169 video_renderer_ = NULL;
170
171 {
172 base::AutoLock auto_lock(data_sources_lock_);
173 data_sources_.clear();
174 }
175 }
176
177 void WebMediaPlayerImpl::Proxy::PipelineInitializationCallback(
178 PipelineStatus status) {
179 render_loop_->PostTask(FROM_HERE, NewRunnableMethod(
180 this, &WebMediaPlayerImpl::Proxy::PipelineInitializationTask, status));
181 }
182
183 void WebMediaPlayerImpl::Proxy::PipelineSeekCallback(PipelineStatus status) {
184 render_loop_->PostTask(FROM_HERE, NewRunnableMethod(
185 this, &WebMediaPlayerImpl::Proxy::PipelineSeekTask, status));
186 }
187
188 void WebMediaPlayerImpl::Proxy::PipelineEndedCallback(PipelineStatus status) {
189 render_loop_->PostTask(FROM_HERE, NewRunnableMethod(
190 this, &WebMediaPlayerImpl::Proxy::PipelineEndedTask, status));
191 }
192
193 void WebMediaPlayerImpl::Proxy::PipelineErrorCallback(PipelineStatus error) {
194 DCHECK_NE(error, media::PIPELINE_OK);
195 render_loop_->PostTask(FROM_HERE, NewRunnableMethod(
196 this, &WebMediaPlayerImpl::Proxy::PipelineErrorTask, error));
197 }
198
199 void WebMediaPlayerImpl::Proxy::NetworkEventCallback(PipelineStatus status) {
200 render_loop_->PostTask(FROM_HERE, NewRunnableMethod(
201 this, &WebMediaPlayerImpl::Proxy::NetworkEventTask, status));
202 }
203
204 void WebMediaPlayerImpl::Proxy::AddDataSource(WebDataSource* data_source) {
205 base::AutoLock auto_lock(data_sources_lock_);
206 data_sources_.push_back(make_scoped_refptr(data_source));
207 }
208
209 void WebMediaPlayerImpl::Proxy::RepaintTask() {
210 DCHECK(MessageLoop::current() == render_loop_);
211 {
212 base::AutoLock auto_lock(lock_);
213 --outstanding_repaints_;
214 DCHECK_GE(outstanding_repaints_, 0);
215 }
216 if (webmediaplayer_) {
217 webmediaplayer_->Repaint();
218 }
219 }
220
221 void WebMediaPlayerImpl::Proxy::PipelineInitializationTask(
222 PipelineStatus status) {
223 DCHECK(MessageLoop::current() == render_loop_);
224 if (webmediaplayer_) {
225 webmediaplayer_->OnPipelineInitialize(status);
226 }
227 }
228
229 void WebMediaPlayerImpl::Proxy::PipelineSeekTask(PipelineStatus status) {
230 DCHECK(MessageLoop::current() == render_loop_);
231 if (webmediaplayer_) {
232 webmediaplayer_->OnPipelineSeek(status);
233 }
234 }
235
236 void WebMediaPlayerImpl::Proxy::PipelineEndedTask(PipelineStatus status) {
237 DCHECK(MessageLoop::current() == render_loop_);
238 if (webmediaplayer_) {
239 webmediaplayer_->OnPipelineEnded(status);
240 }
241 }
242
243 void WebMediaPlayerImpl::Proxy::PipelineErrorTask(PipelineStatus error) {
244 DCHECK(MessageLoop::current() == render_loop_);
245 if (webmediaplayer_) {
246 webmediaplayer_->OnPipelineError(error);
247 }
248 }
249
250 void WebMediaPlayerImpl::Proxy::NetworkEventTask(PipelineStatus status) {
251 DCHECK(MessageLoop::current() == render_loop_);
252 if (webmediaplayer_) {
253 webmediaplayer_->OnNetworkEvent(status);
254 }
255 }
256
257 void WebMediaPlayerImpl::Proxy::GetCurrentFrame(
258 scoped_refptr<media::VideoFrame>* frame_out) {
259 if (video_renderer_)
260 video_renderer_->GetCurrentFrame(frame_out);
261 }
262
263 void WebMediaPlayerImpl::Proxy::PutCurrentFrame(
264 scoped_refptr<media::VideoFrame> frame) {
265 if (video_renderer_)
266 video_renderer_->PutCurrentFrame(frame);
267 }
268
269 void WebMediaPlayerImpl::Proxy::DemuxerOpened(media::ChunkDemuxer* demuxer) {
270 render_loop_->PostTask(FROM_HERE, NewRunnableMethod(
271 this, &WebMediaPlayerImpl::Proxy::DemuxerOpenedTask,
272 scoped_refptr<media::ChunkDemuxer>(demuxer)));
273 }
274
275 void WebMediaPlayerImpl::Proxy::DemuxerClosed() {
276 render_loop_->PostTask(FROM_HERE, NewRunnableMethod(
277 this, &WebMediaPlayerImpl::Proxy::DemuxerClosedTask));
278 }
279
280 void WebMediaPlayerImpl::Proxy::DemuxerFlush() {
281 if (chunk_demuxer_.get())
282 chunk_demuxer_->FlushData();
283 }
284
285 bool WebMediaPlayerImpl::Proxy::DemuxerAppend(const uint8* data,
286 size_t length) {
287 if (chunk_demuxer_.get())
288 return chunk_demuxer_->AppendData(data, length);
289 return false;
290 }
291
292 void WebMediaPlayerImpl::Proxy::DemuxerEndOfStream(
293 media::PipelineStatus status) {
294 if (chunk_demuxer_.get())
295 chunk_demuxer_->EndOfStream(status);
296 }
297
298 void WebMediaPlayerImpl::Proxy::DemuxerShutdown() {
299 if (chunk_demuxer_.get())
300 chunk_demuxer_->Shutdown();
301 }
302
303 void WebMediaPlayerImpl::Proxy::DemuxerOpenedTask(
304 const scoped_refptr<media::ChunkDemuxer>& demuxer) {
305 DCHECK(MessageLoop::current() == render_loop_);
306 chunk_demuxer_ = demuxer;
307 if (webmediaplayer_)
308 webmediaplayer_->OnDemuxerOpened();
309 }
310
311 void WebMediaPlayerImpl::Proxy::DemuxerClosedTask() {
312 chunk_demuxer_ = NULL;
313 }
314
315 /////////////////////////////////////////////////////////////////////////////
316 // WebMediaPlayerImpl implementation
317
318 WebMediaPlayerImpl::WebMediaPlayerImpl( 85 WebMediaPlayerImpl::WebMediaPlayerImpl(
319 WebKit::WebMediaPlayerClient* client, 86 WebKit::WebMediaPlayerClient* client,
320 media::FilterCollection* collection, 87 media::FilterCollection* collection,
321 media::MessageLoopFactory* message_loop_factory, 88 media::MessageLoopFactory* message_loop_factory,
322 MediaStreamClient* media_stream_client) 89 MediaStreamClient* media_stream_client)
323 : network_state_(WebKit::WebMediaPlayer::Empty), 90 : network_state_(WebKit::WebMediaPlayer::Empty),
324 ready_state_(WebKit::WebMediaPlayer::HaveNothing), 91 ready_state_(WebKit::WebMediaPlayer::HaveNothing),
325 main_loop_(NULL), 92 main_loop_(NULL),
326 filter_collection_(collection), 93 filter_collection_(collection),
327 pipeline_(NULL), 94 pipeline_(NULL),
(...skipping 19 matching lines...) Expand all
347 NOTREACHED() << "Could not start PipelineThread"; 114 NOTREACHED() << "Could not start PipelineThread";
348 return false; 115 return false;
349 } 116 }
350 117
351 pipeline_ = new media::PipelineImpl(pipeline_message_loop); 118 pipeline_ = new media::PipelineImpl(pipeline_message_loop);
352 119
353 // Also we want to be notified of |main_loop_| destruction. 120 // Also we want to be notified of |main_loop_| destruction.
354 main_loop_->AddDestructionObserver(this); 121 main_loop_->AddDestructionObserver(this);
355 122
356 // Creates the proxy. 123 // Creates the proxy.
357 proxy_ = new Proxy(main_loop_, this); 124 proxy_ = new WebMediaPlayerProxy(main_loop_, this);
358 web_video_renderer->SetWebMediaPlayerImplProxy(proxy_); 125 web_video_renderer->SetWebMediaPlayerProxy(proxy_);
359 proxy_->SetVideoRenderer(web_video_renderer); 126 proxy_->SetVideoRenderer(web_video_renderer);
360 127
361 // Set our pipeline callbacks. 128 // Set our pipeline callbacks.
362 pipeline_->Init( 129 pipeline_->Init(
363 NewCallback(proxy_.get(), 130 NewCallback(proxy_.get(),
364 &WebMediaPlayerImpl::Proxy::PipelineEndedCallback), 131 &WebMediaPlayerProxy::PipelineEndedCallback),
365 NewCallback(proxy_.get(), 132 NewCallback(proxy_.get(),
366 &WebMediaPlayerImpl::Proxy::PipelineErrorCallback), 133 &WebMediaPlayerProxy::PipelineErrorCallback),
367 NewCallback(proxy_.get(), 134 NewCallback(proxy_.get(),
368 &WebMediaPlayerImpl::Proxy::NetworkEventCallback)); 135 &WebMediaPlayerProxy::NetworkEventCallback));
369 136
370 // A simple data source that keeps all data in memory. 137 // A simple data source that keeps all data in memory.
371 scoped_ptr<media::DataSourceFactory> simple_data_source_factory( 138 scoped_ptr<media::DataSourceFactory> simple_data_source_factory(
372 SimpleDataSource::CreateFactory(MessageLoop::current(), frame, 139 SimpleDataSource::CreateFactory(MessageLoop::current(), frame,
373 proxy_->GetBuildObserver())); 140 proxy_->GetBuildObserver()));
374 141
375 // A sophisticated data source that does memory caching. 142 // A sophisticated data source that does memory caching.
376 scoped_ptr<media::DataSourceFactory> buffered_data_source_factory( 143 scoped_ptr<media::DataSourceFactory> buffered_data_source_factory(
377 BufferedDataSource::CreateFactory(MessageLoop::current(), frame, 144 BufferedDataSource::CreateFactory(MessageLoop::current(), frame,
378 proxy_->GetBuildObserver())); 145 proxy_->GetBuildObserver()));
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 // Get the preload value. 217 // Get the preload value.
451 setPreload(GetClient()->preload()); 218 setPreload(GetClient()->preload());
452 219
453 // Initialize the pipeline. 220 // Initialize the pipeline.
454 SetNetworkState(WebKit::WebMediaPlayer::Loading); 221 SetNetworkState(WebKit::WebMediaPlayer::Loading);
455 SetReadyState(WebKit::WebMediaPlayer::HaveNothing); 222 SetReadyState(WebKit::WebMediaPlayer::HaveNothing);
456 pipeline_->Start( 223 pipeline_->Start(
457 filter_collection_.release(), 224 filter_collection_.release(),
458 url.spec(), 225 url.spec(),
459 NewCallback(proxy_.get(), 226 NewCallback(proxy_.get(),
460 &WebMediaPlayerImpl::Proxy::PipelineInitializationCallback)); 227 &WebMediaPlayerProxy::PipelineInitializationCallback));
461 } 228 }
462 229
463 void WebMediaPlayerImpl::cancelLoad() { 230 void WebMediaPlayerImpl::cancelLoad() {
464 DCHECK(MessageLoop::current() == main_loop_); 231 DCHECK(MessageLoop::current() == main_loop_);
465 } 232 }
466 233
467 void WebMediaPlayerImpl::play() { 234 void WebMediaPlayerImpl::play() {
468 DCHECK(MessageLoop::current() == main_loop_); 235 DCHECK(MessageLoop::current() == main_loop_);
469 236
470 paused_ = false; 237 paused_ = false;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 } 279 }
513 280
514 seeking_ = true; 281 seeking_ = true;
515 282
516 proxy_->DemuxerFlush(); 283 proxy_->DemuxerFlush();
517 284
518 // Kick off the asynchronous seek! 285 // Kick off the asynchronous seek!
519 pipeline_->Seek( 286 pipeline_->Seek(
520 seek_time, 287 seek_time,
521 NewCallback(proxy_.get(), 288 NewCallback(proxy_.get(),
522 &WebMediaPlayerImpl::Proxy::PipelineSeekCallback)); 289 &WebMediaPlayerProxy::PipelineSeekCallback));
523 } 290 }
524 291
525 void WebMediaPlayerImpl::setEndTime(float seconds) { 292 void WebMediaPlayerImpl::setEndTime(float seconds) {
526 DCHECK(MessageLoop::current() == main_loop_); 293 DCHECK(MessageLoop::current() == main_loop_);
527 294
528 // TODO(hclam): add method call when it has been implemented. 295 // TODO(hclam): add method call when it has been implemented.
529 return; 296 return;
530 } 297 }
531 298
532 void WebMediaPlayerImpl::setRate(float rate) { 299 void WebMediaPlayerImpl::setRate(float rate) {
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 } 794 }
1028 } 795 }
1029 796
1030 WebKit::WebMediaPlayerClient* WebMediaPlayerImpl::GetClient() { 797 WebKit::WebMediaPlayerClient* WebMediaPlayerImpl::GetClient() {
1031 DCHECK(MessageLoop::current() == main_loop_); 798 DCHECK(MessageLoop::current() == main_loop_);
1032 DCHECK(client_); 799 DCHECK(client_);
1033 return client_; 800 return client_;
1034 } 801 }
1035 802
1036 } // namespace webkit_glue 803 } // namespace webkit_glue
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698