JRTPLIB  3.11.1
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 "rtpconfig.h"
42 #include "rtcpcompoundpacket.h"
43 #include "rtptimeutilities.h"
44 #include "rtcpsdespacket.h"
45 #include "rtperrors.h"
46 #include <list>
47 
48 namespace jrtplib
49 {
50 
51 class RTPMemoryManager;
52 
59 class JRTPLIB_IMPORTEXPORT RTCPCompoundPacketBuilder : public RTCPCompoundPacket
60 {
61 public:
65 
70  int InitBuild(size_t maxpacketsize);
71 
76  int InitBuild(void *externalbuffer,size_t buffersize);
77 
83  int StartSenderReport(uint32_t senderssrc,const RTPNTPTime &ntptimestamp,uint32_t rtptimestamp,
84  uint32_t packetcount,uint32_t octetcount);
85 
91  int StartReceiverReport(uint32_t senderssrc);
92 
97  int AddReportBlock(uint32_t ssrc,uint8_t fractionlost,int32_t packetslost,uint32_t exthighestseq,
98  uint32_t jitter,uint32_t lsr,uint32_t dlsr);
99 
101  int AddSDESSource(uint32_t ssrc);
102 
107  int AddSDESNormalItem(RTCPSDESPacket::ItemType t,const void *itemdata,uint8_t itemlength);
108 #ifdef RTP_SUPPORT_SDESPRIV
109 
110  int AddSDESPrivateItem(const void *prefixdata,uint8_t prefixlength,const void *valuedata,
111  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,size_t appdatalen);
126 
131  int EndBuild();
132 
133 #ifdef RTP_SUPPORT_RTCPUNKNOWN
134 
137  int AddUnknownPacket(uint8_t payload_type, uint8_t subtype, uint32_t ssrc, const void *data, size_t len);
138 #endif // RTP_SUPPORT_RTCPUNKNOWN
139 private:
140  class Buffer
141  {
142  public:
143  Buffer():packetdata(0),packetlength(0) { }
144  Buffer(uint8_t *data,size_t len):packetdata(data),packetlength(len) { }
145 
146  uint8_t *packetdata;
147  size_t packetlength;
148  };
149 
150  class Report : public RTPMemoryObject
151  {
152  public:
153  Report(RTPMemoryManager *mgr) : RTPMemoryObject(mgr)
154  {
155  headerdata = (uint8_t *)headerdata32;
156  isSR = false;
157  headerlength = 0;
158  }
159  ~Report() { Clear(); }
160 
161  void Clear()
162  {
163  std::list<Buffer>::const_iterator it;
164  for (it = reportblocks.begin() ; it != reportblocks.end() ; it++)
165  {
166  if ((*it).packetdata)
167  RTPDeleteByteArray((*it).packetdata,GetMemoryManager());
168  }
169  reportblocks.clear();
170  isSR = false;
171  headerlength = 0;
172  }
173 
174  size_t NeededBytes()
175  {
176  size_t x,n,d,r;
177  n = reportblocks.size();
178  if (n == 0)
179  {
180  if (headerlength == 0)
181  return 0;
182  x = sizeof(RTCPCommonHeader)+headerlength;
183  }
184  else
185  {
186  x = n*sizeof(RTCPReceiverReport);
187  d = n/31; // max 31 reportblocks per report
188  r = n%31;
189  if (r != 0)
190  d++;
191  x += d*(sizeof(RTCPCommonHeader)+sizeof(uint32_t)); /* header and SSRC */
192  if (isSR)
193  x += sizeof(RTCPSenderReport);
194  }
195  return x;
196  }
197 
198  size_t NeededBytesWithExtraReportBlock()
199  {
200  size_t x,n,d,r;
201  n = reportblocks.size() + 1; // +1 for the extra block
202  x = n*sizeof(RTCPReceiverReport);
203  d = n/31; // max 31 reportblocks per report
204  r = n%31;
205  if (r != 0)
206  d++;
207  x += d*(sizeof(RTCPCommonHeader)+sizeof(uint32_t)); /* header and SSRC */
208  if (isSR)
209  x += sizeof(RTCPSenderReport);
210  return x;
211  }
212 
213  bool isSR;
214 
215  uint8_t *headerdata;
216  uint32_t headerdata32[(sizeof(uint32_t)+sizeof(RTCPSenderReport))/sizeof(uint32_t)]; // either for ssrc and sender info or just ssrc
217  size_t headerlength;
218  std::list<Buffer> reportblocks;
219  };
220 
221  class SDESSource : public RTPMemoryObject
222  {
223  public:
224  SDESSource(uint32_t s,RTPMemoryManager *mgr) : RTPMemoryObject(mgr),ssrc(s),totalitemsize(0) { }
225  ~SDESSource()
226  {
227  std::list<Buffer>::const_iterator it;
228  for (it = items.begin() ; it != items.end() ; it++)
229  {
230  if ((*it).packetdata)
231  RTPDeleteByteArray((*it).packetdata,GetMemoryManager());
232  }
233  items.clear();
234  }
235 
236  size_t NeededBytes()
237  {
238  size_t x,r;
239  x = totalitemsize + 1; // +1 for the 0 byte which terminates the item list
240  r = x%sizeof(uint32_t);
241  if (r != 0)
242  x += (sizeof(uint32_t)-r); // make sure it ends on a 32 bit boundary
243  x += sizeof(uint32_t); // for ssrc
244  return x;
245  }
246 
247  size_t NeededBytesWithExtraItem(uint8_t itemdatalength)
248  {
249  size_t x,r;
250  x = totalitemsize + sizeof(RTCPSDESHeader) + (size_t)itemdatalength + 1;
251  r = x%sizeof(uint32_t);
252  if (r != 0)
253  x += (sizeof(uint32_t)-r); // make sure it ends on a 32 bit boundary
254  x += sizeof(uint32_t); // for ssrc
255  return x;
256  }
257 
258  void AddItem(uint8_t *buf,size_t len)
259  {
260  Buffer b(buf,len);
261  totalitemsize += len;
262  items.push_back(b);
263  }
264 
265  uint32_t ssrc;
266  std::list<Buffer> items;
267  private:
268  size_t totalitemsize;
269  };
270 
271  class SDES : public RTPMemoryObject
272  {
273  public:
274  SDES(RTPMemoryManager *mgr) : RTPMemoryObject(mgr) { sdesit = sdessources.end(); }
275  ~SDES() { Clear(); }
276 
277  void Clear()
278  {
279  std::list<SDESSource *>::const_iterator it;
280 
281  for (it = sdessources.begin() ; it != sdessources.end() ; it++)
282  RTPDelete(*it,GetMemoryManager());
283  sdessources.clear();
284  }
285 
286  int AddSSRC(uint32_t ssrc)
287  {
288  SDESSource *s = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_SDESSOURCE) SDESSource(ssrc,GetMemoryManager());
289  if (s == 0)
290  return ERR_RTP_OUTOFMEM;
291  sdessources.push_back(s);
292  sdesit = sdessources.end();
293  sdesit--;
294  return 0;
295  }
296 
297  int AddItem(uint8_t *buf,size_t len)
298  {
299  if (sdessources.empty())
300  return ERR_RTP_RTCPCOMPPACKBUILDER_NOCURRENTSOURCE;
301  (*sdesit)->AddItem(buf,len);
302  return 0;
303  }
304 
305  size_t NeededBytes()
306  {
307  std::list<SDESSource *>::const_iterator it;
308  size_t x = 0;
309  size_t n,d,r;
310 
311  if (sdessources.empty())
312  return 0;
313 
314  for (it = sdessources.begin() ; it != sdessources.end() ; it++)
315  x += (*it)->NeededBytes();
316  n = sdessources.size();
317  d = n/31;
318  r = n%31;
319  if (r != 0)
320  d++;
321  x += d*sizeof(RTCPCommonHeader);
322  return x;
323  }
324 
325  size_t NeededBytesWithExtraItem(uint8_t itemdatalength)
326  {
327  std::list<SDESSource *>::const_iterator it;
328  size_t x = 0;
329  size_t n,d,r;
330 
331  if (sdessources.empty())
332  return 0;
333 
334  for (it = sdessources.begin() ; it != sdesit ; it++)
335  x += (*it)->NeededBytes();
336  x += (*sdesit)->NeededBytesWithExtraItem(itemdatalength);
337  n = sdessources.size();
338  d = n/31;
339  r = n%31;
340  if (r != 0)
341  d++;
342  x += d*sizeof(RTCPCommonHeader);
343  return x;
344  }
345 
346  size_t NeededBytesWithExtraSource()
347  {
348  std::list<SDESSource *>::const_iterator it;
349  size_t x = 0;
350  size_t n,d,r;
351 
352  if (sdessources.empty())
353  return 0;
354 
355  for (it = sdessources.begin() ; it != sdessources.end() ; it++)
356  x += (*it)->NeededBytes();
357 
358  // for the extra source we'll need at least 8 bytes (ssrc and four 0 bytes)
359  x += sizeof(uint32_t)*2;
360 
361  n = sdessources.size() + 1; // also, the number of sources will increase
362  d = n/31;
363  r = n%31;
364  if (r != 0)
365  d++;
366  x += d*sizeof(RTCPCommonHeader);
367  return x;
368  }
369 
370  std::list<SDESSource *> sdessources;
371  private:
372  std::list<SDESSource *>::const_iterator sdesit;
373  };
374 
375  size_t maximumpacketsize;
376  uint8_t *buffer;
377  bool external;
378  bool arebuilding;
379 
380  Report report;
381  SDES sdes;
382 
383  std::list<Buffer> byepackets;
384  size_t byesize;
385 
386  std::list<Buffer> apppackets;
387  size_t appsize;
388 
389 #ifdef RTP_SUPPORT_RTCPUNKNOWN
390  std::list<Buffer> unknownpackets;
391  size_t unknownsize;
392 #endif // RTP_SUPPORT_RTCPUNKNOWN
393 
394  void ClearBuildBuffers();
395 };
396 
397 } // end namespace
398 
399 #endif // RTCPCOMPOUNDPACKETBUILDER_H
400 
Represents an RTCP compound packet.
Definition: rtcpcompoundpacket.h:53
This is a simple wrapper for the most significant word (MSW) and least significant word (LSW) of an N...
Definition: rtptimeutilities.h:65
ItemType
Identifies the type of an SDES item.
Definition: rtcpsdespacket.h:59
#define RTPMEM_TYPE_CLASS_SDESSOURCE
Buffer to store an SDESSource instance.
Definition: rtpmemorymanager.h:138
Definition: rtpfaketransmitter.h:64
A memory manager.
Definition: rtpmemorymanager.h:150
This class can be used to construct an RTCP compound packet.
Definition: rtcpcompoundpacketbuilder.h:59