/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program 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.0 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, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.voiceconf.red5.media.transcoder;
import java.util.Random;
import java.util.concurrent.*;
import org.bigbluebutton.voiceconf.red5.media.FlashToSipAudioStream.TranscodedAudioListener;
import org.red5.app.sip.codecs.Codec;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
/**
* Speex wideband to Speex wideband Flash to SIP transcoder.
* This class is just a passthrough transcoder.
*
*/
public class SpeexFlashToSipTranscoderImp implements FlashToSipTranscoder {
protected static Logger log = Red5LoggerFactory.getLogger(SpeexFlashToSipTranscoderImp.class, "sip");
private Codec audioCodec;
private long timestamp = 0;
private final static int TS_INCREMENT = 320; // Determined from PCAP traces.
//private final Executor exec = Executors.newSingleThreadExecutor();
//private Runnable audioDataProcessor;
//private volatile boolean processAudioData = false;
//private BlockingQueue<SpeexRtpAudioData> audioDataQ;
private TranscodedAudioListener transcodedAudioListener;
public SpeexFlashToSipTranscoderImp(Codec audioCodec) {
//audioDataQ = new LinkedBlockingQueue<SpeexRtpAudioData>();
this.audioCodec = audioCodec;
Random rgen = new Random();
timestamp = rgen.nextInt(1000);
}
public void transcode(byte[] audioData, int startOffset, int length) {
byte[] transcodedAudio = new byte[length];
// Just copy the audio data removing the codec id which is the first-byte
// represented by the startOffset var.
System.arraycopy(audioData, startOffset, transcodedAudio, 0, length);
SpeexRtpAudioData srad = new SpeexRtpAudioData(transcodedAudio, timestamp += TS_INCREMENT);
transcodedAudioListener.handleTranscodedAudioData(srad.audioData, srad.timestamp);
//try {
// audioDataQ.offer(srad, 100, TimeUnit.MILLISECONDS);
//} catch (InterruptedException e) {
// log.warn("Failed to add speex audio data into queue.");
//}
}
public int getCodecId() {
return audioCodec.getCodecId();
}
public int getOutgoingEncodedFrameSize() {
return audioCodec.getOutgoingEncodedFrameSize();
}
public int getOutgoingPacketization() {
return audioCodec.getOutgoingPacketization();
}
@Override
public void handlePacket(byte[] data, int begin, int end) {
transcode(data, begin, end);
}
@Override
public void setTranscodedAudioListener(TranscodedAudioListener transcodedAudioListener) {
this.transcodedAudioListener = transcodedAudioListener;
}
private void processAudioData() {
//while (processAudioData) {
// SpeexRtpAudioData srad;
// try {
// srad = audioDataQ.take();
// transcodedAudioListener.handleTranscodedAudioData(srad.audioData, srad.timestamp);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//}
}
@Override
public void start() {
//processAudioData = true;
//audioDataProcessor = new Runnable() {
// public void run() {
// processAudioData();
// }
//};
//exec.execute(audioDataProcessor);
}
@Override
public void stop() {
//processAudioData = false;
}
}