better error/retry handling for recorder
[enigma2.git] / lib / service / servicedvb.cpp
index a9d235ec9bac1e5876ff6515f02f724b241181d4..15deff62901599a5e54ab6dae751480e570346a9 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <lib/dvb/dvb.h>
 #include <lib/dvb/db.h>
+#include <lib/dvb/decoder.h>
 
 #include <lib/service/servicedvbrecord.h>
 #include <lib/dvb/metaparser.h>
@@ -127,6 +128,9 @@ public:
        eStaticServiceDVBPVRInformation(const eServiceReference &ref);
        RESULT getName(const eServiceReference &ref, std::string &name);
        int getLength(const eServiceReference &ref);
+       
+       int getInfo(const eServiceReference &ref, int w);
+       std::string getInfoString(const eServiceReference &ref,int w);
 };
 
 DEFINE_REF(eStaticServiceDVBPVRInformation);
@@ -160,7 +164,32 @@ int eStaticServiceDVBPVRInformation::getLength(const eServiceReference &ref)
        return len / 90000;
 }
 
+int eStaticServiceDVBPVRInformation::getInfo(const eServiceReference &ref, int w)
+{
+       switch (w)
+       {
+       case iServiceInformation::sDescription:
+               return iServiceInformation::resIsString;
+       case iServiceInformation::sTimeCreate:
+               if (m_parser.m_time_create)
+                       return m_parser.m_time_create;
+               else
+                       return iServiceInformation::resNA;
+       default:
+               return iServiceInformation::resNA;
+       }
+}
 
+std::string eStaticServiceDVBPVRInformation::getInfoString(const eServiceReference &ref,int w)
+{
+       switch (w)
+       {
+       case iServiceInformation::sDescription:
+               return m_parser.m_description;
+       default:
+               return "";
+       }
+}
 
 class eDVBPVRServiceOfflineOperations: public iServiceOfflineOperations
 {
@@ -459,6 +488,7 @@ eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *serv
        m_reference(ref), m_dvb_service(service), m_service_handler(0), m_is_paused(0)
 {
        m_is_pvr = !ref.path.empty();
+       m_timeshift_enabled = 0;
        
        CONNECT(m_service_handler.serviceEvent, eDVBServicePlay::serviceEvent);
        CONNECT(m_event_handler.m_eit_changed, eDVBServicePlay::gotNewEvent);
@@ -584,12 +614,22 @@ void eDVBServicePlay::serviceEvent(int event)
                                /* don't worry about non-existing services, nor pvr services */
                        if (m_dvb_service && !m_is_pvr)
                        {
+                               if (apidtype == eDVBAudio::aMPEG)
+                               {
+                                       m_dvb_service->setCachePID(eDVBService::cAPID, apid);
+                                       m_dvb_service->setCachePID(eDVBService::cAC3PID, -1);
+                               }
+                               else
+                               {
+                                       m_dvb_service->setCachePID(eDVBService::cAPID, -1);
+                                       m_dvb_service->setCachePID(eDVBService::cAC3PID, apid);
+                               }
                                m_dvb_service->setCachePID(eDVBService::cVPID, vpid);
-                               m_dvb_service->setCachePID(eDVBService::cAPID, apid);
                                m_dvb_service->setCachePID(eDVBService::cPCRPID, pcrpid);
                        }
                }
-               
+
+               m_event((iPlayableService*)this, evUpdatedInfo);
                break;
        }
        }
