1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
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.
13 #ifndef __PLAYLIST_H__
14 #define __PLAYLIST_H__
24 #include "dependencyobject.h"
48 StartMarker
= 1 << 15,
58 PlaylistKind (const char *str
, Kind kind
)
65 class PlaylistNode
: public List::Node
{
70 PlaylistNode (PlaylistEntry
*entry
);
71 virtual ~PlaylistNode ();
72 PlaylistEntry
*GetEntry () { return entry
; }
75 class PlaylistEntry
: public EventObject
{
91 PlaylistKind::Kind set_values
;
94 char *full_source_name
;
96 bool play_when_available
;
99 bool opened
; // if OpenCompleted event has been received
101 void Init (Playlist
*parent
);
102 void OpenMediaPlayer ();
105 PlaylistEntry (Type::Kind kind
);
106 PlaylistEntry (Type::Kind kind
, Playlist
*parent
);
107 virtual ~PlaylistEntry () {}
110 PlaylistEntry (Playlist
*parent
);
112 void Initialize (Media
*media
);
113 void InitializeWithUri (const char *uri
);
114 void InitializeWithDownloader (Downloader
*dl
, const char *PartName
);
115 void InitializeWithDemuxer (IMediaDemuxer
*demuxer
);
116 void InitializeWithStream (ManagedStreamCallbacks
*callbacks
);
117 void InitializeWithSource (IMediaSource
*source
);
119 Media
* CreateMedia ();
121 virtual void Dispose ();
126 Uri
*GetBaseInherited ();
127 void SetBase (Uri
*base
);
129 const char *GetTitle ();
130 void SetTitle (const char *title
);
132 const char *GetAuthor ();
133 void SetAuthor (const char *author
);
135 const char *GetAbstract ();
136 void SetAbstract (const char *abstract
);
138 const char *GetCopyright ();
139 void SetCopyright (const char *copyright
);
141 Uri
*GetSourceName ();
142 void SetSourceName (Uri
*source_name
);
144 TimeSpan
GetStartTime ();
145 void SetStartTime (TimeSpan start_time
);
147 Duration
*GetDuration ();
148 Duration
*GetInheritedDuration ();
149 void SetDuration (Duration
*duration
);
150 bool HasDuration () { return (set_values
& PlaylistKind::Duration
); }
151 bool HasInheritedDuration ();
153 const char *GetInfoTarget ();
154 void SetInfoTarget (const char *info_target
);
156 const char *GetInfoURL ();
157 void SetInfoURL (const char *info_url
);
159 bool GetClientSkip ();
160 void SetClientSkip (bool value
);
162 void AddParams (const char *name
, const char *value
);
164 // non-ASX properties
166 Playlist
*GetParent () { return parent
; }
167 void SetParent (Playlist
*value
) { parent
= value
; }
168 PlaylistRoot
*GetRoot ();
173 virtual MediaElement
*GetElement ();
174 MediaPlayer
*GetMediaPlayer ();
176 const char *GetFullSourceName ();
177 virtual bool IsPlaylist () { return false; }
179 bool GetIsLive () { return is_live
; }
180 void SetIsLive (bool value
) { is_live
= value
; }
184 virtual void Play ();
185 virtual void Pause ();
186 virtual void Stop ();
187 virtual void Seek (guint64 pts
);
188 virtual void Open ();
189 virtual void PopulateMediaAttributes ();
191 virtual PlaylistEntry
*GetCurrentPlaylistEntry () { return this; }
192 virtual bool IsSingleFile ();
194 void Print (int depth
);
196 EVENTHANDLER (PlaylistEntry
, Opening
, Media
, EventArgs
);
197 EVENTHANDLER (PlaylistEntry
, OpenCompleted
, Media
, EventArgs
);
198 EVENTHANDLER (PlaylistEntry
, Seeking
, Media
, EventArgs
);
199 EVENTHANDLER (PlaylistEntry
, SeekCompleted
, Media
, EventArgs
);
200 EVENTHANDLER (PlaylistEntry
, CurrentStateChanged
, Media
, EventArgs
);
201 EVENTHANDLER (PlaylistEntry
, MediaError
, Media
, ErrorEventArgs
);
202 EVENTHANDLER (PlaylistEntry
, DownloadProgressChanged
, Media
, EventArgs
);
203 EVENTHANDLER (PlaylistEntry
, BufferingProgressChanged
, Media
, EventArgs
);
206 virtual void DumpInternal (int tabs
);
210 class Playlist
: public PlaylistEntry
{
213 PlaylistNode
*current_node
;
214 IMediaSource
*source
;
221 bool HasMediaSource ();
222 void OnMediaDownloaded ();
224 void MergeWith (PlaylistEntry
*entry
);
225 bool PlayNext (); // returns false if nothing more to play
228 Playlist (Type::Kind kind
);
229 virtual ~Playlist () {}
233 Playlist (Playlist
*parent
, IMediaSource
*source
);
235 virtual void Dispose ();
237 virtual void Play ();
238 virtual void Pause ();
239 virtual void Stop ();
240 virtual void Seek (guint64 to
);
241 virtual void Open ();
242 virtual void PopulateMediaAttributes ();
244 virtual void AddEntry (PlaylistEntry
*entry
);
246 PlaylistEntry
*GetCurrentEntry () { return current_node
? current_node
->GetEntry () : NULL
; }
247 virtual PlaylistEntry
*GetCurrentPlaylistEntry ();
248 bool ReplaceCurrentEntry (Playlist
*entry
);
250 virtual bool IsPlaylist () { return true; }
251 virtual bool IsSingleFile () { return is_single_file
; }
252 void SetWaiting (bool value
) { waiting
= value
; }
253 bool GetWaiting (void) { return waiting
; }
255 bool IsCurrentEntryLastEntry ();
256 void OnEntryEnded ();
257 void OnEntryFailed (ErrorEventArgs
*args
);
259 void Print (int depth
);
261 gint32
GetCount () { return entries
? entries
->Length () : 0; }
264 virtual void DumpInternal (int tabs
);
268 class PlaylistRoot
: public Playlist
{
270 MediaElement
*element
;
271 MediaPlayer
*mplayer
;
273 guint64 seek_pts
; // the pts to seek to when SeekCallback is called.
275 static void EmitBufferUnderflowEvent (EventObject
*obj
);
276 static void StopCallback (EventObject
*obj
);
277 static void PlayCallback (EventObject
*obj
);
278 static void PauseCallback (EventObject
*obj
);
279 static void OpenCallback (EventObject
*obj
);
280 static void SeekCallback (EventObject
*obj
);
283 virtual ~PlaylistRoot () {}
285 virtual void Stop ();
288 PlaylistRoot (MediaElement
*element
);
289 virtual void Dispose (); // not thread-safe
290 virtual MediaElement
*GetElement ();
296 void SeekAsync (guint64 pts
);
298 virtual bool IsSingleFile ();
300 Media
*GetCurrentMedia ();
301 MediaPlayer
*GetMediaPlayer ();
304 const static int OpeningEvent
;
305 const static int OpenCompletedEvent
;
306 const static int SeekingEvent
;
307 const static int SeekCompletedEvent
;
308 const static int CurrentStateChangedEvent
;
309 const static int PlayEvent
;
310 const static int PauseEvent
;
311 const static int StopEvent
;
312 const static int MediaErrorEvent
;
313 const static int MediaEndedEvent
;
314 const static int DownloadProgressChangedEvent
;
315 const static int BufferingProgressChangedEvent
;
316 const static int BufferUnderflowEvent
;
317 const static int EntryChangedEvent
;
320 EVENTHANDLER (PlaylistRoot
, MediaEnded
, MediaPlayer
, EventArgs
);
321 EVENTHANDLER (PlaylistRoot
, BufferUnderflow
, MediaPlayer
, EventArgs
);
328 class PlaylistParserInternal
{
334 PlaylistParserInternal ();
335 ~PlaylistParserInternal ();
338 class PlaylistParser
{
342 PlaylistEntry
*current_entry
;
343 PlaylistParserInternal
*internal
;
344 IMediaSource
*source
;
346 ErrorEventArgs
*error_args
;
347 // For <ASX* files, this is 3 (or 0 if no version attribute was found).
348 // for [Ref* files, this is 2.
349 // The presence of a version does not guarantee that the playlist
350 // was parsed correctly.
351 int playlist_version
;
361 class KindNode
: public List::Node
{
363 PlaylistKind::Kind kind
;
365 KindNode (PlaylistKind::Kind kind
)
371 static PlaylistKind playlist_kinds
[];
374 void OnASXStartElement (const char *name
, const char **attrs
);
375 void OnASXEndElement (const char *name
);
376 void OnASXText (const char *text
, int len
);
378 static void on_asx_start_element (gpointer user_data
, const char *name
, const char **attrs
);
379 static void on_asx_end_element (gpointer user_data
, const char *name
);
380 static void on_asx_text (gpointer user_data
, const char *text
, int len
);
383 PlaylistEntry
*GetCurrentEntry ();
385 PlaylistEntry
*GetCurrentContent ();
387 void PushCurrentKind (PlaylistKind::Kind kind
);
388 void PopCurrentKind ();
389 PlaylistKind::Kind
GetCurrentKind ();
390 PlaylistKind::Kind
GetParentKind ();
391 bool AssertParentKind (int kind
);
393 void Setup (XmlType type
);
395 void SetSource (IMediaSource
*source
);
396 bool TryFixError (gint8
*buffer
, int bytes_read
);
399 PlaylistParser (PlaylistRoot
*root
, IMediaSource
*source
);
402 Playlist
*GetPlaylist () { return playlist
; }
404 MediaResult
Parse ();
407 static bool Is (IMediaSource
*source
, const char *header
);
408 static bool IsASX2 (IMediaSource
*source
);
409 static bool IsASX3 (IMediaSource
*source
);
411 // This value determines if the data we parsed
412 // actually was a playlist. It may be true even
413 // if the playlist wasn't parsed correctly.
414 bool WasPlaylist () { return was_playlist
; }
415 void ParsingError (ErrorEventArgs
*args
= NULL
);
417 ErrorEventArgs
*GetErrorEventArgs () { return error_args
; }
419 static PlaylistKind::Kind
StringToKind (const char *str
);
420 static const char *KindToString (PlaylistKind::Kind kind
);
423 #endif /* __PLAYLIST_H__ */