<?xml version="1.0" encoding="us-ascii"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<?rfc toc="yes" ?>
<?rfc symrefs="yes" ?>
<?rfc iprnotified="no" ?>
<?rfc strict="yes" ?>
<?rfc compact="yes" ?>
<?rfc sortrefs="yes" ?>
<?rfc colonspace="yes" ?>
<?rfc rfcedstyle="no" ?>
<?rfc docmapping="yes" ?>
<?rfc tocdepth="4"?>
<rfc category="std" docName="draft-ietf-rtcweb-jsep-15"
ipr="trust200902">
    <front>
        <title abbrev="JSEP">Javascript Session Establishment
        Protocol</title>
        <author fullname="Justin Uberti" initials="J."
        surname="Uberti">
            <organization>Google</organization>
            <address>
                <postal>
                    <street>747 6th St S</street>
                    <city>Kirkland</city>
                    <region>WA</region>
                    <code>98033</code>
                    <country>USA</country>
                </postal>
                <email>justin@uberti.name</email>
            </address>
        </author>
        <author fullname="Cullen Jennings" initials="C."
        surname="Jennings">
            <organization>Cisco</organization>
            <address>
                <postal>
                    <street>170 West Tasman Drive</street>
                    <city>San Jose</city>
                    <region>CA</region>
                    <code>95134</code>
                    <country>USA</country>
                </postal>
                <email>fluffy@iii.ca</email>
            </address>
        </author>
        <author fullname="Eric Rescorla" initials="E.K."
        surname="Rescorla" role="editor">
            <organization>Mozilla</organization>
            <address>
                <postal>
                    <street>331 Evelyn Ave</street>
                    <city>Mountain View</city>
                    <region>CA</region>
                    <code>94041</code>
                    <country>USA</country>
                </postal>
                <email>ekr@rtfm.com</email>
            </address>
        </author>
        <date/>
        <area>RAI</area>
        <abstract>

            <t>This document describes the mechanisms for allowing a
            Javascript application to control the signaling plane of a
            multimedia session via the interface specified in the W3C
            RTCPeerConnection API, and discusses how this relates to
            existing signaling protocols.</t>

        </abstract>
    </front>
    <middle>
        <section title="Introduction" anchor="sec.introduction">

            <t>This document describes how the W3C WEBRTC
            RTCPeerConnection interface <xref
            target="W3C.WD-webrtc-20140617"></xref> is used to control
            the setup, management and teardown of a multimedia
            session.</t>

            <section title="General Design of JSEP"
            anchor="sec.general-design-of-jsep">

                <t>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 or Jingle call signaling protocols, 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.</t>

                <t>With these considerations in mind, this document
                describes the Javascript Session Establishment Protocol
                (JSEP) that allows for full control of the signaling
                state machine from Javascript. JSEP removes the browser
                almost entirely from the core signaling flow, which is
                instead handled by the Javascript making use of two
                interfaces: (1) passing in local and remote session
                descriptions and (2) interacting with the ICE state
                machine.</t>

                <t>In this document, the use of JSEP is described as if
                it always occurs between two browsers. Note though in
                many cases it will actually be between a browser and
                some kind of server, such as a gateway or MCU. This
                distinction is invisible to the browser; it just follows
                the instructions it is given via the API.</t>

                <t>JSEP's handling of session descriptions is simple and
                straightforward. Whenever an offer/answer exchange is
                needed, the initiating side creates an offer by calling
                a createOffer() API. The application optionally modifies
                that offer, and then uses it to set up its local config
                via the setLocalDescription() API. The offer is then
                sent off to the remote side over its preferred signaling
                mechanism (e.g., WebSockets); upon receipt of that
                offer, the remote party installs it using the
                setRemoteDescription() API.</t>

                <t>To complete the offer/answer exchange, the remote
                party uses the createAnswer() API to generate an
                appropriate answer, applies it using the
                setLocalDescription() API, and sends the answer back to
                the initiator over the signaling channel. When the
                initiator gets that answer, it installs it using the
                setRemoteDescription() API, and initial setup is
                complete. This process can be repeated for additional
                offer/answer exchanges.</t>

                <t>Regarding ICE <xref target="RFC5245"></xref>, JSEP
                decouples the ICE state machine from the overall
                signaling state machine, as the ICE state machine must
                remain in the browser, because only the browser has the
                necessary knowledge of candidates and other transport
                info. Performing this separation also provides
                additional flexibility; in protocols that decouple
                session descriptions from transport, such as Jingle, the
                session description can be sent immediately and the
                transport information can be sent when available. In
                protocols that don't, such as SIP, the information can
                be used in the aggregated form. Sending transport
                information separately can allow for faster ICE and DTLS
                startup, since ICE checks can start as soon as any
                transport information is available rather than waiting
                for all of it.</t>

                <t>Through its abstraction of signaling, the JSEP
                approach does require the application to be aware of the
                signaling process. While the application does not need
                to understand the contents of session descriptions to
                set up a call, the application must call the right APIs
                at the right times, convert the session descriptions and
                ICE information into the defined messages of its chosen
                signaling protocol, and perform the reverse conversion
                on the messages it receives from the other side.</t>

                <t>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.</t>

            </section>
            <section title="Other Approaches Considered"
            anchor="sec.other-approaches-consider">

                <t>One approach that was considered instead of JSEP was
                to include a lightweight signaling protocol. Instead of
                providing session 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 browser, forcing the browser 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.</t>

                <t>A second approach that was considered but not chosen
                was to decouple the management of the media control
                objects from session descriptions, instead offering APIs
                that would control each component directly. This was
                rejected based on a feeling that requiring exposure of
                this level of complexity to the application programmer
                would not be beneficial; it would result in an API where
                even a simple example would require a significant amount
                of code to orchestrate all the needed interactions, as
                well as creating a large API surface that needed to be
                agreed upon and documented.  In addition, these API
                points could be called in any order, resulting in a more
                complex set of interactions with the media subsystem
                than the JSEP approach, which specifies how session
                descriptions are to be evaluated and applied.</t>

                <t>One variation on JSEP that was considered was to keep
                the basic session description-oriented API, but to move
                the mechanism for generating offers and answers out of
                the browser. Instead of providing
                createOffer/createAnswer methods within the browser,
                this approach would instead expose a getCapabilities API
                which would provide the application with the information
                it needed in order to generate its own session
                descriptions. This increases the amount of work that the
                application needs to do; it needs to know how to
                generate session descriptions from capabilities, and
                especially how to generate the correct answer from an
                arbitrary offer and the supported capabilities. While
                this could certainly be addressed by using a library
                like the one mentioned above, it basically forces the
                use of said library even for a simple example.
                Providing createOffer/createAnswer avoids this problem,
                but still allows applications to generate their own
                offers/answers (to a large extent) if they choose, using
                the description generated by createOffer as an
                indication of the browser's capabilities.</t>

            </section>
        </section>
        <section title="Terminology" anchor="sec.terminology">

            <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL",
            "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY",
            and "OPTIONAL" in this document are to be interpreted as
            described in <xref target="RFC2119"></xref>.</t>

        </section>
        <section title="Semantics and Syntax"
        anchor="sec.semantics-and-syntax">
            <section title="Signaling Model"
            anchor="sec.signaling-model">

                <t>JSEP does not specify a particular signaling model or
                state machine, other than the generic need to exchange
                session descriptions in the fashion described by <xref
                target="RFC3264"></xref>(offer/answer) in order for both
                sides of the session to know how to conduct the
                session. JSEP provides mechanisms to create offers and
                answers, as well as to apply them to a session.
                However, the browser is totally decoupled from the
                actual mechanism by which these offers and answers are
                communicated to the remote side, including addressing,
                retransmission, forking, and glare handling. These
                issues are left entirely up to the application; the
                application has complete control over which offers and
                answers get handed to the browser, and when.</t>

                <figure anchor="fig-sigModel"
                title="JSEP Signaling Model">
                    <artwork>
                        <![CDATA[
    +-----------+                               +-----------+
    |  Web App  |<--- App-Specific Signaling -->|  Web App  |
    +-----------+                               +-----------+
          ^                                            ^
          |  SDP                                       |  SDP
          V                                            V
    +-----------+                                +-----------+
    |  Browser  |<----------- Media ------------>|  Browser  |
    +-----------+                                +-----------+
]]>
</artwork>
                </figure>

            </section>
            <section title="Session Descriptions and State Machine"
            anchor="sec.session-descriptions-and-">

                <t>In order to establish the media plane, the user agent
                needs specific parameters to indicate what to transmit
                to the remote side, as well as how to handle the media
                that is received. These parameters are determined by the
                exchange of session descriptions in offers and answers,
                and there are certain details to this process that must
                be handled in the JSEP APIs.</t>

                <t>Whether a session description applies to the local
                side or the remote side affects the meaning of that
                description. For example, the list of codecs sent to a
                remote party indicates what the local side is willing to
                receive, which, when intersected with the set of codecs
                the remote side supports, specifies what the remote side
                should send. However, not all parameters follow this
                rule; for example, the DTLS-SRTP parameters <xref
                target="RFC5763"></xref> sent to a remote party indicate
                what certificate the local side will use in DTLS setup,
                and thereby what the remote party should expect to
                receive; the remote party will have to accept these
                parameters, with no option to choose different
                values.</t>

                <t>In addition, various RFCs put different conditions on
                the format of offers versus answers. For example, an
                offer may propose an arbitrary number of media streams
                (i.e. m= sections), but an answer must contain the exact
                same number as the offer.</t>

                <t>Lastly, while the exact media parameters are only
                known only after an offer and an answer have been
                exchanged, it is possible for the offerer to receive
                media after they have sent an offer and before they have
                received an answer. To properly process incoming media
                in this case, the offerer's media handler must be aware
                of the details of the offer before the answer
                arrives.</t>

                <t>Therefore, in order to handle session descriptions
                properly, the user agent needs:
                <list style="numbers">

                    <t>To know if a session description pertains to the
                    local or remote side.</t>

                    <t>To know if a session description is an offer or
                    an answer.</t>

                    <t>To allow the offer to be specified independently
                    of the answer.</t>

                </list>
                JSEP addresses this by adding both setLocalDescription
                and setRemoteDescription methods and having session
                description objects contain a type field indicating the
                type of session description being supplied. This
                satisfies the requirements listed above for both the
                offerer, who first calls setLocalDescription(sdp
                [offer]) and then later setRemoteDescription(sdp
                [answer]), as well as for the answerer, who first calls
                setRemoteDescription(sdp [offer]) and then later
                setLocalDescription(sdp [answer]).</t>

                <t>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 to
                allow the session to begin, while allowing a final
                answer to be specified later. This concept of a final
                answer is important to the offer/answer model; when such
                an answer is received, any extra resources allocated by
                the caller can be released, now that the exact session
                configuration is known. These "resources" can include
                things like extra ICE components, TURN candidates, or
                video decoders. Provisional answers, on the other hand,
                do no such deallocation results; as a result, multiple
                dissimilar provisional answers can be received and
                applied during call setup.</t>

                <t>In <xref target="RFC3264"></xref>, the constraint at
                the signaling level is that only one offer can be
                outstanding for a given session, but at the media stack
                level, a new offer can be generated at any point. For
                example, when using SIP for signaling, if one offer is
                sent, then cancelled using a SIP CANCEL, another offer
                can be generated even though no answer was received for
                the first offer. To support this, the JSEP media layer
                can provide an offer via the createOffer() method
                whenever the Javascript application needs one for the
                signaling. The answerer can send back zero or more
                provisional answers, and finally end the offer-answer
                exchange by sending a final answer. The state machine
                for this is as follows:</t>

                <t>
                    <figure anchor="fig-state-machine"
                    title="JSEP State Machine">
                        <artwork>
                            <![CDATA[
                    setRemote(OFFER)               setLocal(PRANSWER)
                        /-----\                               /-----\
                        |     |                               |     |
                        v     |                               v     |
         +---------------+    |                +---------------+    |
         |               |----/                |               |----/
         |               | setLocal(PRANSWER)  |               |
         |  Remote-Offer |------------------- >| Local-Pranswer|
         |               |                     |               |
         |               |                     |               |
         +---------------+                     +---------------+
              ^   |                                   |
              |   | setLocal(ANSWER)                  |
setRemote(OFFER)  |                                   |
              |   V                  setLocal(ANSWER) |
         +---------------+                            |
         |               |                            |
         |               |<---------------------------+
         |    Stable     |
         |               |<---------------------------+
         |               |                            |
         +---------------+          setRemote(ANSWER) |
              ^   |                                   |
              |   | setLocal(OFFER)                   |
setRemote(ANSWER) |                                   |
              |   V                                   |
         +---------------+                     +---------------+
         |               |                     |               |
         |               | setRemote(PRANSWER) |               |
         |  Local-Offer  |------------------- >|Remote-Pranswer|
         |               |                     |               |
         |               |----\                |               |----\
         +---------------+    |                +---------------+    |
                        ^     |                               ^     |
                        |     |                               |     |
                        \-----/                               \-----/
                    setLocal(OFFER)               setRemote(PRANSWER)
]]>
</artwork>
                    </figure>
                </t>

                <t>Aside from these state transitions there is no other
                difference between the handling of provisional
                ("pranswer") and final ("answer") answers.</t>

            </section>
            <section title="Session Description Format"
            anchor="sec.session-description-forma">

                <t>In the WebRTC specification, session descriptions are
                formatted as SDP messages. While this format is not
                optimal for manipulation from Javascript, it is widely
                accepted, and frequently updated with new features. Any
                alternate encoding of session descriptions would have to
                keep pace with the changes to SDP, at least until the
                time that this new encoding eclipsed SDP in
                popularity. As a result, JSEP currently uses SDP as the
                internal representation for its session
                descriptions.</t>

                <t>However, to simplify Javascript processing, and
                provide for future flexibility, the SDP syntax is
                encapsulated within a SessionDescription object, which
                can be constructed from SDP, and be serialized out to
                SDP. If future specifications agree on a JSON format for
                session descriptions, we could easily enable this object
                to generate and consume that JSON.</t>

                <t>Other methods may be added to SessionDescription in
                the future to simplify handling of SessionDescriptions
                from Javascript. In the meantime, Javascript libraries
                can be used to perform these manipulations.</t>

                <t>Note that most applications should be able to treat
                the SessionDescriptions produced and consumed by these
                various API calls as opaque blobs; that is, the
                application will not need to read or change them.</t>

            </section>
            <section title="Session Description Control"
            anchor="sec.session-description-ctrl">

                <t>In order to give the application control over various
                common session parameters, JSEP provides control
                surfaces which tell the browser how to generate session
                descriptions. This avoids the need for Javascript to
                modify session descriptions in most cases.</t>

                <t>Changes to these objects result in changes to the
                session descriptions generated by subsequent
                createOffer/Answer calls.</t>

                <section title="RtpTransceivers"
                anchor="sec.rtptransceivers">

                    <t>RtpTransceivers allow the application to control
                    the RTP media associated with one m= section. Each
                    RtpTransceiver has an RtpSender and an RtpReceiver,
                    which an application can use to control the sending
                    and receiving of RTP media. The application may also
                    modify the RtpTransceiver directly, for instance, by
                    stopping it.</t>

                    <t>RtpTransceivers generally have a 1:1 mapping with
                    m= sections, although there may be more
                    RtpTransceivers than m= sections when
                    RtpTransceivers are created but not yet associated
                    with a m= section, or if RtpTransceivers have been
                    stopped and disassociated from m= sections. 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.</t>

                    <t>RtpTransceivers can be created explicitly by the
                    application or implicitly by calling
                    setRemoteDescription with an offer that adds new m=
                    sections.</t>

                </section>
                <section title="RtpSenders" anchor="sec.rtpsenders">

                    <t>RtpSenders allow the application to control how
                    RTP media is sent. In particular, the application
                    can control whether an RtpSender is active or not,
                    which affects the directionality attribute of the
                    associated m= section.</t>

                </section>
                <section title="RtpReceivers"
                anchor="sec.rtpreceivers">

                    <t>RtpReceivers allows the application to control
                    how RTP media is received. In particular, the
                    application can control whether an RtpReceiver is
                    active or not, which affects the directionality
                    attribute of the associated m= section.</t>

                </section>
            </section>
            <section title="ICE" anchor="sec.ice">
                <section title="ICE Gathering Overview"
                anchor="sec.ice-gather-overview">

                    <t>JSEP gathers ICE candidates as needed by the
                    application. Collection of ICE candidates is
                    referred to as a gathering phase, and this is
                    triggered either by the addition of a new or
                    recycled m= line to the local session description,
                    or new ICE credentials in the description,
                    indicating an ICE restart. Use of new ICE
                    credentials can be triggered explicitly by the
                    application, or implicitly by the browser in
                    response to changes in the ICE configuration.</t>

                    <t>When the ICE configuration changes in a way that
                    requires a new gathering phase, a
                    'needs-ice-restart' bit is set. When this bit is
                    set, calls to the createOffer API will generate new
                    ICE credentials. This bit is cleared by a call to
                    the setLocalDescription API with new ICE credentials
                    from either an offer or an answer, i.e., from either
                    a local- or remote-initiated ICE restart.</t>

                    <t>When a new gathering phase starts, the ICE Agent
                    will notify the application that gathering is
                    occurring through an event. Then, when each new ICE
                    candidate becomes available, the ICE Agent will
                    supply it to the application via an additional
                    event; these candidates will also automatically be
                    added to the current and/or pending local session
                    description. Finally, when all candidates have been
                    gathered, an event will be dispatched to signal that
                    the gathering process is complete.</t>

                    <t>Note that gathering phases only gather the
                    candidates needed by new/recycled/restarting m=
                    lines; other m= lines continue to use their existing
                    candidates. Also, when bundling is active,
                    candidates are only gathered (and exchanged) for the
                    m= lines referenced in BUNDLE-tags, as described in
                    <xref
                    target="I-D.ietf-mmusic-sdp-bundle-negotiation"
                    />.</t>

                </section>
                <section title="ICE Candidate Trickling"
                anchor="sec.ice-candidate-trickling">

                    <t>Candidate trickling is a technique through which
                    a caller may incrementally provide candidates to the
                    callee after the initial offer has been dispatched;
                    the semantics of "Trickle ICE" are defined in <xref
                    target="I-D.ietf-ice-trickle"></xref>. This process
                    allows the callee to begin acting upon the call and
                    setting up the ICE (and perhaps DTLS) connections
                    immediately, without having to wait for the caller
                    to gather all possible candidates. This results in
                    faster media setup in cases where gathering is not
                    performed prior to initiating the call.</t>

                    <t>JSEP supports optional candidate trickling by
                    providing APIs, as described above, that provide
                    control and feedback on the ICE candidate gathering
                    process. Applications that support candidate
                    trickling can send the initial offer immediately
                    and send individual candidates when they get the
                    notified of a new candidate; applications that do
                    not support this feature can simply wait for the
                    indication that gathering is complete, and then
                    create and send their offer, with all the
                    candidates, at this time.</t>

                    <t>Upon receipt of trickled candidates, the
                    receiving application will supply them to its ICE
                    Agent. This triggers the ICE Agent to start using
                    the new remote candidates for connectivity
                    checks.</t>

                    <section title="ICE Candidate Format"
                    anchor="sec.ice-candidate-format">

                        <t>As with session descriptions, the syntax of
                        the IceCandidate object provides some
                        abstraction, but can be easily converted to and
                        from the SDP candidate lines.</t>

                        <t>The candidate lines are the only SDP
                        information that is contained within
                        IceCandidate, as they represent the only
                        information needed that is not present in the
                        initial offer (i.e., for trickle candidates).
                        This information is carried with the same
                        syntax as the "candidate-attribute" field
                        defined for ICE. For example:</t>

                        <figure>
                            <artwork>
                                <![CDATA[
candidate:1 1 UDP 1694498815 192.0.2.33 10000 typ host
]]>
</artwork>
                        </figure>

                        <t>The IceCandidate object also contains fields
                        to indicate which m= line it should be
                        associated with. The m= line can be identified
                        in one of two ways; either by a m= line index,
                        or a MID. The m= line index is a zero-based
                        index, with index N referring to the N+1th m=
                        line in the SDP sent by the entity which sent
                        the IceCandidate. The MID uses the "media stream
                        identification" attribute, as defined in <xref
                        target="RFC5888"></xref>, Section 4, to identify
                        the m= line. JSEP implementations creating an
                        ICE Candidate object MUST populate both of these
                        fields. Implementations receiving an ICE
                        Candidate object MUST use the MID if present, or
                        the m= line index, if not (as it could have come
                        from a non-JSEP endpoint).</t>

                    </section>
                </section>
                <section title="ICE Candidate Policy"
                anchor="sec.ice-candidate-policy">

                    <t>Typically, when gathering ICE candidates, the
                    browser will gather all possible forms of initial
                    candidates - host, server reflexive, and relay.
                    However, in certain cases, applications may want to
                    have more specific control over the gathering
                    process, due to privacy or related concerns. For
                    example, one may want to suppress the use of host
                    candidates, to avoid exposing information about the
                    local network, or go as far as only using relay
                    candidates, to leak as little location information
                    as possible (note that these choices come with
                    corresponding operational costs). To accomplish
                    this, the browser MUST allow the application to
                    restrict which ICE candidates are used in a
                    session. Note that this filtering is applied on top
                    of any restrictions the browser chooses to enforce
                    regarding which IP addresses are permitted for the
                    application, as discussed in <xref
                    target="I-D.ietf-rtcweb-ip-handling" />.</t>

                    <t>There may also be cases where the application
                    wants to change which types of candidates are used
                    while the session is active. A prime example is
                    where a callee may initially want to use only relay
                    candidates, to avoid leaking location information
                    to an arbitrary caller, but then change to use all
                    candidates (for lower operational cost) once the
                    user has indicated they want to take the call. For
                    this scenario, the browser MUST allow the candidate
                    policy to be changed in mid-session, subject to the
                    aforementioned interactions with local policy.</t>

                    <t>To administer the ICE candidate policy, the
                    browser will determine the current setting at the
                    start of each gathering phase. Then, during the
                    gathering phase, the browser MUST NOT expose
                    candidates disallowed by the current policy to the
                    application, use them as the source of connectivity
                    checks, or indirectly expose them via other fields,
                    such as the raddr/rport attributes for other ICE
                    candidates. Later, if a different policy is
                    specified by the application, the application can
                    apply it by kicking off a new gathering phase via
                    an ICE restart.</t>

                </section>
                <section title="ICE Candidate Pool"
                anchor="sec.ice-candidate-pool">

                    <t>JSEP applications typically inform the browser
                    to begin ICE gathering via the information supplied
                    to setLocalDescription, as this is where the app
                    specifies the number of media streams, and thereby
                    ICE components, for which to gather candidates.
                    However, to accelerate cases where the application
                    knows the number of ICE components to use ahead of
                    time, it may ask the browser to gather a pool of
                    potential ICE candidates to help ensure rapid media
                    setup.</t>

                    <t>When setLocalDescription is eventually called,
                    and the browser goes to gather the needed ICE
                    candidates, it SHOULD start by checking if any
                    candidates are available in the pool. If there are
                    candidates in the pool, they SHOULD be handed to
                    the application immediately via the ICE candidate
                    event. If the pool becomes depleted, either because
                    a larger-than-expected number of ICE components is
                    used, or because the pool has not had enough time
                    to gather candidates, the remaining candidates are
                    gathered as usual.</t>

                    <t>One example of where this concept is useful is
                    an application that expects an incoming call at
                    some point in the future, and wants to minimize the
                    time it takes to establish connectivity, to avoid
                    clipping of initial media. By pre-gathering
                    candidates into the pool, it can exchange and start
                    sending connectivity checks from these candidates
                    almost immediately upon receipt of a call. Note
                    though that by holding on to these pre-gathered
                    candidates, which will be kept alive as long as
                    they may be needed, the application will consume
                    resources on the STUN/TURN servers it is using.</t>

                </section>
            </section>
            <section anchor="sec.imageattr"
            title="Video Size Negotiation">

                <t>Video size negotiation is the process through which a
                receiver can use the "a=imageattr" SDP attribute <xref
                target="RFC6236" /> to indicate what video frame sizes
                it is capable of receiving. A receiver may have hard
                limits on what its video decoder can process, or it may
                wish to constrain what it receives due to application
                preferences, e.g. a specific size for the window in
                which the video will be displayed.</t>

                <section title="Creating an imageattr Attribute">

                    <t>In order to determine the limits on what video
                    resolution a receiver wants to receive, it will
                    intersect its decoder hard limits with any
                    mandatory constraints that have been applied to the
                    associated MediaStreamTrack. If the decoder limits
                    are unknown, e.g. when using a software decoder,
                    the mandatory constraints are used directly. For
                    the answerer, these mandatory constraints can be
                    applied to the remote MediaStreamTracks that are
                    created by a setRemoteDescription call, and will
                    affect the output of the ensuing createAnswer call.
                    Any constraints set after setLocalDescription is
                    used to set the answer will result in a new
                    offer-answer exchange. For the offerer, because it
                    does not know about any remote MediaStreamTracks
                    until it receives the answer, the offer can only
                    reflect decoder hard limits. If the offerer wishes
                    to set mandatory constraints on video resolution,
                    it must do so after receiving the answer, and the
                    result will be a new offer-answer to communicate
                    them.</t>

                    <t>If there are no known decoder limits or
                    mandatory constraints, the "a=imageattr" attribute
                    SHOULD be omitted.</t>

                    <t>Otherwise, an "a=imageattr" attribute is created
                    with "recv" direction, and the resulting resolution
                    space formed by intersecting the decoder limits and
                    constraints is used to specify its minimum and
                    maximum x= and y= values. If the intersection is
                    the null set, i.e., there are no resolutions that
                    are permitted by both the decoder and the mandatory
                    constraints, this SHOULD be represented by x=0 and
                    y=0 values.</t>

                    <t>The rules here express a single set of
                    preferences, and therefore, the "a=imageattr" q=
                    value is not important. It SHOULD be set to
                    1.0.</t>

                    <t>The "a=imageattr" field is payload type
                    specific. When all video codecs supported have the
                    same capabilities, use of a single attribute, with
                    the wildcard payload type (*), is RECOMMENDED.
                    However, when the supported video codecs have
                    differing capabilities, specific "a=imageattr"
                    attributes MUST be inserted for each payload
                    type.</t>

                    <t>As an example, consider a system with a
                    HD-capable, multiformat video decoder, where the
                    application has constrained the received track to
                    at most 360p. In this case, the implementation
                    would generate this attribute:</t>

                    <t>a=imageattr:* recv
                    [x=[16:640],y=[16:360],q=1.0]</t>

                    <t>This declaration indicates that the receiver is
                    capable of decoding any image resolution from 16x16
                    up to 640x360 pixels.</t>

                </section>
                <section title="Interpreting an imageattr Attribute">

                    <t><xref target="RFC6236" /> defines "a=imageattr"
                    to be an advisory field. This means that it does not
                    absolutely constrain the video formats that the
                    sender can use, but gives an indication of the
                    preferred values.</t>

                    <t>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), as it significantly simplifies
                    the matching logic.</t>

                    <t>For an "a=imageattr recv" attribute, only size
                    limits are considered. Any other values, e.g.
                    aspect ratio, MUST be ignored.</t>

                    <t>When communicating with a non-JSEP endpoint,
                    multiple relevant "a=imageattr recv" attributes may
                    be received. If this occurs, attributes other than
                    the one with the highest "q=" value MUST be
                    ignored.</t>

                    <t>If an "a=imageattr recv" attribute references a
                    different video codec than what has been selected
                    for the MediaStreamTrack, it MUST be ignored.</t>

                    <t>If the original resolution matches the size
                    limits in the attribute, the track MUST be
                    transmitted untouched.</t>

                    <t>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.</t>

                    <t>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.</t>

                    <t>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.</t>

                    <t>In the special case of receiving a maximum
                    resolution of [0, 0], as described above, the
                    sender MUST NOT transmit the track.</t>

                </section>
            </section>
            <section title="Interactions With Forking"
            anchor="sec.interactions-with-forking">

                <t>Some call signaling systems allow various types of
                forking where an SDP Offer may be provided to more than
                one device. For example, SIP <xref
                target="RFC3261"></xref> defines both a "Parallel
                Search" and "Sequential Search". Although these are
                primarily signaling level issues that are outside the
                scope of JSEP, they do have some impact on the
                configuration of the media plane that is relevant. When
                forking happens at the signaling layer, the Javascript
                application responsible for the signaling needs to make
                the decisions about what media should be sent or
                received at any point of time, as well as which remote
                endpoint it should communicate with; JSEP is used to
                make sure the media engine can make the RTP and media
                perform as required by the application. The basic
                operations that the applications can have the media
                engine do are:
                <list style="symbols">

                    <t>Start exchanging media with a given remote peer,
                    but keep all the resources reserved in the
                    offer.</t>

                    <t>Start exchanging media with a given remote peer,
                    and free any resources in the offer that are not
                    being used.</t>

                </list></t>
                <section title="Sequential Forking"
                anchor="sec.sequential-forking">

                    <t>Sequential forking involves a call being
                    dispatched to multiple remote callees, where each
                    callee can accept the call, but only one active
                    session ever exists at a time; no mixing of
                    received media is performed.</t>

                    <t>JSEP handles sequential forking well, allowing
                    the application to easily control the policy for
                    selecting the desired remote endpoint. When an
                    answer arrives from one of the callees, the
                    application can choose to apply it either as a
                    provisional answer, leaving open the possibility of
                    using a different answer in the future, or apply it
                    as a final answer, ending the setup flow.</t>

                    <t>In a "first-one-wins" situation, the first
                    answer will be applied as a final answer, and the
                    application will reject any subsequent answers. In
                    SIP parlance, this would be ACK + BYE.</t>

                    <t>In a "last-one-wins" situation, all answers
                    would be applied as provisional answers, and any
                    previous call leg will be terminated. At some
                    point, the application will end the setup process,
                    perhaps with a timer; at this point, the
                    application could reapply the pending remote
                    description as a final answer.</t>

                </section>
                <section title="Parallel Forking"
                anchor="sec.parallel-forking">

                    <t>Parallel forking involves a call being dispatched
                    to multiple remote callees, where each callee can
                    accept the call, and multiple simultaneous active
                    signaling sessions can be established as a
                    result. If multiple callees send media at the same
                    time, the possibilities for handling this are
                    described in Section 3.1 of <xref
                    target="RFC3960"></xref>. Most SIP devices today
                    only support exchanging media with a single device
                    at a time, and do not try to mix multiple early
                    media audio sources, as that could result in a
                    confusing situation. For example, consider having a
                    European ringback tone mixed together with the North
                    American ringback tone - the resulting sound would
                    not be like either tone, and would confuse the
                    user. If the signaling application wishes to only
                    exchange media with one of the remote endpoints at a
                    time, then from a media engine point of view, this
                    is exactly like the sequential forking case.</t>

                    <t>In the parallel forking case where the Javascript
                    application wishes to simultaneously exchange media
                    with multiple peers, the flow is slightly more
                    complex, but the Javascript application can follow
                    the strategy that <xref target="RFC3960"></xref>
                    describes using UPDATE. The UPDATE approach 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 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 <xref
                    target="RFC3960"></xref>.</t>

                    <t>As a result of sharing the media streams, the
                    application will end up with N parallel
                    PeerConnection sessions, each with a local and
                    remote description and their own local and remote
                    addresses. The media flow from these sessions can
                    be managed by specifying SDP direction attributes
                    in the descriptions, or the application can choose
                    to play out the media from all sessions mixed
                    together. Of course, if the application wants to
                    only keep a single session, it can simply terminate
                    the sessions that it no longer needs.</t>

                </section>
            </section>
        </section>
        <section title="Interface" anchor="sec.interface">

            <t>This section details the basic operations that must be
            present to implement JSEP functionality. The actual API
            exposed in the W3C API may have somewhat different syntax,
            but should map easily to these concepts.</t>
            <section title="Methods" anchor="sec.methods">
                <section title="Constructor" anchor="sec.constructor">

                    <t>The PeerConnection constructor allows the
                    application to specify global parameters for the
                    media session, such as the STUN/TURN servers and
                    credentials to use when gathering candidates, as
                    well as the initial ICE candidate policy and pool
                    size, and also the bundle policy to use.</t>

                    <t>If an ICE candidate policy is specified, it
                    functions as described in <xref
                    target="sec.ice-candidate-policy" />, causing the
                    browser to only surface the permitted candidates
                    (including any internal browser filtering) to the
                    application, and only use those candidates for
                    connectivity checks. The set of available policies
                    is as follows:

                    <list style="hanging">

                        <t hangText="all:">All candidates permitted by
                        browser policy will be gathered and used.</t>

                        <t></t>

                        <t hangText="relay:">All candidates except
                        relay candidates will be filtered out. This
                        obfuscates the location information that might
                        be ascertained by the remote peer from the
                        received candidates. Depending on how the
                        application deploys its relay servers, this
                        could obfuscate location to a metro or possibly
                        even global level.</t>

                    </list></t>

                    <t>The default ICE candidate policy MUST be set to
                    "all" as this is generally the desired policy, and
                    also typically reduces use of application TURN
                    server resources significantly.</t>

                    <t>If a size is specified for the ICE candidate
                    pool, this indicates the number of ICE components
                    to pre-gather candidates for. Because pre-gathering
                    results in utilizing STUN/TURN server resources for
                    potentially long periods of time, this must only
                    occur upon application request, and therefore the
                    default candidate pool size MUST be zero.</t>

                    <t>The application can specify its preferred policy
                    regarding use of bundle, the multiplexing mechanism
                    defined in <xref
                    target="I-D.ietf-mmusic-sdp-bundle-negotiation">
                    </xref>. Regardless of policy, the application will
                    always try to negotiate bundle onto a single
                    transport, and will offer a single bundle group
                    across all media section; use of this single
                    transport is contingent upon the answerer accepting
                    bundle. However, by specifying a policy from the
                    list below, the application can control exactly how
                    aggressively it will try to bundle media streams
                    together, which affects how it will interoperate
                    with a non-bundle-aware endpoint. When negotiating
                    with a non-bundle-aware endpoint, only the streams
                    not marked as bundle-only streams will be
                    established.</t>

                    <t>The set of available policies is as follows:
                    <list style="hanging">

                        <t hangText="balanced:">The first media section
                        of each type (audio, video, or application)
                        will contain transport parameters, which will
                        allow an answerer to unbundle that section. The
                        second and any subsequent media section of each
                        type will be marked bundle-only. The result is
                        that if there are N distinct media types, then
                        candidates will be gathered for for N media
                        streams. This policy balances desire to
                        multiplex with the need to ensure basic audio
                        and video can still be negotiated in legacy
                        cases. When acting as answerer, if there is
                        no bundle group in the offer, the
                        implementation will reject all but the first
                        m= section of each type.</t>

                        <t></t>

                        <t hangText="max-compat:">All media sections
                        will contain transport parameters; none will be
                        marked as bundle-only. This policy will allow
                        all streams to be received by non-bundle-aware
                        endpoints, but require separate candidates to
                        be gathered for each media stream.</t>

                        <t></t>

                        <t hangText="max-bundle:">Only the first media
                        section will contain transport parameters; all
                        streams other than the first will be marked as
                        bundle-only. This policy aims to minimize
                        candidate gathering and maximize multiplexing,
                        at the cost of less compatibility with legacy
                        endpoints. When acting as answerer, if there
                        if no bundle group in the offer, the
                        implementation will reject all but the first
                        m= section.</t>

                    </list></t>

                    <t>As it provides the best tradeoff between
                    performance and compatibility with legacy
                    endpoints, the default bundle policy MUST be set to
                    "balanced".</t>

                    <t>The application can specify its preferred policy
                    regarding use of RTP/RTCP multiplexing <xref
                    target="RFC5761" /> using one of the following
                    policies:
                    <list style="hanging">

                        <t hangText="negotiate:">The browser will
                        gather both RTP and RTCP candidates but also
                        will offer "a=rtcp-mux", thus allowing for
                        compatibility with either multiplexing or
                        non-multiplexing endpoints.</t>

                        <t hangText="require:">The browser will only
                        gather RTP candidates. This halves the number
                        of candidates that the offerer needs to gather.
                        When acting as answerer, the implementation
                        will reject any m= section that does not
                        contain an "a=rtcp-mux" attribute.</t>

                    </list></t>

                    <t>The default multiplexing policy MUST be set to
                    "require". Implementations MAY choose to reject
                    attempts by the application to set the multiplexing
                    policy to "negotiate".</t>

                </section>

                <section title="addTrack" anchor="sec.addTrack">
                  <t>
                    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 "LS" group when creating an offer or answer.
                    addTrack attempts to minimize the number of transceivers as follows:
                    The track will be attached to the first compatible transceiver
                    (of the same media type) which has never had a direction of
                    "sendonly" or "sendrecv". If no such transceiver exists,
                    then one will be constructed as described in
                    <xref target="sec.addTransceiver"/>.
                  </t>
                </section>

                <section title="addTransceiver" anchor="sec.addTransceiver">
                  <t>[TODO]</t>
                </section>

                <section title="createDataChannel" anchor="sec.createDataChannel">
                  <t>[TODO]</t>
                </section>

                <section title="createOffer" anchor="sec.createoffer">

                    <t>The createOffer method generates a blob of SDP
                    that contains a <xref target="RFC3264"></xref> offer
                    with the supported configurations for the session,
                    including descriptions of the media added to this
                    PeerConnection, the codec/RTP/RTCP options supported
                    by this implementation, and any candidates that have
                    been gathered by the ICE Agent. An options parameter
                    may be supplied to provide additional control over
                    the generated offer. This options parameter allows
                    an application to trigger an ICE restart, for the
                    purpose of reestablishing connectivity.</t>

                    <t>In the initial offer, the generated SDP will
                    contain all desired functionality for the session
                    (functionality that is supported but not desired by
                    default may be omitted); for each SDP line, the
                    generation of the SDP will follow the process
                    defined for generating an initial offer from the
                    document that specifies the given SDP line. The
                    exact handling of initial offer generation is
                    detailed in <xref target="sec.initial-offers" />
                    below.</t>

                    <t>In the event createOffer is called after the
                    session is established, createOffer will generate an
                    offer to modify the current session based on any
                    changes that have been made to the session, e.g.,
                    adding or stopping RtpTransceivers, or requesting an
                    ICE restart. For each existing stream, the
                    generation of each SDP line must follow the process
                    defined for generating an updated offer from the RFC
                    that specifies the given SDP line. For each new
                    stream, the generation of the SDP must follow the
                    process of generating an initial offer, as mentioned
                    above. If no changes have been made, or for SDP
                    lines that are unaffected by the requested changes,
                    the offer will only contain the parameters
                    negotiated by the last offer-answer exchange. The
                    exact handling of subsequent offer generation is
                    detailed in <xref target="sec.subsequent-offers"
                    />. below.</t>

                    <t>Session descriptions generated by createOffer
                    must be immediately usable by setLocalDescription;
                    if a system has limited resources (e.g. a finite
                    number of decoders), createOffer should return an
                    offer that reflects the current state of the
                    system, so that setLocalDescription will succeed
                    when it attempts to acquire those resources.
                    Because this method may need to inspect the system
                    state to determine the currently available
                    resources, it may be implemented as an async
                    operation.</t>

                    <t>Calling this method may do things such as
                    generate new ICE credentials, but does not result
                    in candidate gathering, or cause media to start or
                    stop flowing.</t>
                </section>
                <section title="createAnswer"
                anchor="sec.createanswer">

                    <t>The createAnswer method generates a blob of SDP
                    that contains a <xref target="RFC3264"></xref> SDP
                    answer with the supported configuration for the
                    session that is compatible with the parameters
                    supplied in the most recent call to
                    setRemoteDescription, which MUST have been called
                    prior to calling createAnswer.  Like createOffer,
                    the returned blob contains descriptions of the media
                    added to this PeerConnection, the codec/RTP/RTCP
                    options negotiated for this session, and any
                    candidates that have been gathered by the ICE
                    Agent. An options parameter may be supplied to
                    provide additional control over the generated
                    answer.</t>

                    <t>As an answer, the generated SDP will contain a
                    specific configuration that specifies how the media
                    plane should be established; for each SDP line, the
                    generation of the SDP must follow the process
                    defined for generating an answer from the document
                    that specifies the given SDP line. The exact
                    handling of answer generation is detailed in <xref
                    target="sec.generating-an-answer" />.  below.</t>

                    <t>Session descriptions generated by createAnswer
                    must be immediately usable by setLocalDescription;
                    like createOffer, the returned description should
                    reflect the current state of the system. Because
                    this method may need to inspect the system state to
                    determine the currently available resources, it may
                    need to be implemented as an async operation.</t>

                    <t>Calling this method may do things such as
                    generate new ICE credentials, but does not trigger
                    candidate gathering or change media state.</t>

                </section>
                <section title="SessionDescriptionType"
                anchor="sec.sessiondescriptiontype">

                    <t>Session description objects
                    (RTCSessionDescription) may be of type "offer",
                    "pranswer", "answer" or "rollback". These types
                    provide information as to how the description
                    parameter should be parsed, and how the media state
                    should be changed.</t>

                    <t>"offer" indicates that a description should be
                    parsed as an offer; said description may include
                    many possible media configurations. A description
                    used as an "offer" may be applied anytime the
                    PeerConnection is in a stable state, or as an
                    update to a previously supplied but unanswered
                    "offer".</t>

                    <t>"pranswer" indicates that a description should
                    be parsed as an answer, but not a final answer, and
                    so should not result in the freeing of allocated
                    resources. It may result in the start of media
                    transmission, if the answer does not specify an
                    inactive media direction. A description used as a
                    "pranswer" may be applied as a response to an
                    "offer", or an update to a previously sent
                    "pranswer".</t>

                    <t>"answer" indicates that a description should be
                    parsed as an answer, the offer-answer exchange
                    should be considered complete, and any resources
                    (decoders, candidates) that are no longer needed
                    can be released. A description used as an "answer"
                    may be applied as a response to an "offer", or an
                    update to a previously sent "pranswer".</t>

                    <t>The only difference between a provisional and
                    final answer is that the final answer results in
                    the freeing of any unused resources that were
                    allocated as a result of the offer. As such, the
                    application can use some discretion on whether an
                    answer should be applied as provisional or final,
                    and can change the type of the session description
                    as needed. For example, in a serial forking
                    scenario, an application may receive multiple
                    "final" answers, one from each remote endpoint. The
                    application could choose to accept the initial
                    answers as provisional answers, and only apply an
                    answer as final when it receives one that meets its
                    criteria (e.g. a live user instead of
                    voicemail).</t>

                    <t>"rollback" is a special session description type
                    implying that the state machine should be rolled
                    back to the previous state, as described in <xref
                    target="sec.rollback" />. The contents MUST be
                    empty.</t>

                    <section title="Use of Provisional Answers"
                    anchor="sec.use-of-provisional-answer">

                        <t>Most web applications will not need to create
                        answers using the "pranswer" type. While it is
                        good practice to send an immediate response to
                        an "offer", in order to warm up the session
                        transport and prevent media clipping, the
                        preferred handling for a web application would
                        be to create and send an "inactive" final answer
                        immediately after receiving the offer.  Later,
                        when the called user actually accepts the call,
                        the application can create a new "sendrecv"
                        offer to update the previous offer/answer pair
                        and start the media flow.  While this could also
                        be done with an inactive "pranswer", followed by
                        a sendrecv "answer", the initial "pranswer"
                        leaves the offer-answer exchange open, which
                        means that neither side can send an updated
                        offer during this time.</t>

                        <t>As an example, consider a typical web
                        application that will set up a data channel, an
                        audio channel, and a video channel. When an
                        endpoint receives an offer with these channels,
                        it could send an answer accepting the data
                        channel for two-way data, and accepting the
                        audio and video tracks as inactive or
                        receive-only. It could then ask the user to
                        accept the call, acquire the local media
                        streams, and send a new offer to the remote side
                        moving the audio and video to be two-way
                        media. By the time the human has accepted the
                        call and triggered the new offer, it is likely
                        that the ICE and DTLS handshaking for all the
                        channels will already have finished.</t>

                        <t>Of course, some applications may not be able
                        to perform this double offer-answer exchange,
                        particularly ones that are attempting to gateway
                        to legacy signaling protocols. In these cases,
                        "pranswer" can still provide the application
                        with a mechanism to warm up the transport.</t>

                    </section>
                    <section title="Rollback" anchor="sec.rollback">

                        <t>In certain situations it may be desirable to
                        "undo" a change made to setLocalDescription or
                        setRemoteDescription. Consider a case where a
                        call is ongoing, and one side wants to change
                        some of the session parameters; that side
                        generates an updated offer and then calls
                        setLocalDescription. However, the remote side,
                        either before or after setRemoteDescription,
                        decides it does not want to accept the new
                        parameters, and sends a reject message back to
                        the offerer. Now, the offerer, and possibly the
                        answerer as well, need to return to a stable
                        state and the previous local/remote
                        description. To support this, we introduce the
                        concept of "rollback".</t>

                        <t>A rollback discards any proposed changes to
                        the session, returning the state machine to the
                        stable state, and setting the pending local
                        and/or remote description back to null. Any
                        resources or candidates that were allocated by
                        the abandoned local description are discarded;
                        any media that is received will be processed
                        according to the previous local and remote
                        descriptions. Rollback can only be used to
                        cancel proposed changes; there is no support for
                        rolling back from a stable state to a previous
                        stable state. Note that this implies that once
                        the answerer has performed setLocalDescription
                        with his answer, this cannot be rolled back.</t>

                        <t>A rollback will disassociate any
                        RtpTransceivers that were associated with m=
                        sections by the application of the rolled-back
                        session description (see <xref
                        target="sec.applying-a-remote-desc" /> and <xref
                        target="sec.applying-a-local-desc" />).  This
                        means that some RtpTransceivers that were
                        previously associated will no longer be
                        associated with any m= section; in such cases,
                        the value of the RtpTransceiver's mid attribute
                        MUST be set to null. RtpTransceivers that were
                        created by applying a remote offer that was
                        subsequently rolled back MUST be removed.
                        However, a RtpTransceiver MUST NOT be removed if
                        the RtpTransceiver's RtpSender was activated by
                        the addTrack method. This is so that an
                        application may call addTrack, then call
                        setRemoteDescription with an offer, then roll
                        back that offer, then call createOffer and have
                        a m= section for the added track appear in the
                        generated offer.</t>

                        <t>A rollback is performed by supplying a
                        session description of type "rollback" with
                        empty contents to either setLocalDescription or
                        setRemoteDescription, depending on which was
                        most recently used (i.e. if the new offer was
                        supplied to setLocalDescription, the rollback
                        should be done using setLocalDescription as
                        well).</t>

                    </section>
                </section>
                <section title="setLocalDescription"
                anchor="sec.setlocaldescription">

                    <t>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 an offer, provisional answer, or final
                    answer; offers and answers are checked differently,
                    using the various rules that exist for each SDP
                    line.</t>

                    <t>This API changes the local media state; among
                    other things, it sets up local resources for
                    receiving and decoding media. In order to
                    successfully handle scenarios where the application
                    wants to offer to change from one media format to a
                    different, incompatible format, the PeerConnection
                    must be able to simultaneously support use of both
                    the current and pending local descriptions (e.g.
                    support codecs that exist in both descriptions)
                    until a final answer is received, at which point
                    the PeerConnection can fully adopt the pending
                    local description, or roll back to the current
                    description if the remote side denied the
                    change.</t>

                    <t>This API indirectly controls the candidate
                    gathering process. When a local description is
                    supplied, and the number of transports currently in
                    use does not match the number of transports needed
                    by the local description, the PeerConnection will
                    create transports as needed and begin gathering
                    candidates for them.</t>

                    <t>If setRemoteDescription was previously called
                    with an offer, and setLocalDescription is called
                    with an answer (provisional or final), and the
                    media directions are compatible, and media are
                    available to send, this will result in the starting
                    of media transmission.</t>

                </section>
                <section title="setRemoteDescription"
                anchor="sec.setremotedescription">

                    <t>The setRemoteDescription method instructs the
                    PeerConnection to apply the supplied session
                    description as the desired remote configuration. As
                    in setLocalDescription, the type field of the
                    description indicates how it should be
                    processed.</t>

                    <t>This API changes the local media state; among
                    other things, it sets up local resources for
                    sending and encoding media.</t>

                    <t>If setLocalDescription was previously called
                    with an offer, and setRemoteDescription is called
                    with an answer (provisional or final), and the
                    media directions are compatible, and media are
                    available to send, this will result in the starting
                    of media transmission.</t>

                </section>
                <section title="currentLocalDescription"
                anchor="sec.currentlocaldescription">

                    <t>The currentLocalDescription method returns a
                    copy of the current negotiated local description -
                    i.e., the local description from the last
                    successful offer/answer exchange - in addition to
                    any local candidates that have been generated by
                    the ICE Agent since the local description was
                    set.</t>

                    <t>A null object will be returned if an
                    offer/answer exchange has not yet been
                    completed.</t>

                </section>
                <section title="pendingLocalDescription"
                anchor="sec.pendinglocaldescription">

                    <t>The pendingLocalDescription method returns a
                    copy of the local description currently in
                    negotiation - i.e., a local offer set without any
                    corresponding remote answer - in addition to any
                    local candidates that have been generated by the
                    ICE Agent since the local description was set.</t>

                    <t>A null object will be returned if the state of
                    the PeerConnection is "stable" or
                    "have-remote-offer".</t>

                </section>
                <section title="currentRemoteDescription"
                anchor="sec.currentremotedescription">

                    <t>The currentRemoteDescription method returns a
                    copy of the current negotiated remote description -
                    i.e., the remote description from the last
                    successful offer/answer exchange - in addition to
                    any remote candidates that have been supplied via
                    processIceMessage since the remote description was
                    set.</t>

                    <t>A null object will be returned if an
                    offer/answer exchange has not yet been
                    completed.</t>

                </section>
                <section title="pendingRemoteDescription"
                anchor="sec.pendingremotedescription">

                    <t>The pendingRemoteDescription method returns a
                    copy of the remote description currently in
                    negotiation - i.e., a remote offer set without any
                    corresponding local answer - in addition to any
                    remote candidates that have been supplied via
                    processIceMessage since the remote description was
                    set.</t>

                    <t>A null object will be returned if the state of
                    the PeerConnection is "stable" or
                    "have-local-offer".</t>

                </section>
                <section title="canTrickleIceCandidates"
                anchor="sec.cantrickle">

                    <t>The canTrickleIceCandidates property indicates
                    whether the remote side supports receiving trickled
                    candidates. There are three potential values:

                    <list style="hanging">

                        <t hangText="null:">No SDP has been received
                        from the other side, so it is not known if it
                        can handle trickle. This is the initial value
                        before setRemoteDescription() is called.</t>

                        <t hangText="true:">SDP has been received from
                        the other side indicating that it can support
                        trickle.</t>

                        <t hangText="false:">SDP has been received from
                        the other side indicating that it cannot support
                        trickle.</t>

                    </list></t>

                    <t>As described in <xref
                    target="sec.ice-candidate-trickling" />, JSEP
                    implementations always provide candidates to the
                    application individually, consistent with what is
                    needed for Trickle ICE. However, applications can
                    use the canTrickleIceCandidates property to
                    determine whether their peer can actually do Trickle
                    ICE, i.e., whether it is safe to send an initial
                    offer or answer followed later by candidates as they
                    are gathered. As "true" is the only value that
                    definitively indicates remote Trickle ICE support,
                    an application which compares
                    canTrickleIceCandidates against "true" will by
                    default attempt Half Trickle on initial offers and
                    Full Trickle on subsequent interactions with a
                    Trickle ICE-compatible agent.</t>

                </section>
                <section title="setConfiguration"
                anchor="sec.setconfiguration">

                    <t>The setConfiguration method allows the global
                    configuration of the PeerConnection, which was
                    initially set by constructor parameters, to be
                    changed during the session. The effects of this
                    method call depend on when it is invoked, and
                    differ depending on which specific parameters are
                    changed:</t>

                    <t>
                        <list style="symbols">

                            <t>Any changes to the STUN/TURN servers to
                            use affect the next gathering phase. If an
                            ICE gathering phase has already started or
                            completed, the 'needs-ice-restart' bit
                            mentioned in <xref
                            target="sec.ice-gather-overview" /> will be
                            set. This will cause the next call to
                            createOffer to generate new ICE credentials,
                            for the purpose of forcing an ICE restart
                            and kicking off a new gathering phase, in
                            which the new servers will be used. If the
                            ICE candidate pool has a nonzero size, any
                            existing candidates will be discarded, and
                            new candidates will be gathered from the new
                            servers.</t>

                            <t>Any change to the ICE candidate policy
                            affects the next gathering 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,
                            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.</t>

                            <t>Any changes to the ICE candidate pool
                            size take effect immediately; if increased,
                            additional candidates are pre-gathered; if
                            decreased, the now-superfluous candidates
                            are discarded.</t>

                            <t>The bundle and RTCP-multiplexing
                            policies MUST NOT be changed after the
                            construction of the PeerConnection.</t>
                        </list>
                    </t>

                    <t>This call may result in a change to the state of
                    the ICE Agent, and may result in a change to media
                    state if it results in connectivity being
                    established.</t>

                </section>
                <section title="addIceCandidate"
                anchor="sec.addicecandidate">

                    <t>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.
                    If the MID, m-line index, or candidate string provided in the ICE candidate is
                    invalid, an error is generated. 
                    Connectivity checks will
                    be sent to the new candidate.</t>

                    <t>This method can also be used to provide an
                    end-of-candidates indication (as defined in <xref
                    target="I-D.ietf-ice-trickle" />) to the ICE Agent
                    for all media descriptions in the last remote
                    description.</t>

                    <t>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.</t>

                </section>
            </section>
        </section>
        <section title="SDP Interaction Procedures"
        anchor="sec.sdp-interaction-procedure">

            <t>This section describes the specific procedures to be
            followed when creating and parsing SDP objects.</t>
            <section title="Requirements Overview"
            anchor="sec.requirements-overview">

                <t>JSEP implementations must comply with the
                specifications listed below that govern the creation
                and processing of offers and answers.</t>

                <t>The first set of specifications is the
                "mandatory-to-implement" set. All implementations must
                support these behaviors, but may not use all of them if
                the remote side, which may not be a JSEP endpoint, does
                not support them.</t>

                <t>The second set of specifications is the
                "mandatory-to-use" set. The local JSEP endpoint and any
                remote endpoint must indicate support for these
                specifications in their session descriptions.</t>
                <section title="Implementation Requirements"
                anchor="sec.implementation-requirements">

                    <t>This list of mandatory-to-implement
                    specifications is derived from the requirements
                    outlined in <xref
                    target="I-D.ietf-rtcweb-rtp-usage"></xref>.

                    <list style="format R-%d">

                        <t><xref target="RFC4566"></xref> is the base SDP
                        specification and MUST be implemented.</t>

                        <t><xref target="RFC5764"></xref> MUST be
                        supported for signaling the UDP/TLS/RTP/SAVPF
                        <xref target="RFC5764" />, TCP/DTLS/RTP/SAVPF
                        <xref
                        target="I-D.nandakumar-mmusic-proto-iana-registration"
                        />, "UDP/DTLS/SCTP" <xref
                        target="I-D.ietf-mmusic-sctp-sdp" />, and
                        "TCP/DTLS/SCTP" <xref
                        target="I-D.ietf-mmusic-sctp-sdp" /> RTP
                        profiles.</t>

                        <t> <xref target="RFC5245"></xref> MUST be
                        implemented for signaling the ICE credentials
                        and candidate lines corresponding to each media
                        stream. The ICE implementation MUST be a Full
                        implementation, not a Lite implementation.</t>

                        <t><xref target="RFC5763"></xref> MUST be
                        implemented to signal DTLS certificate
                        fingerprints.</t>

                        <t><xref target="RFC4568"></xref> MUST NOT be
                        implemented to signal SDES SRTP keying
                        information.</t>

                        <t>The <xref target="RFC5888"></xref> grouping
                        framework MUST be implemented for signaling
                        grouping information, and MUST be used to
                        identify m= lines via the a=mid attribute.</t>

                        <t> <xref target="I-D.ietf-mmusic-msid"></xref>
                        MUST be supported, in order to signal
                        associations between RTP objects and W3C
                        MediaStreams and MediaStreamTracks in a standard
                        way.</t>

                        <t>The bundle mechanism in
                        <xref target="I-D.ietf-mmusic-sdp-bundle-negotiation">
                        </xref> MUST be supported to signal the ability
                        to multiplex RTP streams on a single UDP port,
                        in order to avoid excessive use of port number
                        resources.</t>

                        <t>The SDP attributes of "sendonly", "recvonly",
                        "inactive", and "sendrecv" from <xref
                        target="RFC4566"></xref> MUST be implemented to
                        signal information about media direction.</t>

                        <t> <xref target="RFC5576"></xref> MUST be
                        implemented to signal RTP SSRC values and
                        grouping semantics.</t>

                        <t> <xref target="RFC4585"></xref> MUST be
                        implemented to signal RTCP based feedback.</t>

                        <t> <xref target="RFC5761"></xref> MUST be
                        implemented to signal multiplexing of RTP and
                        RTCP.</t>

                        <t> <xref target="RFC5506"></xref> MUST be
                        implemented to signal reduced-size RTCP
                        messages.</t>

                        <t><xref target="RFC4588"></xref> MUST be
                        implemented to signal RTX payload type
                        associations.</t>

                        <t><xref target="RFC3556"></xref> with bandwidth
                        modifiers MAY be supported for specifying RTCP
                        bandwidth as a fraction of the media bandwidth,
                        RTCP fraction allocated to the senders and
                        setting maximum media bit-rate boundaries.</t>

                        <t>TODO: any others?</t>
                    </list></t>

                    <t>As required by <xref target="RFC4566"></xref>,
                    Section 5.13, JSEP implementations MUST ignore
                    unknown attribute (a=) lines.</t>

                </section>
                <section title="Usage Requirements"
                anchor="sec.usage-requirements">

                    <t>All session descriptions handled by JSEP
                    endpoints, both local and remote, MUST indicate
                    support for the following specifications. If any of
                    these are absent, this omission MUST be treated as
                    an error.
                    <list style="format R-%d">

                        <t>ICE, as specified in <xref
                        target="RFC5245"></xref>, MUST be used.  Note
                        that the remote endpoint may use a Lite
                        implementation; implementations MUST properly
                        handle remote endpoints which do ICE-Lite.</t>

                        <t>DTLS <xref target="RFC6347" /> or DTLS-SRTP
                        <xref target="RFC5763"></xref>, MUST be used, as
                        appropriate for the media type, as specified in
                        <xref target="I-D.ietf-rtcweb-security-arch"
                        /></t>

                    </list></t>

                </section>
                <section title="Profile Names and Interoperability"
                anchor="sec.profile-names">

                    <t>For media m= sections, JSEP endpoints MUST
                    support both the "UDP/TLS/ RTP/SAVPF" and
                    "TCP/DTLS/RTP/SAVPF" profiles and MUST indicate one
                    of these two profiles for each media m= line they
                    produce in an offer. For data m= sections, JSEP
                    endpoints must support both the "UDP/DTLS/SCTP" and
                    "TCP/DTLS/SCTP" profiles and MUST indicate one of
                    these two profiles for each data m= line they
                    produce in an offer. Because ICE can select either
                    TCP or UDP transport depending on network
                    conditions, both advertisements are consistent with
                    ICE eventually selecting either either UDP or
                    TCP.</t>

                    <t>Unfortunately, in an attempt at compatibility,
                    some endpoints 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 willingness to support
                    "(UDP,TCP)/TLS/RTP/SAVPF". In order to simplify
                    compatibility with such endpoints, JSEP endpoints
                    MUST follow the following rules when processing the
                    media m= sections in an offer:</t>

                    <t>
                        <list style="symbols">

                            <t>The profile in any "m=" line in any
                            answer MUST exactly match the profile
                            provided in the offer.</t>

                            <t>Any profile matching the following
                            patterns MUST be accepted: "RTP/[S]AVP[F]"
                            and "(UDP/TCP)/TLS/RTP/SAVP[F]"</t>

                            <t>Because DTLS-SRTP is REQUIRED, the
                            choice of SAVP or AVP has no effect;
                            support for DTLS-SRTP is determined by the
                            presence of one or more "a=fingerprint"
                            attribute. Note that lack of an
                            "a=fingerprint" attribute will lead to
                            negotiation failure.</t>

                            <t>The use of AVPF or AVP simply controls
                            the timing rules used for RTCP feedback. If
                            AVPF is provided, or an "a=rtcp-fb"
                            attribute is present, assume AVPF timing,
                            i.e. a default value of "trr-int=0".
                            Otherwise, assume that AVPF is being used
                            in an AVP compatible mode and use AVP
                            timing, i.e., "trr-int=4".</t>

                            <t>For data m= sections, JSEP endpoints
                            MUST support receiving the "UDP/
                            DTLS/SCTP", "TCP/DTLS/SCTP", or "DTLS/SCTP"
                            (for backwards compatibility) profiles.</t>
                        </list>
                    </t>

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

                </section>
            </section>
            <section anchor="sec-create-offer"
            title="Constructing an Offer">

                <t>When createOffer is called, a new SDP description
                must be created that includes the functionality
                specified in <xref
                target="I-D.ietf-rtcweb-rtp-usage"></xref>. The exact
                details of this process are explained below.</t>
                <section title="Initial Offers"
                anchor="sec.initial-offers">

                    <t>When createOffer is called for the first time,
                    the result is known as the initial offer.</t>

                    <t>The first step in generating an initial offer is
                    to generate session-level attributes, as specified
                    in <xref target="RFC4566"></xref>, Section 5.
                    Specifically:
                    <list style="symbols">

                        <t>The first SDP line MUST be "v=0", as
                        specified in <xref target="RFC4566"></xref>,
                        Section 5.1</t>

                        <t>The second SDP line MUST be an "o=" line, as
                        specified in <xref target="RFC4566"></xref>,
                        Section 5.2.  The value of the &lt;username&gt;
                        field SHOULD be "-". The value of the
                        &lt;sess-id&gt; field SHOULD be a
                        cryptographically random number. To ensure
                        uniqueness, this number SHOULD be at least 64
                        bits long. The value of the &lt;sess-version&gt;
                        field SHOULD be zero. The value of the
                        &lt;nettype&gt; &lt;addrtype&gt;
                        &lt;unicast-address&gt; 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 <xref
                        target="RFC4566"></xref>, the entire o= line
                        needs to be unique, but selecting a random
                        number for &lt;sess-id&gt; is sufficient to
                        accomplish this.</t>

                        <t>The third SDP line MUST be a "s=" line, as
                        specified in <xref target="RFC4566"></xref>,
                        Section 5.3; to match the "o=" line, a single
                        dash SHOULD be used as the session name,
                        e.g. "s=-". Note that this differs from the
                        advice in <xref target="RFC4566" /> which
                        proposes a single space, but as both "o=" and
                        "s=" are meaningless, having the same
                        meaningless value seems clearer.</t>

                        <t>Session Information ("i="), URI ("u="),
                        Email Address ("e="), Phone Number ("p="),
                        Bandwidth ("b="), Repeat Times ("r="), and Time
                        Zones ("z=") lines are not useful in this
                        context and SHOULD NOT be included.</t>

                        <t>Encryption Keys ("k=") lines do not provide
                        sufficient security and MUST NOT be
                        included.</t>

                        <t>A "t=" line MUST be added, as specified in
                        <xref target="RFC4566"></xref>, Section 5.9;
                        both &lt;start-time&gt; and &lt;stop-time&gt;
                        SHOULD be set to zero, e.g. "t=0 0".</t>

                        <t>An "a=ice-options" line with the "trickle"
                        option MUST be added, as specified in <xref
                        target="I-D.ietf-ice-trickle"></xref>, Section
                        4.</t>
                    </list></t>

                    <t>The next step is to generate m= sections, as
                    specified in <xref target="RFC4566" /> Section
                    5.14. An m= section is generated for each
                    RtpTransceiver that has been added to the
                    PeerConnection via the addTrack, addTransceiver, and
                    setRemoteDescription methods. [[OPEN ISSUE: move
                    discussion of setRemoteDescription to the
                    subsequent-offer section.]] This is done in the
                    order that their associated RtpTransceivers were
                    added to the PeerConnection and excludes
                    RtpTranscievers that are stopped and not associated
                    with an m= section (either due to an m= section
                    being recycled or an RtpTransceiver having been
                    stopped before being associated with an m= section)
                    .</t>

                    <t>Each m= section, provided it is not marked as
                    bundle-only, MUST generate a unique set of ICE
                    credentials and gather its own unique set of ICE
                    candidates. Bundle-only m= sections MUST NOT
                    contain any ICE credentials and MUST NOT gather any
                    candidates.</t>

                    <t>For DTLS, all m= sections MUST use the
                    certificate for the identity that has been specified
                    for the PeerConnection; as a result, they MUST all
                    have the same <xref target="RFC4572"></xref>
                    fingerprint value, or this value MUST be a
                    session-level attribute.</t>

                    <t>Each m= section should be generated as specified
                    in <xref target="RFC4566"></xref>, Section 5.14. For
                    the m= line itself, the following rules MUST be
                    followed:
                    <list style="symbols">

                        <t>The port value is set to the port of the
                        default ICE candidate for this m= section, but
                        given that no candidates have yet been gathered,
                        the "dummy" port value of 9 (Discard) MUST be
                        used, as indicated in <xref
                        target="I-D.ietf-ice-trickle"></xref>, Section
                        5.1.</t>

                        <t>To properly indicate use of DTLS, the
                        &lt;proto&gt; field MUST be set to
                        "UDP/TLS/RTP/SAVPF", as specified in <xref
                        target="RFC5764" />, Section 8, if the default
                        candidate uses UDP transport, or
                        "TCP/DTLS/RTP/SAVPF", as specified in <xref
                        target="I-D.nandakumar-mmusic-proto-iana-registration"
                        /> if the default candidate uses TCP
                        transport.</t>

                    </list></t>

                    <t>The m= line MUST be followed immediately by a
                    "c=" line, as specified in <xref
                    target="RFC4566"></xref>, Section 5.7. Again, as no
                    candidates have yet been gathered, the "c=" line
                    must contain the "dummy" value "IN IP4 0.0.0.0", as
                    defined in <xref
                    target="I-D.ietf-ice-trickle"></xref>, Section
                    5.1.</t>

                    <t>Each m= section MUST include the following
                    attribute lines:
                    <list style="symbols">

                        <t>An "a=mid" line, as specified in <xref
                        target="RFC5888"></xref>, Section 4. When
                        generating mid values, it is RECOMMENDED that
                        the values be 3 bytes or less, to allow them to
                        efficiently fit into the RTP header extension
                        defined in
                        <xref target="I-D.ietf-mmusic-sdp-bundle-negotiation">
                        </xref>, Section 11.</t>

                        <t>An "a=rtcp" line, as specified in <xref
                        target="RFC3605"></xref>, Section 2.1,
                        containing the dummy value "9 IN IP4 0.0.0.0",
                        because no candidates have yet been
                        gathered.</t>

                        <t>A direction attribute for the associated
                        RtpTransceiver as described by <xref
                        target="sec.offer-dirattr"></xref>.</t>

                        <t>For each supported codec, "a=rtpmap" and
                        "a=fmtp" lines, as specified in <xref
                        target="RFC4566"></xref>, Section 6. The audio
                        and video codecs that MUST be supported are
                        specified in
                        <xref target="I-D.ietf-rtcweb-audio">
                        </xref>(see Section 3) and
                        <xref target="I-D.ietf-rtcweb-video">
                        </xref>(see Section 5).</t>

                        <t>If this m= section is for media with
                        configurable frame sizes, e.g. audio, an
                        "a=maxptime" line, indicating the smallest of
                        the maximum supported frame sizes out of all
                        codecs included above, as specified in <xref
                        target="RFC4566"></xref>, Section 6.</t>

                        <t>If this m= section is for video media, and
                        there are known limitations on the size of
                        images which can be decoded, an "a=imageattr"
                        line, as specified in <xref
                        target="sec.imageattr"></xref>.</t>

                        <t>For each primary codec where RTP
                        retransmission should be used, a corresponding
                        "a=rtpmap" line indicating "rtx" with the clock
                        rate of the primary codec and an "a=fmtp" line
                        that references the payload type of the primary
                        codec, as specified in <xref
                        target="RFC4588"></xref>, Section 8.1.</t>

                        <t>For each supported FEC mechanism, "a=rtpmap"
                        and "a=fmtp" lines, as specified in <xref
                        target="RFC4566"></xref>, Section 6. The FEC
                        mechanisms that MUST be supported are specified
                        in <xref target="I-D.ietf-rtcweb-fec"></xref>,
                        Section 6, and specific usage for each media
                        type is outlined in Sections 4 and 5.</t>

                        <t>"a=ice-ufrag" and "a=ice-pwd" lines, as
                        specified in <xref target="RFC5245"></xref>,
                        Section 15.4.</t>

                        <t>An "a=fingerprint" line for each of the
                        endpoint's certificates, as specified in <xref
                        target="RFC4572"></xref>, Section 5; the digest
                        algorithm used for the fingerprint MUST match
                        that used in the certificate signature.</t>

                        <t>An "a=setup" line, as specified in <xref
                        target="RFC4145"></xref>, Section 4, and
                        clarified for use in DTLS-SRTP scenarios in
                        <xref target="RFC5763"></xref>, Section 5. The
                        role value in the offer MUST be "actpass".</t>

                        <t>An "a=rtcp-mux" line, as specified in <xref
                        target="RFC5761"></xref>, Section 5.1.1.</t>

                        <t>An "a=rtcp-rsize" line, as specified in <xref
                        target="RFC5506"></xref>, Section 5.</t>

                        <t>For each supported RTP header extension, an
                        "a=extmap" line, as specified in <xref
                        target="RFC5285"></xref>, Section 5. The list of
                        header extensions that SHOULD/MUST be supported
                        is specified in
                        <xref target="I-D.ietf-rtcweb-rtp-usage">
                        </xref>, Section 5.2. Any header extensions
                        that require encryption MUST be specified as
                        indicated in
                        <xref target="RFC6904"></xref>, Section 4.</t>

                        <t>For each supported RTCP feedback mechanism,
                        an "a=rtcp-fb" mechanism, as specified in <xref
                        target="RFC4585"></xref>, Section 4.2.  The list
                        of RTCP feedback mechanisms that SHOULD/MUST be
                        supported is specified in
                        <xref target="I-D.ietf-rtcweb-rtp-usage">
                        </xref>, Section 5.1.</t>

                        <t>An "a=ssrc" line, as specified in <xref
                        target="RFC5576"></xref>, Section 4.1,
                        indicating the SSRC to be used for sending
                        media, along with the mandatory "cname" source
                        attribute, as specified in Section 6.1,
                        indicating the CNAME for the source. The CNAME
                        MUST be generated in accordance with Section 4.9
                        of
                        <xref target="I-D.ietf-rtcweb-rtp-usage">
                        </xref>.</t>

                        <t>If RTX is supported for this media type,
                        another "a=ssrc" line with the RTX SSRC, and an
                        "a=ssrc-group" line, as specified in <xref
                        target="RFC5576"></xref>, section 4.2, with
                        semantics set to "FID" and including the primary
                        and RTX SSRCs.</t>

                        <t>If FEC is supported for this media type,
                        another "a=ssrc" line with the FEC SSRC, and an
                        "a=ssrc-group" line with semantics set to
                        "FEC-FR" and including the primary and FEC
                        SSRCs, as specified in <xref
                        target="RFC5956"></xref>, section 4.3.  For
                        simplicity, if both RTX and FEC are supported,
                        the FEC SSRC MUST be the same as the RTX
                        SSRC.</t>

                        <t>If the bundle policy for this PeerConnection
                        is set to "max-bundle", and this is not the
                        first m= section, or the bundle policy is set to
                        "balanced", and this is not the first m= section
                        for this media type, an "a=bundle-only"
                        line.</t>

                        <t>If the RtpSender of the RtpTransceiver
                        associated with this m=section is active:
                        <list style="symbols">

                            <t>An "a=msid" line, as specified in
                            <xref target="I-D.ietf-mmusic-msid">
                            </xref>, Section 2.</t>

                            <t>An "a=ssrc" line, as specified in <xref
                            target="RFC5576"></xref>, Section 4.1,
                            indicating the SSRC to be used for sending
                            media, along with the mandatory "cname"
                            source attribute, as specified in Section
                            6.1, indicating the CNAME for the
                            source. The CNAME MUST be generated in
                            accordance with Section 4.9 of
                            <xref target="I-D.ietf-rtcweb-rtp-usage">
                            </xref>.</t>

                            <t>If RTX is supported for this media type,
                            another "a=ssrc" line with the RTX SSRC, and
                            an "a=ssrc-group" line, as specified in

                            <xref target="RFC5576"></xref>, section 4.2,
                            with semantics set to "FID" and including
                            the primary and RTX SSRCs.</t>

                            <t>If FEC is supported for this media type,
                            another "a=ssrc" line with the FEC SSRC, and
                            an "a=ssrc-group" line with semantics set to
                            "FEC-FR" and including the primary and FEC
                            SSRCs, as specified in <xref
                            target="RFC5956"></xref>, section 4.3. For
                            simplicity, if both RTX and FEC are
                            supported, the FEC SSRC MUST be the same as
                            the RTX SSRC.</t>
                        </list></t>

                        <t>If the RtpTransceiver's RtpSender is active,
                        and the application has specified RID values or
                        has specified more than one encoding in the
                        RtpSenders's parameters, an "a=rid" line for
                        each encoding specified. The "a=rid" line is
                        specified in <xref
                        target="I-D.ietf-mmusic-rid"></xref>, and its
                        direction MUST be "send". If the application has
                        chosen a RID value, it MUST be used as the
                        rid-identifier; otherwise a RID value MUST be
                        generated by the implementation.  When
                        generating RID values, it is RECOMMENDED that
                        the values be 3 bytes or less, to allow them to
                        efficiently fit into the RTP header extension
                        defined in <xref
                        target="I-D.ietf-avtext-rid"></xref>, Section
                        11. If no encodings have been specified, or only
                        one encoding is specified but without a RID
                        value, then no "a=rid" lines are generated.</t>

                        <t>If the RtpTransceiver's RtpSender is active
                        and more than one "a=rid" line has been
                        generated, an "a=simulcast" line, with direction
                        "send", as defined in
                        <xref target="I-D.ietf-mmusic-sdp-simulcast">
                        </xref>, Section 6.2. The list of RIDs MUST
                        include all of the RID identifiers used in the
                        "a=rid" lines for this m= section.</t>
                    </list></t>

                    <t>Lastly, if a data channel has been created, a m=
                    section MUST be generated for data. The
                    &lt;media&gt; field MUST be set to "application" and
                    the &lt;proto&gt; field MUST be set to
                    "UDP/DTLS/SCTP" if the default candidate uses UDP
                    transport, or "TCP/DTLS/SCTP" if the default
                    candidate uses TCP transport <xref
                    target="I-D.ietf-mmusic-sctp-sdp"></xref>.  The
                    "fmt" value MUST be set to "webrtc-datachannel" as
                    specified in <xref
                    target="I-D.ietf-mmusic-sctp-sdp"></xref>, Section
                    4.1.</t>

                    <t>Within the data m= section, the "a=mid",
                    "a=ice-ufrag", "a=ice-pwd", "a=fingerprint", and
                    "a=setup" lines MUST be included as mentioned above,
                    along with an "a=fmtp:webrtc-datachannel" line and
                    an "a=sctp-port" line referencing the SCTP port
                    number as defined in <xref
                    target="I-D.ietf-mmusic-sctp-sdp"></xref>, Section
                    4.1.</t>

                    <t>Once all m= sections have been generated, a
                    session-level "a=group" attribute MUST be added as
                    specified in <xref target="RFC5888"></xref>. This
                    attribute MUST have semantics "bundle", and MUST
                    include the mid identifiers of each m= section. The
                    effect of this is that the browser offers all m=
                    sections as one bundle group. However, whether the
                    m= sections are bundle-only or not depends on the
                    bundle policy.</t>

                    <t>The next step is to generate session-level lip
                    sync groups as defined in <xref target="RFC5888" />,
                    Section 7. For each MediaStream referenced by more
                    than one RtpTransceiver (by passing those
                    MediaStreams as arguments to the addTrack and
                    addTransceiver methods), a group of type "LS" MUST
                    be added that contains the mid values for each
                    RtpTransceiver.</t>

                    <t>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.</t>

                    <t>Attributes other than the ones specified above
                    MAY be included, except for the following attributes
                    which are specifically incompatible with the
                    requirements of <xref
                    target="I-D.ietf-rtcweb-rtp-usage"></xref>, and MUST
                    NOT be included:
                    <list style="symbols">

                        <t>"a=crypto"</t>

                        <t>"a=key-mgmt"</t>

                        <t>"a=ice-lite"</t>
                    </list></t>

                    <t>Note that when bundle is used, any additional
                    attributes that are added MUST follow the advice in

                    <xref target="I-D.ietf-mmusic-sdp-mux-attributes">
                    </xref> on how those attributes interact with
                    bundle.</t>

                    <t>Note that these requirements are in some cases
                    stricter than those of SDP. Implementations MUST be
                    prepared to accept compliant SDP even if it would
                    not conform to the requirements for generating SDP
                    in this specification.</t>
                </section>
                <section title="Subsequent Offers"
                anchor="sec.subsequent-offers">

                    <t>When createOffer is called a second (or later)
                    time, or is called after a local description has
                    already been installed, the processing is somewhat
                    different than for an initial offer.</t>

                    <t>If the initial offer was not applied using
                    setLocalDescription, meaning the PeerConnection is
                    still in the "stable" state, the steps for
                    generating an initial offer should be followed,
                    subject to the following restriction:
                    <list style="symbols">

                        <t>The fields of the "o=" line MUST stay the
                        same except for the &lt;session-version&gt;
                        field, which MUST increment if the session
                        description changes in any way, including the
                        addition of ICE candidates.</t>
                    </list></t>

                    <t>If the initial offer was applied using
                    setLocalDescription, but an answer from the remote
                    side has not yet been applied, meaning the
                    PeerConnection is still in the "local-offer" state,
                    an offer is generated by following the steps in the
                    "stable" state above, along with these exceptions:
                    <list style="symbols">

                        <t>The "s=" and "t=" lines MUST stay the
                        same.</t>

                        <t>If any RtpTransceiver has been added, and
                        there exists an m= section with a zero port in
                        the current local description or the current
                        remote description, that m= section MUST be
                        recycled by generating an m= section for the
                        added RtpTransceiver as if the m= section were
                        being added to the session description, placed
                        at the same index as the m= section with a zero
                        port.</t>

                        <t>If an RtpTransceiver is stopped and is not
                        associated with an m= section, an m= section
                        MUST NOT be generated for it. This prevents
                        adding back RtpTransceivers whose m= sections
                        were recycled and used for a new RtpTransceiver
                        in a previous offer/ answer exchange, as
                        described above.</t>

                        <t>If an RtpTransceiver has been stopped and is
                        associated with an m= section, and the m=
                        section is not being recycled as described
                        above, an m= section MUST be generated for it
                        with the port set to zero and the "a=msid",
                        "a=ssrc", and "a=ssrc-group" lines removed.</t>

                        <t>For RtpTransceivers that are not stopped,
                        the "a=msid", "a=ssrc", and "a=ssrc-group"
                        lines MUST stay the same if they are present in
                        the current description.</t>

                        <t>Each "m=" and c=" line MUST be filled in with
                        the port, protocol, and address of the default
                        candidate for the m= section, as described in
                        <xref target="RFC5245"></xref>, Section 4.3. If
                        ICE checking has already completed for one or
                        more candidate pairs and a candidate pair is in
                        active use, then that pair MUST be used, even if
                        ICE has not yet completed. Note that this
                        differs from the guidance in <xref
                        target="RFC5245" />, Section 9.1.2.2, which only
                        refers to offers created when ICE has
                        completed. Each "a=rtcp" attribute line MUST
                        also be filled in with the port and address of
                        the appropriate default candidate, either the
                        default RTP or RTCP candidate, depending on
                        whether RTCP multiplexing is currently active or
                        not. Note that if RTCP multiplexing is being
                        offered, but not yet active, the default RTCP
                        candidate MUST be used, as indicated in <xref
                        target="RFC5761"></xref>, section 5.1.3.  In
                        each case, if no candidates of the desired type
                        have yet been gathered, dummy values MUST be
                        used, as described above.</t>

                        <t>Each "a=mid" line MUST stay the same.</t>

                        <t>Each "a=ice-ufrag" and "a=ice-pwd" line MUST
                        stay the same, unless the ICE configuration has
                        changed (either changes to the supported
                        STUN/TURN servers, or the ICE candidate policy),
                        or the "IceRestart" option ( <xref
                        target="sec.icerestart" /> was specified.  If
                        the m= section is bundled into another m=
                        section, it still MUST NOT contain any ICE
                        credentials.</t>

                        <t>If the m= section is not bundled into another
                        m= section, for each candidate that has been
                        gathered during the most recent gathering phase
                        (see <xref target="sec.ice-gather-overview">
                        </xref>), an "a=candidate" line MUST be added,
                        as defined in <xref target="RFC5245"></xref>,
                        Section 4.3., paragraph 3. If candidate
                        gathering for the section has completed, an
                        "a=end-of-candidates" attribute MUST be added,
                        as described in <xref
                        target="I-D.ietf-ice-trickle"></xref>, Section
                        9.3. If the m= section is bundled into another
                        m= section, both "a=candidate" and
                        "a=end-of-candidates" MUST be omitted.</t>

                        <t>For RtpTransceivers that are still present,
                        the "a=msid", "a=ssrc", and "a=ssrc-group"
                        lines MUST stay the same.</t>

                        <t>For RtpTransceivers that are still present,
                        the "a=rid" lines MUST stay the same.</t>

                        <t>For RtpTransceivers that are still present,
                        any "a=simulcast" line MUST stay the same.</t>

                        <t>If any RtpTransceiver has been stopped, the
                        port MUST be set to zero and the "a=msid",
                        "a=ssrc", and "a=ssrc-group" lines MUST be
                        removed.</t>

                        <t>If any RtpTransceiver has been added, and
                        there exists a m= section with a zero port in
                        the current local description or the current
                        remote description, that m= section MUST be
                        recycled by generating a m= section for the
                        added RtpTransceiver as if the m= section were
                        being added to session description, except that
                        instead of adding it, the generated m= section
                        replaces the m= section with a zero port.</t>
                    </list></t>

                    <t>If the initial offer was applied using
                    setLocalDescription, and an answer from the remote
                    side has been applied using setRemoteDescription,
                    meaning the PeerConnection is in the
                    "remote-pranswer" or "stable" states, an offer is
                    generated based on the negotiated session
                    descriptions by following the steps mentioned for
                    the "local-offer" state above.</t>

                    <t>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:
                    <list style="symbols">

                        <t>The m= line and corresponding "a=rtpmap" and
                        "a=fmtp" lines MUST only include codecs present
                        in the most recent answer.</t>

                        <t>The RTP header extensions MUST only include
                        those that are present in the most recent answer.</t>

                        <t>The RTCP feedback extensions MUST only
                        include those that are present in the most recent
                        answer.</t>

                        <t>The "a=rtcp-mux" line MUST only be added if
                        present in the most recent answer.</t>

                        <t>The "a=rtcp-rsize" line MUST only be added
                        if present in the most recent answer.</t>
                    </list></t>

                    <t>The "a=group:BUNDLE" attribute MUST include the
                    mid identifiers specified in the bundle group in
                    the most recent answer, minus any m= sections that
                    have been marked as rejected, plus any newly added
                    or re-enabled m= sections. In other words, the
                    bundle attribute must contain all m= sections that
                    were previously bundled, as long as they are still
                    alive, as well as any new m= sections.</t>

                    <t>The "LS" groups are generated in the same way as
                    with initial offers.</t>
                </section>
                <section title="Options Handling"
                anchor="sec.options-handling1">

                    <t>The createOffer method takes as a parameter an
                    RTCOfferOptions object. Special processing is
                    performed when generating a SDP description if the
                    following options are present.</t>
                    <section title="IceRestart"
                    anchor="sec.icerestart">

                        <t>If the "IceRestart" option is specified, with
                        a value of "true", the offer MUST indicate an
                        ICE restart by generating new ICE ufrag and pwd
                        attributes, as specified in <xref
                        target="RFC5245"></xref>, Section 9.1.1.1. If
                        this option is specified on an initial offer, it
                        has no effect (since a new ICE ufrag and pwd are
                        already generated).  Similarly, if the ICE
                        configuration has changed, this option has no
                        effect, since new ufrag and pwd attributes will
                        be generated automatically. This option is
                        primarily useful for reestablishing connectivity
                        in cases where failures are detected by the
                        application.</t>

                    </section>
                    <section title="VoiceActivityDetection"
                    anchor="sec.voiceactivitydetection1">

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

                        <t>If the "VoiceActivityDetection" option is
                        specified, with a value of "false", the browser
                        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.</t>

                        <t>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.</t>

                        <t>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 <xref
                        target="RFC6464"></xref>, Section 4.</t>

                    </section>
                </section>
                <section title="Direction Attribute in Offers"
                anchor="sec.offer-dirattr">

                    <t> <xref target="RFC3264"></xref> direction
                    attributes (defined in Section 6.1) in offers are
                    chosen according to the states of the RtpSender and
                    RtpReceiver of a given RtpTransceiver, as
                    follows:</t>

                    <texttable>
                        <ttcol align='center'>RtpSender</ttcol>
                        <ttcol align='center'>RtpReceiver</ttcol>
                        <ttcol align='center'>offer direction</ttcol>
                        <c>active</c>
                        <c>active</c>
                        <c>sendrecv</c>
                        <c>active</c>
                        <c>inactive</c>
                        <c>sendonly</c>
                        <c>inactive</c>
                        <c>active</c>
                        <c>recvonly</c>
                        <c>inactive</c>
                        <c>inactive</c>
                        <c>inactive</c>
                    </texttable>

                </section>
            </section>
            <section title="Generating an Answer"
            anchor="sec.generating-an-answer">

                <t>When createAnswer is called, a new SDP description
                must be created that is compatible with the supplied
                remote description as well as the requirements specified
                in <xref target="I-D.ietf-rtcweb-rtp-usage"></xref>. The
                exact details of this process are explained below.</t>
                <section title="Initial Answers"
                anchor="sec.initial-answers">

                    <t>When createAnswer is called for the first time
                    after a remote description has been provided, the
                    result is known as the initial answer. If no remote
                    description has been installed, an answer cannot be
                    generated, and an error MUST be returned.</t>

                    <t>Note that the remote description SDP may not have
                    been created by a JSEP endpoint and may not conform
                    to all the requirements listed in <xref
                    target="sec-create-offer"></xref>. For many cases,
                    this is not a problem. However, if any mandatory SDP
                    attributes are missing, or functionality listed as
                    mandatory-to-use above is not present, this MUST be
                    treated as an error, and MUST cause the affected m=
                    sections to be marked as rejected.</t>

                    <t>The first step in generating an initial answer is
                    to generate session-level attributes. The process
                    here is identical to that indicated in the Initial
                    Offers section above, except that the
                    "a=ice-options" line, with the "trickle" option as
                    specified in <xref
                    target="I-D.ietf-ice-trickle"></xref>, Section 4, is
                    only included if such an option was present in the
                    offer.</t>

                    <t>The next step is to generate session-level lip
                    sync groups as defined in <xref target="RFC5888"/>,
                    Section 7. For each group of type "LS" present in the offer,
                    determine which of the local RtpTransceivers identified by
                    that group's mid values reference a common local MediaStream
                    (as specified in the addTrack and
                    addTransceiver methods). If at least two such
                    RtpTransceivers exist, a group of type "LS" with the mid
                    values of these RtpTransceivers MUST be added. Otherwise,
                    this indicates a difference of opinion between the offerer
                    and answerer regarding lip sync status, and as such,
                    the offered group MUST be ignored and no corresponding
                    "LS" group generated.
                    </t>

                    <t>The next step is to generate m= sections for each
                    m= section that is present in the remote offer, as
                    specified in <xref target="RFC3264"></xref>, Section
                    6. For the purposes of this discussion, any
                    session-level attributes in the offer that are also
                    valid as media-level attributes SHALL be considered
                    to be present in each m= section.</t>

                    <t>The next step is to go through each offered m=
                    section. Each offered m= section will have an
                    associated RtpTransceiver, as described in
                    <xref target="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.</t>

                    <t>For each offered m= section, if any of the
                    following conditions are true, the corresponding
                    m= section in the answer MUST be marked as rejected
                    by setting the port in the m= line to zero, as
                    indicated in <xref target="RFC3264"></xref>, Section
                    6., and further processing for this m= section can
                    be skipped:
                    <list style="symbols">
                      <t>The associated RtpTransceiver has been stopped.
                      </t>

                      <t>No supported codec is present in the offer.</t>

                      <t>The bundle policy is "max-bundle", the m=
                      section is not in a bundle group, and this is not
                      the first m= section.</t>

                      <t>The bundle policy is "balanced", the m=
                      section is not in a bundle group, and this is not
                      the first m= section for this media type.</t>

                      <t>The RTP/RTCP multiplexing policy is "require"
                      and the m= section doesn't contain an
                      "a=rtcp-mux" attribute.</t>
                    </list></t>

                    <t>Otherwise, each m= section in
                    the answer should then be generated as specified in
                    <xref target="RFC3264"></xref>, Section 6.1. For the
                    m= line itself, the following rules must be
                    followed:
                    <list style="symbols">

                        <t>The port value would normally be set to the
                        port of the default ICE candidate for this m=
                        section, but given that no candidates have yet
                        been gathered, the "dummy" port value of 9
                        (Discard) MUST be used, as indicated in <xref
                        target="I-D.ietf-ice-trickle"></xref>, Section
                        5.1.</t>

                        <t>The &lt;proto&gt; field MUST be set to
                        exactly match the &lt;proto&gt; field for the
                        corresponding m= line in the offer.</t>
                    </list></t>

                    <t>The m= line MUST be followed immediately by a
                    "c=" line, as specified in <xref
                    target="RFC4566"></xref>, Section 5.7. Again, as no
                    candidates have yet been gathered, the "c=" line
                    must contain the "dummy" value "IN IP4 0.0.0.0", as
                    defined in <xref
                    target="I-D.ietf-ice-trickle"></xref>, Section
                    5.1.</t>

                    <t>If the offer supports bundle, all m= sections to
                    be bundled must use the same ICE credentials and
                    candidates; all m= sections not being bundled must
                    use unique ICE credentials and candidates. Each m=
                    section MUST include the following:
                    <list style="symbols">

                        <t>If and only if present in the offer, an
                        "a=mid" line, as specified in <xref
                        target="RFC5888"></xref>, Section 9.1.  The
                        "mid" value MUST match that specified in the
                        offer.</t>

                        <t>An "a=rtcp" line, as specified in <xref
                        target="RFC3605"></xref>, Section 2.1,
                        containing the dummy value "9 IN IP4 0.0.0.0",
                        because no candidates have yet been
                        gathered.</t>

                        <t>A direction attribute for the associated
                        RtpTransceiver described by <xref
                        target="sec.answer-dirattr"></xref>.</t>

                        <t>For each supported codec that is present in
                        the offer, "a=rtpmap" and "a=fmtp" lines, as
                        specified in <xref target="RFC4566"></xref>,
                        Section 6, and <xref target="RFC3264"></xref>,
                        Section 6.1.  The audio and video codecs that
                        MUST be supported are specified in
                        <xref target="I-D.ietf-rtcweb-audio">
                        </xref>(see Section 3) and
                        <xref target="I-D.ietf-rtcweb-video">
                        </xref>(see Section 5).</t>

                        <t>If this m= section is for media with
                        configurable frame sizes, e.g. audio, an
                        "a=maxptime" line, indicating the smallest of
                        the maximum supported frame sizes out of all
                        codecs included above, as specified in <xref
                        target="RFC4566"></xref>, Section 6.</t>

                        <t>If this m= section is for video media, and
                        there are known limitations on the size of
                        images which can be decoded, an "a=imageattr"
                        line, as specified in <xref
                        target="sec.imageattr"></xref>.</t>

                        <t>If "rtx" is present in the offer, for each
                        primary codec where RTP retransmission should be
                        used, a corresponding "a=rtpmap" line indicating
                        "rtx" with the clock rate of the primary codec
                        and an "a=fmtp" line that references the payload
                        type of the primary codec, as specified in <xref
                        target="RFC4588"></xref>, Section 8.1.</t>

                        <t>For each supported FEC mechanism, "a=rtpmap"
                        and "a=fmtp" lines, as specified in
                        <xref target="RFC4566"></xref>, Section 6. The
                        FEC mechanisms that MUST be supported are
                        specified in
                        <xref target="I-D.ietf-rtcweb-fec"></xref>,
                        Section 6, and specific usage for each media
                        type is outlined in Sections 4 and 5.</t>

                        <t>"a=ice-ufrag" and "a=ice-pwd" lines, as
                        specified in <xref target="RFC5245"></xref>,
                        Section 15.4.</t>

                        <t>An "a=fingerprint" line for each of the
                        endpoint's certificates, as specified in <xref
                        target="RFC4572"></xref>, Section 5; the digest
                        algorithm used for the fingerprint MUST match
                        that used in the certificate signature.</t>

                        <t>An "a=setup" line, as specified in <xref
                        target="RFC4145"></xref>, Section 4, and
                        clarified for use in DTLS-SRTP scenarios in
                        <xref target="RFC5763"></xref>, Section 5. The
                        role value in the answer MUST be "active" or
                        "passive"; the "active" role is RECOMMENDED.</t>

                        <t>If present in the offer, an "a=rtcp-mux"
                        line, as specified in <xref
                        target="RFC5761"></xref>, Section 5.1.1.  If the
                        "require" RTCP multiplexing policy is set and no
                        "a=rtcp-mux" line is present in the offer, then
                        the m=line MUST be marked as rejected by setting
                        the port in the m= line to zero, as indicated in
                        <xref target="RFC3264"></xref>, Section 6.</t>

                        <t>If present in the offer, an "a=rtcp-rsize"
                        line, as specified in <xref
                        target="RFC5506"></xref>, Section 5.</t>

                        <t>For each supported RTP header extension that
                        is present in the offer, an "a=extmap" line, as
                        specified in <xref target="RFC5285"></xref>,
                        Section 5. The list of header extensions that
                        SHOULD/MUST be supported is specified in
                        <xref target="I-D.ietf-rtcweb-rtp-usage">
                        </xref>, Section 5.2. Any header extensions
                        that require encryption MUST be specified as
                        indicated in
                        <xref target="RFC6904"></xref>, Section 4.</t>

                        <t>For each supported RTCP feedback mechanism
                        that is present in the offer, an "a=rtcp-fb"
                        mechanism, as specified in <xref
                        target="RFC4585"></xref>, Section 4.2.  The list
                        of RTCP feedback mechanisms that SHOULD/MUST be
                        supported is specified in
                        <xref target="I-D.ietf-rtcweb-rtp-usage">
                        </xref>, Section 5.1.</t>

                        <t>If the RtpSender of the RtpTransceiver
                        associated with this m=section is active:
                        <list style="symbols">

                            <t>An "a=msid" line, as specified in
                            <xref target="I-D.ietf-mmusic-msid">
                            </xref>, Section 2.</t>

                            <t>An "a=ssrc" line, as specified in <xref
                            target="RFC5576"></xref>, Section 4.1,
                            indicating the SSRC to be used for sending
                            media, along with the mandatory "cname"
                            source attribute, as specified in Section
                            6.1, indicating the CNAME for the
                            source. The CNAME MUST be generated in
                            accordance with Section 4.9 of
                            <xref target="I-D.ietf-rtcweb-rtp-usage">
                            </xref>.</t>

                            <t>If RTX has been negotiated for this m=
                            section, another "a=ssrc" line with the RTX
                            SSRC, and an "a=ssrc-group" line, as
                            specified in <xref target="RFC5576"></xref>,
                            section 4.2, with semantics set to "FID" and
                            including the primary and RTX SSRCs.</t>

                            <t>If FEC has been negotiated for this m=
                            section, another "a=ssrc" line with the FEC
                            SSRC, and an "a=ssrc-group" line with
                            semantics set to "FEC-FR" and including the
                            primary and FEC SSRCs, as specified in <xref
                            target="RFC5956"></xref>, section 4.3. For
                            simplicity, if both RTX and FEC are
                            supported, the FEC SSRC MUST be the same as
                            the RTX SSRC.</t>
                        </list></t>
                    </list></t>

                    <t>If a data channel m= section has been offered, a
                    m= section MUST also be generated for data. The
                    &lt;media&gt; field MUST be set to "application" and
                    the &lt;proto&gt; and "fmt" fields MUST be set to
                    exactly match the fields in the offer.</t>

                    <t>Within the data m= section, the "a=mid",
                    "a=ice-ufrag", "a=ice-pwd", "a=candidate",
                    "a=fingerprint", and "a=setup" lines MUST be
                    included as mentioned above, along with an
                    "a=fmtp:webrtc-datachannel" line and an
                    "a=sctp-port" line referencing the SCTP port number
                    as defined in <xref
                    target="I-D.ietf-mmusic-sctp-sdp"></xref>, Section
                    4.1.</t>

                    <t>If "a=group" attributes with semantics of
                    "BUNDLE" are offered, corresponding session-level
                    "a=group" attributes MUST be added as specified in
                    <xref target="RFC5888"></xref>. These attributes
                    MUST have semantics "BUNDLE", and MUST include the
                    all mid identifiers from the offered bundle groups
                    that have not been rejected. Note that regardless of
                    the presence of "a=bundle-only" in the offer, no m=
                    sections in the answer should have an
                    "a=bundle-only" line.</t>

                    <t>Attributes that are common between all m=
                    sections MAY be moved to session-level, if
                    explicitly defined to be valid at session-level.</t>

                    <t>The attributes prohibited in the creation of
                    offers are also prohibited in the creation of
                    answers.</t>
                </section>
                <section title="Subsequent Answers"
                anchor="sec.subsequent-answers">

                    <t>When createAnswer is called a second (or later)
                    time, or is called after a local description has
                    already been installed, the processing is somewhat
                    different than for an initial answer.</t>

                    <t>If the initial answer was not applied using
                    setLocalDescription, meaning the PeerConnection is
                    still in the "have-remote-offer" state, the steps
                    for generating an initial answer should be
                    followed, subject to the following restriction:
                    <list style="symbols">

                        <t>The fields of the "o=" line MUST stay the
                        same except for the &lt;session-version&gt;
                        field, which MUST increment if the session
                        description changes in any way from the
                        previously generated answer.</t>

                    </list></t>

                    <t>If any session description was previously
                    supplied to setLocalDescription, an answer is
                    generated by following the steps in the
                    "have-remote-offer" state above, along with these
                    exceptions:
                    <list style="symbols">

                        <t>The "s=" and "t=" lines MUST stay the
                        same.</t>

                        <t>Each "m=" and c=" line MUST be filled in with
                        the port and address of the default candidate
                        for the m= section, as described in <xref
                        target="RFC5245"></xref>, Section 4.3.  Note,
                        however, that the m= line protocol need not
                        match the default candidate, because this
                        protocol value must instead match what was
                        supplied in the offer, as described above. Each
                        "a=rtcp" attribute line MUST also be filled in
                        with the port and address of the appropriate
                        default candidate, either the default RTP or
                        RTCP candidate, depending on whether RTCP
                        multiplexing is enabled in the answer. In each
                        case, if no candidates of the desired type have
                        yet been gathered, dummy values MUST be used, as
                        described in the initial answer section
                        above.</t>

                        <t>Each "a=ice-ufrag" and "a=ice-pwd" line MUST
                        stay the same, unless the m= section is
                        restarting, in which case new ICE credentials
                        must be created as specified in <xref
                        target="RFC5245"></xref>, Section 9.2.1.1. If
                        the m= section is bundled into another m=
                        section, it still MUST NOT contain any ICE
                        credentials.</t>

                        <t>If the m= section is not bundled into
                        another m= section, for each candidate that has
                        been gathered during the most recent gathering
                        phase (see
                        <xref target="sec.ice-gather-overview">
                        </xref>), an "a=candidate" line MUST be added,
                        as defined in <xref target="RFC5245"></xref>,
                        Section 4.3., paragraph 3. If candidate
                        gathering for the section has completed, an
                        "a=end-of-candidates" attribute MUST be added,
                        as described in <xref
                        target="I-D.ietf-ice-trickle"></xref>, Section
                        9.3. If the m= section is bundled into another
                        m= section, both "a=candidate" and
                        "a=end-of-candidates" MUST be omitted.</t>

                        <t>For RtpTransceivers that are not stopped,
                        the "a=msid", "a=ssrc", and "a=ssrc-group"
                        lines MUST stay the same.</t>
                    </list></t>

                </section>
                <section title="Options Handling"
                anchor="sec.options-handling2">

                    <t>The createAnswer method takes as a parameter an
                    RTCAnswerOptions object. The set of parameters for
                    RTCAnswerOptions is different than those supported
                    in RTCOfferOptions; the IceRestart option is
                    unnecessary, as ICE credentials will automatically
                    be changed for all m= lines where the offerer chose
                    to perform ICE restart.</t>

                    <t>The following options are supported in
                    RTCAnswerOptions.</t>

                    <section title="VoiceActivityDetection"
                    anchor="sec.voiceactivitydetection2">

                        <t>Silence suppression in the answer is handled
                        as described in
                        <xref target="sec.voiceactivitydetection1">
                        </xref>, with one exception: if support for
                        silence suppression was not indicated in the
                        offer, the VoiceActivityDetection parameter has
                        no effect, and the answer should be generated as
                        if VoiceActivityDetection was set to false.
                        This is 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 codecs and "usedtx=0").</t>

                    </section>
                </section>
                <section title="Direction Attribute in Answers"
                anchor="sec.answer-dirattr">

                    <t><xref target="RFC3264"></xref> direction
                    attributes (defined in Section 6.1) in answers are
                    chosen according to the direction attribute in the
                    remote offer and the states of the RtpSender and
                    RtpReceiver of the corresponding RtpTransceiver, as
                    follows:</t>

                    <texttable>
                        <ttcol align='center'>offer direction</ttcol>
                        <ttcol align='center'>RtpSender</ttcol>
                        <ttcol align='center'>RtpReceiver</ttcol>
                        <ttcol align='center'>answer direction</ttcol>
                        <c>sendrecv</c>
                        <c>active</c>
                        <c>active</c>
                        <c>sendrecv</c>
                        <c>sendrecv</c>
                        <c>active</c>
                        <c>inactive</c>
                        <c>sendonly</c>
                        <c>sendrecv</c>
                        <c>inactive</c>
                        <c>active</c>
                        <c>recvonly</c>
                        <c>sendrecv</c>
                        <c>inactive</c>
                        <c>inactive</c>
                        <c>inactive</c>
                        <c>sendonly</c>
                        <c>*</c>
                        <c>active</c>
                        <c>recvonly</c>
                        <c>sendonly</c>
                        <c>*</c>
                        <c>inactive</c>
                        <c>inactive</c>
                        <c>recvonly</c>
                        <c>active</c>
                        <c>*</c>
                        <c>sendonly</c>
                        <c>recvonly</c>
                        <c>inactive</c>
                        <c>*</c>
                        <c>inactive</c>
                        <c>inactive</c>
                        <c>*</c>
                        <c>*</c>
                        <c>inactive</c>
                    </texttable>

                </section>
            </section>
            <section title="Processing a Local Description"
            anchor="sec.processing-a-local-desc">

                <t>When a SessionDescription is supplied to
                setLocalDescription, the following steps MUST be
                performed:
                <list style="symbols">

                    <t>First, the type of the SessionDescription is
                    checked against the current state of the
                    PeerConnection:
                    <list style="symbols">

                        <t>If the type is "offer", the PeerConnection
                        state MUST be either "stable" or
                        "have-local-offer".</t>

                        <t>If the type is "pranswer" or "answer", the
                        PeerConnection state MUST be either
                        "have-remote-offer" or
                        "have-local-pranswer".</t>
                    </list></t>

                    <t>If the type is not correct for the current
                    state, processing MUST stop and an error MUST be
                    returned.</t>

                    <t>Next, the SessionDescription is parsed into a
                    data structure, as described in the <xref
                    target="sec.parsing-a-desc" /> section below.  If
                    parsing fails for any reason, processing MUST stop
                    and an error MUST be returned.</t>

                    <t>Finally, the parsed SessionDescription is applied
                    as described in the <xref
                    target="sec.applying-a-local-desc" /> section
                    below.</t>
                </list></t>
            </section>
            <section title="Processing a Remote Description"
            anchor="sec.processing-a-remote-desc">

                <t>When a SessionDescription is supplied to
                setRemoteDescription, the following steps MUST be
                performed:
                <list style="symbols">

                    <t>First, the type of the SessionDescription is
                    checked against the current state of the
                    PeerConnection:
                    <list style="symbols">

                        <t>If the type is "offer", the PeerConnection
                        state MUST be either "stable" or
                        "have-remote-offer".</t>

                        <t>If the type is "pranswer" or "answer", the
                        PeerConnection state MUST be either
                        "have-local-offer" or
                        "have-remote-pranswer".</t>
                    </list></t>

                    <t>If the type is not correct for the current
                    state, processing MUST stop and an error MUST be
                    returned.</t>

                    <t>Next, the SessionDescription is parsed into a
                    data structure, as described in the <xref
                    target="sec.parsing-a-desc" /> section below.  If
                    parsing fails for any reason, processing MUST stop
                    and an error MUST be returned.</t>

                    <t>Finally, the parsed SessionDescription is applied
                    as described in the <xref
                    target="sec.applying-a-remote-desc" /> section
                    below.</t>

                </list></t>

            </section>
            <section title="Parsing a Session Description"
            anchor="sec.parsing-a-desc">

                <t>When a SessionDescription of any type is supplied to
                setLocal/RemoteDescription, the implementation must
                parse it and reject it if it is invalid. The exact
                details of this process are explained below.</t>

                <t>The SDP contained in the session description object
                consists of a sequence of text lines, each containing a
                key-value expression, as described in <xref
                target="RFC4566" />, Section 5. The SDP is read,
                line-by-line, and converted to a data structure that
                contains the deserialized information. However, SDP
                allows many types of lines, not all of which are
                relevant to JSEP applications. For each line, the
                implementation will first ensure it is syntactically
                correct according its defining ABNF, check that it
                conforms to <xref target="RFC4566" /> and <xref
                target="RFC3264" /> semantics, and then either parse and
                store or discard the provided value, as described
                below. A partial list of ABNF definitions for SDP
                attributes can found in:</t>

                <texttable anchor="sdp_abnf"
                title="SDP ABNF References">
                    <ttcol align='left'>Attribute</ttcol>
                    <ttcol align='left'>Reference</ttcol>
                    <c>ptime</c>
                    <c> <xref target="RFC4566" /> Section 9</c>
                    <c>maxptime</c>
                    <c> <xref target="RFC4566" /> Section 9</c>
                    <c>rtpmap</c>
                    <c><xref target="RFC4566" /> Section 9</c>
                    <c>recvonly</c>
                    <c><xref target="RFC4566" /> Section 9</c>
                    <c>sendrecv</c>
                    <c><xref target="RFC4566" /> Section 9</c>
                    <c>sendonly</c>
                    <c><xref target="RFC4566" /> Section 9</c>
                    <c>inactive</c>
                    <c> <xref target="RFC4566" /> Section 9</c>
                    <c>framerate</c>
                    <c><xref target="RFC4566" /> Section 9</c>
                    <c>fmtp</c>
                    <c><xref target="RFC4566" /> Section 9</c>
                    <c>quality</c>
                    <c> <xref target="RFC4566" /> Section 9</c>
                    <c>msid</c>
                    <c><xref target="I-D.ietf-mmusic-msid" /> Section 2</c>
                    <c>rtcp</c>
                    <c><xref target=" RFC3605" /> Section 2.1</c>
                    <c>setup</c>
                    <c> <xref target="RFC4145" /> Section 3, 4, and 5</c>
                    <c>connection</c>
                    <c> <xref target="RFC4145" /> Section 3, 4, and 5</c>
                    <c>fingerprint</c>
                    <c><xref target="RFC4572" /> Section 5</c>
                    <c>rtcp-fb</c>
                    <c><xref target="RFC4585" /> Section 4.2</c>
                    <c>candidate</c>
                    <c> <xref target="RFC5245" /> Section 15</c>
                    <c>extmap</c>
                    <c>  <xref target="RFC5285" /> Section 7</c>
                    <c>mid</c>
                    <c><xref target="RFC5888" /> Section 4 and 5</c>
                    <c>group</c>
                    <c> <xref target="RFC5888" /> Section 4 and 5</c>
                    <c>imageattr</c>
                    <c><xref target="RFC6236" /> Section 3.1</c>
                    <c>extmap (encrypt option)</c>
                    <c><xref target="RFC6904" /> Section 4</c>
                </texttable>

                <t>[TODO: ensure that every line is listed below.]</t>

                <t>If the line is not well-formed, or cannot be parsed
                as described, the parser MUST stop with an error and
                reject the session description. This ensures that
                implementations do not accidentally misinterpret
                ambiguous SDP.</t>

                <section title="Session-Level Parsing"
                anchor="sec.session-level-parse">

                    <t>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 <xref
                    target="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.</t>

                    <t>For non-attribute (non-"a=") lines, their
                    sequencing, syntax, and semantics, are checked, as
                    mentioned above. The following lines are not
                    meaningful in the JSEP context and MAY be discarded
                    once they have been checked.
                    <list>

                        <t>The "c=" line MUST be checked for syntax but
                        its value is not used. This supersedes the
                        guidance in <xref target="RFC5245" />, Section
                        6.1, to use "ice-mismatch" to indicate
                        mismatches between "c=" and the candidate lines;
                        because JSEP always uses ICE, "ice-mismatch" is
                        not useful in this context.</t>

                        <t>The "i=", "u=", "e=", "p=", "t=", "r=",
                        "z=", and "k=" lines are not used by this
                        specification; they MUST be checked for syntax
                        but their values are not used.</t>
                    </list></t>

                    <t>The remaining lines are processed as follows:
                    <list>

                        <t>The "v=" line MUST have a version of 0, as
                        specified in <xref target="RFC4566" />, Section
                        5.1.</t>

                        <t>The "o=" line MUST be parsed as specified in
                        <xref target="RFC4566" />, Section 5.2.</t>

                        <t>The "b=" line, if present, MUST be parsed as
                        specified in <xref target="RFC4566" />, Section
                        5.8, and the bwtype and bandwidth values
                        stored.</t>

                    </list></t>

                    <t>Specific processing MUST be applied for the
                    following session-level attribute ("a=") lines:
                    <list style="symbols">

                        <t>Any "a=group" lines are parsed as specified
                        in <xref target="RFC5888" />, Section 5, and the
                        group's semantics and mids are stored.</t>

                        <t>If present, a single "a=ice-lite" line is
                        parsed as specified in <xref target="RFC5245"
                        />, Section 15.3, and a value indicating the
                        presence of ice-lite is stored.</t>

                        <t>If present, a single "a=ice-ufrag" line is
                        parsed as specified in <xref target="RFC5245"
                        />, Section 15.4, and the ufrag value is
                        stored.</t>

                        <t>If present, a single "a=ice-pwd" line is
                        parsed as specified in <xref target="RFC5245"
                        />, Section 15.4, and the password value is
                        stored.</t>

                        <t>If present, a single "a=ice-options" line is
                        parsed as specified in <xref target="RFC5245"
                        />, Section 15.5, and the set of specified
                        options is stored.</t>

                        <t>Any "a=fingerprint" lines are parsed as
                        specified in <xref target="RFC4572" />, Section
                        5, and the set of fingerprint and algorithm
                        values is stored.</t>

                        <t>If present, a single "a=setup" line is parsed
                        as specified in <xref target="RFC4145" />,
                        Section 4, and the setup value is stored.</t>

                        <t>Any "a=extmap" lines are parsed as specified
                        in <xref target="RFC5285" />, Section 5, and
                        their values are stored.</t>

                        <t>TODO: identity, rtcp-rsize, rtcp-mux, and any
                        other attributes valid at session level.</t>

                    </list></t>

                    <t>Once all the session-level lines have been
                    parsed, processing continues with the lines in
                    media sections.</t>
                </section>
                <section title="Media Section Parsing"
                anchor="sec.media-level-parse">

                    <t>Like the session-level lines, the media session
                    lines MUST occur in the specific order and with the
                    specific syntax defined in <xref target="RFC4566"
                    />, Section 5.</t>

                    <t>The "m=" line itself MUST be parsed as described
                    in <xref target="RFC4566" />, Section 5.14, and the
                    media, port, proto, and fmt values stored.</t>

                    <t>Following the "m=" line, specific processing MUST
                    be applied for the following non-attribute lines:

                    <list style="symbols">

                        <t>As with the "c=" line at the session level,
                        the "c=" line MUST be parsed according to <xref
                        target="RFC4566" />, Section 5.7, but its value
                        is not used.</t>

                        <t>The "b=" line, if present, MUST be parsed as
                        specified in <xref target="RFC4566" />, Section
                        5.8, and the bwtype and bandwidth values
                        stored.</t>

                    </list></t>

                    <t>Specific processing MUST also be applied for the
                    following attribute lines:
                    <list style="symbols">

                        <t>If present, a single "a=ice-ufrag" line is
                        parsed as specified in <xref target="RFC5245"
                        />, Section 15.4, and the ufrag value is
                        stored.</t>

                        <t>If present, a single "a=ice-pwd" line is
                        parsed as specified in <xref target="RFC5245"
                        />, Section 15.4, and the password value is
                        stored.</t>

                        <t>If present, a single "a=ice-options" line is
                        parsed as specified in <xref target="RFC5245"
                        />, Section 15.5, and the set of specified
                        options is stored.</t>

                        <t>Any "a=fingerprint" lines are parsed as
                        specified in <xref target="RFC4572" />, Section
                        5, and the set of fingerprint and algorithm
                        values is stored.</t>

                        <t>If present, a single "a=setup" line is parsed
                        as specified in <xref target="RFC4145" />,
                        Section 4, and the setup value is stored.</t>
                    </list></t>

                    <t>If the "m=" proto value indicates use of RTP, as
                    described in the <xref target="sec.profile-names" />
                    section above, the following attribute lines MUST be
                    processed:
                    <list style="symbols">

                        <t>The "m=" fmt value MUST be parsed as
                        specified in <xref target="RFC4566" />, Section
                        5.14, and the individual values stored.</t>

                        <t>Any "a=rtpmap" or "a=fmtp" lines MUST be
                        parsed as specified in <xref target="RFC4566"
                        />, Section 6, and their values stored.</t>

                        <t>If present, a single "a=ptime" line MUST be
                        parsed as described in <xref target="RFC4566"
                        />, Section 6, and its value stored.</t>

                        <t>If present, a single "a=maxptime" line MUST
                        be parsed as described in <xref target="RFC4566"
                        />, Section 6, and its value stored.</t>

                        <t>If present, a single direction attribute line
                        (e.g. "a=sendrecv") MUST be parsed as described
                        in <xref target="RFC4566" />, Section 6, and its
                        value stored.</t>

                        <t>Any "a=ssrc" or "a=ssrc-group" attributes
                        MUST be parsed as specified in <xref
                        target="RFC5576" />, Sections 4.1-4.2, and their
                        values stored.</t>

                        <t>Any "a=extmap" attributes MUST be parsed as
                        specified in <xref target="RFC5285" />, Section
                        5, and their values stored.</t>

                        <t>Any "a=rtcp-fb" attributes MUST be parsed as
                        specified in <xref target="RFC4585" />, Section
                        4.2., and their values stored.</t>

                        <t>If present, a single "a=rtcp-mux" attribute
                        MUST be parsed as specified in <xref
                        target="RFC5761" />, Section 5.1.1, and its
                        presence or absence flagged and stored.</t>

                        <t>If present, a single "a=rtcp-rsize" attribute
                        MUST be parsed as specified in <xref
                        target="RFC5506" />, Section 5, and its presence
                        or absence flagged and stored.</t>

                        <t>If present, a single "a=rtcp" attribute MUST
                        be parsed as specified in <xref target="RFC3605"
                        />, Section 2.1, but its value is ignored.</t>

                        <t>If present, a single "a=msid" attribute MUST
                        be parsed as specified in <xref
                        target="I-D.ietf-mmusic-msid" />, Section 3.2,
                        and its value stored.</t>

                        <t>Any "a=candidate" attributes MUST be parsed
                        as specified in <xref target="RFC5245" />,
                        Section 4.3, and their values stored.</t>

                        <t>Any "a=remote-candidates" attributes MUST be
                        parsed as specified in <xref target="RFC5245"
                        />, Section 4.3, but their values are
                        ignored.</t>

                        <t>If present, a single "a=end-of-candidates"
                        attribute MUST be parsed as specified in <xref
                        target="I-D.ietf-ice-trickle" />, Section 8.2,
                        and its presence or absence flagged and
                        stored.</t>

                        <t>Any "a=imageattr" attributes MUST be parsed
                        as specified in <xref target="RFC6236" />,
                        Section 3, and their values stored.</t>

                        <t>Any "a=rid" lines MUST be parsed as specified
                        in <xref target="I-D.ietf-mmusic-rid"></xref>,
                        Section 10, and their values stored.</t>

                        <t>If present, a single "a=simulcast" line MUST
                        be parsed as specified in
                        <xref target="I-D.ietf-mmusic-sdp-simulcast">
                        </xref>, and its values stored.</t>

                    </list></t>

                    <t>Otherwise, if the "m=" proto value indicates use
                    of SCTP, the following attribute lines MUST be
                    processed:
                    <list style="symbols">

                        <t>The "m=" fmt value MUST be parsed as
                        specified in <xref
                        target="I-D.ietf-mmusic-sctp-sdp" />, Section
                        4.3, and the application protocol value
                        stored.</t>

                        <t>An "a=sctp-port" attribute MUST be present,
                        and it MUST be parsed as specified in <xref
                        target="I-D.ietf-mmusic-sctp-sdp" />, Section
                        5.2, and the value stored.</t>

                        <t>If present, a single "a=max-message-size"
                        attribute MUST be parsed as specified in <xref
                        target="I-D.ietf-mmusic-sctp-sdp" />, Section 6,
                        and the value stored. Otherwise, use the
                        specified default.</t>

                    </list></t>
                </section>
                <section title="Semantics Verification">

                    <t>Assuming parsing completes successfully, the
                    parsed description is then evaluated to ensure
                    internal consistency as well as proper support for
                    mandatory features. Specifically, the following
                    checks are performed:
                    <list style="symbols">

                        <t>For each m= section, valid values for each of
                        the mandatory-to-use features enumerated in
                        <xref target="sec.usage-requirements" /> MUST be
                        present. These values MAY either be present at
                        the media level, or inherited from the session
                        level.
                        <list style="symbols">

                            <t>ICE ufrag and password values, which MUST
                            comply with the size limits specified in
                            <xref target="RFC5245" />, Section 15.4.</t>

                            <t>DTLS setup value, which MUST be set
                            according to the rules specified in <xref
                            target="RFC5763" />, Section 5, and MUST be
                            consistent with the selected role of the
                            current DTLS connection, if one
                            exists.[TODO: may need revision, i.e., use
                            of actpass</t>

                            <t>DTLS fingerprint values, where at least
                            one fingerprint MUST be present.</t>

                        </list></t>

                        <t>All RID values referenced in an "a=simulcast"
                        line MUST exist as "a=rid" lines.</t>

                        <t>Each m= section is also checked to ensure
                        prohibited features are not used. If this is a
                        local description, the "ice-lite" attribute MUST
                        NOT be specified.</t>

                    </list></t>

                    <t>If this session description is of type "pranswer"
                    or "answer", the following additional checks are
                    applied:

                    <list style="symbols">

                        <t>The session description must follow the rules
                        defined in <xref target="RFC3264" />, Section 6,
                        including the requirement that the number of m=
                        sections MUST exactly match the number of m=
                        sections in the associated offer.</t>

                        <t>For each m= section, the media type and
                        protocol values MUST exactly match the media
                        type and protocol values in the corresponding m=
                        section in the associated offer.</t>

                    </list></t>
                </section>
            </section>
            <section title="Applying a Local Description"
            anchor="sec.applying-a-local-desc">

                <t>The following steps are performed at the media engine
                level to apply a local description.</t>

                <t>First, the parsed parameters are checked to ensure
                that any modifications performed fall within those
                explicitly permitted by <xref
                target="sec.configurable-sdp-paramete" />; otherwise,
                processing MUST stop and an error MUST be returned.</t>

                <t>Next, media sections are processed. For each media
                section, the following steps MUST be performed; if any
                parameters are out of bounds, or cannot be applied,
                processing MUST stop and an error MUST be returned.
                <list style="symbols">

                    <t>If this media section is new, begin gathering
                    candidates for it, as defined in <xref
                    target="RFC5245" />, Section 4.1.1, unless it has
                    been marked as bundle-only.</t>

                    <t>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
                    media section, as defined in <xref target="RFC5245"
                    />, Section 9.1.1.1, unless it has been marked as
                    bundle-only.</t>

                    <t>If the media section proto value indicates use of
                    RTP:
                    <list style="symbols">

                        <t>If there is no RtpTransceiver associated with
                        this m= section (which should only happen when
                        applying an offer), find one and associate it
                        with this m= section according to the following
                        steps:
                        <list style="symbols">

                            <t>Find the RtpTransceiver that corresponds
                            to the m= section with the same MID in the
                            created offer.</t>

                            <t>Set the value of the RtpTransceiver's mid
                            attribute to the MID of the m= section.</t>
                        </list></t>

                        <t>If RTCP mux is indicated, prepare to demux
                        RTP and RTCP from the RTP ICE component, as
                        specified in <xref target="RFC5761" />, Section
                        5.1.1. If RTCP mux is not indicated, but was
                        indicated in a previous description, this MUST
                        result in an error.</t>

                        <t>For each specified RTP header extension,
                        establish a mapping between the extension ID and
                        URI, as described in section 6 of <xref
                        target="RFC5285" />. If any indicated RTP header
                        extension is unknown, this MUST result in an
                        error.</t>

                        <t>If the MID header extension is supported,
                        prepare to demux RTP data intended for this
                        media section based on the MID header extension,
                        as described in <xref
                        target="I-D.ietf-mmusic-msid" />, Section
                        3.2.</t>

                        <t>For each specified payload type, establish a
                        mapping between the payload type ID and the
                        actual media format, as described in <xref
                        target="RFC3264" />. If any indicated payload
                        type is unknown, this MUST result in an
                        error.</t>

                        <t>For each specified "rtx" media format,
                        establish a mapping between the RTX payload type
                        and its associated primary payload type, as
                        described in <xref target="RFC4588" />, Sections
                        8.6 and 8.7. If any referenced primary payload
                        types are not present, this MUST result in an
                        error.</t>

                        <t>If the directional attribute is of type
                        "sendrecv" or "recvonly", enable receipt and
                        decoding of media.</t>

                    </list></t>
                </list></t>

                <t>Finally, if this description is of type "pranswer" or
                "answer", follow the processing defined in the <xref
                target="sec.applying-an-answer" /> section below.</t>

            </section>
            <section title="Applying a Remote Description"
            anchor="sec.applying-a-remote-desc">

                <t>If the answer contains any "a=ice-options" attributes
                where "trickle" is listed as an attribute, update the
                PeerConnection canTrickle property to be
                true. Otherwise, set this property to false.</t>

                <t>The following steps are performed at the media engine
                level to apply a remote description.</t>

                <t>The following steps MUST be performed for attributes
                at the session level; if any parameters are out of
                bounds, or cannot be applied, processing MUST stop and
                an error MUST be returned.
                <list style="symbols">

                    <t>For any specified "CT" bandwidth value, set this
                    as the limit for the maximum total bitrate for all
                    m= sections, as specified in Section 5.8 of <xref
                    target="RFC4566"></xref>. The implementation can
                    decide how to allocate the available bandwidth
                    between m= sections to simultaneously meet any
                    limits on individual m= sections, as well as this
                    overall session limit.</t>

                    <t>For any specified "RR" or "RS" bandwidth values,
                    handle as specified in <xref
                    target="RFC3556"></xref>, Section 2.</t>

                    <t>Any "AS" bandwidth value MUST be ignored, as the
                    meaning of this construct at the session level is
                    not well defined.</t>
                </list></t>

                <t>For each media section, the following steps MUST be
                performed; if any parameters are out of bounds, or
                cannot be applied, processing MUST stop and an error
                MUST be returned.
                <list style="symbols">

                    <t>If the description is of type "offer", and the
                    ICE ufrag or password changed from the previous
                    remote description, as described in Section 9.1.1.1
                    of <xref target="RFC5245" />, mark that an ICE
                    restart is needed.</t>

                    <t>Configure the ICE components associated with
                    this media section to use the supplied ICE remote
                    ufrag and password for their connectivity
                    checks.</t>

                    <t>Pair any supplied ICE candidates with any
                    gathered local candidates, as described in Section
                    5.7 of <xref target="RFC5245" /> and start
                    connectivity checks with the appropriate
                    credentials.</t>

                    <t>If an "a=end-of-candidates" attribute is present,
                    process the end-of-candidates indication as
                    described in <xref target="I-D.ietf-ice-trickle" />
                    Section 11.</t>

                    <t>If the media section proto value indicates use of
                    RTP:
                    <list style="symbols">

                        <t>[TODO: header extensions]</t>

                        <t>If the m= section is being recycled (see
                        <xref target="sec.subsequent-offers"></xref>),
                        dissociate the currently associated
                        RtpTransceiver by setting its mid attribute to
                        null.</t>

                        <t>If the m= section is not associated with any
                        RtpTransceiver (possibly because it was
                        dissociated in the previous step), either find
                        an RtpTransceiver or create one according to the
                        following steps:
                        <list style="symbols">

                            <t>If the m= section is sendrecv or
                            recvonly, and there are RtpTransceivers of
                            the same type that were added to the
                            PeerConnection by addTrack and are not
                            associated with any m= section and are not
                            stopped, find the first (according to the
                            canonical order described in <xref
                            target="sec.initial-offers" />) such
                            RtpTransceiver.</t>

                            <t>If no RtpTransceiver was found in the
                            previous step, create one with an inactive
                            RtpSender and active RtpReceiver.</t>

                            <t>Associate the found or created
                            RtpTransceiver with the m= section by
                            setting the value of the RtpTransceiver's
                            mid attribute to the MID of the m=
                            section.</t>
                        </list></t>

                        <t>For each specified payload type that is also
                        supported by the local implementation, establish
                        a mapping between the payload type ID and the
                        actual media format. [TODO - Justin to add more
                        to explain mapping.] If any indicated payload
                        type is unknown, it MUST be ignored.  [TODO:
                        should fail on answers]</t>

                        <t>For each specified "rtx" media format,
                        establish a mapping between the RTX payload type
                        and its associated primary payload type, as
                        described in <xref target="RFC4588" />. If any
                        referenced primary payload types are not
                        present, this MUST result in an error.</t>

                        <t>For each specified fmtp parameter that is
                        supported by the local implementation, enable
                        them on the associated payload types.</t>

                        <t>For each specified RTCP feedback mechanism
                        that is supported by the local implementation,
                        enable them on the associated payload types.</t>

                        <t>For any specified "TIAS" bandwidth value, set
                        this value as a constraint on the maximum RTP
                        bitrate to be used when sending media, as
                        specified in <xref target="RFC3890"></xref>. If
                        a "TIAS" value is not present, but an "AS" value
                        is specified, generate a "TIAS" value using this
                        formula:

                        <list style="format">

                            <t>TIAS = AS * 1000 * 0.95 - 50 * 40 * 8</t>

                        </list>

                        The 50 is based on 50 packets per second, the 40
                        is based on an estimate of total header size, the
                        1000 changes the unit from kbps to bps (as required
                        by TIAS), and the 0.95 is to allocate 5% to RTCP. If more
                        accurate control of bandwidth is needed, "TIAS"
                        should be used instead of "AS".</t>

                        <t>For any "RR" or "RS" bandwidth values, handle
                        as specified in <xref target="RFC3556"></xref>,
                        Section 2.</t>

                        <t>Any specified "CT" bandwidth value MUST be
                        ignored, as the meaning of this construct at
                        the media level is not well defined.</t>

                        <t>[TODO: handling of CN, telephone-event,
                        "red"]</t>

                        <t>If the media section if of type audio:
                        <list style="symbols">

                            <t>For any specified "ptime" value,
                            configure the available payload types to
                            use the specified packet size. If the
                            specified size is not supported for a
                            payload type, use the next closest value
                            instead.</t>

                        </list></t>

                      </list></t>

                </list></t>

                <t>Finally, if this description is of type "pranswer" or
                "answer", follow the processing defined in the <xref
                target="sec.applying-an-answer" /> section below.</t>

            </section>
            <section title="Applying an Answer"
            anchor="sec.applying-an-answer">

                <t>In addition to the steps mentioned above for
                processing a local or remote description, the following
                steps are performed when processing a description of
                type "pranswer" or "answer".</t>

                <t>For each media section, the following steps MUST be
                performed:
                <list style="symbols">

                    <t>If the media section has been rejected (i.e.
                    port is set to zero in the answer), stop any
                    reception or transmission of media for this section,
                    and discard any associated ICE components, as
                    described in Section 9.2.1.3 of <xref
                    target="RFC5245" />.</t>

                    <t>If the remote DTLS fingerprint has been changed,
                    tear down the existing DTLS connection.</t>

                    <t>If no valid DTLS connection exists, prepare to
                    start a DTLS connection, using the specified roles
                    and fingerprints, on any underlying ICE components,
                    once they are active.</t>

                    <t>If the media section proto value indicates use
                    of RTP:
                    <list style="symbols">

                        <t>If the media section has RTCP mux enabled,
                        discard any RTCP component, and begin or
                        continue muxing RTCP over the RTP component, as
                        specified in <xref target="RFC5761" />, Section
                        5.1.3.  Otherwise, transmit RTCP over the RTCP
                        component; if no RTCP component exists, because
                        RTCP mux was previously enabled, this MUST
                        result in an error.</t>

                        <t>If the media section has reduced-size RTCP
                        enabled, configure the RTCP transmission for
                        this media section to use reduced-size RTCP, as
                        specified in <xref target="RFC5506" />.</t>

                        <t>If the directional attribute in the answer is
                        of type "sendrecv" or "sendonly", prepare to
                        start transmitting media using the specified
                        primary SSRC and one of the selected payload
                        types, once the underlying transport layers have
                        been established. If RID values are specified,
                        include the RID header extension in the RTP
                        streams, as indicated in <xref
                        target="I-D.ietf-mmusic-rid"></xref>, Section
                        4). If simulcast is negotiated, send the number
                        of Source RTP Streams as specified in
                        <xref target="I-D.ietf-mmusic-sdp-simulcast">
                        </xref>, Section 6.2.2. If the directional
                        attribute is of type "recvonly" or "inactive",
                        stop transmitting RTP media, although RTCP
                        should still be sent, as described in
                        <xref target="RFC3264" />, Section 5.1.</t>

                    </list></t>

                    <t>If the media section proto value indicates use
                    of SCTP:
                    <list style="symbols">

                        <t>If no SCTP association yet exists, prepare to
                        initiate a SCTP association over the associated
                        ICE component and DTLS connection, using the
                        local SCTP port value from the local
                        description, and the remote SCTP port value from
                        the remote description, as described in <xref
                        target="I-D.ietf-mmusic-sctp-sdp" />, Section
                        10.2.</t>

                    </list></t>
                </list></t>

                <t>If the answer contains valid bundle groups, discard
                any ICE components for the m= sections that will be
                bundled onto the primary ICE components in each bundle,
                and begin muxing these m= sections accordingly, as
                described in <xref
                target="I-D.ietf-mmusic-sdp-bundle-negotiation" />,
                Section 8.2.</t>

            </section>
        </section>
        <section title="Configurable SDP Parameters"
        anchor="sec.configurable-sdp-paramete">

            <t>It is possible to change elements in the SDP returned
            from createOffer before passing it to setLocalDescription.
            When an implementation receives modified SDP it MUST
            either:</t>

            <t>
                <list style="symbols">

                    <t>Accept the changes and adjust its behavior to
                    match the SDP.</t>

                    <t>Reject the changes and return an error via the
                    error callback.</t>

                </list>
            </t>

            <t>Changes MUST NOT be silently ignored.</t>

            <t>The following elements of the session description MUST
            NOT be changed between the createOffer and the
            setLocalDescription (or between the createAnswer and the
            setLocalDescription), since they reflect transport
            attributes that are solely under browser control, and the
            browser MUST NOT honor an attempt to change them:</t>

            <t>
                <list style="symbols">

                    <t>The number, type and port number of m=
                    lines.</t>

                    <t>The generated MID attributes (a=mid).</t>

                    <t>The generated ICE credentials (a=ice-ufrag and
                    a=ice-pwd).</t>

                    <t>The set of ICE candidates and their parameters
                    (a=candidate).</t>

                    <t>The DTLS fingerprint(s) (a=fingerprint).</t>

                    <t>The contents of bundle groups, bundle-only
                    parameters, or "a=rtcp-mux" parameters.</t>

                </list>
            </t>

            <t>The following modifications, if done by the browser to a
            description between createOffer/createAnswer and the
            setLocalDescription, MUST be honored by the browser:</t>

            <t>
                <list style="symbols">

                    <t>Remove or reorder codecs (m=)</t>
                </list>
            </t>

            <t>The following parameters may be controlled by options
            passed into createOffer/createAnswer. As an open issue,
            these changes may also be be performed by manipulating the
            SDP returned from createOffer/createAnswer, as indicated
            above, as long as the capabilities of the endpoint are not
            exceeded (e.g. asking for a resolution greater than what
            the endpoint can encode):</t>

            <t>
                <list style="symbols">

                    <t>[[OPEN ISSUE: This is a placeholder for other
                    modifications, which we may continue adding as use
                    cases appear.]]</t>
                </list>
            </t>

            <t>Implementations MAY choose to either honor or reject any
            elements not listed in the above two categories, but must
            do so explicitly as described at the beginning of this
            section. Note that future standards may add new SDP
            elements to the list of elements which must be accepted or
            rejected, but due to version skew, applications must be
            prepared for implementations to accept changes which must
            be rejected and vice versa.</t>

            <t>The application can also modify the SDP to reduce the
            capabilities in the offer it sends to the far side or the
            offer that it installs from the far side in any way the
            application sees fit, as long as it is 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
            actually in the offer.</t>

            <t>As always, the application is solely responsible for
            what it sends to the other party, and all incoming SDP will
            be processed by the browser to the extent of its
            capabilities. It is an error to assume that all SDP is
            well-formed; however, one should be able to assume that any
            implementation of this specification will be able to
            process, as a remote offer or answer, unmodified SDP coming
            from any other implementation of this specification.</t>
        </section>
        <section title="Examples" anchor="sec.examples">

            <t>Note that this example section shows several SDP
            fragments. To format in 72 columns, some of the lines in
            SDP have been split into multiple lines, where leading
            whitespace indicates that a line is a continuation of the
            previous line. In addition, some blank lines have been
            added to improve readability but are not valid in SDP.</t>

            <t>More examples of SDP for WebRTC call flows can be found
            in <xref target="I-D.nandakumar-rtcweb-sdp"></xref>.</t>

            <section title="Simple Example"
            anchor="sec.simple-examples">

                <t>This section shows a very simple example that sets
                up a minimal audio / video call between two browsers
                and does not use trickle ICE. The example in the
                following section provides a more realistic example of
                what would happen in a normal browser to browser
                connection.</t>

                <t>The flow shows Alice's browser initiating the
                session to Bob's browser. 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 policy of balanced.</t>

                <t>
                    <figure>
                        <artwork>
                            <![CDATA[
//                  set up local media state
AliceJS->AliceUA:   create new PeerConnection
AliceJS->AliceUA:   addTrack with two tracks: audio and video
AliceJS->AliceUA:   createOffer to get offer
AliceJS->AliceUA:   setLocalDescription with offer
AliceUA->AliceJS:   multiple onicecandidate events with candidates

//                  wait for ICE gathering to complete
AliceUA->AliceJS:   onicecandidate event with null candidate
AliceJS->AliceUA:   get |offer-A1| from pendingLocalDescription

//                  |offer-A1| is sent over signaling protocol to Bob
AliceJS->WebServer: signaling with |offer-A1|
WebServer->BobJS:   signaling with |offer-A1|

//                  |offer-A1| arrives at Bob
BobJS->BobUA:       create a PeerConnection
BobJS->BobUA:       setRemoteDescription with |offer-A1|
BobUA->BobJS:       onaddstream event with remoteStream

//                  Bob accepts call
BobJS->BobUA:       addTrack with local tracks
BobJS->BobUA:       createAnswer
BobJS->BobUA:       setLocalDescription with answer
BobUA->BobJS:       multiple onicecandidate events with candidates

//                  wait for ICE gathering to complete
BobUA->BobJS:       onicecandidate event with null candidate
BobJS->BobUA:       get |answer-A1| from currentLocalDescription

//                  |answer-A1| is sent over signaling protocol to Alice
BobJS->WebServer:   signaling with |answer-A1|
WebServer->AliceJS: signaling with |answer-A1|

//                  |answer-A1| arrives at Alice
AliceJS->AliceUA:   setRemoteDescription with |answer-A1|
AliceUA->AliceJS:   onaddstream event with remoteStream

//                  media flows
BobUA->AliceUA:     media sent from Bob to Alice
AliceUA->BobUA:     media sent from Alice to Bob
]]>
</artwork>
                    </figure>
                </t>

                <t>The SDP for |offer-A1| looks like:</t>

                <t>
                    <figure>
                        <artwork>
                            <![CDATA[
v=0
o=- 4962303333179871722 1 IN IP4 0.0.0.0
s=-
t=0 0
a=group:BUNDLE a1 v1
a=ice-options:trickle
m=audio 56500 UDP/TLS/RTP/SAVPF 96 0 8 97 98
c=IN IP4 192.0.2.1
a=mid:a1
a=rtcp:56501 IN IP4 192.0.2.1
a=msid:47017fee-b6c1-4162-929c-a25110252400
       f83006c5-a0ff-4e0a-9ed9-d3e6747be7d9
a=sendrecv
a=rtpmap:96 opus/48000/2
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:97 telephone-event/8000
a=rtpmap:98 telephone-event/48000
a=maxptime:120
a=ice-ufrag:ETEn1v9DoTMB9J4r
a=ice-pwd:OtSK0WpNtpUjkY4+86js7ZQl
a=fingerprint:sha-256
              19:E2:1C:3B:4B:9F:81:E6:B8:5C:F4:A5:A8:D8:73:04
             :BB:05:2F:70:9F:04:A9:0E:05:E9:26:33:E8:70:88:A2
a=setup:actpass
a=rtcp-mux
a=rtcp-rsize
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:2 urn:ietf:params:rtp-hdrext:sdes:mid
a=ssrc:1732846380 cname:EocUG1f0fcg/yvY7
a=candidate:3348148302 1 udp 2113937151 192.0.2.1 56500
            typ host
a=candidate:3348148302 2 udp 2113937151 192.0.2.1 56501
            typ host
a=end-of-candidates

m=video 56502 UDP/TLS/RTP/SAVPF 100 101
c=IN IP4 192.0.2.1
a=rtcp:56503 IN IP4 192.0.2.1
a=mid:v1
a=msid:61317484-2ed4-49d7-9eb7-1414322a7aae
       f30bdb4a-5db8-49b5-bcdc-e0c9a23172e0
a=sendrecv
a=rtpmap:100 VP8/90000
a=rtpmap:101 rtx/90000
a=fmtp:101 apt=100
a=ice-ufrag:BGKkWnG5GmiUpdIV
a=ice-pwd:mqyWsAjvtKwTGnvhPztQ9mIf
a=fingerprint:sha-256
              19:E2:1C:3B:4B:9F:81:E6:B8:5C:F4:A5:A8:D8:73:04
             :BB:05:2F:70:9F:04:A9:0E:05:E9:26:33:E8:70:88:A2
a=setup:actpass
a=rtcp-mux
a=rtcp-rsize
a=extmap:3 urn:ietf:params:rtp-hdrext:sdes:mid
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=ssrc:1366781083 cname:EocUG1f0fcg/yvY7
a=ssrc:1366781084 cname:EocUG1f0fcg/yvY7
a=ssrc-group:FID 1366781083 1366781084
a=candidate:3348148302 1 udp 2113937151 192.0.2.1 56502
            typ host
a=candidate:3348148302 2 udp 2113937151 192.0.2.1 56503
            typ host
a=end-of-candidates
          ]]>
</artwork>
                    </figure>
                </t>

                <t>The SDP for |answer-A1| looks like:</t>

                <t>
                    <figure>
                        <artwork>
                            <![CDATA[
v=0
o=- 6729291447651054566 1 IN IP4 0.0.0.0
s=-
t=0 0
a=group:BUNDLE a1 v1
m=audio 20000 UDP/TLS/RTP/SAVPF 96 0 8 97 98
c=IN IP4 192.0.2.2
a=mid:a1
a=rtcp:20000 IN IP4 192.0.2.2
a=msid:PI39StLS8W7ZbQl1sJsWUXkr3Zf12fJUvzQ1
       PI39StLS8W7ZbQl1sJsWUXkr3Zf12fJUvzQ1a0
a=sendrecv
a=rtpmap:96 opus/48000/2
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:97 telephone-event/8000
a=rtpmap:98 telephone-event/48000
a=maxptime:120
a=ice-ufrag:6sFvz2gdLkEwjZEr
a=ice-pwd:cOTZKZNVlO9RSGsEGM63JXT2
a=fingerprint:sha-256 6B:8B:F0:65:5F:78:E2:51:3B:AC:6F:F3:3F:46:1B:35
            :DC:B8:5F:64:1A:24:C2:43:F0:A1:58:D0:A1:2C:19:08
a=setup:active
a=rtcp-mux
a=rtcp-rsize
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=ssrc:3429951804 cname:Q/NWs1ao1HmN4Xa5
a=candidate:2299743422 1 udp 2113937151 192.0.2.2 20000
            typ host
a=end-of-candidates

m=video 20000 UDP/TLS/RTP/SAVPF 100 101
c=IN IP4 192.0.2.2
a=rtcp 20001 IN IP4 192.0.2.2
a=mid:v1
a=msid:PI39StLS8W7ZbQl1sJsWUXkr3Zf12fJUvzQ1
       PI39StLS8W7ZbQl1sJsWUXkr3Zf12fJUvzQ1v0
a=sendrecv
a=rtpmap:100 VP8/90000
a=rtpmap:101 rtx/90000
a=fmtp:101 apt=100
a=fingerprint:sha-256 6B:8B:F0:65:5F:78:E2:51:3B:AC:6F:F3:3F:46:1B:35
                     :DC:B8:5F:64:1A:24:C2:43:F0:A1:58:D0:A1:2C:19:08
a=setup:active
a=rtcp-mux
a=rtcp-rsize
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=ssrc:3229706345 cname:Q/NWs1ao1HmN4Xa5
a=ssrc:3229706346 cname:Q/NWs1ao1HmN4Xa5
a=ssrc-group:FID 3229706345 3229706346
          ]]>
