📄 rtpsessionmgr.java
字号:
/* * @(#)RTPManager.java * Created: 25-Oct-2005 * Version: 1-1-alpha3 * Copyright (c) 2005-2006, University of Manchester All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. Redistributions in binary * form must reproduce the above copyright notice, this list of conditions and * the following disclaimer in the documentation and/or other materials * provided with the distribution. Neither the name of the University of * Manchester nor the names of its contributors may be used to endorse or * promote products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */package net.sf.fmj.media.rtp;import java.io.ByteArrayOutputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.InetAddress;import java.net.UnknownHostException;import java.util.HashMap;import java.util.Iterator;import java.util.Timer;import java.util.TimerTask;import java.util.Vector;import java.util.logging.Level;import java.util.logging.Logger;import javax.media.Format;import javax.media.format.AudioFormat;import javax.media.format.UnsupportedFormatException;import javax.media.format.VideoFormat;import javax.media.protocol.DataSource;import javax.media.protocol.PullBufferDataSource;import javax.media.protocol.PullBufferStream;import javax.media.protocol.PushBufferDataSource;import javax.media.protocol.PushBufferStream;import javax.media.rtp.EncryptionInfo;import javax.media.rtp.GlobalReceptionStats;import javax.media.rtp.GlobalTransmissionStats;import javax.media.rtp.LocalParticipant;import javax.media.rtp.OutputDataStream;import javax.media.rtp.RTPConnector;import javax.media.rtp.RTPStream;import javax.media.rtp.ReceiveStreamListener;import javax.media.rtp.RemoteListener;import javax.media.rtp.SendStream;import javax.media.rtp.SendStreamListener;import javax.media.rtp.SessionAddress;import javax.media.rtp.SessionListener;import javax.media.rtp.SessionManager;import javax.media.rtp.TransmissionStats;import javax.media.rtp.event.ByeEvent;import javax.media.rtp.event.NewParticipantEvent;import javax.media.rtp.event.NewReceiveStreamEvent;import javax.media.rtp.event.ReceiveStreamEvent;import javax.media.rtp.event.ReceiverReportEvent;import javax.media.rtp.event.RemoteEvent;import javax.media.rtp.event.SenderReportEvent;import javax.media.rtp.event.SessionEvent;import javax.media.rtp.event.StreamMappedEvent;import javax.media.rtp.rtcp.SourceDescription;import net.sf.fmj.utility.LoggerSingleton;/** * * @author Andrew G D Rowley * @version 1-1-alpha3 */public class RTPSessionMgr extends javax.media.rtp.RTPManager implements SessionManager { private static final Logger logger = LoggerSingleton.logger; // The minimum RTCP interval in ms private static final int MIN_RTCP_INTERVAL = 5000; // The map of Integer -> format recognised private HashMap formatMap = new HashMap(); // A vector of receive stream listeners private Vector receiveStreamListeners = new Vector(); // A vector of remote listeners private Vector remoteListeners = new Vector(); // A vector of send stream listeners private Vector sendStreamListeners = new Vector(); // A vector of session listeners private Vector sessionListeners = new Vector(); // The local participant private RTPLocalParticipant localParticipant = null; // A map of active participants (cname -> participant) private HashMap activeParticipants = new HashMap(); // A map of inactive participants (cname -> participant) private HashMap inactiveParticipants = new HashMap(); // The global reception statistics private RTPGlobalReceptionStats globalReceptionStats = new RTPGlobalReceptionStats(); // The global transmission statistics private RTPGlobalTransmissionStats globalTransmissionStats = new RTPGlobalTransmissionStats(); // A map of receive streams (ssrc -> stream) private HashMap receiveStreams = new HashMap(); // A map of send streams (ssrc -> stream) private HashMap sendStreams = new HashMap(); // A map of streams that are ignored as they cannot be recognised private HashMap ignoredStreams = new HashMap(); // A map of ssrcs to cnames private HashMap senders = new HashMap(); // The RTCP Receiver Bandwidth fraction private double rtcpReceiverBandwidthFraction = 0.0375; // The RTCP Sender Bandwidth fraction private double rtcpSenderBandwidthFraction = 0.0125; // The local address to use to bind sockets to private SessionAddress localAddress = null; // The RTP Connectors for targets that have been set up // (address -> connector) private HashMap targets = new HashMap(); // The RTP Handler private RTPHandler rtpHandler = null; // The RTCP Handler private RTCPHandler rtcpHandler = null; // The lock for sending events (so events are received in order) private Integer eventLock = new Integer(0); // True if the event lock has been obtained private boolean eventLocked = false; // True when the session is finished with private boolean done = false; // An RTCP timer private Timer rtcpTimer = new Timer(); // The time at which the last rtcpPacket was sent private long lastRTCPSendTime = -1; // The average size of an RTCP packet received private int averageRTCPSize = 0; // The ssrc if we are not sending protected static long ssrc = (long) (Math.random() * Integer.MAX_VALUE); private void getEventLock() { synchronized (eventLock) { while (eventLocked) { try { eventLock.wait(); } catch (InterruptedException e) { // Do Nothing } } eventLocked = true; } } private void releaseEventLock() { synchronized (eventLock) { eventLocked = false; eventLock.notifyAll(); } } /** * Creates a new RTPManager */ public RTPSessionMgr() { String user = System.getProperty("user.name"); String host = "localhost"; try { host = InetAddress.getLocalHost().getHostName(); } catch (UnknownHostException e) { // Do Nothing } this.localParticipant = new RTPLocalParticipant(user + "@" + host); addFormat(new AudioFormat(AudioFormat.ULAW_RTP, 8000, 8, 1), 0); addFormat(new AudioFormat(AudioFormat.GSM_RTP, 8000, Format.NOT_SPECIFIED, 1), 3); addFormat(new AudioFormat(AudioFormat.G723_RTP, 8000, Format.NOT_SPECIFIED, 1), 4); addFormat(new AudioFormat(AudioFormat.DVI_RTP, 8000, 4, 1), 5); addFormat(new AudioFormat(AudioFormat.MPEG_RTP), 14); addFormat(new AudioFormat(AudioFormat.G728_RTP, 8000.0, Format.NOT_SPECIFIED, 1), 15); addFormat(new AudioFormat(AudioFormat.DVI_RTP, 11025, 4, 1), 16); addFormat(new AudioFormat(AudioFormat.DVI_RTP, 22050, 4, 1), 17); addFormat(new AudioFormat(AudioFormat.G729_RTP, 8000.0, Format.NOT_SPECIFIED, 1), 18); addFormat(new VideoFormat(VideoFormat.JPEG_RTP), 26); addFormat(new VideoFormat(VideoFormat.H261_RTP), 31); addFormat(new VideoFormat(VideoFormat.MPEG_RTP), 32); addFormat(new VideoFormat(VideoFormat.H263_RTP), 34); addFormat(new VideoFormat("h263-1998/rtp"), 42); } /** * This is a function provided by Sun's implementation, which is not in the API as AFAIK - kenlars99. * This does not include formats in the RTP bonus formats mgr. * This is a somewhat dubious function, since the actual RTPSessionMgr used is determined by RTPManager.newInstance(). * To the extend that Sun's code calls this function, it is assuming that its own RTPSessionMgr will be used, which * may be the source of some problems. * * Note: the format list in JMF is static, and in FMJ it is not. So you can add a format once with * JMF, but you have to add it every time you instantiate the manager with FMJ. * */ public static boolean formatSupported(Format f) { final RTPSessionMgr mgr = new RTPSessionMgr(); final Iterator iter = mgr.formatMap.keySet().iterator(); while (iter.hasNext()) { Integer id = (Integer) iter.next(); Format testFormat = (Format) mgr.formatMap.get(id); if (testFormat.matches(f)) { return true; } } return false; } /** Another function provided by Sun's implementation, not in the spec/API. */ public Format getFormat(int payload) { return (Format) formatMap.get(new Integer(payload)); } public void addFormat(Format format, int payload) { formatMap.put(new Integer(payload), format); } public void addReceiveStreamListener(ReceiveStreamListener listener) { receiveStreamListeners.add(listener); } public void addRemoteListener(RemoteListener listener) { remoteListeners.add(listener); } public void addSendStreamListener(SendStreamListener listener) { sendStreamListeners.add(listener); } public void addSessionListener(SessionListener listener) { sessionListeners.add(listener); } public void removeReceiveStreamListener(ReceiveStreamListener listener) { receiveStreamListeners.remove(listener); } public void removeRemoteListener(RemoteListener listener) { remoteListeners.remove(listener); } public void removeSendStreamListener(SendStreamListener listener) { sendStreamListeners.remove(listener); } public void removeSessionListener(SessionListener listener) { sessionListeners.remove(listener); } public Vector getActiveParticipants() { Vector participants = new Vector(activeParticipants.values()); if (localParticipant.isActive()) { participants.add(localParticipant); } return participants; } public Vector getAllParticipants() { Vector participants = new Vector(); participants.addAll(activeParticipants.values()); participants.addAll(inactiveParticipants.values()); participants.add(localParticipant); return participants; } public LocalParticipant getLocalParticipant() { return localParticipant; } public Vector getPassiveParticipants() { Vector participants = new Vector(inactiveParticipants.values()); if (!localParticipant.isActive()) { participants.add(localParticipant); } return participants; } public Vector getRemoteParticipants() { Vector participants = new Vector(); participants.addAll(activeParticipants.values()); participants.addAll(inactiveParticipants.values()); return participants; } public GlobalReceptionStats getGlobalReceptionStats() { return globalReceptionStats; } public GlobalTransmissionStats getGlobalTransmissionStats() { return globalTransmissionStats; } public Vector getReceiveStreams() { return new Vector(receiveStreams.values()); } public Vector getSendStreams() { return new Vector(sendStreams.values()); } public void initialize(SessionAddress localAddress) throws IOException { String user = System.getProperty("user.name"); initialize(new SessionAddress[] { localAddress }, new SourceDescription[] { new SourceDescription( SourceDescription.SOURCE_DESC_CNAME, user + "@" + InetAddress.getLocalHost() .getHostName(), 1, false), new SourceDescription( SourceDescription.SOURCE_DESC_NAME, user + "@" + InetAddress.getLocalHost() .getHostName(), 3, false) }, 0.05, 0.25, null); } public void initialize(SessionAddress[] localAddresses, SourceDescription[] sourceDescription, double rtcpBandwidthFraction, double rtcpSenderBandwidthFraction, EncryptionInfo encryptionInfo) { this.rtcpSenderBandwidthFraction = rtcpBandwidthFraction * rtcpBandwidthFraction; this.rtcpReceiverBandwidthFraction = rtcpBandwidthFraction - this.rtcpSenderBandwidthFraction; this.localParticipant = new RTPLocalParticipant(""); localParticipant.setSourceDescription(sourceDescription); localAddress = localAddresses[0]; start();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -