SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
rtcpcompoundpacketbuilder.h
Go to the documentation of this file.
1 /*
2 
3  This file is a part of JRTPLIB
4  Copyright (c) 1999-2017 Jori Liesenborgs
5 
6  Contact: jori.liesenborgs@gmail.com
7 
8  This library was developed at the Expertise Centre for Digital Media
9  (http://www.edm.uhasselt.be), a research center of the Hasselt University
10  (http://www.uhasselt.be). The library is based upon work done for
11  my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
12 
13  Permission is hereby granted, free of charge, to any person obtaining a
14  copy of this software and associated documentation files (the "Software"),
15  to deal in the Software without restriction, including without limitation
16  the rights to use, copy, modify, merge, publish, distribute, sublicense,
17  and/or sell copies of the Software, and to permit persons to whom the
18  Software is furnished to do so, subject to the following conditions:
19 
20  The above copyright notice and this permission notice shall be included
21  in all copies or substantial portions of the Software.
22 
23  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
29  IN THE SOFTWARE.
30 
31  */
32 
37 #ifndef RTCPCOMPOUNDPACKETBUILDER_H
38 
39 #define RTCPCOMPOUNDPACKETBUILDER_H
40 
41 #include <list>
42 #include <algorithm>
43 
44 #include "rtpconfig.h"
45 #include "rtcpcompoundpacket.h"
46 #include "rtptimeutilities.h"
47 #include "rtcpsdespacket.h"
48 #include "rtperrors.h"
49 #include "rtpendian.h"
50 
51 #include "export.h"
52 
53 namespace qrtplib
54 {
55 
63 {
64 public:
68 
73  int InitBuild(std::size_t maxpacketsize);
74 
79  int InitBuild(void *externalbuffer, std::size_t buffersize);
80 
86  int StartSenderReport(uint32_t senderssrc, const RTPNTPTime &ntptimestamp, uint32_t rtptimestamp, uint32_t packetcount, uint32_t octetcount);
87 
93  int StartReceiverReport(uint32_t senderssrc);
94 
99  int AddReportBlock(uint32_t ssrc, uint8_t fractionlost, int32_t packetslost, uint32_t exthighestseq, uint32_t jitter, uint32_t lsr, uint32_t dlsr);
100 
102  int AddSDESSource(uint32_t ssrc);
103 
108  int AddSDESNormalItem(RTCPSDESPacket::ItemType t, const void *itemdata, uint8_t itemlength);
109 #ifdef RTP_SUPPORT_SDESPRIV
110 
111  int AddSDESPrivateItem(const void *prefixdata, uint8_t prefixlength, const void *valuedata, uint8_t valuelength);
112 #endif // RTP_SUPPORT_SDESPRIV
113 
119  int AddBYEPacket(uint32_t *ssrcs, uint8_t numssrcs, const void *reasondata, uint8_t reasonlength);
120 
125  int AddAPPPacket(uint8_t subtype, uint32_t ssrc, const uint8_t name[4], const void *appdata, std::size_t appdatalen);
126 
131  int EndBuild();
132 
133 private:
134  class Buffer
135  {
136  public:
137  Buffer() :
138  packetdata(0), packetlength(0)
139  {
140  }
141  Buffer(uint8_t *data, std::size_t len) :
142  packetdata(data), packetlength(len)
143  {
144  }
145 
147  std::size_t packetlength;
148  };
149 
150  class Report
151  {
152  public:
154  {
155  headerdata = (uint8_t *) headerdata32;
156  std::fill(&headerdata32[0], &headerdata32[0] + ((sizeof(uint32_t) + sizeof(RTCPSenderReport)) / sizeof(uint32_t)), 0U);
157  isSR = false;
158  headerlength = 0;
159  }
161  {
162  Clear();
163  }
164 
165  void Clear()
166  {
167  std::list<Buffer>::const_iterator it;
168  for (it = reportblocks.begin(); it != reportblocks.end(); it++)
169  {
170  if ((*it).packetdata)
171  delete[] (*it).packetdata;
172  }
173  reportblocks.clear();
174  isSR = false;
175  headerlength = 0;
176  }
177 
178  std::size_t NeededBytes()
179  {
180  std::size_t x, n, d, r;
181  n = reportblocks.size();
182  if (n == 0)
183  {
184  if (headerlength == 0)
185  return 0;
186  x = sizeof(RTCPCommonHeader) + headerlength;
187  }
188  else
189  {
190  x = n * sizeof(RTCPReceiverReport);
191  d = n / 31; // max 31 reportblocks per report
192  r = n % 31;
193  if (r != 0)
194  d++;
195  x += d * (sizeof(RTCPCommonHeader) + sizeof(uint32_t)); /* header and SSRC */
196  if (isSR)
197  x += sizeof(RTCPSenderReport);
198  }
199  return x;
200  }
201 
203  {
204  std::size_t x, n, d, r;
205  n = reportblocks.size() + 1; // +1 for the extra block
206  x = n * sizeof(RTCPReceiverReport);
207  d = n / 31; // max 31 reportblocks per report
208  r = n % 31;
209  if (r != 0)
210  d++;
211  x += d * (sizeof(RTCPCommonHeader) + sizeof(uint32_t)); /* header and SSRC */
212  if (isSR)
213  x += sizeof(RTCPSenderReport);
214  return x;
215  }
216 
217  bool isSR;
218 
220  uint32_t headerdata32[(sizeof(uint32_t) + sizeof(RTCPSenderReport)) / sizeof(uint32_t)]; // either for ssrc and sender info or just ssrc
221  std::size_t headerlength;
222  std::list<Buffer> reportblocks;
223  };
224 
226  {
227  public:
229  ssrc(s), totalitemsize(0)
230  {
231  }
233  {
234  std::list<Buffer>::const_iterator it;
235  for (it = items.begin(); it != items.end(); it++)
236  {
237  if ((*it).packetdata)
238  delete[] (*it).packetdata;
239  }
240  items.clear();
241  }
242 
243  std::size_t NeededBytes()
244  {
245  std::size_t x, r;
246  x = totalitemsize + 1; // +1 for the 0 byte which terminates the item list
247  r = x % sizeof(uint32_t);
248  if (r != 0)
249  x += (sizeof(uint32_t) - r); // make sure it ends on a 32 bit boundary
250  x += sizeof(uint32_t); // for ssrc
251  return x;
252  }
253 
254  std::size_t NeededBytesWithExtraItem(uint8_t itemdatalength)
255  {
256  std::size_t x, r;
257  x = totalitemsize + sizeof(RTCPSDESHeader) + (std::size_t) itemdatalength + 1;
258  r = x % sizeof(uint32_t);
259  if (r != 0)
260  x += (sizeof(uint32_t) - r); // make sure it ends on a 32 bit boundary
261  x += sizeof(uint32_t); // for ssrc
262  return x;
263  }
264 
265  void AddItem(uint8_t *buf, std::size_t len)
266  {
267  Buffer b(buf, len);
268  totalitemsize += len;
269  items.push_back(b);
270  }
271 
273  std::list<Buffer> items;
274  private:
275  std::size_t totalitemsize;
276  };
277 
278  class SDES
279  {
280  public:
282  {
283  sdesit = sdessources.end();
284  }
286  {
287  Clear();
288  }
289 
290  void Clear()
291  {
292  std::list<SDESSource *>::const_iterator it;
293 
294  for (it = sdessources.begin(); it != sdessources.end(); it++)
295  delete *it;
296  sdessources.clear();
297  }
298 
299  int AddSSRC(uint32_t ssrc)
300  {
301  SDESSource *s = new SDESSource(ssrc);
302  sdessources.push_back(s);
303  sdesit = sdessources.end();
304  sdesit--;
305  return 0;
306  }
307 
308  int AddItem(uint8_t *buf, std::size_t len)
309  {
310  if (sdessources.empty())
312  (*sdesit)->AddItem(buf, len);
313  return 0;
314  }
315 
316  std::size_t NeededBytes()
317  {
318  std::list<SDESSource *>::const_iterator it;
319  std::size_t x = 0;
320  std::size_t n, d, r;
321 
322  if (sdessources.empty())
323  return 0;
324 
325  for (it = sdessources.begin(); it != sdessources.end(); it++)
326  x += (*it)->NeededBytes();
327  n = sdessources.size();
328  d = n / 31;
329  r = n % 31;
330  if (r != 0)
331  d++;
332  x += d * sizeof(RTCPCommonHeader);
333  return x;
334  }
335 
336  std::size_t NeededBytesWithExtraItem(uint8_t itemdatalength)
337  {
338  std::list<SDESSource *>::const_iterator it;
339  std::size_t x = 0;
340  std::size_t n, d, r;
341 
342  if (sdessources.empty())
343  return 0;
344 
345  for (it = sdessources.begin(); it != sdesit; it++)
346  x += (*it)->NeededBytes();
347  x += (*sdesit)->NeededBytesWithExtraItem(itemdatalength);
348  n = sdessources.size();
349  d = n / 31;
350  r = n % 31;
351  if (r != 0)
352  d++;
353  x += d * sizeof(RTCPCommonHeader);
354  return x;
355  }
356 
358  {
359  std::list<SDESSource *>::const_iterator it;
360  std::size_t x = 0;
361  std::size_t n, d, r;
362 
363  if (sdessources.empty())
364  return 0;
365 
366  for (it = sdessources.begin(); it != sdessources.end(); it++)
367  x += (*it)->NeededBytes();
368 
369  // for the extra source we'll need at least 8 bytes (ssrc and four 0 bytes)
370  x += sizeof(uint32_t) * 2;
371 
372  n = sdessources.size() + 1; // also, the number of sources will increase
373  d = n / 31;
374  r = n % 31;
375  if (r != 0)
376  d++;
377  x += d * sizeof(RTCPCommonHeader);
378  return x;
379  }
380 
381  std::list<SDESSource *> sdessources;
382  private:
383  std::list<SDESSource *>::const_iterator sdesit;
384  };
385 
387  std::size_t maximumpacketsize;
389  bool external;
391 
394 
395  std::list<Buffer> byepackets;
396  std::size_t byesize;
397 
398  std::list<Buffer> apppackets;
399  std::size_t appsize;
400 
401  void ClearBuildBuffers();
402 };
403 
404 } // end namespace
405 
406 #endif // RTCPCOMPOUNDPACKETBUILDER_H
407 
std::size_t NeededBytesWithExtraItem(uint8_t itemdatalength)
#define QRTPLIB_API
Definition: export.h:112
unsigned int uint32_t
Definition: rtptypes_win.h:46
unsigned char uint8_t
Definition: rtptypes_win.h:42
int int32_t
Definition: rtptypes_win.h:45
std::size_t NeededBytesWithExtraItem(uint8_t itemdatalength)
int AddItem(uint8_t *buf, std::size_t len)
#define ERR_RTP_RTCPCOMPPACKBUILDER_NOCURRENTSOURCE
Definition: rtperrors.h:92
std::list< SDESSource * >::const_iterator sdesit