]> git.tdb.fi Git - xinema.git/commitdiff
A simple application using libxine to play a video file
authorMikko Rasa <tdb@tdb.fi>
Tue, 13 Oct 2015 23:06:26 +0000 (02:06 +0300)
committerMikko Rasa <tdb@tdb.fi>
Tue, 13 Oct 2015 23:06:26 +0000 (02:06 +0300)
.gitignore [new file with mode: 0644]
Build [new file with mode: 0644]
source/xinema.cpp [new file with mode: 0644]
source/xinema.h [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..b7e50c1
--- /dev/null
@@ -0,0 +1,3 @@
+.config
+/temp
+/xinema
diff --git a/Build b/Build
new file mode 100644 (file)
index 0000000..a3f1888
--- /dev/null
+++ b/Build
@@ -0,0 +1,16 @@
+package "xinema"
+{
+       program "xinema"
+       {
+               require "mspcore";
+               require "mspgui";
+               require "xlib";
+               require "libxine";
+               require "sigc++-2.0";
+               source "source";
+               build_info
+               {
+                       standard CXX "c++11";
+               };
+       };
+};
diff --git a/source/xinema.cpp b/source/xinema.cpp
new file mode 100644 (file)
index 0000000..953310a
--- /dev/null
@@ -0,0 +1,109 @@
+#include <sigc++/bind.h>
+#include <msp/core/getopt.h>
+#include <msp/fs/dir.h>
+#include <msp/graphics/display_private.h>
+#include <msp/graphics/window_private.h>
+#include <msp/io/print.h>
+#include "xinema.h"
+
+using namespace std;
+using namespace Msp;
+
+Xinema::EarlyInit::EarlyInit()
+{
+       XInitThreads();
+}
+
+
+Xinema::Xinema(int argc, char **argv):
+       window(display, 1920, 1080)
+{
+       GetOpt getopt;
+       getopt.add_argument("filename", filename, GetOpt::REQUIRED_ARG);
+       getopt(argc, argv);
+
+       window.signal_close.connect(sigc::bind(sigc::mem_fun(this, &Xinema::exit), 0));
+}
+
+int Xinema::main()
+{
+       xine = xine_new();
+
+       FS::Path config_fn = FS::get_home_dir()/".xine"/"config";
+       xine_config_load(xine, config_fn.c_str());
+
+       xine_init(xine);
+
+       xine_audio = xine_open_audio_driver(xine, "auto", 0);
+
+       XLockDisplay(display.get_private().display);
+       window.show();
+       XSync(display.get_private().display, false);
+       XUnlockDisplay(display.get_private().display);
+
+       xine_visual.display = display.get_private().display;
+       xine_visual.screen = 0;
+       xine_visual.d = window.get_private().window;
+       xine_visual.user_data = this;
+       xine_visual.dest_size_cb = &dest_size_cb;
+       xine_visual.frame_output_cb = &frame_output_cb;
+
+       xine_video = xine_open_video_driver(xine, "auto", XINE_VISUAL_TYPE_X11, &xine_visual);
+
+       xine_stream = xine_stream_new(xine, xine_audio, xine_video);
+       xine_open(xine_stream, filename.c_str());
+       xine_play(xine_stream, 0, 0);
+
+       xine_queue = xine_event_new_queue(xine_stream);
+
+       Application::main();
+
+       xine_close(xine_stream);
+       xine_event_dispose_queue(xine_queue);
+       xine_dispose(xine_stream);
+       xine_close_video_driver(xine, xine_video);
+       xine_close_audio_driver(xine, xine_audio);
+       xine_exit(xine);
+
+       return exit_code;
+}
+
+void Xinema::tick()
+{
+       XLockDisplay(display.get_private().display);
+       display.tick();
+       XUnlockDisplay(display.get_private().display);
+
+       while(xine_event_t *event = xine_event_get(xine_queue))
+       {
+               switch(event->type)
+               {
+               case XINE_EVENT_PROGRESS:
+                       {
+                               xine_progress_data_t *data = reinterpret_cast<xine_progress_data_t *>(event->data);
+                               IO::print("%s [%d%%]\n", data->description, data->percent);
+                       }
+                       break;
+               }
+       }
+}
+
+void Xinema::dest_size_cb(void *user_data, int, int, double, int *dest_width, int *dest_height, double *dest_pixel_aspect)
+{
+       Xinema &xinema = *reinterpret_cast<Xinema *>(user_data);
+       *dest_width = xinema.window.get_width();
+       *dest_height = xinema.window.get_height();
+       *dest_pixel_aspect = 1.0;
+}
+
+void Xinema::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)
+{
+       Xinema &xinema = *reinterpret_cast<Xinema *>(user_data);
+       *dest_x = 0;
+       *dest_y = 0;
+       *dest_width = xinema.window.get_width();
+       *dest_height = xinema.window.get_height();
+       *dest_pixel_aspect = 1.0;
+       *win_x = 0;
+       *win_y = 0;
+}
diff --git a/source/xinema.h b/source/xinema.h
new file mode 100644 (file)
index 0000000..ce9e92a
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef XINEMA_H_
+#define XINEMA_H_
+
+#include <msp/core/application.h>
+#include <msp/graphics/display.h>
+#include <msp/graphics/window.h>
+#include <xine.h>
+
+class Xinema: public Msp::RegisteredApplication<Xinema>
+{
+private:
+       struct EarlyInit
+       {
+               EarlyInit();
+       };
+
+       EarlyInit early_init;
+       std::string filename;
+       Msp::Graphics::Display display;
+       Msp::Graphics::Window window;
+       xine_t *xine;
+       xine_audio_port_t *xine_audio;
+       x11_visual_t xine_visual;
+       xine_video_port_t *xine_video;
+       xine_stream_t *xine_stream;
+       xine_event_queue_t *xine_queue;
+
+public:
+       Xinema(int, char **);
+
+       virtual int main();
+
+private:
+       virtual void tick();
+
+       static void dest_size_cb(void *, int, int, double, int *, int *, double *);
+       static void frame_output_cb(void *, int, int, double, int *, int *, int *, int *, double *, int *, int *);
+};
+
+#endif