disable fast winding for non TS mediafiles until we have a usable solution for this..
[enigma2.git] / lib / python / Plugins / Extensions / DVDPlayer / src / servicedvd.cpp
index 016e16a16b4d4fa521e09c9b25b6186097e8bf0a..0372c49719edaf6d223af83fc119e32525535095 100644 (file)
@@ -1,8 +1,8 @@
 /* yes, it's dvd  */
-#include "servicedvd.h"
 #include <lib/base/eerror.h>
 #include <lib/base/object.h>
 #include <lib/base/ebase.h>
+#include <lib/base/nconfig.h>
 #include <string>
 #include <lib/service/service.h>
 #include <lib/base/init_num.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>
 }
+#include "servicedvd.h"
 
 // eServiceFactoryDVD
 
@@ -52,11 +51,11 @@ DEFINE_REF(eServiceFactoryDVD)
 RESULT eServiceFactoryDVD::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
 {
                // check resources...
-       ptr = new eServiceDVD(ref.path.c_str());
+       ptr = new eServiceDVD(ref);
        return 0;
 }
 
-RESULT eServiceFactoryDVD::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
+RESULT eServiceFactoryDVD::record(const eServiceReference &/*ref*/, ePtr<iRecordableService> &ptr)
 {
        ptr=0;
        return -1;
@@ -69,7 +68,7 @@ RESULT eServiceFactoryDVD::list(const eServiceReference &, ePtr<iListableService
 }
 
 
-RESULT eServiceFactoryDVD::info(const eServiceReference &ref, ePtr<iStaticServiceInformation> &ptr)
+RESULT eServiceFactoryDVD::info(const eServiceReference &/*ref*/, ePtr<iStaticServiceInformation> &ptr)
 {
        ptr=0;
        return -1;
@@ -85,31 +84,75 @@ RESULT eServiceFactoryDVD::offlineOperations(const eServiceReference &, ePtr<iSe
 
 DEFINE_REF(eServiceDVD);
 
-eServiceDVD::eServiceDVD(const char *filename):
-       m_filename(filename),
+eServiceDVD::eServiceDVD(eServiceReference ref):
+       m_ref(ref),
        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)
 {
+       int aspect = DDVD_16_9;
+       int policy = DDVD_PAN_SCAN;
+       int policy2 = DDVD_PAN_SCAN;
+
+       char tmp[255];
+       ssize_t rd;
+
+       m_sn = eSocketNotifier::create(eApp, ddvd_get_messagepipe_fd(m_ddvdconfig), eSocketNotifier::Read|eSocketNotifier::Priority|eSocketNotifier::Error|eSocketNotifier::Hungup);
        eDebug("SERVICEDVD construct!");
        // create handle
-       ddvd_set_dvd_path(m_ddvdconfig, filename);
+       ddvd_set_dvd_path(m_ddvdconfig, ref.path.c_str());
        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);
+
+       std::string ddvd_language;
+       if (!ePythonConfigQuery::getConfigValue("config.osd.language", ddvd_language))
+               ddvd_set_language(m_ddvdconfig, (ddvd_language.substr(0,2)).c_str());
+
+       int fd = open("/proc/stb/video/aspect", O_RDONLY);
+       if (fd > -1)
+       {
+               rd = read(fd, tmp, 255);
+               if (rd > 2 && !strncmp(tmp, "4:3", 3))
+                       aspect = DDVD_4_3;
+               else if (rd > 4 && !strncmp(tmp, "16:10", 5))
+                       aspect = DDVD_16_10;
+               close(fd);
+       }
+
+       fd = open("/proc/stb/video/policy", O_RDONLY);
+       if (fd > -1)
+       {
+               rd = read(fd, tmp, 255);
+               if (rd > 6 && !strncmp(tmp, "bestfit", 7))
+                       policy = DDVD_JUSTSCALE;
+               else if (rd > 8 && !strncmp(tmp, "letterbox", 9))
+                       policy = DDVD_LETTERBOX;
+               close(fd);
+       }
+
+#ifdef DDVD_SUPPORTS_16_10_SCALING
+       fd = open("/proc/stb/video/policy2", O_RDONLY);
+       if (fd > -1)
+       {
+               rd = read(fd, tmp, 255);
+               if (rd > 6 && !strncmp(tmp, "bestfit", 7))
+                       policy2 = DDVD_JUSTSCALE;
+               else if (rd > 8 && !strncmp(tmp, "letterbox", 9))
+                       policy2 = DDVD_LETTERBOX;
+               close(fd);
+       }
+       ddvd_set_video_ex(m_ddvdconfig, aspect, policy, policy2, DDVD_PAL /*unused*/);
+#else
+       ddvd_set_video(m_ddvdconfig, aspect, policy, DDVD_PAL /*unused*/);
+#warning please update libdreamdvd for 16:10 scaling support!
+#endif
+
+       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
+       pause();
 }
 
 void eServiceDVD::gotThreadMessage(const int &msg)
@@ -123,7 +166,7 @@ void eServiceDVD::gotThreadMessage(const int &msg)
        }
 }
 
