[Opalvoip-svn] SF.net SVN: opalvoip:[34588] opal/trunk
Brought to you by:
csoutheren,
rjongbloed
From: <rjo...@us...> - 2016-02-03 17:47:23
|
Revision: 34588 http://sourceforge.net/p/opalvoip/code/34588 Author: rjongbloed Date: 2016-02-03 17:47:20 +0000 (Wed, 03 Feb 2016) Log Message: ----------- Fixed RTP round trip time calculation, checking SR to RR lsr field. Modified Paths: -------------- opal/trunk/include/rtp/rtp.h opal/trunk/include/rtp/rtp_session.h opal/trunk/src/rtp/rtp.cxx opal/trunk/src/rtp/rtp_session.cxx Modified: opal/trunk/include/rtp/rtp.h =================================================================== --- opal/trunk/include/rtp/rtp.h 2016-02-03 16:01:51 UTC (rev 34587) +++ opal/trunk/include/rtp/rtp.h 2016-02-03 17:47:20 UTC (rev 34588) @@ -453,7 +453,7 @@ #endif RTP_SyncSourceId sourceIdentifier; - uint32_t ntpPassThrough; + uint64_t ntpPassThrough; PTime realTimestamp; RTP_Timestamp rtpTimestamp; unsigned packetsSent; @@ -465,7 +465,7 @@ { PCLASSINFO(RTP_ReceiverReport, PObject); public: - RTP_ReceiverReport(const RTP_ControlFrame::ReceiverReport & report); + RTP_ReceiverReport(const RTP_ControlFrame::ReceiverReport & report, uint64_t ntpPassThru); #if PTRACING void PrintOn(ostream &) const; #endif @@ -475,7 +475,7 @@ unsigned totalLost; /* cumulative number of packets lost (signed!) */ unsigned lastSequenceNumber; /* extended last sequence number received */ unsigned jitter; /* interarrival jitter */ - PTime lastTimestamp; /* last SR packet from this source */ + PTime lastTimestamp; /* last SR time from this source */ PTimeInterval delay; /* delay since last SR packet */ }; Modified: opal/trunk/include/rtp/rtp_session.h =================================================================== --- opal/trunk/include/rtp/rtp_session.h 2016-02-03 16:01:51 UTC (rev 34587) +++ opal/trunk/include/rtp/rtp_session.h 2016-02-03 17:47:20 UTC (rev 34588) @@ -220,6 +220,7 @@ virtual SendReceiveStatus OnOutOfOrderPacket(RTP_DataFrame & frame); virtual void OnRxSenderReport(const RTP_SenderReport & sender); + virtual void OnRxReceiverReport(RTP_SyncSourceId src, const RTP_ControlFrame::ReceiverReport & rr); virtual void OnRxReceiverReport(RTP_SyncSourceId src, const RTP_ReceiverReport & report); virtual void OnRxSourceDescription(const RTP_SourceDescriptionArray & descriptions); virtual void OnRxGoodbye(const RTP_SyncSourceArray & sources, const PString & reason); @@ -723,8 +724,8 @@ // Things to remember for filling in fields of sent SR/RR/DLRR unsigned m_packetsLostSinceLastRR; uint32_t m_lastRRSequenceNumber; - uint32_t m_ntpPassThrough; - PTime m_lastSenderReportTime; + uint64_t m_ntpPassThrough; // The NTP time from SR + PTime m_lastSenderReportTime; // Local time that SR was sent/received PTime m_referenceReportTime; PTime m_referenceReportNTP; Modified: opal/trunk/src/rtp/rtp.cxx =================================================================== --- opal/trunk/src/rtp/rtp.cxx 2016-02-03 16:01:51 UTC (rev 34587) +++ opal/trunk/src/rtp/rtp.cxx 2016-02-03 17:47:20 UTC (rev 34588) @@ -826,17 +826,17 @@ RTP_SenderReport::RTP_SenderReport(const RTP_ControlFrame::SenderReport & sr) : sourceIdentifier(sr.ssrc) - , ntpPassThrough((uint32_t)(((uint64_t)sr.ntp_ts)>>16)) + , ntpPassThrough(sr.ntp_ts) , realTimestamp(0) , rtpTimestamp(sr.rtp_ts) , packetsSent(sr.psent) , octetsSent(sr.osent) { - realTimestamp.SetNTP(sr.ntp_ts); + realTimestamp.SetNTP(ntpPassThrough); } -RTP_ReceiverReport::RTP_ReceiverReport(const RTP_ControlFrame::ReceiverReport & rr) +RTP_ReceiverReport::RTP_ReceiverReport(const RTP_ControlFrame::ReceiverReport & rr, uint64_t ntpPassThru) : sourceIdentifier(rr.ssrc) , fractionLost(rr.fraction) , totalLost(rr.GetLostPackets()) @@ -845,7 +845,8 @@ , lastTimestamp(0) , delay(((uint32_t)rr.dlsr*1000LL)/65536) // units of 1/65536 seconds { - lastTimestamp.SetNTP((uint64_t)(uint32_t)rr.lsr << 16); + if ((uint32_t)(ntpPassThru>>16) == rr.lsr) + lastTimestamp.SetNTP(ntpPassThru); } Modified: opal/trunk/src/rtp/rtp_session.cxx =================================================================== --- opal/trunk/src/rtp/rtp_session.cxx 2016-02-03 16:01:51 UTC (rev 34587) +++ opal/trunk/src/rtp/rtp_session.cxx 2016-02-03 17:47:20 UTC (rev 34588) @@ -1018,9 +1018,9 @@ report->jitter = m_jitterAccum >> JitterRoundingGuardBits; // Allow for rounding protection bits /* Time remote sent us in SR. Note this has to be IDENTICAL to what we - received in SR as some implementations (WebRTC!) do not use it as a NTP - time, but as a lookup key in a table to find the NTP value. Why? Why? Why? */ - report->lsr = m_ntpPassThrough; + received in SR as it is used as a de-facto sequence number for the + SR that was sent. We match RR's to SR's this way. */ + report->lsr = (uint32_t)(m_ntpPassThrough >> 16); // Delay since last received SR report->dlsr = m_lastSenderReportTime.IsValid() ? (uint32_t)((PTime() - m_lastSenderReportTime).GetMilliSeconds()*65536/1000) : 0; @@ -1091,22 +1091,25 @@ void OpalRTPSession::SyncSource::CalculateRTT(const PTime & reportTime, const PTimeInterval & reportDelay) { - if (reportTime.IsValid()) { - PTimeInterval myDelay = PTime() - reportTime; - if (m_session.m_roundTripTime > 0 && myDelay <= reportDelay) - PTRACE(4, &m_session, *this << "not calculating round trip time, RR arrived too soon after SR."); - else if (myDelay <= reportDelay) { - m_session.m_roundTripTime = 1; - PTRACE(4, &m_session, *this << "very small round trip time, using 1ms"); - } - else if (myDelay > 1000) { - PTRACE(4, &m_session, *this << "very large round trip time, ignoring"); - } - else { - m_session.m_roundTripTime = (myDelay - reportDelay).GetInterval(); - PTRACE(4, &m_session, *this << "determined round trip time: " << m_session.m_roundTripTime << "ms"); - } + if (!reportTime.IsValid()) { + PTRACE(4, &m_session, *this << "not calculating round trip time, NTP in RR does not match SR."); + return; } + + PTimeInterval myDelay = PTime() - reportTime; + if (m_session.m_roundTripTime > 0 && myDelay <= reportDelay) + PTRACE(4, &m_session, *this << "not calculating round trip time, RR arrived too soon after SR."); + else if (myDelay <= reportDelay) { + m_session.m_roundTripTime = 1; + PTRACE(4, &m_session, *this << "very small round trip time, using 1ms"); + } + else if (myDelay > 2000) { + PTRACE(4, &m_session, *this << "very large round trip time, ignoring"); + } + else { + m_session.m_roundTripTime = (myDelay - reportDelay).GetInterval(); + PTRACE(4, &m_session, *this << "determined round trip time: " << m_session.m_roundTripTime << "ms"); + } } @@ -1268,10 +1271,12 @@ sender.m_octets, receivers); + sender.m_ntpPassThrough = sender.m_reportAbsoluteTime.GetNTP(); sender.m_lastSenderReportTime.SetCurrentTime(); PTRACE(logLevel, sender << "sending " << forcedStr << "SenderReport:" " ntp=" << sender.m_reportAbsoluteTime.AsString(PTime::TodayFormat) + << " 0x" << hex << sender.m_ntpPassThrough << dec << " rtp=" << sender.m_reportTimestamp << " psent=" << sender.m_packets << " osent=" << sender.m_octets @@ -1875,16 +1880,23 @@ } -void OpalRTPSession::OnRxReceiverReport(RTP_SyncSourceId ssrc, const RTP_ReceiverReport & report) +void OpalRTPSession::OnRxReceiverReport(RTP_SyncSourceId ssrc, const RTP_ControlFrame::ReceiverReport & rr) { SyncSource * sender = NULL; - if (CheckControlSSRC(ssrc, report.sourceIdentifier, sender PTRACE_PARAM(, "RR"))) { + if (CheckControlSSRC(ssrc, rr.ssrc, sender PTRACE_PARAM(, "RR"))) { + RTP_ReceiverReport report(rr, sender->m_ntpPassThrough); sender->OnRxReceiverReport(report); - m_connection.ExecuteMediaCommand(OpalMediaPacketLoss(report.fractionLost * 100 / 255, m_mediaType, m_sessionId, report.sourceIdentifier), true); + OnRxReceiverReport(ssrc, report); } } +void OpalRTPSession::OnRxReceiverReport(RTP_SyncSourceId, const RTP_ReceiverReport & report) +{ + m_connection.ExecuteMediaCommand(OpalMediaPacketLoss(report.fractionLost * 100 / 255, m_mediaType, m_sessionId, report.sourceIdentifier), true); +} + + void OpalRTPSession::OnRxSourceDescription(const RTP_SourceDescriptionArray & PTRACE_PARAM(description)) { PTRACE(m_throttleRxSDES, *this << "OnSourceDescription: " << description.GetSize() << " entries" << description); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |