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 // Delegate calls from WebCore::MediaPlayerPrivate to Chrome's video player. | |
6 // It contains PipelineImpl which is the actual media player pipeline, it glues | |
7 // the media player pipeline, data source, audio renderer and renderer. | |
8 // PipelineImpl would creates multiple threads and access some public methods | |
9 // of this class, so we need to be extra careful about concurrent access of | |
10 // methods and members. | |
11 // | |
12 // WebMediaPlayerImpl works with multiple objects, the most important ones are: | |
13 // | |
14 // media::PipelineImpl | |
15 // The media playback pipeline. | |
16 // | |
17 // WebVideoRenderer | |
18 // Video renderer object. | |
19 // | |
20 // WebKit::WebMediaPlayerClient | |
21 // WebKit client of this media player object. | |
22 // | |
23 // The following diagram shows the relationship of these objects: | |
24 // (note: ref-counted reference is marked by a "r".) | |
25 // | |
26 // WebMediaPlayerClient (WebKit object) | |
27 // ^ | |
28 // | | |
29 // WebMediaPlayerImpl ---> PipelineImpl | |
30 // | ^ | | |
31 // | | v r | |
32 // | | WebVideoRenderer | |
33 // | | | ^ r | |
34 // | r | v r | | |
35 // '---> WebMediaPlayerProxy --' | |
36 // | |
37 // Notice that WebMediaPlayerProxy and WebVideoRenderer are referencing each | |
38 // other. This interdependency has to be treated carefully. | |
39 // | |
40 // Other issues: | |
41 // During tear down of the whole browser or a tab, the DOM tree may not be | |
42 // destructed nicely, and there will be some dangling media threads trying to | |
43 // the main thread, so we need this class to listen to destruction event of the | |
44 // main thread and cleanup the media threads when the even is received. Also | |
45 // at destruction of this class we will need to unhook it from destruction event | |
46 // list of the main thread. | |
47 | |
48 #ifndef WEBKIT_GLUE_WEBMEDIAPLAYER_IMPL_H_ | |
49 #define WEBKIT_GLUE_WEBMEDIAPLAYER_IMPL_H_ | |
50 | |
51 #include "base/memory/ref_counted.h" | |
52 #include "base/memory/scoped_ptr.h" | |
53 #include "base/memory/weak_ptr.h" | |
54 #include "base/message_loop.h" | |
55 #include "media/base/filters.h" | |
56 #include "media/base/message_loop_factory.h" | |
57 #include "media/base/pipeline.h" | |
58 #include "skia/ext/platform_canvas.h" | |
59 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayer.h" | |
60 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerClient.
h" | |
61 | |
62 class GURL; | |
63 | |
64 namespace WebKit { | |
65 class WebFrame; | |
66 } | |
67 | |
68 namespace media { | |
69 class MediaLog; | |
70 } | |
71 | |
72 namespace webkit_glue { | |
73 | |
74 class MediaResourceLoaderBridgeFactory; | |
75 class MediaStreamClient; | |
76 class WebMediaPlayerDelegate; | |
77 class WebMediaPlayerProxy; | |
78 class WebVideoRenderer; | |
79 | |
80 class WebMediaPlayerImpl | |
81 : public WebKit::WebMediaPlayer, | |
82 public MessageLoop::DestructionObserver, | |
83 public base::SupportsWeakPtr<WebMediaPlayerImpl> { | |
84 public: | |
85 // Construct a WebMediaPlayerImpl with reference to the client, and media | |
86 // filter collection. By providing the filter collection the implementor can | |
87 // provide more specific media filters that does resource loading and | |
88 // rendering. |collection| should contain filter factories for: | |
89 // 1. Data source | |
90 // 2. Audio renderer | |
91 // 3. Video renderer (optional) | |
92 // | |
93 // There are some default filters provided by this method: | |
94 // 1. FFmpeg demuxer | |
95 // 2. FFmpeg audio decoder | |
96 // 3. FFmpeg video decoder | |
97 // 4. Video renderer | |
98 // 5. Null audio renderer | |
99 // The video renderer provided by this class is using the graphics context | |
100 // provided by WebKit to perform renderering. The simple data source does | |
101 // resource loading by loading the whole resource object into memory. Null | |
102 // audio renderer is a fake audio device that plays silence. Provider of the | |
103 // |collection| can override the default filters by adding extra filters to | |
104 // |collection| before calling this method. | |
105 // | |
106 // Callers must call |Initialize()| before they can use the object. | |
107 WebMediaPlayerImpl(WebKit::WebMediaPlayerClient* client, | |
108 base::WeakPtr<WebMediaPlayerDelegate> delegate, | |
109 media::FilterCollection* collection, | |
110 media::MessageLoopFactory* message_loop_factory, | |
111 MediaStreamClient* media_stream_client, | |
112 media::MediaLog* media_log); | |
113 virtual ~WebMediaPlayerImpl(); | |
114 | |
115 // Finalizes initialization of the object. | |
116 bool Initialize( | |
117 WebKit::WebFrame* frame, | |
118 bool use_simple_data_source, | |
119 scoped_refptr<WebVideoRenderer> web_video_renderer); | |
120 | |
121 virtual void load(const WebKit::WebURL& url); | |
122 virtual void cancelLoad(); | |
123 | |
124 // Playback controls. | |
125 virtual void play(); | |
126 virtual void pause(); | |
127 virtual bool supportsFullscreen() const; | |
128 virtual bool supportsSave() const; | |
129 virtual void seek(float seconds); | |
130 virtual void setEndTime(float seconds); | |
131 virtual void setRate(float rate); | |
132 virtual void setVolume(float volume); | |
133 virtual void setVisible(bool visible); | |
134 virtual void setPreload(WebKit::WebMediaPlayer::Preload preload); | |
135 virtual bool totalBytesKnown(); | |
136 virtual const WebKit::WebTimeRanges& buffered(); | |
137 virtual float maxTimeSeekable() const; | |
138 | |
139 // Methods for painting. | |
140 virtual void setSize(const WebKit::WebSize& size); | |
141 | |
142 virtual void paint(WebKit::WebCanvas* canvas, const WebKit::WebRect& rect); | |
143 | |
144 // True if the loaded media has a playable video/audio track. | |
145 virtual bool hasVideo() const; | |
146 virtual bool hasAudio() const; | |
147 | |
148 // Dimensions of the video. | |
149 virtual WebKit::WebSize naturalSize() const; | |
150 | |
151 // Getters of playback state. | |
152 virtual bool paused() const; | |
153 virtual bool seeking() const; | |
154 virtual float duration() const; | |
155 virtual float currentTime() const; | |
156 | |
157 // Get rate of loading the resource. | |
158 virtual int32 dataRate() const; | |
159 | |
160 // Internal states of loading and network. | |
161 // TODO(hclam): Ask the pipeline about the state rather than having reading | |
162 // them from members which would cause race conditions. | |
163 virtual WebKit::WebMediaPlayer::NetworkState networkState() const; | |
164 virtual WebKit::WebMediaPlayer::ReadyState readyState() const; | |
165 | |
166 virtual unsigned long long bytesLoaded() const; | |
167 virtual unsigned long long totalBytes() const; | |
168 | |
169 virtual bool hasSingleSecurityOrigin() const; | |
170 virtual WebKit::WebMediaPlayer::MovieLoadType movieLoadType() const; | |
171 | |
172 virtual float mediaTimeForTimeValue(float timeValue) const; | |
173 | |
174 virtual unsigned decodedFrameCount() const; | |
175 virtual unsigned droppedFrameCount() const; | |
176 virtual unsigned audioDecodedByteCount() const; | |
177 virtual unsigned videoDecodedByteCount() const; | |
178 | |
179 virtual WebKit::WebVideoFrame* getCurrentFrame(); | |
180 virtual void putCurrentFrame(WebKit::WebVideoFrame* web_video_frame); | |
181 | |
182 virtual bool sourceAppend(const unsigned char* data, unsigned length); | |
183 virtual void sourceEndOfStream(EndOfStreamStatus status); | |
184 | |
185 // As we are closing the tab or even the browser, |main_loop_| is destroyed | |
186 // even before this object gets destructed, so we need to know when | |
187 // |main_loop_| is being destroyed and we can stop posting repaint task | |
188 // to it. | |
189 virtual void WillDestroyCurrentMessageLoop(); | |
190 | |
191 void Repaint(); | |
192 | |
193 void OnPipelineInitialize(media::PipelineStatus status); | |
194 void OnPipelineSeek(media::PipelineStatus status); | |
195 void OnPipelineEnded(media::PipelineStatus status); | |
196 void OnPipelineError(media::PipelineStatus error); | |
197 void OnNetworkEvent(bool is_downloading_data); | |
198 void OnDemuxerOpened(); | |
199 | |
200 private: | |
201 // Helpers that set the network/ready state and notifies the client if | |
202 // they've changed. | |
203 void SetNetworkState(WebKit::WebMediaPlayer::NetworkState state); | |
204 void SetReadyState(WebKit::WebMediaPlayer::ReadyState state); | |
205 | |
206 // Destroy resources held. | |
207 void Destroy(); | |
208 | |
209 // Getter method to |client_|. | |
210 WebKit::WebMediaPlayerClient* GetClient(); | |
211 | |
212 // Lets V8 know that player uses extra resources not managed by V8. | |
213 void IncrementExternallyAllocatedMemory(); | |
214 | |
215 // TODO(hclam): get rid of these members and read from the pipeline directly. | |
216 WebKit::WebMediaPlayer::NetworkState network_state_; | |
217 WebKit::WebMediaPlayer::ReadyState ready_state_; | |
218 | |
219 // Keep a list of buffered time ranges. | |
220 WebKit::WebTimeRanges buffered_; | |
221 | |
222 // Message loops for posting tasks between Chrome's main thread. Also used | |
223 // for DCHECKs so methods calls won't execute in the wrong thread. | |
224 MessageLoop* main_loop_; | |
225 | |
226 // A collection of filters. | |
227 scoped_ptr<media::FilterCollection> filter_collection_; | |
228 | |
229 // The actual pipeline and the thread it runs on. | |
230 scoped_refptr<media::Pipeline> pipeline_; | |
231 | |
232 scoped_ptr<media::MessageLoopFactory> message_loop_factory_; | |
233 | |
234 // Playback state. | |
235 // | |
236 // TODO(scherkus): we have these because Pipeline favours the simplicity of a | |
237 // single "playback rate" over worrying about paused/stopped etc... It forces | |
238 // all clients to manage the pause+playback rate externally, but is that | |
239 // really a bad thing? | |
240 // | |
241 // TODO(scherkus): since SetPlaybackRate(0) is asynchronous and we don't want | |
242 // to hang the render thread during pause(), we record the time at the same | |
243 // time we pause and then return that value in currentTime(). Otherwise our | |
244 // clock can creep forward a little bit while the asynchronous | |
245 // SetPlaybackRate(0) is being executed. | |
246 bool paused_; | |
247 bool seeking_; | |
248 float playback_rate_; | |
249 base::TimeDelta paused_time_; | |
250 | |
251 // Seek gets pending if another seek is in progress. Only last pending seek | |
252 // will have effect. | |
253 bool pending_seek_; | |
254 float pending_seek_seconds_; | |
255 | |
256 WebKit::WebMediaPlayerClient* client_; | |
257 | |
258 scoped_refptr<WebMediaPlayerProxy> proxy_; | |
259 | |
260 base::WeakPtr<WebMediaPlayerDelegate> delegate_; | |
261 | |
262 MediaStreamClient* media_stream_client_; | |
263 | |
264 #if WEBKIT_USING_CG | |
265 scoped_ptr<skia::PlatformCanvas> skia_canvas_; | |
266 #endif | |
267 | |
268 scoped_refptr<media::MediaLog> media_log_; | |
269 | |
270 bool incremented_externally_allocated_memory_; | |
271 | |
272 DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerImpl); | |
273 }; | |
274 | |
275 } // namespace webkit_glue | |
276 | |
277 #endif // WEBKIT_GLUE_WEBMEDIAPLAYER_IMPL_H_ | |
OLD | NEW |