Adds more CSRC level encoding params. Adds a new CsrcAudioLevelListener

cusax-fix
Emil Ivov 16 years ago
parent 0880b057c7
commit e57467e87d

@ -10,6 +10,7 @@
import javax.media.format.*;
import javax.media.rtp.*;
import net.java.sip.communicator.impl.neomedia.audiolevel.*;
import net.java.sip.communicator.impl.neomedia.codec.*;
import net.java.sip.communicator.impl.neomedia.device.*;
import net.java.sip.communicator.service.neomedia.*;
@ -65,6 +66,12 @@ public class AudioMediaStreamImpl
*/
private static boolean formatsRegisteredOnce = false;
/**
* The listener that gets notified of changes in the audio level of
* remote conference participants.
*/
private CsrcAudioLevelListener csrcAudioLevelListener = null;
/**
* Initializes a new <tt>AudioMediaStreamImpl</tt> instance which will use
* the specified <tt>MediaDevice</tt> for both capture and playback of audio
@ -114,16 +121,16 @@ public void setStreamAudioLevelListener(SimpleAudioLevelListener listener)
}
/**
* Registers <tt>listener</tt> as the <tt>SoundLevelListener</tt> that will
* receive notifications for changes in the levels of conference
* Registers <tt>listener</tt> as the <tt>CsrcAudioLevelListener</tt> that
* will receive notifications for changes in the levels of conference
* participants that the remote party could be mixing.
*
* @param listener the <tt>SoundLevelListener</tt> that we'd like to
* @param listener the <tt>CsrcAudioLevelListener</tt> that we'd like to
* register or <tt>null</tt> if we'd like to stop receiving notifications.
*/
public void setConferenceMemberAudioLevelListener(
SimpleAudioLevelListener listener)
public void setCsrcAudioLevelListener(CsrcAudioLevelListener listener)
{
this.csrcAudioLevelListener = listener;
}
/**
@ -223,7 +230,7 @@ public void addRTPExtension(byte extensionID, RTPExtension rtpExtension)
if ( RTPExtension.CSRC_AUDIO_LEVEL_URN
.equals(rtpExtension.getURI().toString()))
getCsrcEngine().setCsrcAudioLevelsEnabled(true);
getCsrcEngine().setCsrcAudioLevelAudioLevelExtensionID(extensionID);
}
/**
@ -277,4 +284,16 @@ public int getLastMeasuredAudioLevel(long ssrc)
else
return devSession.getLastMeasuredAudioLevel(ssrc);
}
/**
* Delivers the <tt>audioLevels</tt> map to whoever's interested.
*
* @param audioLevels a bidimensional array mapping CSRC IDs to audio
* levels.
*/
private void fireConferenceAudioLevelEvent(final long[][] audioLevels)
{
if (this.csrcAudioLevelListener != null)
this.csrcAudioLevelListener.audioLevelsReceived(audioLevels);
}
}

