that it does not absolutely constrain the video formats that the sender can use, but gives an indication of the preferred values. <del> This specification prescribes more specific behavior.  When a sender of a given MediaStreamTrack, which is producing video of a certain resolution, receives an "a=imageattr recv" attribute, it MUST check to see if the original resolution meets the size criteria specified in the attribute, and adapt the resolution accordingly by scaling (if appropriate).  Note that when considering a MediaStreamTrack that is producing rotated video, the unrotated resolution MUST be used.  This is required regardless of whether the receiver supports performing receive-side rotation (e.g., through CVO TS26.114), as it significantly simplifies the matching logic. For the purposes of resolution negotiation, only size limits are considered.  Any other values, e.g. picture or sample aspect ratio, MUST be ignored. When communicating with a non-JSEP endpoint, multiple relevant "a=imageattr recv" attributes may be present in a received m= section.  If this occurs, attributes other than the one with the highest "q=" value MUST be ignored.  If multiple attributes have the same "q=" value, those that appear after the first such attribute in the m= section MUST be ignored. If an "a=imageattr recv" attribute references a different video payload type than what has been selected for sending the MediaStreamTrack, it MUST be ignored. If the original resolution matches the size limits in the attribute, the track MUST be transmitted untouched. If the original resolution exceeds the size limits in the attribute, the sender SHOULD apply downscaling to the output of the MediaStreamTrack in order to satisfy the limits.  Downscaling MUST NOT change the track aspect ratio. If the original resolution is less than the size limits in the attribute, upscaling is needed, but this may not be appropriate in all cases.  To address this concern, the application can set an upscaling policy for each sent track.  For this case, if upscaling is permitted by policy, the sender SHOULD apply upscaling in order to provide the desired resolution.  Otherwise, the sender MUST NOT apply upscaling.  The sender SHOULD NOT upscale in other cases, even if the policy permits it.  Upscaling MUST NOT change the track aspect ratio. If there is no appropriate and permitted scaling mechanism that allows the received size limits to be satisfied, the sender MUST NOT transmit the track. If the attribute includes a "sar=" (sample aspect ratio) value set to something other than "1.0", indicating the receiver wants to receive non-square pixels, this cannot be satisfied and the sender MUST NOT transmit the track. In the special case of receiving a maximum resolution of [0, 0], as described above, the sender MUST NOT transmit the track. </del>  3.7.

Specifically consider simulcast Remove upscaling Clean up some contradictory text
I was trying to understand what kind of emoji :GT< was until I realized it was a flubbed LGTM :-)
I am going to rework this PR to deal with what we discussed regarding upscaling today.
Note to self: target , with this
I like the new text - I'd like to do a final read before we merge but so far looks good.
New rev uploaded with editorial fixes from Eric's review.
If a sender is transmitting video at 180p, 360p, and 720p, and it receives an a=imageattr that limits received resolution to 480p, what should happen? a) 180p and 360p are transmitted intact, 720p is not transmitted b) 180p and 360p are transmitted intact; 720p is scaled to 480p c) Everything is scaled down; transmission is 480p, 240p, 120p I would argue that a) makes the most sense here, but this is somewhat at odds with the guidance we are giving for the non-simulcast case, which is more like b).
This might be a case where the browser needs to do b and the JS need to figure out what happened and turn off the 480 so you end up with an effective results of a. Once we move into simulcast land, the JS just need to deal with taking care of more stuff.
I'm good with A.
To meet bandwidth limits, the encoder may dynamically apply downscaling. This may conflict with upscaling performed to meet a=imageattr requirements. This conflict needs to be resolved somehow. I suggest that we remove the language around upscaling and policy and instead state that JSEP implementations SHOULD have appropriate fallback to ensure that they can decode 'too-low' resolutions in software.
Resolution on editor's call: Just remove the ability to upscale (WebRTC API doesn't permit this anyway) If you are in a situation where you would need to upscale to meet the imageattr reqs, just don't send. Implementations SHOULD have software fallback if they have some sort of goofy minimum size decoder. Someone needs to email the mailing list about this change.
BLOCKER: Section 3.6.2, second paragraph, second sentence says a sender MUST scale to match imageattr. The same section, paragraph seven, says it SHOULD scale to match imageattr. There needs to be only one normative statement on this topic, so as to avoid confusion among implementors.
Agreed. It's a bit nuanced because the text says "MUST limit" and "SHOULD scale", but this could be clarified.

that it does not absolutely constrain the video formats that the sender can use, but gives an indication of the preferred values.  <ins> This specification prescribes more specific behavior.  When a MediaStreamTrack, which is producing video of a certain resolution (the "track resolution"), is attached to a RtpSender, which is encoding the track video at the same or lower resolution(s) (the "encoder resolutions"), and a remote description is applied that references the sender and contains valid "a=imageattr recv" attributes, it MUST follow the rules below to ensure the sender does not transmit a resolution that would exceed the size criteria specified in the attributes.  These rules MUST be followed as long as the attributes remain present in the remote description, including cases in which the track changes its resolution, or is replaced with a different track. Depending on how the RtpSender is configured, it may be producing a single encoding at a certain resolution, or, if simulcast sec.simulcast has been negotiated, multiple encodings, each at their own specific resolution.  In addition, depending on the configuration, each encoding may have the flexibility to reduce resolution when needed, or may be locked to a specific output resolution. For each encoding being produced by the RtpSender, the following rules are applied to determine what should be transmitted: First, the most suitable "a=imageattr recv" attribute is selected. This is performed by taking the attribute with the highest "q=" value from the set of attributes that reference the media format that has been selected for the specified encoding.  If multiple attributes have the same "q=" value, the one that appears first in the m= section is used.  Note that while JSEP endpoints will include at most one "a=imageattr recv" attribute per media format, JSEP endpoints may receive session descriptions from non-JSEP endpoints with m= sections that contain multiple such attributes. If there is an applicable "a=imageattr recv" attribute for the encoding, the limits from the attribute are then compared to the encoder resolution.  Only the specific limits mentioned below are considered; any other values, such as picture aspect ratio, MUST be ignored.  Note that when considering a MediaStreamTrack that is producing rotated video, the unrotated resolution MUST be used for the checks.  This is required regardless of whether the receiver supports performing receive-side rotation (e.g., through CVO TS26.114), as it significantly simplifies the matching logic. If the attribute includes a "sar=" (sample aspect ratio) value set to something other than "1.0", indicating the receiver wants to receive non-square pixels, this cannot be satisfied and the sender MUST NOT transmit the encoding. If the encoder resolution exceeds the maximum size permitted by the attribute, and the encoder is allowed to adjust its resolution, the encoder SHOULD apply downscaling in order to satisfy the limits, although the downscaling MUST NOT change the picture aspect ratio of the encoding.  For example, if the encoder resolution is 1280x720, and the attribute specified a maximum of 640x480, the expected output resolution would be 640x360.  If downscaling cannot be applied, the encoding MUST NOT be transmitted, and an error SHOULD be surfaced to the application. If the encoder resolution is less than the minimum size permitted by the attribute, the encoding MUST NOT be transmitted, and an error SHOULD be surfaced to the application; the encoder MUST NOT apply upscaling.  JSEP implementations SHOULD avoid this situation by allowing receipt of arbitrarily small resolutions, perhaps via fallback to a software decoder. In the special case of a maximum resolution of [0, 0], as described above, the sender MUST NOT transmit the encoding. </ins> 3.7.


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.  Attributes other than the ones specified above MAY be included, except for the following attributes which are specifically

I did add a MUST here, but I think it's just a restatement of what is already true.
BLOCKER: Several of the SDP-building procedures in this document call out addition of "a=fingerprint" to individual media sections, while the canonical definition of "a=fingerprint" allows these to be added at either the session level or the media level. The same is true of ice-pwd and ice-ufrag. While the process of SDP building in this document appears to be prescriptive on purpose, one assumes that it is allowed some variation so as to accommodate deployment of future SDP extensions. Because of this state of affairs, it is unclear whether implementations that consolidate these attributes at the session level when they would otherwise be identical among all media sections is such an allowable variation. Ambiguity in specifications is never a good thing, so I believe that the draft needs to do one of: (a) specifically call out this kind of aggregation as allowed; (b) specifically call out this kind of aggregation as disallowed; or (c) include a blanket statement that implementations are allowed to emit SDP that is semantically equivalent to that which is generated by the procedures in this document, but which may vary in exact structure. I have a strong preference for (c) -- implementations will be required to deal with such variations anyway to interop with legacy SDP, so prohibiting JSEP clients from generating them serves no goal.
My suggestion would be to expand the para below to say (a), i.e. that applications that wish to aggregate may do so, even though we recommend not aggregating. 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.
(and also fine with suggestions Justin is suggesting)

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> However, implementations MAY choose to aggregate attributes at the session level and JSEP implementations MUST be prepared to receive attributes in either location. </ins> Attributes other than the ones specified above MAY be included, except for the following attributes which are specifically


section if its mid property is non-null; otherwise it is said to be disassociated.  The associated m= section is determined using a mapping between transceivers and m= section indices, formed when <del> creating an offer or applying a remote offer.  An RtpTransceiver is never associated with more than one m= section, and once a session description is applied, a m= section is always associated with exactly one RtpTransceiver. </del>  RtpTransceivers can be created explicitly by the application or implicitly by calling setRemoteDescription with an offer that adds

PTAL
Section 3.5.1 talks about a "recycled m= section" without any context for what this means. Please provide a forward reference to the section that discusses m= section recycling.
is where m= section recycling is first defined, but it's as a bullet point in how to generate an offer, which makes a direct reference problematic. I guess we could say "as spelled out in [ref]"

section if its mid property is non-null; otherwise it is said to be disassociated.  The associated m= section is determined using a mapping between transceivers and m= section indices, formed when  <ins> creating an offer or applying a remote offer. An RtpTransceiver is never associated with more than one m= section, and once a session description is applied, a m= section is always associated with exactly one RtpTransceiver.  However, in certain cases where a m= section has been rejected, as discussed in sec.subsequent-offers below, that m= section will be "recycled" and associated with a new RtpTransceiver with a new mid value. </ins> RtpTransceivers can be created explicitly by the application or implicitly by calling setRemoteDescription with an offer that adds


descriptions to the API, the API would produce and consume messages from this protocol.  While providing a more high-level API, this put more control of signaling within the JSEP implementation, forcing it <del> to have to understand and handle concepts like signaling glare.  In addition, it prevented the application from driving the state machine to a desired state, as is needed in the page reload case. </del>  A second approach that was considered but not chosen was to decouple the management of the media control objects from session

NAME done. NAME still waiting for you.
Section 1.2 uses the term "glare" without describing it. This term may be unfamiliar to readers, and should be explained or cited.
Agreed.
See URL for a definition.
LGTM, but see comment

descriptions to the API, the API would produce and consume messages from this protocol.  While providing a more high-level API, this put more control of signaling within the JSEP implementation, forcing it  <ins> to have to understand and handle concepts like signaling glare (see RFC3264, Section 4). </ins> A second approach that was considered but not chosen was to decouple the management of the media control objects from session


of what could happen in a JSEP session. The code flow below shows Alice's endpoint initiating the session to <del> Bob's endpoint.  The messages from Alice's JS to Bob's JS are assumed to flow over some signaling protocol via a web server.  The JS on both Alice's side and Bob's side waits for all candidates before sending the offer or answer, so the offers and answers are complete; trickle ICE is not used.  Both Alice and Bob are using the default bundle policy of "balanced", and the default RTCP mux policy of "require". </del>  The SDP for |offer-A1| looks like:

I think I got all the things Justin mentioned.
Will take a final look once Eric's comments are resolved.
Made a slight change to one sentence to mention user agents. PTAL.
For the examples, please expand the acronyms "JS" and "UA".
I think we're going to want to do it once.
I think I want to define some of theses instead of replace all of them because we can't stay in the column limit if they are expanded.

of what could happen in a JSEP session. The code flow below shows Alice's endpoint initiating the session to  <ins> Bob's endpoint.  The messages from the Javascript application in Alice's browser to the Javascript in Bob's browser, abbreviated as AliceJS and BobJS respectively, are assumed to flow over some signaling protocol via a web server.  The Javascript on both Alice's side and Bob's side waits for all candidates before sending the offer or answer, so the offers and answers are complete; trickle ICE is not used.  The user agents (JSEP implementations) in Alice and Bob's browsers, abbreviated as AliceUA and BobUA respectively, are using the default bundle policy of "balanced", and the default RTCP mux policy of "require". </ins> The SDP for |offer-A1| looks like:


1. This document describes how the W3C WEBRTC RTCPeerConnection <del> interface W3C.WD-webrtc-20140617 is used to control the setup, management and teardown of a multimedia session. </del>  1.1. willing to receive, which, when intersected with the set of codecs the remote side supports, specifies what the remote side should send. However, not all parameters follow this rule; for example, the <del> fingerprints I-D.ietf-mmusic-4572-update sent to a remote party are calculated based on the local certificate(s) offered; the remote party MUST either accept these parameters or reject them altogether, with no option to choose different values. </del>  In addition, various RFCs put different conditions on the format of offers versus answers.  For example, an offer may propose an For DTLS, all m= sections MUST use all the certificate(s) that have been specified for the PeerConnection; as a result, they MUST all <del> have the same I-D.ietf-mmusic-4572-update fingerprint value(s), or these value(s) MUST be session-level attributes. </del>  Each m= section should be generated as specified in RFC4566, Section 5.14.  For the m= line itself, the following rules MUST be Section 15.4. An "a=fingerprint" line for each of the endpoint's certificates, <del> as specified in RFC4572, Section 5; the digest algorithm used for </del>  the fingerprint MUST match that used in the certificate signature. An "a=setup" line, as specified in RFC4145, Section 4, and in RFC5245, Section 15.5, and the set of specified options is stored. <del> Any "a=fingerprint" lines are parsed as specified in RFC4572, </del>  Section 5, and the set of fingerprint and algorithm values is stored. parsed as specified in I-D.ietf-ice-trickle, Section 8.2, and its presence or absence flagged and stored. <del> Any "a=fingerprint" lines are parsed as specified in RFC4572, </del>  Section 5, and the set of fingerprint and algorithm values is stored. formats.  Specifically, begin or continue sending the requested feedback types and reacting to received feedback, as specified in RFC4585, Section 4.2.  When sending RTCP feedback, follow <del> 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 in the answer indicates that the JSEP implementation should not be sending media ("recvonly" for have been added to improve readability but are not valid in SDP. More examples of SDP for WebRTC call flows, including examples with <del> IPv6 addresses, can be found in I-D.nandakumar-rtcweb-sdp. </del>  7.1.

I don't know why build of ghpages is failing travis. It works for me on my machine so going to ignore this for a bit.
Here is the diff of the change.
BLOCKER: The nits tool reports (and a cursory hand check supports this) that six of the references are unused, and RFC4572 has been (recently) obsoleted. The remaining references are largely out of date by many versions, which I believe the current tools will automatically handle if version numbers are simply pulled out of the source. Finally, a large number of the referenced working group documents still use the individual name (e.g., draft-nandakumar-rtcweb-sdp instead of draft-ietf-rtcweb-sdp).
Need to verify section numbers when these refs change, but otherwise seems fine.
LGTMLG, assuming this generates the equivalent text.

1. This document describes how the W3C WEBRTC RTCPeerConnection  <ins> interface W3C.webrtc is used to control the setup, management and teardown of a multimedia session. </ins> 1.1. willing to receive, which, when intersected with the set of codecs the remote side supports, specifies what the remote side should send. However, not all parameters follow this rule; for example, the  <ins> fingerprints RFC8122 sent to a remote party are calculated based on the local certificate(s) offered; the remote party MUST either accept these parameters or reject them altogether, with no option to choose different values. </ins> In addition, various RFCs put different conditions on the format of offers versus answers.  For example, an offer may propose an For DTLS, all m= sections MUST use all the certificate(s) that have been specified for the PeerConnection; as a result, they MUST all  <ins> have the same RFC8122 fingerprint value(s), or these value(s) MUST be session-level attributes. </ins> Each m= section should be generated as specified in RFC4566, Section 5.14.  For the m= line itself, the following rules MUST be Section 15.4. An "a=fingerprint" line for each of the endpoint's certificates,  <ins> as specified in RFC8122, Section 5; the digest algorithm used for </ins> the fingerprint MUST match that used in the certificate signature. An "a=setup" line, as specified in RFC4145, Section 4, and in RFC5245, Section 15.5, and the set of specified options is stored.  <ins> Any "a=fingerprint" lines are parsed as specified in RFC8122, </ins> Section 5, and the set of fingerprint and algorithm values is stored. parsed as specified in I-D.ietf-ice-trickle, Section 8.2, and its presence or absence flagged and stored.  <ins> Any "a=fingerprint" lines are parsed as specified in RFC8122, </ins> Section 5, and the set of fingerprint and algorithm values is stored. formats.  Specifically, begin or continue sending the requested feedback types and reacting to received feedback, as specified in RFC4585, Section 4.2.  When sending RTCP feedback, follow  <ins> the rules and recommendations from RFC8108, 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 have been added to improve readability but are not valid in SDP. More examples of SDP for WebRTC call flows, including examples with  <ins> IPv6 addresses, can be found in I-D.ietf-rtcweb-sdp. </ins> 7.1.


MUST occur in a specific order, and with a specific syntax, as defined in RFC4566, Section 5.  Note that while the specific line types (e.g. "v=", "c=") MUST occur in the defined order, lines of the <del> same type (typically "a=") can occur in any order, and their ordering is not meaningful. </del>  The following non-attribute lines are not meaningful in the JSEP context and MAY be discarded once they have been checked.

BLOCKER: Section 5.7.1, first paragraph: this claims that a= lines are order insensitive. Nothing in SDP's base definition makes this true, and nothing precludes specific attributes from assigning meaning to the order in which they appear. See draft-ietf-slim-negotiating-human-language-08 for an example of an SDP extension that does apply meaning to the order in which attributes appear (for better or worse).
Section Session-Level Parsing Text is First, the session-level lines are checked and parsed. These lines MUST occur in a specific order, and with a specific syntax, as defined in [RFC4566], Section 5. Note that while the specific line types (e.g. "v=", "c=") MUST occur in the defined order, lines of the same type (typically "a=") can occur in any order, and their ordering is not meaningful. Remove the text "and their ordering is not meaningful." from above para
FWIW ... some of SDP implementations I work with save a lines in non ordered sets and I never knew this was a bug. Bummer
Agree with proposal.
LGTM

MUST occur in a specific order, and with a specific syntax, as defined in RFC4566, Section 5.  Note that while the specific line types (e.g. "v=", "c=") MUST occur in the defined order, lines of the  <ins> same type (typically "a=") can occur in any order. </ins> The following non-attribute lines are not meaningful in the JSEP context and MAY be discarded once they have been checked.


