I am working on a softphone project using mjsip sip stack. Mjsip only supports g711 or PCMA/PCMU codec. I have added G729 to my project. When I build the project it shows no error. But when the phones get connected it the call gets established there is no voice transmitting, actually my app doesn't generate any rtp packets. And in the log there shows a error like
java.lang.NullPointerException
RtpStreamReceiver - run -> Terminated.
at local.media.RtpStreamReceiver.run(RtpStreamReceiver.java:171)
I have failed to find the bug.
Here is my RtpStreamReceiver.java class.
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 );
}
And the line 171 is: output_stream.write(codedBuffer,offset,length);
If you are interested here is the full project source.
As @gnat said in the comment - most likely output_stream
is null.
If that is the case you should check why. One reason could be that:
private void init( SIPCodec sipCodec, OutputStream output_stream, DatagramSocket socket )
is called with null parameter and that it overrides a value being correctly setup before.
You can log 'who' called a specific function by putting the following as the first line in init:
System.out.println("My function is called from: "
+ Thread.currentThread().getStackTrace()[2].getClassName() + "."
+ Thread.currentThread().getStackTrace()[2].getMethodName());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With