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