</artwork>
                    </figure>
                </t>
            </section>
            <section title="Normal Examples"
            anchor="sec.normal-examples">

                <t>This section shows a typical example of a session
                between two browsers setting up an audio channel and a
                data channel. Trickle ICE is used in full trickle mode
                with a bundle policy of max-bundle, an RTCP mux policy
                of require, and a single TURN server. Later, two video
                flows, one for the presenter and one for screen
                sharing, are added to the session. This example shows
                Alice's browser initiating the session to Bob's
                browser. The messages from Alice's JS to Bob's JS are
                assumed to flow over some signaling protocol via a web
                server.</t>

                <t>
                    <figure>
                        <artwork>
                            <![CDATA[
//                  set up local media state
AliceJS->AliceUA:   create new PeerConnection
AliceJS->AliceUA:   addTrack with an audio track
AliceJS->AliceUA:   createDataChannel to get data channel
AliceJS->AliceUA:   createOffer to get |offer-B1|
AliceJS->AliceUA:   setLocalDescription with |offer-B1|

//                  |offer-B1| is sent over signaling protocol to Bob
AliceJS->WebServer: signaling with |offer-B1|
WebServer->BobJS:   signaling with |offer-B1|

//                  |offer-B1| arrives at Bob
BobJS->BobUA:       create a PeerConnection
BobJS->BobUA:       setRemoteDescription with |offer-B1|
BobUA->BobJS:       onaddstream with audio track from Alice

//                  candidates are sent to Bob
AliceUA->AliceJS:   onicecandidate event with |candidate-B1| (host)
AliceJS->WebServer: signaling with |candidate-B1|
AliceUA->AliceJS:   onicecandidate event with |candidate-B2| (srflx)
AliceJS->WebServer: signaling with |candidate-B2|

WebServer->BobJS:   signaling with |candidate-B1|
BobJS->BobUA:       addIceCandidate with |candidate-B1|
WebServer->BobJS:   signaling with |candidate-B2|
BobJS->BobUA:       addIceCandidate with |candidate-B2|

//                  Bob accepts call
BobJS->BobUA:       addTrack with local audio
BobJS->BobUA:       createDataChannel to get data channel
BobJS->BobUA:       createAnswer to get |answer-B1|
BobJS->BobUA:       setLocalDescription with |answer-B1|

//                  |answer-B1| is sent to Alice
BobJS->WebServer:   signaling with |answer-B1|
WebServer->AliceJS: signaling with |answer-B1|
AliceJS->AliceUA:   setRemoteDescription with |answer-B1|
AliceUA->AliceJS:   onaddstream event with audio track from Bob

//                  candidates are sent to Alice
BobUA->BobJS:       onicecandidate event with |candidate-B3| (host)
BobJS->WebServer:   signaling with |candidate-B3|
BobUA->BobJS:       onicecandidate event with |candidate-B4| (srflx)
BobJS->WebServer:   signaling with |candidate-B4|

WebServer->AliceJS: signaling with |candidate-B3|
AliceJS->AliceUA:   addIceCandidate with |candidate-B3|
WebServer->AliceJS: signaling with |candidate-B4|
AliceJS->AliceUA:   addIceCandidate with |candidate-B4|

//                  data channel opens
BobUA->BobJS:       ondatachannel event
AliceUA->AliceJS:   ondatachannel event
BobUA->BobJS:       onopen
AliceUA->AliceJS:   onopen

//                  media is flowing between browsers
BobUA->AliceUA:     audio+data sent from Bob to Alice
AliceUA->BobUA:     audio+data sent from Alice to Bob

//                  some time later Bob adds two video streams
//                  note, no candidates exchanged, because of bundle
BobJS->BobUA:       addTrack with first video stream
BobJS->BobUA:       addTrack with second video stream
BobJS->BobUA:       createOffer to get |offer-B2|
BobJS->BobUA:       setLocalDescription with |offer-B2|

//                  |offer-B2| is sent to Alice
BobJS->WebServer:   signaling with |offer-B2|
WebServer->AliceJS: signaling with |offer-B2|
AliceJS->AliceUA:   setRemoteDescription with |offer-B2|
AliceUA->AliceJS:   onaddstream event with first video stream
AliceUA->AliceJS:   onaddstream event with second video stream
AliceJS->AliceUA:   createAnswer to get |answer-B2|
AliceJS->AliceUA:   setLocalDescription with |answer-B2|

//                  |answer-B2| is sent over signaling protocol to Bob
AliceJS->WebServer: signaling with |answer-B2|
WebServer->BobJS:   signaling with |answer-B2|
BobJS->BobUA:       setRemoteDescription with |answer-B2|

//                  media is flowing between browsers
BobUA->AliceUA:     audio+video+data sent from Bob to Alice
AliceUA->BobUA:     audio+video+data sent from Alice to Bob
]]>
</artwork>
                    </figure>
                </t>

                <t>The SDP for |offer-B1| looks like:</t>

                <t>
                    <figure>
                        <artwork>
                            <![CDATA[
v=0
o=- 4962303333179871723 1 IN IP4 0.0.0.0
s=-
t=0 0
a=group:BUNDLE a1 d1
a=ice-options:trickle
m=audio 9 UDP/TLS/RTP/SAVPF 96 0 8 97 98
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=mid:a1
a=msid:57017fee-b6c1-4162-929c-a25110252400
       e83006c5-a0ff-4e0a-9ed9-d3e6747be7d9
a=sendrecv
a=rtpmap:96 opus/48000/2
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:97 telephone-event/8000
a=rtpmap:98 telephone-event/48000
a=maxptime:120
a=ice-ufrag:ATEn1v9DoTMB9J4r
a=ice-pwd:AtSK0WpNtpUjkY4+86js7ZQl
a=fingerprint:sha-256
              19:E2:1C:3B:4B:9F:81:E6:B8:5C:F4:A5:A8:D8:73:04
             :BB:05:2F:70:9F:04:A9:0E:05:E9:26:33:E8:70:88:A2
a=setup:actpass
a=rtcp-mux
a=rtcp-rsize
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:2 urn:ietf:params:rtp-hdrext:sdes:mid
a=ssrc:1732846380 cname:FocUG1f0fcg/yvY7

m=application 0 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 0.0.0.0
a=bundle-only
a=mid:d1
a=fmtp:webrtc-datachannel max-message-size=65536
a=sctp-port 5000
a=fingerprint:sha-256 19:E2:1C:3B:4B:9F:81:E6:B8:5C:F4:A5:A8:D8:73:04
                     :BB:05:2F:70:9F:04:A9:0E:05:E9:26:33:E8:70:88:A2
a=setup:actpass
         ]]>
