implement SDT scan on enter transponder (on normale zapping)
authorAndreas Monzner <andreas.monzner@multimedia-labs.de>
Tue, 9 May 2006 20:54:29 +0000 (20:54 +0000)
committerAndreas Monzner <andreas.monzner@multimedia-labs.de>
Tue, 9 May 2006 20:54:29 +0000 (20:54 +0000)
this
a) update changed service/provider names
b) add new services to servicelist and mark it as new services

to prevent change service_name it is possible to set the dxHoldName flag for this service
to prevent change any parameter of a single service it is possible to set the dxNoSDT flag

look at the eServiceDVB class declaration in lib/dvb/idvb.h

lib/dvb/idvb.h
lib/dvb/pmt.cpp
lib/dvb/pmt.h
lib/dvb/scan.cpp
lib/dvb/scan.h

index e9fb3cf00a48f035100e42dc8c19a5e5bf923b30..0326c60ff060230a2629adb9b8c336a5e2fbd4e9 100644 (file)
@@ -240,13 +240,11 @@ public:
        int m_flags;
        enum
        {
        int m_flags;
        enum
        {
-#if 0  // not yet implemented
                dxNoSDT=1,    // don't get SDT
                dxNoSDT=1,    // don't get SDT
-               dxDontshow=2,
+//nyi  dxDontshow=2,
+               dxNoDVB=4,  // dont use PMT for this service ( use cached pids )
                dxHoldName=8,
                dxHoldName=8,
-#endif
                dxNewFound=64,
                dxNewFound=64,
-               dxNoDVB=4  // dont use PMT for this service ( use cached pids )
        };
 
        bool usePMT() const { return !(m_flags & dxNoDVB); }
        };
 
        bool usePMT() const { return !(m_flags & dxNoDVB); }
index 47251835d52c06e36e0725a9dca1ad782e9fb7e8..74042ed09ceb951fb0986459e52ab14e90d3c9de 100644 (file)
@@ -5,6 +5,7 @@
 #include <lib/dvb/metaparser.h>
 #include <lib/dvb_ci/dvbci.h>
 #include <lib/dvb/epgcache.h>
 #include <lib/dvb/metaparser.h>
 #include <lib/dvb_ci/dvbci.h>
 #include <lib/dvb/epgcache.h>
+#include <lib/dvb/scan.h>
 #include <dvbsi++/ca_descriptor.h>
 #include <dvbsi++/ca_program_map_section.h>
 #include <dvbsi++/teletext_descriptor.h>
 #include <dvbsi++/ca_descriptor.h>
 #include <dvbsi++/ca_program_map_section.h>
 #include <dvbsi++/teletext_descriptor.h>
@@ -13,7 +14,7 @@
 #include <dvbsi++/stream_identifier_descriptor.h>
 
 eDVBServicePMTHandler::eDVBServicePMTHandler()
 #include <dvbsi++/stream_identifier_descriptor.h>
 
 eDVBServicePMTHandler::eDVBServicePMTHandler()
-       :m_ca_servicePtr(0), m_decode_demux_num(0xFF)
+       :m_ca_servicePtr(0), m_dvb_scan(0), m_decode_demux_num(0xFF)
 {
        m_use_decode_demux = 0;
        m_pmt_pid = -1;
 {
        m_use_decode_demux = 0;
        m_pmt_pid = -1;
@@ -440,6 +441,39 @@ int eDVBServicePMTHandler::getPVRChannel(ePtr<iDVBPVRChannel> &pvr_channel)
                return -1;
 }
 
                return -1;
 }
 
