2012-02-16 11 views
20

Estoy trabajando en un proyecto de softphone utilizando mjsip sip stack. Mjsip solo es compatible con el códec g711 o PCMA/PCMU. He agregado G729 a mi proyecto. Cuando construyo el proyecto, no muestra ningún error. Pero cuando los teléfonos se conectan, la llamada se establece y no hay transmisión de voz; en realidad, mi aplicación no genera ningún paquete rtp. Y en el registro aparece un error comoLos paquetes de RTP no se envían ni se reciben con mjsip

java.lang.NullPointerException 
RtpStreamReceiver - run -> Terminated. 
    at local.media.RtpStreamReceiver.run(RtpStreamReceiver.java:171) 

No he podido encontrar el error.

Aquí está mi clase 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); 
} 

Y la línea 171 es: output_stream.write(codedBuffer,offset,length);

Si está interesado here es la fuente del proyecto completo.

+1

es más probable que NPE esté causado por 'output_stream' que es nulo cuando se está ejecutando el subproceso' RtpStreamReceiver'. Usaría 'println' para averiguar si este es el caso. – gnat

+0

es el socket enlazado (bind()) o abierto, o la clase RtpSocket maneja esto por usted? – EdH

+0

¿Lo hiciste funcionar? ¿Puedes subir tu proyecto nuevamente? – B770

Respuesta

2

Como @gnat dijo en el comentario: lo más probable es que output_stream sea nulo.

Si ese es el caso, debe comprobar por qué. Una de las razones podría ser que:

private void init(SIPCodec sipCodec, OutputStream output_stream, DatagramSocket socket)

se llama con el parámetro nulo y que anula un valor que es correcta la configuración anterior.

puede iniciar sesión 'que' llama una función específica, colocando lo siguiente como la primera línea en init:

System.out.println("My function is called from: " 
+ Thread.currentThread().getStackTrace()[2].getClassName() + "." 
+ Thread.currentThread().getStackTrace()[2].getMethodName()); 
0

Para la voz de transmisión utilizando RTP Java Media Framework de gran uso. desde el sitio web de Oracle puede obtener jmf.exe. Y puedes transmitir voz usando ese Api. la codificación de la transmisión de voz también está disponible.

Cuestiones relacionadas