Update media statistics.

cusax-fix
Damian Minkov 15 years ago
parent 8a23901ba4
commit 2a29e3645e

Binary file not shown.

@ -26,6 +26,7 @@
import net.java.sip.communicator.impl.neomedia.transform.*;
import net.java.sip.communicator.impl.neomedia.transform.csrc.*;
import net.java.sip.communicator.impl.neomedia.transform.dtmf.*;
import net.java.sip.communicator.impl.neomedia.transform.rtcp.*;
import net.java.sip.communicator.impl.neomedia.transform.zrtp.*;
import net.java.sip.communicator.service.neomedia.*;
import net.java.sip.communicator.service.neomedia.device.*;
@ -203,6 +204,28 @@ else if (MediaDeviceSession.SSRC_LIST.equals(propertyName))
*/
private boolean zrtpRestarted = false;
/**
* Number of received sender reports.
* Used only for logging and debug purposes.
*/
private long numberOfReceivedSenderReports = 0;
/**
* The minimum inter arrival jitter value the other party has reported.
*/
private long maxRemoteInterArrivalJitter = 0;
/**
* The maximum inter arrival jitter value the other party has reported.
*/
private long minRemoteInterArrivalJitter = -1;
/**
* Engine chain reading sent RTCP sender reports and stores/prints
* statistics.
*/
private StatisticsEngine statisticsEngine = null;
/**
* Initializes a new <tt>MediaStreamImpl</tt> instance which will use the
* specified <tt>MediaDevice</tt> for both capture and playback of media.
@ -330,6 +353,11 @@ private TransformEngineChain createTransformEngineChain()
// ZRTP
engineChain.add(zrtpControl.getZrtpEngine());
// RTCP Statistics
if(statisticsEngine == null)
statisticsEngine = new StatisticsEngine();
engineChain.add(statisticsEngine);
return
new TransformEngineChain(
engineChain.toArray(
@ -2036,42 +2064,43 @@ public void update(RemoteEvent remoteEvent)
if(remoteEvent instanceof SenderReportEvent)
{
numberOfReceivedSenderReports++;
SenderReport report =
((SenderReportEvent)remoteEvent).getReport();
if(report.getFeedbackReports().size() > 0)
{
Feedback feedback =
(Feedback)report.getFeedbackReports().get(0);
long remoteJitter = feedback.getJitter();
if(remoteJitter < minRemoteInterArrivalJitter
||minRemoteInterArrivalJitter == -1)
minRemoteInterArrivalJitter = remoteJitter;
if(maxRemoteInterArrivalJitter < remoteJitter)
maxRemoteInterArrivalJitter = remoteJitter;
// As sender reports are received on every 5 seconds
// print every 4th packet, on every 20 seconds
if(numberOfReceivedSenderReports%4 != 1)
return;
Iterator iter = report.getFeedbackReports().iterator();
while(iter.hasNext())
{
Feedback feedback = (Feedback)iter.next();
StringBuilder buff = new StringBuilder(
"SenderReport (for stream ")
.append(hashCode())
.append(") [packetCount:");
buff.append(report.getSenderPacketCount())
.append(", bytes:").append(report.getSenderByteCount())
.append(", interarrival jitter:")
.append(feedback.getJitter())
.append(", lost:").append(feedback.getNumLost())
.append(", lastSRBefore:")
.append((int)(feedback.getDLSR()/65.536))
.append("ms ]");
logger.trace(buff.toString());
}
}
else
{
StringBuilder buff = new StringBuilder(
"SenderReport (for stream ")
.append(hashCode())
.append(") [packetCount:");
"Remote party report received (for stream ")
.append(hashCode())
.append(") [packetCount:");
buff.append(report.getSenderPacketCount())
.append(", bytes:").append(report.getSenderByteCount());
.append(", bytes:").append(report.getSenderByteCount())
.append(", interarrival jitter:")
.append(remoteJitter)
.append(", lost:").append(feedback.getNumLost())
.append(", lastSRBefore:")
.append((int)(feedback.getDLSR()/65.536))
.append("ms ]");
logger.trace(buff.toString());
}
}
@ -2163,40 +2192,57 @@ protected int getPriority()
*/
private void printFlowStatistics(RTPManager rtpManager)
{
String rtpManagerDescription = "stream " + hashCode();
//print flow statistics.
GlobalTransmissionStats s = rtpManager.getGlobalTransmissionStats();
logger.trace(
"global transmission stats (" + rtpManagerDescription + "): \n" +
"bytes sent: " + s.getBytesSent() + "\n" +
"local colls: " + s.getLocalColls() + "\n" +
"remote colls: " + s.getRemoteColls() + "\n" +
"RTCP sent: " + s.getRTCPSent() + "\n" +
"RTP sent: " + s.getRTPSent() + "\n" +
"transmit failed: " + s.getTransmitFailed()
);
GlobalReceptionStats rs = rtpManager.getGlobalReceptionStats();
logger.trace(
"global reception stats (" + rtpManagerDescription + "): \n" +
"bad RTCP packets: " + rs.getBadRTCPPkts() + "\n" +
"bad RTP packets: " + rs.getBadRTPkts() + "\n" +
"bytes received: " + rs.getBytesRecd() + "\n" +
"local collisions: " + rs.getLocalColls() + "\n" +
"malformed BYEs: " + rs.getMalformedBye() + "\n" +
"malformed RRs: " + rs.getMalformedRR() + "\n" +
"malformed SDESs: " + rs.getMalformedSDES() + "\n" +
"malformed SRs: " + rs.getMalformedSR() + "\n" +
"packets looped: " + rs.getPacketsLooped() + "\n" +
"packets received: " + rs.getPacketsRecd() + "\n" +
"remote collisions: " + rs.getRemoteColls() + "\n" +
"RTCPs received: " + rs.getRTCPRecd() + "\n" +
"SRRs received: " + rs.getSRRecd() + "\n" +
"transmit failed: " + rs.getTransmitFailed() + "\n" +
"unknown types: " + rs.getUnknownTypes()
);
try
{
String rtpManagerDescription = "stream " + hashCode();
//print flow statistics.
GlobalTransmissionStats s = rtpManager.getGlobalTransmissionStats();
logger.trace(
"global transmission stats (" + rtpManagerDescription + "): \n" +
"bytes sent: " + s.getBytesSent() + "\n" +
"RTP sent: " + s.getRTPSent() + "\n" +
"remote reported min interarrival jitter : "
+ minRemoteInterArrivalJitter + "\n" +
"remote reported max interarrival jitter : "
+ maxRemoteInterArrivalJitter + "\n" +
"local collisions: " + s.getLocalColls() + "\n" +
"remote collisions: " + s.getRemoteColls() + "\n" +
"RTCP sent: " + s.getRTCPSent() + "\n" +
"transmit failed: " + s.getTransmitFailed()
);
GlobalReceptionStats rs = rtpManager.getGlobalReceptionStats();
logger.trace(
"global reception stats (" + rtpManagerDescription + "): \n" +
"packets received: " + rs.getPacketsRecd() + "\n" +
"bytes received: " + rs.getBytesRecd() + "\n" +
"packets lost: " + statisticsEngine.getLost() + "\n" +
"min interarrival jitter : "
+ statisticsEngine.getMinInterArrivalJitter() + "\n" +
"max interarrival jitter : "
+ statisticsEngine.getMaxInterArrivalJitter() + "\n" +
"RTCPs received: " + rs.getRTCPRecd() + "\n" +
"bad RTCP packets: " + rs.getBadRTCPPkts() + "\n" +
"bad RTP packets: " + rs.getBadRTPkts() + "\n" +
"local collisions: " + rs.getLocalColls() + "\n" +
"malformed BYEs: " + rs.getMalformedBye() + "\n" +
"malformed RRs: " + rs.getMalformedRR() + "\n" +
"malformed SDESs: " + rs.getMalformedSDES() + "\n" +
"malformed SRs: " + rs.getMalformedSR() + "\n" +
"packets looped: " + rs.getPacketsLooped() + "\n" +
"remote collisions: " + rs.getRemoteColls() + "\n" +
"SRRs received: " + rs.getSRRecd() + "\n" +
"transmit failed: " + rs.getTransmitFailed() + "\n" +
"unknown types: " + rs.getUnknownTypes()
);
}
catch(Throwable t)
{
logger.error("Error writing statistics", t);
}
}
}

