]> git.tdb.fi Git - xinema.git/blobdiff - source/xineengine.cpp
Refactor the libxine interface into classes
[xinema.git] / source / xineengine.cpp
diff --git a/source/xineengine.cpp b/source/xineengine.cpp
new file mode 100644 (file)
index 0000000..4175381
--- /dev/null
@@ -0,0 +1,101 @@
+#include <stdexcept>
+#include <msp/fs/dir.h>
+#include <msp/graphics/display_private.h>
+#include <msp/graphics/window_private.h>
+#include "xineengine.h"
+
+using namespace std;
+using namespace Msp;
+
+XineEngine::XineEngine(const Graphics::Window &w, Mutex *m):
+       window(w),
+       display_mutex(m),
+       locked_thread(0),
+       lock_count(0)
+{
+       engine = xine_new();
+
+       FS::Path config_fn = FS::get_home_dir()/".xine"/"config";
+       xine_config_load(engine, config_fn.c_str());
+
+       xine_init(engine);
+
+       audio_driver = xine_open_audio_driver(engine, "auto", 0);
+       if(!audio_driver)
+               throw runtime_error("Could not open audio driver");
+
+       visual.display = window.get_display().get_private().display;
+       visual.screen = 0;
+       visual.d = window.get_private().window;
+       visual.user_data = this;
+       visual.dest_size_cb = &dest_size_cb;
+       visual.frame_output_cb = &frame_output_cb;
+       if(display_mutex)
+       {
+               visual.lock_display = &lock_cb;
+               visual.unlock_display = &unlock_cb;
+       }
+       else
+       {
+               visual.lock_display = 0;
+               visual.unlock_display = 0;
+       }
+
+       video_driver = xine_open_video_driver(engine, "auto", XINE_VISUAL_TYPE_X11_2, &visual);
+       if(!video_driver)
+               throw runtime_error("Could not open video driver");
+}
+
+XineEngine::~XineEngine()
+{
+       xine_close_video_driver(engine, video_driver);
+       xine_close_audio_driver(engine, audio_driver);
+       xine_exit(engine);
+}
+
+void XineEngine::dest_size_cb(void *user_data, int, int, double, int *dest_width, int *dest_height, double *dest_pixel_aspect)
+{
+       XineEngine &engine = *reinterpret_cast<XineEngine *>(user_data);
+       *dest_width = engine.window.get_width();
+       *dest_height = engine.window.get_height();
+       *dest_pixel_aspect = 1.0;
+}
+
+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)
+{
+       XineEngine &engine = *reinterpret_cast<XineEngine *>(user_data);
+       *dest_x = 0;
+       *dest_y = 0;
+       *dest_width = engine.window.get_width();
+       *dest_height = engine.window.get_height();
+       *dest_pixel_aspect = 1.0;
+       *win_x = 0;
+       *win_y = 0;
+}
+
+void XineEngine::lock_cb(void *user_data)
+{
+       XineEngine &engine = *reinterpret_cast<XineEngine *>(user_data);
+       pthread_t tid = pthread_self();
+       if(tid==engine.locked_thread)
+               ++engine.lock_count;
+       else
+       {
+               engine.display_mutex->lock();
+               engine.locked_thread = tid;
+               engine.lock_count = 1;
+       }
+}
+
+void XineEngine::unlock_cb(void *user_data)
+{
+       XineEngine &engine = *reinterpret_cast<XineEngine *>(user_data);
+       pthread_t tid = pthread_self();
+       if(tid!=engine.locked_thread)
+               throw logic_error("Unlock from non-locked thread");
+       if(!--engine.lock_count)
+       {
+               engine.locked_thread = 0;
+               engine.display_mutex->unlock();
+       }
+}