[email protected] | add5177 | 2009-06-11 18:25:17 | [diff] [blame] | 1 | // 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 | |
| 56 | class AudioRendererImpl; |
| 57 | class DataSourceImpl; |
| 58 | class GURL; |
| 59 | class RenderView; |
| 60 | class VideoRendererImpl; |
| 61 | |
| 62 | namespace media { |
| 63 | class FilterFactoryCollection; |
| 64 | } |
| 65 | |
| 66 | namespace webkit_glue { |
| 67 | |
| 68 | // This typedef is used for WebMediaPlayerImpl::PostTask() and |
| 69 | // NotifyWebMediaPlayerTask in the source file. |
| 70 | typedef void (WebKit::WebMediaPlayerClient::*WebMediaPlayerClientMethod)(); |
| 71 | |
| 72 | class 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] | 8380c09 | 2009-06-25 17:45:51 | [diff] [blame^] | 88 | // 5. Null audio renderer |
[email protected] | add5177 | 2009-06-11 18:25:17 | [diff] [blame] | 89 | // 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] | add5177 | 2009-06-11 18:25:17 | [diff] [blame] | 119 | virtual void paint(WebKit::WebCanvas* canvas, const WebKit::WebRect& rect); |
[email protected] | add5177 | 2009-06-11 18:25:17 | [diff] [blame] | 120 | |
| 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_ |