generate other profile strings even when they mean to support one of these profiles.  For instance, an endpoint might generate "RTP/AVP" but supply "a=fingerprint" and "a=rtcp-fb" attributes, indicating its <del> willingness to support "(UDP,TCP)/TLS/RTP/SAVPF".  In order to simplify compatibility with such endpoints, JSEP implementations MUST follow the following rules when processing the media m= sections in a received offer: </del>  <del> Any profile in the offer matching the following patterns MUST be accepted: "RTP/[S]AVP[F]" and "(UDP|TCP)/TLS/RTP/SAVP[F]". </del>  The profile in any "m=" line in any generated answer MUST exactly match the profile provided in the offer.

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?

generate other profile strings even when they mean to support one of these profiles.  For instance, an endpoint might generate "RTP/AVP" but supply "a=fingerprint" and "a=rtcp-fb" attributes, indicating its  <ins> willingness to support "UDP/TLS/RTP/SAVPF" or "TCP/TLS/RTP/SAVPF". In order to simplify compatibility with such endpoints, JSEP implementations MUST follow the following rules when processing the media m= sections in a received offer: </ins>  <ins> Any profile in the offer matching one of the following MUST be accepted: "RTP/AVP" "RTP/AVPF" "RTP/SAVP" "RTP/SAVPF" "UDP/TLS/RTP/AVP" "UDP/TLS/RTP/AVPF" "UDP/TLS/RTP/SAVP" "UDP/TLS/RTP/SAVPF" "TCP/TLS/RTP/SAVP" "TCP/TLS/RTP/SAVPF" </ins> The profile in any "m=" line in any generated answer MUST exactly match the profile provided in the offer.


"a=ice-ufrag" and "a=ice-pwd" lines, as specified in RFC5245, Section 15.4. <del> An "a=fingerprint" line for each of the endpoint's certificates, as specified in RFC8122, Section 5; the digest algorithm used for the fingerprint MUST match that used in the certificate signature. </del>  An "a=setup" line, as specified in RFC4145, Section 4, and clarified for use in DTLS-SRTP scenarios in RFC5763, Section 5.

certificate. This was updated in RFC 8122.
NAME PTAL
NAME PTAL
Section 5.2.1 (creating an offer) still has this paragraph: In RFC4572-update, this requirement doesn't exist. So should this be changed to reference RFC4572-update, removing the second half of this paragraph?
Related webrtc-pc issue: URL

"a=ice-ufrag" and "a=ice-pwd" lines, as specified in RFC5245, Section 15.4.  <ins> For each desired digest algorithm, one or more "a=fingerprint" lines for each of the endpoint's certificates, as specified in RFC8122, Section 5. </ins> An "a=setup" line, as specified in RFC4145, Section 4, and clarified for use in DTLS-SRTP scenarios in RFC5763, Section 5.


Any profile in the offer matching one of the following MUST be accepted: <del> "RTP/AVP" </del>  <del> "RTP/AVPF" </del>  <del> "RTP/SAVP" </del>  <del> "RTP/SAVPF" </del>  <del> "UDP/TLS/RTP/AVP" </del>  <del> "UDP/TLS/RTP/AVPF" </del>  <del> "UDP/TLS/RTP/SAVP" </del>  <del> "UDP/TLS/RTP/SAVPF" "TCP/TLS/RTP/SAVP" "TCP/TLS/RTP/SAVPF" </del>  The profile in any "m=" line in any generated answer MUST exactly match the profile provided in the offer.

The only draft or RFC that uses "UDP/TLS/RTP/AVP" is one typo in URL I just reported an RFC Errata on that. I think the argument here is anyone who was advertising TLS in the label, also put the S in the SAVP so we don't need to worry about any of the cases where we have TLS. The case with TCP it is a bit different. You can take RTP (not SRTP) and send it as unencrypted RTP over a normal TLS (not DTLS-SRTP) tunnel so for that case the label is TCP/TLS/RTP/AVPF. However, this is RTP over 4571 framing so treating it as SRTP is going to not work. Because of this, I think we need to remove all the options from this list that are RTP (not SRTP) framed over 4571. That means remove from the list "TCP/RTP/AVP", "TCP/RTP/AVPF" , "TCP/TLS/RTP/AVP" , "TCP/TLS/RTP/AVPF". For "TCP/RTP/SAVP" and "TCP/RTP/SAVPF", this is SRTP with 4571 framing over TCP ( See URL ). Since this is not DTLS-SRTP, it seems we should also remove theses two labels as well. So what I am proposing is we move the list to be just "RTP/AVP" "RTP/AVPF" "RTP/SAVP" "RTP/SAVPF" "TCP/DTLS/RTP/SAVP" "TCP/DTLS/RTP/SAVPF" "UDP/TLS/RTP/SAVP" "UDP/TLS/RTP/SAVPF" Backing up to first principals on this, the problem we are tying to solve is an offer that is offering RTP or DTLS-SRTP. It is going to have RTP/AVP[F] and a fingerprint so it seems as long as we have that on the list it is good. Of some one, RTP/SAVP is defined in URL(and the RTP/SAVFP version in URL) while the UDP/TLS/RTP/SAVP[F] is in URL )
I added the refs for where these are defined. If that look OK, I think this is ready to merge.
table is at URL
So when I take that table and do grep AVP grep -v MBMS I get RTP/AVP RTP/AVPF RTP/SAVP RTP/SAVPF TCP/DTLS/RTP/SAVP TCP/DTLS/RTP/SAVPF TCP/RTP/AVP TCP/RTP/AVPF TCP/RTP/SAVP TCP/RTP/SAVPF TCP/TLS/RTP/AVP TCP/TLS/RTP/AVPF UDP/TLS/RTP/SAVP UDP/TLS/RTP/SAVPF The diff from what we have now is < TCP/DTLS/RTP/SAVP < TCP/DTLS/RTP/SAVPF < TCP/RTP/AVP < TCP/RTP/AVPF < TCP/RTP/SAVP < TCP/RTP/SAVPF < TCP/TLS/RTP/AVP < TCP/TLS/RTP/AVPF
NAME be sure to check the references for the profiles.

Any profile in the offer matching one of the following MUST be accepted:  <ins> "RTP/AVP" (Defined in RFC4566, Section 8.2.2) </ins>  <ins> "RTP/AVPF" (Defined in RFC4585, Section 9) </ins>  <ins> "RTP/SAVP" (Defined in RFC3711, Section 12) </ins>  <ins> "RTP/SAVPF" (Defined in RFC5124, Section 6) </ins>  <ins> "TCP/DTLS/RTP/SAVP" (Defined in RFC7850, Section 3.4) </ins>  <ins> "TCP/DTLS/RTP/SAVPF" (Defined in RFC7850, Section 3.5) </ins>  <ins> "UDP/TLS/RTP/SAVP" (Defined in RFC5764, Section 9) </ins>  <ins> "UDP/TLS/RTP/SAVPF" (Defined in RFC5764, Section 9) </ins> The profile in any "m=" line in any generated answer MUST exactly match the profile provided in the offer.


defined in I-D.ietf-ice-trickle, Section 5.1. I-D.ietf-mmusic-sdp-mux-attributes groups SDP attributes into <del> different categories.  To avoid unnecessary duplication when bundling I-D.ietf-mmusic-sdp-bundle-negotiation, Section 8.1, 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. </del>  The following attributes, which are of a category other than IDENTICAL or TRANSPORT, MUST be included in each m= section:

I like the text in your comment and changed to that.
Worth taking an editorial pass over this if time permits
I prob have time to run this one down.

defined in I-D.ietf-ice-trickle, Section 5.1. I-D.ietf-mmusic-sdp-mux-attributes groups SDP attributes into  <ins> different categories.  To avoid unnecessary duplication when bundling, attributes of category IDENTICAL or TRANSPORT MUST NOT be repeated in bundled m= sections, as specified in I-D.ietf-mmusic-sdp- bundle-negotiation, Section 8.1.  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:


media formats MUST be generated in the corresponding order, and MUST exclude any codecs not present in the codec preferences. <del> The media formats in the answer MAY include codecs present in the offer that were discarded in a previous offer/answer exchange. This is necessary for compatibility with third- party call control and SIP use cases. </del> Unless excluded by the above restrictions, the media formats MUST include the mandatory audio/video codecs as specified in RFC7874, Section 3, and RFC7742, Section 5. the negotiated session descriptions by following the steps mentioned for the "have-local-offer" state above. <del> In addition, for each non-recycled, non-rejected m= section in the new offer, the following adjustments are made based on the contents of the corresponding m= section in the current remote description, if any: </del>  The m= line and corresponding "a=rtpmap" and "a=fmtp" lines MUST <del> only include codecs present in the most recent answer which have not been excluded by the codec preferences of the associated transceiver.  Note that non-JSEP endpoints are not subject to these restrictions, and might offer media formats that were not present in the most recent answer, as specified in RFC3264, Section 8.  Therefore, JSEP implementations MUST be prepared to receive such offers. </del>  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 current local description. </del>  The RTP header extensions MUST only include those that are present in the most recent answer. <del> The RTCP feedback extensions MUST only include those that are present in the most recent answer. </del>  The "a=rtcp" line MUST NOT be added if the most recent answer included an "a=rtcp-mux" line.

any guess on what happened to these that caused them to not go in ?
They were somehow targeted to a branch other than master, and that branch was never merged
LGTM but you have a conflict

