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 __MOON_MEDIAELEMENT_H__
14
#define __MOON_MEDIAELEMENT_H__
17
#include <gdk/gdkpixbuf.h>
19
#include "mediaplayer.h"
22
#include "frameworkelement.h"
27
class MediaErrorEventArgs : public ErrorEventArgs {
29
virtual ~MediaErrorEventArgs () {}
32
MediaErrorEventArgs (MediaResult result, const char *msg)
33
: ErrorEventArgs (MediaError, (int) result, msg)
37
virtual Type::Kind GetObjectType () { return Type::MEDIAERROREVENTARGS; }
39
MediaResult GetMediaResult () { return (MediaResult) error_code; }
42
/* @Namespace=System.Windows.Controls */
43
class MediaElement : public MediaBase {
45
enum MediaElementState {
56
static void data_write (void *data, gint32 offset, gint32 n, void *closure);
57
static void data_request_position (gint64 *pos, void *closure);
58
static void size_notify (gint64 size, gpointer data);
60
TimelineMarkerCollection *streamed_markers;
61
Queue *pending_streamed_markers;
62
MediaClosure *marker_closure;
63
int advance_frame_timeout_id;
64
bool recalculate_matrix;
65
cairo_matrix_t matrix;
70
// When checking if a marker has been reached, we need to
71
// know the last time the check was made, to see if
72
// the marker's pts hit the region.
73
guint64 previous_position;
74
// When the position is changed by the client, we store the requested position
75
// here and do the actual seeking async. Note that we might get several seek requests
76
// before the actual seek is done, currently we just seek to the last position requested,
77
// the previous requests are ignored. -1 denotes that there are no pending seeks.
78
TimeSpan seek_to_position;
80
// Buffering can be caused by:
81
// [1] When the media is opened, we automatically buffer an amount equal to BufferingTime.
82
// - In this case we ask the pipeline how much it has buffered.
84
// [2] When during playback we realize that we don't have enough data.
85
// - In this case we ask the pipelien how much it has buffered.
87
// [3] When we seek, and realize that we don't have enough data.
88
// - In this case the buffering progress is calculated as:
89
// ("last available pts" - "last played pts") / ("seeked to pts" - "last played pts" + BufferingTime)
91
guint64 last_played_pts;
92
guint64 first_pts; // the first pts, starts off at GUINT_MAX
93
int buffering_mode; // if we're in [3] or not: 0 = unknown, 1 = [1], etc.
95
// this is used to know what to do after a Buffering state finishes
96
MediaElementState prev_state;
98
// The current state of the media element.
99
MediaElementState state;
103
// downloader methods/data
104
IMediaSource *downloaded_file;
106
void DataWrite (void *data, gint32 offset, gint32 n);
107
void DataRequestPosition (gint64 *pos);
108
virtual void DownloaderComplete ();
109
virtual void DownloaderFailed (EventArgs *args);
110
void BufferingComplete ();
111
double GetBufferedSize ();
112
double CalculateBufferingProgress ();
113
void UpdateProgress ();
115
virtual void OnLoaded ();
117
// Try to open the media (i.e. read the headers).
120
// Checks if the media was actually a playlist, in which case false is returned.
121
// Fill in all information from the opened media and raise MediaOpenedEvent. Does not change any state.
122
bool MediaOpened (Media *media);
123
void EmitMediaEnded ();
125
void CheckMarkers (guint64 from, guint64 to, TimelineMarkerCollection *col, bool remove);
126
void CheckMarkers (guint64 from, guint64 to);
129
TimeSpan UpdatePlayerPosition (TimeSpan position);
132
// Private Property Accessors
134
void SetAudioStreamCount (int count);
136
void SetBufferingProgress (double progress);
138
void SetCanPause (bool set);
139
void SetCanSeek (bool set);
141
// XXX NaturalDurationProperty only generates a getter because
142
// this setter doesn't take a Duration. why the disconnect?
143
void SetNaturalDuration (TimeSpan duration);
145
void SetNaturalVideoHeight (double height);
146
void SetNaturalVideoWidth (double width);
148
void PlayOrStopNow ();
153
static void PauseNow (EventObject *value);
154
static void PlayNow (EventObject *value);
155
static void StopNow (EventObject *value);
156
static void SeekNow (EventObject *value);
159
virtual DownloaderAccessPolicy GetDownloaderPolicy (const char *uri);
160
virtual ~MediaElement ();
164
/* @PropertyType=MediaAttributeCollection,ManagedPropertyType=Dictionary<string\,string>,ManagedSetterAccess=Internal,GenerateAccessors */
165
static DependencyProperty *AttributesProperty;
166
/* @PropertyType=gint32,DefaultValue=0,ReadOnly,GenerateAccessors */
167
static DependencyProperty *AudioStreamCountProperty;
168
/* @PropertyType=gint32,Nullable,GenerateAccessors */
169
static DependencyProperty *AudioStreamIndexProperty;
170
/* @PropertyType=bool,DefaultValue=true,GenerateAccessors */
171
static DependencyProperty *AutoPlayProperty;
172
/* @PropertyType=double,DefaultValue=0.0,GenerateAccessors */
173
static DependencyProperty *BalanceProperty;
174
/* @PropertyType=double,DefaultValue=0.0,ReadOnly,GenerateAccessors */
175
static DependencyProperty *BufferingProgressProperty;
176
/* @PropertyType=TimeSpan,DefaultValue="TimeSpan_FromSeconds (5)\,Type::TIMESPAN",GenerateAccessors */
177
static DependencyProperty *BufferingTimeProperty;
178
/* @PropertyType=bool,DefaultValue=false,ReadOnly,GenerateAccessors */
179
static DependencyProperty *CanPauseProperty;
180
/* @PropertyType=bool,DefaultValue=false,ReadOnly,GenerateAccessors */
181
static DependencyProperty *CanSeekProperty;
182
/* @PropertyType=string,ReadOnly,ManagedPropertyType=MediaElementState,GenerateAccessors */
183
static DependencyProperty *CurrentStateProperty;
184
/* @PropertyType=bool,DefaultValue=false,GenerateAccessors */
185
static DependencyProperty *IsMutedProperty;
186
/* @PropertyType=TimelineMarkerCollection,ManagedFieldAccess=Internal,ManagedSetterAccess=Internal,GenerateAccessors */
187
static DependencyProperty *MarkersProperty;
188
/* @PropertyType=Duration,DefaultValue=Duration::FromSeconds (0),ReadOnly,GenerateGetter */
189
static DependencyProperty *NaturalDurationProperty;
190
/* @PropertyType=double,DefaultValue=0.0,ReadOnly,ManagedPropertyType=int,GenerateAccessors */
191
static DependencyProperty *NaturalVideoHeightProperty;
192
/* @PropertyType=double,DefaultValue=0.0,ReadOnly,ManagedPropertyType=int,GenerateAccessors */
193
static DependencyProperty *NaturalVideoWidthProperty;
194
/* @PropertyType=TimeSpan,GenerateAccessors */
195
static DependencyProperty *PositionProperty;
196
/* @PropertyType=double,DefaultValue=0.5,GenerateAccessors */
197
static DependencyProperty *VolumeProperty;
201
const static int BufferingProgressChangedEvent;
202
const static int CurrentStateChangedEvent;
203
const static int MarkerReachedEvent;
204
const static int MediaEndedEvent;
205
const static int MediaFailedEvent;
206
// MediaOpened is raised when media is ready to play (we've already started playing, or, if AutoPlay is false, paused).
207
const static int MediaOpenedEvent;
209
/* @GenerateCBinding,GeneratePInvoke */
211
virtual Type::Kind GetObjectType () { return Type::MEDIAELEMENT; }
213
virtual void SetSurface (Surface *surface);
215
bool AdvanceFrame ();
216
// Called by MediaPlayer when the media reaches its end.
217
// For media with both video and audio this method is called
218
// after both have finished.
219
void MediaFinished ();
221
MediaPlayer *GetMediaPlayer () { return mplayer; }
224
virtual void Render (cairo_t *cr, Region *region);
225
virtual Point GetTransformOrigin ();
226
virtual Rect GetCoverageBounds ();
228
virtual Value *GetValue (DependencyProperty *prop);
229
virtual void OnPropertyChanged (PropertyChangedEventArgs *args);
231
virtual void SetSourceInternal (Downloader *downloader, char *PartName);
232
virtual void SetSource (Downloader *downloader, const char *PartName);
234
/* @GenerateCBinding,GeneratePInvoke,Version=2.0 */
235
void SetStreamSource (ManagedStreamCallbacks *stream);
237
/* @GenerateCBinding,GeneratePInvoke */
240
/* @GenerateCBinding,GeneratePInvoke */
243
/* @GenerateCBinding,GeneratePInvoke */
246
// These methods are the ones that actually call the appropiate methods on the MediaPlayer
247
void PlayInternal ();
248
//void PauseInternal ();
249
//void StopInternal ();
252
bool IsClosed () { return state == Closed; }
253
bool IsOpening () { return state == Opening; }
254
bool IsBuffering () { return state == Buffering; }
255
bool IsPlaying () { return state == Playing; }
256
bool IsPaused () { return state == Paused; }
257
bool IsStopped () { return state == Stopped; }
260
bool IsMissingCodecs ();
261
void EmitMediaOpened ();
262
void Reinitialize (bool dtor); // dtor is true if we're calling from the destructor.
264
pthread_mutex_t open_mutex; // Used when accessing closure.
265
MediaClosure *closure;
266
static void TryOpenFinished (EventObject *user_data);
267
void SetPlayRequested ();
269
// Reset all information to defaults, set state to 'Error' and raise MediaFailedEvent
270
void MediaFailed (ErrorEventArgs *args = NULL);
272
static const char *GetStateName (MediaElementState state);
274
MediaElementState GetState () { return state; }
275
void SetState (MediaElementState state);
277
Playlist *GetPlaylist () { return playlist; }
279
virtual bool EnableAntiAlias ();
281
void AddStreamedMarker (TimelineMarker *marker);
282
static void AddStreamedMarkersCallback (EventObject *obj);
283
void AddStreamedMarkers ();
284
void SetMedia (Media *media);
287
// Public Property Accessors
289
void SetAttributes (MediaAttributeCollection *attrs);
290
MediaAttributeCollection *GetAttributes ();
292
int GetAudioStreamCount ();
294
void SetAudioStreamIndex (gint32 index);
295
void SetAudioStreamIndex (gint32* index);
296
gint32* GetAudioStreamIndex ();
298
void SetAutoPlay (bool set);
301
void SetBalance (double balance);
302
double GetBalance ();
304
double GetBufferingProgress ();
306
void SetBufferingTime (TimeSpan time);
307
TimeSpan GetBufferingTime ();
312
void SetCurrentState (const char *state);
313
const char *GetCurrentState ();
315
void SetIsMuted (bool set);
318
void SetMarkers (TimelineMarkerCollection *markers);
319
TimelineMarkerCollection *GetMarkers ();
321
Duration *GetNaturalDuration ();
322
double GetNaturalVideoHeight ();
323
double GetNaturalVideoWidth ();
325
void SetPosition (TimeSpan position);
326
TimeSpan GetPosition ();
328
void SetVolume (double volume);
332
#endif /* __MEDIAELEMENT_H__ */