Support for non-multiplexed RTP and RTCP

Since the WebRTC 1.0 API allows the browser to not multiplex RTP and RTCP, there has been interest in enabling this feature within ORTC.

At the same time, there has been concern about the potential complexity that the non-multiplex case could add.  After all, support for RTP/RTCP multiplexing is required in the RTP usage draft.

As a result, there has been a strong desire to avoid complicating the task of a developer whose application uses RTP/RTCP and audio/video multiplexing.

In order to get a sense of what is required to implement the non-RTP/RTCP multiplexing case, we have written some sample code, which is based on Peter Thatcher's proposal.

As proposed by Peter, the createAssociatedTransport method is used to create RTCP ICE Transports, and those RTCP ICE Transports are in turn used to construct
DTLS transport objects for RTCP.   In order to utilize the separate RTP and RTCP transports in the sender and receiver objects, those objects then were extended to
support optional RTCP transports.

Here is what the sample code looks like, assuming that both Audio and Video and RTP/RTCP are to be separated out.

The proposed sample code incorporates the changes to RTCRtpCapabilities and RTCRtpParameters and the proposed Javascript library functions
myCapsToSendParams and myCapsToRecvParams, as discussed in earlier posts.

This is not the prettiest example, certainly.    On the other hand, it is not the ugliest thing I have ever seen, and the ugliness that is there will not afflict the developer who is interested in
multiplexing A/V and RTP/RTCP.    For example, such a developer should not need to call either createAssociatedTransport or RTCIceTransportController.


EXAMPLE WITHOUT Audio/Video or RTP/RTCP Multiplexing:

// This is an example of how to utilize distinct ICE transports for RTP and RTCP.
// Assume we have an audioTrack and a videoTrack to send.
//
//create the RTP and RTCP ICE transports for audio and video
var audioRtpIceTransport = new RTCIceTransport(...);
var audioRtcpIceTransport = audioRtpIceTransport.createAssociatedTransport();
var videoRtpIceTransport = new RTCIceTransport(...);
var videoRtcpIceTransport = audioRtpIceTransport.createAssociatedTransport();

//create the DTLS transports
var audioRtpDtlsTransport = new RTCDtlsTransport(audioRtpIceTransport);
var audioRtcpDtlsTransport = new RTCDtlsTransport(audioRtcpIceTransport);
var videoRtpDtlsTransport = new RTCDtlsTransport(videoRtpIceTransport);
var videoRtcpDtlsTransport = new RTCDtlsTransport(videoRtcpIceTransport);

// ... start the ICE and DTLS transports
var controller = new RTCIceTransportController();
controller.addTransport(audioRtpIceTransport);
controller.addTransport(videoRtpIceTransport);
var audioSender = new RtpSender(audioTrack, audioRtpDtlsTransport, audioRtcpDtlsTransport);
var videoSender = new RtpSender(videoTrack, videoRtpDtlsTransport, videoRtcpDtlsTransport);
var audioReceiver = new RtpReceiver(audioRtpDtlsTransport, audioRtcpDtlsTransport);
var videoReceiver = new RtpReceiver(videoRtpDtlsTransport, videoRtcpDtlsTransport);
var recvAudioCaps = RTCRtpReceiver.getCapabilities("audio");
var recvVideoCaps = RTCRtpReceiver.getCapabiltiies("video");
var sendAudioCaps = RTCRtpSender.getCapabilities("audio");
var recvVideoCaps = RTCRtpSender.getCapabilities("video");

// At this point, capabilities can be exchanged.
  mySignaller.myOfferTracks({
// Indicate that the initiator would prefer to multiplex RTP/RTCP.
    "rtcpMux": true,
// Offer the receiver and sender audio and video capabilities.
    "recvAudioCaps": recvAudioCaps,
    "recvVideoCaps": recvVideoCaps,
    "sendAudioCaps": sendAudioCaps,
    "sendVideoCaps": sendVideoCaps
  }, function(answer) {
// The responder answers with its RTP/RTCP multiplexing preference and capabilities

// Derive the send and receive parameters, assuming that RTP/RTCP mux will be enabled.
    var audioSendParams = myCapsToSendParams(sendAudioCaps, answer.recvAudioCaps);
    var videoSendParams = myCapsToSendParams(sendVideoCaps, answer.recvVideoCaps);
    var audioRecvParams = myCapsToRecvParams(recvAudioCaps, answer.sendAudioCaps);
    var videoRecvParams = myCapsToRecvParams(recvVideoCaps, answer.sendVideoCaps);

// If the responder wishes to enable RTP/RTCP multiplexing, we will enable it and so
// we need to remember to stop the unused ICE transports, or else they will go to the
// failed state when the remote endpoint blows theirs away.

if (answer.rtcpMux) {
audioRtcpIceTransport.stop();
audioRtcpDtlsTransport.stop();
videoRtcpIceTransport.stop();
videoRtcpDtlsTransport.stop();
} else {

// If the responder does not want RTP/RTCP multiplexing, we need to set the rtcp.mux parameter to disable it.
  audioSendParams.rtcp.mux = false;
  videoSendParams.rtcp.mux = false;
  audioRecvParams.rtcp.mux = false;
  videoRecvParams.rtcp.mux = false;
};

// Set the audio and video send and receive parameters.
    audioSender.send(audioSendParams);
    videoSender.send(videoSendParams);
    audioReceiver.receive(audioRecvParams);
    videoReceiver.receive(videoRecvParams);
  });

// Now we can render/play
// audioReceiver.track and videoReceiver.track.

Received on Friday, 13 June 2014 21:11:31 UTC