Index: libs/libmythtv/dvbrecorder.h
===================================================================
--- libs/libmythtv/dvbrecorder.h	(revision 12418)
+++ libs/libmythtv/dvbrecorder.h	(working copy)
@@ -78,9 +78,11 @@
     bool IsOpen(void) const { return _stream_fd >= 0; }
     void Close(void);
 
+    // MPEG Stream Listener
     void HandlePAT(const ProgramAssociationTable*);
     void HandleCAT(const ConditionalAccessTable*) {}
     void HandlePMT(uint pid, const ProgramMapTable*);
+    void HandleEncryptionStatus(uint pid, bool encrypted) { }
 
     void SetStreamData(MPEGStreamData*);
     MPEGStreamData* GetStreamData(void) { return _stream_data; }
Index: libs/libmythtv/hdhrrecorder.h
===================================================================
--- libs/libmythtv/hdhrrecorder.h	(revision 12418)
+++ libs/libmythtv/hdhrrecorder.h	(working copy)
@@ -46,6 +46,7 @@
     void HandlePAT(const ProgramAssociationTable*);
     void HandleCAT(const ConditionalAccessTable*) {}
     void HandlePMT(uint pid, const ProgramMapTable*);
+    void HandleEncryptionStatus(uint pid, bool encrypted) { }
 
     // MPEG Single Program Stream Listener
     void HandleSingleProgramPAT(ProgramAssociationTable *pat);
Index: libs/libmythtv/signalmonitor.h
===================================================================
--- libs/libmythtv/signalmonitor.h	(revision 12418)
+++ libs/libmythtv/signalmonitor.h	(working copy)
@@ -148,6 +148,8 @@
     static const uint64_t kDTVSigMon_SDTSeen    = 0x0000000080ULL;
     /// We've seen the FireWire STB power state
     static const uint64_t kFWSigMon_PowerSeen   = 0x0000000100ULL;
+    /// We can encrypt the stream
+    static const uint64_t kDTVSigMon_CryptSeen  = 0x0000000200ULL;
 
     /// We've seen a PAT matching our requirements
     static const uint64_t kDTVSigMon_PATMatch   = 0x0000001000ULL;
@@ -167,6 +169,8 @@
     static const uint64_t kDTVSigMon_SDTMatch   = 0x0000080000ULL;
     /// We've seen a FireWire STB power state matching our requirements
     static const uint64_t kFWSigMon_PowerMatch  = 0x0000100000ULL;
+    /// We can encrypt the stream
+    static const uint64_t kDTVSigMon_CryptMatch = 0x0000200000ULL;
 
     static const uint64_t kDTVSigMon_WaitForPAT = 0x0001000000ULL;
     static const uint64_t kDTVSigMon_WaitForPMT = 0x0002000000ULL;
@@ -176,8 +180,9 @@
     static const uint64_t kDTVSigMon_WaitForSDT = 0x0020000000ULL;
     static const uint64_t kDTVSigMon_WaitForSig = 0x0040000000ULL;
     static const uint64_t kFWSigMon_WaitForPower= 0x0080000000ULL;
+    static const uint64_t kDTVSigMon_WaitForCrypt= 0x1000000000ULL;
 
-    static const uint64_t kDTVSigMon_WaitForAll = 0x00FF000000ULL;
+    static const uint64_t kDTVSigMon_WaitForAll = 0x10FF000000ULL;
 
     /// Wait for the Signal to Noise Ratio to rise above a threshhold
     static const uint64_t kDVBSigMon_WaitForSNR = 0x0100000000ULL;
@@ -228,6 +233,8 @@
         str += "SDT,";
     if (SignalMonitor::kFWSigMon_PowerSeen   & flags)
         str += "STB,";
+    if (SignalMonitor::kDTVSigMon_CryptSeen  & flags)
+        str += "Crypt,";
 
     str += ") Match(";
     if (SignalMonitor::kDTVSigMon_PATMatch   & flags)
@@ -248,6 +255,8 @@
         str += "SDT,";
     if (SignalMonitor::kFWSigMon_PowerMatch  & flags)
         str += "STB,";
+    if (SignalMonitor::kDTVSigMon_CryptMatch & flags)
+        str += "Crypt,";
 
     str += ") Wait(";
     if (SignalMonitor::kDTVSigMon_WaitForPAT & flags)
@@ -266,6 +275,8 @@
         str += "Sig,";
     if (SignalMonitor::kFWSigMon_WaitForPower& flags)
         str += "STB,";