+void eDVBServicePMTHandler::SDTScanEvent(int event)
+{
+       eDebug("scan event %d!", event);
+
+       switch (event)
+       {
+               case eDVBScan::evtFinish:
+               {
+                       ePtr<iDVBChannelList> db;
+                       int err;
+                       if ((err = m_resourceManager->getChannelList(db)) != 0)
+                               eDebug("no channel list");
+                       else
+                       {
+                               m_dvb_scan->insertInto(db);
+                               eDebug("scan done!");
+                       }
+                       break;
+               }
+
+               case eDVBScan::evtNewService:
+                       eDebug("scan new service");
+                       break;
+
+               case eDVBScan::evtFail:
+                       eDebug("scan failed.");
+                       break;
+
+               default:
+                       break;
+       }
+}
+
 int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux, eCueSheet *cue)
 {
        RESULT res;
 int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux, eCueSheet *cue)
 {
        RESULT res;
@@ -500,6 +534,13 @@ int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux,
                m_channel->connectEvent(
                        slot(*this, &eDVBServicePMTHandler::channelEvent), 
                        m_channelEvent_connection);
                m_channel->connectEvent(
                        slot(*this, &eDVBServicePMTHandler::channelEvent), 
                        m_channelEvent_connection);
+
+               if (ref.path.empty())
+               {
+                       delete m_dvb_scan;
+                       m_dvb_scan = new eDVBScan(m_channel);
+                       m_dvb_scan->connectEvent(slot(*this, &eDVBServicePMTHandler::SDTScanEvent), m_scan_event_connection);
+               }
        } else
        {
                serviceEvent(eventTuneFailed);
        } else
        {
                serviceEvent(eventTuneFailed);
@@ -517,6 +558,10 @@ int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux,
 
 void eDVBServicePMTHandler::free()
 {
 
 void eDVBServicePMTHandler::free()
 {
+       eDVBScan *tmp = m_dvb_scan;
+       m_dvb_scan = 0;
+       delete m_dvb_scan;
+
        if (m_ca_servicePtr)
        {
                int demuxes[2] = {0,0};
        if (m_ca_servicePtr)
        {
                int demuxes[2] = {0,0};
index 5149167ce31e10a4dab2127bdbd359967484d4c8..6a5b00db195ef10a24da0df76cd2906f31c3d3be 100644 (file)
@@ -17,6 +17,7 @@
 #include <fcntl.h>
 
 class eDVBCAService;
 #include <fcntl.h>
 
 class eDVBCAService;
+class eDVBScan;
 
 typedef std::map<eServiceReferenceDVB, eDVBCAService*> CAServiceMap;
 
 
 typedef std::map<eServiceReferenceDVB, eDVBCAService*> CAServiceMap;
 
@@ -51,6 +52,7 @@ class eDVBServicePMTHandler: public Object
 
        int m_last_channel_state;
        eDVBCAService *m_ca_servicePtr;
 
        int m_last_channel_state;
        eDVBCAService *m_ca_servicePtr;
+       eDVBScan *m_dvb_scan; // for sdt scan
 
        eAUTable<eTable<ProgramMapSection> > m_PMT;
        eAUTable<eTable<ProgramAssociationSection> > m_PAT;
 
        eAUTable<eTable<ProgramMapSection> > m_PMT;
        eAUTable<eTable<ProgramAssociationSection> > m_PAT;
@@ -64,13 +66,15 @@ class eDVBServicePMTHandler: public Object
        ePtr<eConnection> m_channelStateChanged_connection;
        void channelEvent(iDVBChannel *, int event);
        ePtr<eConnection> m_channelEvent_connection;
        ePtr<eConnection> m_channelStateChanged_connection;
        void channelEvent(iDVBChannel *, int event);
        ePtr<eConnection> m_channelEvent_connection;
+       void SDTScanEvent(int);
+       ePtr<eConnection> m_scan_event_connection;
 
        void PMTready(int error);
        void PATready(int error);
        
        int m_use_decode_demux;
        uint8_t m_decode_demux_num;
 
        void PMTready(int error);
        void PATready(int error);
        
        int m_use_decode_demux;
        uint8_t m_decode_demux_num;
-       
+
 public:
        eDVBServicePMTHandler();
        ~eDVBServicePMTHandler();
 public:
        eDVBServicePMTHandler();
        ~eDVBServicePMTHandler();
@@ -130,7 +134,7 @@ public:
 
        int tune(eServiceReferenceDVB &ref, int use_decode_demux, eCueSheet *sg=0);
        void free();
 
        int tune(eServiceReferenceDVB &ref, int use_decode_demux, eCueSheet *sg=0);
        void free();
-       
+
        int m_pmt_pid;
 };
 
        int m_pmt_pid;
 };
 
index d0949a970ecc66a8d9cae261a1ba03f42e451737..17c6b5c2b170eadfc9fe67e2b0a69b71dd96f907 100644 (file)
@@ -24,6 +24,10 @@ DEFINE_REF(eDVBScan);
 
 eDVBScan::eDVBScan(iDVBChannel *channel): m_channel(channel)
 {
 
 eDVBScan::eDVBScan(iDVBChannel *channel): m_channel(channel)
 {
+       m_ready = m_flags = 0;
+       m_ready_all = readySDT;
+       m_channel_state = iDVBChannel::state_idle;
+
        if (m_channel->getDemux(m_demux))
                SCAN_eDebug("scan: failed to allocate demux!");
        m_channel->connectStateChange(slot(*this, &eDVBScan::stateChange), m_stateChanged_connection);
        if (m_channel->getDemux(m_demux))
                SCAN_eDebug("scan: failed to allocate demux!");
        m_channel->connectStateChange(slot(*this, &eDVBScan::stateChange), m_stateChanged_connection);
@@ -98,10 +102,10 @@ RESULT eDVBScan::nextChannel()
        
        if (m_ch_toScan.empty())
        {
        
        if (m_ch_toScan.empty())
        {
-               eDebug("no channels left to scan.");
-               eDebug("%d channels scanned, %d were unavailable.", 
+               SCAN_eDebug("no channels left to scan.");
+               SCAN_eDebug("%d channels scanned, %d were unavailable.", 
                                m_ch_scanned.size(), m_ch_unavailable.size());
                                m_ch_scanned.size(), m_ch_unavailable.size());
-               eDebug("%d channels in database.", m_new_channels.size());
+               SCAN_eDebug("%d channels in database.", m_new_channels.size());
                m_event(evtFinish);
                return -ENOENT;
        }
                m_event(evtFinish);
                return -ENOENT;
        }
@@ -252,8 +256,14 @@ void eDVBScan::channelDone()
        if (m_ready & validSDT)
        {
                unsigned long hash = 0;
        if (m_ready & validSDT)
        {
                unsigned long hash = 0;
-               m_ch_current->getHash(hash);
-               
+
+               ePtr<iDVBFrontendParameters> p = m_ch_current;
+
+               if (!p)  // used in sdt scan
+                       m_channel->getCurrentFrontendParameters(p);
+
+               p->getHash(hash);
+
                eDVBNamespace dvbnamespace = buildNamespace(
                        (**m_SDT->getSections().begin()).getOriginalNetworkId(),
                        (**m_SDT->getSections().begin()).getTransportStreamId(),
                eDVBNamespace dvbnamespace = buildNamespace(
                        (**m_SDT->getSections().begin()).getOriginalNetworkId(),
                        (**m_SDT->getSections().begin()).getTransportStreamId(),
@@ -339,7 +349,7 @@ void eDVBScan::channelDone()
                                                
                                                if ( m_chid_current.dvbnamespace.get() != -1 &&
                                                        ((ns.get() ^ m_chid_current.dvbnamespace.get()) & 0xFFFF0000))
                                                
                                                if ( m_chid_current.dvbnamespace.get() != -1 &&
                                                        ((ns.get() ^ m_chid_current.dvbnamespace.get()) & 0xFFFF0000))
-                                                       eDebug("dropping this transponder, it's on another satellite.");
+                                                       SCAN_eDebug("dropping this transponder, it's on another satellite.");
                                                else
                                                {
                                                        addChannelToScan(
                                                else
                                                {
                                                        addChannelToScan(
@@ -383,13 +393,17 @@ void eDVBScan::channelDone()
                   These are the reasons for adding the transponder
                   here, and not before.
                */
                   These are the reasons for adding the transponder
                   here, and not before.
                */
-       
+
+       ePtr<iDVBFrontendParameters> p = m_ch_current;
+       if (!p)
+               m_channel->getCurrentFrontendParameters(p);
+
        if (!m_chid_current)
                eWarning("SCAN: the current channel's ID was not corrected - not adding channel.");
        else
        if (!m_chid_current)
                eWarning("SCAN: the current channel's ID was not corrected - not adding channel.");
        else
-               addKnownGoodChannel(m_chid_current, m_ch_current);
-       
-       m_ch_scanned.push_back(m_ch_current);
+               addKnownGoodChannel(m_chid_current, p);
+
+       m_ch_scanned.push_back(p);
        nextChannel();
 }
 
        nextChannel();
 }
 
@@ -421,7 +435,7 @@ void eDVBScan::start(const eSmartPtrList<iDVBFrontendParameters> &known_transpon
        nextChannel();
 }
 
        nextChannel();
 }
 
-void eDVBScan::insertInto(iDVBChannelList *db)
+void eDVBScan::insertInto(iDVBChannelList *db, bool dontRemoveOldFlags)
 {
        if (m_flags & scanRemoveServices)
        {
 {
        if (m_flags & scanRemoveServices)
        {
@@ -499,7 +513,7 @@ void eDVBScan::insertInto(iDVBChannelList *db)
                        eDVBChannelID chid;
                        if (m_flags & scanDontRemoveFeeds)
                                chid.dvbnamespace = eDVBNamespace((*x)<<16);
                        eDVBChannelID chid;
                        if (m_flags & scanDontRemoveFeeds)
                                chid.dvbnamespace = eDVBNamespace((*x)<<16);
-                       eDebug("remove %d %08x", *x, chid.dvbnamespace.get());
+//                     eDebug("remove %d %08x", *x, chid.dvbnamespace.get());
                        db->removeServices(chid, *x);
                }
        }
                        db->removeServices(chid, *x);
                }
        }
@@ -513,8 +527,17 @@ void eDVBScan::insertInto(iDVBChannelList *db)
                ePtr<eDVBService> dvb_service;
                if (!db->getService(service->first, dvb_service))
                {
                ePtr<eDVBService> dvb_service;
                if (!db->getService(service->first, dvb_service))
                {
-                       *dvb_service = *service->second;
-                       dvb_service->m_flags &= ~eDVBService::dxNewFound;
+                       if (dvb_service->m_flags & eDVBService::dxNoSDT)
+                               continue;
+                       if (!(dvb_service->m_flags & eDVBService::dxHoldName))
+                       {
+                               dvb_service->m_service_name = service->second->m_service_name;
+                               dvb_service->m_service_name_sort = service->second->m_service_name_sort;
+                       }
+                       dvb_service->m_provider_name = service->second->m_provider_name;
+
+                       if (!dontRemoveOldFlags) // do not remove new found flags when not wished
+                               dvb_service->m_flags &= ~eDVBService::dxNewFound;
                }
                else
                {
                }
                else
                {
index 0a7c6ada2a723e190ac5c50fbe1e2b23fe25a7ac..1fc55e0fb3891e99e831edb1cec21e1710f3f4a5 100644 (file)
@@ -67,13 +67,13 @@ private:
 public:
        eDVBScan(iDVBChannel *channel);
        ~eDVBScan();
 public:
        eDVBScan(iDVBChannel *channel);
        ~eDVBScan();
-       
+
        enum { scanNetworkSearch = 1, scanSearchBAT = 2, scanRemoveServices = 4, scanDontRemoveFeeds=8 };
        void start(const eSmartPtrList<iDVBFrontendParameters> &known_transponders, int flags);
 
        enum { evtUpdate, evtNewService, evtFinish, evtFail };
        RESULT connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection);
        enum { scanNetworkSearch = 1, scanSearchBAT = 2, scanRemoveServices = 4, scanDontRemoveFeeds=8 };
        void start(const eSmartPtrList<iDVBFrontendParameters> &known_transponders, int flags);
 
        enum { evtUpdate, evtNewService, evtFinish, evtFail };
        RESULT connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection);
-       void insertInto(iDVBChannelList *db);
+       void insertInto(iDVBChannelList *db, bool dontRemoveNewFlags=false);
        
        void getStats(int &transponders_done, int &transponders_total, int &services);
        void getLastServiceName(std::string &name);
        
        void getStats(int &transponders_done, int &transponders_total, int &services);
        void getLastServiceName(std::string &name);