jrtplib  3.6.0
rtcpcompoundpacketbuilder.h
Go to the documentation of this file.
1 /*
2 
3  This file is a part of JRTPLIB
4  Copyright (c) 1999-2006 Jori Liesenborgs
5 
6  Contact: jori.liesenborgs@gmail.com
7 
8  This library was developed at the "Expertisecentrum Digitale 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 class RTPMemoryManager;
49 
57 {
58 public:
62 
67  int InitBuild(size_t maxpacketsize);
68 
73  int InitBuild(void *externalbuffer,size_t buffersize);
74 
80  int StartSenderReport(uint32_t senderssrc,const RTPNTPTime &ntptimestamp,uint32_t rtptimestamp,
81  uint32_t packetcount,uint32_t octetcount);
82 
88  int StartReceiverReport(uint32_t senderssrc);
89 
94  int AddReportBlock(uint32_t ssrc,uint8_t fractionlost,int32_t packetslost,uint32_t exthighestseq,
95  uint32_t jitter,uint32_t lsr,uint32_t dlsr);
96 
98  int AddSDESSource(uint32_t ssrc);
99 
104  int AddSDESNormalItem(RTCPSDESPacket::ItemType t,const void *itemdata,uint8_t itemlength);
105 #ifdef RTP_SUPPORT_SDESPRIV
106 
107  int AddSDESPrivateItem(const void *prefixdata,uint8_t prefixlength,const void *valuedata,
108  uint8_t valuelength);
109 #endif // RTP_SUPPORT_SDESPRIV
110 
116  int AddBYEPacket(uint32_t *ssrcs,uint8_t numssrcs,const void *reasondata,uint8_t reasonlength);
117 
122  int AddAPPPacket(uint8_t subtype,uint32_t ssrc,const uint8_t name[4],const void *appdata,size_t appdatalen);
123 
128  int EndBuild();
129 private:
130  class Buffer
131  {
132  public:
133  Buffer():packetdata(0),packetlength(0) { }
134  Buffer(uint8_t *data,size_t len):packetdata(data),packetlength(len) { }
135 
136  uint8_t *packetdata;
137  size_t packetlength;
138  };
139 
140  class Report : public RTPMemoryObject
141  {
142  public:
143  Report(RTPMemoryManager *mgr) : RTPMemoryObject(mgr)
144  {
145  headerdata = (uint8_t *)headerdata32;
146  isSR = false;
147  headerlength = 0;
148  }
149  ~Report() { Clear(); }
150 
151  void Clear()
152  {
153  std::list<Buffer>::const_iterator it;
154  for (it = reportblocks.begin() ; it != reportblocks.end() ; it++)
155  {
156  if ((*it).packetdata)
157  RTPDeleteByteArray((*it).packetdata,GetMemoryManager());
158  }
159  reportblocks.clear();
160  isSR = false;
161  headerlength = 0;
162  }
163 
164  size_t NeededBytes()
165  {
166  size_t x,n,d,r;
167  n = reportblocks.size();
168  if (n == 0)
169  {
170  if (headerlength == 0)
171  return 0;
172  x = sizeof(RTCPCommonHeader)+headerlength;
173  }
174  else
175  {
176  x = n*sizeof(RTCPReceiverReport);
177  d = n/31; // max 31 reportblocks per report
178  r = n%31;
179  if (r != 0)
180  d++;
181  x += d*(sizeof(RTCPCommonHeader)+sizeof(uint32_t)); /* header and SSRC */
182  if (isSR)
183  x += sizeof(RTCPSenderReport);
184  }
185  return x;
186  }
187 
188  size_t NeededBytesWithExtraReportBlock()
189  {
190  size_t x,n,d,r;
191  n = reportblocks.size() + 1; // +1 for the extra block
192  x = n*sizeof(RTCPReceiverReport);
193  d = n/31; // max 31 reportblocks per report
194  r = n%31;
195  if (r != 0)
196  d++;
197  x += d*(sizeof(RTCPCommonHeader)+sizeof(uint32_t)); /* header and SSRC */
198  if (isSR)
199  x += sizeof(RTCPSenderReport);
200  return x;
201  }
202 
203  bool isSR;
204 
205  uint8_t *headerdata;
206  uint32_t headerdata32[(sizeof(uint32_t)+sizeof(RTCPSenderReport))/sizeof(uint32_t)]; // either for ssrc and sender info or just ssrc
207  size_t headerlength;
208  std::list<Buffer> reportblocks;
209  };
210 
211  class SDESSource : public RTPMemoryObject
212  {
213  public:
214  SDESSource(uint32_t s,RTPMemoryManager *mgr) : RTPMemoryObject(mgr),ssrc(s),totalitemsize(0) { }
215  ~SDESSource()
216  {
217  std::list<Buffer>::const_iterator it;
218  for (it = items.begin() ; it != items.end() ; it++)
219  {
220  if ((*it).packetdata)
221  RTPDeleteByteArray((*it).packetdata,GetMemoryManager());
222  }
223  items.clear();
224  }
225 
226  size_t NeededBytes()
227  {
228  size_t x,r;
229  x = totalitemsize + 1; // +1 for the 0 byte which terminates the item list
230  r = x%sizeof(uint32_t);
231  if (r != 0)
232  x += (sizeof(uint32_t)-r); // make sure it ends on a 32 bit boundary
233  x += sizeof(uint32_t); // for ssrc
234  return x;
235  }
236 
237  size_t NeededBytesWithExtraItem(uint8_t itemdatalength)
238  {
239  size_t x,r;
240  x = totalitemsize + sizeof(RTCPSDESHeader) + (size_t)itemdatalength + 1;
241  r = x%sizeof(uint32_t);
242  if (r != 0)
243  x += (sizeof(uint32_t)-r); // make sure it ends on a 32 bit boundary
244  x += sizeof(uint32_t); // for ssrc
245  return x;
246  }
247 
248  void AddItem(uint8_t *buf,size_t len)
249  {
250  Buffer b(buf,len);
251  totalitemsize += len;
252  items.push_back(b);
253  }
254 
255  uint32_t ssrc;
256  std::list<Buffer> items;
257  private:
258  size_t totalitemsize;
259  };
260 
261  class SDES : public RTPMemoryObject
262  {
263  public:
264  SDES(RTPMemoryManager *mgr) : RTPMemoryObject(mgr) { sdesit = sdessources.end(); }
265  ~SDES() { Clear(); }
266 
267  void Clear()
268  {
269  std::list<SDESSource *>::const_iterator it;
270 
271  for (it = sdessources.begin() ; it != sdessources.end() ; it++)
272  RTPDelete(*it,GetMemoryManager());
273  sdessources.clear();
274  }
275 
276  int AddSSRC(uint32_t ssrc)
277  {
278  SDESSource *s = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_SDESSOURCE) SDESSource(ssrc,GetMemoryManager());
279  if (s == 0)
280  return ERR_RTP_OUTOFMEM;
281  sdessources.push_back(s);
282  sdesit = sdessources.end();
283  sdesit--;
284  return 0;
285  }
286 
287  int AddItem(uint8_t *buf,size_t len)
288  {
289  if (sdessources.empty())
290  return ERR_RTP_RTCPCOMPPACKBUILDER_NOCURRENTSOURCE;
291  (*sdesit)->AddItem(buf,len);
292  return 0;
293  }
294 
295  size_t NeededBytes()
296  {
297  std::list<SDESSource *>::const_iterator it;
298  size_t x = 0;
299  size_t n,d,r;
300 
301  if (sdessources.empty())
302  return 0;
303 
304  for (it = sdessources.begin() ; it != sdessources.end() ; it++)
305  x += (*it)->NeededBytes();
306  n = sdessources.size();
307  d = n/31;
308  r = n%31;
309  if (r != 0)
310  d++;
311  x += d*sizeof(RTCPCommonHeader);
312  return x;
313  }
314 
315  size_t NeededBytesWithExtraItem(uint8_t itemdatalength)
316  {
317  std::list<SDESSource *>::const_iterator it;
318  size_t x = 0;
319  size_t n,d,r;
320 
321  if (sdessources.empty())
322  return 0;
323 
324  for (it = sdessources.begin() ; it != sdesit ; it++)
325  x += (*it)->NeededBytes();
326  x += (*sdesit)->NeededBytesWithExtraItem(itemdatalength);
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  size_t NeededBytesWithExtraSource()
337  {
338  std::list<SDESSource *>::const_iterator it;
339  size_t x = 0;
340  size_t n,d,r;
341 
342  if (sdessources.empty())
343  return 0;
344 
345  for (it = sdessources.begin() ; it != sdessources.end() ; it++)
346  x += (*it)->NeededBytes();
347 
348  // for the extra source we'll need at least 8 bytes (ssrc and four 0 bytes)
349  x += sizeof(uint32_t)*2;
350 
351  n = sdessources.size() + 1; // also, the number of sources will increase
352  d = n/31;
353  r = n%31;
354  if (r != 0)
355  d++;
356  x += d*sizeof(RTCPCommonHeader);
357  return x;
358  }
359 
360  std::list<SDESSource *> sdessources;
361  private:
362  std::list<SDESSource *>::const_iterator sdesit;
363  };
364 
365  size_t maximumpacketsize;
366  uint8_t *buffer;
367  bool external;
368  bool arebuilding;
369 
370  Report report;
371  SDES sdes;
372 
373  std::list<Buffer> byepackets;
374  size_t byesize;
375 
376  std::list<Buffer> apppackets;
377  size_t appsize;
378 
379  void ClearBuildBuffers();
380 };
381 
382 #endif // RTCPCOMPOUNDPACKETBUILDER_H
383 
int AddSDESNormalItem(RTCPSDESPacket::ItemType t, const void *itemdata, uint8_t itemlength)
Adds a normal (non-private) SDES item of type t to the current SDES chunk.
RTCPCompoundPacketBuilder(RTPMemoryManager *memmgr=0)
Constructs an RTCPCompoundPacketBuilder instance, optionally installing a memory manager.
A memory manager.
Definition: rtpmemorymanager.h:144
int StartReceiverReport(uint32_t senderssrc)
Adds a receiver report to the compound packet.
int AddAPPPacket(uint8_t subtype, uint32_t ssrc, const uint8_t name[4], const void *appdata, size_t appdatalen)
Adds the APP packet specified by the arguments to the compound packet.
Represents an RTCP compound packet.
Definition: rtcpcompoundpacket.h:50
int StartSenderReport(uint32_t senderssrc, const RTPNTPTime &ntptimestamp, uint32_t rtptimestamp, uint32_t packetcount, uint32_t octetcount)
Adds a sender report to the compound packet.
This class can be used to construct an RTCP compound packet.
Definition: rtcpcompoundpacketbuilder.h:56
int AddReportBlock(uint32_t ssrc, uint8_t fractionlost, int32_t packetslost, uint32_t exthighestseq, uint32_t jitter, uint32_t lsr, uint32_t dlsr)
Adds the report block information specified by the function's arguments.
int AddBYEPacket(uint32_t *ssrcs, uint8_t numssrcs, const void *reasondata, uint8_t reasonlength)
Adds a BYE packet to the compound packet.
int AddSDESSource(uint32_t ssrc)
Starts an SDES chunk for participant ssrc.
#define RTPMEM_TYPE_CLASS_SDESSOURCE
Buffer to store an SDESSource instance.
Definition: rtpmemorymanager.h:138
ItemType
Identifies the type of an SDES item.
Definition: rtcpsdespacket.h:56
int InitBuild(size_t maxpacketsize)
Starts building an RTCP compound packet with maximum size maxpacketsize.
int EndBuild()
Finishes building the compound packet.
This is a simple wrapper for the most significant word (MSW) and least significant word (LSW) of an N...
Definition: rtptimeutilities.h:58
int AddSDESPrivateItem(const void *prefixdata, uint8_t prefixlength, const void *valuedata, uint8_t valuelength)
Adds an SDES PRIV item described by the function's arguments to the current SDES chunk.