media formats MUST be generated in the corresponding order, and MUST exclude any codecs not present in the codec preferences.  Unless excluded by the above restrictions, the media formats MUST include the mandatory audio/video codecs as specified in RFC7874, Section 3, and RFC7742, Section 5. the negotiated session descriptions by following the steps mentioned for the "have-local-offer" state above.  <ins> In addition, for each existing, non-recycled, non-rejected m= section in the new offer, the following adjustments are made based on the contents of the corresponding m= section in the current local or remote description, as appropriate: </ins> The m= line and corresponding "a=rtpmap" and "a=fmtp" lines MUST  <ins> only include media formats which have not been excluded by the codec preferences of the associated transceiver, and MUST include all currently available formats.  Media formats that were previously offered but are no longer available (e.g., a shared hardware codec) MAY be excluded. </ins> 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.  <ins> The RTCP feedback mechanisms MUST only include those that are present in the most recent answer, except for the case of format- specific mechanisms that are referencing a newly-added media format. </ins> The "a=rtcp" line MUST NOT be added if the most recent answer included an "a=rtcp-mux" line.


The "a=rtcp" line MUST NOT be added if the most recent answer included an "a=rtcp-mux" line. <del> The "a=rtcp-mux" line MUST NOT be added unless present in the most recent answer. </del>  The "a=rtcp-mux-only" line MUST NOT be added. consistent with the existing DTLS association, if the association is being continued by the offerer.  If the m= section is not bundled into another m= section and RTCP multiplexing is not active, an "a=rtcp" attribute line MUST be filled in with the port and address of the default RTCP candidate. not used. If the RTP/RTCP multiplexing policy is "require", each m= section <del> MUST contain an "a=rtcp-mux" attribute.  If an "m=" section contains an "a=rtcp-mux-only" attribute then that section MUST also contain an "a=rtcp-mux" attribute. </del>  If this session description is of type "pranswer" or "answer", the following additional checks are applied: returned. If this m= section is new, begin gathering candidates for it, as <del> defined in RFC5245, Section 4.1.1, unless it has been marked as bundle-only. Or, if the ICE ufrag and password values have changed, and it has not been marked as bundle-only, trigger the ICE agent to start an ICE restart, and begin gathering new candidates for the m= section as described in RFC5245, Section 9.1.1.1.  If this description is an answer, also start checks on that media section as defined in RFC5245, Section 9.3.1.1. </del>  If the m= section proto value indicates use of RTP: If RTCP mux is indicated, prepare to demux RTP and RTCP from the RTP ICE component, as specified in RFC5761, Section 5.1.3. <del> If RTCP mux is not indicated, but was previously negotiated, i.e., the RTCP ICE component no longer exists, this MUST result in an error. </del> For each specified RTP header extension, establish a mapping <del> between the extension ID and URI, as described in section 6 of RFC5285.  If any indicated RTP header extension is not supported, this MUST result in an error. </del>  If the MID header extension is supported, prepare to demux RTP streams intended for this m= section based on the MID header RFC3264, Section 6.1.  In addition, prepare to demux RTP streams intended for this m= section based on the media formats supported by this m= section, as described in I-D.ietf-mmusic- <del> sdp-bundle-negotiation, Section 10.2.  If any indicated media format is not supported, this MUST result in an error. </del>  For each specified "rtx" media format, establish a mapping between the RTX payload type and its associated primary payload <del> type, as described in RFC4588, Sections 8.6 and 8.7.  If any referenced primary payload types are not present, this MUST result in an error. </del>  If the directional attribute is of type "sendrecv" or "recvonly", enable receipt and decoding of media.

The local description can never be wrong, because it is constructed by the browser. I also explicitly added text to make clear that the mux state for any m= line cannot change.
LGTM
Section 5.8 describes the behavior of an implementation processing its own unmodified SDP. It contains significant error language that should have been removed when SDP munging was removed. In particular, please remove all of the following: • "If an error is returned, the session MUST be restored to the state it was in before performing these steps." • "If RTCP mux is not indicated, but was previously negotiated, i.e., the RTCP ICE component no longer exists, this MUST result in an error." • "If any indicated RTP header extension is not supported, this MUST result in an error." • "If any indicated media format is not supported, this MUST result in an error." • "If any referenced primary payload types are not present, this MUST result in an error." The first bullet of section 5.8 includes: "URL it has been marked as bundle-only...," and the second includes "URL it has not been marked as bundle-only..." -- in both cases, I believe the indicated behavior is supposed to happen for any bundled section (e.g., in a re-offer or re-answer), regardless of whether it is bundle-only.
I think Adam is right about this, but I wonder if this actually belongs elsewhere, so further study needed.
This is already duplicated. This seems to be a prohibition that is stricter than RFC 5761, and if we remove it here we have removed it generally, unless I have missed somewhere else we say it. This is not appropriate for remote descriptions. We say this in 5.9. >The first bullet of section 5.8 includes: "URL it has been marked as bundle-only...," and the second includes "URL it has not been marked as bundle-only..." -- in both cases, I believe the indicated behavior is supposed to happen for any bundled section (e.g., in a re-offer or re-answer), regardless of whether it is bundle-only. Yeah, I think Adam is right about this and it's probably the result of some section refactor
Made some progress on it. Editor discussion on the mux piece. Once an m= line has mux or non-mux negotiated, that's immutable.
LG with nits

The "a=rtcp" line MUST NOT be added if the most recent answer included an "a=rtcp-mux" line.  <ins> The "a=rtcp-mux" line MUST be the same as that in the most recent answer. </ins> The "a=rtcp-mux-only" line MUST NOT be added. consistent with the existing DTLS association, if the association is being continued by the offerer. <ins> RTCP multiplexing must be used, and an "a=rtcp-mux" line inserted if and only if the m= section previously used RTCP multiplexing. </ins> If the m= section is not bundled into another m= section and RTCP multiplexing is not active, an "a=rtcp" attribute line MUST be filled in with the port and address of the default RTCP candidate. not used. If the RTP/RTCP multiplexing policy is "require", each m= section  <ins> MUST contain an "a=rtcp-mux" attribute.  If an m= section contains an "a=rtcp-mux-only" attribute then that section MUST also contain an "a=rtcp-mux" attribute. If this m= section was present in the previous answer then the state of RTP/RTCP multiplexing MUST match what was previously negotiated. </ins> If this session description is of type "pranswer" or "answer", the following additional checks are applied: returned. If this m= section is new, begin gathering candidates for it, as  <ins> defined in RFC5245, Section 4.1.1, unless it is definitively being bundled (either this is an offer and the m= section is marked bundle-only, or it is an answer and the m= section is bundled into into another m= section.) Or, if the ICE ufrag and password values have changed, trigger the ICE agent to start an ICE restart, and begin gathering new candidates for the m= section as described in RFC5245, Section 9.1.1.1.  If this description is an answer, also start checks on that media section as defined in RFC5245, Section 9.3.1.1. </ins> If the m= section proto value indicates use of RTP: If RTCP mux is indicated, prepare to demux RTP and RTCP from the RTP ICE component, as specified in RFC5761, Section 5.1.3.  For each specified RTP header extension, establish a mapping  <ins> between the extension ID and URI, as described in RFC5285, Section 6. </ins> If the MID header extension is supported, prepare to demux RTP streams intended for this m= section based on the MID header RFC3264, Section 6.1.  In addition, prepare to demux RTP streams intended for this m= section based on the media formats supported by this m= section, as described in I-D.ietf-mmusic-  <ins> sdp-bundle-negotiation, Section 10.2. </ins> For each specified "rtx" media format, establish a mapping between the RTX payload type and its associated primary payload  <ins> type, as described in RFC4588, Sections 8.6 and 8.7. </ins> If the directional attribute is of type "sendrecv" or "recvonly", enable receipt and decoding of media.


appropriate fmtp parameters for that codec MUST be specified to indicate that silence suppression for received audio is not desired. For example, when using the Opus codec, the "usedtx=0" parameter <del> would be specified in the offer. Note that setting the "VoiceActivityDetection" parameter when generating an offer is a request to receive audio with silence suppression.  It has no impact on whether the local endpoint does silence suppression for the audio it sends. </del>  The "VoiceActivityDetection" option does not have any impact on the setting of the "vad" value in the signaling of the client to mixer done on a per-codec basis (e.g., if the offerer somehow offered support for CN but set "usedtx=0" for Opus, setting VoiceActivityDetection to true would result in an answer with CN <del> codecs and "usedtx=0"). </del>  5.4.

LGTM
I am going to land this and then make a followup PR for S 5.9.
You'll also need to update S 5.9 to ensure CN is only enabled when support is bilateral: For each specified "CN" media format, enable DTX for all supported media formats with the same clockrate, as described in [RFC3389], Section 5, except for formats that have their own internal DTX mechanisms. DTX for such formats (e.g., Opus) is controlled via fmtp parameters, as discussed in Section 5.2.3.2.

appropriate fmtp parameters for that codec MUST be specified to indicate that silence suppression for received audio is not desired. For example, when using the Opus codec, the "usedtx=0" parameter  <ins> would be specified in the offer.  In addition, the implementation MUST NOT use silence suppression for media it generates, regardless of whether the "CN" codecs or related fmtp parameters appear in the peer's description.  The impact of these rules is that silence suppression in JSEP depends on mutual agreement of both sides, which ensures consistent handling regardless of which codec is used. </ins> The "VoiceActivityDetection" option does not have any impact on the setting of the "vad" value in the signaling of the client to mixer done on a per-codec basis (e.g., if the offerer somehow offered support for CN but set "usedtx=0" for Opus, setting VoiceActivityDetection to true would result in an answer with CN  <ins> codecs and "usedtx=0").  The impact of this rule is that an answerer will not try to use silence suppression with any endpoint that does not offer it, making silence suppression support bilateral even with non-JSEP endpoints. </ins> 5.4.


