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  QString filter = "";
253 
254  std::vector<uint> range_min;
255  std::vector<uint> range_max;
256 
257  for (auto it = m_pidInfo.cbegin(); it != m_pidInfo.cend(); ++it)
258  {
259  range_min.push_back(it.key());
260  PIDInfoMap::const_iterator eit = it;
261  for (++eit;
262  (eit != m_pidInfo.cend()) && (it.key() + 1 == eit.key());
263  ++it, ++eit);
264  range_max.push_back(it.key());
265  }
266  if (range_min.size() > 16)
267  {
268  range_min.resize(16);
269  uint pid_max = range_max.back();
270  range_max.resize(15);
271  range_max.push_back(pid_max);
272  }
273 
274  for (size_t i = 0; i < range_min.size(); i++)
275  {
276  filter += filt_str(range_min[i]);
277  if (range_min[i] != range_max[i])
278  filter += QString("-%1").arg(filt_str(range_max[i]));
279  filter += " ";
280  }
281 
282  filter = filter.trimmed();
283 
284  QString new_filter = TunerSet("filter", filter);
285 
286 #ifdef DEBUG_PID_FILTERS
287  QString msg = QString("Filter: '%1'").arg(filter);
288  if (filter != new_filter)
289  msg += QString("\n\t\t\t\t'%2'").arg(new_filter);
290 
291  LOG(VB_RECORD, LOG_DEBUG, LOC + msg);
292 #endif // DEBUG_PID_FILTERS
293 
294  return filter == new_filter;
295 }
296 
298 {
299  if (Connect())
300  {
301  const char *model = hdhomerun_device_get_model_str(m_hdhomerunDevice);
302  m_tunerTypes.clear();
303  if (QString(model).contains("cablecard", Qt::CaseInsensitive))
304  {
305  QString status_channel = "none";
306  hdhomerun_tuner_status_t t_status {};
307 
308  if (hdhomerun_device_get_oob_status(
309  m_hdhomerunDevice, nullptr, &t_status) < 0)
310  {
311  LOG(VB_GENERAL, LOG_ERR, LOC +
312  "Failed to query Cable card OOB channel");
313  }
314  else
315  {
316  status_channel = QString(t_status.channel);
317  LOG(VB_RECORD, LOG_INFO, LOC +
318  QString("Cable card OOB channel is '%1'")
319  .arg(status_channel));
320  }
321 
322  if (status_channel == "none")
323  {
324  LOG(VB_RECORD, LOG_INFO, LOC + "Cable card is not present");
326  }
327  else
328  {
329  LOG(VB_RECORD, LOG_INFO, LOC + "Cable card is present");
331  }
332  }
333  else if (QString(model).endsWith("dvbt", Qt::CaseInsensitive))
334  {
336  }
337  else if (QString(model).endsWith("dvbc", Qt::CaseInsensitive))
338  {
340  }
341  else if (QString(model).endsWith("dvbtc", Qt::CaseInsensitive))
342  {
345  }
346  else
347  {
349  }
350 
351  return true;
352  }
353  return false;
354 }
355 
357 {
358  if (m_hdhomerunDevice)
359  {
360  TuneChannel("none");
361  hdhomerun_device_tuner_lockkey_release(m_hdhomerunDevice);
362  m_hdhomerunDevice = nullptr;
363  }
364  if (m_deviceSelector)
365  {
366  hdhomerun_device_selector_destroy(m_deviceSelector, true);
367  m_deviceSelector = nullptr;
368  }
369 }
370 
372 {
373  m_deviceSelector = hdhomerun_device_selector_create(nullptr);
374  if (!m_deviceSelector)
375  {
376  LOG(VB_GENERAL, LOG_ERR, LOC + "Unable to create device selector");
377  return false;
378  }
379 
380  QStringList devices = m_device.split(",");
381  for (int i = 0; i < devices.size(); ++i)
382  {
383  QByteArray ba = devices[i].toUtf8();
384  int n = hdhomerun_device_selector_load_from_str(
385  m_deviceSelector, ba.data());
386  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Added %1 devices from %3")
387  .arg(n).arg(devices[i]));
388  }
389 
390  m_hdhomerunDevice = hdhomerun_device_selector_choose_and_lock(
391  m_deviceSelector, nullptr);
392  if (!m_hdhomerunDevice)
393  {
394  LOG(VB_GENERAL, LOG_ERR, LOC +
395  QString("Unable to find a free device"));
396  hdhomerun_device_selector_destroy(m_deviceSelector, true);
397  m_deviceSelector = nullptr;
398  return false;
399  }
400 
401  m_tuner = hdhomerun_device_get_tuner(m_hdhomerunDevice);
402 
403  LOG(VB_GENERAL, LOG_INFO, LOC +
404  QString("Connected to device(%1)")
405  .arg(hdhomerun_device_get_name(m_hdhomerunDevice)));
406 
407  return true;
408 }
409 
411  const QString &name, bool report_error_return, bool print_error) const
412 {
413  QMutexLocker locker(&m_hdhrLock);
414 
415  if (!m_hdhomerunDevice)
416  {
417  LOG(VB_GENERAL, LOG_ERR, LOC + "Get request failed (not connected)");
418  return QString();
419  }
420 
421  QString valname = QString("/tuner%1/%2").arg(m_tuner).arg(name);
422  char *value = nullptr;
423  char *error = nullptr;
424  if (hdhomerun_device_get_var(
425  m_hdhomerunDevice, valname.toLocal8Bit().constData(),
426  &value, &error) < 0)
427  {
428  LOG(VB_GENERAL, LOG_ERR, LOC +
429  QString("Get %1 request failed").arg(valname) + ENO);
430  return QString();
431  }
432 
433  if (report_error_return && error)
434  {
435  if (print_error)
436  {
437  LOG(VB_GENERAL, LOG_ERR, LOC + QString("DeviceGet(%1): %2")
438  .arg(name).arg(error));
439  }
440 
441  return QString();
442  }
443 
444  return QString(value);
445 }
446 
448  const QString &name, const QString &val,
449  bool report_error_return, bool print_error)
450 {
451  QMutexLocker locker(&m_hdhrLock);
452 
453  if (!m_hdhomerunDevice)
454  {
455  LOG(VB_GENERAL, LOG_ERR, LOC + "Set request failed (not connected)");
456  return QString();
457  }
458 
459 
460  QString valname = QString("/tuner%1/%2").arg(m_tuner).arg(name);
461  char *value = nullptr;
462  char *error = nullptr;
463 
464 #if 0
465  LOG(VB_CHANSCAN, LOG_DEBUG, LOC + valname + " " + val);
466 #endif
467  if (hdhomerun_device_set_var(
468  m_hdhomerunDevice, valname.toLocal8Bit().constData(),
469  val.toLocal8Bit().constData(), &value, &error) < 0)
470  {
471  LOG(VB_GENERAL, LOG_ERR, LOC +
472  QString("Set %1 to '%2' request failed").arg(valname).arg(val) +
473  ENO);
474 
475  return QString();
476  }
477 
478  if (report_error_return && error)
479  {
480  if (print_error)
481  {
482  // Skip error messages from MPTS recordings
483  if (!(val.contains("0x2000") && strstr(error, "ERROR: invalid pid filter")))
484  {
485  LOG(VB_GENERAL, LOG_ERR, LOC + QString("DeviceSet(%1 %2): %3")
486  .arg(name).arg(val).arg(error));
487  }
488  }
489 
490  return QString();
491  }
492 
493  return QString(value);
494 }
495 
496 void HDHRStreamHandler::GetTunerStatus(struct hdhomerun_tuner_status_t *status)
497 {
498  QMutexLocker locker(&m_hdhrLock);
499 
500  hdhomerun_device_get_tuner_status(m_hdhomerunDevice, nullptr, status);
501 }
502 
504 {
505  return (m_hdhomerunDevice != nullptr);
506 }
507 
508 bool HDHRStreamHandler::TuneChannel(const QString &chanid)
509 {
511 
512  QString current = TunerGet("channel");
513  if (current == chanid)
514  {
515  LOG(VB_RECORD, LOG_INFO, LOC + QString("Not Re-Tuning channel %1")
516  .arg(chanid));
517  return true;
518  }
519 
520  LOG(VB_RECORD, LOG_INFO, LOC + QString("Tuning channel %1 (was %2)")
521  .arg(chanid).arg(current));
522  return !TunerSet("channel", chanid).isEmpty();
523 }
524 
526 {
529 
531  {
532  LOG(VB_GENERAL, LOG_ERR, LOC + "TuneProgram called in wrong tune mode");
533  return false;
534  }
535 
536  LOG(VB_RECORD, LOG_INFO, LOC + QString("Tuning program %1")
537  .arg(mpeg_prog_num));
538  return !TunerSet(
539  "program", QString::number(mpeg_prog_num), false).isEmpty();
540 }
541 
542 bool HDHRStreamHandler::TuneVChannel(const QString &vchn)
543 {
545 
546  QString current = TunerGet("vchannel");
547  if (current == vchn)
548  {
549  LOG(VB_RECORD, LOG_INFO, LOC + QString("Not Re-Tuning channel %1")
550  .arg(vchn));
551  return true;
552  }
553  LOG(VB_RECORD, LOG_INFO, LOC + QString("TuneVChannel(%1) from (%2)")
554  .arg(vchn).arg(current));
555 
556  LOG(VB_RECORD, LOG_INFO, LOC + QString("Tuning vchannel %1").arg(vchn));
557  return !TunerSet("vchannel", vchn).isEmpty();
558 }
559 
560 #ifdef NEED_HDHOMERUN_DEVICE_SELECTOR_LOAD_FROM_STR
561 
562 // Provide functions we need that are not included in some versions of
563 // libhdhomerun. These were taken
564 // from version 20180817 and modified as needed.
565 
566 struct hdhomerun_device_selector_t {
567  struct hdhomerun_device_t **hd_list;
568  size_t hd_count;
569  struct hdhomerun_debug_t *dbg;
570 };
571 
572 static int hdhomerun_device_selector_load_from_str_discover(struct hdhomerun_device_selector_t *hds, uint32_t target_ip, uint32_t device_id)
573 {
574  struct hdhomerun_discover_device_t result;
575  int discover_count = hdhomerun_discover_find_devices_custom(target_ip, HDHOMERUN_DEVICE_TYPE_TUNER, device_id, &result, 1);
576  if (discover_count != 1) {
577  return 0;
578  }
579 
580  int count = 0;
581  unsigned int tuner_index;
582  for (tuner_index = 0; tuner_index < result.tuner_count; tuner_index++) {
583  struct hdhomerun_device_t *hd = hdhomerun_device_create(result.device_id, result.ip_addr, tuner_index, hds->dbg);
584  if (!hd) {
585  continue;
586  }
587 
588  hdhomerun_device_selector_add_device(hds, hd);
589  count++;
590  }
591 
592  return count;
593 }
594 
595 static int hdhomerun_device_selector_load_from_str(struct hdhomerun_device_selector_t *hds, char *device_str)
596 {
597  /*
598  * IP address based device_str.
599  */
600  unsigned int a[4];
601  if (sscanf(device_str, "%u.%u.%u.%u", &a[0], &a[1], &a[2], &a[3]) == 4) {
602  uint32_t ip_addr = (uint32_t)((a[0] << 24) | (a[1] << 16) | (a[2] << 8) | (a[3] << 0));
603 
604  /*
605  * IP address + tuner number.
606  */
607  unsigned int tuner;
608  if (sscanf(device_str, "%u.%u.%u.%u-%u", &a[0], &a[1], &a[2], &a[3], &tuner) == 5) {
609  struct hdhomerun_device_t *hd = hdhomerun_device_create(HDHOMERUN_DEVICE_ID_WILDCARD, ip_addr, tuner, hds->dbg);
610  if (!hd) {
611  return 0;
612  }
613 
614  hdhomerun_device_selector_add_device(hds, hd);
615  return 1;
616  }
617 
618  /*
619  * IP address only - discover and add tuners.
620  */
621  return hdhomerun_device_selector_load_from_str_discover(hds, ip_addr, HDHOMERUN_DEVICE_ID_WILDCARD);
622  }
623 
624  /*
625  * Device ID based device_str.
626  */
627  char *end;
628  uint32_t device_id = (uint32_t)strtoul(device_str, &end, 16);
629  if ((end == device_str + 8) && hdhomerun_discover_validate_device_id(device_id)) {
630  /*
631  * IP address + tuner number.
632  */
633  if (*end == '-') {
634  unsigned int tuner = (unsigned int)strtoul(end + 1, NULL, 10);
635  struct hdhomerun_device_t *hd = hdhomerun_device_create(device_id, 0, tuner, hds->dbg);
636  if (!hd) {
637  return 0;
638  }
639 
640  hdhomerun_device_selector_add_device(hds, hd);
641  return 1;
642  }
643 
644  /*
645  * Device ID only - discover and add tuners.
646  */
647  return hdhomerun_device_selector_load_from_str_discover(hds, 0, device_id);
648  }
649 
650  return 0;
651 }
652 
653 #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:356
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: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:371
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:542
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:151
HDHRStreamHandler::TunerGet
QString TunerGet(const QString &name, bool report_error_return=true, bool print_error=true) const
Definition: hdhrstreamhandler.cpp:410
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:284
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:503
uint
unsigned int uint
Definition: compat.h:140
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:297
HDHRStreamHandler::TuneChannel
bool TuneChannel(const QString &chanid)
Definition: hdhrstreamhandler.cpp:508
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:496
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:153
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:525
HDHRStreamHandler::TunerSet
QString TunerSet(const QString &name, const QString &value, bool report_error_return=true, bool print_error=true)
Definition: hdhrstreamhandler.cpp:447
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