revert jeff's last commit since it breaks the build
[moon.git] / src / mediaelement.h
blob4d405fc0b00bd771e70146e52a77de74db14fdbf
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * mediaelement.h:
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.
13 #ifndef __MOON_MEDIAELEMENT_H__
14 #define __MOON_MEDIAELEMENT_H__
16 #include <glib.h>
17 #include <gdk/gdkpixbuf.h>
19 #include "value.h"
20 #include "frameworkelement.h"
21 #include "pipeline.h"
22 #include "downloader.h"
23 #include "mutex.h"
24 #include "enums.h"
26 /* @Namespace=System.Windows.Controls */
27 class MediaElement : public FrameworkElement {
28 friend class MediaElementPropertyValueProvider;
29 private:
30 Mutex mutex;
32 List *streamed_markers_queue; // Thread-safe: Accesses to this field needs to use the mutex.
33 TimelineMarkerCollection *streamed_markers; // Main thread only.
34 ErrorEventArgs *error_args; // Thread-safe: Accesses to this field needs to use the mutex.
35 MediaMarkerFoundClosure *marker_closure;
36 cairo_matrix_t matrix;
37 int quality_level; // higher number = better quality, starts out at 0.
38 guint64 last_quality_level_change_position; // the pts of the position the last time the quality changed. Used to not change quality too often.
39 MediaState detached_state;
41 MediaPlayer *mplayer;
42 PlaylistRoot *playlist;
44 //
45 guint32 marker_timeout;
46 // When checking if a marker has been reached, we need to
47 // know the last time the check was made, to see if
48 // the marker's pts hit the region.
49 guint64 previous_position;
50 // When the position is changed by the client, we store the requested position
51 // here and do the actual seeking async. Note that we might get several seek requests
52 // before the actual seek is done, currently we just seek to the last position requested,
53 // the previous requests are ignored. -1 denotes that there are no pending seeks.
54 TimeSpan seek_to_position;
55 // This is the last seeked to position. Used to never ever return a Position below this value.
56 guint64 seeked_to_position;
57 // This is the position when Pause is called. Since the actually Pause is done async, we must report
58 // this value as the current Position.
59 guint64 paused_position;
61 guint64 first_pts; // the first pts, starts off at GUINT_MAX
62 int buffering_mode; // if we're in [3] or not: 0 = unknown, 1 = [1], etc.
64 // this is used to know what to do after a Buffering state finishes
65 MediaState prev_state;
67 // The current state of the media element.
68 MediaState state;
70 guint32 flags;
72 void Reinitialize (); // not thread-safe
74 void SetMarkerTimeout (bool start); // not thread-safe
75 static gboolean MarkerTimeout (gpointer context); // not thread-safe
77 // Media event handlers
79 EVENTHANDLER (MediaElement, Opening, PlaylistRoot, EventArgs); // Not thread-safe
80 EVENTHANDLER (MediaElement, OpenCompleted, PlaylistRoot, EventArgs); // Not thread-safe
81 EVENTHANDLER (MediaElement, Seeking, PlaylistRoot, EventArgs); // Not thread-safe
82 EVENTHANDLER (MediaElement, SeekCompleted, PlaylistRoot, EventArgs); // Not thread-safe
83 EVENTHANDLER (MediaElement, Seek, PlaylistRoot, EventArgs); // Not thread-safe
84 EVENTHANDLER (MediaElement, CurrentStateChanged, PlaylistRoot, EventArgs); // Not thread-safe
85 EVENTHANDLER (MediaElement, MediaError, PlaylistRoot, ErrorEventArgs); // Not thread-safe
86 EVENTHANDLER (MediaElement, MediaEnded, PlaylistRoot, EventArgs); // Not thread-safe
87 EVENTHANDLER (MediaElement, DownloadProgressChanged, PlaylistRoot, EventArgs); // Not thread-safe
88 EVENTHANDLER (MediaElement, BufferingProgressChanged, PlaylistRoot, EventArgs); // Not thread-safe
89 EVENTHANDLER (MediaElement, Play, PlaylistRoot, EventArgs); // Not thread-safe
90 EVENTHANDLER (MediaElement, Pause, PlaylistRoot, EventArgs); // Not thread-safe
91 EVENTHANDLER (MediaElement, Stop, PlaylistRoot, EventArgs); // Not thread-safe
92 EVENTHANDLER (MediaElement, BufferUnderflow, PlaylistRoot, EventArgs); // Not thread-safe
93 EVENTHANDLER (MediaElement, EntryChanged, PlaylistRoot, EventArgs); // Not thread-safe
95 EVENTHANDLER (MediaElement, ShuttingDown, Deployment, EventArgs); // Not thread-safe
97 // Fill in information to/from the media, mediaplayer, etc.
98 // Does not change any state
99 void SetProperties (Media *media);
101 void EmitMediaEnded ();
102 void EmitStateChangedAsync ();
103 static void EmitStateChanged (EventObject *obj);
104 static void ReportErrorOccurredCallback (EventObject *obj);
106 void AddStreamedMarker (TimelineMarker *marker); // Thread-safe
107 void AddStreamedMarker (MediaMarker *marker); // Thread-safe
108 static MediaResult AddStreamedMarkerCallback (MediaClosure *closure); // Thread-safe
109 void CheckMarkers (guint64 from, guint64 to, TimelineMarkerCollection *col, bool remove); // Not thread-safe
110 void CheckMarkers (guint64 from, guint64 to); // Not thread-safe
111 void CheckMarkers (); // Not thread-safe
112 void ReadMarkers (Media *media, IMediaDemuxer *demuxer); // Not thread-safe
115 // Private Property Accessors
117 void SetAudioStreamCount (int count);
119 void SetBufferingProgress (double progress);
121 void SetCanPause (bool set);
122 void SetCanSeek (bool set);
124 void SetNaturalVideoHeight (int height);
125 void SetNaturalVideoWidth (int width);
127 void PlayOrStop (); // Not thread-safe. To the right thing if we can pause, if we have to autoplay, etc.
129 void CreatePlaylist ();
130 void SetPlaylist (PlaylistRoot *playlist); // Adds/removes event handlers
132 protected:
133 virtual ~MediaElement () {}
135 public:
136 /* @GenerateCBinding,GeneratePInvoke */
137 MediaElement ();
138 virtual void Dispose ();
140 // properties
141 /* @PropertyType=MediaAttributeCollection,ManagedPropertyType=Dictionary<string\,string>,AutoCreateValue,ManagedSetterAccess=Internal,GenerateAccessors,Validator=MediaAttributeCollectionValidator */
142 const static int AttributesProperty;
143 /* @PropertyType=gint32,DefaultValue=0,ReadOnly,GenerateAccessors */
144 const static int AudioStreamCountProperty;
145 /* @PropertyType=gint32,Nullable,GenerateAccessors,Validator=AudioStreamIndexValidator */
146 const static int AudioStreamIndexProperty;
147 /* @PropertyType=bool,DefaultValue=true,GenerateAccessors */
148 const static int AutoPlayProperty;
149 /* @PropertyType=double,DefaultValue=0.0,GenerateAccessors,Validator=BalanceValidator */
150 const static int BalanceProperty;
151 /* @PropertyType=double,DefaultValue=0.0,ReadOnly,GenerateAccessors */
152 const static int BufferingProgressProperty;
153 /* @PropertyType=TimeSpan,GenerateAccessors,Validator=BufferingTimeValidator */
154 const static int BufferingTimeProperty;
155 /* @PropertyType=bool,DefaultValue=false,ReadOnly,GenerateAccessors */
156 const static int CanPauseProperty;
157 /* @PropertyType=bool,DefaultValue=false,ReadOnly,GenerateAccessors */
158 const static int CanSeekProperty;
159 /* @PropertyType=double,ReadOnly,DefaultValue=0.0,GenerateAccessors */
160 const static int DownloadProgressProperty;
161 /* @PropertyType=MediaState,ReadOnly,ManagedPropertyType=MediaElementState,DefaultValue=MediaStateClosed,GenerateAccessors */
162 const static int CurrentStateProperty;
163 /* @PropertyType=bool,DefaultValue=false,GenerateAccessors */
164 const static int IsMutedProperty;
165 /* @PropertyType=TimelineMarkerCollection,AutoCreateValue,ManagedFieldAccess=Internal,ManagedSetterAccess=Internal,GenerateAccessors */
166 const static int MarkersProperty;
167 /* @PropertyType=Duration,DefaultValue=Duration::FromSeconds (0),ReadOnly,GenerateAccessors */
168 const static int NaturalDurationProperty;
169 /* @PropertyType=gint32,DefaultValue=0,ReadOnly,GenerateAccessors,Validator=IntGreaterThanZeroValidator */
170 const static int NaturalVideoHeightProperty;
171 /* @PropertyType=gint32,DefaultValue=0,ReadOnly,GenerateAccessors,Validator=IntGreaterThanZeroValidator */
172 const static int NaturalVideoWidthProperty;
173 /* @PropertyType=TimeSpan,AlwaysChange,GenerateAccessors */
174 const static int PositionProperty;
175 /* @PropertyType=Uri,AlwaysChange,ManagedPropertyType=Uri,Nullable,GenerateAccessors */
176 const static int SourceProperty;
177 /* @PropertyType=Stretch,DefaultValue=StretchUniform,GenerateAccessors */
178 const static int StretchProperty;
179 /* @PropertyType=double,DefaultValue=0.5,GenerateAccessors,Validator=VolumeValidator */
180 const static int VolumeProperty;
182 /* @PropertyType=double,DefaultValue=0.0,GenerateAccessors,ReadOnly */
183 const static int DownloadProgressOffsetProperty;
184 /* @PropertyType=double,DefaultValue=0.0,GenerateAccessors,ReadOnly */
185 const static int DroppedFramesPerSecondProperty;
186 /* @PropertyType=double,DefaultValue=0.0,GenerateAccessors,ReadOnly */
187 const static int RenderedFramesPerSecondProperty;
189 // events
190 /* @DelegateType=RoutedEventHandler */
191 const static int BufferingProgressChangedEvent;
192 /* @DelegateType=RoutedEventHandler */
193 const static int CurrentStateChangedEvent;
194 /* @DelegateType=RoutedEventHandler */
195 const static int DownloadProgressChangedEvent;
196 /* @DelegateType=TimelineMarkerRoutedEventHandler */
197 const static int MarkerReachedEvent;
198 /* @DelegateType=RoutedEventHandler */
199 const static int MediaEndedEvent;
200 /* @DelegateType=EventHandler<ExceptionRoutedEventArgs> */
201 const static int MediaFailedEvent;
202 // MediaOpened is raised when media is ready to play (we've already started playing, or, if AutoPlay is false, paused).
203 /* @DelegateType=RoutedEventHandler */
204 const static int MediaOpenedEvent;
205 /* @GenerateManagedEvent=false */
206 const static int MediaInvalidatedEvent;
207 /* @DelegateType=LogReadyRoutedEventHandler */
208 const static int LogReadyEvent;
210 virtual void SetIsAttached (bool value);
212 MediaPlayer *GetMediaPlayer () { return mplayer; }
214 // overrides
215 virtual void Render (cairo_t *cr, Region *region, bool path_only = false);
216 virtual Point GetTransformOrigin ();
218 virtual Rect GetCoverageBounds ();
219 virtual Size ComputeActualSize ();
220 virtual Size MeasureOverride (Size availableSize);
221 virtual Size ArrangeOverride (Size finalSize);
223 virtual void OnPropertyChanged (PropertyChangedEventArgs *args, MoonError *error);
225 void MediaInvalidate ();
227 void SetSource (Downloader *downloader, const char *PartName);
228 void SetUriSource (Uri *uri); // This is called from OnPropertyChanged
229 /* @GenerateCBinding,GeneratePInvoke,Version=2.0 */
230 void SetStreamSource (ManagedStreamCallbacks *stream);
231 /* @GenerateCBinding,GeneratePInvoke */
232 IMediaDemuxer *SetDemuxerSource (void *context, CloseDemuxerCallback close_demuxer, GetDiagnosticAsyncCallback get_diagnostic, GetFrameAsyncCallback get_sample, OpenDemuxerAsyncCallback open_demuxer, SeekAsyncCallback seek, SwitchMediaStreamAsyncCallback switch_media_stream);
234 /* @GenerateCBinding,GeneratePInvoke */
235 void Pause (); // Not thread-safe
237 /* @GenerateCBinding,GeneratePInvoke */
238 void Play (); // Not thread-safe
240 /* @GenerateCBinding,GeneratePInvoke */
241 void Stop (); // Not thread-safe
243 void Seek (TimeSpan to, bool force); // Not thread-safe.
245 void ReportErrorOccurred (ErrorEventArgs *args); // Thread safe
246 /* @GenerateCBinding,GeneratePInvoke */
247 void ReportErrorOccurred (const char *args); // Thread safe
249 // State methods
250 bool IsClosed () { return state == MediaStateClosed; }
251 bool IsOpening () { return state == MediaStateOpening; }
252 bool IsBuffering () { return state == MediaStateBuffering; }
253 bool IsPlaying () { return state == MediaStatePlaying; }
254 bool IsPaused () { return state == MediaStatePaused; }
255 bool IsStopped () { return state == MediaStateStopped; }
257 bool IsMissingCodecs (); // Not thread-safe
259 void SetPlayRequested (); // Not thread-safe
261 static const char *GetStateName (MediaState state); // Thread-safe
263 MediaState GetState () { return state; } // Thread-safe
264 MediaState GetDetachedState () { return detached_state; }
265 void SetState (MediaState state); // Thread-safe
267 virtual bool EnableAntiAlias ();
268 int GetQualityLevel (int min, int max); /* returns a quality level between min and max */
271 // Public Property Accessors
273 void SetAttributes (MediaAttributeCollection *attrs);
274 MediaAttributeCollection *GetAttributes ();
276 int GetAudioStreamCount ();
278 void SetAudioStreamIndex (gint32 index);
279 void SetAudioStreamIndex (gint32* index);
280 gint32* GetAudioStreamIndex ();
282 void SetAutoPlay (bool set);
283 bool GetAutoPlay ();
285 void SetBalance (double balance);
286 double GetBalance ();
288 double GetBufferingProgress ();
290 void SetBufferingTime (TimeSpan time);
291 TimeSpan GetBufferingTime ();
293 bool GetCanPause ();
294 bool GetCanSeek ();
296 void SetCurrentState (MediaState state);
297 MediaState GetCurrentState ();
299 void SetIsMuted (bool set);
300 bool GetIsMuted ();
302 void SetMarkers (TimelineMarkerCollection *markers);
303 TimelineMarkerCollection *GetMarkers ();
305 void SetNaturalDuration (Duration *duration);
306 Duration *GetNaturalDuration ();
308 int GetNaturalVideoHeight ();
309 int GetNaturalVideoWidth ();
311 void SetPosition (TimeSpan position);
312 TimeSpan GetPosition ();
314 void SetVolume (double volume);
315 double GetVolume ();
317 void SetDownloadProgressOffset (double value);
318 double GetDownloadProgressOffset ();
320 void SetRenderedFramesPerSecond (double value);
321 double GetRenderedFramesPerSecond ();
323 void SetDroppedFramesPerSecond (double value);
324 double GetDroppedFramesPerSecond ();
326 double GetDownloadProgress ();
327 void SetDownloadProgress (double progress);
329 void SetSource (Uri *uri);
330 void SetSource (Uri uri);
331 Uri *GetSource ();
333 void SetStretch (Stretch stretch);
334 Stretch GetStretch ();
338 * MediaElementPropertyValueProvider
341 class MediaElementPropertyValueProvider : public FrameworkElementProvider {
342 private:
343 Value *position;
344 Value *current_state;
345 Value *rendered_frames_per_second;
346 Value *dropped_frames_per_second;
348 Value *GetPosition ();
349 Value *GetCurrentState ();
350 Value *GetRenderedFramesPerSecond ();
351 Value *GetDroppedFramesPerSecond ();
352 public:
353 MediaElementPropertyValueProvider (MediaElement *obj, PropertyPrecedence precedence);
354 virtual ~MediaElementPropertyValueProvider ();
355 virtual Value *GetPropertyValue (DependencyProperty *property);
358 #endif /* __MEDIAELEMENT_H__ */