├── org.jlibrtp ├── .gitignore ├── .settings │ ├── org.eclipse.buildship.core.prefs │ └── org.eclipse.jdt.core.prefs ├── src │ ├── test │ │ └── java │ │ │ └── org │ │ │ └── jlibrtp │ │ │ ├── validateccrtp │ │ │ ├── package.html │ │ │ ├── CCRTPReceiver.java │ │ │ └── CCRTPSender.java │ │ │ └── test │ │ │ ├── TestRTPSession.java │ │ │ └── protocols │ │ │ └── rtp │ │ │ ├── TestRTPURLMultiSender.java │ │ │ ├── TestRTPURLSender.java │ │ │ └── TestRTPURLReceiver.java │ └── main │ │ └── java │ │ └── org │ │ └── jlibrtp │ │ ├── package.html │ │ ├── README.txt │ │ ├── PktBufNode.java │ │ ├── protocols │ │ └── rtp │ │ │ ├── Handler.java │ │ │ ├── RTPOutputStream.java │ │ │ └── CircularByteBuffer.java │ │ ├── RTPAppIntf.java │ │ ├── DebugAppIntf.java │ │ ├── RTCPAVPFIntf.java │ │ ├── RtcpPktAPP.java │ │ ├── AppCallerThread.java │ │ ├── RtcpPktBYE.java │ │ ├── RTCPAppIntf.java │ │ ├── RtcpPkt.java │ │ ├── RtcpPktRTPFB.java │ │ ├── RtcpPktSR.java │ │ ├── RTPReceiverThread.java │ │ ├── StaticProcs.java │ │ ├── RtcpPktRR.java │ │ ├── CompRtcpPkt.java │ │ ├── DataFrame.java │ │ └── ParticipantDatabase.java ├── .project ├── .classpath └── build.gradle ├── org.jlibrtp.demo ├── .gitignore ├── .settings │ ├── org.eclipse.buildship.core.prefs │ └── org.eclipse.jdt.core.prefs ├── .classpath ├── .project ├── src │ └── main │ │ └── java │ │ └── org │ │ └── jlibrtp │ │ ├── demo │ │ ├── package.html │ │ ├── UnicastExample.java │ │ ├── SoundReceiverDemo.java │ │ ├── UnicastExample2.java │ │ ├── XmlPacketPlayer.java │ │ └── SoundSenderDemo.java │ │ ├── ValidateParticipantDatabase.java │ │ ├── ValidatePktBuffer.java │ │ ├── ValidateStaticProcs.java │ │ └── ValidateRtcpPkt.java └── build.gradle ├── gradlew ├── settings.gradle ├── .settings └── org.eclipse.buildship.core.prefs ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── .gitattributes ├── .project ├── gradle.properties ├── README.md ├── LICENSE └── gradlew.bat /org.jlibrtp/.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | -------------------------------------------------------------------------------- /org.jlibrtp.demo/.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JVoiceXML/jlibrtp/HEAD/gradlew -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include 'org.jlibrtp' 2 | include 'org.jlibrtp.demo' 3 | -------------------------------------------------------------------------------- /.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | connection.project.dir= 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JVoiceXML/jlibrtp/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /org.jlibrtp/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | connection.project.dir=.. 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /org.jlibrtp.demo/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | connection.project.dir=.. 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | /.gradle/ 3 | 4 | # Ignore Gradle project-specific cache directory 5 | .gradle 6 | 7 | # Ignore Gradle build output directory 8 | build 9 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # 2 | # https://help.github.com/articles/dealing-with-line-endings/ 3 | # 4 | # These are explicitly windows files and should use crlf 5 | *.bat text eol=crlf 6 | 7 | -------------------------------------------------------------------------------- /org.jlibrtp/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 3 | org.eclipse.jdt.core.compiler.compliance=1.8 4 | org.eclipse.jdt.core.compiler.source=1.8 5 | -------------------------------------------------------------------------------- /org.jlibrtp.demo/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 3 | org.eclipse.jdt.core.compiler.compliance=1.8 4 | org.eclipse.jdt.core.compiler.source=1.8 5 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /org.jlibrtp/src/test/java/org/jlibrtp/validateccrtp/package.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |ValidateCcrtp is a small package to test compatibility with ccRTP, a popular C++ 4 | implementation of the RTP protocol. It mimicks demo programs distributed with ccRTP.
5 |The jlibrtpDemos package contains simple demonstration programs for testing jlibrtp 4 | and some examples of how the library can be used.
5 |The programs are distributed as sample code, they are not thought to be particularly 6 | useful by themselves, but the XML tools do give a nice way of looking at your stream in 7 | any web browser. You can also easily edit these files to change the stream. 8 |
9 |The jlibrtp package contains the core classes of jlibrtp. Most of these classes 4 | are protected or private, developers looking to use jlibrtp should only concern 5 | themselves with
6 |16 | DebugAppIntf is great for checking network problems and keeping track of packets. 17 | If you need extensive debugging you should statically change the debug values in RTPSession.java 18 | and pay attention to the standard output. 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | # 21 | # General settings 22 | # 23 | 24 | name = RTP Library for Java 25 | group = org.jvoicexml 26 | version = 0.2 27 | 28 | JVOICEXML_GROUP = org.jvoicexml 29 | 30 | -------------------------------------------------------------------------------- /org.jlibrtp.demo/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java-library' 3 | id 'signing' 4 | id 'maven-publish' 5 | } 6 | 7 | repositories { 8 | mavenCentral() 9 | } 10 | 11 | sourceCompatibility = 1.8 12 | targetCompatibility = 1.8 13 | 14 | dependencies { 15 | testImplementation 'junit:junit:4.13.2' 16 | 17 | implementation project(':org.jlibrtp') 18 | implementation 'org.jdom:jdom2:2.0.6' 19 | } 20 | 21 | jar { 22 | manifest { 23 | attributes('Implementation-Title': 'RTP Library for Java Demo', 24 | 'Implementation-Vendor': 'switch', 25 | 'Implementation-Version': version, 26 | 'Built-By' : System.properties['user.name'], 27 | 'Build-Timestamp': new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(new Date()), 28 | 'Created-By' : "Gradle ${gradle.gradleVersion}", 29 | 'Build-Jdk' : "${System.properties['java.version']} (${System.properties['java.vendor']} ${System.properties['java.vm.version']})", 30 | 'Build-OS' : "${System.properties['os.name']} ${System.properties['os.arch']} ${System.properties['os.version']}") 31 | } 32 | baseName 'org.jlibrtp.demo' 33 | } 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RTP Library for Java 2 | 3 | jlibrtp aims to create a library that makes it easy to support RTP (RFC 3550,3551) in Java applications. SRTP (RFC 3771) has been delayed in favor of RFC 4585. 4 | 5 | In order to increase compatibility, this library is compiled with JDK1.8. 6 | 7 | ## Include from from Maven 8 | 9 | Configure maven to use Central from your Project Object Model (POM) file.You may do so by 10 | adding the following to your pom.xml: 11 | 12 |Title: Handler for rtp:// protocol
32 | * 33 | *Description:
34 | * 35 | *Copyright: Copyright (c) 2007-2008
36 | * 37 | *Company: VoiceInteraction
38 | * 39 | * @author Renato Cassaca 40 | * @version 1.0 41 | */ 42 | public class Handler extends URLStreamHandler { 43 | /** Logger instance. */ 44 | private static final Logger LOGGER = 45 | Logger.getLogger(Handler.class.getName()); 46 | 47 | public Handler() { 48 | super(); 49 | } 50 | 51 | protected URLConnection openConnection(URL url) throws IOException { 52 | try { 53 | return new RTPURLConnection(url); 54 | } catch (URISyntaxException ex) { 55 | throw new IOException("Invalid provided URL"); 56 | } 57 | } 58 | 59 | /** 60 | * Returns the default port for a URL parsed by this handler. 61 | * 62 | * @return the default port for aURL parsed by this handler.
63 | */
64 | protected int getDefaultPort() {
65 | return 0;
66 | }
67 |
68 | /**
69 | * Get the IP address of our host.
70 | *
71 | * @param u a URL object
72 | * @return an InetAddress representing the host IP address.
73 | */
74 | protected synchronized InetAddress getHostAddress(URL u) {
75 | try {
76 | return InetAddress.getLocalHost();
77 | } catch (UnknownHostException ex) {
78 | LOGGER.warning(ex.getMessage());
79 | return null;
80 | }
81 | }
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/org.jlibrtp/src/main/java/org/jlibrtp/RTPAppIntf.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Java RTP Library (jlibrtp)
3 | * Copyright (C) 2006 Arne Kepp
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | package org.jlibrtp;
21 |
22 |
23 | /**
24 | * This is the callback interface for RTP packets.
25 | *
26 | * It is mandatory, but you can inore the data if you like.
27 | *
28 | * @author Arne Kepp
29 | */
30 | public interface RTPAppIntf {
31 |
32 | /**
33 | * The callback method through which the application will receive
34 | * data from jlibrtp. These calls are synchronous, so you will not
35 | * receive any new packets until this call returns.
36 | *
37 | * @param frame the frame containing the data
38 | * @param participant the participant from which the data came
39 | */
40 | public void receiveData(DataFrame frame, Participant participant);
41 |
42 |
43 | /**
44 | * The callback method through which the application will receive
45 | * notifications about user updates, additions and byes.
46 | * Types:
47 | * 1 - Bye
48 | * 2 - New through RTP, check .getRtpSendSock()
49 | * 3 - New through RTCP, check .getRtcpSendSock()
50 | * 4 - SDES packet received, check the getCname() etc methods
51 | * 5 - Matched SSRC to ip-address provided by application
52 | *
53 | * @param type the type of event
54 | * @param participant the participants in question
55 | */
56 | public void userEvent(int type, Participant[] participant);
57 |
58 | /**
59 | * The callback method through which the application can specify
60 | * the number of packets that make up a frame for a given payload type.
61 | *
62 | * A negative value denotes frames of variable length, so jlibrtp
63 | * will return whatever it has at the time.
64 | *
65 | * In most applications, this function can simply return 1.
66 | *
67 | * This should be implemented as something fast, such as an
68 | * integer array with the indexes being the payload type.
69 | *
70 | * @param payloadType the payload type specified in the RTP packet
71 | * @return the number of packets that make up a frame
72 | */
73 | public int frameSize(int payloadType);
74 | }
75 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/org.jlibrtp/src/main/java/org/jlibrtp/DebugAppIntf.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Java RTP Library (jlibrtp)
3 | * Copyright (C) 2006 Arne Kepp
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 | package org.jlibrtp;
20 | import java.net.InetSocketAddress;
21 |
22 | /**
23 | * DebugAppIntf can be registered on RTPSession to provide simple
24 | * debugging functionality. This is particularly useful to determine
25 | * whether the client is receing any data at all.
26 | *
27 | * @author Arne Kepp
28 | *
29 | */
30 |
31 | public interface DebugAppIntf {
32 | /**
33 | * This function wil notify you of any packets received, valid or not.
34 | * Useful for network debugging, and finding bugs in jlibrtp.
35 | *
36 | * Type is an integer describing the type of event
37 | * -2 - Invalid RTCP packet received
38 | * -1 - Invalid RTP packet received
39 | * 0 - RTP packet received
40 | * 1 - RTCP packet received
41 | *
42 | * Description is a string that should be meaningful to advanced users, such as
43 | * "RTP packet received from 127.0.0.1:12312, SSRC: 1380912 , payload type 1, packet size 16 octets"
44 | * or
45 | * "Invalid RTP packet received from 127.0.0.1:12312"
46 | *
47 | * This function is synchonous and should return quickly.
48 | *
49 | * @param type , the type of event, see above.
50 | * @param socket , taken directly from the UDP packet
51 | * @param description , see above.
52 | */
53 | public void packetReceived(int type, InetSocketAddress socket, String description);
54 |
55 | /**
56 | * This function will notify you of any packets sent from this instance of RTPSession.
57 | * Useful for network debugging, and finding bugs in jlibrtp.
58 | *
59 | * Type is an integer describing the type of event
60 | * 0 - RTP unicast packet sent
61 | * 1 - RTP multicast packet sent
62 | * 2 - RTCP unicast packet sent
63 | * 3 - RTCP multicast packet sent
64 | *
65 | * Description is a string that should be meaningful to advanced users, such as
66 | *
67 | * This function is synchonous and should return quickly.
68 | *
69 | * @param type , the type of event, see above
70 | * @param socket , taken directly from the UDP packet
71 | * @param description , see above
72 | */
73 | public void packetSent(int type, InetSocketAddress socket, String description);
74 |
75 | /**
76 | * Other important events that can occur in session
77 | * -1 SSRC conflict
78 | * 0 Session is terminating
79 | * @param type see above
80 | * @param description , see above
81 | */
82 | public void importantEvent(int type, String description);
83 | }
84 |
--------------------------------------------------------------------------------
/org.jlibrtp/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'java-library'
3 | id 'signing'
4 | id 'maven-publish'
5 | }
6 |
7 | repositories {
8 | mavenCentral()
9 | }
10 |
11 | sourceCompatibility = 1.8
12 | targetCompatibility = 1.8
13 |
14 | dependencies {
15 | testImplementation 'junit:junit:4.13.2'
16 | }
17 |
18 | jar {
19 | manifest {
20 | attributes('Implementation-Title': 'RTP Library for Java',
21 | 'Implementation-Vendor': 'switch',
22 | 'Implementation-Version': version,
23 | 'Built-By' : System.properties['user.name'],
24 | 'Build-Timestamp': new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(new Date()),
25 | 'Created-By' : "Gradle ${gradle.gradleVersion}",
26 | 'Build-Jdk' : "${System.properties['java.version']} (${System.properties['java.vendor']} ${System.properties['java.vm.version']})",
27 | 'Build-OS' : "${System.properties['os.name']} ${System.properties['os.arch']} ${System.properties['os.version']}")
28 | }
29 | baseName 'org.jlibrtp'
30 | }
31 |
32 | java {
33 | withJavadocJar()
34 | withSourcesJar()
35 | }
36 |
37 | publishing {
38 | publications {
39 | mavenJava(MavenPublication) {
40 | artifactId = tasks.jar.baseName
41 | from components.java
42 | versionMapping {
43 | usage('java-api') {
44 | fromResolutionOf('runtimeClasspath')
45 | }
46 | usage('java-runtime') {
47 | fromResolutionResult()
48 | }
49 | }
50 | pom {
51 | name = 'jlibrtp'
52 | description = 'RTP Library for Java'
53 | url = 'https://github.com/JVoiceXML/jlibrtp'
54 | licenses {
55 | license {
56 | name = 'GNU Lesser General Public License, Version 2.1'
57 | url = 'https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt'
58 | }
59 | }
60 | developers {
61 | developer {
62 | id = 'schnelle'
63 | name = 'Dirk Schnelle-Walka'
64 | email = 'dirk.schnelle@jvoicexml.org'
65 | }
66 | }
67 | scm {
68 | connection = 'scm:git:git@github.com:JVoiceXML/jlibrtp.git'
69 | developerConnection = 'scm:git:ssh://github.com:JVoiceXML/JVoiceXML.git'
70 | url = 'https://github.com/JVoiceXML/jlibrtp'
71 | }
72 | }
73 | }
74 | }
75 | repositories {
76 | maven {
77 | def releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
78 | def snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots/"
79 | url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
80 | credentials {
81 | username = JVOICEXML_OSSRH_USERNAME
82 | password = JVOICEXML_OSSRH_PASSWORD
83 | }
84 | }
85 | }
86 | }
87 |
88 | signing {
89 | sign publishing.publications.mavenJava
90 | }
91 |
92 | javadoc {
93 | if(JavaVersion.current().isJava9Compatible()) {
94 | options.addBooleanOption('html5', true)
95 | }
96 | }
97 |
98 |
--------------------------------------------------------------------------------
/org.jlibrtp/src/test/java/org/jlibrtp/test/TestRTPSession.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Java RTP Library (jlibrtp)
3 | * Copyright (C) 2006 Arne Kepp
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 | package org.jlibrtp.test;
20 | import java.net.DatagramSocket;
21 |
22 | import org.jlibrtp.DataFrame;
23 | import org.jlibrtp.Participant;
24 | import org.jlibrtp.RTPAppIntf;
25 | import org.jlibrtp.RTPSession;
26 |
27 | public class TestRTPSession implements RTPAppIntf {
28 | public RTPSession rtpSession = null;
29 |
30 | TestRTPSession() {
31 | DatagramSocket rtpSocket = null;
32 | DatagramSocket rtcpSocket = null;
33 |
34 | try {
35 | rtpSocket = new DatagramSocket(6002);
36 | rtcpSocket = new DatagramSocket(6003);
37 | } catch (Exception e) {
38 | System.out.println("RTPSession failed to obtain port");
39 | }
40 |
41 |
42 | rtpSession = new RTPSession(rtpSocket, rtcpSocket);
43 |
44 | rtpSession.registerRTPSession(this,null,null);
45 |
46 |
47 | Participant p = new Participant("127.0.0.1", 6004, 6005);
48 |
49 | rtpSession.addParticipant(p);
50 | }
51 |
52 |
53 | public void receiveData(DataFrame frame, Participant p) {
54 | String s = new String(frame.getConcatenatedData());
55 | System.out.println("The Data has been received: "+s+" , thank you "
56 | +p.getCNAME()+"("+p.getSSRC()+")");
57 | }
58 |
59 | public void userEvent(int type, Participant[] participant) {
60 | //Do nothing
61 | }
62 |
63 | public int frameSize(int payloadType) {
64 | return 1;
65 | }
66 |
67 | public static void main(String[] args) {
68 | TestRTPSession test = new TestRTPSession();
69 | //try { Thread.currentThread().sleep(10000); } catch (Exception e) { };
70 | long teststart = System.currentTimeMillis();
71 | String str = "abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd abce abcd ";
72 | byte[] data = str.getBytes();
73 | System.out.println(data.length);
74 |
75 | int i=0;
76 | while(i<100000) {
77 | test.rtpSession.sendData(data);
78 | //try { Thread.currentThread().sleep(500); } catch (Exception e) { };
79 | i++;
80 | }
81 |
82 | long testend = System.currentTimeMillis();
83 | //String str = "efgh";
84 |
85 | //test.rtpSession.sendData(str.getBytes());
86 |
87 | System.out.println("" + (testend - teststart));
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/org.jlibrtp/src/main/java/org/jlibrtp/RTCPAVPFIntf.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Java RTP Library (jlibrtp)
3 | * Copyright (C) 2006 Arne Kepp
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | package org.jlibrtp;
21 |
22 |
23 | /**
24 | * This is the callback interface for the AVPF profile (RFC 4585)
25 | *
26 | * It is optional, you do not have to register it.
27 | *
28 | * If there are specific events you wish to ignore,
29 | * you can simply implement empty functions.
30 | *
31 | * These are all syncrhonous, make sure to return quickly
32 | * or do the handling in a new thread.
33 | *
34 | * @author Arne Kepp
35 | */
36 | public interface RTCPAVPFIntf {
37 |
38 | /**
39 | * This function is called when a
40 | * Picture Loss Indication (PLI, FMT = 1) is received
41 | *
42 | * @param ssrcPacketSender the SSRC of the participant reporting loss of picture
43 | */
44 | public void PSFBPktPictureLossReceived(
45 | long ssrcPacketSender);
46 |
47 | /**
48 | * This function is called when a
49 | * Slice Loss Indication (SLI, FMT=2) is received
50 | *
51 | * @param ssrcPacketSender the SSRC of the participant reporting loss of slice(s)
52 | * @param sliceFirst macroblock address of first macroblock
53 | * @param sliceNumber number of lost macroblocks, in scan order
54 | * @param slicePictureId the six least significant bits of the picture identifier
55 | */
56 | public void PSFBPktSliceLossIndic(
57 | long ssrcPacketSender,
58 | int[] sliceFirst, int[] sliceNumber, int[] slicePictureId);
59 |
60 | /**
61 | * This function is called when a
62 | * Reference Picture Selection Indication (RPSI, FMT=3) is received
63 | *
64 | * @param ssrcPacketSender the SSRC of the participant reporting the selection
65 | * @param rpsiPayloadType the RTP payload type related to the RPSI bit string
66 | * @param rpsiBitString the RPSI information as natively defined by the video codec
67 | * @param rpsiPaddingBits the number of padding bits at the end of the string
68 | */
69 | public void PSFBPktRefPictureSelIndic(
70 | long ssrcPacketSender,
71 | int rpsiPayloadType, byte[] rpsiBitString, int rpsiPaddingBits);
72 |
73 | /**
74 | * This function is called when a
75 | * Transport Layer Feedback Messages is received
76 | *
77 | * @param ssrcPacketSender SSRC of the packet sender
78 | * @param alfBitString message
79 | */
80 | public void PSFBPktAppLayerFBReceived(
81 | long ssrcPacketSender,
82 | byte[] alfBitString);
83 |
84 | /**
85 | * This function is called when a
86 | * Transport Layer Feedback Messages is received
87 | *
88 | * @param ssrcPacketSender SSRC of packet sender
89 | * @param FMT 1: NACK, 0,2-30: unassigned, 31: reserved
90 | * @param packetID the RTP sequence number of the lost packet
91 | * @param bitmaskLostPackets the bitmask of following lost packets
92 | */
93 | public void RTPFBPktReceived(
94 | long ssrcPacketSender,
95 | int FMT, int[] packetID, int[] bitmaskLostPackets);
96 | }
97 |
--------------------------------------------------------------------------------
/org.jlibrtp/src/main/java/org/jlibrtp/RtcpPktAPP.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Java RTP Library (jlibrtp)
3 | * Copyright (C) 2006 Arne Kepp
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 | package org.jlibrtp;
20 |
21 | import java.util.logging.Level;
22 | import java.util.logging.Logger;
23 |
24 | /**
25 | * Application specific RTCP packets
26 | *
27 | * @author Arne Kepp
28 | */
29 | public class RtcpPktAPP extends RtcpPkt {
30 | /** Logger instance. */
31 | private static final Logger LOGGER =
32 | Logger.getLogger(RtcpPktAPP.class.getName());
33 |
34 | /** Name of packet, 4 bytes ASCII */
35 | protected byte[] pktName = null;
36 | /** Data of packet */
37 | protected byte[] pktData = null;
38 |
39 | /**
40 | * Constructor for a new Application RTCP packet
41 | *
42 | * @param ssrc the SSRC of the sender, presumably taken from RTPSession
43 | * @param subtype the subtype of packet, application specific
44 | * @param pktName byte[4] representing ASCII name of packet
45 | * @param pktData the byte[4x] data that represents the message itself
46 | */
47 | protected RtcpPktAPP(long ssrc, int subtype, byte[] pktName, byte[] pktData) {
48 | // Fetch all the right stuff from the database
49 | super.ssrc = ssrc;
50 | super.packetType = 204;
51 | super.itemCount = subtype;
52 | this.pktName = pktName;
53 | this.pktData = pktData;
54 | }
55 |
56 | /**
57 | * Constructor that parses a received Application RTCP packet
58 | *
59 | * @param aRawPkt the raw packet containing the date
60 | * @param start where in the raw packet this packet starts
61 | */
62 | protected RtcpPktAPP(byte[] aRawPkt, int start) {
63 | super.ssrc = StaticProcs.bytesToUIntLong(aRawPkt,4);
64 | super.rawPkt = aRawPkt;
65 |
66 | if(!super.parseHeaders(start) || packetType != 204 ) {
67 | if(LOGGER.isLoggable(Level.FINEST)) {
68 | LOGGER.finest(" <-> RtcpPktAPP.parseHeaders() etc. problem");
69 | }
70 | super.problem = -204;
71 | } else {
72 | //System.out.println("super.length: " + super.length);
73 | if(super.length > 1) {
74 | pktName = new byte[4];
75 | System.arraycopy(aRawPkt, 8, pktName, 0, 4);
76 | }
77 | if(super.length > 2) {
78 | pktData = new byte[(super.length+1)*4 - 12];
79 | System.arraycopy(aRawPkt, 12, pktData, 0, pktData.length);
80 | }
81 | }
82 | }
83 |
84 | /**
85 | * Encode the packet into a byte[], saved in .rawPkt
86 | *
87 | * CompRtcpPkt will call this automatically
88 | */
89 | protected void encode() {
90 | super.rawPkt = new byte[12 + this.pktData.length];
91 | byte[] tmp = StaticProcs.uIntLongToByteWord(super.ssrc);
92 | System.arraycopy(tmp, 0, super.rawPkt, 4, 4);
93 | System.arraycopy(this.pktName, 0, super.rawPkt, 8, 4);
94 | System.arraycopy(this.pktData, 0, super.rawPkt, 12, this.pktData.length);
95 | writeHeaders();
96 | //System.out.println("ENCODE: " + super.length + " " + rawPkt.length + " " + pktData.length);
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/org.jlibrtp.demo/src/main/java/org/jlibrtp/ValidatePktBuffer.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Java RTP Library (jlibrtp)
3 | * Copyright (C) 2006 Arne Kepp
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 | package org.jlibrtp;
20 |
21 | import java.net.DatagramSocket;
22 |
23 |
24 | /**
25 | * Validates the PktBuffer and associated classes.
26 | *
27 | * @author Arne Kepp
28 | *
29 | */
30 | public class ValidatePktBuffer {
31 |
32 | /**
33 | * Instantiates a buffer, creates some packets, adds them and sorts them.
34 | * @param args command line arguments
35 | */
36 | public static void main(String[] args) {
37 | // TODO Auto-generated method stub
38 | DatagramSocket rtpSocket = null;
39 | DatagramSocket rtcpSocket = null;
40 | try {
41 | rtpSocket = new DatagramSocket(6002);
42 | rtcpSocket = new DatagramSocket(6003);
43 | } catch (Exception e) {
44 | System.out.println("RTPSession failed to obtain port");
45 | }
46 | RTPSession rtpSession = new RTPSession(rtpSocket, rtcpSocket);
47 |
48 |
49 | String str1 = "ab";
50 | String str2 = "cd";
51 | String str3 = "ef";
52 | String str4 = "gh";
53 | String str5 = "ij";
54 | String str6 = "kl";
55 | //String str7 = "mn";
56 |
57 | long syncSource1 = 1;
58 | int seqNumber1 = 1;
59 | //int seqNumber2 = 1;
60 | RtpPkt pkt1 = new RtpPkt(10, syncSource1, 1, 0, str1.getBytes());
61 | RtpPkt pkt2 = new RtpPkt(20, syncSource1, 2, 0, str2.getBytes());
62 | RtpPkt pkt3 = new RtpPkt(30, syncSource1, 3, 0, str3.getBytes());
63 | RtpPkt pkt4 = new RtpPkt(40, syncSource1, 4, 0, str4.getBytes());
64 | RtpPkt pkt6 = new RtpPkt(60, syncSource1, 6, 0, str5.getBytes());
65 | RtpPkt pkt7 = new RtpPkt(70, syncSource1, 7, 0, str6.getBytes());
66 |
67 | Participant p = new Participant();
68 |
69 | PktBuffer pktBuf = new PktBuffer(rtpSession, p, pkt1);
70 | pktBuf.addPkt(pkt3); //2
71 | pktBuf.addPkt(pkt2); //3
72 | DataFrame aFrame = pktBuf.popOldestFrame();
73 | String outStr = new String(aFrame.getConcatenatedData());
74 | System.out.println("** 1 Data from first frame: " + outStr + ", should be ab");
75 | pktBuf.addPkt(pkt4); //3
76 | pktBuf.addPkt(pkt7); //4
77 | System.out.println("** 1.5 sixth");
78 | pktBuf.addPkt(pkt6); //5
79 | System.out.println("** 2 Duplicate, should be dropped");
80 | pktBuf.addPkt(pkt3); //5
81 | // Pop second frame
82 | aFrame = pktBuf.popOldestFrame(); //4
83 | outStr = new String(aFrame.getConcatenatedData());
84 | System.out.println("** 3 Data from second frame: " + outStr + ", should be cd");
85 |
86 | // Pop third frame
87 | aFrame = pktBuf.popOldestFrame(); //3
88 | outStr = new String(aFrame.getConcatenatedData());
89 | System.out.println("** 4 Data from third frame: " + outStr + ", should be ef");
90 | System.out.println("** 5 pktBuf.getLength is " + pktBuf.getLength() + ", should be 3");
91 |
92 | System.out.println("** 6 Late arrival, should be dropped");
93 | pktBuf.addPkt(pkt2);
94 |
95 | aFrame = pktBuf.popOldestFrame();
96 | outStr = new String(aFrame.getConcatenatedData());
97 | System.out.println("** 7 Data from fourth frame: " + outStr + ", should be gh");
98 |
99 | aFrame = pktBuf.popOldestFrame();
100 | outStr = new String(aFrame.getConcatenatedData());
101 | System.out.println("** 8 Data from fifth frame: " + outStr + ", should be ij");
102 |
103 | aFrame = pktBuf.popOldestFrame();
104 | outStr = new String(aFrame.getConcatenatedData());
105 | System.out.println("** 9 Data from fifth frame: " + outStr + ", should be kl");
106 | }
107 |
108 | }
109 |
--------------------------------------------------------------------------------
/org.jlibrtp.demo/src/main/java/org/jlibrtp/ValidateStaticProcs.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Java RTP Library (jlibrtp)
3 | * Copyright (C) 2006 Arne Kepp
4 | *
5 | * This library is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU Lesser General Public
7 | * License as published by the Free Software Foundation; either
8 | * version 2.1 of the License, or (at your option) any later version.
9 | *
10 | * This library is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | * Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public
16 | * License along with this library; if not, write to the Free Software
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 | package org.jlibrtp;
20 |
21 | /**
22 | * Validates the StaticProcs.
23 | *
24 | * @author Arne Kepp
25 | *
26 | */
27 | public class ValidateStaticProcs {
28 |
29 | /**
30 | * Main method.
31 | * @param args command line arguments
32 | */
33 | public static void main(String[] args) {
34 | // TODO Auto-generated method stub
35 | long one = 100;
36 | long two = 1;
37 | long three = 9999000;
38 |
39 | byte aByte = (byte) 7;
40 | System.out.println("aByte.hex: " + StaticProcs.hexOfByte(aByte));
41 |
42 | //byte[] oneb = StaticProcs.longToByteWord(one);
43 | byte[] twob = StaticProcs.uIntLongToByteWord(two);
44 | //byte[] threeb = StaticProcs.longToByteWord(three);
45 |
46 | for(int i = 0; i< 4; i++) {
47 | StaticProcs.printBits(twob[i]);
48 | }
49 | //one = StaticProcs.combineBytes(oneb[0], oneb[1], oneb[2], oneb[3]);
50 | two = StaticProcs.bytesToUIntLong(twob,0);
51 | //three = StaticProcs.combineBytes(threeb[0], threeb[1], threeb[2], threeb[3]);
52 |
53 | System.out.println(" one " + one + " two " + two + " three " + three);
54 |
55 | twob = StaticProcs.uIntLongToByteWord(two);
56 |
57 | for(int i = 0; i< 4; i++) {
58 | StaticProcs.printBits(twob[i]);
59 | }
60 |
61 | byte[] bytes = new byte[2];
62 | int check = 0;
63 | for(int i=0; i< 65536; i++) {
64 | bytes = StaticProcs.uIntIntToByteWord(i);
65 | check = StaticProcs.bytesToUIntInt(bytes, 0);
66 | if(check != i) {
67 | System.out.println(" oops:" + check +" != "+ i);
68 | StaticProcs.printBits(bytes[0]);
69 | StaticProcs.printBits(bytes[1]);
70 | }
71 | }
72 | int a = 65534;
73 | bytes = StaticProcs.uIntIntToByteWord(a);
74 | StaticProcs.printBits(bytes[0]);
75 | StaticProcs.printBits(bytes[1]);
76 | check = StaticProcs.bytesToUIntInt(bytes, 0);
77 | System.out.println(check);
78 |
79 | byte[] arbytes = new byte[22];
80 | arbytes[13] = -127;
81 | arbytes[14] = 127;
82 | arbytes[15] = -1;
83 | arbytes[16] = 127;
84 | arbytes[17] = -127;
85 | System.out.println("arbitrary length:");
86 | StaticProcs.printBits(arbytes[14]);
87 | StaticProcs.printBits(arbytes[15]);
88 | StaticProcs.printBits(arbytes[16]);
89 | //long arbTest = StaticProcs.bytesToUintLong(arbytes, 14, 16);
90 | //byte[] reArBytes = StaticProcs.uIntLongToByteWord(arbTest);
91 | //System.out.println("arbitrary length recode: " + Long.toString(arbTest));
92 | //StaticProcs.printBits(reArBytes[0]);
93 | //StaticProcs.printBits(reArBytes[1]);
94 | //StaticProcs.printBits(reArBytes[2]);
95 | //StaticProcs.printBits(reArBytes[3]);
96 |
97 | byte[] tmp = new byte[4];
98 | tmp[0] = -127;
99 | tmp[1] = 127;
100 | tmp[2] = -49;
101 | tmp[3] = -1;
102 |
103 | String str2 = "";
104 | for(int i=0; iDescription:
33 | * 34 | *Copyright: Copyright (c) 2007-2008
35 | * 36 | *Company: VoiceInteraction
37 | * 38 | * @author Renato Cassaca 39 | * @version 1.0 40 | */ 41 | public class TestRTPURLMultiSender { 42 | 43 | static { 44 | registerProtocolHandlers(); 45 | } 46 | 47 | private static void registerProtocolHandlers() { 48 | //Register protocol handler 49 | String javaPropName = "java.protocol.handler.pkgs"; 50 | 51 | //Start value 52 | System.out.println(javaPropName + " = " + 53 | System.getProperty(javaPropName)); 54 | 55 | //Vou actualizar a propriedade que define o meu protocol handler (URL) 56 | String packageName = "org.jlibrtp.protocols"; 57 | System.setProperty(javaPropName, packageName); 58 | 59 | //Value after update 60 | System.out.println(javaPropName + " = " + 61 | System.getProperty(javaPropName)); 62 | } 63 | 64 | 65 | public TestRTPURLMultiSender() { 66 | super(); 67 | } 68 | 69 | public static void main(String[] args) { 70 | 71 | TestRTPURLMultiSender testrtpurlmultisender = new TestRTPURLMultiSender(); 72 | testrtpurlmultisender.doIt(); 73 | } 74 | 75 | /** 76 | * doIt 77 | */ 78 | private void doIt() { 79 | try { 80 | // This block configure the logger with handler and formatter 81 | /* FileHandler fh = new FileHandler("Sender.log", false); 82 | Logger logger = Logger.getLogger("org.jlibrtp"); 83 | logger.addHandler(fh); 84 | logger.setLevel(Level.ALL); 85 | SimpleFormatter formatter = new SimpleFormatter(); 86 | fh.setFormatter(formatter);*/ 87 | 88 | long sTime = System.currentTimeMillis(); 89 | 90 | URL sendURL = new URL("rtp://172.16.4.42:29000/audio?participant=localhost:30000"); 91 | URLConnection sendC = sendURL.openConnection(); 92 | sendC.connect(); 93 | OutputStream rtpOS = sendC.getOutputStream(); 94 | 95 | for (int i = 0; i < 5; i++) { 96 | 97 | InputStream is = new FileInputStream("capture.raw"); 98 | 99 | byte[] buffer = new byte[1024]; 100 | int br; 101 | while ((br = is.read(buffer)) != -1) { 102 | rtpOS.write(buffer, 0, br); 103 | } 104 | 105 | is.close(); 106 | 107 | System.out.println("Will sleep before sending ith: " + (i+1)); 108 | try { 109 | Thread.sleep(5000); 110 | } catch (InterruptedException ex1) { 111 | } 112 | } 113 | 114 | rtpOS.flush(); 115 | rtpOS.close(); 116 | 117 | System.out.println("Finished Sender: " + (System.currentTimeMillis() - sTime) / 1000); 118 | 119 | } catch (Exception ex) { 120 | ex.printStackTrace(); 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /org.jlibrtp/src/test/java/org/jlibrtp/test/protocols/rtp/TestRTPURLSender.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java RTP Library (jlibrtp) 3 | * Copyright (C) 2006 Arne Kepp 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | package org.jlibrtp.test.protocols.rtp; 20 | 21 | import java.net.URL; 22 | import java.net.URLConnection; 23 | import java.io.FileInputStream; 24 | import java.io.OutputStream; 25 | import java.io.BufferedInputStream; 26 | import javax.sound.sampled.AudioInputStream; 27 | import javax.sound.sampled.AudioSystem; 28 | import java.util.logging.FileHandler; 29 | import java.util.logging.Logger; 30 | import java.util.logging.Level; 31 | import java.util.logging.SimpleFormatter; 32 | 33 | 34 | /** 35 | *Title: jlibrtp
36 | * 37 | *Description:
38 | * 39 | *Copyright: Copyright (c) 2007-2008
40 | * 41 | *Company: VoiceInteraction
42 | * 43 | * @author Renato Cassaca 44 | * @version 1.0 45 | */ 46 | public class TestRTPURLSender { 47 | 48 | static { 49 | registerProtocolHandlers(); 50 | } 51 | 52 | private static void registerProtocolHandlers() { 53 | //Register protocol handler 54 | String javaPropName = "java.protocol.handler.pkgs"; 55 | 56 | //Start value 57 | System.out.println(javaPropName + " = " + 58 | System.getProperty(javaPropName)); 59 | 60 | //Vou actualizar a propriedade que define o meu protocol handler (URL) 61 | String packageName = "org.jlibrtp.protocols"; 62 | System.setProperty(javaPropName, packageName); 63 | 64 | //Value after update 65 | System.out.println(javaPropName + " = " + 66 | System.getProperty(javaPropName)); 67 | } 68 | 69 | 70 | public TestRTPURLSender() { 71 | super(); 72 | } 73 | 74 | public static void main(String[] args) { 75 | 76 | TestRTPURLSender testrtpurlsender = new TestRTPURLSender(); 77 | testrtpurlsender.doIt(); 78 | } 79 | 80 | /** 81 | * doIt 82 | */ 83 | private void doIt() { 84 | try { 85 | // This block configure the logger with handler and formatter 86 | FileHandler fh = new FileHandler("Sender.log", false); 87 | Logger logger = Logger.getLogger("org.jlibrtp"); 88 | logger.addHandler(fh); 89 | logger.setLevel(Level.ALL); 90 | SimpleFormatter formatter = new SimpleFormatter(); 91 | fh.setFormatter(formatter); 92 | 93 | long sTime = System.currentTimeMillis(); 94 | 95 | URL sendURL = new URL("rtp://172.16.4.42:29000/audio?participant=localhost:30000&rate=8000"); 96 | URLConnection sendC = sendURL.openConnection(); 97 | sendC.connect(); 98 | OutputStream rtpOS = sendC.getOutputStream(); 99 | 100 | FileInputStream fis = new FileInputStream("capture.wav"); 101 | BufferedInputStream bis = new BufferedInputStream(fis); 102 | AudioInputStream is = AudioSystem.getAudioInputStream(bis); 103 | 104 | byte[] buffer = new byte[1024]; 105 | int br; 106 | while ((br = is.read(buffer)) != -1) { 107 | rtpOS.write(buffer, 0, br); 108 | } 109 | rtpOS.flush(); 110 | rtpOS.close(); 111 | 112 | System.out.println("Finished Sender: " + (System.currentTimeMillis() - sTime) / 1000); 113 | 114 | 115 | } catch (Exception ex) { 116 | ex.printStackTrace(); 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /org.jlibrtp.demo/src/main/java/org/jlibrtp/demo/UnicastExample.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java RTP Library (jlibrtp) 3 | * Copyright (C) 2006 Arne Kepp 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | package org.jlibrtp.demo; 20 | 21 | import java.net.DatagramSocket; 22 | 23 | import org.jlibrtp.DataFrame; 24 | import org.jlibrtp.Participant; 25 | import org.jlibrtp.RTPAppIntf; 26 | import org.jlibrtp.RTPSession; 27 | 28 | /** 29 | *This is an example of how to set up a Unicast session.
30 | *It does not accept any input arguments and is therefore of limited practical value, but it shows 31 | * the basics.
32 | * 33 | *The class has to implement RTPAppIntf.
34 | * @author Arne Kepp 35 | */ 36 | public class UnicastExample implements RTPAppIntf { 37 | /** Holds a RTPSession instance */ 38 | RTPSession rtpSession = null; 39 | 40 | /** 41 | * A minimal constructor 42 | * @param rtpSession the session 43 | */ 44 | public UnicastExample(RTPSession rtpSession) { 45 | this.rtpSession = rtpSession; 46 | } 47 | 48 | // RTPAppIntf All of the following are documented in the JavaDocs 49 | /** 50 | * Used to receive data from the RTP Library. We expect no data. 51 | * {@inheritDoc} 52 | */ 53 | public void receiveData(DataFrame frame, Participant p) { 54 | /** 55 | * This concatenates all received packets for a single timestamp 56 | * into a single byte[] 57 | */ 58 | byte[] data = frame.getConcatenatedData(); 59 | 60 | /** 61 | * This returns the CNAME, if any, associated with the SSRC 62 | * that was provided in the RTP packets received. 63 | */ 64 | String cname = p.getCNAME(); 65 | 66 | System.out.println("Received data from " + cname); 67 | System.out.println(new String(data)); 68 | } 69 | 70 | /** 71 | * Used to communicate updates to the user database through RTCP 72 | * {@inheritDoc} 73 | */ 74 | public void userEvent(int type, Participant[] participant) { 75 | //Do nothing 76 | } 77 | 78 | /** 79 | * How many packets make up a complete frame for the payload type? 80 | * {@inheritDoc} 81 | */ 82 | public int frameSize(int payloadType) { 83 | return 1; 84 | } 85 | // RTPAppIntf/ 86 | 87 | 88 | /** 89 | * Main method. 90 | * @param args command line parameters 91 | */ 92 | public static void main(String[] args) { 93 | // 1. Create sockets for the RTPSession 94 | DatagramSocket rtpSocket = null; 95 | DatagramSocket rtcpSocket = null; 96 | try { 97 | rtpSocket = new DatagramSocket(16384); 98 | rtcpSocket = new DatagramSocket(16385); 99 | } catch (Exception e) { 100 | System.out.println("RTPSession failed to obtain port"); 101 | } 102 | 103 | // 2. Create the RTP session 104 | RTPSession rtpSession = new RTPSession(rtpSocket, rtcpSocket); 105 | 106 | // 3. Instantiate the application object 107 | UnicastExample uex = new UnicastExample(rtpSession); 108 | 109 | // 4. Add participants we want to notify upon registration 110 | // a. Hopefully nobody is listening on this port. 111 | Participant part = new Participant("127.0.0.1",16386,16387); 112 | rtpSession.addParticipant(part); 113 | 114 | // 5. Register the callback interface, this launches RTCP threads too 115 | // The two null parameters are for the RTCP and debug interfaces, not use here 116 | rtpSession.registerRTPSession(uex, null, null); 117 | 118 | // Wait 2500 ms, because of the initial RTCP wait 119 | try{ Thread.sleep(2000); } catch(Exception e) {} 120 | 121 | // Note: The wait is optional, but insures SDES packets 122 | // receive participants before continuing 123 | 124 | // 6. Send some data 125 | String str = "Hi there!"; 126 | rtpSession.sendData(str.getBytes()); 127 | 128 | // 7. Terminate the session, takes a few ms to kill threads in order. 129 | rtpSession.endSession(); 130 | //This may result in "Sleep interrupted" messages, ignore them 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /org.jlibrtp/src/main/java/org/jlibrtp/AppCallerThread.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java RTP Library (jlibrtp) 3 | * Copyright (C) 2006 Arne Kepp 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | package org.jlibrtp; 20 | 21 | import java.util.Enumeration; 22 | import java.util.logging.Level; 23 | import java.util.logging.Logger; 24 | 25 | /** 26 | * The purpose of this thread is to check whether there are packets ready from 27 | * any participants. 28 | * 29 | * It should sleep when not in use, and be woken up by a condition variable. 30 | * 31 | * Optionally, if we do jitter-control, the condition variable should have a max waiting period 32 | * equal to how often we need to push data. 33 | * 34 | * @author Arne Kepp 35 | */ 36 | public class AppCallerThread extends Thread { 37 | /** Logger instance. */ 38 | private static final Logger LOGGER = 39 | Logger.getLogger(AppCallerThread.class.getName()); 40 | 41 | /** The parent RTP Session */ 42 | RTPSession rtpSession; 43 | /** The applications interface, where the callback methods are called */ 44 | RTPAppIntf appl; 45 | 46 | /** 47 | * Instantiates the AppCallerThread 48 | * 49 | * @param session the RTPSession with participants etc 50 | * @param rtpApp the interface to which data is given 51 | */ 52 | protected AppCallerThread(RTPSession session, RTPAppIntf rtpApp) { 53 | rtpSession = session; 54 | appl = rtpApp; 55 | if(LOGGER.isLoggable(Level.FINEST)) { 56 | LOGGER.finest("<-> AppCallerThread created"); 57 | } 58 | setName("AppCallerThread"); 59 | } 60 | 61 | /** 62 | * The AppCallerThread will run in this loop until the RTPSession 63 | * is terminated. 64 | * 65 | * Whenever an RTP packet is received it will loop over the 66 | * participants to check for packet buffers that have available 67 | * frame. 68 | */ 69 | public void run() { 70 | if(LOGGER.isLoggable(Level.FINER)) { 71 | LOGGER.finer("-> AppCallerThread.run()"); 72 | } 73 | 74 | while(rtpSession.endSession == false) { 75 | 76 | rtpSession.pktBufLock.lock(); 77 | try { 78 | if(LOGGER.isLoggable(Level.FINER)) { 79 | LOGGER.finer("<-> AppCallerThread going to Sleep"); 80 | } 81 | 82 | try { rtpSession.pktBufDataReady.await(); } 83 | catch (Exception e) { LOGGER.log(Level.WARNING, "AppCallerThread:" + e.getMessage(), e);} 84 | 85 | // Next loop over all participants and check whether they have anything for us. 86 | EnumerationDescription:
41 | * 42 | *Copyright: Copyright (c) 2007
43 | * 44 | *Company: VoiceInteraction
45 | * 46 | * @author Renato Cassaca 47 | * @version 1.0 48 | */ 49 | public class TestRTPURLReceiver { 50 | 51 | static { 52 | registerProtocolHandlers(); 53 | } 54 | 55 | private static void registerProtocolHandlers() { 56 | //Register protocol handler 57 | String javaPropName = "java.protocol.handler.pkgs"; 58 | 59 | //Start value 60 | System.out.println(javaPropName + " = " + System.getProperty(javaPropName)); 61 | 62 | //Vou actualizar a propriedade que define o meu protocol handler (URL) 63 | String packageName = "org.jlibrtp.protocols"; 64 | System.setProperty(javaPropName, packageName); 65 | 66 | //Value after update 67 | System.out.println(javaPropName + " = " + System.getProperty(javaPropName)); 68 | } 69 | 70 | 71 | public TestRTPURLReceiver() { 72 | super(); 73 | } 74 | 75 | public static void main(String[] args) { 76 | Logger.getLogger("").setLevel(Level.FINEST); 77 | TestRTPURLReceiver testrtpurlreceiver = new TestRTPURLReceiver(); 78 | testrtpurlreceiver.doIt(); 79 | } 80 | 81 | /** 82 | * doIt 83 | */ 84 | private void doIt() { 85 | try { 86 | // This block configure the logger with handler and formatter 87 | FileHandler fh = new FileHandler("Receiver.log", false); 88 | Logger logger = Logger.getLogger("org.jlibrtp"); 89 | logger.addHandler(fh); 90 | logger.setLevel(Level.ALL); 91 | SimpleFormatter formatter = new SimpleFormatter(); 92 | fh.setFormatter(formatter); 93 | 94 | 95 | AudioFormat receiveFormat = new AudioFormat(AudioFormat.Encoding.ULAW, 96 | 8000, 97 | 8, 98 | 1, 99 | 1, 100 | 8000, 101 | false); 102 | 103 | AudioFormat playFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 104 | 8000, 105 | 16, 106 | 1, 107 | 2, 108 | 8000, 109 | false); 110 | 111 | 112 | Info playbackLineInfo = new Info(SourceDataLine.class, playFormat, AudioSystem.NOT_SPECIFIED); 113 | SourceDataLine sourceLine = (SourceDataLine)AudioSystem.getLine(playbackLineInfo); 114 | System.out.println("Playing to: "+playbackLineInfo); 115 | sourceLine.open(); 116 | sourceLine.start(); 117 | 118 | 119 | URL recvURL = new URL("rtp://localhost:30000/audio?rate=8000&keepAlive=false"); 120 | URLConnection recvC = recvURL.openConnection(); 121 | recvC.connect(); 122 | InputStream rtpIS = recvC.getInputStream(); 123 | 124 | byte[] buffer = new byte[1024]; 125 | int br; 126 | OutputStream os = new FileOutputStream("rtp_received.raw"); 127 | 128 | AudioInputStream receiveStream = new AudioInputStream(rtpIS, receiveFormat, AudioSystem.NOT_SPECIFIED); 129 | AudioInputStream convStream = AudioSystem.getAudioInputStream(playFormat, receiveStream); 130 | 131 | while ((br = convStream.read(buffer)) != -1) { 132 | os.write(buffer, 0, br); 133 | sourceLine.write(buffer, 0, br); 134 | } 135 | 136 | os.close(); 137 | rtpIS.close(); 138 | convStream.close(); 139 | receiveStream.close(); 140 | 141 | System.out.println("Finished Receiver"); 142 | } catch (Exception ex) { 143 | ex.printStackTrace(); 144 | } 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /org.jlibrtp.demo/src/main/java/org/jlibrtp/ValidateRtcpPkt.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java RTP Library (jlibrtp) 3 | * Copyright (C) 2006 Arne Kepp 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | package org.jlibrtp; 20 | 21 | import java.net.DatagramSocket; 22 | import java.net.InetSocketAddress; 23 | import java.util.ListIterator; 24 | 25 | /** 26 | * Tests of {@link RtcpPkt}. 27 | * @author Arne Kepp 28 | * 29 | */ 30 | public class ValidateRtcpPkt { 31 | 32 | /** 33 | * Main method. 34 | * @param args command line arguments 35 | */ 36 | public static void main(String[] args) { 37 | DatagramSocket rtpSock = null; 38 | DatagramSocket rtcpSock = null; 39 | 40 | try { 41 | rtpSock = new DatagramSocket(1233); 42 | rtcpSock = new DatagramSocket(1234); 43 | } catch (Exception e) { 44 | //do nothing 45 | } 46 | RTPSession rtpSession = new RTPSession(rtpSock, rtcpSock); 47 | 48 | System.out.println("************************** SSRC: " + rtpSession.ssrc + " **************************"); 49 | ParticipantDatabase partDb = new ParticipantDatabase(rtpSession); 50 | //InetAddress test = InetAddress.getByName("127.0.0.1"); 51 | Participant part1 = new Participant("127.0.0.1",12, 34); 52 | Participant part2 = new Participant("127.0.0.2",56, 78); 53 | 54 | part1.ssrc = 123; 55 | part2.ssrc = 345; 56 | 57 | InetSocketAddress testadr = null; 58 | 59 | try { 60 | testadr = InetSocketAddress.createUnresolved("localhost", 12371); 61 | } catch (Exception e) { 62 | // Do nothing 63 | } 64 | 65 | part1.cname = "test3"; 66 | part2.cname = "test2"; 67 | part1.loc = "1231231231"; 68 | part2.loc = "Asker"; 69 | part1.phone = "+452 1231231"; 70 | part2.phone = "aasdasda.asdasdas"; 71 | part1.lastSeqNumber = 111; 72 | part2.lastSeqNumber = 222; 73 | part1.timeStampLSR = 111111; 74 | part2.timeStampLSR = 222222; 75 | partDb.addParticipant(0,part1); 76 | partDb.addParticipant(0,part2); 77 | 78 | Participant[] partArray = new Participant[2]; 79 | partArray[0] = part1; 80 | partArray[1] = part2; 81 | 82 | RtcpPktRR rrpkt = new RtcpPktRR(partArray,123456789); 83 | RtcpPktSR srpkt = new RtcpPktSR(rtpSession.ssrc,12,21,rrpkt); 84 | //RtcpPktSR srpkt2 = new RtcpPktSR(rtpSession.ssrc,12,21,null); 85 | //rrpkt = new RtcpPktRR(partArray,1234512311); 86 | 87 | //srpkt.debugPrint(); 88 | //rrpkt.debugPrint(); 89 | 90 | CompRtcpPkt compkt = new CompRtcpPkt(); 91 | compkt.addPacket(srpkt); 92 | compkt.addPacket(rrpkt); 93 | compkt.addPacket(rrpkt); 94 | 95 | byte[] test2 = compkt.encode(); 96 | //System.out.print(StaticProcs.bitsOfBytes(test)); 97 | System.out.println("****************************** DONE ENCODING *******************************"); 98 | CompRtcpPkt decomppkt = new CompRtcpPkt(test2,test2.length,testadr,rtpSession); 99 | System.out.println("****************************** DONE DECODING *******************************"); 100 | System.out.println("Problem code:" + decomppkt.problem); 101 | 102 | ListIterator iter = decomppkt.rtcpPkts.listIterator(); 103 | int i = 0; 104 | 105 | while(iter.hasNext()) { 106 | System.out.println(" i:" + i + " "); 107 | i++; 108 | 109 | Object aPkt = iter.next(); 110 | if( aPkt.getClass() == RtcpPktRR.class) { 111 | RtcpPktRR pkt = (RtcpPktRR) aPkt; 112 | pkt.debugPrint(); 113 | } else if(aPkt.getClass() == RtcpPktSR.class) { 114 | RtcpPktSR pkt = (RtcpPktSR) aPkt; 115 | pkt.debugPrint(); 116 | } 117 | } 118 | 119 | System.out.println("****************************** BYE *******************************"); 120 | long[] tempArray = {rtpSession.ssrc}; 121 | byte[] tempReason = "tas".getBytes(); 122 | RtcpPktBYE byepkt = new RtcpPktBYE(tempArray,tempReason); 123 | //byepkt.debugPrint(); 124 | byepkt.encode(); 125 | byte[] rawpktbye = byepkt.rawPkt; 126 | 127 | RtcpPktBYE byepkt2 = new RtcpPktBYE(rawpktbye,0); 128 | byepkt2.debugPrint(); 129 | 130 | System.out.println("****************************** SDES *******************************"); 131 | RtcpPktSDES sdespkt = new RtcpPktSDES(true,rtpSession,null); 132 | rtpSession.cname = "cname123@localhost"; 133 | //rtpSession.loc = "right here"; 134 | sdespkt.encode(); 135 | //rtpSession.cname = "cname124@localhost"; 136 | //rtpSession.loc = "right hera"; 137 | byte[] rawpktsdes = sdespkt.rawPkt; 138 | InetSocketAddress tmpAdr = (InetSocketAddress) rtpSock.getLocalSocketAddress(); 139 | RtcpPktSDES decsdespkt = new RtcpPktSDES(rawpktsdes, 0, (InetSocketAddress) rtpSock.getLocalSocketAddress() , partDb); 140 | decsdespkt.debugPrint(); 141 | //partDb.debugPrint(); 142 | 143 | CompRtcpPkt compkt2 = new CompRtcpPkt(); 144 | compkt2.addPacket(srpkt); 145 | compkt2.addPacket(sdespkt); 146 | byte[] compkt2Raw = compkt.encode(); 147 | 148 | CompRtcpPkt compkt3 = new CompRtcpPkt(compkt2Raw,compkt2Raw.length,tmpAdr,rtpSession); 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /org.jlibrtp/src/main/java/org/jlibrtp/RtcpPkt.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java RTP Library (jlibrtp) 3 | * Copyright (C) 2006 Arne Kepp 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | package org.jlibrtp; 20 | 21 | import java.net.InetAddress; 22 | import java.util.logging.Level; 23 | import java.util.logging.Logger; 24 | /** 25 | * Common RTCP packet headers. 26 | * 27 | * @author Arne Kepp 28 | */ 29 | public class RtcpPkt { 30 | /** Logger instance. */ 31 | private static final Logger LOGGER = 32 | Logger.getLogger(RtcpPkt.class.getName()); 33 | 34 | /** Whether a problem has been encountered during parsing */ 35 | protected int problem = 0; 36 | /** The version, always 2, 2 bits */ 37 | protected int version = 2; 38 | /** Padding , 1 bit */ 39 | protected int padding = 0; 40 | /** Number of items, e.g. receiver report blocks. Usage may vary. 5 bits */ 41 | protected int itemCount = 0; 42 | /** The type of RTCP packet, 8 bits */ 43 | protected int packetType = -1; 44 | /** The length of the RTCP packet, in 32 bit blocks minus 1. 16 bits*/ 45 | protected int length = -1; 46 | /** The ssrc that sent this, usually dictated by RTP Session */ 47 | protected long ssrc = -1; 48 | 49 | /** Contains the actual data (eventually) */ 50 | protected byte[] rawPkt = null; 51 | 52 | /** Only used for feedback messages: Time message was generated */ 53 | protected long time = -1; 54 | /** Only used for feedback message: Whether this packet was received */ 55 | protected boolean received = false; 56 | 57 | 58 | /** 59 | * Parses the common header of an RTCP packet 60 | * 61 | * @param start where in this.rawPkt the headers start 62 | * @return true if parsing succeeded and header cheks 63 | */ 64 | protected boolean parseHeaders(int start) { 65 | version = ((rawPkt[start+0] & 0xC0) >>> 6); 66 | padding = ((rawPkt[start+0] & 0x20) >>> 5); 67 | itemCount = (rawPkt[start+0] & 0x1F); 68 | packetType = (int) rawPkt[start+1]; 69 | if(packetType < 0) { 70 | packetType += 256; 71 | } 72 | length = StaticProcs.bytesToUIntInt(rawPkt, start+2); 73 | 74 | if(LOGGER.isLoggable(Level.FINEST)) { 75 | LOGGER.finest(" <-> RtcpPkt.parseHeaders() version:"+version+" padding:"+padding+" itemCount:"+itemCount 76 | +" packetType:"+packetType+" length:"+length); 77 | } 78 | 79 | if(packetType > 207 || packetType < 200) 80 | LOGGER.warning("RtcpPkt.parseHeaders problem discovered, packetType " + packetType); 81 | 82 | if(version == 2 && length < 65536) { 83 | return true; 84 | } else { 85 | LOGGER.warning("RtcpPkt.parseHeaders() failed header checks, check size and version"); 86 | this.problem = -1; 87 | return false; 88 | } 89 | } 90 | /** 91 | * Writes the common header of RTCP packets. 92 | * The values should be filled in when the packet is initiliazed and this function 93 | * called at the very end of .encode() 94 | */ 95 | protected void writeHeaders() { 96 | byte aByte = 0; 97 | aByte |=(version << 6); 98 | aByte |=(padding << 5); 99 | aByte |=(itemCount); 100 | rawPkt[0] = aByte; 101 | aByte = 0; 102 | aByte |= packetType; 103 | rawPkt[1] = aByte; 104 | if(rawPkt.length % 4 != 0) 105 | LOGGER.warning("!!!! RtcpPkt.writeHeaders() rawPkt was not a multiple of 32 bits / 4 octets!"); 106 | byte[] someBytes = StaticProcs.uIntIntToByteWord((rawPkt.length / 4) - 1); 107 | rawPkt[2] = someBytes[0]; 108 | rawPkt[3] = someBytes[1]; 109 | } 110 | 111 | /** 112 | * This is just a dummy to make Eclipse complain less. 113 | */ 114 | protected void encode() { 115 | LOGGER.warning("RtcpPkt.encode() should never be invoked!! " + this.packetType); 116 | } 117 | 118 | /** 119 | * Check whether this packet came from the source we expected. 120 | * 121 | * Not currently used! 122 | * 123 | * @param adr address that packet came from 124 | * @param partDb the participant database for the session 125 | * @return true if this packet came from the expected source 126 | */ 127 | protected boolean check(InetAddress adr, ParticipantDatabase partDb) { 128 | //Multicast -> We have to be naive 129 | if (partDb.rtpSession.mcSession && adr.equals(partDb.rtpSession.mcGroup)) 130 | return true; 131 | 132 | //See whether this participant is known 133 | Participant part = partDb.getParticipant(this.ssrc); 134 | if(part != null && part.rtcpAddress.getAddress().equals(adr)) 135 | return true; 136 | 137 | //If not, we should look for someone without SSRC with his ip-address? 138 | return false; 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /org.jlibrtp.demo/src/main/java/org/jlibrtp/demo/SoundReceiverDemo.java: -------------------------------------------------------------------------------- 1 | /* This file is based on 2 | * http://www.anyexample.com/programming/java/java_play_wav_sound_file.xml 3 | * 4 | * Java RTP Library (jlibrtp) 5 | * Copyright (C) 2006 Arne Kepp 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2.1 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with this library; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | package org.jlibrtp.demo; 23 | 24 | import java.net.DatagramSocket; 25 | 26 | import javax.sound.sampled.AudioFormat; 27 | import javax.sound.sampled.AudioSystem; 28 | import javax.sound.sampled.DataLine; 29 | import javax.sound.sampled.FloatControl; 30 | import javax.sound.sampled.LineUnavailableException; 31 | import javax.sound.sampled.SourceDataLine; 32 | 33 | import org.jlibrtp.DataFrame; 34 | import org.jlibrtp.Participant; 35 | import org.jlibrtp.RTPAppIntf; 36 | import org.jlibrtp.RTPSession; 37 | 38 | /** 39 | * @author Arne Kepp 40 | */ 41 | public class SoundReceiverDemo implements RTPAppIntf { 42 | //test 43 | RTPSession rtpSession = null; 44 | private Position curPosition; 45 | byte[] abData = null; 46 | int nBytesRead = 0; 47 | int pktCount = 0; 48 | int dataCount = 0; 49 | int offsetCount = 0; 50 | SourceDataLine auline; 51 | 52 | enum Position { 53 | LEFT, RIGHT, NORMAL 54 | }; 55 | 56 | public void receiveData(DataFrame frame, Participant p) { 57 | if(auline != null) { 58 | byte[] data = frame.getConcatenatedData(); 59 | auline.write(data, 0, data.length); 60 | 61 | //dataCount += data.length; 62 | //if(pktCount % 10 == 0) { 63 | // System.out.println("pktCount:" + pktCount + " dataCount:" + dataCount); 64 | // long test = 0; 65 | // for(int i=0; iTitle: RTPOutputStream
30 | * 31 | *Description: Output stream that sends the audio in "real time"
32 | * 33 | *Copyright: Copyright (c) 2008
34 | * 35 | *Company: www.VoiceInteraction.pt
36 | * 37 | * @author Renato Cassaca 38 | * @version 1.0 39 | */ 40 | public class RTPOutputStream extends OutputStream { 41 | /** Logger instance. */ 42 | private static final Logger LOGGER = 43 | Logger.getLogger(RTPOutputStream.class.getName()); 44 | 45 | //RTPSession 46 | private final RTPSession rtpSession; 47 | 48 | //Number of RTP packets that should be sent per second 49 | private final long packetSize; 50 | 51 | //The time in seconds of each frame contents 52 | private final double packetDuration; 53 | 54 | //Buffer that will store bytes to send 55 | private final CircularByteBuffer circularByteBuffer; 56 | 57 | //The next packet timestamp 58 | private long pktTmestamp; 59 | 60 | //Buffer that hols temporary read data 61 | private final byte[] buffer; 62 | 63 | /** 64 | * Constructor 65 | * Given a RTPSession builds an OutputStream to it 66 | * 67 | * @param rtpSession RTPSession 68 | * @param bytesPerSecond long 69 | * @param packetsPerSecond int 70 | */ 71 | public RTPOutputStream(RTPSession rtpSession, long bytesPerSecond, 72 | int packetsPerSecond) { 73 | this.rtpSession = rtpSession; 74 | 75 | packetSize = bytesPerSecond / packetsPerSecond; 76 | packetDuration = 1000f * ((double) packetSize / (double) bytesPerSecond); 77 | pktTmestamp = -1; 78 | buffer = new byte[(int) packetSize]; 79 | 80 | circularByteBuffer = new CircularByteBuffer(buffer.length); 81 | } 82 | 83 | public void write(int b) throws IOException { 84 | circularByteBuffer.getOutputStream().write(b); 85 | 86 | drain(); 87 | } 88 | 89 | public void write(byte b[], int off, int len) throws IOException { 90 | circularByteBuffer.getOutputStream().write(b, off, len); 91 | 92 | drain(); 93 | } 94 | 95 | private void drain() throws IOException { 96 | while (circularByteBuffer.getInputStream().available() >= packetSize) { 97 | sendData(); 98 | } 99 | } 100 | 101 | public void flush() throws IOException { 102 | drain(); 103 | 104 | //Make sure that buffer is empty 105 | if (circularByteBuffer.getInputStream().available() > 0) { 106 | circularByteBuffer.clear(); 107 | } 108 | 109 | pktTmestamp = -1; 110 | } 111 | 112 | public void close() throws IOException { 113 | if (LOGGER.isLoggable(Level.FINE)) { 114 | LOGGER.fine("RTPOutputStream.close() called"); 115 | } 116 | circularByteBuffer.getOutputStream().close(); 117 | circularByteBuffer.getInputStream().close(); 118 | rtpSession.endSession(); 119 | if (LOGGER.isLoggable(Level.FINE)) { 120 | LOGGER.fine("RTPOutputStream.close() done! (rtpEndSession)"); 121 | } 122 | pktTmestamp = -1; 123 | } 124 | 125 | /** 126 | * Send data to RTP session 127 | * 128 | * @todo Should reset timestamp if current time has long passed 129 | */ 130 | private void sendData() throws IOException { 131 | 132 | //Initialize timestamp 133 | if (pktTmestamp < 0) { 134 | pktTmestamp = (long) (System.nanoTime() * 1E-6); 135 | } 136 | 137 | //Fill buffer to send 138 | int bytesRead = circularByteBuffer.getInputStream().read(buffer); 139 | if (bytesRead != packetSize) { 140 | if (bytesRead < 0) { 141 | //ENDED?? 142 | LOGGER.info("bytesRead != packetSize... @ RTPOutputStream"); 143 | } 144 | } 145 | 146 | //Send data 147 | byte[][] pkt = {buffer}; 148 | rtpSession.sendData(pkt, null, null, pktTmestamp, null); 149 | 150 | //Try to keep send rate as "real time" as possible... 151 | long sleepTime = pktTmestamp - (long) (System.nanoTime() * 1E-6); 152 | while (sleepTime > 0) { 153 | try { 154 | Thread.sleep(0, 999999); 155 | sleepTime--; 156 | } catch (InterruptedException ex) { 157 | if (LOGGER.isLoggable(Level.FINE)) { 158 | LOGGER.fine(ex.getLocalizedMessage()); 159 | } 160 | return; 161 | } 162 | } 163 | 164 | //Update timestamp 165 | pktTmestamp += packetDuration; 166 | } 167 | 168 | } 169 | -------------------------------------------------------------------------------- /org.jlibrtp/src/main/java/org/jlibrtp/RtcpPktRTPFB.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java RTP Library (jlibrtp) 3 | * Copyright (C) 2006 Arne Kepp 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | package org.jlibrtp; 20 | 21 | import java.util.logging.Level; 22 | import java.util.logging.Logger; 23 | 24 | /** 25 | * RTCP packets for RTP Feedback Messages 26 | * 27 | * In line with RFC 4585, this packet currently only supports NACKs 28 | * 29 | * @author Arne Kepp 30 | */ 31 | public class RtcpPktRTPFB extends RtcpPkt { 32 | /** Logger instance. */ 33 | private static final Logger LOGGER = 34 | Logger.getLogger(RtcpPktRTPFB.class.getName()); 35 | 36 | /** If this packet was for a different SSRC */ 37 | protected boolean notRelevant = false; 38 | /** SSRC we are sending feeback to */ 39 | protected long ssrcMediaSource = -1; 40 | /** RTP sequence numbers of lost packets */ 41 | protected int PID[]; 42 | /** bitmask of following lost packets, shared index with PID */ 43 | protected int BLP[]; 44 | 45 | /** 46 | * Constructor for RTP Feedback Message 47 | * 48 | * @param ssrcPacketSender SSRC of sender, taken from RTPSession 49 | * @param ssrcMediaSource SSRC of recipient of this message 50 | * @param FMT the Feedback Message Subtype 51 | * @param PID RTP sequence numbers of lost packets 52 | * @param BLP bitmask of following lost packets, shared index with PID 53 | */ 54 | protected RtcpPktRTPFB(long ssrcPacketSender, long ssrcMediaSource, int FMT, int[] PID, int[] BLP) { 55 | super.packetType = 205; //RTPFB 56 | super.itemCount = FMT; 57 | this.PID = PID; 58 | this.BLP = BLP; 59 | } 60 | 61 | /** 62 | * Constructor that parses a raw packet to retrieve information 63 | * 64 | * @param aRawPkt the raw packet to be parsed 65 | * @param start the start of the packet, in bytes 66 | * @param rtpSession the session on which the callback interface resides 67 | */ 68 | protected RtcpPktRTPFB(byte[] aRawPkt, int start, RTPSession rtpSession) { 69 | if(LOGGER.isLoggable(Level.FINEST)) { 70 | LOGGER.finest(" -> RtcpPktRTPFB(byte[], int start)"); 71 | } 72 | 73 | rawPkt = aRawPkt; 74 | 75 | if(! super.parseHeaders(start) || packetType != 205 || super.length < 2) { 76 | if(LOGGER.isLoggable(Level.FINEST)) { 77 | LOGGER.finest(" <-> RtcpPktRTPFB.parseHeaders() etc. problem"); 78 | } 79 | super.problem = -205; 80 | } else { 81 | //FMT = super.itemCount; 82 | 83 | ssrcMediaSource = StaticProcs.bytesToUIntLong(aRawPkt,8+start); 84 | 85 | if(ssrcMediaSource == rtpSession.ssrc) { 86 | super.ssrc = StaticProcs.bytesToUIntLong(aRawPkt,4+start); 87 | int loopStop = super.length - 2; 88 | PID = new int[loopStop]; 89 | BLP = new int[loopStop]; 90 | int curStart = 12; 91 | 92 | // Loop over Feedback Control Information (FCI) fields 93 | for(int i=0; i< loopStop; i++) { 94 | PID[i] = StaticProcs.bytesToUIntInt(aRawPkt, curStart); 95 | BLP[i] = StaticProcs.bytesToUIntInt(aRawPkt, curStart + 2); 96 | curStart += 4; 97 | } 98 | 99 | rtpSession.rtcpAVPFIntf.RTPFBPktReceived( 100 | super.ssrc, super.itemCount, PID, BLP); 101 | } 102 | } 103 | 104 | 105 | 106 | if(LOGGER.isLoggable(Level.FINEST)) { 107 | LOGGER.finest(" <- RtcpPktRTPFB()"); 108 | } 109 | } 110 | 111 | /** 112 | * Encode the packet into a byte[], saved in .rawPkt 113 | * 114 | * CompRtcpPkt will call this automatically 115 | */ 116 | protected void encode() { 117 | super.rawPkt = new byte[12 + this.PID.length*4]; 118 | 119 | byte[] someBytes = StaticProcs.uIntLongToByteWord(super.ssrc); 120 | System.arraycopy(someBytes, 0, super.rawPkt, 4, 4); 121 | someBytes = StaticProcs.uIntLongToByteWord(this.ssrcMediaSource); 122 | System.arraycopy(someBytes, 0, super.rawPkt, 8, 4); 123 | 124 | // Loop over Feedback Control Information (FCI) fields 125 | int curStart = 12; 126 | for(int i=0; i < this.PID.length; i++ ) { 127 | someBytes = StaticProcs.uIntIntToByteWord(PID[i]); 128 | super.rawPkt[curStart++] = someBytes[0]; 129 | super.rawPkt[curStart++] = someBytes[1]; 130 | someBytes = StaticProcs.uIntIntToByteWord(BLP[i]); 131 | super.rawPkt[curStart++] = someBytes[0]; 132 | super.rawPkt[curStart++] = someBytes[1]; 133 | } 134 | writeHeaders(); 135 | } 136 | 137 | /** 138 | * Get the FMT (Feedback Message Type) 139 | * @return value stored in .itemcount, same field 140 | */ 141 | protected int getFMT() { 142 | return this.itemCount; 143 | } 144 | 145 | /** 146 | * Debug purposes only 147 | */ 148 | protected void debugPrint() { 149 | LOGGER.finest("->RtcpPktRTPFB.debugPrint() "); 150 | LOGGER.finest(" ssrcPacketSender: " + super.ssrc + " ssrcMediaSource: " + ssrcMediaSource); 151 | 152 | if(this.PID != null && this.PID.length < 1) { 153 | LOGGER.finest(" No Feedback Control Information (FCI) fields"); 154 | } 155 | 156 | for(int i=0; i < this.PID.length; i++ ) { 157 | LOGGER.finest(" FCI -> PID: " + PID[i] + " BLP: " + BLP[i]); 158 | } 159 | LOGGER.finest("<-RtcpPktRTPFB.debugPrint() "); 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /org.jlibrtp/src/main/java/org/jlibrtp/protocols/rtp/CircularByteBuffer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java RTP Library (jlibrtp) 3 | * Copyright (C) 2009 Arne Kepp 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | package org.jlibrtp.protocols.rtp; 20 | 21 | import java.io.IOException; 22 | import java.io.InputStream; 23 | import java.io.OutputStream; 24 | 25 | public class CircularByteBuffer { 26 | private int readOfs = 0; 27 | 28 | private int writeOfs = 0; 29 | 30 | private int initialSize; 31 | 32 | private CircularByteBufferInputStream is; 33 | 34 | private CircularByteBufferOutputStream os; 35 | 36 | private byte[] buf; 37 | 38 | public CircularByteBuffer(int initialSize) { 39 | buf = new byte[initialSize]; 40 | this.initialSize = initialSize; 41 | is = new CircularByteBufferInputStream(this); 42 | os = new CircularByteBufferOutputStream(this); 43 | } 44 | 45 | private synchronized int bytesLeft() { 46 | return buf.length - bytesUsed(); 47 | } 48 | 49 | private synchronized int bytesUsed() { 50 | if(readOfs == writeOfs) 51 | return 0; 52 | 53 | if(readOfs < writeOfs) 54 | return writeOfs - readOfs; 55 | 56 | return buf.length - (writeOfs - readOfs); 57 | } 58 | 59 | private void doubleBuf() { 60 | byte[] oldBuf = buf; 61 | buf = new byte[oldBuf.length*2]; 62 | 63 | System.arraycopy(oldBuf, 0, buf, 0, oldBuf.length); 64 | } 65 | 66 | private synchronized void write(byte[] data, int offset, int length) { 67 | while(length > bytesLeft()) { 68 | doubleBuf(); 69 | } 70 | 71 | if(writeOfs + length > buf.length) { 72 | int endLength = buf.length - this.writeOfs; 73 | 74 | System.arraycopy(data, 0, buf, writeOfs, endLength); 75 | 76 | writeOfs = 0; 77 | length = length - endLength; 78 | offset = endLength + offset; 79 | } 80 | 81 | System.arraycopy(data, offset, buf, writeOfs, length); 82 | 83 | writeOfs += length; 84 | } 85 | 86 | private synchronized int read(byte[] buffer, int offset, int length) { 87 | int maxLeft= this.bytesUsed(); 88 | int bytesLeft = length; 89 | 90 | if(maxLeft < bytesLeft) { 91 | bytesLeft = maxLeft; 92 | length = maxLeft; 93 | } 94 | 95 | if(readOfs + length > buf.length) { 96 | int endLength = buf.length - readOfs; 97 | 98 | System.arraycopy(buf, readOfs, buffer, offset, endLength); 99 | 100 | readOfs = 0; 101 | bytesLeft = bytesLeft - endLength; 102 | offset = offset + endLength; 103 | } 104 | 105 | System.arraycopy(buf, readOfs, buffer, offset, bytesLeft); 106 | 107 | readOfs += bytesLeft; 108 | 109 | return length; 110 | } 111 | 112 | public synchronized void clear() { 113 | readOfs = 0; 114 | writeOfs = 0; 115 | buf = new byte[this.initialSize]; 116 | } 117 | 118 | public String debugPrintFunction() { 119 | return this.buf.length + " " + readOfs + " " + writeOfs + " " + this.bytesLeft() + " " + this.bytesUsed(); 120 | } 121 | 122 | public String debugPrintData() { 123 | String str = ""; 124 | for(int i=0; iIt does not accept any input arguments and is therefore of limited practical value, but it shows 31 | * the basics.
32 | * 33 | *The class has to implement RTPAppIntf.
34 | * @author Arne Kepp 35 | */ 36 | public class UnicastExample2 implements RTPAppIntf { 37 | /** The tests included in this file */ 38 | static boolean jing = false; 39 | static boolean abhijeet = true; 40 | static long byteCounter = 0; 41 | static long pktCounter = 0; 42 | 43 | /** Holds a RTPSession instance */ 44 | RTPSession rtpSession = null; 45 | 46 | 47 | /** 48 | * A minimal constructor. 49 | * @param rtpSession the RTP session 50 | */ 51 | public UnicastExample2(RTPSession rtpSession) { 52 | this.rtpSession = rtpSession; 53 | } 54 | 55 | // RTPAppIntf All of the following are documented in the JavaDocs 56 | /** 57 | * Used to receive data from the RTP Library. We expect no data. 58 | * {@inheritDoc} 59 | */ 60 | public void receiveData(DataFrame frame, Participant p) { 61 | /** 62 | * This concatenates all received packets for a single timestamp 63 | * into a single byte[] 64 | */ 65 | byte[] data = frame.getConcatenatedData(); 66 | byteCounter += data.length; 67 | pktCounter++; 68 | 69 | if(pktCounter%100 == 0) { 70 | System.out.print("."); 71 | } 72 | 73 | //String cname = p.getCNAME(); 74 | //if(! abhijeet) { 75 | // System.out.println("Received data from " + cname); 76 | // System.out.println(new String(data)); 77 | //} 78 | } 79 | 80 | /** 81 | * Used to communicate updates to the user database through RTCP. 82 | * {@inheritDoc} 83 | */ 84 | public void userEvent(int type, Participant[] participant) { 85 | //Do nothing 86 | } 87 | 88 | /** 89 | * How many packets make up a complete frame for the payload type? 90 | * {@inheritDoc} 91 | */ 92 | public int frameSize(int payloadType) { 93 | return 1; 94 | } 95 | // RTPAppIntf/ 96 | 97 | 98 | /** 99 | * Main method. 100 | * @param args command line parameters 101 | */ 102 | public static void main(String[] args) { 103 | // 1. Create sockets for the RTPSession 104 | DatagramSocket rtpSocket = null; 105 | DatagramSocket rtcpSocket = null; 106 | 107 | if(jing) { 108 | System.out.println("Running test case for Jing"); 109 | } else if(abhijeet) { 110 | System.out.println("Running test case for Abhijeet"); 111 | } else { 112 | System.out.println("Enable one of the test cases in the source code first."); 113 | return; 114 | } 115 | 116 | int portnum = 0; 117 | if(args.length != 1) { 118 | System.out.println("Please specify 1 or 2, denoting the participant."); 119 | return; 120 | } else { 121 | if(args[0].equals("1")) { 122 | portnum = 16384; 123 | } else if(args[0].equals("2")) { 124 | portnum = 16386; 125 | } else { 126 | System.out.println("Unknown argument"); 127 | return; 128 | } 129 | } 130 | System.out.println("Participant "+args[0]+", binding to "+portnum+","+(portnum+1)); 131 | 132 | try { 133 | rtpSocket = new DatagramSocket(portnum); 134 | rtcpSocket = new DatagramSocket(portnum + 1); 135 | } catch (Exception e) { 136 | System.out.println("RTPSession failed to obtain port"); 137 | } 138 | 139 | // 2. Create the RTP session 140 | RTPSession rtpSession = new RTPSession(rtpSocket, rtcpSocket); 141 | //rtpSession.naivePktReception(true); 142 | 143 | System.out.println("My CNAME:" + rtpSession.CNAME()); 144 | 145 | // 3. Instantiate the application object 146 | UnicastExample2 uex = new UnicastExample2(rtpSession); 147 | 148 | // 4. Add participants we want to notify upon registration 149 | // a. Hopefully nobody is listening on this port. 150 | if(portnum == 16386) 151 | portnum = 16382; 152 | 153 | Participant part = new Participant("127.0.0.1", portnum+2, portnum+3); 154 | System.out.println("Will send stuff to "+(portnum+2)+","+(portnum+3)); 155 | rtpSession.addParticipant(part); 156 | 157 | // 5. Register the callback interface, this launches RTCP threads too 158 | // The two null parameters are for the RTCP and debug interfaces, not use here 159 | rtpSession.registerRTPSession(uex, null, null); 160 | 161 | // Wait 2500 ms, because of the initial RTCP wait 162 | try{ Thread.sleep(5000); } catch(Exception e) {} 163 | 164 | // Note: The wait is optional, but insures SDES packets 165 | // receive participants before continuing 166 | 167 | // 6. Send some data 168 | if(args[0].equals("1")) { 169 | System.out.print("Sending data"); 170 | } else { 171 | System.out.print("Receiving data"); 172 | } 173 | if(jing) { 174 | // RTCP SR, RR test for Jing... so we send a little data, and spend a long 175 | // time doing it to collect some reports 176 | byte[] tmp = new byte[10]; 177 | int i; 178 | 179 | for(i=0; i < 60; i++) { 180 | try{ Thread.sleep(200); } catch(Exception e) {} 181 | 182 | if(args[0].equals("1")) 183 | rtpSession.sendData(tmp); 184 | 185 | if(i%10 == 0) 186 | System.out.print("."); 187 | } 188 | 189 | if(args[0].equals("1")) 190 | System.out.println("Done, sent " + (i*10) + " bytes "); 191 | 192 | } else if(abhijeet) { 193 | // Test for abhijeet 194 | 195 | // The question was whether jlibrtp has a problem if you send 4 Mbyte+? 196 | // Could also be related to number of packets, but there are 197 | // current no known bugs in that category either. 198 | 199 | byte[] tmp = new byte[1024]; 200 | int i; 201 | 202 | for(i=0; i < 4000; i++) { 203 | try{ Thread.sleep(5); } catch(Exception e) {} 204 | 205 | if(args[0].equals("1")) { 206 | rtpSession.sendData(tmp); 207 | 208 | if(i%100 == 0) 209 | System.out.print("."); 210 | } 211 | } 212 | 213 | if(args[0].equals("1")) 214 | System.out.println("Done sent, sent " + i + " kbytes "); 215 | } 216 | 217 | // Give the sending threads etc a chance to complete. 218 | try{ Thread.sleep(1000); } catch(Exception e) {} 219 | System.out.println("Received " + byteCounter +" bytes"); 220 | // 7. Terminate the session, takes a few ms to kill threads in order. 221 | rtpSession.endSession(); 222 | //This may result in "Sleep interrupted" messages, ignore them 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /org.jlibrtp/src/main/java/org/jlibrtp/RtcpPktSR.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java RTP Library (jlibrtp) 3 | * Copyright (C) 2006 Arne Kepp 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | package org.jlibrtp; 20 | 21 | import java.util.logging.Level; 22 | import java.util.logging.Logger; 23 | 24 | /** 25 | * RTCP packets for Sender Reports 26 | * 27 | * @author Arne Kepp 28 | */ 29 | public class RtcpPktSR extends RtcpPkt { 30 | /** Logger instance. */ 31 | private static final Logger LOGGER = 32 | Logger.getLogger(RtcpPktSR.class.getName()); 33 | 34 | /** NTP timestamp, MSB */ 35 | protected long ntpTs1 = -1; //32 bits 36 | /** NTP timestamp, LSB */ 37 | protected long ntpTs2 = -1; //32 bits 38 | /** RTP timestamp */ 39 | protected long rtpTs = -1; //32 bits 40 | /** Senders packet count */ 41 | protected long sendersPktCount = -1; //32 bits 42 | /** Senders octet count */ 43 | protected long sendersOctCount = -1; //32 bits 44 | /** RR packet with receiver reports that we can append */ 45 | protected RtcpPktRR rReports = null; 46 | 47 | /** 48 | * Constructor for a new Sender Report packet 49 | * 50 | * @param ssrc the senders SSRC, presumably from RTPSession 51 | * @param pktCount packets sent in this session 52 | * @param octCount octets sent in this session 53 | * @param rReports receiver reports, as RR packets, to be included in this packet 54 | */ 55 | protected RtcpPktSR(long ssrc, long pktCount, long octCount, RtcpPktRR rReports) { 56 | // Fetch all the right stuff from the database 57 | super.ssrc = ssrc; 58 | super.packetType = 200; 59 | sendersPktCount = pktCount; 60 | sendersOctCount = octCount; 61 | this.rReports = rReports; 62 | } 63 | 64 | /** 65 | * Constructor that parses a received packet 66 | * 67 | * @param aRawPkt the raw packet 68 | * @param start the position at which SR starts 69 | * @param length used to determine number of included receiver reports 70 | */ 71 | protected RtcpPktSR(byte[] aRawPkt, int start, int length) { 72 | if(LOGGER.isLoggable(Level.FINEST)) { 73 | LOGGER.finest(" -> RtcpPktSR(rawPkt)"); 74 | } 75 | 76 | super.rawPkt = aRawPkt; 77 | 78 | if(!super.parseHeaders(start) || packetType != 200 ) { 79 | if(LOGGER.isLoggable(Level.FINEST)) { 80 | LOGGER.finest(" <-> RtcpPktSR.parseHeaders() etc. problem: "+ (!super.parseHeaders(start) ) + " " + packetType + " " + super.length); 81 | } 82 | super.problem = -200; 83 | } else { 84 | super.ssrc = StaticProcs.bytesToUIntLong(aRawPkt,4+start); 85 | if(length > 11) 86 | ntpTs1 = StaticProcs.bytesToUIntLong(aRawPkt,8+start); 87 | if(length > 15) 88 | ntpTs2 = StaticProcs.bytesToUIntLong(aRawPkt,12+start); 89 | if(length > 19) 90 | rtpTs = StaticProcs.bytesToUIntLong(aRawPkt,16+start); 91 | if(length > 23) 92 | sendersPktCount = StaticProcs.bytesToUIntLong(aRawPkt,20+start); 93 | if(length > 27) 94 | sendersOctCount = StaticProcs.bytesToUIntLong(aRawPkt,24+start); 95 | 96 | // RRs attached? 97 | if(itemCount > 0) { 98 | rReports = new RtcpPktRR(rawPkt,start,itemCount); 99 | } 100 | } 101 | 102 | if(LOGGER.isLoggable(Level.FINEST)) { 103 | LOGGER.finest(" <- RtcpPktSR(rawPkt)"); 104 | } 105 | } 106 | 107 | /** 108 | * Encode the packet into a byte[], saved in .rawPkt 109 | * 110 | * CompRtcpPkt will call this automatically 111 | */ 112 | protected void encode() { 113 | if(LOGGER.isLoggable(Level.FINEST)) { 114 | if(this.rReports != null) { 115 | LOGGER.finest(" -> RtcpPktSR.encode() receptionReports.length: " + this.rReports.length ); 116 | } else { 117 | LOGGER.finest(" -> RtcpPktSR.encode() receptionReports: null"); 118 | } 119 | } 120 | 121 | if(this.rReports != null) { 122 | super.itemCount = this.rReports.reportees.length; 123 | 124 | byte[] tmp = this.rReports.encodeRR(); 125 | super.rawPkt = new byte[tmp.length+28]; 126 | //super.length = (super.rawPkt.length / 4) - 1; 127 | 128 | System.arraycopy(tmp, 0, super.rawPkt, 28, tmp.length); 129 | 130 | } else { 131 | super.itemCount = 0; 132 | super.rawPkt = new byte[28]; 133 | //super.length = 6; 134 | } 135 | //Write the common header 136 | super.writeHeaders(); 137 | 138 | // Convert to NTP and chop up 139 | long timeNow = System.currentTimeMillis(); 140 | ntpTs1 = 2208988800L + (timeNow/1000); 141 | long ms = timeNow % 1000; 142 | double tmp = ((double)ms) / 1000.0; 143 | tmp = tmp * (double)4294967295L; 144 | ntpTs2 = (long) tmp; 145 | rtpTs = System.currentTimeMillis(); 146 | 147 | //Write SR stuff 148 | byte[] someBytes; 149 | someBytes = StaticProcs.uIntLongToByteWord(super.ssrc); 150 | System.arraycopy(someBytes, 0, super.rawPkt, 4, 4); 151 | someBytes = StaticProcs.uIntLongToByteWord(ntpTs1); 152 | System.arraycopy(someBytes, 0, super.rawPkt, 8, 4); 153 | someBytes = StaticProcs.uIntLongToByteWord(ntpTs2); 154 | System.arraycopy(someBytes, 0, super.rawPkt, 12, 4); 155 | someBytes = StaticProcs.uIntLongToByteWord(rtpTs); 156 | System.arraycopy(someBytes, 0, super.rawPkt, 16, 4); 157 | someBytes = StaticProcs.uIntLongToByteWord(sendersPktCount); 158 | System.arraycopy(someBytes, 0, super.rawPkt, 20, 4); 159 | someBytes = StaticProcs.uIntLongToByteWord(sendersOctCount); 160 | System.arraycopy(someBytes, 0, super.rawPkt, 24, 4); 161 | 162 | if(LOGGER.isLoggable(Level.FINEST)) { 163 | LOGGER.finest(" <- RtcpPktSR.encode() ntpTs1: " 164 | + Long.toString(ntpTs1) + " ntpTs2: " + Long.toString(ntpTs2)); 165 | } 166 | } 167 | 168 | /** 169 | * Debug purposes only 170 | */ 171 | public void debugPrint() { 172 | LOGGER.finest("RtcpPktSR.debugPrint() "); 173 | LOGGER.finest(" SSRC:"+Long.toString(super.ssrc) +" ntpTs1:"+Long.toString(ntpTs1) 174 | +" ntpTS2:"+Long.toString(ntpTs2)+" rtpTS:"+Long.toString(rtpTs) 175 | +" senderPktCount:"+Long.toString(sendersPktCount)+" sendersOctetCount:" 176 | +Long.toString(sendersOctCount)); 177 | if(this.rReports != null) { 178 | System.out.print(" Part of Sender Report: "); 179 | this.rReports.debugPrint(); 180 | LOGGER.finest(" End Sender Report"); 181 | } else { 182 | LOGGER.finest("No Receiver Reports associated with this Sender Report."); 183 | } 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /org.jlibrtp/src/main/java/org/jlibrtp/RTPReceiverThread.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java RTP Library (jlibrtp) 3 | * Copyright (C) 2006 Arne Kepp 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | package org.jlibrtp; 20 | 21 | import java.io.IOException; 22 | import java.net.DatagramPacket; 23 | import java.net.InetSocketAddress; 24 | import java.util.logging.Level; 25 | import java.util.logging.Logger; 26 | 27 | /** 28 | * The RTP receiver thread waits on the designated UDP socket for new packets. 29 | * 30 | * Once one arrives, it is parsed and tested. We also check the ip-address of the sender. 31 | * If accepted, the packet is added onto the packet buffer of the participant. 32 | * 33 | * A separate thread moves the packet from the packet buffer to the application. 34 | * 35 | * @author Arne Kepp 36 | */ 37 | public class RTPReceiverThread extends Thread { 38 | /** Logger instance. */ 39 | private static final Logger LOGGER = 40 | Logger.getLogger(RTPReceiverThread.class.getName()); 41 | 42 | /** Parent RTP Session */ 43 | private RTPSession rtpSession = null; 44 | 45 | /** 46 | * Constructs a new object. 47 | * @param session the session 48 | */ 49 | public RTPReceiverThread(RTPSession session) { 50 | rtpSession = session; 51 | if(LOGGER.isLoggable(Level.FINEST)) { 52 | LOGGER.finest("<-> RTPReceiverThread created"); 53 | } 54 | setName("RTPReceiverThread"); 55 | } 56 | 57 | /** 58 | * Working method. 59 | */ 60 | public void run() { 61 | if(LOGGER.isLoggable(Level.FINEST)) { 62 | if(rtpSession.mcSession) { 63 | LOGGER.finest("-> RTPReceiverThread.run() starting on MC " + rtpSession.rtpMCSock.getLocalPort() ); 64 | } else { 65 | LOGGER.finest("-> RTPReceiverThread.run() starting on " + rtpSession.rtpSock.getLocalPort() ); 66 | } 67 | } 68 | 69 | while(!rtpSession.endSession) { 70 | if(LOGGER.isLoggable(Level.FINEST)) { 71 | if(rtpSession.mcSession) { 72 | LOGGER.finest("-> RTPReceiverThread.run() waiting for MC packet on " + rtpSession.rtpMCSock.getLocalPort() ); 73 | } else { 74 | LOGGER.finest("-> RTPReceiverThread.run() waiting for packet on " + rtpSession.rtpSock.getLocalPort() ); 75 | } 76 | } 77 | 78 | // Prepare a packet 79 | byte[] rawPkt = new byte[1500]; 80 | DatagramPacket packet = new DatagramPacket(rawPkt, rawPkt.length); 81 | // Wait for it to arrive 82 | if(! rtpSession.mcSession) { 83 | //Unicast 84 | try { 85 | rtpSession.rtpSock.receive(packet); 86 | } catch (IOException e) { 87 | if(!rtpSession.endSession) { 88 | e.printStackTrace(); 89 | } else { 90 | continue; 91 | } 92 | } 93 | } else { 94 | //Multicast 95 | try { 96 | rtpSession.rtpMCSock.receive(packet); 97 | } catch (IOException e) { 98 | if(!rtpSession.endSession) { 99 | e.printStackTrace(); 100 | } else { 101 | continue; 102 | } 103 | } 104 | } 105 | 106 | // Parse the received RTP (?) packet 107 | RtpPkt pkt = new RtpPkt(rawPkt, packet.getLength()); 108 | if(pkt.getVersion() != 2) { 109 | // Some old phones, like the SNOM 190, are transmitting one 110 | // Version=0 RTP packet before sending Version=2 RTP packets. 111 | System.out.println("Received invalid RTP packet. Ignoring"); 112 | continue; 113 | } 114 | long pktSsrc = pkt.getSsrc(); 115 | 116 | // Check for loops and SSRC collisions 117 | if( rtpSession.ssrc == pktSsrc ) 118 | rtpSession.resolveSsrcConflict(); 119 | 120 | long[] csrcArray = pkt.getCsrcArray(); 121 | if( csrcArray != null) { 122 | for(int i=0; i< csrcArray.length; i++) { 123 | if(csrcArray[i] == rtpSession.ssrc) { 124 | rtpSession.resolveSsrcConflict(); 125 | } 126 | } 127 | } 128 | 129 | if(LOGGER.isLoggable(Level.FINEST)) { 130 | LOGGER.finest("-> RTPReceiverThread.run() rcvd packet, seqNum " + rtpSession.seqNum + ", ssrc " + pktSsrc); 131 | String str = new String(pkt.getPayload()); 132 | LOGGER.finest("-> RTPReceiverThread.run() payload is " + str ); 133 | } 134 | 135 | //Find the participant in the database based on SSRC 136 | Participant part = rtpSession.partDb.getParticipant(pktSsrc); 137 | 138 | if(part == null) { 139 | InetSocketAddress nullSocket = null; 140 | part = new Participant((InetSocketAddress) packet.getSocketAddress(), nullSocket, pkt.getSsrc()); 141 | part.unexpected = true; 142 | rtpSession.partDb.addParticipant(1, part); 143 | // Note: when adding participant, the result may be an updated pre-existing participant that lacked 144 | // a ssrc. Thus, we need to find the participant that is really stored in the partDb after adding. 145 | // Otherwise the packet will be added to a participant not connected to a rtpSession. 146 | part = rtpSession.partDb.getParticipant(pktSsrc); 147 | } 148 | 149 | // Do checks on whether the datagram came from the expected source for that SSRC. 150 | if(part.rtpAddress == null || packet.getAddress().equals(part.rtpAddress.getAddress())) { 151 | PktBuffer pktBuffer = part.pktBuffer; 152 | 153 | if(pktBuffer != null) { 154 | //A buffer already exists, append to it 155 | pktBuffer.addPkt(pkt); 156 | } else { 157 | // Create a new packet/frame buffer 158 | pktBuffer = new PktBuffer(this.rtpSession, part,pkt); 159 | part.pktBuffer = pktBuffer; 160 | } 161 | } else { 162 | LOGGER.warning("RTPReceiverThread: Got an unexpected packet from " + pkt.getSsrc() 163 | + " the sending ip-address was " + packet.getAddress().toString() 164 | + ", we expected from " + part.rtpAddress.toString()); 165 | } 166 | 167 | // Statistics for receiver report. 168 | part.updateRRStats(packet.getLength(), pkt); 169 | // Upate liveness 170 | part.lastRtpPkt = System.currentTimeMillis(); 171 | 172 | if(LOGGER.isLoggable(Level.FINEST)) { 173 | LOGGER.finest("<-> RTPReceiverThread signalling pktBufDataReady"); 174 | } 175 | 176 | // Signal the thread that pushes data to application 177 | rtpSession.pktBufLock.lock(); 178 | try { rtpSession.pktBufDataReady.signalAll(); } finally { 179 | rtpSession.pktBufLock.unlock(); 180 | } 181 | } 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /org.jlibrtp.demo/src/main/java/org/jlibrtp/demo/XmlPacketPlayer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java RTP Library (jlibrtp) 3 | * Copyright (C) 2006 Arne Kepp 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | package org.jlibrtp.demo; 21 | 22 | import java.io.File; 23 | import java.net.DatagramSocket; 24 | import java.util.Iterator; 25 | import java.util.List; 26 | 27 | import org.jdom2.Document; 28 | import org.jdom2.Element; 29 | import org.jdom2.input.SAXBuilder; 30 | import org.jlibrtp.DataFrame; 31 | import org.jlibrtp.Participant; 32 | import org.jlibrtp.RTPAppIntf; 33 | import org.jlibrtp.RTPSession; 34 | import org.jlibrtp.StaticProcs; 35 | 36 | /** 37 | * XML Packet player demo. 38 | * @author Arne Kepp 39 | * 40 | */ 41 | public class XmlPacketPlayer implements RTPAppIntf { 42 | private RTPSession rtpSession = null; 43 | private Document document = null; 44 | private long origStartTime = -1; 45 | private long startTime = -1; 46 | private int dataCount = 0; 47 | private int pktCount = 0; 48 | 49 | /** 50 | * Constructs a new object. 51 | * @param rtpPortNum RTP port number 52 | * @param rtcpPortNum RTCP port number 53 | * @param address address to use 54 | */ 55 | public XmlPacketPlayer(int rtpPortNum, int rtcpPortNum, String address) { 56 | DatagramSocket rtpSocket = null; 57 | DatagramSocket rtcpSocket = null; 58 | 59 | try { 60 | rtpSocket = new DatagramSocket(rtpPortNum+2); 61 | rtcpSocket = new DatagramSocket(rtcpPortNum+2); 62 | } catch (Exception e) { 63 | System.out.println(e.getMessage()); 64 | System.out.println("RTPSession failed to obtain port"); 65 | } 66 | 67 | this.rtpSession = new RTPSession(rtpSocket, rtcpSocket); 68 | Participant p = new Participant(address, rtpPortNum, rtcpPortNum); 69 | this.rtpSession.addParticipant(p); 70 | 71 | System.out.println("Done creating player."); 72 | } 73 | 74 | /** 75 | * Parses the file with the given name. 76 | * @param filename file to parse 77 | */ 78 | public void parseDocument(String filename) { 79 | System.out.println("Parsing document " + filename); 80 | try { 81 | SAXBuilder builder = new SAXBuilder(); 82 | this.document = builder.build(new File(filename)); 83 | } catch(Exception e) { 84 | e.printStackTrace(); 85 | } 86 | 87 | //RTPSession 88 | Element elm = document.getRootElement(); 89 | List