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  V4LChannel* chn = reinterpret_cast<V4LChannel*>(m_channel);
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, height;
191 
192  if (m_v4l2.GetResolution(width, height))
193  {
194  m_timer.stop();
195  if (width > 0)
196  {
197  LOG(VB_CHANNEL, LOG_INFO, LOC +
198  QString("Resolution already stable at %1 x %2")
199  .arg(width).arg(height));
200  return 100;
201  }
202  LOG(VB_GENERAL, LOG_ERR, LOC + "Device wedged?");
203  return 0;
204  }
205 
206  if (m_width == width)
207  {
208  if (!m_timer.isRunning())
209  {
210  LOG(VB_CHANNEL, LOG_INFO, QString("Resolution %1 x %2")
211  .arg(width).arg(height));
212  if (++m_lock_cnt > 9)
213  m_lock_cnt = 1;
214  m_timer.start();
215  }
216  else if (m_timer.elapsed() > m_stable_time)
217  {
218  LOG(VB_CHANNEL, LOG_INFO, QString("Resolution stable at %1 x %2")
219  .arg(width).arg(height));
220  m_timer.stop();
221  return 100;
222  }
223  else
224  return 40 + m_lock_cnt;
225  }
226  else
227  {
228  // Indicate that we are still waiting for a valid res, every 3 seconds.
229  if (!m_status_time.isValid() || MythDate::current() > m_status_time)
230  {
231  LOG(VB_CHANNEL, LOG_WARNING, "Waiting for valid resolution");
232  m_status_time = MythDate::current().addSecs(3);
233  }
234  m_timer.stop();
235  }
236 
237  m_width = width;
238  return 20 + m_lock_cnt;
239 }
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
QString GetDevice(void) const override
Returns String representing device, useful for debugging.
Definition: v4lchannel.h:61
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
QString GetAudioDevice(void) const
Definition: v4lchannel.h:63
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 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
SignalMonitorValue m_signalStrength
void SetRange(int _min, int _max)
Sets the minimum and maximum values.
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.