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 const uint FirewireSignalMonitor::kPowerTimeout = 3000; /* ms */
28 const uint FirewireSignalMonitor::kBufferTimeout = 5000; /* ms */
29 
30 QMap<void*,uint> FirewireSignalMonitor::s_pat_keys;
32 
48  FirewireChannel *_channel,
49  bool _release_stream,
50  uint64_t _flags)
51  : DTVSignalMonitor(db_cardnum, _channel, _release_stream, _flags)
52 {
53  LOG(VB_CHANNEL, LOG_INFO, LOC + "ctor");
54 
56 
58 
61 }
62 
67 {
68  LOG(VB_CHANNEL, LOG_INFO, LOC + "dtor");
70 }
71 
76 {
77  LOG(VB_CHANNEL, LOG_INFO, LOC + "Stop() -- begin");
80  {
81  m_dtvMonitorRunning = false;
83  delete m_tableMonitorThread;
84  m_tableMonitorThread = nullptr;
85  }
86  LOG(VB_CHANNEL, LOG_INFO, LOC + "Stop() -- end");
87 }
88 
90 {
92 
93  auto *fwchan = dynamic_cast<FirewireChannel*>(m_channel);
94  if (!fwchan)
95  return;
96 
97  bool crc_bogus = !fwchan->GetFirewireDevice()->IsSTBBufferCleared();
98  if (crc_bogus && m_stb_needs_to_wait_for_pat &&
100  {
101  LOG(VB_CHANNEL, LOG_INFO, LOC + "HandlePAT() ignoring PAT");
102  uint tsid = pat->TransportStreamID();
103  GetStreamData()->SetVersionPAT(tsid, -1,0);
104  return;
105  }
106 
107  if (crc_bogus && m_stb_needs_to_wait_for_pat)
108  {
109  LOG(VB_GENERAL, LOG_WARNING, LOC + "Wait for valid PAT timed out");
111  }
112 
114 }
115 
117 {
118  LOG(VB_CHANNEL, LOG_INFO, LOC + "HandlePMT()");
119 
121 
123  {
124  GetStreamData()->SetVersionPMT(pnum, -1,0);
125  LOG(VB_CHANNEL, LOG_INFO, LOC + "HandlePMT() ignoring PMT");
126  return;
127  }
128 
129  DTVSignalMonitor::HandlePMT(pnum, pmt);
130 }
131 
133 {
136  m_dtvMonitorRunning = true;
137 
138  LOG(VB_CHANNEL, LOG_INFO, LOC + "RunTableMonitor(): -- begin");
139 
140  auto *lchan = dynamic_cast<FirewireChannel*>(m_channel);
141  if (!lchan)
142  {
143  // clang-tidy assumes that if the result of dynamic_cast is
144  // nullptr that the thing being casted must also be a nullptr.
145  // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage)
146  LOG(VB_CHANNEL, LOG_INFO, LOC + "RunTableMonitor(): -- err");
147  while (m_dtvMonitorRunning)
148  std::this_thread::sleep_for(std::chrono::milliseconds(10));
149 
150  LOG(VB_CHANNEL, LOG_INFO, LOC + "RunTableMonitor(): -- err end");
151  return;
152  }
153 
154  FirewireDevice *dev = lchan->GetFirewireDevice();
155 
156  dev->OpenPort();
157  dev->AddListener(this);
158 
160  std::this_thread::sleep_for(std::chrono::milliseconds(10));
161 
162  LOG(VB_CHANNEL, LOG_INFO, LOC + "RunTableMonitor(): -- shutdown ");
163 
164  dev->RemoveListener(this);
165  dev->ClosePort();
166 
167  while (m_dtvMonitorRunning)
168  std::this_thread::sleep_for(std::chrono::milliseconds(10));
169 
170  LOG(VB_CHANNEL, LOG_INFO, LOC + "RunTableMonitor(): -- end");
171 }
172 
173 void FirewireSignalMonitor::AddData(const unsigned char *data, uint len)
174 {
175  if (!m_dtvMonitorRunning)
176  return;
177 
178  if (GetStreamData())
179  GetStreamData()->ProcessData((unsigned char *)data, len);
180 }
181 
193 {
194  if (!m_running || m_exit)
195  return;
196 
198  {
199  EmitStatus();
200  if (IsAllGood())
202  // TODO dtv signals...
203 
204  m_update_done = true;
205  return;
206  }
207 
210  {
211  return;
212  }
214 
215  auto *fwchan = dynamic_cast<FirewireChannel*>(m_channel);
216  if (!fwchan)
217  return;
218 
220  {
221  bool retried = false;
222  while (true)
223  {
224  FirewireDevice::PowerState power = fwchan->GetPowerState();
225  if (FirewireDevice::kAVCPowerOn == power)
226  {
228  }
229  else if (FirewireDevice::kAVCPowerOff == power)
230  {
232  fwchan->SetPowerState(true);
235  }
236  else
237  {
238  bool qfailed = (FirewireDevice::kAVCPowerQueryFailed == power);
239  if (qfailed && !retried)
240  {
241  retried = true;
242  continue;
243  }
244 
245  LOG(VB_RECORD, LOG_WARNING,
246  "Can't determine if STB is power on, assuming it is...");
248  }
249  break;
250  }
251  }
252 
253  bool isLocked = !HasFlags(kFWSigMon_WaitForPower) ||
255 
256  if (isLocked && m_stb_needs_retune)
257  {
258  fwchan->Retune();
259  isLocked = m_stb_needs_retune = false;
260  }
261 
263 
264  {
265  QMutexLocker locker(&m_statusLock);
266  if (!m_scriptStatus.IsGood())
267  return;
268  }
269 
270  // Set SignalMonitorValues from info from card.
271  {
272  QMutexLocker locker(&m_statusLock);
273  m_signalStrength.SetValue(isLocked ? 100 : 0);
274  m_signalLock.SetValue(isLocked ? 1 : 0);
275  }
276 
277  EmitStatus();
278  if (IsAllGood())
280 
281  // Start table monitoring if we are waiting on any table
282  // and we have a lock.
283  if (isLocked && GetStreamData() &&
287  {
289 
290  LOG(VB_CHANNEL, LOG_INFO, LOC + "UpdateValues() -- "
291  "Waiting for table monitor to start");
292 
293  while (!m_dtvMonitorRunning)
294  std::this_thread::sleep_for(std::chrono::milliseconds(5));
295 
296  LOG(VB_CHANNEL, LOG_INFO, LOC + "UpdateValues() -- "
297  "Table monitor started");
298  }
299 
300  m_update_done = true;
301 }
SignalMonitor::m_update_done
bool m_update_done
Definition: signalmonitor.h:210
FirewireSignalMonitor::m_stb_needs_to_wait_for_pat
bool m_stb_needs_to_wait_for_pat
Definition: firewiresignalmonitor.h:68
DTVSignalMonitor::AddFlags
void AddFlags(uint64_t _flags) override
Definition: dtvsignalmonitor.cpp:143
FirewireSignalMonitor::m_stb_wait_for_power_timer
MythTimer m_stb_wait_for_power_timer
Definition: firewiresignalmonitor.h:71
FirewireDevice::RemoveListener
virtual void RemoveListener(TSDataListener *listener)
Definition: firewiredevice.cpp:49
SignalMonitorValue::SetValue
void SetValue(int _value)
Definition: signalmonitorvalue.h:75
SignalMonitor::kFWSigMon_WaitForPower
static const uint64_t kFWSigMon_WaitForPower
Definition: signalmonitor.h:188
SignalMonitorValue::SetThreshold
void SetThreshold(int _threshold)
Definition: signalmonitorvalue.h:85
FirewireDevice::kAVCPowerOn
@ kAVCPowerOn
Definition: firewiredevice.h:31
FirewireSignalMonitor::RunTableMonitor
void RunTableMonitor(void)
Definition: firewiresignalmonitor.cpp:132
SignalMonitor::m_channel
ChannelBase * m_channel
Definition: signalmonitor.h:203
FirewireSignalMonitor::kPowerTimeout
static const uint kPowerTimeout
Definition: firewiresignalmonitor.h:61
firewirechannel.h
ProgramMapTable
A PMT table maps a program described in the ProgramAssociationTable to various PID's which describe t...
Definition: mpegtables.h:666
FirewireSignalMonitor::~FirewireSignalMonitor
~FirewireSignalMonitor() override
Stops signal monitoring and table monitoring threads.
Definition: firewiresignalmonitor.cpp:66
SignalMonitor::kDTVSigMon_WaitForMGT
static const uint64_t kDTVSigMon_WaitForMGT
Definition: signalmonitor.h:183
FirewireSignalMonitor::HandlePAT
void HandlePAT(const ProgramAssociationTable *pat) override
Definition: firewiresignalmonitor.cpp:89
SignalMonitor::m_exit
volatile bool m_exit
Definition: signalmonitor.h:227
mythdbcon.h
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:60
atscstreamdata.h
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:202
SignalMonitor::m_running
volatile bool m_running
Definition: signalmonitor.h:226
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:187
SignalMonitor::m_scriptStatus
SignalMonitorValue m_scriptStatus
Definition: signalmonitor.h:220
FirewireDevice::PowerState
PowerState
Definition: firewiredevice.h:29
DTVSignalMonitor::HandlePMT
void HandlePMT(uint program_num, const ProgramMapTable *pmt) override
Definition: dtvsignalmonitor.cpp:351
FirewireSignalMonitor::Stop
void Stop(void) override
Stop signal monitoring and table monitoring threads.
Definition: firewiresignalmonitor.cpp:75
FirewireSignalMonitor::s_pat_keys_lock
static QMutex s_pat_keys_lock
Definition: firewiresignalmonitor.h:76
SignalMonitor::m_signalStrength
SignalMonitorValue m_signalStrength
Definition: signalmonitor.h:219
mythlogging.h
ProgramAssociationTable::TransportStreamID
uint TransportStreamID(void) const
Definition: mpegtables.h:608
SignalMonitor::kFWSigMon_PowerSeen
static const uint64_t kFWSigMon_PowerSeen
We've seen the FireWire STB power state.
Definition: signalmonitor.h:156
SignalMonitor::m_signalLock
SignalMonitorValue m_signalLock
Definition: signalmonitor.h:218
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:66
MPEGStreamData::SetVersionPAT
void SetVersionPAT(uint tsid, int version, uint last_section)
Definition: mpegstreamdata.h:158
MPEGStreamData::ProcessData
virtual int ProcessData(const unsigned char *buffer, int len)
Definition: mpegstreamdata.cpp:945
SignalMonitor::kDTVSigMon_WaitForPMT
static const uint64_t kDTVSigMon_WaitForPMT
Definition: signalmonitor.h:182
SignalMonitor::kDTVSigMon_WaitForPAT
static const uint64_t kDTVSigMon_WaitForPAT
Definition: signalmonitor.h:181
SignalMonitor::kDTVSigMon_WaitForNIT
static const uint64_t kDTVSigMon_WaitForNIT
Definition: signalmonitor.h:185
SignalMonitor::EmitStatus
virtual void EmitStatus(void)
Definition: signalmonitor.cpp:474
SignalMonitor::kDTVSigMon_WaitForSDT
static const uint64_t kDTVSigMon_WaitForSDT
Definition: signalmonitor.h:186
SignalMonitor::UpdateValues
virtual void UpdateValues(void)
This should be overridden to actually do signal monitoring.
Definition: signalmonitor.cpp:458
MThread::RunEpilog
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
Definition: mthread.cpp:215
SignalMonitor::kFWSigMon_PowerMatch
static const uint64_t kFWSigMon_PowerMatch
We've seen a FireWire STB power state matching our requirements.
Definition: signalmonitor.h:177
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:135
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:138
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:589
FirewireSignalMonitor::AddData
void AddData(const unsigned char *data, uint len) override
Callback function to add MPEG2 TS data.
Definition: firewiresignalmonitor.cpp:173
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:57
FirewireSignalMonitor::kBufferTimeout
static const uint kBufferTimeout
Definition: firewiresignalmonitor.h:62
MythTimer::elapsed
int elapsed(void)
Returns milliseconds elapsed since last start() or restart()
Definition: mythtimer.cpp:90
FirewireSignalMonitor::m_stb_needs_retune
bool m_stb_needs_retune
Definition: firewiresignalmonitor.h:67
SignalMonitor::HasFlags
bool HasFlags(uint64_t _flags) const
Definition: signalmonitor.cpp:277
FirewireSignalMonitor::m_stb_wait_for_pat_timer
MythTimer m_stb_wait_for_pat_timer
Definition: firewiresignalmonitor.h:70
FirewireSignalMonitor::HandlePMT
void HandlePMT(uint pnum, const ProgramMapTable *pmt) override
Definition: firewiresignalmonitor.cpp:116
FirewireDevice::kAVCPowerQueryFailed
@ kAVCPowerQueryFailed
Definition: firewiredevice.h:34
SignalMonitor::m_statusLock
QMutex m_statusLock
Definition: signalmonitor.h:229
FirewireSignalMonitor::m_stb_needs_to_wait_for_power
bool m_stb_needs_to_wait_for_power
Definition: firewiresignalmonitor.h:69
SignalMonitor::kDTVSigMon_PATMatch
static const uint64_t kDTVSigMon_PATMatch
We've seen a PAT matching our requirements.
Definition: signalmonitor.h:161
FirewireChannel::GetFirewireDevice
virtual FirewireDevice * GetFirewireDevice(void)
Definition: firewirechannel.h:51
FirewireSignalMonitor::FirewireTableMonitorThread
friend class FirewireTableMonitorThread
Definition: firewiresignalmonitor.h:36
DTVSignalMonitor
This class is intended to detect the presence of needed tables.
Definition: dtvsignalmonitor.h:15
firewiresignalmonitor.h
FirewireTableMonitorThread::m_parent
FirewireSignalMonitor * m_parent
Definition: firewiresignalmonitor.h:31
FirewireSignalMonitor::m_dtvMonitorRunning
volatile bool m_dtvMonitorRunning
Definition: firewiresignalmonitor.h:65
atsctables.h
FirewireSignalMonitor::s_pat_keys
static QMap< void *, uint > s_pat_keys
Definition: firewiresignalmonitor.h:75
MPEGStreamData::SetVersionPMT
void SetVersionPMT(uint pnum, int version, uint last_section)
Definition: mpegstreamdata.h:162
FirewireDevice::IsSTBBufferCleared
bool IsSTBBufferCleared(void) const
Definition: firewiredevice.h:210
MThread::wait
bool wait(unsigned long time=ULONG_MAX)
Wait for the MThread to exit, with a maximum timeout.
Definition: mthread.cpp:309
SignalMonitor::Stop
virtual void Stop()
Stop signal monitoring thread.
Definition: signalmonitor.cpp:306
DTVSignalMonitor::HandlePAT
void HandlePAT(const ProgramAssociationTable *pat) override
Definition: dtvsignalmonitor.cpp:292
FirewireDevice::kAVCPowerOff
@ kAVCPowerOff
Definition: firewiredevice.h:32
DTVSignalMonitor::IsAllGood
bool IsAllGood(void) const override
Definition: dtvsignalmonitor.cpp:566
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:192
SignalMonitor::kDTVSigMon_WaitForVCT
static const uint64_t kDTVSigMon_WaitForVCT
Definition: signalmonitor.h:184
FirewireDevice
Definition: firewiredevice.h:24
FirewireDevice::OpenPort
virtual bool OpenPort(void)=0