aboutsummaryrefslogtreecommitdiff
path: root/lib/python/Plugins/Extensions/DVDPlayer/src
diff options
context:
space:
mode:
authorAndreas Monzner <andreas.monzner@multimedia-labs.de>2008-04-15 12:47:41 +0000
committerAndreas Monzner <andreas.monzner@multimedia-labs.de>2008-04-15 12:47:41 +0000
commit17be24380f07656d14b88baf5af0d9ef3d8eddfd (patch)
treef4415b51ebf4ca4c5281883ea4cdde6107d5560c /lib/python/Plugins/Extensions/DVDPlayer/src
parentc50acf3391bec3f2abaf219c8f52c7d57d6149b5 (diff)
downloadenigma2-17be24380f07656d14b88baf5af0d9ef3d8eddfd.tar.gz
enigma2-17be24380f07656d14b88baf5af0d9ef3d8eddfd.zip
add DVDPlayer plugin (not final yet)
not working without libdreamdvd (not in OE yet)
Diffstat (limited to 'lib/python/Plugins/Extensions/DVDPlayer/src')
-rw-r--r--lib/python/Plugins/Extensions/DVDPlayer/src/.cvsignore5
-rw-r--r--lib/python/Plugins/Extensions/DVDPlayer/src/Makefile.am11
-rw-r--r--lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.cpp858
-rw-r--r--lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.h166
4 files changed, 1040 insertions, 0 deletions
diff --git a/lib/python/Plugins/Extensions/DVDPlayer/src/.cvsignore b/lib/python/Plugins/Extensions/DVDPlayer/src/.cvsignore
new file mode 100644
index 00000000..41818695
--- /dev/null
+++ b/lib/python/Plugins/Extensions/DVDPlayer/src/.cvsignore
@@ -0,0 +1,5 @@
+*.pyc
+*.pyo
+*.so
+Makefile
+Makefile.in
diff --git a/lib/python/Plugins/Extensions/DVDPlayer/src/Makefile.am b/lib/python/Plugins/Extensions/DVDPlayer/src/Makefile.am
new file mode 100644
index 00000000..bb02291c
--- /dev/null
+++ b/lib/python/Plugins/Extensions/DVDPlayer/src/Makefile.am
@@ -0,0 +1,11 @@
+servicedvd.so:
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(DEFS) -I$(top_srcdir)/include -Wall -W servicedvd.cpp -shared -fPIC -Wl,-soname,servicedvd.so -o servicedvd.so $(LDFLAGS) -ldreamdvd
+
+#-nostartfiles
+
+all: servicedvd.so
+
+CLEANFILES = servicedvd.so
+
+install: all
+ $(INSTALL) servicedvd.so $(DESTDIR)/$(LIBDIR)/enigma2/python/Plugins/Extensions/DVDPlayer
diff --git a/lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.cpp b/lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.cpp
new file mode 100644
index 00000000..016e16a1
--- /dev/null
+++ b/lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.cpp
@@ -0,0 +1,858 @@
+/* yes, it's dvd */
+#include "servicedvd.h"
+#include <lib/base/eerror.h>
+#include <lib/base/object.h>
+#include <lib/base/ebase.h>
+#include <string>
+#include <lib/service/service.h>
+#include <lib/base/init_num.h>
+#include <lib/base/init.h>
+#include <lib/gui/esubtitle.h>
+#include <lib/gdi/gpixmap.h>
+
+#ifdef cue
+#include <byteswap.h>
+#include <netinet/in.h>
+#ifndef BYTE_ORDER
+#error no byte order defined!
+#endif
+#endif //cue
+
+extern "C" {
+#include <dreamdvd/ddvdlib.h>
+}
+
+// eServiceFactoryDVD
+
+eServiceFactoryDVD::eServiceFactoryDVD()
+{
+ ePtr<eServiceCenter> sc;
+
+ eServiceCenter::getPrivInstance(sc);
+ if (sc)
+ {
+ std::list<std::string> extensions;
+ extensions.push_back("iso");
+ sc->addServiceFactory(eServiceFactoryDVD::id, this, extensions);
+ }
+}
+
+eServiceFactoryDVD::~eServiceFactoryDVD()
+{
+ ePtr<eServiceCenter> sc;
+
+ eServiceCenter::getPrivInstance(sc);
+ if (sc)
+ sc->removeServiceFactory(eServiceFactoryDVD::id);
+}
+
+DEFINE_REF(eServiceFactoryDVD)
+
+ // iServiceHandler
+RESULT eServiceFactoryDVD::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
+{
+ // check resources...
+ ptr = new eServiceDVD(ref.path.c_str());
+ return 0;
+}
+
+RESULT eServiceFactoryDVD::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
+{
+ ptr=0;
+ return -1;
+}
+
+RESULT eServiceFactoryDVD::list(const eServiceReference &, ePtr<iListableService> &ptr)
+{
+ ptr=0;
+ return -1;
+}
+
+
+RESULT eServiceFactoryDVD::info(const eServiceReference &ref, ePtr<iStaticServiceInformation> &ptr)
+{
+ ptr=0;
+ return -1;
+}
+
+RESULT eServiceFactoryDVD::offlineOperations(const eServiceReference &, ePtr<iServiceOfflineOperations> &ptr)
+{
+ ptr = 0;
+ return -1;
+}
+
+// eServiceDVD
+
+DEFINE_REF(eServiceDVD);
+
+eServiceDVD::eServiceDVD(const char *filename):
+ m_filename(filename),
+ m_ddvdconfig(ddvd_create()),
+ m_pixmap(new gPixmap(eSize(720, 576), 32)),
+ m_subtitle_widget(0),
+ m_state(stIdle),
+ m_current_trick(0),
+ m_sn(eApp, ddvd_get_messagepipe_fd(m_ddvdconfig), eSocketNotifier::Read|eSocketNotifier::Priority|eSocketNotifier::Error|eSocketNotifier::Hungup),
+ m_pump(eApp, 1)
+{
+ eDebug("SERVICEDVD construct!");
+ // create handle
+ ddvd_set_dvd_path(m_ddvdconfig, filename);
+ ddvd_set_ac3thru(m_ddvdconfig, 0);
+ ddvd_set_language(m_ddvdconfig, "de");
+ ddvd_set_video(m_ddvdconfig, DDVD_16_9, DDVD_PAL);
+ ddvd_set_lfb(m_ddvdconfig, (unsigned char *)m_pixmap->surface->data, 720, 576, 4, 720*4);
+ CONNECT(m_sn.activated, eServiceDVD::gotMessage);
+ CONNECT(m_pump.recv_msg, eServiceDVD::gotThreadMessage);
+ strcpy(m_ddvd_titlestring,"");
+ m_doSeekTo = 0;
+ m_seekTitle = 0;
+#ifdef cue
+ m_cue_pts = 0;
+#endif
+}
+
+void eServiceDVD::gotThreadMessage(const int &msg)
+{
+ switch(msg)
+ {
+ case 1: // thread stopped
+ m_state = stStopped;
+ m_event(this, evStopped);
+ break;
+ }
+}
+
+void eServiceDVD::gotMessage(int what)
+{
+ switch(ddvd_get_next_message(m_ddvdconfig,1))
+ {
+ case DDVD_COLORTABLE_UPDATE:
+ {
+/*
+ struct ddvd_color ctmp[4];
+ ddvd_get_last_colortable(ddvdconfig, ctmp);
+ int i=0;
+ while (i < 4)
+ {
+ rd1[252+i]=ctmp[i].red;
+ bl1[252+i]=ctmp[i].blue;
+ gn1[252+i]=ctmp[i].green;
+ tr1[252+i]=ctmp[i].trans;
+ i++;
+ }
+ if(ioctl(fb, FBIOPUTCMAP, &colormap) == -1)
+ {
+ printf("Framebuffer: <FBIOPUTCMAP failed>\n");
+ return 1;
+ }
+*/
+ eDebug("no support for 8bpp framebuffer in dvdplayer yet!");
+ break;
+ }
+ case DDVD_SCREEN_UPDATE:
+ eDebug("DVD_SCREEN_UPDATE!");
+ if (m_subtitle_widget)
+ m_subtitle_widget->setPixmap(m_pixmap, eRect(0, 0, 720, 576));
+ break;
+ case DDVD_SHOWOSD_STATE_PLAY:
+ {
+ eDebug("DVD_SHOWOSD_STATE_PLAY!");
+ m_current_trick = 0;
+ m_event(this, evUser+1);
+ break;
+ }
+ case DDVD_SHOWOSD_STATE_PAUSE:
+ {
+ eDebug("DVD_SHOWOSD_STATE_PAUSE!");
+ m_event(this, evUser+2);
+ break;
+ }
+ case DDVD_SHOWOSD_STATE_FFWD:
+ {
+ eDebug("DVD_SHOWOSD_STATE_FFWD!");
+ m_event(this, evUser+3);
+ break;
+ }
+ case DDVD_SHOWOSD_STATE_FBWD:
+ {
+ eDebug("DVD_SHOWOSD_STATE_FBWD!");
+ m_event(this, evUser+4);
+ break;
+ }
+ case DDVD_SHOWOSD_STRING:
+ {
+ eDebug("DVD_SHOWOSD_STRING!");
+ m_event(this, evUser+5);
+ break;
+ }
+ case DDVD_SHOWOSD_AUDIO:
+ {
+ eDebug("DVD_SHOWOSD_STRING!");
+ m_event(this, evUser+6);
+ break;
+ }
+ case DDVD_SHOWOSD_SUBTITLE:
+ {
+ eDebug("DVD_SHOWOSD_SUBTITLE!");
+ m_event((iPlayableService*)this, evUpdatedInfo);
+ m_event(this, evUser+7);
+ break;
+ }
+ case DDVD_EOF_REACHED:
+ eDebug("DVD_EOF_REACHED!");
+ m_event(this, evEOF);
+ break;
+
+ case DDVD_SOF_REACHED:
+ eDebug("DVD_SOF_REACHED!");
+ m_event(this, evSOF);
+ break;
+ case DDVD_SHOWOSD_TIME:
+ {
+ static struct ddvd_time last_info;
+ struct ddvd_time info;
+ ddvd_get_last_time(m_ddvdconfig, &info);
+ int spu_id;
+ uint16_t spu_lang;
+ ddvd_get_last_spu(m_ddvdconfig, &spu_id, &spu_lang);
+ if ( info.pos_chapter != last_info.pos_chapter )
+ {
+ eDebug("DVD_SHOWOSD_TIME!");
+ m_event(this, evUser+8); // chapterUpdated
+ }
+ if ( info.pos_title != last_info.pos_title )
+ {
+ m_event(this, evUser+9); // titleUpdated
+ }
+ if ( info.pos_title == m_seekTitle && m_doSeekTo )
+ {
+ seekRelative( +1, m_doSeekTo );
+ m_doSeekTo = 0;
+ m_seekTitle = 0;
+ }
+ ddvd_get_last_time(m_ddvdconfig, &last_info);
+ break;
+ }
+ case DDVD_SHOWOSD_TITLESTRING:
+ {
+ ddvd_get_title_string(m_ddvdconfig, m_ddvd_titlestring);
+ eDebug("DDVD_SHOWOSD_TITLESTRING: %s",m_ddvd_titlestring);
+ loadCuesheet();
+ m_event(this, evStart);
+// m_event((iPlayableService*)this, evUpdatedEventInfo);
+// m_event(this, evUser+10);
+ break;
+ }
+ case DDVD_MENU_OPENED:
+ eDebug("DVD_MENU_OPENED!");
+ m_event(this, evUser+11);
+ break;
+ case DDVD_MENU_CLOSED:
+ eDebug("DVD_MENU_CLOSED!");
+ m_event(this, evUser+12);
+ break;
+ default:
+ break;
+ }
+}
+
+eServiceDVD::~eServiceDVD()
+{
+ eDebug("SERVICEDVD destruct!");
+ kill();
+ ddvd_close(m_ddvdconfig);
+}
+
+RESULT eServiceDVD::connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)
+{
+ connection = new eConnection((iPlayableService*)this, m_event.connect(event));
+ return 0;
+}
+
+RESULT eServiceDVD::start()
+{
+ assert(m_state == stIdle);
+ m_state = stRunning;
+ eDebug("eServiceDVD starting");
+ run();
+// m_event(this, evStart);
+ return 0;
+}
+
+RESULT eServiceDVD::stop()
+{
+ assert(m_state != stIdle);
+ if (m_state == stStopped)
+ return -1;
+ eDebug("DVD: stop %s", m_filename.c_str());
+ m_state = stStopped;
+ ddvd_send_key(m_ddvdconfig, DDVD_KEY_EXIT);
+#ifdef cue
+ struct ddvd_time info;
+ ddvd_get_last_time(m_ddvdconfig, &info);
+ if ( info.pos_chapter < info.end_chapter )
+ {
+ pts_t pos;
+ pos = info.pos_hours * 3600;
+ pos += info.pos_minutes * 60;
+ pos += info.pos_seconds;
+ pos *= 90000;
+ m_cue_pts = pos;
+ }
+ else // last chapter - usually credits, don't save cue
+ m_cue_pts = 0;
+ saveCuesheet();
+#endif
+ return 0;
+}
+
+RESULT eServiceDVD::setTarget(int target)
+{
+ return -1;
+}
+
+RESULT eServiceDVD::pause(ePtr<iPauseableService> &ptr)
+{
+ ptr=this;
+ return 0;
+}
+
+RESULT eServiceDVD::seek(ePtr<iSeekableService> &ptr)
+{
+ ptr=this;
+ return 0;
+}
+
+RESULT eServiceDVD::subtitle(ePtr<iSubtitleOutput> &ptr)
+{
+ ptr=this;
+ return 0;
+}
+
+RESULT eServiceDVD::keys(ePtr<iServiceKeys> &ptr)
+{
+ ptr=this;
+ return 0;
+}
+
+ // iPausableService
+RESULT eServiceDVD::setSlowMotion(int ratio)
+{
+ return -1;
+}
+
+RESULT eServiceDVD::setFastForward(int trick)
+{
+ eDebug("setTrickmode(%d)", trick);
+ while (m_current_trick > trick && m_current_trick != -64)
+ {
+ ddvd_send_key(m_ddvdconfig, DDVD_KEY_FBWD);
+ if (m_current_trick == 0)
+ m_current_trick = -2;
+ else if (m_current_trick > 0)
+ {
+ m_current_trick /= 2;
+ if (abs(m_current_trick) == 1)
+ m_current_trick=0;
+ }
+ else
+ m_current_trick *= 2;
+ }
+ while (m_current_trick < trick && m_current_trick != 64)
+ {
+ ddvd_send_key(m_ddvdconfig, DDVD_KEY_FFWD);
+ if (m_current_trick == 0)
+ m_current_trick = 2;
+ else if (m_current_trick < 0)
+ {
+ m_current_trick /= 2;
+ if (abs(m_current_trick) == 1)
+ m_current_trick=0;
+ }
+ else
+ m_current_trick *= 2;
+ }
+ return 0;
+}
+
+RESULT eServiceDVD::pause()
+{
+ ddvd_send_key(m_ddvdconfig, DDVD_KEY_PAUSE);
+ return 0;
+}
+
+RESULT eServiceDVD::unpause()
+{
+ ddvd_send_key(m_ddvdconfig, DDVD_KEY_PLAY);
+ return 0;
+}
+
+void eServiceDVD::thread()
+{
+ eDebug("eServiceDVD dvd thread started");
+ hasStarted();
+ ddvd_run(m_ddvdconfig);
+}
+
+void eServiceDVD::thread_finished()
+{
+ eDebug("eServiceDVD dvd thread finished");
+ m_pump.send(1); // inform main thread
+}
+
+RESULT eServiceDVD::info(ePtr<iServiceInformation>&i)
+{
+ i = this;
+ return 0;
+}
+
+RESULT eServiceDVD::getName(std::string &name)
+{
+ if ( m_ddvd_titlestring[0] != '\0' )
+ name = m_ddvd_titlestring;
+ else
+ name = m_filename;
+ return 0;
+}
+
+int eServiceDVD::getInfo(int w)
+{
+ switch (w)
+ {
+ case sUser:
+ case sArtist:
+ case sAlbum:
+ return resIsPyObject; // then getInfoObject should be called
+ case sComment:
+ case sTracknumber:
+ case sGenre:
+ return resIsString; // then getInfoString should be called
+ case evUser+8:
+ {
+ struct ddvd_time info;
+ ddvd_get_last_time(m_ddvdconfig, &info);
+ return info.pos_chapter;
+ }
+ case evUser+80:
+ {
+ struct ddvd_time info;
+ ddvd_get_last_time(m_ddvdconfig, &info);
+ return info.end_chapter;
+ }
+
+ case evUser+9:
+ {
+ struct ddvd_time info;
+ ddvd_get_last_time(m_ddvdconfig, &info);
+ return info.pos_title;
+ }
+ case evUser+90:
+ {
+ struct ddvd_time info;
+ ddvd_get_last_time(m_ddvdconfig, &info);
+ return info.end_title;
+ }
+
+ case sTXTPID: // we abuse HAS_TELEXT icon in InfoBar to signalize subtitles status
+ {
+ int spu_id;
+ uint16_t spu_lang;
+ ddvd_get_last_spu(m_ddvdconfig, &spu_id, &spu_lang);
+ return spu_id;
+ }
+ default:
+ return resNA;
+ }
+}
+
+std::string eServiceDVD::getInfoString(int w)
+{
+ switch(w)
+ {
+ case evUser+7: {
+ int spu_id;
+ uint16_t spu_lang;
+ ddvd_get_last_spu(m_ddvdconfig, &spu_id, &spu_lang);
+ unsigned char spu_string[3]={spu_lang >> 8, spu_lang, 0};
+ char osd[100];
+ if (spu_id == -1)
+ sprintf(osd,"");
+ else
+ sprintf(osd,"%d - %s",spu_id+1,spu_string);
+// lbo_changed=1;
+ return osd;
+ }
+ case evUser+6:
+ {
+ int audio_id,audio_type;
+ uint16_t audio_lang;
+ ddvd_get_last_audio(m_ddvdconfig, &audio_id, &audio_lang, &audio_type);
+ char audio_string[3]={audio_lang >> 8, audio_lang, 0};
+ char audio_form[5];
+ switch(audio_type)
+ {
+ case DDVD_MPEG:
+ sprintf(audio_form,"MPEG");
+ break;
+ case DDVD_AC3:
+ sprintf(audio_form,"AC3");
+ break;
+ case DDVD_DTS:
+ sprintf(audio_form,"DTS");
+ break;
+ case DDVD_LPCM:
+ sprintf(audio_form,"LPCM");
+ break;
+ default:
+ sprintf(audio_form,"-");
+ }
+ char osd[100];
+ sprintf(osd,"%d - %s (%s)",audio_id+1,audio_string,audio_form);
+ return osd;
+ }
+ default:
+ eDebug("unhandled getInfoString(%d)", w);
+ }
+ return "";
+}
+
+PyObject *eServiceDVD::getInfoObject(int w)
+{
+ switch(w)
+ {
+ default:
+ eDebug("unhandled getInfoObject(%d)", w);
+ }
+ Py_RETURN_NONE;
+}
+
+RESULT eServiceDVD::enableSubtitles(eWidget *parent, SWIG_PYOBJECT(ePyObject) entry)
+{
+ if (m_subtitle_widget)
+ delete m_subtitle_widget;
+ m_subtitle_widget = new eSubtitleWidget(parent);
+ m_subtitle_widget->resize(parent->size());
+ m_subtitle_widget->setPixmap(m_pixmap, eRect(0, 0, 720, 576));
+ m_subtitle_widget->setZPosition(-1);
+ m_subtitle_widget->show();
+ return 0;
+}
+
+RESULT eServiceDVD::disableSubtitles(eWidget *parent)
+{
+ delete m_subtitle_widget;
+ m_subtitle_widget = 0;
+ return 0;
+}
+
+PyObject *eServiceDVD::getSubtitleList()
+{
+ eDebug("eServiceDVD::getSubtitleList nyi");
+ Py_RETURN_NONE;
+}
+
+PyObject *eServiceDVD::getCachedSubtitle()
+{
+ eDebug("eServiceDVD::getCachedSubtitle nyi");
+ Py_RETURN_NONE;
+}
+
+RESULT eServiceDVD::getLength(pts_t &len)
+{
+// eDebug("eServiceDVD::getLength");
+ struct ddvd_time info;
+ ddvd_get_last_time(m_ddvdconfig, &info);
+ len = info.end_hours * 3600;
+ len += info.end_minutes * 60;
+ len += info.end_seconds;
+ len *= 90000;
+ return 0;
+}
+
+// RESULT eServiceDVD::seekTo(pts_t to)
+// {
+// struct ddvd_time info;
+// to /= 90000;
+// int cur;
+// ddvd_get_last_time(m_ddvdconfig, &info);
+// cur = info.pos_hours * 3600;
+// cur += info.pos_minutes * 60;
+// cur += info.pos_seconds;
+// eDebug("seekTo %lld, cur %d, diff %lld", to, cur, cur - to);
+// ddvd_skip_seconds(m_ddvdconfig, cur - to);
+// return 0;
+// }
+
+RESULT eServiceDVD::seekTo(pts_t to)
+{
+ m_seekTitle = 1;
+ eDebug("seekTo %lld", to);
+ ddvd_set_title(m_ddvdconfig, m_seekTitle);
+ m_doSeekTo = to;
+ return 0;
+}
+
+RESULT eServiceDVD::seekRelative(int direction, pts_t to)
+{
+ int seconds = to / 90000;
+ seconds *= direction;
+ eDebug("seekRelative %d %d", direction, seconds);
+ ddvd_skip_seconds(m_ddvdconfig, seconds);
+ return 0;
+}
+
+RESULT eServiceDVD::getPlayPosition(pts_t &pos)
+{
+ struct ddvd_time info;
+ ddvd_get_last_time(m_ddvdconfig, &info);
+ pos = info.pos_hours * 3600;
+ pos += info.pos_minutes * 60;
+ pos += info.pos_seconds;
+// eDebug("getPlayPosition %lld", pos);
+ pos *= 90000;
+ return 0;
+}
+
+RESULT eServiceDVD::seekChapter(int chapter)
+{
+ eDebug("setChapter %d", chapter);
+ if ( chapter > 0 )
+ ddvd_set_chapter(m_ddvdconfig, chapter);
+ return 0;
+}
+
+RESULT eServiceDVD::setTrickmode(int trick)
+{
+ return -1;
+}
+
+RESULT eServiceDVD::isCurrentlySeekable()
+{
+ return 1;
+}
+
+RESULT eServiceDVD::keyPressed(int key)
+{
+ switch(key)
+ {
+ case iServiceKeys::keyLeft:
+ ddvd_send_key(m_ddvdconfig, DDVD_KEY_LEFT);
+ break;
+ case iServiceKeys::keyRight:
+ ddvd_send_key(m_ddvdconfig, DDVD_KEY_RIGHT);
+ break;
+ case iServiceKeys::keyUp:
+ ddvd_send_key(m_ddvdconfig, DDVD_KEY_UP);
+ break;
+ case iServiceKeys::keyDown:
+ ddvd_send_key(m_ddvdconfig, DDVD_KEY_DOWN);
+ break;
+ case iServiceKeys::keyOk:
+ ddvd_send_key(m_ddvdconfig, DDVD_KEY_OK);
+ break;
+ case iServiceKeys::keyUser:
+ ddvd_send_key(m_ddvdconfig, DDVD_KEY_AUDIO);
+ break;
+ case iServiceKeys::keyUser+1:
+ ddvd_send_key(m_ddvdconfig, DDVD_KEY_SUBTITLE);
+ break;
+ case iServiceKeys::keyUser+2:
+ ddvd_send_key(m_ddvdconfig, DDVD_KEY_AUDIOMENU);
+ break;
+ case iServiceKeys::keyUser+3:
+ ddvd_send_key(m_ddvdconfig, DDVD_KEY_NEXT_CHAPTER);
+ break;
+ case iServiceKeys::keyUser+4:
+ ddvd_send_key(m_ddvdconfig, DDVD_KEY_PREV_CHAPTER);
+ break;
+ case iServiceKeys::keyUser+5:
+ ddvd_send_key(m_ddvdconfig, DDVD_KEY_NEXT_TITLE);
+ break;
+ case iServiceKeys::keyUser+6:
+ ddvd_send_key(m_ddvdconfig, DDVD_KEY_PREV_TITLE);
+ break;
+ case iServiceKeys::keyUser+7:
+ ddvd_send_key(m_ddvdconfig, DDVD_KEY_MENU);
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+#ifdef cue
+RESULT eServiceDVD::cueSheet(ePtr<iCueSheet> &ptr)
+{
+ if (m_cue_pts)
+ {
+ ptr = this;
+ return 0;
+ }
+ ptr = 0;
+ return -1;
+}
+
+PyObject *eServiceDVD::getCutList()
+{
+ ePyObject list = PyList_New(0);
+
+// for (std::multiset<struct cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
+// {
+ ePyObject tuple = PyTuple_New(2);
+// PyTuple_SetItem(tuple, 0, PyLong_FromLongLong(i->where));
+ PyTuple_SetItem(tuple, 0, PyLong_FromLongLong(m_cue_pts));
+// PyTuple_SetItem(tuple, 1, PyInt_FromLong(i->what));
+ PyTuple_SetItem(tuple, 1, PyInt_FromLong(3));
+ PyList_Append(list, tuple);
+ Py_DECREF(tuple);
+// }
+
+// eDebug("eServiceDVD::getCutList() pts=%lld",m_cue_pts);
+
+ return list;
+}
+
+void eServiceDVD::setCutList(ePyObject list)
+{
+ eDebug("eServiceDVD::setCutList()");
+
+ if (!PyList_Check(list))
+ return;
+ int size = PyList_Size(list);
+ int i;
+
+// m_cue_entries.clear();
+
+ for (i=0; i<size; ++i)
+ {
+ ePyObject tuple = PyList_GET_ITEM(list, i);
+ if (!PyTuple_Check(tuple))
+ {
+ eDebug("non-tuple in cutlist");
+ continue;
+ }
+ if (PyTuple_Size(tuple) != 2)
+ {
+ eDebug("cutlist entries need to be a 2-tuple");
+ continue;
+ }
+ ePyObject ppts = PyTuple_GET_ITEM(tuple, 0), ptype = PyTuple_GET_ITEM(tuple, 1);
+ if (!(PyLong_Check(ppts) && PyInt_Check(ptype)))
+ {
+ eDebug("cutlist entries need to be (pts, type)-tuples (%d %d)", PyLong_Check(ppts), PyInt_Check(ptype));
+ continue;
+ }
+// pts_t pts = PyLong_AsLongLong(ppts);
+ m_cue_pts = PyLong_AsLongLong(ppts);
+ int type = PyInt_AsLong(ptype);
+// m_cue_entries.insert(cueEntry(pts, type));
+ eDebug("eServiceDVD::setCutList() adding %08llx, %d", m_cue_pts, type);
+ }
+ m_cuesheet_changed = 1;
+
+// cutlistToCuesheet();
+ m_event((iPlayableService*)this, evCuesheetChanged);
+}
+
+void eServiceDVD::setCutListEnable(int enable)
+{
+ eDebug("eServiceDVD::setCutListEnable()");
+ m_cutlist_enabled = enable;
+// cutlistToCuesheet();
+}
+
+
+void eServiceDVD::loadCuesheet()
+{
+ eDebug("eServiceDVD::loadCuesheet()");
+ char filename[128];
+ if ( m_ddvd_titlestring[0] != '\0' )
+ snprintf(filename, 128, "/home/root/dvd-%s.cuts", m_ddvd_titlestring);
+
+ eDebug("eServiceDVD::loadCuesheet() filename=%s",filename);
+// m_cue_entries.clear();
+
+ FILE *f = fopen(filename, "rb");
+
+ if (f)
+ {
+ eDebug("loading cuts..");
+// while (1)
+ {
+ unsigned long long where;
+ unsigned int what;
+
+ if (!fread(&where, sizeof(where), 1, f))
+ return;
+ if (!fread(&what, sizeof(what), 1, f))
+ return;
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ where = bswap_64(where);
+#endif
+ what = ntohl(what);
+
+// if (what > 3)
+// break;
+
+ m_cue_pts = where;
+
+// m_cue_entries.insert(cueEntry(where, what));
+ }
+ fclose(f);
+// eDebug("%d entries", m_cue_entries.size());
+ } else
+ eDebug("cutfile not found!");
+
+ m_cuesheet_changed = 0;
+// cutlistToCuesheet();
+ eDebug("eServiceDVD::loadCuesheet() pts=%lld",m_cue_pts);
+
+ if (m_cue_pts)
+ m_event((iPlayableService*)this, evCuesheetChanged);
+}
+
+void eServiceDVD::saveCuesheet()
+{
+ eDebug("eServiceDVD::saveCuesheet() pts=%lld",m_cue_pts);
+ char filename[128];
+ if ( m_ddvd_titlestring[0] != '\0' )
+ snprintf(filename, 128, "/home/root/dvd-%s.cuts", m_ddvd_titlestring);
+
+ FILE *f = fopen(filename, "wb");
+
+ if (f)
+ {
+ unsigned long long where;
+ int what;
+
+// for (std::multiset<cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
+ {
+#if BYTE_ORDER == BIG_ENDIAN
+ where = m_cue_pts;
+// where = i->where;
+#else
+// where = bswap_64(i->where);
+ where = bswap_64(m_cue_pts);
+#endif
+// what = htonl(i->what);
+ what = 3;
+ fwrite(&where, sizeof(where), 1, f);
+ fwrite(&what, sizeof(what), 1, f);
+
+ }
+ fclose(f);
+ }
+
+ m_cuesheet_changed = 0;
+}
+#endif
+
+eAutoInitPtr<eServiceFactoryDVD> init_eServiceFactoryDVD(eAutoInitNumbers::service+1, "eServiceFactoryDVD");
+
+PyMODINIT_FUNC
+initservicedvd(void)
+{
+ Py_InitModule("servicedvd", NULL);
+}
diff --git a/lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.h b/lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.h
new file mode 100644
index 00000000..ed5d49bd
--- /dev/null
+++ b/lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.h
@@ -0,0 +1,166 @@
+#ifndef __servicedvd_h
+#define __servicedvd_h
+
+#include <lib/base/message.h>
+#include <lib/base/ebase.h>
+#include <lib/base/thread.h>
+#include <lib/service/iservice.h>
+
+#define cue
+
+class eSubtitleWidget;
+class gPixmap;
+class eStaticServiceDVDInfo;
+
+class eServiceFactoryDVD: public iServiceHandler
+{
+DECLARE_REF(eServiceFactoryDVD);
+public:
+ eServiceFactoryDVD();
+ virtual ~eServiceFactoryDVD();
+ enum { id = 0x1111 };
+
+ // iServiceHandler
+ RESULT play(const eServiceReference &, ePtr<iPlayableService> &ptr);
+ RESULT record(const eServiceReference &, ePtr<iRecordableService> &ptr);
+ RESULT list(const eServiceReference &, ePtr<iListableService> &ptr);
+ RESULT info(const eServiceReference &, ePtr<iStaticServiceInformation> &ptr);
+ RESULT offlineOperations(const eServiceReference &, ePtr<iServiceOfflineOperations> &ptr);
+};
+
+class eServiceDVD: public iPlayableService, public iPauseableService, public iSeekableService,
+ public iServiceInformation, public iSubtitleOutput, public iServiceKeys, public eThread, public Object
+#ifdef cue
+, public iCueSheet
+#endif
+{
+ friend class eServiceFactoryDVD;
+DECLARE_REF(eServiceDVD);
+public:
+ virtual ~eServiceDVD();
+ // not implemented (yet)
+ RESULT audioChannel(ePtr<iAudioChannelSelection> &ptr) { ptr = 0; return -1; }
+ RESULT audioTracks(ePtr<iAudioTrackSelection> &ptr) { ptr = 0; return -1; }
+ RESULT frontendInfo(ePtr<iFrontendInformation> &ptr) { ptr = 0; return -1; }
+ RESULT subServices(ePtr<iSubserviceList> &ptr) { ptr = 0; return -1; }
+ RESULT timeshift(ePtr<iTimeshiftService> &ptr) { ptr = 0; return -1; }
+ RESULT audioDelay(ePtr<iAudioDelay> &ptr) { ptr = 0; return -1; }
+ RESULT rdsDecoder(ePtr<iRdsDecoder> &ptr) { ptr = 0; return -1; }
+ RESULT stream(ePtr<iStreamableService> &ptr) { ptr = 0; return -1; }
+#ifdef cue
+ RESULT cueSheet(ePtr<iCueSheet> &ptr);
+#else
+ RESULT cueSheet(ePtr<iCueSheet> &ptr) { ptr = 0; return -1; }
+#endif
+
+ // iPlayableService
+ RESULT connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection);
+ RESULT start();
+ RESULT stop();
+ RESULT setTarget(int target);
+ RESULT info(ePtr<iServiceInformation> &ptr);
+ RESULT pause(ePtr<iPauseableService> &ptr);
+ RESULT subtitle(ePtr<iSubtitleOutput> &ptr);
+ RESULT seek(ePtr<iSeekableService> &ptr);
+ RESULT keys(ePtr<iServiceKeys> &ptr);
+
+ // iPausableService
+ RESULT pause();
+ RESULT unpause();
+ RESULT setSlowMotion(int ratio);
+ RESULT setFastForward(int ratio);
+
+ // iSubtitleOutput
+ RESULT enableSubtitles(eWidget *parent, SWIG_PYOBJECT(ePyObject) entry);
+ RESULT disableSubtitles(eWidget *parent);
+ PyObject *getSubtitleList();
+ PyObject *getCachedSubtitle();
+
+#if 1
+ // iSeekableService
+ RESULT getLength(pts_t &len);
+ RESULT seekTo(pts_t to);
+ RESULT seekRelative(int direction, pts_t to);
+ RESULT getPlayPosition(pts_t &pos);
+ RESULT setTrickmode(int trick=0);
+ RESULT isCurrentlySeekable();
+ RESULT seekChapter(int chapter);
+#endif
+
+ // iServiceInformation
+ RESULT getName(std::string &name);
+ int getInfo(int w);
+ std::string getInfoString(int w);
+ virtual PyObject *getInfoObject(int w);
+
+#ifdef cue
+ // iCueSheet
+ PyObject *getCutList();
+ void setCutList(SWIG_PYOBJECT(ePyObject));
+ void setCutListEnable(int enable);
+#endif
+ // iServiceKeys
+ RESULT keyPressed(int key);
+private:
+ eServiceDVD(const char *filename);
+
+ void gotMessage(int); // message from dvdlib
+ void gotThreadMessage(const int &); // message from dvd thread
+
+ // eThread
+ void thread();
+ void thread_finished();
+
+ std::string m_filename;
+
+ Signal2<void,iPlayableService*,int> m_event;
+
+ struct ddvd *m_ddvdconfig;
+ ePtr<gPixmap> m_pixmap;
+ eSubtitleWidget *m_subtitle_widget;
+
+ enum
+ {
+ stIdle, stRunning, stStopped,
+ };
+
+ int m_state;
+ int m_current_trick;
+
+ pts_t m_doSeekTo;
+ int m_seekTitle;
+ char m_ddvd_titlestring[96];
+
+ eSocketNotifier m_sn;
+ eFixedMessagePump<int> m_pump;
+
+#ifdef cue
+// ePtr<eCueSheet> m_cue;
+//
+// struct cueEntry
+// {
+// pts_t where;
+// unsigned int what;
+//
+// bool operator < (const struct cueEntry &o) const
+// {
+// return where < o.where;
+// }
+// cueEntry(const pts_t &where, unsigned int what) :
+// where(where), what(what)
+// {
+// }
+// };
+
+// std::multiset<cueEntry> m_cue_entries;
+ int m_cuesheet_changed, m_cutlist_enabled;
+ pts_t m_cue_pts;
+
+ void loadCuesheet();
+ void saveCuesheet();
+
+// void cutlistToCuesheet();
+#endif
+};
+
+#endif