Merge branch 'master' of /home/tmbinc/enigma2-git
authorFelix Domke <tmbinc@elitedvb.net>
Sun, 10 May 2009 12:04:45 +0000 (14:04 +0200)
committerFelix Domke <tmbinc@elitedvb.net>
Sun, 10 May 2009 12:04:45 +0000 (14:04 +0200)
20 files changed:
data/menu.xml [changed mode: 0644->0755]
lib/base/smartptr.h
lib/dvb/decoder.cpp
lib/dvb/decoder.h
lib/dvb/frontend.cpp
lib/dvb_ci/dvbci.cpp
lib/dvb_ci/dvbci.h
lib/python/Components/Keyboard.py [new file with mode: 0755]
lib/python/Components/Makefile.am [changed mode: 0644->0755]
lib/python/Components/SetupDevices.py [changed mode: 0644->0755]
lib/python/Plugins/Extensions/DVDPlayer/plugin.py
lib/python/Plugins/SystemPlugins/SoftwareManager/BackupRestore.py
lib/python/Screens/EpgSelection.py
lib/python/enigma_python.i
lib/service/iservice.h
lib/service/servicedvb.cpp
lib/service/servicedvbrecord.cpp
lib/service/servicedvbrecord.h
lib/service/servicemp3.cpp
main/bsod.cpp

old mode 100644 (file)
new mode 100755 (executable)
index 8600053..c7fb889
                                        <item level="0" text="Filesystem Check..." entryID="harddisk_check"><screen module="HarddiskSetup" screen="HarddiskFsckSelection"/></item>
                                </menu>
                                <!--<item text="Remote Control"><setup id="rc" /></item>-->
-                               <!--<item text="Keyboard"><setup id="keyboard" /></item>-->
                                <!--<item text="OSD"><setup id="osd" /></item>-->
                                <item requires="Display"><setup level="1" id="lcd" /></item>
                                <item level="0" text="Network..." entryID="network_setup"><screen module="NetworkSetup" screen="NetworkAdapterSelection" /></item>
+                               <item text="Keyboard"><setup id="keyboard" /></item>
                                <!--<menu level="1" text="Network..." entryID="network_setup">
                                        <id val="network" />
                                        <item level="1" text="Device Setup..." entryID="device_setup"><screen module="NetworkSetup" screen="NetworkAdapterSelection"/></item>
index ac6b9eb..a2c6691 100644 (file)
@@ -57,11 +57,10 @@ public:
 #ifndef SWIG
        T* grabRef() { if (!ptr) return 0; ptr->AddRef(); return ptr; }
        T* &ptrref() { ASSERT(!ptr); return ptr; }
+       operator bool() const { return !!this->ptr; }
 #endif
        T* operator->() const { ptrAssert(ptr); return ptr; }
        operator T*() const { return this->ptr; }
-       
-       operator bool() const { return !!this->ptr; }
 };
 
 
index 0280fe5..30a80d1 100644 (file)
 #define dmxPesFilterParams dmx_pes_filter_params
 #define DMX_PES_VIDEO0 DMX_PES_VIDEO
 #define DMX_PES_AUDIO0 DMX_PES_AUDIO
+#define DMX_PES_PCR0 DMX_PES_PCR
 #define DMX_PES_VIDEO1 DMX_PES_VIDEO
 #define DMX_PES_AUDIO1 DMX_PES_AUDIO
+#define DMX_PES_PCR1 DMX_PES_PCR
 #include <ost/dmx.h>
 #include <ost/video.h>
 #include <ost/audio.h>
@@ -203,8 +205,7 @@ int eDVBAudio::startPid(int pid, int type)
                eDebug("failed (%m)");
        else
                eDebug("ok");
-       freeze();
-
+       freeze();  // why freeze here?!? this is a problem when only a pid change is requested... because of the unfreeze logic in Decoder::setState
        eDebugNoNewLine("AUDIO_PLAY - ");
        if (::ioctl(m_fd, AUDIO_PLAY) < 0)
                eDebug("failed (%m)");
@@ -285,7 +286,7 @@ int eDVBAudio::getPTS(pts_t &now)
 
 eDVBAudio::~eDVBAudio()
 {
-       unfreeze();
+       unfreeze();  // why unfreeze here... but not unfreeze video in ~eDVBVideo ?!?
        if (m_fd >= 0)
                ::close(m_fd);
        if (m_fd_demux >= 0)
@@ -448,7 +449,7 @@ int eDVBVideo::startPid(int pid, int type)
                return -errno;
        }
        eDebug("ok");
-       freeze();
+       freeze();  // why freeze here?!? this is a problem when only a pid change is requested... because of the unfreeze logic in Decoder::setState
        eDebugNoNewLine("VIDEO_PLAY - ");
        if (::ioctl(m_fd, VIDEO_PLAY) < 0)
                eDebug("failed (%m)");
@@ -687,7 +688,7 @@ int eDVBVideo::getFrameRate()
 
 DEFINE_REF(eDVBPCR);
 
-eDVBPCR::eDVBPCR(eDVBDemux *demux): m_demux(demux)
+eDVBPCR::eDVBPCR(eDVBDemux *demux, int dev): m_demux(demux), m_dev(dev)
 {
        char filename[128];
 #if HAVE_DVB_API_VERSION < 3
@@ -746,7 +747,7 @@ int eDVBPCR::startPid(int pid)
        pes.pid      = pid;
        pes.input    = DMX_IN_FRONTEND;
        pes.output   = DMX_OUT_DECODER;
-       pes.pes_type = DMX_PES_PCR;
+       pes.pes_type = m_dev ? DMX_PES_PCR1 : DMX_PES_PCR0; /* FIXME */
        pes.flags    = 0;
        eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - pcr - ", pid);
        if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
@@ -783,7 +784,8 @@ eDVBPCR::~eDVBPCR()
 
 DEFINE_REF(eDVBTText);
 
-eDVBTText::eDVBTText(eDVBDemux *demux): m_demux(demux)
+eDVBTText::eDVBTText(eDVBDemux *demux, int dev)
+    :m_demux(demux), m_dev(dev)
 {
        char filename[128];
 #if HAVE_DVB_API_VERSION < 3
@@ -805,7 +807,7 @@ int eDVBTText::startPid(int pid)
        pes.pid      = pid;
        pes.input    = DMX_IN_FRONTEND;
        pes.output   = DMX_OUT_DECODER;
-       pes.pes_type = DMX_PES_TELETEXT;
+       pes.pes_type = m_dev ? DMX_PES_TELETEXT1 : DMX_PES_TELETEXT0; // FIXME
        pes.flags    = 0;
 
        eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - ttx - ", pid);
@@ -815,7 +817,7 @@ int eDVBTText::startPid(int pid)
                return -errno;
        }
        eDebug("ok");
-       eDebugNoNewLine("DEMUX_START - pcr - ");
+       eDebugNoNewLine("DEMUX_START - ttx - ");
        if (::ioctl(m_fd_demux, DMX_START) < 0)
        {
                eDebug("failed(%m)");
@@ -961,7 +963,7 @@ int eTSMPEGDecoder::setState()
        {
                if ((m_pcrpid >= 0) && (m_pcrpid < 0x1FFF))
                {
-                       m_pcr = new eDVBPCR(m_demux);
+                       m_pcr = new eDVBPCR(m_demux, m_decoder);
                        if (m_pcr->startPid(m_pcrpid))
                                res = -1;
                }
@@ -992,7 +994,7 @@ int eTSMPEGDecoder::setState()
        {
                if ((m_textpid >= 0) && (m_textpid < 0x1FFF) && !nott)
                {
-                       m_text = new eDVBTText(m_demux);
+                       m_text = new eDVBTText(m_demux, m_decoder);
                        if (m_text->startPid(m_textpid))
                                res = -1;
                }
@@ -1093,7 +1095,7 @@ eTSMPEGDecoder::~eTSMPEGDecoder()
 
 RESULT eTSMPEGDecoder::setVideoPID(int vpid, int type)
 {
-       if (m_vpid != vpid)
+       if ((m_vpid != vpid) || (m_vtype != type))
        {
                m_changed |= changeVideo;
                m_vpid = vpid;
@@ -1174,7 +1176,9 @@ RESULT eTSMPEGDecoder::play()
                if (!m_changed)
                        return 0;
        }
-       else
+//     else  
+/* commented out because the changeState is needed to unfreeze decoders in decoder::setState... needed by normal pmt changes
+tmbinc please recheck this! */
        {
                m_state = statePlay;
                m_changed |= changeState;
index 51be514..3bfc70c 100644 (file)
@@ -80,9 +80,9 @@ class eDVBPCR: public iObject
        DECLARE_REF(eDVBPCR);
 private:
        ePtr<eDVBDemux> m_demux;
-       int m_fd_demux;
+       int m_fd_demux, m_dev;
 public:
-       eDVBPCR(eDVBDemux *demux);
+       eDVBPCR(eDVBDemux *demux, int dev);
 #if HAVE_DVB_API_VERSION < 3
        int setPid(int pid);
        int startPid();
@@ -98,9 +98,9 @@ class eDVBTText: public iObject
        DECLARE_REF(eDVBTText);
 private:
        ePtr<eDVBDemux> m_demux;
-       int m_fd_demux;
+       int m_fd_demux, m_dev;
 public:
-       eDVBTText(eDVBDemux *demux);
+       eDVBTText(eDVBDemux *demux, int dev);
        int startPid(int pid);
        void stop();
        virtual ~eDVBTText();
index a2ccf3b..e5e83b4 100644 (file)
@@ -379,7 +379,7 @@ RESULT eDVBFrontendParameters::calculateDifference(const iDVBFrontendParameters
                        terrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto)
                        diff = 1 << 30;
                else
-                       diff = abs(terrestrial.frequency - oterrestrial.frequency);
+                       diff = abs(terrestrial.frequency - oterrestrial.frequency) / 1000;
                return 0;
        default:
                return -1;
@@ -403,7 +403,7 @@ RESULT eDVBFrontendParameters::getHash(unsigned long &hash) const
                return 0;
        case iDVBFrontend::feTerrestrial:
                hash = 0xEEEE0000;
-               hash |= (terrestrial.frequency/1000)&0xFFFF;
+               hash |= (terrestrial.frequency/1000000)&0xFFFF;
                return 0;
        default:
                return -1;
index ce1f7d6..9583db5 100644 (file)
@@ -200,43 +200,39 @@ int eDVBCIInterfaces::cancelEnq(int slotid)
 
 void eDVBCIInterfaces::ciRemoved(eDVBCISlot *slot)
 {
-       eDebug("CI Slot %d: removed... usecount %d", slot->getSlotID(), slot->use_count);
-       for (PMTHandlerList::iterator it(m_pmt_handlers.begin());
-               it != m_pmt_handlers.end(); ++it)
+       if (slot->use_count)
        {
-               eServiceReferenceDVB ref;
-               it->pmthandler->getServiceReference(ref);
-               eDebugCI("check %s cislot %p %d\n", ref.toString().c_str(), it->cislot, it->cislot?it->cislot->getSlotID() : -1);
-               slot->removeService(ref.getServiceID().get());
-               if (slot->use_count && !--slot->use_count)
+               eDebug("CI Slot %d: removed... usecount %d", slot->getSlotID(), slot->use_count);
+               for (PMTHandlerList::iterator it(m_pmt_handlers.begin());
+                       it != m_pmt_handlers.end(); ++it)
                {
-                       if (slot->linked_next)
-                               slot->linked_next->setSource(slot->current_source);
-                       else // last CI in chain
-                               setInputSource(slot->current_tuner, slot->current_source);
-
                        if (it->cislot == slot) // remove the base slot
-                       {
                                it->cislot = slot->linked_next;
-                               eDebugCI("base removed.. so slot is now %p", it->cislot);
-                       }
-                       else
+                       else if (it->cislot)
                        {
-                               eDebugCI("not base removed.. %d", it->cislot->getSlotID());
-                               eDVBCISlot *tmp = it->cislot;
-                               while(tmp->linked_next != slot)
-                                       tmp = tmp->linked_next;
-                               ASSERT(tmp);
-                               if (slot->linked_next)
-                                       tmp->linked_next = slot->linked_next;
-                               else
-                                       tmp->linked_next = 0;
+                               eDVBCISlot *prevSlot = it->cislot, *hSlot = it->cislot->linked_next;
+                               while (hSlot)
+                               {
+                                       if (hSlot == slot) {
+                                               prevSlot->linked_next = slot->linked_next;
+                                               break;
+                                       }
+                                       prevSlot = hSlot;
+                                       hSlot = hSlot->linked_next;
+                               }
                        }
-                       slot->linked_next=0;
-                       slot->user_mapped=false;
                }
+               if (slot->linked_next)
+                       slot->linked_next->setSource(slot->current_source);
+               else // last CI in chain
+                       setInputSource(slot->current_tuner, slot->current_source);
+               slot->linked_next = 0;
+               slot->use_count=0;
+               slot->plugged=true;
+               slot->user_mapped=false;
+               slot->removeService(0xFFFF);
+               recheckPMTHandlers();
        }
-       recheckPMTHandlers();
 }
 
 static bool canDescrambleMultipleServices(int slotid)
@@ -268,22 +264,22 @@ void eDVBCIInterfaces::recheckPMTHandlers()
                eDVBCISlot *tmp = it->cislot;
                eDVBServicePMTHandler *pmthandler = it->pmthandler;
                eDVBServicePMTHandler::program p;
-               bool first_plugged_cis_exist = false;
+               bool plugged_cis_exist = false;
 
                pmthandler->getServiceReference(ref);
                pmthandler->getService(service);
 
                eDebugCI("recheck %p %s", pmthandler, ref.toString().c_str());
                for (eSmartPtrList<eDVBCISlot>::iterator ci_it(m_slots.begin()); ci_it != m_slots.end(); ++ci_it)
-                       if (ci_it->first_plugged && ci_it->getCAManager())
+                       if (ci_it->plugged && ci_it->getCAManager())
                        {
-                               eDebug("Slot %d first plugged", ci_it->getSlotID());
-                               ci_it->first_plugged = false;
-                               first_plugged_cis_exist = true;
+                               eDebug("Slot %d plugged", ci_it->getSlotID());
+                               ci_it->plugged = false;
+                               plugged_cis_exist = true;
                        }
 
                // check if this pmt handler has already assigned CI(s) .. and this CI(s) are already running
-               if (!first_plugged_cis_exist)
+               if (!plugged_cis_exist)
                {
                        while(tmp)
                        {
@@ -1041,7 +1037,7 @@ eDVBCISlot::eDVBCISlot(eMainloop *context, int nr)
        use_count = 0;
        linked_next = 0;
        user_mapped = false;
-       first_plugged = true;
+       plugged = true;
        
        slotid = nr;
 
index cdaaf90..de84e18 100644 (file)
@@ -65,7 +65,7 @@ class eDVBCISlot: public iObject, public Object
        int current_tuner;
        bool user_mapped;
        void data(int);
-       bool first_plugged;
+       bool plugged;
 public:
        enum {stateRemoved, stateInserted, stateInvalid, stateResetted};
        eDVBCISlot(eMainloop *context, int nr);
diff --git a/lib/python/Components/Keyboard.py b/lib/python/Components/Keyboard.py
new file mode 100755 (executable)
index 0000000..820d103
--- /dev/null
@@ -0,0 +1,47 @@
+from Components.Console import Console
+from os import listdir as os_listdir, path as os_path
+from re import compile as re_compile
+
+class Keyboard:
+       def __init__(self):
+               self.keyboardmaps = []
+               self.readKeyboardMapFiles()
+
+       def readKeyboardMapFiles(self):
+               for keymapfile in os_listdir('/usr/share/keymaps/'):
+                       if (keymapfile.endswith(".info")):
+                               f = open('/usr/share/keymaps/' + keymapfile)
+                               mapfile = None
+                               mapname = None
+                               for line in f:
+                                       m = re_compile('^\s*(\w+)\s*=\s*(.*)\s*$').match(line)
+                                       if m:
+                                               key, val = m.groups()
+                                               if key == 'kmap':
+                                                   mapfile = val
+                                               if key == 'name':
+                                                   mapname = val
+                                               if (mapfile is not None) and (mapname is not None):
+                                                   self.keyboardmaps.append(( mapfile,mapname))
+                               f.close()
+
+               if len(self.keyboardmaps) == 0:
+                       self.keyboardmaps = [('dream-de.kmap', 'Dreambox Keyboard Deutsch'), ('eng.kmap', 'Keyboard English')]
+
+       def activateKeyboardMap(self, index):
+               try:
+                       keymap = self.keyboardmaps[index]
+                       print "Activating keymap:",keymap[1]
+                       keymappath = '/usr/share/keymaps/' + keymap[0]
+                       if os_path.exists(keymappath):
+                               Console().ePopen(("loadkmap < " + str(keymappath)))
+               except:
+                       print "Selected keymap does not exist!"
+
+       def getKeyboardMaplist(self):
+               return self.keyboardmaps
+
+       def getDefaultKeyboardMap(self):
+               return 'eng.kmap'
+
+keyboard = Keyboard()
old mode 100644 (file)
new mode 100755 (executable)
index 67cec18..85e4d3e
@@ -18,4 +18,5 @@ install_PYTHON = \
        MultiContent.py MediaPlayer.py TunerInfo.py VideoWindow.py ChoiceList.py \
        Element.py Playlist.py ParentalControl.py ParentalControlList.py \
        Ipkg.py SelectionList.py Scanner.py SystemInfo.py DreamInfoHandler.py \
-       Task.py language_cache.py Console.py ResourceManager.py TuneTest.py
+       Task.py language_cache.py Console.py ResourceManager.py TuneTest.py \
+       Keyboard.py
old mode 100644 (file)
new mode 100755 (executable)
index 71fb1e4..b037ea7
@@ -1,6 +1,7 @@
 from config import config, ConfigSelection, ConfigSubsection, ConfigOnOff, ConfigText
 from Components.Timezones import timezones
 from Components.Language import language
+from Components.Keyboard import keyboard
 
 def InitSetupDevices():
        
@@ -11,8 +12,12 @@ def InitSetupDevices():
        config.timezone.val = ConfigSelection(default = timezones.getDefaultTimezone(), choices = timezones.getTimezoneList())
        config.timezone.val.addNotifier(timezoneNotifier)
 
+       def keyboardNotifier(configElement):
+               keyboard.activateKeyboardMap(configElement.index)
+
        config.keyboard = ConfigSubsection();
-       config.keyboard.keymap = ConfigSelection(choices = [("en", _("English")), ("de",_("German"))])
+       config.keyboard.keymap = ConfigSelection(default = keyboard.getDefaultKeyboardMap(), choices = keyboard.getKeyboardMaplist())
+       config.keyboard.keymap.addNotifier(keyboardNotifier)
 
        def languageNotifier(configElement):
                language.activateLanguage(configElement.value)
index e77b894..32e3593 100644 (file)
@@ -502,8 +502,10 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP
                choices = [(_("Exit"), "exit"), (_("Continue playing"), "play")]
                if True or not self.physicalDVD:
                        choices.insert(1,(_("Return to file browser"), "browser"))
-               if self.physicalDVD and not self.session.nav.getCurrentlyPlayingServiceReference().toString().endswith(harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())):
-                       choices.insert(0,(_("Play DVD"), "playPhysical" ))
+               if self.physicalDVD:
+                       cur = self.session.nav.getCurrentlyPlayingServiceReference()
+                       if cur and not cur.toString().endswith(harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())):
+                           choices.insert(0,(_("Play DVD"), "playPhysical" ))
                self.session.openWithCallback(self.exitCB, ChoiceBox, title=_("Leave DVD Player?"), list = choices)
 
        def sendKey(self, key):
index 65361ad..3925fc4 100755 (executable)
@@ -244,7 +244,7 @@ class RestoreMenu(Screen):
                        if (file.endswith(".tar.gz")):
                                self.flist.append((file))
                                self.entry = True
-                               self["filelist"].l.setList(self.flist)
+               self["filelist"].l.setList(self.flist)
 
        def KeyOk(self):
                if (self.exe == False) and (self.entry == True):
index d09ed00..3dde7e2 100644 (file)
@@ -6,6 +6,8 @@ from Components.Label import Label
 from Components.EpgList import EPGList, EPG_TYPE_SINGLE, EPG_TYPE_SIMILAR, EPG_TYPE_MULTI
 from Components.ActionMap import ActionMap
 from Components.TimerSanityCheck import TimerSanityCheck
+from Components.Sources.ServiceEvent import ServiceEvent
+from Components.Sources.Event import Event
 from Screens.TimerEdit import TimerSanityConflict
 from Screens.EventView import EventViewSimple
 from Screens.MessageBox import MessageBox
@@ -33,6 +35,8 @@ class EPGSelection(Screen):
                self["key_red"] = Button("")
                self.closeRecursive = False
                self.saved_title = None
+               self["Service"] = ServiceEvent()
+               self["Event"] = Event()
                if isinstance(service, str) and eventid != None:
                        self.type = EPG_TYPE_SIMILAR
                        self["key_yellow"] = Button()
@@ -153,6 +157,7 @@ class EPGSelection(Screen):
                        l.moveToService(self.session.nav.getCurrentlyPlayingServiceReference())
                elif self.type == EPG_TYPE_SINGLE:
                        service = self.currentService
+                       self["Service"].newService(service.ref)
                        if self.saved_title is None:
                                self.saved_title = self.instance.getTitle()
                        title = self.saved_title + ' - ' + service.getServiceName()
@@ -306,6 +311,7 @@ class EPGSelection(Screen):
                                self.key_red_choice = self.EMPTY
                        return
                event = cur[0]
+               self["Event"].newEvent(event)
                if self.type == EPG_TYPE_MULTI:
                        count = self["list"].getCurrentChangeCount()
                        if self.ask_time != -1:
@@ -328,8 +334,12 @@ class EPGSelection(Screen):
                                else:
                                        datestr = '%s %d.%d.'%(_("Today"), begTime[2], begTime[1])
                        self["date"].setText(datestr)
+                       if cur[1] is None:
+                               self["Service"].newService(None)
+                       else:
+                               self["Service"].newService(cur[1].ref)
 
-               if cur[1] is None  or cur[1].getServiceName() == "":
+               if cur[1] is None or cur[1].getServiceName() == "":
                        if self.key_green_choice != self.EMPTY:
                                self["key_green"].setText("")
                                self.key_green_choice = self.EMPTY
index bdf1b14..fe0e71e 100644 (file)
@@ -262,7 +262,10 @@ RESULT SwigFromPython(ePtr<gPixmap> &result, PyObject *obj)
 
        res = 0;
        result = 0;
-       if (SWIG_Python_ConvertPtr(obj, (void **)&res, SWIGTYPE_p_ePtrTgPixmap_t, SWIG_POINTER_EXCEPTION | 0))
+#ifndef SWIGTYPE_p_ePtrT_gPixmap_t
+#define SWIGTYPE_p_ePtrT_gPixmap_t SWIGTYPE_p_ePtrTgPixmap_t
+#endif
+       if (SWIG_Python_ConvertPtr(obj, (void **)&res, SWIGTYPE_p_ePtrT_gPixmap_t, SWIG_POINTER_EXCEPTION | 0))
                return -1;
        if (!res)
                return -1;
@@ -277,7 +280,10 @@ PyObject *New_eServiceReference(const eServiceReference &ref)
 PyObject *New_iRecordableServicePtr(const ePtr<iRecordableService> &ptr)
 {
     ePtr<iRecordableService> *result = new ePtr<iRecordableService>(ptr);
-    return SWIG_NewPointerObj((void*)(result), SWIGTYPE_p_ePtrTiRecordableService_t, 1);
+#ifndef SWIGTYPE_p_ePtrT_iRecordableService_t
+#define SWIGTYPE_p_ePtrT_iRecordableService_t SWIGTYPE_p_ePtrTiRecordableService_t
+#endif
+    return SWIG_NewPointerObj((void*)(result), SWIGTYPE_p_ePtrT_iRecordableService_t, 1);
 }
 %}
 
index 7b85c8f..22ffde6 100644 (file)
@@ -138,6 +138,10 @@ public:
                data[3]=data3;
                data[4]=data4;
        }
+       operator bool() const
+       {
+               return valid();
+       }
 #endif
        eServiceReference(int type, int flags, const std::string &path)
                : type(type), flags(flags), path(path)
@@ -170,10 +174,6 @@ public:
                        return r < 0;
                return path < c.path;
        }
-       operator bool() const
-       {
-               return valid();
-       }
        
        int valid() const
        {
@@ -867,7 +867,8 @@ public:
                evRecordStopped,
                evNewProgramInfo,
                evRecordFailed,
-               evRecordWriteError
+               evRecordWriteError,
+               evNewEventInfo
        };
        enum {
                NoError=0,
@@ -899,6 +900,7 @@ public:
        virtual RESULT stop()=0;
        virtual SWIG_VOID(RESULT) frontendInfo(ePtr<iFrontendInformation> &SWIG_OUTPUT)=0;
        virtual SWIG_VOID(RESULT) stream(ePtr<iStreamableService> &SWIG_OUTPUT)=0;
+       virtual SWIG_VOID(RESULT) subServices(ePtr<iSubserviceList> &SWIG_OUTPUT)=0;
 };
 SWIG_TEMPLATE_TYPEDEF(ePtr<iRecordableService>, iRecordableServicePtr);
 
index c844216..45a12ce 100644 (file)
@@ -1737,7 +1737,7 @@ int eDVBServicePlay::selectAudioStream(int i)
 
        m_current_audio_pid = apid;
 
-       if (m_decoder->setAudioPID(apid, apidtype))
+       if (m_is_primary && m_decoder->setAudioPID(apid, apidtype))
        {
                eDebug("set audio pid failed");
                return -4;
@@ -2307,6 +2307,9 @@ void eDVBServicePlay::updateDecoder()
                        m_decode_demux->getMPEGDecoder(m_decoder, m_is_primary);
                        if (m_decoder)
                                m_decoder->connectVideoEvent(slot(*this, &eDVBServicePlay::video_event), m_video_event_connection);
+               }
+               if (m_decode_demux && m_is_primary)
+               {
                        m_teletext_parser = new eDVBTeletextParser(m_decode_demux);
                        m_teletext_parser->connectNewPage(slot(*this, &eDVBServicePlay::newSubtitlePage), m_new_subtitle_page_connection);
                        m_subtitle_parser = new eDVBSubtitleParser(m_decode_demux);
@@ -2375,9 +2378,11 @@ void eDVBServicePlay::updateDecoder()
                else
                        m_decoder->setSyncPCR(-1);
 
-               m_decoder->setTextPID(tpid);
-
-               m_teletext_parser->start(program.textPid);
+               if (m_is_primary)
+               {
+                       m_decoder->setTextPID(tpid);
+                       m_teletext_parser->start(program.textPid);
+               }
 
                if (vpid > 0 && vpid < 0x2000)
                        ;
index 6978849..d9cdb51 100644 (file)
@@ -389,7 +389,7 @@ int eDVBServiceRecord::doRecord()
                        std::set_difference(
                                        m_pids_active.begin(), m_pids_active.end(),
                                        pids_to_record.begin(), pids_to_record.end(), 
-                                       std::inserter(new_pids, new_pids.begin())
+                                       std::inserter(obsolete_pids, obsolete_pids.begin())
                                        );
                        
                        for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i)
@@ -503,6 +503,8 @@ void eDVBServiceRecord::gotNewEvent()
                eDebug("[eDVBServiceRecord] now running: %s (%d seconds)", event_now->getEventName().c_str(), event_now->getDuration());
        
        m_last_event_id = event_id;
+
+       m_event((iRecordableService*)this, evNewEventInfo);
 }
 
 void eDVBServiceRecord::saveCutlist()
@@ -548,3 +550,29 @@ void eDVBServiceRecord::saveCutlist()
        }
        
 }
+
+RESULT eDVBServiceRecord::subServices(ePtr<iSubserviceList> &ptr)
+{
+       ptr = this;
+       return 0;
+}
+
+int eDVBServiceRecord::getNumberOfSubservices()
+{
+       ePtr<eServiceEvent> evt;
+       if (!m_event_handler.getEvent(evt, 0))
+               return evt->getNumOfLinkageServices();
+       return 0;
+}
+
+RESULT eDVBServiceRecord::getSubservice(eServiceReference &sub, unsigned int n)
+{
+       ePtr<eServiceEvent> evt;
+       if (!m_event_handler.getEvent(evt, 0))
+       {
+               if (!evt->getLinkageService(sub, m_ref, n))
+                       return 0;
+       }
+       sub.type=eServiceReference::idInvalid;
+       return -1;
+}
index e70547f..319fbb7 100644 (file)
@@ -13,6 +13,7 @@
 class eDVBServiceRecord: public eDVBServiceBase,
        public iRecordableService, 
        public iStreamableService,
+       public iSubserviceList,
        public Object
 {
        DECLARE_REF(eDVBServiceRecord);
@@ -25,10 +26,14 @@ public:
        RESULT stream(ePtr<iStreamableService> &ptr);
        RESULT getError(int &error) { error = m_error; return 0; }
        RESULT frontendInfo(ePtr<iFrontendInformation> &ptr);
+       RESULT subServices(ePtr<iSubserviceList> &ptr);
 
                /* streamable service */
        PyObject *getStreamingData();
 
+               // iSubserviceList
+       int getNumberOfSubservices();
+       RESULT getSubservice(eServiceReference &subservice, unsigned int n);
 private:
        enum { stateIdle, statePrepared, stateRecording };
        bool m_simulate;
index f8eb194..79098f2 100644 (file)
@@ -441,6 +441,7 @@ RESULT eServiceMP3::pause()
 
 RESULT eServiceMP3::unpause()
 {
+       m_subtitle_pages.clear();
        if (!m_gst_playbin || m_state != stRunning)
                return -1;
 
@@ -476,6 +477,8 @@ RESULT eServiceMP3::getLength(pts_t &pts)
 
 RESULT eServiceMP3::seekTo(pts_t to)
 {
+       m_subtitle_pages.clear();
+
        if (!m_gst_playbin)
                return -1;
 
@@ -1277,7 +1280,7 @@ void eServiceMP3::pushSubtitles()
        GstElement *appsink = gst_bin_get_by_name(GST_BIN(m_gst_playbin),"subtitle_sink");
        GstClock *clock;
        clock = gst_element_get_clock (appsink);
-       do
+       while ( !m_subtitle_pages.empty() )
        {
                page = m_subtitle_pages.front();
 
@@ -1296,7 +1299,7 @@ void eServiceMP3::pushSubtitles()
                        m_subtitle_widget->setPage(page);
                        m_subtitle_pages.pop_front();
                }
-       } while ( !m_subtitle_pages.empty() );
+       } ;
 
        gst_object_unref (clock);
 }
@@ -1330,6 +1333,7 @@ RESULT eServiceMP3::enableSubtitles(eWidget *parent, ePyObject tuple)
        g_object_get (G_OBJECT (m_gst_playbin), "current-text", &text_pid, NULL);
 
        eDebug ("eServiceMP3::switched to subtitle stream %i", text_pid);
+       m_subtitle_pages.clear();
 
        return 0;
 
@@ -1342,6 +1346,7 @@ error_out:
 RESULT eServiceMP3::disableSubtitles(eWidget *parent)
 {
        eDebug("eServiceMP3::disableSubtitles");
+       m_subtitle_pages.clear();
        delete m_subtitle_widget;
        m_subtitle_widget = 0;
        return 0;
index 017f910..aeb31c4 100644 (file)
@@ -93,9 +93,9 @@ void bsodFatal(const char *component)
                                break;
                        end = lines.rfind("/", end);
                                /* skip a potential prefix to the path */
-                       unsigned int path_prefix = lines.find("/image/", start);
-                       if (path_prefix != std::string::npos && ((path_prefix + 6) < end))
-                               start = path_prefix + 6;
+                       unsigned int path_prefix = lines.find("/usr/", start);
+                       if (path_prefix != std::string::npos && path_prefix < end)
+                               start = path_prefix;
 
                        if (end == std::string::npos)
                                break;