+    if (SignalMonitor::kDTVSigMon_WaitForCrypt & flags)
+        str += "Crypt,";
 
     if (SignalMonitor::kDVBSigMon_WaitForSNR & flags)
         str += "SNR,";
Index: libs/libmythtv/mpeg/mpegstreamdata.cpp
===================================================================
--- libs/libmythtv/mpeg/mpegstreamdata.cpp	(revision 12418)
+++ libs/libmythtv/mpeg/mpegstreamdata.cpp	(working copy)
@@ -727,11 +727,23 @@
 bool MPEGStreamData::ProcessTSPacket(const TSPacket& tspacket)
 {
     bool ok = !tspacket.TransportError();
+
+    if (ok && IsEncryptionTestPID(tspacket.PID()))
+    {
+        QMutexLocker locker(&_listener_lock);
+        for (uint i = 0; i < _mpeg_listeners.size(); i++)
+        {
+            _mpeg_listeners[i]->HandleEncryptionStatus(
+                tspacket.PID(), tspacket.ScramplingControl());
+        }
+    }
+
     if (ok && !tspacket.ScramplingControl() && tspacket.HasPayload() &&
         IsListeningPID(tspacket.PID()))
     {
         HandleTSTables(&tspacket);
     }
+
     return ok;
 }
 
@@ -778,6 +790,12 @@
     return it != _pids_audio.end();
 }
 
+bool MPEGStreamData::IsEncryptionTestPID(uint pid) const
+{
+    QMap<uint, bool>::const_iterator it = _pids_encryption.find(pid);
+    return it != _pids_encryption.end();
+}
+
 void MPEGStreamData::SavePartialPES(uint pid, PESPacket* packet)
 {
     pid_pes_map_t::iterator it = _partial_pes_packet_cache.find(pid);
Index: libs/libmythtv/mpeg/streamlisteners.h
===================================================================
--- libs/libmythtv/mpeg/streamlisteners.h	(revision 12418)
+++ libs/libmythtv/mpeg/streamlisteners.h	(working copy)
@@ -1,3 +1,4 @@
+// -*- Mode: c++ -*-
 #ifndef _STREAMLISTENERS_H_
 #define _STREAMLISTENERS_H_
 
@@ -41,6 +42,7 @@
     virtual void HandlePAT(const ProgramAssociationTable*) = 0;
     virtual void HandleCAT(const ConditionalAccessTable*) = 0;
     virtual void HandlePMT(uint program_num, const ProgramMapTable*) = 0;
+    virtual void HandleEncryptionStatus(uint pid, bool encrypted) = 0;
 };
 
 class MPEGSingleProgramStreamListener
Index: libs/libmythtv/mpeg/mpegstreamdata.h
===================================================================
--- libs/libmythtv/mpeg/mpegstreamdata.h	(revision 12418)
+++ libs/libmythtv/mpeg/mpegstreamdata.h	(working copy)
@@ -74,21 +74,28 @@
     virtual void AddNotListeningPID(uint pid){_pids_notlistening[pid] = true;}
     virtual void AddWritingPID(uint pid)    { _pids_writing[pid] = true;   }
     virtual void AddAudioPID(uint pid)      { _pids_audio[pid] = true;     }
+    virtual void AddEncryptionTestPID(uint pid) { _pids_encryption[pid] = true;}
 
     virtual void RemoveListeningPID(uint pid) { _pids_listening.erase(pid);  }
     virtual void RemoveNotListeningPID(uint pid)
         { _pids_notlistening.erase(pid); }
     virtual void RemoveWritingPID(uint pid) { _pids_writing.erase(pid);    }
     virtual void RemoveAudioPID(uint pid)   { _pids_audio.erase(pid);      }
+    virtual void RemoveEncryptionTestPID(uint pid) { _pids_encryption.erase(pid);}
 
     virtual bool IsListeningPID(uint pid) const;
     virtual bool IsNotListeningPID(uint pid) const;
     virtual bool IsWritingPID(uint pid) const;
     virtual bool IsAudioPID(uint pid) const;
+    virtual bool IsEncryptionTestPID(uint pid) const;
 
     virtual QMap<uint, bool> ListeningPIDs(void) const
         { return _pids_listening; }
 
