Support scrambled playback.
[vuplus_dvbapp] / lib / service / servicedvb.cpp
index 3f580fe..1494cc5 100755 (executable)
@@ -19,6 +19,8 @@
 #include <lib/base/nconfig.h> // access to python config
 #include <lib/base/httpstream.h>
 
+#include <lib/service/servicedvbfcc.h>
+
                /* for subtitles */
 #include <lib/gui/esubtitle.h>
 
@@ -28,6 +30,8 @@
 #include <byteswap.h>
 #include <netinet/in.h>
 
+#include <lib/dvb/fcc.h>
+
 #ifndef BYTE_ORDER
 #error no byte order defined!
 #endif
@@ -372,6 +376,8 @@ int eStaticServiceDVBPVRInformation::getInfo(const eServiceReference &ref, int w
                        return m_parser.m_time_create;
                else
                        return iServiceInformation::resNA;
+       case iServiceInformation::sIsScrambled:
+               return m_parser.m_scrambled;
        default:
                return iServiceInformation::resNA;
        }
@@ -814,31 +820,23 @@ RESULT eDVBServiceList::setListName(const std::string &name)
 RESULT eServiceFactoryDVB::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
 {
        ePtr<eDVBService> service;
+
        int r = lookupService(service, ref);
        if (r)
                service = 0;
                // check resources...
-       ptr = new eDVBServicePlay(ref, service);
+       if (eFCCServiceManager::checkAvailable(ref))
+               ptr = new eDVBServiceFCCPlay(ref, service);
+       else
+               ptr = new eDVBServicePlay(ref, service);
        return 0;
 }
 
 RESULT eServiceFactoryDVB::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
 {
-       if (ref.path.empty())
-       {
-               ptr = new eDVBServiceRecord((eServiceReferenceDVB&)ref);
-               return 0;
-       } else
-       {
-               bool isstream = ref.path.substr(0, 7) == "http://";
-               if(isstream)
-               {
-                       ptr = new eDVBServiceRecord((eServiceReferenceDVB&)ref, isstream);
-                       return 0;
-               }
-               ptr = 0;
-               return -1;
-       }
+       bool isstream = ref.path.substr(0, 7) == "http://";
+       ptr = new eDVBServiceRecord((eServiceReferenceDVB&)ref, isstream);
+       return 0;
 }
 
 RESULT eServiceFactoryDVB::list(const eServiceReference &ref, ePtr<iListableService> &ptr)
@@ -933,17 +931,20 @@ RESULT eServiceFactoryDVB::lookupService(ePtr<eDVBService> &service, const eServ
        return 0;
 }
 
-eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *service):
+eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *service, bool connect_event):
        m_reference(ref), m_dvb_service(service), m_have_video_pid(0), m_is_paused(0)
 {
        m_is_primary = 1;
+       m_decoder_index = 0;
        m_is_stream = m_reference.path.substr(0, 7) == "http://";
        m_is_pvr = (!m_reference.path.empty() && !m_is_stream);
-       
+
        m_timeshift_enabled = m_timeshift_active = 0, m_timeshift_changed = 0;
        m_skipmode = m_fastforward = m_slowmotion = 0;
-       
-       CONNECT(m_service_handler.serviceEvent, eDVBServicePlay::serviceEvent);
+
+       if (connect_event)
+               CONNECT(m_service_handler.serviceEvent, eDVBServicePlay::serviceEvent);
+
        CONNECT(m_service_handler_timeshift.serviceEvent, eDVBServicePlay::serviceEventTimeshift);
        CONNECT(m_event_handler.m_eit_changed, eDVBServicePlay::gotNewEvent);
 
@@ -1123,7 +1124,7 @@ void eDVBServicePlay::serviceEventTimeshift(int event)
                        if (m_skipmode < 0)
                                m_cue->seekTo(0, -1000);
                        ePtr<iTsSource> source = createTsSource(r);
-                       m_service_handler_timeshift.tuneExt(r, 1, source, r.path.c_str(), m_cue, 0, m_dvb_service); /* use the decoder demux for everything */
+                       m_service_handler_timeshift.tuneExt(r, 1, source, r.path.c_str(), m_cue, 0, m_dvb_service, false); /* use the decoder demux for everything */
 
                        m_event((iPlayableService*)this, evUser+1);
                }
@@ -1153,38 +1154,62 @@ void eDVBServicePlay::serviceEventTimeshift(int event)
                                resetTimeshift(1);
 
                                ePtr<iTsSource> source = createTsSource(r);
