RTP-пакеты не отправляются или не принимаются с использованием mjsip - PullRequest
20 голосов
/ 16 февраля 2012

Я работаю над проектом софтфона, используя стек sj mjsip. 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);

Если вам интересно здесь - полный исходный код проекта.

Ответы [ 2 ]

2 голосов
/ 02 июля 2012

Как сказал @gnat в комментарии - скорее всего, output_stream равно нулю.

Если это так, вам следует проверить, почему. Одной из причин может быть то, что:

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

вызывается с нулевым параметром и переопределяет значение, которое было правильно установлено ранее.

Вы можете записать 'кто' вызвал определенную функцию, указав в первой строке следующую строку:

System.out.println("My function is called from: "
+ Thread.currentThread().getStackTrace()[2].getClassName() + "."
+ Thread.currentThread().getStackTrace()[2].getMethodName());
0 голосов
/ 19 июля 2012

Для передачи голоса с использованием RTP Java Media Framework отлично подходит для использования.с сайта оракула вы можете получить jmf.exe.И вы можете передавать голос, используя этот Api.кодирование передачи голоса также доступна.

...