+    virtual QMap<uint, bool> EncryptionTestPID(void) const
+        { return _pids_encryption; }
+
+
     // Table versions
     void SetVersionPAT(uint tsid, int version, uint last_section)
     {
@@ -237,6 +244,7 @@
     QMap<uint, bool>          _pids_notlistening;
     QMap<uint, bool>          _pids_writing;
     QMap<uint, bool>          _pids_audio;
+    QMap<uint, bool>          _pids_encryption;
 
     // Signals
     mutable QMutex            _listener_lock;
Index: libs/libmythtv/tv_play.cpp
===================================================================
--- libs/libmythtv/tv_play.cpp	(revision 12418)
+++ libs/libmythtv/tv_play.cpp	(working copy)
@@ -4686,7 +4686,7 @@
     float snr  = 0.0f;
     uint  ber  = 0xffffffff;
     int   pos  = -1;
-    QString pat(""), pmt(""), mgt(""), vct(""), nit(""), sdt("");
+    QString pat(""), pmt(""), mgt(""), vct(""), nit(""), sdt(""), crypt("");
     QString err = QString::null, msg = QString::null;
     for (it = slist.begin(); it != slist.end(); ++it)
     {
@@ -4736,6 +4736,10 @@
             sdt = it->IsGood() ? "s" : "_";
         else if ("matching_sdt" == it->GetShortName())
             sdt = it->IsGood() ? "S" : sdt;
+        else if ("seen_crypt" == it->GetShortName())
+            crypt = it->IsGood() ? "c" : "_";
+        else if ("matching_crypt" == it->GetShortName())
+            crypt = it->IsGood() ? "C" : crypt;
     }
     if (sig)
         infoMap["signal"] = QString::number(sig); // use normalized value
@@ -4753,9 +4757,9 @@
     if ((pos >= 0) && (pos < 100))
         sigDesc += " | " + tr("Rotor %1\%").arg(pos,2);
 
-    sigDesc = sigDesc + QString(" | (%1%2%3%4%5%6%7) %8")
+    sigDesc = sigDesc + QString(" | (%1%2%3%4%5%6%7%8) %9")
         .arg(slock).arg(pat).arg(pmt).arg(mgt).arg(vct)
-        .arg(nit).arg(sdt).arg(sigMsg);
+        .arg(nit).arg(sdt).arg(crypt).arg(sigMsg);
 
     if (!err.isEmpty())
         sigDesc = err;
Index: libs/libmythtv/siscan.h
===================================================================
--- libs/libmythtv/siscan.h	(revision 12418)
+++ libs/libmythtv/siscan.h	(working copy)
@@ -85,6 +85,7 @@
     void HandlePAT(const ProgramAssociationTable*);
     void HandleCAT(const ConditionalAccessTable*) { }
     void HandlePMT(uint, const ProgramMapTable*) { }
+    void HandleEncryptionStatus(uint pid, bool encrypted) { }
 
     // ATSC Main
     void HandleSTT(const SystemTimeTable*) {}
Index: libs/libmythtv/dtvsignalmonitor.h
===================================================================
--- libs/libmythtv/dtvsignalmonitor.h	(revision 12418)
+++ libs/libmythtv/dtvsignalmonitor.h	(working copy)
@@ -86,6 +86,7 @@
     void HandlePAT(const ProgramAssociationTable*);
     void HandleCAT(const ConditionalAccessTable*) {}
     void HandlePMT(uint, const ProgramMapTable*);
+    void HandleEncryptionStatus(uint pid, bool encrypted);
 
     // ATSC Main
     void HandleSTT(const SystemTimeTable*) {}
@@ -118,12 +119,14 @@
     SignalMonitorValue seenVCT;
     SignalMonitorValue seenNIT;
     SignalMonitorValue seenSDT;
+    SignalMonitorValue seenCrypt;
     SignalMonitorValue matchingPAT;
     SignalMonitorValue matchingPMT;
     SignalMonitorValue matchingMGT;
     SignalMonitorValue matchingVCT;
     SignalMonitorValue matchingNIT;
     SignalMonitorValue matchingSDT;
+    SignalMonitorValue matchingCrypt;
 
     // ATSC tuning info
     int                majorChannel;
Index: libs/libmythtv/dtvsignalmonitor.cpp
===================================================================
--- libs/libmythtv/dtvsignalmonitor.cpp	(revision 12418)
+++ libs/libmythtv/dtvsignalmonitor.cpp	(working copy)
@@ -1,6 +1,7 @@
 #include <unistd.h>
 
 #include "dtvchannel.h"
+#include "dvbchannel.h"
 #include "dtvsignalmonitor.h"
 #include "scanstreamdata.h"
 #include "mpegtables.h"
@@ -30,12 +31,15 @@
       seenVCT(tr("Seen")+" VCT", "seen_vct", 1, true, 0, 1, 0),
       seenNIT(tr("Seen")+" NIT", "seen_nit", 1, true, 0, 1, 0),
       seenSDT(tr("Seen")+" SDT", "seen_sdt", 1, true, 0, 1, 0),
+      seenCrypt(tr("Seen")+" Crypt", "seen_crypt", 1, true, 0, 1, 0),
       matchingPAT(tr("Matching")+" PAT", "matching_pat", 1, true, 0, 1, 0),
       matchingPMT(tr("Matching")+" PMT", "matching_pmt", 1, true, 0, 1, 0),
       matchingMGT(tr("Matching")+" MGT", "matching_mgt", 1, true, 0, 1, 0),
       matchingVCT(tr("Matching")+" VCT", "matching_vct", 1, true, 0, 1, 0),
       matchingNIT(tr("Matching")+" NIT", "matching_nit", 1, true, 0, 1, 0),
       matchingSDT(tr("Matching")+" SDT", "matching_sdt", 1, true, 0, 1, 0),
+      matchingCrypt(tr("Matching")+" Crypt", "matching_crypt",
+                    1, true, 0, 1, 0),
       majorChannel(-1), minorChannel(-1),
       networkID(0), transportID(0),
       detectedNetworkID(0), detectedTransportID(0),
@@ -90,6 +94,11 @@
         }
 #endif
     }
