| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  This file is a part of JRTPLIB | 
					
						
							|  |  |  |  Copyright (c) 1999-2017 Jori Liesenborgs | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  Contact: jori.liesenborgs@gmail.com | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  This library was developed at the Expertise Centre for Digital Media | 
					
						
							|  |  |  |  (http://www.edm.uhasselt.be), a research center of the Hasselt University
 | 
					
						
							|  |  |  |  (http://www.uhasselt.be). The library is based upon work done for
 | 
					
						
							|  |  |  |  my thesis at the School for Knowledge Technology (Belgium/The Netherlands). | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  Permission is hereby granted, free of charge, to any person obtaining a | 
					
						
							|  |  |  |  copy of this software and associated documentation files (the "Software"), | 
					
						
							|  |  |  |  to deal in the Software without restriction, including without limitation | 
					
						
							|  |  |  |  the rights to use, copy, modify, merge, publish, distribute, sublicense, | 
					
						
							|  |  |  |  and/or sell copies of the Software, and to permit persons to whom the | 
					
						
							|  |  |  |  Software is furnished to do so, subject to the following conditions: | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  The above copyright notice and this permission notice shall be included | 
					
						
							|  |  |  |  in all copies or substantial portions of the Software. | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | 
					
						
							|  |  |  |  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
					
						
							|  |  |  |  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL | 
					
						
							|  |  |  |  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | 
					
						
							|  |  |  |  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | 
					
						
							|  |  |  |  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | 
					
						
							|  |  |  |  IN THE SOFTWARE. | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "rtcppacketbuilder.h"
 | 
					
						
							|  |  |  | #include "rtpsources.h"
 | 
					
						
							|  |  |  | #include "rtppacketbuilder.h"
 | 
					
						
							|  |  |  | #include "rtcpscheduler.h"
 | 
					
						
							|  |  |  | #include "rtpsourcedata.h"
 | 
					
						
							|  |  |  | #include "rtcpcompoundpacketbuilder.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace qrtplib | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | RTCPPacketBuilder::RTCPPacketBuilder(RTPSources &s, RTPPacketBuilder &pb) : | 
					
						
							|  |  |  |         sources(s), rtppacketbuilder(pb), prevbuildtime(0, 0), transmissiondelay(0, 0) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     init = false; | 
					
						
							|  |  |  |     timeinit.Dummy(); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RTCPPacketBuilder::~RTCPPacketBuilder() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     Destroy(); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  | int RTCPPacketBuilder::Init(std::size_t maxpacksize, double tsunit, const void *cname, std::size_t cnamelen) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (init) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPPACKETBUILDER_ALREADYINIT; | 
					
						
							|  |  |  |     if (maxpacksize < RTP_MINPACKETSIZE) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPPACKETBUILDER_ILLEGALMAXPACKSIZE; | 
					
						
							|  |  |  |     if (tsunit < 0.0) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPPACKETBUILDER_ILLEGALTIMESTAMPUNIT; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (cnamelen > 255) | 
					
						
							|  |  |  |         cnamelen = 255; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     maxpacketsize = maxpacksize; | 
					
						
							|  |  |  |     timestampunit = tsunit; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     int status; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if ((status = ownsdesinfo.SetCNAME((const uint8_t *) cname, cnamelen)) < 0) | 
					
						
							|  |  |  |         return status; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     ClearAllSourceFlags(); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     interval_name = -1; | 
					
						
							|  |  |  |     interval_email = -1; | 
					
						
							|  |  |  |     interval_location = -1; | 
					
						
							|  |  |  |     interval_phone = -1; | 
					
						
							|  |  |  |     interval_tool = -1; | 
					
						
							|  |  |  |     interval_note = -1; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     sdesbuildcount = 0; | 
					
						
							|  |  |  |     transmissiondelay = RTPTime(0, 0); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     firstpacket = true; | 
					
						
							|  |  |  |     processingsdes = false; | 
					
						
							|  |  |  |     init = true; | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RTCPPacketBuilder::Destroy() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (!init) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     ownsdesinfo.Clear(); | 
					
						
							|  |  |  |     init = false; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int RTCPPacketBuilder::BuildNextPacket(RTCPCompoundPacket **pack) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (!init) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPPACKETBUILDER_NOTINIT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     RTCPCompoundPacketBuilder *rtcpcomppack; | 
					
						
							|  |  |  |     int status; | 
					
						
							|  |  |  |     bool sender = false; | 
					
						
							|  |  |  |     RTPSourceData *srcdat; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     *pack = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     rtcpcomppack = new RTCPCompoundPacketBuilder(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((status = rtcpcomppack->InitBuild(maxpacketsize)) < 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         delete rtcpcomppack; | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((srcdat = sources.GetOwnSourceInfo()) != 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (srcdat->IsSender()) | 
					
						
							|  |  |  |             sender = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     uint32_t ssrc = rtppacketbuilder.GetSSRC(); | 
					
						
							|  |  |  |     RTPTime curtime = RTPTime::CurrentTime(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (sender) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         RTPTime rtppacktime = rtppacketbuilder.GetPacketTime(); | 
					
						
							|  |  |  |         uint32_t rtppacktimestamp = rtppacketbuilder.GetPacketTimestamp(); | 
					
						
							|  |  |  |         uint32_t packcount = rtppacketbuilder.GetPacketCount(); | 
					
						
							|  |  |  |         uint32_t octetcount = rtppacketbuilder.GetPayloadOctetCount(); | 
					
						
							|  |  |  |         RTPTime diff = curtime; | 
					
						
							|  |  |  |         diff -= rtppacktime; | 
					
						
							|  |  |  |         diff += transmissiondelay; // the sample being sampled at this very instant will need a larger timestamp
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         uint32_t tsdiff = (uint32_t) ((diff.GetDouble() / timestampunit) + 0.5); | 
					
						
							|  |  |  |         uint32_t rtptimestamp = rtppacktimestamp + tsdiff; | 
					
						
							|  |  |  |         RTPNTPTime ntptimestamp = curtime.GetNTPTime(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ((status = rtcpcomppack->StartSenderReport(ssrc, ntptimestamp, rtptimestamp, packcount, octetcount)) < 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             delete rtcpcomppack; | 
					
						
							|  |  |  |             if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) | 
					
						
							|  |  |  |                 return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON; | 
					
						
							|  |  |  |             return status; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if ((status = rtcpcomppack->StartReceiverReport(ssrc)) < 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             delete rtcpcomppack; | 
					
						
							|  |  |  |             if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) | 
					
						
							|  |  |  |                 return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON; | 
					
						
							|  |  |  |             return status; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     uint8_t *owncname; | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |     std::size_t owncnamelen; | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     owncname = ownsdesinfo.GetCNAME(&owncnamelen); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((status = rtcpcomppack->AddSDESSource(ssrc)) < 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         delete rtcpcomppack; | 
					
						
							|  |  |  |         if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) | 
					
						
							|  |  |  |             return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON; | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if ((status = rtcpcomppack->AddSDESNormalItem(RTCPSDESPacket::CNAME, owncname, owncnamelen)) < 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         delete rtcpcomppack; | 
					
						
							|  |  |  |         if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) | 
					
						
							|  |  |  |             return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON; | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!processingsdes) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         int added, skipped; | 
					
						
							|  |  |  |         bool full, atendoflist; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ((status = FillInReportBlocks(rtcpcomppack, curtime, sources.GetTotalCount(), &full, &added, &skipped, &atendoflist)) < 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             delete rtcpcomppack; | 
					
						
							|  |  |  |             return status; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (full && added == 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             delete rtcpcomppack; | 
					
						
							|  |  |  |             return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!full) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             processingsdes = true; | 
					
						
							|  |  |  |             sdesbuildcount++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             ClearAllSourceFlags(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             doname = false; | 
					
						
							|  |  |  |             doemail = false; | 
					
						
							|  |  |  |             doloc = false; | 
					
						
							|  |  |  |             dophone = false; | 
					
						
							|  |  |  |             dotool = false; | 
					
						
							|  |  |  |             donote = false; | 
					
						
							|  |  |  |             if (interval_name > 0 && ((sdesbuildcount % interval_name) == 0)) | 
					
						
							|  |  |  |                 doname = true; | 
					
						
							|  |  |  |             if (interval_email > 0 && ((sdesbuildcount % interval_email) == 0)) | 
					
						
							|  |  |  |                 doemail = true; | 
					
						
							|  |  |  |             if (interval_location > 0 && ((sdesbuildcount % interval_location) == 0)) | 
					
						
							|  |  |  |                 doloc = true; | 
					
						
							|  |  |  |             if (interval_phone > 0 && ((sdesbuildcount % interval_phone) == 0)) | 
					
						
							|  |  |  |                 dophone = true; | 
					
						
							|  |  |  |             if (interval_tool > 0 && ((sdesbuildcount % interval_tool) == 0)) | 
					
						
							|  |  |  |                 dotool = true; | 
					
						
							|  |  |  |             if (interval_note > 0 && ((sdesbuildcount % interval_note) == 0)) | 
					
						
							|  |  |  |                 donote = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             bool processedall; | 
					
						
							|  |  |  |             int itemcount; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if ((status = FillInSDES(rtcpcomppack, &full, &processedall, &itemcount)) < 0) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 delete rtcpcomppack; | 
					
						
							|  |  |  |                 return status; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (processedall) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 processingsdes = false; | 
					
						
							|  |  |  |                 ClearAllSDESFlags(); | 
					
						
							|  |  |  |                 if (!full && skipped > 0) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     // if the packet isn't full and we skipped some
 | 
					
						
							|  |  |  |                     // sources that we already got in a previous packet,
 | 
					
						
							|  |  |  |                     // we can add some of them now
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     bool atendoflist; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     if ((status = FillInReportBlocks(rtcpcomppack, curtime, skipped, &full, &added, &skipped, &atendoflist)) < 0) | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         delete rtcpcomppack; | 
					
						
							|  |  |  |                         return status; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else // previous sdes processing wasn't finished
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         bool processedall; | 
					
						
							|  |  |  |         int itemcount; | 
					
						
							|  |  |  |         bool full; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ((status = FillInSDES(rtcpcomppack, &full, &processedall, &itemcount)) < 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             delete rtcpcomppack; | 
					
						
							|  |  |  |             return status; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (itemcount == 0) // Big problem: packet size is too small to let any progress happen
 | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             delete rtcpcomppack; | 
					
						
							|  |  |  |             return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (processedall) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             processingsdes = false; | 
					
						
							|  |  |  |             ClearAllSDESFlags(); | 
					
						
							|  |  |  |             if (!full) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 // if the packet isn't full and we skipped some
 | 
					
						
							|  |  |  |                 // we can add some report blocks
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 int added, skipped; | 
					
						
							|  |  |  |                 bool atendoflist; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if ((status = FillInReportBlocks(rtcpcomppack, curtime, sources.GetTotalCount(), &full, &added, &skipped, &atendoflist)) < 0) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     delete rtcpcomppack; | 
					
						
							|  |  |  |                     return status; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 if (atendoflist) // filled in all possible sources
 | 
					
						
							|  |  |  |                     ClearAllSourceFlags(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((status = rtcpcomppack->EndBuild()) < 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         delete rtcpcomppack; | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     *pack = rtcpcomppack; | 
					
						
							|  |  |  |     firstpacket = false; | 
					
						
							|  |  |  |     prevbuildtime = curtime; | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RTCPPacketBuilder::ClearAllSourceFlags() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (sources.GotoFirstSource()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         do | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             RTPSourceData *srcdat = sources.GetCurrentSourceInfo(); | 
					
						
							|  |  |  |             srcdat->SetProcessedInRTCP(false); | 
					
						
							|  |  |  |         } while (sources.GotoNextSource()); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | int RTCPPacketBuilder::FillInReportBlocks(RTCPCompoundPacketBuilder *rtcpcomppack, const RTPTime &curtime, int maxcount, bool *full, int *added, int *skipped, bool *atendoflist) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     RTPSourceData *srcdat; | 
					
						
							|  |  |  |     int addedcount = 0; | 
					
						
							|  |  |  |     int skippedcount = 0; | 
					
						
							|  |  |  |     bool done = false; | 
					
						
							|  |  |  |     bool filled = false; | 
					
						
							|  |  |  |     bool atend = false; | 
					
						
							|  |  |  |     int status; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (sources.GotoFirstSource()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         do | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             bool shouldprocess = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             srcdat = sources.GetCurrentSourceInfo(); | 
					
						
							|  |  |  |             if (!srcdat->IsOwnSSRC()) // don't send to ourselves
 | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if (!srcdat->IsCSRC()) // p 35: no reports should go to CSRCs
 | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     if (srcdat->INF_HasSentData()) // if this isn't true, INF_GetLastRTPPacketTime() won't make any sense
 | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         if (firstpacket) | 
					
						
							|  |  |  |                             shouldprocess = true; | 
					
						
							|  |  |  |                         else | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                             // p 35: only if rtp packets were received since the last RTP packet, a report block
 | 
					
						
							|  |  |  |                             // should be added
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                             RTPTime lastrtptime = srcdat->INF_GetLastRTPPacketTime(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                             if (lastrtptime > prevbuildtime) | 
					
						
							|  |  |  |                                 shouldprocess = true; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (shouldprocess) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if (srcdat->IsProcessedInRTCP()) // already covered this one
 | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     skippedcount++; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     uint32_t rr_ssrc = srcdat->GetSSRC(); | 
					
						
							|  |  |  |                     uint32_t num = srcdat->INF_GetNumPacketsReceivedInInterval(); | 
					
						
							|  |  |  |                     uint32_t prevseq = srcdat->INF_GetSavedExtendedSequenceNumber(); | 
					
						
							|  |  |  |                     uint32_t curseq = srcdat->INF_GetExtendedHighestSequenceNumber(); | 
					
						
							|  |  |  |                     uint32_t expected = curseq - prevseq; | 
					
						
							|  |  |  |                     uint8_t fraclost; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     if (expected < num) // got duplicates
 | 
					
						
							|  |  |  |                         fraclost = 0; | 
					
						
							|  |  |  |                     else | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         double lost = (double) (expected - num); | 
					
						
							|  |  |  |                         double frac = lost / ((double) expected); | 
					
						
							|  |  |  |                         fraclost = (uint8_t) (frac * 256.0); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     expected = curseq - srcdat->INF_GetBaseSequenceNumber(); | 
					
						
							|  |  |  |                     num = srcdat->INF_GetNumPacketsReceived(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     uint32_t diff = expected - num; | 
					
						
							|  |  |  |                     int32_t *packlost = (int32_t *) &diff; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     uint32_t jitter = srcdat->INF_GetJitter(); | 
					
						
							|  |  |  |                     uint32_t lsr; | 
					
						
							|  |  |  |                     uint32_t dlsr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     if (!srcdat->SR_HasInfo()) | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         lsr = 0; | 
					
						
							|  |  |  |                         dlsr = 0; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     else | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         RTPNTPTime srtime = srcdat->SR_GetNTPTimestamp(); | 
					
						
							|  |  |  |                         uint32_t m = (srtime.GetMSW() & 0xFFFF); | 
					
						
							|  |  |  |                         uint32_t l = ((srtime.GetLSW() >> 16) & 0xFFFF); | 
					
						
							|  |  |  |                         lsr = ((m << 16) | l); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         RTPTime diff = curtime; | 
					
						
							|  |  |  |                         diff -= srcdat->SR_GetReceiveTime(); | 
					
						
							|  |  |  |                         double diff2 = diff.GetDouble(); | 
					
						
							|  |  |  |                         diff2 *= 65536.0; | 
					
						
							|  |  |  |                         dlsr = (uint32_t) diff2; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     status = rtcpcomppack->AddReportBlock(rr_ssrc, fraclost, *packlost, curseq, jitter, lsr, dlsr); | 
					
						
							|  |  |  |                     if (status < 0) | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                             done = true; | 
					
						
							|  |  |  |                             filled = true; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         else | 
					
						
							|  |  |  |                             return status; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     else | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         addedcount++; | 
					
						
							|  |  |  |                         if (addedcount >= maxcount) | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                             done = true; | 
					
						
							|  |  |  |                             if (!sources.GotoNextSource()) | 
					
						
							|  |  |  |                                 atend = true; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         srcdat->INF_StartNewInterval(); | 
					
						
							|  |  |  |                         srcdat->SetProcessedInRTCP(true); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (!done) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if (!sources.GotoNextSource()) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     atend = true; | 
					
						
							|  |  |  |                     done = true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         } while (!done); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     *added = addedcount; | 
					
						
							|  |  |  |     *skipped = skippedcount; | 
					
						
							|  |  |  |     *full = filled; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!atend) // search for available sources
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         bool shouldprocess = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         do | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             srcdat = sources.GetCurrentSourceInfo(); | 
					
						
							|  |  |  |             if (!srcdat->IsOwnSSRC()) // don't send to ourselves
 | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if (!srcdat->IsCSRC()) // p 35: no reports should go to CSRCs
 | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     if (srcdat->INF_HasSentData()) // if this isn't true, INF_GetLastRTPPacketTime() won't make any sense
 | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         if (firstpacket) | 
					
						
							|  |  |  |                             shouldprocess = true; | 
					
						
							|  |  |  |                         else | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                             // p 35: only if rtp packets were received since the last RTP packet, a report block
 | 
					
						
							|  |  |  |                             // should be added
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                             RTPTime lastrtptime = srcdat->INF_GetLastRTPPacketTime(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                             if (lastrtptime > prevbuildtime) | 
					
						
							|  |  |  |                                 shouldprocess = true; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (shouldprocess) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if (srcdat->IsProcessedInRTCP()) | 
					
						
							|  |  |  |                     shouldprocess = false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (!shouldprocess) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if (!sources.GotoNextSource()) | 
					
						
							|  |  |  |                     atend = true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         } while (!atend && !shouldprocess); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     *atendoflist = atend; | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | int RTCPPacketBuilder::FillInSDES(RTCPCompoundPacketBuilder *rtcpcomppack, bool *full, bool *processedall, int *added) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     int status; | 
					
						
							|  |  |  |     uint8_t *data; | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |     std::size_t datalen; | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     *full = false; | 
					
						
							|  |  |  |     *processedall = false; | 
					
						
							|  |  |  |     *added = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // We don't need to add a SSRC for our own data, this is still set
 | 
					
						
							|  |  |  |     // from adding the CNAME
 | 
					
						
							|  |  |  |     if (doname) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (!ownsdesinfo.ProcessedName()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             data = ownsdesinfo.GetName(&datalen); | 
					
						
							|  |  |  |             if ((status = rtcpcomppack->AddSDESNormalItem(RTCPSDESPacket::NAME, data, datalen)) < 0) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     *full = true; | 
					
						
							|  |  |  |                     return 0; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             (*added)++; | 
					
						
							|  |  |  |             ownsdesinfo.SetProcessedName(true); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (doemail) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (!ownsdesinfo.ProcessedEMail()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             data = ownsdesinfo.GetEMail(&datalen); | 
					
						
							|  |  |  |             if ((status = rtcpcomppack->AddSDESNormalItem(RTCPSDESPacket::EMAIL, data, datalen)) < 0) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     *full = true; | 
					
						
							|  |  |  |                     return 0; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             (*added)++; | 
					
						
							|  |  |  |             ownsdesinfo.SetProcessedEMail(true); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (doloc) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (!ownsdesinfo.ProcessedLocation()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             data = ownsdesinfo.GetLocation(&datalen); | 
					
						
							|  |  |  |             if ((status = rtcpcomppack->AddSDESNormalItem(RTCPSDESPacket::LOC, data, datalen)) < 0) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     *full = true; | 
					
						
							|  |  |  |                     return 0; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             (*added)++; | 
					
						
							|  |  |  |             ownsdesinfo.SetProcessedLocation(true); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (dophone) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (!ownsdesinfo.ProcessedPhone()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             data = ownsdesinfo.GetPhone(&datalen); | 
					
						
							|  |  |  |             if ((status = rtcpcomppack->AddSDESNormalItem(RTCPSDESPacket::PHONE, data, datalen)) < 0) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     *full = true; | 
					
						
							|  |  |  |                     return 0; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             (*added)++; | 
					
						
							|  |  |  |             ownsdesinfo.SetProcessedPhone(true); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (dotool) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (!ownsdesinfo.ProcessedTool()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             data = ownsdesinfo.GetTool(&datalen); | 
					
						
							|  |  |  |             if ((status = rtcpcomppack->AddSDESNormalItem(RTCPSDESPacket::TOOL, data, datalen)) < 0) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     *full = true; | 
					
						
							|  |  |  |                     return 0; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             (*added)++; | 
					
						
							|  |  |  |             ownsdesinfo.SetProcessedTool(true); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (donote) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (!ownsdesinfo.ProcessedNote()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             data = ownsdesinfo.GetNote(&datalen); | 
					
						
							|  |  |  |             if ((status = rtcpcomppack->AddSDESNormalItem(RTCPSDESPacket::NOTE, data, datalen)) < 0) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     *full = true; | 
					
						
							|  |  |  |                     return 0; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             (*added)++; | 
					
						
							|  |  |  |             ownsdesinfo.SetProcessedNote(true); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     *processedall = true; | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RTCPPacketBuilder::ClearAllSDESFlags() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     ownsdesinfo.ClearFlags(); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  | int RTCPPacketBuilder::BuildBYEPacket(RTCPCompoundPacket **pack, const void *reason, std::size_t reasonlength, bool useSRifpossible) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (!init) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPPACKETBUILDER_NOTINIT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     RTCPCompoundPacketBuilder *rtcpcomppack; | 
					
						
							|  |  |  |     int status; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (reasonlength > 255) | 
					
						
							|  |  |  |         reasonlength = 255; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     *pack = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     rtcpcomppack = new RTCPCompoundPacketBuilder(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((status = rtcpcomppack->InitBuild(maxpacketsize)) < 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         delete rtcpcomppack; | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     uint32_t ssrc = rtppacketbuilder.GetSSRC(); | 
					
						
							|  |  |  |     bool useSR = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (useSRifpossible) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         RTPSourceData *srcdat; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ((srcdat = sources.GetOwnSourceInfo()) != 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (srcdat->IsSender()) | 
					
						
							|  |  |  |                 useSR = true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (useSR) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         RTPTime curtime = RTPTime::CurrentTime(); | 
					
						
							|  |  |  |         RTPTime rtppacktime = rtppacketbuilder.GetPacketTime(); | 
					
						
							|  |  |  |         uint32_t rtppacktimestamp = rtppacketbuilder.GetPacketTimestamp(); | 
					
						
							|  |  |  |         uint32_t packcount = rtppacketbuilder.GetPacketCount(); | 
					
						
							|  |  |  |         uint32_t octetcount = rtppacketbuilder.GetPayloadOctetCount(); | 
					
						
							|  |  |  |         RTPTime diff = curtime; | 
					
						
							|  |  |  |         diff -= rtppacktime; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         uint32_t tsdiff = (uint32_t) ((diff.GetDouble() / timestampunit) + 0.5); | 
					
						
							|  |  |  |         uint32_t rtptimestamp = rtppacktimestamp + tsdiff; | 
					
						
							|  |  |  |         RTPNTPTime ntptimestamp = curtime.GetNTPTime(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ((status = rtcpcomppack->StartSenderReport(ssrc, ntptimestamp, rtptimestamp, packcount, octetcount)) < 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             delete rtcpcomppack; | 
					
						
							|  |  |  |             if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) | 
					
						
							|  |  |  |                 return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON; | 
					
						
							|  |  |  |             return status; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if ((status = rtcpcomppack->StartReceiverReport(ssrc)) < 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             delete rtcpcomppack; | 
					
						
							|  |  |  |             if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) | 
					
						
							|  |  |  |                 return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON; | 
					
						
							|  |  |  |             return status; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     uint8_t *owncname; | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |     std::size_t owncnamelen; | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     owncname = ownsdesinfo.GetCNAME(&owncnamelen); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((status = rtcpcomppack->AddSDESSource(ssrc)) < 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         delete rtcpcomppack; | 
					
						
							|  |  |  |         if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) | 
					
						
							|  |  |  |             return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON; | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if ((status = rtcpcomppack->AddSDESNormalItem(RTCPSDESPacket::CNAME, owncname, owncnamelen)) < 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         delete rtcpcomppack; | 
					
						
							|  |  |  |         if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) | 
					
						
							|  |  |  |             return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON; | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     uint32_t ssrcs[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ssrcs[0] = ssrc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((status = rtcpcomppack->AddBYEPacket(ssrcs, 1, (const uint8_t *) reason, reasonlength)) < 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         delete rtcpcomppack; | 
					
						
							|  |  |  |         if (status == ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT) | 
					
						
							|  |  |  |             return ERR_RTP_RTCPPACKETBUILDER_PACKETFILLEDTOOSOON; | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((status = rtcpcomppack->EndBuild()) < 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         delete rtcpcomppack; | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     *pack = rtcpcomppack; | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // end namespace
 | 
					
						
							|  |  |  | 
 |