From b59b30ecd8131677b42232722df901120bd62213 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 14 Oct 2015 02:06:26 +0300 Subject: [PATCH] A simple application using libxine to play a video file --- .gitignore | 3 ++ Build | 16 +++++++ source/xinema.cpp | 109 ++++++++++++++++++++++++++++++++++++++++++++++ source/xinema.h | 40 +++++++++++++++++ 4 files changed, 168 insertions(+) create mode 100644 .gitignore create mode 100644 Build create mode 100644 source/xinema.cpp create mode 100644 source/xinema.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b7e50c1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.config +/temp +/xinema diff --git a/Build b/Build new file mode 100644 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 index 0000000..953310a --- /dev/null +++ b/source/xinema.cpp @@ -0,0 +1,109 @@ +#include +#include +#include +#include +#include +#include +#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(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(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(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 index 0000000..ce9e92a --- /dev/null +++ b/source/xinema.h @@ -0,0 +1,40 @@ +#ifndef XINEMA_H_ +#define XINEMA_H_ + +#include +#include +#include +#include + +class Xinema: public Msp::RegisteredApplication +{ +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 -- 2.43.0