/* * Copyright (C) 2005 Luca Veltri - University of Parma - Italy * * This source code is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This source code is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this source code; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author(s): * Luca Veltri (luca.veltri@unipr.it) */ package local.media; import local.net.RtpPacket; import local.net.RtpSocket; import java.io.*; import java.net.InetAddress; import java.net.DatagramSocket; /** RtpStreamReceiver is a generic stream receiver. * It receives packets from RTP and writes them into an OutputStream. */ public class RtpStreamTranslator extends Thread { /** Whether debug mode */ private static final boolean DEBUG=true; /** Size of the read buffer */ private static final int BUFFER_SIZE=32768; /** Maximum blocking time, spent waiting for reading new bytes [milliseconds] */ private static final int SO_TIMEOUT=200; /** The OutputStream */ OutputStream output_stream=null; /** The input RtpSocket */ RtpSocket rtp_socket_in=null; /** The input RtpSocket */ RtpSocket rtp_socket_out=null; /** Whether the receive socket has been created here */ boolean socket_in_is_local=false; /** Whether the send socket has been created here */ boolean socket_out_is_local=false; /** Whether it is running */ boolean running=false; /** Constructs a RtpStreamTranslator. * @param recv_port the local receiver port * @param dest_addr the destination address * @param dest_port the thestination port */ public RtpStreamTranslator(int recv_port, String dest_addr, int dest_port) { try { DatagramSocket recv_socket=new DatagramSocket(recv_port); socket_in_is_local=true; init(recv_socket,null,dest_addr,dest_port); } catch (Exception e) { e.printStackTrace(); } } /** Constructs a RtpStreamTranslator. * @param socket_in the local receiver socket * @param socket_out the socket used to send the RTP packet * @param dest_addr the destination address * @param dest_port the thestination port */ public RtpStreamTranslator(DatagramSocket socket_in, DatagramSocket socket_out, String dest_addr, int dest_port) { init(socket_in,socket_out,dest_addr,dest_port); } /** Inits the RtpStreamTranslator */ private void init(DatagramSocket socket_in, DatagramSocket socket_out, String dest_addr, int dest_port) { try { if (socket_out==null) { socket_out=new DatagramSocket(); socket_out_is_local=true; } rtp_socket_in=new RtpSocket(socket_in); rtp_socket_out=new RtpSocket(socket_out,InetAddress.getByName(dest_addr),dest_port); } catch (Exception e) { e.printStackTrace(); } } /** 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_in==null || rtp_socket_out==null) { if (DEBUG) println("ERROR: RTP socket_in or socket_out is null"); return; } //else byte[] buffer_in=new byte[BUFFER_SIZE]; RtpPacket rtp_packet_in=new RtpPacket(buffer_in,0); byte[] buffer_out=new byte[BUFFER_SIZE]; RtpPacket rtp_packet_out=new RtpPacket(buffer_out,0); //rtp_packet_out.setPayloadType(p_type); if (DEBUG) println("Reading blocks of max "+BUFFER_SIZE+" bytes"); //File file=new File("audio.wav"); //javax.sound.sampled.AudioInputStream audio_input_stream=null; //try { audio_input_stream=javax.sound.sampled.AudioSystem.getAudioInputStream(file); } catch (Exception e) { e.printStackTrace(); } running=true; try { rtp_socket_in.getDatagramSocket().setSoTimeout(SO_TIMEOUT); while (running) { try { // read a block of data from the rtp_socket_in rtp_socket_in.receive(rtp_packet_in); //if (DEBUG) System.out.print("."); // send the block to the rtp_socket_out (if still running..) if (running) { byte[] pkt1=rtp_packet_in.getPacket(); int offset1=rtp_packet_in.getHeaderLength(); int len1=rtp_packet_in.getPayloadLength(); byte[] pkt2=rtp_packet_out.getPacket(); int offset2=rtp_packet_out.getHeaderLength(); int pos2=offset2; for (int i=0; i<len1; i++) { int linear=G711.ulaw2linear(pkt1[offset1+i]); //aux[pos++]=(byte)(linear&0xFF); //aux[pos++]=(byte)((linear&0xFF00)>>8); //int linear2=G711.ulaw2linear(audio_input_stream.read()); //linear+=linear2; pkt2[pos2++]=(byte)G711.linear2ulaw(linear); } rtp_packet_out.setPayloadType(rtp_packet_in.getPayloadType()); rtp_packet_out.setSequenceNumber(rtp_packet_in.getSequenceNumber()); rtp_packet_out.setTimestamp(rtp_packet_in.getTimestamp()); rtp_packet_out.setPayloadLength(pos2-offset2); rtp_socket_out.send(rtp_packet_out); } } catch (java.io.InterruptedIOException e) { } } } catch (Exception e) { running=false; e.printStackTrace(); } // close RtpSocket and local DatagramSocket DatagramSocket socket_in=rtp_socket_in.getDatagramSocket(); rtp_socket_in.close(); if (socket_in_is_local && socket_in!=null) socket_in.close(); DatagramSocket socket_out=rtp_socket_out.getDatagramSocket(); rtp_socket_out.close(); if (socket_out_is_local && socket_out!=null) socket_out.close(); // free all rtp_socket_in=null; rtp_socket_out=null; if (DEBUG) println("rtp translator terminated"); } /** Debug output */ private static void println(String str) { System.out.println("RtpStreamTranslator: "+str); } public static int byte2int(byte b) { //return (b>=0)? b : -((b^0xFF)+1); //return (b>=0)? b : b+0x100; return (b+0x100)%0x100; } public static int byte2int(byte b1, byte b2) { return (((b1+0x100)%0x100)<<8)+(b2+0x100)%0x100; } // ******************************* MAIN ******************************* /** The main method. */ public static void main(String[] args) { String daddr=null; int dport=0; int rport=0; boolean help=true; for (int i=0; i<args.length; i++) { if (args[i].equals("-h")) { break; } if (i==0 && args.length>1) { rport=Integer.parseInt(args[i++]); daddr=args[i++]; dport=Integer.parseInt(args[i++]); help=false; continue; } // else, do: System.out.println("unrecognized param '"+args[i]+"'\n"); help=true; } if (help) { System.out.println("usage:\n java RtpStreamTranslator <recv_port> <dest_addr> <dest_port> [options]"); System.out.println(" options:"); System.out.println(" -h this help"); System.exit(0); } RtpStreamTranslator translator=new RtpStreamTranslator(rport,daddr,dport); translator.start(); } }