</artwork>
                    </figure>
                </t>

                <t>The SDP for |candidate-B1| looks like:</t>

                <t>
                    <figure>
                        <artwork>
                            <![CDATA[
candidate:109270923 1 udp 2122194687 192.168.1.2 51556 typ host
         ]]>
</artwork>
                    </figure>
                </t>

                <t>The SDP for |candidate-B2| looks like:</t>

                <t>
                    <figure>
                        <artwork>
                            <![CDATA[
candidate:4036177503 1 udp 1685987071 11.22.33.44 52546 typ srflx
          raddr 192.168.1.2 rport 51556
         ]]>
</artwork>
                    </figure>
                </t>

                <t>The SDP for |answer-B1| looks like:</t>

                <t>
                    <figure>
                        <artwork>
                            <![CDATA[
v=0
o=- 7729291447651054566 1 IN IP4 0.0.0.0
s=-
t=0 0
a=group:BUNDLE a1 d1
a=ice-options:trickle
m=audio 9 UDP/TLS/RTP/SAVPF 96 0 8 97 98
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=mid:a1
a=msid:QI39StLS8W7ZbQl1sJsWUXkr3Zf12fJUvzQ1
       QI39StLS8W7ZbQl1sJsWUXkr3Zf12fJUvzQ1a0
a=sendrecv
a=rtpmap:96 opus/48000/2
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:97 telephone-event/8000
a=rtpmap:98 telephone-event/48000
a=maxptime:120
a=ice-ufrag:7sFvz2gdLkEwjZEr
a=ice-pwd:dOTZKZNVlO9RSGsEGM63JXT2
a=fingerprint:sha-256 6B:8B:F0:65:5F:78:E2:51:3B:AC:6F:F3:3F:46:1B:35
                     :DC:B8:5F:64:1A:24:C2:43:F0:A1:58:D0:A1:2C:19:08
a=setup:active
a=rtcp-mux
a=rtcp-rsize
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:2 urn:ietf:params:rtp-hdrext:sdes:mid
a=ssrc:4429951804 cname:Q/NWs1ao1HmN4Xa5

m=application 9 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 0.0.0.0
a=mid:d1
a=fmtp:webrtc-datachannel max-message-size=65536
a=sctp-port 5000
a=fingerprint:sha-256 6B:8B:F0:65:5F:78:E2:51:3B:AC:6F:F3:3F:46:1B:35
                     :DC:B8:5F:64:1A:24:C2:43:F0:A1:58:D0:A1:2C:19:08
a=setup:active
         ]]>
</artwork>
                    </figure>
                </t>

                <t>The SDP for |candidate-B3| looks like:</t>

                <t>
                    <figure>
                        <artwork>
                            <![CDATA[
candidate:109270924 1 udp 2122194687 192.168.2.3 61665 typ host
     ]]>
</artwork>
                    </figure>
                </t>

                <t>The SDP for |candidate-B4| looks like:</t>

                <t>
                    <figure>
                        <artwork>
                            <![CDATA[
candidate:4036177504 1 udp 1685987071 55.66.77.88 64532 typ srflx
          raddr 192.168.2.3 rport 61665
     ]]>
</artwork>
                    </figure>
                </t>

                <t>The SDP for |offer-B2| looks like: (note the
                increment of the version number in the o= line, and the
                c= and a=rtcp lines, which indicate the local candidate
                that was selected)</t>

                <t>
                    <figure>
                        <artwork>
                            <![CDATA[
v=0
o=- 7729291447651054566 2 IN IP4 0.0.0.0
s=-
t=0 0
a=group:BUNDLE a1 d1 v1 v2
a=ice-options:trickle
m=audio 64532 UDP/TLS/RTP/SAVPF 96 0 8 97 98
c=IN IP4 55.66.77.88
a=rtcp:64532 IN IP4 55.66.77.88
a=mid:a1
a=msid:QI39StLS8W7ZbQl1sJsWUXkr3Zf12fJUvzQ1
       QI39StLS8W7ZbQl1sJsWUXkr3Zf12fJUvzQ1a0
a=sendrecv
a=rtpmap:96 opus/48000/2
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:97 telephone-event/8000
a=rtpmap:98 telephone-event/48000
a=maxptime:120
a=ice-ufrag:7sFvz2gdLkEwjZEr
a=ice-pwd:dOTZKZNVlO9RSGsEGM63JXT2
a=fingerprint:sha-256 6B:8B:F0:65:5F:78:E2:51:3B:AC:6F:F3:3F:46:1B:35
                     :DC:B8:5F:64:1A:24:C2:43:F0:A1:58:D0:A1:2C:19:08
a=setup:actpass
a=rtcp-mux
a=rtcp-rsize
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:2 urn:ietf:params:rtp-hdrext:sdes:mid
a=ssrc:4429951804 cname:Q/NWs1ao1HmN4Xa5
a=candidate:109270924 1 udp 2122194687 192.168.2.3 61665 typ host
a=candidate:4036177504 1 udp 1685987071 55.66.77.88 64532 typ srflx
            raddr 192.168.2.3 rport 61665
a=candidate:3671762467 1 udp 41819903 66.77.88.99 50416 typ relay
            raddr 55.66.77.88 rport 64532
a=end-of-candidates

m=application 64532 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 55.66.77.88
a=mid:d1
a=fmtp:webrtc-datachannel max-message-size=65536
a=sctp-port 5000
a=ice-ufrag:7sFvz2gdLkEwjZEr
a=ice-pwd:dOTZKZNVlO9RSGsEGM63JXT2
a=fingerprint:sha-256 6B:8B:F0:65:5F:78:E2:51:3B:AC:6F:F3:3F:46:1B:35
                     :DC:B8:5F:64:1A:24:C2:43:F0:A1:58:D0:A1:2C:19:08
a=setup:actpass
a=candidate:109270924 1 udp 2122194687 192.168.2.3 61665 typ host
a=candidate:4036177504 1 udp 1685987071 55.66.77.88 64532 typ srflx
            raddr 192.168.2.3 rport 61665
a=candidate:3671762467 1 udp 41819903 66.77.88.99 50416 typ relay
            raddr 55.66.77.88 rport 64532
a=end-of-candidates

m=video 0 UDP/TLS/RTP/SAVPF 100 101
c=IN IP4 55.66.77.88
a=bundle-only
a=rtcp:64532 IN IP4 55.66.77.88
a=mid:v1
a=msid:61317484-2ed4-49d7-9eb7-1414322a7aae
       f30bdb4a-5db8-49b5-bcdc-e0c9a23172e0
a=sendrecv
a=rtpmap:100 VP8/90000
a=rtpmap:101 rtx/90000
a=fmtp:101 apt=100
a=fingerprint:sha-256
              19:E2:1C:3B:4B:9F:81:E6:B8:5C:F4:A5:A8:D8:73:04
             :BB:05:2F:70:9F:04:A9:0E:05:E9:26:33:E8:70:88:A2
a=setup:actpass
a=rtcp-mux
a=rtcp-rsize
a=extmap:2 urn:ietf:params:rtp-hdrext:sdes:mid
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=ssrc:1366781083 cname:Q/NWs1ao1HmN4Xa5
a=ssrc:1366781084 cname:Q/NWs1ao1HmN4Xa5
a=ssrc-group:FID 1366781083 1366781084

m=video 0 UDP/TLS/RTP/SAVPF 100 101
c=IN IP4 55.66.77.88
a=bundle-only
a=rtcp:64532 IN IP4 55.66.77.88
a=mid:v1
a=msid:71317484-2ed4-49d7-9eb7-1414322a7aae
       f30bdb4a-5db8-49b5-bcdc-e0c9a23172e0
a=sendrecv
a=rtpmap:100 VP8/90000
a=rtpmap:101 rtx/90000
a=fmtp:101 apt=100
a=fingerprint:sha-256
              19:E2:1C:3B:4B:9F:81:E6:B8:5C:F4:A5:A8:D8:73:04
             :BB:05:2F:70:9F:04:A9:0E:05:E9:26:33:E8:70:88:A2
a=setup:actpass
a=rtcp-mux
a=rtcp-rsize
a=extmap:2 urn:ietf:params:rtp-hdrext:sdes:mid
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=ssrc:2366781083 cname:Q/NWs1ao1HmN4Xa5
a=ssrc:2366781084 cname:Q/NWs1ao1HmN4Xa5
a=ssrc-group:FID 2366781083 2366781084
         ]]>