+    if (flags & kDTVSigMon_WaitForCrypt)
+    {
+        list<<seenCrypt.GetName()<<seenCrypt.GetStatus();
+        list<<matchingCrypt.GetName()<<matchingCrypt.GetStatus();
+    }
     // atsc tables
     if (flags & kDTVSigMon_WaitForMGT)
     {
@@ -140,12 +149,14 @@
     seenVCT.SetValue(    (flags & kDTVSigMon_VCTSeen)  ? 1 : 0);
     seenNIT.SetValue(    (flags & kDTVSigMon_NITSeen)  ? 1 : 0);
     seenSDT.SetValue(    (flags & kDTVSigMon_SDTSeen)  ? 1 : 0);
+    seenCrypt.SetValue(  (flags & kDTVSigMon_CryptSeen)? 1 : 0);
     matchingPAT.SetValue((flags & kDTVSigMon_PATMatch) ? 1 : 0);
     matchingPMT.SetValue((flags & kDTVSigMon_PMTMatch) ? 1 : 0);
     matchingMGT.SetValue((flags & kDTVSigMon_MGTMatch) ? 1 : 0);
     matchingVCT.SetValue((flags & kDTVSigMon_VCTMatch) ? 1 : 0);
     matchingNIT.SetValue((flags & kDTVSigMon_NITMatch) ? 1 : 0);
     matchingSDT.SetValue((flags & kDTVSigMon_SDTMatch) ? 1 : 0);
+    matchingCrypt.SetValue((flags & kDTVSigMon_CryptMatch) ? 1 : 0);
 }
 
 void DTVSignalMonitor::UpdateListeningForEIT(void)
@@ -179,7 +190,8 @@
     {
         RemoveFlags(kDTVSigMon_PATSeen | kDTVSigMon_PATMatch |
                     kDTVSigMon_PMTSeen | kDTVSigMon_PMTMatch |
-                    kDTVSigMon_VCTSeen | kDTVSigMon_VCTMatch);
+                    kDTVSigMon_VCTSeen | kDTVSigMon_VCTMatch |
+                    kDTVSigMon_CryptSeen | kDTVSigMon_CryptMatch);
         majorChannel = major;
         minorChannel = minor;
         GetATSCStreamData()->SetDesiredChannel(major, minor);
@@ -192,7 +204,8 @@
     DBG_SM(QString("SetProgramNumber(%1)").arg(progNum), "");
     if (programNumber != progNum)
     {
-        RemoveFlags(kDTVSigMon_PMTSeen | kDTVSigMon_PMTMatch);
+        RemoveFlags(kDTVSigMon_PMTSeen   | kDTVSigMon_PMTMatch |
+                    kDTVSigMon_CryptSeen | kDTVSigMon_CryptMatch);
         programNumber = progNum;
         if (GetStreamData())
             GetStreamData()->SetDesiredProgram(programNumber);
@@ -212,7 +225,8 @@
     }
 
     RemoveFlags(kDTVSigMon_PMTSeen | kDTVSigMon_PMTMatch |
-                kDTVSigMon_SDTSeen | kDTVSigMon_SDTMatch);
+                kDTVSigMon_SDTSeen | kDTVSigMon_SDTMatch |
+                kDTVSigMon_CryptSeen | kDTVSigMon_CryptMatch);
 
     transportID   = tsid;
     networkID     = netid;
