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