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