Enable cuesheet (resume) support plus some spu/audio display fixes ***requires Aug...
authorAndreas Frisch <andreas.frisch@multimedia-labs.de>
Fri, 15 Aug 2008 15:21:54 +0000 (15:21 +0000)
committerAndreas Frisch <andreas.frisch@multimedia-labs.de>
Fri, 15 Aug 2008 15:21:54 +0000 (15:21 +0000)
lib/python/Plugins/Extensions/DVDPlayer/plugin.py
lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.cpp
lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.h

index 47807abe407547c6302191ce54b10de3bf694823..1db873761d5f8794b6c792c02be83f9cefd25fc2 100644 (file)
@@ -157,10 +157,9 @@ class ChapterZap(Screen):
                self.Timer.callback.append(self.keyOK)
                self.Timer.start(3000, True)
 
-class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarPVRState, InfoBarShowHide, HelpableScreen):
-#InfoBarCueSheetSupport, 
+class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarPVRState, InfoBarShowHide, HelpableScreen, InfoBarCueSheetSupport):
 #      ALLOW_SUSPEND = True
-#      ENABLE_RESUME_SUPPORT = True
+       ENABLE_RESUME_SUPPORT = True
        
        skin = """
        <screen name="DVDPlayer" flags="wfNoBorder" position="0,380" size="720,160" title="InfoBar" backgroundColor="transparent" >
@@ -233,7 +232,7 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP
                Screen.__init__(self, session)
                InfoBarBase.__init__(self)
                InfoBarNotifications.__init__(self)
-#              InfoBarCueSheetSupport.__init__(self, actionmap = "MediaPlayerCueSheetActions")
+               InfoBarCueSheetSupport.__init__(self, actionmap = "MediaPlayerCueSheetActions")
                InfoBarShowHide.__init__(self)
                HelpableScreen.__init__(self)
                self.save_infobar_seek_config()
@@ -244,7 +243,7 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP
 
                self.oldService = self.session.nav.getCurrentlyPlayingServiceReference()
                self.session.nav.stopService()
-               self["audioLabel"] = Label("1")
+               self["audioLabel"] = Label("n/a")
                self["subtitleLabel"] = Label("")
                self["chapterLabel"] = Label("")
                self.totalChapters = 0
@@ -265,7 +264,6 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP
                                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
                        })
@@ -422,15 +420,19 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP
                print "StringAvail"
 
        def __osdAudioInfoAvail(self):
-               audioString = self.service.info().getInfoString(iServiceInformation.sUser+6)
-               print "AudioInfoAvail "+audioString
+               audioTuple = self.service.info().getInfoObject(iServiceInformation.sUser+6)
+               print "AudioInfoAvail ", repr(audioTuple)
+               audioString = "%d: %s (%s)" % (audioTuple[0],audioTuple[1],audioTuple[2])
                self["audioLabel"].setText(audioString)
                if not self.in_menu:
                        self.doShow()
 
        def __osdSubtitleInfoAvail(self):
-               subtitleString = self.service.info().getInfoString(iServiceInformation.sUser+7)
-               print "SubtitleInfoAvail "+subtitleString
+               subtitleTuple = self.service.info().getInfoObject(iServiceInformation.sUser+7)
+               print "SubtitleInfoAvail ", repr(subtitleTuple)
+               subtitleString = ""
+               if subtitleTuple[0] is not 0:
+                       subtitleString = "%d: %s" % (subtitleTuple[0],subtitleTuple[1])
                self["subtitleLabel"].setText(subtitleString)
                if not self.in_menu:
                        self.doShow()
@@ -449,10 +451,6 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP
                if not self.in_menu:
                        self.doShow()
                
-       #def __initializeDVDinfo(self):
-               #self.__osdAudioInfoAvail()
-               #self.__osdSubtitleInfoAvail()
-
        def askLeavePlayer(self):
                if self.physicalDVD:
                        self.session.openWithCallback(self.exitCB, ChoiceBox, title=_("Leave DVD Player?"), list=[(_("Continue playing"), "play"), (_("Exit"), "exit")])
@@ -583,25 +581,12 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP
                self.restore_infobar_seek_config()
                self.session.nav.playService(self.oldService)
 
-#      def playLastCB(self, answer): # overwrite infobar cuesheet function
-#              print "playLastCB", answer, self.resume_point
-#              pos = self.resume_point
-#              title = self.resume_point % 90000
-#              pos -= title
-#              chapter = title % 256
-#              title /= 256
-#              print "pos", pos, "title", title, "chapter", chapter
-#              if self.service:
-#                      seek = self.service.seek()
-#                      if title != 1:
-#                              seek.seekTitle(title)
-#                              self.resume_state = 1
-#                      elif chapter != 1:
-#                              seek.seekChapter(chapter)
-#                              self.resume_state = 2
-#                      else:
-#                              seek.seekTo(pos)
-#              self.hideAfterResume()
+       def playLastCB(self, answer): # overwrite infobar cuesheet function
+               print "playLastCB", answer, self.resume_point
+               if self.service:
+                       seek = self.service.seek()
+                       seek.seekTo(self.resume_point)
+               self.hideAfterResume()
 
        def showAfterCuesheetOperation(self):
                if not self.in_menu:
index 30ebaecd154b6fff9d242ac54df2069d1126bccc..a756e751736e67f613cc2e2e1d012b0a5b4afd43 100644 (file)
@@ -1,5 +1,4 @@
 /* yes, it's dvd  */
-#include "servicedvd.h"
 #include <lib/base/eerror.h>
 #include <lib/base/object.h>
 #include <lib/base/ebase.h>
@@ -20,6 +19,7 @@
 extern "C" {
 #include <dreamdvd/ddvdlib.h>
 }
+#include "servicedvd.h"
 
 // eServiceFactoryDVD
 
@@ -254,6 +254,7 @@ eServiceDVD::~eServiceDVD()
 {
        eDebug("SERVICEDVD destruct!");
        kill();
+       saveCuesheet();
        ddvd_close(m_ddvdconfig);
 }
 
@@ -281,21 +282,7 @@ RESULT eServiceDVD::stop()
        eDebug("DVD: stop %s", m_filename.c_str());
        m_state = stStopped;
        ddvd_send_key(m_ddvdconfig, DDVD_KEY_EXIT);
-       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;
-               pos += info.pos_title * 256;
-               pos += info.pos_chapter;
-               m_cue_pts = pos;
-               eDebug("POS %llu\n", m_cue_pts);
-       }
-       saveCuesheet();
+
        return 0;
 }
 
@@ -413,14 +400,7 @@ RESULT eServiceDVD::getName(std::string &name)
 int eServiceDVD::getInfo(int w)
 {
        switch (w)
-               {
-               case sUser:
-               case sArtist:
-               case sAlbum:
-                       return resIsPyObject;  // then getInfoObject should be called
-               case sComment:
-               case sGenre:
-                       return resIsString;  // then getInfoString should be called
+       {
                case sCurrentChapter:
                {
                        struct ddvd_time info;
@@ -452,6 +432,9 @@ int eServiceDVD::getInfo(int w)
                        ddvd_get_last_spu(m_ddvdconfig, &spu_id, &spu_lang);
                        return spu_id;
                }
+               case sUser+6:
+               case sUser+7:
+                       return resIsPyObject;
                default:
                        return resNA;
        }
@@ -461,57 +444,65 @@ std::string eServiceDVD::getInfoString(int w)
 {
        switch(w)
        {
-               case sUser+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 sServiceref:
+                       break;
+               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 "";
-}
-
-PyObject *eServiceDVD::getInfoObject(int w)
-{
-       switch(w)
-       {
+                       else
+                       {
+                               PyTuple_SetItem(tuple, 0, PyInt_FromLong(spu_id+1));
+                               PyTuple_SetItem(tuple, 1, PyString_FromString(spu_string));
+                       }                               
+                       return tuple;
+               }
                default:
                        eDebug("unhandled getInfoObject(%d)", w);
        }
@@ -563,15 +554,12 @@ RESULT eServiceDVD::getLength(pts_t &len)
 
 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, to - cur);
-       ddvd_skip_seconds(m_ddvdconfig, to - cur);
+       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;
 }
 
@@ -701,10 +689,11 @@ void eServiceDVD::setCutListEnable(int /*enable*/)
 
 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_filename.c_str());
 
        eDebug("eServiceDVD::loadCuesheet() filename=%s",filename);
 
@@ -712,38 +701,65 @@ void eServiceDVD::loadCuesheet()
 
        if (f)
        {
-               eDebug("loading cuts..");
                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);
 
-               m_cue_pts = where;
+               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);
        } else
                eDebug("cutfile not found!");
 
-       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_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;
+       }
+
+       struct ddvd_resume resume_info;
+       ddvd_get_resume_pos(m_ddvdconfig, &resume_info);
+       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);
+
        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_filename.c_str());
        
        FILE *f = fopen(filename, "wb");
 
@@ -752,16 +768,19 @@ void eServiceDVD::saveCuesheet()
                unsigned long long where;
                int what;
 
-               {
 #if BYTE_ORDER == BIG_ENDIAN
-                       where = m_cue_pts;
+               where = m_cue_pts;
 #else
-                       where = bswap_64(m_cue_pts);
+               where = bswap_64(m_cue_pts);
 #endif
-                       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);
        }
 }
index d0a6bb359cc20cb0466f978c79333eddf538a1af..bdec483650c30dad80cecc1c6c763b68612ba9cb 100644 (file)
@@ -122,6 +122,8 @@ private:
        eFixedMessagePump<int> m_pump;
 
        pts_t m_cue_pts;
+       struct ddvd_resume m_resume_info;
+
        void loadCuesheet();
        void saveCuesheet();
 };