Index: libs/libmythtv/channelscan/channelscan_sm.h
===================================================================
--- libs/libmythtv/channelscan/channelscan_sm.h	(revision 19933)
+++ libs/libmythtv/channelscan/channelscan_sm.h	(working copy)
@@ -182,6 +182,10 @@
 
     static QString loc(const ChannelScanSM*);
 
+    static const uint kDVBTableTimeout;
+    static const uint kATSCTableTimeout;
+    static const uint kMPEGTableTimeout;
+
   private:
     // Set in constructor
     ScanMonitor      *scan_monitor;
Index: libs/libmythtv/channelscan/channelimporter.cpp
===================================================================
--- libs/libmythtv/channelscan/channelimporter.cpp	(revision 19936)
+++ libs/libmythtv/channelscan/channelimporter.cpp	(working copy)
@@ -45,6 +45,12 @@
 
     ScanDTVTransportList transports = _transports;
 
+    // Print out each channel
+    cout << "Before processing: " << endl;
+    ChannelImporterBasicStats infoA = CollectStats(transports);
+    cout << FormatChannels(transports, infoA).toAscii().constData() << endl;
+    cout << endl << endl;
+
     CleanupDuplicates(transports);
 
     uint saved_scan = 0;
@@ -66,6 +72,7 @@
         CollectUniquenessStats(transports, info);
 
     // Print out each channel
+    cout << "After processing: " << endl;
     cout << FormatChannels(transports, info).toAscii().constData() << endl;
 
     // Create summary
@@ -745,9 +752,10 @@
                   .arg(chan.pat_tsid)
                   .arg(si_standard)).toAscii().constData();
     else if (si_standard == "dvb")
-        ssMsg << (QString("%1:%2:%3:%4:%5:%6:%8")
+        ssMsg << (QString("%1:%2:%3:%4:%5:%6=%7:%8")
                   .arg(chan.service_name).arg(chan.chan_num)
                   .arg(chan.netid).arg(chan.orig_netid)
+                  .arg(chan.service_id)
                   .arg(chan.sdt_tsid)
                   .arg(chan.pat_tsid)
                   .arg(si_standard)).toAscii().constData();
Index: libs/libmythtv/channelscan/channelscan_sm.cpp
===================================================================
--- libs/libmythtv/channelscan/channelscan_sm.cpp	(revision 19938)
+++ libs/libmythtv/channelscan/channelscan_sm.cpp	(working copy)
@@ -59,6 +59,15 @@
 #include "hdhrchannel.h"
 #include "v4lchannel.h"
 
+/// SDT's should be sent every 2 seconds and NIT's every
+/// 10 seconds, so lets wait at least 30 seconds, in
+/// case of bad transmitter or lost packets.
+const uint ChannelScanSM::kDVBTableTimeout  = 30 * 1000;
+/// No logic here, lets just wait at least 10 seconds.
+const uint ChannelScanSM::kATSCTableTimeout = 10 * 1000;
+/// No logic here, lets just wait at least 15 seconds.
+const uint ChannelScanSM::kMPEGTableTimeout = 15 * 1000;
+
 QString ChannelScanSM::loc(const ChannelScanSM *siscan)
 {
     if (siscan && siscan->channel)
@@ -511,8 +520,16 @@
     }
 
     // DVB
-    if ((!wait_until_complete || sd->HasCachedAllNIT()) && info->nits.empty())
+    if ((!wait_until_complete || sd->HasCachedAllNIT()) &&
+        info->nits.empty())
+    {
         info->nits = sd->GetCachedNIT();
+        VERBOSE(VB_IMPORTANT,
+                QString("HERE -- Setting info->nits size() : %1, "
+                        "wait_until_complete: %2")
+                .arg(info->nits.size())
+                .arg(wait_until_complete));
+    }
 
     sdt_vec_t sdttmp = sd->GetCachedSDTs();
     tsid_checked.clear();
@@ -536,6 +553,7 @@
         transport_tune_complete &= !info->pmts.empty();
         if (sd->HasCachedMGT() || sd->HasCachedAnyVCTs())
         {
+            transport_tune_complete &= sd->HasCachedMGT();
             transport_tune_complete &=
                 (!info->tvcts.empty() || !info->cvcts.empty());
         }
@@ -544,8 +562,29 @@
             transport_tune_complete &= !info->nits.empty();
             transport_tune_complete &= !info->sdts.empty();
         }
