-
Notifications
You must be signed in to change notification settings - Fork 341
/
signalmonitor.h
309 lines (266 loc) · 11.7 KB
/
signalmonitor.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
// -*- Mode: c++ -*-
// Copyright (c) 2005, Daniel Thor Kristjansson
#ifndef SIGNALMONITOR_H
#define SIGNALMONITOR_H
// C++ headers
#include <vector>
#include <algorithm>
using namespace std;
// Qt headers
#include <QWaitCondition>
#include <QMutex>
// MythTV headers
#include "signalmonitorlistener.h"
#include "signalmonitorvalue.h"
#include "channelbase.h"
#include "mythtimer.h"
#include "cardutil.h"
#include "mthread.h"
#define DBG_SM(FUNC, MSG) LOG(VB_CHANNEL, LOG_DEBUG, \
QString("SM(%1)::%2: %3") .arg(channel->GetDevice()).arg(FUNC).arg(<MSG));
inline QString sm_flags_to_string(uint64_t);
class TVRec;
class SignalMonitor : protected MThread
{
public:
/// Returns true iff the card type supports signal monitoring.
static inline bool IsRequired(const QString &cardtype);
static inline bool IsSupported(const QString &cardtype);
static SignalMonitor *Init(QString cardtype, int db_cardnum,
ChannelBase *channel);
virtual ~SignalMonitor();
// // // // // // // // // // // // // // // // // // // // // // // //
// Control // // // // // // // // // // // // // // // // // // // //
virtual void Start();
virtual void Stop();
// // // // // // // // // // // // // // // // // // // // // // // //
// Flags // // // // // // // // // // // // // // // // // // // // //
virtual void AddFlags(uint64_t _flags);
virtual void RemoveFlags(uint64_t _flags);
bool HasFlags(uint64_t _flags) const;
bool HasAnyFlag(uint64_t _flags) const;
uint64_t GetFlags(void) const { return flags; }
// // // // // // // // // // // // // // // // // // // // // // // //
// Gets // // // // // // // // // // // // // // // // // // // // //
/// \brief Returns whether or not a SIGNAL MythEvent is being sent
/// regularly to the frontend.
bool GetNotifyFrontend() const { return notify_frontend; }
/// \brief Returns milliseconds between signal monitoring events.
int GetUpdateRate() const { return update_rate; }
virtual QStringList GetStatusList(void) const;
/// \brief Returns true iff scriptStatus.IsGood() and signalLock.IsGood()
/// return true
bool HasSignalLock(void) const
{
QMutexLocker locker(&statusLock);
return scriptStatus.IsGood() && signalLock.IsGood();
}
virtual bool IsAllGood(void) const { return HasSignalLock(); }
bool IsErrored(void) const { return !error.isEmpty(); }
// // // // // // // // // // // // // // // // // // // // // // // //
// Sets // // // // // // // // // // // // // // // // // // // // //
/** \brief Enables or disables frontend notification of the current
* signal value.
* \param notify if true SIGNAL MythEvents are sent to the frontend,
* otherwise they are not.
*/
void SetNotifyFrontend(bool notify) { notify_frontend = notify; }
/** \brief Indicate if table monitoring is needed
* \param monitor if true parent->SetupDTVSignalMonitor is called
* after the channel is tuned.
*/
void SetMonitoring(TVRec * parent, bool EITscan, bool monitor)
{ pParent = parent; eit_scan = EITscan, tablemon = monitor; }
/** \brief Sets the number of milliseconds between signal monitoring
* attempts in the signal monitoring thread.
*
* Defaults to 25 milliseconds.
* \param msec Milliseconds between signal monitoring events.
*/
void SetUpdateRate(int msec)
{ update_rate = max(msec, (int)minimum_update_rate); }
// // // // // // // // // // // // // // // // // // // // // // // //
// Listeners // // // // // // // // // // // // // // // // // // //
void AddListener(SignalMonitorListener *listener);
void RemoveListener(SignalMonitorListener *listener);
void SendMessage(SignalMonitorMessageType type,
const SignalMonitorValue &val);
void SendMessageAllGood(void);
virtual void EmitStatus(void);
protected:
SignalMonitor(int db_cardnum, ChannelBase *_channel,
uint64_t wait_for_mask);
virtual void run(void);
/// \brief This should be overridden to actually do signal monitoring.
virtual void UpdateValues(void);
public:
/// We've seen a PAT,
/// which maps MPEG program numbers to pids where we find PMTs
static const uint64_t kDTVSigMon_PATSeen = 0x0000000001ULL;
/// We've seen a PMT,
/// which maps program to audio, video and other stream PIDs
static const uint64_t kDTVSigMon_PMTSeen = 0x0000000002ULL;
/// We've seen a MGT,
/// which tells us on which PIDs to find VCT and other ATSC tables
static const uint64_t kDTVSigMon_MGTSeen = 0x0000000004ULL;
/// We've seen a VCT, which maps ATSC Channels to
/// MPEG program numbers, and provides additional data
static const uint64_t kDTVSigMon_VCTSeen = 0x0000000008ULL;
/// We've seen a TVCT, the terrestrial version of the VCT
static const uint64_t kDTVSigMon_TVCTSeen = 0x0000000010ULL;
/// We've seen a CVCT, the cable version of the VCT
static const uint64_t kDTVSigMon_CVCTSeen = 0x0000000020ULL;
/// We've seen a NIT,
/// which tells us where to find SDT and other DVB tables
static const uint64_t kDTVSigMon_NITSeen = 0x0000000040ULL;
/// We've seen a SDT, which maps DVB Channels to MPEG
/// program numbers, and provides additional data
static const uint64_t kDTVSigMon_SDTSeen = 0x0000000080ULL;
/// We've seen the FireWire STB power state
static const uint64_t kFWSigMon_PowerSeen = 0x0000000100ULL;
/// We've seen something indicating whether the data stream is encrypted
static const uint64_t kDTVSigMon_CryptSeen = 0x0000000200ULL;
/// We've seen a PAT matching our requirements
static const uint64_t kDTVSigMon_PATMatch = 0x0000001000ULL;
/// We've seen a PMT matching our requirements
static const uint64_t kDTVSigMon_PMTMatch = 0x0000002000ULL;
/// We've seen an MGT matching our requirements
static const uint64_t kDTVSigMon_MGTMatch = 0x0000004000ULL;
/// We've seen a VCT matching our requirements
static const uint64_t kDTVSigMon_VCTMatch = 0x0000008000ULL;
/// We've seen a TVCT matching our requirements
static const uint64_t kDTVSigMon_TVCTMatch = 0x0000010000ULL;
/// We've seen a CVCT matching our requirements
static const uint64_t kDTVSigMon_CVCTMatch = 0x0000020000ULL;
/// We've seen an NIT matching our requirements
static const uint64_t kDTVSigMon_NITMatch = 0x0000040000ULL;
/// We've seen an SDT matching our requirements
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've seen unencrypted data in data stream
static const uint64_t kDTVSigMon_CryptMatch = 0x0000200000ULL;
static const uint64_t kDTVSigMon_WaitForPAT = 0x0001000000ULL;
static const uint64_t kDTVSigMon_WaitForPMT = 0x0002000000ULL;
static const uint64_t kDTVSigMon_WaitForMGT = 0x0004000000ULL;
static const uint64_t kDTVSigMon_WaitForVCT = 0x0008000000ULL;
static const uint64_t kDTVSigMon_WaitForNIT = 0x0010000000ULL;
static const uint64_t kDTVSigMon_WaitForSDT = 0x0020000000ULL;
static const uint64_t kSigMon_WaitForSig = 0x0040000000ULL;
static const uint64_t kFWSigMon_WaitForPower= 0x0080000000ULL;
static const uint64_t kDTVSigMon_WaitForCrypt=0x0100000000ULL;
static const uint64_t kDTVSigMon_WaitForAll = 0x01FF000000ULL;
/// Wait for the Signal to Noise Ratio to rise above a threshold
static const uint64_t kDVBSigMon_WaitForSNR = 0x1000000000ULL;
/// Wait for the Bit Error Rate to fall below a threshold
static const uint64_t kDVBSigMon_WaitForBER = 0x2000000000ULL;
/// Wait for uncorrected FEC blocks to fall below a threshold
static const uint64_t kDVBSigMon_WaitForUB = 0x4000000000ULL;
/// Wait for rotor to complete turning the antenna
static const uint64_t kDVBSigMon_WaitForPos = 0x8000000000ULL;
protected:
ChannelBase *channel;
TVRec *pParent;
int capturecardnum;
volatile uint64_t flags;
int update_rate;
uint minimum_update_rate;
bool update_done;
bool notify_frontend;
bool tablemon;
bool eit_scan;
QString error;
SignalMonitorValue signalLock;
SignalMonitorValue signalStrength;
SignalMonitorValue scriptStatus;
vector<SignalMonitorListener*> listeners;
QMutex startStopLock;
QWaitCondition startStopWait; // protected by startStopLock
volatile bool running; // protected by startStopLock
volatile bool exit; // protected by startStopLock
mutable QMutex statusLock;
mutable QMutex listenerLock;
};
inline QString sm_flags_to_string(uint64_t flags)
{
QString str("Seen(");
if (SignalMonitor::kDTVSigMon_PATSeen & flags)
str += "PAT,";
if (SignalMonitor::kDTVSigMon_PMTSeen & flags)
str += "PMT,";
if (SignalMonitor::kDTVSigMon_MGTSeen & flags)
str += "MGT,";
if (SignalMonitor::kDTVSigMon_VCTSeen & flags)
str += "VCT,";
if (SignalMonitor::kDTVSigMon_TVCTSeen & flags)
str += "TVCT,";
if (SignalMonitor::kDTVSigMon_CVCTSeen & flags)
str += "CVCT,";
if (SignalMonitor::kDTVSigMon_NITSeen & flags)
str += "NIT,";
if (SignalMonitor::kDTVSigMon_SDTSeen & flags)
str += "SDT,";
if (SignalMonitor::kFWSigMon_PowerSeen & flags)
str += "STB,";
if (SignalMonitor::kDTVSigMon_CryptSeen & flags)
str += "Crypt,";
str += ") Match(";
if (SignalMonitor::kDTVSigMon_PATMatch & flags)
str += "PAT,";
if (SignalMonitor::kDTVSigMon_PMTMatch & flags)
str += "PMT,";
if (SignalMonitor::kDTVSigMon_MGTMatch & flags)
str += "MGT,";
if (SignalMonitor::kDTVSigMon_VCTMatch & flags)
str += "VCT,";
if (SignalMonitor::kDTVSigMon_TVCTMatch & flags)
str += "TVCT,";
if (SignalMonitor::kDTVSigMon_CVCTMatch & flags)
str += "CVCT,";
if (SignalMonitor::kDTVSigMon_NITMatch & flags)
str += "NIT,";
if (SignalMonitor::kDTVSigMon_SDTMatch & flags)
str += "SDT,";
if (SignalMonitor::kFWSigMon_PowerMatch & flags)
str += "STB,";
if (SignalMonitor::kDTVSigMon_CryptMatch & flags)
str += "Crypt,";
str += ") Wait(";
if (SignalMonitor::kDTVSigMon_WaitForPAT & flags)
str += "PAT,";
if (SignalMonitor::kDTVSigMon_WaitForPMT & flags)
str += "PMT,";
if (SignalMonitor::kDTVSigMon_WaitForMGT & flags)
str += "MGT,";
if (SignalMonitor::kDTVSigMon_WaitForVCT & flags)
str += "VCT,";
if (SignalMonitor::kDTVSigMon_WaitForNIT & flags)
str += "NIT,";
if (SignalMonitor::kDTVSigMon_WaitForSDT & flags)
str += "SDT,";
if (SignalMonitor::kSigMon_WaitForSig & flags)
str += "Sig,";
if (SignalMonitor::kFWSigMon_WaitForPower& flags)
str += "STB,";
if (SignalMonitor::kDTVSigMon_WaitForCrypt & flags)
str += "Crypt,";
if (SignalMonitor::kDVBSigMon_WaitForSNR & flags)
str += "SNR,";
if (SignalMonitor::kDVBSigMon_WaitForBER & flags)
str += "BER,";
if (SignalMonitor::kDVBSigMon_WaitForUB & flags)
str += "UB,";
if (SignalMonitor::kDVBSigMon_WaitForPos & flags)
str += "Pos,";
str += ")";
return str;
}
inline bool SignalMonitor::IsRequired(const QString &cardtype)
{
return (cardtype != "IMPORT" && cardtype != "DEMO");
}
inline bool SignalMonitor::IsSupported(const QString &cardtype)
{
return IsRequired(cardtype);
}
#endif // SIGNALMONITOR_H