00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "RTPSource.hh"
00022 #include "GroupsockHelper.hh"
00023
00025
00026 Boolean RTPSource::lookupByName(UsageEnvironment& env,
00027 char const* sourceName,
00028 RTPSource*& resultSource) {
00029 resultSource = NULL;
00030
00031 MediaSource* source;
00032 if (!MediaSource::lookupByName(env, sourceName, source)) return False;
00033
00034 if (!source->isRTPSource()) {
00035 env.setResultMsg(sourceName, " is not a RTP source");
00036 return False;
00037 }
00038
00039 resultSource = (RTPSource*)source;
00040 return True;
00041 }
00042
00043 Boolean RTPSource::hasBeenSynchronizedUsingRTCP() {
00044 return fCurPacketHasBeenSynchronizedUsingRTCP;
00045 }
00046
00047 Boolean RTPSource::isRTPSource() const {
00048 return True;
00049 }
00050
00051 RTPSource::RTPSource(UsageEnvironment& env, Groupsock* RTPgs,
00052 unsigned char rtpPayloadFormat,
00053 u_int32_t rtpTimestampFrequency)
00054 : FramedSource(env),
00055 fRTPInterface(this, RTPgs),
00056 fCurPacketHasBeenSynchronizedUsingRTCP(False),
00057 fRTPPayloadFormat(rtpPayloadFormat),
00058 fTimestampFrequency(rtpTimestampFrequency),
00059 fSSRC(our_random32()) {
00060 fReceptionStatsDB = new RTPReceptionStatsDB(*this);
00061 }
00062
00063 RTPSource::~RTPSource() {
00064 delete fReceptionStatsDB;
00065 }
00066
00067 void RTPSource::getAttributes() const {
00068 envir().setResultMsg("");
00069 }
00070
00071
00073
00074 RTPReceptionStatsDB::RTPReceptionStatsDB(RTPSource& rtpSource)
00075 : fOurRTPSource(rtpSource),
00076 fTable(HashTable::create(ONE_WORD_HASH_KEYS)), fTotNumPacketsReceived(0) {
00077 reset();
00078 }
00079
00080 void RTPReceptionStatsDB::reset() {
00081 fNumActiveSourcesSinceLastReset = 0;
00082
00083 Iterator iter(*this);
00084 RTPReceptionStats* stats;
00085 while ((stats = iter.next()) != NULL) {
00086 stats->reset();
00087 }
00088 }
00089
00090 RTPReceptionStatsDB::~RTPReceptionStatsDB() {
00091
00092 RTPReceptionStats* stats;
00093 while ((stats = (RTPReceptionStats*)fTable->RemoveNext()) != NULL) {
00094 delete stats;
00095 }
00096
00097
00098 delete fTable;
00099 }
00100
00101 void RTPReceptionStatsDB
00102 ::noteIncomingPacket(u_int32_t SSRC, u_int16_t seqNum,
00103 u_int32_t rtpTimestamp, unsigned timestampFrequency,
00104 Boolean useForJitterCalculation,
00105 struct timeval& resultPresentationTime,
00106 Boolean& resultHasBeenSyncedUsingRTCP,
00107 unsigned packetSize) {
00108 ++fTotNumPacketsReceived;
00109 RTPReceptionStats* stats = lookup(SSRC);
00110 if (stats == NULL) {
00111
00112
00113 stats = new RTPReceptionStats(fOurRTPSource, SSRC, seqNum);
00114 if (stats == NULL) return;
00115 add(SSRC, stats);
00116 }
00117
00118 if (stats->numPacketsReceivedSinceLastReset() == 0) {
00119 ++fNumActiveSourcesSinceLastReset;
00120 }
00121
00122 stats->noteIncomingPacket(seqNum, rtpTimestamp, timestampFrequency,
00123 useForJitterCalculation,
00124 resultPresentationTime,
00125 resultHasBeenSyncedUsingRTCP, packetSize);
00126 }
00127
00128 void RTPReceptionStatsDB
00129 ::noteIncomingSR(u_int32_t SSRC,
00130 u_int32_t ntpTimestampMSW, u_int32_t ntpTimestampLSW,
00131 u_int32_t rtpTimestamp) {
00132 RTPReceptionStats* stats = lookup(SSRC);
00133 if (stats == NULL) {
00134
00135
00136 stats = new RTPReceptionStats(fOurRTPSource, SSRC);
00137 if (stats == NULL) return;
00138 add(SSRC, stats);
00139 }
00140
00141 stats->noteIncomingSR(ntpTimestampMSW, ntpTimestampLSW, rtpTimestamp);
00142 }
00143
00144 void RTPReceptionStatsDB::removeRecord(u_int32_t SSRC) {
00145 RTPReceptionStats* stats = lookup(SSRC);
00146 if (stats != NULL) {
00147 long SSRC_long = (long)SSRC;
00148 fTable->Remove((char const*)SSRC_long);
00149 delete stats;
00150 }
00151 }
00152
00153 RTPReceptionStatsDB::Iterator
00154 ::Iterator(RTPReceptionStatsDB& receptionStatsDB)
00155 : fIter(HashTable::Iterator::create(*(receptionStatsDB.fTable))) {
00156 }
00157
00158 RTPReceptionStatsDB::Iterator::~Iterator() {
00159 delete fIter;
00160 }
00161
00162 RTPReceptionStats*
00163 RTPReceptionStatsDB::Iterator::next(Boolean includeInactiveSources) {
00164 char const* key;
00165
00166
00167
00168 RTPReceptionStats* stats;
00169 do {
00170 stats = (RTPReceptionStats*)(fIter->next(key));
00171 } while (stats != NULL && !includeInactiveSources
00172 && stats->numPacketsReceivedSinceLastReset() == 0);
00173
00174 return stats;
00175 }
00176
00177 RTPReceptionStats* RTPReceptionStatsDB::lookup(u_int32_t SSRC) const {
00178 long SSRC_long = (long)SSRC;
00179 return (RTPReceptionStats*)(fTable->Lookup((char const*)SSRC_long));
00180 }
00181
00182 void RTPReceptionStatsDB::add(u_int32_t SSRC, RTPReceptionStats* stats) {
00183 long SSRC_long = (long)SSRC;
00184 fTable->Add((char const*)SSRC_long, stats);
00185 }
00186
00188
00189 RTPReceptionStats::RTPReceptionStats(RTPSource& rtpSource, u_int32_t SSRC,
00190 u_int16_t initialSeqNum)
00191 : fOurRTPSource(rtpSource) {
00192 initSeqNum(initialSeqNum);
00193 init(SSRC);
00194 }
00195
00196 RTPReceptionStats::RTPReceptionStats(RTPSource& rtpSource, u_int32_t SSRC)
00197 : fOurRTPSource(rtpSource) {
00198 init(SSRC);
00199 }
00200
00201 RTPReceptionStats::~RTPReceptionStats() {
00202 }
00203
00204 void RTPReceptionStats::init(u_int32_t SSRC) {
00205 fSSRC = SSRC;
00206 fTotNumPacketsReceived = 0;
00207 fTotBytesReceived_hi = fTotBytesReceived_lo = 0;
00208 fHaveSeenInitialSequenceNumber = False;
00209 fLastTransit = ~0;
00210 fPreviousPacketRTPTimestamp = 0;
00211 fJitter = 0.0;
00212 fLastReceivedSR_NTPmsw = fLastReceivedSR_NTPlsw = 0;
00213 fLastReceivedSR_time.tv_sec = fLastReceivedSR_time.tv_usec = 0;
00214 fLastPacketReceptionTime.tv_sec = fLastPacketReceptionTime.tv_usec = 0;
00215 fMinInterPacketGapUS = 0x7FFFFFFF;
00216 fMaxInterPacketGapUS = 0;
00217 fTotalInterPacketGaps.tv_sec = fTotalInterPacketGaps.tv_usec = 0;
00218 fHasBeenSynchronized = False;
00219 fSyncTime.tv_sec = fSyncTime.tv_usec = 0;
00220 reset();
00221 }
00222
00223 void RTPReceptionStats::initSeqNum(u_int16_t initialSeqNum) {
00224 fBaseExtSeqNumReceived = initialSeqNum-1;
00225 fHighestExtSeqNumReceived = initialSeqNum;
00226 fHaveSeenInitialSequenceNumber = True;
00227 }
00228
00229 #ifndef MILLION
00230 #define MILLION 1000000
00231 #endif
00232
00233 void RTPReceptionStats
00234 ::noteIncomingPacket(u_int16_t seqNum, u_int32_t rtpTimestamp,
00235 unsigned timestampFrequency,
00236 Boolean useForJitterCalculation,
00237 struct timeval& resultPresentationTime,
00238 Boolean& resultHasBeenSyncedUsingRTCP,
00239 unsigned packetSize) {
00240 if (!fHaveSeenInitialSequenceNumber) initSeqNum(seqNum);
00241
00242 ++fNumPacketsReceivedSinceLastReset;
00243 ++fTotNumPacketsReceived;
00244 u_int32_t prevTotBytesReceived_lo = fTotBytesReceived_lo;
00245 fTotBytesReceived_lo += packetSize;
00246 if (fTotBytesReceived_lo < prevTotBytesReceived_lo) {
00247 ++fTotBytesReceived_hi;
00248 }
00249
00250
00251 unsigned oldSeqNum = (fHighestExtSeqNumReceived&0xFFFF);
00252 if (seqNumLT((u_int16_t)oldSeqNum, seqNum)) {
00253
00254 unsigned seqNumCycle = (fHighestExtSeqNumReceived&0xFFFF0000);
00255 unsigned seqNumDifference = (unsigned)((int)seqNum-(int)oldSeqNum);
00256 if (seqNumDifference >= 0x8000) {
00257
00258 seqNumCycle += 0x10000;
00259 }
00260
00261 unsigned newSeqNum = seqNumCycle|seqNum;
00262 if (newSeqNum > fHighestExtSeqNumReceived) {
00263 fHighestExtSeqNumReceived = newSeqNum;
00264 }
00265 }
00266
00267
00268 struct timeval timeNow;
00269 gettimeofday(&timeNow, NULL);
00270 if (fLastPacketReceptionTime.tv_sec != 0
00271 || fLastPacketReceptionTime.tv_usec != 0) {
00272 unsigned gap
00273 = (timeNow.tv_sec - fLastPacketReceptionTime.tv_sec)*MILLION
00274 + timeNow.tv_usec - fLastPacketReceptionTime.tv_usec;
00275 if (gap > fMaxInterPacketGapUS) {
00276 fMaxInterPacketGapUS = gap;
00277 }
00278 if (gap < fMinInterPacketGapUS) {
00279 fMinInterPacketGapUS = gap;
00280 }
00281 fTotalInterPacketGaps.tv_usec += gap;
00282 if (fTotalInterPacketGaps.tv_usec >= MILLION) {
00283 ++fTotalInterPacketGaps.tv_sec;
00284 fTotalInterPacketGaps.tv_usec -= MILLION;
00285 }
00286 }
00287 fLastPacketReceptionTime = timeNow;
00288
00289
00290
00291
00292
00293
00294
00295 if (useForJitterCalculation
00296 && rtpTimestamp != fPreviousPacketRTPTimestamp) {
00297 unsigned arrival = (timestampFrequency*timeNow.tv_sec);
00298 arrival += (unsigned)
00299 ((2.0*timestampFrequency*timeNow.tv_usec + 1000000.0)/2000000);
00300
00301 int transit = arrival - rtpTimestamp;
00302 if (fLastTransit == (~0)) fLastTransit = transit;
00303 int d = transit - fLastTransit;
00304 fLastTransit = transit;
00305 if (d < 0) d = -d;
00306 fJitter += (1.0/16.0) * ((double)d - fJitter);
00307 }
00308
00309
00310 if (fSyncTime.tv_sec == 0 && fSyncTime.tv_usec == 0) {
00311
00312
00313
00314 fSyncTimestamp = rtpTimestamp;
00315 fSyncTime = timeNow;
00316 }
00317
00318 int timestampDiff = rtpTimestamp - fSyncTimestamp;
00319
00320
00321
00322
00323 double timeDiff
00324 = timestampDiff/(double)(fOurRTPSource.timestampFrequency());
00325
00326
00327 unsigned const million = 1000000;
00328 unsigned seconds, uSeconds;
00329 if (timeDiff >= 0.0) {
00330 seconds = fSyncTime.tv_sec + (unsigned)(timeDiff);
00331 uSeconds = fSyncTime.tv_usec
00332 + (unsigned)((timeDiff - (unsigned)timeDiff)*million);
00333 if (uSeconds >= million) {
00334 uSeconds -= million;
00335 ++seconds;
00336 }
00337 } else {
00338 timeDiff = -timeDiff;
00339 seconds = fSyncTime.tv_sec - (unsigned)(timeDiff);
00340 uSeconds = fSyncTime.tv_usec
00341 - (unsigned)((timeDiff - (unsigned)timeDiff)*million);
00342 if ((int)uSeconds < 0) {
00343 uSeconds += million;
00344 --seconds;
00345 }
00346 }
00347 resultPresentationTime.tv_sec = seconds;
00348 resultPresentationTime.tv_usec = uSeconds;
00349 resultHasBeenSyncedUsingRTCP = fHasBeenSynchronized;
00350
00351
00352 fSyncTimestamp = rtpTimestamp;
00353 fSyncTime = resultPresentationTime;
00354
00355 fPreviousPacketRTPTimestamp = rtpTimestamp;
00356 }
00357
00358 void RTPReceptionStats::noteIncomingSR(u_int32_t ntpTimestampMSW,
00359 u_int32_t ntpTimestampLSW,
00360 u_int32_t rtpTimestamp) {
00361 fLastReceivedSR_NTPmsw = ntpTimestampMSW;
00362 fLastReceivedSR_NTPlsw = ntpTimestampLSW;
00363
00364 gettimeofday(&fLastReceivedSR_time, NULL);
00365
00366
00367 fSyncTimestamp = rtpTimestamp;
00368 fSyncTime.tv_sec = ntpTimestampMSW - 0x83AA7E80;
00369 double microseconds = (ntpTimestampLSW*15625.0)/0x04000000;
00370 fSyncTime.tv_usec = (unsigned)(microseconds+0.5);
00371 fHasBeenSynchronized = True;
00372 }
00373
00374 double RTPReceptionStats::totNumKBytesReceived() const {
00375 double const hiMultiplier = 0x20000000/125.0;
00376 return fTotBytesReceived_hi*hiMultiplier + fTotBytesReceived_lo/1000.0;
00377 }
00378
00379 unsigned RTPReceptionStats::jitter() const {
00380 return (unsigned)fJitter;
00381 }
00382
00383 void RTPReceptionStats::reset() {
00384 fNumPacketsReceivedSinceLastReset = 0;
00385 fLastResetExtSeqNumReceived = fHighestExtSeqNumReceived;
00386 }
00387
00388 Boolean seqNumLT(u_int16_t s1, u_int16_t s2) {
00389
00390 int diff = s2-s1;
00391 if (diff > 0) {
00392 return (diff < 0x8000);
00393 } else if (diff < 0) {
00394 return (diff < -0x8000);
00395 } else {
00396 return False;
00397 }
00398 }