Re: [rtcweb] Proposal for a JS API for NoPlan (adding multiple sources without encoding them in SDP)

"Matthew Kaufman (SKYPE)" <matthew.kaufman@skype.net> Tue, 18 June 2013 01:35 UTC

Return-Path: <matthew.kaufman@skype.net>
X-Original-To: rtcweb@ietfa.amsl.com
Delivered-To: rtcweb@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 1ECEC21F9DD5 for <rtcweb@ietfa.amsl.com>; Mon, 17 Jun 2013 18:35:16 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.598
X-Spam-Level:
X-Spam-Status: No, score=-2.598 tagged_above=-999 required=5 tests=[BAYES_00=-2.599, HTML_MESSAGE=0.001]
Received: from mail.ietf.org ([12.22.58.30]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id OmL5uPhU9l3j for <rtcweb@ietfa.amsl.com>; Mon, 17 Jun 2013 18:35:10 -0700 (PDT)
Received: from na01-by2-obe.outbound.protection.outlook.com (mail-by2lp0242.outbound.protection.outlook.com [207.46.163.242]) by ietfa.amsl.com (Postfix) with ESMTP id 8E74D21F9CCA for <rtcweb@ietf.org>; Mon, 17 Jun 2013 18:35:10 -0700 (PDT)
Received: from BL2FFO11FD005.protection.gbl (10.173.161.203) by BL2FFO11HUB027.protection.gbl (10.173.161.51) with Microsoft SMTP Server (TLS) id 15.0.707.0; Tue, 18 Jun 2013 01:35:07 +0000
Received: from TK5EX14HUBC102.redmond.corp.microsoft.com (131.107.125.37) by BL2FFO11FD005.mail.protection.outlook.com (10.173.161.1) with Microsoft SMTP Server (TLS) id 15.0.707.0 via Frontend Transport; Tue, 18 Jun 2013 01:35:07 +0000
Received: from TK5EX14MBXC273.redmond.corp.microsoft.com ([169.254.1.171]) by TK5EX14HUBC102.redmond.corp.microsoft.com ([157.54.7.154]) with mapi id 14.03.0136.001; Tue, 18 Jun 2013 01:35:06 +0000
From: "Matthew Kaufman (SKYPE)" <matthew.kaufman@skype.net>
To: Peter Thatcher <pthatcher@google.com>, Martin Thomson <martin.thomson@gmail.com>
Thread-Topic: [rtcweb] Proposal for a JS API for NoPlan (adding multiple sources without encoding them in SDP)
Thread-Index: AQHOa1pL3f2CtN2bTEydXd59L0Jyj5k6QmQAgAAH7oCAAGYM4A==
Date: Tue, 18 Jun 2013 01:35:05 +0000
Message-ID: <AE1A6B5FD507DC4FB3C5166F3A05A4841A2C5986@TK5EX14MBXC273.redmond.corp.microsoft.com>
References: <CAJrXDUHdoxLTsofiwLBdwBNnCCkCBgjSdbmLaXrNEPODMrsSVA@mail.gmail.com> <CABkgnnUmRpanfpwryyiCUsOdMLzrd74n-4LXaj_AK3aLe0yQ8Q@mail.gmail.com> <CAJrXDUGnEwtsGZwUUqQgH0vDnMPy=XxqwQB9fpNcW9yQDhFt4w@mail.gmail.com>
In-Reply-To: <CAJrXDUGnEwtsGZwUUqQgH0vDnMPy=XxqwQB9fpNcW9yQDhFt4w@mail.gmail.com>
Accept-Language: en-US
Content-Language: en-US
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
x-originating-ip: [157.54.51.75]
Content-Type: multipart/alternative; boundary="_000_AE1A6B5FD507DC4FB3C5166F3A05A4841A2C5986TK5EX14MBXC273r_"
MIME-Version: 1.0
X-Forefront-Antispam-Report: CIP:131.107.125.37; CTRY:US; IPV:CAL; IPV:NLI; EFV:NLI; SFV:NSPM; SFS:(43544003)(199002)(377454002)(52034003)(189002)(24454002)(51704005)(54356001)(55846006)(74502001)(33656001)(76786001)(47976001)(4396001)(20776003)(50986001)(15202345002)(77982001)(49866001)(31966008)(47446002)(44976003)(77096001)(81342001)(47736001)(74366001)(56776001)(51856001)(74662001)(46102001)(512874002)(76796001)(56816003)(76482001)(16406001)(74876001)(81542001)(6806003)(79102001)(80022001)(69226001)(16236675002)(59766001)(66066001)(561944002)(74706001)(54316002)(71186001)(65816001)(63696002)(53806001); DIR:OUT; SFP:; SCL:1; SRVR:BL2FFO11HUB027; H:TK5EX14HUBC102.redmond.corp.microsoft.com; CLIP:131.107.125.37; RD:InfoDomainNonexistent; A:1; MX:1; LANG:en;
X-OriginatorOrg: microsoft.onmicrosoft.com
X-O365ENT-EOP-Header: Message processed by - O365_ENT: Allow from ranges (Engineering ONLY)
X-Forefront-PRVS: 0881A7A935
Cc: "<rtcweb@ietf.org>" <rtcweb@ietf.org>
Subject: Re: [rtcweb] Proposal for a JS API for NoPlan (adding multiple sources without encoding them in SDP)
X-BeenThere: rtcweb@ietf.org
X-Mailman-Version: 2.1.12
Precedence: list
List-Id: Real-Time Communication in WEB-browsers working group list <rtcweb.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/rtcweb>, <mailto:rtcweb-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/rtcweb>
List-Post: <mailto:rtcweb@ietf.org>
List-Help: <mailto:rtcweb-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/rtcweb>, <mailto:rtcweb-request@ietf.org?subject=subscribe>
X-List-Received-Date: Tue, 18 Jun 2013 01:35:16 -0000

The problem is that all sorts of interesting use cases are hampered by having a giant object that encapsulates everything and which is controlled with a pointy SDP stick or even a stick that has the SDP covered in tape and glue.

Here’s an example case I’d love to have someone show me how to do with the current API:

  Open a connection between client A and client B that tests for a peer-to-peer path between client A and client B (by doing a STUN connectivity test) but which prefers to send media via a relayed path (over my own private fiber backbone).

I want to do the connectivity test so that I know whether when there’s a path failure I need to instantiate a new relay path or I can just fall back to the Internet path. Oh, and I’d like to collect the derived addresses and some other stats from the connectivity test so I can feed that back into my big data analysis system.

Other than opening a second full PeerConnection object, I don’t see that I have enough control over the candidate selection, even if I mangle the SDP, and certainly not at all if I don’t.

Matthew Kaufman

From: rtcweb-bounces@ietf.org [mailto:rtcweb-bounces@ietf.org] On Behalf Of Peter Thatcher
Sent: Monday, June 17, 2013 12:26 PM
To: Martin Thomson
Cc: <rtcweb@ietf.org>
Subject: Re: [rtcweb] Proposal for a JS API for NoPlan (adding multiple sources without encoding them in SDP)

Yes, I was expecting you to be more supportive.  I'm surprised out how your want "all or nothing".  I'm afraid if our options for a clean API are all or nothing, we'll just end up with nothing.  I'd prefer to try incremental improvements to word toward (eventually) a clean API.

Do you think it is impossible to work toward a clean API in an incremental approach?  If you think it's possible, I'd like to hear your thoughts on how.


By the way, these API additions would greatly minimize the amount of SDP editing necessary for JS clients that don't use SDP for signalling.  And later incremental improvements could reduce it further.  Also, it's no longer necessary to do offer/answer for adding tracks.  It's only the intial PeerConnection setup that needs to do Offer/Answer.  So, it doesn't inherit all the problems quite as much as you described.  It may be slightly abominable, but I certainly consider it less abominable than the SDP editing necessary without it.

On Mon, Jun 17, 2013 at 11:57 AM, Martin Thomson <martin.thomson@gmail.com<mailto:martin.thomson@gmail.com>> wrote:
Maybe you'd expect me to be more supportive of something that looked
so much like CU-RTC-Web.  It inherits all the worst properties of JSEP
(Offer/Answer, SDP editing) with a partial implementation of a clean
API.

It's comment 22-lite.  It's an abomination.  If you are going to do
this, do it properly.

On 17 June 2013 05:57, Peter Thatcher <pthatcher@google.com<mailto:pthatcher@google.com>> wrote:
> Google is in full support of "Plan B" for encoding multiple media sources in
> SDP, and would like to see the Plan A vs. Plan B decision resolved soon.
> Recently, though, a third option, called "NoPlan" has been proposed, but it
> lacked the details of what a JS API would look like for NoPlan.  Cullen
> asked to see such an API proposal, and so I have worked with Emil to make
> one.  He will be adding it to the NoPlan draft, but I will also include it
> in this email.
>
> Again, Google is in full support of "Plan B".  But if Plan A vs. Plan B
> cannot be decided, then we support NoPlan with the following additions to
> the WebRTC JS API as an option that allows implementing either Plan A or
> Plan B  in Javascript.  And even if Plan A vs. Plan B is resolved, these API
> additions would still be a big improvement for those WebRTC applications
> that don't use SDP for signalling.
>
> It is a bit long because I have added many comments and examples, but the
> actually additions only include two new methods on PeerConnection and a few
> new dictionaries.  So don't be overwhelmed :).
>
>
>
> Intro: This follows the model of createDataChannel, which has a JS method on
> PeerConnection that makes it possible to add data channels without going
> through SDP.  Furthermore, just like createDataChannel allows 2 ways to
> handle neogitation (the "I know what I'm doing;  Here's what I want to send;
> Let me signal everything" mode and the "please take care of it for me;  send
> an OPEN message" mode), this also has 2 ways to handle negotiation (the "I
> know what I'm doing; Here's what I want to send; Let me signal everything"
> mode and the "please take care of it for me;  send SDP back and forth"
> mode).
>
> Following the success of createDataChannel, this allows simple applications
> to Just Work and more advanced applications to easily control what they need
> to.  In particular, it's possible to use this API to implement either Plan A
> or Plan B.
>
> // The following two method are added to RTCPeerConnection
> partial interface RTCPeerConnection {
>  // Create a stream that is used to send a source stream.
>  // The MediaSendStream.description can be used for signalling.
>  // No media is sent until addStream(MediaSendStream) is called.
>  LocalMediaStream createLocalStream(MediaStream sourceStream);
>
>  // Create a stream that is used to receive media from the remote side,
>  // given the parameters signalled from MedaiSendStream.description.
>  MediaStream createRemoteStream(MediaStreamDescription description);
> }
>
>
> interface LocalMediaStream implements MediaStream {
>   // This can be changed at any time, but especially before calling
>   // PeerConnection.addStream
>   attribute MediaStreamDescription description;
> }
>
>
> // Represents the parameters used to either send or receive a stream
> // over a PeerConnection.
> dictionary MediaStreamDescription {
>   MediaStreamTrackDescription[] tracks;
> }
>
>
> // Represents the parameters used to either send or receive a track over //
> a PeerConnection.  A track has many "flows", which can be grouped
> // together.
> dictionary MediaStreamTrackDescription {
>   // Same as the MediaStreamTrack.id
>   DOMString id;
>
>   // Same as the MediaStreamTrack.kind
>   DOMString kind;
>
>   // A track can have many "flows", such as for Simulcast, FEC, etc.
>   // And they can be grouped in arbitrary ways.
>   MediaFlowDescription[] flows;
>   MediaFlowGroup[] flowGroups;
> }
>
> // Represents the parameters used to either send or receive a "flow"
> // over a PeerConnection.  A "flow" is a media that arrives with a
> // single, unique SSRC.  One to many flows together make up the media
> // for a track.  For example, there may be Simulcast, FEC, and RTX
> // flows.
> dictionay MediaFlowDescription {
>   // The "flow id" must be unique to the track, but need not be unique
>   // outside of the track (two tracks could both have a flow with the
>   // same flow ID).
>   DOMString id;
>
>   // Each flow can go over its own transport.  If the JS sets this to a
>   // transportId that doesn't have a transport setup already, the
>   // browser will use SDP negotiation to setup a transport to back that
>   // transportId.  If This is set to an MID in the SDP, then that MID's
>   // transport is used.
>   DOMString transportId;
>
>   // The SSRC used to send the flow.
>   unsigned int ssrc;
>
>   // When used as receive parameters, this indicates the possible list
>   // of codecs that might come in for this flow.  For exmample, a given
>   // receive flow could be setup to receive any of OPUS, ISAC, or PCMU.
>   // When used as send parameters, this indicates that the first codec
>   // should be used, but the browser can use send other codecs if it
>   // needs to because of either bandwidth or CPU constraints.
>   MediaCodecDescription[] codecs;
> }
>
>
> dictionary MediaFlowGroup {
>   DOMString type;  // "SIM" for Simulcast, "FEC" for FEC, etc
>   DOMString[] flowids;
> }
>
> dictionary MediaCodecDescription {
>   unsigned byte payloadType;
>   DOMString name;
>   unsigned int? clockRate;
>   unsigned int? bitRate;
>   // A grab bag of other fmtp that will need to be further defined.
>   MediaCodecParam[] params;
> }
>
> dictionary MediaCodecParam {
>   DOMString key;
>   DOMString value;
> }
>
>
> Notes:
>
> - When LocalMediaStreams are added using addStream, onnegotiatedneeded is
> not called, and those streams are never reflected in future SDP exchanges.
> Indeed, it would be impossible to put them in the SDP without first
> resolving if that would be Plan A SDP or Plan B SDP.
>
> - Just like piles of attributes would need to be defined for Plan A and for
> Plan B, similar attributes would need to be defined here (Luckily,  much
> work has already been done figuring out what those parameters are :).
>
>
> Pros:
>
> - Either Plan A or Plan B or could be implemented in Javascript using this
> API
> - It exposes all the same functionality to the Javascript as SDP, but in a
> much nicer format that is much easier to work with.
> - Any other signalling mechanism, such as Jingle or CLUE could be
> implemented using this API.
> - There is almost no risk of signalling glare.
> - Debugging errors with misconfigured descriptions should be much easier
> with this than with large SDP blobs.
>
>
> Cons:
>
> - Now there are two slightly different ways to add streams: by creating a
> LocalMediaStream first, and not.  This is, however, analogous to setting
> "negotiated: true" in createDataChannel.  On way is "Just Work", and the
> other is more advanced control.
>
> - All the options in MediaCodecDescription are a bit complicated.  Really,
> this is only necessary because Plan A requires being able to specify codec
> parameters per SSRC, and set each flow on different transports.  If we did
> not have this requirement, we could simplify.
>
>
> Example Usage:
>
> // Imagine I have MyApp, handles creating a PeerConnection,
> // signalling, and rendering streams.  This is how the new API could be
> // used.
> var peerConnection = MyApp.createPeerConnection();
>
> // On sender side:
> var stream = MyApp.getMediaStream();
> var localStream = peerConnection.createSendStream(stream);
> sendStream.description = MyApp.modifyStream(localStream.description)
> MyApp.signalAddStream(localStream.description, function(response)) {
>   if (!response.rejected) {
>     // Media will not be sent.
>     peerConnection.addStream(localStream);
>   }
> }
>
> // On receiver side:
> MyApp.onAddStreamSignalled = function(streamDescription) {
>   var stream = peerConnection.createReceiveStream(streamDescription);
>   MyApp.renderStream(stream);
> }
>
>
> // In this exchange, the MediaStreamDescription signalled from the
> // sender to the receiver may have looked something like this:
>
> {
>   tracks: [
>   {
>     id: "audio1",
>     kind: "audio",
>     flows: [
>     {
>       id: "main",
>       transportId: "transport1",
>       ssrc: 1111,
>       codecs: [
>       {
>         payloadType: 111,
>         name: "opus",
>         // ... more codec details
>       },
>       {
>         payloadType: 112,
>         name: "pcmu",
>         // ... more codec details
>       }]
>    }]
>  },
>  {
>     id: "video1",
>     kind: "video",
>     flows: [
>     {
>       id: "sim0",
>       transportId: "transport2",
>       ssrc: 2222,
>       codecs: [
>       {
>         payloadType: 122,
>         name: "vp8"
>         // ... more codec details
>       }]
>    },
>    {
>      id: "sim1",
>      transportId: "transport2",
>      ssrc: 2223,
>      codecs: [
>      {
>        payloadType: 122,
>        name: "vp8",
>        // ... more codec details
>      }]
>    },
>    {
>      id: "sim2",
>      transportId: "transport2",
>      ssrc: 2224,
>      codecs: [
>      {
>        payloadType: 122,
>        name: "vp8",
>        // ... more codec details
>      }]
>    },
>
>    {
>      id: "sim0fec",
>      transportId: "transport2",
>      ssrc: 2225,
>      codecs: [
>      {
>        payloadType: 122,
>        name: "vp8",
>        // ...
>      }]
>    }],
>    flowGroups: [
>    {
>      semantics: "SIM",
>      ssrcs: [2222, 2223, 2224]
>    },
>    {
>      semantics: "FEC",
>      ssrcs: [2222, 2225]
>    }]
>  }]
> }
>
>
> Constructive feedback is welcome :).
>
> _______________________________________________
> rtcweb mailing list
> rtcweb@ietf.org<mailto:rtcweb@ietf.org>
> https://www.ietf.org/mailman/listinfo/rtcweb
>