forked from w3c/webrtc-stats
-
Notifications
You must be signed in to change notification settings - Fork 0
/
webrtc-stats.html
4066 lines (4046 loc) · 179 KB
/
webrtc-stats.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>
<head>
<meta charset="utf-8">
<link href="webrtc-stats.css" rel="stylesheet" type="text/css">
<title>
Identifiers for WebRTC's Statistics API
</title>
<script class="remove" src="https://www.w3.org/Tools/respec/respec-w3c">
</script>
<script class="remove" src="webrtc-stats.js">
</script>
<!-- TODO Redundant since webidl2.js is already loaded in ReSpec, but not sure how to access it -->
<script class="remove" src="webidl2.js"></script>
</head>
<body>
<section id="abstract">
<p>
This document defines a set of WebIDL objects that allow access to the statistical
information about a {{RTCPeerConnection}}.
</p>
<p>
These objects are returned from the getStats API that is specified in [[WEBRTC]].
</p>
</section>
<section id="sotd">
<!-- Status of the draft -->
<p>Since the previous publication as a Candidate Recommendation, the stats objects were significantly reorganized to better match the underlying data sources. In addition, the <code>networkType</code> property was deprecated for preserving privacy, and the <code>statsended</code> event was removed as no longer needed.</p>
</section><!-- NB: [[!..]] normative refs, [[..]] informative refs-->
<!-- based on the wiki page https://www.w3.org/2011/04/webrtc/wiki/Stats -->
<section class="informative">
<h2>
Introduction
</h2>
<p>
Audio, video, or data packets transmitted over a peer-connection can be lost, and
experience varying amounts of network delay. A web application implementing WebRTC expects
to monitor the performance of the underlying network and media pipeline.
</p>
<p>
This document defines the statistic identifiers used by the web application to extract
metrics from the user agent.
</p>
</section>
<section id="conformance">
<p>
This specification defines the conformance criteria that applies to a single product: the
<em>user agent</em>.
</p>
<p>
Implementations that use ECMAScript to implement the objects defined in this specification
MUST implement them in a manner consistent with the
ECMAScript Bindings defined in the Web IDL specification [[WEBIDL]], as this document uses
that specification and terminology.
</p>
<p>
This specification does not define what objects a conforming implementation should
generate. Specifications that refer to this specification have the need to specify
conformance. They should put in their document text like this (EXAMPLE ONLY):
</p>
<ul>
<li>An implementation MUST support generating statistics for the type
{{RTCInboundRtpStreamStats}}, with members {{RTCReceivedRtpStreamStats/packetsReceived}}, {{RTCInboundRtpStreamStats/bytesReceived}}, {{RTCReceivedRtpStreamStats/packetsLost}}, and
{{RTCReceivedRtpStreamStats/jitter}}.
</li>
<li>It MUST support generating statistics for the type {{RTCOutboundRtpStreamStats}}, with
members {{RTCSentRtpStreamStats/packetsSent}}, {{RTCSentRtpStreamStats/bytesSent}}.
</li>
<li>For all subclasses of {{RTCRtpStreamStats}}, it MUST include {{RTCRtpStreamStats/ssrc}} and {{RTCRtpStreamStats/kind}}. When stats
exist for both sides of a connection, in the form of an {{RTCStatsType/"inbound-rtp"}} / {{RTCStatsType/"remote-outbound-rtp"}}
pair or an {{RTCStatsType/"outbound-rtp"}} / {{RTCStatsType/"remote-inbound-rtp"}} pair, the members {{RTCOutboundRtpStreamStats/remoteId}} and {{RTCRemoteOutboundRtpStreamStats/localId}} MUST
also be present.
</li>
<li>It MAY support generating other stats.
</li>
</ul>
</section>
<section>
<h2>
Terminology
</h2>
<p>
The terms {{RTCPeerConnection}}, {{RTCDataChannel}},
{{RTCDtlsTransport}}, {{RTCDtlsTransportState}}, {{RTCIceTransport}},
{{RTCIceRole}}, {{RTCIceTransportState}}, {{RTCDataChannelState}},
{{RTCIceCandidateType}}, {{RTCStats}}, {{RTCCertificate}} are defined in [[!WEBRTC]].
</p>
<p><dfn class=fixme data-idl>RTCPriorityType</dfn> is defined in [[WEBRTC-PRIORITY]].</p>
<p>
The term <dfn><a href="https://datatracker.ietf.org/doc/html/rfc7656#section-2.1.10">RTP stream</a></dfn> is defined in [[RFC7656]].
</p>
<p>
The terms <dfn data-lt="SSRC"><a href="https://datatracker.ietf.org/doc/html/rfc3550#section-3">Synchronization Source</a></dfn> (SSRC),
<dfn data-lt="Sender Report|SR|RTCP SR"><a href="https://datatracker.ietf.org/doc/html/rfc3550#section-6.4.1">RTCP Sender Report</a></dfn> (SR),
<dfn data-lt="Receiver Report|RR|RTCP RR"><a href="https://datatracker.ietf.org/doc/html/rfc3550#section-6.4.2">RTCP Receiver Report</a></dfn> (RR) are defined in [[RFC3550]].
</p>
<p>The term <dfn data-lt="Extended Report|XR"><a href="https://datatracker.ietf.org/doc/html/rfc3611">RTCP Extended Report</a></dfn> (XR) is defined in [[RFC3611]].</p>
<p>An <dfn>audio sample</dfn> refers to having a sample in any channel of an audio track - if multiple audio channels are used, metrics based on samples do not increment at a higher rate, simultaneously having samples in multiple channels counts as a single sample.</p>
</section>
<section>
<h2>
Basic concepts
</h2>
<p>
The basic object of the stats model is the [= stats object =]. The following terms are
defined to describe it:
</p>
<dl>
<dt>
<dfn data-export>Monitored object</dfn>
</dt>
<dd>
<p>
An internal object that keeps a set of data values. Most monitored objects are object
defined in the WebRTC API; they may be thought of as being internal properties of those
objects.
</p>
</dd>
<dt>
<dfn data-export>Stats object</dfn>
</dt>
<dd>
This is a set of values, copied out from a monitored object at a specific moment in time.
It is returned as a WebIDL dictionary through the getStats API call.
</dd>
<dt>
<dfn data-export>Stats object reference</dfn>
</dt>
<dd>
<p>
A monitored object has a stable identifier <var>id</var>, which is reflected in all stats
objects produced from the monitored object. Stats objects may contain references to
other stats objects using this <var>id</var> value. In a [= stats object =], these references
are represented by a {{DOMString}} containing <var>id</var> value of the referenced stats object.
</p>
<p>
All stats object references have type {{DOMString}} and member names ending in <code>Id</code>, or
they have type <code>sequence<{{DOMString}}></code> and member names ending in <code>Ids</code>.
</p>
</dd>
<dt>
<dfn data-export>Stats value</dfn>
</dt>
<dd>
Refers to a single value within a stats object.
</dd>
</dl>
<p>
A monitored object changes the values it contains continuously over its lifetime, but is
never visible through the getStats API call. A stats object, once returned, never changes.
</p>
<p>
The stats API is defined in [[!WEBRTC]]. It is defined to return a collection of [= stats object =]s, each of which is a dictionary inheriting directly or indirectly from the
<dfn class="informative" data-noexport>RTCStats</dfn> dictionary.
This API is normatively defined in [[!WEBRTC]], but is
reproduced here for ease of reference.
</p>
<pre class="idl informative">
dictionary RTCStats {
required DOMHighResTimeStamp timestamp;
required RTCStatsType type;
required DOMString id;
};
</pre>
<p>
Timestamps are expressed with {{DOMHighResTimeStamp}} [[HIGHRES-TIME]], and are defined as
{{Performance.timeOrigin}} +
{{Performance.now()}} at the time the information is
collected.
</p>
<section>
<h3>
Guidelines for design of stats objects
</h3>
<p>
When introducing a new stats object, the following principles should be followed:
</p>
<ul>
<li>An {{RTCStats}} object should correspond to an object defined in the specification it
supports.
</li>
<li>The object MUST define a new value in the {{RTCStatsType}} enum, and MUST define the
syntax of the [= stats object =] it returns either by reference to an existing
sub-dictionary of {{RTCStats}} or by defining a new sub-dictionary of {{RTCStats}}.
</li>
<li>All members of the new object need to have definitions that make them consistently
implementable. References to other specifications are a good way of doing this.
</li>
<li>All members need to have defined behavior for what happens before the thing it counts
happens, or when the information it's supposed to show is not available. Usually, this
will be "start at zero" or "do not populate the value".
</li>
</ul>
<p>
The new members of the stats dictionary need to be named according to standard practice
(camelCase), as per [[API-DESIGN-PRINCIPLES]].
</p>
<p>
Names ending in <code>Id</code> (such as {{RTCRtpStreamStats/transportId}}) are always a [= stats object reference =];
names ending in <code>Ids</code> are always of type sequence<{{DOMString}}>, where
each {{DOMString}} is a [= stats object reference =].
</p>
<p>
If the natural name for a stats value would end in <code>id</code> (such as when the stats value is
an in-protocol identifier for the monitored object), the recommended practice is to let
the name end in <code>identifier</code>, such as {{RTCDataChannelStats/dataChannelIdentifier}}.
</p>
<p>
Stats are sampled by Javascript. In general, an application will not have overall control
over how often stats are sampled, and the implementation cannot know what the intended
use of the stats is. There is, by design, no control surface for the application to
influence how stats are generated.
</p>
<p>
Therefore, letting the implementation compute "average" rates is not a good idea, since
that implies some averaging time interval that can't be set beforehand. Instead, the
recommended approach is to count the number of measurements of a value and sum the
measurements given even if the sum is meaningless in itself; the JS application can then
compute averages over any desired time interval by calling getStats() twice, taking the
difference of the two sums and dividing by the difference of the two counts.
</p>
<p>
For stats that are measured against time, such as byte counts, no separate counter is
needed; one can instead divide by the difference in the timestamps.
</p>
</section>
<section>
<h3>
Guidelines for implementing stats objects
</h3>
<p>
When implementing stats objects, the following guidelines should be adhered to:
</p>
<ul>
<li>When a feature is not implemented on the platform, omit the dictionary member that is
tracking usage of the feature.
</li>
<li>When a feature is not applicable to an instance of an object (for example {{RTCInboundRtpStreamStats/audioLevel}}
on a video stream), it shall not [= map/exist =]. Do NOT report a count of zero, -1 or "empty string".
</li>
<li>When a feature is an instantaneous measure and it has not yet been
sampled, it shall not [= map/exist =].</li>
<li>When a feature is a cumulative measure and it has not been sampled yet,
but is likely to increment in the future, report a
count of zero. This allows subtraction of such features without additional checks for existence.
</li>
</ul>
</section>
<section>
<h3>
Lifetime considerations for monitored objects
</h3>
<p>
The object descriptions will say what the lifetime of a [= monitored object =] from the
perspective of stats is. When a monitored object is <dfn>deleted</dfn>, it no longer appears in
stats; until this happens, it will appear. This may or may not correspond to the actual
lifetime of an object in an implementation; what matters for this specification is what
appears in stats.
</p>
<p>
If a monitored object can only exist in a few instances over the lifetime of a
{{RTCPeerConnection}}, it may be simplest to consider it "eternal" and never delete it from
the set of objects reported on in stats. This type of object will remain visible until
the {{RTCPeerConnection}} is no longer available; it is also visible in {{RTCPeerConnection/getStats()}} after
pc.close(). This is the default when no lifetime is mentioned in its specification.
</p>
<p>
Objects that might exist in many instances over time should have a defined time at which
they are [= deleted =], at which time they stop appearing in subsequent calls to {{RTCPeerConnection/getStats()}}.
When an object is [= deleted =], we can guarantee that no subsequent {{RTCPeerConnection/getStats()}} call will
contain a [= stats object reference =] that references the deleted object. We also
guarantee that the stats id of the deleted object will never be reused for another
object. This ensures that an application that collects [= stats object =]s for deleted
[= monitored object =]s will always be able to uniquely identify the object pointed to
in the result of any {{RTCPeerConnection/getStats()}} call.
</p>
</section>
<section>
<h3>
Guidelines for {{RTCPeerConnection/getStats()}} results caching/throttling
</h3>
<p>
A call to {{RTCPeerConnection/getStats()}} touches many components of WebRTC and may take significant time to
execute. The implementation may or may not utilize caching or throttling of {{RTCPeerConnection/getStats()}}
calls for performance benefits, however any implementation must adhere to the following:
</p>
<p>
When the state of the {{RTCPeerConnection}} visibly changes as a result of an API call, a
promise resolving or an event firing, subsequent new {{RTCPeerConnection/getStats()}} calls must return
up-to-date dictionaries for the affected objects.
</p>
<p>
When a stats object is [= deleted =], subsequent {{RTCPeerConnection/getStats()}} calls MUST NOT return stats
for that [= monitored object =].
</p>
</section>
</section><!-- VS: getStats() remains in base spec! -->
<section>
<h2>
Maintenance procedures for stats object types
</h2>
<section>
<h3>
Adding new stats objects
</h3>
<p class="status-ED">
This document, in its editors' draft form, serves as the repository for the currently
defined set of stats object types including proposals for new standard types.
</p>
<p class="status-not-ED">
This document specifies the interoperable stats object types. Proposals for new object
types may be made in <a href="https://w3c.github.io/webrtc-stats/">the editors draft
maintained on GitHub</a>. New standard types may appear in future revisions of the W3C
Recommendation.
</p>
<p>
If a need for a new stats object type or stats value within a stats object is found, an
issue should be <a href="https://github.com/w3c/webrtc-stats/issues">raised on
Github</a>, and a review process will decide on whether the stat should be added to the
editors draft or not.
</p>
<p>
A pull request for a change to the editors draft may serve as guidance for the
discussion, but the eventual merge is dependent on the review process.
</p>
<p>
While the WebRTC WG exists, it will serve as the review body; once it has disbanded, the
W3C will have to establish appropriate review.
</p>
<p>
The level of review sought is that of the IETF process' "expert review", as defined in
[[RFC5226]] section 4.1. The documentation needed includes the names of the new stats,
their data types, and the definitions they are based on, specified to a level that allows
interoperable implementation. The specification may consist of references to other
documents.
</p>
<p>
Another specification that wishes to refer to a specific version (for instance for
conformance) should refer to a dated version; these will be produced regularly when
updates happen.
</p>
</section>
</section>
<section>
<h2>
Procedures for mitigating privacy concerns
</h2>
<p class="fingerprint">
The WebRTC's Statistics API exposes information about the system,
including hardware capabilities and network characteristics. To limit
the finger printing surface imposed by this API, some metrics are only
exposed if allowed by the algorithms in this section.
</p>
<section>
<h3>
Limiting exposure of hardware capabilities
</h3>
<p>
To avoid passive fingerprinting, hardware capabilities should only be
exposed in capturing contexts. This is tested using the algorithm
below.
</p>
<p>
To <dfn data-lt="exposing hardware is allowed">check if hardware
exposure is allowed</dfn>, run the following steps:
<ol>
<li>
<p>
If the <a href="https://w3c.github.io/mediacapture-main/#context-capturing-state">
context capturing state</a> is true, return true.
</p>
</li>
<li>
<p>
Otherwise return false.
</p>
</li>
</ol>
</p>
</section>
</section>
<section id="rtctatstype-*">
<h2>
{{RTCStatsType}}
</h2>
<p>
The {{RTCStats/type}} member, of type {{RTCStatsType}}, indicates the type of the
object that the {{RTCStats}} object represents. An object with a given {{RTCStats/type}} can
have only one IDL dictionary type, but multiple {{RTCStats/type}} values may indicate the same IDL
dictionary type; for example, {{RTCStatsType/"local-candidate"}} and {{RTCStatsType/"remote-candidate"}} both use the IDL
dictionary type {{RTCIceCandidateStats}}.
</p>
<p>
This specification is normative for the allowed values of {{RTCStatsType}}.
</p>
<section id="rtcstatstype-str*">
<h3>
<dfn>RTCStatsType</dfn> enum
</h3>
<pre class="idl">
enum RTCStatsType {
"codec",
"inbound-rtp",
"outbound-rtp",
"remote-inbound-rtp",
"remote-outbound-rtp",
"media-source",
"media-playout",
"peer-connection",
"data-channel",
"transport",
"candidate-pair",
"local-candidate",
"remote-candidate",
"certificate"
};
</pre>
<p>
The following strings are valid values for {{RTCStatsType}}:
</p>
<dl data-link-for="RTCStatsType" data-dfn-for="RTCStatsType">
<dt>
<dfn>codec</dfn>
</dt>
<dd>
<p>
Statistics for a codec that is currently being used by <a>RTP stream</a>s being sent or
received by this {{RTCPeerConnection}} object. It is accessed by the
{{RTCCodecStats}}.
</p>
</dd>
<dt>
<dfn>inbound-rtp</dfn>
</dt>
<dd>
<p>
Statistics for an inbound <a>RTP stream</a> that is currently received with this
{{RTCPeerConnection}} object. It is accessed by the
{{RTCInboundRtpStreamStats}}.
</p>
<p>
RTX streams do not show up as separate
{{RTCInboundRtpStreamStats}} objects but affect the {{RTCReceivedRtpStreamStats/packetsReceived}},
{{RTCInboundRtpStreamStats/bytesReceived}}, {{RTCInboundRtpStreamStats/retransmittedPacketsReceived}}
and {{RTCInboundRtpStreamStats/retransmittedBytesReceived}} counters of the relevant
{{RTCInboundRtpStreamStats}} objects.
</p>
<p>
FEC streams do not show up as separate
{{RTCInboundRtpStreamStats}} objects but affect the {{RTCReceivedRtpStreamStats/packetsReceived}},
{{RTCInboundRtpStreamStats/bytesReceived}}, {{RTCInboundRtpStreamStats/fecPacketsReceived}}
and {{RTCInboundRtpStreamStats/fecBytesReceived}} counters of the relevant
{{RTCInboundRtpStreamStats}} objects.
</p>
</dd>
<dt>
<dfn>outbound-rtp</dfn>
</dt>
<dd>
<p>
Statistics for an outbound <a>RTP stream</a> that is currently sent with this
{{RTCPeerConnection}} object. It is accessed by the
{{RTCOutboundRtpStreamStats}}.
</p>
<p>
When there are multiple <a>RTP stream</a>s connected to the same sender due to using
simulcast, there will be one {{RTCOutboundRtpStreamStats}} per <a>RTP stream</a>,
with distinct values of the {{RTCRtpStreamStats/ssrc}} member. RTX streams do not show up as separate
{{RTCOutboundRtpStreamStats}} objects but affect the {{RTCSentRtpStreamStats/packetsSent}},
{{RTCSentRtpStreamStats/bytesSent}}, {{RTCOutboundRtpStreamStats/retransmittedPacketsSent}}
and {{RTCOutboundRtpStreamStats/retransmittedBytesSent}} counters of the relevant
{{RTCOutboundRtpStreamStats}} objects.
</p>
</dd>
<dt>
<dfn>remote-inbound-rtp</dfn>
</dt>
<dd>
<p>
Statistics for the remote endpoint's inbound <a>RTP stream</a> corresponding to an outbound
stream that is currently sent with this {{RTCPeerConnection}} object. It is
measured at the remote endpoint and reported in an <a>RTCP Receiver Report</a> (RR) or <a>RTCP
Extended Report</a> (XR). It is accessed by the
{{RTCRemoteInboundRtpStreamStats}}.
</p>
</dd>
<dt>
<dfn>remote-outbound-rtp</dfn>
</dt>
<dd>
<p>
Statistics for the remote endpoint's outbound <a>RTP stream</a> corresponding to an inbound
stream that is currently received with this {{RTCPeerConnection}} object. It
is measured at the remote endpoint and reported in an <a>RTCP Sender Report</a> (SR). It is
accessed by the {{RTCRemoteOutboundRtpStreamStats}}.
</p>
</dd>
<dt>
<dfn>media-source</dfn>
</dt>
<dd>
<p>
Statistics for the media produced by a {{MediaStreamTrack}} that is
currently attached to an {{RTCRtpSender}}. This reflects the media that is
fed to the encoder; after <code class=gum>getUserMedia()</code> constraints have been applied
(i.e. not the raw media produced by the camera). It is either an
{{RTCAudioSourceStats}} or {{RTCVideoSourceStats}}
depending on its <code class=gum>kind</code>.
</p>
</dd>
<dt>
<dfn>media-playout</dfn>
</dt>
<dd>
<p>
Statistics related to audio playout. It is accessed by the
{{RTCAudioPlayoutStats}}.
</p>
</dd>
<dt>
<dfn>peer-connection</dfn>
</dt>
<dd>
<p>
Statistics related to the {{RTCPeerConnection}} object. It is accessed by
the {{RTCPeerConnectionStats}}.
</p>
</dd>
<dt>
<dfn>data-channel</dfn>
</dt>
<dd>
<p>
Statistics related to each {{RTCDataChannel}} id. It is accessed by the
{{RTCDataChannelStats}}.
</p>
</dd>
<dt>
<dfn>transport</dfn>
</dt>
<dd>
<p>
Transport statistics related to the {{RTCPeerConnection}} object. It is
accessed by the {{RTCTransportStats}}.
</p>
</dd>
<dt>
<dfn>candidate-pair</dfn>
</dt>
<dd>
<p>
ICE candidate pair statistics related to the {{RTCIceTransport}} objects. It
is accessed by the {{RTCIceCandidatePairStats}}.
</p>
<p>
A candidate pair that is not the current pair for a transport is [= deleted =] when the
{{RTCIceTransport}} does an ICE restart, at the time the state changes to {{RTCIceTransportState/"new"}}. The
candidate pair that is the current pair for a transport is [= deleted =] after an ICE
restart when the {{RTCIceTransport}} switches to using a candidate pair generated from
the new candidates; this time doesn't correspond to any other externally observable
event.
</p>
</dd>
<dt>
<dfn>local-candidate</dfn>
</dt>
<dd>
<p>
ICE local candidate statistics related to the {{RTCIceTransport}} objects.
It is accessed by the {{RTCIceCandidateStats}} for the local
candidate.
</p>
<p>
A local candidate is [= deleted =] when the {{RTCIceTransport}} does an ICE restart, and the
candidate is no longer a member of any non-deleted candidate pair.
</p>
</dd>
<dt>
<dfn>remote-candidate</dfn>
</dt>
<dd>
<p>
ICE remote candidate statistics related to the {{RTCIceTransport}} objects.
It is accessed by the {{RTCIceCandidateStats}} for the remote
candidate.
</p>
<p>
A remote candidate is [= deleted =] when the {{RTCIceTransport}} does an ICE restart, and the
candidate is no longer a member of any non-deleted candidate pair.
</p>
</dd>
<dt>
<dfn>certificate</dfn>
</dt>
<dd>
<p>
Information about a certificate used by an {{RTCIceTransport}}. It is accessed by the
{{RTCCertificateStats}}.
</p>
</dd>
</dl>
</section>
</section>
<section>
<h2>
Stats dictionaries
</h2>
<section>
<h3>
The RTP statistics hierarchy
</h3>
<p>
The dictionaries for RTP statistics are structured as a hierarchy, so that those stats
that make sense in many different contexts are represented just once in IDL.
</p>
<p>
The metrics exposed here correspond to local measurements and those reported by RTCP packets.
Compound RTCP packets contain multiple RTCP report blocks, such as <a>Sender Report</a> (SR) and
<a>Receiver Report</a> (RR) whereas a non-compound RTCP packets may contain just a single
RTCP SR or RR block.
</p>
<p>
The lifetime of all RTP [= monitored object =]s starts when the <a>RTP stream</a> is first
used: When the first RTP packet is sent or received on the <a>SSRC</a> it represents, or when
the first RTCP packet is sent or received that refers to the <a>SSRC</a> of the <a>RTP stream</a>.
</p>
<p>
RTP monitored objects are deleted when the corresponding RTP sender or
RTP receiver is reconfigured to remove the corresponding RTP stream.
This happens for the old SSRC when the {{RTCRtpStreamStats/ssrc}}
changes, a simulcast layer is dropped or the {{RTCRtpTransceiver}}'s
{{RTCRtpTransceiver/currentDirection}} becomes <code>"stopped"</code>.
The monitored object is <i>not</i> deleted if the transceiver is made
<code>"inactive"</code> or if the encoding's
{{RTCRtpEncodingParameters/active}} parameter is set to
<code>false</code>. If an SSRC is recycled after a deletion event has
happened, this is considered a new RTP monitored object and the new
RTP stream stats will have reset counters and a new ID.
</p>
<p>
For a given RTP stats object, its total counters must always increase,
but due to changes in SSRC, simulast layers dropping or transceivers
stopping, an RTP stats object can be deleted and/or replaced by a new
RTP stats object. The caller will need to be aware of this when aggregating
packet counters accross multiple RTP stats objects (the aggregates may
decrease due to deletions).
</p>
<pre class="example highlight">
An RTCRtpSender is sending two layers of simulcast (on SSRC=111 and
SSRC=222). Two "outbound-rtp" stats objects are observed, one with
SSRC=111, and the other with SSRC=222. Both objects' packet counters are
increasing.
One layer is inactivated using RTCRtpSender.setParameters(). While
this pauses one of the layers (its packet counter freezes), the RTP
monitored objects are not deleted. The RTCRtpTransceiver is negotiated
as "inactive" and the RTP monitored objects are still not deleted.
When the RTCRtpTransceiver becomes "sendonly" again, the same
"outbound-rtp" objects continue to be used.
Later, RTCRtpTransceiver.stop() is called. The "outbound-rtp" objects
still exist but their packet counters have frozen. Renegotiation
happens and the transceiver.currentDirection becomes "stopped", now
both "outbound-rtp" objects have been deleted.
</pre>
<p>
The hierarchy is as follows:
</p>
<p>
{{RTCRtpStreamStats}}: Stats that apply to any end of any <a>RTP stream</a>
</p>
<ul>
<li>
<p>
{{RTCReceivedRtpStreamStats}}: Stats measured at the receiving end of an RTP
stream, known either because they're measured locally or transmitted via an RTCP
<a>Receiver Report</a> (RR) or <a>Extended Report</a> (XR) block.
</p>
<ul>
<li>
<p>
{{RTCInboundRtpStreamStats}}: Stats that can only be measured at the local
receiving end of an <a>RTP stream</a>.
</p>
</li>
<li>
<p>
{{RTCRemoteInboundRtpStreamStats}}: Stats relevant to the remote receiving end
of an <a>RTP stream</a> - usually computed by combining local data with data received
via an RTCP <a>RR</a> or <a>XR</a> block.
</p>
</li>
</ul>
</li>
<li>
<p>
{{RTCSentRtpStreamStats}}: Stats measured at the sending end of an <a>RTP stream</a>,
known either because they're measured locally or because they're received via RTCP,
usually in an <a>RTCP Sender Report</a> (SR).
</p>
<ul>
<li>
{{RTCOutboundRtpStreamStats}}: Stats measured locally.
</li>
<li>
<p>
{{RTCRemoteOutboundRtpStreamStats}}: Stats relevant to the remote sending end
of an <a>RTP stream</a>, usually computed based on an <a>RTCP SR</a>.
</p>
</li>
</ul>
</li>
</ul>
</section>
<section id="streamstats-dict*">
<h3>
<dfn>RTCRtpStreamStats</dfn> dictionary
</h3>
<div>
<pre class="idl">dictionary RTCRtpStreamStats : RTCStats {
required unsigned long ssrc;
required DOMString kind;
DOMString transportId;
DOMString codecId;
};</pre>
<section>
<h2>
Dictionary {{RTCRtpStreamStats}} Members
</h2>
<dl data-link-for="RTCRtpStreamStats" data-dfn-for="RTCRtpStreamStats" class=
"dictionary-members">
<dt>
<dfn>ssrc</dfn> of type <span class="idlMemberType">unsigned
long</span>
</dt>
<dd>
<p>
The synchronization source (SSRC) identifier is an unsigned integer value per [[RFC3550]]
used to identify the stream of RTP packets that this stats object is describing.
</p>
<p>
For outbound and inbound local, SSRC describes the stats for the RTP stream that were
sent and received, respectively by those endpoints.
For the remote inbound and remote outbound, SSRC describes the stats for the RTP stream
that were received by and sent to the remote endpoint.
</p>
</dd>
<dt>
<dfn>kind</dfn> of type <span class="idlMemberType">DOMString</span>
</dt>
<dd>
<p>
Either "<code class=gum>audio</code>" or "<code class=gum>video</code>". This
MUST match the <code class=gum>kind</code> attribute of the related {{MediaStreamTrack}}.
</p>
</dd>
<dt>
<dfn>transportId</dfn> of type <span class=
"idlMemberType">DOMString</span>
</dt>
<dd>
<p>
It is a unique identifier that is associated to the object that was inspected to
produce the {{RTCTransportStats}} associated with this <a>RTP stream</a>.
</p>
</dd>
<dt>
<dfn>codecId</dfn> of type <span class=
"idlMemberType">DOMString</span>
</dt>
<dd>
<p>
It is a unique identifier that is associated to the object that was inspected to
produce the {{RTCCodecStats}} associated with this <a>RTP stream</a>.
</p>
</dd>
</dl>
</section>
</div>
</section>
<section id="codec-dict*">
<h3>
<dfn>RTCCodecStats</dfn> dictionary
</h3>
<p>
Codecs are created when registered for an RTP transport,
but only the subset of codecs that are in use (referenced by an RTP
stream) are exposed in <code>getStats()</code>.
</p>
<p>
The {{RTCCodecStats}} object is created when one or more
{{RTCRtpStreamStats/codecId}} references the codec. When there no
longer exists any reference to the {{RTCCodecStats}}, the stats object
is deleted. If the same codec is used again in the future, the
{{RTCCodecStats}} object is revived with the same {{RTCStats/id}} as
before.
</p>
<p>
Codec objects may be referenced by multiple RTP streams in
media sections using the same transport, but similar codecs in
different transports have different {{RTCCodecStats}} objects.
</p>
<p class="note">
User agents are expected to coalesce information into a single
<code>"codec"</code> entry per payload type per transport, unless
{{RTCCodecStats/sdpFmtpLine}} differs per direction, in which case two
entries (one for encode and one for decode) are needed.
</p>
<div>
<pre class="idl">dictionary RTCCodecStats : RTCStats {
required unsigned long payloadType;
required DOMString transportId;
required DOMString mimeType;
unsigned long clockRate;
unsigned long channels;
DOMString sdpFmtpLine;
};</pre>
<section>
<h2>
Dictionary {{RTCCodecStats}} Members
</h2>
<dl data-link-for="RTCCodecStats" data-dfn-for="RTCCodecStats" class=
"dictionary-members">
<dt>
<dfn>payloadType</dfn> of type <span class="idlMemberType">unsigned
long</span>
</dt>
<dd>
<p>
Payload type as used in RTP encoding or decoding.
</p>
</dd>
<dt>
<dfn>transportId</dfn> of type <span class=
"idlMemberType">DOMString</span>
</dt>
<dd>
<p>
The unique identifier of the transport on which this codec is being used, which
can be used to look up the corresponding {{RTCTransportStats}}
object.
</p>
</dd>
<dt>
<dfn>mimeType</dfn> of type <span class=
"idlMemberType">DOMString</span>
</dt>
<dd>
<p>
The codec MIME media type/subtype defined in the IANA media types registry
[[!IANA-MEDIA-TYPES]], e.g. video/VP8.
</p>
</dd>
<dt>
<dfn>clockRate</dfn> of type <span class="idlMemberType">unsigned
long</span>
</dt>
<dd>
<p>
Represents the media sampling rate.
</p>
</dd>
<dt>
<dfn>channels</dfn> of type <span class="idlMemberType">unsigned
long</span>
</dt>
<dd>
<p>
When present, indicates the number of channels (mono=1, stereo=2).
</p>
</dd>
<dt>
<dfn>sdpFmtpLine</dfn> of type <span class=
"idlMemberType">DOMString</span>
</dt>
<dd>
<p>
The a=fmtp line in the SDP corresponding to the codec, i.e., after the colon
following the PT. This defined by [[!JSEP]] in Section 5.7.
</p>
</dd>
</dl>
</section>
</div>
</section>
<section id="receivedrtpstats-dict*">
<h3>
<dfn>RTCReceivedRtpStreamStats</dfn> dictionary
</h3>
<div>
<pre class="idl">dictionary RTCReceivedRtpStreamStats : RTCRtpStreamStats {
unsigned long long packetsReceived;
long long packetsLost;
double jitter;
};</pre>
<section>
<h2>
Dictionary {{RTCReceivedRtpStreamStats}} Members
</h2>
<dl data-link-for="RTCReceivedRtpStreamStats" data-dfn-for="RTCReceivedRtpStreamStats"
class="dictionary-members">
<dt>
<dfn>packetsReceived</dfn> of type <span class=
"idlMemberType">unsigned long long</span>
</dt>
<dd>
<p>
Total number of RTP packets received for this <a>SSRC</a>. This includes retransmissions.
At the receiving endpoint, this is calculated as defined in [[!RFC3550]] section 6.4.1. At the sending
endpoint the {{packetsReceived}} is estimated by subtracting the Cumulative Number of Packets Lost
from the Extended Highest Sequence Number Received, both reported in the <a>RTCP Receiver
Report</a>, and then subtracting the initial Extended Sequence Number that was sent to this SSRC in a
<a>RTCP Sender Report</a> and then adding one, to mirror what is discussed in Appendix A.3 in [[!RFC3550]], but for the
sender side. If no <a>RTCP Receiver Report</a> has been received yet, then return 0.
</p>
</dd>
<dt>
<dfn>packetsLost</dfn> of type <span class="idlMemberType">long long</span>
</dt>
<dd>
<p>
Total number of RTP packets lost for this <a>SSRC</a>. Calculated as defined in
[[!RFC3550]] section 6.4.1. Note that because of how this is estimated, it can be
negative if more packets are received than sent.
</p>
</dd>
<dt>
<dfn>jitter</dfn> of type <span class="idlMemberType">double</span>
</dt>
<dd>
<p>
Packet Jitter measured in seconds for this <a>SSRC</a>. Calculated as defined in section
6.4.1. of [[!RFC3550]].
</p>
</dd>
</dl>
</section>
</div>
</section>
<section id="inboundrtpstats-dict*">
<h3>
{{RTCInboundRtpStreamStats}} dictionary
</h3>
<p>
The <dfn>RTCInboundRtpStreamStats</dfn> dictionary represents the measurement metrics for
the incoming RTP media stream. The timestamp reported in the statistics object is the
time at which the data was sampled.
</p>
<div>
<pre class="idl">dictionary RTCInboundRtpStreamStats : RTCReceivedRtpStreamStats {
required DOMString trackIdentifier;
DOMString mid;
DOMString remoteId;
unsigned long framesDecoded;
unsigned long keyFramesDecoded;
unsigned long framesRendered;
unsigned long framesDropped;
unsigned long frameWidth;
unsigned long frameHeight;
double framesPerSecond;
unsigned long long qpSum;
double totalDecodeTime;
double totalInterFrameDelay;
double totalSquaredInterFrameDelay;
unsigned long pauseCount;
double totalPausesDuration;
unsigned long freezeCount;
double totalFreezesDuration;
DOMHighResTimeStamp lastPacketReceivedTimestamp;
unsigned long long headerBytesReceived;
unsigned long long packetsDiscarded;
unsigned long long fecBytesReceived;
unsigned long long fecPacketsReceived;
unsigned long long fecPacketsDiscarded;
unsigned long long bytesReceived;
unsigned long nackCount;
unsigned long firCount;
unsigned long pliCount;
double totalProcessingDelay;
DOMHighResTimeStamp estimatedPlayoutTimestamp;
double jitterBufferDelay;
double jitterBufferTargetDelay;
unsigned long long jitterBufferEmittedCount;
double jitterBufferMinimumDelay;
unsigned long long totalSamplesReceived;
unsigned long long concealedSamples;
unsigned long long silentConcealedSamples;
unsigned long long concealmentEvents;
unsigned long long insertedSamplesForDeceleration;
unsigned long long removedSamplesForAcceleration;
double audioLevel;
double totalAudioEnergy;
double totalSamplesDuration;
unsigned long framesReceived;
DOMString decoderImplementation;
DOMString playoutId;
boolean powerEfficientDecoder;
unsigned long framesAssembledFromMultiplePackets;
double totalAssemblyTime;
unsigned long long retransmittedPacketsReceived;