MythTV  master
dvbstreamhandler.cpp
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 
3 // POSIX headers
4 #include <fcntl.h>
5 #include <sys/select.h>
6 #include <sys/ioctl.h>
7 #include <chrono> // for milliseconds
8 #include <thread> // for sleep_for
9 
10 // Qt headers
11 #include <QString>
12 
13 // MythTV headers
14 #include "dvbstreamhandler.h"
15 #include "dvbchannel.h"
16 #include "dtvsignalmonitor.h"
17 #include "streamlisteners.h"
18 #include "mpegstreamdata.h"
19 #include "cardutil.h"
20 #include "dvbtypes.h" // for pid filtering
21 #include "diseqc.h" // for rotor retune
22 #include "mythlogging.h"
23 
24 #define LOC QString("DVBSH[%1](%2): ").arg(m_inputId).arg(m_device)
25 
28 
29 QMap<QString,DVBStreamHandler*> DVBStreamHandler::s_handlers;
30 QMap<QString,uint> DVBStreamHandler::s_handlersRefCnt;
32 
33 DVBStreamHandler *DVBStreamHandler::Get(const QString &devname,
34  int inputid)
35 {
36  QMutexLocker locker(&s_handlersLock);
37 
38  QMap<QString,DVBStreamHandler*>::iterator it =
39  s_handlers.find(devname);
40 
41  if (it == s_handlers.end())
42  {
43  s_handlers[devname] = new DVBStreamHandler(devname, inputid);
44  s_handlersRefCnt[devname] = 1;
45 
46  LOG(VB_RECORD, LOG_INFO,
47  QString("DVBSH[%1]: Creating new stream handler %2")
48  .arg(inputid).arg(devname));
49  }
50  else
51  {
52  s_handlersRefCnt[devname]++;
53  uint rcount = s_handlersRefCnt[devname];
54  LOG(VB_RECORD, LOG_INFO,
55  QString("DVBSH[%1]: Using existing stream handler for %2")
56  .arg(inputid)
57  .arg(devname) + QString(" (%1 in use)").arg(rcount));
58  }
59 
60  return s_handlers[devname];
61 }
62 
63 void DVBStreamHandler::Return(DVBStreamHandler * & ref, int inputid)
64 {
65  QMutexLocker locker(&s_handlersLock);
66 
67  QString devname = ref->m_device;
68 
69  QMap<QString,uint>::iterator rit = s_handlersRefCnt.find(devname);
70  if (rit == s_handlersRefCnt.end())
71  return;
72 
73  QMap<QString,DVBStreamHandler*>::iterator it = s_handlers.find(devname);
74 
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("DVBSH[%1]: Closing handler for %2")
85  .arg(inputid).arg(devname));
86  delete *it;
87  s_handlers.erase(it);
88  }
89  else
90  {
91  LOG(VB_GENERAL, LOG_ERR,
92  QString("DVBSH[%1] Error: Couldn't find handler for %2")
93  .arg(inputid).arg(devname));
94  }
95 
96  s_handlersRefCnt.erase(rit);
97  ref = nullptr;
98 }
99 
100 DVBStreamHandler::DVBStreamHandler(const QString &dvb_device, int inputid)
101  : StreamHandler(dvb_device, inputid)
102  , m_dvrDevPath(CardUtil::GetDeviceName(DVB_DEV_DVR, m_device))
103  , m_allowRetune(false)
104  , m_sigMon(nullptr)
105  , m_dvbChannel(nullptr)
106  , m_drb(nullptr)
107 {
108  setObjectName("DVBRead");
109 }
110 
112 {
113  RunProlog();
114  LOG(VB_RECORD, LOG_DEBUG, LOC + "run(): begin");
115 
117  RunSR();
118  else
119  RunTS();
120 
121  LOG(VB_RECORD, LOG_DEBUG, LOC + "run(): end");
122  RunEpilog();
123 }
124 
136 {
137  QByteArray dvr_dev_path = m_dvrDevPath.toLatin1();
138  int dvr_fd = 0;
139  for (int tries = 1; ; ++tries)
140  {
141  dvr_fd = open(dvr_dev_path.constData(), O_RDONLY | O_NONBLOCK);
142  if (dvr_fd >= 0)
143  break;
144 
145  LOG(VB_GENERAL, LOG_WARNING, LOC +
146  QString("Opening DVR device %1 failed : %2")
147  .arg(m_dvrDevPath).arg(strerror(errno)));
148 
149  if (tries >= 20 || (errno != EBUSY && errno != EAGAIN))
150  {
151  LOG(VB_GENERAL, LOG_ERR, LOC +
152  QString("Failed to open DVR device %1 : %2")
153  .arg(m_dvrDevPath).arg(strerror(errno)));
154  m_bError = true;
155  return;
156  }
157  std::this_thread::sleep_for(std::chrono::milliseconds(50));
158  }
159 
160  int remainder = 0;
161  int buffer_size = TSPacket::kSize * 15000;
162  auto *buffer = new unsigned char[buffer_size];
163  if (!buffer)
164  {
165  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to allocate memory");
166  close(dvr_fd);
167  m_bError = true;
168  return;
169  }
170  memset(buffer, 0, buffer_size);
171 
172  DeviceReadBuffer *drb = nullptr;
173  if (m_needsBuffering)
174  {
175  drb = new DeviceReadBuffer(this, true, false);
176  if (!drb->Setup(m_device, dvr_fd))
177  {
178  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to allocate DRB buffer");
179  delete drb;
180  delete[] buffer;
181  close(dvr_fd);
182  m_bError = true;
183  return;
184  }
185 
186  drb->Start();
187  }
188 
189  {
190  // SetRunning() + set m_drb
191  QMutexLocker locker(&m_startStopLock);
192  m_running = true;
194  m_usingSectionReader = false;
195  m_drb = drb;
196  }
197 
198  LOG(VB_RECORD, LOG_DEBUG, LOC + "RunTS(): begin");
199 
200  fd_set fd_select_set;
201  FD_ZERO( &fd_select_set); // NOLINT(readability-isolate-declaration)
202  FD_SET (dvr_fd, &fd_select_set);
203  while (m_runningDesired && !m_bError)
204  {
205  RetuneMonitor();
207 
208  ssize_t len = 0;
209 
210  if (drb)
211  {
212  len = drb->Read(&(buffer[remainder]), buffer_size - remainder);
213 
214  // Check for DRB errors
215  if (drb->IsErrored())
216  {
217  LOG(VB_GENERAL, LOG_ERR, LOC + "Device error detected");
218  m_bError = true;
219  }
220 
221  if (drb->IsEOF() && m_runningDesired)
222  {
223  LOG(VB_GENERAL, LOG_ERR, LOC + "Device EOF detected");
224  m_bError = true;
225  }
226  }
227  else
228  {
229  // timeout gets reset by select, so we need to create new one
230  struct timeval timeout = { 0, 50 /* ms */ * 1000 /* -> usec */ };
231  int ret = select(dvr_fd+1, &fd_select_set, nullptr, nullptr, &timeout);
232  if (ret == -1 && errno != EINTR)
233  {
234  LOG(VB_GENERAL, LOG_ERR, LOC + "select() failed" + ENO);
235  }
236  else
237  {
238  len = read(dvr_fd, &(buffer[remainder]),
239  buffer_size - remainder);
240  }
241 
242  if ((0 == len) || (-1 == len))
243  {
244  std::this_thread::sleep_for(std::chrono::microseconds(100));
245  continue;
246  }
247  }
248 
249  len += remainder;
250 
251  if (len < 10) // 10 bytes = 4 bytes TS header + 6 bytes PES header
252  {
253  remainder = len;
254  continue;
255  }
256 
257  m_listenerLock.lock();
258 
259  if (m_streamDataList.empty())
260  {
261  m_listenerLock.unlock();
262  continue;
263  }
264 
265  for (auto sit = m_streamDataList.cbegin(); sit != m_streamDataList.cend(); ++sit)
266  remainder = sit.key()->ProcessData(buffer, len);
267 
268  WriteMPTS(buffer, len - remainder);
269 
270  m_listenerLock.unlock();
271 
272  if (remainder > 0 && (len > remainder)) // leftover bytes
273  memmove(buffer, &(buffer[len - remainder]), remainder);
274  }
275  LOG(VB_RECORD, LOG_DEBUG, LOC + "RunTS(): " + "shutdown");
276 
278 
279  {
280  QMutexLocker locker(&m_startStopLock);
281  m_drb = nullptr;
282  }
283 
284  delete drb;
285  close(dvr_fd);
286  delete[] buffer;
287 
288  LOG(VB_RECORD, LOG_DEBUG, LOC + "RunTS(): " + "end");
289 
290  SetRunning(false, m_needsBuffering, false);
291 }
292 
300 {
301  int buffer_size = 4192; // maximum size of Section we handle
302  unsigned char *buffer = pes_alloc(buffer_size);
303  if (!buffer)
304  {
305  m_bError = true;
306  return;
307  }
308 
309  SetRunning(true, m_needsBuffering, true);
310 
311  LOG(VB_RECORD, LOG_DEBUG, LOC + "RunSR(): begin");
312 
313  while (m_runningDesired && !m_bError)
314  {
315  RetuneMonitor();
317 
318  QMutexLocker read_locker(&m_pidLock);
319 
320  bool readSomething = false;
321  for (auto fit = m_pidInfo.cbegin(); fit != m_pidInfo.cend(); ++fit)
322  {
323  int len = read((*fit)->m_filterFd, buffer, buffer_size);
324  if (len <= 0)
325  continue;
326 
327  readSomething = true;
328 
329  const PSIPTable psip(buffer);
330 
331  if (psip.SectionSyntaxIndicator())
332  {
333  m_listenerLock.lock();
334  for (auto sit = m_streamDataList.cbegin(); sit != m_streamDataList.cend(); ++sit)
335  sit.key()->HandleTables(fit.key() /* pid */, psip);
336  m_listenerLock.unlock();
337  }
338  }
339 
340  if (!readSomething)
341  std::this_thread::sleep_for(std::chrono::milliseconds(3));
342  }
343  LOG(VB_RECORD, LOG_DEBUG, LOC + "RunSR(): " + "shutdown");
344 
346 
347  pes_free(buffer);
348 
349  SetRunning(false, m_needsBuffering, true);
350 
351  LOG(VB_RECORD, LOG_DEBUG, LOC + "RunSR(): " + "end");
352 }
353 
354 using pid_list_t = std::vector<uint>;
355 
356 static pid_list_t::iterator find(
357  const PIDInfoMap &map,
358  pid_list_t &list,
359  pid_list_t::iterator begin,
360  pid_list_t::iterator end, bool find_open)
361 {
362  pid_list_t::iterator it;
363  for (it = begin; it != end; ++it)
364  {
365  PIDInfoMap::const_iterator mit = map.find(*it);
366  if ((mit != map.end()) && ((*mit)->IsOpen() == find_open))
367  return it;
368  }
369 
370  for (it = list.begin(); it != begin; ++it)
371  {
372  PIDInfoMap::const_iterator mit = map.find(*it);
373  if ((mit != map.end()) && ((*mit)->IsOpen() == find_open))
374  return it;
375  }
376 
377  return list.end();
378 }
379 
381 {
382  QMutexLocker writing_locker(&m_pidLock);
383  QMap<PIDPriority, pid_list_t> priority_queue;
384  QMap<PIDPriority, uint> priority_open_cnt;
385 
386  for (auto cit = m_pidInfo.cbegin(); cit != m_pidInfo.cend(); ++cit)
387  {
388  PIDPriority priority = GetPIDPriority((*cit)->m_pid);
389  priority_queue[priority].push_back(cit.key());
390  if ((*cit)->IsOpen())
391  priority_open_cnt[priority]++;
392  }
393 
394  for (auto & it : priority_queue)
395  std::sort(it.begin(), it.end());
396 
398  i = (PIDPriority)((int)i-1))
399  {
400  while (priority_open_cnt[i] < priority_queue[i].size())
401  {
402  // if we can open a filter, just do it
403 
404  // find first closed filter after first open an filter "k"
405  auto open = find(m_pidInfo, priority_queue[i],
406  priority_queue[i].begin(), priority_queue[i].end(), true);
407  if (open == priority_queue[i].end())
408  open = priority_queue[i].begin();
409 
410  auto closed = find(m_pidInfo, priority_queue[i],
411  open, priority_queue[i].end(), false);
412 
413  if (closed == priority_queue[i].end())
414  break; // something is broken
415 
416  if (m_pidInfo[*closed]->Open(m_device, m_usingSectionReader))
417  {
419  priority_open_cnt[i]++;
420  continue;
421  }
422 
423  // if we can't open a filter, try to close a lower priority one
424  bool freed = false;
425  for (auto j = (PIDPriority)((int)i - 1);
426  (j > kPIDPriorityNone) && !freed;
427  j = (PIDPriority)((int)j-1))
428  {
429  if (!priority_open_cnt[j])
430  continue;
431 
432  for (uint k = 0; (k < priority_queue[j].size()) && !freed; k++)
433  {
434  PIDInfo *info = m_pidInfo[priority_queue[j][k]];
435  if (!info->IsOpen())
436  continue;
437 
438  if (info->Close(m_device))
439  freed = true;
440 
442  priority_open_cnt[j]--;
443  }
444  }
445 
446  if (freed)
447  {
448  // if we can open a filter, just do it
449  if (m_pidInfo[*closed]->Open(
451  {
453  priority_open_cnt[i]++;
454  continue;
455  }
456  }
457 
458  // we have to cycle within our priority level
459 
460  if (m_cycleTimer.elapsed() < 1000)
461  break; // we don't want to cycle too often
462 
463  if (!m_pidInfo[*open]->IsOpen())
464  break; // nothing to close..
465 
466  // close "open"
467  bool ok = m_pidInfo[*open]->Close(m_device);
469  priority_open_cnt[i]--;
470 
471  // open "closed"
472  if (ok && m_pidInfo[*closed]->
474  {
476  priority_open_cnt[i]++;
477  }
478 
479  break; // we only want to cycle once per priority per run
480  }
481  }
482 
484 }
485 
487  bool allow,
488  DTVSignalMonitor *sigmon,
489  DVBChannel *dvbchan)
490 {
491  if (allow && sigmon && dvbchan)
492  {
493  m_allowRetune = true;
494  m_sigMon = sigmon;
495  m_dvbChannel = dvbchan;
496  }
497  else
498  {
499  m_allowRetune = false;
500  m_sigMon = nullptr;
501  m_dvbChannel = nullptr;
502  }
503 }
504 
506 {
507  if (!m_allowRetune)
508  return;
509 
510  // Rotor position
512  {
513  const DiSEqCDevRotor *rotor = m_dvbChannel->GetRotor();
514  if (rotor)
515  {
516  bool was_moving = false;
517  bool is_moving = false;
518  m_sigMon->GetRotorStatus(was_moving, is_moving);
519 
520  // Retune if move completes normally
521  if (was_moving && !is_moving)
522  {
523  LOG(VB_CHANNEL, LOG_INFO,
524  LOC + "Retuning for rotor completion");
525  m_dvbChannel->Retune();
526 
527  // (optionally) No need to wait for SDT anymore...
528  // RemoveFlags(kDTVSigMon_WaitForSDT);
529  }
530  }
531  else
532  {
533  // If no rotor is present, pretend the movement is completed
534  m_sigMon->SetRotorValue(100);
535  }
536  }
537 }
538 
548 {
549  const uint pat_pid = 0x0;
550 
551  {
552  QMutexLocker locker(&s_rec_supportsTsMonitoringLock);
553  QMap<QString,bool>::const_iterator it;
554  it = s_recSupportsTsMonitoring.constFind(m_device);
555  if (it != s_recSupportsTsMonitoring.constEnd())
556  return *it;
557  }
558 
559  QByteArray dvr_dev_path = m_dvrDevPath.toLatin1();
560  int dvr_fd = open(dvr_dev_path.constData(), O_RDONLY | O_NONBLOCK);
561  if (dvr_fd < 0)
562  {
563  QMutexLocker locker(&s_rec_supportsTsMonitoringLock);
565  return false;
566  }
567 
568  bool supports_ts = false;
569  if (AddPIDFilter(new DVBPIDInfo(pat_pid)))
570  {
571  supports_ts = true;
572  RemovePIDFilter(pat_pid);
573  }
574 
575  close(dvr_fd);
576 
577  QMutexLocker locker(&s_rec_supportsTsMonitoringLock);
578  s_recSupportsTsMonitoring[m_device] = supports_ts;
579 
580  return supports_ts;
581 }
582 
583 #undef LOC
584 
585 #define LOC QString("PIDInfo(%1): ").arg(dvb_dev)
586 
587 bool DVBPIDInfo::Open(const QString &dvb_dev, bool use_section_reader)
588 {
589  if (m_filterFd >= 0)
590  {
591  close(m_filterFd);
592  m_filterFd = -1;
593  }
594 
595  QString demux_fn = CardUtil::GetDeviceName(DVB_DEV_DEMUX, dvb_dev);
596  QByteArray demux_ba = demux_fn.toLatin1();
597 
598  LOG(VB_RECORD, LOG_DEBUG, LOC + QString("Opening filter for pid 0x%1")
599  .arg(m_pid, 0, 16));
600 
601  int mux_fd = open(demux_ba.constData(), O_RDWR | O_NONBLOCK);
602  if (mux_fd == -1)
603  {
604  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to open demux device %1 "
605  "for filter on pid 0x%2")
606  .arg(demux_fn).arg(m_pid, 0, 16));
607  return false;
608  }
609 
610  if (!use_section_reader)
611  {
612  struct dmx_pes_filter_params pesFilterParams {};
613  pesFilterParams.pid = (uint16_t) m_pid;
614  pesFilterParams.input = DMX_IN_FRONTEND;
615  pesFilterParams.output = DMX_OUT_TS_TAP;
616  pesFilterParams.flags = DMX_IMMEDIATE_START;
617  pesFilterParams.pes_type = DMX_PES_OTHER;
618 
619  if (ioctl(mux_fd, DMX_SET_PES_FILTER, &pesFilterParams) < 0)
620  {
621  LOG(VB_GENERAL, LOG_ERR, LOC +
622  QString("Failed to set TS filter (pid 0x%1)")
623  .arg(m_pid, 0, 16));
624 
625  close(mux_fd);
626  return false;
627  }
628  }
629  else
630  {
631  struct dmx_sct_filter_params sctFilterParams {};
632  switch ( m_pid )
633  {
634  case 0x0: // PAT
635  sctFilterParams.filter.filter[0] = 0;
636  sctFilterParams.filter.mask[0] = 0xff;
637  break;
638  case 0x0010: // assume this is for an NIT, NITo, PMT
639  // This filter will give us table ids 0x00-0x03, 0x40-0x43
640  // we expect to see table ids 0x02, 0x40 and 0x41 on this PID
641  // NOTE: In theory, this will break with ATSC when PID 0x10
642  // is used for ATSC/MPEG tables. This is frowned upon,
643  // but PMTs have been seen on in the wild.
644  sctFilterParams.filter.filter[0] = 0x00;
645  sctFilterParams.filter.mask[0] = 0xbc;
646  break;
647  case 0x0011: // assume this is for an SDT, SDTo, PMT
648  // This filter will give us table ids 0x02, 0x06, 0x42 and 0x46
649  // All but 0x06 are ones we want to see.
650  // NOTE: In theory this will break with ATSC when pid 0x11
651  // is used for random ATSC tables. In practice only
652  // video data has been seen on 0x11.
653  sctFilterParams.filter.filter[0] = 0x02;
654  sctFilterParams.filter.mask[0] = 0xbb;
655  break;
656  case 0x1ffb: // assume this is for various ATSC tables
657  // MGT 0xC7, Terrestrial VCT 0xC8, Cable VCT 0xC9, RRT 0xCA,
658  // STT 0xCD, DCCT 0xD3, DCCSCT 0xD4, Caption 0x86
659  sctFilterParams.filter.filter[0] = 0x80;
660  sctFilterParams.filter.mask[0] = 0xa0;
661  break;
662  default:
663  // otherwise assume it could be any table
664  sctFilterParams.filter.filter[0] = 0x00;
665  sctFilterParams.filter.mask[0] = 0x00;
666  break;
667  }
668  sctFilterParams.pid = (uint16_t) m_pid;
669  sctFilterParams.timeout = 0;
670  sctFilterParams.flags = DMX_IMMEDIATE_START;
671 
672  if (ioctl(mux_fd, DMX_SET_FILTER, &sctFilterParams) < 0)
673  {
674  LOG(VB_GENERAL, LOG_ERR, LOC +
675  "Failed to set \"section\" filter " +
676  QString("(pid 0x%1) (filter %2)").arg(m_pid, 0, 16)
677  .arg(sctFilterParams.filter.filter[0]));
678  close(mux_fd);
679  return false;
680  }
681  }
682 
683  m_filterFd = mux_fd;
684 
685  return true;
686 }
687 
688 bool DVBPIDInfo::Close(const QString &dvb_dev)
689 {
690  LOG(VB_RECORD, LOG_DEBUG, LOC +
691  QString("Closing filter for pid 0x%1").arg(m_pid, 0, 16));
692 
693  if (!IsOpen())
694  return false;
695 
696  int tmp = m_filterFd;
697  m_filterFd = -1;
698 
699  int err = close(tmp);
700  if (err < 0)
701  {
702  LOG(VB_GENERAL, LOG_ERR,
703  LOC + QString("Failed to close mux (pid 0x%1)")
704  .arg(m_pid, 0, 16) + ENO);
705 
706  return false;
707  }
708 
709  return true;
710 }
711 
712 #if 0
713 
714 // We don't yet do kernel buffer allocation in dvbstreamhandler..
715 
716 int DVBRecorder::OpenFilterFd(uint pid, int pes_type, uint stream_type)
717 {
718  if (_open_pid_filters >= _max_pid_filters)
719  return -1;
720 
721  // bits per millisecond
722  uint bpms = (StreamID::IsVideo(stream_type)) ? 19200 : 500;
723  // msec of buffering we want
724  uint msec_of_buffering = max(POLL_WARNING_TIMEOUT + 50, 1500);
725  // actual size of buffer we need
726  uint pid_buffer_size = ((bpms*msec_of_buffering + 7) / 8);
727  // rounded up to the nearest page
728  pid_buffer_size = ((pid_buffer_size + 4095) / 4096) * 4096;
729 
730  LOG(VB_RECORD, LOG_DEBUG, LOC + QString("Adding pid 0x%1 size(%2)")
731  .arg(pid,0,16).arg(pid_buffer_size));
732 
733  // Open the demux device
734  QString dvbdev = CardUtil::GetDeviceName(
735  DVB_DEV_DEMUX, _card_number_option);
736  QByteArray dev = dvbdev.toLatin1();
737 
738  int fd_tmp = open(dev.constData(), O_RDWR);
739  if (fd_tmp < 0)
740  {
741  LOG(VB_GENERAL, LOG_ERR, LOC + "Could not open demux device." + ENO);
742  _max_pid_filters = _open_pid_filters;
743  return -1;
744  }
745 
746  // Try to make the demux buffer large enough to
747  // allow for longish disk writes.
748  uint sz = pid_buffer_size;
749  uint usecs = msec_of_buffering * 1000;
750  while (ioctl(fd_tmp, DMX_SET_BUFFER_SIZE, sz) < 0 && sz > 1024*8)
751  {
752  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to set demux buffer size for "+
753  QString("pid 0x%1 to %2").arg(pid,0,16).arg(sz) + ENO);
754 
755  sz /= 2;
756  sz = ((sz+4095)/4096)*4096;
757  usecs /= 2;
758  }
759 #if 0
760  LOG(VB_RECORD, LOG_DEBUG, LOC + "Set demux buffer size for " +
761  QString("pid 0x%1 to %2,\n\t\t\twhich gives us a %3 msec buffer.")
762  .arg(pid,0,16).arg(sz).arg(usecs/1000));
763 #endif
764 
765  // Set the filter type
766  struct dmx_pes_filter_params params;
767  memset(&params, 0, sizeof(params));
768  params.input = DMX_IN_FRONTEND;
769  params.output = DMX_OUT_TS_TAP;
770  params.flags = DMX_IMMEDIATE_START;
771  params.pid = pid;
772  params.pes_type = (dmx_pes_type_t) pes_type;
773  if (ioctl(fd_tmp, DMX_SET_PES_FILTER, &params) < 0)
774  {
775  close(fd_tmp);
776 
777  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to set demux filter." + ENO);
778  _max_pid_filters = _open_pid_filters;
779  return -1;
780  }
781 
782  _open_pid_filters++;
783  return fd_tmp;
784 }
785 #endif
DVBStreamHandler::m_sigMon
DTVSignalMonitor * m_sigMon
Definition: dvbstreamhandler.h:66
PIDInfo::Close
virtual bool Close(const QString &)
Definition: streamhandler.h:36
ENO
#define ENO
This can be appended to the LOG args with "+".
Definition: mythlogging.h:72
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:103
DeviceReadBuffer::Start
void Start(void)
Definition: DeviceReadBuffer.cpp:104
DVBStreamHandler::SetRetuneAllowed
void SetRetuneAllowed(bool allow, DTVSignalMonitor *sigmon, DVBChannel *dvbchan)
Definition: dvbstreamhandler.cpp:486
DeviceReadBuffer::Setup
bool Setup(const QString &streamName, int streamfd, uint readQuanta=sizeof(TSPacket), uint deviceBufferSize=0, uint deviceBufferCount=1)
Definition: DeviceReadBuffer.cpp:47
DVBChannel::GetRotor
const DiSEqCDevRotor * GetRotor(void) const
Returns rotor object if it exists, nullptr otherwise.
Definition: dvbchannel.cpp:996
DiSEqCDevRotor
Rotor class.
Definition: diseqc.h:303
DVBStreamHandler::m_allowRetune
volatile bool m_allowRetune
Definition: dvbstreamhandler.h:64
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
false
VERBOSE_PREAMBLE false
Definition: verbosedefs.h:85
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:55
discid.disc.read
def read(device=None, features=[])
Definition: disc.py:35
DVBStreamHandler::s_recSupportsTsMonitoring
static QMap< QString, bool > s_recSupportsTsMonitoring
Definition: dvbstreamhandler.h:72
diseqc.h
PIDInfo
Definition: streamhandler.h:26
MThread::setObjectName
void setObjectName(const QString &name)
Definition: mthread.cpp:243
arg
arg(title).arg(filename).arg(doDelete))
DVBStreamHandler::s_rec_supportsTsMonitoringLock
static QMutex s_rec_supportsTsMonitoringLock
Definition: dvbstreamhandler.h:71
DeviceReadBuffer::Read
uint Read(unsigned char *buf, uint count)
Try to Read count bytes from into buffer.
Definition: DeviceReadBuffer.cpp:614
MythTimer::start
void start(void)
starts measuring elapsed time.
Definition: mythtimer.cpp:47
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:198
DVBStreamHandler::RetuneMonitor
void RetuneMonitor(void)
Definition: dvbstreamhandler.cpp:505
streamlisteners.h
kPIDPriorityNone
@ kPIDPriorityNone
Definition: mpegstreamdata.h:77
DeviceReadBuffer
Buffers reads from device files.
Definition: DeviceReadBuffer.h:35
StreamHandler::m_startStopLock
QMutex m_startStopLock
Definition: streamhandler.h:116
DTVSignalMonitor::SetRotorValue
virtual void SetRotorValue(int)
Definition: dtvsignalmonitor.h:49
StreamHandler::GetPIDPriority
PIDPriority GetPIDPriority(uint pid) const
Definition: streamhandler.cpp:337
DVBStreamHandler::m_dvrDevPath
QString m_dvrDevPath
Definition: dvbstreamhandler.h:63
StreamID::IsVideo
static bool IsVideo(uint type)
Returns true iff video is an MPEG1/2/3, H264 or open cable video stream.
Definition: mpegtables.h:168
dvbchannel.h
PIDInfo::IsOpen
bool IsOpen(void) const
Definition: streamhandler.h:37
close
#define close
Definition: compat.h:16
tmp
static guint32 * tmp
Definition: goom_core.cpp:31
DVBPIDInfo
Definition: dvbstreamhandler.h:23
StreamHandler::m_openPidFilters
uint m_openPidFilters
Definition: streamhandler.h:132
dvbstreamhandler.h
PSIPTable
A PSIP table is a variant of a PES packet containing an MPEG, ATSC or DVB table.
Definition: mpegtables.h:399
StreamHandler::m_usingSectionReader
bool m_usingSectionReader
Definition: streamhandler.h:126
StreamHandler::m_needsBuffering
bool m_needsBuffering
Definition: streamhandler.h:111
StreamHandler::m_running
bool m_running
Definition: streamhandler.h:123
StreamHandler::m_pidInfo
PIDInfoMap m_pidInfo
Definition: streamhandler.h:131
dvbtypes.h
mythlogging.h
SignalMonitor::kDVBSigMon_WaitForPos
static const uint64_t kDVBSigMon_WaitForPos
Wait for rotor to complete turning the antenna.
Definition: signalmonitor.h:199
DVBStreamHandler::Return
static void Return(DVBStreamHandler *&ref, int inputid)
Definition: dvbstreamhandler.cpp:63
pid_list_t
std::vector< uint > pid_list_t
Definition: dvbstreamhandler.cpp:354
DVBStreamHandler::Get
static DVBStreamHandler * Get(const QString &devname, int inputid)
Definition: dvbstreamhandler.cpp:33
DVBStreamHandler::DVBStreamHandler
DVBStreamHandler(const QString &dvb_device, int inputid)
Definition: dvbstreamhandler.cpp:100
O_NONBLOCK
#define O_NONBLOCK
Definition: mythmedia.cpp:24
StreamHandler::m_usingBuffering
bool m_usingBuffering
Definition: streamhandler.h:125
DVBStreamHandler::RunSR
void RunSR(void)
Uses "Section" reader to read a DVB device for tables.
Definition: dvbstreamhandler.cpp:299
StreamHandler::UpdateFiltersFromStreamData
bool UpdateFiltersFromStreamData(void)
Definition: streamhandler.cpp:284
DVBStreamHandler::s_handlers
static QMap< QString, DVBStreamHandler * > s_handlers
Definition: dvbstreamhandler.h:76
DVBStreamHandler::RunTS
void RunTS(void)
Uses TS filtering devices to read a DVB device for tables & data.
Definition: dvbstreamhandler.cpp:135
MThread::RunEpilog
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
Definition: mthread.cpp:211
CardUtil
Collection of helper utilities for input DB use.
Definition: cardutil.h:40
pes_free
void pes_free(unsigned char *ptr)
Definition: pespacket.cpp:350
DVBStreamHandler::m_dvbChannel
DVBChannel * m_dvbChannel
Definition: dvbstreamhandler.h:67
uint
unsigned int uint
Definition: compat.h:140
DVBStreamHandler::m_drb
DeviceReadBuffer * m_drb
Definition: dvbstreamhandler.h:68
DVBStreamHandler
Definition: dvbstreamhandler.h:33
DVBChannel::Retune
bool Retune(void) override
Definition: dvbchannel.cpp:838
DTVSignalMonitor::GetRotorStatus
virtual void GetRotorStatus(bool &was_moving, bool &is_moving)
Definition: dtvsignalmonitor.h:47
mpegstreamdata.h
kPIDPriorityHigh
@ kPIDPriorityHigh
Definition: mpegstreamdata.h:80
MThread::priority
QThread::Priority priority(void) const
Definition: mthread.cpp:258
StreamHandler::AddPIDFilter
bool AddPIDFilter(PIDInfo *info)
Definition: streamhandler.cpp:189
CardUtil::GetDeviceName
static QString GetDeviceName(dvb_dev_type_t type, const QString &device)
Definition: cardutil.cpp:2709
MythTimer::elapsed
int elapsed(void)
Returns milliseconds elapsed since last start() or restart()
Definition: mythtimer.cpp:90
DVBChannel
Provides interface to the tuning hardware when using DVB drivers.
Definition: dvbchannel.h:30
StreamHandler::m_cycleTimer
MythTimer m_cycleTimer
Definition: streamhandler.h:133
StreamHandler::m_listenerLock
QMutex m_listenerLock
Definition: streamhandler.h:141
DVBStreamHandler::CycleFiltersByPriority
void CycleFiltersByPriority(void) override
Definition: dvbstreamhandler.cpp:380
DVB_DEV_DEMUX
@ DVB_DEV_DEMUX
Definition: cardutil.h:30
SignalMonitor::HasFlags
bool HasFlags(uint64_t _flags) const
Definition: signalmonitor.cpp:277
StreamHandler::m_pidLock
QMutex m_pidLock
Definition: streamhandler.h:129
PIDInfo::m_pid
uint m_pid
Definition: streamhandler.h:39
pes_alloc
unsigned char * pes_alloc(uint size)
Definition: pespacket.cpp:338
cardutil.h
DVBStreamHandler::s_handlersRefCnt
static QMap< QString, uint > s_handlersRefCnt
Definition: dvbstreamhandler.h:77
StreamHandler::m_runningDesired
volatile bool m_runningDesired
Definition: streamhandler.h:117
PIDInfoMap
QMap< uint, PIDInfo * > PIDInfoMap
Definition: streamhandler.h:47
PIDInfo::m_filterFd
int m_filterFd
Input filter file descriptor.
Definition: streamhandler.h:40
DVBStreamHandler::run
void run(void) override
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
Definition: dvbstreamhandler.cpp:111
StreamHandler::m_streamDataList
StreamDataList m_streamDataList
Definition: streamhandler.h:142
StreamHandler::RemovePIDFilter
bool RemovePIDFilter(uint pid)
Definition: streamhandler.cpp:204
DTVSignalMonitor
This class is intended to detect the presence of needed tables.
Definition: dtvsignalmonitor.h:19
DeviceReadBuffer::IsErrored
bool IsErrored(void) const
Definition: DeviceReadBuffer.cpp:240
DVBStreamHandler::s_handlersLock
static QMutex s_handlersLock
Definition: dvbstreamhandler.h:75
DVBPIDInfo::Open
bool Open(const QString &dvb_dev, bool use_section_reader) override
Definition: dvbstreamhandler.cpp:587
DVBStreamHandler::SupportsTSMonitoring
bool SupportsTSMonitoring(void)
Returns true if TS monitoring is supported.
Definition: dvbstreamhandler.cpp:547
StreamHandler::m_bError
volatile bool m_bError
Definition: streamhandler.h:122
DeviceReadBuffer::IsEOF
bool IsEOF(void) const
Definition: DeviceReadBuffer.cpp:246
uint16_t
unsigned short uint16_t
Definition: iso6937tables.h:3
DVBPIDInfo::Close
bool Close(const QString &dvb_dev) override
Definition: dvbstreamhandler.cpp:688
StreamHandler::m_device
QString m_device
Definition: streamhandler.h:109
DVB_DEV_DVR
@ DVB_DEV_DVR
Definition: cardutil.h:29
LOC
#define LOC
Definition: dvbstreamhandler.cpp:585
PIDPriority
PIDPriority
Definition: mpegstreamdata.h:76
dtvsignalmonitor.h
PSIPTable::SectionSyntaxIndicator
bool SectionSyntaxIndicator(void) const
Definition: mpegtables.h:507
find
static pid_list_t::iterator find(const PIDInfoMap &map, pid_list_t &list, pid_list_t::iterator begin, pid_list_t::iterator end, bool find_open)
Definition: dvbstreamhandler.cpp:356
TSPacket::kSize
static constexpr unsigned int kSize
Definition: tspacket.h:223
StreamHandler::m_allowSectionReader
bool m_allowSectionReader
Definition: streamhandler.h:112