Index: libs/libmythtv/channelutil.cpp
===================================================================
--- libs/libmythtv/channelutil.cpp	(revision 7286)
+++ libs/libmythtv/channelutil.cpp	(working copy)
@@ -442,14 +442,14 @@
     return query.value(0).toInt(); 
 }
 
-QString ChannelUtil::GetChanNum(int chan_id)
+QString ChannelUtil::GetChannelStringField(int chan_id, const QString &field)
 {
     if (chan_id < 0)
         return QString::null;
 
     MSqlQuery query(MSqlQuery::InitCon());
-    query.prepare(QString("SELECT channum FROM channel "
-                          "WHERE chanid=%1").arg(chan_id));
+    query.prepare(QString("SELECT %1 FROM channel "
+            "WHERE chanid=%2").arg(field).arg(chan_id));
     if (!query.exec() || !query.isActive())
     {
         MythContext::DBError("Selecting channel/dtv_multiplex 1", query);
@@ -462,6 +462,21 @@
     return query.value(0).toString();
 }
 
+QString ChannelUtil::GetChanNum(int chan_id)
+{
+    return GetChannelStringField(chan_id, QString("channum"));
+}
+
+QString ChannelUtil::GetCallsign(int chan_id)
+{
+    return GetChannelStringField(chan_id, QString("callsign"));
+}
+
+QString ChannelUtil::GetServiceName(int chan_id)
+{
+    return GetChannelStringField(chan_id, QString("name"));
+}
+
 int ChannelUtil::GetSourceID(int db_mplexid)
 {
     MSqlQuery query(MSqlQuery::InitCon());
@@ -666,8 +681,8 @@
     query.bindValue(":CHANID",    new_channel_id);
     query.bindValue(":CHANNUM",   chan_num);
     query.bindValue(":SOURCEID",  db_sourceid);
-    query.bindValue(":CALLSIGN",  callsign);
-    query.bindValue(":NAME",      service_name);
+    query.bindValue(":CALLSIGN",  callsign.utf8());
+    query.bindValue(":NAME",      service_name.utf8());
     query.bindValue(":XMLTVID",   xmltvid);
     query.bindValue(":FREQID",    freqid);
     query.bindValue(":TVFORMAT",  tvformat);
@@ -684,6 +699,7 @@
 bool ChannelUtil::CreateChannel(uint db_mplexid,
                                 uint db_sourceid,
                                 uint new_channel_id,
+                                const QString &callsign,
                                 const QString &service_name,
                                 const QString &chan_num,
                                 uint service_id,
@@ -714,7 +730,7 @@
     query.bindValue(":CHANID",    new_channel_id);
     query.bindValue(":CHANNUM",   chanNum);
     query.bindValue(":SOURCEID",  db_sourceid);
-    query.bindValue(":CALLSIGN",  service_name.utf8());
+    query.bindValue(":CALLSIGN",  callsign.utf8());
     query.bindValue(":NAME",      service_name.utf8());
 
     query.bindValue(":MPLEXID",   db_mplexid);
@@ -739,6 +755,7 @@
 bool ChannelUtil::UpdateChannel(uint db_mplexid,
                                 uint source_id,
                                 uint channel_id,
+                                const QString &callsign,
                                 const QString &service_name,
                                 const QString &chan_num,
                                 uint service_id,
@@ -761,7 +778,7 @@
     query.bindValue(":MPLEXID",   db_mplexid);
     query.bindValue(":SERVICEID", service_id);
     query.bindValue(":ATSCSRCID", atsc_src_id);
-    query.bindValue(":CALLSIGN",  service_name.utf8());
+    query.bindValue(":CALLSIGN",  callsign.utf8());
     query.bindValue(":NAME",      service_name.utf8());
     query.bindValue(":SOURCEID",  source_id);
     query.bindValue(":CHANID",    channel_id);
Index: libs/libmythtv/mpeg/mpegstreamdata.cpp
===================================================================
--- libs/libmythtv/mpeg/mpegstreamdata.cpp	(revision 7286)
+++ libs/libmythtv/mpeg/mpegstreamdata.cpp	(working copy)
@@ -593,6 +593,8 @@
     _cache_lock.lock();
     DeleteCachedTable(_cached_pat);
     _cached_pat = pat;
+    for (uint i = 0; i < pat->ProgramCount(); i++)
+        AddListeningPID(pat->ProgramPID(i));
     _cache_lock.unlock();
 }
 
Index: libs/libmythtv/mpeg/atscdescriptors.cpp
===================================================================
--- libs/libmythtv/mpeg/atscdescriptors.cpp	(revision 7286)
+++ libs/libmythtv/mpeg/atscdescriptors.cpp	(working copy)
@@ -225,3 +225,28 @@
     return QString("TODO huffman 2");
 }
 
+ExtendedChannelNameDescriptor::ExtendedChannelNameDescriptor(
+        const unsigned char *data) :
+    MPEGDescriptor(data)
+{
+    assert(DescriptorTag() == DescriptorID::extended_channel_name);
+}
+
+MultipleStringStructure ExtendedChannelNameDescriptor::LongChannelName() const
+{
+    return MultipleStringStructure(_data + 2);
+}
+
+QString ExtendedChannelNameDescriptor::LongChannelNameString() const
+{
+    QString str;
+    MultipleStringStructure mstr = LongChannelName();
+
+    for (int i = 0; i < mstr.StringCount(); i++)
+    {
+        for (uint j = 0; j < mstr.SegmentCount(i); j++)
+            str.append(mstr.CompressedString(i,j));
+    }
+    
+    return str;
+}
Index: libs/libmythtv/mpeg/atscdescriptors.h
===================================================================
--- libs/libmythtv/mpeg/atscdescriptors.h	(revision 7286)
+++ libs/libmythtv/mpeg/atscdescriptors.h	(working copy)
@@ -285,4 +285,34 @@
     //   content_identifier                  v   4.0
 };
 
+/**
+ * \brief Provides the long channel name for the virtual channel containing
+ *  this descriptor.
+ * 
+ * See ATSC A/65B section 6.9.5.
+ * When used, this descriptor must be in the Virtual Channel Table.
+ */
+class ExtendedChannelNameDescriptor : public MPEGDescriptor
+{
+public:
+    /**
+     * \brief Creates a new ExtendedChannelNameDescriptor.
+     * 
+     * \param data the raw data representing this descriptor
+     */
+    ExtendedChannelNameDescriptor(const unsigned char *data);
+
+    /**
+     * \brief Returns a MultipleStringStructure representing the
+     *  long name of the associated channel.
+     */
+    MultipleStringStructure LongChannelName() const;
+
+    /**
+     * \brief Convenience function that returns a QString comprising a
+     *  concatenation of all the segments in the LongChannelName() value.
+     */
+    QString LongChannelNameString() const;
+};
+
 #endif
Index: libs/libmythtv/mpeg/mpegtables.cpp
===================================================================
--- libs/libmythtv/mpeg/mpegtables.cpp	(revision 7286)
+++ libs/libmythtv/mpeg/mpegtables.cpp	(working copy)
@@ -157,6 +157,20 @@
 #endif
 }
 
