📄 rtpsessionmgr.java
字号:
} } public int initSession(SessionAddress localAddress, long defaultSSRC, SourceDescription[] defaultUserDesc, double rtcp_bw_fraction, double rtcp_sender_bw_fraction) { initialize(new SessionAddress[]{localAddress}, defaultUserDesc, rtcp_bw_fraction, rtcp_sender_bw_fraction, null); return 0; } public int initSession(SessionAddress localAddress, SourceDescription[] defaultUserDesc, double rtcp_bw_fraction, double rtcp_sender_bw_fraction) { initialize(new SessionAddress[]{localAddress}, defaultUserDesc, rtcp_bw_fraction, rtcp_sender_bw_fraction, null); return 0; } public int startSession(SessionAddress destAddress, int mcastScope, EncryptionInfo encryptionInfo) throws IOException { addTarget(destAddress); return 0; } public int startSession(SessionAddress localReceiverAddress, SessionAddress localSenderAddress, SessionAddress remoteReceiverAddress, EncryptionInfo encryptionInfo) throws IOException { addTarget(remoteReceiverAddress); return 0; } public long getDefaultSSRC() { return 0; } public RTPStream getStream(long filterssrc) { return null; } public int getMulticastScope() { return 127; } public void setMulticastScope(int multicastScope) { // Does Nothing } public void closeSession(String reason) { removeTargets(reason); } public String generateCNAME() { return localParticipant.getCNAME(); } public long generateSSRC() { return (long) (Math.random() * Integer.MAX_VALUE); } public SessionAddress getSessionAddress() { return null; } public SessionAddress getRemoteSessionAddress() { return null; // TODO: added only for JMF Compatibility. Called, for example in AVReceiver example. } public SessionAddress getLocalSessionAddress() { return localAddress; } public SendStream createSendStream(int ssrc, DataSource ds, int streamindex) throws UnsupportedFormatException, IOException { return createSendStream(ds, streamindex); } public int startSession(int mcastScope, EncryptionInfo encryptionInfo) { return -1; } public void addPeer(SessionAddress peerAddress) throws IOException { addTarget(peerAddress); } public void removePeer(SessionAddress peerAddress) { removeTarget(peerAddress, "Leaving"); } public void removeAllPeers() { removeTargets("Leaving"); } public Vector getPeers() { return getAllParticipants(); } /** * Starts the sending of RTCP packets */ public void start() { // Send the first RTCP packet long delay = (long) (Math.random() * 1000) + 500; rtcpTimer.schedule(new RTCPTimerTask(this), delay); globalReceptionStats.resetBytesRecd(); lastRTCPSendTime = System.currentTimeMillis(); } private long calculateRTCPDelay() { long delay = MIN_RTCP_INTERVAL; double bandwidth = ((double) globalReceptionStats.getBytesRecd() / (System.currentTimeMillis() - lastRTCPSendTime)); if (bandwidth < 0.1) { delay = MIN_RTCP_INTERVAL; } else { double senderFraction = 0; if ((activeParticipants.size() > 0) || (inactiveParticipants.size() > 0) ) { senderFraction = activeParticipants.size() / (inactiveParticipants.size() + activeParticipants.size()); } if ((activeParticipants.size() > 0) && (senderFraction < 0.25)) { if (localParticipant.getStreams().size() > 0) { delay = (long) ((averageRTCPSize * activeParticipants.size()) / (bandwidth * rtcpSenderBandwidthFraction)); } else { delay = (long) ((averageRTCPSize * inactiveParticipants.size()) / (bandwidth * rtcpReceiverBandwidthFraction)); } } else { delay = (long) ((averageRTCPSize * (activeParticipants.size() + inactiveParticipants.size())) / (bandwidth * (rtcpSenderBandwidthFraction + rtcpReceiverBandwidthFraction))); } if (delay < MIN_RTCP_INTERVAL) { delay = MIN_RTCP_INTERVAL; } } return delay; } private int writeSDESHeader(DataOutputStream output, int ssrcs, int size) throws IOException { int packetSize = size + 5 + (4 * ssrcs); int padding = 4 - (packetSize % 4); if (padding == 4) { padding = 0; } packetSize += padding; int pBit = 0; if (padding > 0) { pBit = 0x20; } // Add a RTCP header output.writeByte(0x80 | pBit | (ssrcs & 0x1F)); output.writeByte(RTCPPacket.PT_SDES & 0xFF); output.writeShort((packetSize / 4) - 1); return padding; } private void writeSDES(DataOutputStream output, Vector sdesItems, long ssrc) throws IOException { output.writeInt((int) (ssrc & 0xFFFFFFFF)); for (int i = 0; i < sdesItems.size(); i++) { SourceDescription sdes = (SourceDescription) sdesItems.get(i); int type = sdes.getType(); String description = sdes.getDescription(); byte[] desc = description.getBytes("UTF-8"); output.writeByte(type & 0xFF); output.writeByte(desc.length & 0xFF); output.write(desc); } output.writeByte(0); } /** * Sends an RTCP packet, and schedules the next one */ public void sendRTCPPacket() { int rc = receiveStreams.size(); if (rc > 31) { rc = 31; } long delay = calculateRTCPDelay(); long now = System.currentTimeMillis(); // If now is too early to send a packet, wait until later if (now < (lastRTCPSendTime + delay)) { rtcpTimer.schedule(new RTCPTimerTask(this), (lastRTCPSendTime + delay) - now); } else { // Reset the stats lastRTCPSendTime = System.currentTimeMillis(); globalReceptionStats.resetBytesRecd(); // Get the packet details ByteArrayOutputStream bytes = new ByteArrayOutputStream(); DataOutputStream output = new DataOutputStream(bytes); try { // Determine the packet type int packetType = RTCPPacket.PT_RR; int packetSize = (rc * RTCPFeedback.SIZE) + 8; if (localParticipant.getStreams().size() > 0) { packetType = RTCPPacket.PT_SR; packetSize += RTCPSenderInfo.SIZE; } // Add a RTCP header output.writeByte(0x80 | 0 | (rc & 0x1F)); output.writeByte(packetType & 0xFF); output.writeShort(((packetSize) / 4) - 1); output.writeInt((int) (ssrc & 0xFFFFFFFF)); // If we are a sender, add sender stats if (localParticipant.getStreams().size() > 0) { packetType = RTCPPacket.PT_SR; int senderIndex = (int) (Math.random() * localParticipant.getStreams().size()); RTPSendStream sendStream = (RTPSendStream) localParticipant.getStreams().get( senderIndex); TransmissionStats stats = sendStream.getSourceTransmissionStats(); long sendtime = sendStream.getLastSendTime(); sendtime += 22089888000000l; long sendTimeSeconds = sendtime / 1000; long sendTimeFractions = ((sendtime - (sendTimeSeconds * 1000)) / 1000) * (Integer.MAX_VALUE * 2); long timestamp = sendStream.getLastTimestamp(); output.writeInt((int) (sendTimeSeconds & 0xFFFFFFFF)); output.writeInt((int) (sendTimeFractions & 0xFFFFFFFF)); output.writeInt((int) (timestamp & 0xFFFFFFFF)); output.writeInt(stats.getPDUTransmitted()); output.writeInt(stats.getBytesTransmitted()); } // Add the receiver reports Vector streams = new Vector(receiveStreams.values()); now = System.currentTimeMillis(); for (int i = 0; i < rc; i++) { int pos = (int) (Math.random() * streams.size()); RTPReceiveStream stream = (RTPReceiveStream) streams.get(pos); RTPReceptionStats stats = (RTPReceptionStats) stream.getSourceReceptionStats(); RTPDataSource dataSource = (RTPDataSource) stream.getDataSource(); RTPDataStream dataStream = (RTPDataStream) dataSource.getStreams()[0]; long streamSSRC = stream.getSSRC(); int lossFraction = 0; if (stats.getPDUProcessed() > 0) { lossFraction = (256 * stats.getPDUlost()) / stats.getPDUProcessed(); } long lastESequence = (stats.getSequenceWrap() * RTPHeader.MAX_SEQUENCE) + dataStream.getLastSequence(); long packetsExpected = lastESequence - dataStream.getFirstSequence(); int cumulativePacketLoss = (int) (packetsExpected - (stats.getPDUProcessed() + stats.getPDUDuplicate())); long jitter = ((RTPDataSource) stream.getDataSource()).getJitter(); long lsrMSW = stream.getLastSRReportTimestampMSW(); long lsrLSW = stream.getLastSRReportTimestampLSW(); long DLSR = ((now - stream.getLastSRReportTime()) * 1000) / 65536; if (stream.getLastSRReportTime() == 0) { DLSR = 0; } output.writeInt((int) (streamSSRC & 0xFFFFFFFF)); output.writeByte(lossFraction & 0xFF); output.writeByte((cumulativePacketLoss >> 16) & 0xFF); output.writeShort((cumulativePacketLoss & 0xFFFF)); output.writeInt((int) (lastESequence & 0xFFFFFFFF)); output.writeInt((int) (jitter & 0xFFFFFFFF)); output.writeShort((int) (lsrMSW & 0xFFFF)); output.writeShort((int) ((lsrLSW >> 16) & 0xFFFF)); output.writeInt((int) (DLSR & 0xFFFFFFFF)); streams.remove(pos); } // Add the SDES items if (localParticipant.getStreams().size() == 0) { Vector sdesItems = localParticipant.getSourceDescription(); if (sdesItems.size() > 0) { int padding = writeSDESHeader(output, 1, localParticipant.getSdesSize()); writeSDES(output, sdesItems, ssrc); // Add the sdes padding for (int i = 0; i < padding; i++) { output.writeByte(padding); } } } else { Vector sendStreams = localParticipant.getStreams(); int totalSDES = 0; for (int i = 0; i < sendStreams.size(); i++) { totalSDES += ((RTPSendStream) sendStreams.get(i)).getSdesSize(); } int padding = writeSDESHeader(output, sendStreams.size(), totalSDES); for (int i = 0; i < sendStreams.size(); i++) { RTPSendStream sendStream = (RTPSendStream) sendStreams.get(i); writeSDES(output, sendStream.getSourceDescription(), sendStream.getSSRC()); } // Add the sdes padding for (int i = 0; i < padding; i++) { output.writeByte(padding); } } } catch (IOException e) { logger.log(Level.WARNING, "" + e, e); } Iterator iterator = targets.values().iterator(); while (iterator.hasNext()) { RTPConnector connector = (RTPConnector) iterator.next(); try { OutputDataStream outputStream = connector.getControlOutputStream(); output.close(); bytes.close(); byte[] data = bytes.toByteArray(); outputStream.write(data, 0, data.length); } catch (IOException e) { logger.log(Level.WARNING, "" + e, e); } } // Prepare to send the next packet if (!done) { rtcpTimer.schedule(new RTCPTimerTask(this), delay); } } } // A timer task for sending RTCP packets private class RTCPTimerTask extends TimerTask { private RTPSessionMgr rtpSessionManager = null; private RTCPTimerTask(RTPSessionMgr rtpSessionManager) { this.rtpSessionManager = rtpSessionManager; } public void run() { rtpSessionManager.sendRTCPPacket(); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -