If the "VoiceActivityDetection" option is specified, with a value of "true", the offer MUST indicate support for silence suppression in the audio it receives by including comfort noise ("CN") codecs for <del> each supported clock rate, as specified in RFC3389, Section 5.1. This option allows for significant bandwidth reductions with codecs such as G.711. </del>  5.2.3.4.

Late breaking, so if we decide to hold this until after Toronto, no worries
LGTM
Close enough for me. Merge it.

If the "VoiceActivityDetection" option is specified, with a value of "true", the offer MUST indicate support for silence suppression in the audio it receives by including comfort noise ("CN") codecs for  <ins> each offered audio codec, as specified in RFC3389, Section 5.1, except for codecs that have their own internal silence suppression support.  For codecs that have their own internal silence suppression support, the appropriate fmtp parameters for that codec MUST be specified to indicate that silence suppression for received audio is desired.  For example, when using the Opus codec, the "usedtx=1" parameter would be specified in the offer.  This option allows the endpoint to significantly reduce the amount of audio bandwidth it receives, at the cost of some fidelity, depending on the quality of the remote VAD algorithm. </ins> 5.2.3.4.


Unless codec preferences have been set for the associated transceiver, the media formats on the m= line MUST be generated in <del> the same order as in the most recent answer.  Any new media formats that were not present in the most recent answer MUST be added after all existing formats. </del>  The RTP header extensions MUST only include those that are present in the most recent answer.

Merging this, as this change was already discussed and approved in .
Section 5.2.2, "Subsequent Offers", says: However, consider a situation where Alice offers codecs and , and Bob answers with only codec , thereby rejecting . If Bob were to now create a subsequent offer, his remote description still contains both and , so he would technically be allowed to offer both codecs, even though was previously rejected. Is this intentional? It seems to go against the spirit of the rule. Perhaps the rule is meant to be "only include codecs present in the current local and remote descriptions". For context, see: URL
Yes, your understanding is correct. The set to be offered should only include the subset of codecs that were negotiated.
Please, let's specify the context of those already negotiated codecs. Is that per m=line? is that per "RTP session" (whatever that means nowadays)? is that per full SDP? If Alice just offers an m=audio line in the initial SDP offer and Bob answers, aren't they allowed to re-offer later with an added m=video line?
Also, are all those rules take into account multi-stream/participants when in a SFU scenario? Alice may join a SFU conference by offering VP8 and H264 for her sending m=video section, and the SFU may reply with just VP8. But later when a new non-VP8 capable peer join the conference, the SFU may want to generate a re-offer for Alice in behalf of Bob with a new m=video line (a=sendonly) having just H264 codec (since Bob). Why is this illegal?
Related issue open in Chromium project: URL
I assumed it meant per m= line, though this should definitely be made clear. If my assumption is correct, there would be no issue in your later comment about an SFU adding a new m= line.
Thanks NAME it makes sense. Hope it's clarified in the spec.
Eric and I discussed today and I think the simplest change is to reference "the codecs present in the most recent answer", since that is the set of negotiated codecs. This should also be extended to the other bullets in 5.2.2 regarding negotiated properties.
NAME NAME have you consider this scenario?: Alice may join a SFU conference by offering VP8 and H264 in her m=video (a=sendrecv), and the SFU may reply with just VP8 to ensure VP8 is used. Later, when a new non-VP8 capable peer joins the conference, the SFU may want to generate a re-offer for Alice by changing the codec to just H264. With your change this is not legal. And I don't agree because it is an artificial limitation. If we play the SDP game we should follow its rules. Does some RFC state that my suggested use case is illegal?
SFUs can do whatever they want. This spec is for JSEP implementations.
NAME please, re-read my concern. It's about a valid SDP received by WebRTC browser.
Nothing prohibits the SFU from re-offering with H.264 + VP8, and the JSEP endpoint will handle this properly when it is received (generating an appropriate answer). The text being discussed here only affects the offers that JSEP generates.
Re-openened due to discution on ietf list
I think re-offer should contain the full set of codecs or this will cause interesting problems with 3pcc or SIP interop. The order of codecs should ideally be the same as currently negotiated to avoid codec flips. Essentially, what this means all supported codecs not currently negotiated should be added to the end of the offer after the currently negotiated ones.
Note that there is a generic problem about what we mean by "codec". For example, assuming we are only allowed to re-offer previously negotiated codecs (e.g. H.264), are we still allowed to re-offer a different H.264 "codec configuration"?
Related: can an endpoint re-offer by introducing new PT values that were not present in previous O/A? URL
So one way to create a re-offer with all the new PT value that got removed in prev O/A is to create a new PC, add all the steams/tracks to it. Then call create offer to create a "fresh" offer and use that for the offer. However, might be a bit complicated with what happens with incoming media, some of it would be incoming on old PC then move to new PC.
This is even more complicated since you are not supposed to re-use the old PT in the new offer for different codecs. Since this is a completely new offer with no information about previously used PT, this restriction is hard to enforce.
Honestly, I don't think such an approach is acceptable.
Hmm - I see your point.
I don't want to renegotiate ICE+DTLS. I just want to add my audio/video on an already connected transport, and make it work :)
From , it appears the decision was to keep the spec as-is (only negotiate a subset), and possibly add an API in the future for adding codecs. Also, non-JSEP endpoints are still allowed to add codecs, which is covered by . So, I think this issue can be closed.
This will definitely break things.
I just listened to the recording, and the conclusion appeared to be "no one in the room objects to this, though some people on the mailing list might, so we'll continue discussion there". Did that discussion never happen? If so, it needs to. I'll reopen.
I do not think discussion ever happened on the list. My issue is that there is no API to generate a new offer which reuses currently negotiated payload types but lists all available codecs. Without this functionality third party call control is impossible to implement and it is impossible to simulate SIP INVITE without the body which will affect interop.
A possible addition to the API to allow reoffer codecs that were excluded previously: URL And the JSEP part: URL
Assigning Peter since his PR seems like the way forward.
I do worry that handling this in an ad hoc fashion is going to bite us, e.g. what if in the future a SFU wants a new offer with all supported RTP header extensions? I'm going to go dig up the initial issue that led to the approach that is currently in the document and see if it helps frame the situation.
TL; DR: After researching this issue, I think we should resolve it by always putting any supported-but-not-previously-negotiated codecs into the offer, but after the previously-negotiated codecs. [I will note that this is what NAME advocated for in August.] Full analysis OK, I trawled through the archives, and to the best of my understanding there are three issues: How to handle the case where EP1 (offerer) supports codecs [A, B, C] (in that preference order) and EP2 (answerer) supports [D, C, B] (in that order). See URL for more info. Interactions with the codec ordering API discussed in and related - how to prevent problems when both sides don't agree on ordering. Unnecessary SDP traffic (resending stuff that won't be used) Turning our attention to 1), we can consider left with the situation where EP1 and EP2 negotiate [B, C], via default 3264 rules, and EP2 now wants to reoffer. Under the current text, EP2 would have to reoffer [B, C], which prevents any change to the codec in use by either side, but doesn't allow for use of D. However, we definitely do not want to reoffer [D, C, B], since that will lead to [C, B] being negotiated, i.e., it will cause a codec switch. That leaves [D, B, C] or [B, C, D] as the only reasonable options to consider, i.e. "put new ones first" or "put new ones last". "New ones first" is complicated if we consider the case where EP2 suddenly supports [D, C, B, A]. Then the offer would become [D, A, B, C], and result in [A, B, C] being negotiated, which is probably not what EP2 wants. "New ones last" results in [B, C, D, A] being offered in the situation above, and [B, C, A] being negotiated. No codec switch occurs, unless explicit priority tweaking is performed. Ergo, "new ones last" seems like a reasonable policy that should address 1). 2) I think can be handled by the solution I am about to propose in . 3) I believe to be of minor importance. In the common case (e.g. when communicating between like endpoints), there will be no changes, and even in interop cases, the difference should be insignificant. Following up on my earlier comment, what about other things that might need to be renegotiated, such as a=rtcp-fb fields, and a=extmap extensions? It seems likely that if we are going to allow new codecs, we need to allow new a=rtcp-fb (which can be associated with a PT). And if we're going to do that, new a=extmap seems largely harmless. However, I think we should draw the line at any changes to TRANSPORT attributes, e.g. a=rtcp-rsize, etc. So the changes to S 5.2.2 would basically just be to incorporate the policy mentioned above into the first 3 bullets on page 45 (and any related changes needed in the subsequent-answer section). The End.
I can live with this. I would note that in bullet 3 above you could also do "B D C" but I think we can agree that that would be silly.
sounds good to me. Lots of SIP stuff does exactly that so I don't foresee any problem wiht his.
I can live with this as well. I just want to remind about two arguments that I got when I proposed this solution: a. Allocating a new codec can consume resources. For instance some video codecs have hardware resources required for their operation which need to be reserved before codec is offered. If codec is offered but never used, this can lead to waste of resources. b. In case of SIP, complete list of codecs is not produced for every offer. It is only produced for the offer which is generated in response to INVITE with no SDP body. Proposed behavior does not allow to exactly match currently implemented SIP end point behavior. As I have stated, I am fine with the proposed solution. I just want to make sure these two arguments do not cause any issues for anybody else.
NAME wdyt about the most recent comment from NAME ? As I see it we can either do what I propose here always, or only upon a createOffer flag (as NAME suggested). Always seems simpler, if we aren't worried about the issues Roman raises.
So what we sorted on editor call is we are going to make this happen by default for now. If a strong use case for having a knob to control it comes up, we can consider that. One point is you can use codec prefs to eliminate codecs so they don't show up in future offers.
NAME can you update your PR to reflect this consensus?
Hi, sorry as I couldn't track all the conclusions in this issue. However I'd like to confirm whether the current Chrome behavior is correct (according to the conclusion above) or not: Chrome is offered with VP8 PT 123. Chrome answers with VP8 PT 123 (including a sending video track) and no other video codecs. Chrome removes the video track from its PeerConnection. Chrome re-adds the same video track into its PeerConnection. Chrome calls . The new offer contains VP8 PT 123, but also VP9 PT 101, H264 etc etc etc. I didn't expect it since the initial SDP O/A did not contain them. Of course, there is a single BUNDLED transport. If this behavior correct and should Chrome fix it?
I think that behavior is correct by the new definition which is roughly reoffers will offer everything the browser can do at that point of time, but will put the stuff currently in use first.
Fine with me :)
Note that removal/readdition from a MediaStream should have no impact on offers/answers. IOW, the case you describe above is essentially: offer with all codecs, answer with just VP8, reoffer contains all codecs.
See also as a trivial followup on this issue.
Which has been merged, bringing this issue, finally, to a close.
What about if the video track I add to the local stream is not the same as the one I previously removed from it? For example, it is a video track retrieved via with different video resolution/constraints settings.
It has no impact. Only tracks given to addTrack or setTrack are used.
I did not understand you, sorry. I know that, according to the new API, changes in the local do not affect what the sends (although current Chrome does not behave like that and reacts on track addition/removal into the ). Thanks.
Just to be 200% sure, I would like to confirm that the following behaviour in Firefox is wrong. The scenario is the same as but now with Firefox: Firefox is offered with VP8 PT 123. Firefox answers with VP8 PT 123 (including a sending video track) and no other video codecs. Firefox removes the video track from its PeerConnection. Firefox adds another local video track into its PeerConnection. Firefox calls . The new offer contains VP8 PT 120 instead of 123 (wrong). Bug/issue detailed here: URL
What exact text do you believe prohibits this?
Per RFC 3264 this is allowed. What is not allowed is to use PT 123 for anything except VP8. Per :
Well, probably nothing prohibits a re-offer to include new PT values pointing to same codec+configurations as previously negotiated. Said that, a re-offer cannot offer a previously used PT for other codec+configuration. So IMHO this could be simplified by mandating reusing same PT values as before.
I'm not seeing a lot of value in requiring JSEP impls to behave this way.
Just noting that if it was a different m line, then it could use any PT it wanted for VP8. And in the above example, it is fine for it to use 120 in the 2nd offer as long as 120 had not previously been used for something other than VP8. To answer EKR question, the only thing of value here is following use case. In offer/answer 1, we have PT 120 => H264 and PT 123 => VP8. If in offer/answer 2 (on same m-lines, same mid, same blah blah blah) we swapped to PT120 => VP8, if we got a late media packet that was sent before the switch, but arrived after the switch, it might get delivered to the VP8 codec when actually it was encoded with H.264. I think that is all the is meant to stop. And I have allwasy viewed that trying to sop this is silly because what is going to happen is that late packet is going to get discarded. If sending a 264 packet to your VP8 codecs causes anything to happen other than it getting discarded, well seem like that is a problem.
The behavior mentioned by NAME does seem complicated, since the offerer needs to decode VP8 on both PT 120 and 123 at least until the O/A completes, but I agree it appears to be legal, and AFAICT it does not create any interoperability problems.
Uh no no. That's not possible. As long as such a m line belongs to the same BUNDLE group, all the m lines in that group are part of the same RTP session [1] and, hence, their PT values must be unique (in the sense that they must point to the same codec+configuration). I already asked about this exact subject several months ago. The given rationale was: "Existing RTP intermediaries [2] may rely on a single 1:1 mapping between PT and codec+configuration when carried over the same IP:port tuple, this is, the same RTP session" Those are the related threads: URL URL URL [1] Future generations may experience difficulties in understanding the concept of "RTP session". [2] Although no one has ever seen them in a WebRTC environment, they may exist.
The sad thing of all of this is that, at the end, for things to work the offerer and re-offerer must always be the same peer.
I think we definitely need to be able to have the reoffer move the media to a different IP since we do that all the time on non webrtc stuff. I might be missing what the issue is here but I want that to work.
Move the m= section into a separate transport just because it includes PT values already present in the other m= sections but pointing to different codec+configurations?
I don't see how any of this is a an issue. The rule is you can't reuse the PT. There's no rule that you can't reuse the codec with a new PT.
That's right, but it's also true that it causes errors in implementations (such as when Firefox renegotiates with Chrome by offering two different PT for Opus and Chrome assumes receipt of just the first PT). Hi, The following scenario causes setLocalDescription() to fail after renegotiation because the re-offerer (Firefox) introduces new codec PT in the same m= line): 1) Chrome calls to Firefox with an audio track. SDP offer (simplified): m=audio 58234 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 126 a=setup:actpass a=mid:audio a=sendrecv a=rtcp-mux a=rtpmap:111 opus/48000/2 a=rtcp-fb:111 transport-cc a=fmtp:111 minptime=10;useinbandfec=1 a=rtpmap:103 ISAC/16000 a=rtpmap:104 ISAC/32000 a=rtpmap:9 G722/8000 a=rtpmap:0 PCMU/8000 a=rtpmap:8 PCMA/8000 a=rtpmap:106 CN/32000 a=rtpmap:105 CN/16000 a=rtpmap:13 CN/8000 a=rtpmap:126 telephone-event/8000 2) Firefox SDP answer: m=audio 65515 UDP/TLS/RTP/SAVPF 111 a=recvonly a=fmtp:111 maxplaybackrate=48000;stereo=1 a=mid:audio a=rtcp-mux a=rtpmap:111 opus/48000/2 a=setup:active Firefox has chosen PT 111 (opus). Fine. 3) Firefox re-offers with its own audio track. SDP re-offer: m=audio 65515 UDP/TLS/RTP/SAVPF 109 9 0 8 111 a=sendrecv a=fmtp:111 maxplaybackrate=48000;stereo=1 a=mid:audio a=rtcp-mux a=rtpmap:109 opus/48000/2 a=rtpmap:9 G722/8000/1 a=rtpmap:0 PCMU/8000 a=rtpmap:8 PCMA/8000 a=rtpmap:111 opus/48000/2 a=setup:actpass Here Firefox has introduced a new PT value: 109 (also opus). Note that PT 111 (opus) is still present. 4) Chrome gets the SDP re-offer, calls setRemoteDescription() (success) and calls createAnswer(), which produces the following SDP answer: m=audio 58234 UDP/TLS/RTP/SAVPF 109 9 0 8 a=setup:passive a=mid:audio a=sendrecv a=rtcp-mux a=rtpmap:109 opus/48000/2 a=fmtp:109 minptime=10;useinbandfec=1 a=rtpmap:9 G722/8000 a=rtpmap:0 PCMU/8000 a=rtpmap:8 PCMA/8000 Note that Chrome has chosen PT 109 (opus) instead of the previously used PT 111 (opus). 5) Then Chrome calls to setLocalDescription() with such an answer, which produces this error: So my main question is: can an endpoint perform a PeerConnection renegotiation and introduce new PT values within an existing m= line? AFAIR this is NOT valid. If valid, then this is a Chrome bug. If invalid, then this is a Firefox bug. Thanks a lot. Iñaki Baz Castillo

