2009-12-03 Jeffrey Stedfast <fejj@novell.com>
[moon.git] / src / mediaplayer.h
blobda5caabe4faf057ac503a77e44904f60c5f373ba
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * mplayer.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_MEDIAPLAYER_H__
14 #define __MOON_MEDIAPLAYER_H__
16 #include <glib.h>
17 #include <cairo.h>
19 #include "pipeline.h"
20 #include "audio.h"
21 #include "mutex.h"
23 /* @Namespace=None,ManagedEvents=Manual */
24 class MediaPlayer : public EventObject {
25 public:
26 enum PlayerState {
27 // These are not flags, but mutually exclusive states.
28 Stopped = 0,
29 Paused = 1,
30 Playing = 2,
31 StateMask = 3,
33 // If we're waiting for a frame to show immediately
34 LoadFramePending = (1 << 5),
35 // after seeking, we don't want to show any frames until the video has synced with
36 // the audio. Since the video seeks to key frames, and there can be several seconds
37 // between key frames, after seeking we will decode video as fast as possible to
38 // catch up with the audio.
39 SeekSynched = (1 << 6),
40 RenderedFrame = (1 << 7),
41 Opened = (1 << 9),
42 CanSeek = (1 << 10),
43 CanPause = (1 << 11),
44 // If we should stop playing when we reach the duration
45 // Used to support the Duration tag in asx files.
46 FixedDuration = (1 << 12),
47 // If Audio/Video has finished playing
48 AudioEnded = (1 << 13),
49 VideoEnded = (1 << 14),
50 BufferUnderflow = (1 << 15),
51 IsLive = (1 << 16),
54 private:
55 // Some instance variables can be accessed from multiple threads.
56 // This mutex must be locked while these variables are accessed from
57 // any thread.
58 Mutex mutex;
59 AudioSource *audio_unlocked; // mutex must be locked.
60 VideoStream *video_stream;
61 // rendering
62 cairo_surface_t *surface;
63 guint8 *rgb_buffer;
64 gint32 buffer_width;
65 gint32 buffer_height;
66 gint32 seeks; // the count of pending seeks. write on main thread only.
68 MediaElement *element;
69 Media *media;
70 PlayerState state_unlocked; // mutex must be locked
71 gint32 height;
72 gint32 width;
73 MoonPixelFormat format;
74 int audio_stream_count;
75 int advance_frame_timeout_id;
77 // sync
78 guint64 start_time; // 100-nanosecond units (pts)
79 guint64 duration; // 100-nanosecond units (pts)
80 // This is the first pts with live streams (when the first pts might not be 0).
81 guint64 first_live_pts; // 100-nanosecond units (pts)
82 // This is the pts we start playing (0 is still the first pts in the media).
83 guint64 start_pts; // 100-nanosecond units (pts)
84 guint64 current_pts; // 100-nanosecond units (pts)
85 guint64 target_pts; // 100-nanosecond units (pts)
87 // These variables are used to implement RenderedFramesPerSecond and DroppedFramesPerSecond
88 guint64 frames_update_timestamp;
89 guint32 dropped_frames;
90 guint32 rendered_frames;
91 double rendered_frames_per_second;
92 double dropped_frames_per_second;
94 static void LoadVideoFrameCallback (EventObject *object);
95 void LoadVideoFrame ();
96 void Initialize ();
97 void CheckFinished ();
99 void RenderFrame (MediaFrame *frame);
101 EVENTHANDLER (MediaPlayer, SeekCompleted, Media, EventArgs); // Not thread-safe
102 EVENTHANDLER (MediaPlayer, FirstFrameEnqueued, EventObject, EventArgs); // Not thread-safe
104 // Thread-safe
105 static void AudioFinishedCallback (EventObject *user_data);
107 void SetVideoBufferSize (gint32 height, gint32 width);
108 void SetTimeout (gint32 interval /* set to 0 to clear */);
109 void AdvanceFrame ();
110 static gboolean AdvanceFrameCallback (void *user_data);
112 void EmitBufferUnderflow ();
113 static void EmitBufferUnderflowAsync (EventObject *obj);
115 void StopAudio (); // Not thread-safe
116 protected:
117 virtual ~MediaPlayer ();
119 public:
120 MediaPlayer (MediaElement *element);
121 virtual void Dispose ();
123 bool Open (Media *media, PlaylistEntry *entry);
124 void Close ();
126 // Thread-safe.
127 // Returns a refcounted AudioStream.
128 // Caller must call unref when done with it.
129 AudioSource *GetAudio ();
131 bool IsPlaying (); // thread safe
132 bool IsPaused (); // thread safe
133 bool IsStopped (); // thread safe
134 bool IsSeeking (); // thread safe
135 bool IsLoadFramePending (); // thread safe
136 bool IsBufferUnderflow (); // thread safe
138 bool HasRenderedFrame (); // thread safe
139 void VideoFinished (); // not thread safe.
140 // Thread-safe
141 void AudioFinished (); // Called by the audio player when audio reaches the end
142 // Thread-safe
143 void AudioFailed (AudioSource *source); // Called by the audio engine if audio failed to load (async)
145 void SetBit (PlayerState s); // thread safe
146 void RemoveBit (PlayerState s); // thread safe
147 void SetBitTo (PlayerState s, bool value); // thread safe
148 bool GetBit (PlayerState s); // thread safe
149 void SetState (PlayerState s); // thread safe
150 PlayerState GetState (); // thread safe
152 void SetBufferUnderflow (); // thread safe
153 void SetAudioStreamIndex (gint32 i);
155 void Play ();
156 bool GetCanPause ();
157 void SetCanPause (bool value);
158 void Pause ();
159 void Stop ();
161 void SetCanSeek (bool value);
162 bool GetCanSeek ();
163 void NotifySeek (guint64 pts /* 100-nanosecond units (pts) */);
165 cairo_surface_t *GetCairoSurface () { return surface; }
166 gint32 GetTimeoutInterval ();
168 int GetAudioStreamCount () { return audio_stream_count; }
169 Media *GetMedia () { return media; }
171 bool HasVideo () { return video_stream != NULL; }
172 // We may go from having audio to not having audio at any time
173 // (async - this function may return true, but by the time it
174 // returns we don't have audio anymore).
175 bool HasAudio () { return audio_unlocked != NULL; }
177 guint64 GetPosition () { return GetTargetPts (); }
178 guint64 GetDuration () { return duration; }
180 double GetDroppedFramesPerSecond () { return dropped_frames_per_second; }
181 double GetRenderedFramesPerSecond () { return rendered_frames_per_second; }
183 void SetMuted (bool muted);
184 bool GetMuted ();
186 gint32 GetVideoHeight () { return height; }
187 gint32 GetVideoWidth () { return width; }
189 double GetBalance ();
190 void SetBalance (double balance);
192 double GetVolume ();
193 void SetVolume (double volume);
195 guint64 GetTargetPts ();
197 const static int MediaEndedEvent; // This is raised when both audio and video has finished (or either one if not both are present).
198 const static int BufferUnderflowEvent;
201 #endif /* __MOON_MPLAYER_H__ */