Bug 947665 - RTCP stats in getStats and about:webrtc. r=jesup

This commit is contained in:
Jan-Ivar Bruaroey 2014-01-21 14:00:06 -05:00
parent 53d09122db
commit 0683b9ca72
18 changed files with 383 additions and 63 deletions

View File

@ -1565,13 +1565,17 @@ PeerConnectionWrapper.prototype = {
for (var key in stats) {
if (stats.hasOwnProperty(key)) {
var res = stats[key];
counters[res.type] = toNum(counters[res.type]) + 1;
if (!res.isRemote) {
counters[res.type] = toNum(counters[res.type]) + 1;
}
}
}
// Use MapClass way of enumerating stats
var counters2 = {};
stats.forEach(function(res) {
counters2[res.type] = toNum(counters2[res.type]) + 1;
if (!res.isRemote) {
counters2[res.type] = toNum(counters2[res.type]) + 1;
}
});
is(JSON.stringify(counters), JSON.stringify(counters2),
"Spec and MapClass variant of RTCStatsReport enumeration agree");

View File

@ -23,6 +23,7 @@
#endif
#include "webrtc/voice_engine/include/voe_errors.h"
#include "webrtc/system_wrappers/interface/clock.h"
#ifdef MOZ_WIDGET_ANDROID
#include "AndroidJNIWrapper.h"
@ -145,13 +146,63 @@ bool WebrtcAudioConduit::GetRemoteSSRC(unsigned int* ssrc) {
return !mPtrRTP->GetRemoteSSRC(mChannel, *ssrc);
}
bool WebrtcAudioConduit::GetReceivedJitter(unsigned int* jitterMs) {
bool WebrtcAudioConduit::GetRTPJitter(unsigned int* jitterMs) {
unsigned int maxJitterMs;
unsigned int discardedPackets;
return !mPtrRTP->GetRTPStatistics(mChannel, *jitterMs, maxJitterMs,
discardedPackets);
}
DOMHighResTimeStamp
NTPtoDOMHighResTimeStamp(uint32_t ntpHigh, uint32_t ntpLow) {
return (uint32_t(ntpHigh - webrtc::kNtpJan1970) +
double(ntpLow) / webrtc::kMagicNtpFractionalUnit) * 1000;
}
bool WebrtcAudioConduit::GetRTCPReceiverReport(DOMHighResTimeStamp* timestamp,
unsigned int* jitterMs,
unsigned int* packetsReceived,
uint64_t* bytesReceived) {
unsigned int ntpHigh, ntpLow;
unsigned int rtpTimestamp, playoutTimestamp;
unsigned int packetsSent;
unsigned int bytesSent32;
unsigned short fractionLost;
unsigned int cumulativeLost;
bool result = !mPtrRTP->GetRemoteRTCPData(mChannel, ntpHigh, ntpLow,
rtpTimestamp, playoutTimestamp,
packetsSent, bytesSent32,
jitterMs,
&fractionLost, &cumulativeLost);
if (result) {
*timestamp = NTPtoDOMHighResTimeStamp(ntpHigh, ntpLow);
*packetsReceived = (packetsSent >= cumulativeLost) ?
(packetsSent - cumulativeLost) : 0;
*bytesReceived = (packetsSent ?
(bytesSent32 / packetsSent) : 0) * (*packetsReceived);
}
return result;
}
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);
if (result) {
*timestamp = NTPtoDOMHighResTimeStamp(ntpHigh, ntpLow);
*bytesSent = bytesSent32;
}
return result;
}
/*
* WebRTCAudioConduit Implementation
*/

View File