+bool ProgramMapTable::IsStillPicture(void) const
+{
+    static const unsigned char STILL_PICTURE_FLAG = 0x01;
+    
+    for (uint i = 0; i < StreamCount(); i++)
+    {
+        if (IsVideo(i))
+            return StreamInfoLength(i) > 2 &&
+                   (StreamInfo(i)[2] & STILL_PICTURE_FLAG);
+    }
+    return false;
+}
+
+
 /** \fn ProgramMapTable::FindPIDs(uint type, vector<uint>& pids) const
  *  \brief Finds all pids matching type.
  *  \param pids vector pids will be added to
Index: libs/libmythtv/mpeg/mpegtables.h
===================================================================
--- libs/libmythtv/mpeg/mpegtables.h	(revision 7286)
+++ libs/libmythtv/mpeg/mpegtables.h	(working copy)
@@ -440,6 +440,11 @@
     bool IsAudio(uint i) const;
     /// Returns true iff PMT contains CA descriptor.
     bool IsEncrypted(void) const;
+    /**
+     * Returns true iff PMT contains a video stream with the
+     * still-picture flag.
+     */
+    bool IsStillPicture(void) const;
     /// Returns a string representation of type at stream index i
     const QString StreamTypeString(uint i) const;
     uint FindPIDs(uint type, vector<uint>& pids) const;
