Ticket #9670: 9670-allow-non-ts-streams-past-signal-monitor.patch

File 9670-allow-non-ts-streams-past-signal-monitor.patch, 5.2 KB (added by danielk, 12 years ago)

Patch to detect TS streams and disable TS portion of signal monitoring when the stream is not a transport stream.

  • mythtv/libs/libmythtv/iptvsignalmonitor.cpp

    diff --git a/mythtv/libs/libmythtv/iptvsignalmonitor.cpp b/mythtv/libs/libmythtv/iptvsignalmonitor.cpp
    index 04871d5..68f507c 100644
    a b void IPTVTableMonitorThread::run(void) 
    2222    RunEpilog();
    2323}
    2424
     25const uint IPTVSignalMonitor::kStreamTypeDetectionMinSize = 128*1024;
     26
    2527/** \fn IPTVSignalMonitor::IPTVSignalMonitor(int,IPTVChannel*,uint64_t)
    2628 *  \brief Initializes signal lock and signal values.
    2729 *
    IPTVSignalMonitor::IPTVSignalMonitor(int db_cardnum, 
    4951        isLocked = GetChannel()->GetFeeder()->Open(chaninfo.m_url);
    5052    }
    5153
     54    streamTypeDetectionBuffer.reserve(kStreamTypeDetectionMinSize + 64 * 1024);
     55
    5256    QMutexLocker locker(&statusLock);
    5357    signalLock.SetValue((isLocked) ? 1 : 0);
    5458    signalStrength.SetValue((isLocked) ? 100 : 0);
    void IPTVSignalMonitor::RunTableMonitor(void) 
    106110    DBG_SM("Run", "end");
    107111}
    108112
     113/// This tries to find TS sync bytes at 188, 204,and 208 byte intervals.
     114/// If it finds them it returns kStreamTypeTS otherwise it returns
     115/// kStreamTypePES. Ideally we'd really detect PES streams and return
     116/// kStreamTypeUnknown if it isn't a PES stream either, but this is
     117/// a start.
     118static IPTVSignalMonitor::StreamType detect_stream_type(
     119    const vector<unsigned char> &data)
     120{
     121    IPTVSignalMonitor::StreamType st = IPTVSignalMonitor::kStreamTypePES;
     122
     123    QList<uint> sync_locations;
     124    for (uint i = 0; i < data.size(); i++)
     125    {
     126        if (SYNC_BYTE == data[i])
     127            sync_locations.push_back(i);
     128    }
     129
     130    if (sync_locations.empty())
     131        return st;
     132
     133    QMap<uint, uint> counts;
     134
     135    QSet<uint> sizes;
     136    sizes.insert(sizeof(TSPacket));
     137    sizes.insert(sizeof(TSDVBEmissionPacket));
     138    sizes.insert(sizeof(TSISDBEmissionPacket));
     139    sizes.insert(sizeof(TS8VSBEmissionPacket));
     140
     141    QSet<uint>::const_iterator sit = sizes.begin();
     142    for (; sit != sizes.end(); ++sit)
     143    {
     144        uint count = 0;
     145        uint last_loc = sync_locations[0];
     146        for (uint i = 1; i < data.size(); i++)
     147        {
     148            uint next = i + 1;
     149            for (uint j = i; j < data.size() && data[j] <= last_loc + *sit; j++)
     150            {
     151                if (data[j] == last_loc + *sit)
     152                {
     153                    count++;
     154                    next = j;
     155                    break;
     156                }
     157            }
     158        }
     159        counts[*sit] = count;
     160    }
     161
     162    for (sit = sizes.begin(); sit != sizes.end(); ++sit)
     163    {
     164        int expected = (data.size() / *sit) - 1;
     165        LOG(VB_GENERAL, LOG_INFO, QString("Count for %1 was %2, expected %3")
     166            .arg(*sit).arg(counts[*sit]).arg(expected));
     167        if ((counts[*sit] >= 1) && (expected >= 1) &&
     168            (counts[*sit] >= (expected * 0.8f)))
     169        {
     170            st = IPTVSignalMonitor::kStreamTypeTS;
     171        }
     172    }
     173
     174    return st;
     175}
     176
    109177void IPTVSignalMonitor::AddData(
    110178    const unsigned char *data, unsigned int dataSize)
    111179{
     180    LOG(VB_GENERAL, LOG_INFO, LOC + QString("AddData(...%1)").arg(dataSize));
    112181    GetStreamData()->ProcessData((unsigned char*)data, dataSize);
     182    if (kStreamTypeUnknown != streamType)
     183        return;
     184
     185    if (streamTypeDetectionBuffer.size() < kStreamTypeDetectionMinSize)
     186    {
     187        uint old_size = streamTypeDetectionBuffer.size();
     188        streamTypeDetectionBuffer.resize(old_size + dataSize);
     189        memcpy(&streamTypeDetectionBuffer[old_size], data, dataSize);
     190    }
     191
     192    if (streamTypeDetectionBuffer.size() >= kStreamTypeDetectionMinSize)
     193    {
     194        streamType = detect_stream_type(streamTypeDetectionBuffer);
     195        streamTypeDetectionBuffer.clear();
     196        LOG(VB_GENERAL, LOG_INFO, LOC + QString("AddData(...%1) st %2")
     197            .arg(dataSize).arg(streamType));
     198    }
     199
     200    if (kStreamTypePES == streamType)
     201    {
     202        QMutexLocker locker(&statusLock);
     203        RemoveFlags(kDTVSigMon_WaitForPAT | kDTVSigMon_WaitForPMT |
     204                    kDTVSigMon_WaitForMGT | kDTVSigMon_WaitForVCT |
     205                    kDTVSigMon_WaitForNIT | kDTVSigMon_WaitForSDT |
     206                    kDTVSigMon_WaitForCrypt);
     207    }
    113208}
    114209
    115210/** \fn IPTVSignalMonitor::UpdateValues(void)
  • mythtv/libs/libmythtv/iptvsignalmonitor.h

    diff --git a/mythtv/libs/libmythtv/iptvsignalmonitor.h b/mythtv/libs/libmythtv/iptvsignalmonitor.h
    index eae3d1d..8e137a7 100644
    a b class IPTVSignalMonitor : public DTVSignalMonitor, public TSDataListener 
    3333    // implements TSDataListener
    3434    void AddData(const unsigned char *data, unsigned int dataSize);
    3535
     36    typedef enum StreamType
     37    {
     38        kStreamTypeUnknown,
     39        kStreamTypePES,
     40        kStreamTypeTS,
     41    } StreamType;
     42
    3643  protected:
    3744    IPTVSignalMonitor(void);
    3845    IPTVSignalMonitor(const IPTVSignalMonitor&);
    class IPTVSignalMonitor : public DTVSignalMonitor, public TSDataListener 
    4653  protected:
    4754    volatile bool dtvMonitorRunning;
    4855    IPTVTableMonitorThread *tableMonitorThread;
     56
     57    StreamType streamType;
     58    static const uint kStreamTypeDetectionMinSize;
     59    vector<unsigned char> streamTypeDetectionBuffer;
    4960};
    5061
    5162#endif // _IPTVSIGNALMONITOR_H_