the scan should now work for scanning dish network .. they use the SDT OTHER
authorAndreas Monzner <andreas.monzner@multimedia-labs.de>
Thu, 1 Jun 2006 22:47:52 +0000 (22:47 +0000)
committerAndreas Monzner <andreas.monzner@multimedia-labs.de>
Thu, 1 Jun 2006 22:47:52 +0000 (22:47 +0000)
lib/components/scan.cpp
lib/dvb/pmt.cpp
lib/dvb/scan.cpp
lib/dvb/scan.h
lib/dvb/specs.h

index 5355208..2870388 100644 (file)
@@ -106,8 +106,8 @@ int eComponentScan::start(int feid, int flags)
        }
 
        std::list<ePtr<iDVBFrontendParameters> > list;
-               
-       m_scan = new eDVBScan(channel, true);
+
+       m_scan = new eDVBScan(channel);
        m_scan->connectEvent(slot(*this, &eComponentScan::scanEvent), m_scan_event_connection);
        m_scan->start(m_initial, flags);
        
index 5301df9..3b7a376 100644 (file)
@@ -501,7 +501,7 @@ int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux,
                if (ref.path.empty())
                {
                        delete m_dvb_scan;
-                       m_dvb_scan = new eDVBScan(m_channel, false);
+                       m_dvb_scan = new eDVBScan(m_channel, false, false);
                        m_dvb_scan->connectEvent(slot(*this, &eDVBServicePMTHandler::SDTScanEvent), m_scan_event_connection);
                }
        } else
index 89c4735..f9d7547 100644 (file)
@@ -1,7 +1,4 @@
 #include <lib/dvb/idvb.h>
-#include <dvbsi++/service_description_section.h>
-#include <dvbsi++/network_information_section.h>
-#include <dvbsi++/bouquet_association_section.h>
 #include <dvbsi++/descriptor_tag.h>
 #include <dvbsi++/service_descriptor.h>
 #include <dvbsi++/satellite_delivery_system_descriptor.h>
@@ -22,9 +19,10 @@ static bool scan_debug;
 
 DEFINE_REF(eDVBScan);
 
-eDVBScan::eDVBScan(iDVBChannel *channel, bool debug)
+eDVBScan::eDVBScan(iDVBChannel *channel, bool usePAT, bool debug)
        :m_channel(channel), m_channel_state(iDVBChannel::state_idle)
