/
hdhrsignalmonitor.cpp
149 lines (123 loc) · 4.03 KB
/
hdhrsignalmonitor.cpp
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
// -*- Mode: c++ -*-
// Copyright (c) 2006, Daniel Thor Kristjansson
#include <cerrno>
#include <cstring>
#include <fcntl.h>
#include <unistd.h>
#ifndef USING_MINGW
#include <sys/select.h>
#endif
#include "mythlogging.h"
#include "mythdbcon.h"
#include "hdhrsignalmonitor.h"
#include "atscstreamdata.h"
#include "mpegtables.h"
#include "atsctables.h"
#include "hdhrchannel.h"
#include "hdhrrecorder.h"
#include "hdhrstreamhandler.h"
#define LOC QString("HDHRSM[%1](%2): ") \
.arg(capturecardnum).arg(channel->GetDevice())
/**
* \brief Initializes signal lock and signal values.
*
* Start() must be called to actually begin continuous
* signal monitoring. The timeout is set to 3 seconds,
* and the signal threshold is initialized to 0%.
*
* \param db_cardnum Recorder number to monitor,
* if this is less than 0, SIGNAL events will not be
* sent to the frontend even if SetNotifyFrontend(true)
* is called.
* \param _channel HDHRChannel for card
* \param _flags Flags to start with
*/
HDHRSignalMonitor::HDHRSignalMonitor(
int db_cardnum, HDHRChannel* _channel, uint64_t _flags) :
DTVSignalMonitor(db_cardnum, _channel, _flags),
streamHandlerStarted(false), streamHandler(NULL),
lock_timeout(1000 * 30 /* 30 seconds */)
{
LOG(VB_CHANNEL, LOG_INFO, LOC + "ctor");
signalStrength.SetThreshold(45);
AddFlags(kSigMon_WaitForSig);
streamHandler = HDHRStreamHandler::Get(_channel->GetDevice());
}
/** \fn HDHRSignalMonitor::~HDHRSignalMonitor()
* \brief Stops signal monitoring and table monitoring threads.
*/
HDHRSignalMonitor::~HDHRSignalMonitor()
{
LOG(VB_CHANNEL, LOG_INFO, LOC + "dtor");
Stop();
HDHRStreamHandler::Return(streamHandler);
}
/** \fn HDHRSignalMonitor::Stop(void)
* \brief Stop signal monitoring and table monitoring threads.
*/
void HDHRSignalMonitor::Stop(void)
{
LOG(VB_CHANNEL, LOG_INFO, LOC + "Stop() -- begin");
SignalMonitor::Stop();
if (GetStreamData())
streamHandler->RemoveListener(GetStreamData());
streamHandlerStarted = false;
LOG(VB_CHANNEL, LOG_INFO, LOC + "Stop() -- end");
}
HDHRChannel *HDHRSignalMonitor::GetHDHRChannel(void)
{
return dynamic_cast<HDHRChannel*>(channel);
}
/** \fn HDHRSignalMonitor::UpdateValues(void)
* \brief Fills in frontend stats and emits status Qt signals.
*
* This is automatically called by MonitorLoop(), after Start()
* has been used to start the signal monitoring thread.
*/
void HDHRSignalMonitor::UpdateValues(void)
{
if (lock_timer.elapsed() > lock_timeout)
error = "Timed out.";
if (!running || exit)
return;
if (streamHandlerStarted)
{
EmitStatus();
if (IsAllGood())
SendMessageAllGood();
// TODO dtv signals...
update_done = true;
return;
}
struct hdhomerun_tuner_status_t status;
streamHandler->GetTunerStatus(&status);
uint sig = status.signal_strength;
uint snq = status.signal_to_noise_quality;
uint seq = status.symbol_error_quality;
(void) snq; // TODO should convert to S/N
(void) seq; // TODO should report this...
LOG(VB_RECORD, LOG_DEBUG, LOC + "Tuner status: " + QString("'%1:%2:%3'")
.arg(sig).arg(snq).arg(seq));
// Set SignalMonitorValues from info from card.
bool isLocked = false;
{
QMutexLocker locker(&statusLock);
signalStrength.SetValue(sig);
signalLock.SetValue(status.lock_supported);
isLocked = signalLock.IsGood();
}
EmitStatus();
if (IsAllGood())
SendMessageAllGood();
// Start table monitoring if we are waiting on any table
// and we have a lock.
if (isLocked && GetStreamData() &&
HasAnyFlag(kDTVSigMon_WaitForPAT | kDTVSigMon_WaitForPMT |
kDTVSigMon_WaitForMGT | kDTVSigMon_WaitForVCT |
kDTVSigMon_WaitForNIT | kDTVSigMon_WaitForSDT))
{
streamHandler->AddListener(GetStreamData());
streamHandlerStarted = true;
}
update_done = true;
}