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