2009-09-12 Chris Toshok <toshok@ximian.com>
[moon.git] / src / pipeline-asf.h
blob74207e42e4a3d12c8cac2c11a32fe8630311f757
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * pipeline.h: Pipeline for the media
5 * Contact:
6 * Moonlight List (moonlight-list@lists.ximian.com)
8 * Copyright 2007 Novell, Inc. (http://www.novell.com)
10 * See the LICENSE file included with the distribution for details.
14 #ifndef __MOON_PIPELINE_ASF_H_
15 #define __MOON_PIPELINE_ASF_H_
17 class ASFDemuxer;
18 class ASFDemuxerInfo;
19 class ASFMarkerDecoder;
20 class ASFMarkerDecoderInfo;
21 class MmsSource;
22 class MmsPlaylistEntry;
24 #include "pipeline.h"
25 #include "asf.h"
26 #include "mms-downloader.h"
27 #include "mutex.h"
30 * Mms:
32 * # Normal playback (single file or live stream)
33 * * Handled as a playlist with a single entry
35 * # Playlist
36 * * Order of events
38 * - Media is created, with an mms:// uri
40 * Media::Initialize ():
41 * - Media creates a downloader for the uri and opens it
42 * - MmsDownloader sends a DESCRIBE request for the uri, also requesting a packet pair experiment
43 * - Media creates an MmsSource for the downloader (which is an MmsDownloader)
44 * - MmsSource creates the first MmsPlaylistEntry for the first entry (which will be the only one if the mms uri isn't a server-side playlist)
46 * Media::Open ():
47 * Media::SelectDemuxer ():
48 * - MmsSource creates an MmsDemuxer
49 * Media::SelectDecoders ():
50 * - No decoders selected, since MmsDemuxer represents a playlist
51 * OpenCompletedEvent is raised:
52 * - The current PlaylistEntry will replace itself with the playlist the MmsDemuxer returns
54 * NOTE: We rely on the fact that mozilla needs a tick to start downloading something,
55 * after the DESCRIBE request everything has been done sync up till now
57 * (ticks)
59 * - MmsDownloader may receive P (packet pair) responses
60 * - MmsDownloader may receive an M (metadata) response
61 * - MmsSource::SetMmsMetadata is called and fills in the given the metadata (playlist-gen-id, broadcast-id, features)
62 * - MmsDownloader will receive an H (header) response
63 * - MmsSource::ParseHeader is called
65 * then optionally repeat this:
66 * - MmsDownloader receives a C (stream change) response
67 * MmsSource::ReportStreamChange change is called
68 * - MmsSource creates a new MmsPlaylistEntry
69 * - MmsDownloader may receive a M (metadata) response
70 * - MmsSource::SetMmsMetadata is called and fills in the given the metadata (playlist-gen-id, broadcast-id, features)
71 * - MmsDownloader receives an H (header) response
77 * MmsSource
79 class MmsSource : public IMediaSource {
80 private:
81 bool finished;
82 guint64 write_count;
83 Downloader *downloader;
84 // this is the current entry being downloaded (not necessarily played).
85 MmsPlaylistEntry *current;
86 MmsDemuxer *demuxer;
88 EVENTHANDLER (MmsSource, DownloadFailed, Downloader, EventArgs); // Main thread only
89 EVENTHANDLER (MmsSource, DownloadComplete, Downloader, EventArgs); // Main thread only
91 protected:
92 virtual void Dispose (); // Thread safe
94 public:
95 MmsSource (Media *media, Downloader *downloader);
97 void NotifyFinished (guint32 reason); // called by the MmsDownloader when we get the END packet. Main thread only.
99 virtual MediaResult Initialize (); // main thread only
100 virtual MediaSourceType GetType () { return MediaSourceTypeMms; }
102 virtual bool CanSeek () { return true; }
103 virtual bool Eof (); // thread safe
105 virtual bool CanSeekToPts () { return true; }
106 virtual MediaResult SeekToPts (guint64 pts); // thread safe
108 virtual IMediaDemuxer *CreateDemuxer (Media *media); // thread safe
110 bool IsFinished () { return finished; } // If the server sent the MMS_END packet.
112 Downloader *GetDownloaderReffed (); // thread safe
113 MmsDemuxer *GetDemuxerReffed (); // thread safe
115 ASFPacket *Pop (); // forwards to the current entry, thread safe
116 void WritePacket (void *buf, gint32 n); // forwards to the current entry. Main thread only
117 MmsPlaylistEntry *GetCurrentReffed (); // thread safe
119 void SetMmsMetadata (const char *playlist_gen_id, const char *broadcast_id, HttpStreamingFeatures features); // Main thread only
120 MediaResult ParseHeader (void *buffer, gint32 size); // Main thread only
121 void ReportStreamChange (gint32 reason); // called by the MmsDownloader when we get a C (stream change) packet. Main thread only.
122 void ReportDownloadFailure (); // called by the MmsDownloader when the download fails (404 for instance). Main thread only.
124 // returns the MmsDownloader for the Downloader
125 // you must own a ref to the downloader (since this method must be thread safe,
126 // that's the only way to ensure the downloader isn't deleted at any time)
127 // and the returned MmsDownloader is only valid as long as you have a ref to
128 // the downloader.
129 static MmsDownloader *GetMmsDownloader (Downloader *dl); // thread safe
133 * MmsPlaylistEntry
135 class MmsPlaylistEntry : public IMediaSource {
136 private:
137 bool finished;
138 Queue queue;
139 MmsSource *parent;
140 ASFParser *parser;
141 guint64 write_count; // just for statistics
142 ASFDemuxer *demuxer;
144 // mms metadata
145 char *playlist_gen_id;
146 char *broadcast_id;
147 HttpStreamingFeatures features;
149 protected:
150 virtual void Dispose (); // thread safe
152 public:
153 class QueueNode : public List::Node {
154 public:
155 ASFPacket *packet;
156 MemorySource *source;
157 QueueNode (ASFPacket *packet);
158 QueueNode (MemorySource *source);
159 virtual ~QueueNode ();
162 MmsPlaylistEntry (Media *media, MmsSource *source);
164 virtual MediaResult Initialize ();
165 virtual MediaSourceType GetType () { return MediaSourceTypeMmsEntry; }
167 virtual bool CanSeekToPts () { return true; } // thread safe
168 virtual MediaResult SeekToPts (guint64 pts); // thread safe
170 virtual bool Eof () { return finished && queue.IsEmpty (); } // thread safe
171 virtual IMediaDemuxer *CreateDemuxer (Media *media); // thread safe
172 bool IsFinished (); // thread safe
174 // this method reports any errors to the media
175 MediaResult ParseHeader (void *buffer, gint32 size); // main thread
176 bool IsHeaderParsed ();
177 ASFParser *GetParserReffed (); // thread safe
178 MmsSource *GetParentReffed (); // thread safe
180 ASFPacket *Pop (); // thread safe
181 void WritePacket (void *buf, gint32 n); // main thread
183 void AddEntry (); // main thread
185 void SetPlaylistGenId (const char *value); // thread safe
186 char *GetPlaylistGenId (); // thread safe, returns a duped string, must be freed with g_free
187 void SetBroadcastId (const char *value); // thread safe
188 char *GetBroadcastId (); // thread safe, returns a duped string, must be freed with g_free
189 void SetHttpStreamingFeatures (HttpStreamingFeatures value); // thread safe
190 HttpStreamingFeatures GetHttpStreamingFeatures (); // thread safe
192 // fills in each entry of the array with:
193 // -1 - stream does not exist
194 // 0 - stream not selected
195 // 1 - stream selected
196 void GetSelectedStreams (gint64 max_bitrate, gint8 streams [128]); // main thread only
198 void NotifyFinished (); // called by the MmsSource when we get the END packet for this entry. Main thread only.
202 * MmsDemuxer
204 class MmsDemuxer : public IMediaDemuxer {
205 private:
206 Playlist *playlist;
207 MmsSource *mms_source;
208 Mutex mutex;
210 protected:
211 virtual ~MmsDemuxer () {}
212 virtual MediaResult SeekInternal (guint64 pts);
214 virtual void GetFrameAsyncInternal (IMediaStream *stream);
215 virtual void OpenDemuxerAsyncInternal ();
216 virtual void SeekAsyncInternal (guint64 seekToTime);
217 virtual void SwitchMediaStreamAsyncInternal (IMediaStream *stream);
219 public:
220 MmsDemuxer (Media *media, MmsSource *source);
221 virtual void Dispose ();
223 virtual bool IsPlaylist () { return true; }
224 virtual Playlist *GetPlaylist () { return playlist; }
225 virtual const char *GetName () { return "MmsDemuxer"; }
229 * ASFDemuxer
231 class ASFDemuxer : public IMediaDemuxer {
232 private:
233 gint32 *stream_to_asf_index;
234 ASFReader *reader;
235 ASFParser *parser;
237 void ReadMarkers ();
238 MediaResult Open ();
240 static MediaResult GetFrameCallback (MediaClosure *closure);
242 protected:
243 virtual ~ASFDemuxer () {}
245 virtual void GetFrameAsyncInternal (IMediaStream *stream);
246 virtual void OpenDemuxerAsyncInternal ();
247 virtual void SeekAsyncInternal (guint64 seekToTime);
248 virtual void SwitchMediaStreamAsyncInternal (IMediaStream *stream);
250 public:
251 ASFDemuxer (Media *media, IMediaSource *source);
252 virtual void Dispose ();
254 virtual void UpdateSelected (IMediaStream *stream);
256 ASFParser *GetParser () { return parser; }
257 void SetParser (ASFParser *parser);
258 virtual const char *GetName () { return "ASFDemuxer"; }
260 IMediaStream *GetStreamOfASFIndex (gint32 asf_index);
264 * ASFDemuxerInfo
266 class ASFDemuxerInfo : public DemuxerInfo {
267 public:
268 virtual MediaResult Supports (IMediaSource *source);
269 virtual IMediaDemuxer *Create (Media *media, IMediaSource *source);
270 virtual const char *GetName () { return "ASFDemuxer"; }
274 * ASFMarkerDecoder
276 class ASFMarkerDecoder : public IMediaDecoder {
277 protected:
278 virtual ~ASFMarkerDecoder () {};
280 virtual void DecodeFrameAsyncInternal (MediaFrame *frame);
281 virtual void OpenDecoderAsyncInternal ();
283 public:
284 ASFMarkerDecoder (Media *media, IMediaStream *stream) ;
286 virtual const char *GetName () { return "ASFMarkerDecoder"; }
290 * ASFMarkerDecoderInfo
292 class ASFMarkerDecoderInfo : public DecoderInfo {
293 public:
294 virtual bool Supports (const char *codec);
295 virtual IMediaDecoder *Create (Media *media, IMediaStream *stream);
296 virtual const char *GetName ();
299 #endif