+#include <algorithm>
#include <stdexcept>
#include <msp/fs/dir.h>
#include <msp/graphics/display_private.h>
#include <msp/graphics/window_private.h>
#include "xineengine.h"
+#include "xinestream.h"
using namespace std;
using namespace Msp;
-XineEngine::XineEngine(const Graphics::Window &w, Mutex *m):
+XineEngine::XineEngine(Graphics::Window &w):
window(w),
- display_mutex(m),
- locked_thread(0),
- lock_count(0)
+ pending_expose(0)
{
engine = xine_new();
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;
- }
+ visual.lock_display = 0;
+ visual.unlock_display = 0;
- video_driver = xine_open_video_driver(engine, "auto", XINE_VISUAL_TYPE_X11_2, &visual);
+ video_driver = xine_open_video_driver(engine, "auto", XINE_VISUAL_TYPE_X11, &visual);
if(!video_driver)
throw runtime_error("Could not open video driver");
+
+ window.signal_expose.connect(sigc::mem_fun(this, &XineEngine::window_exposed));
}
XineEngine::~XineEngine()
xine_exit(engine);
}
+void XineEngine::add_stream(XineStream &stream)
+{
+ streams.push_back(&stream);
+}
+
+void XineEngine::remove_stream(XineStream &stream)
+{
+ list<XineStream *>::iterator i = find(streams.begin(), streams.end(), &stream);
+ if(i!=streams.end())
+ streams.erase(i);
+}
+
+void XineEngine::tick()
+{
+ if(pending_expose)
+ {
+ xine_port_send_gui_data(video_driver, XINE_GUI_SEND_EXPOSE_EVENT, &pending_expose->xevent);
+ delete pending_expose;
+ pending_expose = 0;
+ }
+
+ for(list<XineStream *>::const_iterator i=streams.begin(); i!=streams.end(); ++i)
+ (*i)->tick();
+}
+
+void XineEngine::window_exposed(unsigned, unsigned, unsigned, unsigned, const Graphics::Window::Event &event)
+{
+ delete pending_expose;
+ pending_expose = new Graphics::Window::Event(event);
+}
+
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);
*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();
- }
-}