add lockState and syncState to getFrontendInfo call
[enigma2.git] / lib / service / servicedvb.cpp
index 3d5510163516d8b94026e2d5c9827b6660afecb0..c3bd1e6920776734eb7df68110332eeb7c792672 100644 (file)
@@ -11,6 +11,7 @@
 #include <lib/dvb/decoder.h>
 
 #include <lib/service/servicedvbrecord.h>
+#include <lib/service/event.h>
 #include <lib/dvb/metaparser.h>
 #include <lib/dvb/tstools.h>
 #include <lib/python/python.h>
@@ -20,6 +21,8 @@
 #include <byteswap.h>
 #include <netinet/in.h>
 
+#include <dvbsi++/event_information_section.h>
+
 #ifndef BYTE_ORDER
 #error no byte order defined!
 #endif
@@ -248,6 +251,7 @@ RESULT eDVBPVRServiceOfflineOperations::getListOfFilenames(std::list<std::string
        res.push_back(m_ref.path + ".meta");
        res.push_back(m_ref.path + ".ap");
        res.push_back(m_ref.path + ".cuts");
+       res.push_back(m_ref.path + ".eit");
        return 0;
 }
 
@@ -547,9 +551,7 @@ eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *serv
        CONNECT(m_event_handler.m_eit_changed, eDVBServicePlay::gotNewEvent);
 
        m_cuesheet_changed = 0;
-       
-       if (m_is_pvr)
-               loadCuesheet();
+       m_cutlist_enabled = 1;
 }
 
 eDVBServicePlay::~eDVBServicePlay()
@@ -644,8 +646,39 @@ RESULT eDVBServicePlay::start()
                   two (one for decoding, one for data source), as we must be prepared
                   to start recording from the data demux. */
        m_cue = new eCueSheet();
+
        m_first_program_info = 1;
-       r = m_service_handler.tune((eServiceReferenceDVB&)m_reference, m_is_pvr, m_cue);
+       eServiceReferenceDVB &service = (eServiceReferenceDVB&)m_reference;
+       r = m_service_handler.tune(service, m_is_pvr, m_cue);
+       
+               /* inject EIT if there is a stored one */
+       if (m_is_pvr)
+       {
+               std::string filename = service.path;
+               filename.erase(filename.length()-2, 2);
+               filename+="eit";
+               int fd = ::open( filename.c_str(), O_RDONLY );
+               if ( fd > -1 )
+               {
+                       __u8 buf[4096];
+                       int rd = ::read(fd, buf, 4096);
+                       ::close(fd);
+                       if ( rd > 12 /*EIT_LOOP_SIZE*/ )
+                       {
+                               Event ev(buf);
+                               ePtr<eServiceEvent> event = new eServiceEvent;
+                               ePtr<eServiceEvent> empty;
+                               event->parseFrom(&ev, (service.getTransportStreamID().get()<<16)|service.getOriginalNetworkID().get());
+                               m_event_handler.inject(event, 0);
+                               m_event_handler.inject(empty, 1);
+                               eDebug("injected");
+                       }
+               }
+       }
+       
+       if (m_is_pvr)
+               loadCuesheet();
+
        m_event(this, evStart);
        m_event((iPlayableService*)this, evSeekableStatusChanged);
        return 0;
@@ -804,12 +837,18 @@ RESULT eDVBServicePlay::seekRelative(int direction, pts_t to)
        if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
                return -1;
        
+       int mode = 1;
+       
+                       /* HACK until we have skip-AP api */
+       if ((to > 0) && (to < 100))
+               mode = 2;
+       
        to *= direction;
        
        if (!m_cue)
                return 0;
        
-       m_cue->seekTo(1, to);
+       m_cue->seekTo(mode, to);
        return 0;
 }
 
@@ -1113,6 +1152,26 @@ int eDVBServicePlay::getFrontendInfo(int w)
        return fe->readFrontendData(w);
 }
 
+PyObject *eDVBServicePlay::getFrontendTransponderData()
+{
+       PyObject *ret=0;
+
+       eUsePtr<iDVBChannel> channel;
+       if(!m_service_handler.getChannel(channel))
+       {
+               ePtr<iDVBFrontend> fe;
+               if(!channel->getFrontend(fe))
+                       ret = fe->readTransponderData();
+       }
+
+       if (!ret)
+       {
+               ret = Py_None;
+               Py_INCREF(ret);
+       }
+       return ret;
+}
+
 int eDVBServicePlay::getNumberOfSubservices()
 {
        ePtr<eServiceEvent> evt;
@@ -1261,9 +1320,16 @@ void eDVBServicePlay::setCutList(PyObject *list)
        }
        m_cuesheet_changed = 1;
        
+       cutlistToCuesheet();
        m_event((iPlayableService*)this, evCuesheetChanged);
 }
 
+void eDVBServicePlay::setCutListEnable(int enable)
+{
+       m_cutlist_enabled = enable;
+       cutlistToCuesheet();
+}
+
 void eDVBServicePlay::updateTimeshiftPids()
 {
        if (!m_record)
@@ -1478,6 +1544,7 @@ void eDVBServicePlay::loadCuesheet()
                eDebug("cutfile not found!");
        
        m_cuesheet_changed = 0;
+       cutlistToCuesheet();
        m_event((iPlayableService*)this, evCuesheetChanged);
 }
 
@@ -1510,6 +1577,57 @@ void eDVBServicePlay::saveCuesheet()
        m_cuesheet_changed = 0;
 }
 
+void eDVBServicePlay::cutlistToCuesheet()
+{
+       if (!m_cue)
+       {
+               eDebug("no cue sheet");
+               return;
+       }       
+       m_cue->clear();
+       
+       if (!m_cutlist_enabled)
+       {
+               m_cue->commitSpans();
+               eDebug("cutlists where disabled");
+               return;
+       }
+
+       pts_t in = 0, out = 0, length = 0;
+       
+       getLength(length);
+               
+       std::multiset<cueEntry>::iterator i(m_cue_entries.begin());
+       
+       while (1)
+       {
+               if (i == m_cue_entries.end())
+                       out = length;
+               else {
+                       if (i->what == 0) /* in */
+                       {
+                               in = i++->where;
+                               continue;
+                       } else if (i->what == 1) /* out */
+                               out = i++->where;
+                       else /* mark */
+                       {
+                               i++;
+                               continue;
+                       }
+               }
+               
+               if (in != out)
+                       m_cue->addSourceSpan(in, out);
+               
+               in = length;
+               
+               if (i == m_cue_entries.end())
+                       break;
+       }
+       m_cue->commitSpans();
+}
+
 DEFINE_REF(eDVBServicePlay)
 
 eAutoInitPtr<eServiceFactoryDVB> init_eServiceFactoryDVB(eAutoInitNumbers::service+1, "eServiceFactoryDVB");