If the m= section is of type audio: <del> For each specified "CN" media format, enable silence </del>  suppression for all supported media formats with the same clockrate, as described in RFC3389, Section 5, except for formats that have their own internal silence suppression event format, this MUST result in an error. For any specified "ptime" value, configure the available <del> media formats to use the specified packet size.  If the specified size is not supported for a media format, use the next closest value instead. </del>  Finally, if this description is of type "pranswer" or "answer", follow the processing defined in the sec.applying-an-answer section header extension in the outgoing RTP streams, as indicated in I-D.ietf-mmusic-rid, Section 4.  If simulcast has been negotiated, send the number of Source RTP Streams as specified in I-D.ietf-mmusic-sdp-simulcast, Section 6.2.2.

The paragraph that spans pages 46 and 47 claims that the "VoiceActivityDetection" parameter has no impact on whether the local endpoint does silence suppression for the audio it sends. The paragraph immediately preceding it says that JSEP implementations MUST NOT emit "CN" codecs if this parameter is set to "false." This only makes sense because RFC 3264 allows SDP to specify codecs that you want to receive by do not plan to generate (i.e., you can send CN even if your offer doesn't have CN in it, as long as the answer does). This is slightly counter-intuitive to many implementors, so it probably bears mention.
This is in VoiceActivityDetection in paragraph that says If the "VoiceActivityDetection" option is specified, with a value of "false", the JSEP implementation MUST NOT emit "CN" codecs. 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 not desired. For example, when using the Opus codec, the "usedtx=0" parameter would be specified in the offer. Note that setting the "VoiceActivityDetection" parameter when generating an offer is a request to receive audio with silence suppression. It has no impact on whether the local endpoint does silence suppression for the audio it sends. The "VoiceActivityDetection" option does not have any impact on the setting of the "vad" value in the signaling of the client to mixer audio level header extension described in [RFC6464], Section 4. Need to figure out how to clarify for Adams point.
The intent of the original text was that setting this parameter might affect what you receive, but not what you send (since that's dependent on the other side's use of VoiceActivityDetection). This text is slightly inaccurate since setting VAD to false will result in it not being negotiated (with the current text), and not sent. However, the text is somewhat at odds with Adam's original comment, since it says that you should not send CN codecs if they weren't present in the offer (see see 5.3.3.1). So, we can either change it to more accurately reflect the current intent, or we can change the normative statements to indicate that use of CN is entirely unilateral. NAME do you have an opinion on this?
So to restate what I think the situation is: We agreed a while ago that the answerer can add things that aren't in the offer. Therefore the answerer can add CN Therefore whether CN is in the offer has no impact on what the offerer sends in RTP The flag controls what is in the offer Which means that the flag controls what you receive in RTP but not what you send in RTP. Correct?
That sounds right to me. is for receive preferences, is for send preferences. Similar to being for receive preferences, and being for send preferences.
Just as info to keep in mind on this. Some codecs, like opus, the dtx in the SDP is unidirectional and only is an indication about receiver preferences. Other codecs, like 729, it is bi directionally negotiated and both need to support dtx for either side to use dtx. So we probably need to be careful about how we phrase if voiceActivityDetection impacts the offer / answer
Per discussion on the call, intent is to enforce G.729 symmetrical/bilateral rules so that if either side says VAD=false you don't get VAD. Also need to clarify 5.3.3.1.
May also want to refer to G.729 as an example, as we do with Opus.
Fixed by

If the m= section is of type audio:  <ins> For each specified "CN" media format, configure silence </ins> suppression for all supported media formats with the same clockrate, as described in RFC3389, Section 5, except for formats that have their own internal silence suppression event format, this MUST result in an error. For any specified "ptime" value, configure the available  <ins> media formats to use the specified packet size when sending. If the specified size is not supported for a media format, use the next closest value instead. </ins> Finally, if this description is of type "pranswer" or "answer", follow the processing defined in the sec.applying-an-answer section header extension in the outgoing RTP streams, as indicated in I-D.ietf-mmusic-rid, Section 4. <ins> If the m= section is of type audio, and silence suppression was configured for the send media format as a result of processing the remote description, and is also enabled for that format in the local description, use silence suppression for outgoing media, in accordance with the guidance in sec.voiceactivitydetection1.  If these conditions are not met, silence suppression MUST NOT be used for outgoing media. </ins> If simulcast has been negotiated, send the number of Source RTP Streams as specified in I-D.ietf-mmusic-sdp-simulcast, Section 6.2.2.


The setLocalDescription method instructs the PeerConnection to apply the supplied session description as its local configuration.  The type field indicates whether the description should be processed as <del> an offer, provisional answer, or final answer; offers and answers are checked differently, using the various rules that exist for each SDP line. </del>  This API changes the local media state; among other things, it sets up local resources for receiving and decoding media.  In order to When creating offers, the transceiver direction is directly reflected in the output, even for re-offers.  When creating answers, the transceiver direction is intersected with the offered direction, as <del> explained in the sec.generating-an-answer section below. </del>  Note that while setDirection sets the direction property of the transceiver immediately (sec.transceiver-direction), this property When a SessionDescription is supplied to setLocalDescription, the following steps MUST be performed: <del> First, the type of the SessionDescription is checked against the current state of the PeerConnection: </del>  If the type is "offer", the PeerConnection state MUST be either "stable" or "have-local-offer". MUST be returned. Next, the SessionDescription is parsed into a data structure, as <del> described in the sec.parsing-a-desc section below. </del>  Finally, the parsed SessionDescription is applied as described in <del> the sec.applying-a-local-desc section below. </del>  5.6. When a SessionDescription is supplied to setRemoteDescription, the following steps MUST be performed: <del> First, the type of the SessionDescription is checked against the current state of the PeerConnection: </del>  If the type is "offer", the PeerConnection state MUST be either "stable" or "have-remote-offer". stop and an error 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 <del> the sec.applying-a-remote-desc section below. </del>  5.7. Section 5, and the set of fingerprint and algorithm values is stored. <del> If the "m=" proto value indicates use of RTP, as described in the sec.profile-names section above, the following attribute lines MUST be processed: </del>  The "m=" fmt value MUST be parsed as specified in RFC4566, Section 5.14, and the individual values stored. "recvonly", enable receipt and decoding of media. Finally, if this description is of type "pranswer" or "answer", <del> follow the processing defined in the sec.applying-an-answer section below. </del>  5.9. use the next closest value instead. Finally, if this description is of type "pranswer" or "answer", <del> follow the processing defined in the sec.applying-an-answer section below. </del>  5.10.

This addresses Adam's actual comment - and adds the first references to rollback in the processing section - but leaves the details to be filled in by a future PR.
LGTM

The setLocalDescription method instructs the PeerConnection to apply the supplied session description as its local configuration.  The type field indicates whether the description should be processed as  <ins> an offer, provisional answer, final answer, or rollback; offers and answers are checked differently, using the various rules that exist for each SDP line. </ins> This API changes the local media state; among other things, it sets up local resources for receiving and decoding media.  In order to When creating offers, the transceiver direction is directly reflected in the output, even for re-offers.  When creating answers, the transceiver direction is intersected with the offered direction, as  <ins> explained in sec.generating-an-answer below. </ins> Note that while setDirection sets the direction property of the transceiver immediately (sec.transceiver-direction), this property When a SessionDescription is supplied to setLocalDescription, the following steps MUST be performed:  <ins> If the description is of type "rollback", follow the processing defined in sec.rollback and skip the processing described in the rest of this section. Otherwise, the type of the SessionDescription is checked against the current state of the PeerConnection: </ins> If the type is "offer", the PeerConnection state MUST be either "stable" or "have-local-offer". MUST be returned. Next, the SessionDescription is parsed into a data structure, as  <ins> described in sec.parsing-a-desc below. </ins> Finally, the parsed SessionDescription is applied as described in  <ins> sec.applying-a-local-desc below. </ins> 5.6. When a SessionDescription is supplied to setRemoteDescription, the following steps MUST be performed:  <ins> If the description is of type "rollback", follow the processing defined in sec.rollback and skip the processing described in the rest of this section. Otherwise, the type of the SessionDescription is checked against the current state of the PeerConnection: </ins> If the type is "offer", the PeerConnection state MUST be either "stable" or "have-remote-offer". stop and an error MUST be returned. Next, the SessionDescription is parsed into a data structure, as  <ins> described in sec.parsing-a-desc below.  If parsing fails for any reason, processing MUST stop and an error MUST be returned. </ins> Finally, the parsed SessionDescription is applied as described in  <ins> sec.applying-a-remote-desc below. </ins> 5.7. Section 5, and the set of fingerprint and algorithm values is stored.  <ins> If the "m=" proto value indicates use of RTP, as described in sec.profile-names above, the following attribute lines MUST be processed: </ins> The "m=" fmt value MUST be parsed as specified in RFC4566, Section 5.14, and the individual values stored. "recvonly", enable receipt and decoding of media. Finally, if this description is of type "pranswer" or "answer",  <ins> follow the processing defined in sec.applying-an-answer below. </ins> 5.9. use the next closest value instead. Finally, if this description is of type "pranswer" or "answer",  <ins> follow the processing defined in sec.applying-an-answer below. </ins> 5.10.


should have its track removed.  The sender's track is cleared, and the sender stops sending.  Future calls to createOffer will mark the m= section associated with the sender as recvonly (if <del> transceiver.currentDirection is sendrecv) or as inactive (if transceiver.currentDirection is sendonly). </del>  4.1.4. The currentDirection property indicates the last negotiated direction for the transceiver's associated m= section.  More specifically, it indicates the RFC3264 directional attribute of the associated m= <del> section in the last applied answer, with "send" and "recv" directions reversed if it was a remote answer.  For example, if the directional attribute for the associated m= section in a remote answer is "recvonly", currentDirection is set to "sendonly". </del>  If an answer that references this transceiver has not yet been applied, or if the transceiver is stopped, currentDirection is set to

is meant to represent "direction in effect", whereas represents "direction the application wants to negotiate". So, the direction that both inspects and modifies should be ; its purpose is to change the application's desired direction for a transceiver, regardless of the current state of negotiation. Also clarifying that also reflects the direction negotiated in a provisional answer, which was the intent (I believe) but wasn't explicitly stated. This is consistent with it being the direction "in effect", since applying a provisional answer allows the endpoint to start sending/receiving media.
NAME do you want to look at this? I believe this is straightforward.
Section 4.1.3, removeTrack, states: This should say "transceiver.direction". Using "currentDirection" doesn't work because it may be null, and it also may result in un-intuitive behavior, where ends up not having any effect and results in a "sendrecv" or "sendonly" direction being negotiated.
Want to make a PR?

should have its track removed.  The sender's track is cleared, and the sender stops sending.  Future calls to createOffer will mark the m= section associated with the sender as recvonly (if  <ins> transceiver.direction is sendrecv) or as inactive (if transceiver.direction is sendonly). </ins> 4.1.4. The currentDirection property indicates the last negotiated direction for the transceiver's associated m= section.  More specifically, it indicates the RFC3264 directional attribute of the associated m=  <ins> section in the last applied answer (including provisional answers), with "send" and "recv" directions reversed if it was a remote answer. For example, if the directional attribute for the associated m= section in a remote answer is "recvonly", currentDirection is set to "sendonly". </ins> If an answer that references this transceiver has not yet been applied, or if the transceiver is stopped, currentDirection is set to


1.1. <del> The thinking behind WebRTC call setup has been to fully specify and control the media plane, but to leave the signaling plane up to the application as much as possible.  The rationale is that different applications may prefer to use different protocols, such as the existing SIP call signaling protocol, or something custom to the particular application, perhaps for a novel use case.  In this approach, the key information that needs to be exchanged is the multimedia session description, which specifies the necessary transport and media configuration information necessary to establish the media plane. </del>  With these considerations in mind, this document describes the JavaScript Session Establishment Protocol (JSEP) that allows for full

Fixed my own comment, now LGTM
I think this got all the text from Robert, it was just not a change so it does not show up in diff.
Suggested change to the first sentence of 1.1 OLD: The thinking behind WebRTC call setup has been to fully specify and control the media plane, but to leave the signaling plane up to the application as much as possible. New: WebRTC call setup has been designed to focus on controlling the media plane, leaving signaling plane behavior up to the application as much as possible.
OK

1.1.  <ins> WebRTC call setup has been designed to focus on controlling the media plane, leaving signaling plane behavior up to the application as much as possible.  The rationale is that different applications may prefer to use different protocols, such as the existing SIP call signaling protocol, or something custom to the particular application, perhaps for a novel use case.  In this approach, the key information that needs to be exchanged is the multimedia session description, which specifies the necessary transport and media configuration information necessary to establish the media plane. </ins> With these considerations in mind, this document describes the JavaScript Session Establishment Protocol (JSEP) that allows for full


a local description.  If an error is returned, the session MUST be restored to the state it was in before performing these steps. <del> Next, m= sections are processed.  For each m= section, the following </del>  steps MUST be performed; if any parameters are out of bounds, or cannot be applied, processing MUST stop and an error MUST be returned.

The second paragraph of 6.8 starts "Next, ". I think it should start "First, ".
I agree with this.

a local description.  If an error is returned, the session MUST be restored to the state it was in before performing these steps.  <ins> First, m= sections are processed.  For each m= section, the following </ins> steps MUST be performed; if any parameters are out of bounds, or cannot be applied, processing MUST stop and an error MUST be returned.


present in the remote offer, as specified in RFC3264, Section 6.  For the purposes of this discussion, any session-level attributes in the offer that are also valid as media-level attributes are considered to <del> be present in each m= section. The next step is to go through each offered m= section.  Each offered m= section will have an associated RtpTransceiver, as described in sec.applying-a-remote-desc.  If there are more RtpTransceivers than there are m= sections, the unmatched RtpTransceivers will need to be associated in a subsequent offer. </del>  For each offered m= section, if any of the following conditions are true, the corresponding m= section in the answer MUST be marked as

There are two paragraphs on page 50 that start "The next step is to". They are both referring to the same step. I suggest combining the paragraphs.
I think I would just change the second one to "Finally"
LGTM

present in the remote offer, as specified in RFC3264, Section 6.  For the purposes of this discussion, any session-level attributes in the offer that are also valid as media-level attributes are considered to  <ins> be present in each m= section.  Each offered m= section will have an associated RtpTransceiver, as described in sec.applying-a-remote- desc.  If there are more RtpTransceivers than there are m= sections, the unmatched RtpTransceivers will need to be associated in a subsequent offer. </ins> For each offered m= section, if any of the following conditions are true, the corresponding m= section in the answer MUST be marked as


The second SDP line MUST be an "o=" line, as specified in RFC4566, Section 5.2.  The value of the <username> field SHOULD be "-". <del> RFC3264 requires that the <sess-id> be representable as a 64-bit signed integer.  It is RECOMMENDED that the <sess-id> be generated as a 64-bit quantity with the high bit being sent to zero and the remaining 63 bits being cryptographically random.  The value of the <nettype> <addrtype> <unicast-address> tuple SHOULD be set to a non-meaningful address, such as IN IP4 0.0.0.0, to prevent leaking the local address in this field.  As mentioned in RFC4566, the entire o= line needs to be unique, but selecting a random number for <sess-id> is sufficient to accomplish this. </del>  The third SDP line MUST be a "s=" line, as specified in RFC4566, Section 5.3; to match the "o=" line, a single dash SHOULD be used

Not sure this is correct yet. Have a read of text in bugs.
The fourth sentence of the second bullet of section 5.2.1 is confusing. (It starts "It is RECOMMENDED that the ".) RFC3265 requires the initial sess-id high-order bit to be zero. As written, this can be read to say that setting that bit to zero is only RECOMMENDED, and that it's possible to have sess-ids that are something other than 64 bits. You mean to say "Do what 3265 says to do and make the lower 63 bits random". Here's one possible replacement for the sentence: "RFC 3265 requires that the high-order bit of the initial be zero. It is RECOMMENDED that the remaining 63 bits be initially set to a cryptographically random value."
Yes, this is a reasonable change.
The text from 3264 is The numeric value of the session id and version in the o line MUST be representable with a 64 bit signed integer. The initial value of the version MUST be less than (262)-1, to avoid rollovers. My read of this is the two high order bits need to be zero
Is there some other SDP formatting that requires this number to be positive ?
LGTM

The second SDP line MUST be an "o=" line, as specified in RFC4566, Section 5.2.  The value of the <username> field SHOULD be "-".  <ins> The sess-id MUST be representable by a 64-bit signed integer, and the initial value MUST be less than (2**62)-1, as required by RFC3264.  It is RECOMMENDED that the sess-id be constructed by generating a 64-bit quantity with the two highest bits being set to zero and the remaining 62 bits being cryptographically random. The value of the <nettype> <addrtype> <unicast-address> tuple SHOULD be set to a non-meaningful address, such as IN IP4 0.0.0.0, to prevent leaking the local address in this field.  As mentioned in RFC4566, the entire o= line needs to be unique, but selecting a random number for <sess-id> is sufficient to accomplish this. </ins> The third SDP line MUST be a "s=" line, as specified in RFC4566, Section 5.3; to match the "o=" line, a single dash SHOULD be used


used instead. When creating an IceCandidate object, JSEP implementations MUST <del> populate all of these fields. </del>  3.5.3.

Last paragraph of 3.5.2.1 - "all of these fields" is ambiguous. Please state precisely which fields you mean.
Yeah, OK.

used instead. When creating an IceCandidate object, JSEP implementations MUST  <ins> populate each of the candidate, ufrag, m= section index, and MID fields.  Implementations MUST also be prepared to receive objects with some fields missing, as mentioned above. </ins> 3.5.3.


protocol, and perform the reverse conversion on the messages it receives from the other side. <del> One way to mitigate this is to provide a JavaScript library that hides this complexity from the developer; said library would implement a given signaling protocol along with its state machine and serialization code, presenting a higher level call-oriented interface to the application developer.  For example, libraries exist to adapt the JSEP API into an API suitable for a SIP or XMPP.  Thus, JSEP provides greater control for the experienced developer without forcing any additional complexity on the novice developer. </del>  1.2.

Last paragraph on page 5 - first sentence: at "One way to mitigate this" - "this" has an unclear antecedent. Did you mean "One way to reduce the complexity of the application's responsibilities"?
Agreed. Editorial

protocol, and perform the reverse conversion on the messages it receives from the other side.  <ins> One way to make life easier for the application is to provide a JavaScript library that hides this complexity from the developer; said library would implement a given signaling protocol along with its state machine and serialization code, presenting a higher level call-oriented interface to the application developer.  For example, libraries exist to adapt the JSEP API into an API suitable for a SIP or XMPP.  Thus, JSEP provides greater control for the experienced developer without forcing any additional complexity on the novice developer. </ins> 1.2.


encoding, the limits from the attribute are then compared to the encoder resolution.  Only the specific limits mentioned below are considered; any other values, such as picture aspect ratio, MUST <del> be ignored.  Note that when considering a MediaStreamTrack that is producing rotated video, the unrotated resolution MUST be used for the checks.  This is required regardless of whether the receiver </del>  supports performing receive-side rotation (e.g., through CVO TS26.114), as it significantly simplifies the matching logic.

The first full bullet on page 18 has a sentence that starts "Note that when considering". Please change that to simply "When considering". As written, there is an implication that this is a consequence of something specified somewhere else.
Yes, this seems rihgt.
To help find it, the whole sentence is is Note that when considering a MediaStreamTrack that is producing rotated video, the unrotated resolution MUST be used for the checks. This is required regardless of whether the receiver supports performing receive-side rotation (e.g., through CVO [TS26.114]), as it significantly simplifies the matching logic.

encoding, the limits from the attribute are then compared to the encoder resolution.  Only the specific limits mentioned below are considered; any other values, such as picture aspect ratio, MUST  <ins> be ignored.  When considering a MediaStreamTrack that is producing rotated video, the unrotated resolution MUST be used for the checks.  This is required regardless of whether the receiver </ins> supports performing receive-side rotation (e.g., through CVO TS26.114), as it significantly simplifies the matching logic.


Note that re-offers by JSEP implementations MUST use the correct profile strings even if the initial offer/answer exchange used an <del> (incorrect) older profile string. </del>  5.2.

The last paragraph of 5.1 needs more context. Why woudn't you expect the re-offer to fail, given that you already know the peer is using the older profile strings? It's not clear from the email list and proceedings how the document ended up with this particular text.
Consensus on editor's call is that this is correct. Rationale is that a new offer would have failed in any case, so why complicate things.
LGTM

Note that re-offers by JSEP implementations MUST use the correct profile strings even if the initial offer/answer exchange used an  <ins> (incorrect) older profile string.  This simplifies JSEP behavior, with minimal downside, as any remote endpoint that fails to handle such a re-offer will also fail to handle a JSEP endpoint's initial offer. </ins> 5.2.


resolution is 1280x720, and the attribute specified a maximum of 640x480, the expected output resolution would be 640x360.  If downscaling cannot be applied, the encoding MUST NOT be <del> transmitted, and an error SHOULD be surfaced to the application. </del>  If the encoder resolution is less than the minimum size permitted by the attribute, the encoding MUST NOT be transmitted, and an <del> error SHOULD be surfaced to the application; the encoder MUST NOT </del>  apply upscaling.  JSEP implementations SHOULD avoid this situation by allowing receipt of arbitrarily small resolutions, perhaps via fallback to a software decoder. phase.  If an ICE gathering phase has already started or completed, the 'needs-ice-restart' bit will be set.  Either way, changes to the policy have no effect on the candidate pool, <del> 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. </del>  The ICE candidate pool size MUST NOT be changed after applying a local description.  If a local description has not yet been

The verb "surfaced" appears three times in the document without support or definition. Can you replace them with simpler language?
I don't see a reason to change this. It seems like relatively straightforward langauge.
I don't care. FWIW ... I asked a few developers what surfaced in an API meant and it did not seem a common term they used but given context they all read it the way we mean in spec..
The first two, which are about errors, will be changed to "raised" The last one, which is about candidates will be changed to "made available"
LGTM

resolution is 1280x720, and the attribute specified a maximum of 640x480, the expected output resolution would be 640x360.  If downscaling cannot be applied, the encoding MUST NOT be  <ins> transmitted, and an error SHOULD be raised to the application. </ins> If the encoder resolution is less than the minimum size permitted by the attribute, the encoding MUST NOT be transmitted, and an  <ins> error SHOULD be raised to the application; the encoder MUST NOT </ins> apply upscaling.  JSEP implementations SHOULD avoid this situation by allowing receipt of arbitrarily small resolutions, perhaps via fallback to a software decoder. phase.  If an ICE gathering phase has already started or completed, the 'needs-ice-restart' bit will be set.  Either way, changes to the policy have no effect on the candidate pool,  <ins> because pooled candidates are not made available to the application until a gathering phase occurs, and so any necessary filtering can still be done on any pooled candidates. </ins> The ICE candidate pool size MUST NOT be changed after applying a local description.  If a local description has not yet been


Calling this method may do things such as generating new ICE credentials, but does not trigger candidate gathering or cause a media state change.  Specifically, the answer is not applied, and <del> does not become the pending local description, until </del>  setLocalDescription is called. 4.1.8.

In 4.1.7 (create Answer) why would calling setLocalDescription cause the answer to be a pending local description. I think it's the full on local description at that point, not a pending one?
Yes, this is an error in the text.
LGTM

Calling this method may do things such as generating new ICE credentials, but does not trigger candidate gathering or cause a media state change.  Specifically, the answer is not applied, and  <ins> does not become the current local description, until </ins> setLocalDescription is called. 4.1.8.


allows the signaling to set up a separate media flow for each peer that it wishes to exchange media with.  In JSEP, this offer used in the UPDATE would be formed by simply creating a new PeerConnection <del> and making sure that the same local media streams have been added into this new PeerConnection.  Then the new PeerConnection object would produce a SDP offer that could be used by the signaling to perform the UPDATE strategy discussed in RFC3960. </del>  As a result of sharing the media streams, the application will end up with N parallel PeerConnection sessions, each with a local and remote

Build error looks like travis bustage
PeerConnection is used first at the next to last paragraph of section 3. Please add a reference at that point.
Yes.
Does Robert mean a ref to Section 4, or a ref to the W3C doc? We do have a ref to the W3C doc in Section 1.
That is why I concluded to S 4 (distinguishing between PC and RTCPC)
LGTM

allows the signaling to set up a separate media flow for each peer that it wishes to exchange media with.  In JSEP, this offer used in the UPDATE would be formed by simply creating a new PeerConnection  <ins> (see sec.peerconnection) and making sure that the same local media streams have been added into this new PeerConnection.  Then the new PeerConnection object would produce a SDP offer that could be used by the signaling to perform the UPDATE strategy discussed in RFC3960. </ins> As a result of sharing the media streams, the application will end up with N parallel PeerConnection sessions, each with a local and remote


The addTrack method adds a MediaStreamTrack to the PeerConnection, using the MediaStream argument to associate the track with other tracks in the same MediaStream, so that they can be added to the same <del> "LS" group when creating an offer or answer. addTrack attempts to minimize the number of transceivers as follows: If the PeerConnection is in the "have-remote-offer" state, the track will be attached to the first compatible transceiver that was created by the most recent call to setRemoteDescription() and does not have a local track. Otherwise, a new transceiver will be created, as described in sec.addTransceiver. </del>  4.1.3.

NAME PTAL at the reformulation I added.
"LS" (lipsync) is first used at 4.1.2, with no context for what it is. Please add a reference.
OK

The addTrack method adds a MediaStreamTrack to the PeerConnection, using the MediaStream argument to associate the track with other tracks in the same MediaStream, so that they can be added to the same  <ins> "LS" group when creating an offer or answer, thus allowing these tracks to be synchronized when played out, as described in RFC5888, Section 7.  addTrack attempts to minimize the number of transceivers as follows: If the PeerConnection is in the "have-remote-offer" state, the track will be attached to the first compatible transceiver that was created by the most recent call to setRemoteDescription() and does not have a local track.  Otherwise, a new transceiver will be created, as described in sec.addTransceiver. </ins> 4.1.3.


4.1.17. <del> The addIceCandidate method provides a remote candidate to the ICE agent, which, if parsed successfully, will be added to the current and/or pending remote description according to the rules defined for Trickle ICE.  The pair of MID and ufrag is used to determine the m= section and ICE candidate generation to which the candidate belongs. If the MID is not present, the m= section index is used to look up the locally generated MID (see sec.applying-a-remote-desc), which is used in place of a supplied MID.  If these values or the candidate string are invalid, an error is generated. The purpose of the ufrag is to resolve ambiguities when trickle ICE is in progress during an ICE restart.  If the ufrag is absent, the candidate MUST be assumed to belong to the most recently applied remote description.  Connectivity checks will be sent to the new candidate. This method can also be used to provide an end-of-candidates indication to the ICE agent, as defined in I-D.ietf-ice-trickle). The MID and ufrag are used as described above to determine the m= section and ICE generation for which candidate gathering is complete. If the ufrag is not present, then the end-of-candidates indication MUST be assumed to apply to the relevant m= section in the most recently applied remote description.  If neither the MID nor the m= index is present, then the indication MUST be assumed to apply to all m= sections in the most recently applied remote description. This call will 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 being established. </del>  4.2.

Upon review, it became apparent that this section needed more work to handle the end-of-candidates case properly. I took a first cut at reworking it, but more polish is needed. NAME NAME PTAL to see if you see anything egregiously wrong before I finish polishing it up.
At 4.1.17's first paragraph: Why is "if parsed successfully" necessary to call out? I suggest removing the phrase.
I think it's useful to remind people of this.
I don't care
Suggest moving this text to the last sentence of this para, where we already mention error conditions.

4.1.17.  <ins> The addIceCandidate method provides an update to the ICE agent via an IceCandidate object sec.ice-candidate-format.  If the IceCandidate's candidate field is filled in, the IceCandidate is treated as a new remote ICE candidate, which will be added to the current and/or pending remote description according to the rules defined for Trickle ICE.  Otherwise, the IceCandidate is treated as an end-of-candidates indication, as defined in I-D.ietf-ice-trickle. In either case, the m= section index, MID, and ufrag fields from the supplied IceCandidate are used to determine which m= section and ICE candidate generation the IceCandidate belongs to, as described in sec.ice-candidate-format above.  In the case of an end-of-candidates indication, the absence of both the m= section index and MID fields is interpreted to mean that the indication applies to all m= sections in the specified ICE candidate generation.  However, if both fields are absent for a new remote candidate, this MUST be treated as an invalid condition, as specified below. If any IceCandidate fields contain invalid values, or an error occurs during the processing of the IceCandidate object, the supplied IceCandidate MUST be ignored and an error MUST be returned. Otherwise, the new remote candidate or end-of-candidates indication is supplied to the ICE agent.  In the case of a new remote candidate, connectivity checks will be sent to the new candidate. </ins> 4.2.


