MythTV  master
iptvstreamhandler.cpp
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 
3 // System headers
4 #ifdef _WIN32
5 # include <ws2tcpip.h>
6 #else
7 # include <sys/types.h>
8 # include <sys/socket.h>
9 # include <netinet/in.h>
10 # include <netinet/ip.h>
11 #endif
12 
13 // Qt headers
14 #include <QUdpSocket>
15 #include <QByteArray>
16 #include <QHostInfo>
17 
18 // MythTV headers
19 #include "iptvstreamhandler.h"
20 #include "rtppacketbuffer.h"
21 #include "udppacketbuffer.h"
22 #include "rtptsdatapacket.h"
23 #include "rtpdatapacket.h"
24 #include "rtpfecpacket.h"
25 #include "rtcpdatapacket.h"
26 #include "mythlogging.h"
27 #include "cetonrtsp.h"
28 
29 #define LOC QString("IPTVSH[%1](%2): ").arg(m_inputId).arg(m_device)
30 
31 QMap<QString,IPTVStreamHandler*> IPTVStreamHandler::s_iptvhandlers;
34 
36  int inputid)
37 {
38  QMutexLocker locker(&s_iptvhandlers_lock);
39 
40  QString devkey = tuning.GetDeviceKey();
41 
42  QMap<QString,IPTVStreamHandler*>::iterator it = s_iptvhandlers.find(devkey);
43 
44  if (it == s_iptvhandlers.end())
45  {
46  auto *newhandler = new IPTVStreamHandler(tuning, inputid);
47  newhandler->Start();
48  s_iptvhandlers[devkey] = newhandler;
49  s_iptvhandlers_refcnt[devkey] = 1;
50 
51  LOG(VB_RECORD, LOG_INFO,
52  QString("IPTVSH[%1]: Creating new stream handler %2 for %3")
53  .arg(inputid).arg(devkey).arg(tuning.GetDeviceName()));
54  }
55  else
56  {
57  s_iptvhandlers_refcnt[devkey]++;
58  uint rcount = s_iptvhandlers_refcnt[devkey];
59  LOG(VB_RECORD, LOG_INFO,
60  QString("IPTVSH[%1]: Using existing stream handler %2 for %3")
61  .arg(inputid).arg(devkey).arg(tuning.GetDeviceName()) +
62  QString(" (%1 in use)").arg(rcount));
63  }
64 
65  return s_iptvhandlers[devkey];
66 }
67 
68 void IPTVStreamHandler::Return(IPTVStreamHandler * & ref, int inputid)
69 {
70  QMutexLocker locker(&s_iptvhandlers_lock);
71 
72  QString devname = ref->m_device;
73 
74  QMap<QString,uint>::iterator rit = s_iptvhandlers_refcnt.find(devname);
75  if (rit == s_iptvhandlers_refcnt.end())
76  return;
77 
78  LOG(VB_RECORD, LOG_INFO, QString("IPTVSH[%1]: Return(%2) has %3 handlers")
79  .arg(inputid).arg(devname).arg(*rit));
80 
81  if (*rit > 1)
82  {
83  ref = nullptr;
84  (*rit)--;
85  return;
86  }
87 
88  QMap<QString,IPTVStreamHandler*>::iterator it = s_iptvhandlers.find(devname);
89  if ((it != s_iptvhandlers.end()) && (*it == ref))
90  {
91  LOG(VB_RECORD, LOG_INFO, QString("IPTVSH[%1]: Closing handler for %2")
92  .arg(inputid).arg(devname));
93  ref->Stop();
94  delete *it;
95  s_iptvhandlers.erase(it);
96  }
97  else
98  {
99  LOG(VB_GENERAL, LOG_ERR,
100  QString("IPTVSH[%1] Error: Couldn't find handler for %2")
101  .arg(inputid).arg(devname));
102  }
103 
104  s_iptvhandlers_refcnt.erase(rit);
105  ref = nullptr;
106 }
107 
109  : StreamHandler(tuning.GetDeviceKey(), inputid)
110  , m_tuning(tuning)
111 {
113 }
114 
116 {
117  RunProlog();
118 
119  LOG(VB_GENERAL, LOG_INFO, LOC + "run()");
120 
121  SetRunning(true, false, false);
122 
123  // TODO Error handling..
124 
125  // Setup
126  CetonRTSP *rtsp = nullptr;
127  IPTVTuningData tuning = m_tuning;
128  if(m_tuning.IsRTSP())
129  {
130  rtsp = new CetonRTSP(m_tuning.GetURL(0));
131 
132  // Check RTSP capabilities
133  QStringList options;
134  if (!(rtsp->GetOptions(options) && options.contains("DESCRIBE") &&
135  options.contains("SETUP") && options.contains("PLAY") &&
136  options.contains("TEARDOWN")))
137  {
138  LOG(VB_RECORD, LOG_ERR, LOC +
139  "RTSP interface did not support the necessary options");
140  delete rtsp;
141  SetRunning(false, false, false);
142  RunEpilog();
143  return;
144  }
145 
146  if (!rtsp->Describe())
147  {
148  LOG(VB_RECORD, LOG_ERR, LOC +
149  "RTSP Describe command failed");
150  delete rtsp;
151  SetRunning(false, false, false);
152  RunEpilog();
153  return;
154  }
155 
156  m_useRtpStreaming = true;
157 
158  QUrl urltuned = m_tuning.GetURL(0);
159  urltuned.setScheme("rtp");
160  urltuned.setPort(0);
161  tuning = IPTVTuningData(urltuned.toString(), 0, IPTVTuningData::kNone,
162  urltuned.toString(), 0, "", 0);
163  }
164 
165  bool error = false;
166 
167  int start_port = 0;
168  for (uint i = 0; i < IPTV_SOCKET_COUNT; i++)
169  {
170  QUrl url = tuning.GetURL(i);
171  if (url.port() < 0)
172  continue;
173 
174  LOG(VB_RECORD, LOG_DEBUG, LOC +
175  QString("setting up url[%1]:%2").arg(i).arg(url.toString()));
176 
177  // always ensure we use consecutive port numbers
178  int port = start_port ? start_port + 1 : url.port();
179  QString host = url.host();
180  QHostAddress dest_addr(host);
181 
182  if (!host.isEmpty() && dest_addr.isNull())
183  {
184  // address is a hostname, attempts to resolve it
185  QHostInfo info = QHostInfo::fromName(host);
186  QList<QHostAddress> list = info.addresses();
187 
188  if (list.isEmpty())
189  {
190  LOG(VB_RECORD, LOG_ERR, LOC +
191  QString("Can't resolve hostname:'%1'").arg(host));
192  }
193  else
194  {
195  for (const auto & addr : qAsConst(list))
196  {
197  dest_addr = addr;
198  if (addr.protocol() == QAbstractSocket::IPv6Protocol)
199  {
200  // We prefer first IPv4
201  break;
202  }
203  }
204  LOG(VB_RECORD, LOG_DEBUG, LOC +
205  QString("resolved %1 as %2").arg(host).arg(dest_addr.toString()));
206  }
207  }
208  bool ipv6 = dest_addr.protocol() == QAbstractSocket::IPv6Protocol;
209  bool is_multicast = ipv6 ?
210  dest_addr.isInSubnet(QHostAddress::parseSubnet("ff00::/8")) :
211  (dest_addr.toIPv4Address() & 0xf0000000) == 0xe0000000;
212 
213  m_sockets[i] = new QUdpSocket();
214  if (!is_multicast)
215  {
216  // this allow to filter incoming traffic, and make sure it's from
217  // the requested server
218  m_sender[i] = dest_addr;
219  }
221 
222  // we need to open the descriptor ourselves so we
223  // can set some socket options
224  int fd = socket(ipv6 ? AF_INET6 : AF_INET, SOCK_DGRAM, 0); // create IPv4 socket
225  if (fd < 0)
226  {
227  LOG(VB_GENERAL, LOG_ERR, LOC +
228  "Unable to create socket " + ENO);
229  continue;
230  }
231  int buf_size = 2 * 1024 * std::max(tuning.GetBitrate(i)/1000, 500U);
232  if (!tuning.GetBitrate(i))
233  buf_size = 2 * 1024 * 1024;
234  int err = setsockopt(fd, SOL_SOCKET, SO_RCVBUF,
235  (char *)&buf_size, sizeof(buf_size));
236  if (err)
237  {
238  LOG(VB_GENERAL, LOG_INFO, LOC +
239  QString("Increasing buffer size to %1 failed")
240  .arg(buf_size) + ENO);
241  }
242 
243  m_sockets[i]->setSocketDescriptor(
244  fd, QAbstractSocket::UnconnectedState, QIODevice::ReadOnly);
245 
246  // we bind to destination address if it's a multicast address, or
247  // the local ones otherwise
248  if (!m_sockets[i]->bind(is_multicast ?
249  dest_addr :
250  (ipv6 ? QHostAddress::AnyIPv6 : QHostAddress::Any),
251  port))
252  {
253  LOG(VB_GENERAL, LOG_ERR, LOC + "Binding to port failed.");
254  error = true;
255  }
256  else
257  {
258  start_port = m_sockets[i]->localPort();
259  }
260 
261  if (is_multicast)
262  {
263  m_sockets[i]->joinMulticastGroup(dest_addr);
264  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Joining %1")
265  .arg(dest_addr.toString()));
266  }
267 
268  if (!is_multicast && rtsp && i == 1)
269  {
270  m_rtcpDest = dest_addr;
271  }
272  }
273 
274  if (!error)
275  {
276  if (m_tuning.IsRTP() || m_tuning.IsRTSP())
277  m_buffer = new RTPPacketBuffer(tuning.GetBitrate(0));
278  else
279  m_buffer = new UDPPacketBuffer(tuning.GetBitrate(0));
281  m_writeHelper->Start();
282  }
283 
284  if (!error && rtsp)
285  {
286  // Start Streaming
287  if (!rtsp->Setup(m_sockets[0]->localPort(), m_sockets[1]->localPort(),
289  !rtsp->Play())
290  {
291  LOG(VB_RECORD, LOG_ERR, LOC +
292  "Starting recording (RTP initialization failed). Aborting.");
293  error = true;
294  }
295  if (m_rtspRtcpPort > 0)
296  {
299  }
300  }
301 
302  if (!error)
303  {
304  // Enter event loop
305  exec();
306  }
307 
308  // Clean up
309  for (uint i = 0; i < IPTV_SOCKET_COUNT; i++)
310  {
311  if (m_sockets[i])
312  {
313  delete m_sockets[i];
314  m_sockets[i] = nullptr;
315  delete m_readHelpers[i];
316  m_readHelpers[i] = nullptr;
317  }
318  }
319  delete m_buffer;
320  m_buffer = nullptr;
321  delete m_writeHelper;
322  m_writeHelper = nullptr;
323 
324  if (rtsp)
325  {
326  rtsp->Teardown();
327  delete rtsp;
328  }
329 
330  SetRunning(false, false, false);
331  RunEpilog();
332 }
333 
335  IPTVStreamHandler *p, QUdpSocket *s, uint stream) :
336  m_parent(p), m_socket(s), m_sender(p->m_sender[stream]),
337  m_stream(stream)
338 {
339  connect(m_socket, &QIODevice::readyRead,
341 }
342 
343 #define LOC_WH QString("IPTVSH(%1): ").arg(m_parent->m_device)
344 
346 {
347  QHostAddress sender;
348  quint16 senderPort = 0;
349  bool sender_null = m_sender.isNull();
350 
351  if (0 == m_stream)
352  {
353  while (m_socket->hasPendingDatagrams())
354  {
356  QByteArray &data = packet.GetDataReference();
357  data.resize(m_socket->pendingDatagramSize());
358  m_socket->readDatagram(data.data(), data.size(),
359  &sender, &senderPort);
360  if (sender_null || sender == m_sender)
361  {
362  m_parent->m_buffer->PushDataPacket(packet);
363  }
364  else
365  {
366  LOG(VB_RECORD, LOG_WARNING, LOC_WH +
367  QString("Received on socket(%1) %2 bytes from non expected "
368  "sender:%3 (expected:%4) ignoring")
369  .arg(m_stream).arg(data.size())
370  .arg(sender.toString()).arg(m_sender.toString()));
371  }
372  }
373  }
374  else
375  {
376  while (m_socket->hasPendingDatagrams())
377  {
379  QByteArray &data = packet.GetDataReference();
380  data.resize(m_socket->pendingDatagramSize());
381  m_socket->readDatagram(data.data(), data.size(),
382  &sender, &senderPort);
383  if (sender_null || sender == m_sender)
384  {
385  m_parent->m_buffer->PushFECPacket(packet, m_stream - 1);
386  }
387  else
388  {
389  LOG(VB_RECORD, LOG_WARNING, LOC_WH +
390  QString("Received on socket(%1) %2 bytes from non expected "
391  "sender:%3 (expected:%4) ignoring")
392  .arg(m_stream).arg(data.size())
393  .arg(sender.toString()).arg(m_sender.toString()));
394  }
395  }
396  }
397 }
398 
400 {
401  if (m_timer)
402  {
403  killTimer(m_timer);
404  }
405  if (m_timerRtcp)
406  {
407  killTimer(m_timerRtcp);
408  }
409  m_timer = 0;
410  m_timerRtcp = 0;
411  m_parent = nullptr;
412 }
413 
415 {
416  if (event->timerId() == m_timerRtcp)
417  {
418  SendRTCPReport();
419  return;
420  }
421 
423  return;
424 
425  while (!m_parent->m_useRtpStreaming)
426  {
428 
429  if (packet.GetDataReference().isEmpty())
430  break;
431 
432  int remainder = 0;
433  {
434  QMutexLocker locker(&m_parent->m_listenerLock);
435  QByteArray &data = packet.GetDataReference();
436  for (auto sit = m_parent->m_streamDataList.cbegin();
437  sit != m_parent->m_streamDataList.cend(); ++sit)
438  {
439  remainder = sit.key()->ProcessData(
440  reinterpret_cast<const unsigned char*>(data.data()),
441  data.size());
442  }
443  }
444 
445  if (remainder != 0)
446  {
447  LOG(VB_RECORD, LOG_INFO, LOC_WH +
448  QString("data_length = %1 remainder = %2")
449  .arg(packet.GetDataReference().size()).arg(remainder));
450  }
451 
452  m_parent->m_buffer->FreePacket(packet);
453  }
454 
455  while (m_parent->m_useRtpStreaming)
456  {
458 
459  if (!packet.IsValid())
460  break;
461 
463  {
464  RTPTSDataPacket ts_packet(packet);
465 
466  if (!ts_packet.IsValid())
467  {
468  m_parent->m_buffer->FreePacket(packet);
469  continue;
470  }
471 
472  uint exp_seq_num = m_lastSequenceNumber + 1;
473  uint seq_num = ts_packet.GetSequenceNumber();
474  if (m_lastSequenceNumber &&
475  ((exp_seq_num&0xFFFF) != (seq_num&0xFFFF)))
476  {
477  LOG(VB_RECORD, LOG_INFO, LOC_WH +
478  QString("Sequence number mismatch %1!=%2")
479  .arg(seq_num).arg(exp_seq_num));
480  if (seq_num > exp_seq_num)
481  {
482  m_lostInterval = seq_num - exp_seq_num;
484  }
485  }
486  m_lastSequenceNumber = seq_num;
487  m_lastTimestamp = ts_packet.GetTimeStamp();
488  LOG(VB_RECORD, LOG_DEBUG,
489  QString("Processing RTP packet(seq:%1 ts:%2)")
491 
492  m_parent->m_listenerLock.lock();
493 
494  int remainder = 0;
495  for (auto sit = m_parent->m_streamDataList.cbegin();
496  sit != m_parent->m_streamDataList.cend(); ++sit)
497  {
498  remainder = sit.key()->ProcessData(
499  ts_packet.GetTSData(), ts_packet.GetTSDataSize());
500  }
501 
502  m_parent->m_listenerLock.unlock();
503 
504  if (remainder != 0)
505  {
506  LOG(VB_RECORD, LOG_INFO, LOC_WH +
507  QString("data_length = %1 remainder = %2")
508  .arg(ts_packet.GetTSDataSize()).arg(remainder));
509  }
510  }
511  m_parent->m_buffer->FreePacket(packet);
512  }
513 }
514 
516 {
517  if (m_parent->m_rtcpDest.isNull())
518  {
519  // no point sending data if we don't know where to
520  return;
521  }
523  RTCPDataPacket rtcp =
527  QByteArray buf = rtcp.GetData();
528 
529  LOG(VB_RECORD, LOG_DEBUG, LOC_WH +
530  QString("Sending RTCPReport to %1:%2")
531  .arg(m_parent->m_rtcpDest.toString())
532  .arg(m_parent->m_rtspRtcpPort));
533  m_parent->m_sockets[1]->writeDatagram(buf.constData(), buf.size(),
537 }
IPTVStreamHandler::Return
static void Return(IPTVStreamHandler *&ref, int inputid)
Definition: iptvstreamhandler.cpp:68
MThread::exec
int exec(void)
Enters the qt event loop. call exit or quit to exit thread.
Definition: mthread.cpp:322
RTPDataPacket::GetTimeStamp
uint GetTimeStamp(void) const
Definition: rtpdatapacket.h:100
IPTVStreamHandler::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: iptvstreamhandler.cpp:115
IPTVStreamHandler::m_tuning
IPTVTuningData m_tuning
Definition: iptvstreamhandler.h:103
rtcpdatapacket.h
IPTVStreamHandlerReadHelper::m_parent
IPTVStreamHandler * m_parent
Definition: iptvstreamhandler.h:40
RTPDataPacket::kPayLoadTypeTS
@ kPayLoadTypeTS
Definition: rtpdatapacket.h:86
ENO
#define ENO
This can be appended to the LOG args with "+".
Definition: mythlogging.h:72
IPTVTuningData::IsRTSP
bool IsRTSP(void) const
Definition: iptvtuningdata.h:188
IPTVStreamHandlerReadHelper::m_sender
QHostAddress m_sender
Definition: iptvstreamhandler.h:42
IPTVStreamHandler::IPTVStreamHandler
IPTVStreamHandler(const IPTVTuningData &tuning, int inputid)
Definition: iptvstreamhandler.cpp:108
IPTVStreamHandler::m_rtspSsrc
uint32_t m_rtspSsrc
Definition: iptvstreamhandler.h:113
IPTVStreamHandler::m_readHelpers
std::array< IPTVStreamHandlerReadHelper *, IPTV_SOCKET_COUNT > m_readHelpers
Definition: iptvstreamhandler.h:105
error
static void error(const char *str,...)
Definition: vbi.cpp:42
IPTVStreamHandlerWriteHelper::Start
void Start(void)
Definition: iptvstreamhandler.h:55
IPTVStreamHandlerWriteHelper::~IPTVStreamHandlerWriteHelper
~IPTVStreamHandlerWriteHelper() override
Definition: iptvstreamhandler.cpp:399
rtpdatapacket.h
RTPTSDataPacket
RTP Transport Stream Data Packet.
Definition: rtptsdatapacket.h:17
StreamHandler::SetRunning
void SetRunning(bool running, bool using_buffering, bool using_section_reader)
Definition: streamhandler.cpp:171
IPTVStreamHandler::m_sockets
std::array< QUdpSocket *, IPTV_SOCKET_COUNT > m_sockets
Definition: iptvstreamhandler.h:104
PacketBuffer::FreePacket
void FreePacket(const UDPPacket &packet)
Frees an RTPDataPacket returned by PopDataPacket.
Definition: packetbuffer.cpp:56
StreamHandler::Stop
void Stop(void)
Definition: streamhandler.cpp:153
StreamHandler
Definition: streamhandler.h:55
RTCP_TIMER
#define RTCP_TIMER
Definition: iptvstreamhandler.h:21
RTPTSDataPacket::GetTSDataSize
unsigned int GetTSDataSize(void) const
Definition: rtptsdatapacket.h:29
IPTVStreamHandlerWriteHelper::StartRTCPRR
void StartRTCPRR(void)
Definition: iptvstreamhandler.h:59
CetonRTSP::Setup
bool Setup(ushort clientPort1, ushort clientPort2, ushort &rtpPort, ushort &rtcpPort, uint32_t &ssrc)
Definition: cetonrtsp.cpp:392
IPTVTuningData::kNone
@ kNone
Definition: iptvtuningdata.h:21
RTCPDataPacket::GetData
QByteArray GetData(void) const
Definition: rtcpdatapacket.h:55
IPTVStreamHandlerReadHelper::ReadPending
void ReadPending(void)
Definition: iptvstreamhandler.cpp:345
IPTVStreamHandlerWriteHelper::m_lastSequenceNumber
uint m_lastSequenceNumber
Definition: iptvstreamhandler.h:73
LOC_WH
#define LOC_WH
Definition: iptvstreamhandler.cpp:343
arg
arg(title).arg(filename).arg(doDelete))
IPTVTuningData::IsRTP
bool IsRTP(void) const
Definition: iptvtuningdata.h:183
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
IPTVStreamHandlerWriteHelper::timerEvent
void timerEvent(QTimerEvent *event) override
Definition: iptvstreamhandler.cpp:414
IPTVStreamHandlerReadHelper::m_stream
uint m_stream
Definition: iptvstreamhandler.h:43
IPTVStreamHandler::s_iptvhandlers
static QMap< QString, IPTVStreamHandler * > s_iptvhandlers
Definition: iptvstreamhandler.h:118
IPTVStreamHandlerWriteHelper::m_timerRtcp
int m_timerRtcp
Definition: iptvstreamhandler.h:72
IPTVStreamHandlerWriteHelper::m_lostInterval
int m_lostInterval
Definition: iptvstreamhandler.h:77
IPTVTuningData::GetDeviceKey
QString GetDeviceKey(void) const
Definition: iptvtuningdata.h:97
IPTVStreamHandlerWriteHelper::m_parent
IPTVStreamHandler * m_parent
Definition: iptvstreamhandler.h:70
IPTVStreamHandlerWriteHelper::m_previousLastSequenceNumber
uint m_previousLastSequenceNumber
Definition: iptvstreamhandler.h:75
IPTVStreamHandler::IPTVStreamHandlerWriteHelper
friend class IPTVStreamHandlerWriteHelper
Definition: iptvstreamhandler.h:83
IPTV_SOCKET_COUNT
#define IPTV_SOCKET_COUNT
Definition: iptvstreamhandler.h:20
mythlogging.h
IPTVStreamHandler::IPTVStreamHandlerReadHelper
friend class IPTVStreamHandlerReadHelper
Definition: iptvstreamhandler.h:82
hardwareprofile.config.p
p
Definition: config.py:33
CetonRTSP::Play
bool Play(void)
Definition: cetonrtsp.cpp:448
IPTVTuningData::GetDeviceName
QString GetDeviceName(void) const
Definition: iptvtuningdata.h:108
IPTVStreamHandler::s_iptvhandlers_refcnt
static QMap< QString, uint > s_iptvhandlers_refcnt
Definition: iptvstreamhandler.h:119
IPTVStreamHandler::m_useRtpStreaming
bool m_useRtpStreaming
Definition: iptvstreamhandler.h:110
IPTVStreamHandlerWriteHelper::m_lost
int m_lost
Definition: iptvstreamhandler.h:76
IPTVTuningData
Definition: iptvtuningdata.h:17
CetonRTSP::Teardown
bool Teardown(void)
Definition: cetonrtsp.cpp:456
MThread::RunEpilog
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
Definition: mthread.cpp:211
CetonRTSP::GetOptions
bool GetOptions(QStringList &options)
Definition: cetonrtsp.cpp:239
IPTVStreamHandler::Get
static IPTVStreamHandler * Get(const IPTVTuningData &tuning, int inputid)
Definition: iptvstreamhandler.cpp:35
IPTVStreamHandler::m_sender
std::array< QHostAddress, IPTV_SOCKET_COUNT > m_sender
Definition: iptvstreamhandler.h:106
RTPTSDataPacket::GetTSData
const unsigned char * GetTSData(void) const
Definition: rtptsdatapacket.h:24
uint
unsigned int uint
Definition: compat.h:140
rtppacketbuffer.h
RTPDataPacket::GetSequenceNumber
uint GetSequenceNumber(void) const
Definition: rtpdatapacket.h:95
LOC
#define LOC
Definition: iptvstreamhandler.cpp:29
IPTVStreamHandler::m_buffer
PacketBuffer * m_buffer
Definition: iptvstreamhandler.h:108
CetonRTSP::Describe
bool Describe(void)
Definition: cetonrtsp.cpp:321
StreamHandler::m_listenerLock
QMutex m_listenerLock
Definition: streamhandler.h:141
udppacketbuffer.h
CetonRTSP
Definition: cetonrtsp.h:25
PacketBuffer::HasAvailablePacket
bool HasAvailablePacket(void) const
Returns true if there are ordered packets ready for processing.
Definition: packetbuffer.cpp:26
PacketBuffer::PushFECPacket
virtual void PushFECPacket(const UDPPacket &, unsigned int)=0
StreamHandler::m_streamDataList
StreamDataList m_streamDataList
Definition: streamhandler.h:142
PacketBuffer::PushDataPacket
virtual void PushDataPacket(const UDPPacket &)=0
RTPDataPacket::GetPayloadType
uint GetPayloadType(void) const
Definition: rtpdatapacket.h:90
IPTVStreamHandler::m_rtcpDest
QHostAddress m_rtcpDest
Definition: iptvstreamhandler.h:114
IPTVStreamHandler::m_rtspRtpPort
ushort m_rtspRtpPort
Definition: iptvstreamhandler.h:111
rtptsdatapacket.h
IPTVStreamHandlerWriteHelper::SendRTCPReport
void SendRTCPReport(void)
Definition: iptvstreamhandler.cpp:515
IPTVStreamHandler
Definition: iptvstreamhandler.h:81
IPTVStreamHandler::m_rtspRtcpPort
ushort m_rtspRtcpPort
Definition: iptvstreamhandler.h:112
RTPDataPacket
RTP Data Packet.
Definition: rtpdatapacket.h:31
IPTVStreamHandler::s_iptvhandlers_lock
static QMutex s_iptvhandlers_lock
Definition: iptvstreamhandler.h:117
IPTVStreamHandlerReadHelper::m_socket
QUdpSocket * m_socket
Definition: iptvstreamhandler.h:41
PacketBuffer::PopDataPacket
UDPPacket PopDataPacket(void)
Fetches a data packet for processing.
Definition: packetbuffer.cpp:31
UDPPacketBuffer
Definition: udppacketbuffer.h:13
iptvstreamhandler.h
RTCPDataPacket
RTCP Data Packet.
Definition: rtcpdatapacket.h:37
UDPPacket::GetDataReference
QByteArray & GetDataReference(void)
Definition: udppacket.h:36
RTPPacketBuffer
Definition: rtppacketbuffer.h:16
StreamHandler::m_device
QString m_device
Definition: streamhandler.h:109
IPTVStreamHandlerReadHelper::IPTVStreamHandlerReadHelper
IPTVStreamHandlerReadHelper(IPTVStreamHandler *p, QUdpSocket *s, uint stream)
Definition: iptvstreamhandler.cpp:334
IPTVTuningData::GetBitrate
uint GetBitrate(uint i) const
Definition: iptvtuningdata.h:147
build_compdb.options
options
Definition: build_compdb.py:11
UDPPacket
UDP Packet.
Definition: udppacket.h:21
rtpfecpacket.h
IPTVTuningData::GetURL
QUrl GetURL(uint i) const
Definition: iptvtuningdata.h:137
cetonrtsp.h
RTPDataPacket::IsValid
bool IsValid(void) const override
IsValid() must return true before any data access methods are called, other than GetDataReference() a...
Definition: rtpdatapacket.h:40
IPTVStreamHandler::m_writeHelper
IPTVStreamHandlerWriteHelper * m_writeHelper
Definition: iptvstreamhandler.h:107
IPTVStreamHandlerWriteHelper::m_timer
int m_timer
Definition: iptvstreamhandler.h:71
PacketBuffer::GetEmptyPacket
UDPPacket GetEmptyPacket(void)
Gets a packet for use in PushDataPacket/PushFECPacket.
Definition: packetbuffer.cpp:42
IPTVStreamHandlerWriteHelper::m_lastTimestamp
uint m_lastTimestamp
Definition: iptvstreamhandler.h:74