@ -484,8 +484,11 @@ private void setExtensionBit(boolean extBit)
*
* @return the length of the extensions currently added to this packet.
*/
public int getExtensionsLength()
public int getExtensionLength()
{
if (!getExtensionBit())
return 0;
//the extension length comes after the RTP header, the CSRC list, and
//after two bytes in the extension header called "defined by profile"
int extLenIndex = offset
@ -502,7 +505,7 @@ public int getExtensionsLength()
* @param length the length of the extensions currently recorded in the
* buffer of this packet.
*/
private void setExtensionsLength(int length)
private void setExtensionLength(int length)
{
//the extension length comes after the RTP header, the CSRC list, and
//after two bytes in the extension header called "defined by profile"
@ -527,9 +530,57 @@ private void setExtensionsLength(int length)
*/
public void addExtension(byte[] extBuff, int length)
{
byte[] newBuffer = new byte[getLength() + EXT_HEADER_SIZE + length ];
int newBuffLen = getLength() + length;
//if there was no extension previously, we also need to consider adding
//the extension header.
if (!getExtensionBit())
newBuffLen += EXT_HEADER_SIZE;
byte[] newBuffer = new byte[ newBuffLen ];
//copy header and CSRC list any previous extensions if any
System.arraycopy(buffer, offset, newBuffer, offset,
FIXED_HEADER_SIZE
+ getCsrcCount()*4 + getExtensionLength());
//raise the extension bit.
newBuffer[offset] |= 0x10;
//if there were no extensions previously, we need to add the hdr now
if(! getExtensionBit())
{
// we will now be adding the RFC 5285 ext header which looks like
// this:
//
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | 0xBE | 0xDE | length=3 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
int extHdrOffset = FIXED_HEADER_SIZE + getCsrcCount()*4;
newBuffer[extHdrOffset] = (byte)0xBE;
newBuffer[extHdrOffset+1] = (byte)0xDE;
int newExtensionLen = length + getExtensionLength();
newBuffer[extHdrOffset+2] = (byte)(newExtensionLen >>4);
newBuffer[extHdrOffset+3] = (byte)newExtensionLen;
}
//copy the extension content from the new extension.
System.arraycopy(extBuff, 0, newBuffer, FIXED_HEADER_SIZE
+ getCsrcCount()*4 + getExtensionLength(),
length);
//now copy the payload
int oldPayloadOffset = FIXED_HEADER_SIZE + getCsrcCount()*4
+ getExtensionLength();
int newPayloadOffset = oldPayloadOffset + length;
System.arraycopy(buffer, oldPayloadOffset,
newBuffer, newPayloadOffset,
FIXED_HEADER_SIZE
+ getCsrcCount()*4 + getExtensionLength());
}
}

@ -0,0 +1,31 @@
/*
* 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.audiolevel;
/**
* The <tt>CsrcAudioLevelListener</tt> delivers audio level events reported by
* the remote party in cases where it (the remote party) is acting as a mixer,
* mixing flows from numerous contributors. It is up to upper layers such as
* SIP to define means of determining the exact members that the CSRC IDs and
* hence audio levels participants belong to.
*
* @author Emil Ivov
*/
public interface CsrcAudioLevelListener
{
/**
* Called by the media service implementation after it has received audio
* levels for the various participants (Contributing SouRCes) that are
* taking part in a conference call.
*
* @param audioLevels the new set of levels for the various contributing
* sources in the conference call.
*/
public void audioLevelsReceived(final long[][] audioLevels);
}

@ -56,8 +56,7 @@ protected AudioMediaDeviceSession(AbstractMediaDevice device)
}
/**
* Called by {@link MediaDeviceSession#addReceiveStream(ReceiveStream,
* DataSource)} when the player associated with this session's
* Called by {@link MediaDeviceSession#addReceiveStream(ReceiveStream)} when the player associated with this session's
* <tt>ReceiveStream</tt> moves enters the <tt>Configured</tt> state, so
* we use the occasion to add our audio level effect.
*

@ -6,6 +6,7 @@
*/
package net.java.sip.communicator.service.neomedia;
import net.java.sip.communicator.impl.neomedia.audiolevel.*;
import net.java.sip.communicator.service.neomedia.event.*;
/**
@ -29,15 +30,14 @@ public interface AudioMediaStream
public void setStreamAudioLevelListener(SimpleAudioLevelListener listener);
/**
* Registers <tt>listener</tt> as the <tt>SoundLevelListener</tt> that will
* receive notifications for changes in the levels of conference
* Registers <tt>listener</tt> as the <tt>CsrcAudioLevelListener</tt> that
* will receive notifications for changes in the levels of conference
* participants that the remote party could be mixing.
*
* @param listener the <tt>SoundLevelListener</tt> that we'd like to
* @param listener the <tt>CsrcAudioLevelListener</tt> that we'd like to
* register or <tt>null</tt> if we'd like to stop receiving notifications.
*/
public void setConferenceMemberAudioLevelListener(
SimpleAudioLevelListener listener);
public void setCsrcAudioLevelListener(CsrcAudioLevelListener listener);
/**
* Sets <tt>listener</tt> as the <tt>SimpleAudioLevelListener</tt>

Loading…
Cancel
Save