@ -38,6 +38,11 @@
namespace mozilla {
// Helper function
DOMHighResTimeStamp
NTPtoDOMHighResTimeStamp(uint32_t ntpHigh, uint32_t ntpLow);
/**
* Concrete class for Audio session. Hooks up
* - media-source and target to external transport
@ -172,7 +177,14 @@ public:
webrtc::VoiceEngine* GetVoiceEngine() { return mVoiceEngine; }
bool GetLocalSSRC(unsigned int* ssrc);
bool GetRemoteSSRC(unsigned int* ssrc);
bool GetReceivedJitter(unsigned int* jitterMs);
bool GetRTPJitter(unsigned int* jitterMs);
bool GetRTCPReceiverReport(DOMHighResTimeStamp* timestamp,
unsigned int* jitterMs,
unsigned int* packetsReceived,
uint64_t* bytesReceived);
bool GetRTCPSenderReport(DOMHighResTimeStamp* timestamp,
unsigned int* packetsSent,
uint64_t* bytesSent);
private:
WebrtcAudioConduit(const WebrtcAudioConduit& other) MOZ_DELETE;

View File

@ -7,6 +7,7 @@
#include "nsISupportsImpl.h"
#include "nsXPCOM.h"
#include "nsDOMNavigationTiming.h"
#include "mozilla/RefPtr.h"
#include "CodecConfig.h"
#include "VideoTypes.h"
@ -138,7 +139,18 @@ public:
virtual bool GetLocalSSRC(unsigned int* ssrc) = 0;
virtual bool GetRemoteSSRC(unsigned int* ssrc) = 0;
virtual bool GetReceivedJitter(unsigned int* jitterMs) = 0;
/**
* Functions returning stats needed by w3c stats model.
*/
virtual bool GetRTPJitter(unsigned int* jitterMs) = 0;
virtual bool GetRTCPReceiverReport(DOMHighResTimeStamp* timestamp,
unsigned int* jitterMs,
unsigned int* packetsReceived,
uint64_t* bytesReceived) = 0;
virtual bool GetRTCPSenderReport(DOMHighResTimeStamp* timestamp,
unsigned int* packetsSent,
uint64_t* bytesSent) = 0;
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaSessionConduit)

View File