Index: libs/libmythtv/channelutil.h
===================================================================
--- libs/libmythtv/channelutil.h	(revision 7286)
+++ libs/libmythtv/channelutil.h	(working copy)
@@ -55,6 +55,7 @@
     static bool    CreateChannel(uint db_mplexid,
                                  uint db_sourceid,
                                  uint new_channel_id,
+                                 const QString &callsign,
                                  const QString &service_name,
                                  const QString &chan_num,
                                  uint service_id,
@@ -67,6 +68,7 @@
     static bool    UpdateChannel(uint db_mplexid,
                                  uint source_id,
                                  uint channel_id,
+                                 const QString &callsign,
                                  const QString &service_name,
                                  const QString &chan_num,
                                  uint service_id,
@@ -81,11 +83,28 @@
     static int     GetServiceVersion(int mplexid);
 
     // Misc
+    /**
+     * \brief Returns the channel-number string of the given channel.
+     * \param chanid primary key for channel record
+     */
     static QString GetChanNum(int chanid);
+    /**
+     * \brief Returns the callsign of the given channel.
+     * \param chanid primary key for channel record
+     */
+    static QString GetCallsign(int chanid);
+    /**
+     * \brief Returns the service name of the given channel.
+     * \param chanid primary key for channel record
+     */
+    static QString GetServiceName(int chanid);
     static int     GetSourceID(int mplexid);
     static QString GetInputName(int sourceid);
     static QString GetDTVPrivateType(uint networkid, const QString &key,
                                      const QString sitype = "dvb");
+
+  private:
+      static QString GetChannelStringField(int chanid, const QString &field);
 };
 
 #endif // CHANUTIL_H
Index: libs/libmythtv/siscan.h
===================================================================
--- libs/libmythtv/siscan.h	(revision 7286)
+++ libs/libmythtv/siscan.h	(working copy)
@@ -38,6 +38,7 @@
 class DTVSignalMonitor;
 class DVBSignalMonitor;
 class ProgramAssociationTable;
+class ProgramMapTable;
 class ServiceDescriptionTable;
 class NetworkInformationTable;
 class VirtualChannelTable;
@@ -52,6 +53,9 @@
     TRANSPORT_LIST, ///< Actively scan for channels
 } SCANMODE;
 
