save mark type '3' on bookmark position
[enigma2.git] / lib / service / servicedvb.cpp
index b7acd1f4b068e31323743c41069db0dad605909d..10de621320e73697dbb313ef5c3ea7f925e48e29 100644 (file)
@@ -25,8 +25,6 @@
 #include <byteswap.h>
 #include <netinet/in.h>
 
-#include <dvbsi++/event_information_section.h>
-
 #define INTERNAL_TELETEXT
 
 #ifndef BYTE_ORDER
@@ -149,7 +147,8 @@ public:
        eStaticServiceDVBPVRInformation(const eServiceReference &ref);
        RESULT getName(const eServiceReference &ref, std::string &name);
        int getLength(const eServiceReference &ref);
-       
+       RESULT getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &SWIG_OUTPUT, time_t start_time);
+
        int getInfo(const eServiceReference &ref, int w);
        std::string getInfoString(const eServiceReference &ref,int w);
 };
@@ -216,6 +215,24 @@ std::string eStaticServiceDVBPVRInformation::getInfoString(const eServiceReferen
        }
 }
 
+RESULT eStaticServiceDVBPVRInformation::getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &evt, time_t start_time)
+{
+       if (!ref.path.empty())
+       {
+               ePtr<eServiceEvent> event = new eServiceEvent;
+               std::string filename = ref.path;
+               filename.erase(filename.length()-2, 2);
+               filename+="eit";
+               if (!event->parseFrom(filename, (m_parser.m_ref.getTransportStreamID().get()<<16)|m_parser.m_ref.getOriginalNetworkID().get()))
+               {
+                       evt = event;
+                       return 0;
+               }
+       }
+       evt = 0;
+       return -1;
+}
+
 class eDVBPVRServiceOfflineOperations: public iServiceOfflineOperations
 {
        DECLARE_REF(eDVBPVRServiceOfflineOperations);
@@ -630,7 +647,7 @@ RESULT eServiceFactoryDVB::lookupService(ePtr<eDVBService> &service, const eServ
 }
 
 eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *service): 
-       m_reference(ref), m_dvb_service(service), m_is_paused(0)
+       m_reference(ref), m_dvb_service(service), m_have_video_pid(0), m_is_paused(0)
 {
        m_is_primary = 1;
        m_is_pvr = !m_reference.path.empty();
@@ -751,32 +768,22 @@ RESULT eDVBServicePlay::start()
        m_first_program_info = 1;
        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 )
+               ePtr<eServiceEvent> event = new eServiceEvent;
+               if (!event->parseFrom(filename, (service.getTransportStreamID().get()<<16)|service.getOriginalNetworkID().get()))
                {
-                       __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");
-                       }
+                       ePtr<eServiceEvent> empty;
+                       m_event_handler.inject(event, 0);
+                       m_event_handler.inject(empty, 1);
                }
        }
-       
+
        if (m_is_pvr)
                loadCuesheet();
 
