Support DVB-S2X.
[vuplus_dvbapp] / lib / dvb / scan.cpp
index d559614..1906c12 100644 (file)
@@ -3,9 +3,12 @@
 #include <dvbsi++/service_descriptor.h>
 #include <dvbsi++/satellite_delivery_system_descriptor.h>
 #include <dvbsi++/terrestrial_delivery_system_descriptor.h>
+#include <dvbsi++/t2_delivery_system_descriptor.h>
 #include <dvbsi++/cable_delivery_system_descriptor.h>
 #include <dvbsi++/ca_identifier_descriptor.h>
 #include <dvbsi++/registration_descriptor.h>
+#include <dvbsi++/extension_descriptor.h>
+#include <dvbsi++/frequency_list_descriptor.h>
 #include <lib/dvb/specs.h>
 #include <lib/dvb/esection.h>
 #include <lib/dvb/scan.h>
@@ -193,9 +196,9 @@ RESULT eDVBScan::nextChannel()
        if (m_ch_toScan.empty())
        {
                SCAN_eDebug("no channels left to scan.");
-               SCAN_eDebug("%d channels scanned, %d were unavailable.", 
+               SCAN_eDebug("%zd channels scanned, %zd were unavailable.",
                                m_ch_scanned.size(), m_ch_unavailable.size());
-               SCAN_eDebug("%d channels in database.", m_new_channels.size());
+               SCAN_eDebug("%zd channels in database.", m_new_channels.size());
                m_event(evtFinish);
                return -ENOENT;
        }
@@ -381,6 +384,7 @@ void eDVBScan::PMTready(int err)
                                switch ((*es)->getType())
                                {
                                case 0x1b: // AVC Video Stream (MPEG4 H264)
+                               case 0x24: // H265 HEVC
                                case 0x10: // MPEG 4 Part 2
                                case 0x01: // MPEG 1 video
                                case 0x02: // MPEG 2 video
@@ -501,7 +505,7 @@ void eDVBScan::addKnownGoodChannel(const eDVBChannelID &chid, iDVBFrontendParame
                m_new_channels.insert(std::pair<eDVBChannelID,ePtr<iDVBFrontendParameters> >(chid, feparm));
 }
 
-void eDVBScan::addChannelToScan(const eDVBChannelID &chid, iDVBFrontendParameters *feparm)
+void eDVBScan::addChannelToScan(iDVBFrontendParameters *feparm)
 {
                /* check if we don't already have that channel ... */
 
@@ -644,9 +648,9 @@ void eDVBScan::channelDone()
                        {
                                SCAN_eDebug("TSID: %04x ONID: %04x", (*tsinfo)->getTransportStreamId(),
                                        (*tsinfo)->getOriginalNetworkId());
-                               
-                               eOriginalNetworkID onid = (*tsinfo)->getOriginalNetworkId();
-                               eTransportStreamID tsid = (*tsinfo)->getTransportStreamId();
+
+                               bool T2 = false;
+                               eDVBFrontendParametersTerrestrial t2transponder;
                                
                                for (DescriptorConstIterator desc = (*tsinfo)->getDescriptors()->begin();
                                                desc != (*tsinfo)->getDescriptors()->end(); ++desc)
@@ -663,13 +667,7 @@ void eDVBScan::channelDone()
                                                cable.set(d);
                                                feparm->setDVBC(cable);
 
-                                               unsigned long hash=0;
-                                               feparm->getHash(hash);
-                                               eDVBNamespace ns = buildNamespace(onid, tsid, hash);
-
-                                               addChannelToScan(
-                                                       eDVBChannelID(ns, tsid, onid),
-                                                       feparm);
+                                               addChannelToScan(feparm);
                                                break;
                                        }
                                        case TERRESTRIAL_DELIVERY_SYSTEM_DESCRIPTOR:
@@ -682,13 +680,7 @@ void eDVBScan::channelDone()
                                                terr.set(d);
                                                feparm->setDVBT(terr);
 
-                                               unsigned long hash=0;
-                                               feparm->getHash(hash);
-                                               eDVBNamespace ns = buildNamespace(onid, tsid, hash);
-
-                                               addChannelToScan(
-                                                       eDVBChannelID(ns, tsid, onid),
-                                                       feparm);
+                                               addChannelToScan(feparm);
                                                break;
                                        }
                                        case SATELLITE_DELIVERY_SYSTEM_DESCRIPTOR:
@@ -722,11 +714,56 @@ void eDVBScan::channelDone()
                                                        SCAN_eDebug("dropping this transponder, it's on another satellite.");
                                                else
                                                {
-                                                       unsigned long hash=0;
-                                                       feparm->getHash(hash);
-                                                       addChannelToScan(
-                                                                       eDVBChannelID(buildNamespace(onid, tsid, hash), tsid, onid),
-                                                                       feparm);
+                                                       addChannelToScan(feparm);
+                                               }
+                                               break;
+                                       }
+                                       case EXTENSION_DESCRIPTOR:
+                                       {
+                                               if (system != iDVBFrontend::feTerrestrial)
+                                                       break; // when current locked transponder is no terrestrial transponder ignore this descriptor
+
+                                               ExtensionDescriptor &d = (ExtensionDescriptor&)**desc;
+                                               switch (d.getExtensionTag())
+                                               {
+                                               case T2_DELIVERY_SYSTEM_DESCRIPTOR:
+                                                       T2 = true;
+                                                       T2DeliverySystemDescriptor &d = (T2DeliverySystemDescriptor&)**desc;
+                                                       t2transponder.set(d);
+
+                                                       for (T2CellConstIterator cell = d.getCells()->begin();
+                                                               cell != d.getCells()->end(); ++cell)
+                                                       {
+                                                               for (T2FrequencyConstIterator freq = (*cell)->getCentreFrequencies()->begin();
+                                                                       freq != (*cell)->getCentreFrequencies()->end(); ++freq)
+                                                               {
+                                                                       t2transponder.frequency = (*freq) * 10;
+                                                                       ePtr<eDVBFrontendParameters> feparm = new eDVBFrontendParameters;
+                                                                       feparm->setDVBT(t2transponder);
+                                                                       addChannelToScan(feparm);
+                                                               }
+                                                       }
+                                               }
+                                               break;
+                                       }
+                                       case FREQUENCY_LIST_DESCRIPTOR:
+                                       {
+                                               if (system != iDVBFrontend::feTerrestrial)
+                                                       break; // when current locked transponder is no terrestrial transponder ignore this descriptor
+                                               if (!T2)
+                                                       break;
+
+                                               FrequencyListDescriptor &d = (FrequencyListDescriptor&)**desc;
+                                               if (d.getCodingType() != 0x03)
+                                                       break;
+
+                                               for (CentreFrequencyConstIterator it = d.getCentreFrequencies()->begin();
+                                                               it != d.getCentreFrequencies()->end(); ++it)
+                                               {
+                                                       t2transponder.frequency = (*it) * 10;
+                                                       ePtr<eDVBFrontendParameters> feparm = new eDVBFrontendParameters;
+                                                       feparm->setDVBT(t2transponder);
+                                                       addChannelToScan(feparm);
                                                }
                                                break;
                                        }
@@ -831,15 +868,41 @@ void eDVBScan::channelDone()
                        {
                                case iDVBFrontend::feSatellite:
                                {
+                                       char system_name[255];
+                                       char modulation_name[255];
+                                       memset(system_name, 0, sizeof(system_name));
+                                       memset(modulation_name, 0, sizeof(modulation_name));
+
                                        eDVBFrontendParametersSatellite parm;
                                        m_ch_current->getDVBS(parm);
+
+                                       if (parm.system == eDVBFrontendParametersSatellite::System_DVB_S2)
+                                               strcpy(system_name, "DVB-S2");
+                                       else if (parm.system == eDVBFrontendParametersSatellite::System_DVB_S2X)
+                                               strcpy(system_name, "DVB-S2X");
+                                       else
+                                               strcpy(system_name, "DVB-S");
+
+                                       if (parm.modulation == eDVBFrontendParametersSatellite::Modulation_QPSK)
+                                               strcpy(modulation_name, "QPSK");
+                                       else if (parm.modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
+                                               strcpy(modulation_name, "8PSK");
+                                       else if (parm.modulation == eDVBFrontendParametersSatellite::Modulation_8APSK)
+                                               strcpy(modulation_name, "8APSK");
+                                       else if (parm.modulation == eDVBFrontendParametersSatellite::Modulation_16APSK)
+                                               strcpy(modulation_name, "16APSK");
+                                       else if (parm.modulation == eDVBFrontendParametersSatellite::Modulation_32APSK)
+                                               strcpy(modulation_name, "32APSK");
+                                       else
+                                               strcpy(modulation_name, "8PSK");
+
                                        snprintf(sname, 255, "%d%c SID 0x%02x",
                                                        parm.frequency/1000,
                                                        parm.polarisation ? 'V' : 'H',
                                                        m_pmt_in_progress->first);
                                        snprintf(pname, 255, "%s %s %d%c %d.%d°%c",
-                                               parm.system ? "DVB-S2" : "DVB-S",
-                                               parm.modulation == 1 ? "QPSK" : "8PSK",
+                                               system_name,
+                                               modulation_name,
                                                parm.frequency/1000,
                                                parm.polarisation ? 'V' : 'H',
                                                parm.orbital_position/10,