diff --git a/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp b/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp
index 85dde8f326..589e23916a 100644
--- a/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp
+++ b/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp
@@ -1324,6 +1324,7 @@ ChannelScanSM::GetChannelList(transport_scan_items_it_t trans_info,
 
     // NIT
     QMap<qlonglong, uint> ukChanNums;
+    QMap<qlonglong, uint> scnChanNums;
     QMap<uint,ChannelInsertInfo>::iterator dbchan_it;
     for (dbchan_it = pnum_to_dbchan.begin();
          dbchan_it != pnum_to_dbchan.end(); ++dbchan_it)
@@ -1352,19 +1353,41 @@ ChannelScanSM::GetChannelList(transport_scan_items_it_t trans_info,
                 const desc_list_t &list =
                     MPEGDescriptor::Parse(nit->TransportDescriptors(i),
                                           nit->TransportDescriptorsLength(i));
+                // Logical channel numbers
+                {
+                    const unsigned char *desc =
+                        MPEGDescriptor::Find(
+                            list, PrivateDescriptorID::dvb_logical_channel_descriptor);
 
-                const unsigned char *desc =
-                    MPEGDescriptor::Find(
-                        list, PrivateDescriptorID::dvb_logical_channel_descriptor);
+                    if (desc)
+                    {
+                        DVBLogicalChannelDescriptor uklist(desc);
+
+                        for (uint j = 0; j < uklist.ChannelCount(); ++j)
+                        {
+                            ukChanNums[((qlonglong)info.orig_netid<<32) |
+                                    uklist.ServiceID(j)] =
+                                uklist.ChannelNumber(j);
+                        }
+                    }
+                }
 
-                if (desc)
+                // HD Simulcast logical channel numbers
                 {
-                    DVBLogicalChannelDescriptor uklist(desc);
-                    for (uint j = 0; j < uklist.ChannelCount(); ++j)
+                    const unsigned char *desc =
+                        MPEGDescriptor::Find(
+                            list, PrivateDescriptorID::dvb_simulcast_channel_descriptor);
+
+                    if (desc)
                     {
-                        ukChanNums[((qlonglong)info.orig_netid<<32) |
-                                   uklist.ServiceID(j)] =
-                            uklist.ChannelNumber(j);
+                        DVBSimulcastChannelDescriptor scnlist(desc);
+
+                        for (uint j = 0; j < scnlist.ChannelCount(); ++j)
+                        {
+                            scnChanNums[((qlonglong)info.orig_netid<<32) |
+                                        scnlist.ServiceID(j)] =
+                                 scnlist.ChannelNumber(j);
+                        }
                     }
                 }
             }
@@ -1382,7 +1405,23 @@ ChannelScanSM::GetChannelList(transport_scan_items_it_t trans_info,
 
         if (iptv_channel.isEmpty()) // DVB Logical channel numbers (LCN)
         {
-            QMap<qlonglong, uint>::const_iterator it = ukChanNums.find
+            // Look for a logical channel number in the HD simulcast channel numbers.
+            // This gives the correct channel number when HD and SD versions of the same
+            // channel are simultaneously broadcast and the receiver is capable
+            // of receiving the HD signal.
+            QMap<qlonglong, uint>::const_iterator it = scnChanNums.find
+                       (((qlonglong)info.orig_netid<<32) | info.service_id);
+
+            if (it != scnChanNums.end())
+            {
+                info.chan_num = QString::number(*it);
+                continue;
+            }
+
+            // If there is no simulcast for this channel then descriptor 0x83
+            // gives the logical channel number. This can be either an SD
+            // or an HD channel.
+            it = ukChanNums.find
                        (((qlonglong)info.orig_netid<<32) | info.service_id);
 
             if (it != ukChanNums.end())
@@ -1394,9 +1433,6 @@ ChannelScanSM::GetChannelList(transport_scan_items_it_t trans_info,
             if (info.service_id)
                 info.chan_num += "-" + QString::number(info.service_id);
         }
-
-        LOG(VB_CHANSCAN, LOG_INFO, LOC +
-            QString("GetChannelList: set chan_num '%1'").arg(info.chan_num));
     }
 
     // Get QAM/SCTE/MPEG channel numbers
diff --git a/mythtv/libs/libmythtv/mpeg/dvbdescriptors.cpp b/mythtv/libs/libmythtv/mpeg/dvbdescriptors.cpp
index 5954a25b1d..c9660aea66 100644
--- a/mythtv/libs/libmythtv/mpeg/dvbdescriptors.cpp
+++ b/mythtv/libs/libmythtv/mpeg/dvbdescriptors.cpp
@@ -597,6 +597,17 @@ QString DVBLogicalChannelDescriptor::toString() const
     return ret;
 }
 
+QString DVBSimulcastChannelDescriptor::toString() const
+{
+    QString ret = "DVBSimulcastChannelDescriptor sid->chan_num: ";
+    for (uint i = 0; i < ChannelCount(); i++)
+    {
+        ret += QString("%1->%2").arg(ServiceID(i)).arg(ChannelNumber(i));
+        ret += (i+1<ChannelCount()) ? ", " : "";
+    }
+    return ret;
+}
+
 QString CAIdentifierDescriptor::toString(void) const
 {
     QString ret = QString("CAIdentifierDescriptor ");
diff --git a/mythtv/libs/libmythtv/mpeg/dvbdescriptors.h b/mythtv/libs/libmythtv/mpeg/dvbdescriptors.h
index 50cb2d07a5..6650930ca4 100644
--- a/mythtv/libs/libmythtv/mpeg/dvbdescriptors.h
+++ b/mythtv/libs/libmythtv/mpeg/dvbdescriptors.h
@@ -2071,6 +2071,34 @@ class DVBLogicalChannelDescriptor : public MPEGDescriptor
     QString toString(void) const override; // MPEGDescriptor
 };
 
+/**
+ *  \brief DVB HD Simulcast Logical Channel Descriptor
+ *
+ * NIT descriptor ID 0x88 (Private Extension)
+ *
+ * Provides the Logical Channel Number (LCN) for each channel when the channel
+ * is simultaneously broadcast in SD and HD.
+ */
+class DVBSimulcastChannelDescriptor : public MPEGDescriptor
+{
+  public:
+    DVBSimulcastChannelDescriptor(const unsigned char *data, int len = 300) :
+        MPEGDescriptor(data, len, PrivateDescriptorID::dvb_simulcast_channel_descriptor) { }
+    //       Name             bits  loc  expected value
+    // descriptor_tag           8   0.0       0x83
+    // descriptor_length        8   1.0
+
+    uint ChannelCount(void) const { return DescriptorLength() >> 2; }
+
+    uint ServiceID(uint i) const
+        { return (_data[2 + (i<<2)] << 8) | _data[3 + (i<<2)]; }
+
+    uint ChannelNumber(uint i) const
+        { return ((_data[4 + (i<<2)] << 8) | _data[5 + (i<<2)]) & 0x3ff; }
+
+    QString toString(void) const override; // MPEGDescriptor
+};
+
 // ETSI TS 102 323 (TV Anytime)
 class DVBContentIdentifierDescriptor : public MPEGDescriptor
 {
diff --git a/mythtv/libs/libmythtv/mpeg/mpegdescriptors.cpp b/mythtv/libs/libmythtv/mpeg/mpegdescriptors.cpp
index 88563bc86d..e249feec8d 100644
--- a/mythtv/libs/libmythtv/mpeg/mpegdescriptors.cpp
+++ b/mythtv/libs/libmythtv/mpeg/mpegdescriptors.cpp
@@ -436,6 +436,8 @@ QString MPEGDescriptor::toString() const
     /// POSSIBLY UNSAFE ! -- begin
     else if (PrivateDescriptorID::dvb_logical_channel_descriptor == DescriptorTag())
         SET_STRING(DVBLogicalChannelDescriptor);
+    else if (PrivateDescriptorID::dvb_simulcast_channel_descriptor == DescriptorTag())
+        SET_STRING(DVBSimulcastChannelDescriptor);
     /// POSSIBLY UNSAFE ! -- end
     else if (IsValid())
     {
diff --git a/mythtv/libs/libmythtv/mpeg/mpegdescriptors.h b/mythtv/libs/libmythtv/mpeg/mpegdescriptors.h
index 2ae824572d..d5b75455b4 100644
--- a/mythtv/libs/libmythtv/mpeg/mpegdescriptors.h
+++ b/mythtv/libs/libmythtv/mpeg/mpegdescriptors.h
@@ -182,6 +182,7 @@ class PrivateDescriptorID
 
         // Private -- UK
         dvb_logical_channel_descriptor = 0x83, /* implemented */
+        dvb_simulcast_channel_descriptor = 0x88, /* implemented */
 
         // Private -- Dish Network
         dish_event_rights              = 0x87,