+        if (transport_tune_complete)
+        {
+            VERBOSE(VB_CHANSCAN,
+                    QString("transport_tune_complete: "
+                            "\n\t\t\tinfo->pmts.empty():     %1"
+                            "\n\t\t\tsd->HasCachedAnyNIT():  %2"
+                            "\n\t\t\tsd->HasCachedAnySDTs(): %3"
+                            "\n\t\t\tinfo->nits.empty():     %4"
+                            "\n\t\t\tinfo->sdts.empty():     %5")
+                    .arg(info->pmts.empty())
+                    .arg(sd->HasCachedAnyNIT())
+                    .arg(sd->HasCachedAnySDTs())
+                    .arg(info->nits.empty())
+                    .arg(info->sdts.empty()));
+        }
     }
     transport_tune_complete |= !wait_until_complete;
+    if (transport_tune_complete)
+    {
+        VERBOSE(VB_CHANSCAN,
+                QString("transport_tune_complete: wait_until_complete %1")
+                .arg(wait_until_complete));
+    }
 
     if (transport_tune_complete &&
         /*!ignoreEncryptedServices &&*/ currentEncryptionStatus.size())
@@ -1134,10 +1173,18 @@
 bool ChannelScanSM::HasTimedOut(void)
 {
     if (currentTestingDecryption)
-        return (timer.elapsed() > (int)kDecryptionTimeout);
+    {
+        bool to = (timer.elapsed() > (int)kDecryptionTimeout);
+        if (to)
+            VERBOSE(VB_IMPORTANT, "HasTimedOut() decryption timeout reached");
+        return to;            
+    }
 
     if (!waitingForTables)
+    {
+        VERBOSE(VB_IMPORTANT, "HasTimedOut() waitingForTables == false");
         return true;
+    }
 
 #ifdef USING_DVB
     // If the rotor is still moving, reset the timer and keep waiting
@@ -1161,14 +1208,84 @@
 
     // have the tables have timed out?
     if (timer.elapsed() > (int)channelTimeout)
+    {
+        // the channelTimeout alone is only valid if we have seen no tables..
+        const ScanStreamData *sd = NULL;
+        if (GetDTVSignalMonitor())
+            sd = GetDTVSignalMonitor()->GetScanStreamData();
+
+        if (!sd)
+        {
+            VERBOSE(VB_IMPORTANT,
+                    "HasTimedOut() !ssd && channel timeout reached");
+            return true;
+        }
+
+        if (sd->HasCachedAnyNIT() || sd->HasCachedAnySDTs())
+        {
+            if (timer.elapsed() > (int) kDVBTableTimeout)
+            {
+                VERBOSE(VB_IMPORTANT,
+                        "HasTimedOut() DVB && DVB table timeout reached");
+                return true;
+            }
+            else
+                return false;
+        }
+        if (sd->HasCachedMGT() || sd->HasCachedAnyVCTs())
+        {
+            if (timer.elapsed() > (int) kATSCTableTimeout)
+            {
+                VERBOSE(VB_IMPORTANT,
+                        "HasTimedOut() ATSC && ATSC table timeout reached");
+                return true;
+            }
+            else
+                return false;
+        }
+        if (sd->HasCachedAnyPAT() || sd->HasCachedAnyPMTs())
+        {
+            if (timer.elapsed() > (int) kMPEGTableTimeout)
+            {
+                VERBOSE(VB_IMPORTANT,
+                        "HasTimedOut() MPEG && MPEG table timeout reached");
+                return true;
+            }
+            else
+                return false;
+        }
+
+        VERBOSE(VB_IMPORTANT,
+                "HasTimedOut() !tables && channel timeout reached");
         return true;
+    }
 
     // ok the tables haven't timed out, but have we hit the signal timeout?
     SignalMonitor *sm = GetSignalMonitor();
     if ((timer.elapsed() > (int)(*current).timeoutTune) &&
         sm && !sm->HasSignalLock())
     {
-        return true;
+        const ScanStreamData *sd = NULL;
+        if (GetDTVSignalMonitor())
+            sd = GetDTVSignalMonitor()->GetScanStreamData();
+
+        if (!sd)
+        {
+            VERBOSE(VB_IMPORTANT,
+                    "HasTimedOut() signal timeout reached && !ssd");
+            return true;
+        }
+
+        // Just is case we temporarily lose the signal after we've seen
+        // tables...
+        if (!sd->HasCachedAnyPAT() && !sd->HasCachedAnyPMTs() &&
+            !sd->HasCachedMGT()    && !sd->HasCachedAnyVCTs() &&
+            !sd->HasCachedAnyNIT() && !sd->HasCachedAnySDTs())
+        {
+            VERBOSE(VB_IMPORTANT,
+                    "HasTimedOut() signal timeout reached && !tables");
+            return true;
+        }
     }
 
     return false;
Index: libs/libmythtv/mpeg/mpegstreamdata.cpp
===================================================================
--- libs/libmythtv/mpeg/mpegstreamdata.cpp	(revision 19932)
+++ libs/libmythtv/mpeg/mpegstreamdata.cpp	(working copy)
@@ -1263,6 +1263,12 @@
     return true;
 }
 
