]> git.tdb.fi Git - xinema.git/blob - source/xineengine.cpp
4175381b8d3a0a4b9f1782f9df00967a1b7121b4
[xinema.git] / source / xineengine.cpp
1 #include <stdexcept>
2 #include <msp/fs/dir.h>
3 #include <msp/graphics/display_private.h>
4 #include <msp/graphics/window_private.h>
5 #include "xineengine.h"
6
7 using namespace std;
8 using namespace Msp;
9
10 XineEngine::XineEngine(const Graphics::Window &w, Mutex *m):
11         window(w),
12         display_mutex(m),
13         locked_thread(0),
14         lock_count(0)
15 {
16         engine = xine_new();
17
18         FS::Path config_fn = FS::get_home_dir()/".xine"/"config";
19         xine_config_load(engine, config_fn.c_str());
20
21         xine_init(engine);
22
23         audio_driver = xine_open_audio_driver(engine, "auto", 0);
24         if(!audio_driver)
25                 throw runtime_error("Could not open audio driver");
26
27         visual.display = window.get_display().get_private().display;
28         visual.screen = 0;
29         visual.d = window.get_private().window;
30         visual.user_data = this;
31         visual.dest_size_cb = &dest_size_cb;
32         visual.frame_output_cb = &frame_output_cb;
33         if(display_mutex)
34         {
35                 visual.lock_display = &lock_cb;
36                 visual.unlock_display = &unlock_cb;
37         }
38         else
39         {
40                 visual.lock_display = 0;
41                 visual.unlock_display = 0;
42         }
43
44         video_driver = xine_open_video_driver(engine, "auto", XINE_VISUAL_TYPE_X11_2, &visual);
45         if(!video_driver)
46                 throw runtime_error("Could not open video driver");
47 }
48
49 XineEngine::~XineEngine()
50 {
51         xine_close_video_driver(engine, video_driver);
52         xine_close_audio_driver(engine, audio_driver);
53         xine_exit(engine);
54 }
55
56 void XineEngine::dest_size_cb(void *user_data, int, int, double, int *dest_width, int *dest_height, double *dest_pixel_aspect)
57 {
58         XineEngine &engine = *reinterpret_cast<XineEngine *>(user_data);
59         *dest_width = engine.window.get_width();
60         *dest_height = engine.window.get_height();
61         *dest_pixel_aspect = 1.0;
62 }
63
64 void XineEngine::frame_output_cb(void *user_data, int, int, double, int *dest_x, int *dest_y, int *dest_width, int *dest_height, double *dest_pixel_aspect, int *win_x, int *win_y)
65 {
66         XineEngine &engine = *reinterpret_cast<XineEngine *>(user_data);
67         *dest_x = 0;
68         *dest_y = 0;
69         *dest_width = engine.window.get_width();
70         *dest_height = engine.window.get_height();
71         *dest_pixel_aspect = 1.0;
72         *win_x = 0;
73         *win_y = 0;
74 }
75
76 void XineEngine::lock_cb(void *user_data)
77 {
78         XineEngine &engine = *reinterpret_cast<XineEngine *>(user_data);
79         pthread_t tid = pthread_self();
80         if(tid==engine.locked_thread)
81                 ++engine.lock_count;
82         else
83         {
84                 engine.display_mutex->lock();
85                 engine.locked_thread = tid;
86                 engine.lock_count = 1;
87         }
88 }
89
90 void XineEngine::unlock_cb(void *user_data)
91 {
92         XineEngine &engine = *reinterpret_cast<XineEngine *>(user_data);
93         pthread_t tid = pthread_self();
94         if(tid!=engine.locked_thread)
95                 throw logic_error("Unlock from non-locked thread");
96         if(!--engine.lock_count)
97         {
98                 engine.locked_thread = 0;
99                 engine.display_mutex->unlock();
100         }
101 }