Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / content / media / video / public / nsWaveDecoder.h
blob70b77a5345fce39701bb588e98498992adfdf970
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 /* ***** BEGIN LICENSE BLOCK *****
4 * Version: ML 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
16 * The Original Code is Mozilla code.
18 * The Initial Developer of the Original Code is the Mozilla Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 2008
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
23 * Matthew Gregan <kinetik@flim.org>
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
38 #if !defined(nsWaveDecoder_h_)
39 #define nsWaveDecoder_h_
41 #include "nsISupports.h"
42 #include "nsCOMPtr.h"
43 #include "nsMediaDecoder.h"
44 #include "nsMediaStream.h"
47 nsWaveDecoder provides an implementation of the abstract nsMediaDecoder
48 class that supports parsing and playback of Waveform Audio (WAVE) chunks
49 embedded in Resource Interchange File Format (RIFF) bitstreams as
50 specified by the Multimedia Programming Interface and Data Specification
51 1.0.
53 Each decoder instance starts one thread (the playback thread). A single
54 nsWaveStateMachine event is dispatched to this thread to start the
55 thread's state machine running. The Run method of the event is a loop
56 that executes the current state. The state can be changed by the state
57 machine, or from the main thread via threadsafe methods on the event.
58 During playback, the playback thread reads data from the network and
59 writes it to the audio backend, attempting to keep the backend's audio
60 buffers full. It is also responsible for seeking, buffering, and
61 pausing/resuming audio.
63 The decoder also owns an nsMediaStream instance that provides a threadsafe
64 blocking interface to read from network channels. The state machine is
65 the primary user of this stream and holds a weak (raw) pointer to it as
66 the thread, state machine, and stream's lifetimes are all managed by the
67 decoder.
69 nsWaveStateMachine has the following states:
71 LOADING_METADATA
72 RIFF/WAVE chunks are being read from the stream, the metadata describing
73 the audio data is parsed.
75 BUFFERING
76 Playback is paused while waiting for additional data.
78 PLAYING
79 If data is available in the stream and the audio backend can consume
80 more data, it is read from the stream and written to the audio backend.
81 Sleep until approximately half of the backend's buffers have drained.
83 SEEKING
84 Decoder is seeking to a specified time in the media.
86 PAUSED
87 Pause the audio backend, then wait for a state transition.
89 ENDED
90 Expected PCM data (or stream EOF) reached, wait for the audio backend to
91 play any buffered data, then wait for shutdown.
93 ERROR
94 Metadata loading/parsing failed, wait for shutdown.
96 SHUTDOWN
97 Close the audio backend and return from the run loop.
99 State transitions within the state machine are:
101 LOADING_METADATA -> PLAYING
102 -> PAUSED
103 -> ERROR
105 BUFFERING -> PLAYING
106 -> PAUSED
108 PLAYING -> BUFFERING
109 -> ENDED
111 SEEKING -> PLAYING
112 -> PAUSED
114 PAUSED -> waits for caller to play, seek, or shutdown
116 ENDED -> waits for caller to shutdown
118 ERROR -> waits for caller to shutdown
120 SHUTDOWN -> exits state machine
122 In addition, the following methods cause state transitions:
124 Shutdown(), Play(), Pause(), Seek(float)
126 The decoder implementation is currently limited to Linear PCM encoded
127 audio data with one or two channels of 8- or 16-bit samples at sample
128 rates from 100 Hz to 96 kHz. The number of channels is limited by what
129 the audio backend (sydneyaudio via nsAudioStream) currently supports. The
130 supported sample rate is artificially limited to arbitrarily selected sane
131 values. Support for additional channels (and other new features) would
132 require extending nsWaveDecoder to support parsing the newer
133 WAVE_FORMAT_EXTENSIBLE chunk format.
136 class nsWaveStateMachine;
138 class nsWaveDecoder : public nsMediaDecoder
140 friend class nsWaveStateMachine;
142 NS_DECL_ISUPPORTS
143 NS_DECL_NSIOBSERVER
145 public:
146 nsWaveDecoder();
147 ~nsWaveDecoder();
149 virtual void GetCurrentURI(nsIURI** aURI);
150 virtual nsIPrincipal* GetCurrentPrincipal();
152 // Return the current playback position in the media in seconds.
153 virtual float GetCurrentTime();
155 // Return the total playback length of the media in seconds.
156 virtual float GetDuration();
158 // Get the current audio playback volume; result in range [0.0, 1.0].
159 virtual float GetVolume();
161 // Set the audio playback volume; must be in range [0.0, 1.0].
162 virtual void SetVolume(float aVolume);
164 virtual nsresult Play();
165 virtual void Stop();
166 virtual void Pause();
168 // Set the current time of the media to aTime. This may cause mStream to
169 // create a new channel to fetch data from the appropriate position in the
170 // stream.
171 virtual nsresult Seek(float aTime);
173 // Report whether the decoder is currently seeking.
174 virtual PRBool IsSeeking() const;
176 // Report whether the decoder has reached end of playback.
177 virtual PRBool IsEnded() const;
179 // Start downloading the media at the specified URI. The media's metadata
180 // will be parsed and made available as the load progresses.
181 virtual nsresult Load(nsIURI* aURI, nsIChannel* aChannel, nsIStreamListener** aStreamListener);
183 // Called by mStream (and possibly the nsChannelToPipeListener used
184 // internally by mStream) when the stream has completed loading.
185 virtual void ResourceLoaded();
187 // Called by mStream (and possibly the nsChannelToPipeListener used
188 // internally by mStream) if the stream encounters a network error.
189 virtual void NetworkError();
191 // Element is notifying us that the requested playback rate has changed.
192 virtual nsresult PlaybackRateChanged();
194 // Getter/setter for mContentLength.
195 virtual PRInt64 GetTotalBytes();
196 virtual void SetTotalBytes(PRInt64 aBytes);
198 // Getter/setter for mSeekable.
199 virtual void SetSeekable(PRBool aSeekable);
200 virtual PRBool GetSeekable();
202 // Getter/setter for mBytesDownloaded.
203 virtual PRUint64 GetBytesLoaded();
204 virtual void UpdateBytesDownloaded(PRUint64 aBytes);
206 // Must be called by the owning object before disposing the decoder.
207 virtual void Shutdown();
209 private:
210 // Notifies the nsHTMLMediaElement that buffering has started.
211 void BufferingStarted();
213 // Notifies the element that buffering has stopped.
214 void BufferingStopped();
216 // Notifies the element that seeking has started.
217 void SeekingStarted();
219 // Notifies the element that seeking has completed.
220 void SeekingStopped();
222 // Notifies the element that metadata loading has completed. Only fired
223 // if metadata is valid.
224 void MetadataLoaded();
226 // Notifies the element that playback has completed.
227 void PlaybackEnded();
229 // Notifies the element that metadata loading has failed.
230 void MediaErrorDecode();
232 void RegisterShutdownObserver();
233 void UnregisterShutdownObserver();
235 // Length of the current resource, or -1 if not available.
236 PRInt64 mContentLength;
238 // Total bytes downloaded by mStream so far.
239 PRUint64 mBytesDownloaded;
241 // Volume that the audio backend will be initialized with.
242 float mInitialVolume;
244 // URI of the current resource.
245 nsCOMPtr<nsIURI> mURI;
247 // Thread that handles audio playback, including data download.
248 nsCOMPtr<nsIThread> mPlaybackThread;
250 // State machine that runs on mPlaybackThread. Methods on this object are
251 // safe to call from any thread.
252 nsCOMPtr<nsWaveStateMachine> mPlaybackStateMachine;
254 // Threadsafe wrapper around channels that provides seeking based on the
255 // underlying channel type.
256 nsAutoPtr<nsMediaStream> mStream;
258 // The media time of the last requested seek. This has not been validated
259 // against the current media, so may be out of bounds. Set when
260 // Seek(float) is called, and passed to the state machine when the
261 // SeekStarted event fires to tell it to update its time offset. The
262 // state machine will validate the offset against the current media.
263 float mTimeOffset;
265 // Copy of the current time, duration, and ended state when the state
266 // machine was disposed. Used to respond to time and duration queries
267 // with sensible values after the state machine is destroyed.
268 float mEndedCurrentTime;
269 float mEndedDuration;
270 PRPackedBool mEnded;
272 // True if we have registered a shutdown observer.
273 PRPackedBool mNotifyOnShutdown;
275 // True if the media resource is seekable.
276 PRPackedBool mSeekable;
279 #endif