@ -145,12 +145,16 @@ bool WebrtcVideoConduit::GetRemoteSSRC(unsigned int* ssrc) {
return !mPtrRTP->GetRemoteSSRC(mChannel, *ssrc);
}
bool WebrtcVideoConduit::GetReceivedJitter(unsigned int* jitterMs) {
bool WebrtcVideoConduit::GetRTPJitter(unsigned int* jitterMs) {
unsigned int ntpHigh, ntpLow;
unsigned int packetsSent, bytesSent;
unsigned short fractionLost;
unsigned int cumulativeLost;
unsigned extendedMax;
int rttMs;
return !mPtrRTP->GetReceivedRTCPStatistics(mChannel,
// GetReceivedRTCPStatistics is a poorly named GetRTPStatistics variant
return !mPtrRTP->GetReceivedRTCPStatistics(mChannel, ntpHigh, ntpLow,
packetsSent, bytesSent,
fractionLost,
cumulativeLost,
extendedMax,
@ -158,6 +162,57 @@ bool WebrtcVideoConduit::GetReceivedJitter(unsigned int* jitterMs) {
rttMs);
}
bool WebrtcVideoConduit::GetRTCPReceiverReport(DOMHighResTimeStamp* timestamp,
unsigned int* jitterMs,
unsigned int* packetsReceived,
uint64_t* bytesReceived) {
unsigned int ntpHigh, ntpLow;
unsigned int packetsSent;
unsigned int bytesSent32;
unsigned short fractionLost;
unsigned int cumulativeLost;
unsigned extendedMax;
int rttMs;
bool result = !mPtrRTP->GetSentRTCPStatistics(mChannel, ntpHigh, ntpLow,
bytesSent32, packetsSent,
fractionLost,
cumulativeLost,
extendedMax,
*jitterMs,
rttMs);
if (result) {
*timestamp = NTPtoDOMHighResTimeStamp(ntpHigh, ntpLow);
*packetsReceived = (packetsSent >= cumulativeLost) ?
(packetsSent - cumulativeLost) : 0;
*bytesReceived = (packetsSent ?
(bytesSent32 / packetsSent) : 0) * (*packetsReceived);
}
return result;
}
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);
if (result) {
*timestamp = NTPtoDOMHighResTimeStamp(ntpHigh, ntpLow);
*bytesSent = bytesSent32;
}
return result;
}
/**
* Peforms intialization of the MANDATORY components of the Video Engine
*/

View File

@ -210,7 +210,14 @@ public:
webrtc::VideoEngine* GetVideoEngine() { return mVideoEngine; }
bool GetLocalSSRC(unsigned int* ssrc);
bool GetRemoteSSRC(unsigned int* ssrc);
bool GetReceivedJitter(unsigned int* jitterMs);
bool GetRTPJitter(unsigned int* jitterMs);
bool GetRTCPReceiverReport(DOMHighResTimeStamp* timestamp,
unsigned int* jitterMs,
unsigned int* packetsReceived,
uint64_t* bytesReceived);
bool GetRTCPSenderReport(DOMHighResTimeStamp* timestamp,
unsigned int* packetsSent,
uint64_t* bytesSent);
private:

View File

@ -1325,7 +1325,7 @@ PeerConnectionImpl::GetStats(MediaStreamTrack *aSelector, bool internalStats) {
} else {
CSFLogError(logTag, "Failed to get NrIceMediaStream for level %u "
"in %s: %s",
level, __FUNCTION__, mHandle.c_str());
uint32_t(level), __FUNCTION__, mHandle.c_str());
MOZ_CRASH();
}
}
@ -1978,36 +1978,103 @@ PeerConnectionImpl::GetStatsImpl_s(
switch (mp.direction()) {
case MediaPipeline::TRANSMIT: {
RTCOutboundRTPStreamStats s;
s.mTimestamp.Construct(now);
s.mId.Construct(NS_LITERAL_STRING("outbound_rtp_") + idstr);
s.mType.Construct(RTCStatsType::Outboundrtp);
unsigned int ssrc;
if (mp.Conduit()->GetLocalSSRC(&ssrc)) {
nsString str;
str.AppendInt(ssrc);
s.mSsrc.Construct(str);
nsString localId = NS_LITERAL_STRING("outbound_rtp_") + idstr;
nsString remoteId;
nsString ssrc;
unsigned int ssrcval;
if (mp.Conduit()->GetLocalSSRC(&ssrcval)) {
ssrc.AppendInt(ssrcval);
}
{
// First, fill in remote stat with rtcp receiver data, if present.
// ReceiverReports have less information than SenderReports,
// so fill in what we can.
DOMHighResTimeStamp timestamp;
uint32_t jitterMs;
uint32_t packetsReceived;
uint64_t bytesReceived;
if (mp.Conduit()->GetRTCPReceiverReport(&timestamp, &jitterMs,
&packetsReceived,
&bytesReceived)) {
remoteId = NS_LITERAL_STRING("outbound_rtcp_") + idstr;
RTCInboundRTPStreamStats s;
s.mTimestamp.Construct(timestamp);
s.mId.Construct(remoteId);
s.mType.Construct(RTCStatsType::Inboundrtp);
if (ssrc.Length()) {
s.mSsrc.Construct(ssrc);
}
s.mJitter.Construct(double(jitterMs)/1000);
s.mRemoteId.Construct(localId);
s.mIsRemote = true;
s.mPacketsReceived.Construct(packetsReceived);
s.mBytesReceived.Construct(bytesReceived);
report->mInboundRTPStreamStats.Value().AppendElement(s);
}
}
// Then, fill in local side (with cross-link to remote only if present)
{
RTCOutboundRTPStreamStats s;
s.mTimestamp.Construct(now);
s.mId.Construct(localId);
s.mType.Construct(RTCStatsType::Outboundrtp);
if (ssrc.Length()) {
s.mSsrc.Construct(ssrc);
}
s.mRemoteId.Construct(remoteId);
s.mIsRemote = false;
s.mPacketsSent.Construct(mp.rtp_packets_sent());
s.mBytesSent.Construct(mp.rtp_bytes_sent());
report->mOutboundRTPStreamStats.Value().AppendElement(s);
}
s.mPacketsSent.Construct(mp.rtp_packets_sent());
s.mBytesSent.Construct(mp.rtp_bytes_sent());
report->mOutboundRTPStreamStats.Value().AppendElement(s);
break;
}
case MediaPipeline::RECEIVE: {
nsString localId = NS_LITERAL_STRING("inbound_rtp_") + idstr;
nsString remoteId;
nsString ssrc;
unsigned int ssrcval;
if (mp.Conduit()->GetRemoteSSRC(&ssrcval)) {
ssrc.AppendInt(ssrcval);
}
{
// First, fill in remote stat with rtcp sender data, if present.
DOMHighResTimeStamp timestamp;
uint32_t packetsSent;
uint64_t bytesSent;
if (mp.Conduit()->GetRTCPSenderReport(&timestamp,
&packetsSent, &bytesSent)) {
remoteId = NS_LITERAL_STRING("inbound_rtcp_") + idstr;
RTCOutboundRTPStreamStats s;
s.mTimestamp.Construct(timestamp);
s.mId.Construct(remoteId);
s.mType.Construct(RTCStatsType::Outboundrtp);
if (ssrc.Length()) {
s.mSsrc.Construct(ssrc);
}
s.mRemoteId.Construct(localId);
s.mIsRemote = true;
s.mPacketsSent.Construct(packetsSent);
s.mBytesSent.Construct(bytesSent);
report->mOutboundRTPStreamStats.Value().AppendElement(s);
}
}
// Then, fill in local side (with cross-link to remote only if present)
RTCInboundRTPStreamStats s;
s.mTimestamp.Construct(now);
s.mId.Construct(NS_LITERAL_STRING("inbound_rtp_") + idstr);
s.mId.Construct(localId);
s.mType.Construct(RTCStatsType::Inboundrtp);
unsigned int ssrc;
if (mp.Conduit()->GetRemoteSSRC(&ssrc)) {
nsString str;
str.AppendInt(ssrc);
s.mSsrc.Construct(str);
if (ssrc.Length()) {
s.mSsrc.Construct(ssrc);
}
unsigned int jitterMs;
if (mp.Conduit()->GetReceivedJitter(&jitterMs)) {
if (mp.Conduit()->GetRTPJitter(&jitterMs)) {
s.mJitter.Construct(double(jitterMs)/1000);
}
if (remoteId.Length()) {
s.mRemoteId.Construct(remoteId);
}
s.mIsRemote = false;
s.mPacketsReceived.Construct(mp.rtp_packets_received());
s.mBytesReceived.Construct(mp.rtp_bytes_received());
report->mInboundRTPStreamStats.Value().AppendElement(s);

View File

@ -264,6 +264,10 @@ class WEBRTC_DLLEXPORT ViERTP_RTCP {
// stream.
virtual int GetReceivedRTCPStatistics(
const int video_channel,
unsigned int& ntpHigh,
unsigned int& ntpLow,
unsigned int& bytes_sent,
unsigned int& packets_sent,
unsigned short& fraction_lost,
unsigned int& cumulative_lost,
unsigned int& extended_max,
@ -273,6 +277,10 @@ class WEBRTC_DLLEXPORT ViERTP_RTCP {
// This function returns statistics reported by the remote client in a RTCP
// packet.
virtual int GetSentRTCPStatistics(const int video_channel,
unsigned int& ntpHigh,
unsigned int& ntpLow,
unsigned int& bytes_sent,
unsigned int& packets_sent,
unsigned short& fraction_lost,
unsigned int& cumulative_lost,
unsigned int& extended_max,

View File

@ -1177,7 +1177,11 @@ int32_t ViEChannel::SendApplicationDefinedRTCPPacket(
return 0;
}
int32_t ViEChannel::GetSendRtcpStatistics(uint16_t* fraction_lost,
int32_t ViEChannel::GetSendRtcpStatistics(uint32_t* ntp_high,
uint32_t* ntp_low,
uint32_t* bytes_sent,
uint32_t* packets_sent,
uint16_t* fraction_lost,
uint32_t* cumulative_lost,
uint32_t* extended_max,
uint32_t* jitter_samples,
@ -1196,6 +1200,20 @@ int32_t ViEChannel::GetSendRtcpStatistics(uint16_t* fraction_lost,
// }
uint32_t remote_ssrc = vie_receiver_.GetRemoteSsrc();
// --- Information from sender info in received RTCP Sender Reports
RTCPSenderInfo sender_info;
if (rtp_rtcp_->RemoteRTCPStat(&sender_info) != 0) {
WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(engine_id_, channel_id_),
"%s: Could not get sender info for remote side", __FUNCTION__);
return -1;
}
*ntp_high = sender_info.NTPseconds;
*ntp_low = sender_info.NTPfraction;
*bytes_sent = sender_info.sendOctetCount;
*packets_sent = sender_info.sendPacketCount;
// 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.
@ -1240,7 +1258,11 @@ int32_t ViEChannel::GetSendRtcpStatistics(uint16_t* fraction_lost,
// TODO(holmer): This is a bad function name as it implies that it returns the
// received RTCP, while it actually returns the statistics which will be sent
// in the RTCP.
int32_t ViEChannel::GetReceivedRtcpStatistics(uint16_t* fraction_lost,
int32_t ViEChannel::GetReceivedRtcpStatistics(uint32_t* ntp_high,
uint32_t* ntp_low,
uint32_t* bytes_sent,
uint32_t* packets_sent,
uint16_t* fraction_lost,
uint32_t* cumulative_lost,
uint32_t* extended_max,
uint32_t* jitter_samples,
@ -1248,6 +1270,22 @@ int32_t ViEChannel::GetReceivedRtcpStatistics(uint16_t* fraction_lost,
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
"%s", __FUNCTION__);
// --- Information from sender info in received RTCP Sender Reports
RTCPSenderInfo sender_info;
if (rtp_rtcp_->RemoteRTCPStat(&sender_info) != 0) {
WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(engine_id_, channel_id_),
"%s: Could not get sender info for remote side", __FUNCTION__);
return -1;
}
*ntp_high = sender_info.NTPseconds;
*ntp_low = sender_info.NTPfraction;
*bytes_sent = sender_info.sendOctetCount;
*packets_sent = sender_info.sendPacketCount;
// --- Locally derived information
uint32_t remote_ssrc = vie_receiver_.GetRemoteSsrc();
uint8_t frac_lost = 0;
StreamStatistician* statistician =

View File

@ -164,14 +164,22 @@ class ViEChannel
uint16_t data_length_in_bytes);
// Returns statistics reported by the remote client in an RTCP packet.
int32_t GetSendRtcpStatistics(uint16_t* fraction_lost,
int32_t GetSendRtcpStatistics(uint32_t* ntp_high,
uint32_t* ntp_low,
uint32_t* bytes_sent,
uint32_t* packets_sent,
uint16_t* fraction_lost,
uint32_t* cumulative_lost,
uint32_t* extended_max,
uint32_t* jitter_samples,
int32_t* rtt_ms);
// Returns our localy created statistics of the received RTP stream.
int32_t GetReceivedRtcpStatistics(uint16_t* fraction_lost,
// Returns RTCP sender report + locally created stats of received RTP stream
int32_t GetReceivedRtcpStatistics(uint32_t* ntp_high,
uint32_t* ntp_low,
uint32_t* bytes_sent,
uint32_t* packets_sent,
uint16_t* fraction_lost,
uint32_t* cumulative_lost,
uint32_t* extended_max,
uint32_t* jitter_samples,

View File

@ -824,6 +824,10 @@ int ViERTP_RTCPImpl::SetTransmissionSmoothingStatus(int video_channel,
}
int ViERTP_RTCPImpl::GetReceivedRTCPStatistics(const int video_channel,
unsigned int& ntp_high,
unsigned int& ntp_low,
unsigned int& bytes_sent,
unsigned int& packets_sent,
uint16_t& fraction_lost,
unsigned int& cumulative_lost,
unsigned int& extended_max,
@ -841,7 +845,11 @@ int ViERTP_RTCPImpl::GetReceivedRTCPStatistics(const int video_channel,
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->GetReceivedRtcpStatistics(&fraction_lost,
if (vie_channel->GetReceivedRtcpStatistics(&ntp_high,
&ntp_low,
&bytes_sent,
&packets_sent,
&fraction_lost,
&cumulative_lost,
&extended_max,
&jitter,
@ -853,6 +861,10 @@ int ViERTP_RTCPImpl::GetReceivedRTCPStatistics(const int video_channel,
}
int ViERTP_RTCPImpl::GetSentRTCPStatistics(const int video_channel,
unsigned int& ntp_high,
unsigned int& ntp_low,
unsigned int& bytes_sent,
unsigned int& packets_sent,
uint16_t& fraction_lost,
unsigned int& cumulative_lost,
unsigned int& extended_max,
@ -871,7 +883,9 @@ int ViERTP_RTCPImpl::GetSentRTCPStatistics(const int video_channel,
return -1;
}
if (vie_channel->GetSendRtcpStatistics(&fraction_lost, &cumulative_lost,
if (vie_channel->GetSendRtcpStatistics(&ntp_high, &ntp_low,
&bytes_sent, &packets_sent,
&fraction_lost, &cumulative_lost,
&extended_max, &jitter,
&rtt_ms) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);

View File

@ -90,12 +90,20 @@ class ViERTP_RTCPImpl
int id);
virtual int SetTransmissionSmoothingStatus(int video_channel, bool enable);
virtual int GetReceivedRTCPStatistics(const int video_channel,
unsigned int& ntpHigh,
unsigned int& ntpLow,
unsigned int& bytes_sent,
unsigned int& packets_sent,
uint16_t& fraction_lost,
unsigned int& cumulative_lost,
unsigned int& extended_max,
unsigned int& jitter,
int& rtt_ms) const;
virtual int GetSentRTCPStatistics(const int video_channel,
unsigned int& ntpHigh,
unsigned int& ntpLow,
unsigned int& bytes_sent,
unsigned int& packets_sent,
uint16_t& fraction_lost,
unsigned int& cumulative_lost,
unsigned int& extended_max,

View File

@ -3799,8 +3799,11 @@ Channel::GetRemoteRTCPData(
unsigned int& NTPLow,
unsigned int& timestamp,
unsigned int& playoutTimestamp,
unsigned int& sendPacketCount,
unsigned int& sendOctetCount,
unsigned int* jitter,
unsigned short* fractionLost)
unsigned short* fractionLost,
unsigned int* cumulativeLost)
{
// --- Information from sender info in received Sender Reports
@ -3814,11 +3817,11 @@ Channel::GetRemoteRTCPData(
return -1;
}
// We only utilize 12 out of 20 bytes in the sender info (ignores packet
// and octet count)
NTPHigh = senderInfo.NTPseconds;
NTPLow = senderInfo.NTPfraction;
timestamp = senderInfo.RTPtimeStamp;
sendPacketCount = senderInfo.sendPacketCount;
sendOctetCount = senderInfo.sendOctetCount;
WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
VoEId(_instanceId, _channelId),
@ -3837,7 +3840,7 @@ Channel::GetRemoteRTCPData(
"GetRemoteRTCPData() => playoutTimestamp=%lu",
playout_timestamp_rtcp_);
if (NULL != jitter || NULL != fractionLost)
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
@ -3882,6 +3885,14 @@ Channel::GetRemoteRTCPData(
"GetRemoteRTCPData() => fractionLost = %lu",
*fractionLost);
}
if (cumulativeLost) {
*cumulativeLost = it->cumulativeLost;
WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
VoEId(_instanceId, _channelId),
"GetRemoteRTCPData() => cumulativeLost = %lu",
*cumulativeLost);
}
}
return 0;
}

View File

@ -264,8 +264,12 @@ public:
int GetRemoteRTCP_CNAME(char cName[256]);
int GetRemoteRTCPData(unsigned int& NTPHigh, unsigned int& NTPLow,
unsigned int& timestamp,
unsigned int& playoutTimestamp, unsigned int* jitter,
unsigned short* fractionLost);
unsigned int& playoutTimestamp,
unsigned int& sendPacketCount,
unsigned int& sendOctetCount,
unsigned int* jitter,
unsigned short* fractionLost,
unsigned int* cumulativeLost);
int SendApplicationDefinedRTCPPacket(unsigned char subType,
unsigned int name, const char* data,
unsigned short dataLengthInBytes);

View File

@ -185,7 +185,9 @@ public:
virtual int GetRemoteRTCPData(
int channel, unsigned int& NTPHigh, unsigned int& NTPLow,
unsigned int& timestamp, unsigned int& playoutTimestamp,
unsigned int* jitter = NULL, unsigned short* fractionLost = NULL) = 0;
unsigned int& sendPacketCount, unsigned int& sendOctetCount,
unsigned int* jitter = NULL, unsigned short* fractionLost = NULL,
unsigned int* cumulativeLost = NULL) = 0;
// Gets RTP statistics for a specific |channel|.
virtual int GetRTPStatistics(

View File

@ -375,8 +375,11 @@ int VoERTP_RTCPImpl::GetRemoteRTCPData(
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 short* fractionLost, // from report block 1 in SR/RR
unsigned int* cumulativeLost) // from report block 1 in SR/RR
{
WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
"GetRemoteRTCPData(channel=%d,...)", channel);
@ -397,8 +400,11 @@ int VoERTP_RTCPImpl::GetRemoteRTCPData(
NTPLow,
timestamp,
playoutTimestamp,
sendPacketCount,
sendOctetCount,
jitter,
fractionLost);
fractionLost,
cumulativeLost);
}
int VoERTP_RTCPImpl::SendApplicationDefinedRTCPPacket(

View File

@ -45,8 +45,11 @@ public:
unsigned int& NTPLow,
unsigned int& timestamp,
unsigned int& playoutTimestamp,
unsigned int& sendPacketCount,
unsigned int& sendOctetCount,
unsigned int* jitter = NULL,
unsigned short* fractionLost = NULL);
unsigned short* fractionLost = NULL,
unsigned int* cumulativeLost = NULL);
virtual int SendApplicationDefinedRTCPPacket(
int channel,

View File

@ -148,6 +148,26 @@ function round00(num) {
return Math.round(num * 100) / 100;
}
function dumpStat(stat, label) {
var div = document.createElement('div');
var statsString = " " + label + new Date(stat.timestamp).toTimeString() +
" " + stat.type + " SSRC: " + stat.ssrc;
if (stat.packetsReceived !== undefined) {
statsString += " Received: " + stat.packetsReceived + " packets";
if (stat.bytesReceived !== undefined) {
statsString += " (" + round00(stat.bytesReceived/1024) + " Kb)";
}
statsString += " Jitter: " + stat.jitter;
} else if (stat.packetsSent !== undefined) {
statsString += " Sent: " + stat.packetsSent + " packets";
if (stat.bytesSent !== undefined) {
statsString += " (" + round00(stat.bytesSent/1024) + " Kb)";
}
}
div.appendChild(document.createTextNode(statsString));
return div;
}
function buildPcDiv(stats, pcDivId) {
var newPcDiv = document.createElement('div');
@ -159,26 +179,16 @@ function buildPcDiv(stats, pcDivId) {
stats.forEach(function(stat) {
if (!stat.componentId) {
var statDiv = document.createElement('div');
statDiv.appendChild(document.createElement('strong'))
.appendChild(document.createTextNode(stat.id));
var statsString = " " + new Date(stat.timestamp).toTimeString() +
" " + stat.type + " SSRC: " + stat.ssrc;
if (stat.packetsReceived !== undefined) {
statsString += " Received: " + stat.packetsReceived + " packets";
if (stat.bytesReceived !== undefined) {
statsString += " (" + round00(stat.bytesReceived/1024) + " Kb)";
}
statsString += " Jitter: " + stat.jitter;
} else if (stat.packetsSent !== undefined) {
statsString += " Sent: " + stat.packetsSent + " packets";
if (stat.bytesSent !== undefined) {
statsString += " (" + round00(stat.bytesSent/1024) + " Kb)";
if (!stat.isRemote) {
newPcDiv.appendChild(document.createElement('h4'))
.appendChild(document.createTextNode(stat.id));
if (stat.remoteId) {
newPcDiv.appendChild(dumpStat(stat, "Local: "));
newPcDiv.appendChild(dumpStat(stats.get(stat.remoteId), "Remote: "));
} else {
newPcDiv.appendChild(dumpStat(stat, ""));
}
}
statDiv.appendChild(document.createTextNode(statsString));
newPcDiv.appendChild(statDiv);
return;
}