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_MEDIAPLAYER_H__
14 #define __MOON_MEDIAPLAYER_H__
23 class MediaPlayer
: public EventObject
{
26 // These are not flags, but mutually exclusive states.
32 // If we're waiting for a frame to show immediately
33 LoadFramePending
= (1 << 5),
34 // after seeking, we don't want to show any frames until the video has synced with
35 // the audio. Since the video seeks to key frames, and there can be several seconds
36 // between key frames, after seeking we will decode video as fast as possible to
37 // catch up with the audio.
38 SeekSynched
= (1 << 6),
39 RenderedFrame
= (1 << 7),
43 // If we should stop playing when we reach the duration
44 // Used to support the Duration tag in asx files.
45 FixedDuration
= (1 << 12),
46 // If Audio/Video has finished playing
47 AudioEnded
= (1 << 13),
48 VideoEnded
= (1 << 14),
49 BufferUnderflow
= (1 << 15),
54 // Some instance variables can be accessed from multiple threads.
55 // This mutex must be locked while these variables are accessed from
58 AudioSource
*audio_unlocked
; // mutex must be locked.
59 VideoStream
*video_stream
;
61 cairo_surface_t
*surface
;
65 gint32 seeks
; // the count of pending seeks. write on main thread only.
67 MediaElement
*element
;
69 PlayerState state_unlocked
; // mutex must be locked
72 MoonPixelFormat format
;
73 int audio_stream_count
;
74 int advance_frame_timeout_id
;
77 guint64 start_time
; // 100-nanosecond units (pts)
78 guint64 duration
; // 100-nanosecond units (pts)
79 // This is the first pts with live streams (when the first pts might not be 0).
80 guint64 first_live_pts
; // 100-nanosecond units (pts)
81 // This is the pts we start playing (0 is still the first pts in the media).
82 guint64 start_pts
; // 100-nanosecond units (pts)
83 guint64 current_pts
; // 100-nanosecond units (pts)
84 guint64 target_pts
; // 100-nanosecond units (pts)
86 // These variables are used to implement RenderedFramesPerSecond and DroppedFramesPerSecond
87 guint64 frames_update_timestamp
;
88 guint32 dropped_frames
;
89 guint32 rendered_frames
;
90 double rendered_frames_per_second
;
91 double dropped_frames_per_second
;
93 static void LoadVideoFrameCallback (EventObject
*object
);
94 void LoadVideoFrame ();
96 void CheckFinished ();
98 void RenderFrame (MediaFrame
*frame
);
100 EVENTHANDLER (MediaPlayer
, SeekCompleted
, Media
, EventArgs
); // Not thread-safe
101 EVENTHANDLER (MediaPlayer
, FirstFrameEnqueued
, EventObject
, EventArgs
); // Not thread-safe
104 static void AudioFinishedCallback (EventObject
*user_data
);
106 void SetVideoBufferSize (gint32 height
, gint32 width
);
107 void SetTimeout (gint32 interval
/* set to 0 to clear */);
108 void AdvanceFrame ();
109 static gboolean
AdvanceFrameCallback (void *user_data
);
111 void EmitBufferUnderflow ();
112 static void EmitBufferUnderflowAsync (EventObject
*obj
);
114 void StopAudio (); // Not thread-safe
116 virtual ~MediaPlayer ();
119 MediaPlayer (MediaElement
*element
);
120 virtual void Dispose ();
122 bool Open (Media
*media
, PlaylistEntry
*entry
);
126 // Returns a refcounted AudioStream.
127 // Caller must call unref when done with it.
128 AudioSource
*GetAudio ();
130 bool IsPlaying (); // thread safe
131 bool IsPaused (); // thread safe
132 bool IsStopped (); // thread safe
133 bool IsSeeking (); // thread safe
134 bool IsLoadFramePending (); // thread safe
135 bool IsBufferUnderflow (); // thread safe
137 bool HasRenderedFrame (); // thread safe
138 void VideoFinished (); // not thread safe.
140 void AudioFinished (); // Called by the audio player when audio reaches the end
142 void AudioFailed (AudioSource
*source
); // Called by the audio engine if audio failed to load (async)
144 void SetBit (PlayerState s
); // thread safe
145 void RemoveBit (PlayerState s
); // thread safe
146 void SetBitTo (PlayerState s
, bool value
); // thread safe
147 bool GetBit (PlayerState s
); // thread safe
148 void SetState (PlayerState s
); // thread safe
149 PlayerState
GetState (); // thread safe
151 void SetBufferUnderflow (); // thread safe
152 void SetAudioStreamIndex (gint32 i
);
156 void SetCanPause (bool value
);
160 void SetCanSeek (bool value
);
162 void NotifySeek (guint64 pts
/* 100-nanosecond units (pts) */);
164 virtual void SetSurface (Surface
*surface
);
166 cairo_surface_t
*GetCairoSurface () { return surface
; }
167 gint32
GetTimeoutInterval ();
169 int GetAudioStreamCount () { return audio_stream_count
; }
170 Media
*GetMedia () { return media
; }
172 bool HasVideo () { return video_stream
!= NULL
; }
173 // We may go from having audio to not having audio at any time
174 // (async - this function may return true, but by the time it
175 // returns we don't have audio anymore).
176 bool HasAudio () { return audio_unlocked
!= NULL
; }
178 guint64
GetPosition () { return GetTargetPts (); }
179 guint64
GetDuration () { return duration
; }
181 double GetDroppedFramesPerSecond () { return dropped_frames_per_second
; }
182 double GetRenderedFramesPerSecond () { return rendered_frames_per_second
; }
184 void SetMuted (bool muted
);
187 gint32
GetVideoHeight () { return height
; }
188 gint32
GetVideoWidth () { return width
; }
190 double GetBalance ();
191 void SetBalance (double balance
);
194 void SetVolume (double volume
);
196 guint64
GetTargetPts ();
198 const static int MediaEndedEvent
; // This is raised when both audio and video has finished (or either one if not both are present).
199 const static int BufferUnderflowEvent
;
202 #endif /* __MOON_MPLAYER_H__ */