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 /* @Namespace=None,ManagedEvents=Manual */
269 class PlaylistRoot
: public Playlist
{
271 class PtsNode
: public List::Node
{
274 PtsNode (guint64 pts
)
279 MediaElement
*element
;
280 MediaPlayer
*mplayer
;
282 List seeks
; // the pts to seek to when SeekCallback is called. Main thread only.
284 static void EmitBufferUnderflowEvent (EventObject
*obj
);
285 static void StopCallback (EventObject
*obj
);
286 static void PlayCallback (EventObject
*obj
);
287 static void PauseCallback (EventObject
*obj
);
288 static void OpenCallback (EventObject
*obj
);
289 static void SeekCallback (EventObject
*obj
);
292 virtual ~PlaylistRoot () {}
294 virtual void Stop ();
297 PlaylistRoot (MediaElement
*element
);
298 virtual void Dispose (); // not thread-safe
299 virtual MediaElement
*GetElement ();
305 void SeekAsync (guint64 pts
);
307 virtual bool IsSingleFile ();
309 Media
*GetCurrentMedia ();
310 MediaPlayer
*GetMediaPlayer ();
313 const static int OpeningEvent
;
314 const static int OpenCompletedEvent
;
315 const static int SeekingEvent
;
316 const static int SeekCompletedEvent
;
317 const static int CurrentStateChangedEvent
;
318 const static int PlayEvent
;
319 const static int PauseEvent
;
320 const static int StopEvent
;
321 const static int MediaErrorEvent
;
322 const static int MediaEndedEvent
;
323 const static int DownloadProgressChangedEvent
;
324 const static int BufferingProgressChangedEvent
;
325 const static int BufferUnderflowEvent
;
326 const static int EntryChangedEvent
;
329 EVENTHANDLER (PlaylistRoot
, MediaEnded
, MediaPlayer
, EventArgs
);
330 EVENTHANDLER (PlaylistRoot
, BufferUnderflow
, MediaPlayer
, EventArgs
);
337 class PlaylistParserInternal
{
343 PlaylistParserInternal ();
344 ~PlaylistParserInternal ();
347 class PlaylistParser
{
351 PlaylistEntry
*current_entry
;
352 PlaylistParserInternal
*internal
;
353 IMediaSource
*source
;
355 ErrorEventArgs
*error_args
;
356 // For <ASX* files, this is 3 (or 0 if no version attribute was found).
357 // for [Ref* files, this is 2.
358 // The presence of a version does not guarantee that the playlist
359 // was parsed correctly.
360 int playlist_version
;
370 class KindNode
: public List::Node
{
372 PlaylistKind::Kind kind
;
374 KindNode (PlaylistKind::Kind kind
)
380 static PlaylistKind playlist_kinds
[];
383 void OnASXStartElement (const char *name
, const char **attrs
);
384 void OnASXEndElement (const char *name
);
385 void OnASXText (const char *text
, int len
);
387 static void on_asx_start_element (gpointer user_data
, const char *name
, const char **attrs
);
388 static void on_asx_end_element (gpointer user_data
, const char *name
);
389 static void on_asx_text (gpointer user_data
, const char *text
, int len
);
392 PlaylistEntry
*GetCurrentEntry ();
394 PlaylistEntry
*GetCurrentContent ();
396 void PushCurrentKind (PlaylistKind::Kind kind
);
397 void PopCurrentKind ();
398 PlaylistKind::Kind
GetCurrentKind ();
399 PlaylistKind::Kind
GetParentKind ();
400 bool AssertParentKind (int kind
);
402 void Setup (XmlType type
);
404 void SetSource (IMediaSource
*source
);
405 bool TryFixError (gint8
*buffer
, int bytes_read
, int total_bytes_read
);
408 PlaylistParser (PlaylistRoot
*root
, IMediaSource
*source
);
411 Playlist
*GetPlaylist () { return playlist
; }
413 MediaResult
Parse ();
416 static bool Is (IMediaSource
*source
, const char *header
);
417 static bool IsASX2 (IMediaSource
*source
);
418 static bool IsASX3 (IMediaSource
*source
);
420 // This value determines if the data we parsed
421 // actually was a playlist. It may be true even
422 // if the playlist wasn't parsed correctly.
423 bool WasPlaylist () { return was_playlist
; }
424 void ParsingError (ErrorEventArgs
*args
= NULL
);
426 ErrorEventArgs
*GetErrorEventArgs () { return error_args
; }
428 static PlaylistKind::Kind
StringToKind (const char *str
);
429 static const char *KindToString (PlaylistKind::Kind kind
);
432 #endif /* __PLAYLIST_H__ */