00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00037 #ifndef RTCPCOMPOUNDPACKETBUILDER_H
00038
00039 #define RTCPCOMPOUNDPACKETBUILDER_H
00040
00041 #include "rtpconfig.h"
00042 #include "rtcpcompoundpacket.h"
00043 #include "rtptimeutilities.h"
00044 #include "rtcpsdespacket.h"
00045 #include "rtperrors.h"
00046 #include <list>
00047
00048 class RTPMemoryManager;
00049
00056 class RTCPCompoundPacketBuilder : public RTCPCompoundPacket
00057 {
00058 public:
00060 RTCPCompoundPacketBuilder(RTPMemoryManager *memmgr = 0);
00061 ~RTCPCompoundPacketBuilder();
00062
00067 int InitBuild(size_t maxpacketsize);
00068
00073 int InitBuild(void *externalbuffer,size_t buffersize);
00074
00080 int StartSenderReport(uint32_t senderssrc,const RTPNTPTime &ntptimestamp,uint32_t rtptimestamp,
00081 uint32_t packetcount,uint32_t octetcount);
00082
00088 int StartReceiverReport(uint32_t senderssrc);
00089
00094 int AddReportBlock(uint32_t ssrc,uint8_t fractionlost,int32_t packetslost,uint32_t exthighestseq,
00095 uint32_t jitter,uint32_t lsr,uint32_t dlsr);
00096
00098 int AddSDESSource(uint32_t ssrc);
00099
00104 int AddSDESNormalItem(RTCPSDESPacket::ItemType t,const void *itemdata,uint8_t itemlength);
00105 #ifdef RTP_SUPPORT_SDESPRIV
00106
00107 int AddSDESPrivateItem(const void *prefixdata,uint8_t prefixlength,const void *valuedata,
00108 uint8_t valuelength);
00109 #endif // RTP_SUPPORT_SDESPRIV
00110
00116 int AddBYEPacket(uint32_t *ssrcs,uint8_t numssrcs,const void *reasondata,uint8_t reasonlength);
00117
00122 int AddAPPPacket(uint8_t subtype,uint32_t ssrc,const uint8_t name[4],const void *appdata,size_t appdatalen);
00123
00128 int EndBuild();
00129 private:
00130 class Buffer
00131 {
00132 public:
00133 Buffer():packetdata(0),packetlength(0) { }
00134 Buffer(uint8_t *data,size_t len):packetdata(data),packetlength(len) { }
00135
00136 uint8_t *packetdata;
00137 size_t packetlength;
00138 };
00139
00140 class Report : public RTPMemoryObject
00141 {
00142 public:
00143 Report(RTPMemoryManager *mgr) : RTPMemoryObject(mgr)
00144 {
00145 headerdata = (uint8_t *)headerdata32;
00146 isSR = false;
00147 headerlength = 0;
00148 }
00149 ~Report() { Clear(); }
00150
00151 void Clear()
00152 {
00153 std::list<Buffer>::const_iterator it;
00154 for (it = reportblocks.begin() ; it != reportblocks.end() ; it++)
00155 {
00156 if ((*it).packetdata)
00157 RTPDeleteByteArray((*it).packetdata,GetMemoryManager());
00158 }
00159 reportblocks.clear();
00160 isSR = false;
00161 headerlength = 0;
00162 }
00163
00164 size_t NeededBytes()
00165 {
00166 size_t x,n,d,r;
00167 n = reportblocks.size();
00168 if (n == 0)
00169 {
00170 if (headerlength == 0)
00171 return 0;
00172 x = sizeof(RTCPCommonHeader)+headerlength;
00173 }
00174 else
00175 {
00176 x = n*sizeof(RTCPReceiverReport);
00177 d = n/31;
00178 r = n%31;
00179 if (r != 0)
00180 d++;
00181 x += d*(sizeof(RTCPCommonHeader)+sizeof(uint32_t));
00182 if (isSR)
00183 x += sizeof(RTCPSenderReport);
00184 }
00185 return x;
00186 }
00187
00188 size_t NeededBytesWithExtraReportBlock()
00189 {
00190 size_t x,n,d,r;
00191 n = reportblocks.size() + 1;
00192 x = n*sizeof(RTCPReceiverReport);
00193 d = n/31;
00194 r = n%31;
00195 if (r != 0)
00196 d++;
00197 x += d*(sizeof(RTCPCommonHeader)+sizeof(uint32_t));
00198 if (isSR)
00199 x += sizeof(RTCPSenderReport);
00200 return x;
00201 }
00202
00203 bool isSR;
00204
00205 uint8_t *headerdata;
00206 uint32_t headerdata32[(sizeof(uint32_t)+sizeof(RTCPSenderReport))/sizeof(uint32_t)];
00207 size_t headerlength;
00208 std::list<Buffer> reportblocks;
00209 };
00210
00211 class SDESSource : public RTPMemoryObject
00212 {
00213 public:
00214 SDESSource(uint32_t s,RTPMemoryManager *mgr) : RTPMemoryObject(mgr),ssrc(s),totalitemsize(0) { }
00215 ~SDESSource()
00216 {
00217 std::list<Buffer>::const_iterator it;
00218 for (it = items.begin() ; it != items.end() ; it++)
00219 {
00220 if ((*it).packetdata)
00221 RTPDeleteByteArray((*it).packetdata,GetMemoryManager());
00222 }
00223 items.clear();
00224 }
00225
00226 size_t NeededBytes()
00227 {
00228 size_t x,r;
00229 x = totalitemsize + 1;
00230 r = x%sizeof(uint32_t);
00231 if (r != 0)
00232 x += (sizeof(uint32_t)-r);
00233 x += sizeof(uint32_t);
00234 return x;
00235 }
00236
00237 size_t NeededBytesWithExtraItem(uint8_t itemdatalength)
00238 {
00239 size_t x,r;
00240 x = totalitemsize + sizeof(RTCPSDESHeader) + (size_t)itemdatalength + 1;
00241 r = x%sizeof(uint32_t);
00242 if (r != 0)
00243 x += (sizeof(uint32_t)-r);
00244 x += sizeof(uint32_t);
00245 return x;
00246 }
00247
00248 void AddItem(uint8_t *buf,size_t len)
00249 {
00250 Buffer b(buf,len);
00251 totalitemsize += len;
00252 items.push_back(b);
00253 }
00254
00255 uint32_t ssrc;
00256 std::list<Buffer> items;
00257 private:
00258 size_t totalitemsize;
00259 };
00260
00261 class SDES : public RTPMemoryObject
00262 {
00263 public:
00264 SDES(RTPMemoryManager *mgr) : RTPMemoryObject(mgr) { sdesit = sdessources.end(); }
00265 ~SDES() { Clear(); }
00266
00267 void Clear()
00268 {
00269 std::list<SDESSource *>::const_iterator it;
00270
00271 for (it = sdessources.begin() ; it != sdessources.end() ; it++)
00272 RTPDelete(*it,GetMemoryManager());
00273 sdessources.clear();
00274 }
00275
00276 int AddSSRC(uint32_t ssrc)
00277 {
00278 SDESSource *s = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_SDESSOURCE) SDESSource(ssrc,GetMemoryManager());
00279 if (s == 0)
00280 return ERR_RTP_OUTOFMEM;
00281 sdessources.push_back(s);
00282 sdesit = sdessources.end();
00283 sdesit--;
00284 return 0;
00285 }
00286
00287 int AddItem(uint8_t *buf,size_t len)
00288 {
00289 if (sdessources.empty())
00290 return ERR_RTP_RTCPCOMPPACKBUILDER_NOCURRENTSOURCE;
00291 (*sdesit)->AddItem(buf,len);
00292 return 0;
00293 }
00294
00295 size_t NeededBytes()
00296 {
00297 std::list<SDESSource *>::const_iterator it;
00298 size_t x = 0;
00299 size_t n,d,r;
00300
00301 if (sdessources.empty())
00302 return 0;
00303
00304 for (it = sdessources.begin() ; it != sdessources.end() ; it++)
00305 x += (*it)->NeededBytes();
00306 n = sdessources.size();
00307 d = n/31;
00308 r = n%31;
00309 if (r != 0)
00310 d++;
00311 x += d*sizeof(RTCPCommonHeader);
00312 return x;
00313 }
00314
00315 size_t NeededBytesWithExtraItem(uint8_t itemdatalength)
00316 {
00317 std::list<SDESSource *>::const_iterator it;
00318 size_t x = 0;
00319 size_t n,d,r;
00320
00321 if (sdessources.empty())
00322 return 0;
00323
00324 for (it = sdessources.begin() ; it != sdesit ; it++)
00325 x += (*it)->NeededBytes();
00326 x += (*sdesit)->NeededBytesWithExtraItem(itemdatalength);
00327 n = sdessources.size();
00328 d = n/31;
00329 r = n%31;
00330 if (r != 0)
00331 d++;
00332 x += d*sizeof(RTCPCommonHeader);
00333 return x;
00334 }
00335
00336 size_t NeededBytesWithExtraSource()
00337 {
00338 std::list<SDESSource *>::const_iterator it;
00339 size_t x = 0;
00340 size_t n,d,r;
00341
00342 if (sdessources.empty())
00343 return 0;
00344
00345 for (it = sdessources.begin() ; it != sdessources.end() ; it++)
00346 x += (*it)->NeededBytes();
00347
00348
00349 x += sizeof(uint32_t)*2;
00350
00351 n = sdessources.size() + 1;
00352 d = n/31;
00353 r = n%31;
00354 if (r != 0)
00355 d++;
00356 x += d*sizeof(RTCPCommonHeader);
00357 return x;
00358 }
00359
00360 std::list<SDESSource *> sdessources;
00361 private:
00362 std::list<SDESSource *>::const_iterator sdesit;
00363 };
00364
00365 size_t maximumpacketsize;
00366 uint8_t *buffer;
00367 bool external;
00368 bool arebuilding;
00369
00370 Report report;
00371 SDES sdes;
00372
00373 std::list<Buffer> byepackets;
00374 size_t byesize;
00375
00376 std::list<Buffer> apppackets;
00377 size_t appsize;
00378
00379 void ClearBuildBuffers();
00380 };
00381
00382 #endif // RTCPCOMPOUNDPACKETBUILDER_H
00383