MythTV  master
v4l2encsignalmonitor.cpp
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 
3 #include <cerrno>
4 #include <cstring>
5 
6 #include <fcntl.h>
7 #include <unistd.h>
8 #ifndef USING_MINGW
9 #include <sys/select.h>
10 #endif
11 
12 #include "mythlogging.h"
13 #include "mythdbcon.h"
14 #include "atscstreamdata.h"
15 #include "mpegtables.h"
16 #include "atsctables.h"
17 
18 #include "v4lchannel.h"
19 #include "v4l2encrecorder.h"
20 #include "v4l2encstreamhandler.h"
21 #include "v4l2encsignalmonitor.h"
22 
23 #define LOC QString("V4L2SigMon[%1](%2): ").arg(inputid).arg(channel->GetDevice())
24 
39  V4LChannel *_channel,
40  bool _release_stream,
41  uint64_t _flags)
42  : DTVSignalMonitor(db_cardnum, _channel, _release_stream, _flags),
43  m_stream_handler(nullptr), m_isTS(false),
44  m_strength(0), m_stable_time(1500), m_width(0), m_height(0), m_lock_cnt(0)
45 {
46  LOG(VB_CHANNEL, LOG_INFO, LOC + "ctor");
47 
49  if (!m_v4l2.IsOpen())
50  {
51  LOG(VB_GENERAL, LOG_ERR, LOC + "ctor -- Open failed");
52  return;
53  }
54 
55  m_isTS = (m_v4l2.GetStreamType() == V4L2_MPEG_STREAM_TYPE_MPEG2_TS);
56 
57 
58  signalStrength.SetRange(0, 100);
59  LOG(VB_CHANNEL, LOG_INFO, LOC + QString("%1 stream.")
60  .arg(m_isTS ? "Transport" : "Program"));
61 }
62 
67 {
68  LOG(VB_CHANNEL, LOG_INFO, LOC + "dtor");
69  Stop();
70  if (m_stream_handler)
72 }
73 
78 {
79  LOG(VB_CHANNEL, LOG_INFO, LOC + "Stop() -- begin");
80 
84 
85  LOG(VB_CHANNEL, LOG_INFO, LOC + "Stop() -- end");
86 }
87 
95 {
96  if (!running || exit)
97  return;
98 
99  if (!m_isTS)
100  {
104 
106 
107  {
108  QMutexLocker locker(&statusLock);
109  if (!scriptStatus.IsGood())
110  return;
111  }
112  }
113 
114  if (m_stream_handler)
115  {
116  EmitStatus();
117  if (IsAllGood())
119 
120  update_done = true;
121  return;
122  }
123 
124  bool isLocked = HasLock();
125 
126  LOG(VB_CHANNEL, LOG_INFO, LOC + QString("isLocked: %1").arg(isLocked));
127 
128  {
129  QMutexLocker locker(&statusLock);
131  signalLock.SetValue(isLocked ? 1 : 0);
132  }
133 
134  EmitStatus();
135  if (IsAllGood())
137 
138  // Start table monitoring if we are waiting on any table
139  // and we have a lock.
140  if (isLocked && !m_stream_handler && GetStreamData() &&
144  {
145  V4LChannel* chn = reinterpret_cast<V4LChannel*>(channel);
148  chn->GetAudioDevice().toInt(), inputid);
150  {
151  LOG(VB_GENERAL, LOG_ERR, LOC +
152  "V4L2encSignalMonitor -- failed to start StreamHandler.");
153  }
154  else
155  {
158  }
159  }
160 
161  update_done = true;
162 }
163 
165 {
166  if (!m_v4l2.IsOpen())
167  {
168  LOG(VB_CHANNEL, LOG_INFO, LOC +
169  "GetSignalStrengthPercent() -- v4l2 device not open");
170  return false;
171  }
172 
173  if (m_strength >= 0)
175  if (m_strength < 0)
176  return (true || StableResolution() == 100);
177 
178  return m_strength > 50;
179 }
180 
191 {
192  int width, height;
193 
194  if (m_v4l2.GetResolution(width, height))
195  {
196  m_timer.stop();
197  if (width > 0)
198  {
199  LOG(VB_CHANNEL, LOG_INFO, LOC +
200  QString("Resolution already stable at %1 x %2")
201  .arg(width).arg(height));
202  return 100;
203  }
204  else
205  {
206  LOG(VB_GENERAL, LOG_ERR, LOC + "Device wedged?");
207  return 0;
208  }
209  }
210 
211  if (m_width == width)
212  {
213  if (!m_timer.isRunning())
214  {
215  LOG(VB_CHANNEL, LOG_INFO, QString("Resolution %1 x %2")
216  .arg(width).arg(height));
217  if (++m_lock_cnt > 9)
218  m_lock_cnt = 1;
219  m_timer.start();
220  }
221  else if (m_timer.elapsed() > m_stable_time)
222  {
223  LOG(VB_CHANNEL, LOG_INFO, QString("Resolution stable at %1 x %2")
224  .arg(width).arg(height));
225  m_timer.stop();
226  return 100;
227  }
228  else
229  return 40 + m_lock_cnt;
230  }
231  else
232  {
233  // Indicate that we are still waiting for a valid res, every 3 seconds.
234  if (!m_status_time.isValid() || MythDate::current() > m_status_time)
235  {
236  LOG(VB_CHANNEL, LOG_WARNING, "Waiting for valid resolution");
237  m_status_time = MythDate::current().addSecs(3);
238  }
239  m_timer.stop();
240  }
241 
242  m_width = width;
243  return 20 + m_lock_cnt;
244 }
static const uint64_t kDVBSigMon_WaitForPos
Wait for rotor to complete turning the antenna.
bool GetResolution(int &width, int &height) const
static const uint64_t kDTVSigMon_WaitForPMT
static const uint64_t kDTVSigMon_WaitForPAT
bool HasAnyFlag(uint64_t _flags) const
virtual void RemoveListener(MPEGStreamData *data)
bool IsOpen(void) const
Definition: v4l2util.h:29
bool HasError(void) const
Definition: streamhandler.h:64
QString GetDevice(void) const override
Returns String representing device, useful for debugging.
Definition: v4lchannel.h:60
static const uint64_t kDTVSigMon_WaitForVCT
static const uint64_t kDTVSigMon_WaitForMGT
bool isRunning(void) const
Returns true if start() or restart() has been called at least once since construction and since any c...
Definition: mythtimer.cpp:134
SignalMonitorValue signalLock
QString GetAudioDevice(void) const
Definition: v4lchannel.h:62
void SetValue(int _value)
static const uint64_t kDTVSigMon_WaitForNIT
Overall structure.
bool Open(const QString &device_name, const QString &vbi_device_name="")
Definition: v4l2util.cpp:47
int GetStreamType(void) const
void RemoveFlags(uint64_t _flags) override
virtual void Stop()
Stop signal monitoring thread.
void Stop(void) override
Stop signal monitoring and table monitoring threads.
int GetSignalStrength(void) const
VERBOSE_PREAMBLE false
Definition: verbosedefs.h:85
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
MPEGStreamData * GetStreamData()
Returns the MPEG stream data if it exists.
void SendMessageAllGood(void)
void UpdateValues(void) override
Fills in frontend stats and emits status Qt signals.
V4L2encStreamHandler * m_stream_handler
Implements tuning for TV cards using the V4L driver API, both versions 1 and 2.
Definition: v4lchannel.h:32
int elapsed(void) const
Returns milliseconds elapsed since last start() or restart()
Definition: mythtimer.cpp:90
int StableResolution(void)
Wait for a stable signal.
This class is intended to detect the presence of needed tables.
virtual QString GetDevice(void) const
Returns String representing device, useful for debugging.
Definition: channelbase.h:78
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
bool IsAllGood(void) const override
#define LOC
void SetRange(int _min, int _max)
Sets the minimum and maximum values.
virtual void AddListener(MPEGStreamData *data, bool allow_section_reader=false, bool needs_drb=false, QString output_file=QString())
static const uint64_t kDTVSigMon_WaitForSDT
SignalMonitorValue signalStrength
SignalMonitorValue scriptStatus
ChannelBase * channel
virtual ~V4L2encSignalMonitor()
Stops signal monitoring and table monitoring threads.
volatile bool running
bool IsGood() const
Returns true if the value is equal to the threshold, or on the right side of the threshold (depends o...
volatile bool exit
void stop(void)
Stops timer, next call to isRunning() will return false and any calls to elapsed() or restart() will ...
Definition: mythtimer.cpp:77
static void Return(V4L2encStreamHandler *&ref, int inputid)
static V4L2encStreamHandler * Get(const QString &devicename, int audioinput, int inputid)
void start(void)
starts measuring elapsed time.
Definition: mythtimer.cpp:47
virtual void EmitStatus(void)
virtual void UpdateValues(void)
This should be overridden to actually do signal monitoring.