@@ -296,6 +310,7 @@
 
 void DTVSignalMonitor::HandlePMT(uint, const ProgramMapTable *pmt)
 {
+    bool test_decryption = false;
     AddFlags(kDTVSigMon_PMTSeen);
 
     if (programNumber < 0)
@@ -309,20 +324,59 @@
         return; // Not the PMT we are looking for...
     }
 
-    if (ignoreEncrypted && pmt->IsEncrypted())
+    if (pmt->IsEncrypted())
     {
-        VERBOSE(VB_IMPORTANT, LOC + "Ignoring encrypted program");
-        return;
+        if (ignoreEncrypted)
+        {
+            VERBOSE(VB_IMPORTANT, LOC + "Ignoring encrypted program");
+            return;
+        }
+        else
+        {
+            DVBChannel *dvbchan = dynamic_cast<DVBChannel*>(GetDTVChannel());
+            if (dvbchan)
+                dvbchan->SetPMT(pmt);
+
+            AddFlags(kDTVSigMon_WaitForCrypt);
+            test_decryption = true;
+        }
     }
 
     // if PMT contains audio and/or video stream set as matching.
     uint hasAudio = 0;
     uint hasVideo = 0;
+    bool needVideo = GetStreamData()->GetVideoStreamsRequired();
 
     for (uint i = 0; i < pmt->StreamCount(); i++)
     {
-        hasVideo += pmt->IsVideo(i, GetDTVChannel()->GetSIStandard());
-        hasAudio += pmt->IsAudio(i, GetDTVChannel()->GetSIStandard());
+        if (pmt->IsVideo(i, GetDTVChannel()->GetSIStandard()))
+        {
+            hasVideo++;
+            if (needVideo && test_decryption)
+            {
+                test_decryption = false;
+                uint pid = pmt->StreamPID(i);
+                VERBOSE(VB_RECORD, LOC +
+                        QString("Trying to decrypt the video stream "
+                                "on PID 0x%1.").arg(pid,0,16));
+                GetStreamData()->AddEncryptionTestPID(pid);
+                GetStreamData()->AddListeningPID(pid);
+            }
+        }
+        if (pmt->IsAudio(i, GetDTVChannel()->GetSIStandard()))
+        {
+            hasAudio++;
+            if (!needVideo && test_decryption)
+            {
+                test_decryption = false;
+                uint pid = pmt->StreamPID(i);
+                VERBOSE(VB_RECORD, LOC +
+                        QString("Trying to decrypt the audio stream "
+                                "on PID 0x%1.").arg(pid,0,16));
+                GetStreamData()->AddEncryptionTestPID(pid);
+                GetStreamData()->AddListeningPID(pid);
+            }
+        }
     }
 
     if ((hasVideo >= GetStreamData()->GetVideoStreamsRequired()) &&
@@ -432,6 +486,21 @@
     }
 }
 
+void DTVSignalMonitor::HandleEncryptionStatus(uint pid, bool encrypted)
+{
+    AddFlags(kDTVSigMon_CryptSeen);
+    if (!encrypted)
+    {
+        VERBOSE(VB_RECORD, LOC +
+                QString("Stream on PID 0x%1 is unencrypted").arg(pid,0,16));
+
+        GetStreamData()->RemoveEncryptionTestPID(pid);
+        GetStreamData()->RemoveListeningPID(pid);
+
+        AddFlags(kDTVSigMon_CryptMatch);
+    }
+}
+
 ATSCStreamData *DTVSignalMonitor::GetATSCStreamData()
 {
     return dynamic_cast<ATSCStreamData*>(stream_data);
@@ -479,6 +548,8 @@
             return false;
     if ((flags & kDTVSigMon_WaitForSDT) && !matchingSDT.IsGood())
             return false;
+    if ((flags & kDTVSigMon_WaitForCrypt) && !matchingCrypt.IsGood())
+            return false;
 
     return true;
 }
