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(m_inputid).arg(m_channel->GetDevice())
24 
39  V4LChannel *_channel,
40  bool _release_stream,
41  uint64_t _flags)
42  : DTVSignalMonitor(db_cardnum, _channel, _release_stream, _flags)
43 {
44  LOG(VB_CHANNEL, LOG_INFO, LOC + "ctor");
45 
47  if (!m_v4l2.IsOpen())
48  {
49  LOG(VB_GENERAL, LOG_ERR, LOC + "ctor -- Open failed");
50  return;
51  }
52 
53  m_isTS = (m_v4l2.GetStreamType() == V4L2_MPEG_STREAM_TYPE_MPEG2_TS);
54 
55 
56  m_signalStrength.SetRange(0, 100);
57  LOG(VB_CHANNEL, LOG_INFO, LOC + QString("%1 stream.")
58  .arg(m_isTS ? "Transport" : "Program"));
59 }
60 
65 {
66  LOG(VB_CHANNEL, LOG_INFO, LOC + "dtor");
68  if (m_stream_handler)
70 }
71 
76 {
77  LOG(VB_CHANNEL, LOG_INFO, LOC + "Stop() -- begin");
78 
82 
83  LOG(VB_CHANNEL, LOG_INFO, LOC + "Stop() -- end");
84 }
85 
93 {
94  if (!m_running || m_exit)
95  return;
96 
97  if (!m_isTS)
98  {
102 
104 
105  {
106  QMutexLocker locker(&m_statusLock);
107  if (!m_scriptStatus.IsGood())
108  return;
109  }
110  }
111 
112  if (m_stream_handler)
113  {
114  EmitStatus();
115  if (IsAllGood())
117 
118  m_update_done = true;
119  return;
120  }
121 
122  bool isLocked = HasLock();
123 
124  LOG(VB_CHANNEL, LOG_INFO, LOC + QString("isLocked: %1").arg(isLocked));
125 
126  {
127  QMutexLocker locker(&m_statusLock);
129  m_signalLock.SetValue(isLocked ? 1 : 0);
130  }
131 
132  EmitStatus();
133  if (IsAllGood())
135 
136  // Start table monitoring if we are waiting on any table
137  // and we have a lock.
138  if (isLocked && !m_stream_handler && GetStreamData() &&
142  {
143  auto* chn = reinterpret_cast<V4LChannel*>(m_channel);
145  V4L2encStreamHandler::Get(chn->GetDevice(),
146  chn->GetAudioDevice().toInt(), m_inputid);
148  {
149  LOG(VB_GENERAL, LOG_ERR, LOC +
150  "V4L2encSignalMonitor -- failed to start StreamHandler.");
151  }
152  else
153  {
156  }
157  }
158 
159  m_update_done = true;
160 }
161 
163 {
164  if (!m_v4l2.IsOpen())
165  {
166  LOG(VB_CHANNEL, LOG_INFO, LOC +
167  "GetSignalStrengthPercent() -- v4l2 device not open");
168  return false;
169  }
170 
171  if (m_strength >= 0)
173  if (m_strength < 0)
174  return (true /* || StableResolution() == 100 */);
175 
176  return m_strength > 50;
177 }
178 
189 {
190  int width;
191  int height;
192 
193  if (m_v4l2.GetResolution(width, height))
194  {
195  m_timer.stop();
196  if (width > 0)
197  {
198  LOG(VB_CHANNEL, LOG_INFO, LOC +
199  QString("Resolution already stable at %1 x %2")
200  .arg(width).arg(height));
201  return 100;
202  }
203  LOG(VB_GENERAL, LOG_ERR, LOC + "Device wedged?");
204  return 0;
205  }
206 
207  if (m_width == width)
208  {
209  if (!m_timer.isRunning())
210  {
211  LOG(VB_CHANNEL, LOG_INFO, QString("Resolution %1 x %2")
212  .arg(width).arg(height));
213  if (++m_lock_cnt > 9)
214  m_lock_cnt = 1;
215  m_timer.start();
216  }
217  else if (m_timer.elapsed() > m_stable_time)
218  {
219  LOG(VB_CHANNEL, LOG_INFO, QString("Resolution stable at %1 x %2")
220  .arg(width).arg(height));
221  m_timer.stop();
222  return 100;
223  }
224  else
225  return 40 + m_lock_cnt;
226  }
227  else
228  {
229  // Indicate that we are still waiting for a valid res, every 3 seconds.
230  if (!m_status_time.isValid() || MythDate::current() > m_status_time)
231  {
232  LOG(VB_CHANNEL, LOG_WARNING, "Waiting for valid resolution");
233  m_status_time = MythDate::current().addSecs(3);
234  }
235  m_timer.stop();
236  }
237 
238  m_width = width;
239  return 20 + m_lock_cnt;
240 }
SignalMonitorValue m_scriptStatus
QMutex m_statusLock
bool Open(const QString &dev_name, const QString &vbi_dev_name="")
Definition: v4l2util.cpp:31
static V4L2encStreamHandler * Get(const QString &devname, int audioinput, int inputid)
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
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
void SetValue(int _value)
static const uint64_t kDTVSigMon_WaitForNIT
Overall structure.
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
virtual void AddListener(MPEGStreamData *data, bool allow_section_reader=false, bool needs_buffering=false, QString output_file=QString())
ChannelBase * m_channel
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
volatile bool m_exit
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.
volatile bool m_running
V4L2encStreamHandler * m_stream_handler
Implements tuning for TV cards using the V4L driver API, both versions 1 and 2.
Definition: v4lchannel.h:32
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
SignalMonitorValue m_signalStrength
void SetRange(int _min, int _max)
Sets the minimum and maximum values.
int elapsed(void)
Returns milliseconds elapsed since last start() or restart()
Definition: mythtimer.cpp:90
static const uint64_t kDTVSigMon_WaitForSDT
virtual ~V4L2encSignalMonitor()
Stops signal monitoring and table monitoring threads.
bool IsGood() const
Returns true if the value is equal to the threshold, or on the right side of the threshold (depends o...
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)
void start(void)
starts measuring elapsed time.
Definition: mythtimer.cpp:47
SignalMonitorValue m_signalLock
virtual void EmitStatus(void)
virtual void UpdateValues(void)
This should be overridden to actually do signal monitoring.