Unless codec preferences have been set for the associated transceiver, the media formats on the m= line MUST be generated in  <ins> the same order as in the most recent answer.  Any media formats that were not present in the most recent answer MUST be added after all existing formats. </ins> The RTP header extensions MUST only include those that are present in the most recent answer.


sdp, Section 5.1, and, if appropriate, an "a=max-message-size" line, as defined in I-D.ietf-mmusic-sctp-sdp, Section 6.1. <del> As discussed above, the following attributes are included only if the m= section either has a unique address or is associated with the bundle-tag: "a=ice-ufrag", "a=ice-pwd", "a=fingerprint", "a=dtls-id", and "a=setup". </del>  Once all m= sections have been generated, a session-level "a=group" attribute MUST be added as specified in RFC5888.  This attribute MUST If a data channel m= section has been offered, a m= section MUST also be generated for data.  The <media> field MUST be set to <del> "application" and the <proto> and "fmt" fields MUST be set to exactly match the fields in the offer.  Note that if media m= sections are bundled into a data m= section, then certain TRANSPORT and IDENTICAL attributes may appear in the data m= section even if they would otherwise only be appropriate for a media m= section (e.g., "a=rtcp- mux"). </del>  Within the data m= section, an "a=mid" line MUST be generated and included as described above, along with an "a=sctp-port" line sdp, Section 5.1, and, if appropriate, an "a=max-message-size" line, as defined in I-D.ietf-mmusic-sctp-sdp, Section 6.1. <del> As discussed above, the following attributes are included only if the m= section is not bundled into another m= section: "a=ice-ufrag", "a=ice-pwd", "a=fingerprint", "a=dtls-id", and "a=setup". </del>  If "a=group" attributes with semantics of "BUNDLE" are offered, corresponding session-level "a=group" attributes MUST be added as

NAME PTAL at this. I realized the answer section also needed to be updated to match the new offer text, so I made some changes there which involved a bit of massaging of the text added in .
LGTM

sdp, Section 5.1, and, if appropriate, an "a=max-message-size" line, as defined in I-D.ietf-mmusic-sctp-sdp, Section 6.1.  <ins> As discussed above, the following attributes of category IDENTICAL or TRANSPORT are included only if the data m= section either has a unique address or is associated with the bundle-tag (e.g., if it is the only m= section): "a=ice-ufrag" "a=ice-pwd" "a=fingerprint" "a=setup" "a=dtls-id" </ins> Once all m= sections have been generated, a session-level "a=group" attribute MUST be added as specified in RFC5888.  This attribute MUST If a data channel m= section has been offered, a m= section MUST also be generated for data.  The <media> field MUST be set to  <ins> "application" and the <proto> and <fmt> fields MUST be set to exactly match the fields in the offer. </ins> Within the data m= section, an "a=mid" line MUST be generated and included as described above, along with an "a=sctp-port" line sdp, Section 5.1, and, if appropriate, an "a=max-message-size" line, as defined in I-D.ietf-mmusic-sctp-sdp, Section 6.1.  <ins> As discussed above, the following attributes of category IDENTICAL or TRANSPORT are included only if the data m= section is not bundled into another m= section: "a=ice-ufrag" "a=ice-pwd" "a=fingerprint" "a=setup" "a=dtls-id" Note that if media m= sections are bundled into a data m= section, then certain TRANSPORT and IDENTICAL attributes may also appear in the data m= section even if they would otherwise only be appropriate for a media m= section (e.g., "a=rtcp-mux"). </ins> If "a=group" attributes with semantics of "BUNDLE" are offered, corresponding session-level "a=group" attributes MUST be added as


parameters are out of bounds, or cannot be applied, processing MUST stop and an error MUST be returned. <del> If the ICE ufrag or password changed from the previous remote description, then an ICE restart is needed, as described in Section 9.1.1.1 of RFC5245.  If the description is of type "offer", mark that an ICE restart is needed.  If the description is of type "answer" and the current local description is also an ICE restart, then signal the ICE agent to begin checks as described in Section 9.3.1.1 of RFC5245.  An answer MUST change the ufrag and password in an answer if and only if ICE is restarting, as described in Section 9.2.1.1 of RFC5245. </del>  Configure the ICE components associated with this media section to use the supplied ICE remote ufrag and password for their described in Section 9.2.1.3 of RFC5245. If the remote DTLS fingerprint has been changed or the dtls-id has <del> changed, tear down the DTLS connection.  If a DTLS connection needs to be torn down but the answer does not indicate an ICE restart, an error MUST be generated.  If an ICE restart is performed without a change in dtls-id or fingerprint, then the same DTLS connection is continued over the new ICE channel. </del>  If no valid DTLS connection exists, prepare to start a DTLS connection, using the specified roles and fingerprints, on any If the m= section proto value indicates use of SCTP: <del> If no SCTP association yet exists, prepare to initiate a SCTP </del>  association over the associated ICE component and DTLS connection, using the local SCTP port value from the local description, and the remote SCTP port value from the remote

ICE credentials, DTLS fingerprint and SCTP port are allowed to change, which is necessary to support sequential forking with pranswers.
I still need to read this all carefully but at first glance looks reasonable to me.
LGTM. NAME do you want to take another pass? NAME do you want to take a look?
LGTM

parameters are out of bounds, or cannot be applied, processing MUST stop and an error MUST be returned.  <ins> If the PeerConnection state is "have-local-offer", and the ICE ufrag or password changed from the previous remote description, then an ICE restart is needed, as described in Section 9.1.1.1 of RFC5245.  If the description is of type "offer", note that an ICE restart is needed.  If the description is of type "answer" or "pranswer" and the current local description is also an ICE restart, then signal the ICE agent to begin checks as described in Section 9.3.1.1 of RFC5245.  An answerer MUST change the ufrag and password in an answer if and only if ICE is restarting, as described in Section 9.2.1.1 of RFC5245. If the PeerConnection state is "have-remote-pranswer", and the ICE ufrag or password changed from the previous provisional answer, then signal the ICE agent to discard any previous ICE check list state for the m= section and begin checks as if this were the first answer.  However, such an answer MAY only change the ICE ufrag or password if the local offer is starting or restarting ICE for the m= section. </ins> Configure the ICE components associated with this media section to use the supplied ICE remote ufrag and password for their described in Section 9.2.1.3 of RFC5245. If the remote DTLS fingerprint has been changed or the dtls-id has  <ins> changed, tear down the DTLS connection.  This includes the case when the PeerConnection state is "have-remote-pranswer".  If a DTLS connection needs to be torn down but the answer does not indicate an ICE restart or, in the case of "have-remote-pranswer", new ICE credentials, an error MUST be generated.  If an ICE restart is performed without a change in dtls-id or fingerprint, then the same DTLS connection is continued over the new ICE channel. </ins> If no valid DTLS connection exists, prepare to start a DTLS connection, using the specified roles and fingerprints, on any If the m= section proto value indicates use of SCTP:  <ins> If an SCTP association exists, and the remote SCTP port has changed, discard the existing SCTP association.  This includes the case when the PeerConnection state is "have-remote- pranswer". If no valid SCTP association exists, prepare to initiate a SCTP </ins> association over the associated ICE component and DTLS connection, using the local SCTP port value from the local description, and the remote SCTP port value from the remote


MUST be parsed as described in RFC4566, Section 6, and its value stored. <del> Any "a=ssrc" or "a=ssrc-group" attributes MUST be parsed as specified in RFC5576, Sections 4.1-4.2, and their values stored. </del>  Any "a=extmap" attributes MUST be parsed as specified in RFC5285, Section 5, and their values stored.

removes parsing of a=ssrc and a=ssrc-group. The createOffer parts were removed in the -17 draft.
Wouldn't it make more sense to add the ssrc-group back into the draft to allow proper handling of RTX.
I'm fine with removing this
Not sure why we need to remove this since this can be used to indicate how to init the demux table.
I do think removing ssrc-group would be a good idea though since we don't plan to use it. We should also make clear that a=ssrc is only used for seeding the demux table.
To be specific: 5.9 (remote desc) should be updated to indicate that any a=ssrc values are supplied to the demuxer, and we should remove discussion of a=ssrc-group here.
You arguments to keep this make sense. I'm fine with keeping it.
Changed it to only remove a=ssrc-group, since IIUC the demux algorithm does not consider it. NAME does this seem reasonable to you? Separately I will add text in 5.9 to say that the a=ssrc values should be supplied to the demuxer.
It was non-obvious to me that RTX has to use the same MID RTP header extension values as the RTP stream it covers. Now the same argument for priming the demuxer could be made for the SSRC learned from ssrc-group. But if we assume that RTX packets will not be the first packets which you receive it's probably fine.
Remaining task from

MUST be parsed as described in RFC4566, Section 6, and its value stored.  <ins> Any "a=ssrc" attributes MUST be parsed as specified in RFC5576, Section 4.1, and their values stored. </ins> Any "a=extmap" attributes MUST be parsed as specified in RFC5285, Section 5, and their values stored.


but supply "a=fingerprint" and "a=rtcp-fb" attributes, indicating its willingness to support "(UDP,TCP)/TLS/RTP/SAVPF".  In order to simplify compatibility with such endpoints, JSEP implementations MUST <del> follow the following rules when processing the media m= sections in an offer: </del>  <del> The profile in any "m=" line in any answer MUST exactly match the profile provided in the offer. </del>  <del> Any profile matching the following patterns MUST be accepted: "RTP/[S]AVP[F]" and "(UDP/TCP)/TLS/RTP/SAVP[F]" </del>  Because DTLS-SRTP is REQUIRED, the choice of SAVP or AVP has no effect; support for DTLS-SRTP is determined by the presence of one

Proposal for how to clarify that when JSEP implementation generates an answer it needs to have the proto value identical to what is in the offer.
NAME do you want to take a look at this one?
BLOCKER: The first bullet on page 35 has a normative statement about the AVT profile strings that must be accepted, but uses an unspecified grammar to actually specify the string. If this is normative, it needs to be formal. Either specify the string using a formal and cited grammar, or provide an exhaustive list.
Proposal on editor's call is to use POSIX extended regular expressions. URL I believe this would give us the expressions. (UDP|TCP)/TLS/RTP/SAVPF? and: RTP/S?AVPF?
You're sure you want to pull in another reference for regexes instead of just listing all eight valid values?
I suggest we merge this without dealing with the formal grammar issue.

but supply "a=fingerprint" and "a=rtcp-fb" attributes, indicating its willingness to support "(UDP,TCP)/TLS/RTP/SAVPF".  In order to simplify compatibility with such endpoints, JSEP implementations MUST  <ins> follow the following rules when processing the media m= sections in a received offer: </ins>  <ins> Any profile in the offer matching the following patterns MUST be accepted: "RTP/[S]AVP[F]" and "(UDP|TCP)/TLS/RTP/SAVP[F]". </ins>  <ins> The profile in any "m=" line in any generated answer MUST exactly match the profile provided in the offer. </ins> Because DTLS-SRTP is REQUIRED, the choice of SAVP or AVP has no effect; support for DTLS-SRTP is determined by the presence of one


3.4. <del> When a new ICE candidate is available, the ICE Agent will notify the application via a callback; these candidates will automatically be added to the local session description.  When all candidates have been gathered, the callback will also be invoked to signal that the gathering process is complete. </del> 3.4.1.  Candidate trickling is a technique through which a caller may incrementally provide candidates to the callee after the initial offer has been dispatched; the semantics of "Trickle ICE" are defined in cases where gathering is not performed prior to initiating the call. <del> JSEP supports optional candidate trickling by providing APIs that provide control and feedback on the ICE candidate gathering process. Applications that support candidate trickling can send the initial offer immediately and send individual candidates when they get the notified of a new candidate; applications that do not support this feature can simply wait for the indication that gathering is complete, and then create and send their offer, with all the candidates, at this time. </del>  Upon receipt of trickled candidates, the receiving application will supply them to its ICE Agent.  This triggers the ICE Agent to start using the new remote candidates for connectivity checks. <del> 3.4.1.1. </del>  As with session descriptions, the syntax of the IceCandidate object provides some abstraction, but can be easily converted to and from Implementations receiving an ICE Candidate object SHOULD use the MID if they implement that functionality, or the m-line index, if not. <del> 3.4.2. </del>  JSEP applications typically inform the browser to begin ICE gathering via the information supplied to setLocalDescription, as this is where <del> the app specifies the number of media streams for which to gather candidates.  However, to accelerate cases where the application knows the number of media streams to use ahead of time, it MAY ask the browser to gather a pool of potential ICE candidates to help ensure rapid media setup.  When setLocalDescription is eventually called, and the browser goes to gather the needed ICE candidates, it SHOULD start by checking if any candidates are available in the pool.  If there are candidates in the pool, they SHOULD be handed to the application immediately via the ICE candidate callback.  If the pool becomes depleted, either because a larger-than-expected number of media streams is used, or because the pool has not had enough time to gather candidates, the remaining candidates are gathered as usual. </del>  3.5. The PeerConnection constructor allows the application to specify global parameters for the media session, such as the STUN/TURN <del> servers and credentials to use when gathering candidates.  The size of the ICE candidate pool can also be set, if desired; this indicates the number of ICE components to pre-gather candidates for.  If the application does not indicate a candidate pool size, the browser may select any default candidate pool size. In addition, the application can specify its preferred policy regarding use of BUNDLE, the multiplexing mechanism defined in I- D.ietf-mmusic-sdp-bundle-negotiation.  By specifying a policy from the list below, the application can control how aggressively it will try to BUNDLE media streams together.  The set of available policies is as follows: </del>  The application will BUNDLE all media streams of the same type together.  That is, if there are multiple audio and multiple video non-BUNDLE-aware endpoints, but require separate candidates to be gathered for each media stream.  4.1.2. The createOffer method generates a blob of SDP that contains a 4.1.9. <del> The updateIce method allows the configuration of the ICE Agent to be changed during the session, primarily for changing which types of local candidates are provided to the application and used for connectivity checks.  A callee may initially configure the ICE Agent to use only relay candidates, to avoid leaking location information, but update this configuration to use all candidates once the call is accepted. </del>  <del> Regardless of the configuration, the gathering process collects all available candidates, but excluded candidates will not be surfaced in onicecandidate callback or used for connectivity checks. </del>  This call may result in a change to the state of the ICE Agent, and may result in a change to media state if it results in connectivity Each "a=mid" line MUST stay the same. <del> Each "a=ice-ufrag" and "a=ice-pwd" line MUST stay the same unless the "IceRestart" option (sec.options-handling was specified.  Note that it's not clear why you would actually want to do this, since at this point ICE has not yet started and is thus unlikely to need a restart. </del>  For MediaStreamTracks that are still present, the "a=msid", "a=ssrc", and "a=ssrc-group" lines MUST stay the same. this option is specified in the case where at least N audio MediaStreamTracks have already been added to the PeerConnection, or N non-rejected m= sections with media type "audio" would otherwise be <del> generated, it has no effect.  For backwards compatibility, a value of "true" is interpreted as equivalent to N=1. </del>  5.2.3.2. this option is specified in the case where at least N video MediaStreamTracks have already been added to the PeerConnection, or N non-rejected m= sections with media type "video" would otherwise be <del> generated, it has no effect.  For backwards compatibility, a value of "true" is interpreted as equivalent to N=1. </del>  5.2.3.3. offer MUST indicate an ICE restart by generating new ICE ufrag and pwd attributes, as specified in RFC5245, Section 9.1.1.1.  If this option is specified on an initial offer, it has no effect (since a <del> new ICE ufrag and pwd are already generated).  This option is useful for reestablishing connectivity in cases where failures are detected. </del>  5.3.

Tony: Explain, give example for ICE candidate pool () Magnus: ICE policy should be overridable by local policy () Explain ICE gathering phase () Replace updateIce with setConfiguration Define behavior of setConfiguration, explain how changing ICE policy works () Default candidate pool size to zero ()
OK, I rewrote a bunch of stuff here to make it clear that changes to the candidate policy require ICE restart, and ICE restart happens automatically in createOffer if the ICE configuration has changed.
PTAL
Note to self: fix the Travis failure on a bad "URL" xref
PTAL
This all LGTM.
Does it happen on PC construction, or on receiving a remote offer? Justin and Cullen thought the former, with unlimited binding keepalive time; Eric thought the latter.
Cullen and I talked about this. I think I mostly hadn't thought through the implications of unlimited keepalive. Based on that, I think we adopt the J/C interpretation but strongly advise a 0-sized default pool.
worksforme
On Jul 4, 2014, at 4:31 PM, ekr EMAIL wrote: I’m fine with default size of zero as long as when the JS explicitly sets it to something else they get that
Fixed by
Section 4.1.9: Should this section discuss that it might be browser that has overriding controls regarding if other candidates then relay ones may be provided, i.e. privacy mode? JU: Probably. The use of host candidates is something that might be forbidden by local policy. I think the right thing to do would be to introduce the concept of iceTransports in section 3.4 (ICE), and then refer to it here in updateIce (now called setConfiguration), as well as the ctor section, where the initial policy can be set. Section 5.2.1: Structure in relation between RTP media and DATA channel. Maybe you should try to find a structure that makes the difference between the two types of transport more clear, and what applies to the perspective. JU: Agree this could be improved. 5.2.3.3. VoiceActivityDetection If the "VoiceActivityDetection" constraint is specified, with a value of "true", the offer MUST indicate support for silence suppression by including comfort noise ("CN") codecs for each supported clock rate, as specified in [RFC3389], Section 5.1. As currently specified this text requires the usage of a comfort noise codec, currently there is no such on required. I think the "MUST" needs to be rewritten. JU: I think this needs to be specified as a MUST in RTP usage then. Otherwise, this setting won't work in some browsers, leading to nondeterministic behavior. This should also be updated to set usedtx=1 for Opus. Section 5.3.1: Note that for simplicity, the answerer MAY use different payload types for codecs than the offerer, as it is not prohibited by Section 6.1. I react to the word simplicity here. I never consider usage of different PTs per direction anything simple. But, yes it is allowed by RFC 3264. But I kind of protest to encourage the usage. JU: Clearly this needs more explanation. The basic issue is the fact that using the same payload types gets really hairy when using RTX and when bundling. We can add an example of the problem.
Proposed resolution is update RTP Usage updated to say 3389 is MTI
Re: 5.2.3.3 - resolution today to suggest 3389 be MTI in rtp-usage.
Proposed resolution for 5.3.1 is to remove "simplicity" and provide an example
Local policy override part addressed in .
I believe this is fixed in the current version. There has been a lot of rewriting here. I'm going to declare this closed and let Magnus re-raise if he is still sad. I believe this is addressed in PR.
I filed a new issue for this last point,
The proposed scenario is where .iceTransports is set to 'relay', and so relay gathering occurs first; non-relay gathering only occurs after .iceTransports is changed to 'all'. The flow is something like: new PC({iceTransports: 'relay'}) setRD(offer) createAnswer setLD(answer) onicegatheringstatechange(gathering) onicecandidate(relay1) onicecandidate(relay2) A: setConfiguration({iceTransports: 'all'}) onicecandidate(null) onicegatheringstatechange(complete) B: setConfiguration({iceTransports: 'all'}) In case A, we could definitely release the gathered ICE candidates immediately, with no issues. But in case B, does it make sense to emit them, since gathering has completed? Options: 1) Emit them. No state change occurs. You called this API, you deal with it. (My preference.) 2) Transition back to gathering, emit the candidates (which will happen immediately, necessarily), go back to complete. (Changes the meaning of a gathering transition.) 3) No candidates are emitted, no state change occurs. The new type of candidates is gathered on the next ICE restart. (Complicates the use case above. But allows changing type to a more restrictive type.)
You should raise this on the list. I think that the non-relay candidates are effectively in the candidate pool. Not that that helps much.
Agree regarding the pool, i.e. they are immediately available. And that it doesn't help much. Took this to the list.
The consensus seems to be that 3) above is preferred.
Fixed by
Editorial changes: I guess my one comment addressing the document as a whole would be that the examples used in the draft are helpful in explaining certain aspects and therefore even more examples would be even more helpful. J: Which particular examples were most useful - the inline hand-wavy descriptions, the API flows, or the example SDP? Section 1.1, Paragraph 3, Last Sentence I think this can be reworded to be clearer and more powerful, something such as: "JSEP removes the browser almost entirely from the core signaling flow. The Javascript application needs interfaces for only (1) passing in local and remote session descriptions and (2) interacting with the ICE state machine." Perhaps the exact wording I've suggested is not ideal, but something that more clearly shows that JSEP removes the browser from the signaling flow and that the application (and therefore, the application's developer) needs to do only two things for establishing a session. The way it is worded now is unclear at first read and does not adequately persuade me why JSEP is awesome (IMO). J: Agree your wording is more direct. We'll rework this part. Section 3.4.2, Paragraph 1 An example of a situation where the browser might know the number of media streams ahead of time might be useful for context here, if one is easily explained. J: Sure, that makes sense. The typical case here is for an endpoint that wants to be able to quickly set up a received call. The caller has the ability to just start the call and leave it in the local-offer state instead. Section 3.5.1, Paragraph 2 How does the application decide whether to apply as provisional or final? Does JSEP care at all or is this left entirely up to the application to decide? This is expounded on somewhat in the 2 paragraphs that follow, but I still don't feel like these questions are completely answered. J: This is an application decision; in JSEP's opinion, forking should overall be avoided. Section 4.1.2, Paragraph 2 I think this sentence would be clearer if "certain parts that are" was replaced with "functionality that is". J: Agreed. Section 4.1.2, Paragraph 3 This sentence was too hard to compute in my opinion, and I'm still not quite sure what "the document" refers to. I think rewording would be beneficial. J: Agreed - refer to "the RFC" or somesuch Section 5.1.2, bullet R-2 This shouldn't be MAY because it is not referring to an optional implementation specification of JSEP but rather a possible scenario that JSEP needs to support. It should read as just a warning and possibly specify that JSEP MUST be equipped to interface with an endpoint that is using a Lite ICE implementation. J: Agree. We'll adjust accordingly (MAY->may, MUST handle ice-lite) Section 5.2.1, bullet 3 Is there a reason to ignore the following SHOULD from RFC4566? It seems like "-" and " " are both equally meaningless, so why deviate from the standard? (I'm also not sure why we need to match it with the username in the o= line). There may be good reason for both of these, but it is not clear to me from reading the draft so I wanted to bring it up. J: It's entirely arbitrary. Since they are meaningless, I figured using similar meaningless values made this more clear than individual meaningless values. We can add some text to make this clear. Section 5.2.1, Paragraph 3 Consider adding: "URL specified in [RFC4566] Section 5.14..." The draft references specific sections for the other SDP fields and I think it is useful here as well. J: Sounds good. Section 5.2.3, Paragraph 1 I think an example of when this would be useful might be nice for context. J: I assume you are asking for when each of the individual constraints parameters would be useful. That sounds helpful. (also dictionary change) Section 5.2.3.1 AND Section 5.2.3.2, Paragraph 1 The use of "N" is confusing. Is "N" referencing an integer value or a string with value "N". I think removing the quotes around "N" would make it entirely more understandable. J: Agreed. Constraints have been replaced with dictionaries, so we can clearly refer to this as an integer var. Section 5.3.1, Paragraph 5 This sentence is long and hard to parse. I think rewording and/or breaking up would be beneficial. J: OK.
ICE candidate pool part addressed by . I think this is now ready to be closed, but worth a double check.
I think this is now done
The text relies on the phrase "most recent gathering phase" to describe which candidates are present in SDP. Justin enumerated a few cases where the browser gathers a completely new set of candidates for an m= section (or component thereof): when a new m= section is added (which happens for a new RTCPeerConnection obviously) when an m= section did have a port of 0, but is repurposed for new media (basically the same scenario as above) ICE restart This needs a clearer definition, or maybe just a single clear description of what it means to do this. This can probably tie into the whole process of describing when candidate events fire and the interaction between that and setLocalDescription.
Martin, could you give us a PR that would satisfy you

3.4.  3.4.1. <ins> JSEP gathers ICE candidates as needed by the application.  Collection of ICE candidates is referred to as a gathering phase, and this is triggered either by the addition of a new or recycled m= line to the local session description, or new ICE credentials in the description, indicating an ICE restart.  Use of new ICE credentials can be triggered explicitly by the application, or implicitly by the browser in response to changes in the ICE configuration. When a new gathering phase starts, the ICE Agent will notify the application that gathering is occurring through a callback.  Then, when each new ICE candidate becomes available, the ICE Agent will supply it to the application via an additional callback; these candidates will also automatically be added to the local session description.  Finally, when all candidates have been gathered, a callback will be dispatched to signal that the gathering process is complete. Note that gathering phases only gather the candidates needed by new/recycled/restarting m= lines; other m= lines continue to use their existing candidates. 3.4.2. </ins> Candidate trickling is a technique through which a caller may incrementally provide candidates to the callee after the initial offer has been dispatched; the semantics of "Trickle ICE" are defined in cases where gathering is not performed prior to initiating the call.  <ins> JSEP supports optional candidate trickling by providing APIs, as described above, that provide control and feedback on the ICE candidate gathering process.  Applications that support candidate trickling can send the initial offer immediately and send individual candidates when they get the notified of a new candidate; applications that do not support this feature can simply wait for the indication that gathering is complete, and then create and send their offer, with all the candidates, at this time. </ins> Upon receipt of trickled candidates, the receiving application will supply them to its ICE Agent.  This triggers the ICE Agent to start using the new remote candidates for connectivity checks.  <ins> 3.4.2.1. </ins> As with session descriptions, the syntax of the IceCandidate object provides some abstraction, but can be easily converted to and from Implementations receiving an ICE Candidate object SHOULD use the MID if they implement that functionality, or the m-line index, if not.  <ins> 3.4.3. Typically, when gathering ICE candidates, the browser will gather all possible forms of initial candidates - host, server reflexive, and relay.  However, in certain cases, applications may want to have more specific control over the gathering process, due to privacy or related concerns.  For example, one may want to suppress the use of host candidates, to avoid exposing information about the local network, or go as far as only using relay candidates, to leak as little location information as possible (note that these choices come with corresponding operational costs).  To accomplish this, the browser MUST allow the application to restrict which ICE candidates are used in a session.  In addition, administrators may also wish to control the set of ICE candidates, and so the browser SHOULD also allow control via local policy, with the most restrictive policy prevailing. There may also be cases where the application wants to change which types of candidates are used while the session is active.  A prime example is where a callee may initially want to use only relay candidates, to avoid leaking location information to an arbitrary caller, but then change to use all candidates (for lower operational cost) once the user has indicated they want to take the call.  For this scenario, the browser MUST allow the candidate policy to be changed in mid-session, subject to the aforementioned interactions with local policy. To administer the ICE candidate policy, the browser will determine the current setting at the start of each gathering phase.  Then, during the gathering phase, the browser MUST NOT expose candidates disallowed by the current policy to the application, use them as the source of connectivity checks, or indirectly expose them via other fields, such as the raddr/rport attributes for other ICE candidates. Later, if a different policy is specified by the application, the application can apply it by kicking off a new gathering phase via an ICE restart. 3.4.4. </ins> JSEP applications typically inform the browser to begin ICE gathering via the information supplied to setLocalDescription, as this is where  <ins> the app specifies the number of media streams, and thereby ICE components, for which to gather candidates.  However, to accelerate cases where the application knows the number of ICE components to use ahead of time, it may ask the browser to gather a pool of potential ICE candidates to help ensure rapid media setup. When setLocalDescription is eventually called, and the browser goes to gather the needed ICE candidates, it SHOULD start by checking if any candidates are available in the pool.  If there are candidates in the pool, they SHOULD be handed to the application immediately via the ICE candidate callback.  If the pool becomes depleted, either because a larger-than-expected number of ICE components is used, or because the pool has not had enough time to gather candidates, the remaining candidates are gathered as usual. One example of where this concept is useful is an application that expects an incoming call at some point in the future, and wants to minimize the time it takes to establish connectivity, to avoid clipping of initial media.  By pre-gathering candidates into the pool, it can exchange and start sending connectivity checks from these candidates almost immediately upon receipt of a call.  Note though that by holding on to these pre-gathered candidates, which will be kept alive as long as they may be needed, the application will consume resources on the STUN/TURN servers it is using. </ins> 3.5. The PeerConnection constructor allows the application to specify global parameters for the media session, such as the STUN/TURN  <ins> servers and credentials to use when gathering candidates, as well as the initial ICE candidate policy and pool size, and also the BUNDLE policy to use. If an ICE candidate policy is specified, it functions as described in sec.ice-candidate-policy, causing the browser to only surface the permitted candidates to the application, and only use those candidates for connectivity checks.  The set of available policies is as follows: All candidates will be gathered and used. Candidates with private IP addresses [RFC1918] will be filtered out.  This prevents exposure of internal network details, at the cost of requiring relay usage even for intranet calls, if the NAT does not allow hairpinning as described in [RFC4787], section 6. All candidates except relay candidates will be filtered out.  This obfuscates the location information that might be ascertained by the remote peer from the received candidates.  Depending on how the application deploys its relay servers, this could obfuscate location to a metro or possibly even global level. Although it can be overridden by local policy, the default ICE candidate policy MUST be set to allow all candidates, as this minimizes use of application STUN/TURN server resources. If a size is specified for the ICE candidate pool, this indicates the number of ICE components to pre-gather candidates for.  Because pre- gathering results in utilizing STUN/TURN server resources for potentially long periods of time, this must only occur upon application request, and therefore the default candidate pool size MUST be zero. Lastly, the application can specify its preferred policy regarding use of BUNDLE, the multiplexing mechanism defined in I-D.ietf-mmusic- sdp-bundle-negotiation.  By specifying a policy from the list below, the application can control how aggressively it will try to BUNDLE media streams together.  The set of available policies is as follows: </ins> The application will BUNDLE all media streams of the same type together.  That is, if there are multiple audio and multiple video non-BUNDLE-aware endpoints, but require separate candidates to be gathered for each media stream. <ins> As it provides the best tradeoff between performance and compatibility with legacy endpoints, the default BUNDLE policy MUST be set to "balanced". </ins> 4.1.2. The createOffer method generates a blob of SDP that contains a 4.1.9.  <ins> The setConfiguration method allows the global configuration of the PeerConnection, which was initially set by constructor parameters, to be changed during the session.  The effects of this method call depend on when it is invoked, and differ depending on which specific parameters are changed: Any changes to the STUN/TURN servers to use affect the next gathering phase.  If gathering has already occurred, this will cause the next call to createOffer to generate new ICE credentials, for the purpose of forcing an ICE restart and kicking off a new gathering phase, in which the new servers will be used. If the ICE candidate pool has a nonzero size, any existing candidates will be discarded, and new candidates will be gathered from the new servers. Any changes to the ICE candidate policy also affect the next gathering phase, in similar fashion to the server changes described above.  Note though that changes to the policy have no effect on the candidate pool, because pooled candidates are not surfaced to the application until a gathering phase occurs, and so any necessary filtering can still be done on any pooled candidates. Any changes to the ICE candidate pool size take effect immediately; if increased, additional candidates are pre-gathered; if decreased, the now-superfluous candidates are discarded. </ins>  <ins> Any changes to the BUNDLE policy take effect immediately, i.e. any future tracks added to the PeerConnection will have their bundle-only state marked accordingly. </ins> This call may result in a change to the state of the ICE Agent, and may result in a change to media state if it results in connectivity Each "a=mid" line MUST stay the same.  <ins> Each "a=ice-ufrag" and "a=ice-pwd" line MUST stay the same, unless the ICE configuration has changed (either changes to the supported STUN/TURN servers, or the ICE candidate policy), or the "IceRestart" option (sec.icerestart was specified. </ins> For MediaStreamTracks that are still present, the "a=msid", "a=ssrc", and "a=ssrc-group" lines MUST stay the same. this option is specified in the case where at least N audio MediaStreamTracks have already been added to the PeerConnection, or N non-rejected m= sections with media type "audio" would otherwise be  <ins> generated, it has no effect.  For backwards compatibility with pre- standard versions of this specification, a value of "true" is interpreted as equivalent to N=1. </ins> 5.2.3.2. this option is specified in the case where at least N video MediaStreamTracks have already been added to the PeerConnection, or N non-rejected m= sections with media type "video" would otherwise be  <ins> generated, it has no effect.  For backwards compatibility with pre- standard versions of this specification, a value of "true" is interpreted as equivalent to N=1. </ins> 5.2.3.3. offer MUST indicate an ICE restart by generating new ICE ufrag and pwd attributes, as specified in RFC5245, Section 9.1.1.1.  If this option is specified on an initial offer, it has no effect (since a  <ins> new ICE ufrag and pwd are already generated).  Similarly, if the ICE configuration has changed, this option has no effect, since new ufrag and pwd attributes will be generated automatically.  This option is primarily useful for reestablishing connectivity in cases where failures are detected by the application. </ins> 5.3.


of codecs sent to a remote party indicates what the local side is willing to receive, which, when intersected with the set of codecs the remote side supports, specifies what the remote side should send. <del> However, not all parameters follow this rule; for example, the SRTP parameters RFC4568 sent to a remote party indicate what the local side will use to encrypt, and thereby what the remote party should expect to receive; the remote party will have to accept these parameters, with no option to choose a different value.  [[OPEN ISSUE: This is not correct because we removed SDES (https://github.com/rtcweb-wg/jsep/issues/10)]] </del>  In addition, various RFCs put different conditions on the format of <del> offers versus answers.  For example, a offer may propose multiple SRTP configurations, but an answer may only contain a single SRTP configuration.  [[OPEN ISSUE: See issue 10 above.]] </del>  Lastly, while the exact media parameters are only known only after an offer and an answer have been exchanged, it is possible for the "candidate-attribute" field defined for ICE.  For example: The IceCandidate object also contains fields to indicate which m= <del> line it should be associated with.  The m line can be identified in one of two ways; either by a m-line index, or a MID.  The m-line index is a zero-based index, with index N referring to the N+1th m-line in the SDP sent by the entity which sent the IceCandidate. The MID uses the "media stream identification", as defined in RFC5888, to identify the m-line.  WebRTC implementations creating an ICE Candidate object MUST populate both of these fields. Implementations receiving an ICE Candidate object SHOULD use the MID if they implement that functionality, or the m-line index, if not. </del>  3.4.2. they reflect transport attributes that are solely under browser control, and the browser MUST NOT honor an attempt to change them: <del> The number, type and port number of m-lines. </del>  The generated ICE credentials (a=ice-ufrag and a=ice-pwd).

Also, update IceCandidate section to use consistent “m= line” terminology, and also make it clearer that use of MID, if present, is a MUST.
WFM
The current example in S 3.2 refers to SDES, but that's not in JSEP any more. We need a new example.

of codecs sent to a remote party indicates what the local side is willing to receive, which, when intersected with the set of codecs the remote side supports, specifies what the remote side should send.  <ins> However, not all parameters follow this rule; for example, the DTLS- SRTP parameters RFC5763 sent to a remote party indicate what certificate the local side will use in DTLS setup, and thereby what the remote party should expect to receive; the remote party will have to accept these parameters, with no option to choose different values. </ins> In addition, various RFCs put different conditions on the format of  <ins> offers versus answers.  For example, a offer may propose an arbitrary number of media streams (i.e. m= sections), but an answer must contain the exact same number as the offer. </ins> Lastly, while the exact media parameters are only known only after an offer and an answer have been exchanged, it is possible for the "candidate-attribute" field defined for ICE.  For example: The IceCandidate object also contains fields to indicate which m=  <ins> line it should be associated with.  The m= line can be identified in one of two ways; either by a m= line index, or a MID.  The m= line index is a zero-based index, with index N referring to the N+1th m= line in the SDP sent by the entity which sent the IceCandidate.  The MID uses the "media stream identification" attribute, as defined in RFC5888, Section 4, to identify the m= line.  JSEP implementations creating an ICE Candidate object MUST populate both of these fields. Implementations receiving an ICE Candidate object MUST use the MID if present, or the m= line index, if not (as it could have come from a non-JSEP endpoint). </ins> 3.4.2. they reflect transport attributes that are solely under browser control, and the browser MUST NOT honor an attempt to change them:  <ins> The number, type and port number of m= lines. </ins> The generated ICE credentials (a=ice-ufrag and a=ice-pwd).


present, but an "AS" value is specified, generate a "TIAS" value using this formula: <del> TIAS = AS * 1000 * 0.95 - 50 * 40 * 8 </del>  The 50 is based on 50 packets per second, the 40 is based on an estimate of total header size, the 1000 changes the unit from

I object to shit sort of crap, if you are too short to do grade 3 math, you are too short to implement this spec.

present, but an "AS" value is specified, generate a "TIAS" value using this formula:  <ins> TIAS = AS * 1000 * 0.95 - (50 * 40 * 8) </ins> The 50 is based on 50 packets per second, the 40 is based on an estimate of total header size, the 1000 changes the unit from


The candidate details are specified in an IceCandidate field, using the same SDP syntax as the "candidate-attribute" field defined in <del> RFC5245, Section 15.1.  For example: </del>  The IceCandidate object contains a field to indicate which ICE ufrag it is associated with, as defined in RFC5245, Section 15.4.  This

Since it has been the cause of actual interop issues in the field, it is probably worth mentioning, in section 3.5.2.1, that the IceCandidate strings explicitly do not start with "a=".
Sure.

The candidate details are specified in an IceCandidate field, using the same SDP syntax as the "candidate-attribute" field defined in  <ins> RFC5245, Section 15.1.  Note that this field does not contain an "a=" prefix, as indicated in the following example: </ins> The IceCandidate object contains a field to indicate which ICE ufrag it is associated with, as defined in RFC5245, Section 15.4.  This


usage, Section 5.2.  Any header extensions that require encryption MUST be specified as indicated in RFC6904, Section 4. <del> For each supported RTCP feedback mechanism, an "a=rtcp-fb" mechanism, as specified in RFC4585, Section 4.2.  The list of RTCP feedback mechanisms that SHOULD/MUST be supported is specified in I-D.ietf-rtcweb-rtp-usage, Section 5.1. </del>  If the RtpTransceiver has a sendrecv or sendonly direction: in RFC6904, Section 4. For each supported RTCP feedback mechanism that is present in the <del> offer, an "a=rtcp-fb" mechanism, as specified in RFC4585, Section 4.2.  The list of RTCP feedback mechanisms that SHOULD/ MUST be supported is specified in I-D.ietf-rtcweb-rtp-usage, Section 5.1. </del>  If the RtpTransceiver has a sendrecv or sendonly direction:

Page 51, bullet starting "For each supported RTCP feedback...": replace "an 'a=rtcp-fb' mechanism" with "an 'a=rtcp-fb' line".
Section Initial Answers Text is For each supported RTCP feedback mechanism that is present in the offer, an "a=rtcp-fb" mechanism, as specified in [RFC4585], Section 4.2. The list of RTCP feedback mechanisms that SHOULD/ MUST be supported is specified in [I-D.ietf-rtcweb-rtp-usage], Section 5.1. Fix trivial typo
Page 38, second-to-last bullet refers to "an 'a=rtcp-fb' mechanism" where it should say "an 'a=rtcp-fb' line".
Agreed

usage, Section 5.2.  Any header extensions that require encryption MUST be specified as indicated in RFC6904, Section 4.  <ins> For each supported RTCP feedback mechanism, an "a=rtcp-fb" line, as specified in RFC4585, Section 4.2.  The list of RTCP feedback mechanisms that SHOULD/MUST be supported is specified in I-D.ietf- rtcweb-rtp-usage, Section 5.1. </ins> If the RtpTransceiver has a sendrecv or sendonly direction: in RFC6904, Section 4. For each supported RTCP feedback mechanism that is present in the  <ins> offer, an "a=rtcp-fb" line, as specified in RFC4585, Section 4.2. The list of RTCP feedback mechanisms that SHOULD/MUST be supported is specified in I-D.ietf-rtcweb-rtp-usage, Section 5.1. </ins> If the RtpTransceiver has a sendrecv or sendonly direction:


Section 5.3; to match the "o=" line, a single dash SHOULD be used as the session name, e.g. "s=-".  Note that this differs from the advice in RFC4566 which proposes a single space, but as both "o=" <del> and "s=" are meaningless, having the same meaningless value seems clearer. </del>  Session Information ("i="), URI ("u="), Email Address ("e="), Phone Number ("p="), Repeat Times ("r="), and Time Zones ("z=")

…eless.
Section 5.2.1 contains the statement "both 'o=' and 's=' are meaningless" -- this should be qualified with "in JSEP." These fields are not generally meaningless in all uses of SDP.
Sure.

Section 5.3; to match the "o=" line, a single dash SHOULD be used as the session name, e.g. "s=-".  Note that this differs from the advice in RFC4566 which proposes a single space, but as both "o="  <ins> and "s=" are meaningless in JSEP, having the same meaningless value seems clearer. </ins> Session Information ("i="), URI ("u="), Email Address ("e="), Phone Number ("p="), Repeat Times ("r="), and Time Zones ("z=")


MUST be returned. Next, the SessionDescription is parsed into a data structure, as <del> described in the sec.parsing-a-desc section below.  If parsing fails for any reason, processing MUST stop and an error MUST be returned. </del>  Finally, the parsed SessionDescription is applied as described in the sec.applying-a-local-desc section below.

It seems like there are two implementation strategies here: Keep a parsed version Re-parse. I think we probably could dispense with this sentence, but I don't object to it, because I think of "lookup in cache" as "parse".
Knowing how things go in the real world, I'm a bit reluctant to make this change, but it should address Adam's concern.

MUST be returned. Next, the SessionDescription is parsed into a data structure, as  <ins> described in the sec.parsing-a-desc section below. </ins> Finally, the parsed SessionDescription is applied as described in the sec.applying-a-local-desc section below.


Attributes which SDP permits to either be at the session level or the media level SHOULD generally be at the media level even if they are <del> identical.  This promotes readability, especially if one of a set of initially identical attributes is subsequently changed. </del>  Attributes other than the ones specified above MAY be included, except for the following attributes which are specifically

Page 41 contains a statement reading "This promotes readability," which might be read by some as promoting machine parsing rather than troubleshooting. I propose replacing "readability" with "troubleshooting."
Full text: Attributes which SDP permits to either be at the session level or the media level SHOULD generally be at the media level even if they are identical. This promotes readability, especially if one of a set of initially identical attributes is subsequently changed. I'm not sure that 'troubleshooting' is the exact word we're looking for here, but I think we can come up with something.

Attributes which SDP permits to either be at the session level or the media level SHOULD generally be at the media level even if they are  <ins> identical.  This assists development and debugging by making it easier to understand individual media sections, especially if one of a set of initially identical attributes is subsequently changed. </ins> Attributes other than the ones specified above MAY be included, except for the following attributes which are specifically


5.7. <del> When a SessionDescription of any type is supplied to setLocal/ RemoteDescription, the implementation must parse it and reject it if it is invalid.  The exact details of this process are explained below. </del> The SDP contained in the session description object consists of a sequence of text lines, each containing a key-value expression, as described in RFC4566, Section 5.  The SDP is read, line-by-line, and

Adam's concern here was that the local description could never be invalid, since it was generated by the implementation.
Correct. I think you need to either remove setLocal or do: parse and (if setRemote, choke one error).
Editor discussion: this paragraph seems redundant so just remove it? NAME to look.
NAME NAME - ready for re-review
Section 5.7, first paragraph: similar to above, change "setLocal/RemoteDescription" to "setRemoteDescription."
Section Parsing a Session Description Text is When a SessionDescription of any type is supplied to setLocal/ RemoteDescription, the implementation must parse it and reject it if it is invalid. The exact details of this process are explained below. Fix as adam sugested

5.7.  The SDP contained in the session description object consists of a sequence of text lines, each containing a key-value expression, as described in RFC4566, Section 5.  The SDP is read, line-by-line, and


Any "a=extmap" lines are parsed as specified in RFC5285, Section 5, and their values are stored. <del> As required by RFC4566, Section 5.13, unknown attribute lines MUST be </del>  ignored. Once all the session-level lines have been parsed, processing as specified in I-D.ietf-mmusic-sctp-sdp, Section 6, and the value stored.  Otherwise, use the specified default. <del> As required by RFC4566, Section 5.13, unknown attribute lines MUST be </del>  ignored. 5.7.3.

Not sure I love what I have done here.
Section 5.7.2 should include a statement (probably at the end) that implementations may know and process attributes other than those described in this section.
Section Media Section Parsing Text As required by [RFC4566], Section 5.13, unknown attribute lines MUST be ignored. proposal update that text to say something about OK to process things are known but not specified in JSEP.

Any "a=extmap" lines are parsed as specified in RFC5285, Section 5, and their values are stored.  <ins> Other attributes that are not relevant to JSEP may also be present, and implementations SHOULD process any that they recognize.  As required by RFC4566, Section 5.13, unknown attribute lines MUST be </ins> ignored. Once all the session-level lines have been parsed, processing as specified in I-D.ietf-mmusic-sctp-sdp, Section 6, and the value stored.  Otherwise, use the specified default.  <ins> Other attributes that are not relevant to JSEP may also be present, and implementations SHOULD process any that they recognize.  As required by RFC4566, Section 5.13, unknown attribute lines MUST be </ins> ignored. 5.7.3.


continuation of the previous line.  In addition, some blank lines have been added to improve readability but are not valid in SDP. <del> More examples of SDP for WebRTC call flows can be found in I- D.nandakumar-rtcweb-sdp. </del>  7.1.

Section 7 does not acknowledge IPv6. The IAB statement on IPv6 has a recommendation that all protocol specifications have IPv6 examples in them. Since we have a separate example document, and Suhas has indicated that he will be including some IPv6 examples in it, I think you can get away in this document by amending the final paragraph of section 7 as: "More examples of SDP for WebRTC call flows, including examples of IPv6 addresses, can be found in [I-D.ietf-rtcweb-sdp]." I make no promise that other IESG members will find this sufficient, but I'm personally okay with it.

continuation of the previous line.  In addition, some blank lines have been added to improve readability but are not valid in SDP.  <ins> More examples of SDP for WebRTC call flows, including examples with IPv6 addresses, can be found in I-D.nandakumar-rtcweb-sdp. </ins> 7.1.


section with a zero port in the current local description or the current remote description, that m= section MUST be recycled by generating an m= section for the added RtpTransceiver as if the m= <del> section were being added to the session description, placed at the same index as the m= section with a zero port. </del>  If an RtpTransceiver is stopped and is not associated with an m= section, an m= section MUST NOT be generated for it.  This For RtpTransceivers that are still present, any "a=simulcast" line MUST stay the same. <del> If any RtpTransceiver has been stopped, the port MUST be set to zero and all "a=msid" lines MUST be removed. If any RtpTransceiver has been added, and there exists a m= section with a zero port in the current local description or the current remote description, that m= section MUST be recycled by generating a m= section for the added RtpTransceiver as if the m= section were being added to session description, except that instead of adding it, the generated m= section replaces the m= section with a zero port.  The new m= section MUST contain a new MID. </del> If the initial offer was applied using setLocalDescription, and an answer from the remote side has been applied using setRemoteDescription, meaning the PeerConnection is in the "remote-

BLOCKER: The second bullet on page 43 ("If an RtpTranceiver has been stopped and is associated..." is normative and redundant with (and slightly contradictory to) the bullet on page 44 starting "If any RtpTranceiver has been slopped...") which is also normative. Remove one.
Looks like an editorial oversight. I'm inclined to remove the second instance. NAME as FYI
BLOCKER: The bullet at the bottom of of page 42 ("If any RtpTranceiver has been added...") is normative and redundant with the bullet in the middle of page 44 ("If any RtpTranceiver has been added..."), which is also normative. Remove one.
Agreed. Let's remove the second one. NAME as FYI

section with a zero port in the current local description or the current remote description, that m= section MUST be recycled by generating an m= section for the added RtpTransceiver as if the m=  <ins> section were being added to the session description (including a new MID value), and placing it at the same index as the m= section with a zero port. </ins> If an RtpTransceiver is stopped and is not associated with an m= section, an m= section MUST NOT be generated for it.  This For RtpTransceivers that are still present, any "a=simulcast" line MUST stay the same.  If the initial offer was applied using setLocalDescription, and an answer from the remote side has been applied using setRemoteDescription, meaning the PeerConnection is in the "remote-


RTCP transmission for this m= section to use reduced-size RTCP, as specified in RFC5506. <del> If the directional attribute in the answer is of type "sendrecv" or "sendonly", choose the media format to send as the most preferred media format from the remote description that is also present in the answer, as described in RFC3264, Sections 6.1 and 7, and start transmitting RTP media once the underlying transport layers have been established.  If an SSRC has not already been chosen for this outgoing RTP stream, choose a random one.  If media is already being transmitted, the same SSRC SHOULD be used unless the clockrate of the new codec is different, in which case a new SSRC MUST be chosen, as </del>  specified in RFC7160, Section 3.1. The payload type mapping from the remote description is used to

BLOCKER: The final bullet of page 68 refers to answer directionality of "sendrecv" and "sendonly." These are incorrect when applying remote answers, for which these should be "sendrecv" and "recvonly." Please rephrase in terms of whether media is to be sent, or fix in some other way that doesn't get the sense reversed for remote answers.

RTCP transmission for this m= section to use reduced-size RTCP, as specified in RFC5506.  <ins> If the directional attribute in the answer indicates that the JSEP implementation should be sending media ("sendonly" for local answers, "recvonly" for remote answers, or "sendrecv" for either type of answer), choose the media format to send as the most preferred media format from the remote description that is also present in the answer, as described in RFC3264, Sections 6.1 and 7, and start transmitting RTP media once the underlying transport layers have been established.  If an SSRC has not already been chosen for this outgoing RTP stream, choose a random one.  If media is already being transmitted, the same SSRC SHOULD be used unless the clockrate of the new codec is different, in which case a new SSRC MUST be chosen, as </ins> specified in RFC7160, Section 3.1. The payload type mapping from the remote description is used to


An "a=setup" line, as specified in RFC4145, Section 4, and clarified for use in DTLS-SRTP scenarios in RFC5763, Section 5. <del> The role value in the answer MUST be "active" or "passive"; the "active" role is RECOMMENDED. </del>  An "a=tls-id" line, as specified in I-D.ietf-mmusic-dtls-sdp Section 5.3.

Isn't actpass always offered? Not sure I understand the context here.
My understanding is the JSEP compliant implementations are suppose to always use 'actpass' in offers. But you may interop with something which will only present it's current role in a subsequent offer.
If that's the intent, I think that rationale should be spelled out in the text here.
NAME
LGTM
OK, so this took a bit of research to get clear on. First, let me state what I believe the rules are: JSEP endpoints MUST always send actpass in offers. This is defined in http://rtcweb-URL and never modified in 5.2.2 In initial answers, JSEP endpoints (a) MUST send active or passive. (b) if the other side sent something other than actpass, MUST send the complement (c) if the other side sent actpass, SHOULD send active. http://rtcweb-URL In subsquent answers, JSEP endpoints: (a) MUST send active or passive. (b) MUST send something consistent with the current state http://rtcweb-URL The text we are working on here is the initial answer text, therefore, I think that rule 3(b) does not apply, which, I believe, makes the current text correct.
NAME
The explanation from EKR above looks right to me
Actually, 5763 requires it to always be actpass, so we can remove the non-JSEP section. Ugh, but the revision does not require it: URL
I think we have two options here: Get dtls-sdp modified (the offending text is in) URL URL Make JSEP handle this condition, as above. Does anyone know why we changed the rules in dtls-sdp? NAME ^^?
I would have to check the archives in order to find out why we relaxed the must-use-actpass-in-initial-offer rule. Most likely people didn't see a need for not allowing other values. Having said that, JSEP can always mandate sending "actpass" in initial offers. A JSEP implementation must of course still be prepared to receive something else.
That's probably fine, as long as dtls-sdp ensures that everyone has to handle actpass in offers. I don't want people trying to avoid implementing part of the spec by only supporting passive mode or some such.
If you think there is some text indicating that support of "actpass" is optional, that should be corrected.
OK, after all that discussion, I think we need to keep the text that says only JSEP endpoints are guaranteed to do this, but they wwill always do so, which means, I believe that the current text is right, modulo the repeated "the" which the new commit fixes.
Page 52, bullet starting "An 'a=setup' line": add the words "when allowed" to the end of the bullet.
Text is An "a=setup" line, as specified in [RFC4145], Section 4, and clarified for use in DTLS-SRTP scenarios in [RFC5763], Section 5. The role value in the answer MUST be "active" or "passive"; the "active" role is RECOMMENDED. Fix per adam.

An "a=setup" line, as specified in RFC4145, Section 4, and clarified for use in DTLS-SRTP scenarios in RFC5763, Section 5.  <ins> The role value in the answer MUST be "active" or "passive".  When the offer contains the "actpass" value, as will always be the case with JSEP endpoints, the answerer SHOULD use the "active" role. Offers from non-JSEP endpoints MAY send other values for "a=setup", in which case the answer MUST use a value consistent with the value in the offer. </ins> An "a=tls-id" line, as specified in I-D.ietf-mmusic-dtls-sdp Section 5.3.


between the RTX payload type and its associated primary payload type, as described in RFC4588, Section 4.  If any referenced primary payload types are not present, this MUST result in an <del> error. </del>  For each specified fmtp parameter that is supported by the local implementation, enable them on the associated media

The bullet in the middle of page 66 (starting "For each specified media format...") states that unsupported media formats must be ignored. The following bullet specifies that "rtx" media formats that refer to "primary payload types [that] are not present" MUST result in an error. Read naïvely, implementors may very well discard a payload type for lack of understanding, and then discover an "rtx" for that discarded PT, and generate an error ("it's not present!"). These bullets need additional text regarding how they interact with each other.
LGTM with comment

between the RTX payload type and its associated primary payload type, as described in RFC4588, Section 4.  If any referenced primary payload types are not present, this MUST result in an  <ins> error.  Note that RTX payload types may refer to primary payload types which are not supported by the local media implementation, in which case, the RTX payload type MUST also be ignored. </ins> For each specified fmtp parameter that is supported by the local implementation, enable them on the associated media


The RTCP feedback extensions MUST only include those that are present in the most recent answer. <del> The "a=rtcp" line MUST only be added if the most recent answer did not include an "a=rtcp-mux" line. </del>  <del> The "a=rtcp-mux" line MUST only be added if present in the most </del>  recent answer. The "a=rtcp-mux-only" line MUST NOT be added. <del> The "a=rtcp-rsize" line MUST only be added if present in the most recent answer. </del>  An "a=bundle-only" line MUST NOT be added, as indicated in I- D.ietf-mmusic-sdp-bundle-negotiation, Section 6.  Instead, JSEP

The bullets on page 45 use the construct "MUST only" three times. This is confusing, and likely to lead to implementors doing the wrong thing. Please rewrite in the form "The 'a=rtcp' line MUST NOT be added unless..."
In the section "Subsequent Offers" we have the text o The RTCP feedback extensions MUST only include those that are present in the most recent answer. o The "a=rtcp" line MUST only be added if the most recent answer did not include an "a=rtcp-mux" line. o The "a=rtcp-mux" line MUST only be added if present in the most recent answer. Next step - Rewrite as adam suggested.
This works for me.

The RTCP feedback extensions MUST only include those that are present in the most recent answer.  <ins> The "a=rtcp" line MUST NOT be added if the most recent answer included an "a=rtcp-mux" line. </ins>  <ins> The "a=rtcp-mux" line MUST NOT be added unless present in the most </ins> recent answer. The "a=rtcp-mux-only" line MUST NOT be added.  <ins> The "a=rtcp-rsize" line MUST NOT be added unless present in the most recent answer. </ins> An "a=bundle-only" line MUST NOT be added, as indicated in I- D.ietf-mmusic-sdp-bundle-negotiation, Section 6.  Instead, JSEP


the rules and recommendations from I-D.ietf-avtcore-rtp-multi- stream, Section 5.4.1 to select which SSRC to use. <del> If the directional attribute is of type "recvonly" or "inactive", stop transmitting all RTP media, but continue sending RTCP, as described in RFC3264, Section 5.1. </del>  If the m= section proto value indicates use of SCTP:

BLOCKER: The first bullet on page 70 exhibits the same error.
Maybe I am just dumb but I am not seeing this in the text.
Sorry, I mis-entered this one. This is regarding media directionality again.
NAME PTAL and see if there's anything from that we need to do here.

the rules and recommendations from I-D.ietf-avtcore-rtp-multi- stream, Section 5.4.1 to select which SSRC to use.  <ins> If the directional attribute in the answer indicates that the JSEP implementation should not be sending media ("recvonly" for local answers, "sendonly" for remote answers, or "inactive" for either type of answer) stop transmitting all RTP media, but continue sending RTCP, as described in RFC3264, Section 5.1. </ins> If the m= section proto value indicates use of SCTP:


Section 5.14.  For the m= line itself, the following rules MUST be followed: <del> The port value is set to the port of the default ICE candidate for this m= section, but given that no candidates are available yet, the "dummy" port value of 9 (Discard) MUST be used, as indicated in I-D.ietf-ice-trickle, Section 5.1. </del>  To properly indicate use of DTLS, the <proto> field MUST be set to "UDP/TLS/RTP/SAVPF", as specified in RFC5764, Section 8.

BLOCKER: The first bullet on page 37 says that port 9 "MUST be used," which contradicts the behavior required of BUNDLE-only sections (for which port 0 MUST be used). Clarify.
Yes - we need to indicate that bundle-only sections use 0 instead of 9.

Section 5.14.  For the m= line itself, the following rules MUST be followed:  <ins> If the m= section is marked as bundle-only, then the port value MUST be set to 0.  Otherwise, the port value is set to the port of the default ICE candidate for this m= section, but given that no candidates are available yet, the "dummy" port value of 9 (Discard) MUST be used, as indicated in I-D.ietf-ice-trickle, Section 5.1. </ins> To properly indicate use of DTLS, the <proto> field MUST be set to "UDP/TLS/RTP/SAVPF", as specified in RFC5764, Section 8.


exact same number as the offer. Lastly, while the exact media parameters are only known only after an <del> offer and an answer have been exchanged, it is possible for the offerer to receive media after they have sent an offer and before they have received an answer.  To properly process incoming media in this case, the offerer's media handler must be aware of the details of the offer before the answer arrives. </del>  Therefore, in order to handle session descriptions properly, the user agent needs: calls to createOffer and createAnswer. When creating offers, the transceiver direction is directly reflected <del> in the output, even for reoffers.  When creating answers, the </del>  transceiver direction is intersected with the offered direction, as explained in the sec.generating-an-answer section below.

Section 3.2 has a paragraph starting "Lastly, while the actual media parameters are only know after an offer..."; the entire contents of this paragraph appear to be actually false if both ICE and DTLS are in use. I know there's conversation underway on MMUSIC and the WebRTC mailing lists on this topic, but none of them have yet described a situation in which this paragraph is actually true. Please remove it or add a sequence diagram showing how it arises.
It may not be able to receive media (due to lack of DTLS fingerprint), but it can certainly receive ICE checks. We should clarify accordingly.

exact same number as the offer. Lastly, while the exact media parameters are only known only after an  <ins> offer and an answer have been exchanged, the offerer may receive ICE checks, and possibly media (e.g., in the case of a re-offer after a connection has been established) before it receives an answer.  To properly process incoming media in this case, the offerer's media handler must be aware of the details of the offer before the answer arrives. </ins> Therefore, in order to handle session descriptions properly, the user agent needs: calls to createOffer and createAnswer. When creating offers, the transceiver direction is directly reflected  <ins> in the output, even for re-offers.  When creating answers, the </ins> transceiver direction is intersected with the offered direction, as explained in the sec.generating-an-answer section below.


I-D.ietf-mmusic-sdp-mux-attributes groups SDP attributes into different categories.  To avoid unnecessary duplication when bundling, Section 8.1 of I-D.ietf-mmusic-sdp-bundle-negotiation <del> specifies that attributes of category IDENTICAL or TRANSPORT should not be repeated in bundled m= sections. </del>  The following attributes, which are of a category other than IDENTICAL or TRANSPORT, MUST be included in each m= section:

Page 37 contains a statement that "attributes of category IDENTICAL or TRANSPORT should not be repeated in bundled m= sections". Two issues: this reads as normative, so consider "SHOULD NOT" rather than "should not." Also, I think this is true of bundle-only sections, not bundled sections in general.
If we are going to use normative language, seems like we should match the language from BUNDLE, which probably says 'MUST NOT'. The statement is correct regarding any actively bundled sections (which includes bundle-only), but this part of the text has caused enough confusion that some extra explanation is probably warranted.

I-D.ietf-mmusic-sdp-mux-attributes groups SDP attributes into different categories.  To avoid unnecessary duplication when bundling, Section 8.1 of I-D.ietf-mmusic-sdp-bundle-negotiation  <ins> specifies that attributes of category IDENTICAL or TRANSPORT MUST NOT be repeated in bundled m= sections.  This includes m= sections for which bundling has been negotiated and is still desired, as well as m= sections marked as bundle-only. </ins> The following attributes, which are of a category other than IDENTICAL or TRANSPORT, MUST be included in each m= section:


Note that gathering phases only gather the candidates needed by new/recycled/restarting m= sections; other m= sections continue to <del> use their existing candidates.  Also, when bundling is active, candidates are only gathered (and exchanged) for the m= sections referenced in BUNDLE-tags, as described in I-D.ietf-mmusic-sdp- bundle-negotiation. </del>  3.5.2. JSEP applications typically inform the JSEP implementation to begin ICE gathering via the information supplied to setLocalDescription, as <del> this is where the app specifies the number of media streams, and thereby ICE components, for which to gather candidates.  However, to accelerate cases where the application knows the number of ICE </del>  components to use ahead of time, it may ask the implementation to gather a pool of potential ICE candidates to help ensure rapid media setup.

I tried to clarify bundle-only while Iw as in here.
BLOCKER: The final paragraph in section 3.5.1 says that candidates are only gathered for m= sections referenced in BUNDLE tags. Section 3.5.4 talks about gathering more candidates than that under certain circumstances. Please make these consistent with each other.
Agree this needs to be rewritten; with BUNDLE, # of media streams is not the number of ICE components.

Note that gathering phases only gather the candidates needed by new/recycled/restarting m= sections; other m= sections continue to  <ins> use their existing candidates.  Also, if an m= section is bundled (either by a successful bundle negotiation or by being marked as bundle-only), then candidates will be gathered and exchanged for that m= section if and only if its MID is a BUNDLE-tag, as described in I- D.ietf-mmusic-sdp-bundle-negotiation. </ins> 3.5.2. JSEP applications typically inform the JSEP implementation to begin ICE gathering via the information supplied to setLocalDescription, as  <ins> the local description indicates the number of ICE components which will be needed and for which candidates must be gathered.  However, to accelerate cases where the application knows the number of ICE </ins> components to use ahead of time, it may ask the implementation to gather a pool of potential ICE candidates to help ensure rapid media setup.