aboutsummaryrefslogtreecommitdiffstats
path: root/src/net
diff options
context:
space:
mode:
authorLyubomir Marinov <lyubomir.marinov@jitsi.org>2010-12-15 09:21:42 +0000
committerLyubomir Marinov <lyubomir.marinov@jitsi.org>2010-12-15 09:21:42 +0000
commit284e5dcac1bb26f78934547be887ece48c6aae0c (patch)
treefc071ddc49914d208fecf6f558cc25327e49634a /src/net
parent352c5f2509959e5c7ad8806aee67ecebbc60017f (diff)
downloadjitsi-284e5dcac1bb26f78934547be887ece48c6aae0c.zip
jitsi-284e5dcac1bb26f78934547be887ece48c6aae0c.tar.gz
jitsi-284e5dcac1bb26f78934547be887ece48c6aae0c.tar.bz2
Fixes an incorrect removal of audio-level data by CSRC.
Diffstat (limited to 'src/net')
-rw-r--r--src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelEffect.java99
-rw-r--r--src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelMap.java81
-rw-r--r--src/net/java/sip/communicator/impl/neomedia/device/AudioMixerMediaDevice.java29
-rw-r--r--src/net/java/sip/communicator/impl/neomedia/transform/csrc/CsrcTransformEngine.java12
4 files changed, 104 insertions, 117 deletions
diff --git a/src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelEffect.java b/src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelEffect.java
index 2d173c5..1d61e34 100644
--- a/src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelEffect.java
+++ b/src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelEffect.java
@@ -25,9 +25,19 @@ public class AudioLevelEffect
implements Effect
{
/**
- * The supported audio formats by this effect.
+ * The indicator which determines whether <tt>AudioLevelEffect</tt>
+ * instances are to perform the copying of the data from input
+ * <tt>Buffer</tt>s to output <tt>Buffer</tt>s themselves (e.g. using
+ * {@link System#arraycopy(Object, int, Object, int, int)}).
*/
- private Format[] supportedAudioFormats;
+ private static final boolean COPY_DATA_FROM_INPUT_TO_OUTPUT = true;
+
+ /**
+ * The dispatcher of the events which handles the calculation and the event
+ * firing in different thread in order to now slow down the JMF codec chain.
+ */
+ private final AudioLevelEventDispatcher eventDispatcher
+ = new AudioLevelEventDispatcher();
/**
* Input Format
@@ -40,11 +50,9 @@ public class AudioLevelEffect
private AudioFormat outputFormat;
/**
- * The dispatcher of the events which handles the calculation and the event
- * firing in different thread in order to now slow down the JMF codec chain.
+ * The supported audio formats by this effect.
*/
- private final AudioLevelEventDispatcher eventDispatcher
- = new AudioLevelEventDispatcher();
+ private Format[] supportedAudioFormats;
/**
* The minimum and maximum values of the scale
@@ -67,7 +75,7 @@ public class AudioLevelEffect
}
/**
- * Sets (or unsets if <tt>listener</tt> is <tt>null</tt>, the listener that
+ * Sets (or unsets if <tt>listener</tt> is <tt>null</tt>), the listener that
* is going to be notified of audio level changes detected by this effect.
* Given the semantics of the {@link AudioLevelEventDispatcher} this effect
* would do no real work if no listener is set or if it is set to
@@ -84,6 +92,7 @@ public class AudioLevelEffect
/**
* Lists all of the input formats that this codec accepts.
+ *
* @return An array that contains the supported input <tt>Formats</tt>.
*/
public Format[] getSupportedInputFormats()
@@ -93,8 +102,9 @@ public class AudioLevelEffect
/**
* Lists the output formats that this codec can generate.
- * @param input The <tt>Format</tt> of the data to be used
- * as input to the plug-in.
+ *
+ * @param input The <tt>Format</tt> of the data to be used as input to the
+ * plug-in.
* @return An array that contains the supported output <tt>Formats</tt>.
*/
public Format[] getSupportedOutputFormats(Format input)
@@ -115,6 +125,7 @@ public class AudioLevelEffect
/**
* Sets the format of the data to be input to this codec.
+ *
* @param format The <tt>Format</tt> to be set.
* @return The <tt>Format</tt> that was set.
*/
@@ -126,6 +137,7 @@ public class AudioLevelEffect
/**
* Sets the format for the data this codec outputs.
+ *
* @param format The <tt>Format</tt> to be set.
* @return The <tt>Format</tt> that was set.
*/
@@ -137,48 +149,59 @@ public class AudioLevelEffect
/**
* Performs the media processing defined by this codec.
- * @param inputBuffer The <tt>Buffer</tt> that contains the media data
- * to be processed.
- * @param outputBuffer The <tt>Buffer</tt> in which to store
- * the processed media data.
+ *
+ * @param inputBuffer The <tt>Buffer</tt> that contains the media data to be
+ * processed.
+ * @param outputBuffer The <tt>Buffer</tt> in which to store the processed
+ * media data.
* @return <tt>BUFFER_PROCESSED_OK</tt> if the processing is successful.
- * @see PlugIn
+ * @see PlugIn
*/
public int process(Buffer inputBuffer, Buffer outputBuffer)
{
- //copy the actual data from input to the output.
- Object data = outputBuffer.getData();
- byte[] bufferData;
- if (data instanceof byte[] &&
- ((byte[])data).length >= inputBuffer.getLength())
+ if (COPY_DATA_FROM_INPUT_TO_OUTPUT)
{
- bufferData = (byte[])data;
+ // Copy the actual data from the input to the output.
+ Object data = outputBuffer.getData();
+ int inputBufferLength = inputBuffer.getLength();
+ byte[] bufferData;
+
+ if ((data instanceof byte[]) &&
+ (((byte[])data).length >= inputBufferLength))
+ {
+ bufferData = (byte[])data;
+ }
+ else
+ {
+ bufferData = new byte[inputBufferLength];
+ outputBuffer.setData(bufferData);
+ }
+ outputBuffer.setLength(inputBufferLength);
+ outputBuffer.setOffset(0);
+
+ System.arraycopy(
+ inputBuffer.getData(), inputBuffer.getOffset(),
+ bufferData, 0,
+ inputBufferLength);
+
+ // Now copy the remaining attributes.
+ outputBuffer.setFormat(inputBuffer.getFormat());
+ outputBuffer.setHeader(inputBuffer.getHeader());
+ outputBuffer.setSequenceNumber(inputBuffer.getSequenceNumber());
+ outputBuffer.setTimeStamp(inputBuffer.getTimeStamp());
+ outputBuffer.setFlags(inputBuffer.getFlags());
+ outputBuffer.setDiscard(inputBuffer.isDiscard());
+ outputBuffer.setEOM(inputBuffer.isEOM());
+ outputBuffer.setDuration(inputBuffer.getDuration());
}
else
{
- bufferData = new byte[inputBuffer.getLength()];
- outputBuffer.setData(bufferData);
+ outputBuffer.copy(inputBuffer);
}
- outputBuffer.setLength(inputBuffer.getLength());
- outputBuffer.setOffset(0);
-
- System.arraycopy(
- inputBuffer.getData(), inputBuffer.getOffset(), bufferData, 0,
- inputBuffer.getLength());
//now copy the output to the level dispatcher.
eventDispatcher.addData(outputBuffer);
- //now copy the rest of the data.
- outputBuffer.setFormat(inputBuffer.getFormat());
- outputBuffer.setHeader(inputBuffer.getHeader());
- outputBuffer.setSequenceNumber(inputBuffer.getSequenceNumber());
- outputBuffer.setTimeStamp(inputBuffer.getTimeStamp());
- outputBuffer.setFlags(inputBuffer.getFlags());
- outputBuffer.setDiscard(inputBuffer.isDiscard());
- outputBuffer.setEOM(inputBuffer.isEOM());
- outputBuffer.setDuration(inputBuffer.getDuration());
-
return BUFFER_PROCESSED_OK;
}
diff --git a/src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelMap.java b/src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelMap.java
index 759cdb7..ef9533a 100644
--- a/src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelMap.java
+++ b/src/net/java/sip/communicator/impl/neomedia/audiolevel/AudioLevelMap.java
@@ -39,10 +39,9 @@ public class AudioLevelMap
{
//copy the levels matrix so that no one pulls it from under our feet.
long[][] levelsRef = levels;
-
int csrcIndex = findCSRC(levelsRef, csrc);
- if ( csrcIndex == -1)
+ if (csrcIndex == -1)
{
//we don't have the csrc in there yet so we need a new row.
levels = appendCSRCToMatrix(levelsRef, csrc, level);
@@ -54,7 +53,7 @@ public class AudioLevelMap
}
/**
- * Removes <tt>csrc</tt> and it's mapped level from this map.
+ * Removes <tt>csrc</tt> and its mapped level from this map.
*
* @param csrc the CSRC ID that we'd like to remove from this map.
*
@@ -65,13 +64,12 @@ public class AudioLevelMap
{
//copy the levels matrix so that no one pulls it from under our feet.
long[][] levelsRef = levels;
-
int index = findCSRC(levelsRef, csrc);
- if ( index == -1)
+ if (index == -1)
return false;
- if( levelsRef.length == 1)
+ if (levelsRef.length == 1)
{
levels = null;
return true;
@@ -79,16 +77,12 @@ public class AudioLevelMap
//copy levelsRef into newLevels ref making sure we skip the entry
//containing the CSRC ID that we are trying to remove;
- long[][] newLevelsRef = new long[levelsRef.length - 1][2];
-
- for( int j=0, i = 0; i < levelsRef.length; i++ )
- {
- if(levelsRef[i][0] == csrc)
- continue;
+ long[][] newLevelsRef = new long[levelsRef.length - 1][];
- newLevelsRef[j][0] = levelsRef[i][0];
- newLevelsRef[j][1] = levelsRef[i][1];
- }
+ System.arraycopy(levelsRef, 0, newLevelsRef, 0, index);
+ System.arraycopy(
+ levelsRef, index + 1,
+ newLevelsRef, index, newLevelsRef.length - index);
levels = newLevelsRef;
return true;
@@ -106,27 +100,9 @@ public class AudioLevelMap
public int getLevel(long csrc)
{
long[][] levelsRef = levels;
-
int index = findCSRC(levelsRef, csrc);
- if( index == -1)
- return -1;
-
- return (int)levelsRef[index][1];
- }
-
- /**
- * Returns a reference to the bi-directional array encapsulated by this map.
- * Note that the actual array used by this map may change as soon as this
- * method returns and its contents and order may hence no longer correspond
- * to those in the returned array.
- *
- * @return a reference to the bi-directional array encapsulated by this map
- * or <tt>null</tt> if the map is still empty.
- */
- public long[][] getReference()
- {
- return levels;
+ return (index == -1) ? -1 : ((int) levelsRef[index][1]);
}
/**
@@ -144,15 +120,14 @@ public class AudioLevelMap
*/
private int findCSRC(long[][] levels, long csrc)
{
- if( levels == null )
- return -1;
-
- for (int i = 0; i < levels.length; i++)
+ if (levels != null)
{
- if (levels [i][0] == csrc)
- return i;
+ for (int i = 0; i < levels.length; i++)
+ {
+ if (levels[i][0] == csrc)
+ return i;
+ }
}
-
return -1;
}
@@ -172,30 +147,16 @@ public class AudioLevelMap
*/
private long[][] appendCSRCToMatrix(long[][] levels, long csrc, int level)
{
- int newLength = 1;
-
- if( levels != null && levels.length > 0)
- {
- newLength = levels.length + 1;
- }
-
- long[][] newLevels = new long[newLength][2];
+ int newLength = 1 + ((levels == null) ? 0 : levels.length);
+ long[][] newLevels = new long[newLength][];
//put the new level.
- newLevels[0][0] = csrc;
- newLevels[0][1] = level;
+ newLevels[0] = new long[] { csrc, level };
- if( newLength == 1)
+ if (newLength == 1)
return newLevels;
- for (int i = 0; i < levels.length; i ++)
- {
- //csrc
- newLevels[i+1][0] = levels [i][0];
-
- //level
- newLevels[i+1][1] = levels [i][1];
- }
+ System.arraycopy(levels, 0, newLevels, 1, levels.length);
return newLevels;
}
diff --git a/src/net/java/sip/communicator/impl/neomedia/device/AudioMixerMediaDevice.java b/src/net/java/sip/communicator/impl/neomedia/device/AudioMixerMediaDevice.java
index 2d92cfa..8343145 100644
--- a/src/net/java/sip/communicator/impl/neomedia/device/AudioMixerMediaDevice.java
+++ b/src/net/java/sip/communicator/impl/neomedia/device/AudioMixerMediaDevice.java
@@ -119,7 +119,7 @@ public class AudioMixerMediaDevice
*/
private final Map<ReceiveStream, AudioLevelEventDispatcher>
streamAudioLevelListeners
- = new Hashtable<ReceiveStream, AudioLevelEventDispatcher>();
+ = new HashMap<ReceiveStream, AudioLevelEventDispatcher>();
/**
* Initializes a new <tt>AudioMixerMediaDevice</tt> instance which is to
@@ -278,7 +278,7 @@ public class AudioMixerMediaDevice
*/
synchronized(localUserAudioLevelListeners)
{
- if (localUserAudioLevelListeners.size() == 0)
+ if (localUserAudioLevelListeners.isEmpty())
return;
}
@@ -462,9 +462,8 @@ public class AudioMixerMediaDevice
{
//if this is the first listener that we are seeing then we also
//need to create the dispatcher.
- if (localUserAudioLevelListeners.size() == 0)
+ if (localUserAudioLevelListeners.isEmpty())
{
-
localUserAudioLevelDispatcher
.setAudioLevelListener(localUserAudioLevelDelegator);
@@ -577,15 +576,15 @@ public class AudioMixerMediaDevice
* from <tt>stream</tt>.
*/
public void putStreamAudioLevelListener(
- ReceiveStream stream,
- SimpleAudioLevelListener listener)
+ ReceiveStream stream,
+ SimpleAudioLevelListener listener)
{
synchronized(streamAudioLevelListeners)
{
AudioLevelEventDispatcher dispatcher
= streamAudioLevelListeners.get(stream);
- if ( dispatcher == null )
+ if (dispatcher == null)
{
//this is not a replacement but a registration for a stream
//that was not listened to so far. create it and "put" it
@@ -606,7 +605,7 @@ public class AudioMixerMediaDevice
* @param l the listener we'd like to remove.
*/
public void removeLocalUserAudioLevelListener(
- SimpleAudioLevelListener l)
+ SimpleAudioLevelListener l)
{
synchronized(localUserAudioLevelListeners)
{
@@ -629,10 +628,9 @@ public class AudioMixerMediaDevice
//if this was the last listener then we also need to remove the
//dispatcher
- if (localUserAudioLevelListeners.size() == 0)
+ if (localUserAudioLevelListeners.isEmpty())
{
localUserAudioLevelDispatcher.stop();
-
localUserAudioLevelDispatcher.setAudioLevelListener(null);
}
}
@@ -948,6 +946,7 @@ public class AudioMixerMediaDevice
*
* @param processor the processor.
*/
+ @Override
protected void registerLocalUserAudioLevelEffect(Processor processor)
{
}
@@ -1032,8 +1031,9 @@ public class AudioMixerMediaDevice
@Override
public int getLastMeasuredAudioLevel(long csrc)
{
- return ((AudioMixerMediaDevice)getDevice())
- .audioLevelCache.getLevel(csrc);
+ return
+ ((AudioMixerMediaDevice) getDevice()).audioLevelCache.getLevel(
+ csrc);
}
/**
@@ -1045,8 +1045,9 @@ public class AudioMixerMediaDevice
@Override
public int getLastMeasuredLocalUserAudioLevel()
{
- return ((AudioMixerMediaDevice)getDevice())
- .lastMeasuredLocalUserAudioLevel;
+ return
+ ((AudioMixerMediaDevice) getDevice())
+ .lastMeasuredLocalUserAudioLevel;
}
/**
diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/csrc/CsrcTransformEngine.java b/src/net/java/sip/communicator/impl/neomedia/transform/csrc/CsrcTransformEngine.java
index f5fe4da..80ef4e7 100644
--- a/src/net/java/sip/communicator/impl/neomedia/transform/csrc/CsrcTransformEngine.java
+++ b/src/net/java/sip/communicator/impl/neomedia/transform/csrc/CsrcTransformEngine.java
@@ -218,17 +218,19 @@ public class CsrcTransformEngine
byte[] extensionBuff = getExtensionBuff(buffLen);
- extensionBuff[0] =
- (byte)((csrcAudioLevelExtID << 4) | (csrcList.length - 1));
+ extensionBuff[0]
+ = (byte)((csrcAudioLevelExtID << 4) | (csrcList.length - 1));
int csrcOffset = 1; // initial offset is equal to ext hdr size
for(long csrc : csrcList)
{
- byte level = (byte)((AudioMediaStreamImpl)mediaStream)
- .getLastMeasuredAudioLevel(csrc);
- extensionBuff[csrcOffset] = level;
+ byte level
+ = (byte)
+ ((AudioMediaStreamImpl)mediaStream)
+ .getLastMeasuredAudioLevel(csrc);
+ extensionBuff[csrcOffset] = level;
csrcOffset ++;
}