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