-void eServiceDVD::gotMessage(int what)
+void eServiceDVD::gotMessage(int /*what*/)
 {
        switch(ddvd_get_next_message(m_ddvdconfig,1))
        {
@@ -152,8 +195,24 @@ void eServiceDVD::gotMessage(int what)
                }
                case DDVD_SCREEN_UPDATE:
                        eDebug("DVD_SCREEN_UPDATE!");
-                       if (m_subtitle_widget)
-                               m_subtitle_widget->setPixmap(m_pixmap, eRect(0, 0, 720, 576));
+                       if (m_subtitle_widget) {
+                               int x1,x2,y1,y2;
+                               ddvd_get_last_blit_area(m_ddvdconfig, &x1, &x2, &y1, &y2);
+                               
+                               int x_offset = 0, y_offset = 0, width = 720, height = 576;
+
+#ifdef DDVD_SUPPORTS_GET_BLIT_DESTINATION
+                               ddvd_get_blit_destination(m_ddvdconfig, &x_offset, &y_offset, &width, &height);
+                               eDebug("values got from ddvd: %d %d %d %d", x_offset, y_offset, width, height);
+                               y_offset = -y_offset;
+                               width -= x_offset * 2;
+                               height -= y_offset * 2;
+#endif
+                               eRect dest(x_offset, y_offset, width, height);
+
+                               if (dest.width() && dest.height())
+                                       m_subtitle_widget->setPixmap(m_pixmap, eRect(x1, y1, (x2-x1)+1, (y2-y1)+1), dest);
+                       }
                        break;
                case DDVD_SHOWOSD_STATE_PLAY:
                {
@@ -203,35 +262,29 @@ void eServiceDVD::gotMessage(int what)
                        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_ANGLE:
+               {
+                       int current, num;
+                       ddvd_get_angle_info(m_ddvdconfig, &current, &num);
+                       eDebug("DVD_ANGLE_INFO: %d / %d", current, num);
+                       m_event(this, evUser+13);
+                       break;
+               }
                case DDVD_SHOWOSD_TIME:
                {
                        static struct ddvd_time last_info;
                        struct ddvd_time info;
+//                     eDebug("DVD_SHOWOSD_TIME!");
                        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 )
-                       {
+                       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);
+                       memcpy(&last_info, &info, sizeof(struct ddvd_time));
                        break;
                }
                case DDVD_SHOWOSD_TITLESTRING:
@@ -239,17 +292,21 @@ void eServiceDVD::gotMessage(int what)
                        ddvd_get_title_string(m_ddvdconfig, m_ddvd_titlestring);
                        eDebug("DDVD_SHOWOSD_TITLESTRING: %s",m_ddvd_titlestring);
                        loadCuesheet();
+                       if (!m_cue_pts)
+                               unpause();
                        m_event(this, evStart);
-//                     m_event((iPlayableService*)this, evUpdatedEventInfo);
-//                     m_event(this, evUser+10);
                        break;
                }
                case DDVD_MENU_OPENED:
                        eDebug("DVD_MENU_OPENED!");
+                       m_state = stMenu;
+                       m_event(this, evSeekableStatusChanged);
                        m_event(this, evUser+11);
                        break;
                case DDVD_MENU_CLOSED:
                        eDebug("DVD_MENU_CLOSED!");
+                       m_state = stRunning;
+                       m_event(this, evSeekableStatusChanged);
                        m_event(this, evUser+12);
                        break;
                default:
@@ -261,7 +318,9 @@ eServiceDVD::~eServiceDVD()
 {
        eDebug("SERVICEDVD destruct!");
        kill();
+       saveCuesheet();
        ddvd_close(m_ddvdconfig);
+       disableSubtitles(0);
 }
 
 RESULT eServiceDVD::connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)
@@ -272,42 +331,26 @@ RESULT eServiceDVD::connectEvent(const Slot2<void,iPlayableService*,int> &event,
 
 RESULT eServiceDVD::start()
 {
-       assert(m_state == stIdle);
+       ASSERT(m_state == stIdle);
        m_state = stRunning;
        eDebug("eServiceDVD starting");
-       run();
 //     m_event(this, evStart);
        return 0;
 }
 
 RESULT eServiceDVD::stop()
 {
-       assert(m_state != stIdle);
+       ASSERT(m_state != stIdle);
        if (m_state == stStopped)
                return -1;
-       eDebug("DVD: stop %s", m_filename.c_str());
+       eDebug("DVD: stop %s", m_ref.path.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)
+RESULT eServiceDVD::setTarget(int /*target*/)
 {
        return -1;
 }
@@ -337,7 +380,7 @@ RESULT eServiceDVD::keys(ePtr<iServiceKeys> &ptr)
 }
 
        // iPausableService
-RESULT eServiceDVD::setSlowMotion(int ratio)
+RESULT eServiceDVD::setSlowMotion(int /*ratio*/)
 {
        return -1;
 }
@@ -378,12 +421,14 @@ RESULT eServiceDVD::setFastForward(int trick)
 
 RESULT eServiceDVD::pause()
 {
+       eDebug("set pause!\n");
        ddvd_send_key(m_ddvdconfig, DDVD_KEY_PAUSE);
        return 0;
 }
 
 RESULT eServiceDVD::unpause()
 {
+       eDebug("set unpause!\n");
        ddvd_send_key(m_ddvdconfig, DDVD_KEY_PLAY);
        return 0;
 }
@@ -412,48 +457,38 @@ RESULT eServiceDVD::getName(std::string &name)
        if ( m_ddvd_titlestring[0] != '\0' )
                name = m_ddvd_titlestring;
        else
-               name = m_filename;
+               name = m_ref.path;
        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:
+       {
+               case sCurrentChapter:
                {
                        struct ddvd_time info;
                        ddvd_get_last_time(m_ddvdconfig, &info);
                        return info.pos_chapter;
                }
-               case evUser+80:
+               case sTotalChapters:
                {
                        struct ddvd_time info;
                        ddvd_get_last_time(m_ddvdconfig, &info);
                        return info.end_chapter;
                }
-       
-               case evUser+9:
+               case sCurrentTitle:
                {
                        struct ddvd_time info;
                        ddvd_get_last_time(m_ddvdconfig, &info);
                        return info.pos_title;
                }
-               case evUser+90:
+               case sTotalTitles:
                {
                        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;
@@ -461,6 +496,10 @@ int eServiceDVD::getInfo(int w)
                        ddvd_get_last_spu(m_ddvdconfig, &spu_id, &spu_lang);
                        return spu_id;
                }
+               case sUser+6:
+               case sUser+7:
+               case sUser+8:
+                       return resIsPyObject;
                default:
                        return resNA;
        }
@@ -470,76 +509,109 @@ 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:
-                       {
+               case sServiceref:
+                       return m_ref.toString();
+               default:
+                       eDebug("unhandled getInfoString(%d)", w);
+       }
+       return "";
+}
+
+PyObject *eServiceDVD::getInfoObject(int w)
+{
+       switch(w)
+       {
+               case sUser+6:
+               {
+                       ePyObject tuple = PyTuple_New(3);
                        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];
+                       PyTuple_SetItem(tuple, 0, PyInt_FromLong(audio_id+1));
+                       PyTuple_SetItem(tuple, 1, PyString_FromString(audio_string));
                        switch(audio_type)
                        {
                                case DDVD_MPEG:
-                                       sprintf(audio_form,"MPEG");
+                                       PyTuple_SetItem(tuple, 2, PyString_FromString("MPEG"));
                                        break;
                                case DDVD_AC3:
-                                       sprintf(audio_form,"AC3");
+                                       PyTuple_SetItem(tuple, 2, PyString_FromString("AC3"));
                                        break;
                                case DDVD_DTS:
-                                       sprintf(audio_form,"DTS");
+                                       PyTuple_SetItem(tuple, 2, PyString_FromString("DTS"));
                                        break;
                                case DDVD_LPCM:
-                                       sprintf(audio_form,"LPCM");
+                                       PyTuple_SetItem(tuple, 2, PyString_FromString("LPCM"));
                                        break;
                                default:
-                                       sprintf(audio_form,"-");
+                                       PyTuple_SetItem(tuple, 2, PyString_FromString(""));
                        }
-                       char osd[100];
-                       sprintf(osd,"%d - %s (%s)",audio_id+1,audio_string,audio_form);
-                       return osd;
+                       return tuple;
+               }
+               case sUser+7:
+               {
+                       ePyObject tuple = PyTuple_New(2);
+                       int spu_id;
+                       uint16_t spu_lang;
+                       ddvd_get_last_spu(m_ddvdconfig, &spu_id, &spu_lang);
+                       char spu_string[3]={spu_lang >> 8, spu_lang, 0};
+                       if (spu_id == -1)
+                       {
+                               PyTuple_SetItem(tuple, 0, PyInt_FromLong(0));
+                               PyTuple_SetItem(tuple, 1, PyString_FromString(""));
                        }
-               default:
-                       eDebug("unhandled getInfoString(%d)", w);
-       }
-       return "";
-}
+                       else
+                       {
+                               PyTuple_SetItem(tuple, 0, PyInt_FromLong(spu_id+1));
+                               PyTuple_SetItem(tuple, 1, PyString_FromString(spu_string));
+                       }                               
+                       return tuple;
+               }
+               case sUser+8:
+               {
+                       ePyObject tuple = PyTuple_New(2);
+                       int current, num;
+                       ddvd_get_angle_info(m_ddvdconfig, &current, &num);
+                       PyTuple_SetItem(tuple, 0, PyInt_FromLong(current));
+                       PyTuple_SetItem(tuple, 1, PyInt_FromLong(num));
 
-PyObject *eServiceDVD::getInfoObject(int w)
-{
-       switch(w)
-       {
+                       return tuple;
+               }
                default:
                        eDebug("unhandled getInfoObject(%d)", w);
        }
        Py_RETURN_NONE;
 }
 
