rtcpcompoundpacketbuilder.h

Go to the documentation of this file.
00001 /*
00002 
00003   This file is a part of JRTPLIB
00004   Copyright (c) 1999-2007 Jori Liesenborgs
00005 
00006   Contact: jori.liesenborgs@gmail.com
00007 
00008   This library was developed at the "Expertisecentrum Digitale Media"
00009   (http://www.edm.uhasselt.be), a research center of the Hasselt University
00010   (http://www.uhasselt.be). The library is based upon work done for 
00011   my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
00012 
00013   Permission is hereby granted, free of charge, to any person obtaining a
00014   copy of this software and associated documentation files (the "Software"),
00015   to deal in the Software without restriction, including without limitation
00016   the rights to use, copy, modify, merge, publish, distribute, sublicense,
00017   and/or sell copies of the Software, and to permit persons to whom the
00018   Software is furnished to do so, subject to the following conditions:
00019 
00020   The above copyright notice and this permission notice shall be included
00021   in all copies or substantial portions of the Software.
00022 
00023   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00024   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00025   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00026   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00027   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00028   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
00029   IN THE SOFTWARE.
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; // max 31 reportblocks per report
00178                                 r = n%31;
00179                                 if (r != 0)
00180                                         d++;
00181                                 x += d*(sizeof(RTCPCommonHeader)+sizeof(uint32_t)); /* header and SSRC */
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; // +1 for the extra block
00192                         x = n*sizeof(RTCPReceiverReport);
00193                         d = n/31; // max 31 reportblocks per report
00194                         r = n%31;
00195                         if (r != 0)
00196                                 d++;
00197                         x += d*(sizeof(RTCPCommonHeader)+sizeof(uint32_t)); /* header and SSRC */
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)]; // either for ssrc and sender info or just ssrc
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; // +1 for the 0 byte which terminates the item list
00230                         r = x%sizeof(uint32_t);
00231                         if (r != 0)
00232                                 x += (sizeof(uint32_t)-r); // make sure it ends on a 32 bit boundary
00233                         x += sizeof(uint32_t); // for ssrc
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); // make sure it ends on a 32 bit boundary
00244                         x += sizeof(uint32_t); // for ssrc
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                         // for the extra source we'll need at least 8 bytes (ssrc and four 0 bytes)
00349                         x += sizeof(uint32_t)*2;
00350                         
00351                         n = sdessources.size() + 1; // also, the number of sources will increase
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 

Generated on Thu Feb 8 16:22:05 2007 for jrtplib by  doxygen 1.5.1