MythTV  master
firewiresignalmonitor.cpp
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 // Copyright (c) 2006, Daniel Thor Kristjansson
3 
4 #include <fcntl.h>
5 #include <sys/select.h>
6 #include <chrono> // for milliseconds
7 #include <thread> // for sleep_for
8 
9 #include "mythdbcon.h"
10 #include "atscstreamdata.h"
11 #include "mpegtables.h"
12 #include "atsctables.h"
13 #include "firewirechannel.h"
14 #include "firewiresignalmonitor.h"
15 #include "mythlogging.h"
16 
17 #define LOC QString("FireSigMon[%1](%2): ") \
18  .arg(m_inputid).arg(m_channel->GetDevice())
19 
21 {
22  RunProlog();
24  RunEpilog();
25 }
26 
27 QHash<void*,uint> FirewireSignalMonitor::s_patKeys;
29 
45  FirewireChannel *_channel,
46  bool _release_stream,
47  uint64_t _flags)
48  : DTVSignalMonitor(db_cardnum, _channel, _release_stream, _flags)
49 {
50  LOG(VB_CHANNEL, LOG_INFO, LOC + "ctor");
51 
53 
55 
58 }
59 
64 {
65  LOG(VB_CHANNEL, LOG_INFO, LOC + "dtor");
67 }
68 
73 {
74  LOG(VB_CHANNEL, LOG_INFO, LOC + "Stop() -- begin");
77  {
78  m_dtvMonitorRunning = false;
80  delete m_tableMonitorThread;
81  m_tableMonitorThread = nullptr;
82  }
83  LOG(VB_CHANNEL, LOG_INFO, LOC + "Stop() -- end");
84 }
85 
87 {
89 
90  auto *fwchan = dynamic_cast<FirewireChannel*>(m_channel);
91  if (!fwchan)
92  return;
93 
94  bool crc_bogus = !fwchan->GetFirewireDevice()->IsSTBBufferCleared();
95  if (crc_bogus && m_stbNeedsToWaitForPat &&
97  {
98  LOG(VB_CHANNEL, LOG_INFO, LOC + "HandlePAT() ignoring PAT");
99  uint tsid = pat->TransportStreamID();
100  GetStreamData()->SetVersionPAT(tsid, -1,0);
101  return;
102  }
103 
104  if (crc_bogus && m_stbNeedsToWaitForPat)
105  {
106  LOG(VB_GENERAL, LOG_WARNING, LOC + "Wait for valid PAT timed out");
107  m_stbNeedsToWaitForPat = false;
108  }
109 
111 }
112 
114 {
115  LOG(VB_CHANNEL, LOG_INFO, LOC + "HandlePMT()");
116 
118 
120  {
121  GetStreamData()->SetVersionPMT(pnum, -1,0);
122  LOG(VB_CHANNEL, LOG_INFO, LOC + "HandlePMT() ignoring PMT");
123  return;
124  }
125 
126  DTVSignalMonitor::HandlePMT(pnum, pmt);
127 }
128 
130 {
131  m_stbNeedsToWaitForPat = true;
133  m_dtvMonitorRunning = true;
134 
135  LOG(VB_CHANNEL, LOG_INFO, LOC + "RunTableMonitor(): -- begin");
136 
137  auto *lchan = dynamic_cast<FirewireChannel*>(m_channel);
138  if (!lchan)
139  {
140  // clang-tidy assumes that if the result of dynamic_cast is
141  // nullptr that the thing being casted must also be a nullptr.
142  // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage)
143  LOG(VB_CHANNEL, LOG_INFO, LOC + "RunTableMonitor(): -- err");
144  while (m_dtvMonitorRunning)
145  std::this_thread::sleep_for(10ms);
146 
147  LOG(VB_CHANNEL, LOG_INFO, LOC + "RunTableMonitor(): -- err end");
148  return;
149  }
150 
151  FirewireDevice *dev = lchan->GetFirewireDevice();
152 
153  dev->OpenPort();
154  dev->AddListener(this);
155 
157  std::this_thread::sleep_for(10ms);
158 
159  LOG(VB_CHANNEL, LOG_INFO, LOC + "RunTableMonitor(): -- shutdown ");
160 
161  dev->RemoveListener(this);
162  dev->ClosePort();
163 
164  while (m_dtvMonitorRunning)
165  std::this_thread::sleep_for(10ms);
166 
167  LOG(VB_CHANNEL, LOG_INFO, LOC + "RunTableMonitor(): -- end");
168 }
169 
170 void FirewireSignalMonitor::AddData(const unsigned char *data, uint len)
171 {
172  if (!m_dtvMonitorRunning)
173  return;
174 
175  if (GetStreamData())
176  GetStreamData()->ProcessData((unsigned char *)data, len);
177 }
178 
190 {
191  if (!m_running || m_exit)
192  return;
193 
195  {
196  EmitStatus();
197  if (IsAllGood())
199  // TODO dtv signals...
200 
201  m_updateDone = true;
202  return;
203  }
204 
207  {
208  return;
209  }
210  m_stbNeedsToWaitForPower = false;
211 
212  auto *fwchan = dynamic_cast<FirewireChannel*>(m_channel);
213  if (!fwchan)
214  return;
215 
217  {
218  bool retried = false;
219  while (true)
220  {
221  FirewireDevice::PowerState power = fwchan->GetPowerState();
222  if (FirewireDevice::kAVCPowerOn == power)
223  {
225  }
226  else if (FirewireDevice::kAVCPowerOff == power)
227  {
229  fwchan->SetPowerState(true);
232  }
233  else
234  {
235  bool qfailed = (FirewireDevice::kAVCPowerQueryFailed == power);
236  if (qfailed && !retried)
237  {
238  retried = true;
239  continue;
240  }
241 
242  LOG(VB_RECORD, LOG_WARNING,
243  "Can't determine if STB is power on, assuming it is...");
245  }
246  break;
247  }
248  }
249 
250  bool isLocked = !HasFlags(kFWSigMon_WaitForPower) ||
252 
253  if (isLocked && m_stbNeedsRetune)
254  {
255  fwchan->Retune();
256  isLocked = m_stbNeedsRetune = false;
257  }
258 
260 
261  {
262  QMutexLocker locker(&m_statusLock);
263  if (!m_scriptStatus.IsGood())
264  return;
265  }
266 
267  // Set SignalMonitorValues from info from card.
268  {
269  QMutexLocker locker(&m_statusLock);
270  m_signalStrength.SetValue(isLocked ? 100 : 0);
271  m_signalLock.SetValue(isLocked ? 1 : 0);
272  }
273 
274  EmitStatus();
275  if (IsAllGood())
277 
278  // Start table monitoring if we are waiting on any table
279  // and we have a lock.
280  if (isLocked && GetStreamData() &&
284  {
286 
287  LOG(VB_CHANNEL, LOG_INFO, LOC + "UpdateValues() -- "
288  "Waiting for table monitor to start");
289 
290  while (!m_dtvMonitorRunning)
291  std::this_thread::sleep_for(5ms);
292 
293  LOG(VB_CHANNEL, LOG_INFO, LOC + "UpdateValues() -- "
294  "Table monitor started");
295  }
296 
297  m_updateDone = true;
298 }
MythTimer::elapsed
std::chrono::milliseconds elapsed(void)
Returns milliseconds elapsed since last start() or restart()
Definition: mythtimer.cpp:91
DTVSignalMonitor::AddFlags
void AddFlags(uint64_t _flags) override
Definition: dtvsignalmonitor.cpp:140
FirewireDevice::RemoveListener
virtual void RemoveListener(TSDataListener *listener)
Definition: firewiredevice.cpp:49
FirewireSignalMonitor::s_patKeysLock
static QMutex s_patKeysLock
Definition: firewiresignalmonitor.h:75
SignalMonitorValue::SetValue
void SetValue(int _value)
Definition: signalmonitorvalue.h:74
SignalMonitor::kFWSigMon_WaitForPower
static const uint64_t kFWSigMon_WaitForPower
Definition: signalmonitor.h:190
SignalMonitorValue::SetThreshold
void SetThreshold(int _threshold)
Definition: signalmonitorvalue.h:84
FirewireDevice::kAVCPowerOn
@ kAVCPowerOn
Definition: firewiredevice.h:30
FirewireSignalMonitor::s_patKeys
static QHash< void *, uint > s_patKeys
Definition: firewiresignalmonitor.h:74
MThread::wait
bool wait(std::chrono::milliseconds time=std::chrono::milliseconds::max())
Wait for the MThread to exit, with a maximum timeout.
Definition: mthread.cpp:303
FirewireSignalMonitor::RunTableMonitor
void RunTableMonitor(void)
Definition: firewiresignalmonitor.cpp:129
SignalMonitor::m_channel
ChannelBase * m_channel
Definition: signalmonitor.h:205
firewirechannel.h
ProgramMapTable
A PMT table maps a program described in the ProgramAssociationTable to various PID's which describe t...
Definition: mpegtables.h:692
FirewireSignalMonitor::~FirewireSignalMonitor
~FirewireSignalMonitor() override
Stops signal monitoring and table monitoring threads.
Definition: firewiresignalmonitor.cpp:63
SignalMonitor::kDTVSigMon_WaitForMGT
static const uint64_t kDTVSigMon_WaitForMGT
Definition: signalmonitor.h:185
FirewireSignalMonitor::HandlePAT
void HandlePAT(const ProgramAssociationTable *pat) override
Definition: firewiresignalmonitor.cpp:86
SignalMonitor::m_exit
volatile bool m_exit
Definition: signalmonitor.h:229
mythdbcon.h
FirewireSignalMonitor::m_stbNeedsRetune
bool m_stbNeedsRetune
Definition: firewiresignalmonitor.h:66
FirewireDevice::AddListener
virtual void AddListener(TSDataListener *listener)
Definition: firewiredevice.cpp:36
DTVSignalMonitor::GetStreamData
MPEGStreamData * GetStreamData()
Returns the MPEG stream data if it exists.
Definition: dtvsignalmonitor.h:59
atscstreamdata.h
FirewireSignalMonitor::kPowerTimeout
static constexpr std::chrono::milliseconds kPowerTimeout
Definition: firewiresignalmonitor.h:60
MythTimer::start
void start(void)
starts measuring elapsed time.
Definition: mythtimer.cpp:47
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MThread::RunProlog
void RunProlog(void)
Sets up a thread, call this if you reimplement run().
Definition: mthread.cpp:196
SignalMonitor::m_running
volatile bool m_running
Definition: signalmonitor.h:228
FirewireSignalMonitor::FirewireSignalMonitor
FirewireSignalMonitor(void)
SignalMonitor::HasAnyFlag
bool HasAnyFlag(uint64_t _flags) const
Definition: signalmonitor.cpp:282
SignalMonitor::kSigMon_WaitForSig
static const uint64_t kSigMon_WaitForSig
Definition: signalmonitor.h:189
SignalMonitor::m_statusLock
QRecursiveMutex m_statusLock
Definition: signalmonitor.h:234
SignalMonitor::m_scriptStatus
SignalMonitorValue m_scriptStatus
Definition: signalmonitor.h:222
FirewireDevice::PowerState
PowerState
Definition: firewiredevice.h:28
DTVSignalMonitor::HandlePMT
void HandlePMT(uint program_num, const ProgramMapTable *pmt) override
Definition: dtvsignalmonitor.cpp:342
FirewireSignalMonitor::Stop
void Stop(void) override
Stop signal monitoring and table monitoring threads.
Definition: firewiresignalmonitor.cpp:72
SignalMonitor::m_signalStrength
SignalMonitorValue m_signalStrength
Definition: signalmonitor.h:221
mythlogging.h
ProgramAssociationTable::TransportStreamID
uint TransportStreamID(void) const
Definition: mpegtables.h:634
SignalMonitor::kFWSigMon_PowerSeen
static const uint64_t kFWSigMon_PowerSeen
We've seen the FireWire STB power state.
Definition: signalmonitor.h:158
SignalMonitor::m_signalLock
SignalMonitorValue m_signalLock
Definition: signalmonitor.h:220
FirewireSignalMonitor::m_stbNeedsToWaitForPat
bool m_stbNeedsToWaitForPat
Definition: firewiresignalmonitor.h:67
FirewireSignalMonitor::m_stbNeedsToWaitForPower
bool m_stbNeedsToWaitForPower
Definition: firewiresignalmonitor.h:68
SignalMonitor::SendMessageAllGood
void SendMessageAllGood(void)
Definition: signalmonitor.cpp:467
FirewireChannel
FirewireChannel Copyright (c) 2005 by Jim Westfall and Dave Abrahams Distributed as part of MythTV un...
Definition: firewirechannel.h:14
FirewireSignalMonitor::m_tableMonitorThread
FirewireTableMonitorThread * m_tableMonitorThread
Definition: firewiresignalmonitor.h:65
MPEGStreamData::SetVersionPAT
void SetVersionPAT(uint tsid, int version, uint last_section)
Definition: mpegstreamdata.h:161
MPEGStreamData::ProcessData
virtual int ProcessData(const unsigned char *buffer, int len)
Definition: mpegstreamdata.cpp:956
SignalMonitor::kDTVSigMon_WaitForPMT
static const uint64_t kDTVSigMon_WaitForPMT
Definition: signalmonitor.h:184
SignalMonitor::kDTVSigMon_WaitForPAT
static const uint64_t kDTVSigMon_WaitForPAT
Definition: signalmonitor.h:183
SignalMonitor::m_updateDone
bool m_updateDone
Definition: signalmonitor.h:212
SignalMonitor::kDTVSigMon_WaitForNIT
static const uint64_t kDTVSigMon_WaitForNIT
Definition: signalmonitor.h:187
SignalMonitor::EmitStatus
virtual void EmitStatus(void)
Definition: signalmonitor.cpp:474
SignalMonitor::kDTVSigMon_WaitForSDT
static const uint64_t kDTVSigMon_WaitForSDT
Definition: signalmonitor.h:188
SignalMonitor::UpdateValues
virtual void UpdateValues(void)
This should be overridden to actually do signal monitoring.
Definition: signalmonitor.cpp:458
FirewireSignalMonitor::m_stbWaitForPatTimer
MythTimer m_stbWaitForPatTimer
Definition: firewiresignalmonitor.h:69
MThread::RunEpilog
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
Definition: mthread.cpp:209
SignalMonitor::kFWSigMon_PowerMatch
static const uint64_t kFWSigMon_PowerMatch
We've seen a FireWire STB power state matching our requirements.
Definition: signalmonitor.h:179
mpegtables.h
SignalMonitor::kDTVSigMon_PATSeen
static const uint64_t kDTVSigMon_PATSeen
We've seen a PAT, which maps MPEG program numbers to pids where we find PMTs.
Definition: signalmonitor.h:137
SignalMonitor::kDTVSigMon_PMTSeen
static const uint64_t kDTVSigMon_PMTSeen
We've seen a PMT, which maps program to audio, video and other stream PIDs.
Definition: signalmonitor.h:140
FirewireTableMonitorThread::run
void run(void) override
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
Definition: firewiresignalmonitor.cpp:20
uint
unsigned int uint
Definition: compat.h:140
ProgramAssociationTable
The Program Association Table lists all the programs in a stream, and is always found on PID 0.
Definition: mpegtables.h:615
FirewireSignalMonitor::AddData
void AddData(const unsigned char *data, uint len) override
Callback function to add MPEG2 TS data.
Definition: firewiresignalmonitor.cpp:170
FirewireChannel::GetPowerState
virtual FirewireDevice::PowerState GetPowerState(void) const
Definition: firewirechannel.cpp:108
SignalMonitorValue::IsGood
bool IsGood() const
Returns true if the value is equal to the threshold, or on the right side of the threshold (depends o...
Definition: signalmonitorvalue.h:56
SignalMonitor::HasFlags
bool HasFlags(uint64_t _flags) const
Definition: signalmonitor.cpp:277
FirewireSignalMonitor::HandlePMT
void HandlePMT(uint pnum, const ProgramMapTable *pmt) override
Definition: firewiresignalmonitor.cpp:113
FirewireDevice::kAVCPowerQueryFailed
@ kAVCPowerQueryFailed
Definition: firewiredevice.h:33
SignalMonitor::kDTVSigMon_PATMatch
static const uint64_t kDTVSigMon_PATMatch
We've seen a PAT matching our requirements.
Definition: signalmonitor.h:163
FirewireChannel::GetFirewireDevice
virtual FirewireDevice * GetFirewireDevice(void)
Definition: firewirechannel.h:51
FirewireSignalMonitor::FirewireTableMonitorThread
friend class FirewireTableMonitorThread
Definition: firewiresignalmonitor.h:35
DTVSignalMonitor
This class is intended to detect the presence of needed tables.
Definition: dtvsignalmonitor.h:14
firewiresignalmonitor.h
FirewireTableMonitorThread::m_parent
FirewireSignalMonitor * m_parent
Definition: firewiresignalmonitor.h:30
FirewireSignalMonitor::m_dtvMonitorRunning
volatile bool m_dtvMonitorRunning
Definition: firewiresignalmonitor.h:64
atsctables.h
FirewireSignalMonitor::m_stbWaitForPowerTimer
MythTimer m_stbWaitForPowerTimer
Definition: firewiresignalmonitor.h:70
MPEGStreamData::SetVersionPMT
void SetVersionPMT(uint pnum, int version, uint last_section)
Definition: mpegstreamdata.h:165
FirewireDevice::IsSTBBufferCleared
bool IsSTBBufferCleared(void) const
Definition: firewiredevice.h:209
SignalMonitor::Stop
virtual void Stop()
Stop signal monitoring thread.
Definition: signalmonitor.cpp:306
DTVSignalMonitor::HandlePAT
void HandlePAT(const ProgramAssociationTable *pat) override
Definition: dtvsignalmonitor.cpp:291
FirewireDevice::kAVCPowerOff
@ kAVCPowerOff
Definition: firewiredevice.h:31
DTVSignalMonitor::IsAllGood
bool IsAllGood(void) const override
Definition: dtvsignalmonitor.cpp:564
FirewireSignalMonitor::kBufferTimeout
static constexpr std::chrono::milliseconds kBufferTimeout
Definition: firewiresignalmonitor.h:61
LOC
#define LOC
Definition: firewiresignalmonitor.cpp:17
FirewireDevice::ClosePort
virtual bool ClosePort(void)=0
FirewireSignalMonitor::UpdateValues
void UpdateValues(void) override
Fills in frontend stats and emits status Qt signals.
Definition: firewiresignalmonitor.cpp:189
SignalMonitor::kDTVSigMon_WaitForVCT
static const uint64_t kDTVSigMon_WaitForVCT
Definition: signalmonitor.h:186
FirewireDevice
Definition: firewiredevice.h:23
FirewireDevice::OpenPort
virtual bool OpenPort(void)=0