-                               m_service_handler_timeshift.tuneExt(r, 1, source, m_timeshift_file_next.c_str(), m_cue, 0, m_dvb_service); /* use the decoder demux for everything */
+                               int use_decode_demux = 1;
+                               eDVBServicePMTHandler::serviceType type = eDVBServicePMTHandler::timeshift_playback;
+                               m_service_handler_timeshift.tuneExt(r, use_decode_demux, source, m_timeshift_file_next.c_str(), m_cue, 0, m_dvb_service, type, false); /* use the decoder demux for everything */
 
                                m_event((iPlayableService*)this, evUser+1);
                        }
                }
                break;
+       case eDVBServicePMTHandler::eventNoDiskSpace:
+               eDebug("No space!");
+               m_event((iPlayableService*)this, evUser+3);
+               break;
        }
 }
 
 RESULT eDVBServicePlay::start()
 {
        eServiceReferenceDVB service = (eServiceReferenceDVB&)m_reference;
+       bool scrambled = true;
+       eDVBServicePMTHandler::serviceType type = eDVBServicePMTHandler::livetv;
+
+       int use_decode_demux = 0;
 
                /* in pvr mode, we only want to use one demux. in tv mode, we're using 
                   two (one for decoding, one for data source), as we must be prepared
                   to start recording from the data demux. */
        if (m_is_pvr)
        {
+               use_decode_demux = 1;
                eDVBMetaParser meta;
                if (!meta.parseFile(m_reference.path))
                {
                        service = meta.m_ref;
                        service.path = m_reference.path;
+                       scrambled = meta.m_scrambled;
+               }
+               else
+               {
+                       /* when there is no meta file we need to handle ts/m2ts as descrambled */
+                       scrambled = false;
                }
                m_cue = new eCueSheet();
+               type = eDVBServicePMTHandler::playback;
        }
        else
                m_event(this, evStart);
 
+       if (m_is_stream)
+       {
+               scrambled = true;
+               type = eDVBServicePMTHandler::streamclient;
+       }
+
        m_first_program_info = 1;
        ePtr<iTsSource> source = createTsSource(service);
-       m_service_handler.tuneExt(service, m_is_pvr, source, service.path.c_str(), m_cue, false, m_dvb_service, m_is_stream);
+       m_service_handler.tuneExt(service, use_decode_demux, source, service.path.c_str(), m_cue, false, m_dvb_service, type, scrambled);
 
        if (m_is_pvr)
        {
@@ -1254,6 +1279,7 @@ RESULT eDVBServicePlay::stop()
 RESULT eDVBServicePlay::setTarget(int target)
 {
        m_is_primary = !target;
+       m_decoder_index = target;
        return 0;
 }
 
@@ -2233,6 +2259,7 @@ RESULT eDVBServicePlay::startTimeshift()
        m_record->setTargetFD(m_timeshift_fd);
        m_record->setTargetFilename(m_timeshift_file.c_str());
        m_record->enableAccessPoints(false);
+       m_record->setTimeshift(true);
 
        m_timeshift_enabled = 1;
        
@@ -2499,7 +2526,9 @@ void eDVBServicePlay::switchToTimeshift()
        m_cue->seekTo(0, -1000);
 
        ePtr<iTsSource> source = createTsSource(r);
-       m_service_handler_timeshift.tuneExt(r, 1, source, m_timeshift_file.c_str(), m_cue, 0, m_dvb_service); /* use the decoder demux for everything */
+       int use_decode_demux = 1;
+       eDVBServicePMTHandler::serviceType type = eDVBServicePMTHandler::timeshift_playback;
+       m_service_handler_timeshift.tuneExt(r, use_decode_demux, source, m_timeshift_file.c_str(), m_cue, 0, m_dvb_service, type, false); /* use the decoder demux for everything */
 
        eDebug("eDVBServicePlay::switchToTimeshift, in pause mode now.");
        pause();
@@ -2562,7 +2591,7 @@ void eDVBServicePlay::updateDecoder(bool sendSeekableStateChanged)
                h.getDecodeDemux(m_decode_demux);
                if (m_decode_demux)
                {
-                       m_decode_demux->getMPEGDecoder(m_decoder, m_is_primary);
+                       m_decode_demux->getMPEGDecoder(m_decoder, m_decoder_index);
                        if (m_decoder)
                                m_decoder->connectVideoEvent(slot(*this, &eDVBServicePlay::video_event), m_video_event_connection);
                        if (m_is_primary)