2009-11-13 Jeffrey Stedfast <fejj@novell.com>
[moon.git] / src / pipeline-asf.h
blob59eb973a8f086dc41811092a21d4dab890a08146
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
179 IMediaDemuxer *GetDemuxerReffed (); // thread safe
181 ASFPacket *Pop (); // thread safe
182 void WritePacket (void *buf, gint32 n); // main thread
184 void AddEntry (); // main thread
186 void SetPlaylistGenId (const char *value); // thread safe
187 char *GetPlaylistGenId (); // thread safe, returns a duped string, must be freed with g_free
188 void SetBroadcastId (const char *value); // thread safe
189 char *GetBroadcastId (); // thread safe, returns a duped string, must be freed with g_free
190 void SetHttpStreamingFeatures (HttpStreamingFeatures value); // thread safe
191 HttpStreamingFeatures GetHttpStreamingFeatures (); // thread safe
193 // fills in each entry of the array with:
194 // -1 - stream does not exist
195 // 0 - stream not selected
196 // 1 - stream selected
197 void GetSelectedStreams (gint64 max_bitrate, gint8 streams [128]); // main thread only
199 void NotifyFinished (); // called by the MmsSource when we get the END packet for this entry. Main thread only.
203 * MmsDemuxer
205 class MmsDemuxer : public IMediaDemuxer {
206 private:
207 Playlist *playlist;
208 MmsSource *mms_source;
209 Mutex mutex;
211 protected:
212 virtual ~MmsDemuxer () {}
213 virtual MediaResult SeekInternal (guint64 pts);
215 virtual void GetFrameAsyncInternal (IMediaStream *stream);
216 virtual void OpenDemuxerAsyncInternal ();
217 virtual void SeekAsyncInternal (guint64 seekToTime);
218 virtual void SwitchMediaStreamAsyncInternal (IMediaStream *stream);
220 public:
221 MmsDemuxer (Media *media, MmsSource *source);
222 virtual void Dispose ();
224 virtual bool IsPlaylist () { return true; }
225 virtual Playlist *GetPlaylist () { return playlist; }
226 virtual const char *GetName () { return "MmsDemuxer"; }
230 * ASFDemuxer
232 class ASFDemuxer : public IMediaDemuxer {
233 private:
234 gint32 *stream_to_asf_index;
235 ASFReader *reader;
236 ASFParser *parser;
238 void ReadMarkers ();
239 MediaResult Open ();
241 static MediaResult GetFrameCallback (MediaClosure *closure);
243 protected:
244 virtual ~ASFDemuxer () {}
246 virtual void GetFrameAsyncInternal (IMediaStream *stream);
247 virtual void OpenDemuxerAsyncInternal ();
248 virtual void SeekAsyncInternal (guint64 seekToTime);
249 virtual void SwitchMediaStreamAsyncInternal (IMediaStream *stream);
251 public:
252 ASFDemuxer (Media *media, IMediaSource *source);
253 virtual void Dispose ();
255 virtual void UpdateSelected (IMediaStream *stream);
257 ASFParser *GetParser () { return parser; }
258 void SetParser (ASFParser *parser);
259 virtual const char *GetName () { return "ASFDemuxer"; }
261 IMediaStream *GetStreamOfASFIndex (gint32 asf_index);
265 * ASFDemuxerInfo
267 class ASFDemuxerInfo : public DemuxerInfo {
268 public:
269 virtual MediaResult Supports (IMediaSource *source);
270 virtual IMediaDemuxer *Create (Media *media, IMediaSource *source);
271 virtual const char *GetName () { return "ASFDemuxer"; }
275 * ASFMarkerDecoder
277 class ASFMarkerDecoder : public IMediaDecoder {
278 protected:
279 virtual ~ASFMarkerDecoder () {};
281 virtual void DecodeFrameAsyncInternal (MediaFrame *frame);
282 virtual void OpenDecoderAsyncInternal ();
284 public:
285 ASFMarkerDecoder (Media *media, IMediaStream *stream) ;
287 virtual const char *GetName () { return "ASFMarkerDecoder"; }
291 * ASFMarkerDecoderInfo
293 class ASFMarkerDecoderInfo : public DecoderInfo {
294 public:
295 virtual bool Supports (const char *codec);
296 virtual IMediaDecoder *Create (Media *media, IMediaStream *stream);
297 virtual const char *GetName ();
300 #endif