-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathindex.html
1630 lines (1626 loc) · 67.9 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<link href="webrtc.css" rel="stylesheet">
<title>WebRTC Extensions</title>
<script class="remove" src="https://www.w3.org/Tools/respec/respec-w3c"></script>
<script class="remove" src="webrtc-extensions.js" ></script>
</head>
<body>
<section id="abstract">
<p>
This document defines a set of ECMAScript APIs in WebIDL to extend the WebRTC 1.0 API.
</p>
</section>
<section id="sotd">
<p>The API is based on preliminary work done in the W3C WEBRTC Working Group.</p>
</section>
<section class="informative" id="intro">
<h2>Introduction</h2>
<p>
This document contains proposed extensions to the [[WEBRTC]] specification.
Some of these extensions were originally included within the [[WEBRTC]] specification,
but needed to be removed due to lack of implementation experience. Others were not
sufficiently mature to be incorporated into that specification when they were developed,
but were too small to warrant creation of a separate document.
</p>
<p>
This document contains some sections extending one specific interface or dictionary in
the base specification; in this case the extension is only described in an individual
section. Where an extension affects multiple interfaces or dictionaries, a subsection
in the "Overviews" section describes the extension as a whole, while normative text
is provided in sections relating to the individual interfaces.
</p>
<p>
As extensions mature and gain implementation experience, they may move from this document
to the base specification if WG consensus emerges to do so.
</p>
</section>
<section id="conformance">
<p>This specification defines conformance criteria that apply to a single
product: the <dfn>user agent</dfn> that implements the interfaces that it
contains.</p>
<p>Conformance requirements phrased as algorithms or specific steps may be
implemented in any manner, so long as the end result is equivalent. (In
particular, the algorithms defined in this specification are intended to be
easy to follow, and not intended to be performant.)</p>
<p>Implementations that use ECMAScript to implement the APIs defined in
this specification MUST implement them in a manner consistent with the
ECMAScript Bindings defined in the Web IDL specification [[WEBIDL]], as
this specification uses that specification and terminology.</p>
</section>
<section>
<h2>Terminology</h2>
<p>
The following terms are defined in
<dfn data-cite="RTP-EXT-CAPTURE-TIME#">RTP Header Extension for Absolute Capture Time</dfn>:
</p>
<ul>
<li><dfn data-cite="RTP-EXT-CAPTURE-TIME#absolute-capture-timestamp">absolute capture timestamp</dfn></li>
<li><dfn data-cite="RTP-EXT-CAPTURE-TIME#timestamp-interpolation">timestamp interpolation</dfn></li>
<li><dfn data-cite="RTP-EXT-CAPTURE-TIME#estimated-capture-clock-offset">estimated capture clock offset</dfn></li>
</ul>
<p>
The process of <dfn data-lt="form|formed|forming">forming</dfn> a candidate pair is defined in
[[RFC8445]] Section 6.1.2.2.
</p>
<p>
The process of <dfn data-lt="nominate|nominated|nomination">nominating</dfn> a candidate pair is defined in
[[RFC8445]] Section 8.1.1.
</p>
<p>
The process of <dfn data-lt="free|freed|freeing">freeing</dfn> a candidate is defined in [[RFC8445]] Section 8.3.
</p>
</section>
<section id="ice-csp">
<h3>
Filtering ICE candidates with Content-Security-Policy
</h3>
<p>
The {{RTCPeerConnection}} interface is defined in [[WEBRTC]]. This document
extends that interface by using Content-Security-Policy for ICE candidate
filtering.
</p>
<section id="ice-csp-modifications">
<h2>Modifications to existing procedures</h2>
<p>Append the following paragraph to the
<a data-cite="WEBRTC#dfn-administratively-prohibited">administratively prohibited</a>
algorithm:</p>
<p>If <a data-cite="CSP#should-block-rtc-connection">
should RTC connections be blocked for global?</a> with the
[=relevant global object=] of the {{RTCPeerConnection}} object in question
returns `"Blocked"`, then all candidates MUST be <a
data-cite="WEBRTC#dfn-administratively-prohibited">
administratively prohibited</a>.</p>
</section>
</section>
<section id="rtp-header-extension-control">
<h2>RTP header extension control</h2>
<p>
RTP header extension control is an extension to {{RTCRtpTransceiver}} that allows
to set and query the RTP header extensions supported and negotiated in SDP.
<p>
The RTP header extension mechanism is defined in [[RFC8285]], with
the SDP negotiation mechanism defined in section 5. It goes into some
detail on the meaning of "direction" with regard to RTP header
extensions, and gives a detailed procedure for negotiating RTP header
extension IDs.
</p>
<p>
This API extension gives the means to control the use and direction of
RTP header extensions as documented in [[RFC8285]]. It does not
influence the ID negotiation mechanism, except for being able to
control the number of extensions offered.
</p>
<section id="rtp-header-extension-control-transceiver-interface">
<h3>
{{RTCRtpTransceiver}} interface extensions
</h3>
<p>
The {{RTCRtpTransceiver}}
interface is defined in [[WEBRTC]]. This document extends that interface
by adding an additional method and attribute in order to control negotiation of
RTP header extensions.
</p>
<pre class="idl">
partial dictionary RTCRtpHeaderExtensionCapability {
required RTCRtpTransceiverDirection direction;
};
partial interface RTCRtpTransceiver {
sequence<RTCRtpHeaderExtensionCapability> getHeaderExtensionsToNegotiate();
undefined setHeaderExtensionsToNegotiate(
sequence<RTCRtpHeaderExtensionCapability> extensions);
sequence<RTCRtpHeaderExtensionCapability> getNegotiatedHeaderExtensions();
};
</pre>
<p>
Let
<dfn data-dfn-for=RTCRtpTransceiver>{{RTCRtpTransceiver/[[HeaderExtensionsToNegotiate]]}}</dfn>
and
<dfn data-dfn-for=RTCRtpTransceiver>{{RTCRtpTransceiver/[[NegotiatedHeaderExtensions]]}}</dfn>
be internal slots of the {{RTCRtpTransceiver}}, initialized as follows:
</p>
<ol>
<li>
<p>Set {{RTCRtpTransceiver/[[HeaderExtensionsToNegotiate]]}} to the
platform-specific list of implemented RTP header extensions. The
{{RTCRtpHeaderExtensionCapability/direction}} attribute for all
extensions that are mandatory to use MUST be initialized to an
appropriate value other than {{RTCRtpTransceiverDirection/"stopped"}}.
The {{RTCRtpHeaderExtensionCapability/direction}} attribute for
extensions that will not be offered by default in an initial offer MUST
be initialized to {{RTCRtpTransceiverDirection/"stopped"}}.</p>
<p class="note">The list of header extensions that MUST/SHOULD be
supported is listed in [[RTCWEB-RTP]], section 5.2. The "mid" extension
is mandatory to use when BUNDLE is in use, per [[BUNDLE]] section
9.1.</p>
</li>
<li>
<p>Set {{RTCRtpTransceiver/[[NegotiatedHeaderExtensions]]}} to an empty
list.</p>
</li>
</ol>
</section>
<section id="rtp-header-extension-control-modifications">
<h2>Modifications to existing procedures</h2>
<p>
Make the following modifications to the
<a data-cite="WEBRTC#set-description">set a session description</a>
algorithm:
</p>
<ul>
<li>
<p>In the step for processing a <var>description</var> of type
{{RTCSdpType/"answer"}} that runs for both local and remote
descriptions, insert the following steps:</p>
<ol>
<li>
<p>For each <var>media description</var> and corresponding
<var>transceiver</var>, let <var>negotiatedExtensions</var> be the
value of
<var>transceiver</var>.{{RTCRtpTransceiver/[[HeaderExtensionsToNegotiate]]}}.</p>
</li>
<li>
<p>For each <var>extension</var> in
<var>negotiatedExtensions</var>, run the following steps:</p>
<ol>
<li>
<p>Let <var>answeredDirection</var> be the direction attribute
of the "a=extmap" line in the answer's
<var>media description</var> that correspond to this
<var>extension</var> if one exists, otherwise set
<var>answeredDirection</var> to
{{RTCRtpTransceiverDirection/"stopped"}}.</p>
</li>
<li>
<p>If <var>description</var> is a remote description, reverse
<var>answeredDirection</var> to represent the peer's point of
view.</p>
</li>
<li>
<p>Set
<var>extension</var>.{{RTCRtpHeaderExtensionCapability/direction}}
to <var>answeredDirection</var>.</p>
</li>
</ol>
</li>
<li>
<p>Set
<var>transceiver</var>.{{RTCRtpTransceiver/[[NegotiatedHeaderExtensions]]}}
to <var>negotiatedExtensions</var>.</p>
</li>
</ol>
</li>
</ul>
<p>
In the algorithms for generating initial offers in [[RTCWEB-JSEP]] section 5.2.1,
replace "for each supported RTP header extension, an "a=extmap" line, as specified in
[[RFC5285]], section 5" " with "For each RTP header extension "e"
listed in {{RTCRtpTransceiver/[[HeaderExtensionsToNegotiate]]}} where {{RTCRtpHeaderExtensionCapability/direction}} is not {{RTCRtpTransceiverDirection/"stopped"}}, an "a=extmap"
line, as specified in [[RFC5285]], section 5, with direction taken from "e"'s {{RTCRtpHeaderExtensionCapability/direction}}
attribute."
</p>
<p>
In the algorithm for generating subsequent offers in [[RTCWEB-JSEP]] section 5.2.2, replace "The
RTP header extensions MUST only include those that are present in the most recent answer"
with "For each RTP header extension listed in {{RTCRtpTransceiver/[[HeaderExtensionsToNegotiate]]}},
and where {{RTCRtpHeaderExtensionCapability/direction}} is not {{RTCRtpTransceiverDirection/"stopped"}}, generate
an appropriate "a=extmap" line with "direction" set according to the rules of [[RFC5285]]
section 6, considering the {{RTCRtpHeaderExtensionCapability/direction}} in {{RTCRtpTransceiver/[[HeaderExtensionsToNegotiate]]}} to indicate the
answerer's desired usage".
</p>
<p>
In the algorithm for generating initial answers in [[RTCWEB-JSEP]] section 5.3.1, replace "For
each supported RTP header extension that is present in the offer" with "For each
supported RTP header extension that is present in the offer and is also present in
{{RTCRtpTransceiver/[[HeaderExtensionsToNegotiate]]}} with a {{RTCRtpHeaderExtensionCapability/direction}} different from {{RTCRtpTransceiverDirection/"stopped"}},
set the appropriate direction based on {{RTCRtpHeaderExtensionCapability/direction}} that does not exceed the direction in the offer".
</p>
<p class="note">
Since JSEP does not know about WebRTC internal slots, merging this change requires
more work on a JSEP revision.
</p>
</section>
<section id="rtp-header-extension-control-transceiver-methods">
<h3>Methods</h3>
<dl>
<dt><dfn data-dfn-for=RTCRtpTransceiver>getHeaderExtensionsToNegotiate</dfn></dt>
<dd>
<p>Execute the following steps:</p>
<ol>
<li>
<p>Let <var>transceiver</var> be the {{RTCRtpTransceiver}} that
this method was invoked on.</p>
</li>
<li>
<p>Return
<var>transceiver</var>.{{RTCRtpTransceiver/[[HeaderExtensionsToNegotiate]]}}.</p>
</li>
</ol>
</dd>
</dl>
<dl>
<dt><dfn data-dfn-for=RTCRtpTransceiver>setHeaderExtensionsToNegotiate</dfn></dt>
<dd>
<p>Execute the following steps:</p>
<ol>
<li>
<p>Let <var>transceiver</var> be the {{RTCRtpTransceiver}} that
this method was invoked on.</p>
</li>
<li>
<p>Let <var>extensions</var> be the first argument of this
method.</p>
</li>
<li>
<p>If the size of <var>extensions</var> does not match the size of
<var>transceiver</var>.{{RTCRtpTransceiver/[[HeaderExtensionsToNegotiate]]}}
[=exception/throw=] an {{InvalidModificationError}}.
</p>
</li>
<li>
<p>For each index <var>i</var> of <var>extensions</var>, run the
following steps:</p>
<ol>
<li>
<p>Let <var>extension</var> be the <var>i</var>-th element of
<var>extensions</var>.</p>
</li>
<li>
<p>If
<var>extension</var>.{{RTCRtpHeaderExtensionCapability/uri}}
is not equal to the {{RTCRtpHeaderExtensionCapability/uri}} of
the <var>i</var>-th element of
<var>transceiver</var>.{{RTCRtpTransceiver/[[HeaderExtensionsToNegotiate]]}},
[=exception/throw=] an {{InvalidModificationError}}.</p>
</li>
<li>
<p>If
<var>extension</var>.{{RTCRtpHeaderExtensionCapability/direction}}
is not {{RTCRtpTransceiverDirection/"sendrecv"}} and
{{RTCRtpHeaderExtensionParameters/uri}} indicates a
mandatory-to-use attribute that is required to be both sent
and received, [=exception/throw=] an
{{InvalidModificationError}}.</p>
</li>
<li>
<p>If
<var>extension</var>.{{RTCRtpHeaderExtensionCapability/direction}}
is {{RTCRtpTransceiverDirection/"stopped"}} and
{{RTCRtpHeaderExtensionCapability/uri}} indicates a
mandatory-to-implement extension, [=exception/throw=] an
{{InvalidModificationError}}.</p>
</li>
<li>
<p>If necessary, restrict
<var>extension</var>.{{RTCRtpHeaderExtensionCapability/direction}}
as to not exceed the user agent's capabilities for this
extension.</p>
</li>
</ol>
</li>
<li>
<p>Set
<var>transceiver</var>.{{RTCRtpTransceiver/[[HeaderExtensionsToNegotiate]]}}
to <var>extensions</var>.</p>
</li>
</ol>
</dd>
</dl>
<dl>
<dt><dfn data-dfn-for=RTCRtpTransceiver>getNegotiatedHeaderExtensions</dfn></dt>
<dd>
<p>Execute the following steps:</p>
<ol>
<li>
<p>Let <var>transceiver</var> be the {{RTCRtpTransceiver}} that
this method was invoked on.</p>
</li>
<li>
<p>Return
<var>transceiver</var>.{{RTCRtpTransceiver/[[NegotiatedHeaderExtensions]]}}.</p>
</li>
</ol>
</dd>
</dl>
</section>
</section>
<section id="rtcrtpencodingparameters">
<h3>
RTCRtpEncodingParameters extensions
</h3>
<p>
The {{RTCRtpEncodingParameters}} dictionary is defined in
[[WEBRTC]]. This document extends that dictionary with
additional members to control audio packetization.
</p>
<pre class="idl">partial dictionary RTCRtpEncodingParameters {
RTCResolutionRestriction scaleResolutionDownTo;
unsigned long ptime;
boolean adaptivePtime = false;
};</pre>
<section id="rtcrtpencodingparameters-attributes">
<h2>Dictionary {{RTCRtpEncodingParameters}} Members</h2>
<dl data-link-for="RTCRtpEncodingParameters" data-dfn-for="RTCRtpEncodingParameters" class="dictionary-members">
<dt>
<dfn data-idl>scaleResolutionDownTo</dfn> of type <span class="idlMemberType">{{RTCResolutionRestriction}}</span>
</dt>
<dd>
<p>The maximum dimensions at which to restrict this encoding.</p>
<p>When {{scaleResolutionDownTo}} is specified, the
{{RTCRtpEncodingParameters/scaleResolutionDownBy}} value MUST be
ignored. Instead, frames are sent according to the specified
resolution restrictions: frames MUST NOT be upscaled.</p>
<p>When configuring parameters, the following validation MUST be
performed if {{scaleResolutionDownTo}} is specified on any encoding or
else {{RTCPeerConnection/addTransceiver()}} [= exception/throws =] a
newly [= exception/created =] {{OperationError}} and
{{RTCRtpSender/setParameters()}} [= reject|rejects =] with a newly
[= exception/created =] {{InvalidModificationError}}:</p>
<ul>
<li>
<p>{{scaleResolutionDownTo}} is specified on all
{{RTCRtpEncodingParameters/active}} encodings.</p>
</li>
<li>
<p>For each {{scaleResolutionDownTo}} value, both dimensions have
a value greater than 0.</p>
</li>
</ul>
</dd>
<dt>
<dfn data-idl>ptime</dfn> of type <span class="idlMemberType">unsigned long</span>
</dt>
<dd>
<p>The preferred duration of media represented by a packet in milliseconds.</p>
<div class="issue atrisk">
<p>
{{RTCRtpEncodingParameters/ptime}} was moved from [[WEBRTC]] to
this specification due to lack of support from implementers. It is
therefore marked as a feature at risk.
</p>
</div>
</dd>
<dt>
<dfn data-idl>adaptivePtime</dfn> of type <span class="idlMemberType">boolean</span>,
defaulting to <code>false</code>.
</dt>
<dd>
<p>Indicates whether this encoding MAY dynamically change
the frame length. If the value is <code>true</code>, the
<a>user agent</a> MAY use any valid frame length for any of its
frames, and MAY change this at any time. Valid values are
multiples of 10ms. If the <code>maxptime</code> attribute
(defined in [[RFC4566]] Section 6) is specified, that maximum
applies. If the value is <code>false</code>, the <a>user agent</a>
MUST use a fixed frame length.</p>
<p>If {{adaptivePtime}} is set to <code>true</code>,
{{ptime}} MUST NOT be set; otherwise,
{{InvalidModificationError}} MUST be [=exception/throw|thrown=].</p>
<p class="note">Using a longer frame length reduces the
bandwidth consumption due to overhead, but does so at the cost
of increased latency. Changing the frame length dynamically
allows the <a>user agent</a> to adapt its bandwidth allocation strategy
based on the current network conditions.</p>
</dd>
</dl>
</section>
</section>
<section id="rtcresolutionrestriction">
<h3>
The {{RTCResolutionRestriction}} dictionary.
</h3>
<pre class="idl">dictionary RTCResolutionRestriction {
unsigned long maxWidth;
unsigned long maxHeight;
};</pre>
<section id="rtcresolutionrestriction-attributes">
<h2>Dictionary {{RTCResolutionRestriction}} Members</h2>
<dl data-link-for="RTCResolutionRestriction" data-dfn-for="RTCResolutionRestriction" class="dictionary-members">
<dt>
<dfn data-idl>maxWidth</dfn> of type <span class="idlMemberType">unsigned long</span>
</dt>
<dd>
<p>The maximum width that frames will be encoded with. The
restrictions are orientation agnostic, see note below. When scaling is
applied, both dimensions of the frame MUST be downscaled using the
same factor.</p>
</dd>
<dt>
<dfn data-idl>maxHeight</dfn> of type <span class="idlMemberType">unsigned long</span>
</dt>
<dd>
<p>The maximum height that frames will be encoded with. The
restrictions are orientation agnostic, see note below. When scaling is
applied, both dimensions of the frame MUST be downscaled using the
same factor.</p>
<p class="note">
The restrictions being orientation agnostic means that they will
automatically be adjusted to the orientation of the frame being
restricted (portrait mode or landscape mode) by swapping width and
height if necessary. This means that it does not matter if 1280x720 or
720x1280 is specified, both always result in the exact same scaling
factor regardless of the orientation of the frame.
</p>
</dd>
</dl>
</section>
</section>
<section id="rtcrtpsender-setparameters-keyframe">
<h3>
{{RTCRtpSender}} {{RTCRtpSender/setParameters()}} extensions for requesting the generation of a key frame.
</h3>
<p>
The {{RTCRtpSender}}'s {{RTCRtpSender/setParameters()}} method is defined in
[[WEBRTC]]. This document extends the optional second argument to request
generation of a key frame by the encoder.
</p>
<pre class="idl">partial dictionary RTCSetParameterOptions {
sequence<RTCEncodingOptions> encodingOptions = [];
};
dictionary RTCEncodingOptions {
boolean keyFrame = false;
};</pre>
<section id="rtcrtpsender-setparameters-keyframe-setparameteroptions-idl">
<h2>Dictionary {{RTCSetParameterOptions}} Members</h2>
<p>
The {{RTCSetParameterOptions}} are extended by a sequence of {{RTCEncodingOptions}}, one for each encoding.
</p>
<dl data-link-for="RTCSetParameterOptions" data-dfn-for="RTCSetParameterOptions" class="dictionary-members">
<dt>
<dfn data-idl>encodingOptions</dfn> of type <span class="idlMemberType">sequence<{{RTCEncodingOptions}}></span>, defaulting to <code>[]</code>.
</dt>
<dd>
<p>
A sequence containing encoding options for each RTP encoding.
</p>
</dd>
</dl>
</section>
<section id="rtcrtpsender-setparameters-keyframe-encodingoptions-idl">
<h2>Dictionary {{RTCEncodingOptions}} Members</h2>
<p>
{{RTCEncodingOptions}} is the WebRTC equivalent of {{VideoEncoderEncodeOptions}} in [[WebCodecs]].
</p>
<dl data-link-for="RTCEncodingOptions" data-dfn-for="RTCEncodingOptions" class="dictionary-members">
<dt>
<dfn data-idl>keyFrame</dfn> of type <span class="idlMemberType">boolean</span>, defaulting to <code>false</code>.
</dt>
<dd>
<p>
When set to true, request that RTCRtpSender's encoder generates a keyframe for the encoding.
The semantic of this boolean is similar to the RTCP FIR message described in [RFC5104], section 3.5.1.
</p>
</dd>
</dl>
</section>
<section id="rtcrtpsender-setparameters-keyframe-interface-extensions">
<h2>{{RTCRtpSender}} {{RTCRtpSender/setParameters()}} modifications to existing procedures</h2>
<p>
In the steps to call the {{RTCRtpSender/setParameters()}} method,
let <var>parameters</var> be the method's first argument and let
<var>setParameterOptions</var> be the method's second argument.
</p>
<p>Append the following steps after the steps to validate the <var>parameters</var>:</p>
<ul>
<li>
<p>If the [=RTCRtpTransceiver/transceiver kind=] of the associated kind is `"audio"`, set
<var>setParameterOptions.encodingOptions</var> to the empty list.</p>
</li>
<li>
<p>If <var>setParameterOptions.encodingOptions</var> is not empty and
<code><var>setParameterOptions.encodingOptions</var>.length</code> is
different from <code><var>parameters</var>.encodings.length</code>,
return a promise [= rejected =] with a newly [= exception/created =] {{InvalidModificationError}}.</p>
</li>
</ul>
<p>In the steps to configure the media stack to use <var>parameters</var>, append the following step:</p>
<ul>
<li>
<p>For each <var>setParameterOptions.encodingOptions</var> indexed by <var>i</var>,
if <code><var>setParameterOptions.encodingOptions</var>[i].keyFrame</code> is set to <code>true</code>,
request that the encoder associated with <code><var>parameters</var>.encodings[i]</code> generates a key frame.</p>
</li>
</ul>
<p class="note">
{{RTCRtpSender/setParameters()}} does not wait for a key frame to be produced by the encoder.
</p>
</section>
</section>
<section id="rtcicetransport">
<h3>
{{RTCIceTransport}} extensions
</h3>
<p>
The {{RTCIceTransport}} interface is defined in [[WEBRTC]]. This document extends that interface to allow an
application to observe and affect certain actions that an <dfn>ICE agent</dfn> [[RFC5245]] performs.
</p>
<p>
The [= ICE agent =] performs connectivity checks to identify valid candidate pairs on which it is possible to send
and receive media and data. In order to conclude ICE processing, the [= ICE agent =] {{nominates}} a valid candidate
pair as the selected candidate pair. Prior to nomination, any valid candidate pair may be used to send and receive data.
Once
a candidate pair is nominated successfully, only the selected candidate pair will be used to send and receive data.
Changing
the selected candidate pair after a successful nomination requires an ICE restart.
</p>
<p>
When the [= ICE agent =] has [= formed =] a candidate pair, the [= user agent =] MUST [= queue a task =] to <dfn
id="rtcicetransport-add">add a candidate pair</dfn>:
</p>
<ol class="algorithm">
<li>
<p>
Let |connection:RTCPeerConnection| be the {{RTCPeerConnection}} object associated with this [= ICE agent =].
</p>
</li>
<li>
<p>
If <var>connection</var>.{{RTCPeerConnection/[[IsClosed]]}} is
<code>true</code>, abort these steps.
</p>
</li>
<li>
<p>
Let |candidatePair:RTCIceCandidatePair| be a new {{RTCIceCandidatePair}} dictionary
with its {{RTCIceCandidatePair/local}} and {{RTCIceCandidatePair/remote}} members
initialized to new {{RTCIceCandidate}}s representing the local and remote part of the
[= formed =] pair respectively.
</p>
</li>
<li>
<p>
Let |transport:RTCIceTransport| be the {{RTCIceTransport}} object associated with |candidatePair|.
</p>
</li>
<li>
<p>
[=Assert=]: |candidatePair| does not [= candidate pair match | match =] any
item in |transport|.{{RTCIceTransport/[[CandidatePairs]]}}
</p>
</li>
<li>
<p>
[= list/Append =] |candidatePair| to {{RTCIceTransport/[[CandidatePairs]]}}.
</p>
</li>
<li>
<p>
[= Fire an event =] named
{{RTCIceTransport/icecandidatepairadd}} at |transport|, using {{RTCIceCandidatePairEvent}},
with the {{RTCIceCandidatePairEvent/local}} and {{RTCIceCandidatePairEvent/remote}} attributes
initialized to the local and remote candidates, respectively, of |candidatePair|.
</p>
</li>
</ol>
<p>
When the [= ICE agent =] has picked a candidate pair to {{nominate}} as the selected candidate pair, the [= user
agent =]
MUST [= queue a task =] to <dfn id="rtcicetransport-nominate" data-lt="nominate the candidate pair">nominate a
candidate pair</dfn>:
</p>
<ol class="algorithm">
<li>
<p>
Let |connection:RTCPeerConnection| be the {{RTCPeerConnection}} object associated with this [= ICE agent =].
</p>
</li>
<li>
<p>
If <var>connection</var>.{{RTCPeerConnection/[[IsClosed]]}} is
<code>true</code>, abort these steps.
</p>
</li>
<li>
<p>
Let |transport:RTCIceTransport| be the {{RTCIceTransport}} object associated with this candidate pair.
</p>
</li>
<li>
<p>
Let |candidatePair:RTCIceCandidatePair| be the candidate pair which is being {{nominated}}.
</p>
</li>
<li>
<p>
Set |transport|.{{RTCIceTransport/[[ProposalPending]]}} to <code>true</code>.
</p>
</li>
<li>
<p>
Let |accepted:boolean| be the result of [= fire an event | firing an event =] named
{{RTCIceTransport/icecandidatepairnominate}} at |transport|, using {{RTCIceCandidatePairEvent}}, with the
{{Event/cancelable}} attribute initialized to <code>true</code>, and the {{RTCIceCandidatePairEvent/local}} and
{{RTCIceCandidatePairEvent/remote}} attributes initialized to the local and remote candidates, respectively, of
|candidatePair|.
</p>
</li>
<li>
<p>
Set |transport|.{{RTCIceTransport/[[ProposalPending]]}} to <code>false</code>.
</p>
</li>
<li>
<p>
If |accepted| is <code>false</code>, abort these steps and instruct the [= ICE agent =] to continue to perform connectivity checks.
</p>
</li>
<li>
<p>
Otherwise, instruct the [= ICE agent =] to {{nominate}} the candidate pair indicated by |candidatePair|.
</p>
</li>
</ol>
<p class="note">
The [= ICE agent =] will continue to send data using |candidatePair| until instructed to use another candidate pair with {{RTCIceTransport/selectCandidatePair}}.
</p>
<p>
When the [= ICE agent =] has picked a candidate pair to remove, the [= user agent =] MUST [= queue a task =] to <dfn
id="rtcicetransport-remove">remove a candidate pair</dfn>:
</p>
<ol class="algorithm">
<li>
<p>
Let |connection:RTCPeerConnection| be the {{RTCPeerConnection}} object associated with this [= ICE agent =].
</p>
</li>
<li>
<p>
If <var>connection</var>.{{RTCPeerConnection/[[IsClosed]]}} is
<code>true</code>, abort these steps.
</p>
</li>
<li>
<p>
Let |candidatePair:RTCIceCandidatePair| be the candidate pair which is being removed.
</p>
</li>
<li>
<p>
Let |transport:RTCIceTransport| be the {{RTCIceTransport}} object associated with |candidatePair|.
</p>
</li>
<li>
<p>
Let |cancelable:boolean| be <code>true</code> if the candidate pair is being removed in order to [= free =] an unused
candidate, and
<code>false</code> otherwise.
</p>
</li>
<li>
<p>
Set |transport|.{{RTCIceTransport/[[ProposalPending]]}} to <code>true</code>.
</p>
</li>
<li>
<p>
Let |accepted:boolean| be the result of [= fire an event | firing an event =] named
{{RTCIceTransport/icecandidatepairremove}} at |transport|, using {{RTCIceCandidatePairEvent}}, with the
{{Event/cancelable}} attribute initialized to <var>cancelable</var>, and the {{RTCIceCandidatePairEvent/local}}
and {{RTCIceCandidatePairEvent/remote}} attributes initialized to the local and remote candidates, respectively,
of |candidatePair|.
</p>
</li>
<li>
<p>
Set |transport|.{{RTCIceTransport/[[ProposalPending]]}} to <code>false</code>.
</p>
</li>
<li>
<p>
If |accepted| is <code>false</code>, instruct the [= ICE agent =] to not remove the candidate pair indicated by
|candidatePair|, and instead continue to send and respond to ICE connectivity checks on the candidate pair as
before.
</p>
</li>
<li>
<p>
Otherwise (if |accepted| is <code>true</code>), run the following steps:
</p>
<ol>
<li>
<p>
[= list/Remove =] |candidatePair| from |transport|.{{RTCIceTransport/[[CandidatePairs]]}}.
</p>
</li>
<li>
<p>
Instruct the [= ICE agent =] to remove the candidate pair indicated by |candidatePair|.
</p>
</li>
</ol>
</li>
</ol>
<p>
The {{RTCIceTransport}} object is extended by adding the following internal slots:
</p>
<ul>
<li>
<dfn data-dfn-for="RTCIceTransport">[[\CandidatePairs]]</dfn> initialized to an empty list.
</li>
<li>
<dfn data-dfn-for="RTCIceTransport">[[\ProposalPending]]</dfn> initialized to <code>false</code>.
</li>
</ul>
<pre class="idl">
partial interface RTCIceTransport {
attribute EventHandler onicecandidatepairadd;
attribute EventHandler onicecandidatepairremove;
attribute EventHandler onicecandidatepairnominate;
Promise<undefined> selectCandidatePair(RTCIceCandidatePair candidatePair);
Promise<undefined> removeCandidatePair(RTCIceCandidatePair candidatePair);
};</pre>
<section id="rtcicetransport-attributes">
<h2>Attributes</h2>
<dl data-link-for="RTCIceTransport" data-dfn-for="RTCIceTransport" class="attributes">
<dt>
<dfn>onicecandidatepairadd</dfn> of type <span class="idlAttrType">{{EventHandler}}</span>
</dt>
<dd>
<p>
The event type of this event handler is {{icecandidatepairadd}}, and is fired as part of
the [= add a candidate pair =] algorithm.
</p>
</dd>
<dt>
<dfn>onicecandidatepairremove</dfn> of type <span class="idlAttrType">{{EventHandler}}</span>
</dt>
<dd>
<p>
The event type of this event handler is {{icecandidatepairremove}}, and is fired as part of
the [= remove a candidate pair =] algorithm.
</p>
</dd>
<dt>
<dfn>onicecandidatepairnominate</dfn> of type <span class="idlAttrType">{{EventHandler}}</span>
</dt>
<dd>
<p>
The event type of this event handler is {{icecandidatepairnominate}}, and is fired as part
of the [= nominate a candidate pair =] algorithm.
</p>
</dd>
</dl>
</section>
<section id="rtcicetransport-methods">
<h2>Methods</h2>
<dl data-link-for="RTCIceTransport" data-dfn-for="RTCIceTransport" class="methods">
<dt>
<dfn>selectCandidatePair</dfn>
</dt>
<dd>
<p>
The {{selectCandidatePair}} method attempts to select a different candidate pair to send data
over. If successful, data will be sent on the provided candidate pair.
It is meant to be called after the application defers the {{nomination}} of a candidate pair
by cancelling the {{RTCIceTransport/icecandidatepairnominate}} event.
<p>
<p>
When this method is invoked, the [= user agent =] MUST run the following steps:
</p>
<ol class="algorithm">
<li>
<p>
Let |connection:RTCPeerConnection| be the {{RTCPeerConnection}} object associated with [=this=].
</p>
</li>
<li>
<p>
If <var>connection</var>.{{RTCPeerConnection/[[IsClosed]]}} is
<code>true</code>, [= exception/throw =] an {{InvalidStateError}}.
</p>
</li>
<li>
<p>
If [=this=].{{RTCIceTransport/[[ProposalPending]]}} is <code>true</code>, [= exception/throw =] an {{InvalidStateError}}.
</p>
</li>
<li>
<p>
If [=this=].{{RTCIceTransport/[[IceTransportState]]}} is either of
{{RTCIceTransportState/"new"}}, {{RTCIceTransportState/"failed"}} or {{RTCIceTransportState/"closed"}}, [=
exception/throw =]
an {{InvalidStateError}}.
</p>
</li>
<li>
<p>
Let |candidatePair:RTCIceCandidatePair| be the method's first argument.
</p>
</li>
<li>
<p>
If |candidatePair| does not [= candidate pair match | match =] any item in [=this=].
{{RTCIceTransport/[[CandidatePairs]]}}, [= exception/throw =] a {{NotFoundError}}.
</p>
</li>
<li>
<p>
Let |p:Promise| be a new promise.
</p>
</li>
<li>
<p>
In parallel, instruct the [= ICE agent =] to use |candidatePair| to send data.
</p>
<ol>
<li>
<p>
When the [= ICE agent =] has completed selecting |candidatePair|, [= queue a task =] to run the following steps:
</p>
<ol>
<li>
<p>
Run the [=RTCIceTransport/change the selected candidate pair and state=] steps to update [=this=].{{RTCIceTransport/[[SelectedCandidatePair]]}} and [=this=].{{RTCIceTransport/[[IceTransportState]]}} as necessary and fire any associated events.
</p>
</li>
<li>
<p>
Resolve <var>p</var>.
</p>
</li>
</ol>
</li>
</ol>
</li>
<li>
<p>
Return <var>p</var>.
</p>
</li>
</ol>
<p class="note">
After changing the selected candidate pair, the controlling [= ICE agent =] may attempt to [= nominate the candidate
pair =] as
well to conclude ICE processing. The application may cancel the nomination to allow further changes to the selected
candidate pair.
</p>
</dd>
<dt>
<dfn>removeCandidatePair</dfn>
</dt>
<dd>
<p>
The {{removeCandidatePair}} method removes the provided candidate pair. The [= ICE agent =] will stop sending and
responding to ICE connectivity checks on the removed candidate pair, and it can no longer be used to send data for this
transport. This method is meant to be called when the application wants to allow the [= ICE agent =] to [= free =]
candidates that it no longer needs.
</p>
<p>
When this method is invoked, the [= user agent =] MUST run the following steps:
</p>
<ol class="algorithm">
<li>
<p>
Let |connection:RTCPeerConnection| be the {{RTCPeerConnection}} object associated with [= this =].
</p>
</li>
<li>
<p>
If <var>connection</var>.{{RTCPeerConnection/[[IsClosed]]}} is
<code>true</code>, [= exception/throw =] an
{{InvalidStateError}}.
</p>
</li>
<li>
<p>
If [= this =].{{RTCIceTransport/[[ProposalPending]]}} is <code>true</code>, [= exception/throw =] an
{{InvalidStateError}}.
</p>
</li>
<li>
<p>
If [= this =].{{RTCIceTransport/[[IceTransportState]]}} is either of {{RTCIceTransportState/"new"}}, {{RTCIceTransportState/"failed"}} or {{RTCIceTransportState/"closed"}}, [= exception/throw =] an {{InvalidStateError}}.
</p>
</li>
<li>
<p>
Let |candidatePair:RTCIceCandidatePair| be the method's first argument.
</p>
</li>
<li>
<p>
If |candidatePair| does not [= candidate pair match | match =] any item in [=this=].
{{RTCIceTransport/[[CandidatePairs]]}}, [= exception/throw =] a {{NotFoundError}}.
</p>
</li>
<li>
<p>
[= list/Remove =] the item in
[=this=].{{RTCIceTransport/[[CandidatePairs]]}} that
[= candidate pair match | matches =] |candidatePair|.
</p>
</li>
<li>
<p>
Let |p:Promise| be a new promise.
</p>
</li>
<li>
<p>
In parallel, instruct the [= ICE agent =] to remove the candidate pair indicated by <var>candidatePair</var>.
</p>
<ol>
<li>
<p>
When the [= ICE agent =] has completed the removal, [= queue a task =] to run the following steps:
</p>
<ol>
<li>
<p>
[= Fire an event =] named {{RTCIceTransport/icecandidatepairremove}} at |transport|, using {{RTCIceCandidatePairEvent}}, with the {{Event/cancelable}} attribute initialized to <code>false</code>, and the {{RTCIceCandidatePairEvent/local}} and {{RTCIceCandidatePairEvent/remote}} attributes initialized to the {{RTCIceCandidatePair/local}} and {{RTCIceCandidatePair/remote}} candidates, respectively, of <var>candidatePair</var>.
</p>
</li>
<li>
<p>
Resolve <var>p</var>.
</p>
</li>
</ol>
</li>
</ol>
</li>
<li>
<p>
Return <var>p</var>.
</p>
</li>
</ol>
</dd>
</dl>
</section>
<section>
<h2>
<dfn>RTCIceCandidatePairEvent</dfn>
</h2>