4 /* yes, it's xine, not Xine. But eServicexine looks odd. */
6 #include <lib/base/eerror.h>
7 #include <lib/base/object.h>
8 #include <lib/base/ebase.h>
10 #include <lib/service/servicexine.h>
11 #include <lib/service/service.h>
12 #include <lib/base/init_num.h>
13 #include <lib/base/init.h>
15 static xine_t *xine; /* TODO: move this into a static class */
17 // eServiceFactoryXine
19 eServiceFactoryXine::eServiceFactoryXine()
21 ePtr<eServiceCenter> sc;
23 eServiceCenter::getPrivInstance(sc);
25 sc->addServiceFactory(eServiceFactoryXine::id, this);
27 m_service_info = new eStaticServiceXineInfo();
30 eServiceFactoryXine::~eServiceFactoryXine()
32 ePtr<eServiceCenter> sc;
34 eServiceCenter::getPrivInstance(sc);
36 sc->removeServiceFactory(eServiceFactoryXine::id);
39 DEFINE_REF(eServiceFactoryXine)
42 RESULT eServiceFactoryXine::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
45 ptr = new eServiceXine(ref.path.c_str());
49 RESULT eServiceFactoryXine::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
55 RESULT eServiceFactoryXine::list(const eServiceReference &, ePtr<iListableService> &ptr)
61 RESULT eServiceFactoryXine::info(const eServiceReference &ref, ePtr<iStaticServiceInformation> &ptr)
67 RESULT eServiceFactoryXine::offlineOperations(const eServiceReference &, ePtr<iServiceOfflineOperations> &ptr)
74 // eStaticServiceXineInfo
77 DEFINE_REF(eStaticServiceXineInfo)
79 eStaticServiceXineInfo::eStaticServiceXineInfo()
83 RESULT eStaticServiceXineInfo::getName(const eServiceReference &ref, std::string &name)
85 size_t last = ref.path.rfind('/');
86 if (last != std::string::npos)
87 name = ref.path.substr(last+1);
93 int eStaticServiceXineInfo::getLength(const eServiceReference &ref)
100 eServiceXine::eServiceXine(const char *filename): m_filename(filename), m_pump(eApp, 1)
109 // if ((vo_port = xine_open_video_driver(xine, "fb", XINE_VISUAL_TYPE_FB, NULL)) == NULL)
110 if ((vo_port = xine_open_video_driver(xine, "none", XINE_VISUAL_TYPE_NONE, NULL)) == NULL)
112 eWarning("cannot open xine video driver");
115 if ((ao_port = xine_open_audio_driver(xine , "alsa", NULL)) == NULL)
117 eWarning("cannot open xine audio driver");
119 stream = xine_stream_new(xine, ao_port, vo_port);
120 event_queue = xine_event_new_queue(stream);
121 xine_event_create_listener_thread(event_queue, eventListenerWrap, this);
123 // CONNECT(m_pump.recv_msg, eServiceXine::gstPoll);
127 eServiceXine::~eServiceXine()
129 if (m_state == stRunning)
132 eDebug("close stream");
135 eDebug("dispose queue");
137 xine_event_dispose_queue(event_queue);
138 eDebug("dispose stream");
140 xine_dispose(stream);
141 eDebug("dispose ao_port");
143 xine_close_audio_driver(xine, ao_port);
144 eDebug("dispose vo port");
146 xine_close_video_driver(xine, vo_port);
150 DEFINE_REF(eServiceXine);
152 void eServiceXine::eventListenerWrap(void *user_data, const xine_event_t *event)
154 eServiceXine *e = (eServiceXine*)user_data;
155 e->eventListener(event);
158 void eServiceXine::eventListener(const xine_event_t *event)
160 eDebug("handle %d", event->type);
161 switch(event->type) {
162 case XINE_EVENT_UI_PLAYBACK_FINISHED:
167 RESULT eServiceXine::connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)
169 connection = new eConnection((iPlayableService*)this, m_event.connect(event));
173 RESULT eServiceXine::start()
175 if (m_state == stError)
178 assert(m_state == stIdle);
181 if (!xine_open(stream, m_filename.c_str()))
183 eWarning("xine_open failed!");
187 if (!xine_play(stream, 0, 0))
189 eWarning("xine_play failed!");
195 m_event(this, evStart);
199 RESULT eServiceXine::stop()
201 if (m_state == stError)
204 assert(m_state != stIdle);
206 if (m_state == stStopped)
208 printf("Xine: %s stop\n", m_filename.c_str());
215 RESULT eServiceXine::setTarget(int target)
220 RESULT eServiceXine::pause(ePtr<iPauseableService> &ptr)
226 RESULT eServiceXine::setSlowMotion(int ratio)
231 RESULT eServiceXine::setFastForward(int ratio)
237 RESULT eServiceXine::pause()
243 RESULT eServiceXine::unpause()
250 /* iSeekableService */
251 RESULT eServiceXine::seek(ePtr<iSeekableService> &ptr)
257 RESULT eServiceXine::getLength(pts_t &pts)
260 if (m_state == stError)
264 int pos_stream, pos_time, length_time;
266 if (!xine_get_pos_length(stream, &pos_stream, &pos_time, &length_time))
268 eDebug("xine_get_pos_length failed!");
272 eDebug("length: %d ms", length_time);
274 pts = length_time * 90;
279 RESULT eServiceXine::seekTo(pts_t to)
285 RESULT eServiceXine::seekRelative(int direction, pts_t to)
291 RESULT eServiceXine::getPlayPosition(pts_t &pts)
294 if (m_state == stError)
298 int pos_stream, pos_time, length_time;
300 if (!xine_get_pos_length(stream, &pos_stream, &pos_time, &length_time))
303 eDebug("pos_time: %d", pos_time);
310 RESULT eServiceXine::setTrickmode(int trick)
312 /* trickmode currently doesn't make any sense for us. */
316 RESULT eServiceXine::isCurrentlySeekable()
321 RESULT eServiceXine::info(ePtr<iServiceInformation>&i)
327 RESULT eServiceXine::getName(std::string &name)
329 name = "xine File: " + m_filename;
333 int eServiceXine::getInfo(int w)
350 std::string eServiceXine::getInfoString(int w)
360 /* this should be done once. */
362 if(!xine_check_version(1, 1, 0))
364 int major, minor, sub;
365 xine_get_version (&major, &minor, &sub);
366 eWarning("Require xine library version 1.1.0, found %d.%d.%d.\n",
370 int major, minor, sub;
371 eDebug("Built with xine library %d.%d.%d (%s)\n",
372 XINE_MAJOR_VERSION, XINE_MINOR_VERSION, XINE_SUB_VERSION, XINE_VERSION);
374 xine_get_version (&major, &minor, &sub);
376 eDebug("Found xine library version: %d.%d.%d (%s).\n",
377 major, minor, sub, xine_get_version_string());
381 xine_engine_set_param(xine, XINE_ENGINE_PARAM_VERBOSITY, 1);
391 eAutoInitP0<eXine> init_eXine(eAutoInitNumbers::service, "libxine");
392 eAutoInitPtr<eServiceFactoryXine> init_eServiceFactoryXine(eAutoInitNumbers::service+1, "eServiceFactoryXine");
394 #warning xine not available