- can now make calls using speex. need to improve audio from fp to sip
This commit is contained in:
parent
da00988ce2
commit
0326506df6
@ -23,6 +23,8 @@ import java.net.DatagramSocket;
|
||||
import java.net.SocketException;
|
||||
import org.bigbluebutton.voiceconf.red5.media.transcoder.NellyToPcmTranscoder;
|
||||
import org.bigbluebutton.voiceconf.red5.media.transcoder.PcmToNellyTranscoder;
|
||||
import org.bigbluebutton.voiceconf.red5.media.transcoder.RtmpToRtpSpeexTranscoder;
|
||||
import org.bigbluebutton.voiceconf.red5.media.transcoder.RtpToRtmpSpeexTranscoder;
|
||||
import org.bigbluebutton.voiceconf.red5.media.transcoder.SpeexToSpeexTranscoder;
|
||||
import org.bigbluebutton.voiceconf.red5.media.transcoder.Transcoder;
|
||||
import org.bigbluebutton.voiceconf.sip.SipConnectInfo;
|
||||
@ -50,17 +52,19 @@ public class CallStream implements StreamObserver {
|
||||
|
||||
public void start() {
|
||||
Transcoder rtmpToRtpTranscoder, rtpToRtmpTranscoder;
|
||||
System.out.println("Using codec " + sipCodec.getCodecId() + " " + sipCodec.getCodecName());
|
||||
if (sipCodec.getCodecId() == SpeexCodec.codecId) {
|
||||
rtmpToRtpTranscoder = new SpeexToSpeexTranscoder(sipCodec);
|
||||
rtpToRtmpTranscoder = new SpeexToSpeexTranscoder(sipCodec, userListenStream);
|
||||
System.out.println("Using SPEEX codec " + sipCodec.getCodecId() + " " + sipCodec.getCodecName());
|
||||
rtmpToRtpTranscoder = new RtmpToRtpSpeexTranscoder(sipCodec);
|
||||
rtpToRtmpTranscoder = new RtpToRtmpSpeexTranscoder(sipCodec);
|
||||
|
||||
} else {
|
||||
rtmpToRtpTranscoder = new NellyToPcmTranscoder(sipCodec);
|
||||
rtpToRtmpTranscoder = new PcmToNellyTranscoder(sipCodec);
|
||||
}
|
||||
userListenStream = new SipToFlashAudioStream(scope, rtpToRtmpTranscoder, connInfo.getSocket());
|
||||
userListenStream.addListenStreamObserver(this);
|
||||
((PcmToNellyTranscoder)rtpToRtmpTranscoder).addTranscodedAudioDataListener(userListenStream);
|
||||
}
|
||||
|
||||
rtpToRtmpTranscoder.addTranscodedAudioDataListener(userListenStream);
|
||||
userTalkStream = new FlashToSipAudioStream(rtmpToRtpTranscoder, connInfo.getSocket(), connInfo);
|
||||
}
|
||||
|
||||
|
@ -68,6 +68,7 @@ public class FlashToSipAudioStream {
|
||||
|
||||
if (packet instanceof AudioData) {
|
||||
byte[] data = SerializeUtils.ByteBufferToByteArray(buf);
|
||||
System.out.println("Speex header " + data[0] + " packet length " + (data.length -1));
|
||||
rtpSender.send(data, 1, data.length-1);
|
||||
}
|
||||
}
|
||||
|
@ -85,8 +85,10 @@ public class RtpStreamReceiver {
|
||||
try {
|
||||
byte[] internalBuffer = new byte[internalBufferLength];
|
||||
RtpPacket rtpPacket = new RtpPacket(internalBuffer, 0);
|
||||
System.out.println("Waiting for RTP packet [" + rtpPacket.getLength() + "," + rtpPacket.getPayloadLength() + "," + internalBufferLength + "]");
|
||||
rtpSocket.receive(rtpPacket);
|
||||
packetReceivedCounter++;
|
||||
System.out.println("Received RTP packet [" + rtpPacket.getLength() + "," + rtpPacket.getPayloadLength() + "]");
|
||||
transcoder.transcode(rtpPacket.getPayload());
|
||||
} catch (IOException e) {
|
||||
// We get this when the socket closes when the call hangs up.
|
||||
|
@ -179,6 +179,13 @@ public class NellyToPcmTranscoder implements Transcoder {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Not implemented. Implemented by transcoders for voice conf server to Flash.
|
||||
*/
|
||||
public void addTranscodedAudioDataListener(TranscodedAudioDataListener listener) {
|
||||
log.error("Not implemented.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Not implemented. Implemented by transcoders for voice conf server to Flash.
|
||||
*/
|
||||
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* BigBlueButton - http://www.bigbluebutton.org
|
||||
*
|
||||
* Copyright (c) 2008-2009 by respective authors (see below). All rights reserved.
|
||||
*
|
||||
* BigBlueButton is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation; either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with BigBlueButton; if not, If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* $Id: $
|
||||
*/
|
||||
package org.bigbluebutton.voiceconf.red5.media.transcoder;
|
||||
|
||||
import org.bigbluebutton.voiceconf.red5.media.RtpStreamSender;
|
||||
import org.bigbluebutton.voiceconf.red5.media.StreamException;
|
||||
import org.red5.app.sip.codecs.Codec;
|
||||
import org.red5.logging.Red5LoggerFactory;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class RtmpToRtpSpeexTranscoder implements Transcoder {
|
||||
protected static Logger log = Red5LoggerFactory.getLogger(RtmpToRtpSpeexTranscoder.class, "sip");
|
||||
|
||||
private Codec audioCodec;
|
||||
|
||||
public RtmpToRtpSpeexTranscoder(Codec audioCodec) {
|
||||
this.audioCodec = audioCodec;
|
||||
}
|
||||
|
||||
public void transcode(byte[] asaoBuffer, int offset, int num,
|
||||
byte[] transcodedData, int dataOffset, RtpStreamSender rtpSender) {
|
||||
System.arraycopy(asaoBuffer, offset, transcodedData, dataOffset, num);
|
||||
try {
|
||||
rtpSender.sendTranscodedData();
|
||||
} catch (StreamException e) {
|
||||
// Swallow this error for now. We don't really want to end the call if sending hiccups.
|
||||
// Just log it for now. (ralam june 18, 2010)
|
||||
log.warn("Error while sending transcoded audio packet.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Not implemented. Implemented by transcoders for voice conf server to Flash.
|
||||
*/
|
||||
public void addTranscodedAudioDataListener(TranscodedAudioDataListener listener) {
|
||||
log.error("Not implemented.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Not implemented. Implemented by transcoders for voice conf server to Flash.
|
||||
*/
|
||||
public void transcode(byte[] codedBuffer) {
|
||||
log.error("Not implemented.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Not implemented. Implemented by transcoders for voice conf server to Flash.
|
||||
*/
|
||||
public int getIncomingEncodedFrameSize() {
|
||||
log.error("Not implemented.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getCodecId() {
|
||||
return audioCodec.getCodecId();
|
||||
}
|
||||
|
||||
public int getOutgoingEncodedFrameSize() {
|
||||
return audioCodec.getOutgoingEncodedFrameSize();
|
||||
}
|
||||
|
||||
public int getOutgoingPacketization() {
|
||||
return audioCodec.getOutgoingPacketization();
|
||||
}
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* BigBlueButton - http://www.bigbluebutton.org
|
||||
*
|
||||
* Copyright (c) 2008-2009 by respective authors (see below). All rights reserved.
|
||||
*
|
||||
* BigBlueButton is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation; either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with BigBlueButton; if not, If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* $Id: $
|
||||
*/
|
||||
package org.bigbluebutton.voiceconf.red5.media.transcoder;
|
||||
|
||||
import org.apache.mina.core.buffer.IoBuffer;
|
||||
import org.bigbluebutton.voiceconf.red5.media.RtpStreamSender;
|
||||
import org.bigbluebutton.voiceconf.red5.media.StreamException;
|
||||
import org.red5.app.sip.codecs.Codec;
|
||||
import org.red5.logging.Red5LoggerFactory;
|
||||
import org.red5.server.net.rtmp.event.AudioData;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class RtpToRtmpSpeexTranscoder implements Transcoder {
|
||||
protected static Logger log = Red5LoggerFactory.getLogger(RtpToRtmpSpeexTranscoder.class, "sip");
|
||||
|
||||
private Codec audioCodec;
|
||||
private TranscodedAudioDataListener listener;
|
||||
private int timestamp = 0;
|
||||
|
||||
private static final int SPEEX_CODEC = 178; /* 1011 1111 (see flv spec) */
|
||||
private long start = 0;
|
||||
|
||||
public RtpToRtmpSpeexTranscoder(Codec audioCodec, TranscodedAudioDataListener listener) {
|
||||
this.audioCodec = audioCodec;
|
||||
this.listener = listener;
|
||||
start = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public RtpToRtmpSpeexTranscoder(Codec audioCodec) {
|
||||
this.audioCodec = audioCodec;
|
||||
}
|
||||
|
||||
public void addTranscodedAudioDataListener(TranscodedAudioDataListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public void transcode(byte[] asaoBuffer, int offset, int num,
|
||||
byte[] transcodedData, int dataOffset, RtpStreamSender rtpSender) {
|
||||
System.arraycopy(asaoBuffer, offset, transcodedData, dataOffset, num);
|
||||
try {
|
||||
rtpSender.sendTranscodedData();
|
||||
} catch (StreamException e) {
|
||||
// Swallow this error for now. We don't really want to end the call if sending hiccups.
|
||||
// Just log it for now. (ralam june 18, 2010)
|
||||
log.warn("Error while sending transcoded audio packet.");
|
||||
}
|
||||
}
|
||||
|
||||
public void transcode(byte[] codedBuffer) {
|
||||
pushAudio(codedBuffer);
|
||||
}
|
||||
|
||||
private void pushAudio(byte[] audio) {
|
||||
timestamp = timestamp + audio.length;
|
||||
|
||||
IoBuffer buffer = IoBuffer.allocate(1024);
|
||||
buffer.setAutoExpand(true);
|
||||
|
||||
buffer.clear();
|
||||
|
||||
buffer.put((byte) SPEEX_CODEC);
|
||||
byte[] copy = new byte[audio.length];
|
||||
System.arraycopy(audio, 0, copy, 0, audio.length );
|
||||
|
||||
buffer.put(copy);
|
||||
buffer.flip();
|
||||
|
||||
AudioData audioData = new AudioData( buffer );
|
||||
audioData.setTimestamp((int)(System.currentTimeMillis() - start) );
|
||||
|
||||
listener.handleTranscodedAudioData(audioData);
|
||||
}
|
||||
|
||||
public int getCodecId() {
|
||||
return audioCodec.getCodecId();
|
||||
}
|
||||
|
||||
public int getOutgoingEncodedFrameSize() {
|
||||
return audioCodec.getOutgoingEncodedFrameSize();
|
||||
}
|
||||
|
||||
public int getOutgoingPacketization() {
|
||||
return audioCodec.getOutgoingPacketization();
|
||||
}
|
||||
|
||||
public int getIncomingEncodedFrameSize() {
|
||||
return audioCodec.getIncomingEncodedFrameSize();
|
||||
}
|
||||
}
|
@ -35,10 +35,12 @@ public class SpeexToSpeexTranscoder implements Transcoder {
|
||||
private int timestamp = 0;
|
||||
|
||||
private static final int SPEEX_CODEC = 178; /* 1011 1111 (see flv spec) */
|
||||
private long start = 0;
|
||||
|
||||
public SpeexToSpeexTranscoder(Codec audioCodec, TranscodedAudioDataListener listener) {
|
||||
this.audioCodec = audioCodec;
|
||||
this.listener = listener;
|
||||
start = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public SpeexToSpeexTranscoder(Codec audioCodec) {
|
||||
@ -77,7 +79,7 @@ public class SpeexToSpeexTranscoder implements Transcoder {
|
||||
buffer.flip();
|
||||
|
||||
AudioData audioData = new AudioData( buffer );
|
||||
audioData.setTimestamp((int)timestamp );
|
||||
audioData.setTimestamp((int)(System.currentTimeMillis() - start) );
|
||||
|
||||
listener.handleTranscodedAudioData(audioData);
|
||||
}
|
||||
@ -97,4 +99,11 @@ public class SpeexToSpeexTranscoder implements Transcoder {
|
||||
public int getIncomingEncodedFrameSize() {
|
||||
return audioCodec.getIncomingEncodedFrameSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTranscodedAudioDataListener(
|
||||
TranscodedAudioDataListener listener) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ import org.bigbluebutton.voiceconf.red5.media.RtpStreamSender;
|
||||
public interface Transcoder {
|
||||
void transcode(byte[] asaoBuffer, int offset, int num, byte[] transcodedData, int dataOffset, RtpStreamSender rtpSender);
|
||||
void transcode(byte[] codedBuffer);
|
||||
|
||||
void addTranscodedAudioDataListener(TranscodedAudioDataListener listener);
|
||||
int getOutgoingEncodedFrameSize();
|
||||
|
||||
int getCodecId();
|
||||
|
@ -28,6 +28,7 @@ import org.bigbluebutton.voiceconf.red5.CallStreamFactory;
|
||||
import org.bigbluebutton.voiceconf.red5.ClientConnectionManager;
|
||||
import org.bigbluebutton.voiceconf.red5.media.CallStream;
|
||||
import org.bigbluebutton.voiceconf.red5.media.StreamException;
|
||||
import org.bigbluebutton.voiceconf.util.StackTraceUtil;
|
||||
import org.red5.app.sip.codecs.Codec;
|
||||
import org.red5.app.sip.codecs.CodecUtils;
|
||||
import org.slf4j.Logger;
|
||||
@ -181,6 +182,7 @@ public class CallAgent extends CallListenerAdapter {
|
||||
notifyListenersOnCallConnected(callStream.getTalkStreamName(), callStream.getListenStreamName());
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to create Call Stream.");
|
||||
System.out.println(StackTraceUtil.getStackTrace(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -174,8 +174,8 @@ public class SipPeerProfile {
|
||||
/** VIC command-line executable */
|
||||
public String binVIC = "vic";
|
||||
|
||||
public String audioCodecsPrecedence = "8;18;0;110;111";
|
||||
//public String audioCodecsPrecedence = "";
|
||||
public String audioCodecsPrecedence = "110;8;18;0;111";
|
||||
//public String audioCodecsPrecedence = "110";
|
||||
|
||||
|
||||
// ************************** Costructors *************************
|
||||
|
1
bbb-voice/src/main/java/org/red5/app/sip/codecs/CodecFactory.java
Normal file → Executable file
1
bbb-voice/src/main/java/org/red5/app/sip/codecs/CodecFactory.java
Normal file → Executable file
@ -14,6 +14,7 @@ public class CodecFactory {
|
||||
private static final int audioCodeciLBC = 111;
|
||||
|
||||
private int[] availableAudioCodecsId = {audioCodecPCMU, audioCodecPCMA, audioCodecG729, audioCodecSpeex, audioCodeciLBC};
|
||||
// private int[] availableAudioCodecsId = {audioCodecSpeex};
|
||||
|
||||
private int[] availableVideoCodecsId = {};
|
||||
|
||||
|
4
bbb-voice/src/main/java/org/red5/app/sip/codecs/SpeexCodec.java
Normal file → Executable file
4
bbb-voice/src/main/java/org/red5/app/sip/codecs/SpeexCodec.java
Normal file → Executable file
@ -11,8 +11,8 @@ import local.media.G711;
|
||||
public class SpeexCodec implements Codec {
|
||||
private static final String codecName = "Speex";
|
||||
|
||||
private static int defaultEncodedFrameSize = 160;
|
||||
private static int defaultDecodedFrameSize = 160;
|
||||
private static int defaultEncodedFrameSize = 320;
|
||||
private static int defaultDecodedFrameSize = 320;
|
||||
private static int defaultSampleRate = 16000;
|
||||
private int outgoingPacketization = 0;
|
||||
private int incomingPacketization = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user