+bool MPEGStreamData::HasCachedAnyPMTs(void) const
+{
+    QMutexLocker locker(&_cache_lock);
+    return _cached_pmts.size();
+}
+
 const pat_ptr_t MPEGStreamData::GetCachedPAT(
     uint tsid, uint section_num) const
 {
Index: libs/libmythtv/mpeg/atscstreamdata.cpp
===================================================================
--- libs/libmythtv/mpeg/atscstreamdata.cpp	(revision 19932)
+++ libs/libmythtv/mpeg/atscstreamdata.cpp	(working copy)
@@ -617,6 +617,9 @@
     if (!current)
         VERBOSE(VB_IMPORTANT, "Currently we ignore \'current\' param");
 
+    QMutexLocker locker(&_cache_lock);
+    return !_cached_tvcts.empty();
+#if 0
     if (!_cached_mgt)
         return false;
 
@@ -630,6 +633,7 @@
     _cache_lock.unlock();
 
     return ret;
+#endif
 }
 
 bool ATSCStreamData::HasCachedAnyCVCTs(bool current) const
@@ -637,6 +641,9 @@
     if (!current)
         VERBOSE(VB_IMPORTANT, "Currently we ignore \'current\' param");
 
+    QMutexLocker locker(&_cache_lock);
+    return !_cached_cvcts.empty();
+#if 0
     if (!_cached_mgt)
         return false;
 
@@ -650,6 +657,7 @@
     _cache_lock.unlock();
 
     return ret;
+#endif
 }
 
 const MasterGuideTable *ATSCStreamData::GetCachedMGT(bool current) const
Index: libs/libmythtv/mpeg/dvbstreamdata.cpp
===================================================================
--- libs/libmythtv/mpeg/dvbstreamdata.cpp	(revision 19932)
+++ libs/libmythtv/mpeg/dvbstreamdata.cpp	(working copy)
@@ -738,7 +738,8 @@
 bool DVBStreamData::HasCachedAnySDTs(bool current) const
 {
     QMutexLocker locker(&_cache_lock);
-
+    return !_cached_sdts.empty();
+#if 0
     if (_cached_nit.empty())
         return false;
 
@@ -753,6 +754,7 @@
     }
 
     return false;
+#endif
 }
 
 bool DVBStreamData::HasCachedAllSDTs(bool current) const
Index: libs/libmythtv/mpeg/mpegstreamdata.h
===================================================================
--- libs/libmythtv/mpeg/mpegstreamdata.h	(revision 19932)
+++ libs/libmythtv/mpeg/mpegstreamdata.h	(working copy)
@@ -198,6 +198,7 @@
     bool HasCachedAllPMT(uint program_num) const;
     bool HasCachedAnyPMT(uint program_num) const;
     bool HasCachedAllPMTs(void) const;
+    bool HasCachedAnyPMTs(void) const;
 
     const pat_ptr_t GetCachedPAT(uint tsid, uint section_num) const;
     pat_vec_t       GetCachedPATs(uint tsid) const;
