From 17be24380f07656d14b88baf5af0d9ef3d8eddfd Mon Sep 17 00:00:00 2001 From: Andreas Monzner Date: Tue, 15 Apr 2008 12:47:41 +0000 Subject: [PATCH] add DVDPlayer plugin (not final yet) not working without libdreamdvd (not in OE yet) --- configure.ac | 3 + lib/python/Plugins/Extensions/DVDPlayer/.cvsignore | 4 + lib/python/Plugins/Extensions/DVDPlayer/LICENSE | 12 + .../Plugins/Extensions/DVDPlayer/Makefile.am | 9 + .../Plugins/Extensions/DVDPlayer/__init__.py | 1 + lib/python/Plugins/Extensions/DVDPlayer/keymap.xml | 36 + lib/python/Plugins/Extensions/DVDPlayer/plugin.py | 535 +++++++++++++ .../Plugins/Extensions/DVDPlayer/src/.cvsignore | 5 + .../Plugins/Extensions/DVDPlayer/src/Makefile.am | 11 + .../Extensions/DVDPlayer/src/servicedvd.cpp | 858 +++++++++++++++++++++ .../Plugins/Extensions/DVDPlayer/src/servicedvd.h | 166 ++++ lib/python/Plugins/Extensions/Makefile.am | 2 +- 12 files changed, 1641 insertions(+), 1 deletion(-) create mode 100644 lib/python/Plugins/Extensions/DVDPlayer/.cvsignore create mode 100644 lib/python/Plugins/Extensions/DVDPlayer/LICENSE create mode 100644 lib/python/Plugins/Extensions/DVDPlayer/Makefile.am create mode 100644 lib/python/Plugins/Extensions/DVDPlayer/__init__.py create mode 100644 lib/python/Plugins/Extensions/DVDPlayer/keymap.xml create mode 100644 lib/python/Plugins/Extensions/DVDPlayer/plugin.py create mode 100644 lib/python/Plugins/Extensions/DVDPlayer/src/.cvsignore create mode 100644 lib/python/Plugins/Extensions/DVDPlayer/src/Makefile.am create mode 100644 lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.cpp create mode 100644 lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.h diff --git a/configure.ac b/configure.ac index 20b9736..b429a17 100644 --- a/configure.ac +++ b/configure.ac @@ -114,6 +114,9 @@ lib/python/Plugins/Extensions/FileManager/Makefile lib/python/Plugins/Extensions/CutListEditor/Makefile lib/python/Plugins/Extensions/MediaScanner/Makefile lib/python/Plugins/Extensions/MediaPlayer/Makefile +lib/python/Plugins/Extensions/DVDPlayer/Makefile +lib/python/Plugins/Extensions/DVDPlayer/src/Makefile +lib/python/Plugins/Extensions/DVDPlayer/data/Makefile lib/python/Plugins/Extensions/PicturePlayer/Makefile lib/python/Plugins/Extensions/PicturePlayer/data/Makefile lib/python/Plugins/Extensions/GraphMultiEPG/Makefile diff --git a/lib/python/Plugins/Extensions/DVDPlayer/.cvsignore b/lib/python/Plugins/Extensions/DVDPlayer/.cvsignore new file mode 100644 index 0000000..138b9cc --- /dev/null +++ b/lib/python/Plugins/Extensions/DVDPlayer/.cvsignore @@ -0,0 +1,4 @@ +*.pyc +*.pyo +Makefile +Makefile.in diff --git a/lib/python/Plugins/Extensions/DVDPlayer/LICENSE b/lib/python/Plugins/Extensions/DVDPlayer/LICENSE new file mode 100644 index 0000000..9970059 --- /dev/null +++ b/lib/python/Plugins/Extensions/DVDPlayer/LICENSE @@ -0,0 +1,12 @@ +This plugin is licensed under the Creative Commons +Attribution-NonCommercial-ShareAlike 3.0 Unported +License. To view a copy of this license, visit +http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative +Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA. + +Alternatively, this plugin may be distributed and executed on hardware which +is licensed by Dream Multimedia GmbH. + +This plugin is NOT free software. It is open source, you are allowed to +modify it (if you keep the license), but it may not be commercially +distributed other than under the conditions noted above. diff --git a/lib/python/Plugins/Extensions/DVDPlayer/Makefile.am b/lib/python/Plugins/Extensions/DVDPlayer/Makefile.am new file mode 100644 index 0000000..ed47415 --- /dev/null +++ b/lib/python/Plugins/Extensions/DVDPlayer/Makefile.am @@ -0,0 +1,9 @@ +SUBDIRS = src + +installdir = $(LIBDIR)/enigma2/python/Plugins/Extensions/DVDPlayer + +install_PYTHON = \ + __init__.py \ + plugin.py \ + keymap.xml \ + LICENSE diff --git a/lib/python/Plugins/Extensions/DVDPlayer/__init__.py b/lib/python/Plugins/Extensions/DVDPlayer/__init__.py new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/lib/python/Plugins/Extensions/DVDPlayer/__init__.py @@ -0,0 +1 @@ + diff --git a/lib/python/Plugins/Extensions/DVDPlayer/keymap.xml b/lib/python/Plugins/Extensions/DVDPlayer/keymap.xml new file mode 100644 index 0000000..b8b4994 --- /dev/null +++ b/lib/python/Plugins/Extensions/DVDPlayer/keymap.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + diff --git a/lib/python/Plugins/Extensions/DVDPlayer/plugin.py b/lib/python/Plugins/Extensions/DVDPlayer/plugin.py new file mode 100644 index 0000000..856c7d1 --- /dev/null +++ b/lib/python/Plugins/Extensions/DVDPlayer/plugin.py @@ -0,0 +1,535 @@ +from os import path as os_path, remove as os_remove, listdir as os_listdir, system +from time import strftime +from enigma import eTimer, iPlayableService, eServiceCenter, iServiceInformation, eServiceReference, iServiceKeys +from Screens.Screen import Screen +from Screens.MessageBox import MessageBox +from Screens.ChoiceBox import ChoiceBox +from Screens.InputBox import InputBox +from Screens.HelpMenu import HelpableScreen +from Screens.InfoBarGenerics import InfoBarSeek, InfoBarPVRState, InfoBarCueSheetSupport, InfoBarShowHide, InfoBarNotifications +from Components.ActionMap import ActionMap, NumberActionMap, HelpableActionMap +from Components.Label import Label +from Components.FileList import FileList +from Components.ServiceEventTracker import ServiceEventTracker +from Components.config import config +from Components.ProgressBar import ProgressBar +from ServiceReference import ServiceReference +from Tools.Directories import pathExists, fileExists + +import random +import servicedvd # load c++ part of dvd player plugin + +class FileBrowser(Screen): + skin = """ + + + """ + def __init__(self, session): + Screen.__init__(self, session) + currDir = "/media/dvd/" + if not pathExists(currDir): + currDir = "/" + #else: + #print system("mount "+currDir) + self.filelist = FileList(currDir, matchingPattern = "(?i)^.*\.(iso)", useServiceRef = True) + self["filelist"] = self.filelist + + self["FilelistActions"] = ActionMap(["OkCancelActions"], + { + "ok": self.ok, + "cancel": self.exit + }) + + def ok(self): + if self["filelist"].getFilename().upper().endswith("VIDEO_TS/"): + print "dvd structure found, trying to open..." + self.close(self["filelist"].getFilename()[0:-9]) + + elif self["filelist"].canDescent(): # isDir + self["filelist"].descent() + + else: + self.close(self["filelist"].getFilename()) + + def exit(self): + self.close(None) + +class DVDSummary(Screen): + skin = """ + + + Name + + + + + Position + + + Position + + """ + + def __init__(self, session, parent): + Screen.__init__(self, session, parent) + + self["DVDPlayer"] = Label("DVD Player") + self["Title"] = Label("") + self["Time"] = Label("") + self["Chapter"] = Label("") + + def updateChapter(self, chapter): + self["Chapter"].setText(chapter) + + def setTitle(self, title): + self["Title"].setText(title) + +class DVDOverlay(Screen): + skin = """""" + def __init__(self, session, args = None): + Screen.__init__(self, session) + +class ChapterZap(Screen): + skin = """ + + + + """ + + def quit(self): + self.Timer.stop() + self.close(0) + + def keyOK(self): + self.Timer.stop() + self.close(int(self["number"].getText())) + + def keyNumberGlobal(self, number): + self.Timer.start(3000, True) #reset timer + self.field = self.field + str(number) + self["number"].setText(self.field) + if len(self.field) >= 4: + self.keyOK() + + def __init__(self, session, number): + Screen.__init__(self, session) + self.field = str(number) + + self["chapter"] = Label(_("Chapter:")) + + self["number"] = Label(self.field) + + self["actions"] = NumberActionMap( [ "SetupActions" ], + { + "cancel": self.quit, + "ok": self.keyOK, + "1": self.keyNumberGlobal, + "2": self.keyNumberGlobal, + "3": self.keyNumberGlobal, + "4": self.keyNumberGlobal, + "5": self.keyNumberGlobal, + "6": self.keyNumberGlobal, + "7": self.keyNumberGlobal, + "8": self.keyNumberGlobal, + "9": self.keyNumberGlobal, + "0": self.keyNumberGlobal + }) + + self.Timer = eTimer() + self.Timer.callback.append(self.keyOK) + self.Timer.start(3000, True) + +class DVDPlayer(Screen, InfoBarNotifications, InfoBarSeek, InfoBarCueSheetSupport, InfoBarPVRState, InfoBarShowHide, HelpableScreen): + ALLOW_SUSPEND = True + ENABLE_RESUME_SUPPORT = True + + skin = """ + + + + + + + + + + Name + + + + + + + + + HasTelext + + + + + + Position,ShowHours + + + + Gauge + + + + Remaining,Negate,ShowHours + + """ + + def save_infobar_seek_config(self): + self.saved_config_speeds_forward = config.seek.speeds_forward.value + self.saved_config_speeds_backward = config.seek.speeds_backward.value + self.saved_config_enter_forward = config.seek.enter_forward.value + self.saved_config_enter_backward = config.seek.enter_backward.value + self.saved_config_seek_stepwise_minspeed = config.seek.stepwise_minspeed.value + self.saved_config_seek_stepwise_repeat = config.seek.stepwise_repeat.value + self.saved_config_seek_on_pause = config.seek.on_pause.value + self.saved_config_seek_speeds_slowmotion = config.seek.speeds_slowmotion.value + + def change_infobar_seek_config(self): + config.seek.speeds_forward.value = [2, 4, 8, 16, 32, 64] + config.seek.speeds_backward.value = [8, 16, 32, 64] + config.seek.speeds_slowmotion.value = [ ] + config.seek.enter_forward.value = "2" + config.seek.enter_backward.value = "2" + config.seek.stepwise_minspeed.value = "Never" + config.seek.stepwise_repeat.value = "3" + config.seek.on_pause.value = "play" + + def restore_infobar_seek_config(self): + config.seek.speeds_forward.value = self.saved_config_speeds_forward + config.seek.speeds_backward.value = self.saved_config_speeds_backward + config.seek.speeds_slowmotion.value = self.saved_config_seek_speeds_slowmotion + config.seek.enter_forward.value = self.saved_config_enter_forward + config.seek.enter_backward.value = self.saved_config_enter_backward + config.seek.stepwise_minspeed.value = self.saved_config_seek_stepwise_minspeed + config.seek.stepwise_repeat.value = self.saved_config_seek_stepwise_repeat + config.seek.on_pause.value = self.saved_config_seek_on_pause + + def __init__(self, session, args = None): + Screen.__init__(self, session) + InfoBarNotifications.__init__(self) + InfoBarCueSheetSupport.__init__(self, actionmap = "MediaPlayerCueSheetActions") + InfoBarShowHide.__init__(self) + HelpableScreen.__init__(self) + self.save_infobar_seek_config() + self.change_infobar_seek_config() + InfoBarSeek.__init__(self) + InfoBarPVRState.__init__(self) + self.dvdScreen = self.session.instantiateDialog(DVDOverlay) + + self.oldService = self.session.nav.getCurrentlyPlayingServiceReference() + self.session.nav.stopService() + self["audioLabel"] = Label("1") + self["subtitleLabel"] = Label("") + self["chapterLabel"] = Label("") + self.totalChapters = 0 + self.currentChapter = 0 + self.totalTitles = 0 + self.currentTitle = 0 + + self.__event_tracker = ServiceEventTracker(screen=self, eventmap= + { + iPlayableService.evUser: self.__timeUpdated, + iPlayableService.evUser+1: self.__statePlay, + iPlayableService.evUser+2: self.__statePause, + iPlayableService.evUser+3: self.__osdFFwdInfoAvail, + iPlayableService.evUser+4: self.__osdFBwdInfoAvail, + iPlayableService.evUser+5: self.__osdStringAvail, + iPlayableService.evUser+6: self.__osdAudioInfoAvail, + iPlayableService.evUser+7: self.__osdSubtitleInfoAvail, + iPlayableService.evUser+8: self.__chapterUpdated, + iPlayableService.evUser+9: self.__titleUpdated, + #iPlayableService.evUser+10: self.__initializeDVDinfo, + iPlayableService.evUser+11: self.__menuOpened, + iPlayableService.evUser+12: self.__menuClosed + }) + + self["DVDPlayerDirectionActions"] = HelpableActionMap(self, "DirectionActions", + { + #MENU KEY DOWN ACTIONS + "left": (self.keyLeft, _("DVD left key")), + "right": (self.keyRight, _("DVD right key")), + "up": (self.keyUp, _("DVD up key")), + "down": (self.keyDown, _("DVD down key")), + + #MENU KEY REPEATED ACTIONS + "leftRepeated": self.doNothing, + "rightRepeated": self.doNothing, + "upRepeated": self.doNothing, + "downRepeated": self.doNothing, + + #MENU KEY UP ACTIONS + "leftUp": self.doNothing, + "rightUp": self.doNothing, + "upUp": self.doNothing, + "downUp": self.doNothing, + }, -2) + + self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", + { + "ok": (self.keyOk, _("DVD ENTER key")), + "cancel": self.keyCancel, + }, -2) + + self["DVDPlayerPlaybackActions"] = HelpableActionMap(self, "DVDPlayerActions", + { + #PLAYER ACTIONS + "dvdMenu": (self.enterDVDMenu, _("show DVD main menu")), + "toggleInfo": (self.toggleInfo, _("toggle time, chapter, audio, subtitle info")), + "nextChapter": (self.nextChapter, _("forward to the next chapter")), + "prevChapter": (self.prevChapter, _("rewind to the previous chapter")), + "nextTitle": (self.nextTitle, _("jump forward to the next title")), + "prevTitle": (self.prevTitle, _("jump back to the previous title")), + "tv": (self.askLeavePlayer, _("exit DVD player or return to file browser")), + "dvdAudioMenu": (self.enterDVDAudioMenu, _("(show optional DVD audio menu)")), + "nextAudioTrack": (self.nextAudioTrack, _("switch to the next audio track")), + "nextSubtitleTrack": (self.nextSubtitleTrack, _("switch to the next subtitle language")), + "seekBeginning": (self.seekBeginning, _("Jump to video title 1 (play movie from start)")), + }, -2) + + self["NumberActions"] = NumberActionMap( [ "NumberActions"], + { + "1": self.keyNumberGlobal, + "2": self.keyNumberGlobal, + "3": self.keyNumberGlobal, + "4": self.keyNumberGlobal, + "5": self.keyNumberGlobal, + "6": self.keyNumberGlobal, + "7": self.keyNumberGlobal, + "8": self.keyNumberGlobal, + "9": self.keyNumberGlobal, + "0": self.keyNumberGlobal, + }) + + self.onClose.append(self.__onClose) + self.onFirstExecBegin.append(self.showFileBrowser) + self.service = None + self.in_menu = False + + def keyNumberGlobal(self, number): + print "You pressed number " + str(number) + self.session.openWithCallback(self.numberEntered, ChapterZap, number) + + def numberEntered(self, retval): +# print self.servicelist + if retval > 0: + self.zapToNumber(retval) + + def serviceStarted(self): #override InfoBarShowHide function + pass + + def doEofInternal(self, playing): + if self.in_menu: + self.hide() + + def __menuOpened(self): + self.hide() + self.in_menu = True + + def __menuClosed(self): + self.show() + self.in_menu = False + + def setChapterLabel(self): + chapterLCD = "Menu" + chapterOSD = "DVD Menu" + if self.currentTitle > 0: + chapterLCD = "%s %d" % (_("Chap."), self.currentChapter) + chapterOSD = "DVD %s %d/%d" % (_("Chapter"), self.currentChapter, self.totalChapters) + chapterOSD += " (%s %d/%d)" % (_("Title"), self.currentTitle, self.totalTitles) + self["chapterLabel"].setText(chapterOSD) + try: + self.session.summary.updateChapter(chapterLCD) + except: + pass + + def doNothing(self): + pass + + def toggleInfo(self): + if not self.in_menu: + self.toggleShow() + print "toggleInfo" + + def __timeUpdated(self): + print "timeUpdated" + + def __statePlay(self): + print "statePlay" + + def __statePause(self): + print "statePause" + + def __osdFFwdInfoAvail(self): + self.setChapterLabel() + print "FFwdInfoAvail" + + def __osdFBwdInfoAvail(self): + self.setChapterLabel() + print "FBwdInfoAvail" + + def __osdStringAvail(self): + print "StringAvail" + + def __osdAudioInfoAvail(self): + audioString = self.service.info().getInfoString(iPlayableService.evUser+6) + print "AudioInfoAvail "+audioString + self["audioLabel"].setText(audioString) + self.doShow() + + def __osdSubtitleInfoAvail(self): + subtitleString = self.service.info().getInfoString(iPlayableService.evUser+7) + print "SubtitleInfoAvail "+subtitleString + self["subtitleLabel"].setText(subtitleString) + self.doShow() + + def __chapterUpdated(self): + self.currentChapter = self.service.info().getInfo(iPlayableService.evUser+8) + self.totalChapters = self.service.info().getInfo(iPlayableService.evUser+80) + self.setChapterLabel() + print "__chapterUpdated: %d/%d" % (self.currentChapter, self.totalChapters) + + def __titleUpdated(self): + self.currentTitle = self.service.info().getInfo(iPlayableService.evUser+9) + self.totalTitles = self.service.info().getInfo(iPlayableService.evUser+90) + self.setChapterLabel() + print "__titleUpdated: %d/%d" % (self.currentTitle, self.totalTitles) + self.doShow() + + #def __initializeDVDinfo(self): + #self.__osdAudioInfoAvail() + #self.__osdSubtitleInfoAvail() + + def askLeavePlayer(self): + self.session.openWithCallback(self.exitCB, ChoiceBox, title=_("Leave DVD Player?"), list=[(_("Exit"), "exit"), (_("Return to file browser"), "browser"), (_("Continue playing"), "play")]) + + def nextAudioTrack(self): + if self.service: + self.service.keys().keyPressed(iServiceKeys.keyUser) + + def nextSubtitleTrack(self): + if self.service: + self.service.keys().keyPressed(iServiceKeys.keyUser+1) + + def enterDVDAudioMenu(self): + if self.service: + self.service.keys().keyPressed(iServiceKeys.keyUser+2) + + def nextChapter(self): + if self.service: + self.service.keys().keyPressed(iServiceKeys.keyUser+3) + + def prevChapter(self): + if self.service: + self.service.keys().keyPressed(iServiceKeys.keyUser+4) + + def nextTitle(self): + if self.service: + self.service.keys().keyPressed(iServiceKeys.keyUser+5) + + def prevTitle(self): + if self.service: + self.service.keys().keyPressed(iServiceKeys.keyUser+6) + + def enterDVDMenu(self): + if self.service: + self.service.keys().keyPressed(iServiceKeys.keyUser+7) + + def seekBeginning(self): + if self.service: + seekable = self.getSeek() + if seekable is not None: + seekable.seekTo(0) + + def zapToNumber(self, number): + if self.service: + seekable = self.getSeek() + if seekable is not None: + print "seek to chapter %d" % number + seekable.seekChapter(number) + +# MENU ACTIONS + def keyRight(self): + if self.service: + self.service.keys().keyPressed(iServiceKeys.keyRight) + + def keyLeft(self): + if self.service: + self.service.keys().keyPressed(iServiceKeys.keyLeft) + + def keyUp(self): + if self.service: + self.service.keys().keyPressed(iServiceKeys.keyUp) + + def keyDown(self): + if self.service: + self.service.keys().keyPressed(iServiceKeys.keyDown) + + def keyOk(self): + if self.service: + self.service.keys().keyPressed(iServiceKeys.keyOk) + + def keyCancel(self): + self.askLeavePlayer() + + def showFileBrowser(self): + self.session.openWithCallback(self.FileBrowserClosed, FileBrowser) + + def FileBrowserClosed(self, val): + curref = self.session.nav.getCurrentlyPlayingServiceReference() + print "FileBrowserClosed", val + if val is None: + self.askLeavePlayer() + else: + newref = eServiceReference(4369, 0, val) + print "play", newref.toString() + if curref is None or curref != newref: + self.session.nav.playService(newref) + self.service = self.session.nav.getCurrentService() + print "self.service", self.service + print "cur_dlg", self.session.current_dialog + self.dvdScreen.show() + self.service.subtitle().enableSubtitles(self.dvdScreen.instance, None) + + def exitCB(self, answer): + if answer is not None: + if answer[1] == "exit": + if self.service: + self.dvdScreen.hide() + self.service.subtitle().disableSubtitles(self.session.current_dialog.instance) + self.service = None + self.close() + if answer[1] == "browser": + #TODO check here if a paused dvd playback is already running... then re-start it... + #else + self.showFileBrowser() + else: + pass + + def __onClose(self): + self.restore_infobar_seek_config() + self.session.nav.playService(self.oldService) + + def showAfterCuesheetOperation(self): + self.show() + + def createSummary(self): + print "DVDCreateSummary" + return DVDSummary + +def main(session, **kwargs): + session.open(DVDPlayer) + +def menu(menuid, **kwargs): + if menuid == "mainmenu": + return [(_("DVD Player"), main, "dvd_player", 46)] + return [] + +from Plugins.Plugin import PluginDescriptor +def Plugins(**kwargs): + return [PluginDescriptor(name = "DVDPlayer", description = "Play DVDs", where = PluginDescriptor.WHERE_MENU, fnc = menu)] diff --git a/lib/python/Plugins/Extensions/DVDPlayer/src/.cvsignore b/lib/python/Plugins/Extensions/DVDPlayer/src/.cvsignore new file mode 100644 index 0000000..4181869 --- /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 0000000..bb02291 --- /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 0000000..016e16a --- /dev/null +++ b/lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.cpp @@ -0,0 +1,858 @@ +/* yes, it's dvd */ +#include "servicedvd.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef cue +#include +#include +#ifndef BYTE_ORDER +#error no byte order defined! +#endif +#endif //cue + +extern "C" { +#include +} + +// eServiceFactoryDVD + +eServiceFactoryDVD::eServiceFactoryDVD() +{ + ePtr sc; + + eServiceCenter::getPrivInstance(sc); + if (sc) + { + std::list extensions; + extensions.push_back("iso"); + sc->addServiceFactory(eServiceFactoryDVD::id, this, extensions); + } +} + +eServiceFactoryDVD::~eServiceFactoryDVD() +{ + ePtr sc; + + eServiceCenter::getPrivInstance(sc); + if (sc) + sc->removeServiceFactory(eServiceFactoryDVD::id); +} + +DEFINE_REF(eServiceFactoryDVD) + + // iServiceHandler +RESULT eServiceFactoryDVD::play(const eServiceReference &ref, ePtr &ptr) +{ + // check resources... + ptr = new eServiceDVD(ref.path.c_str()); + return 0; +} + +RESULT eServiceFactoryDVD::record(const eServiceReference &ref, ePtr &ptr) +{ + ptr=0; + return -1; +} + +RESULT eServiceFactoryDVD::list(const eServiceReference &, ePtr &ptr) +{ + ptr=0; + return -1; +} + + +RESULT eServiceFactoryDVD::info(const eServiceReference &ref, ePtr &ptr) +{ + ptr=0; + return -1; +} + +RESULT eServiceFactoryDVD::offlineOperations(const eServiceReference &, ePtr &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: \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 &event, ePtr &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 &ptr) +{ + ptr=this; + return 0; +} + +RESULT eServiceDVD::seek(ePtr &ptr) +{ + ptr=this; + return 0; +} + +RESULT eServiceDVD::subtitle(ePtr &ptr) +{ + ptr=this; + return 0; +} + +RESULT eServiceDVD::keys(ePtr &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&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 &ptr) +{ + if (m_cue_pts) + { + ptr = this; + return 0; + } + ptr = 0; + return -1; +} + +PyObject *eServiceDVD::getCutList() +{ + ePyObject list = PyList_New(0); + +// for (std::multiset::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 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::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 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 0000000..ed5d49b --- /dev/null +++ b/lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.h @@ -0,0 +1,166 @@ +#ifndef __servicedvd_h +#define __servicedvd_h + +#include +#include +#include +#include + +#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 &ptr); + RESULT record(const eServiceReference &, ePtr &ptr); + RESULT list(const eServiceReference &, ePtr &ptr); + RESULT info(const eServiceReference &, ePtr &ptr); + RESULT offlineOperations(const eServiceReference &, ePtr &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 &ptr) { ptr = 0; return -1; } + RESULT audioTracks(ePtr &ptr) { ptr = 0; return -1; } + RESULT frontendInfo(ePtr &ptr) { ptr = 0; return -1; } + RESULT subServices(ePtr &ptr) { ptr = 0; return -1; } + RESULT timeshift(ePtr &ptr) { ptr = 0; return -1; } + RESULT audioDelay(ePtr &ptr) { ptr = 0; return -1; } + RESULT rdsDecoder(ePtr &ptr) { ptr = 0; return -1; } + RESULT stream(ePtr &ptr) { ptr = 0; return -1; } +#ifdef cue + RESULT cueSheet(ePtr &ptr); +#else + RESULT cueSheet(ePtr &ptr) { ptr = 0; return -1; } +#endif + + // iPlayableService + RESULT connectEvent(const Slot2 &event, ePtr &connection); + RESULT start(); + RESULT stop(); + RESULT setTarget(int target); + RESULT info(ePtr &ptr); + RESULT pause(ePtr &ptr); + RESULT subtitle(ePtr &ptr); + RESULT seek(ePtr &ptr); + RESULT keys(ePtr &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 m_event; + + struct ddvd *m_ddvdconfig; + ePtr 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 m_pump; + +#ifdef cue +// ePtr 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 m_cue_entries; + int m_cuesheet_changed, m_cutlist_enabled; + pts_t m_cue_pts; + + void loadCuesheet(); + void saveCuesheet(); + +// void cutlistToCuesheet(); +#endif +}; + +#endif diff --git a/lib/python/Plugins/Extensions/Makefile.am b/lib/python/Plugins/Extensions/Makefile.am index e0a7f81..5970477 100644 --- a/lib/python/Plugins/Extensions/Makefile.am +++ b/lib/python/Plugins/Extensions/Makefile.am @@ -1,2 +1,2 @@ -SUBDIRS = TuxboxPlugins FileManager CutListEditor PicturePlayer MediaScanner MediaPlayer IpkgInstaller GraphMultiEPG SocketMMI +SUBDIRS = TuxboxPlugins FileManager CutListEditor PicturePlayer MediaScanner MediaPlayer IpkgInstaller GraphMultiEPG SocketMMI DVDPlayer # SimpleRSS is still not finished -- 2.7.4