</artwork>
                    </figure>
                </t>

                <t>The SDP for |answer-B2| looks like: (note the use of
                setup:passive to maintain the existing DTLS roles, and
                the use of a=recvonly to indicate that the video
                streams are one-way)</t>

                <t>
                    <figure>
                        <artwork>
                            <![CDATA[
v=0
o=- 4962303333179871723 2 IN IP4 0.0.0.0
s=-
t=0 0
a=group:BUNDLE a1 d1 v1 v2
a=ice-options:trickle
m=audio 52546 UDP/TLS/RTP/SAVPF 96 0 8 97 98
c=IN IP4 11.22.33.44
a=rtcp:52546 IN IP4 11.22.33.44
a=mid:a1
a=msid:57017fee-b6c1-4162-929c-a25110252400
       e83006c5-a0ff-4e0a-9ed9-d3e6747be7d9
a=sendrecv
a=rtpmap:96 opus/48000/2
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:97 telephone-event/8000
a=rtpmap:98 telephone-event/48000
a=maxptime:120
a=ice-ufrag:ATEn1v9DoTMB9J4r
a=ice-pwd:AtSK0WpNtpUjkY4+86js7ZQl
a=fingerprint:sha-256
              19:E2:1C:3B:4B:9F:81:E6:B8:5C:F4:A5:A8:D8:73:04
             :BB:05:2F:70:9F:04:A9:0E:05:E9:26:33:E8:70:88:A2
a=setup:passive
a=rtcp-mux
a=rtcp-rsize
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:2 urn:ietf:params:rtp-hdrext:sdes:mid
a=ssrc:1732846380 cname:FocUG1f0fcg/yvY7
a=candidate:109270923 1 udp 2122194687 192.168.1.2 51556 typ host
a=candidate:4036177503 1 udp 1685987071 11.22.33.44 52546 typ srflx
            raddr 192.168.1.2 rport 51556
a=candidate:3671762466 1 udp 41819903 22.33.44.55 61405 typ relay
            raddr 11.22.33.44 rport 52546
a=end-of-candidates

m=application 52546 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 11.22.33.44
a=mid:d1
a=fmtp:webrtc-datachannel max-message-size=65536
a=sctp-port 5000
a=fingerprint:sha-256 19:E2:1C:3B:4B:9F:81:E6:B8:5C:F4:A5:A8:D8:73:04
                     :BB:05:2F:70:9F:04:A9:0E:05:E9:26:33:E8:70:88:A2
a=setup:passive

m=video 52546 UDP/TLS/RTP/SAVPF 100 101
c=IN IP4 11.22.33.44
a=rtcp:52546 IN IP4 11.22.33.44
a=mid:v1
a=recvonly
a=rtpmap:100 VP8/90000
a=rtpmap:101 rtx/90000
a=fmtp:101 apt=100
a=fingerprint:sha-256
              19:E2:1C:3B:4B:9F:81:E6:B8:5C:F4:A5:A8:D8:73:04
             :BB:05:2F:70:9F:04:A9:0E:05:E9:26:33:E8:70:88:A2
a=setup:passive
a=rtcp-mux
a=rtcp-rsize
a=extmap:2 urn:ietf:params:rtp-hdrext:sdes:mid
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli

m=video 52546 UDP/TLS/RTP/SAVPF 100 101
c=IN IP4 11.22.33.44
a=rtcp:52546 IN IP4 11.22.33.44
a=mid:v2
a=recvonly
a=rtpmap:100 VP8/90000
a=rtpmap:101 rtx/90000
a=fmtp:101 apt=100
a=fingerprint:sha-256
              19:E2:1C:3B:4B:9F:81:E6:B8:5C:F4:A5:A8:D8:73:04
             :BB:05:2F:70:9F:04:A9:0E:05:E9:26:33:E8:70:88:A2
a=setup:passive
a=rtcp-mux
a=rtcp-rsize
a=extmap:2 urn:ietf:params:rtp-hdrext:sdes:mid
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
         ]]>
