OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "webkit/glue/webmediaplayer_proxy.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/logging.h" | |
9 #include "base/message_loop.h" | |
10 #include "media/base/pipeline_status.h" | |
11 #include "media/filters/chunk_demuxer.h" | |
12 #include "webkit/glue/media/web_video_renderer.h" | |
13 #include "webkit/glue/webmediaplayer_impl.h" | |
14 | |
15 using media::PipelineStatus; | |
16 | |
17 namespace webkit_glue { | |
18 | |
19 // Limits the maximum outstanding repaints posted on render thread. | |
20 // This number of 50 is a guess, it does not take too much memory on the task | |
21 // queue but gives up a pretty good latency on repaint. | |
22 static const int kMaxOutstandingRepaints = 50; | |
23 | |
24 WebMediaPlayerProxy::WebMediaPlayerProxy(MessageLoop* render_loop, | |
25 WebMediaPlayerImpl* webmediaplayer) | |
26 : render_loop_(render_loop), | |
27 webmediaplayer_(webmediaplayer), | |
28 outstanding_repaints_(0) { | |
29 DCHECK(render_loop_); | |
30 DCHECK(webmediaplayer_); | |
31 } | |
32 | |
33 WebMediaPlayerProxy::~WebMediaPlayerProxy() { | |
34 Detach(); | |
35 } | |
36 | |
37 void WebMediaPlayerProxy::Repaint() { | |
38 base::AutoLock auto_lock(lock_); | |
39 if (outstanding_repaints_ < kMaxOutstandingRepaints) { | |
40 ++outstanding_repaints_; | |
41 | |
42 render_loop_->PostTask(FROM_HERE, | |
43 NewRunnableMethod(this, &WebMediaPlayerProxy::RepaintTask)); | |
44 } | |
45 } | |
46 | |
47 void WebMediaPlayerProxy::SetVideoRenderer( | |
48 scoped_refptr<WebVideoRenderer> video_renderer) { | |
49 video_renderer_ = video_renderer; | |
50 } | |
51 | |
52 WebDataSourceBuildObserverHack WebMediaPlayerProxy::GetBuildObserver() { | |
53 if (build_observer_.is_null()) | |
54 build_observer_ = base::Bind(&WebMediaPlayerProxy::AddDataSource, this); | |
55 return build_observer_; | |
56 } | |
57 | |
58 void WebMediaPlayerProxy::Paint(SkCanvas* canvas, const gfx::Rect& dest_rect) { | |
59 DCHECK(MessageLoop::current() == render_loop_); | |
60 if (video_renderer_) { | |
61 video_renderer_->Paint(canvas, dest_rect); | |
62 } | |
63 } | |
64 | |
65 void WebMediaPlayerProxy::SetSize(const gfx::Rect& rect) { | |
66 DCHECK(MessageLoop::current() == render_loop_); | |
67 if (video_renderer_) { | |
68 video_renderer_->SetRect(rect); | |
69 } | |
70 } | |
71 | |
72 bool WebMediaPlayerProxy::HasSingleOrigin() { | |
73 DCHECK(MessageLoop::current() == render_loop_); | |
74 | |
75 base::AutoLock auto_lock(data_sources_lock_); | |
76 | |
77 for (DataSourceList::iterator itr = data_sources_.begin(); | |
78 itr != data_sources_.end(); | |
79 itr++) { | |
80 if (!(*itr)->HasSingleOrigin()) | |
81 return false; | |
82 } | |
83 return true; | |
84 } | |
85 | |
86 void WebMediaPlayerProxy::AbortDataSources() { | |
87 DCHECK(MessageLoop::current() == render_loop_); | |
88 base::AutoLock auto_lock(data_sources_lock_); | |
89 | |
90 for (DataSourceList::iterator itr = data_sources_.begin(); | |
91 itr != data_sources_.end(); | |
92 itr++) { | |
93 (*itr)->Abort(); | |
94 } | |
95 } | |
96 | |
97 void WebMediaPlayerProxy::Detach() { | |
98 DCHECK(MessageLoop::current() == render_loop_); | |
99 webmediaplayer_ = NULL; | |
100 video_renderer_ = NULL; | |
101 | |
102 { | |
103 base::AutoLock auto_lock(data_sources_lock_); | |
104 data_sources_.clear(); | |
105 } | |
106 } | |
107 | |
108 void WebMediaPlayerProxy::PipelineInitializationCallback( | |
109 PipelineStatus status) { | |
110 render_loop_->PostTask(FROM_HERE, NewRunnableMethod( | |
111 this, &WebMediaPlayerProxy::PipelineInitializationTask, status)); | |
112 } | |
113 | |
114 void WebMediaPlayerProxy::PipelineSeekCallback(PipelineStatus status) { | |
115 render_loop_->PostTask(FROM_HERE, NewRunnableMethod( | |
116 this, &WebMediaPlayerProxy::PipelineSeekTask, status)); | |
117 } | |
118 | |
119 void WebMediaPlayerProxy::PipelineEndedCallback(PipelineStatus status) { | |
120 render_loop_->PostTask(FROM_HERE, NewRunnableMethod( | |
121 this, &WebMediaPlayerProxy::PipelineEndedTask, status)); | |
122 } | |
123 | |
124 void WebMediaPlayerProxy::PipelineErrorCallback(PipelineStatus error) { | |
125 DCHECK_NE(error, media::PIPELINE_OK); | |
126 render_loop_->PostTask(FROM_HERE, NewRunnableMethod( | |
127 this, &WebMediaPlayerProxy::PipelineErrorTask, error)); | |
128 } | |
129 | |
130 void WebMediaPlayerProxy::NetworkEventCallback(bool is_downloading_data) { | |
131 render_loop_->PostTask(FROM_HERE, NewRunnableMethod( | |
132 this, &WebMediaPlayerProxy::NetworkEventTask, is_downloading_data)); | |
133 } | |
134 | |
135 void WebMediaPlayerProxy::AddDataSource(WebDataSource* data_source) { | |
136 base::AutoLock auto_lock(data_sources_lock_); | |
137 data_sources_.push_back(make_scoped_refptr(data_source)); | |
138 } | |
139 | |
140 void WebMediaPlayerProxy::RepaintTask() { | |
141 DCHECK(MessageLoop::current() == render_loop_); | |
142 { | |
143 base::AutoLock auto_lock(lock_); | |
144 --outstanding_repaints_; | |
145 DCHECK_GE(outstanding_repaints_, 0); | |
146 } | |
147 if (webmediaplayer_) { | |
148 webmediaplayer_->Repaint(); | |
149 } | |
150 } | |
151 | |
152 void WebMediaPlayerProxy::PipelineInitializationTask(PipelineStatus status) { | |
153 DCHECK(MessageLoop::current() == render_loop_); | |
154 if (webmediaplayer_) | |
155 webmediaplayer_->OnPipelineInitialize(status); | |
156 } | |
157 | |
158 void WebMediaPlayerProxy::PipelineSeekTask(PipelineStatus status) { | |
159 DCHECK(MessageLoop::current() == render_loop_); | |
160 if (webmediaplayer_) | |
161 webmediaplayer_->OnPipelineSeek(status); | |
162 } | |
163 | |
164 void WebMediaPlayerProxy::PipelineEndedTask(PipelineStatus status) { | |
165 DCHECK(MessageLoop::current() == render_loop_); | |
166 if (webmediaplayer_) | |
167 webmediaplayer_->OnPipelineEnded(status); | |
168 } | |
169 | |
170 void WebMediaPlayerProxy::PipelineErrorTask(PipelineStatus error) { | |
171 DCHECK(MessageLoop::current() == render_loop_); | |
172 if (webmediaplayer_) | |
173 webmediaplayer_->OnPipelineError(error); | |
174 } | |
175 | |
176 void WebMediaPlayerProxy::NetworkEventTask(bool is_downloading_data) { | |
177 DCHECK(MessageLoop::current() == render_loop_); | |
178 if (webmediaplayer_) | |
179 webmediaplayer_->OnNetworkEvent(is_downloading_data); | |
180 } | |
181 | |
182 void WebMediaPlayerProxy::GetCurrentFrame( | |
183 scoped_refptr<media::VideoFrame>* frame_out) { | |
184 if (video_renderer_) | |
185 video_renderer_->GetCurrentFrame(frame_out); | |
186 } | |
187 | |
188 void WebMediaPlayerProxy::PutCurrentFrame( | |
189 scoped_refptr<media::VideoFrame> frame) { | |
190 if (video_renderer_) | |
191 video_renderer_->PutCurrentFrame(frame); | |
192 } | |
193 | |
194 void WebMediaPlayerProxy::DemuxerOpened(media::ChunkDemuxer* demuxer) { | |
195 render_loop_->PostTask(FROM_HERE, NewRunnableMethod( | |
196 this, &WebMediaPlayerProxy::DemuxerOpenedTask, | |
197 scoped_refptr<media::ChunkDemuxer>(demuxer))); | |
198 } | |
199 | |
200 void WebMediaPlayerProxy::DemuxerClosed() { | |
201 render_loop_->PostTask(FROM_HERE, NewRunnableMethod( | |
202 this, &WebMediaPlayerProxy::DemuxerClosedTask)); | |
203 } | |
204 | |
205 void WebMediaPlayerProxy::DemuxerFlush() { | |
206 if (chunk_demuxer_.get()) | |
207 chunk_demuxer_->FlushData(); | |
208 } | |
209 | |
210 bool WebMediaPlayerProxy::DemuxerAppend(const uint8* data, size_t length) { | |
211 if (chunk_demuxer_.get()) | |
212 return chunk_demuxer_->AppendData(data, length); | |
213 return false; | |
214 } | |
215 | |
216 void WebMediaPlayerProxy::DemuxerEndOfStream(media::PipelineStatus status) { | |
217 if (chunk_demuxer_.get()) | |
218 chunk_demuxer_->EndOfStream(status); | |
219 } | |
220 | |
221 void WebMediaPlayerProxy::DemuxerShutdown() { | |
222 if (chunk_demuxer_.get()) | |
223 chunk_demuxer_->Shutdown(); | |
224 } | |
225 | |
226 void WebMediaPlayerProxy::DemuxerOpenedTask( | |
227 const scoped_refptr<media::ChunkDemuxer>& demuxer) { | |
228 DCHECK(MessageLoop::current() == render_loop_); | |
229 chunk_demuxer_ = demuxer; | |
230 if (webmediaplayer_) | |
231 webmediaplayer_->OnDemuxerOpened(); | |
232 } | |
233 | |
234 void WebMediaPlayerProxy::DemuxerClosedTask() { | |
235 chunk_demuxer_ = NULL; | |
236 } | |
237 | |
238 } // namespace webkit_glue | |
OLD | NEW |