Newer
Older
* Updates the jitter stream stats with the new feedback sent.
* @param feedback The last RTCP feedback sent by the MediaStream.
* @param streamDirection The stream direction (DOWNLOAD or UPLOAD) of the
* stream from which this function retrieve the jitter.
private void updateJitterRTPTimestampUnits(
RTCPFeedback feedback,
StreamDirection streamDirection)
// Updates the download jitter in RTP timestamp units. There is no need
// to compute a jitter average, since (cf. RFC3550, section 6.4.1 SR:
// Sender Report RTCP Packet, subsection interarrival jitter: 32 bits)
// the value contained in the RTCP sender report packet contains a mean
// deviation of the jitter.
jitterRTPTimestampUnits[streamDirection.ordinal()]
= feedback.getJitter();
/**
* Updates the number of discarded packets.
*
* @param newNbDiscarded The last update of the number of lost.
* @param nbSteps The number of elapsed steps since the last number of loss
* update.
*/
private void updateNbDiscarded(
long newNbDiscarded,
long nbSteps)
{
double newPercentDiscarded
= MediaStreamStatsImpl.computePercentLoss(nbSteps, newNbDiscarded);
percentDiscarded
= MediaStreamStatsImpl.computeEWMA(
nbSteps,
percentDiscarded,
newPercentDiscarded);
// Saves the last update number download lost value.
nbDiscarded += newNbDiscarded;
}
/**
* Updates the <tt>nbFec</tt> field with the sum of FEC-decoded packets
* over the different <tt>ReceiveStream</tt>s
*/
private void updateNbFec()
{

Lyubomir Marinov
committed
MediaDeviceSession devSession = mediaStreamImpl.getDeviceSession();
int nbFec = 0;

Lyubomir Marinov
committed
if(devSession != null)
{

Lyubomir Marinov
committed
for(ReceiveStream receiveStream : devSession.getReceiveStreams())

Boris Grozev
committed
{

Lyubomir Marinov
committed
for(FECDecoderControl fecDecoderControl

Lyubomir Marinov
committed
: devSession.getDecoderControls(
receiveStream,

Lyubomir Marinov
committed
FECDecoderControl.class))

Lyubomir Marinov
committed
{

Lyubomir Marinov
committed
nbFec += fecDecoderControl.fecPacketsDecoded();

Lyubomir Marinov
committed
}

Boris Grozev
committed
}
}
this.nbFec = nbFec;
}

Lyubomir Marinov
committed
/**
* Updates the number of loss for a given stream.
*
* @param streamDirection The stream direction (DOWNLOAD or UPLOAD) of the
* stream from which this function updates the stats.
* @param newNbLost The last update of the number of lost.
* @param nbSteps The number of elapsed steps since the last number of loss
* update.
*/
private void updateNbLoss(
StreamDirection streamDirection,
long newNbLost,
long nbSteps)
{
int streamDirectionIndex = streamDirection.ordinal();
double newPercentLoss
= MediaStreamStatsImpl.computePercentLoss(nbSteps, newNbLost);
percentLoss[streamDirectionIndex]
= MediaStreamStatsImpl.computeEWMA(
nbSteps,
percentLoss[streamDirectionIndex],
newPercentLoss);
// Saves the last update number download lost value.
nbLost[streamDirectionIndex] += newNbLost;

Boris Grozev
committed
}
/**
* Updates this stream stats with the new feedback received.

Boris Grozev
committed
*
* @param feedback The last RTCP feedback received by the MediaStream.

Boris Grozev
committed
*/
private void updateNewReceivedFeedback(RTCPFeedback feedback)

