blob: da1b142bfe0a3bcdd06537db687a380ffdb2c176 [file] [log] [blame]
[email protected]add51772009-06-11 18:25:171// 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 found
3// 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//
[email protected]8931c41a2009-07-07 17:31:4912// WebMediaPlayerImpl works with multiple objects, the most important ones are:
[email protected]add51772009-06-11 18:25:1713//
[email protected]8931c41a2009-07-07 17:31:4914// media::PipelineImpl
15// The media playback pipeline.
[email protected]add51772009-06-11 18:25:1716//
[email protected]8931c41a2009-07-07 17:31:4917// VideoRendererImpl
18// Video renderer object.
19//
20// WebMediaPlayerImpl::Proxy
21// Proxies methods calls from the media pipeline to WebKit.
22//
23// WebKit::WebMediaPlayerClient
24// WebKit client of this media player object.
25//
26// The following diagram shows the relationship of these objects:
27// (note: ref-counted reference is marked by a "r".)
28//
29// WebMediaPlayerImpl ------> PipelineImpl
30// | ^ | r
31// | | v
32// | | VideoRendererImpl
33// | | ^ r
34// | | |
35// | r | r |
36// .------> Proxy <-----.
37// |
38// |
39// v
40// WebMediaPlayerClient
41//
42// Notice that Proxy and VideoRendererImpl are referencing each other. This
43// interdependency has to be treated carefully.
[email protected]add51772009-06-11 18:25:1744//
45// Other issues:
46// During tear down of the whole browser or a tab, the DOM tree may not be
47// destructed nicely, and there will be some dangling media threads trying to
48// the main thread, so we need this class to listen to destruction event of the
49// main thread and cleanup the media threads when the even is received. Also
50// at destruction of this class we will need to unhook it from destruction event
51// list of the main thread.
52
53#ifndef WEBKIT_GLUE_WEBMEDIAPLAYER_IMPL_H_
[email protected]8931c41a2009-07-07 17:31:4954#define WEBKIT_GLUE_WEBMEDIAPLAYER_IMPL_H_
[email protected]add51772009-06-11 18:25:1755
56#include <vector>
57
[email protected]8931c41a2009-07-07 17:31:4958#include "base/gfx/rect.h"
59#include "base/gfx/size.h"
[email protected]add51772009-06-11 18:25:1760#include "base/lock.h"
61#include "base/message_loop.h"
[email protected]8931c41a2009-07-07 17:31:4962#include "base/ref_counted.h"
[email protected]add51772009-06-11 18:25:1763#include "media/base/filters.h"
64#include "media/base/pipeline_impl.h"
[email protected]66a473c2009-07-22 02:12:5065#include "skia/ext/platform_canvas.h"
[email protected]add51772009-06-11 18:25:1766#include "webkit/api/public/WebMediaPlayer.h"
67#include "webkit/api/public/WebMediaPlayerClient.h"
68
[email protected]add51772009-06-11 18:25:1769class GURL;
[email protected]add51772009-06-11 18:25:1770
71namespace media {
72class FilterFactoryCollection;
73}
74
75namespace webkit_glue {
76
[email protected]8931c41a2009-07-07 17:31:4977class VideoRendererImpl;
[email protected]add51772009-06-11 18:25:1778
79class WebMediaPlayerImpl : public WebKit::WebMediaPlayer,
80 public MessageLoop::DestructionObserver {
81 public:
[email protected]8931c41a2009-07-07 17:31:4982 // A proxy class that dispatches method calls from the media pipeline to
83 // WebKit. Since there are multiple threads in the media pipeline and there's
84 // need for the media pipeline to call to WebKit, e.g. repaint requests,
85 // initialization events, etc, we have this class to bridge all method calls
86 // from the media pipeline on different threads and serialize these calls
87 // on the render thread.
88 // Because of the nature of this object that it works with different threads,
89 // it is made ref-counted.
90 class Proxy : public base::RefCountedThreadSafe<Proxy> {
91 public:
92 Proxy(MessageLoop* render_loop,
93 WebMediaPlayerImpl* webmediaplayer);
94 virtual ~Proxy();
95
[email protected]96706912009-07-15 17:18:0596 // Public methods called from the video renderer.
[email protected]8931c41a2009-07-07 17:31:4997 void Repaint();
[email protected]8931c41a2009-07-07 17:31:4998 void SetVideoRenderer(VideoRendererImpl* video_renderer);
99
[email protected]96706912009-07-15 17:18:05100 // Public methods called from WebMediaPlayerImpl.
101 void Paint(skia::PlatformCanvas* canvas, const gfx::Rect& dest_rect);
102 void SetSize(const gfx::Rect& rect);
103 void Detach();
[email protected]8931c41a2009-07-07 17:31:49104
[email protected]96706912009-07-15 17:18:05105 // Public methods called from the pipeline via callback issued by
106 // WebMediaPlayerImpl.
107 void PipelineInitializationCallback();
108 void PipelineSeekCallback();
[email protected]576537842009-08-12 23:52:05109 void PipelineEndedCallback();
[email protected]db190487d2009-07-30 18:51:52110 void PipelineErrorCallback();
[email protected]96706912009-07-15 17:18:05111
112 private:
[email protected]8931c41a2009-07-07 17:31:49113 // Invoke |webmediaplayer_| to perform a repaint.
114 void RepaintTask();
115
[email protected]96706912009-07-15 17:18:05116 // Notify |webmediaplayer_| that initialization has finished.
117 void PipelineInitializationTask();
[email protected]8931c41a2009-07-07 17:31:49118
[email protected]96706912009-07-15 17:18:05119 // Notify |webmediaplayer_| that a seek has finished.
120 void PipelineSeekTask();
[email protected]8931c41a2009-07-07 17:31:49121
[email protected]576537842009-08-12 23:52:05122 // Notify |webmediaplayer_| that the media has ended.
123 void PipelineEndedTask();
124
[email protected]db190487d2009-07-30 18:51:52125 // Notify |webmediaplayer_| that a pipeline error has been set.
126 void PipelineErrorTask();
127
[email protected]8931c41a2009-07-07 17:31:49128 // The render message loop where WebKit lives.
129 MessageLoop* render_loop_;
130 WebMediaPlayerImpl* webmediaplayer_;
131 scoped_refptr<VideoRendererImpl> video_renderer_;
132
133 Lock lock_;
134 int outstanding_repaints_;
135 };
136
[email protected]add51772009-06-11 18:25:17137 // Construct a WebMediaPlayerImpl with reference to the client, and media
138 // filter factory collection. By providing the filter factory collection
139 // the implementor can provide more specific media filters that does resource
140 // loading and rendering. |factory| should contain filter factories for:
141 // 1. Data source
142 // 2. Audio renderer
143 // 3. Video renderer (optional)
144 //
145 // There are some default filters provided by this method:
146 // 1. FFmpeg demuxer
147 // 2. FFmpeg audio decoder
148 // 3. FFmpeg video decoder
149 // 4. Video renderer
[email protected]8380c092009-06-25 17:45:51150 // 5. Null audio renderer
[email protected]add51772009-06-11 18:25:17151 // The video renderer provided by this class is using the graphics context
152 // provided by WebKit to perform renderering. The simple data source does
153 // resource loading by loading the whole resource object into memory. Null
154 // audio renderer is a fake audio device that plays silence. Provider of the
155 // |factory| can override the default filters by adding extra filters to
156 // |factory| before calling this method.
157 WebMediaPlayerImpl(WebKit::WebMediaPlayerClient* client,
158 media::FilterFactoryCollection* factory);
159 virtual ~WebMediaPlayerImpl();
160
161 virtual void load(const WebKit::WebURL& url);
162 virtual void cancelLoad();
163
164 // Playback controls.
165 virtual void play();
166 virtual void pause();
[email protected]574a1d62009-07-17 03:23:46167 virtual bool supportsFullscreen() const;
168 virtual bool supportsSave() const;
[email protected]add51772009-06-11 18:25:17169 virtual void seek(float seconds);
170 virtual void setEndTime(float seconds);
171 virtual void setRate(float rate);
172 virtual void setVolume(float volume);
173 virtual void setVisible(bool visible);
174 virtual bool setAutoBuffer(bool autoBuffer);
175 virtual bool totalBytesKnown();
176 virtual float maxTimeBuffered() const;
177 virtual float maxTimeSeekable() const;
178
179 // Methods for painting.
180 virtual void setSize(const WebKit::WebSize& size);
181
[email protected]add51772009-06-11 18:25:17182 virtual void paint(WebKit::WebCanvas* canvas, const WebKit::WebRect& rect);
[email protected]add51772009-06-11 18:25:17183
184 // True if a video is loaded.
185 virtual bool hasVideo() const;
186
187 // Dimensions of the video.
188 virtual WebKit::WebSize naturalSize() const;
189
190 // Getters of playback state.
191 virtual bool paused() const;
192 virtual bool seeking() const;
193 virtual float duration() const;
194 virtual float currentTime() const;
195
196 // Get rate of loading the resource.
197 virtual int32 dataRate() const;
198
199 // Internal states of loading and network.
200 // TODO(hclam): Ask the pipeline about the state rather than having reading
201 // them from members which would cause race conditions.
202 virtual WebKit::WebMediaPlayer::NetworkState networkState() const {
203 return network_state_;
204 }
205 virtual WebKit::WebMediaPlayer::ReadyState readyState() const {
206 return ready_state_;
207 }
208
209 virtual unsigned long long bytesLoaded() const;
210 virtual unsigned long long totalBytes() const;
211
[email protected]38259a7a82009-07-29 21:49:49212 virtual bool hasSingleSecurityOrigin() const;
213 virtual WebKit::WebMediaPlayer::MovieLoadType movieLoadType() const;
214
[email protected]add51772009-06-11 18:25:17215 // As we are closing the tab or even the browser, |main_loop_| is destroyed
216 // even before this object gets destructed, so we need to know when
217 // |main_loop_| is being destroyed and we can stop posting repaint task
218 // to it.
219 virtual void WillDestroyCurrentMessageLoop();
220
[email protected]8931c41a2009-07-07 17:31:49221 void Repaint();
[email protected]add51772009-06-11 18:25:17222
[email protected]96706912009-07-15 17:18:05223 void OnPipelineInitialize();
[email protected]add51772009-06-11 18:25:17224
[email protected]96706912009-07-15 17:18:05225 void OnPipelineSeek();
[email protected]add51772009-06-11 18:25:17226
[email protected]576537842009-08-12 23:52:05227 void OnPipelineEnded();
228
[email protected]db190487d2009-07-30 18:51:52229 void OnPipelineError();
230
[email protected]add51772009-06-11 18:25:17231 private:
[email protected]96706912009-07-15 17:18:05232 // Helpers that set the network/ready state and notifies the client if
233 // they've changed.
234 void SetNetworkState(WebKit::WebMediaPlayer::NetworkState state);
235 void SetReadyState(WebKit::WebMediaPlayer::ReadyState state);
236
[email protected]8931c41a2009-07-07 17:31:49237 // Destroy resources held.
238 void Destroy();
[email protected]add51772009-06-11 18:25:17239
[email protected]8931c41a2009-07-07 17:31:49240 // Getter method to |client_|.
241 WebKit::WebMediaPlayerClient* GetClient();
[email protected]add51772009-06-11 18:25:17242
243 // TODO(hclam): get rid of these members and read from the pipeline directly.
244 WebKit::WebMediaPlayer::NetworkState network_state_;
245 WebKit::WebMediaPlayer::ReadyState ready_state_;
246
247 // Message loops for posting tasks between Chrome's main thread. Also used
248 // for DCHECKs so methods calls won't execute in the wrong thread.
249 MessageLoop* main_loop_;
250
251 // A collection of factories for creating filters.
252 scoped_refptr<media::FilterFactoryCollection> filter_factory_;
253
[email protected]3b4cbbf2009-07-11 00:16:19254 // The actual pipeline and the thread it runs on.
[email protected]a5648152009-07-18 03:37:43255 scoped_refptr<media::PipelineImpl> pipeline_;
[email protected]3b4cbbf2009-07-11 00:16:19256 base::Thread pipeline_thread_;
[email protected]add51772009-06-11 18:25:17257
[email protected]49480902009-07-14 20:23:43258 // Playback state.
259 //
260 // TODO(scherkus): we have these because Pipeline favours the simplicity of a
261 // single "playback rate" over worrying about paused/stopped etc... It forces
262 // all clients to manage the pause+playback rate externally, but is that
263 // really a bad thing?
264 bool paused_;
265 float playback_rate_;
266
[email protected]add51772009-06-11 18:25:17267 WebKit::WebMediaPlayerClient* client_;
268
[email protected]8931c41a2009-07-07 17:31:49269 scoped_refptr<Proxy> proxy_;
[email protected]add51772009-06-11 18:25:17270
271 DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerImpl);
272};
273
274} // namespace webkit_glue
275
276#endif // WEBKIT_GLUE_WEBMEDIAPLAYER_IMPL_H_