-       ,m_ready(0), m_ready_all(readySDT), m_flags(0)
+       ,m_ready(0), m_ready_all(usePAT ? (readySDT|readyPAT) : readySDT)
+       ,m_flags(0), m_usePAT(usePAT)
 {
        scan_debug=debug;
        if (m_channel->getDemux(m_demux))
@@ -89,7 +87,7 @@ RESULT eDVBScan::nextChannel()
        m_SDT = 0; m_BAT = 0; m_NIT = 0;
 
        m_ready = 0;
-       
+
                /* check what we need */
        m_ready_all = readySDT;
        
@@ -98,7 +96,10 @@ RESULT eDVBScan::nextChannel()
        
        if (m_flags & scanSearchBAT)
                m_ready_all |= readyBAT;
-       
+
+       if (m_usePAT)
+               m_ready_all |= readyPAT;
+
        if (m_ch_toScan.empty())
        {
                SCAN_eDebug("no channels left to scan.");
@@ -144,38 +145,62 @@ RESULT eDVBScan::nextChannel()
 
 RESULT eDVBScan::startFilter()
 {
+       bool startSDT=true;
        assert(m_demux);
-       
+
                        /* only start required filters filter */
-       
-       m_SDT = 0;
 
-       if (m_ready_all & readySDT)
+       if (m_ready_all & readyPAT)
+               startSDT = m_ready & readyPAT;
+
+       m_SDT = 0;
+       if (startSDT && (m_ready_all & readySDT))
        {
                m_SDT = new eTable<ServiceDescriptionSection>();
-               if (m_SDT->start(m_demux, eDVBSDTSpec()))
+               if (m_ready & readyPAT)
+               {
+                       std::vector<ProgramAssociationSection*>::const_iterator i =
+                               m_PAT->getSections().begin();
+                       assert(i != m_PAT->getSections().end());
+                       int tsid = (*i)->getTableIdExtension(); // in PAT this is the transport stream id
+                       if (m_SDT->start(m_demux, eDVBSDTSpec(tsid, true)))
+                               return -1;
+               }
+               else if (m_SDT->start(m_demux, eDVBSDTSpec()))
                        return -1;
                CONNECT(m_SDT->tableReady, eDVBScan::SDTready);
        }
 
-       m_NIT = 0;
-       if (m_ready_all & readyNIT)
+       if (!(m_ready & readyPAT))
        {
-               m_NIT = new eTable<NetworkInformationSection>();
-               if (m_NIT->start(m_demux, eDVBNITSpec()))
-                       return -1;
-               CONNECT(m_NIT->tableReady, eDVBScan::NITready);
-       }
+               m_PAT = 0;
+               if (m_ready_all & readyPAT)
+               {
+                       m_PAT = new eTable<ProgramAssociationSection>();
+                       if (m_PAT->start(m_demux, eDVBPATSpec()))
+                               return -1;
+                       CONNECT(m_PAT->tableReady, eDVBScan::PATready);
+               }
 
-       m_BAT = 0;
-       if (m_ready_all & readyBAT)
-       {
-               m_BAT = new eTable<BouquetAssociationSection>();
-               if (m_BAT->start(m_demux, eDVBBATSpec()))
-                       return -1;
-               CONNECT(m_BAT->tableReady, eDVBScan::BATready);
+               m_NIT = 0;
+               if (m_ready_all & readyNIT)
+               {
+                       m_NIT = new eTable<NetworkInformationSection>();
+                       if (m_NIT->start(m_demux, eDVBNITSpec()))
+                               return -1;
+                       CONNECT(m_NIT->tableReady, eDVBScan::NITready);
+               }
+
+               m_BAT = 0;
+               if (m_ready_all & readyBAT)
+               {
+                       m_BAT = new eTable<BouquetAssociationSection>();
+                       if (m_BAT->start(m_demux, eDVBBATSpec()))
+                               return -1;
+                       CONNECT(m_BAT->tableReady, eDVBScan::BATready);
+               }
        }
-       
+
        return 0;
 }
 
@@ -206,6 +231,15 @@ void eDVBScan::BATready(int err)
        channelDone();
 }
 
+void eDVBScan::PATready(int err)
+{
+       SCAN_eDebug("got pat");
+       m_ready |= readyPAT;
+       if (!err)
+               m_ready |= validPAT;
+       startFilter(); // for starting the SDT filter
+}
+
 void eDVBScan::addKnownGoodChannel(const eDVBChannelID &chid, iDVBFrontendParameters *feparm)
 {
                /* add it to the list of known channels. */
@@ -548,10 +582,9 @@ RESULT eDVBScan::processSDT(eDVBNamespace dvbnamespace, const ServiceDescription
        SCAN_eDebug("ONID: %04x", sdt.getOriginalNetworkId());
        eDVBChannelID chid(dvbnamespace, sdt.getTransportStreamId(), sdt.getOriginalNetworkId());
        
-               /* save correct CHID for this channel if this is an ACTUAL_SDT */
-       if (sdt.getTableId() == TID_SDT_ACTUAL)
-               m_chid_current = chid;
-       
+       /* save correct CHID for this channel */
+       m_chid_current = chid;
+
        for (ServiceDescriptionConstIterator s(services.begin()); s != services.end(); ++s)
        {
                SCAN_eDebugNoNewLine("SID %04x: ", (*s)->getServiceId());
index fe5e068..0f32d67 100644 (file)
@@ -1,9 +1,10 @@
 #ifndef __lib_dvb_scan_h
 #define __lib_dvb_scan_h
 
-#include <dvbsi++/network_information_section.h>
 #include <dvbsi++/service_description_section.h>
+#include <dvbsi++/network_information_section.h>
 #include <dvbsi++/bouquet_association_section.h>
+#include <dvbsi++/program_association_section.h>
 #include <lib/dvb/idemux.h>
 #include <lib/dvb/esection.h>
 #include <lib/dvb/db.h>
@@ -31,8 +32,8 @@ private:
        RESULT nextChannel();
        
        RESULT startFilter();   
-       enum { readySDT=1, readyNIT=2, readyBAT=4,
-              validSDT=8, validNIT=16, validBAT=32};
+       enum { readyPAT=1, readySDT=2, readyNIT=4, readyBAT=8,
+              validPAT=16, validSDT=32, validNIT=64, validBAT=128};
 
                /* scan state variables */
        int m_channel_state;
@@ -49,11 +50,13 @@ private:
        ePtr<eTable<ServiceDescriptionSection> > m_SDT;
        ePtr<eTable<NetworkInformationSection> > m_NIT;
        ePtr<eTable<BouquetAssociationSection> > m_BAT;
-       
+       ePtr<eTable<ProgramAssociationSection> > m_PAT;
+               
        void SDTready(int err);
        void NITready(int err);
        void BATready(int err);
-       
+       void PATready(int err);
+               
        void addKnownGoodChannel(const eDVBChannelID &chid, iDVBFrontendParameters *feparm);
        void addChannelToScan(const eDVBChannelID &chid, iDVBFrontendParameters *feparm);
        int  sameChannel(iDVBFrontendParameters *ch1, iDVBFrontendParameters *ch2) const;
@@ -64,8 +67,9 @@ private:
        RESULT processSDT(eDVBNamespace dvbnamespace, const ServiceDescriptionSection &sdt);
        
        int m_flags;
+       bool m_usePAT;
 public:
-       eDVBScan(iDVBChannel *channel, bool debug=false);
+       eDVBScan(iDVBChannel *channel, bool usePAT=true, bool debug=true );
        ~eDVBScan();
 
        enum { scanNetworkSearch = 1, scanSearchBAT = 2, scanRemoveServices = 4, scanDontRemoveFeeds=8 };
index afd5cef..6f30c7b 100644 (file)
@@ -43,6 +43,23 @@ public:
                        eDVBTableSpec::tfHaveTID | eDVBTableSpec::tfCheckCRC |
                        eDVBTableSpec::tfHaveTimeout;
        }
+       eDVBSDTSpec(int tsid, bool other=false)
+       {
+               m_spec.pid     = ServiceDescriptionSection::PID;
+               m_spec.tid     = ServiceDescriptionSection::TID;
+               m_spec.tidext  = tsid;
+               m_spec.timeout = 20000; // ServiceDescriptionSection::TIMEOUT;
+               m_spec.flags   = eDVBTableSpec::tfAnyVersion |
+                       eDVBTableSpec::tfHaveTID | eDVBTableSpec::tfCheckCRC |
+                       eDVBTableSpec::tfHaveTIDExt | eDVBTableSpec::tfHaveTimeout;
+               if (other)
+               {
+                       // SDT other transport stream have TID 0x46 (current is 0x42)
+                       // so we mask out the third bit in table id mask..
+                       m_spec.flags |= eDVBTableSpec::tfHaveTIDMask;
+                       m_spec.tid_mask = 0xFB;
+               }
+       }
        operator eDVBTableSpec &()
        {
                return m_spec;