@@ -787,6 +794,29 @@ RESULT eDVBServicePlay::start()
 
 RESULT eDVBServicePlay::stop()
 {
+               /* add bookmark for last play position */
+       if (m_is_pvr)
+       {
+               pts_t play_position;
+               if (!getPlayPosition(play_position))
+               {
+                               /* remove last position */
+                       for (std::multiset<struct cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end();)
+                       {
+                               if (i->what == 3) /* current play position */
+                               {
+                                       m_cue_entries.erase(i);
+                                       i = m_cue_entries.begin();
+                                       continue;
+                               } else
+                                       ++i;
+                       }
+                       
+                       m_cue_entries.insert(cueEntry(play_position, 3)); /* last play position */
+                       m_cuesheet_changed = 1;
+               }
+       }
+
        stopTimeshift(); /* in case timeshift was enabled, remove buffer etc. */
 
        m_service_handler_timeshift.free();
@@ -1028,7 +1058,8 @@ RESULT eDVBServicePlay::subServices(ePtr<iSubserviceList> &ptr)
 RESULT eDVBServicePlay::timeshift(ePtr<iTimeshiftService> &ptr)
 {
        ptr = 0;
-       if (m_timeshift_enabled || !m_is_pvr)
+       if (m_have_video_pid &&  // HACK !!! FIXMEE !! temporary no timeshift on radio services !!
+               (m_timeshift_enabled || !m_is_pvr))
        {
                if (!m_timeshift_enabled)
                {
@@ -1290,7 +1321,7 @@ int eDVBServicePlay::getCurrentChannel()
 
 RESULT eDVBServicePlay::selectChannel(int i)
 {
-       if (i < LEFT || i > RIGHT)
+       if (i < LEFT || i > RIGHT || i == STEREO)
                i = -1;  // Stereo
        if (m_dvb_service)
                m_dvb_service->setCacheEntry(eDVBService::cACHANNEL, i);
@@ -1689,30 +1720,31 @@ void eDVBServicePlay::updateDecoder()
                        ac3_delay = m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
                        pcm_delay = m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
                }
-/*
-               else if (m_reference.path.length()) // workaround for recordings
+               else // subservice or recording
                {
-                       eDebug("playback %s", m_reference.toString().c_str());
-                       
-                       ePtr<eDVBResourceManager> res_mgr;
-                       if (!eDVBResourceManager::getInstance(res_mgr))
+                       eServiceReferenceDVB ref;
+                       m_service_handler.getServiceReference(ref);
+                       eServiceReferenceDVB parent = ref.getParentServiceReference();
+                       if (!parent)
+                               parent = ref;
+                       if (parent)
                        {
-                               ePtr<iDVBChannelList> db;
-                               if (!res_mgr->getChannelList(db))
+                               ePtr<eDVBResourceManager> res_mgr;
+                               if (!eDVBResourceManager::getInstance(res_mgr))
                                {
-                                       ePtr<eDVBService> origService;
-                                       eServiceReference tmp = m_reference;
-                                       tmp.path="";
-                                       if (!db->getService((eServiceReferenceDVB&)tmp, origService))
+                                       ePtr<iDVBChannelList> db;
+                                       if (!res_mgr->getChannelList(db))
                                        {
-                                               ac3_delay = origService->getCacheEntry(eDVBService::cAC3DELAY);
-                                               pcm_delay = origService->getCacheEntry(eDVBService::cPCMDELAY);
+                                               ePtr<eDVBService> origService;
+                                               if (!db->getService(parent, origService))
+                                               {
+                                                       ac3_delay = origService->getCacheEntry(eDVBService::cAC3DELAY);
+                                                       pcm_delay = origService->getCacheEntry(eDVBService::cPCMDELAY);
+                                               }
                                        }
                                }
                        }
                }
-*/
-
                m_decoder->setAC3Delay(ac3_delay == -1 ? 0 : ac3_delay);
                m_decoder->setPCMDelay(pcm_delay == -1 ? 0 : pcm_delay);
 
@@ -1768,6 +1800,7 @@ void eDVBServicePlay::updateDecoder()
                        m_dvb_service->setCacheEntry(eDVBService::cTPID, tpid);
                }
        }
+       m_have_video_pid = (vpid > 0 && vpid < 0x2000);
 }
 
 void eDVBServicePlay::loadCuesheet()
@@ -1796,7 +1829,7 @@ void eDVBServicePlay::loadCuesheet()
 #endif
                        what = ntohl(what);
                        
-                       if (what > 2)
+                       if (what > 3)
                                break;
                        
                        m_cue_entries.insert(cueEntry(where, what));
@@ -1852,7 +1885,7 @@ void eDVBServicePlay::cutlistToCuesheet()
        if (!m_cutlist_enabled)
        {
                m_cue->commitSpans();
-               eDebug("cutlists where disabled");
+               eDebug("cutlists were disabled");
                return;
        }
 
@@ -1873,7 +1906,7 @@ void eDVBServicePlay::cutlistToCuesheet()
                                continue;
                        } else if (i->what == 1) /* out */
                                out = i++->where;
-                       else /* mark */
+                       else /* mark (2) or last play position (3) */
                        {
                                i++;
                                continue;
@@ -2013,7 +2046,7 @@ int eDVBServicePlay::getPCMDelay()
 void eDVBServicePlay::setAC3Delay(int delay)
 {
        if (m_dvb_service)
-               m_dvb_service->setCacheEntry(eDVBService::cAC3DELAY, delay);
+               m_dvb_service->setCacheEntry(eDVBService::cAC3DELAY, delay ? delay : -1);
        if (m_decoder)
                m_decoder->setAC3Delay(delay);
 }
@@ -2021,7 +2054,7 @@ void eDVBServicePlay::setAC3Delay(int delay)
 void eDVBServicePlay::setPCMDelay(int delay)
 {
        if (m_dvb_service)
-               m_dvb_service->setCacheEntry(eDVBService::cPCMDELAY, delay);
+               m_dvb_service->setCacheEntry(eDVBService::cPCMDELAY, delay ? delay : -1);
        if (m_decoder)
                m_decoder->setPCMDelay(delay);
 }