Ticket #2874: 2874-v4.patch

File 2874-v4.patch, 28.1 KB (added by danielk, 17 years ago)

Enhanced version of patch which tracks encryption for each program in PAT.

  • libs/libmythtv/dvbrecorder.h

     
    8484    void HandlePAT(const ProgramAssociationTable*);
    8585    void HandleCAT(const ConditionalAccessTable*) {}
    8686    void HandlePMT(uint pid, const ProgramMapTable*);
     87    void HandleEncryptionStatus(uint /*pnum*/, bool /*encrypted*/) { }
    8788
    8889    // ATSC Main
    8990    void HandleSTT(const SystemTimeTable*);
  • libs/libmythtv/hdhrrecorder.h

     
    4646    void HandlePAT(const ProgramAssociationTable*);
    4747    void HandleCAT(const ConditionalAccessTable*) {}
    4848    void HandlePMT(uint pid, const ProgramMapTable*);
     49    void HandleEncryptionStatus(uint /*pnum*/, bool /*encrypted*/) { }
    4950
    5051    // MPEG Single Program Stream Listener
    5152    void HandleSingleProgramPAT(ProgramAssociationTable *pat);
  • libs/libmythtv/signalmonitor.h

     
    148148    static const uint64_t kDTVSigMon_SDTSeen    = 0x0000000080ULL;
    149149    /// We've seen the FireWire STB power state
    150150    static const uint64_t kFWSigMon_PowerSeen   = 0x0000000100ULL;
     151    /// We can encrypt the stream
     152    static const uint64_t kDTVSigMon_CryptSeen  = 0x0000000200ULL;
    151153
    152154    /// We've seen a PAT matching our requirements
    153155    static const uint64_t kDTVSigMon_PATMatch   = 0x0000001000ULL;
     
    167169    static const uint64_t kDTVSigMon_SDTMatch   = 0x0000080000ULL;
    168170    /// We've seen a FireWire STB power state matching our requirements
    169171    static const uint64_t kFWSigMon_PowerMatch  = 0x0000100000ULL;
     172    /// We can encrypt the stream
     173    static const uint64_t kDTVSigMon_CryptMatch = 0x0000200000ULL;
    170174
    171175    static const uint64_t kDTVSigMon_WaitForPAT = 0x0001000000ULL;
    172176    static const uint64_t kDTVSigMon_WaitForPMT = 0x0002000000ULL;
     
    176180    static const uint64_t kDTVSigMon_WaitForSDT = 0x0020000000ULL;
    177181    static const uint64_t kDTVSigMon_WaitForSig = 0x0040000000ULL;
    178182    static const uint64_t kFWSigMon_WaitForPower= 0x0080000000ULL;
     183    static const uint64_t kDTVSigMon_WaitForCrypt=0x0100000000ULL;
    179184
    180     static const uint64_t kDTVSigMon_WaitForAll = 0x00FF000000ULL;
     185    static const uint64_t kDTVSigMon_WaitForAll = 0x01FF000000ULL;
    181186
    182187    /// Wait for the Signal to Noise Ratio to rise above a threshhold
    183     static const uint64_t kDVBSigMon_WaitForSNR = 0x0100000000ULL;
     188    static const uint64_t kDVBSigMon_WaitForSNR = 0x1000000000ULL;
    184189    /// Wait for the Bit Error Rate to fall below a threshhold
    185     static const uint64_t kDVBSigMon_WaitForBER = 0x0200000000ULL;
     190    static const uint64_t kDVBSigMon_WaitForBER = 0x2000000000ULL;
    186191    /// Wait for uncorrected FEC blocks to fall below a threshhold
    187     static const uint64_t kDVBSigMon_WaitForUB  = 0x0400000000ULL;
     192    static const uint64_t kDVBSigMon_WaitForUB  = 0x4000000000ULL;
    188193    /// Wait for rotor to complete turning the antenna
    189     static const uint64_t kDVBSigMon_WaitForPos = 0x0800000000ULL;
     194    static const uint64_t kDVBSigMon_WaitForPos = 0x8000000000ULL;
    190195
    191196  protected:
    192197    pthread_t    monitor_thread;
     
    228233        str += "SDT,";
    229234    if (SignalMonitor::kFWSigMon_PowerSeen   & flags)
    230235        str += "STB,";
     236    if (SignalMonitor::kDTVSigMon_CryptSeen  & flags)
     237        str += "Crypt,";
    231238
    232239    str += ") Match(";
    233240    if (SignalMonitor::kDTVSigMon_PATMatch   & flags)
     
    248255        str += "SDT,";
    249256    if (SignalMonitor::kFWSigMon_PowerMatch  & flags)
    250257        str += "STB,";
     258    if (SignalMonitor::kDTVSigMon_CryptMatch & flags)
     259        str += "Crypt,";
    251260
    252261    str += ") Wait(";
    253262    if (SignalMonitor::kDTVSigMon_WaitForPAT & flags)
     
    266275        str += "Sig,";
    267276    if (SignalMonitor::kFWSigMon_WaitForPower& flags)
    268277        str += "STB,";
     278    if (SignalMonitor::kDTVSigMon_WaitForCrypt & flags)
     279        str += "Crypt,";
    269280
    270281    if (SignalMonitor::kDVBSigMon_WaitForSNR & flags)
    271282        str += "SNR,";
  • libs/libmythtv/mpeg/mpegstreamdata.cpp

     
    11// -*- Mode: c++ -*-
    22// Copyright (c) 2003-2004, Daniel Thor Kristjansson
    33
     4#include <algorithm> // for find
     5using namespace std;
     6
    47// POSIX headers
    58#include <sys/time.h> // for gettimeofday
    69
     
    5457      _local_utc_offset(0), _si_time_offset_cnt(0),
    5558      _si_time_offset_indx(0),
    5659      _eit_helper(NULL), _eit_rate(0.0f),
    57       _listener_lock(true),
     60      _encryption_lock(true), _listener_lock(true),
    5861      _cache_tables(cacheTables), _cache_lock(true),
    5962      // Single program stuff
    6063      _desired_program(desiredProgram),
     
    172175        _cached_pmts.clear();
    173176    }
    174177
     178    ResetDecryptionMonitoringState();
     179
    175180    AddListeningPID(MPEG_PAT_PID);
    176181}
    177182
     
    777782bool MPEGStreamData::ProcessTSPacket(const TSPacket& tspacket)
    778783{
    779784    bool ok = !tspacket.TransportError();
     785
     786    if (IsEncryptionTestPID(tspacket.PID()))
     787    {
     788        ProcessEncryptedPacket(tspacket);
     789    }
     790
    780791    if (ok && !tspacket.ScramplingControl() && tspacket.HasPayload() &&
    781792        IsListeningPID(tspacket.PID()))
    782793    {
    783794        HandleTSTables(&tspacket);
    784795    }
     796
    785797    return ok;
    786798}
    787799
     
    12391251        }
    12401252    }
    12411253}
     1254
     1255void MPEGStreamData::AddEncryptionTestPID(uint pnum, uint pid, bool isvideo)
     1256{
     1257    QMutexLocker locker(&_encryption_lock);
     1258
     1259    //VERBOSE(VB_IMPORTANT, "AddEncryptionTestPID("<<pnum
     1260    //        <<", 0x"<<hex<<pid<<dec<<")");
     1261
     1262    _encryption_pid_to_info[pid] = CryptInfo((isvideo) ? 10000 : 500, 8);
     1263   
     1264    _encryption_pid_to_pnums[pid].push_back(pnum);
     1265    _encryption_pnum_to_pids[pnum].push_back(pid);
     1266    _encryption_pnum_to_status[pnum] = kEncUnknown;
     1267}
     1268
     1269void MPEGStreamData::RemoveEncryptionTestPIDs(uint pnum)
     1270{
     1271    QMutexLocker locker(&_encryption_lock);
     1272
     1273    //VERBOSE(VB_RECORD,
     1274    //        QString("Tearing down up decryption monitoring "
     1275    //                "for program %1").arg(pnum));
     1276
     1277    QMap<uint, uint_vec_t>::iterator list;
     1278    uint_vec_t::iterator it;
     1279
     1280    uint_vec_t pids = _encryption_pnum_to_pids[pnum];
     1281    for (uint i = 0; i < pids.size(); i++)
     1282    {
     1283        uint pid = pids[i];
     1284
     1285        //VERBOSE(VB_IMPORTANT, QString("Removing 0x%1 PID Enc monitoring")
     1286        //        .arg(pid,0,16));
     1287
     1288        list = _encryption_pid_to_pnums.find(pid);
     1289        if (list != _encryption_pid_to_pnums.end())
     1290        {
     1291            it = find((*list).begin(), (*list).end(), pnum);
     1292
     1293            if (it != (*list).end())
     1294                (*list).erase(it);
     1295
     1296            if ((*list).empty())
     1297            {
     1298                _encryption_pid_to_pnums.erase(pid);
     1299                _encryption_pid_to_info.erase(pid);
     1300            }
     1301        }
     1302    }
     1303
     1304    _encryption_pnum_to_pids.erase(pnum);
     1305}
     1306
     1307bool MPEGStreamData::IsEncryptionTestPID(uint pid) const
     1308{
     1309    QMutexLocker locker(&_encryption_lock);
     1310
     1311    QMap<uint, CryptInfo>::const_iterator it =
     1312        _encryption_pid_to_info.find(pid);
     1313
     1314    return it != _encryption_pid_to_info.end();
     1315}
     1316
     1317void MPEGStreamData::TestDecryption(const ProgramMapTable *pmt)
     1318{
     1319    QMutexLocker locker(&_encryption_lock);
     1320
     1321    //VERBOSE(VB_RECORD,
     1322    //        QString("Setting up decryption monitoring "
     1323    //                "for program %1").arg(pmt->ProgramNumber()));
     1324
     1325    bool encrypted = pmt->IsProgramEncrypted();
     1326    for (uint i = 0; i < pmt->StreamCount(); i++)
     1327    {
     1328        if (!encrypted && !pmt->IsStreamEncrypted(i))
     1329            continue;
     1330
     1331        bool is_vid = pmt->IsVideo(i, _sistandard);
     1332        bool is_aud = pmt->IsAudio(i, _sistandard);
     1333        if (is_vid || is_aud)
     1334        {
     1335            AddEncryptionTestPID(
     1336                pmt->ProgramNumber(), pmt->StreamPID(i), is_vid);
     1337        }
     1338    }
     1339}
     1340
     1341void MPEGStreamData::ResetDecryptionMonitoringState(void)
     1342{
     1343    QMutexLocker locker(&_encryption_lock);
     1344
     1345    _encryption_pid_to_info.clear();
     1346    _encryption_pid_to_pnums.clear();
     1347    _encryption_pnum_to_pids.clear();
     1348}
     1349
     1350bool MPEGStreamData::IsProgramDecrypted(uint pnum) const
     1351{
     1352    QMutexLocker locker(&_encryption_lock);
     1353    return _encryption_pnum_to_status[pnum] == kEncDecrypted;
     1354}
     1355
     1356bool MPEGStreamData::IsProgramEncrypted(uint pnum) const
     1357{
     1358    QMutexLocker locker(&_encryption_lock);
     1359    return _encryption_pnum_to_status[pnum] == kEncEncrypted;
     1360}
     1361
     1362static QString toString(CryptStatus status)
     1363{
     1364    if (kEncDecrypted == status)
     1365        return "Decrypted";
     1366    else if (kEncEncrypted == status)
     1367        return "Encrypted";
     1368    else
     1369        return "Unknown";
     1370}
     1371
     1372/** \fn MPEGStreamData::ProcessEncryptedPacket(const TSPacket& tspacket)
     1373 *  \brief counts en/decrypted packets to decide if a stream is en/decrypted
     1374 */
     1375void MPEGStreamData::ProcessEncryptedPacket(const TSPacket& tspacket)
     1376{
     1377    QMutexLocker locker(&_encryption_lock);
     1378
     1379    const uint pid = tspacket.PID();
     1380    CryptInfo &info = _encryption_pid_to_info[pid];
     1381
     1382    CryptStatus status = kEncUnknown;
     1383
     1384    if (tspacket.ScramplingControl())
     1385    {
     1386        info.decrypted_packets = 0;
     1387
     1388        // If a fair amount of encrypted packets is passed assume that
     1389        // the stream is not decryptable
     1390        if (++info.encrypted_packets >= info.encrypted_min)
     1391            status = kEncEncrypted;
     1392    }
     1393    else
     1394    {
     1395        info.encrypted_packets = 0;
     1396        if (++info.decrypted_packets > info.decrypted_min)
     1397            status = kEncDecrypted;
     1398    }
     1399
     1400    if (status == info.status)
     1401        return; // pid encryption status unchanged
     1402
     1403    info.status = status;
     1404
     1405    VERBOSE(VB_IMPORTANT, QString("PID 0x%1 status: %2")
     1406            .arg(pid,0,16).arg(status));
     1407
     1408    uint_vec_t pnum_del_list;
     1409    const uint_vec_t &pnums = _encryption_pid_to_pnums[pid];
     1410    for (uint i = 0; i < pnums.size(); i++)
     1411    {
     1412        CryptStatus status = _encryption_pnum_to_status[pnums[i]];
     1413
     1414        const uint_vec_t &pids = _encryption_pnum_to_pids[pnums[i]];
     1415        if (!pids.empty())
     1416        {
     1417            uint enc_cnt[3] = { 0, 0, 0 };
     1418            for (uint j = 0; j < pids.size(); j++)
     1419            {
     1420                CryptStatus stat = _encryption_pid_to_info[pids[j]].status;
     1421                enc_cnt[stat]++;
     1422
     1423                //VERBOSE(VB_IMPORTANT,
     1424                //        QString("\tpnum %1 PID 0x%2 status: %3")
     1425                //        .arg(pnums[i]).arg(pids[j],0,16)
     1426                //        .arg(toString(stat)));
     1427            }
     1428            status = kEncUnknown;
     1429
     1430            if (enc_cnt[kEncEncrypted])
     1431                status = kEncEncrypted;
     1432            else if (enc_cnt[kEncDecrypted] >= 2)
     1433                status = kEncDecrypted;
     1434        }
     1435
     1436        if (status == _encryption_pnum_to_status[pnums[i]])
     1437            continue; // program encryption status unchanged
     1438
     1439        VERBOSE(VB_RECORD, QString("Program %1 status: %2")
     1440                .arg(pnums[i]).arg(toString(status)));
     1441
     1442        _encryption_pnum_to_status[pnums[i]] = status;
     1443
     1444        _listener_lock.lock();
     1445        for (uint j = 0; j < _mpeg_listeners.size(); j++)
     1446        {
     1447            _mpeg_listeners[j]->HandleEncryptionStatus(
     1448                pnums[i], toString(status));
     1449        }
     1450        _listener_lock.unlock();
     1451
     1452        if (status != kEncUnknown)
     1453            pnum_del_list.push_back(pnums[i]);
     1454    }
     1455
     1456    for (uint i = 0; i < pnum_del_list.size(); i++)
     1457        RemoveEncryptionTestPIDs(pnums[i]);
     1458}
  • libs/libmythtv/mpeg/mpegtables.h

     
    528528    bool IsVideo(uint i, QString sistandard) const;
    529529    bool IsAudio(uint i, QString sistandard) const;
    530530    bool IsEncrypted(void) const;
     531    bool IsProgramEncrypted(void) const;
     532    bool IsStreamEncrypted(uint pid) const;
    531533    /// Returns true iff PMT contains a still-picture video stream
    532534    bool IsStillPicture(QString sistandard) const;
    533535    /// Returns a string representation of type at stream index i
  • libs/libmythtv/mpeg/streamlisteners.h

     
     1// -*- Mode: c++ -*-
    12#ifndef _STREAMLISTENERS_H_
    23#define _STREAMLISTENERS_H_
    34
     
    4243    virtual void HandlePAT(const ProgramAssociationTable*) = 0;
    4344    virtual void HandleCAT(const ConditionalAccessTable*) = 0;
    4445    virtual void HandlePMT(uint program_num, const ProgramMapTable*) = 0;
     46    virtual void HandleEncryptionStatus(uint program_number, bool) = 0;
    4547};
    4648
    4749class MPEGSingleProgramStreamListener
  • libs/libmythtv/mpeg/mpegstreamdata.h

     
    4040typedef vector<MPEGStreamListener*>     mpeg_listener_vec_t;
    4141typedef vector<MPEGSingleProgramStreamListener*> mpeg_sp_listener_vec_t;
    4242
     43typedef enum
     44{
     45    kEncUnknown   = 0,
     46    kEncDecrypted = 1,
     47    kEncEncrypted = 2,
     48} CryptStatus;
     49
     50class CryptInfo
     51{
     52  public:
     53    CryptInfo() :
     54        status(kEncUnknown), encrypted_packets(0), decrypted_packets(0),
     55        encrypted_min(1000), decrypted_min(8) { }
     56    CryptInfo(uint e, uint d) :
     57        status(kEncUnknown), encrypted_packets(0), decrypted_packets(0),
     58        encrypted_min(e), decrypted_min(d) { }
     59
     60  public:
     61    CryptStatus status;
     62    uint encrypted_packets;
     63    uint decrypted_packets;
     64    uint encrypted_min;
     65    uint decrypted_min;
     66};
     67
    4368void init_sections(sections_t &sect, uint last_section);
    4469
    4570class MPEGStreamData : public EITSource
     
    158183    virtual void ReturnCachedPMTTables(pmt_vec_t&) const;
    159184    virtual void ReturnCachedPMTTables(pmt_map_t&) const;
    160185
     186    // Encryption Monitoring
     187    void AddEncryptionTestPID(uint pnum, uint pid, bool isvideo);
     188    void RemoveEncryptionTestPIDs(uint pnum);
     189    bool IsEncryptionTestPID(uint pid) const;
     190
     191    void TestDecryption(const ProgramMapTable* pmt);
     192    void ResetDecryptionMonitoringState(void);
     193
     194    bool IsProgramDecrypted(uint pnum) const;
     195    bool IsProgramEncrypted(uint pnum) const;
     196
    161197    // "signals"
    162198    void AddMPEGListener(MPEGStreamListener*);
    163199    void RemoveMPEGListener(MPEGStreamListener*);
     
    218254    void DeletePartialPES(uint pid);
    219255    void ProcessPAT(const ProgramAssociationTable *pat);
    220256    void ProcessPMT(const ProgramMapTable *pmt);
     257    void ProcessEncryptedPacket(const TSPacket&);
    221258
    222259    static int ResyncStream(unsigned char *buffer, int curr_pos, int len);
    223260
     
    251288    QMap<uint, bool>          _pids_writing;
    252289    QMap<uint, bool>          _pids_audio;
    253290
     291    // Encryption monitoring
     292    mutable QMutex            _encryption_lock;
     293    QMap<uint, CryptInfo>     _encryption_pid_to_info;
     294    QMap<uint, uint_vec_t>    _encryption_pnum_to_pids;
     295    QMap<uint, uint_vec_t>    _encryption_pid_to_pnums;
     296    QMap<uint, CryptStatus>   _encryption_pnum_to_status;
     297
    254298    // Signals
    255299    mutable QMutex            _listener_lock;
    256300    mpeg_listener_vec_t       _mpeg_listeners;
  • libs/libmythtv/mpeg/mpegtables.cpp

     
    281281 */
    282282bool ProgramMapTable::IsEncrypted(void) const
    283283{
     284    bool encrypted = IsProgramEncrypted();
     285
     286    for (uint i = 0; !encrypted && i < StreamCount(); i++)
     287        encrypted |= IsStreamEncrypted(i);
     288
     289    return encrypted;
     290}
     291
     292/** \fn ProgramMapTable::IsProgramEncrypted(void) const
     293 *  \brief Returns true iff PMT's ProgramInfo contains CA descriptor.
     294 */
     295bool ProgramMapTable::IsProgramEncrypted(void) const
     296{
    284297    desc_list_t descs = MPEGDescriptor::ParseOnlyInclude(
    285298        ProgramInfo(), ProgramInfoLength(), DescriptorID::conditional_access);
    286299
     
    295308        //VERBOSE(VB_IMPORTANT, "DTVsm: "<<cad.toString());
    296309    }
    297310
    298     for (uint i = 0; i < StreamCount(); i++)
     311    return encrypted;
     312}
     313
     314/** \fn ProgramMapTable::IsStreamEncrypted(uint i) const
     315 *  \brief Returns true iff PMT contains CA descriptor.
     316 *
     317 *  \param i index of stream
     318 */
     319bool ProgramMapTable::IsStreamEncrypted(uint i) const
     320{
     321    desc_list_t descs = MPEGDescriptor::ParseOnlyInclude(
     322        StreamInfo(i), StreamInfoLength(i), DescriptorID::conditional_access);
     323
     324    bool encrypted = false;
     325    QMap<uint,uint> encryption_system;
     326    for (uint j = 0; j < descs.size(); j++)
    299327    {
    300         desc_list_t descs = MPEGDescriptor::ParseOnlyInclude(
    301             StreamInfo(i), StreamInfoLength(i),
    302             DescriptorID::conditional_access);
     328        ConditionalAccessDescriptor cad(descs[j]);
     329        encryption_system[cad.PID()] = cad.SystemID();
     330        encrypted |= cad.SystemID();
    303331
    304         for (uint j = 0; j < descs.size(); j++)
    305         {
    306             ConditionalAccessDescriptor cad(descs[j]);
    307             encryption_system[cad.PID()] = cad.SystemID();
    308             encrypted |= cad.SystemID();
    309 
    310             //VERBOSE(VB_IMPORTANT, "DTVsm: "<<cad.toString());
    311         }
     332        //VERBOSE(VB_IMPORTANT, "DTVsm: "<<cad.toString());
    312333    }
    313334
    314335    return encrypted;
  • libs/libmythtv/tv_play.cpp

     
    46864686    float snr  = 0.0f;
    46874687    uint  ber  = 0xffffffff;
    46884688    int   pos  = -1;
    4689     QString pat(""), pmt(""), mgt(""), vct(""), nit(""), sdt("");
     4689    QString pat(""), pmt(""), mgt(""), vct(""), nit(""), sdt(""), crypt("");
    46904690    QString err = QString::null, msg = QString::null;
    46914691    for (it = slist.begin(); it != slist.end(); ++it)
    46924692    {
     
    47364736            sdt = it->IsGood() ? "s" : "_";
    47374737        else if ("matching_sdt" == it->GetShortName())
    47384738            sdt = it->IsGood() ? "S" : sdt;
     4739        else if ("seen_crypt" == it->GetShortName())
     4740            crypt = it->IsGood() ? "c" : "_";
     4741        else if ("matching_crypt" == it->GetShortName())
     4742            crypt = it->IsGood() ? "C" : crypt;
    47394743    }
    47404744    if (sig)
    47414745        infoMap["signal"] = QString::number(sig); // use normalized value
     
    47534757    if ((pos >= 0) && (pos < 100))
    47544758        sigDesc += " | " + tr("Rotor %1\%").arg(pos,2);
    47554759
    4756     sigDesc = sigDesc + QString(" | (%1%2%3%4%5%6%7) %8")
     4760    sigDesc = sigDesc + QString(" | (%1%2%3%4%5%6%7%8) %9")
    47574761        .arg(slock).arg(pat).arg(pmt).arg(mgt).arg(vct)
    4758         .arg(nit).arg(sdt).arg(sigMsg);
     4762        .arg(nit).arg(sdt).arg(crypt).arg(sigMsg);
    47594763
    47604764    if (!err.isEmpty())
    47614765        sigDesc = err;
  • libs/libmythtv/siscan.h

     
    8585    void HandlePAT(const ProgramAssociationTable*);
    8686    void HandleCAT(const ConditionalAccessTable*) { }
    8787    void HandlePMT(uint, const ProgramMapTable*) { }
     88    void HandleEncryptionStatus(uint /*pnum*/, bool /*encrypted*/) { }
    8889
    8990    // ATSC Main
    9091    void HandleSTT(const SystemTimeTable*) {}
  • libs/libmythtv/dtvsignalmonitor.h

     
    4747    uint GetDetectedNetworkID(void)   const  { return detectedNetworkID; }
    4848    uint GetDetectedTransportID(void) const  { return detectedTransportID; }
    4949
    50     void SetFTAOnly(bool fta)    { ignoreEncrypted = fta;  }
    51     bool GetFTAOnly() const      { return ignoreEncrypted; }
    52 
    5350    /// Sets rotor target pos from 0.0 to 1.0
    5451    virtual void SetRotorTarget(float) {}
    5552
     
    8683    void HandlePAT(const ProgramAssociationTable*);
    8784    void HandleCAT(const ConditionalAccessTable*) {}
    8885    void HandlePMT(uint, const ProgramMapTable*);
     86    void HandleEncryptionStatus(uint, bool enc_status);
    8987
    9088    // ATSC Main
    9189    void HandleSTT(const SystemTimeTable*);
     
    119117    SignalMonitorValue seenVCT;
    120118    SignalMonitorValue seenNIT;
    121119    SignalMonitorValue seenSDT;
     120    SignalMonitorValue seenCrypt;
    122121    SignalMonitorValue matchingPAT;
    123122    SignalMonitorValue matchingPMT;
    124123    SignalMonitorValue matchingMGT;
    125124    SignalMonitorValue matchingVCT;
    126125    SignalMonitorValue matchingNIT;
    127126    SignalMonitorValue matchingSDT;
     127    SignalMonitorValue matchingCrypt;
    128128
    129129    // ATSC tuning info
    130130    int                majorChannel;
     
    138138    // MPEG/DVB/ATSC tuning info
    139139    int                programNumber;
    140140
    141     bool               ignoreEncrypted;
    142141    QString            error;
    143142};
    144143
  • libs/libmythtv/tv_rec.cpp

     
    16641664        sd->SetCaching(true);
    16651665    }
    16661666
    1667     bool fta = CardUtil::IgnoreEncrypted(
    1668         GetCaptureCardNum(), channel->GetCurrentInput());
    1669 
    16701667    QString sistandard = dtvchan->GetSIStandard();
    16711668
    16721669    // Check if this is an ATSC Channel
     
    16901687        sm->SetStreamData(sd);
    16911688        sm->SetChannel(major, minor);
    16921689        sd->SetVideoStreamsRequired(1);
    1693         sm->SetFTAOnly(fta);
    16941690
    16951691        // Try to get pid of VCT from cache and
    16961692        // require MGT if we don't have VCT pid.
     
    17461742        sm->SetDVBService(netid, tsid, progNum);
    17471743        sd->SetVideoStreamsRequired(neededVideo);
    17481744        sd->SetAudioStreamsRequired(neededAudio);
    1749         sm->SetFTAOnly(fta);
    17501745
    17511746        sm->AddFlags(SignalMonitor::kDTVSigMon_WaitForPMT |
    17521747                     SignalMonitor::kDTVSigMon_WaitForSDT |
     
    17841779        sm->SetStreamData(sd);
    17851780        sm->SetProgramNumber(progNum);
    17861781        sd->SetVideoStreamsRequired(1);
    1787         sm->SetFTAOnly(fta);
    17881782        sm->AddFlags(SignalMonitor::kDTVSigMon_WaitForPAT |
    17891783                     SignalMonitor::kDTVSigMon_WaitForPMT |
    17901784                     SignalMonitor::kDVBSigMon_WaitForPos);
  • libs/libmythtv/dtvsignalmonitor.cpp

     
    11#include <unistd.h>
    22
    33#include "dtvchannel.h"
     4#include "dvbchannel.h"
    45#include "dtvsignalmonitor.h"
    56#include "scanstreamdata.h"
    67#include "mpegtables.h"
     
    3031      seenVCT(tr("Seen")+" VCT", "seen_vct", 1, true, 0, 1, 0),
    3132      seenNIT(tr("Seen")+" NIT", "seen_nit", 1, true, 0, 1, 0),
    3233      seenSDT(tr("Seen")+" SDT", "seen_sdt", 1, true, 0, 1, 0),
     34      seenCrypt(tr("Seen")+" Crypt", "seen_crypt", 1, true, 0, 1, 0),
    3335      matchingPAT(tr("Matching")+" PAT", "matching_pat", 1, true, 0, 1, 0),
    3436      matchingPMT(tr("Matching")+" PMT", "matching_pmt", 1, true, 0, 1, 0),
    3537      matchingMGT(tr("Matching")+" MGT", "matching_mgt", 1, true, 0, 1, 0),
    3638      matchingVCT(tr("Matching")+" VCT", "matching_vct", 1, true, 0, 1, 0),
    3739      matchingNIT(tr("Matching")+" NIT", "matching_nit", 1, true, 0, 1, 0),
    3840      matchingSDT(tr("Matching")+" SDT", "matching_sdt", 1, true, 0, 1, 0),
     41      matchingCrypt(tr("Matching")+" Crypt", "matching_crypt",
     42                    1, true, 0, 1, 0),
    3943      majorChannel(-1), minorChannel(-1),
    4044      networkID(0), transportID(0),
    4145      detectedNetworkID(0), detectedTransportID(0),
    4246      programNumber(-1),
    43       ignoreEncrypted(true),
    4447      error("")
    4548{
    4649}
     
    112115        list<<seenSDT.GetName()<<seenSDT.GetStatus();
    113116        list<<matchingSDT.GetName()<<matchingSDT.GetStatus();
    114117    }
     118    if (flags & kDTVSigMon_WaitForCrypt)
     119    {
     120        list<<seenCrypt.GetName()<<seenCrypt.GetStatus();
     121        list<<matchingCrypt.GetName()<<matchingCrypt.GetStatus();
     122    }
    115123    if (error != "")
    116124    {
    117125        list<<"error"<<error;
     
    140148    seenVCT.SetValue(    (flags & kDTVSigMon_VCTSeen)  ? 1 : 0);
    141149    seenNIT.SetValue(    (flags & kDTVSigMon_NITSeen)  ? 1 : 0);
    142150    seenSDT.SetValue(    (flags & kDTVSigMon_SDTSeen)  ? 1 : 0);
     151    seenCrypt.SetValue(  (flags & kDTVSigMon_CryptSeen)? 1 : 0);
    143152    matchingPAT.SetValue((flags & kDTVSigMon_PATMatch) ? 1 : 0);
    144153    matchingPMT.SetValue((flags & kDTVSigMon_PMTMatch) ? 1 : 0);
    145154    matchingMGT.SetValue((flags & kDTVSigMon_MGTMatch) ? 1 : 0);
    146155    matchingVCT.SetValue((flags & kDTVSigMon_VCTMatch) ? 1 : 0);
    147156    matchingNIT.SetValue((flags & kDTVSigMon_NITMatch) ? 1 : 0);
    148157    matchingSDT.SetValue((flags & kDTVSigMon_SDTMatch) ? 1 : 0);
     158    matchingCrypt.SetValue((flags & kDTVSigMon_CryptMatch) ? 1 : 0);
    149159}
    150160
    151161void DTVSignalMonitor::UpdateListeningForEIT(void)
     
    177187    DBG_SM(QString("SetChannel(%1, %2)").arg(major).arg(minor), "");
    178188    if (GetATSCStreamData() && (majorChannel != major || minorChannel != minor))
    179189    {
    180         RemoveFlags(kDTVSigMon_PATSeen | kDTVSigMon_PATMatch |
    181                     kDTVSigMon_PMTSeen | kDTVSigMon_PMTMatch |
    182                     kDTVSigMon_VCTSeen | kDTVSigMon_VCTMatch);
     190        RemoveFlags(kDTVSigMon_PATSeen   | kDTVSigMon_PATMatch |
     191                    kDTVSigMon_PMTSeen   | kDTVSigMon_PMTMatch |
     192                    kDTVSigMon_VCTSeen   | kDTVSigMon_VCTMatch |
     193                    kDTVSigMon_CryptSeen | kDTVSigMon_CryptMatch);
    183194        majorChannel = major;
    184195        minorChannel = minor;
    185196        GetATSCStreamData()->SetDesiredChannel(major, minor);
     
    192203    DBG_SM(QString("SetProgramNumber(%1)").arg(progNum), "");
    193204    if (programNumber != progNum)
    194205    {
    195         RemoveFlags(kDTVSigMon_PMTSeen | kDTVSigMon_PMTMatch);
     206        RemoveFlags(kDTVSigMon_PMTSeen   | kDTVSigMon_PMTMatch |
     207                    kDTVSigMon_CryptSeen | kDTVSigMon_CryptMatch);
    196208        programNumber = progNum;
    197209        if (GetStreamData())
    198210            GetStreamData()->SetDesiredProgram(programNumber);
     
    211223        return;
    212224    }
    213225
    214     RemoveFlags(kDTVSigMon_PMTSeen | kDTVSigMon_PMTMatch |
    215                 kDTVSigMon_SDTSeen | kDTVSigMon_SDTMatch);
     226    RemoveFlags(kDTVSigMon_PMTSeen   | kDTVSigMon_PMTMatch |
     227                kDTVSigMon_SDTSeen   | kDTVSigMon_SDTMatch |
     228                kDTVSigMon_CryptSeen | kDTVSigMon_CryptMatch);
    216229
    217230    transportID   = tsid;
    218231    networkID     = netid;
     
    298311{
    299312    AddFlags(kDTVSigMon_PMTSeen);
    300313
     314    if (pmt->IsEncrypted())
     315        GetStreamData()->TestDecryption(pmt);
     316
    301317    if (programNumber < 0)
    302318        return; // don't print error messages during channel scan.
    303319
     
    309325        return; // Not the PMT we are looking for...
    310326    }
    311327
    312     if (ignoreEncrypted && pmt->IsEncrypted())
    313     {
    314         VERBOSE(VB_IMPORTANT, LOC + "Ignoring encrypted program");
    315         return;
    316     }
    317 
    318328    // if PMT contains audio and/or video stream set as matching.
    319329    uint hasAudio = 0;
    320330    uint hasVideo = 0;
     
    328338    if ((hasVideo >= GetStreamData()->GetVideoStreamsRequired()) &&
    329339        (hasAudio >= GetStreamData()->GetAudioStreamsRequired()))
    330340    {
     341#ifdef USING_DVB
     342        DVBChannel* dvbchan = dynamic_cast<DVBChannel*>(GetDTVChannel());
     343        if (dvbchan)
     344            dvbchan->SetPMT(pmt);
     345#endif // USING_DVB
     346
     347        if (pmt->IsEncrypted())
     348            AddFlags(kDTVSigMon_WaitForCrypt);
     349
    331350        AddFlags(kDTVSigMon_PMTMatch);
    332351    }
    333352    else
     
    442461    }
    443462}
    444463
     464void DTVSignalMonitor::HandleEncryptionStatus(uint, bool enc_status)
     465{
     466    AddFlags(kDTVSigMon_CryptSeen);
     467    if (!enc_status)
     468        AddFlags(kDTVSigMon_CryptMatch);
     469}
     470
    445471ATSCStreamData *DTVSignalMonitor::GetATSCStreamData()
    446472{
    447473    return dynamic_cast<ATSCStreamData*>(stream_data);
     
    489515            return false;
    490516    if ((flags & kDTVSigMon_WaitForSDT) && !matchingSDT.IsGood())
    491517            return false;
     518    if ((flags & kDTVSigMon_WaitForCrypt) && !matchingCrypt.IsGood())
     519            return false;
    492520
    493521    return true;
    494522}