@ -0,0 +1,183 @@
/*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.neomedia.transform.rtcp;
import com.sun.media.rtp.*;
import net.java.sip.communicator.impl.neomedia.*;
import net.java.sip.communicator.impl.neomedia.transform.*;
import net.java.sip.communicator.util.*;
import net.sf.fmj.media.rtp.*;
/**
* @author Damian Minkov
*/
public class StatisticsEngine
implements TransformEngine,
PacketTransformer
{
/**
* The <tt>Logger</tt> used by the <tt>StatisticsEngine</tt> class
* and its instances for logging output.
*/
private static final Logger logger
= Logger.getLogger(StatisticsEngine.class);
/**
* Number of sender reports send.
* Used only for logging and debug purposes.
*/
private long numberOfSenderReports = 0;
/**
* The minimum inter arrival jitter value we have reported.
*/
private long maxInterArrivalJitter = 0;
/**
* The minimum inter arrival jitter value we have reported.
*/
private long minInterArrivalJitter = -1;
/**
* Number of lost packets reported.
*/
private long lost = 0;
/**
* Finds the info needed for statistics in the packet and stores it.
* Then returns the same packet as we are not modifying it.
*
* @param pkt the packet
* @return the packet
*/
public RawPacket transform(RawPacket pkt)
{
if(!logger.isTraceEnabled())
return pkt;
try
{
numberOfSenderReports++;
byte[] data = pkt.getBuffer();
int offset = pkt.getOffset();
int length = pkt.getLength();
RTCPHeader header = new RTCPHeader(
data, offset, length);
if (header.getPacketType() == RTCPPacket.SR)
{
RTCPSenderReport report = new RTCPSenderReport(
data, offset, length);
if(report.getFeedbackReports().size() > 0)
{
RTCPFeedback feedback =
(RTCPFeedback)report.getFeedbackReports().get(0);
long jitter = feedback.getJitter();
if(jitter < getMinInterArrivalJitter()
|| getMinInterArrivalJitter() == -1)
minInterArrivalJitter = jitter;
if(getMaxInterArrivalJitter() < jitter)
maxInterArrivalJitter = jitter;
lost = feedback.getNumLost();
// As sender reports are send on every 5 seconds
// print every 4th packet, on every 20 seconds
if(numberOfSenderReports%4 != 1)
return pkt;
StringBuilder buff = new StringBuilder(
"Sending report to remote party [packetCount:");
buff.append(report.getSenderPacketCount())
.append(", bytes:").append(report.getSenderByteCount())
.append(", interarrival jitter:")
.append(jitter)
.append(", lost:").append(feedback.getNumLost())
.append(", lastSRBefore:")
.append((int) (feedback.getDLSR() / 65.536))
.append("ms ]");
logger.trace(buff.toString());
}
}
}
catch(Throwable t)
{
t.printStackTrace();
}
return pkt;
}
/**
* Returns the packet as we are listening just for sending packages.
*
* @param pkt the packet without any change.
* @return the packet without any change.
*/
public RawPacket reverseTransform(RawPacket pkt)
{
return pkt;
}
/**
* Always returns <tt>null</tt> since this engine does not require any
* RTP transformations.
*
* @return <tt>null</tt> since this engine does not require any
* RTP transformations.
*/
public PacketTransformer getRTPTransformer()
{
return null;
}
/**
* Returns a reference to this class since it is performing RTP
* transformations in here.
*
* @return a reference to <tt>this</tt> instance of the
* <tt>StatisticsEngine</tt>.
*/
public PacketTransformer getRTCPTransformer()
{
return this;
}
/**
* The minimum inter arrival jitter value we have reported.
* @return minimum inter arrival jitter value we have reported.
*/
public long getMaxInterArrivalJitter()
{
return maxInterArrivalJitter;
}
/**
* The maximum inter arrival jitter value we have reported.
* @return maximum inter arrival jitter value we have reported.
*/
public long getMinInterArrivalJitter()
{
return minInterArrivalJitter;
}
/**
* Number of lost packets reported.
* @return number of lost packets reported.
*/
public long getLost()
{
return lost;
}
}
Loading…
Cancel
Save