servicedvb.cpp: also disable fast winding for only audio ts files
[vuplus_dvbapp] / lib / service / servicedvb.cpp
index a75c6ca..e34e0b9 100644 (file)
@@ -97,50 +97,9 @@ int eStaticServiceDVBInformation::isPlayable(const eServiceReference &ref, const
 }
 
 extern void PutToDict(ePyObject &dict, const char*key, long value);  // defined in dvb/frontend.cpp
-extern void PutToDict(ePyObject &dict, const char*key, ePyObject item); // defined in dvb/frontend.cpp
-extern void PutToDict(ePyObject &dict, const char*key, const char *value); // defined in dvb/frontend.cpp
-
-void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &feparm)
-{
-       PutToDict(dict, "tuner_type", "DVB-S");
-       PutToDict(dict, "frequency", feparm.frequency);
-       PutToDict(dict, "symbol_rate", feparm.symbol_rate);
-       PutToDict(dict, "orbital_position", feparm.orbital_position);
-       PutToDict(dict, "inversion", feparm.inversion);
-       PutToDict(dict, "fec_inner", feparm.fec);
-       PutToDict(dict, "modulation", feparm.modulation);
-       PutToDict(dict, "polarization", feparm.polarisation);
-       if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2)
-       {
-               PutToDict(dict, "rolloff", feparm.rolloff);
-               PutToDict(dict, "pilot", feparm.pilot);
-       }
-       PutToDict(dict, "system", feparm.system);
-}
-
-void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial &feparm)
-{
-       PutToDict(dict, "tuner_type", "DVB-T");
-       PutToDict(dict, "frequency", feparm.frequency);
-       PutToDict(dict, "bandwidth", feparm.bandwidth);
-       PutToDict(dict, "code_rate_lp", feparm.code_rate_LP);
-       PutToDict(dict, "code_rate_hp", feparm.code_rate_HP);
-       PutToDict(dict, "constellation", feparm.modulation);
-       PutToDict(dict, "transmission_mode", feparm.transmission_mode);
-       PutToDict(dict, "guard_interval", feparm.guard_interval);
-       PutToDict(dict, "hierarchy_information", feparm.hierarchy);
-       PutToDict(dict, "inversion", feparm.inversion);
-}
-
-void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm)
-{
-       PutToDict(dict, "tuner_type", "DVB-C");
-       PutToDict(dict, "frequency", feparm.frequency);
-       PutToDict(dict, "symbol_rate", feparm.symbol_rate);
-       PutToDict(dict, "modulation", feparm.modulation);
-       PutToDict(dict, "inversion", feparm.inversion);
-       PutToDict(dict, "fec_inner", feparm.fec_inner);
-}
+extern void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &feparm); // defined in dvb/frontend.cpp
+extern void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial &feparm); // defined in dvb/frontend.cpp
+extern void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm); // defined in dvb/frontend.cpp
 
 PyObject *eStaticServiceDVBInformation::getInfoObject(const eServiceReference &r, int what)
 {
@@ -466,6 +425,7 @@ public:
        
        RESULT deleteFromDisk(int simulate);
        RESULT getListOfFilenames(std::list<std::string> &);
+       RESULT reindex();
 };
 
 DEFINE_REF(eDVBPVRServiceOfflineOperations);
@@ -528,6 +488,42 @@ RESULT eDVBPVRServiceOfflineOperations::getListOfFilenames(std::list<std::string
        return 0;
 }
 
+RESULT eDVBPVRServiceOfflineOperations::reindex()
+{
+       const char *filename = m_ref.path.c_str();
+       eDebug("reindexing %s...", filename);
+
+       eMPEGStreamInformation info;
+       eMPEGStreamParserTS parser(info);
+       
+       info.startSave(filename);
+       
+       eRawFile f;
+       
+       int err = f.open(m_ref.path.c_str(), 0);
+       if (err < 0)
+               return -1;
+       
+       off_t length = f.length();
+       unsigned char buffer[188*256*4];
+       while (1)
+       {
+               off_t offset = f.lseek(0, SEEK_CUR);
+               eDebug("at %08llx / %08llx (%d %%)", offset, length, (int)(offset * 100 / length));
+               int r = f.read(buffer, sizeof(buffer));
+               if (!r)
+                       break;
+               if (r < 0)
+                       return r;
+               parser.parseData(offset, buffer, r);
+       }
+       
+       info.stopSave();
+       f.close();
+       
+       return 0;
+}
+
 DEFINE_REF(eServiceFactoryDVB)
 
 eServiceFactoryDVB::eServiceFactoryDVB()
@@ -1065,22 +1061,30 @@ void eDVBServicePlay::serviceEventTimeshift(int event)
 
 RESULT eDVBServicePlay::start()
 {
-       int r;
+       eServiceReferenceDVB service = (eServiceReferenceDVB&)m_reference;
+
                /* 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)
+       {
+               eDVBMetaParser meta;
+               if (!meta.parseFile(m_reference.path))
+               {
+                       service = meta.m_ref;
+                       service.path = m_reference.path;
+               }
                m_cue = new eCueSheet();
+       }
        else
                m_event(this, evStart);
 
        m_first_program_info = 1;
-       eServiceReferenceDVB &service = (eServiceReferenceDVB&)m_reference;
-       r = m_service_handler.tune(service, m_is_pvr, m_cue, false, m_dvb_service);
+       m_service_handler.tune(service, m_is_pvr, m_cue, false, m_dvb_service);
 
-               /* inject EIT if there is a stored one */
        if (m_is_pvr)
        {
+               /* inject EIT if there is a stored one */
                std::string filename = service.path;
                filename.erase(filename.length()-2, 2);
                filename+="eit";
@@ -1091,10 +1095,6 @@ RESULT eDVBServicePlay::start()
                        m_event_handler.inject(event, 0);
                        m_event_handler.inject(empty, 1);
                }
-       }
-
-       if (m_is_pvr)
-       {
                loadCuesheet();
                m_event(this, evStart);
        }
@@ -1370,7 +1370,14 @@ RESULT eDVBServicePlay::setTrickmode(int trick)
 
 RESULT eDVBServicePlay::isCurrentlySeekable()
 {
-       return m_is_pvr || m_timeshift_active;
+       int ret = 0;
+       if (m_decoder)
+       {
+               ret = (m_is_pvr || m_timeshift_active) ? 3 : 0; // fast forward/backward possible and seeking possible
+               if (m_decoder->getVideoWidth() == -1)
+                       ret &= ~2;
+       }
+       return ret;
 }
 
 RESULT eDVBServicePlay::frontendInfo(ePtr<iFrontendInformation> &ptr)
@@ -1758,21 +1765,26 @@ int eDVBServicePlay::selectAudioStream(int i)
                return -4;
        }
 
+       int rdsPid = apid;
+
                /* if we are not in PVR mode, timeshift is not active and we are not in pip mode, check if we need to enable the rds reader */
        if (!(m_is_pvr || m_timeshift_active || !m_is_primary))
-               if (!m_rds_decoder)
+       {
+               int different_pid = program.videoStreams.empty() && program.audioStreams.size() == 1 && program.audioStreams[stream].rdsPid != -1;
+               if (different_pid)
+                       rdsPid = program.audioStreams[stream].rdsPid;
+               if (!m_rds_decoder || m_rds_decoder->getPid() != rdsPid)
                {
+                       m_rds_decoder = 0;
                        ePtr<iDVBDemux> data_demux;
                        if (!h.getDataDemux(data_demux))
                        {
-                               m_rds_decoder = new eDVBRdsDecoder(data_demux);
+                               m_rds_decoder = new eDVBRdsDecoder(data_demux, different_pid);
                                m_rds_decoder->connectEvent(slot(*this, &eDVBServicePlay::rdsDecoderEvent), m_rds_decoder_event_connection);
+                               m_rds_decoder->start(rdsPid);
                        }
                }
-
-               /* if we decided that we need one, update the pid */
-       if (m_rds_decoder)
-               m_rds_decoder->start(apid);
+       }
 
                        /* store new pid as default only when:
                                a.) we have an entry in the service db for the current service,
@@ -2350,9 +2362,11 @@ void eDVBServicePlay::updateDecoder()
                                        Py_DECREF(subs);
                                }
                        }
+                       m_decoder->play(); /* pids will be set later */
                }
                if (m_cue)
                        m_cue->setDecodingDemux(m_decode_demux, m_decoder);
+               m_decoder->play(); /* pids will be set later. */
        }
 
        m_timeshift_changed = 0;
@@ -2426,13 +2440,7 @@ void eDVBServicePlay::updateDecoder()
                                m_decoder->setRadioPic(radio_pic);
                }
 
-/*             if (!m_is_primary)
-                       m_decoder->setTrickmode();
-               else */ if (m_is_paused)
-                       m_decoder->pause();
-               else
-                       m_decoder->play();
-
+               m_decoder->set();
                m_decoder->setAudioChannel(achannel);
 
                /* don't worry about non-existing services, nor pvr services */