-RESULT eServiceDVD::enableSubtitles(eWidget *parent, SWIG_PYOBJECT(ePyObject) entry)
+RESULT eServiceDVD::enableSubtitles(eWidget *parent, SWIG_PYOBJECT(ePyObject) /*entry*/)
 {
-       if (m_subtitle_widget)
-               delete 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));
+
+       eSize size = eSize(720, 576);
+
+       if (!m_pixmap)
+       {
+               m_pixmap = new gPixmap(size, 32, 1); /* allocate accel surface (if possible) */
+#ifdef DDVD_SUPPORTS_GET_BLIT_DESTINATION
+               ddvd_set_lfb_ex(m_ddvdconfig, (unsigned char *)m_pixmap->surface->data, size.width(), size.height(), 4, size.width()*4, 1);
+#else
+               ddvd_set_lfb(m_ddvdconfig, (unsigned char *)m_pixmap->surface->data, size.width(), size.height(), 4, size.width()*4);
+#warning please update libdreamdvd for fast scaling
+#endif
+               run(); // start the thread
+       }
+
        m_subtitle_widget->setZPosition(-1);
        m_subtitle_widget->show();
+
        return 0;
 }
 
-RESULT eServiceDVD::disableSubtitles(eWidget *parent)
+RESULT eServiceDVD::disableSubtitles(eWidget */*parent*/)
 {
        delete m_subtitle_widget;
        m_subtitle_widget = 0;
@@ -570,26 +642,14 @@ RESULT eServiceDVD::getLength(pts_t &len)
        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;
+       eDebug("eServiceDVD::seekTo(%lld)",to);
+       if ( to > 0 )
+       {
+               eDebug("set_resume_pos: resume_info.title=%d, chapter=%d, block=%lu, audio_id=%d, audio_lock=%d, spu_id=%d, spu_lock=%d",m_resume_info.title,m_resume_info.chapter,m_resume_info.block,m_resume_info.audio_id, m_resume_info.audio_lock, m_resume_info.spu_id, m_resume_info.spu_lock);
+               ddvd_set_resume_pos(m_ddvdconfig, m_resume_info);
+       }
        return 0;
 }
 
@@ -614,6 +674,13 @@ RESULT eServiceDVD::getPlayPosition(pts_t &pos)
        return 0;
 }
 
+RESULT eServiceDVD::seekTitle(int title)
+{
+       eDebug("setTitle %d", title);
+       ddvd_set_title(m_ddvdconfig, title);
+       return 0;
+}
+
 RESULT eServiceDVD::seekChapter(int chapter)
 {
        eDebug("setChapter %d", chapter);
@@ -622,14 +689,14 @@ RESULT eServiceDVD::seekChapter(int chapter)
        return 0;
 }
 
-RESULT eServiceDVD::setTrickmode(int trick)
+RESULT eServiceDVD::setTrickmode(int /*trick*/)
 {
        return -1;
 }
 
 RESULT eServiceDVD::isCurrentlySeekable()
 {
-       return 1;
+       return m_state == stRunning ? 3 : 0;
 }
 
 RESULT eServiceDVD::keyPressed(int key)