Boris Grozev
committed
{
StreamDirection streamDirection = StreamDirection.UPLOAD;

Boris Grozev
committed
updateJitterRTPTimestampUnits(feedback, streamDirection);

Boris Grozev
committed
// Updates the loss rate with the RTCP sender report feedback, since
// this is the only information source available for the upload stream.
long uploadNewNbRecv = feedback.getXtndSeqNum();
long newNbLost
= feedback.getNumLost() - nbLost[streamDirection.ordinal()];
long nbSteps = uploadNewNbRecv - uploadFeedbackNbPackets;
updateNbLoss(streamDirection, newNbLost, nbSteps);
// Updates the upload loss counters.
uploadFeedbackNbPackets = uploadNewNbRecv;
// Computes RTT.
setRttMs(computeRTTInMs(feedback));

Boris Grozev
committed
}
/**
* Updates this stream stats with the new feedback sent.

Boris Grozev
committed
*
* @param feedback The last RTCP feedback sent by the MediaStream.

Boris Grozev
committed
*/
private void updateNewSentFeedback(RTCPFeedback feedback)

Boris Grozev
committed
{
updateJitterRTPTimestampUnits(feedback, StreamDirection.DOWNLOAD);
// No need to update the download loss as we have a more accurate value
// in the global reception stats, which are updated for each new packet
// received.

Boris Grozev
committed
}
/**
* Computes and updates information for a specific stream.

Boris Grozev
committed
*/

Boris Grozev
committed
{
// Gets the current time.
long currentTimeMs = System.currentTimeMillis();
// UPdates stats for the download stream.
updateStreamDirectionStats(StreamDirection.DOWNLOAD, currentTimeMs);
// UPdates stats for the upload stream.
updateStreamDirectionStats(StreamDirection.UPLOAD, currentTimeMs);
// Saves the last update values.
updateTimeMs = currentTimeMs;

Boris Grozev
committed
}
/**
* Computes and updates information for a specific stream.

Boris Grozev
committed
*
* @param streamDirection The stream direction (DOWNLOAD or UPLOAD) of the
* stream from which this function updates the stats.
* @param currentTimeMs The current time in ms.

Boris Grozev
committed
*/
private void updateStreamDirectionStats(
StreamDirection streamDirection,
long currentTimeMs)

Boris Grozev
committed
{
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
int streamDirectionIndex = streamDirection.ordinal();
// Gets the current number of packets correctly received since the
// beginning of this stream.
long newNbRecv = getNbPDU(streamDirection);
// Gets the number of byte received/sent since the beginning of this
// stream.
long newNbByte = getNbBytes(streamDirection);
// Computes the number of update steps which has not been done since
// last update.
long nbSteps = newNbRecv - nbPackets[streamDirectionIndex];
// Even if the remote peer does not send any packets (i.e. is
// microphone is muted), Jitsi must updates it stats. Thus, Jitsi
// computes a number of steps equivalent as if Jitsi receives a packet
// each 20ms (default value).
if(nbSteps == 0)
nbSteps = (currentTimeMs - updateTimeMs) / 20;
// The upload percentLoss is only computed when a new RTCP feedback is
// received. This is not the case for the download percentLoss which is
// updated for each new RTP packet received.
// Computes the loss rate for this stream.
if(streamDirection == StreamDirection.DOWNLOAD)

Boris Grozev
committed
{
// Gets the current number of losses in download since the beginning
// of this stream.
long newNbLost
= getDownloadNbPDULost() - nbLost[streamDirectionIndex];
updateNbLoss(streamDirection, newNbLost, nbSteps + newNbLost);
long newNbDiscarded = getNbDiscarded() - nbDiscarded;
updateNbDiscarded(newNbDiscarded, nbSteps + newNbDiscarded);

Boris Grozev
committed
}
// Computes the bandwidth used by this stream.
double newRateKiloBitPerSec
= MediaStreamStatsImpl.computeRateKiloBitPerSec(
newNbByte - nbByte[streamDirectionIndex],
currentTimeMs - updateTimeMs);
rateKiloBitPerSec[streamDirectionIndex]
= MediaStreamStatsImpl.computeEWMA(
nbSteps,
rateKiloBitPerSec[streamDirectionIndex],
newRateKiloBitPerSec);
// Saves the last update values.
nbPackets[streamDirectionIndex] = newNbRecv;
nbByte[streamDirectionIndex] = newNbByte;
updateNbFec();

Boris Grozev
committed
}