+/// PMTs by PID
+typedef QMap<uint, const ProgramMapTable *> QMap_PMTs;
+
 class SIScan : public QObject
 {
     Q_OBJECT
@@ -126,6 +130,7 @@
     void HandleMPEGDBInsertion(const ScanStreamData *sd, bool wait);
     void UpdatePATinDB(int mplexid,
                        const ProgramAssociationTable*,
+                       const QMap_PMTs &,
                        bool force_update);
 
     void HandleATSCDBInsertion(const ScanStreamData *sd, bool wait);
Index: libs/libmythtv/siscan.cpp
===================================================================
--- libs/libmythtv/siscan.cpp	(revision 7286)
+++ libs/libmythtv/siscan.cpp	(working copy)
@@ -345,7 +345,12 @@
     const ProgramAssociationTable *pat = sd->GetCachedPAT();
     if (pat)
     {
-        UpdatePATinDB((*current).mplexid, pat, true);
+        QMap_PMTs pmt_map;
+        pmt_vec_t pmt_vector = sd->GetCachedPMTs();
+        for (pmt_vec_t::iterator mi = pmt_vector.begin(); mi != pmt_vector.end(); mi++)
+            pmt_map[(*mi)->tsheader()->PID()] = *mi;
+        UpdatePATinDB((*current).mplexid, pat, pmt_map, true);
+        sd->ReturnCachedTables(pmt_vector);
         sd->ReturnCachedTable(pat);
     }
 
@@ -936,10 +941,11 @@
 // ///////////////////// DB STUFF /////////////////////
 // ///////////////////// DB STUFF /////////////////////
 
-/** \fn UpdatePATinDB(int, const ProgramAssociationTable*, bool)
+/** \fn UpdatePATinDB(int, const ProgramAssociationTable*, const QMap_PMTs &, bool)
  */
 void SIScan::UpdatePATinDB(int tid_db,
                            const ProgramAssociationTable *pat,
+                           const QMap_PMTs &pmt_map,
                            bool)
 {
     SISCAN(QString("UpdatePATinDB(): mplex: %1:%2")
@@ -959,6 +965,24 @@
 
     for (uint i = 0; i < pat->ProgramCount(); i++)
     {
+        const ProgramMapTable *pmt = pmt_map[pat->ProgramPID(i)];
+        VERBOSE(VB_SIPARSER,
+                tr("UpdatePATinDB(): Prog %1 PID %2: PMT @ %3")
+                    .arg(pat->ProgramNumber(i))
+                    .arg(pat->ProgramPID(i))
+                    .arg((long long unsigned int)pmt));
+        //TODO: user preference for still picture?
+        // For now we just ignore still-picture services such as
+        // music channels; Myth can't play them properly anyway.
+        // Eventually we might want to add a preference flag
+        // to the UI.
+        if (! pmt || // adding undefined services is rarely a good idea
+            ignoreEncryptedServices && pmt->IsEncrypted() ||
+            pmt->IsStillPicture())
+        {
+            continue;
+        }
+        
         // See if service already in database based on program number
         int chanid = ChannelUtil::GetChanID(
             db_mplexid, -1, 0, 0, pat->ProgramNumber(i));
@@ -969,8 +993,14 @@
             chan_num = QString("%1#%2")
                 .arg((freqid) ? freqid : db_mplexid).arg(i);
         }
+        
+        QString callsign = ChannelUtil::GetCallsign(chanid);
+        if (callsign == QString::null || callsign == "")
+            callsign = tr("C%1", "Synthesized callsign").arg(chan_num);
 
-        QString service_name = QString("Unknown %1").arg(chan_num);
+        QString service_name = ChannelUtil::GetServiceName(chanid);
+        if (service_name == QString::null || service_name == "")
+            service_name = callsign;
 
         QString common_status_info = tr("%1 %2-%3 as %4 on %5 (%6)")
             .arg(service_name)
@@ -985,6 +1015,7 @@
             chanid = ChannelUtil::CreateChanID(db_source_id, chan_num);
             ChannelUtil::CreateChannel(
                 db_mplexid, db_source_id, chanid,
+                callsign,
                 service_name,
                 chan_num,
                 pat->ProgramNumber(i),
@@ -999,6 +1030,7 @@
                 db_mplexid,
                 db_source_id,
                 chanid,
+                callsign,
                 service_name,
                 chan_num,
                 pat->ProgramNumber(i),
@@ -1078,6 +1110,28 @@
                 .arg(vct->MinorChannel(i));
         }
 
+        // try to find an extended channel name
+        QString extendedChannelName = vct->ShortChannelName(i); // fallback
+        if (vct->DescriptorsLength(i) > 0)
+        {
+            vector<const unsigned char*> descVec = 
+                MPEGDescriptor::Parse(vct->Descriptors(i), vct->DescriptorsLength(i));
+            for (uint j = 0; j < descVec.size(); j++)
+            {
+                if (MPEGDescriptor(descVec[j]).DescriptorTag() ==
+                    DescriptorID::extended_channel_name)
+                {
+                    QString longName =
+                        ExtendedChannelNameDescriptor(descVec[j]).LongChannelNameString();
+                    SISCAN(QString("UpdateVCTinDB(): chan index %1 has long name \"%2\"")
+                            .arg(i).arg(longName));
+                    if (! longName.isEmpty())
+                        extendedChannelName = longName;
+                    break;
+                }
+            }
+        }
+
         QString common_status_info = tr("%1 %2-%3 as %4 on %5 (%6)")
             .arg(vct->ShortChannelName(i))
             .arg(vct->MajorChannel(i)).arg(vct->MinorChannel(i))
@@ -1096,6 +1150,7 @@
                     db_source_id,
                     chanid,
                     vct->ShortChannelName(i),
+                    extendedChannelName,
                     chan_num,
                     vct->ProgramNumber(i),
                     vct->MajorChannel(i), vct->MinorChannel(i),
@@ -1113,6 +1168,7 @@
                 db_source_id,
                 chanid,
                 vct->ShortChannelName(i),
+                extendedChannelName,
                 chan_num,
                 vct->ProgramNumber(i),
                 vct->MajorChannel(i), vct->MinorChannel(i),
@@ -1232,6 +1288,7 @@
                 ChannelUtil::CreateChannel(
                     db_mplexid, db_source_id, chanid,
                     service_name,
+                    service_name,
                     chan_num,
                     sdt->ServiceID(i),
                     0, 0,
@@ -1248,6 +1305,7 @@
                 db_source_id,
                 chanid,
                 service_name,
+                service_name,
                 chan_num,
                 sdt->ServiceID(i),
                 0, 0, 
@@ -1436,6 +1494,7 @@
                 db_source_id,
                 chanid,
                 (*s).ServiceName,
+                (*s).ServiceName,
                 chan_num,
                 (*s).ServiceID,
                 atsc_major, atsc_minor,
@@ -1452,6 +1511,7 @@
                 db_source_id,
                 chanid,
                 (*s).ServiceName,
+                (*s).ServiceName,
                 chan_num,
                 (*s).ServiceID,
                 (*s).ChanNum / 10, (*s).ChanNum % 10,
