blob: d8a365c00cb6af6110dee6a414639ab9f4c45226 [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//
12// Properties that are shared by main thread and media threads:
13// CancelableTaskList tasks_;
14// ^--- This property is shared for keeping records of the tasks posted to
15// make sure there will be only one task for each task type that can
16// exist in the main thread.
17//
18// Methods that are accessed in media threads:
19// SetAudioRenderer()
20// ^--- Called during the initialization of the pipeline, essentially from the
21// the pipeline thread.
22// SetVideoRenderer()
23// ^--- Called during the initialization of the pipeline, essentially from the
24// the pipeline thread.
25// PostRepaintTask()
26// ^--- Called from the video renderer thread to notify a video frame has
27// been prepared.
28// PostTask()
29// ^--- A method that helps posting tasks to the main thread, it is
30// accessed from main thread and media threads, it access the |tasks_|
31// internally. Needs locking inside to avoid concurrent access to
32// |tasks_|.
33//
34//
35// Other issues:
36// During tear down of the whole browser or a tab, the DOM tree may not be
37// destructed nicely, and there will be some dangling media threads trying to
38// the main thread, so we need this class to listen to destruction event of the
39// main thread and cleanup the media threads when the even is received. Also
40// at destruction of this class we will need to unhook it from destruction event
41// list of the main thread.
42
43#ifndef WEBKIT_GLUE_WEBMEDIAPLAYER_IMPL_H_
44#define WEBKTI_GLUE_WEBMEDIAPLAYER_IMPL_H_
45
46#include <vector>
47
48#include "base/gfx/platform_canvas.h"
49#include "base/lock.h"
50#include "base/message_loop.h"
51#include "media/base/filters.h"
52#include "media/base/pipeline_impl.h"
53#include "webkit/api/public/WebMediaPlayer.h"
54#include "webkit/api/public/WebMediaPlayerClient.h"
55
56class AudioRendererImpl;
57class DataSourceImpl;
58class GURL;
59class RenderView;
60class VideoRendererImpl;
61
62namespace media {
63class FilterFactoryCollection;
64}
65
66namespace webkit_glue {
67
68// This typedef is used for WebMediaPlayerImpl::PostTask() and
69// NotifyWebMediaPlayerTask in the source file.
70typedef void (WebKit::WebMediaPlayerClient::*WebMediaPlayerClientMethod)();
71
72class WebMediaPlayerImpl : public WebKit::WebMediaPlayer,
73 public MessageLoop::DestructionObserver {
74 public:
75 // Construct a WebMediaPlayerImpl with reference to the client, and media
76 // filter factory collection. By providing the filter factory collection
77 // the implementor can provide more specific media filters that does resource
78 // loading and rendering. |factory| should contain filter factories for:
79 // 1. Data source
80 // 2. Audio renderer
81 // 3. Video renderer (optional)
82 //
83 // There are some default filters provided by this method:
84 // 1. FFmpeg demuxer
85 // 2. FFmpeg audio decoder
86 // 3. FFmpeg video decoder
87 // 4. Video renderer
[email protected]8380c092009-06-25 17:45:5188 // 5. Null audio renderer
[email protected]add51772009-06-11 18:25:1789 // The video renderer provided by this class is using the graphics context
90 // provided by WebKit to perform renderering. The simple data source does
91 // resource loading by loading the whole resource object into memory. Null
92 // audio renderer is a fake audio device that plays silence. Provider of the
93 // |factory| can override the default filters by adding extra filters to
94 // |factory| before calling this method.
95 WebMediaPlayerImpl(WebKit::WebMediaPlayerClient* client,
96 media::FilterFactoryCollection* factory);
97 virtual ~WebMediaPlayerImpl();
98
99 virtual void load(const WebKit::WebURL& url);
100 virtual void cancelLoad();
101
102 // Playback controls.
103 virtual void play();
104 virtual void pause();
105 virtual void stop();
106 virtual void seek(float seconds);
107 virtual void setEndTime(float seconds);
108 virtual void setRate(float rate);
109 virtual void setVolume(float volume);
110 virtual void setVisible(bool visible);
111 virtual bool setAutoBuffer(bool autoBuffer);
112 virtual bool totalBytesKnown();
113 virtual float maxTimeBuffered() const;
114 virtual float maxTimeSeekable() const;
115
116 // Methods for painting.
117 virtual void setSize(const WebKit::WebSize& size);
118
[email protected]add51772009-06-11 18:25:17119 virtual void paint(WebKit::WebCanvas* canvas, const WebKit::WebRect& rect);
[email protected]add51772009-06-11 18:25:17120
121 // True if a video is loaded.
122 virtual bool hasVideo() const;
123
124 // Dimensions of the video.
125 virtual WebKit::WebSize naturalSize() const;
126
127 // Getters of playback state.
128 virtual bool paused() const;
129 virtual bool seeking() const;
130 virtual float duration() const;
131 virtual float currentTime() const;
132
133 // Get rate of loading the resource.
134 virtual int32 dataRate() const;
135
136 // Internal states of loading and network.
137 // TODO(hclam): Ask the pipeline about the state rather than having reading
138 // them from members which would cause race conditions.
139 virtual WebKit::WebMediaPlayer::NetworkState networkState() const {
140 return network_state_;
141 }
142 virtual WebKit::WebMediaPlayer::ReadyState readyState() const {
143 return ready_state_;
144 }
145
146 virtual unsigned long long bytesLoaded() const;
147 virtual unsigned long long totalBytes() const;
148
149 // As we are closing the tab or even the browser, |main_loop_| is destroyed
150 // even before this object gets destructed, so we need to know when
151 // |main_loop_| is being destroyed and we can stop posting repaint task
152 // to it.
153 virtual void WillDestroyCurrentMessageLoop();
154
155 // Notification from |pipeline_| when initialization has finished.
156 void OnPipelineInitialize(bool successful);
157
158 // Notification from |pipeline_| when a seek has finished.
159 void OnPipelineSeek(bool successful);
160
161 // Called from tasks posted to |main_loop_| from this object to remove
162 // reference of them.
163 void DidTask(CancelableTask* task);
164
165 // Public methods to be called from renderers and data source so that
166 // WebMediaPlayerImpl has references to them.
167 void SetVideoRenderer(VideoRendererImpl* video_renderer);
168
169 // Called from VideoRenderer to fire a repaint task to |main_loop_|.
170 void PostRepaintTask();
171
172 // Inline getters.
173 WebKit::WebMediaPlayerClient* client() { return client_; }
174
175 private:
176 // Methods for posting tasks and cancelling tasks. This method may lives in
177 // the main thread or the media threads.
178 void PostTask(int index, WebMediaPlayerClientMethod method);
179
180 // Cancel all tasks currently live in |main_loop_|.
181 void CancelAllTasks();
182
183 // Indexes for tasks.
184 enum {
185 kRepaintTaskIndex = 0,
186 kReadyStateTaskIndex,
187 kNetworkStateTaskIndex,
188 kTimeChangedTaskIndex,
189 kLastTaskIndex
190 };
191
192 // TODO(hclam): get rid of these members and read from the pipeline directly.
193 WebKit::WebMediaPlayer::NetworkState network_state_;
194 WebKit::WebMediaPlayer::ReadyState ready_state_;
195
196 // Message loops for posting tasks between Chrome's main thread. Also used
197 // for DCHECKs so methods calls won't execute in the wrong thread.
198 MessageLoop* main_loop_;
199
200 // A collection of factories for creating filters.
201 scoped_refptr<media::FilterFactoryCollection> filter_factory_;
202
203 // The actual pipeline. We do it a composition here because we expect to have
204 // the same lifetime as the pipeline.
205 media::PipelineImpl pipeline_;
206
207 // We have the interface to VideoRenderer to delegate paint messages to it
208 // from WebKit.
209 scoped_refptr<VideoRendererImpl> video_renderer_;
210
211 WebKit::WebMediaPlayerClient* client_;
212
213 // List of tasks for holding pointers to all tasks currently in the
214 // |main_loop_|. |tasks_| can be access from main thread or the media threads
215 // we need a lock for protecting it.
216 Lock task_lock_;
217 typedef std::vector<CancelableTask*> CancelableTaskList;
218 CancelableTaskList tasks_;
219
220 DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerImpl);
221};
222
223} // namespace webkit_glue
224
225#endif // WEBKIT_GLUE_WEBMEDIAPLAYER_IMPL_H_