MythTV  master
firewiresignalmonitor.cpp
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 // Copyright (c) 2006, Daniel Thor Kristjansson
3 
4 #include <chrono> // for milliseconds
5 #include <fcntl.h>
6 #include <sys/select.h>
7 #include <thread> // for sleep_for
8 
11 
12 #include "firewirechannel.h"
13 #include "firewiresignalmonitor.h"
14 #include "mpeg/atscstreamdata.h"
15 #include "mpeg/atsctables.h"
16 #include "mpeg/mpegtables.h"
17 
18 #define LOC QString("FireSigMon[%1](%2): ") \
19  .arg(m_inputid).arg(m_channel->GetDevice())
20 
22 {
23  RunProlog();
25  RunEpilog();
26 }
27 
28 QHash<void*,uint> FirewireSignalMonitor::s_patKeys;
30 
46  FirewireChannel *_channel,
47  bool _release_stream,
48  uint64_t _flags)
49  : DTVSignalMonitor(db_cardnum, _channel, _release_stream, _flags)
50 {
51  LOG(VB_CHANNEL, LOG_INFO, LOC + "ctor");
52 
54 
56 
59 }
60 
65 {
66  LOG(VB_CHANNEL, LOG_INFO, LOC + "dtor");
68 }
69 
74 {
75  LOG(VB_CHANNEL, LOG_INFO, LOC + "Stop() -- begin");
78  {
79  m_dtvMonitorRunning = false;
81  delete m_tableMonitorThread;
82  m_tableMonitorThread = nullptr;
83  }
84  LOG(VB_CHANNEL, LOG_INFO, LOC + "Stop() -- end");
85 }
86 
88 {
90 
91  auto *fwchan = dynamic_cast<FirewireChannel*>(m_channel);
92  if (!fwchan)
93  return;
94 
95  bool crc_bogus = !fwchan->GetFirewireDevice()->IsSTBBufferCleared();
96  if (crc_bogus && m_stbNeedsToWaitForPat &&
98  {
99  LOG(VB_CHANNEL, LOG_INFO, LOC + "HandlePAT() ignoring PAT");
100  uint tsid = pat->TransportStreamID();
101  GetStreamData()->SetVersionPAT(tsid, -1,0);
102  return;
103  }
104 
105  if (crc_bogus && m_stbNeedsToWaitForPat)
106  {
107  LOG(VB_GENERAL, LOG_WARNING, LOC + "Wait for valid PAT timed out");
108  m_stbNeedsToWaitForPat = false;
109  }
110 
112 }
113 
115 {
116  LOG(VB_CHANNEL, LOG_INFO, LOC + "HandlePMT()");
117 
119 
121  {
122  GetStreamData()->SetVersionPMT(pnum, -1,0);
123  LOG(VB_CHANNEL, LOG_INFO, LOC + "HandlePMT() ignoring PMT");
124  return;
125  }
126 
127  DTVSignalMonitor::HandlePMT(pnum, pmt);
128 }
129 
131 {
132  m_stbNeedsToWaitForPat = true;
134  m_dtvMonitorRunning = true;
135 
136  LOG(VB_CHANNEL, LOG_INFO, LOC + "RunTableMonitor(): -- begin");
137 
138  auto *lchan = dynamic_cast<FirewireChannel*>(m_channel);
139  if (!lchan)
140  {
141  // clang-tidy assumes that if the result of dynamic_cast is
142  // nullptr that the thing being casted must also be a nullptr.
143  // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage)
144  LOG(VB_CHANNEL, LOG_INFO, LOC + "RunTableMonitor(): -- err");
145  while (m_dtvMonitorRunning)
146  std::this_thread::sleep_for(10ms);
147 
148  LOG(VB_CHANNEL, LOG_INFO, LOC + "RunTableMonitor(): -- err end");
149  return;
150  }
151 
152  FirewireDevice *dev = lchan->GetFirewireDevice();
153 
154  dev->OpenPort();
155  dev->AddListener(this);
156 
158  std::this_thread::sleep_for(10ms);
159 
160  LOG(VB_CHANNEL, LOG_INFO, LOC + "RunTableMonitor(): -- shutdown ");
161 
162  dev->RemoveListener(this);
163  dev->ClosePort();
164 
165  while (m_dtvMonitorRunning)
166  std::this_thread::sleep_for(10ms);
167 
168  LOG(VB_CHANNEL, LOG_INFO, LOC + "RunTableMonitor(): -- end");
169 }
170 
171 void FirewireSignalMonitor::AddData(const unsigned char *data, uint len)
172 {
173  if (!m_dtvMonitorRunning)
174  return;
175 
176  if (GetStreamData())
177  GetStreamData()->ProcessData((unsigned char *)data, len);
178 }
179 
191 {
192  if (!m_running || m_exit)
193  return;
194 
196  {
197  EmitStatus();
198  if (IsAllGood())
200  // TODO dtv signals...
201 
202  m_updateDone = true;
203  return;
204  }
205 
208  {
209  return;
210  }
211  m_stbNeedsToWaitForPower = false;
212 
213  auto *fwchan = dynamic_cast<FirewireChannel*>(m_channel);
214  if (!fwchan)
215  return;
216 
218  {
219  bool retried = false;
220  while (true)
221  {
222  FirewireDevice::PowerState power = fwchan->GetPowerState();
223  if (FirewireDevice::kAVCPowerOn == power)
224  {
226  }
227  else if (FirewireDevice::kAVCPowerOff == power)
228  {
230  fwchan->SetPowerState(true);
233  }
234  else
235  {
236  bool qfailed = (FirewireDevice::kAVCPowerQueryFailed == power);
237  if (qfailed && !retried)
238  {
239  retried = true;
240  continue;
241  }
242 
243  LOG(VB_RECORD, LOG_WARNING,
244  "Can't determine if STB is power on, assuming it is...");
246  }
247  break;
248  }
249  }
250 
251  bool isLocked = !HasFlags(kFWSigMon_WaitForPower) ||
253 
254  if (isLocked && m_stbNeedsRetune)
255  {
256  fwchan->Retune();
257  isLocked = m_stbNeedsRetune = false;
258  }
259 
261 
262  {
263  QMutexLocker locker(&m_statusLock);
264  if (!m_scriptStatus.IsGood())
265  return;
266  }
267 
268  // Set SignalMonitorValues from info from card.
269  {
270  QMutexLocker locker(&m_statusLock);
271  m_signalStrength.SetValue(isLocked ? 100 : 0);
272  m_signalLock.SetValue(isLocked ? 1 : 0);
273  }
274 
275  EmitStatus();
276  if (IsAllGood())
278 
279  // Start table monitoring if we are waiting on any table
280  // and we have a lock.
281  if (isLocked && GetStreamData() &&
285  {
287 
288  LOG(VB_CHANNEL, LOG_INFO, LOC + "UpdateValues() -- "
289  "Waiting for table monitor to start");
290 
291  while (!m_dtvMonitorRunning)
292  std::this_thread::sleep_for(5ms);
293 
294  LOG(VB_CHANNEL, LOG_INFO, LOC + "UpdateValues() -- "
295  "Table monitor started");
296  }
297 
298  m_updateDone = true;
299 }
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:50
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:186
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:300
FirewireSignalMonitor::RunTableMonitor
void RunTableMonitor(void)
Definition: firewiresignalmonitor.cpp:130
SignalMonitor::m_channel
ChannelBase * m_channel
Definition: signalmonitor.h:201
firewirechannel.h
ProgramMapTable
A PMT table maps a program described in the ProgramAssociationTable to various PID's which describe t...
Definition: mpegtables.h:694
FirewireSignalMonitor::~FirewireSignalMonitor
~FirewireSignalMonitor() override
Stops signal monitoring and table monitoring threads.
Definition: firewiresignalmonitor.cpp:64
SignalMonitor::kDTVSigMon_WaitForMGT
static const uint64_t kDTVSigMon_WaitForMGT
Definition: signalmonitor.h:181
FirewireSignalMonitor::HandlePAT
void HandlePAT(const ProgramAssociationTable *pat) override
Definition: firewiresignalmonitor.cpp:87
SignalMonitor::m_exit
volatile bool m_exit
Definition: signalmonitor.h:225
mythdbcon.h
FirewireSignalMonitor::m_stbNeedsRetune
bool m_stbNeedsRetune
Definition: firewiresignalmonitor.h:66
FirewireDevice::AddListener
virtual void AddListener(TSDataListener *listener)
Definition: firewiredevice.cpp:37
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:39
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:224
FirewireSignalMonitor::FirewireSignalMonitor
FirewireSignalMonitor(void)
SignalMonitor::HasAnyFlag
bool HasAnyFlag(uint64_t _flags) const
Definition: signalmonitor.cpp:280
SignalMonitor::kSigMon_WaitForSig
static const uint64_t kSigMon_WaitForSig
Definition: signalmonitor.h:185
SignalMonitor::m_statusLock
QRecursiveMutex m_statusLock
Definition: signalmonitor.h:227
SignalMonitor::m_scriptStatus
SignalMonitorValue m_scriptStatus
Definition: signalmonitor.h:218
FirewireDevice::PowerState
PowerState
Definition: firewiredevice.h:28
DTVSignalMonitor::HandlePMT
void HandlePMT(uint program_num, const ProgramMapTable *pmt) override
Definition: dtvsignalmonitor.cpp:359
FirewireSignalMonitor::Stop
void Stop(void) override
Stop signal monitoring and table monitoring threads.
Definition: firewiresignalmonitor.cpp:73
SignalMonitor::m_signalStrength
SignalMonitorValue m_signalStrength
Definition: signalmonitor.h:217
mythlogging.h
ProgramAssociationTable::TransportStreamID
uint TransportStreamID(void) const
Definition: mpegtables.h:636
SignalMonitor::kFWSigMon_PowerSeen
static const uint64_t kFWSigMon_PowerSeen
We've seen the FireWire STB power state.
Definition: signalmonitor.h:154
SignalMonitor::m_signalLock
SignalMonitorValue m_signalLock
Definition: signalmonitor.h:216
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:465
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:162
MPEGStreamData::ProcessData
virtual int ProcessData(const unsigned char *buffer, int len)
Definition: mpegstreamdata.cpp:951
SignalMonitor::kDTVSigMon_WaitForPMT
static const uint64_t kDTVSigMon_WaitForPMT
Definition: signalmonitor.h:180
SignalMonitor::kDTVSigMon_WaitForPAT
static const uint64_t kDTVSigMon_WaitForPAT
Definition: signalmonitor.h:179
SignalMonitor::m_updateDone
bool m_updateDone
Definition: signalmonitor.h:208
SignalMonitor::kDTVSigMon_WaitForNIT
static const uint64_t kDTVSigMon_WaitForNIT
Definition: signalmonitor.h:183
SignalMonitor::EmitStatus
virtual void EmitStatus(void)
Definition: signalmonitor.cpp:472
SignalMonitor::kDTVSigMon_WaitForSDT
static const uint64_t kDTVSigMon_WaitForSDT
Definition: signalmonitor.h:184
SignalMonitor::UpdateValues
virtual void UpdateValues(void)
This should be overridden to actually do signal monitoring.
Definition: signalmonitor.cpp:456
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:175
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:133
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:136
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:21
uint
unsigned int uint
Definition: compat.h:81
ProgramAssociationTable
The Program Association Table lists all the programs in a stream, and is always found on PID 0.
Definition: mpegtables.h:617
FirewireSignalMonitor::AddData
void AddData(const unsigned char *data, uint len) override
Callback function to add MPEG2 TS data.
Definition: firewiresignalmonitor.cpp:171
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:275
FirewireSignalMonitor::HandlePMT
void HandlePMT(uint pnum, const ProgramMapTable *pmt) override
Definition: firewiresignalmonitor.cpp:114
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:159
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:166
FirewireDevice::IsSTBBufferCleared
bool IsSTBBufferCleared(void) const
Definition: firewiredevice.h:209
SignalMonitor::Stop
virtual void Stop()
Stop signal monitoring thread.
Definition: signalmonitor.cpp:304
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:585
FirewireSignalMonitor::kBufferTimeout
static constexpr std::chrono::milliseconds kBufferTimeout
Definition: firewiresignalmonitor.h:61
LOC
#define LOC
Definition: firewiresignalmonitor.cpp:18
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:190
SignalMonitor::kDTVSigMon_WaitForVCT
static const uint64_t kDTVSigMon_WaitForVCT
Definition: signalmonitor.h:182
FirewireDevice
Definition: firewiredevice.h:23
FirewireDevice::OpenPort
virtual bool OpenPort(void)=0