MythTV  master
rtcpdatapacket.h
Go to the documentation of this file.
1 //
2 // rtcpdatapacket.h
3 // MythTV
4 //
5 // Created by Jean-Yves Avenard on 6/05/2014.
6 // Copyright (c) 2014 Bubblestuff Pty Ltd. All rights reserved.
7 //
8 
9 #ifndef MythTV_rtcpdatapacket_h
10 #define MythTV_rtcpdatapacket_h
11 
12 #include <limits> // workaround QTBUG-90395
13 
14 #include <QHostAddress>
15 #include <QByteArray>
16 #include <QtEndian>
17 
19 #include "udppacket.h"
20 
21 #define RTP_VERSION 2
22 #define RTCP_RR 201
23 #define RTCP_SDES 202
24 
38 class RTCPDataPacket : public UDPPacket
39 {
40 public:
42  : UDPPacket(o),
45  m_lost(o.m_lost), m_ssrc(o.m_ssrc)
46  { }
47 
48  RTCPDataPacket(uint32_t timestamp, uint32_t last_timestamp,
49  uint32_t sequence, uint32_t last_sequence,
50  uint32_t lost, uint32_t lost_interval,
51  uint32_t ssrc)
52  : m_timestamp(timestamp), m_last_timestamp(last_timestamp),
53  m_sequence(sequence), m_last_sequence(last_sequence),
54  m_lost(lost), m_lost_interval(lost_interval),
55  m_ssrc(ssrc) { }
56 
57  QByteArray GetData(void) const
58  {
59  QByteArray buffer;
60 
61  if (m_sequence == 0)
62  {
63  // No packet received yet, send an empty RTPC RR packet
64  uchar rtcp[10];
65 
66  rtcp[0] = RTP_VERSION << 6; // RTP version
67  rtcp[1] = RTCP_RR; // RTCP_RR
68  qToBigEndian((qint16)1, &rtcp[2]); // length in words - 1
69  qToBigEndian( 0, &rtcp[4]); // our own SSRC
70  buffer = QByteArray((char *)rtcp, 10);
71  }
72  else
73  {
74  static char *hostname = (char *)"MythTV";
75  uint32_t len = strlen(hostname);
76  auto *rtcp = new uchar[46 + len + 1];
77 
78  rtcp[0] = (RTP_VERSION << 6) + 1; // 1 report block
79  rtcp[1] = RTCP_RR; // RTCP_RR)
80  qToBigEndian((qint16)7, &rtcp[2]); // length in words - 1
81  // our own SSRC: we use the server's SSRC + 1 to avoid conflicts
82  qToBigEndian((quint32)m_ssrc + 1, &rtcp[4]);
83  qToBigEndian((quint32)m_ssrc, &rtcp[8]);
84  // some placeholders we should really fill...
85  // RFC 1889/p 27
86 
87 // extended_max = stats->cycles + stats->max_seq;
88 // expected = extended_max - stats->base_seq;
89 // lost = expected - stats->received;
90 // lost = FFMIN(lost, 0xffffff); // clamp it since it's only 24 bits...
91 // expected_interval = expected - stats->expected_prior;
92 // stats->expected_prior = expected;
93 // received_interval = stats->received - stats->received_prior;
94 // stats->received_prior = stats->received;
95 // lost_interval = expected_interval - received_interval;
96 // if (expected_interval == 0 || lost_interval <= 0)
97 // fraction = 0;
98 // else
99 // fraction = (lost_interval << 8) / expected_interval;
100 //
101 // fraction = (fraction << 24) | lost;
102 // avio_wb32(pb, fraction); /* 8 bits of fraction, 24 bits of total packets lost */
103 // avio_wb32(pb, extended_max); /* max sequence received */
104 // avio_wb32(pb, stats->jitter >> 4); /* jitter */
105 //
106 // if (s->last_rtcp_ntp_time == AV_NOPTS_VALUE) {
107 // avio_wb32(pb, 0); /* last SR timestamp */
108 // avio_wb32(pb, 0); /* delay since last SR */
109 // } else {
110 // uint32_t middle_32_bits = s->last_rtcp_ntp_time >> 16; // this is valid, right? do we need to handle 64 bit values special?
111 // uint32_t delay_since_last = av_rescale(av_gettime() - s->last_rtcp_reception_time,
112 // 65536, AV_TIME_BASE);
113 //
114 // avio_wb32(pb, middle_32_bits); /* last SR timestamp */
115 // avio_wb32(pb, delay_since_last); /* delay since last SR */
116 // }
117 
118  qToBigEndian((quint32) 0, &rtcp[12]); /* 8 bits of fraction, 24 bits of total packets lost */
119  qToBigEndian((quint32) 0, &rtcp[16]); /* max sequence received */
120  qToBigEndian((quint32) 0, &rtcp[20]); /* jitter */
121 
122  qToBigEndian((quint32) m_timestamp, &rtcp[24]); /* last SR timestamp */
123  qToBigEndian((quint32) m_last_timestamp, &rtcp[28]); /* delay since last SR timestamp */
124 
125  // CNAME
126  rtcp[32] = (RTP_VERSION << 6) + 1; // 1 report block
127  rtcp[33] = RTCP_SDES; // RTCP_SDES)
128  qToBigEndian((qint16)((7 + len + 3) / 4), &rtcp[34]); /* length in words - 1 */
129  qToBigEndian((quint32)m_ssrc, &rtcp[36]);
130  qToBigEndian((quint32)m_ssrc + 1, &rtcp[40]);
131 
132  buffer = QByteArray((char *)rtcp, 44);
133 
134  buffer.append((char)0x01); //44
135  buffer.append((char)len); //45
136  buffer.append(hostname, len); //46
137  buffer.append((char)0); // 46 + len END
138 
139  // padding
140  for (len = (7 + len) % 4; len % 4; len++)
141  {
142  buffer.append((char)0);
143  }
144  delete[] rtcp;
145  }
146  return buffer;
147  }
148 
150  {
151  return m_sequence;
152  }
153 
154 protected:
155  uint32_t m_timestamp;
157  uint32_t m_sequence;
158  uint32_t m_last_sequence;
159  uint32_t m_lost;
160  uint32_t m_lost_interval {0};
161  uint32_t m_ssrc;
162 };
163 #endif
RTCPDataPacket::m_ssrc
uint32_t m_ssrc
Definition: rtcpdatapacket.h:161
RTCPDataPacket::m_last_sequence
uint32_t m_last_sequence
Definition: rtcpdatapacket.h:158
RTCPDataPacket::RTCPDataPacket
RTCPDataPacket(const RTCPDataPacket &o)
Definition: rtcpdatapacket.h:41
RTCP_SDES
#define RTCP_SDES
Definition: rtcpdatapacket.h:23
RTCPDataPacket::m_timestamp
uint32_t m_timestamp
Definition: rtcpdatapacket.h:155
RTCPDataPacket::m_lost_interval
uint32_t m_lost_interval
Definition: rtcpdatapacket.h:160
RTCPDataPacket::m_sequence
uint32_t m_sequence
Definition: rtcpdatapacket.h:157
RTCPDataPacket::GetData
QByteArray GetData(void) const
Definition: rtcpdatapacket.h:57
RTCPDataPacket::m_last_timestamp
uint32_t m_last_timestamp
Definition: rtcpdatapacket.h:156
mythlogging.h
RTCPDataPacket::m_lost
uint32_t m_lost
Definition: rtcpdatapacket.h:159
uint
unsigned int uint
Definition: compat.h:81
RTP_VERSION
#define RTP_VERSION
Definition: rtcpdatapacket.h:21
udppacket.h
RTCP_RR
#define RTCP_RR
Definition: rtcpdatapacket.h:22
musicbrainzngs.caa.hostname
string hostname
Definition: caa.py:17
RTCPDataPacket
RTCP Data Packet.
Definition: rtcpdatapacket.h:38
RTCPDataPacket::RTCPDataPacket
RTCPDataPacket(uint32_t timestamp, uint32_t last_timestamp, uint32_t sequence, uint32_t last_sequence, uint32_t lost, uint32_t lost_interval, uint32_t ssrc)
Definition: rtcpdatapacket.h:48
UDPPacket
UDP Packet.
Definition: udppacket.h:20
RTCPDataPacket::GetSequenceNumber
uint GetSequenceNumber(void) const
Definition: rtcpdatapacket.h:149