rfc8829.form.txt | rfc8829.txt | |||
---|---|---|---|---|
Internet Engineering Task Force (IETF) J. Uberti | Internet Engineering Task Force (IETF) J. Uberti | |||
Request for Comments: 0000 Google | Request for Comments: 8829 Google | |||
Category: Standards Track C. Jennings | Category: Standards Track C. Jennings | |||
ISSN: 2070-1721 Cisco | ISSN: 2070-1721 Cisco | |||
E.K. Rescorla, Ed. | E. Rescorla, Ed. | |||
Mozilla | Mozilla | |||
May 2020 | July 2020 | |||
JavaScript Session Establishment Protocol | JavaScript Session Establishment Protocol (JSEP) | |||
Abstract | Abstract | |||
This document describes the mechanisms for allowing a JavaScript | This document describes the mechanisms for allowing a JavaScript | |||
application to control the signaling plane of a multimedia session | application to control the signaling plane of a multimedia session | |||
via the interface specified in the W3C RTCPeerConnection API, and | via the interface specified in the W3C RTCPeerConnection API and | |||
discusses how this relates to existing signaling protocols. | discusses how this relates to existing signaling protocols. | |||
Status of This Memo | Status of This Memo | |||
This is an Internet Standards Track document. | This is an Internet Standards Track document. | |||
This document is a product of the Internet Engineering Task Force | This document is a product of the Internet Engineering Task Force | |||
(IETF). It represents the consensus of the IETF community. It has | (IETF). It represents the consensus of the IETF community. It has | |||
received public review and has been approved for publication by the | received public review and has been approved for publication by the | |||
Internet Engineering Steering Group (IESG). Further information on | Internet Engineering Steering Group (IESG). Further information on | |||
Internet Standards is available in Section 2 of RFC 7841. | Internet Standards is available in Section 2 of RFC 7841. | |||
Information about the current status of this document, any errata, | Information about the current status of this document, any errata, | |||
and how to provide feedback on it may be obtained at | and how to provide feedback on it may be obtained at | |||
https://www.rfc-editor.org/info/rfc0000. | https://www.rfc-editor.org/info/rfc8829. | |||
Copyright Notice | Copyright Notice | |||
Copyright (c) 2020 IETF Trust and the persons identified as the | Copyright (c) 2020 IETF Trust and the persons identified as the | |||
document authors. All rights reserved. | document authors. All rights reserved. | |||
This document is subject to BCP 78 and the IETF Trust's Legal | This document is subject to BCP 78 and the IETF Trust's Legal | |||
Provisions Relating to IETF Documents | Provisions Relating to IETF Documents | |||
(https://trustee.ietf.org/license-info) in effect on the date of | (https://trustee.ietf.org/license-info) in effect on the date of | |||
publication of this document. Please review these documents | publication of this document. Please review these documents | |||
skipping to change at line 73 ¶ | skipping to change at line 73 ¶ | |||
3.5.1. ICE Gathering Overview | 3.5.1. ICE Gathering Overview | |||
3.5.2. ICE Candidate Trickling | 3.5.2. ICE Candidate Trickling | |||
3.5.2.1. ICE Candidate Format | 3.5.2.1. ICE Candidate Format | |||
3.5.3. ICE Candidate Policy | 3.5.3. ICE Candidate Policy | |||
3.5.4. ICE Candidate Pool | 3.5.4. ICE Candidate Pool | |||
3.5.5. ICE Versions | 3.5.5. ICE Versions | |||
3.6. Video Size Negotiation | 3.6. Video Size Negotiation | |||
3.6.1. Creating an imageattr Attribute | 3.6.1. Creating an imageattr Attribute | |||
3.6.2. Interpreting imageattr Attributes | 3.6.2. Interpreting imageattr Attributes | |||
3.7. Simulcast | 3.7. Simulcast | |||
3.8. Interactions With Forking | 3.8. Interactions with Forking | |||
3.8.1. Sequential Forking | 3.8.1. Sequential Forking | |||
3.8.2. Parallel Forking | 3.8.2. Parallel Forking | |||
4. Interface | 4. Interface | |||
4.1. PeerConnection | 4.1. PeerConnection | |||
4.1.1. Constructor | 4.1.1. Constructor | |||
4.1.2. addTrack | 4.1.2. addTrack | |||
4.1.3. removeTrack | 4.1.3. removeTrack | |||
4.1.4. addTransceiver | 4.1.4. addTransceiver | |||
4.1.5. createDataChannel | 4.1.5. createDataChannel | |||
4.1.6. createOffer | 4.1.6. createOffer | |||
skipping to change at line 137 ¶ | skipping to change at line 137 ¶ | |||
5.9. Applying a Local Description | 5.9. Applying a Local Description | |||
5.10. Applying a Remote Description | 5.10. Applying a Remote Description | |||
5.11. Applying an Answer | 5.11. Applying an Answer | |||
6. Processing RTP/RTCP | 6. Processing RTP/RTCP | |||
7. Examples | 7. Examples | |||
7.1. Simple Example | 7.1. Simple Example | |||
7.2. Detailed Example | 7.2. Detailed Example | |||
7.3. Early Transport Warmup Example | 7.3. Early Transport Warmup Example | |||
8. Security Considerations | 8. Security Considerations | |||
9. IANA Considerations | 9. IANA Considerations | |||
10. Acknowledgements | 10. References | |||
11. References | 10.1. Normative References | |||
11.1. Normative References | 10.2. Informative References | |||
11.2. Informative References | Appendix A. ABNF Definitions | |||
Appendix A. Appendix A | Acknowledgements | |||
Appendix B. Change log | ||||
Authors' Addresses | Authors' Addresses | |||
1. Introduction | 1. Introduction | |||
This document describes how the W3C WEBRTC RTCPeerConnection | This document describes how the W3C Web Real-Time Communication | |||
interface [W3C.webrtc] is used to control the setup, management and | (WebRTC) RTCPeerConnection interface [W3C.webrtc] is used to control | |||
teardown of a multimedia session. | the setup, management, and teardown of a multimedia session. | |||
1.1. General Design of JSEP | 1.1. General Design of JSEP | |||
WebRTC call setup has been designed to focus on controlling the media | WebRTC call setup has been designed to focus on controlling the media | |||
plane, leaving signaling plane behavior up to the application as much | plane, leaving signaling-plane behavior up to the application as much | |||
as possible. The rationale is that different applications may prefer | as possible. The rationale is that different applications may prefer | |||
to use different protocols, such as the existing SIP call signaling | to use different protocols, such as the existing SIP call signaling | |||
protocol, or something custom to the particular application, perhaps | protocol, or something custom to the particular application, perhaps | |||
for a novel use case. In this approach, the key information that | for a novel use case. In this approach, the key information that | |||
needs to be exchanged is the multimedia session description, which | needs to be exchanged is the multimedia session description, which | |||
specifies the necessary transport and media configuration information | specifies the transport and media configuration information necessary | |||
necessary to establish the media plane. | to establish the media plane. | |||
With these considerations in mind, this document describes the | With these considerations in mind, this document describes the | |||
JavaScript Session Establishment Protocol (JSEP) that allows for full | JavaScript Session Establishment Protocol (JSEP), which allows for | |||
control of the signaling state machine from JavaScript. As described | full control of the signaling state machine from JavaScript. As | |||
above, JSEP assumes a model in which a JavaScript application | described above, JSEP assumes a model in which a JavaScript | |||
executes inside a runtime containing WebRTC APIs (the "JSEP | application executes inside a runtime containing WebRTC APIs (the | |||
implementation"). The JSEP implementation is almost entirely | "JSEP implementation"). The JSEP implementation is almost entirely | |||
divorced from the core signaling flow, which is instead handled by | divorced from the core signaling flow, which is instead handled by | |||
the JavaScript making use of two interfaces: (1) passing in local and | the JavaScript making use of two interfaces: (1) passing in local and | |||
remote session descriptions and (2) interacting with the ICE state | remote session descriptions and (2) interacting with the Interactive | |||
machine. The combination of the JSEP implementation and the | Connectivity Establishment (ICE) state machine [RFC8445]. The | |||
JavaScript application is referred to throughout this document as a | combination of the JSEP implementation and the JavaScript application | |||
"JSEP endpoint". | is referred to throughout this document as a "JSEP endpoint". | |||
In this document, the use of JSEP is described as if it always occurs | In this document, the use of JSEP is described as if it always occurs | |||
between two JSEP endpoints. Note though in many cases it will | between two JSEP endpoints. Note, though, that in many cases it will | |||
actually be between a JSEP endpoint and some kind of server, such as | actually be between a JSEP endpoint and some kind of server, such as | |||
a gateway or MCU. This distinction is invisible to the JSEP | a gateway or Multipoint Control Unit (MCU). This distinction is | |||
endpoint; it just follows the instructions it is given via the API. | invisible to the JSEP endpoint; it just follows the instructions it | |||
is given via the API. | ||||
JSEP's handling of session descriptions is simple and | JSEP's handling of session descriptions is simple and | |||
straightforward. Whenever an offer/answer exchange is needed, the | straightforward. Whenever an offer/answer exchange is needed, the | |||
initiating side creates an offer by calling a createOffer() API. 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 | application then uses that offer to set up its local config via the | |||
setLocalDescription() API. The offer is finally sent off to the | setLocalDescription() API. The offer is finally sent off to the | |||
remote side over its preferred signaling mechanism (e.g., | remote side over its preferred signaling mechanism (e.g., | |||
WebSockets); upon receipt of that offer, the remote party installs it | WebSockets); upon receipt of that offer, the remote party installs it | |||
using the setRemoteDescription() API. | using the setRemoteDescription() API. | |||
skipping to change at line 207 ¶ | skipping to change at line 207 ¶ | |||
additional offer/answer exchanges. | additional offer/answer exchanges. | |||
Regarding ICE [RFC8445], JSEP decouples the ICE state machine from | Regarding ICE [RFC8445], JSEP decouples the ICE state machine from | |||
the overall signaling state machine, as the ICE state machine must | the overall signaling state machine, as the ICE state machine must | |||
remain in the JSEP implementation, because only the implementation | remain in the JSEP implementation, because only the implementation | |||
has the necessary knowledge of candidates and other transport | has the necessary knowledge of candidates and other transport | |||
information. Performing this separation provides additional | information. Performing this separation provides additional | |||
flexibility in protocols that decouple session descriptions from | flexibility in protocols that decouple session descriptions from | |||
transport. For instance, in traditional SIP, each offer or answer is | transport. For instance, in traditional SIP, each offer or answer is | |||
self-contained, including both the session descriptions and the | self-contained, including both the session descriptions and the | |||
transport information. However, [RFCYYY8] allows SIP to be used with | transport information. However, [RFC8840] allows SIP to be used with | |||
trickle ICE [RFCYYY6], in which the session description can be sent | Trickle ICE [RFC8838], in which the session description can be sent | |||
immediately and the transport information can be sent when available. | immediately and the transport information can be sent when available. | |||
Sending transport information separately can allow for faster ICE and | Sending transport information separately can allow for faster ICE and | |||
DTLS startup, since ICE checks can start as soon as any transport | DTLS startup, since ICE checks can start as soon as any transport | |||
information is available rather than waiting for all of it. JSEP's | information is available rather than waiting for all of it. JSEP's | |||
decoupling of the ICE and signaling state machines allows it to | decoupling of the ICE and signaling state machines allows it to | |||
accommodate either model. | accommodate either model. | |||
Through its abstraction of signaling, the JSEP approach does require | Through its abstraction of signaling, the JSEP approach does require | |||
the application to be aware of the signaling process. While the | the application to be aware of the signaling process. While the | |||
application does not need to understand the contents of session | application does not need to understand the contents of session | |||
descriptions to set up a call, the application must call the right | descriptions to set up a call, the application must call the right | |||
APIs at the right times, convert the session descriptions and ICE | APIs at the right times, convert the session descriptions and ICE | |||
information into the defined messages of its chosen signaling | information into the defined messages of its chosen signaling | |||
protocol, and perform the reverse conversion on the messages it | protocol, and perform the reverse conversion on the messages it | |||
receives from the other side. | receives from the other side. | |||
One way to make life easier for the application is to provide a | One way to make life easier for the application is to provide a | |||
JavaScript library that hides this complexity from the developer; | JavaScript library that hides this complexity from the developer; | |||
said library would implement a given signaling protocol along with | said library would implement a given signaling protocol along with | |||
its state machine and serialization code, presenting a higher level | its state machine and serialization code, presenting a higher-level | |||
call-oriented interface to the application developer. For example, | call-oriented interface to the application developer. For example, | |||
libraries exist to adapt the JSEP API into an API suitable for a SIP | libraries exist to adapt the JSEP API into an API suitable for a SIP | |||
or XMPP. Thus, JSEP provides greater control for the experienced | interface or an Extensible Messaging and Presence Protocol (XMPP) | |||
developer without forcing any additional complexity on the novice | interface [RFC6120]. Thus, JSEP provides greater control for the | |||
developer. | experienced developer without forcing any additional complexity on | |||
the novice developer. | ||||
1.2. Other Approaches Considered | 1.2. Other Approaches Considered | |||
One approach that was considered instead of JSEP was to include a | One approach that was considered instead of JSEP was to include a | |||
lightweight signaling protocol. Instead of providing session | lightweight signaling protocol. Instead of providing session | |||
descriptions to the API, the API would produce and consume messages | descriptions to the API, the API would produce and consume messages | |||
from this protocol. While providing a more high-level API, this put | from this protocol. While providing a more high-level API, this put | |||
more control of signaling within the JSEP implementation, forcing it | more control of signaling within the JSEP implementation, forcing it | |||
to have to understand and handle concepts like signaling glare (see | to have to understand and handle concepts like signaling glare (see | |||
[RFC3264], Section 4). | [RFC3264], Section 4). | |||
skipping to change at line 260 ¶ | skipping to change at line 261 ¶ | |||
would not be beneficial; it would result in an API where even a | would not be beneficial; it would result in an API where even a | |||
simple example would require a significant amount of code to | simple example would require a significant amount of code to | |||
orchestrate all the needed interactions, as well as creating a large | orchestrate all the needed interactions, as well as creating a large | |||
API surface that needed to be agreed upon and documented. In | API surface that needed to be agreed upon and documented. In | |||
addition, these API points could be called in any order, resulting 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 | a more complex set of interactions with the media subsystem than the | |||
JSEP approach, which specifies how session descriptions are to be | JSEP approach, which specifies how session descriptions are to be | |||
evaluated and applied. | evaluated and applied. | |||
One variation on JSEP that was considered was to keep the basic | One variation on JSEP that was considered was to keep the basic | |||
session description-oriented API, but to move the mechanism for | session-description-oriented API but to move the mechanism for | |||
generating offers and answers out of the JSEP implementation. | generating offers and answers out of the JSEP implementation. | |||
Instead of providing createOffer/createAnswer methods within the | Instead of providing createOffer/createAnswer methods within the | |||
implementation, this approach would instead expose a getCapabilities | implementation, this approach would instead expose a getCapabilities | |||
API which would provide the application with the information it | API, which would provide the application with the information it | |||
needed in order to generate its own session descriptions. This | needed in order to generate its own session descriptions. This | |||
increases the amount of work that the application needs to do; it | increases the amount of work that the application needs to do; it | |||
needs to know how to generate session descriptions from capabilities, | needs to know how to generate session descriptions from capabilities, | |||
and especially how to generate the correct answer from an arbitrary | and especially how to generate the correct answer from an arbitrary | |||
offer and the supported capabilities. While this could certainly be | offer and the supported capabilities. While this could certainly be | |||
addressed by using a library like the one mentioned above, it | addressed by using a library like the one mentioned above, it | |||
basically forces the use of said library even for a simple example. | basically forces the use of said library even for a simple example. | |||
Providing createOffer/createAnswer avoids this problem. | Providing createOffer/createAnswer avoids this problem. | |||
2. Terminology | 2. Terminology | |||
skipping to change at line 327 ¶ | skipping to change at line 328 ¶ | |||
parameters are determined by the exchange of session descriptions in | parameters are determined by the exchange of session descriptions in | |||
offers and answers, and there are certain details to this process | offers and answers, and there are certain details to this process | |||
that must be handled in the JSEP APIs. | that must be handled in the JSEP APIs. | |||
Whether a session description applies to the local side or the remote | Whether a session description applies to the local side or the remote | |||
side affects the meaning of that description. For example, the list | side affects the meaning of that description. For example, the list | |||
of codecs sent to a remote party indicates what the local side is | of codecs sent to a remote party indicates what the local side is | |||
willing to receive, which, when intersected with the set of codecs | willing to receive, which, when intersected with the set of codecs | |||
the remote side supports, specifies what the remote side should send. | the remote side supports, specifies what the remote side should send. | |||
However, not all parameters follow this rule; some parameters are | However, not all parameters follow this rule; some parameters are | |||
declarative and the remote side MUST either accept them or reject | declarative, and the remote side MUST either accept them or reject | |||
them altogether. An example of such a parameter is the DTLS | them altogether. An example of such a parameter is the DTLS | |||
fingerprints [RFC8122], which are calculated based on the local | fingerprints [RFC8122], which are calculated based on the local | |||
certificate(s) offered, and are not subject to negotiation. | certificate(s) offered and are not subject to negotiation. | |||
In addition, various RFCs put different conditions on the format of | In addition, various RFCs put different conditions on the format of | |||
offers versus answers. For example, an offer may propose an | offers versus answers. For example, an offer may propose an | |||
arbitrary number of m= sections (i.e., media descriptions as | arbitrary number of "m=" sections (i.e., media descriptions as | |||
described in [RFC4566], Section 5.14), but an answer must contain the | described in [RFC4566], Section 5.14), but an answer must contain the | |||
exact same number as the offer. | exact same number as the offer. | |||
Lastly, while the exact media parameters are only known only after an | Lastly, while the exact media parameters are known only after an | |||
offer and an answer have been exchanged, the offerer may receive ICE | offer and an answer have been exchanged, the offerer may receive ICE | |||
checks, and possibly media (e.g., in the case of a re-offer after a | checks, and possibly media (e.g., in the case of a re-offer after a | |||
connection has been established) before it receives an answer. To | connection has been established) before it receives an answer. To | |||
properly process incoming media in this case, the offerer's media | properly process incoming media in this case, the offerer's media | |||
handler must be aware of the details of the offer before the answer | handler must be aware of the details of the offer before the answer | |||
arrives. | arrives. | |||
Therefore, in order to handle session descriptions properly, the JSEP | Therefore, in order to handle session descriptions properly, the JSEP | |||
implementation needs: | implementation needs: | |||
skipping to change at line 361 ¶ | skipping to change at line 362 ¶ | |||
2. To know if a session description is an offer or an answer. | 2. To know if a session description is an offer or an answer. | |||
3. To allow the offer to be specified independently of the answer. | 3. To allow the offer to be specified independently of the answer. | |||
JSEP addresses this by adding both setLocalDescription and | JSEP addresses this by adding both setLocalDescription and | |||
setRemoteDescription methods and having session description objects | setRemoteDescription methods and having session description objects | |||
contain a type field indicating the type of session description being | contain a type field indicating the type of session description being | |||
supplied. This satisfies the requirements listed above for both the | supplied. This satisfies the requirements listed above for both the | |||
offerer, who first calls setLocalDescription(sdp [offer]) and then | offerer, who first calls setLocalDescription(sdp [offer]) and then | |||
later setRemoteDescription(sdp [answer]), as well as for the | later setRemoteDescription(sdp [answer]), and the answerer, who first | |||
answerer, who first calls setRemoteDescription(sdp [offer]) and then | calls setRemoteDescription(sdp [offer]) and then later | |||
later setLocalDescription(sdp [answer]). | setLocalDescription(sdp [answer]). | |||
During the offer/answer exchange, the outstanding offer is considered | During the offer/answer exchange, the outstanding offer is considered | |||
to be "pending" at the offerer and the answerer, as it may either be | to be "pending" at the offerer and the answerer, as it may be either | |||
accepted or rejected. If this is a re-offer, each side will also | accepted or rejected. If this is a re-offer, each side will also | |||
have "current" local and remote descriptions, which reflect the | have "current" local and remote descriptions, which reflect the | |||
result of the last offer/answer exchange. Sections 4.1.12, 4.1.14, | result of the last offer/answer exchange. Sections 4.1.12, 4.1.14, | |||
4.1.11, and 4.1.13, provide more detail on pending and current | 4.1.11, and 4.1.13 provide more detail on pending and current | |||
descriptions. | descriptions. | |||
JSEP also allows for an answer to be treated as provisional by the | JSEP also allows for an answer to be treated as provisional by the | |||
application. Provisional answers provide a way for an answerer to | application. Provisional answers provide a way for an answerer to | |||
communicate initial session parameters back to the offerer, in order | communicate initial session parameters back to the offerer, in order | |||
to allow the session to begin, while allowing a final answer to be | 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 | specified later. This concept of a final answer is important to the | |||
offer/answer model; when such an answer is received, any extra | offer/answer model; when such an answer is received, any extra | |||
resources allocated by the caller can be released, now that the exact | resources allocated by the caller can be released, now that the exact | |||
session configuration is known. These "resources" can include things | session configuration is known. These "resources" can include things | |||
like extra ICE components, TURN candidates, or video decoders. | like extra ICE components, Traversal Using Relays around NAT (TURN) | |||
Provisional answers, on the other hand, do no such deallocation; as a | candidates, or video decoders. Provisional answers, on the other | |||
result, multiple dissimilar provisional answers, with their own codec | hand, do no such deallocation; as a result, multiple dissimilar | |||
choices, transport parameters, etc., can be received and applied | provisional answers, with their own codec choices, transport | |||
during call setup. Note that the final answer itself may be | parameters, etc., can be received and applied during call setup. | |||
different than any received provisional answers. | Note that the final answer itself may be different than any received | |||
provisional answers. | ||||
In [RFC3264], the constraint at the signaling level is that only one | In [RFC3264], the constraint at the signaling level is that only one | |||
offer can be outstanding for a given session, but at the media stack | 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 | 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 | using SIP for signaling, if one offer is sent and is then canceled | |||
SIP CANCEL, another offer can be generated even though no answer was | using a SIP CANCEL, another offer can be generated even though no | |||
received for the first offer. To support this, the JSEP media layer | answer was received for the first offer. To support this, the JSEP | |||
can provide an offer via the createOffer() method whenever the | media layer can provide an offer via the createOffer() method | |||
JavaScript application needs one for the signaling. The answerer can | whenever the JavaScript application needs one for the signaling. The | |||
send back zero or more provisional answers, and finally end the | answerer can send back zero or more provisional answers and then | |||
offer-answer exchange by sending a final answer. The state machine | finally end the offer/answer exchange by sending a final answer. The | |||
for this is as follows: | state machine for this is as follows: | |||
setRemote(OFFER) setLocal(PRANSWER) | setRemote(OFFER) setLocal(PRANSWER) | |||
/-----\ /-----\ | /-----\ /-----\ | |||
| | | | | | | | | | |||
v | v | | v | v | | |||
+---------------+ | +---------------+ | | +---------------+ | +---------------+ | | |||
| |----/ | |----/ | | |----/ | |----/ | |||
| have- | setLocal(PRANSWER) | have- | | | have- | setLocal(PRANSWER) | have- | | |||
| remote-offer |------------------- >| local-pranswer| | | remote-offer |------------------- >| local-pranswer| | |||
| | | | | | | | | | |||
skipping to change at line 440 ¶ | skipping to change at line 442 ¶ | |||
| | | | | | | | | | |||
| |----\ | |----\ | | |----\ | |----\ | |||
+---------------+ | +---------------+ | | +---------------+ | +---------------+ | | |||
^ | ^ | | ^ | ^ | | |||
| | | | | | | | | | |||
\-----/ \-----/ | \-----/ \-----/ | |||
setLocal(OFFER) setRemote(PRANSWER) | setLocal(OFFER) setRemote(PRANSWER) | |||
Figure 2: JSEP State Machine | Figure 2: JSEP State Machine | |||
Aside from these state transitions there is no other difference | Aside from these state transitions, there is no other difference | |||
between the handling of provisional ("pranswer") and final ("answer") | between the handling of provisional ("pranswer") and final ("answer") | |||
answers. | answers. | |||
3.3. Session Description Format | 3.3. Session Description Format | |||
JSEP's session descriptions use SDP syntax for their internal | JSEP's session descriptions use Session Description Protocol (SDP) | |||
representation. While this format is not optimal for manipulation | syntax for their internal representation. While this format is not | |||
from JavaScript, it is widely accepted, and frequently updated with | optimal for manipulation from JavaScript, it is widely accepted and | |||
new features; any alternate encoding of session descriptions would | is frequently updated with new features; any alternate encoding of | |||
have to keep pace with the changes to SDP, at least until the time | session descriptions would have to keep pace with the changes to SDP, | |||
that this new encoding eclipsed SDP in popularity. | at least until the time that this new encoding eclipsed SDP in | |||
popularity. | ||||
However, to provide for future flexibility, the SDP syntax is | However, to provide for future flexibility, the SDP syntax is | |||
encapsulated within a SessionDescription object, which can be | encapsulated within a SessionDescription object, which can be | |||
constructed from SDP, and be serialized out to SDP. If future | constructed from SDP and be serialized out to SDP. If future | |||
specifications agree on a JSON format for session descriptions, we | specifications agree on a JSON format for session descriptions, we | |||
could easily enable this object to generate and consume that JSON. | could easily enable this object to generate and consume that JSON. | |||
As detailed below, most applications should be able to treat the | As detailed below, most applications should be able to treat the | |||
SessionDescriptions produced and consumed by these various API calls | SessionDescriptions produced and consumed by these various API calls | |||
as opaque blobs; that is, the application will not need to read or | as opaque blobs; that is, the application will not need to read or | |||
change them. | change them. | |||
3.4. Session Description Control | 3.4. Session Description Control | |||
In order to give the application control over various common session | In order to give the application control over various common session | |||
parameters, JSEP provides control surfaces which tell the JSEP | parameters, JSEP provides control surfaces that tell the JSEP | |||
implementation how to generate session descriptions. This avoids the | implementation how to generate session descriptions. This avoids the | |||
need for JavaScript to modify session descriptions in most cases. | need for JavaScript to modify session descriptions in most cases. | |||
Changes to these objects result in changes to the session | Changes to these objects result in changes to the session | |||
descriptions generated by subsequent createOffer/Answer calls. | descriptions generated by subsequent createOffer/createAnswer calls. | |||
3.4.1. RtpTransceivers | 3.4.1. RtpTransceivers | |||
RtpTransceivers allow the application to control the RTP media | RtpTransceivers allow the application to control the RTP media | |||
associated with one m= section. Each RtpTransceiver has an RtpSender | associated with one "m=" section. Each RtpTransceiver has an | |||
and an RtpReceiver, which an application can use to control the | RtpSender and an RtpReceiver, which an application can use to control | |||
sending and receiving of RTP media. The application may also modify | the sending and receiving of RTP media. The application may also | |||
the RtpTransceiver directly, for instance, by stopping it. | modify the RtpTransceiver directly, for instance, by stopping it. | |||
RtpTransceivers generally have a 1:1 mapping with m= sections, | RtpTransceivers generally have a 1:1 mapping with "m=" sections, | |||
although there may be more RtpTransceivers than m= sections when | although there may be more RtpTransceivers than "m=" sections when | |||
RtpTransceivers are created but not yet associated with a m= section, | RtpTransceivers are created but not yet associated with an "m=" | |||
or if RtpTransceivers have been stopped and disassociated from m= | section, or if RtpTransceivers have been stopped and disassociated | |||
sections. An RtpTransceiver is said to be associated with an m= | from "m=" sections. An RtpTransceiver is said to be associated with | |||
section if its mid property is non-null; otherwise it is said to be | an "m=" section if its media identification (mid) property is non- | |||
disassociated. The associated m= section is determined using a | null; otherwise, it is said to be disassociated. The associated "m=" | |||
mapping between transceivers and m= section indices, formed when | section is determined using a mapping between transceivers and "m=" | |||
creating an offer or applying a remote offer. | section indices, formed when creating an offer or applying a remote | |||
offer. | ||||
An RtpTransceiver is never associated with more than one m= section, | An RtpTransceiver is never associated with more than one "m=" | |||
and once a session description is applied, a m= section is always | section, and once a session description is applied, an "m=" section | |||
associated with exactly one RtpTransceiver. However, in certain | is always associated with exactly one RtpTransceiver. However, in | |||
cases where a m= section has been rejected, as discussed in | certain cases where an "m=" section has been rejected, as discussed | |||
Section 5.2.2 below, that m= section will be "recycled" and | in Section 5.2.2 below, that "m=" section will be "recycled" and | |||
associated with a new RtpTransceiver with a new mid value. | associated with a new RtpTransceiver with a new mid value. | |||
RtpTransceivers can be created explicitly by the application or | RtpTransceivers can be created explicitly by the application or | |||
implicitly by calling setRemoteDescription with an offer that adds | implicitly by calling setRemoteDescription with an offer that adds | |||
new m= sections. | new "m=" sections. | |||
3.4.2. RtpSenders | 3.4.2. RtpSenders | |||
RtpSenders allow the application to control how RTP media is sent. | RtpSenders allow the application to control how RTP media is sent. | |||
An RtpSender is conceptually responsible for the outgoing RTP | An RtpSender is conceptually responsible for the outgoing RTP | |||
stream(s) described by an m= section. This includes encoding the | stream(s) described by an "m=" section. This includes encoding the | |||
attached MediaStreamTrack, sending RTP media packets, and generating/ | attached MediaStreamTrack, sending RTP media packets, and generating/ | |||
processing RTCP for the outgoing RTP streams(s). | processing the RTP Control Protocol (RTCP) for the outgoing RTP | |||
streams(s). | ||||
3.4.3. RtpReceivers | 3.4.3. RtpReceivers | |||
RtpReceivers allow the application to inspect how RTP media is | RtpReceivers allow the application to inspect how RTP media is | |||
received. An RtpReceiver is conceptually responsible for the | received. An RtpReceiver is conceptually responsible for the | |||
incoming RTP stream(s) described by an m= section. This includes | incoming RTP stream(s) described by an "m=" section. This includes | |||
processing received RTP media packets, decoding the incoming | processing received RTP media packets, decoding the incoming | |||
stream(s) to produce a remote MediaStreamTrack, and generating/ | stream(s) to produce a remote MediaStreamTrack, and generating/ | |||
processing RTCP for the incoming RTP stream(s). | processing RTCP for the incoming RTP stream(s). | |||
3.5. ICE | 3.5. ICE | |||
3.5.1. ICE Gathering Overview | 3.5.1. ICE Gathering Overview | |||
JSEP gathers ICE candidates as needed by the application. Collection | JSEP gathers ICE candidates as needed by the application. Collection | |||
of ICE candidates is referred to as a gathering phase, and this is | 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 | triggered either by the addition of a new or recycled "m=" section to | |||
the local session description, or new ICE credentials in the | the local session description or by new ICE credentials in the | |||
description, indicating an ICE restart. Use of new ICE credentials | description, indicating an ICE restart. Use of new ICE credentials | |||
can be triggered explicitly by the application, or implicitly by the | can be triggered explicitly by the application or implicitly by the | |||
JSEP implementation in response to changes in the ICE configuration. | JSEP implementation in response to changes in the ICE configuration. | |||
When the ICE configuration changes in a way that requires a new | 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 | gathering phase, a 'needs-ice-restart' bit is set. When this bit is | |||
set, calls to the createOffer API will generate new ICE credentials. | set, calls to the createOffer API will generate new ICE credentials. | |||
This bit is cleared by a call to the setLocalDescription API with new | 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 | ICE credentials from either an offer or an answer, i.e., from either | |||
a local- or remote-initiated ICE restart. | a locally or remotely initiated ICE restart. | |||
When a new gathering phase starts, the ICE agent will notify the | When a new gathering phase starts, the ICE agent will notify the | |||
application that gathering is occurring through an event. Then, when | application that gathering is occurring through an event. Then, when | |||
each new ICE candidate becomes available, the ICE agent will supply | each new ICE candidate becomes available, the ICE agent will supply | |||
it to the application via an additional event; these candidates will | it to the application via an additional event; these candidates will | |||
also automatically be added to the current and/or pending local | also automatically be added to the current and/or pending local | |||
session description. Finally, when all candidates have been | session description. Finally, when all candidates have been | |||
gathered, an event will be dispatched to signal that the gathering | gathered, an event will be dispatched to signal that the gathering | |||
process is complete. | process is complete. | |||
Note that gathering phases only gather the candidates needed by | Note that gathering phases only gather the candidates needed by | |||
new/recycled/restarting m= sections; other m= sections continue to | new/recycled/restarting "m=" sections; other "m=" sections continue | |||
use their existing candidates. Also, if an m= section is bundled | to use their existing candidates. Also, if an "m=" section is | |||
(either by a successful bundle negotiation or by being marked as | bundled (either by a successful bundle negotiation or by being marked | |||
bundle-only), then candidates will be gathered and exchanged for that | as bundle-only), then candidates will be gathered and exchanged for | |||
m= section if and only if its MID is a BUNDLE-tag, as described in | that "m=" section if and only if its MID item is a BUNDLE-tag, as | |||
[RFCYYYB]. | described in [RFC8843]. | |||
3.5.2. ICE Candidate Trickling | 3.5.2. ICE Candidate Trickling | |||
Candidate trickling is a technique through which a caller may | Candidate trickling is a technique through which a caller may | |||
incrementally provide candidates to the callee after the initial | incrementally provide candidates to the callee after the initial | |||
offer has been dispatched; the semantics of "Trickle ICE" are defined | offer has been dispatched; the semantics of "Trickle ICE" are defined | |||
in [RFCYYY6]. This process allows the callee to begin acting upon | in [RFC8838]. This process allows the callee to begin acting upon | |||
the call and setting up the ICE (and perhaps DTLS) connections | the call and setting up the ICE (and perhaps DTLS) connections | |||
immediately, without having to wait for the caller to gather all | immediately, without having to wait for the caller to gather all | |||
possible candidates. This results in faster media setup in cases | possible candidates. This results in faster media setup in cases | |||
where gathering is not performed prior to initiating the call. | where gathering is not performed prior to initiating the call. | |||
JSEP supports optional candidate trickling by providing APIs, as | JSEP supports optional candidate trickling by providing APIs, as | |||
described above, that provide control and feedback on the ICE | described above, that provide control and feedback on the ICE | |||
candidate gathering process. Applications that support candidate | candidate gathering process. Applications that support candidate | |||
trickling can send the initial offer immediately and send individual | trickling can send the initial offer immediately and send individual | |||
candidates when they get the notified of a new candidate; | candidates when they get notified of a new candidate; applications | |||
applications that do not support this feature can simply wait for the | that do not support this feature can simply wait for the indication | |||
indication that gathering is complete, and then create and send their | that gathering is complete, and then create and send their offer, | |||
offer, with all the candidates, at this time. | with all the candidates, at that time. | |||
Upon receipt of trickled candidates, the receiving application will | Upon receipt of trickled candidates, the receiving application will | |||
supply them to its ICE agent. This triggers the ICE agent to start | supply them to its ICE agent. This triggers the ICE agent to start | |||
using the new remote candidates for connectivity checks. | using the new remote candidates for connectivity checks. | |||
3.5.2.1. ICE Candidate Format | 3.5.2.1. ICE Candidate Format | |||
In JSEP, ICE candidates are abstracted by an IceCandidate object, and | In JSEP, ICE candidates are abstracted by an IceCandidate object, and | |||
as with session descriptions, SDP syntax is used for the internal | as with session descriptions, SDP syntax is used for the internal | |||
representation. | representation. | |||
The candidate details are specified in an IceCandidate field, using | The candidate details are specified in an IceCandidate field, using | |||
the same SDP syntax as the "candidate-attribute" field defined in | the same SDP syntax as the "candidate-attribute" field defined in | |||
[RFCYYY7], Section 4.1. Note that this field does not contain an | [RFC8839], Section 5.1. Note that this field does not contain an | |||
"a=" prefix, as indicated in the following example: | "a=" prefix, as indicated in the following example: | |||
candidate:1 1 UDP 1694498815 192.0.2.33 10000 typ host | candidate:1 1 UDP 1694498815 192.0.2.33 10000 typ host | |||
The IceCandidate object contains a field to indicate which ICE ufrag | The IceCandidate object contains a field to indicate which ICE ufrag | |||
it is associated with, as defined in [RFCYYY7], Section 4.4. This | it is associated with, as defined in [RFC8839], Section 5.4. This | |||
value is used to determine which session description (and thereby | value is used to determine which session description (and thereby | |||
which gathering phase) this IceCandidate belongs to, which helps | which gathering phase) this IceCandidate belongs to, which helps | |||
resolve ambiguities during ICE restarts. If this field is absent in | resolve ambiguities during ICE restarts. If this field is absent in | |||
a received IceCandidate (perhaps when communicating with a non-JSEP | a received IceCandidate (perhaps when communicating with a non-JSEP | |||
endpoint), the most recently received session description is assumed. | endpoint), the most recently received session description is assumed. | |||
The IceCandidate object also contains fields to indicate which m= | The IceCandidate object also contains fields to indicate which "m=" | |||
section it is associated with, which can be identified in one of two | 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 | ways: either by an "m=" section index or by a MID. The "m=" section | |||
is a zero-based index, with index N referring to the N+1th m= section | index is a zero-based index, with index N referring to the N+1th "m=" | |||
in the session description referenced by this IceCandidate. The MID | section in the session description referenced by this IceCandidate. | |||
is a "media stream identification" value, as defined in [RFC5888], | The MID is a "media stream identification" value, as defined in | |||
Section 4, which provides a more robust way to identify the m= | [RFC5888], Section 4, which provides a more robust way to identify | |||
section in the session description, using the MID of the associated | the "m=" section in the session description, using the MID of the | |||
RtpTransceiver object (which may have been locally generated by the | associated RtpTransceiver object (which may have been locally | |||
answerer when interacting with a non-JSEP endpoint that does not | generated by the answerer when interacting with a non-JSEP endpoint | |||
support the MID attribute, as discussed in Section 5.10 below). If | that does not support the MID attribute, as discussed in Section 5.10 | |||
the MID field is present in a received IceCandidate, it MUST be used | below). If the MID field is present in a received IceCandidate, it | |||
for identification; otherwise, the m= section index is used instead. | MUST be used for identification; otherwise, the "m=" section index is | |||
used instead. | ||||
When creating an IceCandidate object, JSEP implementations MUST | When creating an IceCandidate object, JSEP implementations MUST | |||
populate each of the candidate, ufrag, m= section index, and MID | populate each of the candidate, ufrag, "m=" section index, and MID | |||
fields. Implementations MUST also be prepared to receive objects | fields. Implementations MUST also be prepared to receive objects | |||
with some fields missing, as mentioned above. | with some fields missing, as mentioned above. | |||
3.5.3. ICE Candidate Policy | 3.5.3. ICE Candidate Policy | |||
Typically, when gathering ICE candidates, the JSEP implementation | Typically, when gathering ICE candidates, the JSEP implementation | |||
will gather all possible forms of initial candidates - host, server | will gather all possible forms of initial candidates -- host, server- | |||
reflexive, and relay. However, in certain cases, applications may | reflexive, and relay. However, in certain cases, applications may | |||
want to have more specific control over the gathering process, due to | want to have more specific control over the gathering process, due to | |||
privacy or related concerns. For example, one may want to only use | privacy or related concerns. For example, one may want to only use | |||
relay candidates, to leak as little location information as possible | relay candidates, to leak as little location information as possible | |||
(keeping in mind that this choice comes with corresponding | (keeping in mind that this choice comes with corresponding | |||
operational costs). To accomplish this, JSEP allows the application | operational costs). To accomplish this, JSEP allows the application | |||
to restrict which ICE candidates are used in a session. Note that | to restrict which ICE candidates are used in a session. Note that | |||
this filtering is applied on top of any restrictions the | this filtering is applied on top of any restrictions the | |||
implementation chooses to enforce regarding which IP addresses are | implementation chooses to enforce regarding which IP addresses are | |||
permitted for the application, as discussed in [RFCYYY3]. | permitted for the application, as discussed in [RFC8828]. | |||
There may also be cases where the application wants to change which | There may also be cases where the application wants to change which | |||
types of candidates are used while the session is active. A prime | types of candidates are used while the session is active. A prime | |||
example is where a callee may initially want to use only relay | example is where a callee may initially want to use only relay | |||
candidates, to avoid leaking location information to an arbitrary | candidates, to avoid leaking location information to an arbitrary | |||
caller, but then change to use all candidates (for lower operational | caller, but then change to use all candidates (for lower operational | |||
cost) once the user has indicated they want to take the call. For | cost) once the user has indicated that they want to take the call. | |||
this scenario, the JSEP implementation MUST allow the candidate | For this scenario, the JSEP implementation MUST allow the candidate | |||
policy to be changed in mid-session, subject to the aforementioned | policy to be changed in mid-session, subject to the aforementioned | |||
interactions with local policy. | interactions with local policy. | |||
To administer the ICE candidate policy, the JSEP implementation will | To administer the ICE candidate policy, the JSEP implementation will | |||
determine the current setting at the start of each gathering phase. | determine the current setting at the start of each gathering phase. | |||
Then, during the gathering phase, the implementation MUST NOT expose | Then, during the gathering phase, the implementation MUST NOT expose | |||
candidates disallowed by the current policy to the application, use | candidates disallowed by the current policy to the application, use | |||
them as the source of connectivity checks, or indirectly expose them | them as the source of connectivity checks, or indirectly expose them | |||
via other fields, such as the raddr/rport attributes for other ICE | via other fields, such as the raddr/rport attributes for other ICE | |||
candidates. Later, if a different policy is specified by the | candidates. Later, if a different policy is specified by the | |||
application, the application can apply it by kicking off a new | application, the application can apply it by kicking off a new | |||
gathering phase via an ICE restart. | gathering phase via an ICE restart. | |||
3.5.4. ICE Candidate Pool | 3.5.4. ICE Candidate Pool | |||
JSEP applications typically inform the JSEP implementation to begin | JSEP applications typically inform the JSEP implementation to begin | |||
ICE gathering via the information supplied to setLocalDescription, as | ICE gathering via the information supplied to setLocalDescription, as | |||
the local description indicates the number of ICE components which | the local description indicates the number of ICE components that | |||
will be needed and for which candidates must be gathered. However, | will be needed and for which candidates must be gathered. However, | |||
to accelerate cases where the application knows the number of ICE | to accelerate cases where the application knows the number of ICE | |||
components to use ahead of time, it may ask the implementation to | components to use ahead of time, it may ask the implementation to | |||
gather a pool of potential ICE candidates to help ensure rapid media | gather a pool of potential ICE candidates to help ensure rapid media | |||
setup. | setup. | |||
When setLocalDescription is eventually called, and the JSEP | When setLocalDescription is eventually called and the JSEP | |||
implementation goes to gather the needed ICE candidates, it SHOULD | implementation goes to gather the needed ICE candidates, it SHOULD | |||
start by checking if any candidates are available in the pool. If | start by checking if any candidates are available in the pool. If | |||
there are candidates in the pool, they SHOULD be handed to the | there are candidates in the pool, they SHOULD be handed to the | |||
application immediately via the ICE candidate event. If the pool | application immediately via the ICE candidate event. If the pool | |||
becomes depleted, either because a larger-than-expected number of ICE | becomes depleted, either because a larger-than-expected number of ICE | |||
components is used, or because the pool has not had enough time to | components are used or because the pool has not had enough time to | |||
gather candidates, the remaining candidates are gathered as usual. | gather candidates, the remaining candidates are gathered as usual. | |||
This only occurs for the first offer/answer exchange, after which the | This only occurs for the first offer/answer exchange, after which the | |||
candidate pool is emptied and no longer used. | candidate pool is emptied and no longer used. | |||
One example of where this concept is useful is an application that | 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 | expects an incoming call at some point in the future, and wants to | |||
minimize the time it takes to establish connectivity, to avoid | minimize the time it takes to establish connectivity, to avoid | |||
clipping of initial media. By pre-gathering candidates into the | clipping of initial media. By pre-gathering candidates into the | |||
pool, it can exchange and start sending connectivity checks from | pool, it can exchange and start sending connectivity checks from | |||
these candidates almost immediately upon receipt of a call. Note | these candidates almost immediately upon receipt of a call. Note, | |||
though that by holding on to these pre-gathered candidates, which | 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 be kept alive as long as they may be needed, the application | |||
will consume resources on the STUN/TURN servers it is using. | will consume resources on the STUN/TURN servers it is using. ("STUN" | |||
stands for "Session Traversal Utilities for NAT".) | ||||
3.5.5. ICE Versions | 3.5.5. ICE Versions | |||
While this specification formally relies on [RFC8445], at the time of | While this specification formally relies on [RFC8445], at the time of | |||
its publication, the majority of WebRTC implementations support the | its publication, the majority of WebRTC implementations support the | |||
version of ICE described in [RFC5245]. The use of the "ice2" | version of ICE described in [RFC5245]. The "ice2" attribute defined | |||
attribute defined in [RFC8445] can be used to detect the version in | in [RFC8445] can be used to detect the version in use by a remote | |||
use by a remote endpoint and to provide a smooth transition from the | endpoint and to provide a smooth transition from the older | |||
older specification to the newer one. Implementations MUST be able | specification to the newer one. Implementations MUST be able to | |||
to accept remote descriptions that do not have the "ice2" attribute. | accept remote descriptions that do not have the "ice2" attribute. | |||
3.6. Video Size Negotiation | 3.6. Video Size Negotiation | |||
Video size negotiation is the process through which a receiver can | Video size negotiation is the process through which a receiver can | |||
use the "a=imageattr" SDP attribute [RFC6236] to indicate what video | use the "a=imageattr" SDP attribute [RFC6236] to indicate what video | |||
frame sizes it is capable of receiving. A receiver may have hard | frame sizes it is capable of receiving. A receiver may have hard | |||
limits on what its video decoder can process, or it may have some | limits on what its video decoder can process, or it may have some | |||
maximum set by policy. By specifying these limits in an | maximum set by policy. By specifying these limits in an | |||
"a=imageattr" attribute, JSEP endpoints can attempt to ensure that | "a=imageattr" attribute, JSEP endpoints can attempt to ensure that | |||
the remote sender transmits video at an acceptable resolution. | the remote sender transmits video at an acceptable resolution. | |||
However, when communicating with a non-JSEP endpoint that does not | However, when communicating with a non-JSEP endpoint that does not | |||
understand this attribute, any signaled limits may be exceeded, and | understand this attribute, any signaled limits may be exceeded, and | |||
the JSEP implementation MUST handle this gracefully, e.g., by | the JSEP implementation MUST handle this gracefully, e.g., by | |||
discarding the video. | discarding the video. | |||
Note that certain codecs support transmission of samples with aspect | Note that certain codecs support transmission of samples with aspect | |||
ratios other than 1.0 (i.e., non-square pixels). JSEP | ratios other than 1.0 (i.e., non-square pixels). JSEP | |||
implementations will not transmit non-square pixels, but SHOULD | implementations will not transmit non-square pixels but SHOULD | |||
receive and render such video with the correct aspect ratio. | receive and render such video with the correct aspect ratio. | |||
However, sample aspect ratio has no impact on the size negotiation | However, sample aspect ratio has no impact on the size negotiation | |||
described below; all dimensions are measured in pixels, whether | described below; all dimensions are measured in pixels, whether | |||
square or not. | square or not. | |||
3.6.1. Creating an imageattr Attribute | 3.6.1. Creating an imageattr Attribute | |||
The receiver will first intersect any known local limits (e.g., | The receiver will first intersect any known local limits (e.g., | |||
hardware decoder capababilities, local policy) to determine the | hardware decoder capabilities, local policy) to determine the | |||
absolute minimum and maximum sizes it can receive. If there are no | absolute minimum and maximum sizes it can receive. If there are no | |||
known local limits, the "a=imageattr" attribute SHOULD be omitted. | known local limits, the "a=imageattr" attribute SHOULD be omitted. | |||
If these local limits preclude receiving any video, i.e., the | If these local limits preclude receiving any video, i.e., the | |||
degenerate case of no permitted resolutions, the "a=imageattr" | degenerate case of no permitted resolutions, the "a=imageattr" | |||
attribute MUST be omitted, and the m= section MUST be marked as | attribute MUST be omitted, and the "m=" section MUST be marked as | |||
sendonly/inactive, as appropriate. | sendonly/inactive, as appropriate. | |||
Otherwise, an "a=imageattr" attribute is created with "recv" | Otherwise, an "a=imageattr" attribute is created with a "recv" | |||
direction, and the resulting resolution space formed from the | direction, and the resulting resolution space formed from the | |||
aforementioned intersection is used to specify its minimum and | aforementioned intersection is used to specify its minimum and | |||
maximum x= and y= values. | maximum "x=" and "y=" values. | |||
The rules here express a single set of preferences, and therefore, | The rules here express a single set of preferences, and therefore, | |||
the "a=imageattr" q= value is not important. It SHOULD be set to | the "a=imageattr" "q=" value is not important. It SHOULD be set to | |||
1.0. | "1.0". | |||
The "a=imageattr" field is payload type specific. When all video | The "a=imageattr" field is payload type specific. When all video | |||
codecs supported have the same capabilities, use of a single | codecs supported have the same capabilities, use of a single | |||
attribute, with the wildcard payload type (*), is RECOMMENDED. | attribute, with the wildcard payload type (*), is RECOMMENDED. | |||
However, when the supported video codecs have different limitations, | However, when the supported video codecs have different limitations, | |||
specific "a=imageattr" attributes MUST be inserted for each payload | specific "a=imageattr" attributes MUST be inserted for each payload | |||
type. | type. | |||
As an example, consider a system with a multiformat video decoder, | As an example, consider a system with a multiformat video decoder, | |||
which is capable of decoding any resolution from 48x48 to 720p, In | which is capable of decoding any resolution from 48x48 to 720p. In | |||
this case, the implementation would generate this attribute: | this case, the implementation would generate this attribute: | |||
a=imageattr:* recv [x=[48:1280],y=[48:720],q=1.0] | a=imageattr:* recv [x=[48:1280],y=[48:720],q=1.0] | |||
This declaration indicates that the receiver is capable of decoding | This declaration indicates that the receiver is capable of decoding | |||
any image resolution from 48x48 up to 1280x720 pixels. | any image resolution from 48x48 up to 1280x720 pixels. | |||
3.6.2. Interpreting imageattr Attributes | 3.6.2. Interpreting imageattr Attributes | |||
[RFC6236] defines "a=imageattr" to be an advisory field. This means | [RFC6236] defines "a=imageattr" to be an advisory field. This means | |||
that it does not absolutely constrain the video formats that the | that it does not absolutely constrain the video formats that the | |||
sender can use, but gives an indication of the preferred values. | sender can use but gives an indication of the preferred values. | |||
This specification prescribes more specific behavior. When a | This specification prescribes behavior that is more specific. When a | |||
MediaStreamTrack, which is producing video of a certain resolution | MediaStreamTrack, which is producing video of a certain resolution | |||
(the "track resolution"), is attached to a RtpSender, which is | (the "track resolution"), is attached to an RtpSender, which is | |||
encoding the track video at the same or lower resolution(s) (the | encoding the track video at the same or lower resolution(s) (the | |||
"encoder resolutions"), and a remote description is applied that | "encoder resolutions"), and a remote description is applied that | |||
references the sender and contains valid "a=imageattr recv" | references the sender and contains valid "a=imageattr recv" | |||
attributes, it MUST follow the rules below to ensure the sender does | attributes, it MUST follow the rules below to ensure that the sender | |||
not transmit a resolution that would exceed the size criteria | does not transmit a resolution that would exceed the size criteria | |||
specified in the attributes. These rules MUST be followed as long as | specified in the attributes. These rules MUST be followed as long as | |||
the attributes remain present in the remote description, including | the attributes remain present in the remote description, including | |||
cases in which the track changes its resolution, or is replaced with | cases in which the track changes its resolution or is replaced with a | |||
a different track. | different track. | |||
Depending on how the RtpSender is configured, it may be producing a | Depending on how the RtpSender is configured, it may be producing a | |||
single encoding at a certain resolution, or, if simulcast Section 3.7 | single encoding at a certain resolution or, if simulcast | |||
has been negotiated, multiple encodings, each at their own specific | (Section 3.7) has been negotiated, multiple encodings, each at their | |||
resolution. In addition, depending on the configuration, each | own specific resolution. In addition, depending on the | |||
encoding may have the flexibility to reduce resolution when needed, | configuration, each encoding may have the flexibility to reduce | |||
or may be locked to a specific output resolution. | resolution when needed or may be locked to a specific output | |||
resolution. | ||||
For each encoding being produced by the RtpSender, the set of | For each encoding being produced by the RtpSender, the set of | |||
"a=imageattr recv" attributes in the corresponding m= section of the | "a=imageattr recv" attributes in the corresponding "m=" section of | |||
remote description is processed to determine what should be | the remote description is processed to determine what should be | |||
transmitted. Only attributes that reference the media format | transmitted. Only attributes that reference the media format | |||
selected for the encoding are considered; each such attribute is | selected for the encoding are considered; each such attribute is | |||
evaluated individually, starting with the attribute with the highest | evaluated individually, starting with the attribute with the highest | |||
"q=" value. If multiple attributes have the same "q=" value, they | "q=" value. If multiple attributes have the same "q=" value, they | |||
are evaluated in the order they appear in their containing m= | are evaluated in the order they appear in their containing "m=" | |||
section. Note that while JSEP endpoints will include at most one | section. Note that while JSEP endpoints will include at most one | |||
"a=imageattr recv" attribute per media format, JSEP endpoints may | "a=imageattr recv" attribute per media format, JSEP endpoints may | |||
receive session descriptions from non-JSEP endpoints with m= sections | receive session descriptions from non-JSEP endpoints with "m=" | |||
that contain multiple such attributes. | sections that contain multiple such attributes. | |||
For each "a=imageattr recv" attribute, the following rules are | For each "a=imageattr recv" attribute, the following rules are | |||
applied. If this processing is successful, the encoding is | applied. If this processing is successful, the encoding is | |||
transmitted accordingly, and no further attributes are considered for | transmitted accordingly, and no further attributes are considered for | |||
that encoding. Otherwise, the next attribute is evaluated, in the | that encoding. Otherwise, the next attribute is evaluated, in the | |||
aforementioned order. If none of the supplied attributes can be | aforementioned order. If none of the supplied attributes can be | |||
processed successfully, the encoding MUST NOT be transmitted, and an | processed successfully, the encoding MUST NOT be transmitted, and an | |||
error SHOULD be raised to the application. | error SHOULD be raised to the application. | |||
* The limits from the attribute are compared to the encoder | * The limits from the attribute are compared to the encoder | |||
resolution. Only the specific limits mentioned below are | resolution. Only the specific limits mentioned below are | |||
considered; any other values, such as picture aspect ratio, MUST | considered; any other values, such as picture aspect ratio, MUST | |||
be ignored. When considering a MediaStreamTrack that is producing | be ignored. When considering a MediaStreamTrack that is producing | |||
rotated video, the unrotated resolution MUST be used for the | rotated video, the unrotated resolution MUST be used for the | |||
checks. This is required regardless of whether the receiver | checks. This is required regardless of whether the receiver | |||
supports performing receive-side rotation (e.g., through CVO | supports performing receive-side rotation (e.g., through | |||
[TS26.114]), as it significantly simplifies the matching logic. | Coordination of Video Orientation (CVO) [TS26.114]), as it | |||
significantly simplifies the matching logic. | ||||
* If the attribute includes a "sar=" (sample aspect ratio) value set | * If the attribute includes a "sar=" (sample aspect ratio) value set | |||
to something other than "1.0", indicating the receiver wants to | to something other than "1.0", indicating that the receiver wants | |||
receive non-square pixels, this cannot be satisfied and the | to receive non-square pixels, this cannot be satisfied and the | |||
attribute MUST NOT be used. | attribute MUST NOT be used. | |||
* If the encoder resolution exceeds the maximum size permitted by | * If the encoder resolution exceeds the maximum size permitted by | |||
the attribute, and the encoder is allowed to adjust its | the attribute and the encoder is allowed to adjust its resolution, | |||
resolution, the encoder SHOULD apply downscaling in order to | the encoder SHOULD apply downscaling in order to satisfy the | |||
satisfy the limits. Downscaling MUST NOT change the picture | limits. Downscaling MUST NOT change the picture aspect ratio of | |||
aspect ratio of the encoding, ignoring any trivial differences due | the encoding, ignoring any trivial differences due to rounding. | |||
to rounding. For example, if the encoder resolution is 1280x720, | For example, if the encoder resolution is 1280x720 and the | |||
and the attribute specified a maximum of 640x480, the expected | attribute specified a maximum of 640x480, the expected output | |||
output resolution would be 640x360. If downscaling cannot be | resolution would be 640x360. If downscaling cannot be applied, | |||
applied, the attribute MUST NOT be used. | the attribute MUST NOT be used. | |||
* If the encoder resolution is less than the minimum size permitted | * If the encoder resolution is less than the minimum size permitted | |||
by the attribute, the attribute MUST NOT be used; the encoder MUST | by the attribute, the attribute MUST NOT be used; the encoder MUST | |||
NOT apply upscaling. JSEP implementations SHOULD avoid this | NOT apply upscaling. JSEP implementations SHOULD avoid this | |||
situation by allowing receipt of arbitrarily small resolutions, | situation by allowing receipt of arbitrarily small resolutions, | |||
perhaps via fallback to a software decoder. | perhaps via fallback to a software decoder. | |||
* If the encoder resolution is within the maximum and minimum sizes, | * If the encoder resolution is within the maximum and minimum sizes, | |||
no action is needed. | no action is needed. | |||
3.7. Simulcast | 3.7. Simulcast | |||
JSEP supports simulcast transmission of a MediaStreamTrack, where | JSEP supports simulcast transmission of a MediaStreamTrack, where | |||
multiple encodings of the source media can be transmitted within the | multiple encodings of the source media can be transmitted within the | |||
context of a single m= section. The current JSEP API is designed to | context of a single "m=" section. The current JSEP API is designed | |||
allow applications to send simulcasted media but only to receive a | to allow applications to send simulcasted media but only to receive a | |||
single encoding. This allows for multi-user scenarios where each | single encoding. This allows for multi-user scenarios where each | |||
sending client sends multiple encodings to a server, which then, for | sending client sends multiple encodings to a server, which then, for | |||
each receiving client, chooses the appropriate encoding to forward. | each receiving client, chooses the appropriate encoding to forward. | |||
Applications request support for simulcast by configuring multiple | Applications request support for simulcast by configuring multiple | |||
encodings on an RtpSender. Upon generation of an offer or answer, | encodings on an RtpSender. Upon generation of an offer or answer, | |||
these encodings are indicated via SDP markings on the corresponding | these encodings are indicated via SDP markings on the corresponding | |||
m= section, as described below. Receivers that understand simulcast | "m=" section, as described below. Receivers that understand | |||
and are willing to receive it will also include SDP markings to | simulcast and are willing to receive it will also include SDP | |||
indicate their support, and JSEP endpoints will use these markings to | markings to indicate their support, and JSEP endpoints will use these | |||
determine whether simulcast is permitted for a given RtpSender. If | markings to determine whether simulcast is permitted for a given | |||
simulcast support is not negotiated, the RtpSender will only use the | RtpSender. If simulcast support is not negotiated, the RtpSender | |||
first configured encoding. | will only use the first configured encoding. | |||
Note that the exact simulcast parameters are up to the sending | Note that the exact simulcast parameters are up to the sending | |||
application. While the aforementioned SDP markings are provided to | application. While the aforementioned SDP markings are provided to | |||
ensure the remote side can receive and demux multiple simulcast | ensure that the remote side can receive and demux multiple simulcast | |||
encodings, the specific resolutions and bitrates to be used for each | encodings, the specific resolutions and bitrates to be used for each | |||
encoding are purely a send-side decision in JSEP. | encoding are purely a send-side decision in JSEP. | |||
JSEP currently does not provide a mechanism to configure receipt of | JSEP currently does not provide a mechanism to configure receipt of | |||
simulcast. This means that if simulcast is offered by the remote | simulcast. This means that if simulcast is offered by the remote | |||
endpoint, the answer generated by a JSEP endpoint will not indicate | endpoint, the answer generated by a JSEP endpoint will not indicate | |||
support for receipt of simulcast, and as such the remote endpoint | support for receipt of simulcast, and as such the remote endpoint | |||
will only send a single encoding per m= section. | will only send a single encoding per "m=" section. | |||
In addition, JSEP does not provide a mechanism to handle an incoming | In addition, JSEP does not provide a mechanism to handle an incoming | |||
offer requesting simulcast from the JSEP endpoint. This means that | offer requesting simulcast from the JSEP endpoint. This means that | |||
setting up simulcast in the case where the JSEP endpoint receives the | setting up simulcast in the case where the JSEP endpoint receives the | |||
initial offer requires out-of-band signaling or SDP inspection. | initial offer requires out-of-band signaling or SDP inspection. | |||
However, in the case where the JSEP endpoint sets up simulcast in its | However, in the case where the JSEP endpoint sets up simulcast in its | |||
in initial offer, any established simulcast streams will continue to | initial offer, any established simulcast streams will continue to | |||
work upon receipt of an incoming re-offer. Future versions of this | work upon receipt of an incoming re-offer. Future versions of this | |||
specification may add additional APIs to handle the incoming initial | specification may add additional APIs to handle the incoming initial | |||
offer scenario. | offer scenario. | |||
When using JSEP to transmit multiple encodings from a RtpSender, the | When using JSEP to transmit multiple encodings from an RtpSender, the | |||
techniques from [RFCYYYE] and [RFCYYYC] are used. Specifically, when | techniques from [RFC8853] and [RFC8851] are used. Specifically, when | |||
multiple encodings have been configured for a RtpSender, the m= | multiple encodings have been configured for an RtpSender, the "m=" | |||
section for the RtpSender will include an "a=simulcast" attribute, as | section for the RtpSender will include an "a=simulcast" attribute, as | |||
defined in [RFCYYYE], Section 6.2, with a "send" simulcast stream | defined in [RFC8853], Section 6.2, with a "send" simulcast stream | |||
description that lists each desired encoding, and no "recv" simulcast | description that lists each desired encoding, and no "recv" simulcast | |||
stream description. The m= section will also include an "a=rid" | stream description. The "m=" section will also include an "a=rid" | |||
attribute for each encoding, as specified in [RFCYYYC], Section 4; | attribute for each encoding, as specified in [RFC8851], Section 4; | |||
the use of RID identifiers allows the individual encodings to be | the use of Restriction Identifiers (RIDs) allows the individual | |||
disambiguated even though they are all part of the same m= section. | encodings to be disambiguated even though they are all part of the | |||
same "m=" section. | ||||
3.8. Interactions With Forking | 3.8. Interactions with Forking | |||
Some call signaling systems allow various types of forking where an | Some call signaling systems allow various types of forking where an | |||
SDP Offer may be provided to more than one device. For example, SIP | SDP Offer may be provided to more than one device. For example, SIP | |||
[RFC3261] defines both a "Parallel Search" and "Sequential Search". | [RFC3261] defines both a "parallel search" and "sequential search". | |||
Although these are primarily signaling level issues that are outside | Although these are primarily signaling-level issues that are outside | |||
the scope of JSEP, they do have some impact on the configuration of | the scope of JSEP, they do have some impact on the configuration of | |||
the media plane that is relevant. When forking happens at the | the media plane that is relevant. When forking happens at the | |||
signaling layer, the JavaScript application responsible for the | signaling layer, the JavaScript application responsible for the | |||
signaling needs to make the decisions about what media should be sent | 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 | or received at any point in time, as well as which remote endpoint it | |||
should communicate with; JSEP is used to make sure the media engine | should communicate with; JSEP is used to make sure the media engine | |||
can make the RTP and media perform as required by the application. | can make the RTP and media perform as required by the application. | |||
The basic operations that the applications can have the media engine | The basic operations that the applications can have the media engine | |||
do are: | do are as follows: | |||
* Start exchanging media with a given remote peer, but keep all the | * Start exchanging media with a given remote peer, but keep all the | |||
resources reserved in the offer. | resources reserved in the offer. | |||
* Start exchanging media with a given remote peer, and free any | * Start exchanging media with a given remote peer, and free any | |||
resources in the offer that are not being used. | resources in the offer that are not being used. | |||
3.8.1. Sequential Forking | 3.8.1. Sequential Forking | |||
Sequential forking involves a call being dispatched to multiple | Sequential forking involves a call being dispatched to multiple | |||
remote callees, where each callee can accept the call, but only one | 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 | active session ever exists at a time; no mixing of received media is | |||
performed. | performed. | |||
JSEP handles sequential forking well, allowing the application to | JSEP handles sequential forking well, allowing the application to | |||
easily control the policy for selecting the desired remote endpoint. | easily control the policy for selecting the desired remote endpoint. | |||
When an answer arrives from one of the callees, the application can | When an answer arrives from one of the callees, the application can | |||
choose to apply it either as a provisional answer, leaving open the | choose to apply it as either (1) a provisional answer, leaving open | |||
possibility of using a different answer in the future, or apply it as | the possibility of using a different answer in the future or (2) a | |||
a final answer, ending the setup flow. | final answer, ending the setup flow. | |||
In a "first-one-wins" situation, the first answer will be applied as | In a "first-one-wins" situation, the first answer will be applied as | |||
a final answer, and the application will reject any subsequent | a final answer, and the application will reject any subsequent | |||
answers. In SIP parlance, this would be ACK + BYE. | answers. In SIP parlance, this would be ACK + BYE. | |||
In a "last-one-wins" situation, all answers would be applied as | In a "last-one-wins" situation, all answers would be applied as | |||
provisional answers, and any previous call leg will be terminated. | provisional answers, and any previous call leg will be terminated. | |||
At some point, the application will end the setup process, perhaps | At some point, the application will end the setup process, perhaps | |||
with a timer; at this point, the application could reapply the | with a timer; at this point, the application could reapply the | |||
pending remote description as a final answer. | pending remote description as a final answer. | |||
3.8.2. Parallel Forking | 3.8.2. Parallel Forking | |||
Parallel forking involves a call being dispatched to multiple remote | Parallel forking involves a call being dispatched to multiple remote | |||
callees, where each callee can accept the call, and multiple | callees, where each callee can accept the call and multiple | |||
simultaneous active signaling sessions can be established as a | simultaneous active signaling sessions can be established as a | |||
result. If multiple callees send media at the same time, the | result. If multiple callees send media at the same time, the | |||
possibilities for handling this are described in [RFC3960], | possibilities for handling this are described in [RFC3960], | |||
Section 3.1. Most SIP devices today only support exchanging media | Section 3.1. Most SIP devices today only support exchanging media | |||
with a single device at a time, and do not try to mix multiple early | 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. | media audio sources, as that could result in a confusing situation. | |||
For example, consider having a European ringback tone mixed together | For example, consider having a European ringback tone mixed together | |||
with the North American ringback tone - the resulting sound would not | with the North American ringback tone -- the resulting sound would | |||
be like either tone, and would confuse the user. If the signaling | not be like either tone and would confuse the user. If the signaling | |||
application wishes to only exchange media with one of the remote | 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 | endpoints at a time, then from a media engine point of view, this is | |||
exactly like the sequential forking case. | exactly like the sequential forking case. | |||
In the parallel forking case where the JavaScript application wishes | In the parallel forking case where the JavaScript application wishes | |||
to simultaneously exchange media with multiple peers, the flow is | to simultaneously exchange media with multiple peers, the flow is | |||
slightly more complex, but the JavaScript application can follow the | slightly more complex, but the JavaScript application can follow the | |||
strategy that [RFC3960] describes using UPDATE. The UPDATE approach | strategy that [RFC3960] describes, using UPDATE. The UPDATE approach | |||
allows the signaling to set up a separate media flow for each peer | 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 | that it wishes to exchange media with. In JSEP, this offer used in | |||
the UPDATE would be formed by simply creating a new PeerConnection | the UPDATE would be formed by simply creating a new PeerConnection | |||
(see Section 4.1) and making sure that the same local media streams | (see Section 4.1) and making sure that the same local media streams | |||
have been added into this new PeerConnection. Then the new | have been added into this new PeerConnection. Then the new | |||
PeerConnection object would produce a SDP offer that could be used by | PeerConnection object would produce an SDP offer that could be used | |||
the signaling to perform the UPDATE strategy discussed in [RFC3960]. | by the signaling to perform the UPDATE strategy discussed in | |||
[RFC3960]. | ||||
As a result of sharing the media streams, the application will end up | As a result of sharing the media streams, the application will end up | |||
with N parallel PeerConnection sessions, each with a local and remote | with N parallel PeerConnection sessions, each with a local and remote | |||
description and their own local and remote addresses. The media flow | description and their own local and remote addresses. The media flow | |||
from these sessions can be managed using setDirection (see | from these sessions can be managed using setDirection (see | |||
Section 4.2.3), or the application can choose to play out the media | Section 4.2.3), or the application can choose to play out the media | |||
from all sessions mixed together. Of course, if the application | from all sessions mixed together. Of course, if the application | |||
wants to only keep a single session, it can simply terminate the | wants to only keep a single session, it can simply terminate the | |||
sessions that it no longer needs. | sessions that it no longer needs. | |||
4. Interface | 4. Interface | |||
This section details the basic operations that must be present to | This section details the basic operations that must be present to | |||
implement JSEP functionality. The actual API exposed in the W3C API | implement JSEP functionality. The actual API exposed in the W3C API | |||
may have somewhat different syntax, but should map easily to these | may have somewhat different syntax but should map easily to these | |||
concepts. | concepts. | |||
4.1. PeerConnection | 4.1. PeerConnection | |||
4.1.1. Constructor | 4.1.1. Constructor | |||
The PeerConnection constructor allows the application to specify | The PeerConnection constructor allows the application to specify | |||
global parameters for the media session, such as the STUN/TURN | global parameters for the media session, such as the STUN/TURN | |||
servers and credentials to use when gathering candidates, as well as | servers and credentials to use when gathering candidates, as well as | |||
the initial ICE candidate policy and pool size, and also the bundle | the initial ICE candidate policy and pool size, and also the bundle | |||
policy to use. | policy to use. | |||
If an ICE candidate policy is specified, it functions as described in | If an ICE candidate policy is specified, it functions as described in | |||
Section 3.5.3, causing the JSEP implementation to only surface the | Section 3.5.3, causing the JSEP implementation to only surface the | |||
permitted candidates (including any implementation-internal | permitted candidates (including any implementation-internal | |||
filtering) to the application, and only use those candidates for | filtering) to the application and only use those candidates for | |||
connectivity checks. The set of available policies is as follows: | connectivity checks. The set of available policies is as follows: | |||
all: All candidates permitted by implementation policy will be | all: All candidates permitted by implementation policy will be | |||
gathered and used. | gathered and used. | |||
relay: All candidates except relay candidates will be filtered out. | relay: All candidates except relay candidates will be filtered out. | |||
This obfuscates the location information that might be ascertained | This obfuscates the location information that might be ascertained | |||
by the remote peer from the received candidates. Depending on how | by the remote peer from the received candidates. Depending on how | |||
the application deploys and chooses relay servers, this could | the application deploys and chooses relay servers, this could | |||
obfuscate location to a metro or possibly even global level. | obfuscate location to a metro or possibly even global level. | |||
The default ICE candidate policy MUST be set to "all" as this is | The default ICE candidate policy MUST be set to "all", as this is | |||
generally the desired policy, and also typically reduces use of | generally the desired policy and also typically reduces the use of | |||
application TURN server resources significantly. | application TURN server resources significantly. | |||
If a size is specified for the ICE candidate pool, this indicates the | If a size is specified for the ICE candidate pool, this indicates the | |||
number of ICE components to pre-gather candidates for. Because pre- | number of ICE components to pre-gather candidates for. Because | |||
gathering results in utilizing STUN/TURN server resources for | pre-gathering results in utilizing STUN/TURN server resources for | |||
potentially long periods of time, this must only occur upon | potentially long periods of time, this must only occur upon | |||
application request, and therefore the default candidate pool size | application request, and therefore the default candidate pool size | |||
MUST be zero. | MUST be zero. | |||
The application can specify its preferred policy regarding use of | The application can specify its preferred policy regarding use of | |||
bundle, the multiplexing mechanism defined in [RFCYYYB]. Regardless | bundle, the multiplexing mechanism defined in [RFC8843]. Regardless | |||
of policy, the application will always try to negotiate bundle onto a | of policy, the application will always try to negotiate bundle onto a | |||
single transport, and will offer a single bundle group across all m= | single transport and will offer a single bundle group across all "m=" | |||
sections; use of this single transport is contingent upon the | sections; use of this single transport is contingent upon the | |||
answerer accepting bundle. However, by specifying a policy from the | answerer accepting bundle. However, by specifying a policy from the | |||
list below, the application can control exactly how aggressively it | list below, the application can control exactly how aggressively it | |||
will try to bundle media streams together, which affects how it will | will try to bundle media streams together, which affects how it will | |||
interoperate with a non-bundle-aware endpoint. When negotiating with | interoperate with a non-bundle-aware endpoint. When negotiating with | |||
a non-bundle-aware endpoint, only the streams not marked as bundle- | a non-bundle-aware endpoint, only the streams not marked as bundle- | |||
only streams will be established. | only streams will be established. | |||
The set of available policies is as follows: | The set of available policies is as follows: | |||
balanced: The first m= section of each type (audio, video, or | balanced: The first "m=" section of each type (audio, video, or | |||
application) will contain transport parameters, which will allow | application) will contain transport parameters, which will allow | |||
an answerer to unbundle that section. The second and any | an answerer to unbundle that section. The second and any | |||
subsequent m= section of each type will be marked bundle-only. | subsequent "m=" sections of each type will be marked bundle-only. | |||
The result is that if there are N distinct media types, then | The result is that if there are N distinct media types, then | |||
candidates will be gathered for for N media streams. This policy | candidates will be gathered for N media streams. This policy | |||
balances desire to multiplex with the need to ensure basic audio | balances desire to multiplex with the need to ensure that basic | |||
and video can still be negotiated in legacy cases. When acting as | audio and video can still be negotiated in legacy cases. When | |||
answerer, if there is no bundle group in the offer, the | acting as answerer, if there is no bundle group in the offer, the | |||
implementation will reject all but the first m= section of each | implementation will reject all but the first "m=" section of each | |||
type. | type. | |||
max-compat: All m= sections will contain transport parameters; none | max-compat: All "m=" sections will contain transport parameters; | |||
will be marked as bundle-only. This policy will allow all streams | none will be marked as bundle-only. This policy will allow all | |||
to be received by non-bundle-aware endpoints, but require separate | streams to be received by non-bundle-aware endpoints but will | |||
candidates to be gathered for each media stream. | require separate candidates to be gathered for each media stream. | |||
max-bundle: Only the first m= section will contain transport | max-bundle: Only the first "m=" section will contain transport | |||
parameters; all streams other than the first will be marked as | parameters; all streams other than the first will be marked as | |||
bundle-only. This policy aims to minimize candidate gathering and | bundle-only. This policy aims to minimize candidate gathering and | |||
maximize multiplexing, at the cost of less compatibility with | maximize multiplexing, at the cost of less compatibility with | |||
legacy endpoints. When acting as answerer, the implementation | legacy endpoints. When acting as answerer, the implementation | |||
will reject any m= sections other than the first m= section, | will reject any "m=" sections other than the first "m=" section, | |||
unless they are in the same bundle group as that m= section. | unless they are in the same bundle group as that "m=" section. | |||
As it provides the best tradeoff between performance and | As it provides the best trade-off between performance and | |||
compatibility with legacy endpoints, the default bundle policy MUST | compatibility with legacy endpoints, the default bundle policy MUST | |||
be set to "balanced". | be set to "balanced". | |||
The application can specify its preferred policy regarding use of | The application can specify its preferred policy regarding use of | |||
RTP/RTCP multiplexing [RFC5761] using one of the following policies: | RTP/RTCP multiplexing [RFC5761] using one of the following policies: | |||
negotiate: The JSEP implementation will gather both RTP and RTCP | negotiate: The JSEP implementation will gather both RTP and RTCP | |||
candidates but also will offer "a=rtcp-mux", thus allowing for | candidates but also will offer "a=rtcp-mux", thus allowing for | |||
compatibility with either multiplexing or non-multiplexing | compatibility with either multiplexing or non-multiplexing | |||
endpoints. | endpoints. | |||
require: The JSEP implementation will only gather RTP candidates and | require: The JSEP implementation will only gather RTP candidates and | |||
will insert an "a=rtcp-mux-only" indication into any new m= | will insert an "a=rtcp-mux-only" indication into any new "m=" | |||
sections in offers it generates. This halves the number of | sections in offers it generates. This halves the number of | |||
candidates that the offerer needs to gather. Applying a | candidates that the offerer needs to gather. Applying a | |||
description with an m= section that does not contain an "a=rtcp- | description with an "m=" section that does not contain an "a=rtcp- | |||
mux" attribute will cause an error to be returned. | mux" attribute will cause an error to be returned. | |||
The default multiplexing policy MUST be set to "require". | The default multiplexing policy MUST be set to "require". | |||
Implementations MAY choose to reject attempts by the application to | Implementations MAY choose to reject attempts by the application to | |||
set the multiplexing policy to "negotiate". | set the multiplexing policy to "negotiate". | |||
4.1.2. addTrack | 4.1.2. addTrack | |||
The addTrack method adds a MediaStreamTrack to the PeerConnection, | The addTrack method adds a MediaStreamTrack to the PeerConnection, | |||
using the MediaStream argument to associate the track with other | using the MediaStream argument to associate the track with other | |||
tracks in the same MediaStream, so that they can be added to the same | tracks in the same MediaStream, so that they can be added to the same | |||
"LS" group when creating an offer or answer. Adding tracks to the | "LS" (Lip Synchronization) group when creating an offer or answer. | |||
same "LS" group indicates that the playback of these tracks should be | Adding tracks to the same "LS" group indicates that the playback of | |||
synchronized for proper lip sync, as described in [RFC5888], | these tracks should be synchronized for proper lip sync, as described | |||
Section 7. addTrack attempts to minimize the number of transceivers | in [RFC5888], Section 7. addTrack attempts to minimize the number of | |||
as follows: If the PeerConnection is in the "have-remote-offer" | transceivers as follows: if the PeerConnection is in the | |||
state, the track will be attached to the first compatible transceiver | "have-remote-offer" state, the track will be attached to the first | |||
that was created by the most recent call to setRemoteDescription() | compatible transceiver that was created by the most recent call to | |||
and does not have a local track. Otherwise, a new transceiver will | setRemoteDescription() and does not have a local track. Otherwise, a | |||
be created, as described in Section 4.1.4. | new transceiver will be created, as described in Section 4.1.4. | |||
4.1.3. removeTrack | 4.1.3. removeTrack | |||
The removeTrack method removes a MediaStreamTrack from the | The removeTrack method removes a MediaStreamTrack from the | |||
PeerConnection, using the RtpSender argument to indicate which sender | PeerConnection, using the RtpSender argument to indicate which sender | |||
should have its track removed. The sender's track is cleared, and | should have its track removed. The sender's track is cleared, and | |||
the sender stops sending. Future calls to createOffer will mark the | the sender stops sending. Future calls to createOffer will mark the | |||
m= section associated with the sender as recvonly (if | "m=" section associated with the sender as recvonly (if | |||
transceiver.direction is sendrecv) or as inactive (if | transceiver.direction is sendrecv) or as inactive (if | |||
transceiver.direction is sendonly). | transceiver.direction is sendonly). | |||
4.1.4. addTransceiver | 4.1.4. addTransceiver | |||
The addTransceiver method adds a new RtpTransceiver to the | The addTransceiver method adds a new RtpTransceiver to the | |||
PeerConnection. If a MediaStreamTrack argument is provided, then the | PeerConnection. If a MediaStreamTrack argument is provided, then the | |||
transceiver will be configured with that media type and the track | transceiver will be configured with that media type and the track | |||
will be attached to the transceiver. Otherwise, the application MUST | will be attached to the transceiver. Otherwise, the application MUST | |||
explicitly specify the type; this mode is useful for creating | explicitly specify the type; this mode is useful for creating | |||
recvonly transceivers as well as for creating transceivers to which a | recvonly transceivers as well as for creating transceivers to which a | |||
track can be attached at some later point. | track can be attached at some later point. | |||
At the time of creation, the application can also specify a | At the time of creation, the application can also specify a | |||
transceiver direction attribute, a set of MediaStreams which the | transceiver direction attribute, a set of MediaStreams that the | |||
transceiver is associated with (allowing LS group assignments), and a | transceiver is associated with (allowing "LS" group assignments), and | |||
set of encodings for the media (used for simulcast as described in | a set of encodings for the media (used for simulcast as described in | |||
Section 3.7). | Section 3.7). | |||
4.1.5. createDataChannel | 4.1.5. createDataChannel | |||
The createDataChannel method creates a new data channel and attaches | The createDataChannel method creates a new data channel and attaches | |||
it to the PeerConnection. If no data channel currently exists for | it to the PeerConnection. If no data channel currently exists for | |||
this PeerConnection, then a new offer/answer exchange is required. | this PeerConnection, then a new offer/answer exchange is required. | |||
All data channels on a given PeerConnection share the same SCTP/DTLS | All data channels on a given PeerConnection share the same SCTP/DTLS | |||
association and therefore the same m= section, so subsequent creation | association ("SCTP" stands for "Stream Control Transmission | |||
of data channels does not have any impact on the JSEP state. | Protocol") 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 | The createDataChannel method also includes a number of arguments that | |||
which are used by the PeerConnection (e.g., maxPacketLifetime) but | are used by the PeerConnection (e.g., maxPacketLifetime) but are not | |||
are not reflected in the SDP and do not affect the JSEP state. | reflected in the SDP and do not affect the JSEP state. | |||
4.1.6. createOffer | 4.1.6. createOffer | |||
The createOffer method generates a blob of SDP that contains a | The createOffer method generates a blob of SDP that contains an offer | |||
[RFC3264] offer with the supported configurations for the session, | per [RFC3264] with the supported configurations for the session, | |||
including descriptions of the media added to this PeerConnection, the | including descriptions of the media added to this PeerConnection, the | |||
codec/RTP/RTCP options supported by this implementation, and any | codec/RTP/RTCP options supported by this implementation, and any | |||
candidates that have been gathered by the ICE agent. An options | candidates that have been gathered by the ICE agent. An options | |||
parameter may be supplied to provide additional control over the | parameter may be supplied to provide additional control over the | |||
generated offer. This options parameter allows an application to | generated offer. This options parameter allows an application to | |||
trigger an ICE restart, for the purpose of reestablishing | trigger an ICE restart, for the purpose of reestablishing | |||
connectivity. | connectivity. | |||
In the initial offer, the generated SDP will contain all desired | In the initial offer, the generated SDP will contain all desired | |||
functionality for the session (functionality that is supported but | functionality for the session (functionality that is supported but | |||
skipping to change at line 1161 ¶ | skipping to change at line 1173 ¶ | |||
In the event createOffer is called after the session is established, | In the event createOffer is called after the session is established, | |||
createOffer will generate an offer to modify the current session | createOffer will generate an offer to modify the current session | |||
based on any changes that have been made to the session, e.g., adding | based on any changes that have been made to the session, e.g., adding | |||
or stopping RtpTransceivers, or requesting an ICE restart. For each | or stopping RtpTransceivers, or requesting an ICE restart. For each | |||
existing stream, the generation of each SDP line must follow the | existing stream, the generation of each SDP line must follow the | |||
process defined for generating an updated offer from the RFC that | process defined for generating an updated offer from the RFC that | |||
specifies the given SDP line. For each new stream, the generation of | specifies the given SDP line. For each new stream, the generation of | |||
the SDP must follow the process of generating an initial offer, as | 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 | mentioned above. If no changes have been made, or for SDP lines that | |||
are unaffected by the requested changes, the offer will only contain | are unaffected by the requested changes, the offer will only contain | |||
the parameters negotiated by the last offer-answer exchange. The | the parameters negotiated by the last offer/answer exchange. The | |||
exact handling of subsequent offer generation is detailed in | exact handling of subsequent offer generation is detailed in | |||
Section 5.2.2. below. | Section 5.2.2 below. | |||
Session descriptions generated by createOffer must be immediately | Session descriptions generated by createOffer must be immediately | |||
usable by setLocalDescription; if a system has limited resources | usable by setLocalDescription; if a system has limited resources | |||
(e.g. a finite number of decoders), createOffer should return an | (e.g., a finite number of decoders), createOffer should return an | |||
offer that reflects the current state of the system, so that | offer that reflects the current state of the system, so that | |||
setLocalDescription will succeed when it attempts to acquire those | setLocalDescription will succeed when it attempts to acquire those | |||
resources. | resources. | |||
Calling this method may do things such as generating new ICE | Calling this method may do things such as generating new ICE | |||
credentials, but does not change the PeerConnection state, trigger | credentials, but it does not change the PeerConnection state, trigger | |||
candidate gathering, or cause media to start or stop flowing. | candidate gathering, or cause media to start or stop flowing. | |||
Specifically, the offer is not applied, and does not become the | Specifically, the offer is not applied, and does not become the | |||
pending local description, until setLocalDescription is called. | pending local description, until setLocalDescription is called. | |||
4.1.7. createAnswer | 4.1.7. createAnswer | |||
The createAnswer method generates a blob of SDP that contains a | The createAnswer method generates a blob of SDP that contains an SDP | |||
[RFC3264] SDP answer with the supported configuration for the session | answer per [RFC3264] with the supported configuration for the session | |||
that is compatible with the parameters supplied in the most recent | that is compatible with the parameters supplied in the most recent | |||
call to setRemoteDescription, which MUST have been called prior to | call to setRemoteDescription, which MUST have been called prior to | |||
calling createAnswer. Like createOffer, the returned blob contains | calling createAnswer. Like createOffer, the returned blob contains | |||
descriptions of the media added to this PeerConnection, the | descriptions of the media added to this PeerConnection, the | |||
codec/RTP/RTCP options negotiated for this session, and any | codec/RTP/RTCP options negotiated for this session, and any | |||
candidates that have been gathered by the ICE agent. An options | candidates that have been gathered by the ICE agent. An options | |||
parameter may be supplied to provide additional control over the | parameter may be supplied to provide additional control over the | |||
generated answer. | generated answer. | |||
As an answer, the generated SDP will contain a specific configuration | As an answer, the generated SDP will contain a specific configuration | |||
that specifies how the media plane should be established; for each | that specifies how the media plane should be established; for each | |||
SDP line, the generation of the SDP must follow the process defined | SDP line, the generation of the SDP must follow the process defined | |||
for generating an answer from the document that specifies the given | for generating an answer from the document that specifies the given | |||
SDP line. The exact handling of answer generation is detailed in | SDP line. The exact handling of answer generation is detailed in | |||
Section 5.3. below. | Section 5.3 below. | |||
Session descriptions generated by createAnswer must be immediately | Session descriptions generated by createAnswer must be immediately | |||
usable by setLocalDescription; like createOffer, the returned | usable by setLocalDescription; like createOffer, the returned | |||
description should reflect the current state of the system. | description should reflect the current state of the system. | |||
Calling this method may do things such as generating new ICE | Calling this method may do things such as generating new ICE | |||
credentials, but does not change the PeerConnection state, trigger | credentials, but it does not change the PeerConnection state, trigger | |||
candidate gathering, or or cause a media state change. Specifically, | candidate gathering, or cause a media state change. Specifically, | |||
the answer is not applied, and does not become the current local | the answer is not applied, and does not become the current local | |||
description, until setLocalDescription is called. | description, until setLocalDescription is called. | |||
4.1.8. SessionDescriptionType | 4.1.8. SessionDescriptionType | |||
Session description objects (RTCSessionDescription) may be of type | Session description objects (RTCSessionDescription) may be of type | |||
"offer", "pranswer", "answer" or "rollback". These types provide | "offer", "pranswer", "answer", or "rollback". These types provide | |||
information as to how the description parameter should be parsed, and | information as to how the description parameter should be parsed and | |||
how the media state should be changed. | how the media state should be changed. | |||
"offer" indicates that a description should be parsed as an offer; | "offer" indicates that a description should be parsed as an offer; | |||
said description may include many possible media configurations. A | said description may include many possible media configurations. A | |||
description used as an "offer" may be applied anytime the | description used as an "offer" may be applied any time the | |||
PeerConnection is in a stable state, or as an update to a previously | PeerConnection is in a stable state or applied as an update to a | |||
supplied but unanswered "offer". | previously supplied but unanswered "offer". | |||
"pranswer" indicates that a description should be parsed as an | "pranswer" indicates that a description should be parsed as an | |||
answer, but not a final answer, and so should not result in the | 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 | freeing of allocated resources. It may result in the start of media | |||
transmission, if the answer does not specify an inactive media | transmission, if the answer does not specify an inactive media | |||
direction. A description used as a "pranswer" may be applied as a | direction. A description used as a "pranswer" may be applied as a | |||
response to an "offer", or an update to a previously sent "pranswer". | response to an "offer" or as an update to a previously sent | |||
"pranswer". | ||||
"answer" indicates that a description should be parsed as an answer, | "answer" indicates that a description should be parsed as an answer, | |||
the offer-answer exchange should be considered complete, and any | the offer/answer exchange should be considered complete, and any | |||
resources (decoders, candidates) that are no longer needed can be | resources (decoders, candidates) that are no longer needed can be | |||
released. A description used as an "answer" may be applied as a | released. A description used as an "answer" may be applied as a | |||
response to an "offer", or an update to a previously sent "pranswer". | response to an "offer" or as an update to a previously sent | |||
"pranswer". | ||||
The only difference between a provisional and final answer is that | The only difference between a provisional and final answer is that | |||
the final answer results in the freeing of any unused resources 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 | were allocated as a result of the offer. As such, the application | |||
can use some discretion on whether an answer should be applied as | can use some discretion on whether an answer should be applied as | |||
provisional or final, and can change the type of the session | provisional or final and can change the type of the session | |||
description as needed. For example, in a serial forking scenario, an | description as needed. For example, in a serial forking scenario, an | |||
application may receive multiple "final" answers, one from each | application may receive multiple "final" answers, one from each | |||
remote endpoint. The application could choose to accept the initial | remote endpoint. The application could choose to accept the initial | |||
answers as provisional answers, and only apply an answer as final | answers as provisional answers and only apply an answer as final when | |||
when it receives one that meets its criteria (e.g. a live user | it receives one that meets its criteria (e.g., a live user instead of | |||
instead of voicemail). | voicemail). | |||
"rollback" is a special session description type implying that the | "rollback" is a special session description type implying that the | |||
state machine should be rolled back to the previous stable state, as | state machine should be rolled back to the previous stable state, as | |||
described in Section 4.1.8.2. The contents MUST be empty. | described in Section 4.1.8.2. The contents MUST be empty. | |||
4.1.8.1. Use of Provisional Answers | 4.1.8.1. Use of Provisional Answers | |||
Most applications will not need to create answers using the | Most applications will not need to create answers using the | |||
"pranswer" type. While it is good practice to send an immediate | "pranswer" type. While it is good practice to send an immediate | |||
response to an offer, in order to warm up the session transport and | response to an offer, in order to warm up the session transport and | |||
prevent media clipping, the preferred handling for a JSEP application | prevent media clipping, the preferred handling for a JSEP application | |||
is to create and send a "sendonly" final answer with a null | is to create and send a "sendonly" final answer with a null | |||
MediaStreamTrack immediately after receiving the offer, which will | MediaStreamTrack immediately after receiving the offer, which will | |||
prevent media from being sent by the caller, and allow media to be | prevent media from being sent by the caller and allow media to be | |||
sent immediately upon answer by the callee. Later, when the callee | sent immediately upon answer by the callee. Later, when the callee | |||
actually accepts the call, the application can plug in the real | actually accepts the call, the application can plug in the real | |||
MediaStreamTrack and create a new "sendrecv" offer to update the | MediaStreamTrack and create a new "sendrecv" offer to update the | |||
previous offer/answer pair and start bidirectional media flow. While | previous offer/answer pair and start bidirectional media flow. While | |||
this could also be done with a "sendonly" pranswer, followed by a | this could also be done with a "sendonly" pranswer, followed by a | |||
"sendrecv" answer, the initial pranswer leaves the offer-answer | "sendrecv" answer, the initial pranswer leaves the offer/answer | |||
exchange open, which means that the caller cannot send an updated | exchange open, which means that the caller cannot send an updated | |||
offer during this time. | offer during this time. | |||
As an example, consider a typical JSEP application that wants to set | As an example, consider a typical JSEP application that wants to set | |||
up audio and video as quickly as possible. When the callee receives | up audio and video as quickly as possible. When the callee receives | |||
an offer with audio and video MediaStreamTracks, it will send an | an offer with audio and video MediaStreamTracks, it will send an | |||
immediate answer accepting these tracks as sendonly (meaning that the | immediate answer accepting these tracks as sendonly (meaning that the | |||
caller will not send the callee any media yet, and because the callee | caller will not send the callee any media yet, and because the callee | |||
has not yet added its own MediaStreamTracks, the callee will not send | has not yet added its own MediaStreamTracks, the callee will not send | |||
any media either). It will then ask the user to accept the call and | any media either). It will then ask the user to accept the call and | |||
acquire the needed local tracks. Upon acceptance by the user, the | acquire the needed local tracks. Upon acceptance by the user, the | |||
application will plug in the tracks it has acquired, which, because | application will plug in the tracks it has acquired, which, because | |||
ICE and DTLS handshaking have likely completed by this point, can | ICE handshaking and DTLS handshaking have likely completed by this | |||
start transmitting immediately. The application will also send a new | point, can start transmitting immediately. The application will also | |||
offer to the remote side indicating call acceptance and moving the | send a new offer to the remote side indicating call acceptance and | |||
audio and video to be two-way media. A detailed example flow along | moving the audio and video to be two-way media. A detailed example | |||
these lines is shown in Section 7.3. | flow along these lines is shown in Section 7.3. | |||
Of course, some applications may not be able to perform this double | Of course, some applications may not be able to perform this double | |||
offer-answer exchange, particularly ones that are attempting to | offer/answer exchange, particularly ones that are attempting to | |||
gateway to legacy signaling protocols. In these cases, pranswer can | gateway to legacy signaling protocols. In these cases, pranswer can | |||
still provide the application with a mechanism to warm up the | still provide the application with a mechanism to warm up the | |||
transport. | transport. | |||
4.1.8.2. Rollback | 4.1.8.2. Rollback | |||
In certain situations it may be desirable to "undo" a change made to | In certain situations, it may be desirable to "undo" a change made to | |||
setLocalDescription or setRemoteDescription. Consider a case where a | setLocalDescription or setRemoteDescription. Consider a case where a | |||
call is ongoing, and one side wants to change some of the session | call is ongoing and one side wants to change some of the session | |||
parameters; that side generates an updated offer and then calls | parameters; that side generates an updated offer and then calls | |||
setLocalDescription. However, the remote side, either before or | setLocalDescription. However, the remote side, either before or | |||
after setRemoteDescription, decides it does not want to accept the | after setRemoteDescription, decides it does not want to accept the | |||
new parameters, and sends a reject message back to the offerer. Now, | 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 | the offerer, and possibly the answerer as well, needs to return to a | |||
stable state and the previous local/remote description. To support | stable state and the previous local/remote description. To support | |||
this, we introduce the concept of "rollback", which discards any | this, we introduce the concept of "rollback", which discards any | |||
proposed changes to the session, returning the state machine to the | proposed changes to the session, returning the state machine to the | |||
stable state. A rollback is performed by supplying a session | stable state. A rollback is performed by supplying a session | |||
description of type "rollback" with empty contents to either | description of type "rollback" with empty contents to either | |||
setLocalDescription or setRemoteDescription. | setLocalDescription or setRemoteDescription. | |||
4.1.9. setLocalDescription | 4.1.9. setLocalDescription | |||
The setLocalDescription method instructs the PeerConnection to apply | The setLocalDescription method instructs the PeerConnection to apply | |||
skipping to change at line 1322 ¶ | skipping to change at line 1336 ¶ | |||
answers are checked differently, using the various rules that exist | answers are checked differently, using the various rules that exist | |||
for each SDP line. | for each SDP line. | |||
This API changes the local media state; among other things, it sets | This API changes the local media state; among other things, it sets | |||
up local resources for receiving and decoding media. In order to | up local resources for receiving and decoding media. In order to | |||
successfully handle scenarios where the application wants to offer to | successfully handle scenarios where the application wants to offer to | |||
change from one media format to a different, incompatible format, the | change from one media format to a different, incompatible format, the | |||
PeerConnection must be able to simultaneously support use of both the | PeerConnection must be able to simultaneously support use of both the | |||
current and pending local descriptions (e.g., support the codecs that | current and pending local descriptions (e.g., support the codecs that | |||
exist in either description). This dual processing begins when the | exist in either description). This dual processing begins when the | |||
PeerConnection enters the "have-local-offer" state, and continues | PeerConnection enters the "have-local-offer" state, and it continues | |||
until setRemoteDescription is called with either a final answer, at | until setRemoteDescription is called with either (1) a final answer, | |||
which point the PeerConnection can fully adopt the pending local | at which point the PeerConnection can fully adopt the pending local | |||
description, or a rollback, which results in a revert to the current | description or (2) a rollback, which results in a revert to the | |||
local description. | current local description. | |||
This API indirectly controls the candidate gathering process. When a | This API indirectly controls the candidate gathering process. When a | |||
local description is supplied, and the number of transports currently | local description is supplied and the number of transports currently | |||
in use does not match the number of transports needed by the local | in use does not match the number of transports needed by the local | |||
description, the PeerConnection will create transports as needed and | description, the PeerConnection will create transports as needed and | |||
begin gathering candidates for each transport, using ones from the | begin gathering candidates for each transport, using ones from the | |||
candidate pool if available. | candidate pool if available. | |||
If setRemoteDescription was previously called with an offer, and | If setRemoteDescription was previously called with an offer, and | |||
setLocalDescription is called with an answer (provisional or final), | setLocalDescription is called with an answer (provisional or final), | |||
and the media directions are compatible, and media is available to | and the media directions are compatible, and media is available to | |||
send, this will result in the starting of media transmission. | send, this will result in the starting of media transmission. | |||
skipping to change at line 1358 ¶ | skipping to change at line 1372 ¶ | |||
up local resources for sending and encoding media. | up local resources for sending and encoding media. | |||
If setLocalDescription was previously called with an offer, and | If setLocalDescription was previously called with an offer, and | |||
setRemoteDescription is called with an answer (provisional or final), | setRemoteDescription is called with an answer (provisional or final), | |||
and the media directions are compatible, and media is available to | and the media directions are compatible, and media is available to | |||
send, this will result in the starting of media transmission. | send, this will result in the starting of media transmission. | |||
4.1.11. currentLocalDescription | 4.1.11. currentLocalDescription | |||
The currentLocalDescription method returns the current negotiated | The currentLocalDescription method returns the current negotiated | |||
local description - i.e., the local description from the last | local description -- i.e., the local description from the last | |||
successful offer/answer exchange - in addition to any local | successful offer/answer exchange -- in addition to any local | |||
candidates that have been generated by the ICE agent since the local | candidates that have been generated by the ICE agent since the local | |||
description was set. | description was set. | |||
A null object will be returned if an offer/answer exchange has not | A null object will be returned if an offer/answer exchange has not | |||
yet been completed. | yet been completed. | |||
4.1.12. pendingLocalDescription | 4.1.12. pendingLocalDescription | |||
The pendingLocalDescription method returns a copy of the local | The pendingLocalDescription method returns a copy of the local | |||
description currently in negotiation - i.e., a local offer set | description currently in negotiation -- i.e., a local offer set | |||
without any corresponding remote answer - in addition to any local | without any corresponding remote answer -- in addition to any local | |||
candidates that have been generated by the ICE agent since the local | candidates that have been generated by the ICE agent since the local | |||
description was set. | description was set. | |||
A null object will be returned if the state of the PeerConnection is | A null object will be returned if the state of the PeerConnection is | |||
"stable" or "have-remote-offer". | "stable" or "have-remote-offer". | |||
4.1.13. currentRemoteDescription | 4.1.13. currentRemoteDescription | |||
The currentRemoteDescription method returns a copy of the current | The currentRemoteDescription method returns a copy of the current | |||
negotiated remote description - i.e., the remote description from the | negotiated remote description -- i.e., the remote description from | |||
last successful offer/answer exchange - in addition to any remote | the last successful offer/answer exchange -- in addition to any | |||
candidates that have been supplied via processIceMessage since the | remote candidates that have been supplied via processIceMessage since | |||
remote description was set. | the remote description was set. | |||
A null object will be returned if an offer/answer exchange has not | A null object will be returned if an offer/answer exchange has not | |||
yet been completed. | yet been completed. | |||
4.1.14. pendingRemoteDescription | 4.1.14. pendingRemoteDescription | |||
The pendingRemoteDescription method returns a copy of the remote | The pendingRemoteDescription method returns a copy of the remote | |||
description currently in negotiation - i.e., a remote offer set | description currently in negotiation -- i.e., a remote offer set | |||
without any corresponding local answer - in addition to any remote | without any corresponding local answer -- in addition to any remote | |||
candidates that have been supplied via processIceMessage since the | candidates that have been supplied via processIceMessage since the | |||
remote description was set. | remote description was set. | |||
A null object will be returned if the state of the PeerConnection is | A null object will be returned if the state of the PeerConnection is | |||
"stable" or "have-local-offer". | "stable" or "have-local-offer". | |||
4.1.15. canTrickleIceCandidates | 4.1.15. canTrickleIceCandidates | |||
The canTrickleIceCandidates property indicates whether the remote | The canTrickleIceCandidates property indicates whether the remote | |||
side supports receiving trickled candidates. There are three | side supports receiving trickled candidates. There are three | |||
skipping to change at line 1422 ¶ | skipping to change at line 1436 ¶ | |||
false: SDP has been received from the other side indicating that it | false: SDP has been received from the other side indicating that it | |||
cannot support trickle. | cannot support trickle. | |||
As described in Section 3.5.2, JSEP implementations always provide | As described in Section 3.5.2, JSEP implementations always provide | |||
candidates to the application individually, consistent with what is | candidates to the application individually, consistent with what is | |||
needed for Trickle ICE. However, applications can use the | needed for Trickle ICE. However, applications can use the | |||
canTrickleIceCandidates property to determine whether their peer can | canTrickleIceCandidates property to determine whether their peer can | |||
actually do Trickle ICE, i.e., whether it is safe to send an initial | 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. | offer or answer followed later by candidates as they are gathered. | |||
As "true" is the only value that definitively indicates remote | As "true" is the only value that definitively indicates remote | |||
Trickle ICE support, an application which compares | Trickle ICE support, an application that compares | |||
canTrickleIceCandidates against "true" will by default attempt Half | canTrickleIceCandidates against "true" will by default attempt Half | |||
Trickle on initial offers and Full Trickle on subsequent interactions | Trickle on initial offers and Full Trickle on subsequent interactions | |||
with a Trickle ICE-compatible agent. | with a Trickle ICE-compatible agent. | |||
4.1.16. setConfiguration | 4.1.16. setConfiguration | |||
The setConfiguration method allows the global configuration of the | The setConfiguration method allows the global configuration of the | |||
PeerConnection, which was initially set by constructor parameters, to | PeerConnection, which was initially set by constructor parameters, to | |||
be changed during the session. The effects of this method call | be changed during the session. The effects of this method call | |||
depend on when it is invoked, and differ depending on which specific | depend on when it is invoked, and they will differ, depending on | |||
parameters are changed: | which specific parameters are changed: | |||
* Any changes to the STUN/TURN servers to use affect the next | * Any changes to the STUN/TURN servers to use affect the next | |||
gathering phase. If an ICE gathering phase has already started or | gathering phase. If an ICE gathering phase has already started or | |||
completed, the 'needs-ice-restart' bit mentioned in Section 3.5.1 | completed, the 'needs-ice-restart' bit mentioned in Section 3.5.1 | |||
will be set. This will cause the next call to createOffer to | will be set. This will cause the next call to createOffer to | |||
generate new ICE credentials, for the purpose of forcing an ICE | generate new ICE credentials, for the purpose of forcing an ICE | |||
restart and kicking off a new gathering phase, in which the new | restart and kicking off a new gathering phase, in which the new | |||
servers will be used. If the ICE candidate pool has a nonzero | servers will be used. If the ICE candidate pool has a nonzero | |||
size, and a local description has not yet been applied, any | size and a local description has not yet been applied, any | |||
existing candidates will be discarded, and new candidates will be | existing candidates will be discarded, and new candidates will be | |||
gathered from the new servers. | gathered from the new servers. | |||
* Any change to the ICE candidate policy affects the next gathering | * Any change to the ICE candidate policy affects the next gathering | |||
phase. If an ICE gathering phase has already started or | phase. If an ICE gathering phase has already started or | |||
completed, the 'needs-ice-restart' bit will be set. Either way, | completed, the 'needs-ice-restart' bit will be set. Either way, | |||
changes to the policy have no effect on the candidate pool, | changes to the policy have no effect on the candidate pool, | |||
because pooled candidates are not made available to the | because pooled candidates are not made available to the | |||
application until a gathering phase occurs, and so any necessary | application until a gathering phase occurs, and so any necessary | |||
filtering can still be done on any pooled candidates. | filtering can still be done on any pooled candidates. | |||
* The ICE candidate pool size MUST NOT be changed after applying a | * The ICE candidate pool size MUST NOT be changed after applying a | |||
local description. If a local description has not yet been | local description. If a local description has not yet been | |||
applied, any changes to the ICE candidate pool size take effect | applied, any changes to the ICE candidate pool size take effect | |||
immediately; if increased, additional candidates are pre-gathered; | immediately; if increased, additional candidates are pre-gathered; | |||
if decreased, the now-superfluous candidates are discarded. | if decreased, the now-superfluous candidates are discarded. | |||
* The bundle and RTCP-multiplexing policies MUST NOT be changed | * The bundle and RTCP-multiplexing policies MUST NOT be changed | |||
after the construction of the PeerConnection. | after the construction of the PeerConnection. | |||
This call may result in a change to the state of the ICE Agent. | This call may result in a change to the state of the ICE agent. | |||
4.1.17. addIceCandidate | 4.1.17. addIceCandidate | |||
The addIceCandidate method provides an update to the ICE agent via an | The addIceCandidate method provides an update to the ICE agent via an | |||
IceCandidate object Section 3.5.2.1. If the IceCandidate's candidate | IceCandidate object (Section 3.5.2.1). If the IceCandidate's | |||
field is filled in, the IceCandidate is treated as a new remote ICE | candidate field is filled in, the IceCandidate is treated as a new | |||
candidate, which will be added to the current and/or pending remote | remote ICE candidate, which will be added to the current and/or | |||
description according to the rules defined for Trickle ICE. | pending remote description according to the rules defined for Trickle | |||
Otherwise, the IceCandidate is treated as an end-of-candidates | ICE. Otherwise, the IceCandidate is treated as an end-of-candidates | |||
indication, as defined in [RFCYYY6]. | indication, as defined in [RFC8838]. | |||
In either case, the m= section index, MID, and ufrag fields from the | In either case, the "m=" section index, MID, and ufrag fields from | |||
supplied IceCandidate are used to determine which m= section and ICE | the supplied IceCandidate are used to determine which "m=" section | |||
candidate generation the IceCandidate belongs to, as described in | and ICE candidate generation the IceCandidate belongs to, as | |||
Section 3.5.2.1 above. In the case of an end-of-candidates | described in Section 3.5.2.1 above. In the case of an end-of- | |||
indication, the absence of both the m= section index and MID fields | candidates indication, the absence of both the "m=" section index and | |||
is interpreted to mean that the indication applies to all m= sections | MID fields is interpreted to mean that the indication applies to all | |||
in the specified ICE candidate generation. However, if both fields | "m=" sections in the specified ICE candidate generation. However, if | |||
are absent for a new remote candidate, this MUST be treated as an | both fields are absent for a new remote candidate, this MUST be | |||
invalid condition, as specified below. | treated as an invalid condition, as specified below. | |||
If any IceCandidate fields contain invalid values, or an error occurs | If any IceCandidate fields contain invalid values or an error occurs | |||
during the processing of the IceCandidate object, the supplied | during the processing of the IceCandidate object, the supplied | |||
IceCandidate MUST be ignored and an error MUST be returned. | IceCandidate MUST be ignored and an error MUST be returned. | |||
Otherwise, the new remote candidate or end-of-candidates indication | Otherwise, the new remote candidate or end-of-candidates indication | |||
is supplied to the ICE agent. In the case of a new remote candidate, | is supplied to the ICE agent. In the case of a new remote candidate, | |||
connectivity checks will be sent to the new candidate. | connectivity checks will be sent to the new candidate. | |||
4.2. RtpTransceiver | 4.2. RtpTransceiver | |||
4.2.1. stop | 4.2.1. stop | |||
The stop method stops an RtpTransceiver. This will cause future | The stop method stops an RtpTransceiver. This will cause future | |||
calls to createOffer to generate a zero port for the associated m= | calls to createOffer to generate a zero port for the associated "m=" | |||
section. See below for more details. | section. See below for more details. | |||
4.2.2. stopped | 4.2.2. stopped | |||
The stopped property indicates whether the transceiver has been | The stopped property indicates whether the transceiver has been | |||
stopped, either by a call to stopTransceiver or by applying an answer | stopped, either by a call to stopTransceiver or by applying an answer | |||
that rejects the associated m= section. In either of these cases, it | that rejects the associated "m=" section. In either of these cases, | |||
is set to "true", and otherwise will be set to "false". | it is set to "true" and otherwise will be set to "false". | |||
A stopped RtpTransceiver does not send any outgoing RTP or RTCP or | A stopped RtpTransceiver does not send any outgoing RTP or RTCP or | |||
process any incoming RTP or RTCP. It cannot be restarted. | process any incoming RTP or RTCP. It cannot be restarted. | |||
4.2.3. setDirection | 4.2.3. setDirection | |||
The setDirection method sets the direction of a transceiver, which | The setDirection method sets the direction of a transceiver, which | |||
affects the direction property of the associated m= section on future | affects the direction property of the associated "m=" section on | |||
calls to createOffer and createAnswer. The permitted values for | future calls to createOffer and createAnswer. The permitted values | |||
direction are "recvonly", "sendrecv", "sendonly", and "inactive", | for direction are "recvonly", "sendrecv", "sendonly", and "inactive", | |||
mirroring the identically-named directional attributes defined in | mirroring the identically named directional attributes defined in | |||
[RFC4566], Section 6. | [RFC4566], Section 6. | |||
When creating offers, the transceiver direction is directly reflected | When creating offers, the transceiver direction is directly reflected | |||
in the output, even for re-offers. When creating answers, the | in the output, even for re-offers. When creating answers, the | |||
transceiver direction is intersected with the offered direction, as | transceiver direction is intersected with the offered direction, as | |||
explained in Section 5.3 below. | explained in Section 5.3 below. | |||
Note that while setDirection sets the direction property of the | Note that while setDirection sets the direction property of the | |||
transceiver immediately ( Section 4.2.4), this property does not | transceiver immediately (Section 4.2.4), this property does not | |||
immediately affect whether the transceiver's RtpSender will send or | immediately affect whether the transceiver's RtpSender will send or | |||
its RtpReceiver will receive. The direction in effect is represented | its RtpReceiver will receive. The direction in effect is represented | |||
by the currentDirection property, which is only updated when an | by the currentDirection property, which is only updated when an | |||
answer is applied. | answer is applied. | |||
4.2.4. direction | 4.2.4. direction | |||
The direction property indicates the last value passed into | The direction property indicates the last value passed into | |||
setDirection. If setDirection has never been called, it is set to | setDirection. If setDirection has never been called, it is set to | |||
the direction the transceiver was initialized with. | the direction the transceiver was initialized with. | |||
4.2.5. currentDirection | 4.2.5. currentDirection | |||
The currentDirection property indicates the last negotiated direction | The currentDirection property indicates the last negotiated direction | |||
for the transceiver's associated m= section. More specifically, it | for the transceiver's associated "m=" section. More specifically, it | |||
indicates the [RFC3264] directional attribute of the associated m= | indicates the directional attribute [RFC3264] of the associated "m=" | |||
section in the last applied answer (including provisional answers), | section in the last applied answer (including provisional answers), | |||
with "send" and "recv" directions reversed if it was a remote answer. | with "send" and "recv" directions reversed if it was a remote answer. | |||
For example, if the directional attribute for the associated m= | For example, if the directional attribute for the associated "m=" | |||
section in a remote answer is "recvonly", currentDirection is set to | section in a remote answer is "recvonly", currentDirection is set to | |||
"sendonly". | "sendonly". | |||
If an answer that references this transceiver has not yet been | If an answer that references this transceiver has not yet been | |||
applied, or if the transceiver is stopped, currentDirection is set to | applied or if the transceiver is stopped, currentDirection is set to | |||
null. | "null". | |||
4.2.6. setCodecPreferences | 4.2.6. setCodecPreferences | |||
The setCodecPreferences method sets the codec preferences of a | The setCodecPreferences method sets the codec preferences of a | |||
transceiver, which in turn affect the presence and order of codecs of | transceiver, which in turn affect the presence and order of codecs of | |||
the associated m= section on future calls to createOffer and | the associated "m=" section on future calls to createOffer and | |||
createAnswer. Note that setCodecPreferences does not directly affect | createAnswer. Note that setCodecPreferences does not directly affect | |||
which codec the implementation decides to send. It only affects | which codec the implementation decides to send. It only affects | |||
which codecs the implementation indicates that it prefers to receive, | which codecs the implementation indicates that it prefers to receive, | |||
via the offer or answer. Even when a codec is excluded by | via the offer or answer. Even when a codec is excluded by | |||
setCodecPreferences, it still may be used to send until the next | setCodecPreferences, it still may be used to send until the next | |||
offer/answer exchange discards it. | offer/answer exchange discards it. | |||
The codec preferences of an RtpTransceiver can cause codecs to be | The codec preferences of an RtpTransceiver can cause codecs to be | |||
excluded by subsequent calls to createOffer and createAnswer, in | excluded by subsequent calls to createOffer and createAnswer, in | |||
which case the corresponding media formats in the associated m= | which case the corresponding media formats in the associated "m=" | |||
section will be excluded. The codec preferences cannot add media | section will be excluded. The codec preferences cannot add media | |||
formats that would otherwise not be present. | formats that would otherwise not be present. | |||
The codec preferences of an RtpTransceiver can also determine the | The codec preferences of an RtpTransceiver can also determine the | |||
order of codecs in subsequent calls to createOffer and createAnswer, | order of codecs in subsequent calls to createOffer and createAnswer, | |||
in which case the order of the media formats in the associated m= | in which case the order of the media formats in the associated "m=" | |||
section will follow the specified preferences. | section will follow the specified preferences. | |||
5. SDP Interaction Procedures | 5. SDP Interaction Procedures | |||
This section describes the specific procedures to be followed when | This section describes the specific procedures to be followed when | |||
creating and parsing SDP objects. | creating and parsing SDP objects. | |||
5.1. Requirements Overview | 5.1. Requirements Overview | |||
JSEP implementations must comply with the specifications listed below | JSEP implementations must comply with the specifications listed below | |||
that govern the creation and processing of offers and answers. | that govern the creation and processing of offers and answers. | |||
5.1.1. Usage Requirements | 5.1.1. Usage Requirements | |||
All session descriptions handled by JSEP implementations, both local | All session descriptions handled by JSEP implementations, both local | |||
and remote, MUST indicate support for the following specifications. | and remote, MUST indicate support for the following specifications. | |||
If any of these are absent, this omission MUST be treated as an | If any of these are absent, this omission MUST be treated as an | |||
error. | error. | |||
* ICE, as specified in [RFC8445], MUST be used. Note that the | * ICE, as specified in [RFC8445], MUST be used. Note that the | |||
remote endpoint may use a Lite implementation; implementations | remote endpoint may use a lite implementation; implementations | |||
MUST properly handle remote endpoints which do ICE-Lite. | MUST properly handle remote endpoints that do ICE-lite. | |||
* DTLS [RFC6347] or DTLS-SRTP [RFC5763], MUST be used, as | * DTLS [RFC6347] or DTLS-SRTP [RFC5763] MUST be used, as appropriate | |||
appropriate for the media type, as specified in [RFCYYY2] | for the media type, as specified in [RFC8827]. | |||
The SDES SRTP keying mechanism from [RFC4568] MUST NOT be used, as | The SDES SRTP keying mechanism from [RFC4568] MUST NOT be used, as | |||
discussed in [RFCYYY2]. | discussed in [RFC8827]. | |||
5.1.2. Profile Names and Interoperability | 5.1.2. Profile Names and Interoperability | |||
For media m= sections, JSEP implementations MUST support the | For media "m=" sections, JSEP implementations MUST support the | |||
"UDP/TLS/RTP/SAVPF" profile specified in [RFC5764] as well as the | "UDP/TLS/RTP/SAVPF" profile specified in [RFC5764] as well as the | |||
"TCP/DTLS/RTP/SAVPF" profile specified in [RFC7850], and MUST | "TCP/DTLS/RTP/SAVPF" profile specified in [RFC7850] and MUST indicate | |||
indicate one of these profiles for each media m= line they produce in | one of these profiles for each media "m=" line they produce in an | |||
an offer. For data m= sections, implementations MUST support the | offer. For data "m=" sections, implementations MUST support the | |||
"UDP/DTLS/SCTP" profile as well as the "TCP/DTLS/SCTP" profile, and | "UDP/DTLS/SCTP" profile as well as the "TCP/DTLS/SCTP" profile and | |||
MUST indicate one of these profiles for each data m= line they | MUST indicate one of these profiles for each data "m=" line they | |||
produce in an offer. The exact profile to use is determined by the | produce in an offer. The exact profile to use is determined by the | |||
protocol associated with the current default or selected ICE | protocol associated with the current default or selected ICE | |||
candidate, as described in [RFCYYY7], Section 3.2.1.2. | candidate, as described in [RFC8839], Section 4.2.1.2. | |||
Unfortunately, in an attempt at compatibility, some endpoints | Unfortunately, in an attempt at compatibility, some endpoints | |||
generate other profile strings even when they mean to support one of | generate other profile strings even when they mean to support one of | |||
these profiles. For instance, an endpoint might generate "RTP/AVP" | these profiles. For instance, an endpoint might generate "RTP/AVP" | |||
but supply "a=fingerprint" and "a=rtcp-fb" attributes, indicating its | but supply "a=fingerprint" and "a=rtcp-fb" attributes, indicating its | |||
willingness to support "UDP/TLS/RTP/SAVPF" or "TCP/DTLS/RTP/SAVPF". | willingness to support "UDP/TLS/RTP/SAVPF" or "TCP/DTLS/RTP/SAVPF". | |||
In order to simplify compatibility with such endpoints, JSEP | In order to simplify compatibility with such endpoints, JSEP | |||
implementations MUST follow the following rules when processing the | implementations MUST follow the following rules when processing the | |||
media m= sections in a received offer: | media "m=" sections in a received offer: | |||
* Any profile in the offer matching one of the following MUST be | * Any profile in the offer matching one of the following MUST be | |||
accepted: | accepted: | |||
- "RTP/AVP" (Defined in [RFC4566], Section 8.2.2) | - "RTP/AVP" (defined in [RFC4566], Section 8.2.2) | |||
- "RTP/AVPF" (Defined in [RFC4585], Section 9) | - "RTP/AVPF" (defined in [RFC4585], Section 9) | |||
- "RTP/SAVP" (Defined in [RFC3711], Section 12) | - "RTP/SAVP" (defined in [RFC3711], Section 12) | |||
- "RTP/SAVPF" (Defined in [RFC5124], Section 6) | - "RTP/SAVPF" (defined in [RFC5124], Section 6) | |||
- "TCP/DTLS/RTP/SAVP" (Defined in [RFC7850], Section 3.4) | - "TCP/DTLS/RTP/SAVP" (defined in [RFC7850], Section 3.4) | |||
- "TCP/DTLS/RTP/SAVPF" (Defined in [RFC7850], Section 3.5) | - "TCP/DTLS/RTP/SAVPF" (defined in [RFC7850], Section 3.5) | |||
- "UDP/TLS/RTP/SAVP" (Defined in [RFC5764], Section 9) | - "UDP/TLS/RTP/SAVP" (defined in [RFC5764], Section 9) | |||
- "UDP/TLS/RTP/SAVPF" (Defined in [RFC5764], Section 9) | - "UDP/TLS/RTP/SAVPF" (defined in [RFC5764], Section 9) | |||
* The profile in any "m=" line in any generated answer MUST exactly | * The profile in any "m=" line in any generated answer MUST exactly | |||
match the profile provided in the offer. | match the profile provided in the offer. | |||
* Because DTLS-SRTP is REQUIRED, the choice of SAVP or AVP has no | * 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 | effect; support for DTLS-SRTP is determined by the presence of one | |||
or more "a=fingerprint" attribute. Note that lack of an | or more "a=fingerprint" attributes. Note that lack of an | |||
"a=fingerprint" attribute will lead to negotiation failure. | "a=fingerprint" attribute will lead to negotiation failure. | |||
* The use of AVPF or AVP simply controls the timing rules used for | * 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 | RTCP feedback. If AVPF is provided or an "a=rtcp-fb" attribute is | |||
is present, assume AVPF timing, i.e., a default value of "trr- | present, assume AVPF timing, i.e., a default value of "trr-int=0". | |||
int=0". Otherwise, assume that AVPF is being used in an AVP | Otherwise, assume that AVPF is being used in an AVP-compatible | |||
compatible mode and use a value of "trr-int=4000". | mode and use a value of "trr-int=4000". | |||
* For data m= sections, implementations MUST support receiving the | * For data "m=" sections, implementations MUST support receiving the | |||
"UDP/DTLS/SCTP", "TCP/DTLS/SCTP", or "DTLS/SCTP" (for backwards | "UDP/DTLS/SCTP", "TCP/DTLS/SCTP", or "DTLS/SCTP" (for backwards | |||
compatibility) profiles. | compatibility) profiles. | |||
Note that re-offers by JSEP implementations MUST use the correct | Note that re-offers by JSEP implementations MUST use the correct | |||
profile strings even if the initial offer/answer exchange used an | profile strings even if the initial offer/answer exchange used an | |||
(incorrect) older profile string. This simplifies JSEP behavior, | (incorrect) older profile string. This simplifies JSEP behavior, | |||
with minimal downside, as any remote endpoint that fails to handle | with minimal downside, as any remote endpoint that fails to handle | |||
such a re-offer will also fail to handle a JSEP endpoint's initial | such a re-offer will also fail to handle a JSEP endpoint's initial | |||
offer. | offer. | |||
5.2. Constructing an Offer | 5.2. Constructing an Offer | |||
When createOffer is called, a new SDP description must be created | When createOffer is called, a new SDP description must be created | |||
that includes the functionality specified in [RFCYYY5]. The exact | that includes the functionality specified in [RFC8834]. The exact | |||
details of this process are explained below. | details of this process are explained below. | |||
5.2.1. Initial Offers | 5.2.1. Initial Offers | |||
When createOffer is called for the first time, the result is known as | When createOffer is called for the first time, the result is known as | |||
the initial offer. | the initial offer. | |||
The first step in generating an initial offer is to generate session- | The first step in generating an initial offer is to generate session- | |||
level attributes, as specified in [RFC4566], Section 5. | level attributes, as specified in [RFC4566], Section 5. | |||
Specifically: | Specifically: | |||
* The first SDP line MUST be "v=0", as specified in [RFC4566], | * The first SDP line MUST be "v=0", as specified in [RFC4566], | |||
Section 5.1 | Section 5.1. | |||
* The second SDP line MUST be an "o=" line, as specified in | * The second SDP line MUST be an "o=" line, as specified in | |||
[RFC4566], Section 5.2. The value of the <username> field SHOULD | [RFC4566], Section 5.2. The value of the <username> field SHOULD | |||
be "-". The sess-id MUST be representable by a 64-bit signed | be "-". The sess-id MUST be representable by a 64-bit signed | |||
integer, and the value MUST be less than (2**63)-1. It is | integer, and the value MUST be less than (2**63)-1 ((2^(63))-1). | |||
RECOMMENDED that the sess-id be constructed by generating a 64-bit | It is RECOMMENDED that the sess-id be constructed by generating a | |||
quantity with the highest bit set to zero and the remaining 63 | 64-bit quantity with the highest bit set to zero and the remaining | |||
bits being cryptographically random. The value of the <nettype> | 63 bits being cryptographically random. The value of the | |||
<addrtype> <unicast-address> tuple SHOULD be set to a non- | <nettype> <addrtype> <unicast-address> tuple SHOULD be set to a | |||
meaningful address, such as IN IP4 0.0.0.0, to prevent leaking a | non-meaningful address, such as IN IP4 0.0.0.0, to prevent leaking | |||
local IP address in this field; this problem is discussed in | a local IP address in this field; this problem is discussed in | |||
[RFCYYY3]. As mentioned in [RFC4566], the entire o= line needs to | [RFC8828]. As mentioned in [RFC4566], the entire "o=" line needs | |||
be unique, but selecting a random number for <sess-id> is | to be unique, but selecting a random number for <sess-id> is | |||
sufficient to accomplish this. | sufficient to accomplish this. | |||
* The third SDP line MUST be a "s=" line, as specified in [RFC4566], | * The third SDP line MUST be a "s=" line, as specified in [RFC4566], | |||
Section 5.3; to match the "o=" line, a single dash SHOULD be used | 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 | as the session name, e.g., "s=-". Note that this differs from the | |||
advice in [RFC4566] which proposes a single space, but as both | advice in [RFC4566], which proposes a single space, but as both | |||
"o=" and "s=" are meaningless in JSEP, having the same meaningless | "o=" and "s=" are meaningless in JSEP, having the same meaningless | |||
value seems clearer. | value seems clearer. | |||
* Session Information ("i="), URI ("u="), Email Address ("e="), | * Session Information ("i="), URI ("u="), Email Address ("e="), | |||
Phone Number ("p="), Repeat Times ("r="), and Time Zones ("z=") | Phone Number ("p="), Repeat Times ("r="), and Time Zones ("z=") | |||
lines are not useful in this context and SHOULD NOT be included. | lines are not useful in this context and SHOULD NOT be included. | |||
* Encryption Keys ("k=") lines do not provide sufficient security | * Encryption Keys ("k=") lines do not provide sufficient security | |||
and MUST NOT be included. | and MUST NOT be included. | |||
* A "t=" line MUST be added, as specified in [RFC4566], Section 5.9; | * A "t=" line MUST be added, as specified in [RFC4566], Section 5.9; | |||
both <start-time> and <stop-time> SHOULD be set to zero, e.g. "t=0 | both <start-time> and <stop-time> SHOULD be set to zero, e.g., | |||
0". | "t=0 0". | |||
* An "a=ice-options" line with the "trickle" and "ice2" options MUST | * An "a=ice-options" line with the "trickle" and "ice2" options MUST | |||
be added, as specified in [RFCYYY6], Section 3 and [RFC8445], | be added, as specified in [RFC8840], Section 4.1.1 and [RFC8445], | |||
Section 10. | Section 10. | |||
* If WebRTC identity is being used, an "a=identity" line as | * If WebRTC identity is being used, an "a=identity" line, as | |||
described in [RFCYYY2], Section 5. | described in [RFC8827], Section 5, needs to be included. | |||
The next step is to generate m= sections, as specified in [RFC4566], | The next step is to generate "m=" sections, as specified in | |||
Section 5.14. An m= section is generated for each RtpTransceiver | [RFC4566], Section 5.14. An "m=" section is generated for each | |||
that has been added to the PeerConnection, excluding any stopped | RtpTransceiver that has been added to the PeerConnection, excluding | |||
RtpTransceivers; this is done in the order the RtpTransceivers were | any stopped RtpTransceivers; this is done in the order the | |||
added to the PeerConnection. If there are no such RtpTransceivers, | RtpTransceivers were added to the PeerConnection. If there are no | |||
no m= sections are generated; more can be added later, as discussed | such RtpTransceivers, no "m=" sections are generated; more can be | |||
in [RFC3264], Section 5. | added later, as discussed in [RFC3264], Section 5. | |||
For each m= section generated for an RtpTransceiver, establish a | For each "m=" section generated for an RtpTransceiver, establish a | |||
mapping between the transceiver and the index of the generated m= | mapping between the transceiver and the index of the generated "m=" | |||
section. | section. | |||
Each m= section, provided it is not marked as bundle-only, MUST | Each "m=" section, provided it is not marked as bundle-only, MUST | |||
generate a unique set of ICE credentials and gather its own unique | generate a unique set of ICE credentials and gather its own unique | |||
set of ICE candidates. Bundle-only m= sections MUST NOT contain any | set of ICE candidates. Bundle-only "m=" sections MUST NOT contain | |||
ICE credentials and MUST NOT gather any candidates. | any ICE credentials and MUST NOT gather any candidates. | |||
For DTLS, all m= sections MUST use all the certificate(s) that have | For DTLS, all "m=" sections MUST use any and all certificates that | |||
been specified for the PeerConnection; as a result, they MUST all | have been specified for the PeerConnection; as a result, they MUST | |||
have the same [RFC8122] fingerprint value(s), or these value(s) MUST | all have the same fingerprint value or values [RFC8122], or these | |||
be session-level attributes. | values MUST be session-level attributes. | |||
Each m= section should be generated as specified in [RFC4566], | Each "m=" section should be generated as specified in [RFC4566], | |||
Section 5.14. For the m= line itself, the following rules MUST be | Section 5.14. For the "m=" line itself, the following rules MUST be | |||
followed: | followed: | |||
* If the m= section is marked as bundle-only, then the port value | * If the "m=" section is marked as bundle-only, then the port value | |||
MUST be set to 0. Otherwise, the port value is set to the port of | MUST be set to 0. Otherwise, the port value is set to the port of | |||
the default ICE candidate for this m= section, but given that no | the default ICE candidate for this "m=" section, but given that no | |||
candidates are available yet, the "dummy" port value of 9 | candidates are available yet, the "dummy" port value of 9 | |||
(Discard) MUST be used, as indicated in [RFCYYY6], Section 5.1. | (Discard) MUST be used, as indicated in [RFC8840], Section 4.1.1. | |||
* To properly indicate use of DTLS, the <proto> field MUST be set to | * To properly indicate use of DTLS, the <proto> field MUST be set to | |||
"UDP/TLS/RTP/SAVPF", as specified in [RFC5764], Section 8. | "UDP/TLS/RTP/SAVPF", as specified in [RFC5764], Section 8. | |||
* If codec preferences have been set for the associated transceiver, | * If codec preferences have been set for the associated transceiver, | |||
media formats MUST be generated in the corresponding order, and | media formats MUST be generated in the corresponding order and | |||
MUST exclude any codecs not present in the codec preferences. | MUST exclude any codecs not present in the codec preferences. | |||
* Unless excluded by the above restrictions, the media formats MUST | * Unless excluded by the above restrictions, the media formats MUST | |||
include the mandatory audio/video codecs as specified in | include the mandatory audio/video codecs as specified in | |||
[RFC7874], Section 3, and [RFC7742], Section 5. | [RFC7874], Section 3 and [RFC7742], Section 5. | |||
The m= line MUST be followed immediately by a "c=" line, as specified | The "m=" line MUST be followed immediately by a "c=" line, as | |||
in [RFC4566], Section 5.7. Again, as no candidates are available | specified in [RFC4566], Section 5.7. Again, as no candidates are | |||
yet, the "c=" line must contain the "dummy" value "IN IP4 0.0.0.0", | available yet, the "c=" line must contain the "dummy" value "IN IP4 | |||
as defined in [RFCYYY6], Section 5.1. | 0.0.0.0", as defined in [RFC8840], Section 4.1.1. | |||
[RFCYYYH] groups SDP attributes into different categories. To avoid | [RFC8859] groups SDP attributes into different categories. To avoid | |||
unnecessary duplication when bundling, attributes of category | unnecessary duplication when bundling, attributes of category | |||
IDENTICAL or TRANSPORT MUST NOT be repeated in bundled m= sections, | IDENTICAL or TRANSPORT MUST NOT be repeated in bundled "m=" sections, | |||
repeating the guidance from [RFCYYYB], Section 8.1. This includes m= | repeating the guidance from [RFC8843], Section 8.1. This includes | |||
sections for which bundling has been negotiated and is still desired, | "m=" sections for which bundling has been negotiated and is still | |||
as well as m= sections marked as bundle-only. | desired, as well as "m=" sections marked as bundle-only. | |||
The following attributes, which are of a category other than | The following attributes, which are of a category other than | |||
IDENTICAL or TRANSPORT, MUST be included in each m= section: | IDENTICAL or TRANSPORT, MUST be included in each "m=" section: | |||
* An "a=mid" line, as specified in [RFC5888], Section 4. All MID | * An "a=mid" line, as specified in [RFC5888], Section 4. All MID | |||
values MUST be generated in a fashion that does not leak user | values MUST be generated in a fashion that does not leak user | |||
information, e.g., randomly or using a per-PeerConnection counter, | information, e.g., randomly or using a per-PeerConnection counter, | |||
and SHOULD be 3 bytes or less, to allow them to efficiently fit | and SHOULD be 3 bytes or less, to allow them to efficiently fit | |||
into the RTP header extension defined in [RFCYYYB], Section 14. | into the RTP header extension defined in [RFC8843], Section 14. | |||
Note that this does not set the RtpTransceiver mid property, as | Note that this does not set the RtpTransceiver mid property, as | |||
that only occurs when the description is applied. The generated | that only occurs when the description is applied. The generated | |||
MID value can be considered a "proposed" MID at this point. | MID value can be considered a "proposed" MID at this point. | |||
* A direction attribute which is the same as that of the associated | * A direction attribute that is the same as that of the associated | |||
transceiver. | transceiver. | |||
* For each media format on the m= line, "a=rtpmap" and "a=fmtp" | * For each media format on the "m=" line, "a=rtpmap" and "a=fmtp" | |||
lines, as specified in [RFC4566], Section 6, and [RFC3264], | lines, as specified in [RFC4566], Section 6 and [RFC3264], | |||
Section 5.1. | Section 5.1. | |||
* For each primary codec where RTP retransmission should be used, a | * For each primary codec where RTP retransmission should be used, a | |||
corresponding "a=rtpmap" line indicating "rtx" with the clock rate | corresponding "a=rtpmap" line indicating "rtx" with the clock rate | |||
of the primary codec and an "a=fmtp" line that references the | of the primary codec and an "a=fmtp" line that references the | |||
payload type of the primary codec, as specified in [RFC4588], | payload type of the primary codec, as specified in [RFC4588], | |||
Section 8.1. | Section 8.1. | |||
* For each supported FEC mechanism, "a=rtpmap" and "a=fmtp" lines, | * For each supported Forward Error Correction (FEC) mechanism, | |||
as specified in [RFC4566], Section 6. The FEC mechanisms that | "a=rtpmap" and "a=fmtp" lines, as specified in [RFC4566], | |||
MUST be supported are specified in [RFCYYYF], Section 6, and | Section 6. The FEC mechanisms that MUST be supported are | |||
specific usage for each media type is outlined in Sections 4 and | specified in [RFC8854], Section 6, and specific usage for each | |||
5. | media type is outlined in Sections 4 and 5. | |||
* If this m= section is for media with configurable durations of | * If this "m=" section is for media with configurable durations of | |||
media per packet, e.g., audio, an "a=maxptime" line, indicating | media per packet, e.g., audio, an "a=maxptime" line, indicating | |||
the maximum amount of media, specified in milliseconds, that can | the maximum amount of media, specified in milliseconds, that can | |||
be encapsulated in each packet, as specified in [RFC4566], | be encapsulated in each packet, as specified in [RFC4566], | |||
Section 6. This value is set to the smallest of the maximum | Section 6. This value is set to the smallest of the maximum | |||
duration values across all the codecs included in the m= section. | duration values across all the codecs included in the "m=" | |||
section. | ||||
* If this m= section is for video media, and there are known | * If this "m=" section is for video media and there are known | |||
limitations on the size of images which can be decoded, an | limitations on the size of images that can be decoded, an | |||
"a=imageattr" line, as specified in Section 3.6. | "a=imageattr" line, as specified in Section 3.6. | |||
* For each supported RTP header extension, an "a=extmap" line, as | * For each supported RTP header extension, an "a=extmap" line, as | |||
specified in [RFC5285], Section 5. The list of header extensions | specified in [RFC5285], Section 5. The list of header extensions | |||
that SHOULD/MUST be supported is specified in [RFCYYY5], | that SHOULD/MUST be supported is specified in [RFC8834], | |||
Section 5.2. Any header extensions that require encryption MUST | Section 5.2. Any header extensions that require encryption MUST | |||
be specified as indicated in [RFC6904], Section 4. | be specified as indicated in [RFC6904], Section 4. | |||
* For each supported RTCP feedback mechanism, an "a=rtcp-fb" line, | * For each supported RTCP feedback mechanism, an "a=rtcp-fb" line, | |||
as specified in [RFC4585], Section 4.2. The list of RTCP feedback | as specified in [RFC4585], Section 4.2. The list of RTCP feedback | |||
mechanisms that SHOULD/MUST be supported is specified in | mechanisms that SHOULD/MUST be supported is specified in | |||
[RFCYYY5], Section 5.1. | [RFC8834], Section 5.1. | |||
* If the RtpTransceiver has a sendrecv or sendonly direction: | * If the RtpTransceiver has a sendrecv or sendonly direction: | |||
- For each MediaStream that was associated with the transceiver | - For each MediaStream that was associated with the transceiver | |||
when it was created via addTrack or addTransceiver, an "a=msid" | when it was created via addTrack or addTransceiver, an "a=msid" | |||
line, as specified in [RFCYYY4], Section 2, but omitting the | line, as specified in [RFC8830], Section 2, but omitting the | |||
"appdata" field. | "appdata" field. | |||
* If the RtpTransceiver has a sendrecv or sendonly direction, and | * If the RtpTransceiver has a sendrecv or sendonly direction, and | |||
the application has specified RID values or has specified more | the application has specified RID values or has specified more | |||
than one encoding in the RtpSenders's parameters, an "a=rid" line | than one encoding in the RtpSenders's parameters, an "a=rid" line | |||
for each encoding specified. The "a=rid" line is specified in | for each encoding specified. The "a=rid" line is specified in | |||
[RFCYYYC], and its direction MUST be "send". If the application | [RFC8851], and its direction MUST be "send". If the application | |||
has chosen a RID value, it MUST be used as the rid-identifier; | has chosen a RID value, it MUST be used as the rid-identifier; | |||
otherwise a RID value MUST be generated by the implementation. | otherwise, a RID value MUST be generated by the implementation. | |||
RID values MUST be generated in a fashion that does not leak user | RID values MUST be generated in a fashion that does not leak user | |||
information, e.g., randomly or using a per-PeerConnection counter, | information, e.g., randomly or using a per-PeerConnection counter, | |||
and SHOULD be 3 bytes or less, to allow them to efficiently fit | and SHOULD be 3 bytes or less, to allow them to efficiently fit | |||
into the RTP header extension defined in [RFCYYYD], Section 3. If | into the RTP header extension defined in [RFC8852], Section 3. If | |||
no encodings have been specified, or only one encoding is | no encodings have been specified, or only one encoding is | |||
specified but without a RID value, then no "a=rid" lines are | specified but without a RID value, then no "a=rid" lines are | |||
generated. | generated. | |||
* If the RtpTransceiver has a sendrecv or sendonly direction and | * If the RtpTransceiver has a sendrecv or sendonly direction and | |||
more than one "a=rid" line has been generated, an "a=simulcast" | more than one "a=rid" line has been generated, an "a=simulcast" | |||
line, with direction "send", as defined in [RFCYYYE], Section 6.2. | line, with direction "send", as defined in [RFC8853], Section 6.2. | |||
The list of RIDs MUST include all of the RID identifiers used in | The list of RIDs MUST include all of the RID identifiers used in | |||
the "a=rid" lines for this m= section. | the "a=rid" lines for this "m=" section. | |||
* If the bundle policy for this PeerConnection is set to "max- | * If the bundle policy for this PeerConnection is set to "max- | |||
bundle", and this is not the first m= section, or the bundle | 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 | policy is set to "balanced", and this is not the first "m=" | |||
for this media type, an "a=bundle-only" line. | section for this media type, an "a=bundle-only" line. | |||
The following attributes, which are of category IDENTICAL or | The following attributes, which are of category IDENTICAL or | |||
TRANSPORT, MUST appear only in "m=" sections which either have a | TRANSPORT, MUST appear only in "m=" sections that either have a | |||
unique address or which are associated with the bundle-tag. (In | unique address or are associated with the BUNDLE-tag. (In initial | |||
initial offers, this means those "m=" sections which do not contain | offers, this means those "m=" sections that do not contain an | |||
an "a=bundle-only" attribute.) | "a=bundle-only" attribute.) | |||
* "a=ice-ufrag" and "a=ice-pwd" lines, as specified in [RFCYYY7], | * "a=ice-ufrag" and "a=ice-pwd" lines, as specified in [RFC8839], | |||
Section 4.4. | Section 5.4. | |||
* For each desired digest algorithm, one or more "a=fingerprint" | * For each desired digest algorithm, one or more "a=fingerprint" | |||
lines for each of the endpoint's certificates, as specified in | lines for each of the endpoint's certificates, as specified in | |||
[RFC8122], Section 5. | [RFC8122], Section 5. | |||
* An "a=setup" line, as specified in [RFC4145], Section 4, and | * An "a=setup" line, as specified in [RFC4145], Section 4 and | |||
clarified for use in DTLS-SRTP scenarios in [RFC5763], Section 5. | clarified for use in DTLS-SRTP scenarios in [RFC5763], Section 5. | |||
The role value in the offer MUST be "actpass". | The role value in the offer MUST be "actpass". | |||
* An "a=tls-id" line, as specified in [RFCYYYA], Section 5.2. | * An "a=tls-id" line, as specified in [RFC8842], Section 5.2. | |||
* An "a=rtcp" line, as specified in [RFC3605], Section 2.1, | * An "a=rtcp" line, as specified in [RFC3605], Section 2.1, | |||
containing the dummy value "9 IN IP4 0.0.0.0", because no | containing the dummy value "9 IN IP4 0.0.0.0", because no | |||
candidates have yet been gathered. | candidates have yet been gathered. | |||
* An "a=rtcp-mux" line, as specified in [RFC5761], Section 5.1.3. | * An "a=rtcp-mux" line, as specified in [RFC5761], Section 5.1.3. | |||
* If the RTP/RTCP multiplexing policy is "require", an "a=rtcp-mux- | * If the RTP/RTCP multiplexing policy is "require", an "a=rtcp-mux- | |||
only" line, as specified in [RFCYYYG], Section 4. | only" line, as specified in [RFC8858], Section 4. | |||
* An "a=rtcp-rsize" line, as specified in [RFC5506], Section 5. | * An "a=rtcp-rsize" line, as specified in [RFC5506], Section 5. | |||
Lastly, if a data channel has been created, a m= section MUST be | Lastly, if a data channel has been created, an "m=" section MUST be | |||
generated for data. The <media> field MUST be set to "application" | generated for data. The <media> field MUST be set to "application", | |||
and the <proto> field MUST be set to "UDP/DTLS/SCTP" [RFCYYY9]. The | and the <proto> field MUST be set to "UDP/DTLS/SCTP" [RFC8841]. The | |||
"fmt" value MUST be set to "webrtc-datachannel" as specified in | "fmt" value MUST be set to "webrtc-datachannel" as specified in | |||
[RFCYYY9], Section 4.1. | [RFC8841], Section 4.1. | |||
Within the data m= section, an "a=mid" line MUST be generated and | Within the data "m=" section, an "a=mid" line MUST be generated and | |||
included as described above, along with an "a=sctp-port" line | included as described above, along with an "a=sctp-port" line | |||
referencing the SCTP port number, as defined in [RFCYYY9], | referencing the SCTP port number, as defined in [RFC8841], | |||
Section 5.1, and, if appropriate, an "a=max-message-size" line, as | Section 5.1; and, if appropriate, an "a=max-message-size" line, as | |||
defined in [RFCYYY9], Section 6.1. | defined in [RFC8841], Section 6.1. | |||
As discussed above, the following attributes of category IDENTICAL or | As discussed above, the following attributes of category IDENTICAL or | |||
TRANSPORT are included only if the data m= section either has a | TRANSPORT are included only if the data "m=" section either has a | |||
unique address or is associated with the bundle-tag (e.g., if it is | unique address or is associated with the BUNDLE-tag (e.g., if it is | |||
the only m= section): | the only "m=" section): | |||
* "a=ice-ufrag" | * "a=ice-ufrag" | |||
* "a=ice-pwd" | * "a=ice-pwd" | |||
* "a=fingerprint" | * "a=fingerprint" | |||
* "a=setup" | * "a=setup" | |||
* "a=tls-id" | * "a=tls-id" | |||
Once all m= sections have been generated, a session-level "a=group" | Once all "m=" sections have been generated, a session-level "a=group" | |||
attribute MUST be added as specified in [RFC5888]. This attribute | attribute MUST be added as specified in [RFC5888]. This attribute | |||
MUST have semantics "BUNDLE", and MUST include the mid identifiers of | MUST have semantics "BUNDLE" and MUST include the mid identifiers of | |||
each m= section. The effect of this is that the JSEP implementation | each "m=" section. The effect of this is that the JSEP | |||
offers all m= sections as one bundle group. However, whether the m= | implementation offers all "m=" sections as one bundle group. | |||
sections are bundle-only or not depends on the bundle policy. | 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 | The next step is to generate session-level lip sync groups as defined | |||
in [RFC5888], Section 7. For each MediaStream referenced by more | in [RFC5888], Section 7. For each MediaStream referenced by more | |||
than one RtpTransceiver (by passing those MediaStreams as arguments | than one RtpTransceiver (by passing those MediaStreams as arguments | |||
to the addTrack and addTransceiver methods), a group of type "LS" | to the addTrack and addTransceiver methods), a group of type "LS" | |||
MUST be added that contains the mid values for each RtpTransceiver. | MUST be added that contains the mid values for each RtpTransceiver. | |||
Attributes which SDP permits to either be at the session level or the | Attributes that SDP permits to be at either the session level or the | |||
media level SHOULD generally be at the media level even if they are | media level SHOULD generally be at the media level even if they are | |||
identical. This assists development and debugging by making it | identical. This assists development and debugging by making it | |||
easier to understand individual media sections, especially if one of | easier to understand individual media sections, especially if one of | |||
a set of initially identical attributes is subsequently changed. | a set of initially identical attributes is subsequently changed. | |||
However, implementations MAY choose to aggregate attributes at the | However, implementations MAY choose to aggregate attributes at the | |||
session level and JSEP implementations MUST be prepared to receive | session level, and JSEP implementations MUST be prepared to receive | |||
attributes in either location. | attributes in either location. | |||
Attributes other than the ones specified above MAY be included, | Attributes other than the ones specified above MAY be included, | |||
except for the following attributes which are specifically | except for the following attributes, which are specifically | |||
incompatible with the requirements of [RFCYYY5], and MUST NOT be | incompatible with the requirements of [RFC8834] and MUST NOT be | |||
included: | included: | |||
* "a=crypto" | * "a=crypto" | |||
* "a=key-mgmt" | * "a=key-mgmt" | |||
* "a=ice-lite" | * "a=ice-lite" | |||
Note that when bundle is used, any additional attributes that are | Note that when bundle is used, any additional attributes that are | |||
added MUST follow the advice in [RFCYYYH] on how those attributes | added MUST follow the advice in [RFC8859] on how those attributes | |||
interact with bundle. | interact with bundle. | |||
Note that these requirements are in some cases stricter than those of | Note that these requirements are in some cases stricter than those of | |||
SDP. Implementations MUST be prepared to accept compliant SDP even | SDP. Implementations MUST be prepared to accept compliant SDP even | |||
if it would not conform to the requirements for generating SDP in | if it would not conform to the requirements for generating SDP in | |||
this specification. | this specification. | |||
5.2.2. Subsequent Offers | 5.2.2. Subsequent Offers | |||
When createOffer is called a second (or later) time, or is called | When createOffer is called a second (or later) time or is called | |||
after a local description has already been installed, the processing | after a local description has already been installed, the processing | |||
is somewhat different than for an initial offer. | is somewhat different than for an initial offer. | |||
If the previous offer was not applied using setLocalDescription, | If the previous offer was not applied using setLocalDescription, | |||
meaning the PeerConnection is still in the "stable" state, the steps | meaning the PeerConnection is still in the "stable" state, the steps | |||
for generating an initial offer should be followed, subject to the | for generating an initial offer should be followed, subject to the | |||
following restriction: | following restriction: | |||
* The fields of the "o=" line MUST stay the same except for the | * The fields of the "o=" line MUST stay the same except for the | |||
<session-version> field, which MUST increment by one on each call | <session-version> field, which MUST increment by one on each call | |||
skipping to change at line 2006 ¶ | skipping to change at line 2022 ¶ | |||
<session-version>. | <session-version>. | |||
If the previous offer was applied using setLocalDescription, but a | If the previous offer was applied using setLocalDescription, but a | |||
corresponding answer from the remote side has not yet been applied, | corresponding answer from the remote side has not yet been applied, | |||
meaning the PeerConnection is still in the "have-local-offer" state, | meaning the PeerConnection is still in the "have-local-offer" state, | |||
an offer is generated by following the steps in the "stable" state | an offer is generated by following the steps in the "stable" state | |||
above, along with these exceptions: | above, along with these exceptions: | |||
* The "s=" and "t=" lines MUST stay the same. | * The "s=" and "t=" lines MUST stay the same. | |||
* If any RtpTransceiver has been added, and there exists an m= | * If any RtpTransceiver has been added and there exists an "m=" | |||
section with a zero port in the current local description or the | section with a zero port in the current local description or the | |||
current remote description, that m= section MUST be recycled by | current remote description, that "m=" section MUST be recycled by | |||
generating an m= section for the added RtpTransceiver as if the m= | generating an "m=" section for the added RtpTransceiver as if the | |||
section were being added to the session description (including a | "m=" section were being added to the session description | |||
new MID value), and placing it at the same index as the m= section | (including a new MID value) and placing it at the same index as | |||
with a zero port. | the "m=" section with a zero port. | |||
* If an RtpTransceiver is stopped and is not associated with an m= | * If an RtpTransceiver is stopped and is not associated with an "m=" | |||
section, an m= section MUST NOT be generated for it. This | section, an "m=" section MUST NOT be generated for it. This | |||
prevents adding back RtpTransceivers whose m= sections were | prevents adding back RtpTransceivers whose "m=" sections were | |||
recycled and used for a new RtpTransceiver in a previous offer/ | recycled and used for a new RtpTransceiver in a previous offer/ | |||
answer exchange, as described above. | answer exchange, as described above. | |||
* If an RtpTransceiver has been stopped and is associated with an m= | * If an RtpTransceiver has been stopped and is associated with an | |||
section, and the m= section is not being recycled as described | "m=" section, and the "m=" section is not being recycled as | |||
above, an m= section MUST be generated for it with the port set to | described above, an "m=" section MUST be generated for it with the | |||
zero and all "a=msid" lines removed. | port set to zero and all "a=msid" lines removed. | |||
* For RtpTransceivers that are not stopped, the "a=msid" line(s) | * For RtpTransceivers that are not stopped, the "a=msid" line or | |||
MUST stay the same if they are present in the current description, | lines MUST stay the same if they are present in the current | |||
regardless of changes to the transceiver's direction or track. If | description, regardless of changes to the transceiver's direction | |||
no "a=msid" line is present in the current description, "a=msid" | or track. If no "a=msid" line is present in the current | |||
line(s) MUST be generated according to the same rules as for an | description, "a=msid" line(s) MUST be generated according to the | |||
initial offer. | same rules as for an initial offer. | |||
* Each "m=" and c=" line MUST be filled in with the port, relevant | * Each "m=" and "c=" line MUST be filled in with the port, relevant | |||
RTP profile, and address of the default candidate for the m= | RTP profile, and address of the default candidate for the "m=" | |||
section, as described in [RFCYYY7], Section 3.2.1.2, and clarified | section, as described in [RFC8839], Section 4.2.1.2 and clarified | |||
in Section 5.1.2. If no RTP candidates have yet been gathered, | in Section 5.1.2. If no RTP candidates have yet been gathered, | |||
dummy values MUST still be used, as described above. | dummy values MUST still be used, as described above. | |||
* Each "a=mid" line MUST stay the same. | * Each "a=mid" line MUST stay the same. | |||
* Each "a=ice-ufrag" and "a=ice-pwd" line MUST stay the same, unless | * Each "a=ice-ufrag" and "a=ice-pwd" line MUST stay the same, unless | |||
the ICE configuration has changed (either changes to the supported | the ICE configuration has changed (e.g., changes to either the | |||
STUN/TURN servers, or the ICE candidate policy), or the | supported STUN/TURN servers or the ICE candidate policy) or the | |||
"IceRestart" option ( Section 5.2.3.1 was specified. If the m= | "IceRestart" option (Section 5.2.3.1) was specified. If the "m=" | |||
section is bundled into another m= section, it still MUST NOT | section is bundled into another "m=" section, it still MUST NOT | |||
contain any ICE credentials. | contain any ICE credentials. | |||
* If the m= section is not bundled into another m= section, its | * If the "m=" section is not bundled into another "m=" section, its | |||
"a=rtcp" attribute line MUST be filled in with the port and | "a=rtcp" attribute line MUST be filled in with the port and | |||
address of the default RTCP candidate, as indicated in [RFC5761], | address of the default RTCP candidate, as indicated in [RFC5761], | |||
Section 5.1.3. If no RTCP candidates have yet been gathered, | Section 5.1.3. If no RTCP candidates have yet been gathered, | |||
dummy values MUST be used, as described in the initial offer | dummy values MUST be used, as described in Section 5.2.1 above. | |||
section above. | ||||
* If the m= section is not bundled into another m= section, for each | * If the "m=" section is not bundled into another "m=" section, for | |||
candidate that has been gathered during the most recent gathering | each candidate that has been gathered during the most recent | |||
phase (see Section 3.5.1), an "a=candidate" line MUST be added, as | gathering phase (see Section 3.5.1), an "a=candidate" line MUST be | |||
defined in [RFCYYY7], Section 4.1. If candidate gathering for the | added, as defined in [RFC8839], Section 5.1. If candidate | |||
section has completed, an "a=end-of-candidates" attribute MUST be | gathering for the section has completed, an "a=end-of-candidates" | |||
added, as described in [RFCYYY6], Section 9.3. If the m= section | attribute MUST be added, as described in [RFC8840], Section 8.2. | |||
is bundled into another m= section, both "a=candidate" and "a=end- | If the "m=" section is bundled into another "m=" section, both | |||
of-candidates" MUST be omitted. | "a=candidate" and "a=end-of-candidates" MUST be omitted. | |||
* For RtpTransceivers that are still present, the "a=rid" lines MUST | * For RtpTransceivers that are still present, the "a=rid" lines MUST | |||
stay the same. | stay the same. | |||
* For RtpTransceivers that are still present, any "a=simulcast" line | * For RtpTransceivers that are still present, any "a=simulcast" line | |||
MUST stay the same. | MUST stay the same. | |||
If the previous offer was applied using setLocalDescription, and a | If the previous offer was applied using setLocalDescription, and a | |||
corresponding answer from the remote side has been applied using | corresponding answer from the remote side has been applied using | |||
setRemoteDescription, meaning the PeerConnection is in the "have- | setRemoteDescription, meaning the PeerConnection is in the "have- | |||
remote-pranswer" or "stable" states, an offer is generated based on | remote-pranswer" state or the "stable" state, an offer is generated | |||
the negotiated session descriptions by following the steps mentioned | based on the negotiated session descriptions by following the steps | |||
for the "have-local-offer" state above. | mentioned for the "have-local-offer" state above. | |||
In addition, for each existing, non-recycled, non-rejected m= section | In addition, for each existing, non-recycled, non-rejected "m=" | |||
in the new offer, the following adjustments are made based on the | section in the new offer, the following adjustments are made based on | |||
contents of the corresponding m= section in the current local or | the contents of the corresponding "m=" section in the current local | |||
remote description, as appropriate: | or remote description, as appropriate: | |||
* The m= line and corresponding "a=rtpmap" and "a=fmtp" lines MUST | * The "m=" line and corresponding "a=rtpmap" and "a=fmtp" lines MUST | |||
only include media formats which have not been excluded by the | only include media formats that have not been excluded by the | |||
codec preferences of the associated transceiver, and MUST include | codec preferences of the associated transceiver and also MUST | |||
all currently available formats. Media formats that were | include all currently available formats. Media formats that were | |||
previously offered but are no longer available (e.g., a shared | previously offered but are no longer available (e.g., a shared | |||
hardware codec) MAY be excluded. | hardware codec) MAY be excluded. | |||
* Unless codec preferences have been set for the associated | * Unless codec preferences have been set for the associated | |||
transceiver, the media formats on the m= line MUST be generated in | transceiver, the media formats on the "m=" line MUST be generated | |||
the same order as in the most recent answer. Any media formats | in the same order as in the most recent answer. Any media formats | |||
that were not present in the most recent answer MUST be added | that were not present in the most recent answer MUST be added | |||
after all existing formats. | after all existing formats. | |||
* The RTP header extensions MUST only include those that are present | * The RTP header extensions MUST only include those that are present | |||
in the most recent answer. | in the most recent answer. | |||
* The RTCP feedback mechanisms MUST only include those that are | * The RTCP feedback mechanisms MUST only include those that are | |||
present in the most recent answer, except for the case of format- | present in the most recent answer, except for the case of format- | |||
specific mechanisms that are referencing a newly-added media | specific mechanisms that are referencing a newly added media | |||
format. | format. | |||
* The "a=rtcp" line MUST NOT be added if the most recent answer | * The "a=rtcp" line MUST NOT be added if the most recent answer | |||
included an "a=rtcp-mux" line. | included an "a=rtcp-mux" line. | |||
* The "a=rtcp-mux" line MUST be the same as that in the most recent | * The "a=rtcp-mux" line MUST be the same as that in the most recent | |||
answer. | answer. | |||
* The "a=rtcp-mux-only" line MUST NOT be added. | * The "a=rtcp-mux-only" line MUST NOT be added. | |||
* The "a=rtcp-rsize" line MUST NOT be added unless present in the | * The "a=rtcp-rsize" line MUST NOT be added unless present in the | |||
most recent answer. | most recent answer. | |||
* An "a=bundle-only" line MUST NOT be added, as indicated in | * An "a=bundle-only" line MUST NOT be added, as indicated in | |||
[RFCYYYB], Section 6. Instead, JSEP implementations MUST simply | [RFC8843], Section 6. Instead, JSEP implementations MUST simply | |||
omit parameters in the IDENTICAL and TRANSPORT categories for | omit parameters in the IDENTICAL and TRANSPORT categories for | |||
bundled m= sections, as described in [RFCYYYB], Section 8.1. | bundled "m=" sections, as described in [RFC8843], Section 8.1. | |||
* Note that if media m= sections are bundled into a data m= section, | * Note that if media "m=" sections are bundled into a data "m=" | |||
then certain TRANSPORT and IDENTICAL attributes may appear in the | section, then certain TRANSPORT and IDENTICAL attributes may | |||
data m= section even if they would otherwise only be appropriate | appear in the data "m=" section even if they would otherwise only | |||
for a media m= section (e.g., "a=rtcp-mux"). This cannot happen | be appropriate for a media "m=" section (e.g., "a=rtcp-mux"). | |||
in initial offers because in the initial offer JSEP | This cannot happen in initial offers because in the initial offer | |||
implementations always list media m= sections (if any) before the | JSEP implementations always list media "m=" sections (if any) | |||
data m= section (if any), and at least one of those media m= | before the data "m=" section (if any), and at least one of those | |||
sections will not have the "a=bundle-only" attribute. Therefore, | media "m=" sections will not have the "a=bundle-only" attribute. | |||
in initial offers, any "a=bundle-only" m= sections will be bundled | Therefore, in initial offers, any "a=bundle-only" "m=" sections | |||
into a preceding non-bundle-only media m= section. | will be bundled into a preceding non-bundle-only media "m=" | |||
section. | ||||
The "a=group:BUNDLE" attribute MUST include the MID identifiers | The "a=group:BUNDLE" attribute MUST include the MID identifiers | |||
specified in the bundle group in the most recent answer, minus any m= | specified in the bundle group in the most recent answer, minus any | |||
sections that have been marked as rejected, plus any newly added or | "m=" sections that have been marked as rejected, plus any newly added | |||
re-enabled m= sections. In other words, the bundle attribute must | or re-enabled "m=" sections. In other words, the bundle attribute | |||
contain all m= sections that were previously bundled, as long as they | must contain all "m=" sections that were previously bundled, as long | |||
are still alive, as well as any new m= sections. | as they are still alive, as well as any new "m=" sections. | |||
"a=group:LS" attributes are generated in the same way as for initial | "a=group:LS" attributes are generated in the same way as for initial | |||
offers, with the additional stipulation that any lip sync groups that | offers, with the additional stipulation that any lip sync groups that | |||
were present in the most recent answer MUST continue to exist and | were present in the most recent answer MUST continue to exist and | |||
MUST contain any previously existing MID identifiers, as long as the | MUST contain any previously existing MID identifiers, as long as the | |||
identified m= sections still exist and are not rejected, and the | identified "m=" sections still exist and are not rejected, and the | |||
group still contains at least two MID identifiers. This ensures that | group still contains at least two MID identifiers. This ensures that | |||
any synchronized "recvonly" m= sections continue to be synchronized | any synchronized "recvonly" "m=" sections continue to be synchronized | |||
in the new offer. | in the new offer. | |||
5.2.3. Options Handling | 5.2.3. Options Handling | |||
The createOffer method takes as a parameter an RTCOfferOptions | The createOffer method takes as a parameter an RTCOfferOptions | |||
object. Special processing is performed when generating a SDP | object. Special processing is performed when generating an SDP | |||
description if the following options are present. | description if the following options are present. | |||
5.2.3.1. IceRestart | 5.2.3.1. IceRestart | |||
If the "IceRestart" option is specified, with a value of "true", the | If the "IceRestart" option is specified, with a value of "true", the | |||
offer MUST indicate an ICE restart by generating new ICE ufrag and | offer MUST indicate an ICE restart by generating new ICE ufrag and | |||
pwd attributes, as specified in [RFCYYY7], Section 3.4.1.1.1. If | pwd attributes, as specified in [RFC8839], Section 4.4.3.1.1. If | |||
this option is specified on an initial offer, it has no effect (since | 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 | a new ICE ufrag and pwd are already generated). Similarly, if the | |||
ICE configuration has changed, this option has no effect, since new | ICE configuration has changed, this option has no effect, since new | |||
ufrag and pwd attributes will be generated automatically. This | ufrag and pwd attributes will be generated automatically. This | |||
option is primarily useful for reestablishing connectivity in cases | option is primarily useful for reestablishing connectivity in cases | |||
where failures are detected by the application. | where failures are detected by the application. | |||
5.2.3.2. VoiceActivityDetection | 5.2.3.2. VoiceActivityDetection | |||
Silence suppression, also known as discontinuous transmission | Silence suppression, also known as discontinuous transmission | |||
skipping to change at line 2196 ¶ | skipping to change at line 2212 ¶ | |||
indicate that silence suppression for received audio is not desired. | indicate that silence suppression for received audio is not desired. | |||
For example, when using the Opus codec, the "usedtx=0" parameter | For example, when using the Opus codec, the "usedtx=0" parameter | |||
would be specified in the offer. In addition, the implementation | would be specified in the offer. In addition, the implementation | |||
MUST NOT use silence suppression for media it generates, regardless | MUST NOT use silence suppression for media it generates, regardless | |||
of whether the "CN" codecs or related fmtp parameters appear in the | of whether the "CN" codecs or related fmtp parameters appear in the | |||
peer's description. The impact of these rules is that silence | peer's description. The impact of these rules is that silence | |||
suppression in JSEP depends on mutual agreement of both sides, which | suppression in JSEP depends on mutual agreement of both sides, which | |||
ensures consistent handling regardless of which codec is used. | ensures consistent handling regardless of which codec is used. | |||
The "VoiceActivityDetection" option does not have any impact on the | The "VoiceActivityDetection" option does not have any impact on the | |||
setting of the "vad" value in the signaling of the client to mixer | setting of the "vad" value in the signaling of the client-to-mixer | |||
audio level header extension described in [RFC6464], Section 4. | audio level header extension described in [RFC6464], Section 4. | |||
5.3. Generating an Answer | 5.3. Generating an Answer | |||
When createAnswer is called, a new SDP description must be created | When createAnswer is called, a new SDP description must be created | |||
that is compatible with the supplied remote description as well as | that is compatible with the supplied remote description as well as | |||
the requirements specified in [RFCYYY5]. The exact details of this | the requirements specified in [RFC8834]. The exact details of this | |||
process are explained below. | process are explained below. | |||
5.3.1. Initial Answers | 5.3.1. Initial Answers | |||
When createAnswer is called for the first time after a remote | When createAnswer is called for the first time after a remote | |||
description has been provided, the result is known as the initial | description has been provided, the result is known as the initial | |||
answer. If no remote description has been installed, an answer | answer. If no remote description has been installed, an answer | |||
cannot be generated, and an error MUST be returned. | cannot be generated, and an error MUST be returned. | |||
Note that the remote description SDP may not have been created by a | 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 | JSEP endpoint and may not conform to all the requirements listed in | |||
Section 5.2. For many cases, this is not a problem. However, if any | Section 5.2. For many cases, this is not a problem. However, if any | |||
mandatory SDP attributes are missing, or functionality listed as | mandatory SDP attributes are missing or functionality listed as | |||
mandatory-to-use above is not present, this MUST be treated as an | 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 | error and MUST cause the affected "m=" sections to be marked as | |||
rejected. | rejected. | |||
The first step in generating an initial answer is to generate | The first step in generating an initial answer is to generate | |||
session-level attributes. The process here is identical to that | session-level attributes. The process here is identical to that | |||
indicated in the initial offers section above, except that the | indicated in Section 5.2.1 above, except that the "a=ice-options" | |||
"a=ice-options" line, with the "trickle" option as specified in | line, with the "trickle" option as specified in [RFC8840], | |||
[RFCYYY6], Section 3, and the "ice2" option as specified in | Section 4.1.3 and the "ice2" option as specified in [RFC8445], | |||
[RFC8445], Section 10, is only included if such an option was present | Section 10, is only included if such an option was present in the | |||
in the offer. | offer. | |||
The next step is to generate session-level lip sync groups, as | The next step is to generate session-level lip sync groups, as | |||
defined in [RFC5888], Section 7. For each group of type "LS" present | defined in [RFC5888], Section 7. For each group of type "LS" present | |||
in the offer, select the local RtpTransceivers that are referenced by | in the offer, select the local RtpTransceivers that are referenced by | |||
the MID values in the specified group, and determine which of them | the MID values in the specified group, and determine which of them | |||
either reference a common local MediaStream (specified in the calls | either reference a common local MediaStream (specified in the calls | |||
to addTrack/addTransceiver used to create them), or have no | to addTrack/addTransceiver used to create them) or have no | |||
MediaStream to reference because they were not created by addTrack/ | MediaStream to reference because they were not created by addTrack/ | |||
addTransceiver. If at least two such RtpTransceivers exist, a group | addTransceiver. If at least two such RtpTransceivers exist, a group | |||
of type "LS" with the mid values of these RtpTransceivers MUST be | of type "LS" with the mid values of these RtpTransceivers MUST be | |||
added. Otherwise the offered "LS" group MUST be ignored and no | added. Otherwise, the offered "LS" group MUST be ignored and no | |||
corresponding group generated in the answer. | corresponding group generated in the answer. | |||
As a simple example, consider the following offer of a single audio | As a simple example, consider the following offer of a single audio | |||
and single video track contained in the same MediaStream. SDP lines | and single video track contained in the same MediaStream. SDP lines | |||
not relevant to this example have been removed for clarity. As | not relevant to this example have been removed for clarity. As | |||
explained in Section 5.2, a group of type "LS" has been added that | explained in Section 5.2, a group of type "LS" has been added that | |||
references each track's RtpTransceiver. | references each track's RtpTransceiver. | |||
a=group:LS a1 v1 | a=group:LS a1 v1 | |||
m=audio 10000 UDP/TLS/RTP/SAVPF 0 | m=audio 10000 UDP/TLS/RTP/SAVPF 0 | |||
skipping to change at line 2292 ¶ | skipping to change at line 2308 ¶ | |||
an identical "LS" group. | an identical "LS" group. | |||
a=group:LS a1 v1 | a=group:LS a1 v1 | |||
m=audio 20000 UDP/TLS/RTP/SAVPF 0 | m=audio 20000 UDP/TLS/RTP/SAVPF 0 | |||
a=mid:a1 | a=mid:a1 | |||
a=recvonly | a=recvonly | |||
m=video 20001 UDP/TLS/RTP/SAVPF 96 | m=video 20001 UDP/TLS/RTP/SAVPF 96 | |||
a=mid:v1 | a=mid:v1 | |||
a=recvonly | a=recvonly | |||
The Section 7.2 example later in this document shows a more involved | The example in Section 7.2 shows a more involved case of "LS" group | |||
case of "LS" group generation. | generation. | |||
The next step is to generate m= sections for each m= section that is | The next step is to generate "m=" sections for each "m=" section that | |||
present in the remote offer, as specified in [RFC3264], Section 6. | is present in the remote offer, as specified in [RFC3264], Section 6. | |||
For the purposes of this discussion, any session-level attributes in | For the purposes of this discussion, any session-level attributes in | |||
the offer that are also valid as media-level attributes are | the offer that are also valid as media-level attributes are | |||
considered to be present in each m= section. Each offered m= section | considered to be present in each "m=" section. Each offered "m=" | |||
will have an associated RtpTransceiver, as described in Section 5.10. | section will have an associated RtpTransceiver, as described in | |||
If there are more RtpTransceivers than there are m= sections, the | Section 5.10. If there are more RtpTransceivers than there are "m=" | |||
unmatched RtpTransceivers will need to be associated in a subsequent | sections, the unmatched RtpTransceivers will need to be associated in | |||
offer. | a subsequent offer. | |||
For each offered m= section, if any of the following conditions are | For each offered "m=" section, if any of the following conditions are | |||
true, the corresponding m= section in the answer MUST be marked as | 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 | rejected by setting the port in the "m=" line to zero, as indicated | |||
[RFC3264], Section 6, and further processing for this m= section can | in [RFC3264], Section 6, and further processing for this "m=" section | |||
be skipped: | can be skipped: | |||
* The associated RtpTransceiver has been stopped. | * The associated RtpTransceiver has been stopped. | |||
* None of the offered media formats are supported and, if | * None of the offered media formats are supported and, if | |||
applicable, allowed by codec preferences. | applicable, allowed by codec preferences. | |||
* The bundle policy is "max-bundle", and this is not the first m= | * 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. | section or in the same bundle group as the first "m=" section. | |||
* The bundle policy is "balanced", and this is not the first m= | * 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 | section for this media type or in the same bundle group as the | |||
first m= section for this media type. | first "m=" section for this media type. | |||
* This m= section is in a bundle group, and the group's offerer | * This "m=" section is in a bundle group, and the group's offerer | |||
tagged m= section is being rejected due to one of the above | tagged "m=" section is being rejected due to one of the above | |||
reasons. This requires all m= sections in the bundle group to be | reasons. This requires all "m=" sections in the bundle group to | |||
rejected, as specified in [RFCYYYB], Section 7.3.3. | be rejected, as specified in [RFC8843], Section 7.3.3. | |||
Otherwise, each m= section in the answer should then be generated as | Otherwise, each "m=" section in the answer should then be generated | |||
specified in [RFC3264], Section 6.1. For the m= line itself, the | as specified in [RFC3264], Section 6.1. For the "m=" line itself, | |||
following rules must be followed: | the following rules must be followed: | |||
* The port value would normally be set to the port of the default | * The port value would normally be set to the port of the default | |||
ICE candidate for this m= section, but given that no candidates | ICE candidate for this "m=" section, but given that no candidates | |||
are available yet, the "dummy" port value of 9 (Discard) MUST be | are available yet, the "dummy" port value of 9 (Discard) MUST be | |||
used, as indicated in [RFCYYY6], Section 5.1. | used, as indicated in [RFC8840], Section 4.1.1. | |||
* The <proto> field MUST be set to exactly match the <proto> field | * The <proto> field MUST be set to exactly match the <proto> field | |||
for the corresponding m= line in the offer. | for the corresponding "m=" line in the offer. | |||
* If codec preferences have been set for the associated transceiver, | * If codec preferences have been set for the associated transceiver, | |||
media formats MUST be generated in the corresponding order, | media formats MUST be generated in the corresponding order, | |||
regardless of what was offered, and MUST exclude any codecs not | regardless of what was offered, and MUST exclude any codecs not | |||
present in the codec preferences. | present in the codec preferences. | |||
* Otherwise, the media formats on the m= line MUST be generated in | * Otherwise, the media formats on the "m=" line MUST be generated in | |||
the same order as those offered in the current remote description, | the same order as those offered in the current remote description, | |||
excluding any currently unsupported formats. Any currently | excluding any currently unsupported formats. Any currently | |||
available media formats that are not present in the current remote | available media formats that are not present in the current remote | |||
description MUST be added after all existing formats. | description MUST be added after all existing formats. | |||
* In either case, the media formats in the answer MUST include at | * In either case, the media formats in the answer MUST include at | |||
least one format that is present in the offer, but MAY include | least one format that is present in the offer but MAY include | |||
formats that are locally supported but not present in the offer, | formats that are locally supported but not present in the offer, | |||
as mentioned in [RFC3264], Section 6.1. If no common format | as mentioned in [RFC3264], Section 6.1. If no common format | |||
exists, the m= section is rejected as described above. | exists, the "m=" section is rejected as described above. | |||
The m= line MUST be followed immediately by a "c=" line, as specified | The "m=" line MUST be followed immediately by a "c=" line, as | |||
in [RFC4566], Section 5.7. Again, as no candidates are available | specified in [RFC4566], Section 5.7. Again, as no candidates are | |||
yet, the "c=" line must contain the "dummy" value "IN IP4 0.0.0.0", | available yet, the "c=" line must contain the "dummy" value "IN IP4 | |||
as defined in [RFCYYY6], Section 5.1. | 0.0.0.0", as defined in [RFC8840], Section 4.1.3. | |||
If the offer supports bundle, all m= sections to be bundled must use | If the offer supports bundle, all "m=" sections to be bundled must | |||
the same ICE credentials and candidates; all m= sections not being | use the same ICE credentials and candidates; all "m=" sections not | |||
bundled must use unique ICE credentials and candidates. Each m= | being bundled must use unique ICE credentials and candidates. Each | |||
section MUST contain the following attributes (which are of attribute | "m=" section MUST contain the following attributes (which are of | |||
types other than IDENTICAL and TRANSPORT): | attribute types other than IDENTICAL or TRANSPORT): | |||
* If and only if present in the offer, an "a=mid" line, as specified | * If and only if present in the offer, an "a=mid" line, as specified | |||
in [RFC5888], Section 9.1. The "mid" value MUST match that | in [RFC5888], Section 9.1. The "mid" value MUST match that | |||
specified in the offer. | specified in the offer. | |||
* A direction attribute, determined by applying the rules regarding | * A direction attribute, determined by applying the rules regarding | |||
the offered direction specified in [RFC3264], Section 6.1, and | the offered direction specified in [RFC3264], Section 6.1, and | |||
then intersecting with the direction of the associated | then intersecting with the direction of the associated | |||
RtpTransceiver. For example, in the case where an m= section is | RtpTransceiver. For example, in the case where an "m=" section is | |||
offered as "sendonly", and the local transceiver is set to | offered as "sendonly" and the local transceiver is set to | |||
"sendrecv", the result in the answer is a "recvonly" direction. | "sendrecv", the result in the answer is a "recvonly" direction. | |||
* For each media format on the m= line, "a=rtpmap" and "a=fmtp" | * For each media format on the "m=" line, "a=rtpmap" and "a=fmtp" | |||
lines, as specified in [RFC4566], Section 6, and [RFC3264], | lines, as specified in [RFC4566], Section 6 and [RFC3264], | |||
Section 6.1. | Section 6.1. | |||
* If "rtx" is present in the offer, for each primary codec where RTP | * If "rtx" is present in the offer, for each primary codec where RTP | |||
retransmission should be used, a corresponding "a=rtpmap" line | retransmission should be used, a corresponding "a=rtpmap" line | |||
indicating "rtx" with the clock rate of the primary codec and an | indicating "rtx" with the clock rate of the primary codec and an | |||
"a=fmtp" line that references the payload type of the primary | "a=fmtp" line that references the payload type of the primary | |||
codec, as specified in [RFC4588], Section 8.1. | codec, as specified in [RFC4588], Section 8.1. | |||
* For each supported FEC mechanism, "a=rtpmap" and "a=fmtp" lines, | * For each supported FEC mechanism, "a=rtpmap" and "a=fmtp" lines, | |||
as specified in [RFC4566], Section 6. The FEC mechanisms that | as specified in [RFC4566], Section 6. The FEC mechanisms that | |||
MUST be supported are specified in [RFCYYYF], Section 6, and | MUST be supported are specified in [RFC8854], Section 6, and | |||
specific usage for each media type is outlined in Sections 4 and | specific usage for each media type is outlined in Sections 4 and | |||
5. | 5. | |||
* If this m= section is for media with configurable durations of | * If this "m=" section is for media with configurable durations of | |||
media per packet, e.g., audio, an "a=maxptime" line, as described | media per packet, e.g., audio, an "a=maxptime" line, as described | |||
in Section 5.2. | in Section 5.2. | |||
* If this m= section is for video media, and there are known | * If this "m=" section is for video media and there are known | |||
limitations on the size of images which can be decoded, an | limitations on the size of images that can be decoded, an | |||
"a=imageattr" line, as specified in Section 3.6. | "a=imageattr" line, as specified in Section 3.6. | |||
* For each supported RTP header extension that is present in the | * For each supported RTP header extension that is present in the | |||
offer, an "a=extmap" line, as specified in [RFC5285], Section 5. | offer, an "a=extmap" line, as specified in [RFC5285], Section 5. | |||
The list of header extensions that SHOULD/MUST be supported is | The list of header extensions that SHOULD/MUST be supported is | |||
specified in [RFCYYY5], Section 5.2. Any header extensions that | specified in [RFC8834], Section 5.2. Any header extensions that | |||
require encryption MUST be specified as indicated in [RFC6904], | require encryption MUST be specified as indicated in [RFC6904], | |||
Section 4. | Section 4. | |||
* For each supported RTCP feedback mechanism that is present in the | * For each supported RTCP feedback mechanism that is present in the | |||
offer, an "a=rtcp-fb" line, as specified in [RFC4585], | offer, an "a=rtcp-fb" line, as specified in [RFC4585], | |||
Section 4.2. The list of RTCP feedback mechanisms that SHOULD/ | Section 4.2. The list of RTCP feedback mechanisms that SHOULD/ | |||
MUST be supported is specified in [RFCYYY5], Section 5.1. | MUST be supported is specified in [RFC8834], Section 5.1. | |||
* If the RtpTransceiver has a sendrecv or sendonly direction: | * If the RtpTransceiver has a sendrecv or sendonly direction: | |||
- For each MediaStream that was associated with the transceiver | - For each MediaStream that was associated with the transceiver | |||
when it was created via addTrack or addTransceiver, an "a=msid" | when it was created via addTrack or addTransceiver, an "a=msid" | |||
line, as specified in [RFCYYY4], Section 2, but omitting the | line, as specified in [RFC8830], Section 2, but omitting the | |||
"appdata" field. | "appdata" field. | |||
Each m= section which is not bundled into another m= section, MUST | Each "m=" section that is not bundled into another "m=" section MUST | |||
contain the following attributes (which are of category IDENTICAL or | contain the following attributes (which are of category IDENTICAL or | |||
TRANSPORT): | TRANSPORT): | |||
* "a=ice-ufrag" and "a=ice-pwd" lines, as specified in [RFCYYY7], | * "a=ice-ufrag" and "a=ice-pwd" lines, as specified in [RFC8839], | |||
Section 4.4. | Section 5.4. | |||
* For each desired digest algorithm, one or more "a=fingerprint" | * For each desired digest algorithm, one or more "a=fingerprint" | |||
lines for each of the endpoint's certificates, as specified in | lines for each of the endpoint's certificates, as specified in | |||
[RFC8122], Section 5. | [RFC8122], Section 5. | |||
* An "a=setup" line, as specified in [RFC4145], Section 4, and | * An "a=setup" line, as specified in [RFC4145], Section 4 and | |||
clarified for use in DTLS-SRTP scenarios in [RFC5763], Section 5. | clarified for use in DTLS-SRTP scenarios in [RFC5763], Section 5. | |||
The role value in the answer MUST be "active" or "passive". When | The role value in the answer MUST be "active" or "passive". When | |||
the offer contains the "actpass" value, as will always be the case | the offer contains the "actpass" value, as will always be the case | |||
with JSEP endpoints, the answerer SHOULD use the "active" role. | with JSEP endpoints, the answerer SHOULD use the "active" role. | |||
Offers from non-JSEP endpoints MAY send other values for | Offers from non-JSEP endpoints MAY send other values for | |||
"a=setup", in which case the answer MUST use a value consistent | "a=setup", in which case the answer MUST use a value consistent | |||
with the value in the offer. | with the value in the offer. | |||
* An "a=tls-id" line, as specified in [RFCYYYA], Section 5.3. | * An "a=tls-id" line, as specified in [RFC8842], Section 5.3. | |||
* If present in the offer, an "a=rtcp-mux" line, as specified in | * If present in the offer, an "a=rtcp-mux" line, as specified in | |||
[RFC5761], Section 5.1.3. Otherwise, an "a=rtcp" line, as | [RFC5761], Section 5.1.3. Otherwise, an "a=rtcp" line, as | |||
specified in [RFC3605], Section 2.1, containing the dummy value "9 | specified in [RFC3605], Section 2.1, containing the dummy value "9 | |||
IN IP4 0.0.0.0" (because no candidates have yet been gathered). | 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 | * If present in the offer, an "a=rtcp-rsize" line, as specified in | |||
[RFC5506], Section 5. | [RFC5506], Section 5. | |||
If a data channel m= section has been offered, a m= section MUST also | If a data channel "m=" section has been offered, an "m=" section MUST | |||
be generated for data. The <media> field MUST be set to | also be generated for data. The <media> field MUST be set to | |||
"application" and the <proto> and <fmt> fields MUST be set to exactly | "application", and the <proto> and <fmt> fields MUST be set to | |||
match the fields in the offer. | exactly match the fields in the offer. | |||
Within the data m= section, an "a=mid" line MUST be generated and | Within the data "m=" section, an "a=mid" line MUST be generated and | |||
included as described above, along with an "a=sctp-port" line | included as described above, along with an "a=sctp-port" line | |||
referencing the SCTP port number, as defined in [RFCYYY9], | referencing the SCTP port number, as defined in [RFC8841], | |||
Section 5.1, and, if appropriate, an "a=max-message-size" line, as | Section 5.1; and, if appropriate, an "a=max-message-size" line, as | |||
defined in [RFCYYY9], Section 6.1. | defined in [RFC8841], Section 6.1. | |||
As discussed above, the following attributes of category IDENTICAL or | As discussed above, the following attributes of category IDENTICAL or | |||
TRANSPORT are included only if the data m= section is not bundled | TRANSPORT are included only if the data "m=" section is not bundled | |||
into another m= section: | into another "m=" section: | |||
* "a=ice-ufrag" | * "a=ice-ufrag" | |||
* "a=ice-pwd" | * "a=ice-pwd" | |||
* "a=fingerprint" | * "a=fingerprint" | |||
* "a=setup" | * "a=setup" | |||
* "a=tls-id" | * "a=tls-id" | |||
Note that if media m= sections are bundled into a data m= section, | Note that if media "m=" sections are bundled into a data "m=" | |||
then certain TRANSPORT and IDENTICAL attributes may also appear in | section, then certain TRANSPORT and IDENTICAL attributes may also | |||
the data m= section even if they would otherwise only be appropriate | appear in the data "m=" section even if they would otherwise only be | |||
for a media m= section (e.g., "a=rtcp-mux"). | appropriate for a media "m=" section (e.g., "a=rtcp-mux"). | |||
If "a=group" attributes with semantics of "BUNDLE" are offered, | If "a=group" attributes with semantics of "BUNDLE" are offered, | |||
corresponding session-level "a=group" attributes MUST be added as | corresponding session-level "a=group" attributes MUST be added as | |||
specified in [RFC5888]. These attributes MUST have semantics | specified in [RFC5888]. These attributes MUST have semantics | |||
"BUNDLE", and MUST include the all mid identifiers from the offered | "BUNDLE" and MUST include all mid identifiers from the offered bundle | |||
bundle groups that have not been rejected. Note that regardless of | groups that have not been rejected. Note that regardless of the | |||
the presence of "a=bundle-only" in the offer, no m= sections in the | presence of "a=bundle-only" in the offer, no "m=" sections in the | |||
answer should have an "a=bundle-only" line. | answer should have an "a=bundle-only" line. | |||
Attributes that are common between all m= sections MAY be moved to | Attributes that are common between all "m=" sections MAY be moved to | |||
session-level, if explicitly defined to be valid at session-level. | the session level if explicitly defined to be valid at the session | |||
level. | ||||
The attributes prohibited in the creation of offers are also | The attributes prohibited in the creation of offers are also | |||
prohibited in the creation of answers. | prohibited in the creation of answers. | |||
5.3.2. Subsequent Answers | 5.3.2. Subsequent Answers | |||
When createAnswer is called a second (or later) time, or is called | When createAnswer is called a second (or later) time or is called | |||
after a local description has already been installed, the processing | after a local description has already been installed, the processing | |||
is somewhat different than for an initial answer. | is somewhat different than for an initial answer. | |||
If the previous answer was not applied using setLocalDescription, | If the previous answer was not applied using setLocalDescription, | |||
meaning the PeerConnection is still in the "have-remote-offer" state, | meaning the PeerConnection is still in the "have-remote-offer" state, | |||
the steps for generating an initial answer should be followed, | the steps for generating an initial answer should be followed, | |||
subject to the following restriction: | subject to the following restriction: | |||
* The fields of the "o=" line MUST stay the same except for the | * The fields of the "o=" line MUST stay the same except for the | |||
<session-version> field, which MUST increment if the session | <session-version> field, which MUST increment if the session | |||
description changes in any way from the previously generated | description changes in any way from the previously generated | |||
answer. | answer. | |||
If any session description was previously supplied to | If any session description was previously supplied to | |||
setLocalDescription, an answer is generated by following the steps in | setLocalDescription, an answer is generated by following the steps in | |||
the "have-remote-offer" state above, along with these exceptions: | the "have-remote-offer" state above, along with these exceptions: | |||
* The "s=" and "t=" lines MUST stay the same. | * The "s=" and "t=" lines MUST stay the same. | |||
* Each "m=" and c=" line MUST be filled in with the port and address | * Each "m=" and "c=" line MUST be filled in with the port and | |||
of the default candidate for the m= section, as described in | address of the default candidate for the "m=" section, as | |||
[RFCYYY7], Section 3.2.1.2. Note that in certain cases, the m= | described in [RFC8839], Section 4.2.1.2. Note that in certain | |||
line protocol may not match that of the default candidate, because | cases, the "m=" line protocol may not match that of the default | |||
the m= line protocol value MUST match what was supplied in the | candidate, because the "m=" line protocol value MUST match what | |||
offer, as described above. | was supplied in the offer, as described above. | |||
* Each "a=ice-ufrag" and "a=ice-pwd" line MUST stay the same, unless | * 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 | the "m=" section is restarting, in which case new ICE credentials | |||
must be created as specified in [RFCYYY7], Section 3.4.1.1.1. If | must be created as specified in [RFC8839], Section 4.4.1.1.1. If | |||
the m= section is bundled into another m= section, it still MUST | the "m=" section is bundled into another "m=" section, it still | |||
NOT contain any ICE credentials. | MUST NOT contain any ICE credentials. | |||
* Each "a=tls-id" line MUST stay the same unless the offerer's | * Each "a=tls-id" line MUST stay the same, unless the offerer's | |||
"a=tls-id" line changed, in which case a new "a=tls-id" value MUST | "a=tls-id" line changed, in which case a new "a=tls-id" value MUST | |||
be created, as described in [RFCYYYA], Section 5.2. | be created, as described in [RFC8842], Section 5.2. | |||
* Each "a=setup" line MUST use an "active" or "passive" role value | * Each "a=setup" line MUST use an "active" or "passive" role value | |||
consistent with the existing DTLS association, if the association | consistent with the existing DTLS association, if the association | |||
is being continued by the offerer. | is being continued by the offerer. | |||
* RTCP multiplexing must be used, and an "a=rtcp-mux" line inserted | * RTCP multiplexing must be used, and an "a=rtcp-mux" line inserted | |||
if and only if the m= section previously used RTCP multiplexing. | if and only if the "m=" section previously used RTCP multiplexing. | |||
* If the m= section is not bundled into another m= section and RTCP | * If the "m=" section is not bundled into another "m=" section and | |||
multiplexing is not active, an "a=rtcp" attribute line MUST be | RTCP multiplexing is not active, an "a=rtcp" attribute line MUST | |||
filled in with the port and address of the default RTCP candidate. | be filled in with the port and address of the default RTCP | |||
If no RTCP candidates have yet been gathered, dummy values MUST be | candidate. If no RTCP candidates have yet been gathered, dummy | |||
used, as described in the initial answer section above. | values MUST be used, as described in Section 5.3.1 above. | |||
* If the m= section is not bundled into another m= section, for each | * If the "m=" section is not bundled into another "m=" section, for | |||
candidate that has been gathered during the most recent gathering | each candidate that has been gathered during the most recent | |||
phase (see Section 3.5.1), an "a=candidate" line MUST be added, as | gathering phase (see Section 3.5.1), an "a=candidate" line MUST be | |||
defined in [RFCYYY7], Section 4.1. If candidate gathering for the | added, as defined in [RFC8839], Section 5.1. If candidate | |||
section has completed, an "a=end-of-candidates" attribute MUST be | gathering for the section has completed, an "a=end-of-candidates" | |||
added, as described in [RFCYYY6], Section 9.3. If the m= section | attribute MUST be added, as described in [RFC8840], Section 8.2. | |||
is bundled into another m= section, both "a=candidate" and "a=end- | If the "m=" section is bundled into another "m=" section, both | |||
of-candidates" MUST be omitted. | "a=candidate" and "a=end-of-candidates" MUST be omitted. | |||
* For RtpTransceivers that are not stopped, the "a=msid" line(s) | * For RtpTransceivers that are not stopped, the "a=msid" line(s) | |||
MUST stay the same, regardless of changes to the transceiver's | MUST stay the same, regardless of changes to the transceiver's | |||
direction or track. If no "a=msid" line is present in the current | direction or track. If no "a=msid" line is present in the current | |||
description, "a=msid" line(s) MUST be generated according to the | description, "a=msid" line(s) MUST be generated according to the | |||
same rules as for an initial answer. | same rules as for an initial answer. | |||
5.3.3. Options Handling | 5.3.3. Options Handling | |||
The createAnswer method takes as a parameter an RTCAnswerOptions | The createAnswer method takes as a parameter an RTCAnswerOptions | |||
object. The set of parameters for RTCAnswerOptions is different than | object. The set of parameters for RTCAnswerOptions is different than | |||
those supported in RTCOfferOptions; the IceRestart option is | those supported in RTCOfferOptions; the IceRestart option is | |||
unnecessary, as ICE credentials will automatically be changed for all | unnecessary, as ICE credentials will automatically be changed for all | |||
m= sections where the offerer chose to perform ICE restart. | "m=" sections where the offerer chose to perform ICE restart. | |||
The following options are supported in RTCAnswerOptions. | The following options are supported in RTCAnswerOptions. | |||
5.3.3.1. VoiceActivityDetection | 5.3.3.1. VoiceActivityDetection | |||
Silence suppression in the answer is handled as described in | Silence suppression in the answer is handled as described in | |||
Section 5.2.3.2, with one exception: if support for silence | Section 5.2.3.2, with one exception: if support for silence | |||
suppression was not indicated in the offer, the | suppression was not indicated in the offer, the | |||
VoiceActivityDetection parameter has no effect, and the answer should | VoiceActivityDetection parameter has no effect, and the answer should | |||
be generated as if VoiceActivityDetection was set to false. This is | be generated as if VoiceActivityDetection was set to "false". This | |||
done on a per-codec basis (e.g., if the offerer somehow offered | is done on a per-codec basis (e.g., if the offerer somehow offered | |||
support for CN but set "usedtx=0" for Opus, setting | support for CN but set "usedtx=0" for Opus, setting | |||
VoiceActivityDetection to true would result in an answer with CN | VoiceActivityDetection to "true" would result in an answer with CN | |||
codecs and "usedtx=0"). The impact of this rule is that an answerer | codecs and "usedtx=0"). The impact of this rule is that an answerer | |||
will not try to use silence suppression with any endpoint that does | will not try to use silence suppression with any endpoint that does | |||
not offer it, making silence suppression support bilateral even with | not offer it, making silence suppression support bilateral even with | |||
non-JSEP endpoints. | non-JSEP endpoints. | |||
5.4. Modifying an Offer or Answer | 5.4. Modifying an Offer or Answer | |||
The SDP returned from createOffer or createAnswer MUST NOT be changed | The SDP returned from createOffer or createAnswer MUST NOT be changed | |||
before passing it to setLocalDescription. If precise control over | before passing it to setLocalDescription. If precise control over | |||
the SDP is needed, the aforementioned createOffer/createAnswer | the SDP is needed, the aforementioned createOffer/createAnswer | |||
skipping to change at line 2606 ¶ | skipping to change at line 2623 ¶ | |||
application MAY modify the SDP to reduce its capabilities before | application MAY modify the SDP to reduce its capabilities before | |||
sending it to the far side, as long as it follows the rules above | sending it to the far side, as long as it follows the rules above | |||
that define a valid JSEP offer or answer. Likewise, an application | that define a valid JSEP offer or answer. Likewise, an application | |||
that has received an offer or answer from a peer MAY modify the | that has received an offer or answer from a peer MAY modify the | |||
received SDP, subject to the same constraints, before calling | received SDP, subject to the same constraints, before calling | |||
setRemoteDescription. | setRemoteDescription. | |||
As always, the application is solely responsible for what it sends to | As always, the application is solely responsible for what it sends to | |||
the other party, and all incoming SDP will be processed by the JSEP | the other party, and all incoming SDP will be processed by the JSEP | |||
implementation to the extent of its capabilities. It is an error to | implementation 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 all SDP is well formed; however, one should be able to | |||
assume that any implementation of this specification will 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 | process, as a remote offer or answer, unmodified SDP coming from any | |||
other implementation of this specification. | other implementation of this specification. | |||
5.5. Processing a Local Description | 5.5. Processing a Local Description | |||
When a SessionDescription is supplied to setLocalDescription, the | When a SessionDescription is supplied to setLocalDescription, the | |||
following steps MUST be performed: | following steps MUST be performed: | |||
* If the description is of type "rollback", follow the processing | * If the description is of type "rollback", follow the processing | |||
skipping to change at line 2681 ¶ | skipping to change at line 2698 ¶ | |||
5.7. Processing a Rollback | 5.7. Processing a Rollback | |||
A rollback may be performed if the PeerConnection is in any state | A rollback may be performed if the PeerConnection is in any state | |||
except for "stable". This means that both offers and provisional | except for "stable". This means that both offers and provisional | |||
answers can be rolled back. Rollback can only be used to cancel | answers can be rolled back. Rollback can only be used to cancel | |||
proposed changes; there is no support for rolling back from a stable | proposed changes; there is no support for rolling back from a stable | |||
state to a previous stable state. If a rollback is attempted in the | state to a previous stable state. If a rollback is attempted in the | |||
"stable" state, processing MUST stop and an error MUST be returned. | "stable" state, processing MUST stop and an error MUST be returned. | |||
Note that this implies that once the answerer has performed | Note that this implies that once the answerer has performed | |||
setLocalDescription with his answer, this cannot be rolled back. | setLocalDescription with its answer, this cannot be rolled back. | |||
The effect of rollback MUST be the same regardless of whether | The effect of rollback MUST be the same regardless of whether | |||
setLocalDescription or setRemoteDescription is called. | setLocalDescription or setRemoteDescription is called. | |||
In order to process rollback, a JSEP implementation abandons the | In order to process rollback, a JSEP implementation abandons the | |||
current offer/answer transaction, sets the signaling state to | current offer/answer transaction, sets the signaling state to | |||
"stable", and sets the pending local and/or remote description (see | "stable", and sets the pending local and/or remote description (see | |||
Sections 4.1.12 and 4.1.14) to null. Any resources or candidates | Sections 4.1.12 and 4.1.14) to "null". Any resources or candidates | |||
that were allocated by the abandoned local description are discarded; | that were allocated by the abandoned local description are discarded; | |||
any media that is received is processed according to the previous | any media that is received is processed according to the previous | |||
local and remote descriptions. | local and remote descriptions. | |||
A rollback disassociates any RtpTransceivers that were associated | A rollback disassociates any RtpTransceivers that were associated | |||
with m= sections by the application of the rolled-back session | with "m=" sections by the application of the rolled-back session | |||
description (see Sections 5.10 and 5.9). This means that some | description (see Sections 5.10 and 5.9). This means that some | |||
RtpTransceivers that were previously associated will no longer be | RtpTransceivers that were previously associated will no longer be | |||
associated with any m= section; in such cases, the value of the | associated with any "m=" section; in such cases, the value of the | |||
RtpTransceiver's mid property MUST be set to null, and the mapping | RtpTransceiver's mid property MUST be set to "null", and the mapping | |||
between the transceiver and its m= section index MUST be discarded. | between the transceiver and its "m=" section index MUST be discarded. | |||
RtpTransceivers that were created by applying a remote offer that was | RtpTransceivers that were created by applying a remote offer that was | |||
subsequently rolled back MUST be stopped and removed from the | subsequently rolled back MUST be stopped and removed from the | |||
PeerConnection. However, a RtpTransceiver MUST NOT be removed if a | PeerConnection. However, an RtpTransceiver MUST NOT be removed if a | |||
track was attached to the RtpTransceiver via the addTrack method. | track was attached to the RtpTransceiver via the addTrack method. | |||
This is so that an application may call addTrack, then call | This is so that an application may call addTrack, then call | |||
setRemoteDescription with an offer, then roll back that offer, then | setRemoteDescription with an offer, then roll back that offer, then | |||
call createOffer and have a m= section for the added track appear in | call createOffer and have an "m=" section for the added track appear | |||
the generated offer. | in the generated offer. | |||
5.8. Parsing a Session Description | 5.8. Parsing a Session Description | |||
The SDP contained in the session description object consists of a | The SDP contained in the session description object consists of a | |||
sequence of text lines, each containing a key-value expression, as | sequence of text lines, each containing a key-value expression, as | |||
described in [RFC4566], Section 5. The SDP is read, line-by-line, | described in [RFC4566], Section 5. The SDP is read, line by line, | |||
and converted to a data structure that contains the deserialized | and converted to a data structure that contains the deserialized | |||
information. However, SDP allows many types of lines, not all of | information. However, SDP allows many types of lines, not all of | |||
which are relevant to JSEP applications. For each line, the | which are relevant to JSEP applications. For each line, the | |||
implementation will first ensure it is syntactically correct | implementation will first ensure that it is syntactically correct | |||
according to its defining ABNF, check that it conforms to [RFC4566] | according to its defining ABNF, check that it conforms to the | |||
and [RFC3264] semantics, and then either parse and store or discard | semantics used in [RFC4566] and [RFC3264], and then either parse and | |||
the provided value, as described below. | store or discard the provided value, as described below. | |||
If any line is not well-formed, or cannot be parsed as described, the | 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, | parser MUST stop with an error and reject the session description, | |||
even if the value is to be discarded. This ensures that | even if the value is to be discarded. This ensures that | |||
implementations do not accidentally misinterpret ambiguous SDP. | implementations do not accidentally misinterpret ambiguous SDP. | |||
5.8.1. Session-Level Parsing | 5.8.1. Session-Level Parsing | |||
First, the session-level lines are checked and parsed. These lines | First, the session-level lines are checked and parsed. These lines | |||
MUST occur in a specific order, and with a specific syntax, as | MUST occur in a specific order, and with a specific syntax, as | |||
defined in [RFC4566], Section 5. Note that while the specific line | defined in [RFC4566], Section 5. Note that while the specific line | |||
types (e.g. "v=", "c=") MUST occur in the defined order, lines of the | types (e.g., "v=", "c=") MUST occur in the defined order, lines of | |||
same type (typically "a=") can occur in any order. | the same type (typically "a=") can occur in any order. | |||
The following non-attribute lines are not meaningful in the JSEP | The following non-attribute lines are not meaningful in the JSEP | |||
context and MAY be discarded once they have been checked. | context and MAY be discarded once they have been checked. | |||
* The "c=" line MUST be checked for syntax but its value is only | * The "c=" line MUST be checked for syntax, but its value is only | |||
used for ICE mismatch detection, as defined in [RFC8445], | used for ICE mismatch detection, as defined in [RFC8445], | |||
Section 5.4. Note that JSEP implementations should never | Section 5.4. Note that JSEP implementations should never | |||
encounter this condition because ICE is required for WebRTC. | encounter this condition because ICE is required for WebRTC. | |||
* The "i=", "u=", "e=", "p=", "t=", "r=", "z=", and "k=" lines are | * The "i=", "u=", "e=", "p=", "t=", "r=", "z=", and "k=" lines are | |||
not used by this specification; they MUST be checked for syntax | not used by this specification; they MUST be checked for syntax, | |||
but their values are not used. | but their values are not used. | |||
The remaining non-attribute lines are processed as follows: | The remaining non-attribute lines are processed as follows: | |||
* The "v=" line MUST have a version of 0, as specified in [RFC4566], | * The "v=" line MUST have a version of 0, as specified in [RFC4566], | |||
Section 5.1. | Section 5.1. | |||
* The "o=" line MUST be parsed as specified in [RFC4566], | * The "o=" line MUST be parsed as specified in [RFC4566], | |||
Section 5.2. | Section 5.2. | |||
skipping to change at line 2767 ¶ | skipping to change at line 2784 ¶ | |||
[RFC4566], Section 5.8, and the bwtype and bandwidth values | [RFC4566], Section 5.8, and the bwtype and bandwidth values | |||
stored. | stored. | |||
Finally, the attribute lines are processed. Specific processing MUST | Finally, the attribute lines are processed. Specific processing MUST | |||
be applied for the following session-level attribute ("a=") lines: | be applied for the following session-level attribute ("a=") lines: | |||
* Any "a=group" lines are parsed as specified in [RFC5888], | * Any "a=group" lines are parsed as specified in [RFC5888], | |||
Section 5, and the group's semantics and mids are stored. | Section 5, and the group's semantics and mids are stored. | |||
* If present, a single "a=ice-lite" line is parsed as specified in | * If present, a single "a=ice-lite" line is parsed as specified in | |||
[RFCYYY7], Section 4.3, and a value indicating the presence of | [RFC8839], Section 5.3, and a value indicating the presence of | |||
ice-lite is stored. | ice-lite is stored. | |||
* If present, a single "a=ice-ufrag" line is parsed as specified in | * If present, a single "a=ice-ufrag" line is parsed as specified in | |||
[RFCYYY7], Section 4.4, and the ufrag value is stored. | [RFC8839], Section 5.4, and the ufrag value is stored. | |||
* If present, a single "a=ice-pwd" line is parsed as specified in | * If present, a single "a=ice-pwd" line is parsed as specified in | |||
[RFCYYY7], Section 4.4, and the password value is stored. | [RFC8839], Section 5.4, and the password value is stored. | |||
* If present, a single "a=ice-options" line is parsed as specified | * If present, a single "a=ice-options" line is parsed as specified | |||
in [RFCYYY7], Section 4.6, and the set of specified options is | in [RFC8839], Section 5.6, and the set of specified options is | |||
stored. | stored. | |||
* Any "a=fingerprint" lines are parsed as specified in [RFC8122], | * Any "a=fingerprint" lines are parsed as specified in [RFC8122], | |||
Section 5, and the set of fingerprint and algorithm values is | Section 5, and the set of fingerprint and algorithm values is | |||
stored. | stored. | |||
* If present, a single "a=setup" line is parsed as specified in | * If present, a single "a=setup" line is parsed as specified in | |||
[RFC4145], Section 4, and the setup value is stored. | [RFC4145], Section 4, and the setup value is stored. | |||
* If present, a single "a=tls-id" line is parsed as specified in | * If present, a single "a=tls-id" line is parsed as specified in | |||
[RFCYYYA], Section 5, and the tls-id value is stored. | [RFC8842], Section 5, and the tls-id value is stored. | |||
* Any "a=identity" lines are parsed and the identity values stored | * Any "a=identity" lines are parsed and the identity values stored | |||
for subsequent verification, as specified [RFCYYY2], Section 5. | for subsequent verification, as specified in [RFC8827], Section 5. | |||
* Any "a=extmap" lines are parsed as specified in [RFC5285], | * Any "a=extmap" lines are parsed as specified in [RFC5285], | |||
Section 5, and their values are stored. | Section 5, and their values are stored. | |||
Other attributes that are not relevant to JSEP may also be present, | Other attributes that are not relevant to JSEP may also be present, | |||
and implementations SHOULD process any that they recognize. As | and implementations SHOULD process any that they recognize. As | |||
required by [RFC4566], Section 5.13, unknown attribute lines MUST be | required by [RFC4566], Section 5.13, unknown attribute lines MUST be | |||
ignored. | ignored. | |||
Once all the session-level lines have been parsed, processing | Once all the session-level lines have been parsed, processing | |||
continues with the lines in m= sections. | continues with the lines in "m=" sections. | |||
5.8.2. Media Section Parsing | 5.8.2. Media Section Parsing | |||
Like the session-level lines, the media section lines MUST occur in | Like the session-level lines, the media section lines MUST occur in | |||
the specific order and with the specific syntax defined in [RFC4566], | the specific order and with the specific syntax defined in [RFC4566], | |||
Section 5. | Section 5. | |||
The "m=" line itself MUST be parsed as described in [RFC4566], | The "m=" line itself MUST be parsed as described in [RFC4566], | |||
Section 5.14, and the media, port, proto, and fmt values stored. | Section 5.14, and the media, port, proto, and fmt values stored. | |||
skipping to change at line 2828 ¶ | skipping to change at line 2845 ¶ | |||
used. | used. | |||
* The "b=" line, if present, MUST be parsed as specified in | * The "b=" line, if present, MUST be parsed as specified in | |||
[RFC4566], Section 5.8, and the bwtype and bandwidth values | [RFC4566], Section 5.8, and the bwtype and bandwidth values | |||
stored. | stored. | |||
Specific processing MUST also be applied for the following attribute | Specific processing MUST also be applied for the following attribute | |||
lines: | lines: | |||
* If present, a single "a=ice-ufrag" line is parsed as specified in | * If present, a single "a=ice-ufrag" line is parsed as specified in | |||
[RFCYYY7], Section 4.4, and the ufrag value is stored. | [RFC8839], Section 5.4, and the ufrag value is stored. | |||
* If present, a single "a=ice-pwd" line is parsed as specified in | * If present, a single "a=ice-pwd" line is parsed as specified in | |||
[RFCYYY7], Section 4.4, and the password value is stored. | [RFC8839], Section 5.4, and the password value is stored. | |||
* If present, a single "a=ice-options" line is parsed as specified | * If present, a single "a=ice-options" line is parsed as specified | |||
in [RFCYYY7], Section 4.6, and the set of specified options is | in [RFC8839], Section 5.6, and the set of specified options is | |||
stored. | stored. | |||
* Any "a=candidate" attributes MUST be parsed as specified in | * Any "a=candidate" attributes MUST be parsed as specified in | |||
[RFCYYY7], Section 4.1, and their values stored. | [RFC8839], Section 5.1, and their values stored. | |||
* Any "a=remote-candidates" attributes MUST be parsed as specified | * Any "a=remote-candidates" attributes MUST be parsed as specified | |||
in [RFCYYY7], Section 4.2, but their values are ignored. | in [RFC8839], Section 5.2, but their values are ignored. | |||
* If present, a single "a=end-of-candidates" attribute MUST be | * If present, a single "a=end-of-candidates" attribute MUST be | |||
parsed as specified in [RFCYYY6], Section 8.2, and its presence or | parsed as specified in [RFC8840], Section 8.1, and its presence or | |||
absence flagged and stored. | absence flagged and stored. | |||
* Any "a=fingerprint" lines are parsed as specified in [RFC8122], | * Any "a=fingerprint" lines are parsed as specified in [RFC8122], | |||
Section 5, and the set of fingerprint and algorithm values is | Section 5, and the set of fingerprint and algorithm values is | |||
stored. | stored. | |||
If the "m=" proto value indicates use of RTP, as described in | If the "m=" proto value indicates use of RTP, as described in | |||
Section 5.1.2 above, the following attribute lines MUST be processed: | Section 5.1.2 above, the following attribute lines MUST be processed: | |||
* The "m=" fmt value MUST be parsed as specified in [RFC4566], | * The "m=" fmt value MUST be parsed as specified in [RFC4566], | |||
skipping to change at line 2866 ¶ | skipping to change at line 2883 ¶ | |||
* Any "a=rtpmap" or "a=fmtp" lines MUST be parsed as specified in | * Any "a=rtpmap" or "a=fmtp" lines MUST be parsed as specified in | |||
[RFC4566], Section 6, and their values stored. | [RFC4566], Section 6, and their values stored. | |||
* If present, a single "a=ptime" line MUST be parsed as described in | * If present, a single "a=ptime" line MUST be parsed as described in | |||
[RFC4566], Section 6, and its value stored. | [RFC4566], Section 6, and its value stored. | |||
* If present, a single "a=maxptime" line MUST be parsed as described | * If present, a single "a=maxptime" line MUST be parsed as described | |||
in [RFC4566], Section 6, and its value stored. | in [RFC4566], Section 6, and its value stored. | |||
* If present, a single direction attribute line (e.g. "a=sendrecv") | * If present, a single direction attribute line (e.g., "a=sendrecv") | |||
MUST be parsed as described in [RFC4566], Section 6, and its value | MUST be parsed as described in [RFC4566], Section 6, and its value | |||
stored. | stored. | |||
* Any "a=ssrc" attributes MUST be parsed as specified in [RFC5576], | * Any "a=ssrc" attributes MUST be parsed as specified in [RFC5576], | |||
Section 4.1, and their values stored. | Section 4.1, and their values stored. | |||
* Any "a=extmap" attributes MUST be parsed as specified in | * Any "a=extmap" attributes MUST be parsed as specified in | |||
[RFC5285], Section 5, and their values stored. | [RFC5285], Section 5, and their values stored. | |||
* Any "a=rtcp-fb" attributes MUST be parsed as specified in | * Any "a=rtcp-fb" attributes MUST be parsed as specified in | |||
[RFC4585], Section 4.2, and their values stored. | [RFC4585], Section 4.2, and their values stored. | |||
* If present, a single "a=rtcp-mux" attribute MUST be parsed as | * If present, a single "a=rtcp-mux" attribute MUST be parsed as | |||
specified in [RFC5761], Section 5.1.3, and its presence or absence | specified in [RFC5761], Section 5.1.3, and its presence or absence | |||
flagged and stored. | flagged and stored. | |||
* If present, a single "a=rtcp-mux-only" attribute MUST be parsed as | * If present, a single "a=rtcp-mux-only" attribute MUST be parsed as | |||
specified in [RFCYYYG], Section 3, and its presence or absence | specified in [RFC8858], Section 3, and its presence or absence | |||
flagged and stored. | flagged and stored. | |||
* If present, a single "a=rtcp-rsize" attribute MUST be parsed as | * If present, a single "a=rtcp-rsize" attribute MUST be parsed as | |||
specified in [RFC5506], Section 5, and its presence or absence | specified in [RFC5506], Section 5, and its presence or absence | |||
flagged and stored. | flagged and stored. | |||
* If present, a single "a=rtcp" attribute MUST be parsed as | * If present, a single "a=rtcp" attribute MUST be parsed as | |||
specified in [RFC3605], Section 2.1, but its value is ignored, as | specified in [RFC3605], Section 2.1, but its value is ignored, as | |||
this information is superfluous when using ICE. | this information is superfluous when using ICE. | |||
* If present, "a=msid" attributes MUST be parsed as specified in | * If present, "a=msid" attributes MUST be parsed as specified in | |||
[RFCYYY4], Section 3.2, and their values stored, ignoring any | [RFC8830], Section 3.2, and their values stored, ignoring any | |||
"appdata" field. If no "a=msid" attributes are present, a random | "appdata" field. If no "a=msid" attributes are present, a random | |||
msid-id value is generated for a "default" MediaStream for the | msid-id value is generated for a "default" MediaStream for the | |||
session, if not already present, and this value is stored. | session, if not already present, and this value is stored. | |||
* Any "a=imageattr" attributes MUST be parsed as specified in | * Any "a=imageattr" attributes MUST be parsed as specified in | |||
[RFC6236], Section 3, and their values stored. | [RFC6236], Section 3, and their values stored. | |||
* Any "a=rid" lines MUST be parsed as specified in [RFCYYYC], | * Any "a=rid" lines MUST be parsed as specified in [RFC8851], | |||
Section 10, and their values stored. | Section 10, and their values stored. | |||
* If present, a single "a=simulcast" line MUST be parsed as | * If present, a single "a=simulcast" line MUST be parsed as | |||
specified in [RFCYYYE], and its values stored. | specified in [RFC8853], and its values stored. | |||
Otherwise, if the "m=" proto value indicates use of SCTP, the | Otherwise, if the "m=" proto value indicates use of SCTP, the | |||
following attribute lines MUST be processed: | following attribute lines MUST be processed: | |||
* The "m=" fmt value MUST be parsed as specified in [RFCYYY9], | * The "m=" fmt value MUST be parsed as specified in [RFC8841], | |||
Section 4.3, and the application protocol value stored. | Section 4.3, and the application protocol value stored. | |||
* An "a=sctp-port" attribute MUST be present, and it MUST be parsed | * An "a=sctp-port" attribute MUST be present, and it MUST be parsed | |||
as specified in [RFCYYY9], Section 5.2, and the value stored. | as specified in [RFC8841], Section 5.2, and the value stored. | |||
* If present, a single "a=max-message-size" attribute MUST be parsed | * If present, a single "a=max-message-size" attribute MUST be parsed | |||
as specified in [RFCYYY9], Section 6, and the value stored. | as specified in [RFC8841], Section 6, and the value stored. | |||
Otherwise, use the specified default. | Otherwise, use the specified default. | |||
Other attributes that are not relevant to JSEP may also be present, | Other attributes that are not relevant to JSEP may also be present, | |||
and implementations SHOULD process any that they recognize. As | and implementations SHOULD process any that they recognize. As | |||
required by [RFC4566], Section 5.13, unknown attribute lines MUST be | required by [RFC4566], Section 5.13, unknown attribute lines MUST be | |||
ignored. | ignored. | |||
5.8.3. Semantics Verification | 5.8.3. Semantics Verification | |||
Assuming parsing completes successfully, the parsed description is | Assuming that parsing completes successfully, the parsed description | |||
then evaluated to ensure internal consistency as well as proper | is then evaluated to ensure internal consistency as well as proper | |||
support for mandatory features. Specifically, the following checks | support for mandatory features. Specifically, the following checks | |||
are performed: | are performed: | |||
* For each m= section, valid values for each of the mandatory-to-use | * For each "m=" section, valid values for each of the mandatory-to- | |||
features enumerated in Section 5.1.1 MUST be present. These | use features enumerated in Section 5.1.1 MUST be present. These | |||
values MAY either be present at the media level, or inherited from | values MAY be either present at the media level or inherited from | |||
the session level. | the session level. | |||
- ICE ufrag and password values, which MUST comply with the size | - ICE ufrag and password values, which MUST comply with the size | |||
limits specified in [RFCYYY7], Section 4.4. | limits specified in [RFC8839], Section 5.4. | |||
- tls-id value, which MUST be set according to [RFCYYYA], | - A tls-id value, which MUST be set according to [RFC8842], | |||
Section 5. If this is a re-offer or a response to a re-offer | Section 5. If this is a re-offer or a response to a re-offer | |||
and the tls-id value is different from that presently in use, | and the tls-id value is different from that presently in use, | |||
the DTLS connection is not being continued and the remote | the DTLS connection is not being continued and the remote | |||
description MUST be part of an ICE restart, together with new | description MUST be part of an ICE restart, together with new | |||
ufrag and password values. | ufrag and password values. | |||
- DTLS setup value, which MUST be set according to the rules | - A DTLS setup value, which MUST be set according to the rules | |||
specified in [RFC5763], Section 5 and MUST be consistent with | specified in [RFC5763], Section 5 and MUST be consistent with | |||
the selected role of the current DTLS connection, if one exists | the selected role of the current DTLS connection, if one exists | |||
and is being continued. | and is being continued. | |||
- DTLS fingerprint values, where at least one fingerprint MUST be | - DTLS fingerprint values, where at least one fingerprint MUST be | |||
present. | present. | |||
* All RID values referenced in an "a=simulcast" line MUST exist as | * All RID values referenced in an "a=simulcast" line MUST exist as | |||
"a=rid" lines. | "a=rid" lines. | |||
* Each m= section is also checked to ensure prohibited features are | * Each "m=" section is also checked to ensure that prohibited | |||
not used. | features are not used. | |||
* If the RTP/RTCP multiplexing policy is "require", each m= section | * If the RTP/RTCP multiplexing policy is "require", each "m=" | |||
MUST contain an "a=rtcp-mux" attribute. If an m= section contains | section MUST contain an "a=rtcp-mux" attribute. If an "m=" | |||
an "a=rtcp-mux-only" attribute, that section MUST also contain an | section contains an "a=rtcp-mux-only" attribute, that section MUST | |||
"a=rtcp-mux" attribute. | also contain an "a=rtcp-mux" attribute. | |||
* If an m= section was present in the previous answer, the state of | * If an "m=" section was present in the previous answer, the state | |||
RTP/RTCP multiplexing MUST match what was previously negotiated. | of RTP/RTCP multiplexing MUST match what was previously | |||
negotiated. | ||||
If this session description is of type "pranswer" or "answer", the | If this session description is of type "pranswer" or "answer", the | |||
following additional checks are applied: | following additional checks are applied: | |||
* The session description must follow the rules defined in | * The session description must follow the rules defined in | |||
[RFC3264], Section 6, including the requirement that the number of | [RFC3264], Section 6, including the requirement that the number of | |||
m= sections MUST exactly match the number of m= sections in the | "m=" sections MUST exactly match the number of "m=" sections in | |||
associated offer. | the associated offer. | |||
* For each m= section, the media type and protocol values MUST | * For each "m=" section, the media type and protocol values MUST | |||
exactly match the media type and protocol values in the | exactly match the media type and protocol values in the | |||
corresponding m= section in the associated offer. | corresponding "m=" section in the associated offer. | |||
If any of the preceding checks failed, processing MUST stop and an | If any of the preceding checks failed, processing MUST stop and an | |||
error MUST be returned. | error MUST be returned. | |||
5.9. Applying a Local Description | 5.9. Applying a Local Description | |||
The following steps are performed at the media engine level to apply | The following steps are performed at the media engine level to apply | |||
a local description. If an error is returned, the session MUST be | a local description. If an error is returned, the session MUST be | |||
restored to the state it was in before performing these steps. | restored to the state it was in before performing these steps. | |||
First, m= sections are processed. For each m= section, the following | First, "m=" sections are processed. For each "m=" section, the | |||
steps MUST be performed; if any parameters are out of bounds, or | following steps MUST be performed; if any parameters are out of | |||
cannot be applied, processing MUST stop and an error MUST be | bounds or cannot be applied, processing MUST stop and an error MUST | |||
returned. | be returned. | |||
* If this m= section is new, begin gathering candidates for it, as | * If this "m=" section is new, begin gathering candidates for it, as | |||
defined in [RFC8445], Section 5.1.1, unless it is definitively | defined in [RFC8445], Section 5.1.1, unless it is definitively | |||
being bundled (either this is an offer and the m= section is | being bundled (either (1) this is an offer and the "m=" section is | |||
marked bundle-only, or it is an answer and the m= section is | marked bundle-only or (2) it is an answer and the "m=" section is | |||
bundled into into another m= section.) | bundled into another "m=" section). | |||
* Or, if the ICE ufrag and password values have changed, trigger the | * Or, if the ICE ufrag and password values have changed, trigger the | |||
ICE agent to start an ICE restart as described in [RFC8445], | ICE agent to start an ICE restart as described in [RFC8445], | |||
Section 9, and begin gathering new candidates for the m= section. | Section 9, and begin gathering new candidates for the "m=" | |||
If this description is an answer, also start checks on that media | section. If this description is an answer, also start checks on | |||
section. | that media section. | |||
* If the m= section proto value indicates use of RTP: | * If the "m=" section proto value indicates use of RTP: | |||
- If there is no RtpTransceiver associated with this m= section, | - If there is no RtpTransceiver associated with this "m=" | |||
find one and associate it with this m= section according to the | section, find one and associate it with this "m=" section | |||
following steps. Note that this situation will only occur when | according to the following steps. Note that this situation | |||
applying an offer. | will only occur when applying an offer. | |||
o Find the RtpTransceiver that corresponds to this m= section, | o Find the RtpTransceiver that corresponds to this "m=" | |||
using the mapping between transceivers and m= section | section, using the mapping between transceivers and "m=" | |||
indices established when creating the offer. | section indices established when creating the offer. | |||
o Set the value of this RtpTransceiver's mid property to the | o Set the value of this RtpTransceiver's mid property to the | |||
MID of the m= section. | MID of the "m=" section. | |||
- If RTCP mux is indicated, prepare to demux RTP and RTCP from | - If RTCP mux is indicated, prepare to demux RTP and RTCP from | |||
the RTP ICE component, as specified in [RFC5761], | the RTP ICE component, as specified in [RFC5761], | |||
Section 5.1.3. | Section 5.1.3. | |||
- For each specified RTP header extension, establish a mapping | - For each specified RTP header extension, establish a mapping | |||
between the extension ID and URI, as described in [RFC5285], | between the extension ID and URI, as described in [RFC5285], | |||
Section 6. | Section 6. | |||
- If the MID header extension is supported, prepare to demux RTP | - If the MID header extension is supported, prepare to demux RTP | |||
streams intended for this m= section based on the MID header | streams intended for this "m=" section based on the MID header | |||
extension, as described in [RFCYYYB], Section 15. | extension, as described in [RFC8843], Section 15. | |||
- For each specified media format, establish a mapping between | - For each specified media format, establish a mapping between | |||
the payload type and the actual media format, as described in | the payload type and the actual media format, as described in | |||
[RFC3264], Section 6.1. In addition, prepare to demux RTP | [RFC3264], Section 6.1. In addition, prepare to demux RTP | |||
streams intended for this m= section based on the media formats | streams intended for this "m=" section based on the media | |||
supported by this m= section, as described in [RFCYYYB], | formats supported by this "m=" section, as described in | |||
Section 10.2. | [RFC8843], Section 9.2. | |||
- For each specified "rtx" media format, establish a mapping | - For each specified "rtx" media format, establish a mapping | |||
between the RTX payload type and its associated primary payload | between the RTX payload type and its associated primary payload | |||
type, as described in Sections 8.6 and 8.7 of [RFC4588]. | type, as described in Sections 8.6 and 8.7 of [RFC4588]. | |||
- If the directional attribute is of type "sendrecv" or | - If the directional attribute is of type "sendrecv" or | |||
"recvonly", enable receipt and decoding of media. | "recvonly", enable receipt and decoding of media. | |||
Finally, if this description is of type "pranswer" or "answer", | Finally, if this description is of type "pranswer" or "answer", | |||
follow the processing defined in Section 5.11 below. | follow the processing defined in Section 5.11 below. | |||
5.10. Applying a Remote Description | 5.10. Applying a Remote Description | |||
The following steps are performed to apply a remote description. If | The following steps are performed to apply a remote description. If | |||
an error is returned, the session MUST be restored to the state it | an error is returned, the session MUST be restored to the state it | |||
was in before performing these steps. | was in before performing these steps. | |||
If the answer contains any "a=ice-options" attributes where "trickle" | If the answer contains any "a=ice-options" attributes where "trickle" | |||
is listed as an attribute, update the PeerConnection canTrickle | is listed as an attribute, update the PeerConnection canTrickle | |||
property to be true. Otherwise, set this property to false. | property to be "true". Otherwise, set this property to "false". | |||
The following steps MUST be performed for attributes at the session | The following steps MUST be performed for attributes at the session | |||
level; if any parameters are out of bounds, or cannot be applied, | level; if any parameters are out of bounds or cannot be applied, | |||
processing MUST stop and an error MUST be returned. | processing MUST stop and an error MUST be returned. | |||
* For any specified "CT" bandwidth value, set this as the limit for | * For any specified "CT" bandwidth value, set this value as the | |||
the maximum total bitrate for all m= sections, as specified in | limit for the maximum total bitrate for all "m=" sections, as | |||
[RFC4566], Section 5.8. Within this overall limit, the | specified in [RFC4566], Section 5.8. Within this overall limit, | |||
implementation can dynamically decide how to best allocate the | the implementation can dynamically decide how to best allocate the | |||
available bandwidth between m= sections, respecting any specific | available bandwidth between "m=" sections, respecting any specific | |||
limits that have been specified for individual m= sections. | limits that have been specified for individual "m=" sections. | |||
* For any specified "RR" or "RS" bandwidth values, handle as | * For any specified "RR" or "RS" bandwidth values, handle as | |||
specified in [RFC3556], Section 2. | specified in [RFC3556], Section 2. | |||
* Any "AS" bandwidth value MUST be ignored, as the meaning of this | * Any "AS" bandwidth value MUST be ignored, as the meaning of this | |||
construct at the session level is not well defined. | construct at the session level is not well defined. | |||
For each m= section, the following steps MUST be performed; if any | For each "m=" section, the following steps MUST be performed; if any | |||
parameters are out of bounds, or cannot be applied, processing MUST | parameters are out of bounds or cannot be applied, processing MUST | |||
stop and an error MUST be returned. | stop and an error MUST be returned. | |||
* If the ICE ufrag or password changed from the previous remote | * If the ICE ufrag or password changed from the previous remote | |||
description: | description: | |||
- If the description is of type "offer", the implementation MUST | - If the description is of type "offer", the implementation MUST | |||
note that an ICE restart is needed, as described in [RFCYYY7], | note that an ICE restart is needed, as described in [RFC8839], | |||
Section 3.4.1.1.1 | Section 4.4.1.1.1. | |||
- If the description is of type "answer" or "pranswer", then | - If the description is of type "answer" or "pranswer", then | |||
check to see if the current local description is an ICE | check to see if the current local description is an ICE | |||
restart, and if not, generate an error. If the PeerConnection | restart, and if not, generate an error. If the PeerConnection | |||
state is "have-remote-pranswer", and the ICE ufrag or password | state is "have-remote-pranswer" and the ICE ufrag or password | |||
changed from the previous provisional answer, then signal the | changed from the previous provisional answer, then signal the | |||
ICE agent to discard any previous ICE check list state for the | ICE agent to discard any previous ICE check list state for the | |||
m= section. Finally, signal the ICE agent to begin checks. | "m=" section. Finally, signal the ICE agent to begin checks. | |||
* If the current local description indicates an ICE restart, and | * If the current local description indicates an ICE restart and | |||
either the ICE ufrag or password has not changed from the previous | either the ICE ufrag or password has not changed from the previous | |||
remote description, as prescribed by [RFC8445], Section 9, | remote description, as prescribed by [RFC8445], Section 9, | |||
generate an error. | generate an error. | |||
* Configure the ICE components associated with this media section to | * Configure the ICE components associated with this media section to | |||
use the supplied ICE remote ufrag and password for their | use the supplied ICE remote ufrag and password for their | |||
connectivity checks. | connectivity checks. | |||
* Pair any supplied ICE candidates with any gathered local | * Pair any supplied ICE candidates with any gathered local | |||
candidates, as described in [RFC8445], Section 6.1.2, and start | candidates, as described in [RFC8445], Section 6.1.2, and start | |||
connectivity checks with the appropriate credentials. | connectivity checks with the appropriate credentials. | |||
* If an "a=end-of-candidates" attribute is present, process the end- | * If an "a=end-of-candidates" attribute is present, process the end- | |||
of-candidates indication as described in [RFCYYY6], Section 11. | of-candidates indication as described in [RFC8838], Section 14. | |||
* If the m= section proto value indicates use of RTP: | * If the "m=" section proto value indicates use of RTP: | |||
- If the m= section is being recycled (see Section 5.2.2), | - If the "m=" section is being recycled (see Section 5.2.2), | |||
dissociate the currently associated RtpTransceiver by setting | dissociate the currently associated RtpTransceiver by setting | |||
its mid property to null, and discard the mapping between the | its mid property to "null", and discard the mapping between the | |||
transceiver and its m= section index. | transceiver and its "m=" section index. | |||
- If the m= section is not associated with any RtpTransceiver | - If the "m=" section is not associated with any RtpTransceiver | |||
(possibly because it was dissociated in the previous step), | (possibly because it was dissociated in the previous step), | |||
either find an RtpTransceiver or create one according to the | either find an RtpTransceiver or create one according to the | |||
following steps: | following steps: | |||
o If the m= section is sendrecv or recvonly, and there are | o If the "m=" section is sendrecv or recvonly, and there are | |||
RtpTransceivers of the same type that were added to the | RtpTransceivers of the same type that were added to the | |||
PeerConnection by addTrack and are not associated with any | PeerConnection by addTrack and are not associated with any | |||
m= section and are not stopped, find the first (according to | "m=" section and are not stopped, find the first (according | |||
the canonical order described in Section 5.2.1) such | to the canonical order described in Section 5.2.1) such | |||
RtpTransceiver. | RtpTransceiver. | |||
o If no RtpTransceiver was found in the previous step, create | o If no RtpTransceiver was found in the previous step, create | |||
one with a recvonly direction. | one with a recvonly direction. | |||
o Associate the found or created RtpTransceiver with the m= | o Associate the found or created RtpTransceiver with the "m=" | |||
section by setting the value of the RtpTransceiver's mid | section by setting the value of the RtpTransceiver's mid | |||
property to the MID of the m= section, and establish a | property to the MID of the "m=" section, and establish a | |||
mapping between the transceiver and the index of the m= | mapping between the transceiver and the index of the "m=" | |||
section. If the m= section does not include a MID (i.e., | section. If the "m=" section does not include a MID (i.e., | |||
the remote endpoint does not support the MID extension), | the remote endpoint does not support the MID extension), | |||
generate a value for the RtpTransceiver mid property, | generate a value for the RtpTransceiver mid property, | |||
following the guidance for "a=mid" mentioned in | following the guidance for "a=mid" mentioned in | |||
Section 5.2.1. | Section 5.2.1. | |||
- For each specified media format that is also supported by the | - For each specified media format that is also supported by the | |||
local implementation, establish a mapping between the specified | local implementation, establish a mapping between the specified | |||
payload type and the media format, as described in [RFC3264], | payload type and the media format, as described in [RFC3264], | |||
Section 6.1. Specifically, this means that the implementation | Section 6.1. Specifically, this means that the implementation | |||
records the payload type to be used in outgoing RTP packets | records the payload type to be used in outgoing RTP packets | |||
when sending each specified media format, as well as the | when sending each specified media format, as well as the | |||
relative preference for each format that is indicated in their | relative preference for each format that is indicated in their | |||
ordering. If any indicated media format is not supported by | ordering. If any indicated media format is not supported by | |||
the local implementation, it MUST be ignored. | the local implementation, it MUST be ignored. | |||
- For each specified "rtx" media format, establish a mapping | - For each specified "rtx" media format, establish a mapping | |||
between the RTX payload type and its associated primary payload | between the RTX payload type and its associated primary payload | |||
type, as described in [RFC4588], Section 4. If any referenced | type, as described in [RFC4588], Section 4. If any referenced | |||
primary payload types are not present, this MUST result in an | primary payload types are not present, this MUST result in an | |||
error. Note that RTX payload types may refer to primary | error. Note that RTX payload types may refer to primary | |||
payload types which are not supported by the local media | payload types that are not supported by the local media | |||
implementation, in which case, the RTX payload type MUST also | implementation, in which case the RTX payload type MUST also be | |||
be ignored. | ignored. | |||
- For each specified fmtp parameter that is supported by the | - For each specified fmtp parameter that is supported by the | |||
local implementation, enable them on the associated media | local implementation, enable them on the associated media | |||
formats. | formats. | |||
- For each specified SSRC that is signaled in the m= section, | - For each specified Synchronization Source (SSRC) that is | |||
prepare to demux RTP streams intended for this m= section using | signaled in the "m=" section, prepare to demux RTP streams | |||
that SSRC, as described in [RFCYYYB], Section 10.2. | intended for this "m=" section using that SSRC, as described in | |||
[RFC8843], Section 9.2. | ||||
- For each specified RTP header extension that is also supported | - For each specified RTP header extension that is also supported | |||
by the local implementation, establish a mapping between the | by the local implementation, establish a mapping between the | |||
extension ID and URI, as described in [RFC5285], Section 5. | extension ID and URI, as described in [RFC5285], Section 5. | |||
Specifically, this means that the implementation records the | Specifically, this means that the implementation records the | |||
extension ID to be used in outgoing RTP packets when sending | extension ID to be used in outgoing RTP packets when sending | |||
each specified header extension. If any indicated RTP header | each specified header extension. If any indicated RTP header | |||
extension is not supported by the local implementation, it MUST | extension is not supported by the local implementation, it MUST | |||
be ignored. | be ignored. | |||
- For each specified RTCP feedback mechanism that is supported by | - For each specified RTCP feedback mechanism that is supported by | |||
the local implementation, enable them on the associated media | the local implementation, enable them on the associated media | |||
formats. | formats. | |||
- For any specified "TIAS" bandwidth value, set this value as a | - For any specified "TIAS" ("Transport Independent Application | |||
Specific Maximum") bandwidth value, set this value as a | ||||
constraint on the maximum RTP bitrate to be used when sending | constraint on the maximum RTP bitrate to be used when sending | |||
media, as specified in [RFC3890]. If a "TIAS" value is not | media, as specified in [RFC3890]. If a "TIAS" value is not | |||
present, but an "AS" value is specified, generate a "TIAS" | present but an "AS" value is specified, generate a "TIAS" value | |||
value using this formula: | using this formula: | |||
TIAS = AS * 1000 * 0.95 - (50 * 40 * 8) | TIAS = AS * 1000 * 0.95 - (50 * 40 * 8) | |||
The 50 is based on 50 packets per second, the 40 is based on an | The "50" is based on 50 packets per second, the "40" is based | |||
estimate of total header size, the 1000 changes the unit from | on an estimate of total header size, the "1000" changes the | |||
kbps to bps (as required by TIAS), and the 0.95 is to allocate | unit from kbps to bps (as required by TIAS), and the "0.95" is | |||
5% to RTCP. "TIAS" is used in preference to "AS" because it | to allocate 5% to RTCP. "TIAS" is used in preference to "AS" | |||
provides more accurate control of bandwidth. | because it provides more accurate control of bandwidth. | |||
- For any "RR" or "RS" bandwidth values, handle as specified in | - For any "RR" or "RS" bandwidth values, handle as specified in | |||
[RFC3556], Section 2. | [RFC3556], Section 2. | |||
- Any specified "CT" bandwidth value MUST be ignored, as the | - Any specified "CT" bandwidth value MUST be ignored, as the | |||
meaning of this construct at the media level is not well | meaning of this construct at the media level is not well | |||
defined. | defined. | |||
- If the m= section is of type audio: | - If the "m=" section is of type "audio": | |||
o For each specified "CN" media format, configure silence | o For each specified "CN" media format, configure silence | |||
suppression for all supported media formats with the same | suppression for all supported media formats with the same | |||
clockrate, as described in [RFC3389], Section 5, except for | clock rate, as described in [RFC3389], Section 5, except for | |||
formats that have their own internal silence suppression | formats that have their own internal silence suppression | |||
mechanisms. Silence suppression for such formats (e.g., | mechanisms. Silence suppression for such formats (e.g., | |||
Opus) is controlled via fmtp parameters, as discussed in | Opus) is controlled via fmtp parameters, as discussed in | |||
Section 5.2.3.2. | Section 5.2.3.2. | |||
o For each specified "telephone-event" media format, enable | o For each specified "telephone-event" media format, enable | |||
DTMF transmission for all supported media formats with the | dual-tone multifrequency (DTMF) transmission for all | |||
same clockrate, as described in [RFC4733], Section 2.5.1.2. | supported media formats with the same clock rate, as | |||
If there are any supported media formats that do not have a | described in [RFC4733], Section 2.5.1.2. If there are any | |||
corresponding telephone-event format, disable DTMF | supported media formats that do not have a corresponding | |||
transmission for those formats. | telephone-event format, disable DTMF transmission for those | |||
formats. | ||||
o For any specified "ptime" value, configure the available | o For any specified "ptime" value, configure the available | |||
media formats to use the specified packet size when sending. | media formats to use the specified packet size when sending. | |||
If the specified size is not supported for a media format, | If the specified size is not supported for a media format, | |||
use the next closest value instead. | use the next closest value instead. | |||
Finally, if this description is of type "pranswer" or "answer", | Finally, if this description is of type "pranswer" or "answer", | |||
follow the processing defined in Section 5.11 below. | follow the processing defined in Section 5.11 below. | |||
5.11. Applying an Answer | 5.11. Applying an Answer | |||
In addition to the steps mentioned above for processing a local or | In addition to the steps mentioned above for processing a local or | |||
remote description, the following steps are performed when processing | remote description, the following steps are performed when processing | |||
a description of type "pranswer" or "answer". | a description of type "pranswer" or "answer". | |||
For each m= section, the following steps MUST be performed: | For each "m=" section, the following steps MUST be performed: | |||
* If the m= section has been rejected (i.e. port is set to zero in | * If the "m=" section has been rejected (i.e., the port value is set | |||
the answer), stop any reception or transmission of media for this | to zero in the answer), stop any reception or transmission of | |||
section, and, unless a non-rejected m= section is bundled with | media for this section, and, unless a non-rejected "m=" section is | |||
this m= section, discard any associated ICE components, as | bundled with this "m=" section, discard any associated ICE | |||
described in [RFCYYY7], Section 3.4.3.1. | components, as described in [RFC8839], Section 4.4.3.1. | |||
* If the remote DTLS fingerprint has been changed or the tls-id has | * If the remote DTLS fingerprint has been changed or the tls-id has | |||
changed, tear down the DTLS connection. This includes the case | changed, tear down the DTLS connection. This includes the case | |||
when the PeerConnection state is "have-remote-pranswer". If a | when the PeerConnection state is "have-remote-pranswer". If a | |||
DTLS connection needs to be torn down but the answer does not | DTLS connection needs to be torn down but the answer does not | |||
indicate an ICE restart or, in the case of "have-remote-pranswer", | indicate an ICE restart or, in the case of "have-remote-pranswer", | |||
new ICE credentials, an error MUST be generated. If an ICE | new ICE credentials, an error MUST be generated. If an ICE | |||
restart is performed without a change in tls-id or fingerprint, | restart is performed without a change in tls-id or fingerprint, | |||
then the same DTLS connection is continued over the new ICE | then the same DTLS connection is continued over the new ICE | |||
channel. Note that although JSEP requires that answerers change | channel. Note that although JSEP requires that answerers change | |||
the tls-id value if and only if the offerer does, non-JSEP | the tls-id value if and only if the offerer does, non-JSEP | |||
answerers are permitted to change the tls-id as long as the offer | answerers are permitted to change the tls-id as long as the offer | |||
contained an ICE restart. Thus, JSEP implementations which | contained an ICE restart. Thus, JSEP implementations that process | |||
process DTLS data prior to receiving an answer MUST be prepared to | DTLS data prior to receiving an answer MUST be prepared to receive | |||
receive either a ClientHello or data from the previous DTLS | either a ClientHello or data from the previous DTLS connection. | |||
connection. | ||||
* If no valid DTLS connection exists, prepare to start a DTLS | * If no valid DTLS connection exists, prepare to start a DTLS | |||
connection, using the specified roles and fingerprints, on any | connection, using the specified roles and fingerprints, on any | |||
underlying ICE components, once they are active. | underlying ICE components, once they are active. | |||
* If the m= section proto value indicates use of RTP: | * If the "m=" section proto value indicates use of RTP: | |||
- If the m= section references RTCP feedback mechanisms that were | - If the "m=" section references RTCP feedback mechanisms that | |||
not present in the corresponding m= section in the offer, this | were not present in the corresponding "m=" section in the | |||
indicates a negotiation problem and MUST result in an error. | offer, this indicates a negotiation problem and MUST result in | |||
However, new media formats and new RTP header extension values | an error. However, new media formats and new RTP header | |||
are permitted in the answer, as described in [RFC3264], | extension values are permitted in the answer, as described in | |||
Section 7, and [RFC5285], Section 6. | [RFC3264], Section 7 and [RFC5285], Section 6. | |||
- If the m= section has RTCP mux enabled, discard the RTCP ICE | - If the "m=" section has RTCP mux enabled, discard the RTCP ICE | |||
component, if one exists, and begin or continue muxing RTCP | component, if one exists, and begin or continue muxing RTCP | |||
over the RTP ICE component, as specified in [RFC5761], | over the RTP ICE component, as specified in [RFC5761], | |||
Section 5.1.3. Otherwise, prepare to transmit RTCP over the | Section 5.1.3. Otherwise, prepare to transmit RTCP over the | |||
RTCP ICE component; if no RTCP ICE component exists, because | RTCP ICE component; if no RTCP ICE component exists because | |||
RTCP mux was previously enabled, this MUST result in an error. | RTCP mux was previously enabled, this MUST result in an error. | |||
- If the m= section has reduced-size RTCP enabled, configure the | - If the "m=" section has Reduced-Size RTCP enabled, configure | |||
RTCP transmission for this m= section to use reduced-size RTCP, | the RTCP transmission for this "m=" section to use Reduced-Size | |||
as specified in [RFC5506]. | RTCP, as specified in [RFC5506]. | |||
- If the directional attribute in the answer indicates that the | - If the directional attribute in the answer indicates that the | |||
JSEP implementation should be sending media ("sendonly" for | JSEP implementation should be sending media ("sendonly" for | |||
local answers, "recvonly" for remote answers, or "sendrecv" for | local answers, "recvonly" for remote answers, or "sendrecv" for | |||
either type of answer), choose the media format to send as the | either type of answer), choose the media format to send as the | |||
most preferred media format from the remote description that is | most preferred media format from the remote description that is | |||
also locally supported, as discussed in Sections 6.1 and 7 of | also locally supported, as discussed in Sections 6.1 and 7 of | |||
[RFC3264], and start transmitting RTP media using that format | [RFC3264], and start transmitting RTP media using that format | |||
once the underlying transport layers have been established. If | once the underlying transport layers have been established. If | |||
an SSRC has not already been chosen for this outgoing RTP | an SSRC has not already been chosen for this outgoing RTP | |||
stream, choose a random one. If media is already being | stream, choose a random one. If media is already being | |||
transmitted, the same SSRC SHOULD be used unless the clockrate | transmitted, the same SSRC SHOULD be used unless the clock rate | |||
of the new codec is different, in which case a new SSRC MUST be | of the new codec is different, in which case a new SSRC MUST be | |||
chosen, as specified in [RFC7160], Section 3.1. | chosen, as specified in [RFC7160], Section 3.1. | |||
- The payload type mapping from the remote description is used to | - The payload type mapping from the remote description is used to | |||
determine payload types for the outgoing RTP streams, including | determine payload types for the outgoing RTP streams, including | |||
the payload type for the send media format chosen above. Any | the payload type for the send media format chosen above. Any | |||
RTP header extensions that were negotiated should be included | RTP header extensions that were negotiated should be included | |||
in the outgoing RTP streams, using the extension mapping from | in the outgoing RTP streams, using the extension mapping from | |||
the remote description; if the RID header extension has been | the remote description; if the RID header extension has been | |||
negotiated, and RID values are specified, include the RID | negotiated and RID values are specified, include the RID header | |||
header extension in the outgoing RTP streams, as indicated in | extension in the outgoing RTP streams, as indicated in | |||
[RFCYYYC], Section 4. | [RFC8851], Section 4. | |||
- If the m= section is of type audio, and silence suppression was | - If (1) the "m=" section is of type "audio" and (2) silence | |||
configured for the send media format as a result of processing | suppression was configured for the send media format as a | |||
the remote description, and is also enabled for that format in | result of processing the remote description and is also enabled | |||
the local description, use silence suppression for outgoing | for that format in the local description, use silence | |||
media, in accordance with the guidance in Section 5.2.3.2. If | suppression for outgoing media, in accordance with the guidance | |||
these conditions are not met, silence suppression MUST NOT be | in Section 5.2.3.2. If these conditions are not met, silence | |||
used for outgoing media. | suppression MUST NOT be used for outgoing media. | |||
- If simulcast has been negotiated, send the number of Source RTP | - If simulcast has been negotiated, send the number of Source RTP | |||
Streams as specified in [RFCYYYE], Section 6.2.2. | Streams as specified in [RFC8853], Section 6.2.2. | |||
- If the send media format chosen above has a corresponding "rtx" | - If the send media format chosen above has a corresponding "rtx" | |||
media format, or a FEC mechanism has been negotiated, establish | media format or a FEC mechanism has been negotiated, establish | |||
a Redundancy RTP Stream with a random SSRC for each Source RTP | a redundancy RTP stream with a random SSRC for each Source RTP | |||
Stream, and start or continue transmitting RTX/FEC packets as | Stream, and start or continue transmitting RTX/FEC packets as | |||
needed. | needed. | |||
- If the send media format chosen above has a corresponding "red" | - If the send media format chosen above has a corresponding "red" | |||
media format of the same clockrate, allow redundant encoding | media format of the same clock rate, allow redundant encoding | |||
using the specified format for resiliency purposes, as | using the specified format for resiliency purposes, as | |||
discussed in [RFCYYYF], Section 3.2. Note that unlike RTX or | discussed in [RFC8854], Section 3.2. Note that unlike RTX or | |||
FEC media formats, the "red" format is transmitted on the | FEC media formats, the "red" format is transmitted on the | |||
Source RTP Stream, not the Redundancy RTP Stream. | Source RTP Stream, not the redundancy RTP stream. | |||
- Enable the RTCP feedback mechanisms referenced in the media | - Enable the RTCP feedback mechanisms referenced in the media | |||
section for all Source RTP Streams using the specified media | section for all Source RTP Streams using the specified media | |||
formats. Specifically, begin or continue sending the requested | formats. Specifically, begin or continue sending the requested | |||
feedback types and reacting to received feedback, as specified | feedback types and reacting to received feedback, as specified | |||
in [RFC4585], Section 4.2. When sending RTCP feedback, follow | in [RFC4585], Section 4.2. When sending RTCP feedback, follow | |||
the rules and recommendations from [RFC8108], Section 5.4.1, to | the rules and recommendations from [RFC8108], Section 5.4.1 to | |||
select which SSRC to use. | select which SSRC to use. | |||
- If the directional attribute in the answer indicates that the | - If the directional attribute in the answer indicates that the | |||
JSEP implementation should not be sending media ("recvonly" for | JSEP implementation should not be sending media ("recvonly" for | |||
local answers, "sendonly" for remote answers, or "inactive" for | local answers, "sendonly" for remote answers, or "inactive" for | |||
either type of answer) stop transmitting all RTP media, but | either type of answer), stop transmitting all RTP media, but | |||
continue sending RTCP, as described in [RFC3264], Section 5.1. | continue sending RTCP, as described in [RFC3264], Section 5.1. | |||
* If the m= section proto value indicates use of SCTP: | * If the "m=" section proto value indicates use of SCTP: | |||
- If an SCTP association exists, and the remote SCTP port has | - If an SCTP association exists and the remote SCTP port has | |||
changed, discard the existing SCTP association. This includes | changed, discard the existing SCTP association. This includes | |||
the case when the PeerConnection state is "have-remote- | the case when the PeerConnection state is "have-remote- | |||
pranswer". | pranswer". | |||
- If no valid SCTP association exists, prepare to initiate a SCTP | - If no valid SCTP association exists, prepare to initiate an | |||
association over the associated ICE component and DTLS | SCTP association over the associated ICE component and DTLS | |||
connection, using the local SCTP port value from the local | connection, using the local SCTP port value from the local | |||
description, and the remote SCTP port value from the remote | description and the remote SCTP port value from the remote | |||
description, as described in [RFCYYY9], Section 10.2. | description, as described in [RFC8841], Section 10.2. | |||
If the answer contains valid bundle groups, discard any ICE | If the answer contains valid bundle groups, discard any ICE | |||
components for the m= sections that will be bundled onto the primary | components for the "m=" sections that will be bundled onto the | |||
ICE components in each bundle, and begin muxing these m= sections | primary ICE components in each bundle, and begin muxing these "m=" | |||
accordingly, as described in [RFCYYYB], Section 8.2. | sections accordingly, as described in [RFC8843], Section 7.2. | |||
If the description is of type "answer", and there are still remaining | If the description is of type "answer" and there are still remaining | |||
candidates in the ICE candidate pool, discard them. | candidates in the ICE candidate pool, discard them. | |||
6. Processing RTP/RTCP | 6. Processing RTP/RTCP | |||
When bundling, associating incoming RTP/RTCP with the proper m= | When bundling, associating incoming RTP/RTCP with the proper "m=" | |||
section is defined in [RFCYYYB], Section 10.2. When not bundling, | section is defined in [RFC8843], Section 9.2. When not bundling, the | |||
the proper m= section is clear from the ICE component over which the | proper "m=" section is clear from the ICE component over which the | |||
RTP/RTCP is received. | RTP/RTCP is received. | |||
Once the proper m= section(s) are known, RTP/RTCP is delivered to the | Once the proper "m=" section or sections are known, RTP/RTCP is | |||
RtpTransceiver(s) associated with the m= section(s) and further | delivered to the RtpTransceiver(s) associated with the "m=" | |||
processing of the RTP/RTCP is done at the RtpTransceiver level. This | section(s) and further processing of the RTP/RTCP is done at the | |||
includes using RID [RFCYYYC] to distinguish between multiple Encoded | RtpTransceiver level. This includes using RID [RFC8851] to | |||
Streams, as well as determine which Source RTP stream should be | distinguish between multiple encoded streams, as well as to determine | |||
repaired by a given Redundancy RTP stream. | which Source RTP stream should be repaired by a given redundancy RTP | |||
stream. | ||||
7. Examples | 7. Examples | |||
Note that this example section shows several SDP fragments. To | Note that this example section shows several SDP fragments. To | |||
format in 72 columns, some of the lines in SDP have been split into | accommodate RFC line-length restrictions, some of the SDP lines have | |||
multiple lines, where leading whitespace indicates that a line is a | been split into multiple lines, where leading whitespace indicates | |||
continuation of the previous line. In addition, some blank lines | that a line is a continuation of the previous line. In addition, | |||
have been added to improve readability but are not valid in SDP. | some blank lines have been added to improve readability but are not | |||
valid in SDP. | ||||
More examples of SDP for WebRTC call flows, including examples with | More examples of SDP for WebRTC call flows, including examples with | |||
IPv6 addresses, can be found in [SDP4WebRTC]. | IPv6 addresses, can be found in [SDP4WebRTC]. | |||
7.1. Simple Example | 7.1. Simple Example | |||
This section shows a very simple example that sets up a minimal audio | This section shows a very simple example that sets up a minimal | |||
/ video call between two JSEP endpoints without using trickle ICE. | audio/video call between two JSEP endpoints without using Trickle | |||
The example in the following section provides a more detailed example | ICE. The example in the following section provides a more detailed | |||
of what could happen in a JSEP session. | example of what could happen in a JSEP session. | |||
The code flow below shows Alice's endpoint initiating the session to | The code flow below shows Alice's endpoint initiating the session to | |||
Bob's endpoint. The messages from the JavaScript application in | Bob's endpoint. The messages from the JavaScript application in | |||
Alice's browser to the JavaScript in Bob's browser, abbreviated as | Alice's browser to the JavaScript in Bob's browser, abbreviated as | |||
AliceJS and BobJS respectively, are assumed to flow over some | "AliceJS" and "BobJS", respectively, are assumed to flow over some | |||
signaling protocol via a web server. The JavaScript on both Alice's | signaling protocol via a web server. The JavaScript on both Alice's | |||
side and Bob's side waits for all candidates before sending the offer | 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 | or answer, so the offers and answers are complete; Trickle ICE is not | |||
used. The user agents (JSEP implementations) in Alice and Bob's | used. The user agents (JSEP implementations) in Alice's and Bob's | |||
browsers, abbreviated as AliceUA and BobUA respectively, are using | browsers, abbreviated as "AliceUA" and "BobUA", respectively, are | |||
the default bundle policy of "balanced", and the default RTCP mux | using the default bundle policy of "balanced", and the default RTCP | |||
policy of "require". | mux policy of "require". | |||
// set up local media state | // set up local media state | |||
AliceJS->AliceUA: create new PeerConnection | AliceJS->AliceUA: create new PeerConnection | |||
AliceJS->AliceUA: addTrack with two tracks: audio and video | AliceJS->AliceUA: addTrack with two tracks: audio and video | |||
AliceJS->AliceUA: createOffer to get offer | AliceJS->AliceUA: createOffer to get offer | |||
AliceJS->AliceUA: setLocalDescription with offer | AliceJS->AliceUA: setLocalDescription with offer | |||
AliceUA->AliceJS: multiple onicecandidate events with candidates | AliceUA->AliceJS: multiple onicecandidate events with candidates | |||
// wait for ICE gathering to complete | // wait for ICE gathering to complete | |||
AliceUA->AliceJS: onicecandidate event with null candidate | AliceUA->AliceJS: onicecandidate event with null candidate | |||
skipping to change at line 3444 ¶ | skipping to change at line 3466 ¶ | |||
// Bob accepts call | // Bob accepts call | |||
BobJS->BobUA: addTrack with local tracks | BobJS->BobUA: addTrack with local tracks | |||
BobJS->BobUA: createAnswer | BobJS->BobUA: createAnswer | |||
BobJS->BobUA: setLocalDescription with answer | BobJS->BobUA: setLocalDescription with answer | |||
BobUA->BobJS: multiple onicecandidate events with candidates | BobUA->BobJS: multiple onicecandidate events with candidates | |||
// wait for ICE gathering to complete | // wait for ICE gathering to complete | |||
BobUA->BobJS: onicecandidate event with null candidate | BobUA->BobJS: onicecandidate event with null candidate | |||
BobJS->BobUA: get |answer-A1| from currentLocalDescription | BobJS->BobUA: get |answer-A1| from currentLocalDescription | |||
// |answer-A1| is sent over signaling protocol to Alice | // |answer-A1| is sent over signaling protocol | |||
// to Alice | ||||
BobJS->WebServer: signaling with |answer-A1| | BobJS->WebServer: signaling with |answer-A1| | |||
WebServer->AliceJS: signaling with |answer-A1| | WebServer->AliceJS: signaling with |answer-A1| | |||
// |answer-A1| arrives at Alice | // |answer-A1| arrives at Alice | |||
AliceJS->AliceUA: setRemoteDescription with |answer-A1| | AliceJS->AliceUA: setRemoteDescription with |answer-A1| | |||
AliceUA->AliceJS: ontrack events for audio and video tracks | AliceUA->AliceJS: ontrack events for audio and video tracks | |||
// media flows | // media flows | |||
BobUA->AliceUA: media sent from Bob to Alice | BobUA->AliceUA: media sent from Bob to Alice | |||
AliceUA->BobUA: media sent from Alice to Bob | AliceUA->BobUA: media sent from Alice to Bob | |||
skipping to change at line 3587 ¶ | skipping to change at line 3610 ¶ | |||
a=rtcp-fb:100 nack | a=rtcp-fb:100 nack | |||
a=rtcp-fb:100 nack pli | a=rtcp-fb:100 nack pli | |||
a=msid:61317484-2ed4-49d7-9eb7-1414322a7aae | a=msid:61317484-2ed4-49d7-9eb7-1414322a7aae | |||
7.2. Detailed Example | 7.2. Detailed Example | |||
This section shows a more involved example of a session between two | This section shows a more involved example of a session between two | |||
JSEP endpoints. Trickle ICE is used in full trickle mode, with a | JSEP endpoints. Trickle ICE is used in full trickle mode, with a | |||
bundle policy of "max-bundle", an RTCP mux policy of "require", and a | bundle policy of "max-bundle", an RTCP mux policy of "require", and a | |||
single TURN server. Initially, both Alice and Bob establish an audio | single TURN server. Initially, both Alice and Bob establish an audio | |||
channel and a data channel. Later, Bob adds two video flows, one for | channel and a data channel. Later, Bob adds two video flows -- one | |||
his video feed, and one for screensharing, both supporting FEC, and | for his video feed and one for screen sharing, both supporting FEC -- | |||
with the video feed configured for simulcast. Alice accepts these | with the video feed configured for simulcast. Alice accepts these | |||
video flows, but does not add video flows of her own, so they are | video flows but does not add video flows of her own, so they are | |||
handled as recvonly. Alice also specifies a maximum video decoder | handled as recvonly. Alice also specifies a maximum video decoder | |||
resolution. | resolution. | |||
// set up local media state | // set up local media state | |||
AliceJS->AliceUA: create new PeerConnection | AliceJS->AliceUA: create new PeerConnection | |||
AliceJS->AliceUA: addTrack with an audio track | AliceJS->AliceUA: addTrack with an audio track | |||
AliceJS->AliceUA: createDataChannel to get data channel | AliceJS->AliceUA: createDataChannel to get data channel | |||
AliceJS->AliceUA: createOffer to get |offer-B1| | AliceJS->AliceUA: createOffer to get |offer-B1| | |||
AliceJS->AliceUA: setLocalDescription with |offer-B1| | AliceJS->AliceUA: setLocalDescription with |offer-B1| | |||
// |offer-B1| is sent over signaling protocol to Bob | // |offer-B1| is sent over signaling protocol to Bob | |||
AliceJS->WebServer: signaling with |offer-B1| | AliceJS->WebServer: signaling with |offer-B1| | |||
WebServer->BobJS: signaling with |offer-B1| | WebServer->BobJS: signaling with |offer-B1| | |||
// |offer-B1| arrives at Bob | // |offer-B1| arrives at Bob | |||
BobJS->BobUA: create a PeerConnection | BobJS->BobUA: create a PeerConnection | |||
BobJS->BobUA: setRemoteDescription with |offer-B1| | BobJS->BobUA: setRemoteDescription with |offer-B1| | |||
BobUA->BobJS: ontrack with audio track from Alice | BobUA->BobJS: ontrack event with audio track from Alice | |||
// candidates are sent to Bob | // candidates are sent to Bob | |||
AliceUA->AliceJS: onicecandidate (host) |offer-B1-candidate-1| | AliceUA->AliceJS: onicecandidate (host) |offer-B1-candidate-1| | |||
AliceJS->WebServer: signaling with |offer-B1-candidate-1| | AliceJS->WebServer: signaling with |offer-B1-candidate-1| | |||
AliceUA->AliceJS: onicecandidate (srflx) |offer-B1-candidate-2| | AliceUA->AliceJS: onicecandidate (srflx) |offer-B1-candidate-2| | |||
AliceJS->WebServer: signaling with |offer-B1-candidate-2| | AliceJS->WebServer: signaling with |offer-B1-candidate-2| | |||
AliceUA->AliceJS: onicecandidate (relay) |offer-B1-candidate-3| | AliceUA->AliceJS: onicecandidate (relay) |offer-B1-candidate-3| | |||
AliceJS->WebServer: signaling with |offer-B1-candidate-3| | AliceJS->WebServer: signaling with |offer-B1-candidate-3| | |||
WebServer->BobJS: signaling with |offer-B1-candidate-1| | WebServer->BobJS: signaling with |offer-B1-candidate-1| | |||
skipping to change at line 3662 ¶ | skipping to change at line 3685 ¶ | |||
// data channel opens | // data channel opens | |||
BobUA->BobJS: ondatachannel event | BobUA->BobJS: ondatachannel event | |||
AliceUA->AliceJS: ondatachannel event | AliceUA->AliceJS: ondatachannel event | |||
BobUA->BobJS: onopen | BobUA->BobJS: onopen | |||
AliceUA->AliceJS: onopen | AliceUA->AliceJS: onopen | |||
// media is flowing between endpoints | // media is flowing between endpoints | |||
BobUA->AliceUA: audio+data sent from Bob to Alice | BobUA->AliceUA: audio+data sent from Bob to Alice | |||
AliceUA->BobUA: audio+data sent from Alice to Bob | AliceUA->BobUA: audio+data sent from Alice to Bob | |||
// some time later Bob adds two video streams | // some time later, Bob adds two video streams | |||
// note, no candidates exchanged, because of bundle | // note: no candidates exchanged, because of bundle | |||
BobJS->BobUA: addTrack with first video stream | BobJS->BobUA: addTrack with first video stream | |||
BobJS->BobUA: addTrack with second video stream | BobJS->BobUA: addTrack with second video stream | |||
BobJS->BobUA: createOffer to get |offer-B2| | BobJS->BobUA: createOffer to get |offer-B2| | |||
BobJS->BobUA: setLocalDescription with |offer-B2| | BobJS->BobUA: setLocalDescription with |offer-B2| | |||
// |offer-B2| is sent to Alice | // |offer-B2| is sent to Alice | |||
BobJS->WebServer: signaling with |offer-B2| | BobJS->WebServer: signaling with |offer-B2| | |||
WebServer->AliceJS: signaling with |offer-B2| | WebServer->AliceJS: signaling with |offer-B2| | |||
AliceJS->AliceUA: setRemoteDescription with |offer-B2| | AliceJS->AliceUA: setRemoteDescription with |offer-B2| | |||
AliceUA->AliceJS: ontrack event with first video track | AliceUA->AliceJS: ontrack event with first video track | |||
AliceUA->AliceJS: ontrack event with second video track | AliceUA->AliceJS: ontrack event with second video track | |||
AliceJS->AliceUA: createAnswer to get |answer-B2| | AliceJS->AliceUA: createAnswer to get |answer-B2| | |||
AliceJS->AliceUA: setLocalDescription with |answer-B2| | AliceJS->AliceUA: setLocalDescription with |answer-B2| | |||
// |answer-B2| is sent over signaling protocol to Bob | // |answer-B2| is sent over signaling protocol | |||
// to Bob | ||||
AliceJS->WebServer: signaling with |answer-B2| | AliceJS->WebServer: signaling with |answer-B2| | |||
WebServer->BobJS: signaling with |answer-B2| | WebServer->BobJS: signaling with |answer-B2| | |||
BobJS->BobUA: setRemoteDescription with |answer-B2| | BobJS->BobUA: setRemoteDescription with |answer-B2| | |||
// media is flowing between endpoints | // media is flowing between endpoints | |||
BobUA->AliceUA: audio+video+data sent from Bob to Alice | BobUA->AliceUA: audio+video+data sent from Bob to Alice | |||
AliceUA->BobUA: audio+video+data sent from Alice to Bob | AliceUA->BobUA: audio+video+data sent from Alice to Bob | |||
The SDP for |offer-B1| looks like: | The SDP for |offer-B1| looks like: | |||
skipping to change at line 3816 ¶ | skipping to change at line 3840 ¶ | |||
raddr 203.0.113.200 rport 10200 | raddr 203.0.113.200 rport 10200 | |||
|answer-B1-candidate-3| looks like: | |answer-B1-candidate-3| looks like: | |||
ufrag 7sFv | ufrag 7sFv | |||
index 0 | index 0 | |||
mid a1 | mid a1 | |||
attr candidate:1 1 udp 255 192.0.2.200 12200 typ relay | attr candidate:1 1 udp 255 192.0.2.200 12200 typ relay | |||
raddr 198.51.100.200 rport 11200 | raddr 198.51.100.200 rport 11200 | |||
The SDP for |offer-B2| is shown below. In addition to the new m= | The SDP for |offer-B2| is shown below. In addition to the new "m=" | |||
sections for video, both of which are offering FEC, and one of which | sections for video, both of which are offering FEC and one of which | |||
is offering simulcast, note the increment of the version number in | is offering simulcast, note the increment of the version number in | |||
the o= line, changes to the c= line, indicating the local candidate | the "o=" line; changes to the "c=" line, indicating the local | |||
that was selected, and the inclusion of gathered candidates as | candidate that was selected; and the inclusion of gathered candidates | |||
a=candidate lines. | as a=candidate lines. | |||
v=0 | v=0 | |||
o=- 7729291447651054566 2 IN IP4 0.0.0.0 | o=- 7729291447651054566 2 IN IP4 0.0.0.0 | |||
s=- | s=- | |||
t=0 0 | t=0 0 | |||
a=ice-options:trickle ice2 | a=ice-options:trickle ice2 | |||
a=group:BUNDLE a1 d1 v1 v2 | a=group:BUNDLE a1 d1 v1 v2 | |||
a=group:LS a1 v1 | a=group:LS a1 v1 | |||
m=audio 12200 UDP/TLS/RTP/SAVPF 96 0 8 97 98 | m=audio 12200 UDP/TLS/RTP/SAVPF 96 0 8 97 98 | |||
skipping to change at line 3912 ¶ | skipping to change at line 3936 ¶ | |||
a=fmtp:103 apt=101 | a=fmtp:103 apt=101 | |||
a=rtpmap:104 flexfec/90000 | a=rtpmap:104 flexfec/90000 | |||
a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid | a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid | |||
a=extmap:3 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id | a=extmap:3 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id | |||
a=rtcp-fb:100 ccm fir | a=rtcp-fb:100 ccm fir | |||
a=rtcp-fb:100 nack | a=rtcp-fb:100 nack | |||
a=rtcp-fb:100 nack pli | a=rtcp-fb:100 nack pli | |||
a=msid:81317484-2ed4-49d7-9eb7-1414322a7aae | a=msid:81317484-2ed4-49d7-9eb7-1414322a7aae | |||
The SDP for |answer-B2| is shown below. In addition to the | The SDP for |answer-B2| is shown below. In addition to the | |||
acceptance of the video m= sections, the use of a=recvonly to | acceptance of the video "m=" sections, the use of a=recvonly to | |||
indicate one-way video, and the use of a=imageattr to limit the | indicate one-way video, and the use of a=imageattr to limit the | |||
received resolution, note the use of setup:passive to maintain the | received resolution, note the use of setup:passive to maintain the | |||
existing DTLS roles. | existing DTLS roles. | |||
v=0 | v=0 | |||
o=- 4962303333179871723 2 IN IP4 0.0.0.0 | o=- 4962303333179871723 2 IN IP4 0.0.0.0 | |||
s=- | s=- | |||
t=0 0 | t=0 0 | |||
a=ice-options:trickle ice2 | a=ice-options:trickle ice2 | |||
a=group:BUNDLE a1 d1 v1 v2 | a=group:BUNDLE a1 d1 v1 v2 | |||
skipping to change at line 4001 ¶ | skipping to change at line 4025 ¶ | |||
a=fmtp:103 apt=101 | a=fmtp:103 apt=101 | |||
a=imageattr:100 recv [x=[48:1920],y=[48:1080],q=1.0] | a=imageattr:100 recv [x=[48:1920],y=[48:1080],q=1.0] | |||
a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid | a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid | |||
a=extmap:3 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id | a=extmap:3 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id | |||
a=rtcp-fb:100 ccm fir | a=rtcp-fb:100 ccm fir | |||
a=rtcp-fb:100 nack | a=rtcp-fb:100 nack | |||
a=rtcp-fb:100 nack pli | a=rtcp-fb:100 nack pli | |||
7.3. Early Transport Warmup Example | 7.3. Early Transport Warmup Example | |||
This example demonstrates the early warmup technique described in | This example demonstrates the early-warmup technique described in | |||
Section 4.1.8.1. Here, Alice's endpoint sends an offer to Bob's | Section 4.1.8.1. Here, Alice's endpoint sends an offer to Bob's | |||
endpoint to start an audio/video call. Bob immediately responds with | endpoint to start an audio/video call. Bob immediately responds with | |||
an answer that accepts the audio/video m= sections, but marks them as | an answer that accepts the audio/video "m=" sections but marks them | |||
sendonly (from his perspective), meaning that Alice will not yet send | as sendonly (from his perspective), meaning that Alice will not yet | |||
media. This allows the JSEP implementation to start negotiating ICE | send media. This allows the JSEP implementation to start negotiating | |||
and DTLS immediately. Bob's endpoint then prompts him to answer the | ICE and DTLS immediately. Bob's endpoint then prompts him to answer | |||
call, and when he does, his endpoint sends a second offer which | the call, and when he does, his endpoint sends a second offer, which | |||
enables the audio and video m= sections, and thereby bidirectional | enables the audio and video "m=" sections, and thereby bidirectional | |||
media transmission. The advantage of such a flow is that as soon as | media transmission. The advantage of such a flow is that as soon as | |||
the first answer is received, the implementation can proceed with ICE | the first answer is received, the implementation can proceed with ICE | |||
and DTLS negotiation and establish the session transport. If the | and DTLS negotiation and establish the session transport. If the | |||
transport setup completes before the second offer is sent, then media | transport setup completes before the second offer is sent, then media | |||
can be transmitted immediately by the callee immediately upon | can be transmitted by the callee immediately upon answering the call, | |||
answering the call, minimizing perceived post-dial-delay. The second | minimizing perceived post-dial delay. The second offer/answer | |||
offer/answer exchange can also change the preferred codecs or other | exchange can also change the preferred codecs or other session | |||
session parameters. | parameters. | |||
This example also makes use of the "relay" ICE candidate policy | This example also makes use of the "relay" ICE candidate policy | |||
described in Section 3.5.3 to minimize the ICE gathering and checking | described in Section 3.5.3 to minimize the ICE gathering and checking | |||
needed. | needed. | |||
// set up local media state | // set up local media state | |||
AliceJS->AliceUA: create new PeerConnection with "relay" ICE policy | AliceJS->AliceUA: create new PeerConnection with "relay" ICE policy | |||
AliceJS->AliceUA: addTrack with two tracks: audio and video | AliceJS->AliceUA: addTrack with two tracks: audio and video | |||
AliceJS->AliceUA: createOffer to get |offer-C1| | AliceJS->AliceUA: createOffer to get |offer-C1| | |||
AliceJS->AliceUA: setLocalDescription with |offer-C1| | AliceJS->AliceUA: setLocalDescription with |offer-C1| | |||
skipping to change at line 4045 ¶ | skipping to change at line 4069 ¶ | |||
BobJS->BobUA: setRemoteDescription with |offer-C1| | BobJS->BobUA: setRemoteDescription with |offer-C1| | |||
BobUA->BobJS: ontrack events for audio and video | BobUA->BobJS: ontrack events for audio and video | |||
// a relay candidate is sent to Bob | // a relay candidate is sent to Bob | |||
AliceUA->AliceJS: onicecandidate (relay) |offer-C1-candidate-1| | AliceUA->AliceJS: onicecandidate (relay) |offer-C1-candidate-1| | |||
AliceJS->WebServer: signaling with |offer-C1-candidate-1| | AliceJS->WebServer: signaling with |offer-C1-candidate-1| | |||
WebServer->BobJS: signaling with |offer-C1-candidate-1| | WebServer->BobJS: signaling with |offer-C1-candidate-1| | |||
BobJS->BobUA: addIceCandidate with |offer-C1-candidate-1| | BobJS->BobUA: addIceCandidate with |offer-C1-candidate-1| | |||
// Bob prepares an early answer to warmup the transport | // Bob prepares an early answer to warm up the | |||
// transport | ||||
BobJS->BobUA: addTransceiver with null audio and video tracks | BobJS->BobUA: addTransceiver with null audio and video tracks | |||
BobJS->BobUA: transceiver.setDirection(sendonly) for both | BobJS->BobUA: transceiver.setDirection(sendonly) for both | |||
BobJS->BobUA: createAnswer | BobJS->BobUA: createAnswer | |||
BobJS->BobUA: setLocalDescription with answer | BobJS->BobUA: setLocalDescription with answer | |||
// |answer-C1| is sent over signaling protocol to Alice | // |answer-C1| is sent over signaling protocol | |||
// to Alice | ||||
BobJS->WebServer: signaling with |answer-C1| | BobJS->WebServer: signaling with |answer-C1| | |||
WebServer->AliceJS: signaling with |answer-C1| | WebServer->AliceJS: signaling with |answer-C1| | |||
// |answer-C1| (sendonly) arrives at Alice | // |answer-C1| (sendonly) arrives at Alice | |||
AliceJS->AliceUA: setRemoteDescription with |answer-C1| | AliceJS->AliceUA: setRemoteDescription with |answer-C1| | |||
AliceUA->AliceJS: ontrack events for audio and video | AliceUA->AliceJS: ontrack events for audio and video | |||
// a relay candidate is sent to Alice | // a relay candidate is sent to Alice | |||
BobUA->BobJS: onicecandidate (relay) |answer-B1-candidate-1| | BobUA->BobJS: onicecandidate (relay) |answer-B1-candidate-1| | |||
BobJS->WebServer: signaling with |answer-B1-candidate-1| | BobJS->WebServer: signaling with |answer-B1-candidate-1| | |||
WebServer->AliceJS: signaling with |answer-B1-candidate-1| | WebServer->AliceJS: signaling with |answer-B1-candidate-1| | |||
AliceJS->AliceUA: addIceCandidate with |answer-B1-candidate-1| | AliceJS->AliceUA: addIceCandidate with |answer-B1-candidate-1| | |||
// ICE and DTLS establish while call is ringing | // ICE and DTLS establish while call is ringing | |||
// Bob accepts call, starts media, and sends new offer | // Bob accepts call, starts media, and sends | |||
// new offer | ||||
BobJS->BobUA: transceiver.setTrack with audio and video tracks | BobJS->BobUA: transceiver.setTrack with audio and video tracks | |||
BobUA->AliceUA: media sent from Bob to Alice | BobUA->AliceUA: media sent from Bob to Alice | |||
BobJS->BobUA: transceiver.setDirection(sendrecv) for both | BobJS->BobUA: transceiver.setDirection(sendrecv) for both | |||
transceivers | transceivers | |||
BobJS->BobUA: createOffer | BobJS->BobUA: createOffer | |||
BobJS->BobUA: setLocalDescription with offer | BobJS->BobUA: setLocalDescription with offer | |||
// |offer-C2| is sent over signaling protocol to Alice | // |offer-C2| is sent over signaling protocol | |||
// to Alice | ||||
BobJS->WebServer: signaling with |offer-C2| | BobJS->WebServer: signaling with |offer-C2| | |||
WebServer->AliceJS: signaling with |offer-C2| | WebServer->AliceJS: signaling with |offer-C2| | |||
// |offer-C2| (sendrecv) arrives at Alice | // |offer-C2| (sendrecv) arrives at Alice | |||
AliceJS->AliceUA: setRemoteDescription with |offer-C2| | AliceJS->AliceUA: setRemoteDescription with |offer-C2| | |||
AliceJS->AliceUA: createAnswer | AliceJS->AliceUA: createAnswer | |||
AliceJS->AliceUA: setLocalDescription with |answer-C2| | AliceJS->AliceUA: setLocalDescription with |answer-C2| | |||
AliceUA->BobUA: media sent from Alice to Bob | AliceUA->BobUA: media sent from Alice to Bob | |||
// |answer-C2| is sent over signaling protocol to Bob | // |answer-C2| is sent over signaling protocol | |||
// to Bob | ||||
AliceJS->WebServer: signaling with |answer-C2| | AliceJS->WebServer: signaling with |answer-C2| | |||
WebServer->BobJS: signaling with |answer-C2| | WebServer->BobJS: signaling with |answer-C2| | |||
BobJS->BobUA: setRemoteDescription with |answer-C2| | BobJS->BobUA: setRemoteDescription with |answer-C2| | |||
The SDP for |offer-C1| looks like: | The SDP for |offer-C1| looks like: | |||
v=0 | v=0 | |||
o=- 1070771854436052752 1 IN IP4 0.0.0.0 | o=- 1070771854436052752 1 IN IP4 0.0.0.0 | |||
s=- | s=- | |||
t=0 0 | t=0 0 | |||
skipping to change at line 4332 ¶ | skipping to change at line 4361 ¶ | |||
a=fmtp:103 apt=101 | a=fmtp:103 apt=101 | |||
a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid | a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid | |||
a=extmap:3 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id | a=extmap:3 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id | |||
a=rtcp-fb:100 ccm fir | a=rtcp-fb:100 ccm fir | |||
a=rtcp-fb:100 nack | a=rtcp-fb:100 nack | |||
a=rtcp-fb:100 nack pli | a=rtcp-fb:100 nack pli | |||
a=msid:bbce3ba6-abfc-ac63-d00a-e15b286f8fce | a=msid:bbce3ba6-abfc-ac63-d00a-e15b286f8fce | |||
8. Security Considerations | 8. Security Considerations | |||
The IETF has published separate documents [RFCYYY2] [RFCYYY1] | The IETF has published separate documents [RFC8827] [RFC8826] | |||
describing the security architecture for WebRTC as a whole. The | describing the security architecture for WebRTC as a whole. The | |||
remainder of this section describes security considerations for this | remainder of this section describes security considerations for this | |||
document. | document. | |||
While formally the JSEP interface is an API, it is better to think of | While formally the JSEP interface is an API, it is better to think of | |||
it as an Internet protocol, with the application JavaScript being | it as an Internet protocol, with the application JavaScript being | |||
untrustworthy from the perspective of the JSEP implementation. Thus, | untrustworthy from the perspective of the JSEP implementation. Thus, | |||
the threat model of [RFC3552] applies. In particular, JavaScript can | the threat model of [RFC3552] applies. In particular, JavaScript can | |||
call the API in any order and with any inputs, including malicious | call the API in any order and with any inputs, including malicious | |||
ones. This is particularly relevant when we consider the SDP which | ones. This is particularly relevant when we consider the SDP that is | |||
is passed to setLocalDescription(). While correct API usage requires | passed to setLocalDescription(). While correct API usage requires | |||
that the application pass in SDP which was derived from createOffer() | that the application pass in SDP that was derived from createOffer() | |||
or createAnswer(), there is no guarantee that applications do so. | or createAnswer(), there is no guarantee that applications do so. | |||
The JSEP implementation MUST be prepared for the JavaScript to pass | The JSEP implementation MUST be prepared for the JavaScript to pass | |||
in bogus data instead. | in bogus data instead. | |||
Conversely, the application programmer needs to be aware that the | Conversely, the application programmer needs to be aware that the | |||
JavaScript does not have complete control of endpoint behavior. One | JavaScript does not have complete control of endpoint behavior. One | |||
case that bears particular mention is that editing ICE candidates out | case that bears particular mention is that editing ICE candidates out | |||
of the SDP or suppressing trickled candidates does not have the | of the SDP or suppressing trickled candidates does not have the | |||
expected behavior: implementations will still perform checks from | expected behavior: implementations will still perform checks from | |||
those candidates even if they are not sent to the other side. Thus, | 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 | for instance, it is not possible to prevent the remote peer from | |||
learning your public IP address by removing server reflexive | learning your public IP address by removing server-reflexive | |||
candidates. Applications which wish to conceal their public IP | candidates. Applications that wish to conceal their public IP | |||
address should instead configure the ICE agent to use only relay | address should instead configure the ICE agent to use only relay | |||
candidates. | candidates. | |||
9. IANA Considerations | 9. IANA Considerations | |||
This document requires no actions from IANA. | This document has no IANA actions. | |||
10. Acknowledgements | ||||
Harald Alvestrand, Taylor Brandstetter, Suhas Nandakumar, and Peter | ||||
Thatcher provided significant text for this draft. Bernard Aboba, | ||||
Adam Bergkvist, Dan Burnett, Ben Campbell, Alissa Cooper, Richard | ||||
Ejzak, Stefan HÃ¥kansson, Ted Hardie, Christer Holmberg Andrew Hutton, | ||||
Randell Jesup, Matthew Kaufman, Anant Narayanan, Adam Roach, Robert | ||||
Sparks, Neil Stratford, Martin Thomson, Sean Turner, and Magnus | ||||
Westerlund all provided valuable feedback on this proposal. | ||||
11. References | 10. References | |||
11.1. Normative References | 10.1. Normative References | |||
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | |||
Requirement Levels", BCP 14, RFC 2119, | Requirement Levels", BCP 14, RFC 2119, | |||
DOI 10.17487/RFC2119, March 1997, | DOI 10.17487/RFC2119, March 1997, | |||
<https://www.rfc-editor.org/info/rfc2119>. | <https://www.rfc-editor.org/info/rfc2119>. | |||
[RFC3261] Rosenberg, J., Schulzrinne, H., Camarillo, G., Johnston, | [RFC3261] Rosenberg, J., Schulzrinne, H., Camarillo, G., Johnston, | |||
A., Peterson, J., Sparks, R., Handley, M., and E. | A., Peterson, J., Sparks, R., Handley, M., and E. | |||
Schooler, "SIP: Session Initiation Protocol", RFC 3261, | Schooler, "SIP: Session Initiation Protocol", RFC 3261, | |||
DOI 10.17487/RFC3261, June 2002, | DOI 10.17487/RFC3261, June 2002, | |||
skipping to change at line 4511 ¶ | skipping to change at line 4530 ¶ | |||
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | |||
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | |||
May 2017, <https://www.rfc-editor.org/info/rfc8174>. | May 2017, <https://www.rfc-editor.org/info/rfc8174>. | |||
[RFC8445] Keranen, A., Holmberg, C., and J. Rosenberg, "Interactive | [RFC8445] Keranen, A., Holmberg, C., and J. Rosenberg, "Interactive | |||
Connectivity Establishment (ICE): A Protocol for Network | Connectivity Establishment (ICE): A Protocol for Network | |||
Address Translator (NAT) Traversal", RFC 8445, | Address Translator (NAT) Traversal", RFC 8445, | |||
DOI 10.17487/RFC8445, July 2018, | DOI 10.17487/RFC8445, July 2018, | |||
<https://www.rfc-editor.org/info/rfc8445>. | <https://www.rfc-editor.org/info/rfc8445>. | |||
[RFCYYY1] Rescorla, E., "Security Considerations for WebRTC", | [RFC8826] Rescorla, E., "Security Considerations for WebRTC", | |||
RFC YYY1, DOI 10.17487/RFCYYY1, May 2020, | RFC 8826, DOI 10.17487/RFC8826, July 2020, | |||
<https://www.rfc-editor.org/info/rfcYYY1>. | <https://www.rfc-editor.org/info/rfc8826>. | |||
[RFCYYY2] Rescorla, E., "WebRTC Security Architecture", RFC YYY2, | [RFC8827] Rescorla, E., "WebRTC Security Architecture", RFC 8827, | |||
DOI 10.17487/RFCYYY2, May 2020, | DOI 10.17487/RFC8827, July 2020, | |||
<https://www.rfc-editor.org/info/rfcYYY2>. | <https://www.rfc-editor.org/info/rfc8827>. | |||
[RFCYYY4] Alvestrand, H. T., "WebRTC MediaStream Identification in | [RFC8830] Alvestrand, H., "WebRTC MediaStream Identification in the | |||
the Session Description Protocol", RFC YYY4, | Session Description Protocol", RFC 8830, | |||
DOI 10.17487/RFCYYY4, May 2020, | DOI 10.17487/RFC8830, July 2020, | |||
<https://www.rfc-editor.org/info/rfcYYY4>. | <https://www.rfc-editor.org/info/rfc8830>. | |||
[RFCYYY5] Perkins, C., Westerlund, M., and J. Ott, "Web Real-Time | [RFC8834] Perkins, C., Westerlund, M., and J. Ott, "Media Transport | |||
Communication (WebRTC): Media Transport and Use of RTP", | and Use of RTP in WebRTC", RFC 8834, DOI 10.17487/RFC8834, | |||
RFC YYY5, DOI 10.17487/RFCYYY5, May 2020, | July 2020, <https://www.rfc-editor.org/info/rfc8834>. | |||
<https://www.rfc-editor.org/info/rfcYYY5>. | ||||
[RFCYYY6] Ivov, E., Rescorla, E., Uberti, J., and P. Saint-Andre, | [RFC8838] Ivov, E., Uberti, J., and P. Saint-Andre, "Trickle ICE: | |||
"Trickle ICE: Incremental Provisioning of Candidates for | Incremental Provisioning of Candidates for the Interactive | |||
the Interactive Connectivity Establishment (ICE) | Connectivity Establishment (ICE) Protocol", RFC 8838, | |||
Protocol", RFC YYY6, DOI 10.17487/RFCYYY6, May 2020, | DOI 10.17487/RFC8838, July 2020, | |||
<https://www.rfc-editor.org/info/rfcYYY6>. | <https://www.rfc-editor.org/info/rfc8838>. | |||
[RFCYYY7] Petit-Huguenin, M., Nandakumar, S., Holmberg, C., Keränen, | [RFC8839] Petit-Huguenin, M., Nandakumar, S., Holmberg, C., Keränen, | |||
A., and R. Shpount, "Session Description Protocol (SDP) | A., and R. Shpount, "Session Description Protocol (SDP) | |||
Offer/Answer Procedures for Interactive Connectivity | Offer/Answer Procedures for Interactive Connectivity | |||
Establishment (ICE)", RFC YYY7, DOI 10.17487/RFCYYY7, May | Establishment (ICE)", RFC 8839, DOI 10.17487/RFC8839, July | |||
2020, <https://www.rfc-editor.org/info/rfcYYY7>. | 2020, <https://www.rfc-editor.org/info/rfc8839>. | |||
[RFCYYY9] Holmberg, C., Shpount, R.S., Loreto, S., and G. Camarillo, | [RFC8840] Ivov, E., Stach, T., Marocco, E., and C. Holmberg, "A | |||
Session Initiation Protocol (SIP) Usage for Incremental | ||||
Provisioning of Candidates for the Interactive | ||||
Connectivity Establishment (Trickle ICE)", | ||||
DOI 10.17487/RFC8840, RFC 8840, July 2018, | ||||
<https://www.rfc-editor.org/info/rfc8840>. | ||||
[RFC8841] Holmberg, C., Shpount, R., Loreto, S., and G. Camarillo, | ||||
"Session Description Protocol (SDP) Offer/Answer | "Session Description Protocol (SDP) Offer/Answer | |||
Procedures for Stream Control Transmission Protocol (SCTP) | Procedures for Stream Control Transmission Protocol (SCTP) | |||
over Datagram Transport Layer Security (DTLS) Transport", | over Datagram Transport Layer Security (DTLS) Transport", | |||
RFC YYY9, DOI 10.17487/RFCYYY9, May 2020, | RFC 8841, DOI 10.17487/RFC8841, July 2020, | |||
<https://www.rfc-editor.org/info/rfcYYY9>. | <https://www.rfc-editor.org/info/rfc8841>. | |||
[RFCYYYA] Holmberg, C.H. and R.S. Shpount, "Session Description | [RFC8842] Holmberg, C. and R. Shpount, "Session Description Protocol | |||
Protocol (SDP) Offer/Answer Considerations for Datagram | (SDP) Offer/Answer Considerations for Datagram Transport | |||
Transport Layer Security (DTLS) and Transport Layer | Layer Security (DTLS) and Transport Layer Security (TLS)", | |||
Security (TLS)", RFC YYYA, DOI 10.17487/RFCYYYA, May 2020, | RFC 8842, DOI 10.17487/RFC8842, July 2020, | |||
<https://www.rfc-editor.org/info/rfcYYYA>. | <https://www.rfc-editor.org/info/rfc8842>. | |||
[RFCYYYB] Holmberg, C.H., Alvestrand, H. T., and C. Jennings, | [RFC8843] Holmberg, C., Alvestrand, H., and C. Jennings, | |||
"Negotiating Media Multiplexing Using the Session | "Negotiating Media Multiplexing Using the Session | |||
Description Protocol (SDP)", RFC YYYB, | Description Protocol (SDP)", RFC 8843, | |||
DOI 10.17487/RFCYYYB, May 2020, | DOI 10.17487/RFC8843, July 2020, | |||
<https://www.rfc-editor.org/info/rfcYYYB>. | <https://www.rfc-editor.org/info/rfc8843>. | |||
[RFCYYYC] Roach, A.B., Ed., "RTP Payload Format Restrictions", | [RFC8851] Roach, A.B., Ed., "RTP Payload Format Restrictions", | |||
RFC YYYC, DOI 10.17487/RFCYYYC, May 2020, | DOI 10.17487/RFC8851, RFC 8851, July 2020, | |||
<https://www.rfc-editor.org/info/rfcYYYC>. | <https://www.rfc-editor.org/info/rfc8851>. | |||
[RFCYYYD] Roach, A.B., Nandakumar, S., and P. Thatcher, "RTP Stream | [RFC8852] Roach, A.B., Nandakumar, S., and P. Thatcher, "RTP Stream | |||
Identifier Source Description (SDES)", RFC YYYD, | Identifier Source Description (SDES)", | |||
DOI 10.17487/RFCYYYD, May 2020, | DOI 10.17487/RFC8852, RFC 8852, July 2020, | |||
<https://www.rfc-editor.org/info/rfcYYYD>. | <https://www.rfc-editor.org/info/rfc8852>. | |||
[RFCYYYE] Burman, B., Westerlund, M., Nandakumar, S., and M. Zanaty, | [RFC8853] Burman, B., Westerlund, M., Nandakumar, S., and M. Zanaty, | |||
"Using Simulcast in Session Description Protocol (SDP) and | "Using Simulcast in Session Description Protocol (SDP) and | |||
RTP Sessions", RFC YYYE, DOI 10.17487/RFCYYYE, May 2020, | RTP Sessions", DOI 10.17487/RFC8853, RFC 8853, July 2020, | |||
<https://www.rfc-editor.org/info/rfcYYYE>. | <https://www.rfc-editor.org/info/rfc8853>. | |||
[RFCYYYF] Uberti, J., "WebRTC Forward Error Correction | [RFC8854] Uberti, J., "WebRTC Forward Error Correction | |||
Requirements", RFC YYYF, DOI 10.17487/RFCYYYF, May 2020, | Requirements", RFC 8854, DOI 10.17487/RFC8854, July 2020, | |||
<https://www.rfc-editor.org/info/rfcYYYF>. | <https://www.rfc-editor.org/info/rfc8854>. | |||
[RFCYYYG] Holmberg, C., "Indicating Exclusive Support of RTP/RTCP | [RFC8858] Holmberg, C., "Indicating Exclusive Support of RTP and RTP | |||
Multiplexing Using the Session Description Protocol | Control Protocol (RTCP) Multiplexing Using the Session | |||
(SDP)", RFC YYYG, DOI 10.17487/RFCYYYG, May 2020, | Description Protocol (SDP)", RFC 8858, | |||
<https://www.rfc-editor.org/info/rfcYYYG>. | DOI 10.17487/RFC8858, July 2020, | |||
<https://www.rfc-editor.org/info/rfc8858>. | ||||
[RFCYYYH] Nandakumar, S., "A Framework for Session Description | [RFC8859] Nandakumar, S., "A Framework for Session Description | |||
Protocol (SDP) Attributes When Multiplexing", RFC YYYH, | Protocol (SDP) Attributes When Multiplexing", | |||
DOI 10.17487/RFCYYYH, May 2020, | DOI 10.17487/RFC8859, RFC 8859, July 2020, | |||
<https://www.rfc-editor.org/info/rfcYYYH>. | <https://www.rfc-editor.org/info/rfc8859>. | |||
11.2. Informative References | 10.2. Informative References | |||
[RFC3389] Zopf, R., "Real-time Transport Protocol (RTP) Payload for | [RFC3389] Zopf, R., "Real-time Transport Protocol (RTP) Payload for | |||
Comfort Noise (CN)", RFC 3389, DOI 10.17487/RFC3389, | Comfort Noise (CN)", RFC 3389, DOI 10.17487/RFC3389, | |||
September 2002, <https://www.rfc-editor.org/info/rfc3389>. | September 2002, <https://www.rfc-editor.org/info/rfc3389>. | |||
[RFC3556] Casner, S., "Session Description Protocol (SDP) Bandwidth | [RFC3556] Casner, S., "Session Description Protocol (SDP) Bandwidth | |||
Modifiers for RTP Control Protocol (RTCP) Bandwidth", | Modifiers for RTP Control Protocol (RTCP) Bandwidth", | |||
RFC 3556, DOI 10.17487/RFC3556, July 2003, | RFC 3556, DOI 10.17487/RFC3556, July 2003, | |||
<https://www.rfc-editor.org/info/rfc3556>. | <https://www.rfc-editor.org/info/rfc3556>. | |||
skipping to change at line 4647 ¶ | skipping to change at line 4673 ¶ | |||
(SRTP) Security Context Using Datagram Transport Layer | (SRTP) Security Context Using Datagram Transport Layer | |||
Security (DTLS)", RFC 5763, DOI 10.17487/RFC5763, May | Security (DTLS)", RFC 5763, DOI 10.17487/RFC5763, May | |||
2010, <https://www.rfc-editor.org/info/rfc5763>. | 2010, <https://www.rfc-editor.org/info/rfc5763>. | |||
[RFC5764] McGrew, D. and E. Rescorla, "Datagram Transport Layer | [RFC5764] McGrew, D. and E. Rescorla, "Datagram Transport Layer | |||
Security (DTLS) Extension to Establish Keys for the Secure | Security (DTLS) Extension to Establish Keys for the Secure | |||
Real-time Transport Protocol (SRTP)", RFC 5764, | Real-time Transport Protocol (SRTP)", RFC 5764, | |||
DOI 10.17487/RFC5764, May 2010, | DOI 10.17487/RFC5764, May 2010, | |||
<https://www.rfc-editor.org/info/rfc5764>. | <https://www.rfc-editor.org/info/rfc5764>. | |||
[RFC6120] Saint-Andre, P., "Extensible Messaging and Presence | ||||
Protocol (XMPP): Core", RFC 6120, DOI 10.17487/RFC6120, | ||||
March 2011, <https://www.rfc-editor.org/info/rfc6120>. | ||||
[RFC6464] Lennox, J., Ed., Ivov, E., and E. Marocco, "A Real-time | [RFC6464] Lennox, J., Ed., Ivov, E., and E. Marocco, "A Real-time | |||
Transport Protocol (RTP) Header Extension for Client-to- | Transport Protocol (RTP) Header Extension for Client-to- | |||
Mixer Audio Level Indication", RFC 6464, | Mixer Audio Level Indication", RFC 6464, | |||
DOI 10.17487/RFC6464, December 2011, | DOI 10.17487/RFC6464, December 2011, | |||
<https://www.rfc-editor.org/info/rfc6464>. | <https://www.rfc-editor.org/info/rfc6464>. | |||
[RFC6544] Rosenberg, J., Keranen, A., Lowekamp, B. B., and A. B. | [RFC6544] Rosenberg, J., Keranen, A., Lowekamp, B. B., and A. B. | |||
Roach, "TCP Candidates with Interactive Connectivity | Roach, "TCP Candidates with Interactive Connectivity | |||
Establishment (ICE)", RFC 6544, DOI 10.17487/RFC6544, | Establishment (ICE)", RFC 6544, DOI 10.17487/RFC6544, | |||
March 2012, <https://www.rfc-editor.org/info/rfc6544>. | March 2012, <https://www.rfc-editor.org/info/rfc6544>. | |||
[RFCYYY3] Uberti, J., "WebRTC IP Address Handling Requirements", | [RFC8828] Uberti, J., "WebRTC IP Address Handling Requirements", | |||
RFC YYY3, DOI 10.17487/RFCYYY3, May 2020, | RFC 8828, DOI 10.17487/RFC8828, July 2020, | |||
<https://www.rfc-editor.org/info/rfcYYY3>. | <https://www.rfc-editor.org/info/rfc8828>. | |||
[RFCYYY8] Ivov, E., Stach, T., Marocco, E., and C.H. Holmberg, "A | ||||
Session Initiation Protocol (SIP) Usage for Incremental | ||||
Provisioning of Candidates for the Interactive | ||||
Connectivity Establishment (Trickle ICE)", RFC YYY8, | ||||
DOI 10.17487/RFCYYY8, May 2020, | ||||
<https://www.rfc-editor.org/info/rfcYYY8>. | ||||
[SDP4WebRTC] | [SDP4WebRTC] | |||
Nandakumar, S. and C. Jennings, "Annotated Example SDP for | Nandakumar, S. and C. Jennings, "Annotated Example SDP for | |||
WebRTC", Work in Progress, Internet-Draft, draft-ietf- | WebRTC", Work in Progress, Internet-Draft, draft-ietf- | |||
rtcweb-sdp-12, 9 May 2020, | rtcweb-sdp-12, 9 May 2020, | |||
<https://tools.ietf.org/html/draft-ietf-rtcweb-sdp-12>. | <https://tools.ietf.org/html/draft-ietf-rtcweb-sdp-12>. | |||
[TS26.114] 3GPP, "3rd Generation Partnership Project; Technical | [TS26.114] 3GPP, "3rd Generation Partnership Project; Technical | |||
Specification Group Services and System Aspects; IP | Specification Group Services and System Aspects; IP | |||
Multimedia Subsystem (IMS); Multimedia Telephony; Media | Multimedia Subsystem (IMS); Multimedia Telephony; Media | |||
skipping to change at line 4689 ¶ | skipping to change at line 4712 ¶ | |||
V12.8.0, December 2014, | V12.8.0, December 2014, | |||
<https://www.3gpp.org/DynaReport/26114.htm>. | <https://www.3gpp.org/DynaReport/26114.htm>. | |||
[W3C.webrtc] | [W3C.webrtc] | |||
Bergkvist, A., Burnett, D., Jennings, C., Narayanan, A., | Bergkvist, A., Burnett, D., Jennings, C., Narayanan, A., | |||
Aboba, B., and T. Brandstetter, "WebRTC 1.0: Real-time | Aboba, B., and T. Brandstetter, "WebRTC 1.0: Real-time | |||
Communication Between Browsers", World Wide Web Consortium | Communication Between Browsers", World Wide Web Consortium | |||
WD WD-webrtc-20170515, May 2017, | WD WD-webrtc-20170515, May 2017, | |||
<https://www.w3.org/TR/2017/WD-webrtc-20170515/>. | <https://www.w3.org/TR/2017/WD-webrtc-20170515/>. | |||
Appendix A. Appendix A | Appendix A. ABNF Definitions | |||
For the syntax validation performed in Section 5.8, the following | For the syntax validation performed in Section 5.8, the following | |||
list of ABNF definitions is used: | list of ABNF definitions is used: | |||
+=========================+===================================+ | +=========================+===================================+ | |||
| Attribute | Reference | | | Attribute | Reference | | |||
+=========================+===================================+ | +=========================+===================================+ | |||
| ptime | Section 9 of [RFC4566] | | | ptime | Section 9 of [RFC4566] | | |||
+-------------------------+-----------------------------------+ | +-------------------------+-----------------------------------+ | |||
| maxptime | Section 9 of [RFC4566] | | | maxptime | Section 9 of [RFC4566] | | |||
skipping to change at line 4737 ¶ | skipping to change at line 4760 ¶ | |||
| extmap | Section 7 of [RFC5285] | | | extmap | Section 7 of [RFC5285] | | |||
+-------------------------+-----------------------------------+ | +-------------------------+-----------------------------------+ | |||
| mid | Sections 4 and 5 of [RFC5888] | | | mid | Sections 4 and 5 of [RFC5888] | | |||
+-------------------------+-----------------------------------+ | +-------------------------+-----------------------------------+ | |||
| group | Sections 4 and 5 of [RFC5888] | | | group | Sections 4 and 5 of [RFC5888] | | |||
+-------------------------+-----------------------------------+ | +-------------------------+-----------------------------------+ | |||
| imageattr | Section 3.1 of [RFC6236] | | | imageattr | Section 3.1 of [RFC6236] | | |||
+-------------------------+-----------------------------------+ | +-------------------------+-----------------------------------+ | |||
| extmap (encrypt option) | Section 4 of [RFC6904] | | | extmap (encrypt option) | Section 4 of [RFC6904] | | |||
+-------------------------+-----------------------------------+ | +-------------------------+-----------------------------------+ | |||
| candidate | Section 4.1 of [RFCYYY7] | | | candidate | Section 5.1 of [RFC8839] | | |||
+-------------------------+-----------------------------------+ | +-------------------------+-----------------------------------+ | |||
| remote-candidates | Section 4.2 of [RFCYYY7] | | | remote-candidates | Section 5.2 of [RFC8839] | | |||
+-------------------------+-----------------------------------+ | +-------------------------+-----------------------------------+ | |||
| ice-lite | Section 4.3 of [RFCYYY7] | | | ice-lite | Section 5.3 of [RFC8839] | | |||
+-------------------------+-----------------------------------+ | +-------------------------+-----------------------------------+ | |||
| ice-ufrag | Section 4.4 of [RFCYYY7] | | | ice-ufrag | Section 5.4 of [RFC8839] | | |||
+-------------------------+-----------------------------------+ | +-------------------------+-----------------------------------+ | |||
| ice-pwd | Section 4.4 of [RFCYYY7] | | | ice-pwd | Section 5.4 of [RFC8839] | | |||
+-------------------------+-----------------------------------+ | +-------------------------+-----------------------------------+ | |||
| ice-options | Section 4.6 of [RFCYYY7] | | | ice-options | Section 5.6 of [RFC8839] | | |||
+-------------------------+-----------------------------------+ | +-------------------------+-----------------------------------+ | |||
| msid | Section 2 of [RFCYYY4] | | | msid | Section 3 of [RFC8830] | | |||
+-------------------------+-----------------------------------+ | +-------------------------+-----------------------------------+ | |||
| rid | Section 10 of [RFCYYYC] | | | rid | Section 10 of [RFC8851] | | |||
+-------------------------+-----------------------------------+ | +-------------------------+-----------------------------------+ | |||
| simulcast | Section 6.1 of [RFCYYYE] | | | simulcast | Section 6.1 of [RFC8853] | | |||
+-------------------------+-----------------------------------+ | +-------------------------+-----------------------------------+ | |||
| tls-id | Section 4 of [RFCYYYA] | | | tls-id | Section 4 of [RFC8842] | | |||
+-------------------------+-----------------------------------+ | +-------------------------+-----------------------------------+ | |||
Table 1: SDP ABNF References | Table 1: SDP ABNF References | |||
Appendix B. Change log | Acknowledgements | |||
Note to RFC Editor: Please remove this section before publication. | ||||
Changes in draft-26: | ||||
* Update guidance on generation of the m= proto value to be | ||||
consistent with ice-sip-sdp. | ||||
Changes in draft-25: | ||||
* Remove MSID track ID from offers and answers. | ||||
* Add note about rejecting all m= sections in a BUNDLE group. | ||||
* Update ICE references to RFC 8445 and mention ice2. | ||||
Changes in draft-24: | ||||
* Clarify that rounding is permitted when trying to maintain aspect | ||||
ratio. | ||||
* Update tls-id handling to match what is specified in dtls-sdp. | ||||
Changes in draft-23: | ||||
* Clarify rollback handling, and treat it similarly to other | ||||
setLocal/setRemote usages. | ||||
* Adopt a first-fit policy for handling multiple remote a=imageattr | ||||
attributes. | ||||
* Clarify that a session description with zero m= sections is legal. | ||||
Changes in draft-22: | ||||
* Clarify currentDirection versus direction. | ||||
* Correct session-id text so that it aligns with RFC 3264. | ||||
* Clarify that generated ICE candidate objects must have all four | ||||
fields. | ||||
* Make rollback work from any state besides stable and regardless of | ||||
whether setLocalDescription or setRemoteDescription is used. | ||||
* Allow modifying SDP before sending or after receiving either | ||||
offers or answers (previously this was forbidden for answers). | ||||
* Provide rationale for several design choices. | ||||
Changes in draft-21: | ||||
* Change dtls-id to tls-id to match MMUSIC draft. | ||||
* Replace regular expression for proto field with a list and clarify | ||||
that the answer must exactly match the offer. | ||||
* Remove text about how to error check on setLocal because local | ||||
descriptions cannot be changed. | ||||
* Rework silence suppression support to always require that both | ||||
sides agree to silence suppression or none is used. | ||||
* Remove instructions to parse "a=ssrc-group". | ||||
* Allow the addition of new codecs in answers and in subsequent | ||||
offers. | ||||
* Clarify imageattr processing. Replace use of [x=0,y=0] with | ||||
direction indicators. | ||||
* Document when early media can occur. | ||||
* Fix ICE default port handling when bundle-only is used. | ||||
* Forbid duplicating IDENTICAL/TRANSPORT attributes when you are | ||||
bundling. | ||||
* Clarify the number of components to gather when bundle is | ||||
involved. | ||||
* Explicitly state that PTs and SSRCs are to be used for demuxing. | ||||
* Update guidance on "a=setup" line. This should now match the | ||||
MMUSIC draft. | ||||
* Update guidance on certificate/digest matching to conform to | ||||
RFC8122. | ||||
* Update examples. | ||||
Changes in draft-20: | ||||
* Remove Appendix-B. | ||||
Changes in draft-19: | ||||
* Examples are now machine-generated for correctness, and use IETF- | ||||
approved example IP addresses. | ||||
* Add early transport warmup example, and add missing attributes to | ||||
existing examples. | ||||
* Only send "a=rtcp-mux-only" and "a=bundle-only" on new m= | ||||
sections. | ||||
* Update references. | ||||
* Add coverage of a=identity. | ||||
* Explain the lipsync group algorithm more thoroughly. | ||||
* Remove unnecessary list of MTI specs. | ||||
* Allow codecs which weren't offered to appear in answers and which | ||||
weren't selected to appear in subsequent offers. | ||||
* Codec preferences now are applied on both initial and subsequent | ||||
offers and answers. | ||||
* Clarify a=msid handling for recvonly m= sections. | ||||
* Clarify behavior of attributes for bundle-only data channels. | ||||
* Allow media attributes to appear in data m= sections when all the | ||||
media m= sections are bundle-only. | ||||
* Use consistent terminology for JSEP implementations. | ||||
* Describe how to handle failed API calls. | ||||
* Some cleanup on routing rules. | ||||
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 cleanup | ||||
Changes 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 specification | ||||
Changes in draft-02: | ||||
* Converted from nroff | ||||
* Removed comparisons to old approaches abandoned by the working | ||||
group | ||||
* Removed stuff that has moved to W3C specification | ||||
* Align SDP handling with W3C draft | ||||
* Clarified 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. | Harald Alvestrand, Taylor Brandstetter, Suhas Nandakumar, and Peter | |||
Thatcher provided significant text for this document. Bernard Aboba, | ||||
Adam Bergkvist, Dan Burnett, Ben Campbell, Alissa Cooper, Richard | ||||
Ejzak, Stefan HÃ¥kansson, Ted Hardie, Christer Holmberg, Andrew | ||||
Hutton, Randell Jesup, Matthew Kaufman, Anant Narayanan, Adam Roach, | ||||
Robert Sparks, Neil Stratford, Martin Thomson, Sean Turner, and | ||||
Magnus Westerlund all provided valuable feedback on this document. | ||||
Authors' Addresses | Authors' Addresses | |||
Justin Uberti | Justin Uberti | |||
747 6th St S | 747 6th Street South | |||
Kirkland, WA 98033 | Kirkland, WA 98033 | |||
United States of America | United States of America | |||
Email: justin@uberti.name | Email: justin@uberti.name | |||
Cullen Jennings | Cullen Jennings | |||
Cisco | Cisco | |||
400 3rd Avenue SW | 400 3rd Avenue SW | |||
Calgary AB T2P 4H2 | Calgary AB T2P 4H2 | |||
Canada | Canada | |||
Email: fluffy@iii.ca | Email: fluffy@iii.ca | |||
Eric Rescorla (editor) | Eric Rescorla (editor) | |||
Mozilla | Mozilla | |||
331 Evelyn Ave | 331 E. Evelyn Ave. | |||
Mountain View, CA 94041 | Mountain View, CA 94041 | |||
United States of America | United States of America | |||
Email: ekr@rtfm.com | Email: ekr@rtfm.com | |||
End of changes. 483 change blocks. | ||||
1483 lines changed or deleted | 1031 lines changed or added | |||
This html diff was produced by rfcdiff 1.45. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |