diff --git a/dom/media/tests/mochitest/pc.js b/dom/media/tests/mochitest/pc.js index 943b1abedb27..17eb1b591f07 100644 --- a/dom/media/tests/mochitest/pc.js +++ b/dom/media/tests/mochitest/pc.js @@ -1594,8 +1594,8 @@ PeerConnectionWrapper.prototype = { var res = stats[key]; // validate stats ok(res.id == key, "Coherent stats id"); - var nowish = Date.now() + 10000; // TODO: severe drift observed - var minimum = this.whenCreated - 10000; // on Windows XP (Bug 979649) + var nowish = Date.now() + 1000; // TODO: clock drift observed + var minimum = this.whenCreated - 1000; // on Windows XP (Bug 979649) ok(res.timestamp >= minimum, "Valid " + (res.isRemote? "rtcp" : "rtp") + " timestamp " + res.timestamp + " >= " + minimum + " (" + @@ -1631,12 +1631,10 @@ PeerConnectionWrapper.prototype = { if(res.type == "outboundrtp") { ok(rem.type == "inboundrtp", "Rtcp is inbound"); ok(rem.packetsReceived !== undefined, "Rtcp packetsReceived"); - // TODO: Re-enable once Bug 980497 is fixed - // ok(rem.packetsReceived <= res.packetsSent, "No more than sent"); + ok(rem.packetsReceived <= res.packetsSent, "No more than sent"); ok(rem.packetsLost !== undefined, "Rtcp packetsLost"); ok(rem.bytesReceived >= rem.packetsReceived * 8, "Rtcp bytesReceived"); - // TODO: Re-enable once Bug 980497 is fixed - // ok(rem.bytesReceived <= res.bytesSent, "No more than sent bytes"); + ok(rem.bytesReceived <= res.bytesSent, "No more than sent bytes"); ok(rem.jitter !== undefined, "Rtcp jitter"); } else { ok(rem.type == "outboundrtp", "Rtcp is outbound"); diff --git a/dom/webidl/RTCStatsReport.webidl b/dom/webidl/RTCStatsReport.webidl index f6bab2182de0..3f118d306389 100644 --- a/dom/webidl/RTCStatsReport.webidl +++ b/dom/webidl/RTCStatsReport.webidl @@ -40,6 +40,7 @@ dictionary RTCInboundRTPStreamStats : RTCRTPStreamStats { unsigned long packetsLost; long mozAvSyncDelay; long mozJitterBufferDelay; + long mozRtt; }; dictionary RTCOutboundRTPStreamStats : RTCRTPStreamStats { @@ -58,7 +59,6 @@ dictionary RTCMediaStreamTrackStats : RTCStats { unsigned long framesSent; unsigned long framesReceived; // Only for remoteSource=true unsigned long framesDecoded; - unsigned long first; }; dictionary RTCMediaStreamStats : RTCStats { diff --git a/media/webrtc/signaling/src/media-conduit/AudioConduit.cpp b/media/webrtc/signaling/src/media-conduit/AudioConduit.cpp index 3081d7bf9088..ff8837e9b4b2 100644 --- a/media/webrtc/signaling/src/media-conduit/AudioConduit.cpp +++ b/media/webrtc/signaling/src/media-conduit/AudioConduit.cpp @@ -153,26 +153,22 @@ NTPtoDOMHighResTimeStamp(uint32_t ntpHigh, uint32_t ntpLow) { } bool WebrtcAudioConduit::GetRTCPReceiverReport(DOMHighResTimeStamp* timestamp, - unsigned int* jitterMs, - unsigned int* packetsReceived, + uint32_t* jitterMs, + uint32_t* packetsReceived, uint64_t* bytesReceived, - unsigned int *cumulativeLost) { - unsigned int ntpHigh, ntpLow; - unsigned int rtpTimestamp, playoutTimestamp; - unsigned int packetsSent; - unsigned int bytesSent32; - unsigned short fractionLost; - bool result = !mPtrRTP->GetRemoteRTCPData(mChannel, ntpHigh, ntpLow, - rtpTimestamp, playoutTimestamp, - packetsSent, bytesSent32, - jitterMs, - &fractionLost, cumulativeLost); + uint32_t* cumulativeLost, + int32_t* rttMs) { + uint32_t ntpHigh, ntpLow; + uint16_t fractionLost; + bool result = !mPtrRTP->GetRemoteRTCPReceiverInfo(mChannel, ntpHigh, ntpLow, + *packetsReceived, + *bytesReceived, + *jitterMs, + fractionLost, + *cumulativeLost, + *rttMs); if (result) { *timestamp = NTPtoDOMHighResTimeStamp(ntpHigh, ntpLow); - *packetsReceived = (packetsSent >= *cumulativeLost) ? - (packetsSent - *cumulativeLost) : 0; - *bytesReceived = (packetsSent ? - (bytesSent32 / packetsSent) : 0) * (*packetsReceived); } return result; } @@ -180,18 +176,13 @@ bool WebrtcAudioConduit::GetRTCPReceiverReport(DOMHighResTimeStamp* timestamp, bool WebrtcAudioConduit::GetRTCPSenderReport(DOMHighResTimeStamp* timestamp, unsigned int* packetsSent, uint64_t* bytesSent) { - unsigned int ntpHigh, ntpLow; - unsigned int rtpTimestamp, playoutTimestamp; - unsigned int bytesSent32; - unsigned int jitterMs; - unsigned short fractionLost; - bool result = !mPtrRTP->GetRemoteRTCPData(mChannel, ntpHigh, ntpLow, - rtpTimestamp, playoutTimestamp, - *packetsSent, bytesSent32, - &jitterMs, &fractionLost); + struct webrtc::SenderInfo senderInfo; + bool result = !mPtrRTP->GetRemoteRTCPSenderInfo(mChannel, &senderInfo); if (result) { - *timestamp = NTPtoDOMHighResTimeStamp(ntpHigh, ntpLow); - *bytesSent = bytesSent32; + *timestamp = NTPtoDOMHighResTimeStamp(senderInfo.NTP_timestamp_high, + senderInfo.NTP_timestamp_low); + *packetsSent = senderInfo.sender_packet_count; + *bytesSent = senderInfo.sender_octet_count; } return result; } diff --git a/media/webrtc/signaling/src/media-conduit/AudioConduit.h b/media/webrtc/signaling/src/media-conduit/AudioConduit.h index 8101d95745d3..5211c734a931 100755 --- a/media/webrtc/signaling/src/media-conduit/AudioConduit.h +++ b/media/webrtc/signaling/src/media-conduit/AudioConduit.h @@ -185,10 +185,11 @@ public: int32_t* avSyncOffsetMs); bool GetRTPStats(unsigned int* jitterMs, unsigned int* cumulativeLost); bool GetRTCPReceiverReport(DOMHighResTimeStamp* timestamp, - unsigned int* jitterMs, - unsigned int* packetsReceived, + uint32_t* jitterMs, + uint32_t* packetsReceived, uint64_t* bytesReceived, - unsigned int *cumulativeLost); + uint32_t *cumulativeLost, + int32_t* rttMs); bool GetRTCPSenderReport(DOMHighResTimeStamp* timestamp, unsigned int* packetsSent, uint64_t* bytesSent); diff --git a/media/webrtc/signaling/src/media-conduit/MediaConduitInterface.h b/media/webrtc/signaling/src/media-conduit/MediaConduitInterface.h index 9267b94c97d2..6651117f595f 100755 --- a/media/webrtc/signaling/src/media-conduit/MediaConduitInterface.h +++ b/media/webrtc/signaling/src/media-conduit/MediaConduitInterface.h @@ -149,10 +149,11 @@ public: virtual bool GetRTPStats(unsigned int* jitterMs, unsigned int* cumulativeLost) = 0; virtual bool GetRTCPReceiverReport(DOMHighResTimeStamp* timestamp, - unsigned int* jitterMs, - unsigned int* packetsReceived, + uint32_t* jitterMs, + uint32_t* packetsReceived, uint64_t* bytesReceived, - unsigned int* cumulativeLost) = 0; + uint32_t* cumulativeLost, + int32_t* rttMs) = 0; virtual bool GetRTCPSenderReport(DOMHighResTimeStamp* timestamp, unsigned int* packetsSent, uint64_t* bytesSent) = 0; diff --git a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp index 481dcf79bb11..4fadb49b224c 100644 --- a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp +++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp @@ -157,29 +157,22 @@ bool WebrtcVideoConduit::GetRTPStats(unsigned int* jitterMs, } bool WebrtcVideoConduit::GetRTCPReceiverReport(DOMHighResTimeStamp* timestamp, - unsigned int* jitterMs, - unsigned int* packetsReceived, + uint32_t* jitterMs, + uint32_t* packetsReceived, uint64_t* bytesReceived, - unsigned int* cumulativeLost) { - unsigned int ntpHigh, ntpLow; - unsigned int packetsSent; - unsigned int bytesSent32; - unsigned short fractionLost; - unsigned extendedMax; - int rttMs; - bool result = !mPtrRTP->GetSentRTCPStatistics(mChannel, ntpHigh, ntpLow, - bytesSent32, packetsSent, - fractionLost, - *cumulativeLost, - extendedMax, - *jitterMs, - rttMs); + uint32_t* cumulativeLost, + int32_t* rttMs) { + uint32_t ntpHigh, ntpLow; + uint16_t fractionLost; + bool result = !mPtrRTP->GetRemoteRTCPReceiverInfo(mChannel, ntpHigh, ntpLow, + *packetsReceived, + *bytesReceived, + jitterMs, + &fractionLost, + cumulativeLost, + rttMs); if (result) { *timestamp = NTPtoDOMHighResTimeStamp(ntpHigh, ntpLow); - *packetsReceived = (packetsSent >= *cumulativeLost) ? - (packetsSent - *cumulativeLost) : 0; - *bytesReceived = (packetsSent ? - (bytesSent32 / packetsSent) : 0) * (*packetsReceived); } return result; } @@ -187,22 +180,13 @@ bool WebrtcVideoConduit::GetRTCPReceiverReport(DOMHighResTimeStamp* timestamp, bool WebrtcVideoConduit::GetRTCPSenderReport(DOMHighResTimeStamp* timestamp, unsigned int* packetsSent, uint64_t* bytesSent) { - unsigned int ntpHigh, ntpLow; - unsigned int bytesSent32; - unsigned int jitterMs; - unsigned short fractionLost; - unsigned int cumulativeLost; - unsigned extendedMax; - int rttMs; - bool result = !mPtrRTP->GetReceivedRTCPStatistics(mChannel, ntpHigh, ntpLow, - bytesSent32, *packetsSent, - fractionLost, - cumulativeLost, - jitterMs, extendedMax, - rttMs); + struct webrtc::SenderInfo senderInfo; + bool result = !mPtrRTP->GetRemoteRTCPSenderInfo(mChannel, &senderInfo); if (result) { - *timestamp = NTPtoDOMHighResTimeStamp(ntpHigh, ntpLow); - *bytesSent = bytesSent32; + *timestamp = NTPtoDOMHighResTimeStamp(senderInfo.NTP_timestamp_high, + senderInfo.NTP_timestamp_low); + *packetsSent = senderInfo.sender_packet_count; + *bytesSent = senderInfo.sender_octet_count; } return result; } diff --git a/media/webrtc/signaling/src/media-conduit/VideoConduit.h b/media/webrtc/signaling/src/media-conduit/VideoConduit.h index 912006418d17..16681eea4637 100755 --- a/media/webrtc/signaling/src/media-conduit/VideoConduit.h +++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.h @@ -210,10 +210,11 @@ public: int32_t* avSyncOffsetMs); bool GetRTPStats(unsigned int* jitterMs, unsigned int* cumulativeLost); bool GetRTCPReceiverReport(DOMHighResTimeStamp* timestamp, - unsigned int* jitterMs, - unsigned int* packetsReceived, + uint32_t* jitterMs, + uint32_t* packetsReceived, uint64_t* bytesReceived, - unsigned int* cumulativeLost); + uint32_t* cumulativeLost, + int32_t* rttMs); bool GetRTCPSenderReport(DOMHighResTimeStamp* timestamp, unsigned int* packetsSent, uint64_t* bytesSent); diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp index 5d5dcccd931b..03b84ca63d64 100644 --- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp +++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp @@ -2164,10 +2164,12 @@ PeerConnectionImpl::ExecuteStatsQuery_s(RTCStatsQuery *query) { uint32_t packetsReceived; uint64_t bytesReceived; uint32_t packetsLost; + int32_t rtt; if (mp.Conduit()->GetRTCPReceiverReport(×tamp, &jitterMs, &packetsReceived, &bytesReceived, - &packetsLost)) { + &packetsLost, + &rtt)) { remoteId = NS_LITERAL_STRING("outbound_rtcp_") + idstr; RTCInboundRTPStreamStats s; s.mTimestamp.Construct(timestamp); @@ -2182,6 +2184,7 @@ PeerConnectionImpl::ExecuteStatsQuery_s(RTCStatsQuery *query) { s.mPacketsReceived.Construct(packetsReceived); s.mBytesReceived.Construct(bytesReceived); s.mPacketsLost.Construct(packetsLost); + s.mMozRtt.Construct(rtt); query->report.mInboundRTPStreamStats.Value().AppendElement(s); } } diff --git a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h index 65d57946b9a0..0f16c57e871f 100644 --- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h +++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h @@ -424,6 +424,17 @@ class RtpRtcp : public Module { */ virtual void SetRtt(uint32_t rtt) = 0; + /* + * Get time of last rr, as well as packets received remotely + * (derived from rr report + cached sender-side info). + * + * return -1 on failure else 0 + */ + virtual int32_t GetReportBlockInfo(const uint32_t remote_ssrc, + uint32_t* ntp_high, + uint32_t* ntp_low, + uint32_t* packets_received, + uint64_t* octets_received) const = 0; /* * Force a send of a RTCP packet * normal SR and RR are triggered via the process function diff --git a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc index 9ab1fb69b2d2..5b459197f3df 100644 --- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc +++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_receiver.cc @@ -234,6 +234,27 @@ int RTCPReceiver::SetRTT(uint16_t rtt) { return 0; } +int32_t RTCPReceiver::GetReportBlockInfo(uint32_t remoteSSRC, + uint32_t* NTPHigh, + uint32_t* NTPLow, + uint32_t* PacketsReceived, + uint64_t* OctetsReceived) const +{ + CriticalSectionScoped lock(_criticalSectionRTCPReceiver); + + RTCPReportBlockInformation* reportBlock = + GetReportBlockInformation(remoteSSRC); + + if (reportBlock == NULL) { + return -1; + } + *NTPHigh = reportBlock->lastReceivedRRNTPsecs; + *NTPLow = reportBlock->lastReceivedRRNTPfrac; + *PacketsReceived = reportBlock->remotePacketsReceived; + *OctetsReceived = reportBlock->remoteOctetsReceived; + return 0; +} + int32_t RTCPReceiver::NTP(uint32_t *ReceivedNTPsecs, uint32_t *ReceivedNTPfrac, @@ -477,8 +498,11 @@ RTCPReceiver::HandleReportBlock(const RTCPUtility::RTCPPacket& rtcpPacket, // To avoid problem with acquiring _criticalSectionRTCPSender while holding // _criticalSectionRTCPReceiver. _criticalSectionRTCPReceiver->Leave(); - uint32_t sendTimeMS = - _rtpRtcp.SendTimeOfSendReport(rtcpPacket.ReportBlockItem.LastSR); + uint32_t sendTimeMS = 0; + uint32_t sentPackets = 0; + uint64_t sentOctets = 0; + _rtpRtcp.GetSendReportMetadata(rtcpPacket.ReportBlockItem.LastSR, + &sendTimeMS, &sentPackets, &sentOctets); _criticalSectionRTCPReceiver->Enter(); RTCPReportBlockInformation* reportBlock = @@ -496,6 +520,12 @@ RTCPReceiver::HandleReportBlock(const RTCPUtility::RTCPPacket& rtcpPacket, reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost; reportBlock->remoteReceiveBlock.cumulativeLost = rb.CumulativeNumOfPacketsLost; + if (sentPackets > rb.CumulativeNumOfPacketsLost) { + uint32_t packetsReceived = sentPackets - rb.CumulativeNumOfPacketsLost; + reportBlock->remotePacketsReceived = packetsReceived; + reportBlock->remoteOctetsReceived = (sentOctets / sentPackets) * + packetsReceived; + } if (rb.ExtendedHighestSequenceNumber > reportBlock->remoteReceiveBlock.extendedHighSeqNum) { // We have successfully delivered new RTP packets to the remote side after @@ -516,14 +546,15 @@ RTCPReceiver::HandleReportBlock(const RTCPUtility::RTCPPacket& rtcpPacket, rtcpPacket.ReportBlockItem.DelayLastSR; // local NTP time when we received this - uint32_t lastReceivedRRNTPsecs = 0; - uint32_t lastReceivedRRNTPfrac = 0; + reportBlock->lastReceivedRRNTPsecs = 0; + reportBlock->lastReceivedRRNTPfrac = 0; - _clock->CurrentNtp(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac); + _clock->CurrentNtp(reportBlock->lastReceivedRRNTPsecs, + reportBlock->lastReceivedRRNTPfrac); // time when we received this in MS - uint32_t receiveTimeMS = Clock::NtpToMs(lastReceivedRRNTPsecs, - lastReceivedRRNTPfrac); + uint32_t receiveTimeMS = Clock::NtpToMs(reportBlock->lastReceivedRRNTPsecs, + reportBlock->lastReceivedRRNTPfrac); // Estimate RTT uint32_t d = (delaySinceLastSendReport & 0x0000ffff) * 1000; diff --git a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h index 014323188711..ca17282066a7 100644 --- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h +++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_receiver.h @@ -82,6 +82,12 @@ public: int32_t ResetRTT(const uint32_t remoteSSRC); + int32_t GetReportBlockInfo(uint32_t remoteSSRC, + uint32_t* NTPHigh, + uint32_t* NTPLow, + uint32_t* PacketsReceived, + uint64_t* OctetsReceived) const; + int32_t SenderInfoReceived(RTCPSenderInfo* senderInfo) const; // get statistics diff --git a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.cc b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.cc index 964512c4b94c..eab7232e526d 100644 --- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.cc +++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.cc @@ -101,6 +101,10 @@ RTCPPacketInformation::AddReportInfo( RTCPReportBlockInformation::RTCPReportBlockInformation(): remoteReceiveBlock(), remoteMaxJitter(0), + remotePacketsReceived(0), + remoteOctetsReceived(0), + lastReceivedRRNTPsecs(0), + lastReceivedRRNTPfrac(0), RTT(0), minRTT(0), maxRTT(0), diff --git a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.h b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.h index 85d3f53629ed..2d53bb736dab 100644 --- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.h +++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.h @@ -32,6 +32,10 @@ public: // Statistics RTCPReportBlock remoteReceiveBlock; uint32_t remoteMaxJitter; + uint32_t remotePacketsReceived; + uint64_t remoteOctetsReceived; + uint32_t lastReceivedRRNTPsecs; + uint32_t lastReceivedRRNTPfrac; // RTT uint16_t RTT; diff --git a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc index 6d81d95963d2..e52c0d5569f5 100644 --- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc +++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc @@ -127,6 +127,8 @@ RTCPSender::RTCPSender(const int32_t id, _lastSendReport(), _lastRTCPTime(), + _lastSRPacketCount(), + _lastSROctetCount(), _CSRCs(0), _CSRC(), @@ -157,6 +159,8 @@ RTCPSender::RTCPSender(const int32_t id, memset(_CNAME, 0, sizeof(_CNAME)); memset(_lastSendReport, 0, sizeof(_lastSendReport)); memset(_lastRTCPTime, 0, sizeof(_lastRTCPTime)); + memset(_lastSRPacketCount, 0, sizeof(_lastSRPacketCount)); + memset(_lastSROctetCount, 0, sizeof(_lastSROctetCount)); WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id, "%s created", __FUNCTION__); } @@ -228,6 +232,8 @@ RTCPSender::Init() memset(_CNAME, 0, sizeof(_CNAME)); memset(_lastSendReport, 0, sizeof(_lastSendReport)); memset(_lastRTCPTime, 0, sizeof(_lastRTCPTime)); + memset(_lastSRPacketCount, 0, sizeof(_lastSRPacketCount)); + memset(_lastSROctetCount, 0, sizeof(_lastSROctetCount)); _nackCount = 0; _pliCount = 0; @@ -569,26 +575,32 @@ RTCPSender::LastSendReport( uint32_t& lastRTCPTime) return _lastSendReport[0]; } -uint32_t -RTCPSender::SendTimeOfSendReport(const uint32_t sendReport) +bool +RTCPSender::GetSendReportMetadata(const uint32_t sendReport, + uint32_t *timeOfSend, + uint32_t *packetCount, + uint64_t *octetCount) { CriticalSectionScoped lock(_criticalSectionRTCPSender); // This is only saved when we are the sender if((_lastSendReport[0] == 0) || (sendReport == 0)) { - return 0; // will be ignored + return false; } else { for(int i = 0; i < RTCP_NUMBER_OF_SR; ++i) { if( _lastSendReport[i] == sendReport) { - return _lastRTCPTime[i]; + *timeOfSend = _lastRTCPTime[i]; + *packetCount = _lastSRPacketCount[i]; + *octetCount = _lastSROctetCount[i]; + return true; } } } - return 0; + return false; } int32_t RTCPSender::AddExternalReportBlock( @@ -664,10 +676,14 @@ int32_t RTCPSender::BuildSR(const FeedbackState& feedback_state, // shift old _lastSendReport[i+1] = _lastSendReport[i]; _lastRTCPTime[i+1] =_lastRTCPTime[i]; + _lastSRPacketCount[i+1] = _lastSRPacketCount[i]; + _lastSROctetCount[i+1] = _lastSROctetCount[i]; } _lastRTCPTime[0] = Clock::NtpToMs(NTPsec, NTPfrac); _lastSendReport[0] = (NTPsec << 16) + (NTPfrac >> 16); + _lastSRPacketCount[0] = feedback_state.packet_count_sent; + _lastSROctetCount[0] = feedback_state.byte_count_sent; // The timestamp of this RTCP packet should be estimated as the timestamp of // the frame being captured at this moment. We are calculating that diff --git a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_sender.h b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_sender.h index 909c15d231c2..48c218b89ff2 100644 --- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_sender.h +++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtcp_sender.h @@ -105,7 +105,10 @@ public: int32_t RemoveMixedCNAME(const uint32_t SSRC); - uint32_t SendTimeOfSendReport(const uint32_t sendReport); + bool GetSendReportMetadata(const uint32_t sendReport, + uint32_t *timeOfSend, + uint32_t *packetCount, + uint64_t *octetCount); bool TimeToSendRTCPReport(const bool sendKeyframeBeforeRTP = false) const; @@ -288,6 +291,8 @@ private: // Sent uint32_t _lastSendReport[RTCP_NUMBER_OF_SR]; // allow packet loss and RTT above 1 sec uint32_t _lastRTCPTime[RTCP_NUMBER_OF_SR]; + uint32_t _lastSRPacketCount[RTCP_NUMBER_OF_SR]; + uint64_t _lastSROctetCount[RTCP_NUMBER_OF_SR]; // send CSRCs uint8_t _CSRCs; diff --git a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc index 7c4cee7e8739..9228210af1e6 100644 --- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc +++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc @@ -910,6 +910,19 @@ void ModuleRtpRtcpImpl:: SetRtt(uint32_t rtt) { rtcp_receiver_.SetRTT(static_cast(rtt)); } +int32_t +ModuleRtpRtcpImpl::GetReportBlockInfo(const uint32_t remote_ssrc, + uint32_t* ntp_high, + uint32_t* ntp_low, + uint32_t* packets_received, + uint64_t* octets_received) const { + WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "RemotePacketsReceived()"); + + return rtcp_receiver_.GetReportBlockInfo(remote_ssrc, + ntp_high, ntp_low, + packets_received, octets_received); +} + // Reset RTP data counters for the sending side. int32_t ModuleRtpRtcpImpl::ResetSendDataCountersRTP() { WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, @@ -1538,9 +1551,14 @@ int32_t ModuleRtpRtcpImpl::SendRTCPReferencePictureSelection( feedback_state, kRtcpRpsi, 0, 0, false, picture_id); } -uint32_t ModuleRtpRtcpImpl::SendTimeOfSendReport( - const uint32_t send_report) { - return rtcp_sender_.SendTimeOfSendReport(send_report); +bool ModuleRtpRtcpImpl::GetSendReportMetadata(const uint32_t send_report, + uint32_t *time_of_send, + uint32_t *packet_count, + uint64_t *octet_count) { + return rtcp_sender_.GetSendReportMetadata(send_report, + time_of_send, + packet_count, + octet_count); } void ModuleRtpRtcpImpl::OnReceivedNACK( diff --git a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h index ada2442fe3ac..2e45f3216025 100644 --- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h +++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h @@ -173,6 +173,12 @@ class ModuleRtpRtcpImpl : public RtpRtcp { virtual void SetRtt(uint32_t rtt) OVERRIDE; + virtual int32_t GetReportBlockInfo(const uint32_t remote_ssrc, + uint32_t* ntp_high, + uint32_t* ntp_low, + uint32_t* packets_received, + uint64_t* octets_received) const OVERRIDE; + // Force a send of an RTCP packet. // Normal SR and RR are triggered via the process function. virtual int32_t SendRTCP(uint32_t rtcp_packet_type = kRtcpReport) OVERRIDE; @@ -331,7 +337,10 @@ class ModuleRtpRtcpImpl : public RtpRtcp { uint32_t* fec_rate, uint32_t* nackRate) const OVERRIDE; - virtual uint32_t SendTimeOfSendReport(const uint32_t send_report); + virtual bool GetSendReportMetadata(const uint32_t send_report, + uint32_t *time_of_send, + uint32_t *packet_count, + uint64_t *octet_count); // Good state of RTP receiver inform sender. virtual int32_t SendRTCPReferencePictureSelection( diff --git a/media/webrtc/trunk/webrtc/video_engine/include/vie_rtp_rtcp.h b/media/webrtc/trunk/webrtc/video_engine/include/vie_rtp_rtcp.h index c28a804b85ee..11094bffebd8 100644 --- a/media/webrtc/trunk/webrtc/video_engine/include/vie_rtp_rtcp.h +++ b/media/webrtc/trunk/webrtc/video_engine/include/vie_rtp_rtcp.h @@ -91,6 +91,8 @@ class WEBRTC_DLLEXPORT ViERTCPObserver { virtual ~ViERTCPObserver() {} }; +struct SenderInfo; + class WEBRTC_DLLEXPORT ViERTP_RTCP { public: enum { KDefaultDeltaTransmitTimeSeconds = 15 }; @@ -171,6 +173,16 @@ class WEBRTC_DLLEXPORT ViERTP_RTCP { const int video_channel, char rtcp_cname[KMaxRTCPCNameLength]) const = 0; + virtual int GetRemoteRTCPReceiverInfo(const int video_channel, + uint32_t& NTPHigh, + uint32_t& NTPLow, + uint32_t& receivedPacketCount, + uint64_t& receivedOctetCount, + uint32_t* jitter, + uint16_t* fractionLost, + uint32_t* cumulativeLost, + int32_t* rttMs) const = 0; + // This function sends an RTCP APP packet on a specific channel. virtual int SendApplicationDefinedRTCPPacket( const int video_channel, @@ -294,6 +306,10 @@ class WEBRTC_DLLEXPORT ViERTP_RTCP { unsigned int& bytes_received, unsigned int& packets_received) const = 0; + // Gets the sender info part of the last received RTCP Sender Report (SR) + virtual int GetRemoteRTCPSenderInfo(const int video_channel, + SenderInfo* sender_info) const = 0; + // The function gets bandwidth usage statistics from the sent RTP streams in // bits/s. virtual int GetBandwidthUsage(const int video_channel, diff --git a/media/webrtc/trunk/webrtc/video_engine/vie_channel.cc b/media/webrtc/trunk/webrtc/video_engine/vie_channel.cc index 0574eda004b9..0aa9468e1a79 100644 --- a/media/webrtc/trunk/webrtc/video_engine/vie_channel.cc +++ b/media/webrtc/trunk/webrtc/video_engine/vie_channel.cc @@ -30,6 +30,7 @@ #include "webrtc/video_engine/include/vie_image_process.h" #include "webrtc/video_engine/include/vie_rtp_rtcp.h" #include "webrtc/video_engine/vie_defines.h" +#include "webrtc/voice_engine/include/voe_rtp_rtcp.h" // for webrtc::SenderInfo namespace webrtc { @@ -1177,6 +1178,81 @@ int32_t ViEChannel::SendApplicationDefinedRTCPPacket( return 0; } +int32_t ViEChannel::GetRemoteRTCPReceiverInfo(uint32_t& NTPHigh, + uint32_t& NTPLow, + uint32_t& receivedPacketCount, + uint64_t& receivedOctetCount, + uint32_t* jitterSamples, + uint16_t* fractionLost, + uint32_t* cumulativeLost, + int32_t* rttMs) { + WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s", + __FUNCTION__); + + // TODO: how do we do this for simulcast ? average for all + // except cumulative_lost that is the sum ? + // CriticalSectionScoped cs(rtp_rtcp_cs_.get()); + + // for (std::list::const_iterator it = simulcast_rtp_rtcp_.begin(); + // it != simulcast_rtp_rtcp_.end(); + // it++) { + // RtpRtcp* rtp_rtcp = *it; + // } + uint32_t remote_ssrc = vie_receiver_.GetRemoteSsrc(); + + // Get all RTCP receiver report blocks that have been received on this + // channel. If we receive RTP packets from a remote source we know the + // remote SSRC and use the report block from him. + // Otherwise use the first report block. + std::vector remote_stats; + if (rtp_rtcp_->RemoteRTCPStat(&remote_stats) != 0 || remote_stats.empty()) { + WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(engine_id_, channel_id_), + "%s: Could not get remote stats", __FUNCTION__); + return -1; + } + std::vector::const_iterator statistics = + remote_stats.begin(); + for (; statistics != remote_stats.end(); ++statistics) { + if (statistics->remoteSSRC == remote_ssrc) + break; + } + + if (statistics == remote_stats.end()) { + // If we have not received any RTCP packets from this SSRC it probably means + // we have not received any RTP packets. + // Use the first received report block instead. + statistics = remote_stats.begin(); + remote_ssrc = statistics->remoteSSRC; + } + + if (rtp_rtcp_->GetReportBlockInfo(remote_ssrc, + &NTPHigh, + &NTPLow, + &receivedPacketCount, + &receivedOctetCount) != 0) { + WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(engine_id_, channel_id_), + "%s: failed to retrieve RTT", __FUNCTION__); + NTPHigh = 0; + NTPLow = 0; + receivedPacketCount = 0; + receivedOctetCount = 0; + } + + *fractionLost = statistics->fractionLost; + *cumulativeLost = statistics->cumulativeLost; + *jitterSamples = statistics->jitter; + + uint16_t dummy; + uint16_t rtt = 0; + if (rtp_rtcp_->RTT(remote_ssrc, &rtt, &dummy, &dummy, &dummy) != 0) { + WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(engine_id_, channel_id_), + "%s: Could not get RTT", __FUNCTION__); + return -1; + } + *rttMs = rtt; + return 0; +} + int32_t ViEChannel::GetSendRtcpStatistics(uint32_t* ntp_high, uint32_t* ntp_low, uint32_t* bytes_sent, @@ -1345,6 +1421,26 @@ int32_t ViEChannel::GetRtpStatistics(uint32_t* bytes_sent, return 0; } +int32_t ViEChannel::GetRemoteRTCPSenderInfo(SenderInfo* sender_info) const { + WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s", + __FUNCTION__); + + // Get the sender info from the latest received RTCP Sender Report. + RTCPSenderInfo rtcp_sender_info; + if (rtp_rtcp_->RemoteRTCPStat(&rtcp_sender_info) != 0) { + WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_), + "%s: failed to read RTCP SR sender info", __FUNCTION__); + return -1; + } + + sender_info->NTP_timestamp_high = rtcp_sender_info.NTPseconds; + sender_info->NTP_timestamp_low = rtcp_sender_info.NTPfraction; + sender_info->RTP_timestamp = rtcp_sender_info.RTPtimeStamp; + sender_info->sender_packet_count = rtcp_sender_info.sendPacketCount; + sender_info->sender_octet_count = rtcp_sender_info.sendOctetCount; + return 0; +} + void ViEChannel::GetBandwidthUsage(uint32_t* total_bitrate_sent, uint32_t* video_bitrate_sent, uint32_t* fec_bitrate_sent, diff --git a/media/webrtc/trunk/webrtc/video_engine/vie_channel.h b/media/webrtc/trunk/webrtc/video_engine/vie_channel.h index e806b13349dc..b952abccb2c6 100644 --- a/media/webrtc/trunk/webrtc/video_engine/vie_channel.h +++ b/media/webrtc/trunk/webrtc/video_engine/vie_channel.h @@ -48,6 +48,8 @@ class VideoDecoder; class VideoRenderCallback; class VoEVideoSync; +struct SenderInfo; + class ViEChannel : public VCMFrameTypeCallback, public VCMReceiveCallback, @@ -155,6 +157,7 @@ class ViEChannel // Gets the CName of the incoming stream. int32_t GetRemoteRTCPCName(char rtcp_cname[]); + int32_t RegisterRtpObserver(ViERTPObserver* observer); int32_t RegisterRtcpObserver(ViERTCPObserver* observer); int32_t SendApplicationDefinedRTCPPacket( @@ -163,6 +166,16 @@ class ViEChannel const uint8_t* data, uint16_t data_length_in_bytes); + // Gets info (including timestamp) from last rr + remote packetcount + // (derived from rr report + cached sender-side info). + int32_t GetRemoteRTCPReceiverInfo(uint32_t& NTPHigh, uint32_t& NTPLow, + uint32_t& receivedPacketCount, + uint64_t& receivedOctetCount, + uint32_t* jitterSamples, + uint16_t* fractionLost, + uint32_t* cumulativeLost, + int32_t* rttMs); + // Returns statistics reported by the remote client in an RTCP packet. int32_t GetSendRtcpStatistics(uint32_t* ntp_high, uint32_t* ntp_low, @@ -190,6 +203,9 @@ class ViEChannel uint32_t* packets_sent, uint32_t* bytes_received, uint32_t* packets_received) const; + + int32_t GetRemoteRTCPSenderInfo(SenderInfo* sender_info) const; + void GetBandwidthUsage(uint32_t* total_bitrate_sent, uint32_t* video_bitrate_sent, uint32_t* fec_bitrate_sent, diff --git a/media/webrtc/trunk/webrtc/video_engine/vie_rtp_rtcp_impl.cc b/media/webrtc/trunk/webrtc/video_engine/vie_rtp_rtcp_impl.cc index 25a3fef51ec4..3bc36e7e9375 100644 --- a/media/webrtc/trunk/webrtc/video_engine/vie_rtp_rtcp_impl.cc +++ b/media/webrtc/trunk/webrtc/video_engine/vie_rtp_rtcp_impl.cc @@ -424,6 +424,41 @@ int ViERTP_RTCPImpl::GetRemoteRTCPCName( return 0; } +int ViERTP_RTCPImpl::GetRemoteRTCPReceiverInfo(const int video_channel, + uint32_t& NTPHigh, + uint32_t& NTPLow, + uint32_t& receivedPacketCount, + uint64_t& receivedOctetCount, + uint32_t* jitter, + uint16_t* fractionLost, + uint32_t* cumulativeLost, + int32_t* rttMs) const { + WEBRTC_TRACE(kTraceApiCall, kTraceVideo, + ViEId(shared_data_->instance_id(), video_channel), + "%s(channel: %d)", __FUNCTION__, video_channel); + ViEChannelManagerScoped cs(*(shared_data_->channel_manager())); + ViEChannel* vie_channel = cs.Channel(video_channel); + if (!vie_channel) { + WEBRTC_TRACE(kTraceError, kTraceVideo, + ViEId(shared_data_->instance_id(), video_channel), + "%s: Channel %d doesn't exist", __FUNCTION__, video_channel); + shared_data_->SetLastError(kViERtpRtcpInvalidChannelId); + return -1; + } + if (vie_channel->GetRemoteRTCPReceiverInfo(NTPHigh, + NTPLow, + receivedPacketCount, + receivedOctetCount, + jitter, + fractionLost, + cumulativeLost, + rttMs) != 0) { + shared_data_->SetLastError(kViERtpRtcpUnknownError); + return -1; + } + return 0; +} + int ViERTP_RTCPImpl::SendApplicationDefinedRTCPPacket( const int video_channel, const unsigned char sub_type, @@ -921,6 +956,27 @@ int ViERTP_RTCPImpl::GetRTPStatistics(const int video_channel, return 0; } +int ViERTP_RTCPImpl::GetRemoteRTCPSenderInfo(const int video_channel, + SenderInfo* sender_info) const { + WEBRTC_TRACE(kTraceApiCall, kTraceVideo, + ViEId(shared_data_->instance_id(), video_channel), + "%s(channel: %d)", __FUNCTION__, video_channel); + ViEChannelManagerScoped cs(*(shared_data_->channel_manager())); + ViEChannel* vie_channel = cs.Channel(video_channel); + if (!vie_channel) { + WEBRTC_TRACE(kTraceError, kTraceVideo, + ViEId(shared_data_->instance_id(), video_channel), + "%s: Channel %d doesn't exist", __FUNCTION__, video_channel); + shared_data_->SetLastError(kViERtpRtcpInvalidChannelId); + return -1; + } + if (vie_channel->GetRemoteRTCPSenderInfo(sender_info) != 0) { + shared_data_->SetLastError(kViERtpRtcpUnknownError); + return -1; + } + return 0; +} + int ViERTP_RTCPImpl::GetBandwidthUsage(const int video_channel, unsigned int& total_bitrate_sent, unsigned int& video_bitrate_sent, diff --git a/media/webrtc/trunk/webrtc/video_engine/vie_rtp_rtcp_impl.h b/media/webrtc/trunk/webrtc/video_engine/vie_rtp_rtcp_impl.h index bd2926984aba..2ea63e041837 100644 --- a/media/webrtc/trunk/webrtc/video_engine/vie_rtp_rtcp_impl.h +++ b/media/webrtc/trunk/webrtc/video_engine/vie_rtp_rtcp_impl.h @@ -55,6 +55,15 @@ class ViERTP_RTCPImpl char rtcp_cname[KMaxRTCPCNameLength]) const; virtual int GetRemoteRTCPCName(const int video_channel, char rtcp_cname[KMaxRTCPCNameLength]) const; + virtual int GetRemoteRTCPReceiverInfo(const int video_channel, + uint32_t& NTPHigh, + uint32_t& NTPLow, + uint32_t& receivedPacketCount, + uint64_t& receivedOctetCount, + uint32_t* jitter, + uint16_t* fractionLost, + uint32_t* cumulativeLost, + int32_t* rttMs) const; virtual int SendApplicationDefinedRTCPPacket( const int video_channel, const unsigned char sub_type, @@ -113,6 +122,8 @@ class ViERTP_RTCPImpl unsigned int& packets_sent, unsigned int& bytes_received, unsigned int& packets_received) const; + virtual int GetRemoteRTCPSenderInfo(const int video_channel, + SenderInfo* sender_info) const; virtual int GetBandwidthUsage(const int video_channel, unsigned int& total_bitrate_sent, unsigned int& video_bitrate_sent, diff --git a/media/webrtc/trunk/webrtc/voice_engine/channel.cc b/media/webrtc/trunk/webrtc/voice_engine/channel.cc index a7a8ef2fd17c..b342194213c0 100644 --- a/media/webrtc/trunk/webrtc/voice_engine/channel.cc +++ b/media/webrtc/trunk/webrtc/voice_engine/channel.cc @@ -3797,107 +3797,81 @@ Channel::GetRemoteRTCP_CNAME(char cName[256]) } int -Channel::GetRemoteRTCPData( - unsigned int& NTPHigh, - unsigned int& NTPLow, - unsigned int& timestamp, - unsigned int& playoutTimestamp, - unsigned int& sendPacketCount, - unsigned int& sendOctetCount, - unsigned int* jitter, - unsigned short* fractionLost, - unsigned int* cumulativeLost) +Channel::GetRemoteRTCPReceiverInfo( + uint32_t& NTPHigh, + uint32_t& NTPLow, + uint32_t& receivedPacketCount, + uint64_t& receivedOctetCount, + uint32_t& jitter, + uint16_t& fractionLost, + uint32_t& cumulativeLost, + int32_t& rttMs) { - // --- Information from sender info in received Sender Reports + // Get all RTCP receiver report blocks that have been received on this + // channel. If we receive RTP packets from a remote source we know the + // remote SSRC and use the report block from him. + // Otherwise use the first report block. + std::vector remote_stats; + if (_rtpRtcpModule->RemoteRTCPStat(&remote_stats) != 0 || + remote_stats.empty()) { + WEBRTC_TRACE(kTraceWarning, kTraceVoice, + VoEId(_instanceId, _channelId), + "GetRemoteRTCPReceiverInfo() failed to measure statistics due" + " to lack of received RTP and/or RTCP packets"); + return -1; + } - RTCPSenderInfo senderInfo; - if (_rtpRtcpModule->RemoteRTCPStat(&senderInfo) != 0) - { - _engineStatisticsPtr->SetLastError( - VE_RTP_RTCP_MODULE_ERROR, kTraceError, - "GetRemoteRTCPData() failed to retrieve sender info for remote " - "side"); - return -1; - } + uint32_t remoteSSRC = rtp_receiver_->SSRC(); + std::vector::const_iterator it = remote_stats.begin(); + for (; it != remote_stats.end(); ++it) { + if (it->remoteSSRC == remoteSSRC) + break; + } - NTPHigh = senderInfo.NTPseconds; - NTPLow = senderInfo.NTPfraction; - timestamp = senderInfo.RTPtimeStamp; - sendPacketCount = senderInfo.sendPacketCount; - sendOctetCount = senderInfo.sendOctetCount; + if (it == remote_stats.end()) { + // If we have not received any RTCP packets from this SSRC it probably + // means that we have not received any RTP packets. + // Use the first received report block instead. + it = remote_stats.begin(); + remoteSSRC = it->remoteSSRC; + } - WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, + if (_rtpRtcpModule->GetReportBlockInfo(remoteSSRC, + &NTPHigh, + &NTPLow, + &receivedPacketCount, + &receivedOctetCount) != 0) { + WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), - "GetRemoteRTCPData() => NTPHigh=%lu, NTPLow=%lu, " - "timestamp=%lu", - NTPHigh, NTPLow, timestamp); + "GetRemoteRTCPReceiverInfo() failed to retrieve RTT from " + "the RTP/RTCP module"); + NTPHigh = 0; + NTPLow = 0; + receivedPacketCount = 0; + receivedOctetCount = 0; + } - // --- Locally derived information + jitter = it->jitter; + fractionLost = it->fractionLost; + cumulativeLost = it->cumulativeLost; + WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, + VoEId(_instanceId, _channelId), + "GetRemoteRTCPReceiverInfo() => jitter = %lu, " + "fractionLost = %lu, cumulativeLost = %lu", + jitter, fractionLost, cumulativeLost); - // This value is updated on each incoming RTCP packet (0 when no packet - // has been received) - playoutTimestamp = playout_timestamp_rtcp_; - - WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, + uint16_t dummy; + uint16_t rtt = 0; + if (_rtpRtcpModule->RTT(remoteSSRC, &rtt, &dummy, &dummy, &dummy) + != 0) + { + WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), - "GetRemoteRTCPData() => playoutTimestamp=%lu", - playout_timestamp_rtcp_); - - if (NULL != jitter || NULL != fractionLost || NULL != cumulativeLost) - { - // Get all RTCP receiver report blocks that have been received on this - // channel. If we receive RTP packets from a remote source we know the - // remote SSRC and use the report block from him. - // Otherwise use the first report block. - std::vector remote_stats; - if (_rtpRtcpModule->RemoteRTCPStat(&remote_stats) != 0 || - remote_stats.empty()) { - WEBRTC_TRACE(kTraceWarning, kTraceVoice, - VoEId(_instanceId, _channelId), - "GetRemoteRTCPData() failed to measure statistics due" - " to lack of received RTP and/or RTCP packets"); - return -1; - } - - uint32_t remoteSSRC = rtp_receiver_->SSRC(); - std::vector::const_iterator it = remote_stats.begin(); - for (; it != remote_stats.end(); ++it) { - if (it->remoteSSRC == remoteSSRC) - break; - } - - if (it == remote_stats.end()) { - // If we have not received any RTCP packets from this SSRC it probably - // means that we have not received any RTP packets. - // Use the first received report block instead. - it = remote_stats.begin(); - remoteSSRC = it->remoteSSRC; - } - - if (jitter) { - *jitter = it->jitter; - WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, - VoEId(_instanceId, _channelId), - "GetRemoteRTCPData() => jitter = %lu", *jitter); - } - - if (fractionLost) { - *fractionLost = it->fractionLost; - WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, - VoEId(_instanceId, _channelId), - "GetRemoteRTCPData() => fractionLost = %lu", - *fractionLost); - } - - if (cumulativeLost) { - *cumulativeLost = it->cumulativeLost; - WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, - VoEId(_instanceId, _channelId), - "GetRemoteRTCPData() => cumulativeLost = %lu", - *cumulativeLost); - } - } - return 0; + "GetRTPStatistics() failed to retrieve RTT from " + "the RTP/RTCP module"); + } + rttMs = rtt; + return 0; } int diff --git a/media/webrtc/trunk/webrtc/voice_engine/channel.h b/media/webrtc/trunk/webrtc/voice_engine/channel.h index c70bb31c5345..274b6ea7ef7a 100644 --- a/media/webrtc/trunk/webrtc/voice_engine/channel.h +++ b/media/webrtc/trunk/webrtc/voice_engine/channel.h @@ -264,14 +264,13 @@ public: int SetRTCP_CNAME(const char cName[256]); int GetRTCP_CNAME(char cName[256]); int GetRemoteRTCP_CNAME(char cName[256]); - int GetRemoteRTCPData(unsigned int& NTPHigh, unsigned int& NTPLow, - unsigned int& timestamp, - unsigned int& playoutTimestamp, - unsigned int& sendPacketCount, - unsigned int& sendOctetCount, - unsigned int* jitter, - unsigned short* fractionLost, - unsigned int* cumulativeLost); + int GetRemoteRTCPReceiverInfo(uint32_t& NTPHigh, uint32_t& NTPLow, + uint32_t& receivedPacketCount, + uint64_t& receivedOctetCount, + uint32_t& jitter, + uint16_t& fractionLost, + uint32_t& cumulativeLost, + int32_t& rttMs); int SendApplicationDefinedRTCPPacket(unsigned char subType, unsigned int name, const char* data, unsigned short dataLengthInBytes); diff --git a/media/webrtc/trunk/webrtc/voice_engine/include/voe_rtp_rtcp.h b/media/webrtc/trunk/webrtc/voice_engine/include/voe_rtp_rtcp.h index 8f7286b190a4..943864647856 100644 --- a/media/webrtc/trunk/webrtc/voice_engine/include/voe_rtp_rtcp.h +++ b/media/webrtc/trunk/webrtc/voice_engine/include/voe_rtp_rtcp.h @@ -182,12 +182,12 @@ public: virtual int GetRemoteRTCP_CNAME(int channel, char cName[256]) = 0; // Gets RTCP data from incoming RTCP Sender Reports. - virtual int GetRemoteRTCPData( - int channel, unsigned int& NTPHigh, unsigned int& NTPLow, - unsigned int& timestamp, unsigned int& playoutTimestamp, - unsigned int& sendPacketCount, unsigned int& sendOctetCount, - unsigned int* jitter = NULL, unsigned short* fractionLost = NULL, - unsigned int* cumulativeLost = NULL) = 0; + virtual int GetRemoteRTCPReceiverInfo( + int channel, uint32_t& NTPHigh, uint32_t& NTPLow, + uint32_t& receivedPacketCount, uint64_t& receivedOctetCount, + uint32_t& jitter, uint16_t& fractionLost, + uint32_t& cumulativeLost, + int32_t& rttMs) = 0; // Gets RTP statistics for a specific |channel|. virtual int GetRTPStatistics( diff --git a/media/webrtc/trunk/webrtc/voice_engine/voe_rtp_rtcp_impl.cc b/media/webrtc/trunk/webrtc/voice_engine/voe_rtp_rtcp_impl.cc index 3f251d6f15a2..c12ff6d4173f 100644 --- a/media/webrtc/trunk/webrtc/voice_engine/voe_rtp_rtcp_impl.cc +++ b/media/webrtc/trunk/webrtc/voice_engine/voe_rtp_rtcp_impl.cc @@ -369,20 +369,19 @@ int VoERTP_RTCPImpl::GetRemoteRTCP_CNAME(int channel, char cName[256]) return channelPtr->GetRemoteRTCP_CNAME(cName); } -int VoERTP_RTCPImpl::GetRemoteRTCPData( +int VoERTP_RTCPImpl::GetRemoteRTCPReceiverInfo( int channel, - unsigned int& NTPHigh, // from sender info in SR - unsigned int& NTPLow, // from sender info in SR - unsigned int& timestamp, // from sender info in SR - unsigned int& playoutTimestamp, // derived locally - unsigned int& sendPacketCount, // from sender info in SR - unsigned int& sendOctetCount, // from sender info in SR - unsigned int* jitter, // from report block 1 in SR/RR - unsigned short* fractionLost, // from report block 1 in SR/RR - unsigned int* cumulativeLost) // from report block 1 in SR/RR + uint32_t& NTPHigh, // when last RR received + uint32_t& NTPLow, // when last RR received + uint32_t& receivedPacketCount, // derived from RR + cached info + uint64_t& receivedOctetCount, // derived from RR + cached info + uint32_t& jitter, // from report block 1 in RR + uint16_t& fractionLost, // from report block 1 in RR + uint32_t& cumulativeLost, // from report block 1 in RR + int32_t& rttMs) { WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), - "GetRemoteRTCPData(channel=%d,...)", channel); + "GetRemoteRTCPReceiverInfo(channel=%d,...)", channel); if (!_shared->statistics().Initialized()) { _shared->SetLastError(VE_NOT_INITED, kTraceError); @@ -393,18 +392,17 @@ int VoERTP_RTCPImpl::GetRemoteRTCPData( if (channelPtr == NULL) { _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, - "GetRemoteRTCP_CNAME() failed to locate channel"); + "GetRemoteRTCPReceiverInfo() failed to locate channel"); return -1; } - return channelPtr->GetRemoteRTCPData(NTPHigh, - NTPLow, - timestamp, - playoutTimestamp, - sendPacketCount, - sendOctetCount, - jitter, - fractionLost, - cumulativeLost); + return channelPtr->GetRemoteRTCPReceiverInfo(NTPHigh, + NTPLow, + receivedPacketCount, + receivedOctetCount, + jitter, + fractionLost, + cumulativeLost, + rttMs); } int VoERTP_RTCPImpl::SendApplicationDefinedRTCPPacket( diff --git a/media/webrtc/trunk/webrtc/voice_engine/voe_rtp_rtcp_impl.h b/media/webrtc/trunk/webrtc/voice_engine/voe_rtp_rtcp_impl.h index 73280967bf4e..db14cfc4fcce 100644 --- a/media/webrtc/trunk/webrtc/voice_engine/voe_rtp_rtcp_impl.h +++ b/media/webrtc/trunk/webrtc/voice_engine/voe_rtp_rtcp_impl.h @@ -40,16 +40,15 @@ public: virtual int GetRemoteRTCP_CNAME(int channel, char cName[256]); - virtual int GetRemoteRTCPData(int channel, - unsigned int& NTPHigh, - unsigned int& NTPLow, - unsigned int& timestamp, - unsigned int& playoutTimestamp, - unsigned int& sendPacketCount, - unsigned int& sendOctetCount, - unsigned int* jitter = NULL, - unsigned short* fractionLost = NULL, - unsigned int* cumulativeLost = NULL); + virtual int GetRemoteRTCPReceiverInfo(int channel, + uint32_t& NTPHigh, + uint32_t& NTPLow, + uint32_t& receivedPacketCount, + uint64_t& receivedOctetCount, + uint32_t& jitter, + uint16_t& fractionLost, + uint32_t& cumulativeLost, + int32_t& rttMs); virtual int SendApplicationDefinedRTCPPacket( int channel,