Javascript Session Establishment
ProtocolGoogle747 6th St SKirklandWA98033USAjustin@uberti.nameCisco400 3rd Avenue SWCalgaryABT2P 4H2Canadafluffy@iii.caMozilla331 Evelyn AveMountain ViewCA94041USAekr@rtfm.com
RAI
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.This document describes how the W3C WEBRTC RTCPeerConnection
interface
is used to control
the setup, management and teardown of a multimedia session.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.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.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.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 then uses that offer to set up its local config
via the setLocalDescription() API. The offer is finally 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.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.Regarding ICE
, 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.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.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.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.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.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.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
.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
(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.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.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
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.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.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.Therefore, in order to handle session descriptions properly,
the user agent needs:
To know if a session description pertains to the local or
remote side.To know if a session description is an offer or an
answer.To allow the offer to be specified independently of the
answer.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]).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; as
a result, multiple dissimilar provisional answers, with their
own codec choices, transport parameters, etc., can be
received and applied during call setup. Note that the final answer
itself may be different than any received provisional answers.In
, 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:Aside from these state transitions there is no other
difference between the handling of provisional ("pranswer") and
final ("answer") answers.JSEP's session descriptions use SDP syntax for their internal
representation. 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.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.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.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.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.Changes to these objects result in changes to the session
descriptions generated by subsequent createOffer/Answer
calls.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.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 said to be associated with an m= section if its mid property
is non-null; otherwise it is said to be disassociated.
The associated m= section is determined using a mapping between
transceivers and m= section indices, formed when creating an
offer or applying a remote offer. An RtpTransceiver is never
associated with more than one m= section, and once a session
description is applied, a m= section is always associated with
exactly one RtpTransceiver.RtpTransceivers can be created explicitly by the
application or implicitly by calling setRemoteDescription
with an offer that adds new m= sections.RtpSenders allow the application to control how RTP media
is sent. An RtpSender is conceptually responsible for the
outgoing RTP stream(s) described by an m= section. This includes
encoding the attached MediaStreamTrack, sending RTP media
packets, and generating/processing RTCP for the outgoing RTP
streams(s).RtpReceivers allow the application to inspect how RTP media
is received. An RtpReceiver is conceptually responsible for the
incoming RTP stream(s) described by an m= section. This includes
processing received RTP media packets, decoding the incoming
stream(s) to produce a remote MediaStreamTrack, and
generating/processing RTCP for the incoming RTP stream(s).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= section to the local session description, or new
ICE credentials in the description, indicating an ICE
restart. Use of new ICE credentials can be triggered
explicitly by the application, or implicitly by the browser
in response to changes in the ICE configuration.When 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.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.Note that gathering phases only gather the candidates
needed by new/recycled/restarting m= sections; other m= sections
continue to use their existing candidates. Also, when
bundling is active, candidates are only gathered (and
exchanged) for the m= sections referenced in BUNDLE-tags, as
described in
.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
. 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.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.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.In JSEP, ICE candidates
are abstracted by an IceCandidate object, and as with session
descriptions, SDP syntax is used for the internal representation.
The candidate details are specified in an IceCandidate field,
using the same SDP syntax as the "candidate-attribute" field
defined in , Section 15.1. For example:The IceCandidate object contains a field to indicate which
ICE ufrag it is associated with, as defined in
, Section 15.4. This value is used to
determine which session description (and thereby which gathering
phase) this IceCandidate belongs to, which helps resolve ambiguities
during ICE restarts. If this field is absent in a received
IceCandidate (perhaps when communicating with a non-JSEP endpoint),
the most recently received session description is assumed.The IceCandidate object also contains fields to indicate
which m= section it is associated with, which can
be identified in one of two ways, either by a m= section
index, or a MID. The m= section index is a zero-based index,
with index N referring to the N+1th m= section in the session
description referenced by this IceCandidate. The MID is a
"media stream identification" value, as defined in
, Section 4, which provides a
more robust way to identify the m= section in the session description,
using the MID of the associated RtpTransceiver object
(which may have been locally generated by the answerer when interacting
with a non-JSEP endpoint that does not support the MID
attribute, as discussed in
below).
If the MID field is present in a received IceCandidate, it MUST be
used for identification; otherwise, the m= section index is
used instead.
When creating an IceCandidate object, JSEP implementations
MUST populate all of these fields.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 only use relay candidates, to leak as little
location information as possible (keeping in mind that this choice
comes with corresponding operational costs). To accomplish this,
JSEP allows 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
.There may also be cases where the application wants to
change which types of candidates are used while the session
is active. A prime example is where a callee may initially
want to use only relay candidates, to avoid leaking location
information to an arbitrary caller, but then change to use
all candidates (for lower operational cost) once the user has
indicated they want to take the call. For this scenario, the
browser MUST allow the candidate policy to be changed in
mid-session, subject to the aforementioned interactions with
local policy.To administer the ICE candidate policy, the browser will
determine the current setting at the start of each gathering
phase. Then, during the gathering phase, the browser MUST NOT
expose candidates disallowed by the current policy to the
application, use them as the source of connectivity checks,
or indirectly expose them via other fields, such as the
raddr/rport attributes for other ICE candidates. Later, if a
different policy is specified by the application, the
application can apply it by kicking off a new gathering phase
via an ICE restart.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.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. This only occurs for the first offer/answer exchange,
after which the candidate pool is emptied and no longer used.
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.Video size negotiation is the process through which a
receiver can use the "a=imageattr" SDP attribute
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.Note that certain codecs support transmission of samples with aspect
ratios other than 1.0 (i.e., non-square pixels).
JSEP implementations will not transmit non-square pixels, but SHOULD
receive and render such video with the correct aspect ratio.
However, sample aspect ratio has no impact on the size negotiation
described below; all dimensions are measured in pixels, whether square
or not.
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.If there are no known decoder limits or mandatory
constraints, the "a=imageattr" attribute SHOULD be
omitted.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 MUST be represented by x=0 and y=0
values.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.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.As an example, consider a system with a multiformat video decoder,
which is capable of decoding any resolution from 48x48 to 720p,
and where the application has
constrained the received track to at most 360p. In this case,
the implementation would generate this attribute:a=imageattr:* recv [x=[48:640],y=[48:360],q=1.0]This declaration indicates that the receiver is capable of
decoding any image resolution from 48x48 up to 640x360
pixels. 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.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.For the purposes of resolution negotiation, only size limits are
considered. Any other values, e.g. picture or sample aspect ratio,
MUST be ignored.When communicating with a non-JSEP endpoint, multiple
relevant "a=imageattr recv" attributes may be present in a received
m= section. If this occurs, attributes other than the one with the
highest "q=" value MUST be ignored. If multiple attributes have the
same "q=" value, those that appear after the first such attribute in
the m= section MUST be ignored.If an "a=imageattr recv" attribute references a different
video payload type than what has been selected for sending the
MediaStreamTrack, it MUST be ignored.If the original resolution matches the size limits in the
attribute, the track MUST be transmitted untouched.If the original resolution exceeds the size limits in the
attribute, the sender SHOULD apply downscaling to the output
of the MediaStreamTrack in order to satisfy the limits.
Downscaling MUST NOT change the track aspect ratio.If the original resolution is less than the size limits in
the attribute, upscaling is needed, but this may not be
appropriate in all cases. To address this concern, the
application can set an upscaling policy for each sent track.
For this case, if upscaling is permitted by policy, the
sender SHOULD apply upscaling in order to provide the desired
resolution. Otherwise, the sender MUST NOT apply upscaling.
The sender SHOULD NOT upscale in other cases, even if the
policy permits it. Upscaling MUST NOT change the track aspect
ratio.If there is no appropriate and permitted scaling mechanism
that allows the received size limits to be satisfied, the
sender MUST NOT transmit the track.If the attribute includes a "sar=" (sample aspect ratio) value set
to something other than "1.0", indicating the receiver wants to
receive non-square pixels, this cannot be satisfied and the sender
MUST NOT transmit the track.In the special case of receiving a maximum resolution of
[0, 0], as described above, the sender MUST NOT transmit the
track.JSEP supports simulcast transmission of a MediaStreamTrack, where
multiple encodings of the source media can be transmitted
within the context of a single m= section. The current JSEP API
is designed to allow applications to send simulcasted media but
only to receive a single encoding. This allows for multi-user
scenarios where each sending client sends multiple encodings to
a server, which then, for each receiving client, chooses the
appropriate encoding to forward.Applications request support for simulcast by configuring
multiple encodings on an RtpSender, which, upon generation of
an offer or answer, are indicated in SDP markings on the
corresponding m= section, as described below. Receivers that
understand simulcast and are willing to receive it will also
include SDP markings to indicate their support, and JSEP
endpoints will use these markings to determine whether
simulcast is permitted for a given RtpSender. If simulcast
support is not negotiated, the RtpSender will only use the
first configured encoding.Note that the exact simulcast parameters are up to the
sending application. While the aforementioned SDP markings are
provided to ensure the remote side can receive and demux
multiple simulcast encodings, the specific resolutions and
bitrates to be used for each encoding are purely a send-side
decision in JSEP.JSEP currently does not provide a mechanism to configure receipt
of simulcast. This means that if simulcast is offered by the
remote endpoint, the answer generated by a JSEP endpoint will
not indicate support for receipt of simulcast, and as such the
remote endpoint will only send a single encoding per m= section.In addition, JSEP does not provide a mechanism to handle an
incoming offer requesting simulcast from the JSEP endpoint.
This means that established simulcast streams
will continue to work through a received re-offer, but setting
up initial simulcast by way of a received offer requires
out-of-band signaling or SDP inspection. Future versions of
this specification may add additional APIs to provide direct
control.When using JSEP to transmit multiple encodings from a
RtpSender, the techniques from
and
are used. Specifically,
when multiple encodings have been configured for a RtpSender,
the m= section for the RtpSender will include an "a=simulcast"
attribute, as defined in
, Section 6.2,
with a "send" simulcast stream description that lists each
desired encoding, and no "recv" simulcast stream description.
The m= section will also include an "a=rid" attribute for each
encoding, as specified in
, Section 4; the use of
RID identifiers allows the individual encodings to be
disambiguated even though they are all part of the same m=
section.Some call signaling systems allow various types of forking
where an SDP Offer may be provided to more than one device. For
example, SIP
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:
Start exchanging media with a given remote peer, but keep
all the resources reserved in the offer.Start exchanging media with a given remote peer, and free
any resources in the offer that are not being used.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.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.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.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.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
. 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.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
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
.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 using setDirection (see ), 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.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.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.If an ICE candidate policy is specified, it functions as
described in
, 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:
All candidates permitted by browser
policy will be gathered and used.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 and chooses relay servers, this could obfuscate
location to a metro or possibly even global level.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.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.The application can specify its preferred policy regarding
use of bundle, the multiplexing mechanism defined in
. 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.The set of available policies is as follows:
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.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.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, the implementation will reject any m=
sections other than the first m= section, unless they are
in the same bundle group as that m= section.As it provides the best tradeoff between performance and
compatibility with legacy endpoints, the default bundle
policy MUST be set to "balanced".The application can specify its preferred policy regarding
use of RTP/RTCP multiplexing
using one of the following policies:
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.The browser will only gather RTP
candidates. This halves the number of candidates that the
offerer needs to gather. Applying a description with an
m= section that does not contain an "a=rtcp-mux" attribute
will cause an error to be returned.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".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: If the PeerConnection is in the
"have-remote-offer" state, the track will be attached to the
first compatible transceiver that was created by the most
recent call to setRemoteDescription() and does not have a
local track. Otherwise, a new transceiver will be created, as
described in
.The removeTrack method removes a MediaStreamTrack from the
PeerConnection, using the RtpSender argument to indicate
which sender should have its track removed. The sender's track is cleared,
and the sender stops sending. Future calls to createOffer
will mark the media description associated with the sender
as recvonly (if transceiver.currentDirection is sendrecv) or as
inactive (if transceiver.currentDirection is sendonly).The addTransceiver method adds a new RtpTransceiver to the
PeerConnection. If a MediaStreamTrack argument is provided,
then the transceiver will be configured with that media type
and the track will be attached to the transceiver. Otherwise,
the application MUST explicitly specify the type; this mode
is useful for creating recvonly transceivers as well as for
creating transceivers to which a track can be attached at
some later point.At the time of creation, the application can also specify
a transceiver direction attribute, a set of MediaStreams
which the transceiver is associated with (allowing LS group
assignments), and a set of encodings for the media (used for
simulcast as described in
).The createDataChannel method creates a new data channel
and attaches it to the PeerConnection. If no data channel
currently exists for this PeerConnection, then a new
offer/answer exchange is required. All data channels on a
given PeerConnection share the same SCTP/DTLS association and
therefore the same m= section, so subsequent creation of data
channels does not have any impact on the JSEP state.The createDataChannel method also includes a number of
arguments which are used by the PeerConnection (e.g.,
maxPacketLifetime) but are not reflected in the SDP and do
not affect the JSEP state.The createOffer method generates a blob of SDP that
contains a
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.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
below.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
. below.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.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.The createAnswer method generates a blob of SDP that
contains a
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.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
. below.Session descriptions generated by createAnswer must be
immediately usable by setLocalDescription; like createOffer,
the returned description should reflect the current state of
the system. Calling this method may do things such as generate new ICE
credentials, but does not trigger candidate gathering or
change media state.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."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"."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"."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".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)."rollback" is a special session description type implying
that the state machine should be rolled back to the previous
stable state, as described in
. The contents MUST be
empty.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.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.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.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".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
(see
and ) 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.A rollback will disassociate any RtpTransceivers that
were associated with m= sections by the application of the
rolled-back session description (see
and
). 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 property MUST
be set to null, and the mapping between the transceiver and
its m= section index MUST be discarded.
RtpTransceivers that were created by
applying a remote offer that was subsequently rolled back
MUST be stopped and removed from the PeerConnection.
However, a RtpTransceiver MUST NOT be
removed if a track was attached to the RtpTransceiver via
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.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).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.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 the codecs that exist in either
description). This dual processing begins when the PeerConnection
enters the have-local-offer state, and continues until
setRemoteDescription is called with either a final answer, at which
point the PeerConnection can fully adopt the pending local
description, or a rollback, which results in a revert to the current
local description.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 each transport, using ones from the candidate pool
if available.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 is available to send, this will result
in the starting of media transmission.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.This API changes the local media state; among other
things, it sets up local resources for sending and encoding
media.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 is available to send, this will result
in the starting of media transmission.The currentLocalDescription method returns 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.A null object will be returned if an offer/answer exchange
has not yet been completed.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.A null object will be returned if the state of the
PeerConnection is "stable" or "have-remote-offer".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.A null object will be returned if an offer/answer exchange
has not yet been completed.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.A null object will be returned if the state of the
PeerConnection is "stable" or "have-local-offer".The canTrickleIceCandidates property indicates whether the
remote side supports receiving trickled candidates. There are
three potential values:
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.SDP has been received from the other
side indicating that it can support trickle.SDP has been received from the other
side indicating that it cannot support trickle.As described in
, 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.The setConfiguration method allows the global
configuration of the PeerConnection, which was initially set
by constructor parameters, to be changed during the session.
The effects of this method call depend on when it is invoked,
and differ depending on which specific parameters are
changed:Any changes to the STUN/TURN servers to use affect the
next gathering phase. If an ICE gathering phase has
already started or completed, the 'needs-ice-restart' bit
mentioned in
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, and a local description has not yet been
applied, any existing candidates will be discarded, and new
candidates will be gathered from the new servers.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.The ICE candidate pool size MUST NOT be changed after
applying a local description. If a local description has not
yet been applied, 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.The bundle and RTCP-multiplexing policies MUST NOT be
changed after the construction of the PeerConnection.This call may result in a change to the state of the ICE
Agent.The addIceCandidate method provides a remote candidate to
the ICE Agent, which, if parsed successfully, will be added
to the current and/or pending remote description according to
the rules defined for Trickle ICE. The pair of MID and ufrag
is used to determine the m= section and ICE candidate
generation to which the candidate belongs. If the MID is not
present, the m= section index is used to look up the locally
generated MID (see
), which is used
in place of a supplied MID. If these values or the candidate
string are invalid, an error is generated.The purpose of the ufrag is to resolve ambiguities when
trickle ICE is in progress during an ICE restart. If the
ufrag is absent, the candidate MUST be assumed to belong to
the most recently applied remote description. Connectivity
checks will be sent to the new candidate.This method can also be used to provide an
end-of-candidates indication to the ICE Agent, as defined in
). The MID and ufrag
are used as described above to determine the m= section and
ICE generation for which candidate gathering is complete. If
the ufrag is not present, then the end-of-candidates
indication MUST be assumed to apply to the relevant m=
section in the most recently applied remote description. If
neither the MID nor the m= index is present, then the
indication MUST be assumed to apply to all m= sections in the
most recently applied remote description.This call will result in a change to the state of the ICE
Agent, and may result in a change to media state if it
results in connectivity being established.
The stop method stops an RtpTransceiver. This
will cause future calls to createOffer to generate a zero
port for the associated m= section. See below for more
details.
The stopped property indicates whether the transceiver has
been stopped, either by a call to stopTransceiver or by
applying an answer that rejects the associated m= section.
In either of these cases, it is set to "true", and otherwise
will be set to "false".
A stopped RtpTransceiver does not send any
outgoing RTP or RTCP or process any incoming RTP
or RTCP. It cannot be restarted.
The setDirection method sets the direction of a transceiver,
which affects the direction property of the associated m=
section on future calls to createOffer and createAnswer.
When creating offers, the transceiver direction is directly
reflected in the output, even for reoffers. When creating answers,
the transceiver direction is intersected with the offered direction,
as explained in the
section below.
Note that while setDirection sets the direction property of
the transceiver immediately
(), this property
does not immediately affect whether the transceiver's
RtpSender will send or its RtpReceiver will receive. The
direction in effect is represented by the currentDirection
property, which is only updated when an answer is applied.
The direction property indicates the last value passed into
setDirection. If setDirection has never been called, it
is set to the direction the transceiver was initialized with.
The currentDirection property indicates the last negotiated
direction for the transceiver's associated m= section. More
specifically, it indicates the
directional attribute of the associated m= section in the last
applied answer, with "send" and "recv" directions reversed if
it was a remote answer. For example, if the directional
attribute for the associated m= section in a remote answer is
"recvonly", currentDirection is set to "sendonly".
If an answer that references this transceiver has not yet been
applied, or if the transceiver is stopped, currentDirection
is set to null.
The setCodecPreferences method sets the codec preferences of a
transceiver, which in turn affect the presence and order of
codecs of the associated m= section on future calls to
createOffer and createAnswer. Note that setCodecPreferences
does not directly affect which codec the implementation decides
to send. It only affects which codecs the implementation
indicates that it prefers to receive, via the offer or answer.
Even when a codec is excluded by setCodecPreferences, it still
may be used to send until the next offer/answer exchange
discards it.
The codec preferences of an RtpTransceiver can cause codecs
to be excluded by subsequent calls to createOffer and
createAnswer, in which case the corresponding media formats
in the associated m= section will be excluded. The codec
preferences cannot add media formats that would otherwise not
be present. This includes codecs that were not negotiated in a
previous offer/answer exchange that included the transceiver.
The codec preferences of an RtpTransceiver can also determine
the order of codecs in subsequent calls to createOffer and
createAnswer, in which case the order of the media formats in
the associated m= section will match. However, the codec
preferences cannot change the order of the media formats after
an answer containing the transceiver has been applied. At this
point, codecs can only be removed, not reordered.
This section describes the specific procedures to be followed
when creating and parsing SDP objects.JSEP implementations must comply with the specifications
listed below that govern the creation and processing of offers
and answers.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.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. Implementations of JSEP MUST conform to
.
This list of mandatory-to-implement specifications is
derived from the requirements outlined in that document
and from . is the base SDP specification
and MUST be implemented. MUST be supported for
signaling the UDP/TLS/RTP/SAVPF
, TCP/DTLS/RTP/SAVPF
,
"UDP/DTLS/SCTP"
, and
"TCP/DTLS/SCTP"
RTP profiles. 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. MUST be implemented to signal
DTLS certificate fingerprints. MUST be
implemented for signaling grouping information, and MUST be
used to identify m= lines via the a=mid attribute. MUST be
supported, in order to signal associations between RTP
objects and W3C MediaStreams and MediaStreamTracks in a
standard way.The bundle mechanism in
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.The SDP attributes of "sendonly", "recvonly",
"inactive", and "sendrecv" from
MUST be implemented to signal
information about media direction. MUST be implemented to signal
RTP SSRC values and grouping semantics. MUST be implemented to signal
RTCP based feedback. MUST be implemented to signal
multiplexing of RTP and RTCP. MUST be implemented to signal
reduced-size RTCP messages. MUST be implemented to signal
RTX payload type associations. MUST be supported for control
of RTCP bandwidth limits.The SDES SRTP keying mechanism from
MUST NOT be implemented, as discussed in
.As required by
, Section 5.13, JSEP
implementations MUST ignore unknown attribute (a=) lines.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.
ICE, as specified in
, MUST be used. Note that the
remote endpoint may use a Lite implementation;
implementations MUST properly handle remote endpoints which
do ICE-Lite.DTLS
or DTLS-SRTP
, MUST be used, as
appropriate for the media type, as specified in
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.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:The profile in any "m=" line in any answer MUST
exactly match the profile provided in the offer.Any profile matching the following patterns MUST be
accepted: "RTP/[S]AVP[F]" and
"(UDP/TCP)/TLS/RTP/SAVP[F]"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.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 a value of "trr-int=4000".For data m= sections, JSEP endpoints MUST support
receiving the "UDP/DTLS/SCTP", "TCP/DTLS/SCTP", or
"DTLS/SCTP" (for backwards compatibility) profiles.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.When createOffer is called, a new SDP description must be
created that includes the functionality specified in
. The exact
details of this process are explained below.When createOffer is called for the first time, the result
is known as the initial offer.The first step in generating an initial offer is to
generate session-level attributes, as specified in
, Section 5. Specifically:
The first SDP line MUST be "v=0", as specified in
, Section 5.1The second SDP line MUST be an "o=" line, as specified
in
, Section 5.2. The value of
the <username> field SHOULD be "-".
requires that the <sess-id>
be representable as a 64-bit signed integer. It is
RECOMMENDED that the <sess-id> be generated as a
64-bit quantity with the high bit being sent to zero and
the remaining 63 bits being cryptographically random. The
value of the <nettype> <addrtype>
<unicast-address> tuple SHOULD be set to a
non-meaningful address, such as IN IP4 0.0.0.0, to prevent
leaking the local address in this field. As mentioned in
, the entire o= line needs to
be unique, but selecting a random number for
<sess-id> is sufficient to accomplish this.The third SDP line MUST be a "s=" line, as specified in
, 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
which proposes a single space, but
as both "o=" and "s=" are meaningless, having the same
meaningless value seems clearer.Session Information ("i="), URI ("u="), Email Address
("e="), Phone Number ("p="), Repeat Times
("r="), and Time Zones ("z=") lines are not useful in this
context and SHOULD NOT be included.Encryption Keys ("k=") lines do not provide sufficient
security and MUST NOT be included.A "t=" line MUST be added, as specified in
, Section 5.9; both
<start-time> and <stop-time> SHOULD be set to
zero, e.g. "t=0 0".An "a=ice-options" line with the "trickle" option MUST
be added, as specified in
, Section 4.The next step is to generate m= sections, as specified in
Section 5.14. An m= section is
generated for each RtpTransceiver that has been added to the
PeerConnection, excluding any stopped RtpTransceivers.
This is done in the order the
RtpTransceivers were added to the PeerConnection.For each m= section generated for an RtpTransceiver,
establish a mapping between the transceiver and the index of
the generated m= section.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.For DTLS, all m= sections MUST use all the certificate(s)
that have been specified for the PeerConnection; as a result,
they MUST all have the same
fingerprint
value(s), or these value(s) MUST be session-level
attributes.Each m= section should be generated as specified in
, Section 5.14. For the m= line
itself, the following rules MUST be followed:
The port value is set to the port of the default ICE
candidate for this m= section, but given that no
candidates are available yet, the "dummy" port value of 9
(Discard) MUST be used, as indicated in
, Section
5.1.To properly indicate use of DTLS, the <proto>
field MUST be set to "UDP/TLS/RTP/SAVPF", as specified in
, Section 8.If codec preferences have been set for the associated
transceiver, media formats MUST be generated in the
corresponding order, and MUST exclude any codecs not present
in the codec preferences.The media formats in the answer MAY include codecs present
in the offer that were discarded in a previous offer/answer
exchange. This is necessary for compatibility with third-
party call control and SIP use cases.Unless excluded by the above restrictions, the media
formats MUST include the mandatory audio/video codecs as
specified in
(see Section 3)
and
(see Section
5).The m= line MUST be followed immediately by a "c=" line,
as specified in
, Section 5.7. Again, as no
candidates are available yet, the "c=" line must contain
the "dummy" value "IN IP4 0.0.0.0", as defined in
, Section 5.1. groups
SDP attributes into different categories. To avoid
unnecessary duplication when bundling, Section 8.1 of
specifies
that attributes of category IDENTICAL or TRANSPORT should not
be repeated in bundled m= sections.The following attributes, which are of a category other
than IDENTICAL or TRANSPORT, MUST be included in each m=
section:An "a=mid" line, as specified in
, Section 4. All MID values
MUST be generated in a fashion that does not leak user
information, e.g., randomly or using a per-PeerConnection counter, and
SHOULD be 3 bytes or less, to allow them to efficiently fit into
the RTP header extension defined in
, Section 14. Note that this does not set the
RtpTransceiver mid property, as that only occurs when
the description is applied. The generated MID value can be
considered a "proposed" MID at this point.A direction attribute which is the same as that of the
associated transceiver.For each media format on the m= line,
"a=rtpmap" and "a=fmtp" lines, as specified in
, Section 6, and
, Section 5.1.If this m= section is for media with configurable
durations of media per packet, e.g., audio, an
"a=maxptime" line, indicating the maximum amount of
media, specified in milliseconds, that can be
encapsulated in each packet, as specified in , Section 6. This value is set
to the smallest of the maximum duration values across all the
codecs included in the m= section. 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
.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
, Section 8.1.For each supported FEC mechanism, "a=rtpmap" and
"a=fmtp" lines, as specified in
, Section 6. The FEC
mechanisms that MUST be supported are specified in
, Section 6,
and specific usage for each media type is outlined in
Sections 4 and 5.For each supported RTP header extension, an "a=extmap"
line, as specified in
, Section 5. The list of
header extensions that SHOULD/MUST be supported is
specified in
, Section
5.2. Any header extensions that require encryption MUST
be specified as indicated in
, Section 4.For each supported RTCP feedback mechanism, an
"a=rtcp-fb" mechanism, as specified in
, Section 4.2. The list of
RTCP feedback mechanisms that SHOULD/MUST be supported is
specified in
, Section
5.1.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.If the RtpTransceiver has a sendrecv or sendonly
direction:
An "a=msid" line, as specified in
, Section
2.If the RtpTransceiver has a sendrecv or sendonly
direction, 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
, 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. RID values MUST be generated in a fashion that does not leak user
information, e.g., randomly or using a per-PeerConnection counter, and
SHOULD be 3 bytes or less, to allow them to efficiently fit into
the RTP header extension defined in
, Section 3.
If no encodings have been specified, or only one encoding
is specified but without a RID value, then no "a=rid"
lines are generated.If the RtpTransceiver has a sendrecv or sendonly
direction and more than one "a=rid" line has been generated,
an "a=simulcast" line, with direction "send", as defined in
,
Section 6.2. The list of RIDs MUST include all of the RID
identifiers used in the "a=rid" lines for this m=
section.The following attributes, which are of category IDENTICAL
or TRANSPORT, MUST appear only in "m=" sections which either
have a unique address or which are associated with the
bundle-tag. (In initial offers, this means those "m="
sections which do not contain an "a=bundle-only"
attribute."a=ice-ufrag" and "a=ice-pwd" lines, as specified in
, Section 15.4.An "a=fingerprint" line for each of the endpoint's
certificates, as specified in
, Section 5; the digest
algorithm used for the fingerprint MUST match that used
in the certificate signature.An "a=setup" line, as specified in
, Section 4, and clarified
for use in DTLS-SRTP scenarios in
, Section 5. The role value
in the offer MUST be "actpass".An "a=dtls-id" line, as specified in
Section 5.2.An "a=rtcp" line, as specified in
, Section 2.1, containing
the dummy value "9 IN IP4 0.0.0.0", because no candidates
have yet been gathered.An "a=rtcp-mux" line, as specified in , Section
5.1.3. An "a=rtcp-rsize" line, as specified in
, Section 5.Lastly, if a data channel has been created, a m= section
MUST be generated for data. The <media> field MUST be
set to "application" and the <proto> field MUST be set
to "UDP/DTLS/SCTP"
. The "fmt"
value MUST be set to "webrtc-datachannel" as specified in
, Section
4.1.Within the data m= section, the "a=mid", "a=ice-ufrag",
"a=ice-pwd", "a=fingerprint", "a=dtls-id", 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
, Section
4.1.Once all m= sections have been generated, a session-level
"a=group" attribute MUST be added as specified in
. 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.The next step is to generate session-level lip sync groups
as defined in
, 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.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.Attributes other than the ones specified above MAY be
included, except for the following attributes which are
specifically incompatible with the requirements of
, and MUST
NOT be included:
"a=crypto""a=key-mgmt""a=ice-lite"Note that when bundle is used, any additional attributes
that are added MUST follow the advice in
on
how those attributes interact with bundle.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.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.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:
The fields of the "o=" line MUST stay the same except
for the <session-version> field, which MUST increment
by one on each call to createOffer if the offer might
differ from the output of the previous call to createOffer;
implementations MAY opt to increment
<session-version> on every call. The value of the
generated <session-version> is independent of the
<session-version> of the current local description;
in particular, in the case where the current version is N,
an offer is created and applied with version N+1, and then that offer
is rolled back so that the current version is again N, the
next generated offer will still have version N+2.Note that if the application creates an offer by reading
currentLocalDescription instead of calling createOffer, the
returned SDP may be different than when setLocalDescription
was originally called, due to the addition of gathered ICE
candidates, but the <session-version> will not have
changed. There are no known scenarios in which this causes
problems, but if this is a concern, the solution is simply to
use createOffer to ensure a unique
<session-version>.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:
The "s=" and "t=" lines MUST stay the same.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.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.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" line removed.For RtpTransceivers that are not stopped, the "a=msid"
line MUST stay the same if
they are present in the current description.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
, 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
, Section 9.1.2.2, which only
refers to offers created when ICE has completed. In each
case, if no RTP candidates have yet been
gathered, dummy values MUST be used, as described
above.Each "a=mid" line MUST stay the same.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 (
was specified. If the m=
section is bundled into another m= section, it still MUST
NOT contain any ICE credentials.If the m= section is not bundled into another
m= section, an "a=rtcp" attribute line MUST be added with
of the default RTCP candidate, as indicated in
, Section 5.1.3.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
), an
"a=candidate" line MUST be added, as defined in
, 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
, Section 9.3.
If the m= section is bundled into another m= section, both
"a=candidate" and "a=end-of-candidates" MUST be
omitted.For RtpTransceivers that are still present, the
"a=msid" line MUST stay the same.For RtpTransceivers that are still present, the "a=rid"
lines MUST stay the same.For RtpTransceivers that are still present, any
"a=simulcast" line MUST stay the same.If any RtpTransceiver has been stopped, the port MUST be
set to zero and the "a=msid"
line MUST be removed.If any RtpTransceiver has been added, and there exists a
m= section with a zero port in the current local
description or the current remote description, that m=
section MUST be recycled by generating a m= section for the
added RtpTransceiver as if the m= section were being added
to session description, except that instead of adding it,
the generated m= section replaces the m= section with a
zero port. The new m= section MUST contain a new MID.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.
In addition, for each non-recycled, non-rejected m=
section in the new offer, the following adjustments are made
based on the contents of the corresponding m= section in the
current remote description, if any:
The m= line and corresponding "a=rtpmap" and "a=fmtp"
lines MUST only include codecs present in the most recent
answer which have not been excluded by the codec preferences
of the associated transceiver. Note that non-JSEP endpoints
are not subject to these restrictions, and might offer media
formats that were not present in the most recent answer, as
specified in , Section 8.
Therefore, JSEP endpoints MUST be prepared to receive such
offers.The media formats on the m= line MUST be generated in the
same order as in the current local description.The RTP header extensions MUST only include those that
are present in the most recent answer.The RTCP feedback extensions MUST only include those
that are present in the most recent answer.The "a=rtcp" line MUST only be added if the most recent
answer did not include an "a=rtcp-mux" line.The "a=rtcp-mux" line MUST only be added if present in
the most recent answer.The "a=rtcp-mux-only" line MUST only be added if present
in the most recent answer.The "a=rtcp-rsize" line MUST only be added if present in
the most recent answer.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.The "LS" groups are generated in the same way as with
initial offers.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.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
, 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.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
, 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.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.Note that setting the "VoiceActivityDetection" parameter
when generating an offer is a request to receive audio with
silence suppression. It has no impact on whether the local
endpoint does silence suppression for the audio it
sends.The "VoiceActivityDetection" option does not have any
impact on the setting of the "vad" value in the signaling
of the client to mixer audio level header extension
described in
, Section 4.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
. The exact
details of this process are explained below.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.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
. 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.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
, Section 4, is
only included if such an option was present in the offer.The next step is to generate session-level lip sync groups
as defined in
, 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.The next step is to generate m= sections for each m=
section that is present in the remote offer, as specified in
, 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.The next step is to go through each offered m= section.
Each offered m= section will have an associated
RtpTransceiver, as described in
. If there are
more RtpTransceivers than there are m= sections, the
unmatched RtpTransceivers will need to be associated in a
subsequent offer.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
, Section 6., and further
processing for this m= section can be skipped:
The associated RtpTransceiver has been stopped.No supported codec is present in the offer.The bundle policy is "max-bundle", and this is not the
first m= section or in the same bundle group as the first
m= section.The bundle policy is "balanced", and this is not the
first m= section for this media type or in the same bundle
group as the first m= section for this media type.Otherwise, each m= section in the answer should then be
generated as specified in
, Section 6.1. For the m= line
itself, the following rules must be followed:
The port value would normally be set to the port of the
default ICE candidate for this m= section, but given that
no candidates are available yet,
the "dummy" port
value of 9 (Discard) MUST be used, as indicated in
, Section
5.1.The <proto> field MUST be set to exactly match the
<proto> field for the corresponding m= line in the
offer.If codec preferences have been set for the associated
transceiver, media formats MUST be generated in the
corresponding order, and MUST exclude any codecs not present
in the codec preferences or not present in the offer. Note
that non-JSEP endpoints are not subject to this restriction,
and might add media formats in the answer that are not present
in the offer, as specified in ,
Section 6.1. Therefore, JSEP endpoints MUST be prepared to
receive such answers.Unless excluded by the above restrictions, the media
formats MUST include the mandatory audio/video codecs as
specified in
(see Section 3)
and
(see Section
5).The m= line MUST be followed immediately by a "c=" line,
as specified in
, Section 5.7. Again, as no
candidates are available yet, the "c=" line must contain
the "dummy" value "IN IP4 0.0.0.0", as defined in
, Section 5.1.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 contain the following
attributes (which are of attribute types other than IDENTICAL
and TRANSPORT):
If and only if present in the offer, an "a=mid" line, as
specified in
, Section 9.1. The "mid"
value MUST match that specified in the offer.A direction attribute, determined by applying the
rules regarding the offered direction specified
in , Section 6.1, and then
intersecting with the direction of the associated
RtpTransceiver. For example,
in the case where an m= section is offered as "sendonly",
and the local transceiver is set to "sendrecv", the
result in the answer is a "recvonly" direction.For each media format on the m= line,
"a=rtpmap" and "a=fmtp" lines, as specified in
, Section 6, and
, Section 6.1.If this m= section is for media with configurable
durations of media per packet, e.g., audio, an
"a=maxptime" line, as described in .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
.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
, Section 8.1.For each supported FEC mechanism, "a=rtpmap" and
"a=fmtp" lines, as specified in
, Section 6. The FEC
mechanisms that MUST be supported are specified in
, Section 6, and
specific usage for each media type is outlined in Sections
4 and 5.For each supported RTP header extension that is present
in the offer, an "a=extmap" line, as specified in
, Section 5. The list of
header extensions that SHOULD/MUST be supported is
specified in
, Section
5.2. Any header extensions that require encryption MUST be
specified as indicated in
, Section 4.For each supported RTCP feedback mechanism that is
present in the offer, an "a=rtcp-fb" mechanism, as
specified in
, Section 4.2. The list of
RTCP feedback mechanisms that SHOULD/MUST be supported is
specified in
, Section
5.1.If the RtpTransceiver has a sendrecv or sendonly direction:
An "a=msid" line, as specified in
, Section
2.Each m= section which is not bundled into another m=
section, MUST contain the following attributes (which are of
category IDENTICAL or TRANSPORT):"a=ice-ufrag" and "a=ice-pwd" lines, as specified in
, Section 15.4.An "a=fingerprint" line for each of the endpoint's
certificates, as specified in
, Section 5; the digest
algorithm used for the fingerprint MUST match that used
in the certificate signature.An "a=setup" line, as specified in
, Section 4, and clarified
for use in DTLS-SRTP scenarios in
, Section 5. The role value
in the answer MUST be "active" or "passive"; the "active"
role is RECOMMENDED.An "a=dtls-id" line, as specified in
Section 5.3.If present in the offer, an "a=rtcp-mux" line, as
specified in
, Section 5.1.3.
Otherwise, an "a=rtcp" line, as specified in
, Section 2.1, containing the
dummy value "9 IN IP4 0.0.0.0" (because no candidates have
yet been gathered).If present in the offer, an "a=rtcp-rsize" line, as
specified in
, Section 5.If a data channel m= section has been offered, a m=
section MUST also be generated for data. The <media>
field MUST be set to "application" and the <proto> and
"fmt" fields MUST be set to exactly match the fields in the
offer.Within the data m= section, the "a=mid", "a=ice-ufrag",
"a=ice-pwd", "a=candidate", "a=fingerprint", "a=dtls-id",
and "a=setup" lines MUST be included under the conditions described above,
along with an "a=fmtp:webrtc-datachannel" line and an
"a=sctp-port" line referencing the SCTP port number as
defined in
, Section
4.1.If "a=group" attributes with semantics of "BUNDLE" are
offered, corresponding session-level "a=group" attributes
MUST be added as specified in
. 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.Attributes that are common between all m= sections MAY be
moved to session-level, if explicitly defined to be valid at
session-level.The attributes prohibited in the creation of offers are
also prohibited in the creation of answers.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.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:
The fields of the "o=" line MUST stay the same except
for the <session-version> field, which MUST increment
if the session description changes in any way from the
previously generated answer.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:
The "s=" and "t=" lines MUST stay the same.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
, 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.The media formats on the m= line MUST be generated in the
same order as in the current local description.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
, Section 9.2.1.1. If the m=
section is bundled into another m= section, it still MUST
NOT contain any ICE credentials.Each "a=setup" line MUST use an "active" or "passive" role
value consistent with the existing DTLS association, if the
association is being continued by the offerer.If the m= section is not bundled into another m=
section and RTCP multiplexing is not active, an "a=rtcp" attribute
line MUST be filled in with the port and address of the default RTCP
candidate. If no RTCP candidates have yet been gathered, dummy values MUST be
used, as described in the initial answer section above.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
), an
"a=candidate" line MUST be added, as defined in
, 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
, Section 9.3.
If the m= section is bundled into another m= section, both
"a=candidate" and "a=end-of-candidates" MUST be
omitted.For RtpTransceivers that are not stopped, the "a=msid"
line MUST stay the same.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= sections
where the offerer chose to perform ICE restart.The following options are supported in
RTCAnswerOptions.Silence suppression in the answer is handled as
described in
, 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").The SDP returned from createOffer or createAnswer MUST NOT
be changed before passing it to setLocalDescription. If precise
control over the SDP is needed, the aforementioned
createOffer/createAnswer options or RtpTransceiver APIs MUST be
used.Note that the application MAY modify the SDP to reduce the
capabilities in the offer it sends to the far side
(post-setLocalDescription) or the offer that it installs from
the far side (pre-setRemoteDescription), as long as it remains
a valid SDP offer and specifies a subset of what was in the
original offer. This is safe because the answer is not
permitted to expand capabilities, and therefore will just
respond to what is present in the offer.The application SHOULD NOT modify the SDP in the answer it
transmits, as the answer contains the negotiated capabilities,
and this can cause the two sides to have different ideas about
what exactly was negotiated.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.When a SessionDescription is supplied to
setLocalDescription, the following steps MUST be performed:
First, the type of the SessionDescription is checked
against the current state of the PeerConnection:
If the type is "offer", the PeerConnection state MUST be
either "stable" or "have-local-offer".If the type is "pranswer" or "answer", the
PeerConnection state MUST be either "have-remote-offer" or
"have-local-pranswer".If the type is not correct for the current state,
processing MUST stop and an error MUST be returned.Next, the SessionDescription is parsed into a data
structure, as described in the
section below. If parsing
fails for any reason, processing MUST stop and an error MUST
be returned.Finally, the parsed SessionDescription is applied as
described in the
section below.When a SessionDescription is supplied to
setRemoteDescription, the following steps MUST be performed:
First, the type of the SessionDescription is checked
against the current state of the PeerConnection:
If the type is "offer", the PeerConnection state MUST be
either "stable" or "have-remote-offer".If the type is "pranswer" or "answer", the
PeerConnection state MUST be either "have-local-offer" or
"have-remote-pranswer".If the type is not correct for the current state,
processing MUST stop and an error MUST be returned.Next, the SessionDescription is parsed into a data
structure, as described in the
section below. If parsing
fails for any reason, processing MUST stop and an error MUST
be returned.Finally, the parsed SessionDescription is applied as
described in the
section
below.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.The SDP contained in the session description object consists
of a sequence of text lines, each containing a key-value
expression, as described in
, 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 to its defining ABNF, check
that it conforms to
and
semantics, and then either parse and
store or discard the provided value, as described below.If any line is not well-formed, or cannot be parsed as
described, the parser MUST stop with an error and reject the
session description, even if the value is to be discarded. This
ensures that implementations do not accidentally misinterpret
ambiguous SDP.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
, 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.The following non-attribute lines are not meaningful in
the JSEP context and MAY be discarded once they have been
checked.
The "c=" line MUST be checked for syntax but its value
is not used. This supersedes the guidance in
, 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.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.The remaining non-attribute lines are processed as
follows:
The "v=" line MUST have a version of 0, as specified in
, Section 5.1.The "o=" line MUST be parsed as specified in
, Section 5.2.The "b=" line, if present, MUST be parsed as specified
in
, Section 5.8, and the bwtype and
bandwidth values stored.Finally, the attribute lines are processed. Specific
processing MUST be applied for the following session-level
attribute ("a=") lines:
Any "a=group" lines are parsed as specified in
, Section 5, and the group's
semantics and mids are stored.If present, a single "a=ice-lite" line is parsed as
specified in
, Section 15.3, and a value
indicating the presence of ice-lite is stored.If present, a single "a=ice-ufrag" line is parsed as
specified in
, Section 15.4, and the ufrag
value is stored.If present, a single "a=ice-pwd" line is parsed as
specified in
, Section 15.4, and the password
value is stored.If present, a single "a=ice-options" line is parsed as
specified in
, Section 15.5, and the set of
specified options is stored.Any "a=fingerprint" lines are parsed as specified in
, Section 5, and the set of
fingerprint and algorithm values is stored.If present, a single "a=setup" line is parsed as
specified in
, Section 4, and the setup value
is stored.If present, a single "a=dtls-id" line is parsed as
specified in
Section 5,
and the dtls-id value is stored.Any "a=extmap" lines are parsed as specified in
, Section 5, and their values are
stored.Once all the session-level lines have been parsed,
processing continues with the lines in media sections.Like the session-level lines, the media session lines MUST
occur in the specific order and with the specific syntax
defined in
, Section 5.The "m=" line itself MUST be parsed as described in
, Section 5.14, and the media, port,
proto, and fmt values stored.Following the "m=" line, specific processing MUST be
applied for the following non-attribute lines:
As with the "c=" line at the session level, the "c="
line MUST be parsed according to
, Section 5.7, but its value is
not used.The "b=" line, if present, MUST be parsed as specified
in
, Section 5.8, and the bwtype and
bandwidth values stored.Specific processing MUST also be applied for the following
attribute lines:
If present, a single "a=ice-ufrag" line is parsed as
specified in
, Section 15.4, and the ufrag
value is stored.If present, a single "a=ice-pwd" line is parsed as
specified in
, Section 15.4, and the password
value is stored.If present, a single "a=ice-options" line is parsed as
specified in
, Section 15.5, and the set of
specified options is stored.Any "a=candidate" attributes MUST be parsed as specified
in
, Section 15.1, and their values
stored.Any "a=remote-candidates" attributes MUST be parsed as
specified in
, Section 15.2, but their values
are ignored.If present, a single "a=end-of-candidates" attribute
MUST be parsed as specified in
, Section 8.2, and
its presence or absence flagged and stored.Any "a=fingerprint" lines are parsed as specified in
, Section 5, and the set of
fingerprint and algorithm values is stored.If the "m=" proto value indicates use of RTP, as described
in the
section above, the
following attribute lines MUST be processed:
The "m=" fmt value MUST be parsed as specified in
, Section 5.14, and the individual
values stored.Any "a=rtpmap" or "a=fmtp" lines MUST be parsed as
specified in
, Section 6, and their values
stored.If present, a single "a=ptime" line MUST be parsed as
described in
, Section 6, and its value
stored.If present, a single "a=maxptime" line MUST be parsed as
described in
, Section 6, and its value
stored.If present, a single direction attribute line (e.g.
"a=sendrecv") MUST be parsed as described in
, Section 6, and its value
stored.Any "a=ssrc" or "a=ssrc-group" attributes MUST be parsed
as specified in
, Sections 4.1-4.2, and their
values stored.Any "a=extmap" attributes MUST be parsed as specified in
, Section 5, and their values
stored.Any "a=rtcp-fb" attributes MUST be parsed as specified
in
, Section 4.2., and their values
stored.If present, a single "a=rtcp-mux" attribute MUST be
parsed as specified in
, Section 5.1.3, and its presence
or absence flagged and stored.If present, a single "a=rtcp-mux-only" attribute MUST be
parsed as specified in
, Section 3,
and its presence or absence flagged and stored.If present, a single "a=rtcp-rsize" attribute MUST be
parsed as specified in
, Section 5, and its presence or
absence flagged and stored.If present, a single "a=rtcp" attribute MUST be parsed
as specified in
, Section 2.1, but its value is
ignored, as this information is superfluous when using
ICE.If present, a single "a=msid" attribute MUST be parsed
as specified in
, Section 3.2, and
its value stored.Any "a=imageattr" attributes MUST be parsed as specified
in
, Section 3, and their values
stored.Any "a=rid" lines MUST be parsed as specified in
, Section 10, and
their values stored.If present, a single "a=simulcast" line MUST be parsed
as specified in
, and
its values stored.Otherwise, if the "m=" proto value indicates use of SCTP,
the following attribute lines MUST be processed:
The "m=" fmt value MUST be parsed as specified in
, Section 4.3,
and the application protocol value stored.An "a=sctp-port" attribute MUST be present, and it MUST
be parsed as specified in
, Section 5.2,
and the value stored.If present, a single "a=max-message-size" attribute MUST
be parsed as specified in
, Section 6, and
the value stored. Otherwise, use the specified default.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:
For each m= section, valid values for each of the
mandatory-to-use features enumerated in
MUST be present.
These values MAY either be present at the media level, or
inherited from the session level.
ICE ufrag and password values, which MUST comply with
the size limits specified in
, Section 15.4.dtls-id value, which MUST be set according to
Section 5.
If this is a re-offer and the dtls-id value is different
from that presently in use, the DTLS connection is not being
continued and the remote description MUST be part of an
ICE restart, together with new ufrag and password
values. If this is an answer, the
dtls-id value, if present, MUST be the same as in the
offer.DTLS setup value, which MUST be set according to the
rules specified in ,
Section 5 and MUST
be consistent with the selected role of the current DTLS
connection, if one exists and is being continued.DTLS fingerprint values, where at least one
fingerprint MUST be present.All RID values referenced in an "a=simulcast" line MUST
exist as "a=rid" lines.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.If the RTP/RTCP multiplexing policy is "require", each m=
section MUST contain an "a=rtcp-mux" attribute.If this session description is of type "pranswer" or
"answer", the following additional checks are applied:
The session description must follow the rules defined in
, Section 6, including the
requirement that the number of m= sections MUST exactly
match the number of m= sections in the associated
offer.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.If any of the preceding checks failed, processing MUST stop
and an error MUST be returned.The following steps are performed at the media engine level
to apply a local description.First, the parsed parameters are checked to ensure that they
are identical to those generated in the last call to
createOffer/createAnswer, and thus have not been altered, as
discussed in ; otherwise,
processing MUST stop and an error MUST be returned.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.
If this media section is new, begin gathering candidates
for it, as defined in
, Section 4.1.1, unless it has been
marked as bundle-only.Or, if the ICE ufrag and password values have changed, and
it has not been marked as bundle-only, trigger the ICE Agent
to start an ICE restart, and begin gathering new candidates
for the media section as described in
, Section 9.1.1.1. If this
description is an answer, also start checks on that media
section as defined in
, Section 9.3.1.1.If the media section proto value indicates use of RTP:
If there is no RtpTransceiver associated with this m=
section (which will only happen when applying an offer),
find one and associate it with this m= section according to
the following steps:
Find the RtpTransceiver that corresponds to this m=
section, using the mapping between transceivers and m=
section indices established when creating the offer.Set the value of this RtpTransceiver's mid property to
the MID of the m= section.If RTCP mux is indicated, prepare to demux RTP and RTCP
from the RTP ICE component, as specified in
, Section 5.1.3. If RTCP mux is
not indicated, but was previously negotiated, i.e., the RTCP ICE
component no longer exists, this MUST result in an error.For each specified RTP header extension, establish a
mapping between the extension ID and URI, as described in
section 6 of
. If any indicated RTP header
extension is not supported, this MUST result in an
error.If the MID header extension is supported, prepare to
demux RTP streams intended for this media section based on the
MID header extension, as described in
, Section 14.For each specified media format, establish a mapping
between the payload type and the actual media format, as
described in
, Section 6.1. If any indicated
media format is not supported, this MUST result in an
error.For each specified "rtx" media format, establish a
mapping between the RTX payload type and its associated
primary payload type, as described in
, Sections 8.6 and 8.7. If any
referenced primary payload types are not present, this MUST
result in an error.If the directional attribute is of type "sendrecv" or
"recvonly", enable receipt and decoding of media.Finally, if this description is of type "pranswer" or
"answer", follow the processing defined in the
section below.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.The following steps are performed at the media engine level
to apply a remote description.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.
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
.
Within this overall limit, the implementation can dynamically decide
how to best allocate the available bandwidth between m= sections,
respecting any specific limits that have been specified for
individual m= sections.For any specified "RR" or "RS" bandwidth values, handle as
specified in
, Section 2.Any "AS" bandwidth value MUST be ignored, as the meaning
of this construct at the session level is not well
defined.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.
If the ICE ufrag or password changed from the previous
remote description, then an ICE restart is needed, as
described in Section 9.1.1.1 of
If the description is of type
"offer", mark that an ICE restart is needed. If the
description is of type "answer" and the current local
description is also an ICE restart, then signal the ICE agent
to begin checks as described in Section 9.3.1.1 of
. An answer MUST change the ufrag
and password in an answer if and only if ICE is restarting,
as described in Section 9.2.1.1 of
.Configure the ICE components associated with this media
section to use the supplied ICE remote ufrag and password for
their connectivity checks.Pair any supplied ICE candidates with any gathered local
candidates, as described in Section 5.7 of
and start connectivity checks with
the appropriate credentials.If an "a=end-of-candidates" attribute is present, process
the end-of-candidates indication as described in
Section 11.If the media section proto value indicates use of RTP:
If the m= section is being recycled (see
), dissociate
the currently associated RtpTransceiver by setting its mid
property to null, and discard the mapping between the
transceiver and its m= section index.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:
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
) such
RtpTransceiver.If no RtpTransceiver was found in the previous step,
create one with a recvonly direction.Associate the found or created RtpTransceiver with the
m= section by setting the value of the RtpTransceiver's
mid property to the MID of the m= section, and establish
a mapping between the transceiver and the index of the m=
section. If the m= section does not include a MID (i.e., the
remote endpoint does not support the MID extension),
generate a value for the RtpTransceiver mid property,
following the guidance for "a=mid" mentioned in
.For each specified media format that is also supported
by the local implementation, establish a mapping between
the specified payload type and the media format, as
described in
, Section 6.1. Specifically, this
means that the implementation records the payload type to
be used in outgoing RTP packets when sending each specified
media format, as well as the relative preference for each
format that is indicated in their ordering. If any
indicated media format is not supported by the local
implementation, it MUST be ignored.For each specified "rtx" media format, establish a
mapping between the RTX payload type and its associated
primary payload type, as described in
, Section 4. If any referenced
primary payload types are not present, this MUST result in
an error.For each specified fmtp parameter that is supported by
the local implementation, enable them on the associated
media formats.For each specified RTP header extension that is also
supported by the local implementation, establish a mapping
between the extension ID and URI, as described in
, Section 5. Specifically, this
means that the implementation records the extension ID to
be used in outgoing RTP packets when sending each specified
header extension. If any indicated RTP header extension is
not supported by the local implementation, it MUST be
ignored.For each specified RTCP feedback mechanism that is
supported by the local implementation, enable them on the
associated media formats.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
. If a "TIAS" value is not
present, but an "AS" value is specified, generate a "TIAS"
value using this formula:
TIAS = AS * 1000 * 0.95 - 50 * 40 * 8The 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. "TIAS" is used in preference
to "AS" because it provides more accurate control of bandwidth.
For any "RR" or "RS" bandwidth values, handle as
specified in
, Section 2.Any specified "CT" bandwidth value MUST be ignored, as
the meaning of this construct at the media level is not
well defined.If the media section is of type audio:
For each specified "CN" media format, enable DTX for
all supported media formats with the same clockrate,
as described in ,
Section 5, except for formats that have their own internal DTX
mechanisms. DTX for such formats (e.g., Opus) is controlled via
fmtp parameters, as discussed in
.For each specified "telephone-event" media format, enable DTMF
transmission for all supported media formats with the same
clockrate, as described in , Section
2.5.1.2. If the application attempts to transmit DTMF when using
a media format that does not have a corresponding telephone-event
format, this MUST result in an error.For any specified "ptime" value, configure the
available media formats to use the specified packet size.
If the specified size is not supported for a media
format, use the next closest value instead.Finally, if this description is of type "pranswer" or
"answer", follow the processing defined in the
section below.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".For each media section, the following steps MUST be
performed:
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, unless a non-rejected media section is
bundled with this media section, discard any associated ICE
components, as described in Section 9.2.1.3 of
.If the remote DTLS fingerprint has been changed or
the dtls-id has changed, tear down the DTLS connection.
If a DTLS connection needs to be torn down but the answer
does not indicate an ICE restart, an error MUST be generated.
If an ICE restart is performed without a change in dtls-id
or fingerprint, then the same DTLS connection is continued over
the new ICE channel.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.If the media section proto value indicates use of RTP:
If the media section references any media formats, RTP
header extensions, or RTCP feedback mechanisms that were
not present in the corresponding media section in the
offer, this indicates a negotiation problem and MUST result
in an error.If the media section has RTCP mux enabled, discard the
RTCP ICE component, if one exists, and begin or continue muxing
RTCP over the RTP ICE component, as specified in
, Section 5.1.3. Otherwise,
prepare to transmit RTCP over the RTCP ICE component; if no RTCP
ICE component exists, because RTCP mux was previously enabled, this
MUST result in an error.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
.If the directional attribute in the answer is of type
"sendrecv" or "sendonly", choose the media format to send as
the most preferred media format from the remote
description that is also present in the answer, as
described in
, Sections 6.1 and 7, and start
transmitting RTP media once the underlying transport layers have
been established. If a SSRC has not already been chosen for this
outgoing RTP stream, choose a random one.The payload type mapping
from the remote description is used to determine payload
types for the outgoing RTP streams, including the payload type for
the send media format chosen above. Any RTP header
extensions that were negotiated should be included in the
outgoing RTP streams, using the extension mapping from the
remote description; if the RID header extension has been
negotiated, and RID values are specified, include the RID
header extension in the outgoing RTP streams, as indicated
in
, Section 4.If simulcast has been negotiated, send the number of Source RTP
Streams as specified in
,
Section 6.2.2.If the send media format chosen above has a corresponding "rtx"
media format, or a FEC mechanism has been negotiated, establish a
Redundancy RTP Stream with a random SSRC for each Source RTP Stream,
and start or continue transmitting RTX/FEC packets as needed.
If the send media format chosen above has a corresponding "red"
media format of the same clockrate, allow redundant encoding using
the specified format for resiliency purposes, as discussed in
, Section 3.2. Note that unlike
RTX or FEC media formats, the "red" format is transmitted on the
Source RTP Stream, not the Redundancy RTP Stream.Enable the RTCP feedback mechanisms referenced in the media
section for all Source RTP Streams using the specified
media formats. Specifically,
begin or continue sending the requested feedback types and
reacting to received feedback, as specified in
, Section 4.2.
When sending RTCP feedback, follow the rules and
recommendations from ,
Section 5.4.1 to select which SSRC to use.
If the directional attribute is of type "recvonly" or
"inactive", stop transmitting all RTP media, but continue sending
RTCP, as described in
, Section 5.1.If the media section proto value indicates use of SCTP:
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
, Section
10.2.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
,
Section 8.2.If the description is of type "answer", and there are still
remaining candidates in the ICE candidate pool, discard them.When bundling, associating incoming RTP/RTCP with the proper
m= section is defined in . [The BUNDLE
draft does not currently contain the necessary text to describe
this demux, but when it does it will contain text like that
contained in .] When not bundling, the proper m= section is
clear from the ICE component over which the RTP/RTCP is
received.Once the proper m= section(s) are known, RTP/RTCP is
delivered to the RtpTransceiver(s) associated with the m=
section(s) and further processing of the RTP/RTCP is done at
the RtpTransceiver level. This includes using RID to distinguish between multiple
Encoded Streams, as well as determine which Source RTP stream
should be repaired by a given Redundancy RTP stream.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.More examples of SDP for WebRTC call flows can be found in
.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.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.The SDP for |offer-A1| looks like:The SDP for |answer-A1| looks like: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.The SDP for |offer-B1| looks like:The SDP for |candidate-B1| looks like:The SDP for |candidate-B2| looks like:The SDP for |answer-B1| looks like:The SDP for |candidate-B3| looks like:The SDP for |candidate-B4| looks like: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)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)The IETF has published separate documents
describing the security
architecture for WebRTC as a whole. The remainder of this section
describes security considerations for this document.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
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(), there is no guarantee that
applications do so. The browser MUST be prepared for the JS to
pass in bogus data instead.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.This document requires no actions from IANA.Significant text incorporated in the draft as well and review
was provided by Peter Thatcher, Taylor Brandstetter, Harald
Alvestrand and Suhas Nandakumar.
Dan Burnett, Neil Stratford, Anant Narayanan,
Andrew Hutton, Richard Ejzak,
Adam Bergkvist and Matthew Kaufman all provided
valuable feedback on this proposal.
Interactive Connectivity Establishment (ICE): A
Protocol for Network Address Translator (NAT) Traversal for
Offer/Answer ProtocolsThe Session Description Protocol (SDP) Grouping
FrameworkMultiplexing RTP Data and Control Packets on a Single
PortExtended RTP Profile for Real-time Transport Control
Protocol (RTCP)-Based Feedback (RTP/AVPF)SIP: Session Initiation ProtocolWebRTC Video Processing and Codec RequirementsA Transport Independent Bandwidth Modifier for the
Session Description Protocol (SDP)WebRTC Audio Codec and Processing RequirementsStream Control Transmission Protocol (SCTP)-Based
Media Transport in the Session Description Protocol
(SDP)Connection-Oriented Media Transport over the Transport
Layer Security (TLS) Protocol in the Session Description
Protocol (SDP)TCP-Based Media Transport in the Session Description
Protocol (SDP)Registering Values of the SDP 'proto' Field for Transporting RTP Media over TCP under Various RTP ProfilesThe Real-time Transport Protocol (RTP) specification establishes a registry of profile names for use by higher-level control protocols, such as the Session Description Protocol (SDP), to refer to the transport methods. This specification describes the following new SDP transport protocol identifiers for transporting RTP Media over TCP: 'TCP/RTP/AVPF', 'TCP/RTP/SAVP', 'TCP/RTP/SAVPF', 'TCP/DTLS/RTP/SAVP', 'TCP/DTLS/RTP/SAVPF', 'TCP/TLS/RTP/AVP', and 'TCP/TLS/RTP/AVPF'.A Framework for SDP Attributes when
MultiplexingA General Mechanism for RTP Header ExtensionsEncryption of Header Extensions in the Secure
Real-time Transport Protocol (SRTP)Web Real-Time Communication (WebRTC): Media Transport
and Use of RTPMultiplexing Negotiation Using Session Description
Protocol (SDP) Port NumbersCross Session Stream Identification in the Session
Description ProtocolSending Multiple RTP Streams in a Single RTP SessionSecurity Considerations for WebRTCWebRTC Security ArchitectureGuidelines for Writing RFC Text on Security
ConsiderationsKey words for use in RFCs to
Indicate Requirement LevelsHarvard University1350 Mass. Ave.CambridgeMA 02138- +1 617 495 3864sob@harvard.edu
General
keywordAn Offer/Answer Model with Session Description
Protocol (SDP)SDP: Session Description ProtocolReal Time Control Protocol (RTCP) attribute in Session
Description Protocol (SDP)WebRTC Forward Error Correction RequirementsDatagram Transport Layer Security Version 1.2Trickle ICE: Incremental
Provisioning of Candidates for the Interactive Connectivity
Establishment (ICE) ProtocolJitsiStrasbourg67000France+33 6 72 81 15 55emcho@jitsi.orgRTFM, Inc.2064 Edgewood DrivePalo AltoCA94303USA+1 650 678 2350ekr@rtfm.comGoogle747 6th St SKirklandWA98033USA+1 857 288 8888justin@uberti.name&yetpeter@andyet.comhttps://andyet.com/Negotiation of Generic Image Attributes in the Session
Description Protocol (SDP)Using Simulcast in SDP and RTP SessionsRTP Payload Format ConstraintsRTP Stream Identifier (RID) Source Description
(SDES)Indicating Exclusive Support of RTP/RTCP Multiplexing
using SDPUpdates to RFC 4572Using the SDP Offer/Answer Mechanism for DTLSSession Description Protocol (SDP) Bandwidth Modifiers
for RTP Control Protocol (RTCP) BandwidthSource-Specific Media Attributes in the Session
Description Protocol (SDP)Support for Reduced-Size Real-Time Transport Control
Protocol (RTCP): Opportunities and ConsequencesA Real-time Transport Protocol (RTP) Header Extension
for Client-to-Mixer Audio Level IndicationEarly Media and Ringing Tone Generation in the Session
Initiation Protocol (SIP)RTP Retransmission Payload FormatReal-time Transport Protocol (RTP) Payload for Comfort
Noise (CN)SDP for the WebRTCFramework for Establishing a Secure Real-time
Transport Protocol (SRTP) Security Context Using Datagram
Transport Layer Security (DTLS)Datagram Transport Layer Security (DTLS) Extension to
Establish Keys for the Secure Real-time Transport Protocol
(SRTP)Session Description Protocol (SDP) Security
Descriptions for Media StreamsWebRTC 1.0: Real-time Communication Between
BrowsersWebRTC IP Address Handling RecommendationsRTP Payload for DTMF Digits, Telephony Tones, and Telephony SignalsRTP: A Transport Protocol for Real-Time ApplicationsA Taxonomy of Semantics and Mechanisms for Real-Time Transport Protocol (RTP) SourcesThe terminology about, and associations among, Real-time Transport Protocol (RTP) sources can be complex and somewhat opaque. This document describes a number of existing and proposed properties and relationships among RTP sources and defines common terminology for discussing protocol entities and their relationships.For the syntax validation performed in
, the following list of ABNF
definitions is used:AttributeReferenceptime Section 9maxptime Section 9rtpmap Section 9recvonly Section 9sendrecv Section 9sendonly Section 9inactive Section 9framerate Section 9fmtp Section 9quality Section 9rtcp Section 2.1setup Sections 3, 4, and 5connection Sections 3, 4, and 5fingerprint Section 5rtcp-fb Section 4.2candidate Section 15.1remote-candidates Section 15.2ice-lite Section 15.3ice-ufrag Section 15.4ice-pwd Section 15.4ice-options Section 15.5extmap Section 7mid Section 4 and 5group Section 4 and 5imageattr Section 3.1extmap (encrypt option) Section 4msid Section 2rid Section 10 simulcastSection 6.1dtls-idSection 4The following text is meant to completely replace section
"Associating RTP/RTCP Streams With Correct SDP Media
Description" of .
As described in , RTP/RTCP packets
are associated with RTP streams as defined in .
Each RTP stream is identified by an SSRC value, and each
RTP/RTCP packet carries an SSRC value that is used to associate the packet with the correct
RTP stream. An RTCP packet can carry multiple SSRC values, and might therefore be associated
with multiple RTP streams.
In order to be able to process received RTP/RTCP packets correctly it must be possible
to associate an RTP stream with the correct "m=" line, as the "m=" line and SDP attributes
associated with the "m=" line contain information needed to process the packets.
As all RTP streams associated with a BUNDLE group use the same
address:port combination for sending and receiving RTP/RTCP packets, the
local address:port combination cannot be used to associate an RTP stream
with the correct "m=" line. In addition, multiple RTP streams might be
associated with the same "m=" line.
An offerer and answerer can inform each other which SSRC values they will use
for an RTP stream by using the SDP 'ssrc' attribute . However, an offerer will not know which SSRC values the
answerer will use until the offerer has received the answer providing that information.
Due to this, before the offerer has received the answer, the offerer will not be
able to associate an RTP stream with the correct "m=" line using the SSRC value associated
with the RTP stream. In addition, the offerer and answerer may start using new SSRC
values mid-session, without informing each other using the SDP 'ssrc' attribute.
In order for an offerer and answerer to always be able to associate an RTP stream
with the correct "m=" line, the offerer and answerer using the BUNDLE extension MUST
support the mechanism defined in section 14.
where the offerer and answerer insert the identification-tag
associated with an "m=" line (provided by the remote peer)
into RTP and RTCP packets associated with a BUNDLE group.
The mapping from an SSRC to an identification-tag is carried in RTCP
SDES packets or in RTP header extensions ( section 14).
Since a compound RTCP packet can contain multiple
RTCP SDES packets, and each RTCP SDES packet can contain multiple chunks, an
RTCP packet can contain several SSRC to identification-tag mappings. The offerer
and answerer maintain tables used for routing that are
updated each time an RTP/RTCP packet contains new
information that affects how packets should be routed.
To prepare for demultiplexing RTP packets to the correct "m="
line, the following steps MUST be followed for each BUNDLE
group.Construct a table mapping MID to "m=" line for each "m="
line in this BUNDLE group. Note that an "m=" line may only
have one MID.Construct a table mapping incoming SSRC to "m=" line for
each "m=" line in this BUNDLE group and for each SSRC
configured for receiving in that "m=" line.Construct a table mapping outgoing SSRC to "m=line" for
each "m=" line in this BUNDLE group and for each SSRC
configured for sending in that "m=" line.Construct a table mapping payload type to "m=" line for
each "m=" line in the BUNDLE group and for each payload type
configured for receiving in that "m=" line. If any payload
type is configured for receiving in more than one "m=" line
in the BUNDLE group, do not it include it in the table.Note that for each of these tables, there can only be one
mapping for any given key (MID, SSRC, or PT). In other
words, the tables are not multimaps.As "m=" lines are added or removed from the BUNDLE groups, or
their configurations are changed, the tables above MUST also
be updated.For each RTP packet received, the following steps MUST be
followed to route the packet to the correct "m=" section within
a BUNDLE group. Note that the phrase 'deliver a packet to the
"m=" line' means to further process the packet as would normally
happen with RTP/RTCP, if it were received on a transport
associated with that "m=" line outside of a BUNDLE group (i.e., if the
"m=" line were not BUNDLEd), including dropping an RTP packet if
the packet's PT does not match any PT in the "m=" line.If the packet has a MID and that MID is not in the table
mapping MID to "m=" line, drop the packet and stop.If the packet has a MID and that MID is in the table
mapping MID to "m=" line, update the incoming SSRC mapping
table to include an entry that maps the packet's SSRC to the
"m=" line for that MID.If the packet's SSRC is in the incoming SSRC mapping
table, route the packet to the associated "m=" line and
stop.If the packet's payload type is in the payload type
table, update the the incoming SSRC mapping table to include
an entry that maps the packet's SSRC to the
"m=" line for that payload type. In addition, route the packet
to the associated "m=" line and stop.Otherwise, drop the packet.For each RTCP packet received (including each RTCP packet
that is part of a compound RTCP packet), the packet MUST be
routed to the appropriate handler for the SSRCs it contains
information about. Some examples of such handling are given
below.If the packet is of type SR, and the sender SSRC for the
packet is found in the incoming SSRC table, deliver a copy of the
packet to the "m=" line associated with that SSRC. In addition,
for each report block in the report whose SSRC is found in the
outgoing SSRC table, deliver a copy of the RTCP packet to the
"m=" line associated with that SSRC.If the packet is of type RR, for each report block in the
packet whose SSRC is found in the outgoing SSRC table, deliver a copy
of the RTCP packet to the "m=" line associated with that SSRC.If the packet is of type SDES, and the sender SSRC for
the packet is found in the incoming SSRC table, deliver the
packet to the "m=" line associated with that SSRC. In addition, for
each chunk in the packet that contains a MID that is in the table
mapping MID to "m=" line, update the incoming SSRC mapping
table to include an entry that maps the SSRC for that chunk to
the "m=" line associated with that MID. (This case can occur
when RTCP for a source is received before any RTP packets.)If the packet is of type BYE, for each SSRC indicated in the
packet that is found in the incoming SSRC table, deliver a copy of the
packet to the "m=" line associated with that SSRC.If the packet is of type RTPFB or PSFB, as defined in
, and the media source SSRC for the packet
is found in the outgoing SSRC table, deliver the packet
to the "m=" line associated with that SSRC.Note: This section will be removed by RFC Editor before
publication.Changes in draft-18:Update demux algorithm and move it to an appendix in
preparation for merging it into BUNDLE.Clarify why we can't handle an incoming offer to
send simulcast.Expand IceCandidate object text.Further document use of ICE candidate pool.Document removeTrack.Update requirements to only accept the last
generated offer/answer as an argument to setLocalDescription.Allow round pixels.Fix code around default timing when AVPF is not specified.Clean up terminology around m= line and m=section.Provide a more realistic example for minimum decoder capabilities.Document behavior when rtcp-mux policy is require but rtcp-mux
attribute not provided.Expanded discussion of RtpSender and RtpReceiver.Add RtpTransceiver.currentDirection and document setDirection.Require imageattr x=0, y=0 to indicate that there are no valid resolutions.Require a privacy-preserving MID/RID construction.Require support for RFC 3556 bandwidth modifiers.Update maxptime description.Note that endpoints may encounter extra codecs in answers and subsequent offers
from non-JSEP peers.Update references.Changes in draft-17:Split createOffer and createAnswer sections to clearly indicate
attributes which always appear and which only appear when
not bundled into another m= section.Add descriptions of RtpTransceiver methods.Describe how to process RTCP feedback attributes.Clarify transceiver directions and their interaction with 3264.Describe setCodecPreferences.Update RTP demux algorithm. Include RTCP.Update requirements for when a=rtcp is included, limiting
to cases where it is needed for backward compatibility.Clarify SAR handling.Updated addTrack matching algorithm.Remove a=ssrc requirements.Handle a=setup in reoffers.Discuss how RTX/FEC should be handled.Discuss how telephone-event should be handled.Discuss how CN/DTX should be handled.Add missing references to ABNF table.Changes in draft-16:Update addIceCandidate to indicate ICE generation and
allow per-m= section end-of-candidates.Update fingerprint handling to use
draft-ietf-mmusic-4572-update.Update text around SDP processing of RTP header extensions
and payload formats.Add sections on simulcast, addTransceiver, and
createDataChannel.Clarify text to ensure that the session ID is a positive
63 bit integer.Clarify SDP processing for direction indication.Describe SDP processing for rtcp-mux-only.Specify how SDP session version in o= line.Require that when doing an re-offer, the capabilities of
the new session are mostly required to be a subset of the
previously negotiated session.Clarified ICE restart interaction with bundle-only.Remove support for changing SDP before calling
setLocalDescription.Specify algorithm for demuxing RTP based on MID, PT, and
SSRC.Clarify rules for rejecting m= lines when bundle policy is
balanced or max-bundle.Changes in draft-15:Clarify text around codecs offered in subsequent
transactions to refer to what's been negotiated.Rewrite LS handling text to indicate edge cases and that
we're living with them.Require that answerer reject m= lines when there are no
codecs in common.Enforce max-bundle on offer processing.Fix TIAS formula to handle bits vs. kilobits.Describe addTrack algorithm.Clean up references.Changes in draft-14:Added discussion of RtpTransceivers + RtpSenders +
RtpReceivers, and how they interact with
createOffer/createAnswer.Removed obsolete OfferToReceiveX options.Explained how addIceCandidate can be used for
end-of-candidates.Changes in draft-13:Clarified which SDP lines can be ignored.Clarified how to handle various received attributes.Revised how attributes should be generated for bundled m=
lines.Remove unused references.Remove text advocating use of unilateral PTs.Trigger an ICE restart even if the ICE candidate policy is
being made more strict.Remove the 'public' ICE candidate policy.Move open issues into GitHub issues.Split local/remote description accessors into
current/pending.Clarify a=imageattr handling.Add more detail on VoiceActivityDetection handling.Reference draft-shieh-rtcweb-ip-handling.Make it clear when an ICE restart should occur.Resolve changes needed in references.Remove MSID semantics.ice-options are now at session level.Default RTCP mux policy is now 'require'.Changes in draft-12:Filled in sections on applying local and remote
descriptions.Discussed downscaling and upscaling to fulfill imageattr
requirements.Updated what SDP can be modified by the application.Updated to latest datachannel SDP.Allowed multiple fingerprint lines.Switched back to IPv4 for dummy candidates.Added additional clarity on ICE default candidates.Changes in draft-11:Clarified handling of RTP CNAMEs.Updated what SDP lines should be processed or ignored.Specified how a=imageattr should be used.Changes in draft-10: Described video size negotiation with imageattr. Clarified rejection of sections that do not have mux-only. Add handling of LS groups Changes in draft-09:Don't return null for {local,remote}Description after
close().Changed TCP/TLS to UDP/DTLS in RTP profile names.Separate out bundle and mux policy.Added specific references to FEC mechanisms.Added canTrickle mechanism.Added section on subsequent answers and, answer
options.Added text defining set{Local,Remote}Description
behavior.Changes in draft-08:
Added new example section and removed old examples in
appendix.Fixed <proto> field handling.Added text describing a=rtcp attribute.Reworked handling of OfferToReceiveAudio and
OfferToReceiveVideo per discussion at IETF 90.Reworked trickle ICE handling and its impact on m= and c=
lines per discussion at interim.Added max-bundle-and-rtcp-mux policy.Added description of maxptime handling.Updated ICE candidate pool default to 0.Resolved open issues around AppID/receiver-ID.Reworked and expanded how changes to the ICE configuration
are handled.Some reference updates.Editorial clarification.Changes in draft-07:
Expanded discussion of VAD and Opus DTX.Added a security considerations section.Rewrote the section on modifying SDP to require
implementations to clearly indicate whether any given
modification is allowed.Clarified impact of IceRestart on CreateOffer in local-offer
state.Guidance on whether attributes should be defined at the
media level or the session level.Renamed "default" bundle policy to "balanced".Removed default ICE candidate pool size and clarify how it
works.Defined a canonical order for assignment of MSTs to m=
lines.Removed discussion of rehydration.Added Eric Rescorla as a draft editor.Cleaned up references.Editorial cleanupChanges in draft-06:
Reworked handling of m= line recycling.Added handling of BUNDLE and bundle-only.Clarified handling of rollback.Added text describing the ICE Candidate Pool and its
behavior.Allowed OfferToReceiveX to create multiple recvonly m=
sections.Changes in draft-05:
Fixed several issues identified in the createOffer/Answer
sections during document review.Updated references.Changes in draft-04:
Filled in sections on createOffer and createAnswer.Added SDP examples.Fixed references.Changes in draft-03:
Added text describing relationship to W3C specificationChanges in draft-02:
Converted from nroffRemoved comparisons to old approaches abandoned by the
working groupRemoved stuff that has moved to W3C specificationAlign SDP handling with W3C draftClarified section on forking.Changes in draft-01:
Added diagrams for architecture and state machine.Added sections on forking and rehydration.Clarified meaning of "pranswer" and "answer".Reworked how ICE restarts and media directions are
controlled.Added list of parameters that can be changed in a
description.Updated suggested API and examples to match latest
thinking.Suggested API and examples have been moved to an
appendix.Changes in draft -00:
Migrated from draft-uberti-rtcweb-jsep-02.