我正在使用 mjsip sip 堆栈开发一个软件电话项目。Mjsip 仅支持 g711 或 PCMA/PCMU 编解码器。我已将 G729 添加到我的项目中。当我构建项目时,它没有显示错误。但是当电话连接起来时,呼叫就建立起来了,没有语音传输,实际上我的应用程序不会生成任何 rtp 数据包。并且在日志中显示了一个错误,例如
java.lang.NullPointerException
RtpStreamReceiver - run -> Terminated.
at local.media.RtpStreamReceiver.run(RtpStreamReceiver.java:171)
我没能找到错误。
这是我的 RtpStreamReceiver.java 类。
package local.media;
import local.net.RtpPacket;
import local.net.RtpSocket;
import java.io.*;
import java.net.DatagramSocket;
import org.flamma.codec.SIPCodec;
/** RtpStreamReceiver is a generic stream receiver.
* It receives packets from RTP and writes them into an OutputStream.
*/
public class RtpStreamReceiver extends Thread {
public static int RTP_HEADER_SIZE = 12;
private long start = System.currentTimeMillis();
public static final int SO_TIMEOUT = 200; // Maximum blocking time, spent waiting for reading new bytes [milliseconds]
private SIPCodec sipCodec = null; // Sip codec to be used on audio session
private RtpSocket rtp_socket = null;
private boolean socketIsLocal = false; // Whether the socket has been created here
private boolean running = false;
private int timeStamp = 0;
private int frameCounter = 0;
private OutputStream output_stream;
public RtpStreamReceiver( SIPCodec sipCodec, OutputStream output_stream, int local_port )
{
try {
DatagramSocket socket = new DatagramSocket( local_port );
socketIsLocal = true;
init( sipCodec, output_stream, socket );
start = System.currentTimeMillis();
}
catch ( Exception e ) {
e.printStackTrace();
}
}
public RtpStreamReceiver( SIPCodec sipCodec, OutputStream output_stream, DatagramSocket socket )
{
init( sipCodec, output_stream, socket );
}
/** Inits the RtpStreamReceiver */
private void init( SIPCodec sipCodec, OutputStream output_stream, DatagramSocket socket )
{
this.sipCodec = sipCodec;
this.output_stream = output_stream;
if ( socket != null ) {
rtp_socket = new RtpSocket( socket );
}
}
/** Whether is running */
public boolean isRunning()
{
return running;
}
/** Stops running */
public void halt()
{
running = false;
}
/** Runs it in a new Thread. */
public void run()
{
if ( rtp_socket == null )
{
println( "run", "RTP socket is null." );
return;
}
byte[] codedBuffer = new byte[ sipCodec.getIncomingEncodedFrameSize() ];
byte[] internalBuffer = new byte[sipCodec.getIncomingEncodedFrameSize() + RTP_HEADER_SIZE ];
RtpPacket rtpPacket = new RtpPacket( internalBuffer, 0 );
running = true;
try {
rtp_socket.getDatagramSocket().setSoTimeout( SO_TIMEOUT );
float[] decodingBuffer = new float[ sipCodec.getIncomingDecodedFrameSize() ];
int packetCount = 0;
println( "run",
"internalBuffer.length = " + internalBuffer.length
+ ", codedBuffer.length = " + codedBuffer.length
+ ", decodingBuffer.length = " + decodingBuffer.length + "." );
while ( running ) {
try {
rtp_socket.receive( rtpPacket );
frameCounter++;
if ( running ) {
byte[] packetBuffer = rtpPacket.getPacket();
int offset = rtpPacket.getHeaderLength();
int length = rtpPacket.getPayloadLength();
int payloadType = rtpPacket.getPayloadType();
if(payloadType < 20)
{
System.arraycopy(packetBuffer, offset, codedBuffer, 0, sipCodec.getIncomingEncodedFrameSize());
timeStamp = (int)(System.currentTimeMillis() - start);
output_stream.write(codedBuffer,offset,length);
}
}
}
catch ( java.io.InterruptedIOException e ) {
}
}
}
catch ( Exception e ) {
running = false;
e.printStackTrace();
}
// Close RtpSocket and local DatagramSocket.
DatagramSocket socket = rtp_socket.getDatagramSocket();
rtp_socket.close();
if ( socketIsLocal && socket != null ) {
socket.close();
}
// Free all.
rtp_socket = null;
println( "run", "Terminated." );
}
/** Debug output */
private static void println( String method, String message ) {
System.out.println( "RtpStreamReceiver - " + method + " -> " + message );
}
第 171 行是:output_stream.write(codedBuffer,offset,length);
如果您有兴趣,这里是完整的项目源代码。