~ubuntu-branches/ubuntu/lucid/gnome-subtitles/lucid

« back to all changes in this revision

Viewing changes to gstreamer-playbin-0.2.1/src/Engine.cs

  • Committer: Bazaar Package Importer
  • Author(s): Tiago Bortoletto Vaz
  • Date: 2007-12-03 20:52:52 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20071203205252-2y6uuv4gcw9mi9n5
Tags: 0.7-1
* New upstream release;
* Add libxml-parser-perl to Build-Depends-Indep. Thanks to Lucas Nussbaum.
  (Closes: #445799);
* Fixes manpage issue with dpatch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 
 
3
        Copyright (c)  Goran Sterjov
 
4
 
 
5
    This file is part of the GStreamer Playbin Wrapper.
 
6
    Derived from the Dissent Project.
 
7
 
 
8
    GStreamer Playbin Wrapper is free software; you can redistribute it and/or modify
 
9
    it under the terms of the GNU General Public License as published by
 
10
    the Free Software Foundation; either version 2 of the License, or
 
11
    (at your option) any later version.
 
12
 
 
13
    The Dissent Project is distributed in the hope that it will be useful,
 
14
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
    GNU General Public License for more details.
 
17
 
 
18
    You should have received a copy of the GNU General Public License
 
19
    along with the Dissent Project; if not, write to the Free Software
 
20
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
21
*/
 
22
 
 
23
 
 
24
 
 
25
using System;
 
26
using System.Runtime.InteropServices;
 
27
 
 
28
 
 
29
namespace GStreamer
 
30
{
 
31
        
 
32
        
 
33
        // media engine enumerations
 
34
        public enum MediaStatus { Playing, Stopped, Paused, Loaded, Unloaded }
 
35
        public enum MediaEvents { EndOfStream, Error, Buffering, Volume, Seek }
 
36
        
 
37
        // media engine event handlers
 
38
        public delegate void EngineEventHandler (object o, EngineEventArgs args);
 
39
        public delegate void EngineStateHandler (object o, EngineStateArgs args);
 
40
        
 
41
        
 
42
        
 
43
        /// <summary>
 
44
        /// The GStreamer Playbin.
 
45
        /// </summary>
 
46
        public class Playbin
 
47
        {
 
48
                
 
49
                // engine callbacks from the C wrapper
 
50
                delegate void eosCallback (IntPtr engine);
 
51
                delegate void errorCallback (IntPtr engine, string error, string debug);
 
52
                delegate void bufferCallback (IntPtr engine, int prog);
 
53
                
 
54
                eosCallback eos_cb;
 
55
                errorCallback error_cb;
 
56
                bufferCallback buffer_cb;
 
57
                
 
58
                
 
59
                // declarations
 
60
                HandleRef engine;
 
61
                MediaStatus status = MediaStatus.Unloaded;
 
62
                bool buffer_fin;
 
63
                EngineVideoInfo videoInfo = null;
 
64
                
 
65
                /// <summary>Raised when an event occurs. ie: EndOfStream, Error, etc.</summary>
 
66
                public event EngineEventHandler EventChanged;
 
67
                
 
68
                /// <summary>Raised when the playbin state changes. ie: Playing, Paused, etc.</summary>
 
69
                public event EngineStateHandler StateChanged;
 
70
                
 
71
                /// <summary>
 
72
                /// Load the GStreamer library and attach it
 
73
                /// to the specified window.
 
74
                /// </summary>
 
75
                public bool Initiate (ulong x_window_id)
 
76
                {
 
77
                        
 
78
                        // load the gstreamer library
 
79
                        IntPtr ptr = gst_binding_init (x_window_id);
 
80
                        
 
81
                        if(ptr == IntPtr.Zero)
 
82
                        {
 
83
                                throwError ("Failed to load the Gstreamer library");
 
84
                                return false;
 
85
                        }
 
86
                        else engine = new HandleRef (this, ptr);
 
87
                        
 
88
                        
 
89
                        // set up callbacks
 
90
                        eos_cb = new eosCallback (onEos);
 
91
                        error_cb = new errorCallback (onError);
 
92
                        buffer_cb = new bufferCallback (onBuffer);
 
93
                        
 
94
                        gst_binding_set_eos_cb (engine, eos_cb);
 
95
                        gst_binding_set_error_cb (engine, error_cb);
 
96
                        gst_binding_set_buffer_cb (engine, buffer_cb);
 
97
                        
 
98
                        
 
99
                        status = MediaStatus.Stopped;
 
100
                        return true;
 
101
                }
 
102
                
 
103
                
 
104
                /// <summary>
 
105
                /// Load the GStreamer library.
 
106
                /// </summary>
 
107
                public bool Initiate ()
 
108
                {
 
109
                        return Initiate (0);
 
110
                }
 
111
                
 
112
                
 
113
                
 
114
                
 
115
                
 
116
                /// <summary>
 
117
                /// Disposes the GStreamer library.
 
118
                /// </summary>
 
119
                public void Dispose ()
 
120
                {
 
121
                        Stop ();
 
122
                        gst_binding_deinit (engine);
 
123
                        ChangeState (MediaStatus.Unloaded);
 
124
                }
 
125
                
 
126
                /// <summary>
 
127
                /// Loads the specified path into the GStreamer library.
 
128
                /// </summary>
 
129
                public bool Load (string uri)
 
130
                {
 
131
                        if (!isStopped) Stop ();
 
132
                        gst_binding_load (engine, uri);
 
133
                        //ChangeState (MediaStatus.Loaded);
 
134
                        ChangeState (MediaStatus.Paused);
 
135
                        return true;
 
136
                }
 
137
                
 
138
                /// <summary>
 
139
                /// Plays the loaded media file.
 
140
                /// </summary>
 
141
                public void Play ()
 
142
                {
 
143
                        if (!isPlaying && !isUnloaded) {
 
144
                                gst_binding_play (engine);
 
145
                                ChangeState (MediaStatus.Playing);
 
146
                        }
 
147
                }
 
148
                
 
149
                /// <summary>
 
150
                /// Pauses the loaded media file.
 
151
                /// </summary>
 
152
                public void Pause ()
 
153
                {
 
154
                        if (isPlaying) {
 
155
                                gst_binding_pause (engine);
 
156
                                ChangeState (MediaStatus.Paused);
 
157
                        }
 
158
                }
 
159
                
 
160
                /// <summary>
 
161
                /// Stops the loaded media file and unloads it.
 
162
                /// </summary>
 
163
                public void Stop ()
 
164
                {
 
165
                        if (isPlaying || isPaused) {
 
166
                                gst_binding_unload (engine);
 
167
                                Seek (0);
 
168
                                ChangeState (MediaStatus.Stopped);
 
169
                                videoInfo = null;
 
170
                        }
 
171
                }
 
172
                
 
173
                /// <summary>
 
174
                /// Changes the window to which video playback is attached to.
 
175
                /// </summary>
 
176
                public void SetWindow (ulong window_id)
 
177
                {
 
178
                        gst_binding_set_xid (engine, window_id);
 
179
                }
 
180
                
 
181
                
 
182
                
 
183
                /// <summary>
 
184
                /// Seeks to the nearest millisecond on the media file.
 
185
                /// </summary>
 
186
                public void Seek (TimeSpan time)
 
187
                {
 
188
                        if (isUnloaded) return;
 
189
                        gst_binding_set_position (engine, (ulong) time.TotalMilliseconds);
 
190
                        ChangeEvent (MediaEvents.Seek, null, 0);
 
191
                }
 
192
                
 
193
                
 
194
                /// <summary>
 
195
                /// Seeks to the nearest millisecond on the media file.
 
196
                /// </summary>
 
197
                public void Seek (double milliseconds)
 
198
                {
 
199
                        TimeSpan time = TimeSpan.FromMilliseconds (milliseconds);
 
200
                        Seek (time);
 
201
                }
 
202
                
 
203
                
 
204
                
 
205
                
 
206
                /// <summary>
 
207
                /// Returns the current position that the media file is on.
 
208
                /// </summary>
 
209
                public TimeSpan CurrentPosition
 
210
                {
 
211
                        get
 
212
                        {
 
213
                                if (!isPlaying && !isPaused)
 
214
                                        return TimeSpan.Zero;
 
215
                                
 
216
                                double pos = (double) gst_binding_get_position (engine);
 
217
                                return TimeSpan.FromMilliseconds (pos);
 
218
                        }
 
219
                }
 
220
                
 
221
                
 
222
                /// <summary>
 
223
                /// Returns the total duration of the media file.
 
224
                /// </summary>
 
225
                public TimeSpan Duration
 
226
                {
 
227
                        get{
 
228
                                if (isUnloaded)
 
229
                                        return TimeSpan.Zero;
 
230
                                
 
231
                                double dur = (double) gst_binding_get_duration (engine);
 
232
                                return TimeSpan.FromMilliseconds (dur);
 
233
                        }
 
234
                }
 
235
                
 
236
                /// <summary>
 
237
                /// Returns information on the video stream, or null if it's not available
 
238
                /// </summary>
 
239
                public EngineVideoInfo VideoInfo
 
240
                {
 
241
                        get{
 
242
                                if (isUnloaded)
 
243
                                        return null;
 
244
                                        
 
245
                                if (videoInfo == null) {
 
246
                                        IntPtr ptr = gst_binding_get_video_info (engine);
 
247
                                        if (ptr == IntPtr.Zero)
 
248
                                                return null;
 
249
                                        else {
 
250
                                                videoInfo = new EngineVideoInfo();
 
251
                                                Marshal.PtrToStructure(ptr, videoInfo);
 
252
                                        }
 
253
                                }
 
254
                                return videoInfo;
 
255
                        }
 
256
                }
 
257
 
 
258
                /// <summary>
 
259
                /// Returns the current volume of the GStreamer library.
 
260
                /// </summary>
 
261
                public double Volume
 
262
                {
 
263
                        get{ return (double) gst_binding_get_volume (engine); }
 
264
                        set
 
265
                        {
 
266
                                gst_binding_set_volume (engine, (int) value);
 
267
                                ChangeEvent (MediaEvents.Volume, null, 0);
 
268
                        }
 
269
                }
 
270
                
 
271
                
 
272
                
 
273
                /// <summary>
 
274
                /// Returns a value determining if the media file is a video file.
 
275
                /// </summary>
 
276
                public bool HasVideo
 
277
                {
 
278
                        get{ return !isUnloaded ? gst_binding_has_video (engine) : false; }
 
279
                }
 
280
                
 
281
                /// <summary>
 
282
                /// Returns the current status of the media engine.
 
283
                /// </summary>
 
284
                public MediaStatus CurrentStatus
 
285
                {
 
286
                        get { return status; }
 
287
                }
 
288
                
 
289
                
 
290
                
 
291
                
 
292
                // throws an error to the global error handler
 
293
                void throwError (string message)
 
294
                {
 
295
                        EngineEventArgs args = new EngineEventArgs (MediaEvents.Error, message, 0);
 
296
                if(EventChanged != null) EventChanged(this, args);
 
297
                }
 
298
                
 
299
                
 
300
                // the stream has ended
 
301
                void onEos (IntPtr engine)
 
302
                {
 
303
                        ChangeEvent (MediaEvents.EndOfStream, null, 0);
 
304
                }
 
305
                
 
306
                
 
307
                // an error in the gstreamer pipeline has occured
 
308
                void onError (IntPtr engine, string error, string debug)
 
309
                {
 
310
                        throwError (error + "\n\nDebug Message:\n" + debug);
 
311
                        ChangeState (MediaStatus.Stopped);
 
312
                        ChangeEvent (MediaEvents.Error, error, 0);
 
313
                }
 
314
                
 
315
                
 
316
                // the gstreamer pipeline is being buffered
 
317
                void onBuffer (IntPtr engine, int prog)
 
318
                {
 
319
                        if(!buffer_fin) {
 
320
                                buffer_fin = prog >= 100;
 
321
                                ChangeEvent (MediaEvents.Buffering, "Buffering", (double)prog);
 
322
                        }
 
323
                }
 
324
                
 
325
                
 
326
                // throw the media state changed event
 
327
                void ChangeState(MediaStatus state)
 
328
                {
 
329
                        status = state;
 
330
                EngineStateArgs args = new EngineStateArgs (state);
 
331
                if(StateChanged != null) StateChanged(this, args);
 
332
        }
 
333
        
 
334
        // throw the media event changed event
 
335
        void ChangeEvent(MediaEvents engineEvent, string message, double percent)
 
336
        {
 
337
                EngineEventArgs args = new EngineEventArgs (engineEvent, message, percent);
 
338
                if(EventChanged != null) EventChanged(this, args);
 
339
        }
 
340
                
 
341
                
 
342
                // private convenience properties
 
343
                bool isPlaying { get{ return status == MediaStatus.Playing; } }
 
344
                bool isPaused { get{ return status == MediaStatus.Paused; } }
 
345
                bool isStopped { get{ return status == MediaStatus.Stopped; } }
 
346
                bool isUnloaded { get{ return status == MediaStatus.Unloaded; } }
 
347
                
 
348
                
 
349
                
 
350
                // core engine functions
 
351
                [DllImport("gstreamer_playbin")]
 
352
                static extern IntPtr gst_binding_init (ulong xwin);
 
353
                [DllImport("gstreamer_playbin")]
 
354
                static extern void gst_binding_deinit (HandleRef play);
 
355
                [DllImport("gstreamer_playbin")]
 
356
                static extern void gst_binding_load (HandleRef play, string uri);
 
357
                [DllImport("gstreamer_playbin")]
 
358
                static extern void gst_binding_play (HandleRef play);
 
359
                [DllImport("gstreamer_playbin")]
 
360
                static extern void gst_binding_pause (HandleRef play);
 
361
                [DllImport("gstreamer_playbin")]
 
362
                static extern void gst_binding_unload (HandleRef play);
 
363
                [DllImport("gstreamer_playbin")]
 
364
                static extern void gst_binding_set_xid (HandleRef play, ulong xid);
 
365
                
 
366
                
 
367
                // engine property functions
 
368
                [DllImport("gstreamer_playbin")]
 
369
                static extern ulong gst_binding_get_duration (HandleRef play);
 
370
                [DllImport("gstreamer_playbin")]
 
371
                static extern IntPtr gst_binding_get_video_info (HandleRef play);
 
372
                [DllImport("gstreamer_playbin")]
 
373
                static extern ulong gst_binding_get_position (HandleRef play);
 
374
                [DllImport("gstreamer_playbin")]
 
375
                static extern int gst_binding_get_volume (HandleRef play);
 
376
                [DllImport("gstreamer_playbin")]
 
377
                static extern void gst_binding_set_position (HandleRef play, ulong pos);
 
378
                [DllImport("gstreamer_playbin")]
 
379
                static extern void gst_binding_set_volume (HandleRef play, int vol);
 
380
                [DllImport("gstreamer_playbin")]
 
381
                static extern bool gst_binding_has_video (HandleRef play);
 
382
                
 
383
                
 
384
                // engine callbacks
 
385
                [DllImport("gstreamer_playbin")]
 
386
                static extern void gst_binding_set_eos_cb (HandleRef play, eosCallback cb);
 
387
                [DllImport("gstreamer_playbin")]
 
388
                static extern void gst_binding_set_error_cb (HandleRef play, errorCallback cb);
 
389
                [DllImport("gstreamer_playbin")]
 
390
                static extern void gst_binding_set_buffer_cb (HandleRef play, bufferCallback cb);
 
391
        }
 
392
        
 
393
        
 
394
        
 
395
        
 
396
        /// <summary>
 
397
        /// Arguments for a raised event.
 
398
        /// </summary>
 
399
        public sealed class EngineEventArgs
 
400
        {
 
401
                MediaEvents engine_event;
 
402
                string message;
 
403
                double buffer;
 
404
                
 
405
                public EngineEventArgs (MediaEvents engine_event, string message, double buffer)
 
406
                {
 
407
                this.engine_event = engine_event;
 
408
                this.message = message;
 
409
                this.buffer = buffer;
 
410
        }
 
411
        
 
412
        public MediaEvents Event { get{ return engine_event; } }
 
413
        public string Message { get{ return message; } }
 
414
        public double BufferingPercent { get{ return buffer; } }
 
415
    }
 
416
    
 
417
    
 
418
        
 
419
        
 
420
        /// <summary>
 
421
        /// Arguments for a raised state.
 
422
        /// </summary>
 
423
    public sealed class EngineStateArgs
 
424
    {
 
425
        MediaStatus state;
 
426
        
 
427
        public EngineStateArgs (MediaStatus state)
 
428
        {
 
429
                this.state = state;
 
430
        }
 
431
        
 
432
        public MediaStatus State { get{ return state; } }
 
433
    }
 
434
    
 
435
    [StructLayout(LayoutKind.Sequential)]
 
436
    public class EngineVideoInfo
 
437
    {
 
438
        int width;
 
439
                int height;
 
440
        float frame_rate;
 
441
        
 
442
        public int Width { get{ return width; } }
 
443
        public int Height { get{ return height; } }
 
444
        public float AspectRatio { get { return (float)width/height; } }
 
445
        public float FrameRate { get{ return frame_rate; } }
 
446
        
 
447
        public override string ToString () { return "Width=" + width + ", Height=" + height + ", FrameRate=" + frame_rate; }
 
448
    }
 
449
        
 
450
        
 
451
}