2012-02-16 7 views
20

Sto lavorando a un progetto di softphone utilizzando mjsip sip stack. Mjsip supporta solo il codec g711 o PCMA/PCMU. Ho aggiunto G729 al mio progetto. Quando costruisco il progetto non mostra alcun errore. Ma quando i telefoni vengono collegati, la chiamata viene stabilita, non c'è trasmissione vocale, in realtà la mia app non genera pacchetti rtp. E nel registro viene visualizzato un errore comeI pacchetti RTP non vengono inviati o ricevuti utilizzando mjsip

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

Non ho trovato il bug.

Ecco la mia classe 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); 
} 

E la linea 171 è: output_stream.write(codedBuffer,offset,length);

Se siete interessati here è la sorgente del progetto completo.

+1

molto probabilmente NPE è causato da 'output_stream' che è nullo quando è in esecuzione la stringa 'RtpStreamReceiver'. Userei 'println' per scoprire se questo è il caso. – gnat

+0

è il socket associato (bind()) o aperto, oppure la classe RtpSocket gestisce questo per te? – EdH

+0

Hai funzionato? Puoi caricare di nuovo il tuo progetto? – B770

risposta

2

Come @gnat ha detto nel commento - molto probabilmente output_stream è nullo.

Se è il caso, è necessario controllare perché. Una ragione potrebbe essere che:

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

è chiamato con il parametro nullo e che sostituisce un valore essere impostato correttamente prima.

è possibile accedere 'chi' ha chiamato una funzione specifica, mettendo quanto segue come la prima linea di init:

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

Per voce di trasmissione utilizzando RTP Java Media Framework ottimo da utilizzare. dal sito Web di oracle puoi ottenere jmf.exe. E puoi trasmettere la voce usando quell'API. è disponibile anche il coading della voce trasmittente.