MythTV  master
hdhrstreamhandler.cpp
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 
3 // POSIX headers
4 #include <fcntl.h>
5 #include <unistd.h>
6 #ifndef _WIN32
7 #include <sys/select.h>
8 #include <sys/ioctl.h>
9 #endif
10 #include <chrono> // for milliseconds
11 #include <thread> // for sleep_for
12 
13 // MythTV headers
14 #include "hdhrstreamhandler.h"
15 #include "hdhrchannel.h"
16 #include "dtvsignalmonitor.h"
17 #include "streamlisteners.h"
18 #include "mpegstreamdata.h"
19 #include "cardutil.h"
20 #include "mythlogging.h"
21 
22 #ifdef NEED_HDHOMERUN_DEVICE_SELECTOR_LOAD_FROM_STR
23 static int hdhomerun_device_selector_load_from_str(struct hdhomerun_device_selector_t *hds, char *device_str);
24 #endif
25 
26 #define LOC QString("HDHRSH[%1](%2): ").arg(m_inputId).arg(m_device)
27 
28 QMap<int,HDHRStreamHandler*> HDHRStreamHandler::s_handlers;
31 
32 HDHRStreamHandler *HDHRStreamHandler::Get(const QString &devname,
33  int inputid, int majorid)
34 {
35  QMutexLocker locker(&s_handlersLock);
36 
37  QMap<int,HDHRStreamHandler*>::iterator it = s_handlers.find(majorid);
38 
39  if (it == s_handlers.end())
40  {
41  auto *newhandler = new HDHRStreamHandler(devname, inputid, majorid);
42  newhandler->Open();
43  s_handlers[majorid] = newhandler;
44  s_handlersRefCnt[majorid] = 1;
45 
46  LOG(VB_RECORD, LOG_INFO,
47  QString("HDHRSH[%1]: Creating new stream handler %2 for %3")
48  .arg(inputid).arg(majorid).arg(devname));
49  }
50  else
51  {
52  s_handlersRefCnt[majorid]++;
53  uint rcount = s_handlersRefCnt[majorid];
54  LOG(VB_RECORD, LOG_INFO,
55  QString("HDHRSH[%1]: Using existing stream handler %2 for %3")
56  .arg(inputid).arg(majorid)
57  .arg(devname) + QString(" (%1 in use)").arg(rcount));
58  }
59 
60  return s_handlers[majorid];
61 }
62 
63 void HDHRStreamHandler::Return(HDHRStreamHandler * & ref, int inputid)
64 {
65  QMutexLocker locker(&s_handlersLock);
66 
67  int majorid = ref->m_majorId;
68 
69  QMap<int,uint>::iterator rit = s_handlersRefCnt.find(majorid);
70  if (rit == s_handlersRefCnt.end())
71  return;
72 
73  QMap<int,HDHRStreamHandler*>::iterator it = s_handlers.find(majorid);
74  if (*rit > 1)
75  {
76  ref = nullptr;
77  (*rit)--;
78  return;
79  }
80 
81  if ((it != s_handlers.end()) && (*it == ref))
82  {
83  LOG(VB_RECORD, LOG_INFO, QString("HDHRSH[%1]: Closing handler for %2")
84  .arg(inputid).arg(majorid));
85  ref->Close();
86  delete *it;
87  s_handlers.erase(it);
88  }
89  else
90  {
91  LOG(VB_GENERAL, LOG_ERR,
92  QString("HDHRSH[%1] Error: Couldn't find handler for %2")
93  .arg(inputid).arg(majorid));
94  }
95 
96  s_handlersRefCnt.erase(rit);
97  ref = nullptr;
98 }
99 
100 HDHRStreamHandler::HDHRStreamHandler(const QString &device, int inputid,
101  int majorid)
102  : StreamHandler(device, inputid)
103  , m_majorId(majorid)
104 {
105  setObjectName("HDHRStreamHandler");
106 }
107 
112 {
113  RunProlog();
114 
115  {
116  QMutexLocker locker(&m_hdhrLock);
117 
118  /* Create TS socket. */
119  if (!hdhomerun_device_stream_start(m_hdhomerunDevice))
120  {
121  LOG(VB_GENERAL, LOG_ERR, LOC +
122  "Starting recording (set target failed). Aborting.");
123  m_bError = true;
124  RunEpilog();
125  return;
126  }
127  hdhomerun_device_stream_flush(m_hdhomerunDevice);
128  }
129 
130  SetRunning(true, false, false);
131 
132  LOG(VB_RECORD, LOG_INFO, LOC + "RunTS(): begin");
133 
134  int remainder = 0;
135  QElapsedTimer last_update;
136  while (m_runningDesired && !m_bError)
137  {
138  auto elapsed = !last_update.isValid()
139  ? -1ms : std::chrono::milliseconds(last_update.elapsed());
140  elapsed = (elapsed < 0ms) ? 1s : elapsed;
141  if (elapsed > 100ms)
142  {
145  UpdateFilters();
146  last_update.restart();
147  }
148 
149  size_t read_size = VIDEO_DATA_BUFFER_SIZE_1S / 8; // read up to 1/8s
150  read_size /= VIDEO_DATA_PACKET_SIZE;
151  read_size *= VIDEO_DATA_PACKET_SIZE;
152 
153  size_t data_length = 0;
154  unsigned char *data_buffer = hdhomerun_device_stream_recv(
155  m_hdhomerunDevice, read_size, &data_length);
156 
157  if (!data_buffer)
158  {
159  std::this_thread::sleep_for(20ms);
160  continue;
161  }
162 
163  // Assume data_length is a multiple of 188 (packet size)
164 
165  m_listenerLock.lock();
166 
167  if (m_streamDataList.empty())
168  {
169  m_listenerLock.unlock();
170  continue;
171  }
172 
173  for (auto sit = m_streamDataList.cbegin(); sit != m_streamDataList.cend(); ++sit)
174  remainder = sit.key()->ProcessData(data_buffer, data_length);
175 
176  WriteMPTS(data_buffer, data_length - remainder);
177 
178  m_listenerLock.unlock();
179  if (remainder != 0)
180  {
181  LOG(VB_RECORD, LOG_INFO, LOC +
182  QString("RunTS(): data_length = %1 remainder = %2")
183  .arg(data_length).arg(remainder));
184  }
185  }
186  LOG(VB_RECORD, LOG_INFO, LOC + "RunTS(): " + "shutdown");
187 
189 
190  {
191  QMutexLocker locker(&m_hdhrLock);
192  hdhomerun_device_stream_stop(m_hdhomerunDevice);
193  }
194 
195  if (VERBOSE_LEVEL_CHECK(VB_RECORD, LOG_INFO))
196  {
197  struct hdhomerun_video_sock_t* vs = nullptr;
198  struct hdhomerun_video_stats_t stats {};
199  vs = hdhomerun_device_get_video_sock(m_hdhomerunDevice);
200  if (vs)
201  {
202  hdhomerun_video_get_stats(vs, &stats);
203  LOG(VB_RECORD, LOG_INFO, LOC +
204  QString("stream stats: packet_count=%1 "
205  "network_errors=%2 "
206  "transport_errors=%3 "
207  "sequence_errors=%4 "
208  "overflow_errors=%5")
209  .arg(stats.packet_count)
210  .arg(stats.network_error_count)
211  .arg(stats.transport_error_count)
212  .arg(stats.sequence_error_count)
213  .arg(stats.overflow_error_count));
214  }
215  }
216 
217  LOG(VB_RECORD, LOG_INFO, LOC + "RunTS(): " + "end");
218 
219  SetRunning(false, false, false);
220 
221  RunEpilog();
222 }
223 
224 static QString filt_str(uint pid)
225 {
226  uint pid0 = (pid / (16*16*16)) % 16;
227  uint pid1 = (pid / (16*16)) % 16;
228  uint pid2 = (pid / (16)) % 16;
229  uint pid3 = pid % 16;
230  return QString("0x%1%2%3%4")
231  .arg(pid0,0,16).arg(pid1,0,16)
232  .arg(pid2,0,16).arg(pid3,0,16);
233 }
234 
236 {
239 
241  {
242  LOG(VB_GENERAL, LOG_ERR, LOC +
243  "UpdateFilters called in wrong tune mode");
244  return false;
245  }
246 
247 #ifdef DEBUG_PID_FILTERS
248  LOG(VB_RECORD, LOG_DEBUG, LOC + "UpdateFilters()");
249 #endif // DEBUG_PID_FILTERS
250  QMutexLocker locker(&m_pidLock);
251 
252  if (!m_filtersChanged)
253  {
254  return true;
255  }
256 
257  QString filter = "";
258 
259  std::vector<uint> range_min;
260  std::vector<uint> range_max;
261 
262  for (auto it = m_pidInfo.cbegin(); it != m_pidInfo.cend(); ++it)
263  {
264  range_min.push_back(it.key());
265  PIDInfoMap::const_iterator eit = it;
266  for (++eit;
267  (eit != m_pidInfo.cend()) && (it.key() + 1 == eit.key());
268  ++it, ++eit);
269  range_max.push_back(it.key());
270  }
271  if (range_min.size() > 16)
272  {
273  range_min.resize(16);
274  uint pid_max = range_max.back();
275  range_max.resize(15);
276  range_max.push_back(pid_max);
277  }
278 
279  for (size_t i = 0; i < range_min.size(); i++)
280  {
281  filter += filt_str(range_min[i]);
282  if (range_min[i] != range_max[i])
283  filter += QString("-%1").arg(filt_str(range_max[i]));
284  filter += " ";
285  }
286 
287  filter = filter.trimmed();
288 
289  QString new_filter = TunerSet("filter", filter);
290 
291 #ifdef DEBUG_PID_FILTERS
292  QString msg = QString("Filter: '%1'").arg(filter);
293  if (filter != new_filter)
294  msg += QString("\n\t\t\t\t'%2'").arg(new_filter);
295 
296  LOG(VB_RECORD, LOG_DEBUG, LOC + msg);
297 #endif // DEBUG_PID_FILTERS
298 
299  m_filtersChanged = false;
300 
301  return filter == new_filter;
302 }
303 
305 {
306  if (Connect())
307  {
308  const char *model = hdhomerun_device_get_model_str(m_hdhomerunDevice);
309  m_tunerTypes.clear();
310  if (QString(model).contains("cablecard", Qt::CaseInsensitive))
311  {
312  QString status_channel = "none";
313  hdhomerun_tuner_status_t t_status {};
314 
315  if (hdhomerun_device_get_oob_status(
316  m_hdhomerunDevice, nullptr, &t_status) < 0)
317  {
318  LOG(VB_GENERAL, LOG_ERR, LOC +
319  "Failed to query Cable card OOB channel");
320  }
321  else
322  {
323  status_channel = QString(t_status.channel);
324  LOG(VB_RECORD, LOG_INFO, LOC +
325  QString("Cable card OOB channel is '%1'")
326  .arg(status_channel));
327  }
328 
329  if (status_channel == "none")
330  {
331  LOG(VB_RECORD, LOG_INFO, LOC + "Cable card is not present");
333  }
334  else
335  {
336  LOG(VB_RECORD, LOG_INFO, LOC + "Cable card is present");
338  }
339  }
340  else if (QString(model).endsWith("dvbt", Qt::CaseInsensitive))
341  {
343  }
344  else if (QString(model).endsWith("dvbc", Qt::CaseInsensitive))
345  {
347  }
348  else if (QString(model).endsWith("dvbtc", Qt::CaseInsensitive))
349  {
352  }
353  else
354  {
356  }
357 
358  return true;
359  }
360  return false;
361 }
362 
364 {
365  if (m_hdhomerunDevice)
366  {
367  TuneChannel("none");
368  hdhomerun_device_tuner_lockkey_release(m_hdhomerunDevice);
369  m_hdhomerunDevice = nullptr;
370  }
371  if (m_deviceSelector)
372  {
373  hdhomerun_device_selector_destroy(m_deviceSelector, true);
374  m_deviceSelector = nullptr;
375  }
376 }
377 
379 {
380  m_deviceSelector = hdhomerun_device_selector_create(nullptr);
381  if (!m_deviceSelector)
382  {
383  LOG(VB_GENERAL, LOG_ERR, LOC + "Unable to create device selector");
384  return false;
385  }
386 
387  QStringList devices = m_device.split(",");
388  for (const QString& device : qAsConst(devices))
389  {
390  QByteArray ba = device.toUtf8();
391  int n = hdhomerun_device_selector_load_from_str(
392  m_deviceSelector, ba.data());
393  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Added %1 devices from %3")
394  .arg(n).arg(device));
395  }
396 
397  m_hdhomerunDevice = hdhomerun_device_selector_choose_and_lock(
398  m_deviceSelector, nullptr);
399  if (!m_hdhomerunDevice)
400  {
401  LOG(VB_GENERAL, LOG_ERR, LOC +
402  QString("Unable to find a free device"));
403  hdhomerun_device_selector_destroy(m_deviceSelector, true);
404  m_deviceSelector = nullptr;
405  return false;
406  }
407 
408  m_tuner = hdhomerun_device_get_tuner(m_hdhomerunDevice);
409 
410  LOG(VB_GENERAL, LOG_INFO, LOC +
411  QString("Connected to device(%1)")
412  .arg(hdhomerun_device_get_name(m_hdhomerunDevice)));
413 
414  return true;
415 }
416 
418  const QString &name, bool report_error_return, bool print_error) const
419 {
420  QMutexLocker locker(&m_hdhrLock);
421 
422  if (!m_hdhomerunDevice)
423  {
424  LOG(VB_GENERAL, LOG_ERR, LOC + "Get request failed (not connected)");
425  return QString();
426  }
427 
428  QString valname = QString("/tuner%1/%2").arg(m_tuner).arg(name);
429  char *value = nullptr;
430  char *error = nullptr;
431  if (hdhomerun_device_get_var(
432  m_hdhomerunDevice, valname.toLocal8Bit().constData(),
433  &value, &error) < 0)
434  {
435  LOG(VB_GENERAL, LOG_ERR, LOC +
436  QString("Get %1 request failed").arg(valname) + ENO);
437  return QString();
438  }
439 
440  if (report_error_return && error)
441  {
442  if (print_error)
443  {
444  LOG(VB_GENERAL, LOG_ERR, LOC + QString("DeviceGet(%1): %2")
445  .arg(name, error));
446  }
447 
448  return QString();
449  }
450 
451  return QString(value);
452 }
453 
455  const QString &name, const QString &val,
456  bool report_error_return, bool print_error)
457 {
458  QMutexLocker locker(&m_hdhrLock);
459 
460  if (!m_hdhomerunDevice)
461  {
462  LOG(VB_GENERAL, LOG_ERR, LOC + "Set request failed (not connected)");
463  return QString();
464  }
465 
466 
467  QString valname = QString("/tuner%1/%2").arg(m_tuner).arg(name);
468  char *value = nullptr;
469  char *error = nullptr;
470 
471 #if 0
472  LOG(VB_CHANSCAN, LOG_DEBUG, LOC + valname + " " + val);
473 #endif
474  if (hdhomerun_device_set_var(
475  m_hdhomerunDevice, valname.toLocal8Bit().constData(),
476  val.toLocal8Bit().constData(), &value, &error) < 0)
477  {
478  LOG(VB_GENERAL, LOG_ERR, LOC +
479  QString("Set %1 to '%2' request failed").arg(valname, val) +
480  ENO);
481 
482  return QString();
483  }
484 
485  if (report_error_return && error)
486  {
487  if (print_error)
488  {
489  // Skip error messages from MPTS recordings
490  if (!(val.contains("0x2000") && strstr(error, "ERROR: invalid pid filter")))
491  {
492  LOG(VB_GENERAL, LOG_ERR, LOC + QString("DeviceSet(%1 %2): %3")
493  .arg(name, val, error));
494  }
495  }
496 
497  return QString();
498  }
499 
500  return QString(value);
501 }
502 
503 void HDHRStreamHandler::GetTunerStatus(struct hdhomerun_tuner_status_t *status)
504 {
505  QMutexLocker locker(&m_hdhrLock);
506 
507  hdhomerun_device_get_tuner_status(m_hdhomerunDevice, nullptr, status);
508 }
509 
511 {
512  return (m_hdhomerunDevice != nullptr);
513 }
514 
515 bool HDHRStreamHandler::TuneChannel(const QString &chanid)
516 {
518 
519  QString current = TunerGet("channel");
520  if (current == chanid)
521  {
522  LOG(VB_RECORD, LOG_INFO, LOC + QString("Not Re-Tuning channel %1")
523  .arg(chanid));
524  return true;
525  }
526 
527  LOG(VB_RECORD, LOG_INFO, LOC + QString("Tuning channel %1 (was %2)")
528  .arg(chanid, current));
529  return !TunerSet("channel", chanid).isEmpty();
530 }
531 
533 {
536 
538  {
539  LOG(VB_GENERAL, LOG_ERR, LOC + "TuneProgram called in wrong tune mode");
540  return false;
541  }
542 
543  LOG(VB_RECORD, LOG_INFO, LOC + QString("Tuning program %1")
544  .arg(mpeg_prog_num));
545  return !TunerSet(
546  "program", QString::number(mpeg_prog_num), false).isEmpty();
547 }
548 
549 bool HDHRStreamHandler::TuneVChannel(const QString &vchn)
550 {
552 
553  QString current = TunerGet("vchannel");
554  if (current == vchn)
555  {
556  LOG(VB_RECORD, LOG_INFO, LOC + QString("Not Re-Tuning channel %1")
557  .arg(vchn));
558  return true;
559  }
560  LOG(VB_RECORD, LOG_INFO, LOC + QString("TuneVChannel(%1) from (%2)")
561  .arg(vchn, current));
562 
563  LOG(VB_RECORD, LOG_INFO, LOC + QString("Tuning vchannel %1").arg(vchn));
564  return !TunerSet("vchannel", vchn).isEmpty();
565 }
566 
567 #ifdef NEED_HDHOMERUN_DEVICE_SELECTOR_LOAD_FROM_STR
568 
569 // Provide functions we need that are not included in some versions of
570 // libhdhomerun. These were taken
571 // from version 20180817 and modified as needed.
572 
573 struct hdhomerun_device_selector_t {
574  struct hdhomerun_device_t **hd_list;
575  size_t hd_count;
576  struct hdhomerun_debug_t *dbg;
577 };
578 
579 static int hdhomerun_device_selector_load_from_str_discover(struct hdhomerun_device_selector_t *hds, uint32_t target_ip, uint32_t device_id)
580 {
581  struct hdhomerun_discover_device_t result;
582  int discover_count = hdhomerun_discover_find_devices_custom(target_ip, HDHOMERUN_DEVICE_TYPE_TUNER, device_id, &result, 1);
583  if (discover_count != 1) {
584  return 0;
585  }
586 
587  int count = 0;
588  unsigned int tuner_index;
589  for (tuner_index = 0; tuner_index < result.tuner_count; tuner_index++) {
590  struct hdhomerun_device_t *hd = hdhomerun_device_create(result.device_id, result.ip_addr, tuner_index, hds->dbg);
591  if (!hd) {
592  continue;
593  }
594 
595  hdhomerun_device_selector_add_device(hds, hd);
596  count++;
597  }
598 
599  return count;
600 }
601 
602 static int hdhomerun_device_selector_load_from_str(struct hdhomerun_device_selector_t *hds, char *device_str)
603 {
604  /*
605  * IP address based device_str.
606  */
607  unsigned int a[4];
608  if (sscanf(device_str, "%u.%u.%u.%u", &a[0], &a[1], &a[2], &a[3]) == 4) {
609  uint32_t ip_addr = (uint32_t)((a[0] << 24) | (a[1] << 16) | (a[2] << 8) | (a[3] << 0));
610 
611  /*
612  * IP address + tuner number.
613  */
614  unsigned int tuner;
615  if (sscanf(device_str, "%u.%u.%u.%u-%u", &a[0], &a[1], &a[2], &a[3], &tuner) == 5) {
616  struct hdhomerun_device_t *hd = hdhomerun_device_create(HDHOMERUN_DEVICE_ID_WILDCARD, ip_addr, tuner, hds->dbg);
617  if (!hd) {
618  return 0;
619  }
620 
621  hdhomerun_device_selector_add_device(hds, hd);
622  return 1;
623  }
624 
625  /*
626  * IP address only - discover and add tuners.
627  */
628  return hdhomerun_device_selector_load_from_str_discover(hds, ip_addr, HDHOMERUN_DEVICE_ID_WILDCARD);
629  }
630 
631  /*
632  * Device ID based device_str.
633  */
634  char *end;
635  uint32_t device_id = (uint32_t)strtoul(device_str, &end, 16);
636  if ((end == device_str + 8) && hdhomerun_discover_validate_device_id(device_id)) {
637  /*
638  * IP address + tuner number.
639  */
640  if (*end == '-') {
641  unsigned int tuner = (unsigned int)strtoul(end + 1, NULL, 10);
642  struct hdhomerun_device_t *hd = hdhomerun_device_create(device_id, 0, tuner, hds->dbg);
643  if (!hd) {
644  return 0;
645  }
646 
647  hdhomerun_device_selector_add_device(hds, hd);
648  return 1;
649  }
650 
651  /*
652  * Device ID only - discover and add tuners.
653  */
654  return hdhomerun_device_selector_load_from_str_discover(hds, 0, device_id);
655  }
656 
657  return 0;
658 }
659 
660 #endif
ENO
#define ENO
This can be appended to the LOG args with "+".
Definition: mythlogging.h:72
HDHRStreamHandler::Close
void Close(void)
Definition: hdhrstreamhandler.cpp:363
DTVTunerType::kTunerTypeDVBC
static const int kTunerTypeDVBC
Definition: dtvconfparserhelpers.h:95
error
static void error(const char *str,...)
Definition: vbi.cpp:42
HDHRStreamHandler::run
void run(void) override
Reads HDHomeRun socket for tables & data.
Definition: hdhrstreamhandler.cpp:111
StreamHandler::RemoveAllPIDFilters
bool RemoveAllPIDFilters(void)
Definition: streamhandler.cpp:238
StreamHandler::SetRunning
void SetRunning(bool running, bool using_buffering, bool using_section_reader)
Definition: streamhandler.cpp:171
StreamHandler::WriteMPTS
void WriteMPTS(const unsigned char *buffer, uint len)
Write out a copy of the raw MPTS.
Definition: streamhandler.cpp:353
StreamHandler
Definition: streamhandler.h:57
hdhrTuneModeFrequency
@ hdhrTuneModeFrequency
Definition: hdhrstreamhandler.h:36
MThread::setObjectName
void setObjectName(const QString &name)
Definition: mthread.cpp:241
HDHRStreamHandler::m_tunerTypes
std::vector< DTVTunerType > m_tunerTypes
Definition: hdhrstreamhandler.h:95
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MThread::RunProlog
void RunProlog(void)
Sets up a thread, call this if you reimplement run().
Definition: mthread.cpp:196
HDHRStreamHandler::s_handlersRefCnt
static QMap< int, uint > s_handlersRefCnt
Definition: hdhrstreamhandler.h:108
HDHRStreamHandler::m_deviceSelector
hdhomerun_device_selector_t * m_deviceSelector
Definition: hdhrstreamhandler.h:93
HDHRStreamHandler::Connect
bool Connect(void)
Definition: hdhrstreamhandler.cpp:378
LOC
#define LOC
Definition: hdhrstreamhandler.cpp:26
streamlisteners.h
NULL
#define NULL
Definition: H2645Parser.h:67
HDHRStreamHandler::TuneVChannel
bool TuneVChannel(const QString &vchn)
Definition: hdhrstreamhandler.cpp:549
StreamHandler::m_filtersChanged
bool m_filtersChanged
Definition: streamhandler.h:140
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
hdhrTuneModeFrequencyPid
@ hdhrTuneModeFrequencyPid
Definition: hdhrstreamhandler.h:37
hdhrTuneModeVChannel
@ hdhrTuneModeVChannel
Definition: hdhrstreamhandler.h:39
StreamHandler::m_listenerLock
QRecursiveMutex m_listenerLock
Definition: streamhandler.h:152
HDHRStreamHandler::TunerGet
QString TunerGet(const QString &name, bool report_error_return=true, bool print_error=true) const
Definition: hdhrstreamhandler.cpp:417
StreamHandler::m_pidInfo
PIDInfoMap m_pidInfo
Definition: streamhandler.h:138
mythlogging.h
HDHRStreamHandler::Return
static void Return(HDHRStreamHandler *&ref, int inputid)
Definition: hdhrstreamhandler.cpp:63
StreamHandler::m_pidLock
QRecursiveMutex m_pidLock
Definition: streamhandler.h:135
StreamHandler::UpdateFiltersFromStreamData
bool UpdateFiltersFromStreamData(void)
Definition: streamhandler.cpp:288
filt_str
static QString filt_str(uint pid)
Definition: hdhrstreamhandler.cpp:224
MThread::RunEpilog
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
Definition: mthread.cpp:209
HDHRStreamHandler::m_hdhomerunDevice
hdhomerun_device_t * m_hdhomerunDevice
Definition: hdhrstreamhandler.h:92
HDHRStreamHandler::IsConnected
bool IsConnected(void) const
Definition: hdhrstreamhandler.cpp:510
uint
unsigned int uint
Definition: compat.h:144
HDHRStreamHandler::m_tuneMode
HDHRTuneMode m_tuneMode
Definition: hdhrstreamhandler.h:96
mpegstreamdata.h
HDHRStreamHandler::HDHRStreamHandler
HDHRStreamHandler(const QString &device, int inputid, int majorid)
Definition: hdhrstreamhandler.cpp:100
hdhrTuneModeFrequencyProgram
@ hdhrTuneModeFrequencyProgram
Definition: hdhrstreamhandler.h:38
HDHRStreamHandler
Definition: hdhrstreamhandler.h:48
HDHRStreamHandler::m_tuner
int m_tuner
Definition: hdhrstreamhandler.h:94
VERBOSE_LEVEL_CHECK
#define VERBOSE_LEVEL_CHECK(_MASK_, _LEVEL_)
Definition: mythlogging.h:14
HDHRStreamHandler::Open
bool Open(void)
Definition: hdhrstreamhandler.cpp:304
HDHRStreamHandler::TuneChannel
bool TuneChannel(const QString &chanid)
Definition: hdhrstreamhandler.cpp:515
cardutil.h
StreamHandler::m_runningDesired
volatile bool m_runningDesired
Definition: streamhandler.h:120
HDHRStreamHandler::m_hdhrLock
QRecursiveMutex m_hdhrLock
Definition: hdhrstreamhandler.h:102
HDHRStreamHandler::m_majorId
int m_majorId
Definition: hdhrstreamhandler.h:97
HDHRStreamHandler::GetTunerStatus
void GetTunerStatus(struct hdhomerun_tuner_status_t *status)
Definition: hdhrstreamhandler.cpp:503
HDHRStreamHandler::UpdateFilters
bool UpdateFilters(void) override
Definition: hdhrstreamhandler.cpp:235
DTVTunerType::kTunerTypeOCUR
static const int kTunerTypeOCUR
Definition: dtvconfparserhelpers.h:101
StreamHandler::m_streamDataList
StreamDataList m_streamDataList
Definition: streamhandler.h:154
StreamHandler::m_bError
volatile bool m_bError
Definition: streamhandler.h:125
DTVTunerType::kTunerTypeATSC
static const int kTunerTypeATSC
Definition: dtvconfparserhelpers.h:98
HDHRStreamHandler::TuneProgram
bool TuneProgram(uint mpeg_prog_num)
Definition: hdhrstreamhandler.cpp:532
HDHRStreamHandler::TunerSet
QString TunerSet(const QString &name, const QString &value, bool report_error_return=true, bool print_error=true)
Definition: hdhrstreamhandler.cpp:454
HDHRStreamHandler::Get
static HDHRStreamHandler * Get(const QString &devname, int inputid, int majorid)
Definition: hdhrstreamhandler.cpp:32
hdhrstreamhandler.h
DTVTunerType::kTunerTypeDVBT
static const int kTunerTypeDVBT
Definition: dtvconfparserhelpers.h:96
HDHRStreamHandler::s_handlersLock
static QMutex s_handlersLock
Definition: hdhrstreamhandler.h:106
hdhrchannel.h
StreamHandler::m_device
QString m_device
Definition: streamhandler.h:112
dtvsignalmonitor.h
HDHRStreamHandler::s_handlers
static QMap< int, HDHRStreamHandler * > s_handlers
Definition: hdhrstreamhandler.h:107