5.1.2. For media m= sections, JSEP implementations MUST support the <del> "UDP/TLS/RTP/SAVPF" profile specified in RFC7850, and MUST indicate </del>  this profile for each media m= line they produce in an offer.  For data m= sections, implementations MUST support the "UDP/DTLS/SCTP" profile and MUST indicate this profile for each data m= line they <del> produce in an offer.  Because ICE can select either UDP RFC5245 or TCP RFC6544 transport depending on network conditions, this advertisement is consistent with ICE eventually selecting either either UDP or TCP. </del>  Unfortunately, in an attempt at compatibility, some endpoints generate other profile strings even when they mean to support one of

Slightly more than minor maybe: The first paragraph of 5.1.2 has at least a reference error. UDP/TLS/RTP/SAVPF is not specified in RFC7850. It's in RFC5764. Assuming that this is only a reference error, then the last sentence seems like a stray. It doesn't seem to be in the right context ("this advertisement" doesn't cast back to the discussion of the two profiles above it, which are both UDP only). Please clarify the sentence, giving it the right context, or remove it.
This text is correct. The point is we are saying "advertise UDP but we can do TCP or UDP". We can try to rewrite.
LGTM

5.1.2. For media m= sections, JSEP implementations MUST support the  <ins> "UDP/TLS/RTP/SAVPF" profile specified in RFC5764, and MUST indicate </ins> this profile for each media m= line they produce in an offer.  For data m= sections, implementations MUST support the "UDP/DTLS/SCTP" profile and MUST indicate this profile for each data m= line they  <ins> produce in an offer.  Although these profiles are formally associated with UDP, ICE can select either UDP RFC5245 or TCP RFC6544 transport depending on network conditions, even when advertising a UDP profile. </ins> Unfortunately, in an attempt at compatibility, some endpoints generate other profile strings even when they mean to support one of


resources. Calling this method may do things such as generating new ICE <del> credentials, but does not result in candidate gathering, or cause media to start or stop flowing.  Specifically, the offer is not applied, and does not become the pending local description, until setLocalDescription is called. </del>  4.1.7. description should reflect the current state of the system. Calling this method may do things such as generating new ICE <del> credentials, but does not trigger candidate gathering or cause a media state change.  Specifically, the answer is not applied, and does not become the current local description, until setLocalDescription is called. </del>  4.1.8.

Odd edge: The description createAnswer (in 4.1.7) leaves open the possibility that the application could call createAnswer twice (back-to-back with no intervening calls to other APIs) with different values in the options parameter. Is this ok? If not, should there be language that says not to do that somewhere?
This is explicitly OK, and the state machine makes it clear.
Not sure we need to say anything here, though, given the state machine.
NAME I forgot to mark this invalid but I think it may be.
Discussed with team and plan is to amend the paras that talk about cO/cA not changing media state to also mention that they don't change signaling state.
LGTM

resources. Calling this method may do things such as generating new ICE  <ins> credentials, but does not change the PeerConnection state, trigger candidate gathering, or cause media to start or stop flowing. Specifically, the offer is not applied, and does not become the pending local description, until setLocalDescription is called. </ins> 4.1.7. description should reflect the current state of the system. Calling this method may do things such as generating new ICE  <ins> credentials, but does not change the PeerConnection state, trigger candidate gathering, or or cause a media state change.  Specifically, the answer is not applied, and does not become the current local description, until setLocalDescription is called. </ins> 4.1.8.


answerer, who first calls setRemoteDescription(sdp [offer]) and then later setLocalDescription(sdp [answer]).  JSEP also allows for an answer to be treated as provisional by the application.  Provisional answers provide a way for an answerer to communicate initial session parameters back to the offerer, in order

NAME PTAL
The concept of a "pending local description" is used in sections 3.5.1, , and 4.1.7 but isn't really explained until much later in the document. Please provide forward references, or move a description of what a pending description is earlier in the document.
Yah, this does seem like it needs a fix. Probably something about this in S 3.2.
The second paragraph of section 5.4 is confusing. A slight restructuring of the sentences would remove much of the potential confusion, I think. I suggest replacing the first sentence (which is very complex) with this: "After calling setLocalDescription, the application MAY modify the SDP to reduce the capabilities in the offer before sending it to the far side, as long as it remains a valid SDP offer and specifies a subset of what was in the original offer. Likewise, an application that has received an offer from a peer MAY modify the received SDP, subject to those same constraints, before calling setRemoteDescription."
LGTMLG with nits

answerer, who first calls setRemoteDescription(sdp [offer]) and then later setLocalDescription(sdp [answer]). <ins> During the offer/answer exchange, the outstanding offer is considered to be "pending" at the offerer and the answerer, as it may either be accepted or rejected.  If this is a re-offer, each side will also have "current" local and remote descriptions, which reflect the result of the last offer/answer exchange.  Sections sec.pendingLocalDescription, sec.pendingRemoteDescription, sec.currentLocalDescription, and sec.currentRemoteDescription, provide more detail on pending and current descriptions. </ins> JSEP also allows for an answer to be treated as provisional by the application.  Provisional answers provide a way for an answerer to communicate initial session parameters back to the offerer, in order


the SDP is needed, the aforementioned createOffer/createAnswer options or RtpTransceiver APIs MUST be used. <del> Note that the application MAY modify the SDP to reduce the capabilities in the offer it sends to the far side (post- setLocalDescription) or the offer that it installs from the far side (pre-setRemoteDescription), as long as it remains a valid SDP offer and specifies a subset of what was in the original offer.  This is safe because the answer is not permitted to expand capabilities, and therefore will just respond to what is present in the offer. The application SHOULD NOT modify the SDP in the answer it transmits, as the answer contains the negotiated capabilities, and this can cause the two sides to have different ideas about what exactly was negotiated. </del>  As always, the application is solely responsible for what it sends to the other party, and all incoming SDP will be processed by the JSEP

But also clarify that this can be used to modify an offer OR answer, as long as it remains a legal JSEP o/a.
The second paragraph of section 5.4 is confusing. A slight restructuring of the sentences would remove much of the potential confusion, I think. I suggest replacing the first sentence (which is very complex) with this: "After calling setLocalDescription, the application MAY modify the SDP to reduce the capabilities in the offer before sending it to the far side, as long as it remains a valid SDP offer and specifies a subset of what was in the original offer. Likewise, an application that has received an offer from a peer MAY modify the received SDP, subject to those same constraints, before calling setRemoteDescription."
lgtm

the SDP is needed, the aforementioned createOffer/createAnswer options or RtpTransceiver APIs MUST be used.  <ins> After calling setLocalDescription with an offer or answer, the application MAY modify the SDP to reduce its capabilities before sending it to the far side, as long as it follows the rules above that define a valid JSEP offer or answer.  Likewise, an application that has received an offer or answer from a peer MAY modify the received SDP, subject to the same constraints, before calling setRemoteDescription. </ins> As always, the application is solely responsible for what it sends to the other party, and all incoming SDP will be processed by the JSEP


For each specified "telephone-event" media format, enable DTMF transmission for all supported media formats with the same clockrate, as described in RFC4733, Section 2.5.1.2. <del> If the application attempts to transmit DTMF when using a media format that does not have a corresponding telephone- event format, this MUST result in an error. </del>  For any specified "ptime" value, configure the available media formats to use the specified packet size when sending.

NAME PTAL
On page 69, at "If the application attempt to transmit DTMF when using a media format that does not have a corresponding telephone-event format, this MUST result in an error". This sentence is out-of-place. The section is about applying a remote description. If the document needs to retain the sentence, it belongs off in some "processing media" section. In particular, the current placement of text is confusing about what and when an error could be returned, and it could be misread to say that an error should be returned to the setRemoteDescription call.
I agree
Agreed; I don't really feel like we need to create a new "Sending DTMF" section, so my recommendation would be to adjust the text to something like For each specified "telephone-event" media format, enable DTMF transmission for all supported media formats with the same clockrate, as described in [RFC4733], Section 2.5.1.2. If there are any supported media formats that do not have a corresponding telephone-event format, disable DTMF transmission for those formats.
LGTM

For each specified "telephone-event" media format, enable DTMF transmission for all supported media formats with the same clockrate, as described in RFC4733, Section 2.5.1.2.  <ins> If there are any supported media formats that do not have a corresponding telephone-event format, disable DTMF transmission for those formats. </ins> For any specified "ptime" value, configure the available media formats to use the specified packet size when sending.


The setDirection method sets the direction of a transceiver, which affects the direction property of the associated m= section on future <del> calls to createOffer and createAnswer. </del>  When creating offers, the transceiver direction is directly reflected in the output, even for re-offers.  When creating answers, the

talks about setting direction properties, but the values that can be set aren't called out (and even then only by inference from a list in an example) in section 4.2.5. Should there be explicit pointers to the api doc here? (And in section 4.2.6?)
Yes, I think a pointer to the API doc is what's needed here.
The more I look at it, I think it is the SDP, not the API doc that effectively defines the allow values of the direction.
LGTM

The setDirection method sets the direction of a transceiver, which affects the direction property of the associated m= section on future  <ins> calls to createOffer and createAnswer.  The permitted values for direction are "recvonly", "sendrecv", "sendonly", and "inactive", mirroring the identically-named directional attributes defined in RFC4566, Section 6. </ins> When creating offers, the transceiver direction is directly reflected in the output, even for re-offers.  When creating answers, the