6
votes

I want to capture and stream audio using JMF 2.1.1e in RTP format. I wrote a simple transmitter, I can transmit and receive the audio. But when I saw in Wireshark, I saw the packets as UDP. Can anyone point me out the problem, please.

And here is my function responsible for audio capture and transmit.

public void captureAudio(){

    // Get the device list for ULAW
    Vector devices = captureDevices();

    CaptureDeviceInfo captureDeviceInfo = null;

    if (devices.size() > 0) {
         //get the first device from the list and cast it as CaptureDeviceInfo
         captureDeviceInfo = (CaptureDeviceInfo) devices.firstElement();
    }
    else {
        // exit if we could not find the relevant capturedevice.
        System.out.println("No such device found");
        System.exit(-1);
    }


    Processor processor = null;
    try {
        //Create a Processor for the specified media.
        processor = Manager.createProcessor(captureDeviceInfo.getLocator());
    } catch (IOException ex) {
        System.err.println(ex);
    } catch (NoProcessorException ex) {
        System.err.println(ex);
    }
    //Prepares the Processor to be programmed.
    //puts the Processor into the Configuring state.
    processor.configure();

    //Wait till the Processor configured.
    while (processor.getState() != Processor.Configured){
       try {
           Thread.sleep(100);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
   }


    //Sets the output content-type for this Processor
    processor.setContentDescriptor(CONTENT_DESCRIPTOR); 
    /** 
         ContentDescriptor CONTENT_DESCRIPTOR
                = new ContentDescriptor(ContentDescriptor.RAW_RTP); 
      */

    //Gets a TrackControl for each track in the media stream.
    TrackControl track[] = processor.getTrackControls();

    boolean encodingOk = false;

    //searching through tracks to get a supported audio format track.
    for (int i = 0; i < track.length; i++) {
        if (!encodingOk && track[i] instanceof FormatControl) {
            if (((FormatControl)
                    track[i]).setFormat( new AudioFormat(AudioFormat.ULAW_RTP, 8000, 8, 1) ) == null)
            {
               track[i].setEnabled(false);
            }
            else {
                encodingOk = true;
                track[i].setEnabled(encodingOk);
                System.out.println("enc: " + i);
            }
        } else {
            // we could not set this track to ULAW, so disable it
            track[i].setEnabled(false);
        }
    }

    //If we could set this track to ULAW we proceed
    if (encodingOk){            
        processor.realize();
        while (processor.getState() != Processor.Realized){
           try {
               Thread.sleep(100);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
        }

        DataSource dataSource = null;
        try {
            dataSource = processor.getDataOutput();
        } catch (NotRealizedError e) {
            e.printStackTrace();
        }

        try {

            String url= "rtp://192.168.1.99:49150/audio/1";
            MediaLocator m = new MediaLocator(url);
            DataSink d = Manager.createDataSink(dataSource, m);
            d.open();
            d.start();
            System.out.println("transmitting...");
            processor.start();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

And please ask, if you find anything improper or vague. Thanks in advance. :)

Clarification: I have a peice of C# code for RTP streaming. And when I capture the data using wireshark, I can see them as RTP, but the problem is when I capture the data stream from JMF wireshark show them as UDP. And my question is, why?

I know the difference between UDP and RTP.

2
I think the problem is on the CONTENT_DESCRIPTOR, it is raw-rtp.shibli049
I understand that you code is running except for the problem you are facing right now. We need to see in JMF source code how JMF implements the Processor class when it uses the CONTENT_DESCRIPTOR like what Osbcure has said. Maybe this is the difference between the C# codes and the Java JMF codes. Care to tell what streaming library you are using for the C# version?ecle
@eee : C# project is using pjsipDll,I just brought it from a friend to test the packets in wireshark, and I am not used to work with C#. So, couldn't give you any further detail on C#.shibli049

2 Answers

8
votes

RTP is the Application layer, UDP is the Transport Layer, that is not the same level! Wikipedia helps to explain that in detail. So your data is send as a RTP stream within a UDP "Frame"

A small overview...

Application layers:

* DHCP
* DHCPv6
* DNS
* FTP
* HTTP
* IMAP
* IRC
* LDAP
* MGCP
* NNTP
* BGP
* NTP
* POP
* RPC
* RTP
* RTSP
* RIP
* SIP
* SMTP
* SNMP
* SOCKS
* SSH
* Telnet
* TLS/SSL
* XMPP
* (more)

Transport layer

* TCP
* UDP
* DCCP
* SCTP
* RSVP
* (more)

Internet layer

* IP
      o IPv4
      o IPv6
* ICMP
* ICMPv6
* ECN
* IGMP
* IPsec
* (more)

Link layer

* ARP/InARP
* NDP
* OSPF
* Tunnels
      o L2TP
* PPP
* Media access control
      o Ethernet
      o DSL
      o ISDN
      o FDDI
* (more)
5
votes

If I understand your question correctly you want to know why the RTP packets are not recognised as RTP packets in wireshark. In my experience this can be the case if wireshark does not have enough information about the RTP session.

For example: 1) if I sniff an RTP session that has been setup using RTSP or SIP and SDP, then wireshark will show detect RTP. 2) However in another application in which I was setting up the session using local SDP descriptions, the packets show up as UDP. In the second scenario wireshark sees the RTP packets but lacks the information to classify them as RTP. Since RTP usually sits on top of UDP and wireshark can classify UDP packets, they are classified as such.

FYI, you can then select a packet from stream that you know is RTP, and select "Decode as". Then select RTP from the protocol list for the appropriate stream (and RTCP for the other one if applicable), and then wireshark will show the packets as being RTP and you'll be able to see the packet info.

I'm not sure if this is the reason in your specific case, but perhaps there is a signaling difference between your JMF and your C# example? It sounds like you might be using SIP for the C# application, and nothing for the JMF one?