@@ -675,13 +742,15 @@ RESULT eServiceDVD::keyPressed(int key)
        case iServiceKeys::keyUser+7:
                ddvd_send_key(m_ddvdconfig, DDVD_KEY_MENU);
                break;
+       case iServiceKeys::keyUser+8:
+               ddvd_send_key(m_ddvdconfig, DDVD_KEY_ANGLE);
+               break;
        default:
                return -1;
        }
        return 0;
 }
 
-#ifdef cue
 RESULT eServiceDVD::cueSheet(ePtr<iCueSheet> &ptr)
 {
        if (m_cue_pts)
@@ -695,130 +764,100 @@ RESULT eServiceDVD::cueSheet(ePtr<iCueSheet> &ptr)
 
 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);
-
+       ePyObject list = PyList_New(1);
+       ePyObject tuple = PyTuple_New(2);
+       PyTuple_SetItem(tuple, 0, PyLong_FromLongLong(m_cue_pts));
+       PyTuple_SetItem(tuple, 1, PyInt_FromLong(3));
+       PyList_SetItem(list, 0, tuple);
        return list;
 }
 
-void eServiceDVD::setCutList(ePyObject 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)
+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);
+       else
+               snprintf(filename, 128, "%s/dvd.cuts", m_ref.path.c_str());
 
        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;
-                       
+               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);
+               where = bswap_64(where);
 #endif
-                       what = ntohl(what);
-                       
-//                     if (what > 3)
-//                             break;
-
-                       m_cue_pts = where;
-                       
-//                     m_cue_entries.insert(cueEntry(where, what));
-               }
+               what = ntohl(what);
+
+               if (!fread(&m_resume_info, sizeof(struct ddvd_resume), 1, f))
+                       return;
+               if (!fread(&what, sizeof(what), 1, f))
+                       return;
+
+               what = ntohl(what);
+               if (what != 4 )
+                       return;
+
+               m_cue_pts = where;
+
                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);
+               eDebug("eServiceDVD::loadCuesheet() pts=%lld",m_cue_pts);
+       }
 }
 
 void eServiceDVD::saveCuesheet()
 {
-       eDebug("eServiceDVD::saveCuesheet() pts=%lld",m_cue_pts);
+       eDebug("eServiceDVD::saveCuesheet()");
+
+       struct ddvd_resume resume_info;
+       ddvd_get_resume_pos(m_ddvdconfig, &resume_info);
+
+       if (resume_info.title)
+       {
+               struct ddvd_time info;
+               ddvd_get_last_time(m_ddvdconfig, &info);
+               pts_t pos;
+               pos = info.pos_hours * 3600;
+               pos += info.pos_minutes * 60;
+               pos += info.pos_seconds;
+               pos *= 90000;
+               m_cue_pts = pos;
+               eDebug("ddvd_get_resume_pos resume_info.title=%d, chapter=%d, block=%lu, audio_id=%d, audio_lock=%d, spu_id=%d, spu_lock=%d  (pts=%llu)",resume_info.title,resume_info.chapter,resume_info.block,resume_info.audio_id, resume_info.audio_lock, resume_info.spu_id, resume_info.spu_lock,m_cue_pts);
+       }
+       else
+       {
+               eDebug("we're in a menu or somewhere else funny. so save cuesheet with pts=0");
+               m_cue_pts = 0;
+       }
+
        char filename[128];
        if ( m_ddvd_titlestring[0] != '\0' )
                snprintf(filename, 128, "/home/root/dvd-%s.cuts", m_ddvd_titlestring);
+       else
+               snprintf(filename, 128, "%s/dvd.cuts", m_ref.path.c_str());
        
        FILE *f = fopen(filename, "wb");
 
@@ -827,27 +866,22 @@ void eServiceDVD::saveCuesheet()
                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;
+               where = m_cue_pts;
 #else
-//                     where = bswap_64(i->where);
-                       where = bswap_64(m_cue_pts);
+               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);
-                       
-               }
+               what = htonl(3);
+               fwrite(&where, sizeof(where), 1, f);
+               fwrite(&what, sizeof(what), 1, f);
+               
+               what = htonl(4);
+               fwrite(&resume_info, sizeof(struct ddvd_resume), 1, f);
+               fwrite(&what, sizeof(what), 1, f);
+
                fclose(f);
        }
-       
-       m_cuesheet_changed = 0;
 }
-#endif
 
 eAutoInitPtr<eServiceFactoryDVD> init_eServiceFactoryDVD(eAutoInitNumbers::service+1, "eServiceFactoryDVD");