11const SDPUtils = window . adapter . sdp ;
22
3+ import {
4+ isBoring ,
5+ } from './timeseries.js' ;
6+
37function filterStatsGraphs ( event , container ) {
48 const filter = event . target . value ;
59 const filters = filter . split ( ',' ) ;
@@ -21,9 +25,7 @@ export function processDescriptionEvent(container, eventType, description, last_
2125 const { type, sdp} = description ;
2226 const sections = SDPUtils . splitSections ( sdp ) ;
2327 container . innerText += ' (type: "' + type + '", ' + sections . length + ' sections)' ;
24- if ( last_sections ) {
25- container . innerText += ' munged' ;
26- }
28+
2729 const copyBtn = document . createElement ( 'button' ) ;
2830 copyBtn . innerText = '\uD83D\uDCCB' ; // clipboard
2931 copyBtn . className = 'copyBtn' ;
@@ -32,6 +34,7 @@ export function processDescriptionEvent(container, eventType, description, last_
3234 } ;
3335 container . appendChild ( copyBtn ) ;
3436
37+ let munged = false ;
3538 const el = document . createElement ( 'pre' ) ;
3639 sections . forEach ( ( section , index ) => {
3740 const lines = SDPUtils . splitLines ( section ) ;
@@ -59,25 +62,30 @@ export function processDescriptionEvent(container, eventType, description, last_
5962 }
6063 details . open = false ;
6164 }
62- if ( last_sections && last_sections [ index ] !== sections [ index ] ) {
63- // Ignore triggering from simple reordering which is ok-ish.
64- const last_lines = SDPUtils . splitLines ( last_sections [ index ] ) . sort ( ) ;
65- const current_lines = SDPUtils . splitLines ( sections [ index ] ) . sort ( ) ;
66- const mungedIndex = last_lines . findIndex ( ( line , index ) => line !== current_lines [ index ] ) ;
67- if ( mungedIndex !== - 1 ) {
68- summary . innerText += ' munged' ;
69- summary . style . backgroundColor = '#FBCEB1' ;
70- summary . title = 'First munged line: ' + current_lines [ mungedIndex ] ;
71- details . style . backgroundColor = '#FBCEB1' ;
72- details . open = true ;
73- } else {
74- summary . innerText += ' reordered' ;
75- }
65+ }
66+ if ( last_sections && last_sections [ index ] !== sections [ index ] ) {
67+ // Ignore triggering from simple reordering which is ok-ish.
68+ const last_lines = SDPUtils . splitLines ( last_sections [ index ] ) . sort ( ) ;
69+ const current_lines = SDPUtils . splitLines ( sections [ index ] ) . sort ( ) ;
70+ const mungedIndex = last_lines . findIndex ( ( line , index ) => line !== current_lines [ index ] ) ;
71+ if ( mungedIndex !== - 1 ) {
72+ summary . innerText += ' munged' ;
73+ summary . style . backgroundColor = '#FBCEB1' ;
74+ summary . title = 'First munged line: ' + current_lines [ mungedIndex ] ;
75+ details . style . backgroundColor = '#FBCEB1' ;
76+ details . open = true ;
77+ } else {
78+ summary . innerText += ' reordered' ;
79+ summary . style . backgroundColor = '#FBCEB1' ;
7680 }
81+ munged = true ;
7782 }
7883 details . appendChild ( summary ) ;
7984 el . appendChild ( details ) ;
8085 } ) ;
86+ if ( munged ) {
87+ container . innerText += ' munged' ;
88+ }
8189 container . appendChild ( el ) ;
8290}
8391
@@ -109,19 +117,26 @@ export function createContainers(connid, url, containers) {
109117 connectionState . textContent = 'Connection state:' ;
110118 container . appendChild ( connectionState ) ;
111119
120+ const candidateContainer = document . createElement ( 'details' ) ;
121+ container . style . margin = '10px' ;
122+ const candidateSummary = document . createElement ( 'summary' ) ;
123+ candidateSummary . innerText = 'ICE candidate grid' ;
124+ candidateContainer . appendChild ( candidateSummary ) ;
112125 const candidates = document . createElement ( 'table' ) ;
113126 candidates . className = 'candidatepairtable' ;
114- container . appendChild ( candidates ) ;
127+ candidateContainer . appendChild ( candidates ) ;
128+ container . appendChild ( candidateContainer ) ;
115129
116130 const updateLog = document . createElement ( 'table' ) ;
117131 const head = document . createElement ( 'tr' ) ;
118132 updateLog . appendChild ( head ) ;
119133
120134 el = document . createElement ( 'th' ) ;
121- el . innerText = 'connection ' + connid ;
135+ el . innerText = 'Time' ;
122136 head . appendChild ( el ) ;
123137
124138 el = document . createElement ( 'th' ) ;
139+ el . innerText = 'Event' ;
125140 head . appendChild ( el ) ;
126141
127142 container . appendChild ( updateLog ) ;
@@ -138,7 +153,7 @@ export function createContainers(connid, url, containers) {
138153 input . oninput = ( e ) => filterStatsGraphs ( e , graphs ) ;
139154 graphHeader . appendChild ( input ) ;
140155
141- container . appendChild ( graphHeader ) ;
156+ graphs . appendChild ( graphHeader ) ;
142157 container . appendChild ( graphs ) ;
143158
144159 containers [ connid ] = {
@@ -312,7 +327,7 @@ export function processGetUserMedia(data, parentElement) {
312327
313328 parentElement . appendChild ( container ) ;
314329 data . forEach ( gumEvent => {
315- const id = [ 'gum-row' , gumEvent . pid , gumEvent . rid , gumEvent . request_id ] . join ( '-' ) ;
330+ const id = [ container . id , 'gum-row' , gumEvent . pid , gumEvent . rid , gumEvent . request_id ] . join ( '-' ) ;
316331 if ( ! gumEvent . origin ) {
317332 // Not a getUserMedia call but a response, update the row with the request.
318333 const existingRow = document . getElementById ( id ) ;
@@ -357,9 +372,9 @@ export function createGraphOptions(statsId, statsType, reports, referenceTime) {
357372 } ;
358373 reports . sort ( ) . forEach ( report => {
359374 const [ name , data , statsType ] = report ;
375+ // set up a x-axis plotbands:
376+ // https://www.highcharts.com/docs/chart-concepts/plot-bands-and-plot-lines
360377 if ( name === 'active' && statsType === 'outbound-rtp' ) {
361- // set up a x-axis plotbands:
362- // https://www.highcharts.com/docs/chart-concepts/plot-bands-and-plot-lines
363378 data . filter ( ( el , index , values ) => {
364379 return ! ( index > 0 && index < values . length - 1 && values [ index - 1 ] [ 1 ] == el [ 1 ] ) ;
365380 } ) . forEach ( ( item , index , values ) => {
@@ -378,8 +393,6 @@ export function createGraphOptions(statsId, statsType, reports, referenceTime) {
378393 return ;
379394 }
380395 if ( name === 'qualityLimitationReason' && statsType === 'outbound-rtp' ) {
381- // set up a x-axis plotbands:
382- // https://www.highcharts.com/docs/chart-concepts/plot-bands-and-plot-lines
383396 data . filter ( ( el , index , values ) => {
384397 return ! ( index > 0 && index < values . length - 1 && values [ index - 1 ] [ 1 ] == el [ 1 ] ) ;
385398 } ) . forEach ( ( item , index , values ) => {
@@ -398,8 +411,6 @@ export function createGraphOptions(statsId, statsType, reports, referenceTime) {
398411 return ;
399412 }
400413 if ( [ 'encoderImplementation' , 'decoderImplementation' ] . includes ( name ) && [ 'inbound-rtp' , 'outbound-rtp' ] . includes ( statsType ) ) {
401- // set up a x-axis plotbands:
402- // https://www.highcharts.com/docs/chart-concepts/plot-bands-and-plot-lines
403414 data . filter ( ( el , index , values ) => {
404415 return ! ( index > 0 && index < values . length - 1 && values [ index - 1 ] [ 1 ] == el [ 1 ] ) ;
405416 } ) . forEach ( ( item , index , values ) => {
@@ -416,8 +427,6 @@ export function createGraphOptions(statsId, statsType, reports, referenceTime) {
416427 return ;
417428 }
418429 if ( name === 'scalabilityMode' && statsType === 'outbound-rtp' ) {
419- // set up a x-axis plotbands:
420- // https://www.highcharts.com/docs/chart-concepts/plot-bands-and-plot-lines
421430 data . filter ( ( el , index , values ) => {
422431 return ! ( index > 0 && index < values . length - 1 && values [ index - 1 ] [ 1 ] == el [ 1 ] ) ;
423432 } ) . forEach ( ( item , index , values ) => {
@@ -440,7 +449,7 @@ export function createGraphOptions(statsId, statsType, reports, referenceTime) {
440449 }
441450
442451 const statsForLabels = [
443- 'kind' , 'mid' , 'rid' ,
452+ 'kind' , 'mid' , 'rid' , 'encodingIndex' ,
444453 'ssrc' , 'rtxSsrc' , 'fecSsrc' ,
445454 'encoderImplementation' , 'decoderImplementation' , 'scalabilityMode' ,
446455 'scalabilityMode' , '[codec]' ,
@@ -458,24 +467,12 @@ export function createGraphOptions(statsId, statsType, reports, referenceTime) {
458467 'streamIdentifier' , 'trackIdentifier' ,
459468 'priority' , 'port' ,
460469 'ssrc' , 'rtxSsrc' , 'fecSsrc' ,
461- 'mid' , 'rid' ,
470+ 'mid' , 'rid' , 'encodingIndex' ,
462471 ] ;
463472 if ( ignoredSeries . includes ( name ) ) {
464473 return ;
465474 }
466475
467- const hiddenSeries = [
468- 'bytesReceived' , 'bytesSent' ,
469- 'headerBytesReceived' , 'headerBytesSent' ,
470- 'packetsReceived' , 'packetsSent' ,
471- 'qpSum' ,
472- 'framesEncoded' , 'framesDecoded' , 'totalEncodeTime' ,
473- 'lastPacketReceivedTimestamp' , 'lastPacketSentTimestamp' ,
474- 'remoteTimestamp' , 'estimatedPlayoutTimestamp' ,
475- 'audioInputLevel' , 'audioOutputLevel' ,
476- 'totalSamplesDuration' , 'totalSamplesReceived' ,
477- 'jitterBufferEmittedCount' ,
478- ] ;
479476 const secondYAxis = [
480477 // candidate-pair
481478 'consentRequestsSent' , 'requestsSent' , 'requestsReceived' , 'responsesSent' , 'responsesReceived' ,
@@ -487,13 +484,16 @@ export function createGraphOptions(statsId, statsType, reports, referenceTime) {
487484 '[framesSent/s]' , '[framesEncoded/s]' , '[keyFramesEncoded/s]' , 'frameWidth' , 'frameHeight' ,
488485 ] ;
489486
487+ // Hide "boring" series. Graphs with all boring series should be deprioritized too.
488+ const hidden = isBoring ( name , data ) ;
490489 series . push ( {
491490 name,
492491 data,
493- visible : ! hiddenSeries . includes ( name ) ,
492+ visible : ! hidden ,
494493 yAxis : secondYAxis . includes ( name ) ? 1 : 0 ,
495494 } ) ;
496495 } ) ;
496+ labels [ 'visibleSeries' ] = series . filter ( s => s . visible ) . length + '/' + series . length ;
497497
498498 // Optionally start all graphs at the same point in time.
499499 if ( referenceTime ) {
0 commit comments