@@ -619,14 +659,14 @@ RESULT eDVBServicePlay::connectEvent(const Slot2<void,iPlayableService*,int> &ev
 
 RESULT eDVBServicePlay::pause(ePtr<iPauseableService> &ptr)
 {
-       if (m_is_pvr)
+       if (!m_is_pvr)
        {
-               ptr = this;
-               return 0;
+               ptr = 0;
+               return -1;
        }
 
-       ptr = 0;
-       return -1;
+       ptr = this;
+       return 0;
 }
 
 RESULT eDVBServicePlay::setSlowMotion(int ratio)
@@ -640,7 +680,7 @@ RESULT eDVBServicePlay::setSlowMotion(int ratio)
 RESULT eDVBServicePlay::setFastForward(int ratio)
 {
        if (m_decoder)
-               m_decoder->setFastForward(ratio);
+               return m_decoder->setFastForward(ratio);
        else
                return -1;
 }
@@ -692,7 +732,19 @@ RESULT eDVBServicePlay::unpause()
 
 RESULT eDVBServicePlay::seekTo(pts_t to)
 {
-       return -1;
+       eDebug("eDVBServicePlay::seekTo: jump %lld", to);
+
+       ePtr<iDVBPVRChannel> pvr_channel;
+       
+       if (m_service_handler.getPVRChannel(pvr_channel))
+               return -1;
+       
+       ePtr<iDVBDemux> demux;
+       m_service_handler.getDemux(demux);
+       if (!demux)
+               return -1;
+       
+       return pvr_channel->seekTo(demux, 0, to);
 }
 
 RESULT eDVBServicePlay::seekRelative(int direction, pts_t to)
@@ -726,7 +778,14 @@ RESULT eDVBServicePlay::getPlayPosition(pts_t &pos)
        if (!demux)
                return -1;
        
-       return pvr_channel->getCurrentPosition(demux, pos);
+       return pvr_channel->getCurrentPosition(demux, pos, 1);
+}
+
+RESULT eDVBServicePlay::setTrickmode(int trick)
+{
+       if (m_decoder)
+               m_decoder->setTrickmode(trick);
+       return 0;
 }
 
 RESULT eDVBServicePlay::frontendStatusInfo(ePtr<iFrontendStatusInformation> &ptr)
@@ -753,6 +812,17 @@ RESULT eDVBServicePlay::subServices(ePtr<iSubserviceList> &ptr)
        return 0;
 }
 
+RESULT eDVBServicePlay::timeshift(ePtr<iTimeshiftService> &ptr)
+{
+       if (m_timeshift_enabled || !m_is_pvr)
+       {
+               ptr = this;
+               return 0;
+       }
+       ptr = 0;
+       return -1;
+}
+
 RESULT eDVBServicePlay::getName(std::string &name)
 {
        if (m_dvb_service)
@@ -782,12 +852,51 @@ int eDVBServicePlay::getInfo(int w)
        
        switch (w)
        {
+       case sAspect:
+               if (!program.videoStreams.empty() && program.videoStreams[0].component_tag != -1)
+               {
+                       ePtr<eServiceEvent> evt;
+                       if (!m_event_handler.getEvent(evt, 0))
+                       {
+                               ePtr<eComponentData> data;
+                               if (!evt->getComponentData(data, program.videoStreams[0].component_tag))
+                               {
+                                       if ( data->getStreamContent() == 1 )
+                                       {
+                                               switch(data->getComponentType())
+                                               {
+                                                       // SD
+                                                       case 1: // 4:3 SD PAL
+                                                       case 2:
+                                                       case 3: // 16:9 SD PAL
+                                                       case 4: // > 16:9 PAL
+                                                       case 5: // 4:3 SD NTSC
+                                                       case 6: 
+                                                       case 7: // 16:9 SD NTSC
+                                                       case 8: // > 16:9 NTSC
+
+                                                       // HD
+                                                       case 9: // 4:3 HD PAL
+                                                       case 0xA:
+                                                       case 0xB: // 16:9 HD PAL
+                                                       case 0xC: // > 16:9 HD PAL
+                                                       case 0xD: // 4:3 HD NTSC
+                                                       case 0xE:
+                                                       case 0xF: // 16:9 HD NTSC
+                                                       case 0x10: // > 16:9 HD PAL
+                                                               return data->getComponentType();
+                                               }
+                                       }
+                               }
+                       }
+               }
+               return -1;
+       case sIsCrypted: return program.isCrypted;
        case sVideoPID: if (program.videoStreams.empty()) return -1; return program.videoStreams[0].pid;
        case sAudioPID: if (program.audioStreams.empty()) return -1; return program.audioStreams[m_current_audio_stream].pid;
        case sPCRPID: return program.pcrPid;
        case sPMTPID: return program.pmtPid;
        case sTXTPID: return -1;
-               
        case sSID: return ((const eServiceReferenceDVB&)m_reference).getServiceID().get();
        case sONID: return ((const eServiceReferenceDVB&)m_reference).getOriginalNetworkID().get();
        case sTSID: return ((const eServiceReferenceDVB&)m_reference).getTransportStreamID().get();
@@ -880,6 +989,23 @@ int eDVBServicePlay::selectAudioStream(int i)
        if (m_decoder->setAudioPID(program.audioStreams[i].pid, program.audioStreams[i].type))
                return -4;
 
+       if (m_dvb_service && !m_is_pvr)
+       {
+               if (m_dvb_service && !m_is_pvr)
+               {
+                       if (program.audioStreams[i].type == eDVBAudio::aMPEG)
+                       {
+                               m_dvb_service->setCachePID(eDVBService::cAPID, program.audioStreams[i].pid);
+                               m_dvb_service->setCachePID(eDVBService::cAC3PID, -1);
+                       }
+                       else
+                       {
+                               m_dvb_service->setCachePID(eDVBService::cAPID, -1);
+                               m_dvb_service->setCachePID(eDVBService::cAC3PID, program.audioStreams[i].pid);
+                       }
+               }
+       }
+
        m_current_audio_stream = i;
 
        return 0;
@@ -911,34 +1037,30 @@ RESULT eDVBServicePlay::getSubservice(eServiceReference &sub, unsigned int n)
        ePtr<eServiceEvent> evt;
        if (!m_event_handler.getEvent(evt, 0))
        {
-               if (!evt->getLinkageService(sub, n))
-               {
-                       eServiceReferenceDVB &subservice = (eServiceReferenceDVB&) sub;
-                       eServiceReferenceDVB &current = (eServiceReferenceDVB&) m_reference;
-                       subservice.setDVBNamespace(current.getDVBNamespace());
-                       if ( current.getParentTransportStreamID().get() )
-                       {
-                               subservice.setParentTransportStreamID( current.getParentTransportStreamID() );
-                               subservice.setParentServiceID( current.getParentServiceID() );
-                       }
-                       else
-                       {
-                               subservice.setParentTransportStreamID( current.getTransportStreamID() );
-                               subservice.setParentServiceID( current.getServiceID() );
-                       }
-                       if ( subservice.getParentTransportStreamID() == subservice.getTransportStreamID() &&
-                               subservice.getParentServiceID() == subservice.getServiceID() )
-                       {
-                               subservice.setParentTransportStreamID( eTransportStreamID(0) );
-                               subservice.setParentServiceID( eServiceID(0) );
-                       }
+               if (!evt->getLinkageService(sub, m_reference, n))
                        return 0;
-               }
        }
        sub.type=eServiceReference::idInvalid;
        return -1;
 }
 
+RESULT eDVBServicePlay::startTimeshift()
+{
+       if (m_timeshift_enabled)
+               return -1;
+       eDebug("TIMESHIFT - start!");
+       return 0;
+}
+
+RESULT eDVBServicePlay::stopTimeshift()
+{
+       if (!m_timeshift_enabled)
+               return -1;
+       m_timeshift_enabled = 0;
+       eDebug("timeshift disabled");
+       return 0;
+}
+
 DEFINE_REF(eDVBServicePlay)
 
 eAutoInitPtr<eServiceFactoryDVB> init_eServiceFactoryDVB(eAutoInitNumbers::service+1, "eServiceFactoryDVB");