</artwork>
                    </figure>
                </t>
            </section>
        </section>
        <section title="Security Considerations"
        anchor="sec.security-considerations">

            <t>The IETF has published separate documents
            <xref target="I-D.ietf-rtcweb-security-arch" />
            <xref target="I-D.ietf-rtcweb-security" /> describing the
            security architecture for WebRTC as a whole. The remainder
            of this section describes security considerations for this
            document.</t>

            <t>While formally the JSEP interface is an API, it is better
            to think of it is an Internet protocol, with the JS being
            untrustworthy from the perspective of the browser.  Thus,
            the threat model of <xref target="RFC3552" /> applies. In
            particular, JS can call the API in any order and with any
            inputs, including malicious ones. This is particularly
            relevant when we consider the SDP which is passed to
            setLocalDescription().  While correct API usage requires
            that the application pass in SDP which was derived from
            createOffer() or createAnswer() (perhaps suitably modified
            as described in <xref target="sec.configurable-sdp-paramete"
            />, there is no guarantee that applications do so. The
            browser MUST be prepared for the JS to pass in bogus data
            instead.</t>

            <t>Conversely, the application programmer MUST recognize
            that the JS does not have complete control of browser
            behavior. One case that bears particular mention is that
            editing ICE candidates out of the SDP or suppressing
            trickled candidates does not have the expected behavior:
            implementations will still perform checks from those
            candidates even if they are not sent to the other side.
            Thus, for instance, it is not possible to prevent the remote
            peer from learning your public IP address by removing server
            reflexive candidates. Applications which wish to conceal
            their public IP address should instead configure the ICE
            agent to use only relay candidates.</t>
        </section>
        <section title="IANA Considerations"
        anchor="sec.iana-considerations">

            <t>This document requires no actions from IANA.</t>
        </section>
        <section title="Acknowledgements"
        anchor="sec.acknowledgements">

            <t>Significant text incorporated in the draft as well and
            review was provided by Peter Thatcher, Taylor Brandstetter,
            Harald Alvestrand and Suhas Nandakumar.
            <!-- ACK 1 -->Dan Burnett, Neil Stratford, Anant Narayanan,
            Andrew Hutton, Richard Ejzak,
            <!-- ACK 2 -->
            <!-- ACK 3 -->
            <!-- ACK 4 -->Adam Bergkvist and Matthew Kaufman all
            provided valuable feedback on this proposal.
            <!-- ACK 5 -->
            <!-- ACK 5a -->
            <!-- ACK 5b -->
            <!-- ACK 5c -->
            <!-- ACK 6 -->
            <!-- ACK 7 --></t>
        </section>
    </middle>
    <back>
        <references title="Normative References">
            <!-- NORM 1 -->
            <reference anchor="RFC5245">
                <front>
                    <title>Interactive Connectivity Establishment
                    (ICE): A Protocol for Network Address Translator
                    (NAT) Traversal for Offer/Answer Protocols</title>
                    <author fullname="J. Rosenberg" initials="J."
                    surname="Rosenberg">
                        <organization></organization>
                    </author>
                    <date month="April" year="2010" />
                </front>
                <seriesInfo name="RFC" value="5245" />
                <format octets="285120"
                target="http://www.rfc-editor.org/rfc/rfc5245.txt"
                type="TXT" />
            </reference>
            <reference anchor="RFC5888">
                <front>
                    <title>The Session Description Protocol (SDP)
                    Grouping Framework</title>
                    <author fullname="G. Camarillo" initials="G."
                    surname="Camarillo">
                        <organization></organization>
                    </author>
                    <author fullname="H. Schulzrinne" initials="H."
                    surname="Schulzrinne">
                        <organization></organization>
                    </author>
                    <date month="June" year="2010" />
                </front>
                <seriesInfo name="RFC" value="5888" />
                <format octets="43924"
                target="http://www.rfc-editor.org/rfc/rfc5888.txt"
                type="TXT" />
            </reference>
            <reference anchor="RFC5761">
                <front>
                    <title>Multiplexing RTP Data and Control Packets on
                    a Single Port</title>
                    <author fullname="C. Perkins" initials="C."
                    surname="Perkins">
                        <organization></organization>
                    </author>
                    <author fullname="M. Westerlund" initials="M."
                    surname="Westerlund">
                        <organization></organization>
                    </author>
                    <date month="April" year="2010" />
                </front>
                <seriesInfo name="RFC" value="5761" />
                <format octets="31778"
                target="http://www.rfc-editor.org/rfc/rfc5761.txt"
                type="TXT" />
            </reference>
            <reference anchor="RFC4585">
                <front>
                    <title>Extended RTP Profile for Real-time Transport
                    Control Protocol (RTCP)-Based Feedback
                    (RTP/AVPF)</title>
                    <author fullname="J. Ott" initials="J."
                    surname="Ott">
                        <organization></organization>
                    </author>
                    <author fullname="S. Wenger" initials="S."
                    surname="Wenger">
                        <organization></organization>
                    </author>
                    <author fullname="N. Sato" initials="N."
                    surname="Sato">
                        <organization></organization>
                    </author>
                    <author fullname="C. Burmeister" initials="C."
                    surname="Burmeister">
                        <organization></organization>
                    </author>
                    <author fullname="J. Rey" initials="J."
                    surname="Rey">
                        <organization></organization>
                    </author>
                    <date month="July" year="2006" />
                </front>
                <seriesInfo name="RFC" value="4585" />
                <format octets="117762"
                target="http://www.rfc-editor.org/rfc/rfc4585.txt"
                type="TXT" />
            </reference>
            <reference anchor="RFC3261">
                <front>
                    <title>SIP: Session Initiation Protocol</title>
                    <author fullname="J. Rosenberg" initials="J."
                    surname="Rosenberg">
                        <organization></organization>
                    </author>
                    <author fullname="H. Schulzrinne" initials="H."
                    surname="Schulzrinne">
                        <organization></organization>
                    </author>
                    <author fullname="G. Camarillo" initials="G."
                    surname="Camarillo">
                        <organization></organization>
                    </author>
                    <author fullname="A. Johnston" initials="A."
                    surname="Johnston">
                        <organization></organization>
                    </author>
                    <author fullname="J. Peterson" initials="J."
                    surname="Peterson">
                        <organization></organization>
                    </author>
                    <author fullname="R. Sparks" initials="R."
                    surname="Sparks">
                        <organization></organization>
                    </author>
                    <author fullname="M. Handley" initials="M."
                    surname="Handley">
                        <organization></organization>
                    </author>
                    <author fullname="E. Schooler" initials="E."
                    surname="Schooler">
                        <organization></organization>
                    </author>
                    <date month="June" year="2002" />
                </front>
                <seriesInfo name="RFC" value="3261" />
                <format octets="647976"
                target="http://www.rfc-editor.org/rfc/rfc3261.txt"
                type="TXT" />
            </reference>
            <!-- NORM 2 -->
            <reference anchor='I-D.ietf-rtcweb-video'>
                <front>
                    <title>WebRTC Video Processing and Codec
                    Requirements</title>
                    <author initials='A' surname='Roach'
                    fullname='Adam Roach'>
                        <organization />
                    </author>
                    <date month='July' day='1' year='2014' />
                </front>
                <seriesInfo name='Internet-Draft'
                value='draft-ietf-rtcweb-video-00' />
                <format type='TXT'
                target='http://www.ietf.org/internet-drafts/draft-ietf-rtcweb-video-00.txt' />
            </reference>
            <reference anchor="RFC3890"
            target="http://www.rfc-editor.org/info/rfc3890">
                <front>
                    <title>A Transport Independent Bandwidth Modifier
                    for the Session Description Protocol (SDP)</title>
                    <author initials="M." surname="Westerlund"
                    fullname="M. Westerlund">
                        <organization />
                    </author>
                    <date year="2004" month="September" />
                </front>
                <seriesInfo name="RFC" value="3890" />
                <seriesInfo name="DOI" value="10.17487/RFC3890" />
            </reference>
            <!-- NORM 2a -->
            <reference anchor="I-D.ietf-rtcweb-audio">
                <front>
                    <title>WebRTC Audio Codec and Processing
                    Requirements</title>
                    <author fullname="Jean-Marc Valin" initials="J"
                    surname="Valin">
                        <organization></organization>
                    </author>
                    <author fullname="Cary Bran" initials="C"
                    surname="Bran">
                        <organization></organization>
                    </author>
                    <date day="2" month="August" year="2013" />
                </front>
                <seriesInfo name="Internet-Draft"
                value="draft-ietf-rtcweb-audio-02" />
                <format target="http://www.ietf.org/internet-drafts/draft-ietf-rtcweb-audio-02.txt"
                type="TXT" />
            </reference>
            <!-- NORM 3 -->
            <reference anchor="I-D.ietf-mmusic-sctp-sdp">
                <front>
                    <title>Stream Control Transmission Protocol
                    (SCTP)-Based Media Transport in the Session
                    Description Protocol (SDP)</title>
                    <author fullname="Salvatore Loreto" initials="S"
                    surname="Loreto">
                        <organization></organization>
                    </author>
                    <author fullname="Gonzalo Camarillo" initials="G"
                    surname="Camarillo">
                        <organization></organization>
                    </author>
                    <date day="30" month="June" year="2013" />
                </front>
                <seriesInfo name="Internet-Draft"
                value="draft-ietf-mmusic-sctp-sdp-04" />
                <format target="http://www.ietf.org/internet-drafts/draft-ietf-mmusic-sctp-sdp-04.txt"
                type="TXT" />
            </reference>
            <!-- NORM 4 -->
            <reference anchor="RFC4572">
                <front>
                    <title>Connection-Oriented Media Transport over the
                    Transport Layer Security (TLS) Protocol in the
                    Session Description Protocol (SDP)</title>
                    <author fullname="J. Lennox" initials="J."
                    surname="Lennox">
                        <organization></organization>
                    </author>
                    <date month="July" year="2006" />
                </front>
                <seriesInfo name="RFC" value="4572" />
                <format octets="38658"
                target="http://www.rfc-editor.org/rfc/rfc4572.txt"
                type="TXT" />
            </reference>
            <!-- NORM 5 -->
            <reference anchor="RFC4145">
                <front>
                    <title>TCP-Based Media Transport in the Session
                    Description Protocol (SDP)</title>
                    <author fullname="D. Yon" initials="D."
                    surname="Yon">
                        <organization></organization>
                    </author>
                    <author fullname="G. Camarillo" initials="G."
                    surname="Camarillo">
                        <organization></organization>
                    </author>
                    <date month="September" year="2005" />
                </front>
                <seriesInfo name="RFC" value="4145" />
                <format octets="30225"
                target="http://www.rfc-editor.org/rfc/rfc4145.txt"
                type="TXT" />
            </reference>
            <!-- NORM 6 -->
            <reference anchor="I-D.nandakumar-mmusic-proto-iana-registration">

                <front>
                    <title abbrev="SDP Proto Registrations">IANA
                    registration of SDP 'proto' attribute for
                    transporting RTP Media over TCP under various RTP
                    profiles.</title>
                    <author fullname="Suhas Nandakumar" initials="S."
                    surname="Nandakumar">
                        <organization>Cisco Systems Inc</organization>
                        <address>
                            <postal>
                                <street>707 Tasman Drive</street>
                                <city>San Jose</city>
                                <region>CA</region>
                                <code>95134</code>
                                <country>USA</country>
                            </postal>
                            <email>snandaku@cisco.com</email>
                        </address>
                    </author>
                    <date day="18" month="September" year="2014" />
                    <area>RAI</area>
                    <workgroup>MMUSIC</workgroup>
                </front>
            </reference>
            <!-- NORM 7 -->
            <reference anchor='I-D.ietf-mmusic-sdp-mux-attributes'>
                <front>
                    <title>A Framework for SDP Attributes when
                    Multiplexing</title>
                    <author initials='S' surname='Nandakumar'
                    fullname='Suhas Nandakumar'>
                        <organization />
                    </author>
                    <date month='February' day='14' year='2014' />
                </front>
                <seriesInfo name='Internet-Draft'
                value='draft-ietf-mmusic-sdp-mux-attributes-01' />
                <format type='TXT'
                target='http://www.ietf.org/internet-drafts/draft-ietf-mmusic-sdp-mux-attributes-01.txt' />
            </reference>
            <!-- NORM 8 -->
            <!-- NORM 9 -->
            <!-- NORM 10 -->
            <reference anchor="RFC5285">
                <front>
                    <title>A General Mechanism for RTP Header
                    Extensions</title>
                    <author fullname="D. Singer" initials="D."
                    surname="Singer">
                        <organization></organization>
                    </author>
                    <author fullname="H. Desineni" initials="H."
                    surname="Desineni">
                        <organization></organization>
                    </author>
                    <date month="July" year="2008" />
                </front>
                <seriesInfo name="RFC" value="5285" />
                <format octets="36844"
                target="http://www.rfc-editor.org/rfc/rfc5285.txt"
                type="TXT" />
            </reference>
            <!-- NORM 11 -->
            <reference anchor="RFC6904">
                <front>
                    <title>Encryption of Header Extensions in the
                    Secure Real-time Transport Protocol (SRTP)</title>
                    <author fullname="J. Lennox" initials="J."
                    surname="Lennox">
                        <organization></organization>
                    </author>
                    <date month="April" year="2013" />
                </front>
                <seriesInfo name="RFC" value="6904" />
                <format octets="33486"
                target="http://www.rfc-editor.org/rfc/rfc6904.txt"
                type="TXT" />
            </reference>
            <!-- NORM 12 -->
            <reference anchor="I-D.ietf-rtcweb-rtp-usage">
                <front>
                    <title>Web Real-Time Communication (WebRTC): Media
                    Transport and Use of RTP</title>
                    <author fullname="Colin Perkins" initials="C"
                    surname="Perkins">
                        <organization></organization>
                    </author>
                    <author fullname="Magnus Westerlund" initials="M"
                    surname="Westerlund">
                        <organization></organization>
                    </author>
                    <author fullname="Joerg Ott" initials="J"
                    surname="Ott">
                        <organization></organization>
                    </author>
                    <date day="5" month="September" year="2013" />
                </front>
                <seriesInfo name="Internet-Draft"
                value="draft-ietf-rtcweb-rtp-usage-09" />
                <format target="http://www.ietf.org/internet-drafts/draft-ietf-rtcweb-rtp-usage-09.txt"
                type="TXT" />
            </reference>
            <!-- NORM 13 -->
            <reference anchor="I-D.ietf-mmusic-sdp-bundle-negotiation">
                <front>
                    <title>Multiplexing Negotiation Using Session
                    Description Protocol (SDP) Port Numbers</title>
                    <author fullname="Christer Holmberg" initials="C"
                    surname="Holmberg">
                        <organization></organization>
                    </author>
                    <author fullname="Harald Alvestrand" initials="H"
                    surname="Alvestrand">
                        <organization></organization>
                    </author>
                    <author fullname="Cullen Jennings" initials="C"
                    surname="Jennings">
                        <organization></organization>
                    </author>
                    <date day="14" month="June" year="2013" />
                </front>
                <seriesInfo name="Internet-Draft"
                value="draft-ietf-mmusic-sdp-bundle-negotiation-04" />
                <format target="http://www.ietf.org/internet-drafts/draft-ietf-mmusic-sdp-bundle-negotiation-04.txt"
                type="TXT" />
            </reference>
            <!-- NORM 14 -->
            <reference anchor="I-D.ietf-mmusic-msid">
                <front>
                    <title>Cross Session Stream Identification in the
                    Session Description Protocol</title>
                    <author fullname="Harald Alvestrand" initials="H"
                    surname="Alvestrand">
                        <organization></organization>
                    </author>
                    <date day="13" month="August" year="2013" />
                </front>
                <seriesInfo name="Internet-Draft"
                value="draft-ietf-mmusic-msid-01" />
                <format target="http://www.ietf.org/internet-drafts/draft-ietf-mmusic-msid-01.txt"
                type="TXT" />
            </reference>
            <!-- NORM 15 -->
            <!-- NORM 16 -->
            <reference anchor='I-D.ietf-rtcweb-security'>
                <front>
                    <title>Security Considerations for WebRTC</title>
                    <author initials='E' surname='Rescorla'
                    fullname='Eric Rescorla'>
                        <organization />
                    </author>
                    <date month='January' day='21' year='2014' />
                </front>
                <seriesInfo name='Internet-Draft'
                value='draft-ietf-rtcweb-security-06' />
                <format type='TXT'
                target='http://www.ietf.org/internet-drafts/draft-ietf-rtcweb-security-06.txt' />
            </reference>
            <!-- NORM 17 -->
            <reference anchor='I-D.ietf-rtcweb-security-arch'>
                <front>
                    <title>WebRTC Security Architecture</title>
                    <author initials='E' surname='Rescorla'
                    fullname='Eric Rescorla'>
                        <organization />
                    </author>
                    <date month='February' day='14' year='2014' />
                </front>
                <seriesInfo name='Internet-Draft'
                value='draft-ietf-rtcweb-security-arch-09' />
                <format type='TXT'
                target='http://www.ietf.org/internet-drafts/draft-ietf-rtcweb-security-arch-09.txt' />
            </reference>
            <!-- NORM 18 -->
            <reference anchor='RFC3552'>
                <front>
                    <title>Guidelines for Writing RFC Text on Security
                    Considerations</title>
                    <author initials='E.' surname='Rescorla'
                    fullname='E. Rescorla'>
                        <organization />
                    </author>
                    <author initials='B.' surname='Korver'
                    fullname='B. Korver'>
                        <organization />
                    </author>
                    <date year='2003' month='July' />
                </front>
                <seriesInfo name='BCP' value='72' />
                <seriesInfo name='RFC' value='3552' />
                <format type='TXT' octets='110393'
                target='http://www.rfc-editor.org/rfc/rfc3552.txt' />
            </reference>
            <!-- NORM 19 -->
            <reference anchor="RFC2119">
                <front>
                    <title abbrev="RFC Key Words">Key words for use in
                    RFCs to Indicate Requirement Levels</title>
                    <author fullname="Scott Bradner" initials="S."
                    surname="Bradner">
                        <organization>Harvard University</organization>
                        <address>
                            <postal>
                                <street>1350 Mass. Ave.</street>
                                <street>Cambridge</street>
                                <street>MA 02138</street>
                            </postal>
                            <phone>- +1 617 495 3864</phone>
                            <email>sob@harvard.edu</email>
                        </address>
                    </author>
                    <date month="March" year="1997" />
                    <area>General</area>
                    <keyword>keyword</keyword>
                </front>
                <seriesInfo name="BCP" value="14" />
                <seriesInfo name="RFC" value="2119" />
                <format octets="4723"
                target="http://www.rfc-editor.org/rfc/rfc2119.txt"
                type="TXT" />
                <format octets="17491"
                target="http://xml.resource.org/public/rfc/html/rfc2119.html"
                type="HTML" />
                <format octets="5777"
                target="http://xml.resource.org/public/rfc/xml/rfc2119.xml"
                type="XML" />
            </reference>
            <reference anchor="RFC3264">
                <front>
                    <title>An Offer/Answer Model with Session
                    Description Protocol (SDP)</title>
                    <author fullname="J. Rosenberg" initials="J."
                    surname="Rosenberg">
                        <organization></organization>
                    </author>
                    <author fullname="H. Schulzrinne" initials="H."
                    surname="Schulzrinne">
                        <organization></organization>
                    </author>
                    <date month="June" year="2002" />
                </front>
                <seriesInfo name="RFC" value="3264" />
                <format octets="60854"
                target="http://www.rfc-editor.org/rfc/rfc3264.txt"
                type="TXT" />
            </reference>
            <reference anchor="RFC4566">
                <front>
                    <title>SDP: Session Description Protocol</title>
                    <author fullname="M. Handley" initials="M."
                    surname="Handley">
                        <organization></organization>
                    </author>
                    <author fullname="V. Jacobson" initials="V."
                    surname="Jacobson">
                        <organization></organization>
                    </author>
                    <author fullname="C. Perkins" initials="C."
                    surname="Perkins">
                        <organization></organization>
                    </author>
                    <date month="July" year="2006" />
                </front>
                <seriesInfo name="RFC" value="4566" />
                <format octets="108820"
                target="http://www.rfc-editor.org/rfc/rfc4566.txt"
                type="TXT" />
            </reference>
            <reference anchor="RFC3605">
                <front>
                    <title>Real Time Control Protocol (RTCP) attribute
                    in Session Description Protocol (SDP)</title>
                    <author initials="C." surname="Huitema"
                    fullname="C. Huitema">
                        <organization />
                    </author>
                    <date year="2003" month="October" />
                </front>
                <seriesInfo name="RFC" value="3605" />
                <format type="TXT" octets="17270"
                target="http://www.rfc-editor.org/rfc/rfc3605.txt" />
            </reference>
            <reference anchor="I-D.ietf-rtcweb-fec">
                <front>
                    <title>WebRTC Forward Error Correction
                    Requirements</title>
                    <author initials="J" surname="Uberti"
                    fullname="Justin Uberti">
                        <organization />
                    </author>
                    <date month="February" day="6" year="2015" />
                </front>
                <seriesInfo name="Internet-Draft"
                value="draft-ietf-rtcweb-fec-00" />
                <format type="TXT"
                target="http://www.ietf.org/internet-drafts/draft-ietf-rtcweb-fec-00.txt" />
            </reference>
            <reference anchor='RFC6347'>
                <front>
                    <title>Datagram Transport Layer Security Version
                    1.2</title>
                    <author initials='E.' surname='Rescorla'
                    fullname='E. Rescorla'>
                        <organization />
                    </author>
                    <author initials='N.' surname='Modadugu'
                    fullname='N. Modadugu'>
                        <organization />
                    </author>
                    <date year='2012' month='January' />
                </front>
                <seriesInfo name='RFC' value='6347' />
                <format type='TXT' octets='73546'
                target='http://www.rfc-editor.org/rfc/rfc6347.txt' />
            </reference>
            <reference anchor="I-D.ietf-ice-trickle">
                <front>
                    <title abbrev='Trickle ICE'>Trickle ICE:
                    Incremental Provisioning of Candidates for the
                    Interactive Connectivity Establishment (ICE)
                    Protocol</title>
                    <author initials='E.' surname='Ivov'
                    fullname='Emil Ivov'>
                        <organization abbrev='Jitsi'>
                        Jitsi</organization>
                        <address>
                            <postal>
                                <street></street>
                                <city>Strasbourg</city>
                                <code>67000</code>
                                <country>France</country>
                            </postal>
                            <phone>+33 6 72 81 15 55</phone>
                            <email>emcho@jitsi.org</email>
                        </address>
                    </author>
                    <author fullname="Eric Rescorla" initials="E.K."
                    surname="Rescorla">
                        <organization>RTFM, Inc.</organization>
                        <address>
                            <postal>
                                <street>2064 Edgewood Drive</street>
                                <city>Palo Alto</city>
                                <region>CA</region>
                                <code>94303</code>
                                <country>USA</country>
                            </postal>
                            <phone>+1 650 678 2350</phone>
                            <email>ekr@rtfm.com</email>
                        </address>
                    </author>
                    <author fullname="Justin Uberti" initials="J."
                    surname="Uberti">
                        <organization>Google</organization>
                        <address>
                            <postal>
                                <street>747 6th St S</street>
                                <city>Kirkland</city>
                                <region>WA</region>
                                <code>98033</code>
                                <country>USA</country>
                            </postal>
                            <phone>+1 857 288 8888</phone>
                            <email>justin@uberti.name</email>
                        </address>
                    </author>
                    <author initials="P." surname="Saint-Andre"
                    fullname="Peter Saint-Andre">
                        <organization>&amp;yet</organization>
                        <address>
                            <email>peter@andyet.com</email>
                            <uri>https://andyet.com/</uri>
                        </address>
                    </author>
                    <date />
                </front>
            </reference>
            <reference anchor="RFC6236">
                <front>
                    <title>Negotiation of Generic Image Attributes in
                    the Session Description Protocol (SDP)</title>
                    <author initials="I." surname="Johansson"
                    fullname="I. Johansson">
                        <organization />
                    </author>
                    <author initials="K." surname="Jung"
                    fullname="K. Jung">
                        <organization />
                    </author>
                    <date year="2011" month="May" />
                </front>
                <seriesInfo name="RFC" value="6236" />
                <format type="TXT" octets="49356"
                target="http://www.rfc-editor.org/rfc/rfc6236.txt" />
            </reference>
            <reference anchor="I-D.ietf-mmusic-sdp-simulcast">
                <front>
                    <title>Using Simulcast in SDP and RTP
                    Sessions</title>
                    <author initials="B" surname="Burman"
                    fullname="Bo Burman">
                        <organization />
                    </author>
                    <author initials="M" surname="Westerlund"
                    fullname="Magnus Westerlund">
                        <organization />
                    </author>
                    <author initials="S" surname="Nandakumar"
                    fullname="Suhas Nandakumar">
                        <organization />
                    </author>
                    <author initials="M" surname="Zanaty"
                    fullname="Mo Zanaty">
                        <organization />
                    </author>
                    <date month="February" day="3" year="2016" />
                </front>
                <seriesInfo name="Internet-Draft"
                value="draft-ietf-mmusic-sdp-simulcast-04" />
                <format type="TXT"
                target="http://www.ietf.org/internet-drafts/draft-ietf-mmusic-sdp-simulcast-04.txt" />
            </reference>
            <reference anchor="I-D.ietf-mmusic-rid">
                <front>
                    <title>RTP Payload Format Constraints</title>
                    <author initials="P" surname="Thatcher"
                    fullname="Peter Thatcher">
                        <organization />
                    </author>
                    <author initials="M" surname="Zanaty"
                    fullname="Mo Zanaty">
                        <organization />
                    </author>
                    <author initials="S" surname="Nandakumar"
                    fullname="Suhas Nandakumar">
                        <organization />
                    </author>
                    <author initials="B" surname="Burman"
                    fullname="Bo Burman">
                        <organization />
                    </author>
                    <author initials="A" surname="Roach"
                    fullname="Adam Roach">
                        <organization />
                    </author>
                    <author initials="B" surname="Campen"
                    fullname="Byron Campen">
                        <organization />
                    </author>
                    <date month="February" day="8" year="2016" />
                </front>
                <seriesInfo name="Internet-Draft"
                value="draft-ietf-mmusic-rid-04" />
                <format type="TXT"
                target="http://www.ietf.org/internet-drafts/draft-ietf-mmusic-rid-04.txt" />
            </reference>
            <reference anchor="I-D.ietf-avtext-rid">
                <front>
                    <title>RTP Stream Identifier (RID) Source
                    Description (SDES)</title>
                    <author initials="A" surname="Roach"
                    fullname="Adam Roach">
                        <organization />
                    </author>
                    <author initials="S" surname="Nandakumar"
                    fullname="Suhas Nandakumar">
                        <organization />
                    </author>
                    <author initials="P" surname="Thatcher"
                    fullname="Peter Thatcher">
                        <organization />
                    </author>
                    <date month="February" day="18" year="2016" />
                </front>
                <seriesInfo name="Internet-Draft"
                value="draft-ietf-avtext-rid-00" />
                <format type="TXT"
                target="http://www.ietf.org/internet-drafts/draft-ietf-avtext-rid-00.txt" />
            </reference>
        </references>
        <references title="Informative References">
            <!-- INFORM 1 -->
            <reference anchor="RFC3556">
                <front>
                    <title>Session Description Protocol (SDP) Bandwidth
                    Modifiers for RTP Control Protocol (RTCP)
                    Bandwidth</title>
                    <author fullname="S. Casner" initials="S."
                    surname="Casner">
                        <organization></organization>
                    </author>
                    <date month="July" year="2003" />
                </front>
                <seriesInfo name="RFC" value="3556" />
                <format octets="15310"
                target="http://www.rfc-editor.org/rfc/rfc3556.txt"
                type="TXT" />
            </reference>
            <reference anchor="RFC5576">
                <front>
                    <title>Source-Specific Media Attributes in the
                    Session Description Protocol (SDP)</title>
                    <author fullname="J. Lennox" initials="J."
                    surname="Lennox">
                        <organization></organization>
                    </author>
                    <author fullname="J. Ott" initials="J."
                    surname="Ott">
                        <organization></organization>
                    </author>
                    <author fullname="T. Schierl" initials="T."
                    surname="Schierl">
                        <organization></organization>
                    </author>
                    <date month="June" year="2009" />
                </front>
                <seriesInfo name="RFC" value="5576" />
                <format octets="40454"
                target="http://www.rfc-editor.org/rfc/rfc5576.txt"
                type="TXT" />
            </reference>
            <reference anchor="RFC5956">
                <front>
                    <title>Forward Error Correction Grouping Semantics
                    in the Session Description Protocol</title>
                    <author initials="A." surname="Begen"
                    fullname="A. Begen">
                        <organization />
                    </author>
                    <date year="2010" month="September" />
                </front>
                <seriesInfo name="RFC" value="5956" />
                <format type="TXT" octets="29530"
                target="http://www.rfc-editor.org/rfc/rfc5956.txt" />
            </reference>
            <reference anchor="RFC5506">
                <front>
                    <title>Support for Reduced-Size Real-Time Transport
                    Control Protocol (RTCP): Opportunities and
                    Consequences</title>
                    <author fullname="I. Johansson" initials="I."
                    surname="Johansson">
                        <organization></organization>
                    </author>
                    <author fullname="M. Westerlund" initials="M."
                    surname="Westerlund">
                        <organization></organization>
                    </author>
                    <date month="April" year="2009" />
                </front>
                <seriesInfo name="RFC" value="5506" />
                <format octets="41011"
                target="http://www.rfc-editor.org/rfc/rfc5506.txt"
                type="TXT" />
            </reference>
            <!-- INFORM 2 -->
            <reference anchor='RFC6464'
            target='http://www.rfc-editor.org/info/rfc6464'>
                <front>
                    <title>A Real-time Transport Protocol (RTP) Header
                    Extension for Client-to-Mixer Audio Level
                    Indication</title>
                    <author initials='J.' surname='Lennox'
                    fullname='J. Lennox' role='editor'>
                        <organization />
                    </author>
                    <author initials='E.' surname='Ivov'
                    fullname='E. Ivov'>
                        <organization />
                    </author>
                    <author initials='E.' surname='Marocco'
                    fullname='E. Marocco'>
                        <organization />
                    </author>
                    <date year='2011' month='December' />
                </front>
                <seriesInfo name='RFC' value='6464' />
                <seriesInfo name='DOI' value='10.17487/RFC6464' />
            </reference>
            <!-- INFORM 3 -->
            <!-- INFORM 4 -->
            <reference anchor="RFC3960">
                <front>
                    <title>Early Media and Ringing Tone Generation in
                    the Session Initiation Protocol (SIP)</title>
                    <author fullname="G. Camarillo" initials="G."
                    surname="Camarillo">
                        <organization></organization>
                    </author>
                    <author fullname="H. Schulzrinne" initials="H."
                    surname="Schulzrinne">
                        <organization></organization>
                    </author>
                    <date month="December" year="2004" />
                </front>
                <seriesInfo name="RFC" value="3960" />
                <format octets="31692"
                target="http://www.rfc-editor.org/rfc/rfc3960.txt"
                type="TXT" />
            </reference>
            <!-- INFORM 5 -->
            <!-- INFORM 6 -->
            <reference anchor="RFC4588">
                <front>
                    <title>RTP Retransmission Payload Format</title>
                    <author fullname="J. Rey" initials="J."
                    surname="Rey">
                        <organization></organization>
                    </author>
                    <author fullname="D. Leon" initials="D."
                    surname="Leon">
                        <organization></organization>
                    </author>
                    <author fullname="A. Miyazaki" initials="A."
                    surname="Miyazaki">
                        <organization></organization>
                    </author>
                    <author fullname="V. Varsa" initials="V."
                    surname="Varsa">
                        <organization></organization>
                    </author>
                    <author fullname="R. Hakenberg" initials="R."
                    surname="Hakenberg">
                        <organization></organization>
                    </author>
                    <date month="July" year="2006" />
                </front>
                <seriesInfo name="RFC" value="4588" />
                <format octets="76630"
                target="http://www.rfc-editor.org/rfc/rfc4588.txt"
                type="TXT" />
            </reference>
            <!-- INFORM 7 -->
            <reference anchor="RFC3389">
                <front>
                    <title>Real-time Transport Protocol (RTP) Payload
                    for Comfort Noise (CN)</title>
                    <author fullname="R. Zopf" initials="R."
                    surname="Zopf">
                        <organization></organization>
                    </author>
                    <date month="September" year="2002" />
                </front>
                <seriesInfo name="RFC" value="3389" />
                <format octets="17018"
                target="http://www.rfc-editor.org/rfc/rfc3389.txt"
                type="TXT" />
            </reference>
            <!-- INFORM 8 -->
            <!-- INFORM 9 -->
            <!-- INFORM 10 -->
            <!-- INFORM 11 -->
            <!-- INFORM 12 -->
            <!-- INFORM 13 -->
            <!-- INFORM 14 -->
            <!-- INFORM 15 -->
            <!-- INFORM 16 -->
            <reference anchor="I-D.nandakumar-rtcweb-sdp">
                <front>
                    <title>SDP for the WebRTC</title>
                    <author fullname="Suhas Nandakumar" initials="S"
                    surname="Nandakumar">
                        <organization></organization>
                    </author>
                    <author fullname="Cullen Jennings" initials="C"
                    surname="Jennings">
                        <organization></organization>
                    </author>
                    <date day="13" month="July" year="2013" />
                </front>
                <seriesInfo name="Internet-Draft"
                value="draft-nandakumar-rtcweb-sdp-02" />
                <format target="http://www.ietf.org/internet-drafts/draft-nandakumar-rtcweb-sdp-02.txt"
                type="TXT" />
                <format target="http://www.ietf.org/internet-drafts/draft-nandakumar-rtcweb-sdp-02.pdf"
                type="PDF" />
            </reference>
            <!-- INFORM 17 -->
            <reference anchor="RFC5763">
                <front>
                    <title>Framework for Establishing a Secure
                    Real-time Transport Protocol (SRTP) Security
                    Context Using Datagram Transport Layer Security
                    (DTLS)</title>
                    <author fullname="J. Fischl" initials="J."
                    surname="Fischl">
                        <organization></organization>
                    </author>
                    <author fullname="H. Tschofenig" initials="H."
                    surname="Tschofenig">
                        <organization></organization>
                    </author>
                    <author fullname="E. Rescorla" initials="E."
                    surname="Rescorla">
                        <organization></organization>
                    </author>
                    <date month="May" year="2010" />
                </front>
                <seriesInfo name="RFC" value="5763" />
                <format octets="81546"
                target="http://www.rfc-editor.org/rfc/rfc5763.txt"
                type="TXT" />
            </reference>
            <reference anchor='RFC5764'>
                <front>
                    <title>Datagram Transport Layer Security (DTLS)
                    Extension to Establish Keys for the Secure
                    Real-time Transport Protocol (SRTP)</title>
                    <author initials='D.' surname='McGrew'
                    fullname='D. McGrew'>
                        <organization />
                    </author>
                    <author initials='E.' surname='Rescorla'
                    fullname='E. Rescorla'>
                        <organization />
                    </author>
                    <date year='2010' month='May' />
                </front>
                <seriesInfo name='RFC' value='5764' />
                <format type='TXT' octets='60590'
                target='http://www.rfc-editor.org/rfc/rfc5764.txt' />
            </reference>
            <reference anchor="RFC4568">
                <front>
                    <title>Session Description Protocol (SDP) Security
                    Descriptions for Media Streams</title>
                    <author fullname="F. Andreasen" initials="F."
                    surname="Andreasen">
                        <organization></organization>
                    </author>
                    <author fullname="M. Baugher" initials="M."
                    surname="Baugher">
                        <organization></organization>
                    </author>
                    <author fullname="D. Wing" initials="D."
                    surname="Wing">
                        <organization></organization>
                    </author>
                    <date month="July" year="2006" />
                </front>
                <seriesInfo name="RFC" value="4568" />
                <format octets="107881"
                target="http://www.rfc-editor.org/rfc/rfc4568.txt"
                type="TXT" />
            </reference>
            <reference anchor="W3C.WD-webrtc-20140617"
            target="http://www.w3.org/TR/2011/WD-webrtc-20140617">
                <front>
                    <title>WebRTC 1.0: Real-time Communication Between
                    Browsers</title>
                    <author fullname="Adam Bergkvist" initials="A."
                    surname="Bergkvist">
                        <organization></organization>
                    </author>
                    <author fullname="Daniel C. Burnett" initials="D."
                    surname="Burnett">
                        <organization></organization>
                    </author>
                    <author fullname="Anant Narayanan" initials="A."
                    surname="Narayanan">
                        <organization></organization>
                    </author>
                    <author fullname="Cullen Jennings" initials="C."
                    surname="Jennings">
                        <organization></organization>
                    </author>
                    <date day="17" month="June" year="2014" />
                </front>
                <seriesInfo name="World Wide Web Consortium WD"
                value="WD-webrtc-20140617" />
                <format target="http://www.w3.org/TR/2011/WD-webrtc-20140617"
                type="HTML" />
            </reference>
            <reference anchor='I-D.ietf-rtcweb-ip-handling'>
                <front>
                    <title>WebRTC IP Address Handling
                    Recommendations</title>
                    <author initials='J' surname='Uberti'
                    fullname='Justin Uberti'>
                        <organization />
                    </author>
                    <author initials='G' surname='Shieh'
                    fullname='Guo-wei Shieh'>
                        <organization />
                    </author>
                    <date month='March' day='20' year='2016' />
                </front>
                <seriesInfo name='Internet-Draft'
                value='draft-ietf-rtcweb-ip-handling-01' />
                <format type='TXT'
                target='http://www.ietf.org/internet-drafts/draft-ietf-rtcweb-ip-handling-01.txt' />
            </reference>
        </references>
        <section title="Change log" anchor="sec.change-log">

            <t>Note: This section will be removed by RFC Editor before
            publication.</t>

            <t>Changes in draft-15:</t>
            <t>
              <list style="symbols">
                <t>Clarify text around codecs offered in subsequent transactions
                to refer to what's been negotiated.</t>
                
                <t>Rewrite LS handling text to indicate edge cases and that we're
                living with them.</t>
                
                <t>Require that answerer reject m= lines when there are no codecs
                in common.</t>
                
                <t>Enforce max-bundle on offer processing.</t>
                
                <t>Fix TIAS formula to handle bits vs. kilobits.</t>
                
                <t>Describe addTrack algorithm.</t>
                
                <t>Clean up references.</t>
              </list>
            </t>
            <t>Changes in draft-14:</t>

            <t>
                <list style="symbols">

                    <t>Added discussion of RtpTransceivers + RtpSenders
                    + RtpReceivers, and how they interact with
                    createOffer/createAnswer.</t>

                    <t>Removed obsolete OfferToReceiveX options.</t>

                    <t>Explained how addIceCandidate can be used for
                    end-of-candidates.</t>
                </list>
            </t>

            <t>Changes in draft-13:</t>

            <t>
                <list style="symbols">

                    <t>Clarified which SDP lines can be ignored.</t>

                    <t>Clarified how to handle various received
                    attributes.</t>

                    <t>Revised how attributes should be generated for
                    bundled m= lines.</t>

                    <t>Remove unused references.</t>

                    <t>Remove text advocating use of unilateral
                    PTs.</t>

                    <t>Trigger an ICE restart even if the ICE candidate
                    policy is being made more strict.</t>

                    <t>Remove the 'public' ICE candidate policy.</t>

                    <t>Move open issues/TODOs into GitHub issues.</t>

                    <t>Split local/remote description accessors into
                    current/pending.</t>

                    <t>Clarify a=imageattr handling.</t>

                    <t>Add more detail on VoiceActivityDetection
                    handling.</t>

                    <t>Reference draft-shieh-rtcweb-ip-handling.</t>

                    <t>Make it clear when an ICE restart should
                    occur.</t>

                    <t>Resolve reference TODOs.</t>

                    <t>Remove MSID semantics.</t>

                    <t>ice-options are now at session level.</t>

                    <t>Default RTCP mux policy is now 'require'.</t>
                </list>
            </t>

            <t>Changes in draft-12:</t>

            <t>
                <list style="symbols">

                    <t>Filled in sections on applying local and remote
                    descriptions.</t>

                    <t>Discussed downscaling and upscaling to fulfill
                    imageattr requirements.</t>

                    <t>Updated what SDP can be modified by the
                    application.</t>

                    <t>Updated to latest datachannel SDP.</t>

                    <t>Allowed multiple fingerprint lines.</t>

                    <t>Switched back to IPv4 for dummy candidates.</t>

                    <t>Added additional clarity on ICE default
                    candidates.</t>
                </list>
            </t>

            <t>Changes in draft-11:</t>

            <t>
                <list style="symbols">

                    <t>Clarified handling of RTP CNAMEs.</t>

                    <t>Updated what SDP lines should be processed or
                    ignored.</t>

                    <t>Specified how a=imageattr should be used.</t>
                </list>
            </t>

            <t>Changes in draft-10:</t>

            <t>
                <list style="symbols">

                    <t>TODO</t>
                </list>
            </t>

            <t>Changes in draft-09:</t>

            <t>
                <list style="symbols">

                    <t>Don't return null for {local,remote}Description
                    after close().</t>

                    <t>Changed TCP/TLS to UDP/DTLS in RTP profile
                    names.</t>

                    <t>Separate out bundle and mux policy.</t>

                    <t>Added specific references to FEC mechanisms.</t>

                    <t>Added canTrickle mechanism.</t>

                    <t>Added section on subsequent answers and, answer
                    options.</t>

                    <t>Added text defining set{Local,Remote}Description
                    behavior.</t>
                </list>
            </t>

            <t>Changes in draft-08:
            <list style="symbols">

                <t>Added new example section and removed old examples
                in appendix.</t>

                <t>Fixed &lt;proto&gt; field handling.</t>

                <t>Added text describing a=rtcp attribute.</t>

                <t>Reworked handling of OfferToReceiveAudio and
                OfferToReceiveVideo per discussion at IETF 90.</t>

                <t>Reworked trickle ICE handling and its impact on m=
                and c= lines per discussion at interim.</t>

                <t>Added max-bundle-and-rtcp-mux policy.</t>

                <t>Added description of maxptime handling.</t>

                <t>Updated ICE candidate pool default to 0.</t>

                <t>Resolved open issues around AppID/receiver-ID.</t>

                <t>Reworked and expanded how changes to the ICE
                configuration are handled.</t>

                <t>Some reference updates.</t>

                <t>Editorial clarification.</t>
            </list></t>

            <t>Changes in draft-07:
            <list style="symbols">

                <t>Expanded discussion of VAD and Opus DTX.</t>

                <t>Added a security considerations section.</t>

                <t>Rewrote the section on modifying SDP to require
                implementations to clearly indicate whether any given
                modification is allowed.</t>

                <t>Clarified impact of IceRestart on CreateOffer in
                local-offer state.</t>

                <t>Guidance on whether attributes should be defined at
                the media level or the session level.</t>

                <t>Renamed "default" bundle policy to "balanced".</t>

                <t>Removed default ICE candidate pool size and clarify
                how it works.</t>

                <t>Defined a canonical order for assignment of MSTs to
                m= lines.</t>

                <t>Removed discussion of rehydration.</t>

                <t>Added Eric Rescorla as a draft editor.</t>

                <t>Cleaned up references.</t>

                <t>Editorial cleanup</t>
            </list></t>

            <t>Changes in draft-06:
            <list style="symbols">

                <t>Reworked handling of m= line recycling.</t>

                <t>Added handling of BUNDLE and bundle-only.</t>

                <t>Clarified handling of rollback.</t>

                <t>Added text describing the ICE Candidate Pool and its
                behavior.</t>

                <t>Allowed OfferToReceiveX to create multiple recvonly
                m= sections.</t>
            </list></t>

            <t>Changes in draft-05:
            <list style="symbols">

                <t>Fixed several issues identified in the
                createOffer/Answer sections during document review.</t>

                <t>Updated references.</t>
            </list></t>

            <t>Changes in draft-04:
            <list style="symbols">

                <t>Filled in sections on createOffer and
                createAnswer.</t>

                <t>Added SDP examples.</t>

                <t>Fixed references.</t>
            </list></t>

            <t>Changes in draft-03:
            <list style="symbols">

                <t>Added text describing relationship to W3C
                specification</t>
            </list></t>

            <t>Changes in draft-02:
            <list style="symbols">
                <!-- A -->

                <t>Converted from nroff</t>
                <!-- B -->

                <t>Removed comparisons to old approaches abandoned by
                the working group</t>
                <!-- C -->

                <t>Removed stuff that has moved to W3C
                specification</t>
                <!-- D -->

                <t>Align SDP handling with W3C draft</t>
                <!-- E -->

                <t>Clarified section on forking.</t>
                <!-- F -->
                <!-- G -->
                <!-- H -->
                <!-- I -->
                <!-- J -->
                <!-- K -->
                <!-- L -->
            </list></t>

            <t>Changes in draft-01:
            <list style="symbols">

                <t>Added diagrams for architecture and state
                machine.</t>

                <t>Added sections on forking and rehydration.</t>

                <t>Clarified meaning of "pranswer" and "answer".</t>

                <t>Reworked how ICE restarts and media directions are
                controlled.</t>

                <t>Added list of parameters that can be changed in a
                description.</t>

                <t>Updated suggested API and examples to match latest
                thinking.</t>

                <t>Suggested API and examples have been moved to an
                appendix.</t>
            </list></t>

            <t>Changes in draft -00:
            <list style="symbols">

                <t>Migrated from draft-uberti-rtcweb-jsep-02.</t>
            </list></t>
        </section>
    </back>
</rfc>

