Ticket #5562: patch4_scanning.patch

File patch4_scanning.patch, 9.5 KB (added by David Matthews <dm@…>, 11 years ago)
  • libs/libmythtv/siscan.h

     
    4343               public MPEGStreamListener,
    4444               public ATSCMainStreamListener,
    4545               public DVBMainStreamListener,
    46                public SignalMonitorListener
     46               public SignalMonitorListener,
     47               public DVBOtherStreamListener
    4748{
    4849    Q_OBJECT
    4950  public:
     
    105106    virtual void StatusSignalLock(const SignalMonitorValue&) { }
    106107    virtual void StatusSignalStrength(const SignalMonitorValue&) { }
    107108
     109    // DVB Other
     110    void HandleNITo(const NetworkInformationTable*) {}
     111    void HandleSDTo(uint tsid, const ServiceDescriptionTable*);
     112    void HandleBAT(const BouquetAssociationTable*);
     113
    108114  public slots:
    109115    void deleteLater(void);
    110116
     
    191197    SCANMODE          scanMode;
    192198    uint              signalTimeout;
    193199    uint              channelTimeout;
     200    uint              otherTableTimeout;
     201    uint              otherTableTime;
     202    bool              setOtherTables;
    194203    QString           inputname;
    195204
    196205    // Settable
     
    213222    transport_scan_items_it_t   current;
    214223    transport_scan_items_it_t   nextIt;
    215224    QMap<uint, uint>            dvbChanNums;
     225    QMap<uint64_t, QString>     defAuthorities;
    216226
    217227    /// Scanner thread, runs SIScan::StartScanner()
    218228    pthread_t        scanner_thread;
  • libs/libmythtv/siscan.cpp

     
    9292      scanMode(IDLE),
    9393      signalTimeout(signal_timeout),
    9494      channelTimeout(channel_timeout),
     95      otherTableTimeout(0),
     96      otherTableTime(0),
     97      setOtherTables(false),
    9598      inputname(_inputname),
    9699      // Settable
    97100      isAnalog(false),
     
    133136        data->AddMPEGListener(this);
    134137        data->AddATSCMainListener(this);
    135138        data->AddDVBMainListener(this);
     139        data->AddDVBOtherListener(this);
    136140    }
    137141}
    138142
     
    148152    disconnect();
    149153    StopScanner();
    150154    VERBOSE(VB_SIPARSER, LOC + "SIScanner Stopped");
     155    channel = 0; // Deleted by caller
    151156    QObject::deleteLater();
    152157}
    153158
     
    312317            .arg((*current).FriendlyName));
    313318    VERBOSE(VB_SIPARSER, LOC + sdt->toString());
    314319
     320    // If this is Astra 28.2 add start listening for Freesat BAT and SDTo
     321    if (!setOtherTables && (sdt->OriginalNetworkID() == 2 || sdt->OriginalNetworkID() == 59))
     322    {
     323        GetDTVSignalMonitor()->GetScanStreamData()->SetOtherTablePid(FREESAT_SI_PID);
     324        setOtherTables = true;
     325        otherTableTimeout = 10000; // The whole BAT & SDTo group comes round in 10s
     326        // Delay processing the SDT until we've seen BATs and SDTos
     327        otherTableTime = timer.elapsed() + otherTableTimeout;
     328    }
     329
     330    if (timer.elapsed() < otherTableTime)
     331    {
     332        // Set the version for the SDT so we see it again.
     333        GetDTVSignalMonitor()->GetDVBStreamData()->SetVersionSDT(sdt->TSID(), -1, 0);
     334    }
     335
    315336    HandleDVBDBInsertion(GetDTVSignalMonitor()->GetScanStreamData(), true);
    316337}
    317338
     
    362383    HandleDVBDBInsertion(GetDTVSignalMonitor()->GetScanStreamData(), true);
    363384}
    364385
     386void SIScan::HandleBAT(const BouquetAssociationTable *bat)
     387{
     388    VERBOSE(VB_SIPARSER, LOC +
     389            QString("Got a Bouquet Association Table"));
     390    VERBOSE(VB_SIPARSER, LOC + bat->toString());
     391
     392    otherTableTime = timer.elapsed() + otherTableTimeout;
     393
     394    for (uint i = 0; i < bat->TransportStreamCount(); i++)
     395    {
     396        uint tsid = bat->TSID(i);
     397        uint netid = bat->OriginalNetworkID(i);
     398        desc_list_t parsed =
     399            MPEGDescriptor::Parse(bat->TransportDescriptors(i),
     400                                  bat->TransportDescriptorsLength(i));
     401        // Look for default authority
     402        const unsigned char *def_auth =
     403            MPEGDescriptor::Find(parsed, DescriptorID::default_authority);
     404        const unsigned char *serv_list =
     405            MPEGDescriptor::Find(parsed, DescriptorID::service_list);
     406
     407        if (def_auth && serv_list)
     408        {
     409            DefaultAuthorityDescriptor authority(def_auth);
     410            ServiceListDescriptor services(serv_list);
     411
     412            for (uint j = 0; j < services.ServiceCount(); j++)
     413            {
     414               // If the default authority is given in the SDT this
     415               // overrides any definition in the BAT (or in the NIT)
     416               uint64_t index =
     417                   ((uint64_t)netid << 32) | (tsid << 16) | services.ServiceID(j);
     418               if (! defAuthorities.contains(index))
     419                   defAuthorities[index] = authority.DefaultAuthority();
     420            }
     421        }
     422    }
     423}
     424
     425
     426void SIScan::HandleSDTo(uint tsid, const ServiceDescriptionTable *sdt)
     427{
     428    VERBOSE(VB_SIPARSER, LOC +
     429            QString("Got a Service Description Table (other)"));
     430    VERBOSE(VB_SIPARSER, LOC + sdt->toString());
     431
     432    otherTableTime = timer.elapsed() + otherTableTimeout;
     433
     434    uint netid = sdt->OriginalNetworkID();
     435
     436    for (uint i = 0; i < sdt->ServiceCount(); i++)
     437    {
     438        uint serviceId = sdt->ServiceID(i);
     439        desc_list_t parsed =
     440            MPEGDescriptor::Parse(sdt->ServiceDescriptors(i),
     441                                  sdt->ServiceDescriptorsLength(i));
     442        // Look for default authority
     443        const unsigned char *def_auth =
     444            MPEGDescriptor::Find(parsed, DescriptorID::default_authority);
     445        if (def_auth)
     446        {
     447            DefaultAuthorityDescriptor authority(def_auth);
     448            defAuthorities[((uint64_t)netid << 32) | (tsid << 16) | serviceId] =
     449                authority.DefaultAuthority();
     450        }
     451
     452    }
     453
     454}
     455
    365456void SIScan::HandleMPEGDBInsertion(const ScanStreamData *sd, bool)
    366457{
    367458    // Try to determine if this might be "OpenCable" transport.
     
    443534                                  bool wait_until_complete)
    444535{
    445536    const DVBStreamData &dsd = (const DVBStreamData &)(*sd);
    446     if (wait_until_complete && !(dsd.HasCachedSDT() && dsd.HasCachedAllNIT()))
     537    if (wait_until_complete && !(dsd.HasCachedSDT() && dsd.HasCachedAllNIT()
     538        && timer.elapsed() > (int)otherTableTime))
    447539        return;
    448540
    449541    emit ServiceScanUpdateText(tr("Updating Services"));
     
    730822    emit ServiceScanUpdateStatusText(cur_chan);
    731823    VERBOSE(VB_SIPARSER, LOC + tune_msg_str);
    732824
     825    setOtherTables = false;
     826    otherTableTime = 0;
     827
    733828    if (!Tune(transport))
    734829    {   // If we did not tune successfully, bail with message
    735830        UpdateScanPercentCompleted();
     
    14731568        const unsigned char *def_auth =
    14741569            MPEGDescriptor::Find(parsed, DescriptorID::default_authority);
    14751570        if (def_auth)
    1476             default_authority =
    1477                 QString::fromAscii((const char*)def_auth+2, def_auth[1]);
     1571        {
     1572            DefaultAuthorityDescriptor authority(def_auth);
     1573            default_authority = authority.DefaultAuthority();
     1574        }
     1575        else
     1576        {
     1577            uint64_t index =
     1578                ((uint64_t)sdt->OriginalNetworkID() << 32) |
     1579                (sdt->TSID() << 16) | sdt->ServiceID(i);
     1580            if (defAuthorities.contains(index))
     1581                default_authority = defAuthorities[index];
     1582        }
    14781583
    14791584        QString common_status_info = service_name;
    14801585
  • libs/libmythtv/mpeg/scanstreamdata.h

     
    2727                          uint_vec_t& /*del_pids*/) const { return false; }
    2828
    2929    QString GetSIStandard(QString guess = "mpeg") const;
     30
     31    void SetOtherTablePid(int pid);
     32
     33  private:
     34    int otherTablepid;
    3035};
    3136
    3237#endif // SCANSTREAMDATA_H_
  • libs/libmythtv/mpeg/scanstreamdata.cpp

     
    77ScanStreamData::ScanStreamData()
    88    : MPEGStreamData(-1, true),
    99      ATSCStreamData(-1,-1, true),
    10       DVBStreamData(0, 0, -1, true)
     10      DVBStreamData(0, 0, -1, true),
     11      otherTablepid(-1)
    1112{
    1213}
    1314
     
    1819 */
    1920bool ScanStreamData::IsRedundant(uint pid, const PSIPTable &psip) const
    2021{
    21     return (ATSCStreamData::IsRedundant(pid,psip) ||
    22             DVBStreamData::IsRedundant(pid,psip));
     22    if (ATSCStreamData::IsRedundant(pid,psip) ||
     23        DVBStreamData::IsRedundant(pid,psip))
     24        return true;
     25    // Treat BAT and SDTo as redundant unless they are on the required PID.
     26    if (psip.TableID() == TableID::BAT || psip.TableID() == TableID::SDTo)
     27        return otherTablepid < 0 || pid != (uint)otherTablepid;
     28    return false;
    2329}
    2430
    2531/** \fn ScanStreamData::HandleTables(uint, const PSIPTable&)
     
    4248    AddListeningPID(ATSC_PSIP_PID);
    4349    AddListeningPID(DVB_NIT_PID);
    4450    AddListeningPID(DVB_SDT_PID);
     51    if (otherTablepid >= 0)
     52        AddListeningPID((uint)otherTablepid);
    4553}
    4654
    4755QString ScanStreamData::GetSIStandard(QString guess) const
     
    7987
    8088    return "mpeg";
    8189}
     90
     91/** \fn ScanStreamData::SetOtherTablePid(int pid)
     92 *  \brief Sets the PID to be used to receive BAT and SDTo tables
     93 */
     94void ScanStreamData::SetOtherTablePid(int pid)
     95{
     96    if (pid >= 0)
     97        AddListeningPID((uint)pid);
     98    otherTablepid = pid;
     99}
     100