blob: 7fdd72a3e85d47f624349a3fce520431c8fb188f [file] [log] [blame]
[email protected]8400e032010-02-26 18:50:111// Copyright (c) 2010 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
[email protected]add51772009-06-11 18:25:175// 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]8400e032010-02-26 18:50:1117// WebVideoRenderer
[email protected]8931c41a2009-07-07 17:31:4918// 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
[email protected]8400e032010-02-26 18:50:1132// | | WebVideoRenderer
[email protected]8931c41a2009-07-07 17:31:4933// | | ^ r
34// | | |
35// | r | r |
36// .------> Proxy <-----.
37// |
38// |
39// v
40// WebMediaPlayerClient
41//
[email protected]8400e032010-02-26 18:50:1142// Notice that Proxy and WebVideoRenderer are referencing each other. This
[email protected]8931c41a2009-07-07 17:31:4943// 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
[email protected]add51772009-06-11 18:25:1756#include "base/lock.h"
57#include "base/message_loop.h"
[email protected]8931c41a2009-07-07 17:31:4958#include "base/ref_counted.h"
[email protected]5097dc82010-07-15 17:23:2359#include "base/scoped_ptr.h"
[email protected]34b99632011-01-01 01:01:0660#include "base/threading/thread.h"
[email protected]5badb082010-06-11 17:40:1561#include "base/waitable_event.h"
[email protected]e0fc2f12010-03-14 23:30:5962#include "gfx/rect.h"
63#include "gfx/size.h"
[email protected]add51772009-06-11 18:25:1764#include "media/base/filters.h"
[email protected]583634b2010-11-11 17:47:1565#include "media/base/pipeline.h"
[email protected]66a473c2009-07-22 02:12:5066#include "skia/ext/platform_canvas.h"
[email protected]418ed5ab2009-11-12 01:14:4967#include "third_party/WebKit/WebKit/chromium/public/WebMediaPlayer.h"
68#include "third_party/WebKit/WebKit/chromium/public/WebMediaPlayerClient.h"
[email protected]add51772009-06-11 18:25:1769
[email protected]add51772009-06-11 18:25:1770class GURL;
[email protected]add51772009-06-11 18:25:1771
[email protected]79684282010-12-06 21:15:4672namespace WebKit {
73class WebFrame;
74}
75
[email protected]add51772009-06-11 18:25:1776namespace webkit_glue {
77
[email protected]5b5bb9d2010-10-22 19:57:3678class MediaResourceLoaderBridgeFactory;
79class WebDataSource;
[email protected]8400e032010-02-26 18:50:1180class WebVideoRenderer;
[email protected]add51772009-06-11 18:25:1781
82class WebMediaPlayerImpl : public WebKit::WebMediaPlayer,
83 public MessageLoop::DestructionObserver {
84 public:
[email protected]8931c41a2009-07-07 17:31:4985 // A proxy class that dispatches method calls from the media pipeline to
86 // WebKit. Since there are multiple threads in the media pipeline and there's
87 // need for the media pipeline to call to WebKit, e.g. repaint requests,
88 // initialization events, etc, we have this class to bridge all method calls
89 // from the media pipeline on different threads and serialize these calls
90 // on the render thread.
91 // Because of the nature of this object that it works with different threads,
92 // it is made ref-counted.
93 class Proxy : public base::RefCountedThreadSafe<Proxy> {
94 public:
95 Proxy(MessageLoop* render_loop,
96 WebMediaPlayerImpl* webmediaplayer);
[email protected]8931c41a2009-07-07 17:31:4997
[email protected]f8db8132010-12-03 00:27:4998 // Methods for Filter -> WebMediaPlayerImpl communication.
[email protected]8931c41a2009-07-07 17:31:4999 void Repaint();
[email protected]457d8342010-10-23 01:20:37100 void SetVideoRenderer(scoped_refptr<WebVideoRenderer> video_renderer);
101 void SetDataSource(scoped_refptr<WebDataSource> data_source);
[email protected]8931c41a2009-07-07 17:31:49102
[email protected]f8db8132010-12-03 00:27:49103 // Methods for WebMediaPlayerImpl -> Filter communication.
[email protected]96706912009-07-15 17:18:05104 void Paint(skia::PlatformCanvas* canvas, const gfx::Rect& dest_rect);
105 void SetSize(const gfx::Rect& rect);
106 void Detach();
[email protected]e81283bb2010-08-31 18:01:21107 void GetCurrentFrame(scoped_refptr<media::VideoFrame>* frame_out);
108 void PutCurrentFrame(scoped_refptr<media::VideoFrame> frame);
[email protected]cf31d6f2010-10-26 02:23:47109 bool HasSingleOrigin();
[email protected]5b5bb9d2010-10-22 19:57:36110 void AbortDataSource();
[email protected]8931c41a2009-07-07 17:31:49111
[email protected]cf31d6f2010-10-26 02:23:47112 // Methods for PipelineImpl -> WebMediaPlayerImpl communication.
[email protected]96706912009-07-15 17:18:05113 void PipelineInitializationCallback();
114 void PipelineSeekCallback();
[email protected]576537842009-08-12 23:52:05115 void PipelineEndedCallback();
[email protected]db190487d2009-07-30 18:51:52116 void PipelineErrorCallback();
[email protected]4f92fbc2009-10-16 01:29:50117 void NetworkEventCallback();
[email protected]96706912009-07-15 17:18:05118
[email protected]8400e032010-02-26 18:50:11119 // Returns the message loop used by the proxy.
120 MessageLoop* message_loop() { return render_loop_; }
121
[email protected]96706912009-07-15 17:18:05122 private:
[email protected]122331d52009-11-05 23:40:45123 friend class base::RefCountedThreadSafe<Proxy>;
124
125 virtual ~Proxy();
126
[email protected]8931c41a2009-07-07 17:31:49127 // Invoke |webmediaplayer_| to perform a repaint.
128 void RepaintTask();
129
[email protected]96706912009-07-15 17:18:05130 // Notify |webmediaplayer_| that initialization has finished.
131 void PipelineInitializationTask();
[email protected]8931c41a2009-07-07 17:31:49132
[email protected]96706912009-07-15 17:18:05133 // Notify |webmediaplayer_| that a seek has finished.
134 void PipelineSeekTask();
[email protected]8931c41a2009-07-07 17:31:49135
[email protected]576537842009-08-12 23:52:05136 // Notify |webmediaplayer_| that the media has ended.
137 void PipelineEndedTask();
138
[email protected]db190487d2009-07-30 18:51:52139 // Notify |webmediaplayer_| that a pipeline error has been set.
140 void PipelineErrorTask();
141
[email protected]4f92fbc2009-10-16 01:29:50142 // Notify |webmediaplayer_| that there's a network event.
143 void NetworkEventTask();
144
[email protected]8931c41a2009-07-07 17:31:49145 // The render message loop where WebKit lives.
146 MessageLoop* render_loop_;
147 WebMediaPlayerImpl* webmediaplayer_;
[email protected]5b5bb9d2010-10-22 19:57:36148 scoped_refptr<WebDataSource> data_source_;
[email protected]8400e032010-02-26 18:50:11149 scoped_refptr<WebVideoRenderer> video_renderer_;
[email protected]8931c41a2009-07-07 17:31:49150
151 Lock lock_;
152 int outstanding_repaints_;
153 };
154
[email protected]add51772009-06-11 18:25:17155 // Construct a WebMediaPlayerImpl with reference to the client, and media
[email protected]457d8342010-10-23 01:20:37156 // filter collection. By providing the filter collection the implementor can
157 // provide more specific media filters that does resource loading and
158 // rendering. |collection| should contain filter factories for:
[email protected]add51772009-06-11 18:25:17159 // 1. Data source
160 // 2. Audio renderer
161 // 3. Video renderer (optional)
162 //
163 // There are some default filters provided by this method:
164 // 1. FFmpeg demuxer
165 // 2. FFmpeg audio decoder
166 // 3. FFmpeg video decoder
167 // 4. Video renderer
[email protected]8380c092009-06-25 17:45:51168 // 5. Null audio renderer
[email protected]add51772009-06-11 18:25:17169 // The video renderer provided by this class is using the graphics context
170 // provided by WebKit to perform renderering. The simple data source does
171 // resource loading by loading the whole resource object into memory. Null
172 // audio renderer is a fake audio device that plays silence. Provider of the
[email protected]457d8342010-10-23 01:20:37173 // |collection| can override the default filters by adding extra filters to
174 // |collection| before calling this method.
[email protected]8400e032010-02-26 18:50:11175 //
[email protected]a8e24d522010-12-01 07:13:58176 // Callers must call |Initialize()| before they can use the object.
[email protected]add51772009-06-11 18:25:17177 WebMediaPlayerImpl(WebKit::WebMediaPlayerClient* client,
[email protected]f8db8132010-12-03 00:27:49178 media::FilterCollection* collection);
[email protected]add51772009-06-11 18:25:17179 virtual ~WebMediaPlayerImpl();
180
[email protected]a8e24d522010-12-01 07:13:58181 // Finalizes initialization of the object.
182 bool Initialize(
[email protected]79684282010-12-06 21:15:46183 WebKit::WebFrame* frame,
[email protected]a8e24d522010-12-01 07:13:58184 bool use_simple_data_source,
185 scoped_refptr<WebVideoRenderer> web_video_renderer);
186
[email protected]add51772009-06-11 18:25:17187 virtual void load(const WebKit::WebURL& url);
188 virtual void cancelLoad();
189
190 // Playback controls.
191 virtual void play();
192 virtual void pause();
[email protected]574a1d62009-07-17 03:23:46193 virtual bool supportsFullscreen() const;
194 virtual bool supportsSave() const;
[email protected]add51772009-06-11 18:25:17195 virtual void seek(float seconds);
196 virtual void setEndTime(float seconds);
197 virtual void setRate(float rate);
198 virtual void setVolume(float volume);
199 virtual void setVisible(bool visible);
200 virtual bool setAutoBuffer(bool autoBuffer);
201 virtual bool totalBytesKnown();
[email protected]f70f8e12010-05-25 21:30:39202 virtual const WebKit::WebTimeRanges& buffered();
[email protected]add51772009-06-11 18:25:17203 virtual float maxTimeSeekable() const;
204
205 // Methods for painting.
206 virtual void setSize(const WebKit::WebSize& size);
207
[email protected]add51772009-06-11 18:25:17208 virtual void paint(WebKit::WebCanvas* canvas, const WebKit::WebRect& rect);
[email protected]add51772009-06-11 18:25:17209
[email protected]83f2a8a2009-08-18 22:42:15210 // True if the loaded media has a playable video/audio track.
[email protected]add51772009-06-11 18:25:17211 virtual bool hasVideo() const;
[email protected]fc367af2009-08-14 23:06:35212 virtual bool hasAudio() const;
[email protected]add51772009-06-11 18:25:17213
214 // Dimensions of the video.
215 virtual WebKit::WebSize naturalSize() const;
216
217 // Getters of playback state.
218 virtual bool paused() const;
219 virtual bool seeking() const;
220 virtual float duration() const;
221 virtual float currentTime() const;
222
223 // Get rate of loading the resource.
224 virtual int32 dataRate() const;
225
226 // Internal states of loading and network.
227 // TODO(hclam): Ask the pipeline about the state rather than having reading
228 // them from members which would cause race conditions.
[email protected]ddb1e5a2010-12-13 20:10:45229 virtual WebKit::WebMediaPlayer::NetworkState networkState() const;
230 virtual WebKit::WebMediaPlayer::ReadyState readyState() const;
[email protected]add51772009-06-11 18:25:17231
232 virtual unsigned long long bytesLoaded() const;
233 virtual unsigned long long totalBytes() const;
234
[email protected]38259a7a82009-07-29 21:49:49235 virtual bool hasSingleSecurityOrigin() const;
236 virtual WebKit::WebMediaPlayer::MovieLoadType movieLoadType() const;
237
[email protected]e81283bb2010-08-31 18:01:21238 virtual WebKit::WebVideoFrame* getCurrentFrame();
239 virtual void putCurrentFrame(WebKit::WebVideoFrame* web_video_frame);
240
[email protected]add51772009-06-11 18:25:17241 // As we are closing the tab or even the browser, |main_loop_| is destroyed
242 // even before this object gets destructed, so we need to know when
243 // |main_loop_| is being destroyed and we can stop posting repaint task
244 // to it.
245 virtual void WillDestroyCurrentMessageLoop();
246
[email protected]8931c41a2009-07-07 17:31:49247 void Repaint();
[email protected]add51772009-06-11 18:25:17248
[email protected]96706912009-07-15 17:18:05249 void OnPipelineInitialize();
[email protected]add51772009-06-11 18:25:17250
[email protected]96706912009-07-15 17:18:05251 void OnPipelineSeek();
[email protected]add51772009-06-11 18:25:17252
[email protected]576537842009-08-12 23:52:05253 void OnPipelineEnded();
254
[email protected]db190487d2009-07-30 18:51:52255 void OnPipelineError();
256
[email protected]4f92fbc2009-10-16 01:29:50257 void OnNetworkEvent();
258
[email protected]add51772009-06-11 18:25:17259 private:
[email protected]96706912009-07-15 17:18:05260 // Helpers that set the network/ready state and notifies the client if
261 // they've changed.
262 void SetNetworkState(WebKit::WebMediaPlayer::NetworkState state);
263 void SetReadyState(WebKit::WebMediaPlayer::ReadyState state);
264
[email protected]8931c41a2009-07-07 17:31:49265 // Destroy resources held.
266 void Destroy();
[email protected]add51772009-06-11 18:25:17267
[email protected]5badb082010-06-11 17:40:15268 // Callback executed after |pipeline_| stops which signals Destroy()
269 // to continue.
270 void PipelineStoppedCallback();
271
[email protected]8931c41a2009-07-07 17:31:49272 // Getter method to |client_|.
273 WebKit::WebMediaPlayerClient* GetClient();
[email protected]add51772009-06-11 18:25:17274
275 // TODO(hclam): get rid of these members and read from the pipeline directly.
276 WebKit::WebMediaPlayer::NetworkState network_state_;
277 WebKit::WebMediaPlayer::ReadyState ready_state_;
278
[email protected]67cd5052009-09-10 21:53:22279 // Keep a list of buffered time ranges.
280 WebKit::WebTimeRanges buffered_;
281
[email protected]add51772009-06-11 18:25:17282 // Message loops for posting tasks between Chrome's main thread. Also used
283 // for DCHECKs so methods calls won't execute in the wrong thread.
284 MessageLoop* main_loop_;
285
[email protected]457d8342010-10-23 01:20:37286 // A collection of filters.
[email protected]f8db8132010-12-03 00:27:49287 scoped_ptr<media::FilterCollection> filter_collection_;
[email protected]add51772009-06-11 18:25:17288
[email protected]3b4cbbf2009-07-11 00:16:19289 // The actual pipeline and the thread it runs on.
[email protected]583634b2010-11-11 17:47:15290 scoped_refptr<media::Pipeline> pipeline_;
[email protected]3b4cbbf2009-07-11 00:16:19291 base::Thread pipeline_thread_;
[email protected]add51772009-06-11 18:25:17292
[email protected]49480902009-07-14 20:23:43293 // Playback state.
294 //
295 // TODO(scherkus): we have these because Pipeline favours the simplicity of a
296 // single "playback rate" over worrying about paused/stopped etc... It forces
297 // all clients to manage the pause+playback rate externally, but is that
298 // really a bad thing?
[email protected]f467d032009-10-23 00:56:24299 //
300 // TODO(scherkus): since SetPlaybackRate(0) is asynchronous and we don't want
301 // to hang the render thread during pause(), we record the time at the same
302 // time we pause and then return that value in currentTime(). Otherwise our
303 // clock can creep forward a little bit while the asynchronous
304 // SetPlaybackRate(0) is being executed.
[email protected]49480902009-07-14 20:23:43305 bool paused_;
[email protected]b3766a22010-12-22 17:34:13306 bool seeking_;
[email protected]49480902009-07-14 20:23:43307 float playback_rate_;
[email protected]f467d032009-10-23 00:56:24308 base::TimeDelta paused_time_;
[email protected]49480902009-07-14 20:23:43309
[email protected]add51772009-06-11 18:25:17310 WebKit::WebMediaPlayerClient* client_;
311
[email protected]8931c41a2009-07-07 17:31:49312 scoped_refptr<Proxy> proxy_;
[email protected]add51772009-06-11 18:25:17313
[email protected]5badb082010-06-11 17:40:15314 // Used to block Destroy() until Pipeline::Stop() is completed.
315 base::WaitableEvent pipeline_stopped_;
316
[email protected]776775e2009-09-21 15:21:29317#if WEBKIT_USING_CG
318 scoped_ptr<skia::PlatformCanvas> skia_canvas_;
319#endif
320
[email protected]add51772009-06-11 18:25:17321 DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerImpl);
322};
323
[email protected]add51772009-06-11 18:25:17324} // namespace webkit_glue
325
326#endif // WEBKIT_GLUE_WEBMEDIAPLAYER_IMPL_H_