Skip to content
Snippets Groups Projects
Commit f9b19f51 authored by Lyubomir Marinov's avatar Lyubomir Marinov
Browse files

Works around a failure to detect ReceiveStreams. Improves the implementations...

Works around a failure to detect ReceiveStreams. Improves the implementations of the Min and Max ThroughputRTCPTerminationStrategies.
parent b60ece93
No related branches found
No related tags found
No related merge requests found
......@@ -38,6 +38,7 @@
* information that it collects and from information found in FMJ.
*
* @author George Politis
* @author Lyubomir Marinov
*/
public class BasicRTCPTerminationStrategy
extends MediaStreamRTCPTerminationStrategy
......@@ -408,13 +409,27 @@ private RTCPReportBlock[] makeRTCPReportBlocks(long time)
return MIN_RTCP_REPORTS_BLOCKS_ARRAY;
}
Collection<ReceiveStream> receiveStreams
= streamRTPManager.getReceiveStreams();
Collection<ReceiveStream> receiveStreams;
if (receiveStreams == null || receiveStreams.size() == 0)
// XXX MediaStreamImpl's implementation of #getReceiveStreams() says
// that, unfortunately, it has been observed that sometimes there are
// valid ReceiveStreams in MediaStreamImpl which are not returned by
// FMJ's RTPManager. Since (1) MediaStreamImpl#getReceiveStreams() will
// include the results of StreamRTPManager#getReceiveStreams() and (2)
// we are going to check the results against SSRCCache, it should be
// relatively safe to rely on MediaStreamImpl's implementation.
if (stream instanceof MediaStreamImpl)
{
logger.info("There are no receive streams to build report " +
"blocks for.");
receiveStreams = ((MediaStreamImpl) stream).getReceiveStreams();
}
else
{
receiveStreams = streamRTPManager.getReceiveStreams();
}
if (receiveStreams == null || receiveStreams.isEmpty())
{
logger.info(
"There are no receive streams to build report blocks for.");
return MIN_RTCP_REPORTS_BLOCKS_ARRAY;
}
......@@ -425,11 +440,10 @@ private RTCPReportBlock[] makeRTCPReportBlocks(long time)
return MIN_RTCP_REPORTS_BLOCKS_ARRAY;
}
// Create the return object.
// Create and populate the return object.
Collection<RTCPReportBlock> rtcpReportBlocks
= new ArrayList<RTCPReportBlock>();
// Populate the return object.
for (ReceiveStream receiveStream : receiveStreams)
{
// Dig into the guts of FMJ and get the stats for the current
......@@ -443,8 +457,9 @@ private RTCPReportBlock[] makeRTCPReportBlocks(long time)
}
}
return rtcpReportBlocks.toArray(
new RTCPReportBlock[rtcpReportBlocks.size()]);
return
rtcpReportBlocks.toArray(
new RTCPReportBlock[rtcpReportBlocks.size()]);
}
/**
......@@ -454,7 +469,7 @@ private RTCPReportBlock[] makeRTCPReportBlocks(long time)
* @return an <tt>RTCPREMBPacket</tt> that provides receiver feedback to the
* endpoint from which we receive.
*/
protected RTCPREMBPacket makeRTCPREMBPacket()
private RTCPREMBPacket makeRTCPREMBPacket()
{
// TODO we should only make REMBs if REMB support has been advertised.
// Destination
......@@ -472,22 +487,46 @@ protected RTCPREMBPacket makeRTCPREMBPacket()
for (Integer ssrc : ssrcs)
dest[i++] = ssrc & 0xFFFFFFFFL;
// Exp & mantissa
long bitrate = remoteBitrateEstimator.getLatestEstimate();
if (bitrate == -1)
return null;
if (logger.isDebugEnabled())
logger.debug("Estimated bitrate: " + bitrate);
// Create and return the packet.
// We use the stream's local source ID (SSRC) as the SSRC of packet
// sender.
long streamSSRC = getLocalSSRC();
return
new RTCPREMBPacket(streamSSRC, /* mediaSSRC */ 0L, bitrate, dest);
makeRTCPREMBPacket(
remoteBitrateEstimator,
streamSSRC, /* mediaSSRC */ 0L, dest);
}
/**
* Makes an <tt>RTCPREMBPacket</tt> that provides receiver feedback to the
* endpoint from which we receive.
*
* @param remoteBitrateEstimator
* @param senderSSRC
* @param mediaSSRC
* @param dest
* @return an <tt>RTCPREMBPacket</tt> that provides receiver feedback to the
* endpoint from which we receive.
*/
protected RTCPREMBPacket makeRTCPREMBPacket(
RemoteBitrateEstimator remoteBitrateEstimator,
long senderSSRC, long mediaSSRC, long[] dest)
{
// Exp & mantissa
long bitrate = remoteBitrateEstimator.getLatestEstimate();
if (bitrate == -1)
{
return null;
}
else
{
if (logger.isDebugEnabled())
logger.debug("Estimated bitrate: " + bitrate);
return new RTCPREMBPacket(senderSSRC, mediaSSRC, bitrate, dest);
}
}
/**
......
......@@ -16,6 +16,7 @@
package org.jitsi.impl.neomedia.rtcp.termination.strategies;
import org.jitsi.impl.neomedia.rtcp.*;
import org.jitsi.service.neomedia.rtp.*;
/**
* Maximizes endpoint throughput. It does that by sending REMB messages with the
......@@ -42,15 +43,15 @@ public class MaxThroughputRTCPTerminationStrategy
* {@inheritDoc}
*/
@Override
protected RTCPREMBPacket makeRTCPREMBPacket()
protected RTCPREMBPacket makeRTCPREMBPacket(
RemoteBitrateEstimator remoteBitrateEstimator,
long senderSSRC, long mediaSSRC, long[] dest)
{
RTCPREMBPacket remb = super.makeRTCPREMBPacket();
if (remb != null)
{
remb.exp = MAX_EXP;
remb.mantissa = MAX_MANTISSA;
}
return remb;
return
new RTCPREMBPacket(
senderSSRC,
mediaSSRC,
MAX_EXP, MAX_MANTISSA,
dest);
}
}
......@@ -16,6 +16,7 @@
package org.jitsi.impl.neomedia.rtcp.termination.strategies;
import org.jitsi.impl.neomedia.rtcp.*;
import org.jitsi.service.neomedia.rtp.*;
/**
* Minimizes endpoint throughput. It does that by sending REMB messages with the
......@@ -42,15 +43,15 @@ public class MinThroughputRTCPTerminationStrategy
* {@inheritDoc}
*/
@Override
protected RTCPREMBPacket makeRTCPREMBPacket()
protected RTCPREMBPacket makeRTCPREMBPacket(
RemoteBitrateEstimator remoteBitrateEstimator,
long senderSSRC, long mediaSSRC, long[] dest)
{
RTCPREMBPacket remb = super.makeRTCPREMBPacket();
if (remb != null)
{
remb.exp = MIN_EXP;
remb.mantissa = MIN_MANTISSA;
}
return remb;
return
new RTCPREMBPacket(
senderSSRC,
mediaSSRC,
MIN_EXP, MIN_MANTISSA,
dest);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment