1*d9f75844SAndroid Build Coastguard Worker<?% config.freshness.reviewed = '2021-04-12' %?> 2*d9f75844SAndroid Build Coastguard Worker 3*d9f75844SAndroid Build Coastguard Worker# PeerConnection Level Framework 4*d9f75844SAndroid Build Coastguard Worker 5*d9f75844SAndroid Build Coastguard Worker## API 6*d9f75844SAndroid Build Coastguard Worker 7*d9f75844SAndroid Build Coastguard Worker* [Fixture][1] 8*d9f75844SAndroid Build Coastguard Worker* [Fixture factory function][2] 9*d9f75844SAndroid Build Coastguard Worker 10*d9f75844SAndroid Build Coastguard Worker## Documentation 11*d9f75844SAndroid Build Coastguard Worker 12*d9f75844SAndroid Build Coastguard WorkerThe PeerConnection level framework is designed for end-to-end media quality 13*d9f75844SAndroid Build Coastguard Workertesting through the PeerConnection level public API. The framework uses the 14*d9f75844SAndroid Build Coastguard Worker*Unified plan* API to generate offers/answers during the signaling phase. The 15*d9f75844SAndroid Build Coastguard Workerframework also wraps the video encoder/decoder and inject it into 16*d9f75844SAndroid Build Coastguard Worker*`webrtc::PeerConnection`* to measure video quality, performing 1:1 frames 17*d9f75844SAndroid Build Coastguard Workermatching between captured and rendered frames without any extra requirements to 18*d9f75844SAndroid Build Coastguard Workerinput video. For audio quality evaluation the standard `GetStats()` API from 19*d9f75844SAndroid Build Coastguard WorkerPeerConnection is used. 20*d9f75844SAndroid Build Coastguard Worker 21*d9f75844SAndroid Build Coastguard WorkerThe framework API is located in the namespace *`webrtc::webrtc_pc_e2e`*. 22*d9f75844SAndroid Build Coastguard Worker 23*d9f75844SAndroid Build Coastguard Worker### Supported features 24*d9f75844SAndroid Build Coastguard Worker 25*d9f75844SAndroid Build Coastguard Worker* Single or bidirectional media in the call 26*d9f75844SAndroid Build Coastguard Worker* RTC Event log dump per peer 27*d9f75844SAndroid Build Coastguard Worker* AEC dump per peer 28*d9f75844SAndroid Build Coastguard Worker* Compatible with *`webrtc::TimeController`* for both real and simulated time 29*d9f75844SAndroid Build Coastguard Worker* Media 30*d9f75844SAndroid Build Coastguard Worker * AV sync 31*d9f75844SAndroid Build Coastguard Worker* Video 32*d9f75844SAndroid Build Coastguard Worker * Any amount of video tracks both from caller and callee sides 33*d9f75844SAndroid Build Coastguard Worker * Input video from 34*d9f75844SAndroid Build Coastguard Worker * Video generator 35*d9f75844SAndroid Build Coastguard Worker * Specified file 36*d9f75844SAndroid Build Coastguard Worker * Any instance of *`webrtc::test::FrameGeneratorInterface`* 37*d9f75844SAndroid Build Coastguard Worker * Dumping of captured/rendered video into file 38*d9f75844SAndroid Build Coastguard Worker * Screen sharing 39*d9f75844SAndroid Build Coastguard Worker * Vp8 simulcast from caller side 40*d9f75844SAndroid Build Coastguard Worker * Vp9 SVC from caller side 41*d9f75844SAndroid Build Coastguard Worker * Choosing of video codec (name and parameters), having multiple codecs 42*d9f75844SAndroid Build Coastguard Worker negotiated to support codec-switching testing. 43*d9f75844SAndroid Build Coastguard Worker * FEC (ULP or Flex) 44*d9f75844SAndroid Build Coastguard Worker * Forced codec overshooting (for encoder overshoot emulation on some 45*d9f75844SAndroid Build Coastguard Worker mobile devices, when hardware encoder can overshoot target bitrate) 46*d9f75844SAndroid Build Coastguard Worker* Audio 47*d9f75844SAndroid Build Coastguard Worker * Up to 1 audio track both from caller and callee sides 48*d9f75844SAndroid Build Coastguard Worker * Generated audio 49*d9f75844SAndroid Build Coastguard Worker * Audio from specified file 50*d9f75844SAndroid Build Coastguard Worker * Dumping of captured/rendered audio into file 51*d9f75844SAndroid Build Coastguard Worker * Parameterizing of `cricket::AudioOptions` 52*d9f75844SAndroid Build Coastguard Worker * Echo emulation 53*d9f75844SAndroid Build Coastguard Worker* Injection of various WebRTC components into underlying 54*d9f75844SAndroid Build Coastguard Worker *`webrtc::PeerConnection`* or *`webrtc::PeerConnectionFactory`*. You can see 55*d9f75844SAndroid Build Coastguard Worker the full list [here][11] 56*d9f75844SAndroid Build Coastguard Worker* Scheduling of events, that can happen during the test, for example: 57*d9f75844SAndroid Build Coastguard Worker * Changes in network configuration 58*d9f75844SAndroid Build Coastguard Worker * User statistics measurements 59*d9f75844SAndroid Build Coastguard Worker * Custom defined actions 60*d9f75844SAndroid Build Coastguard Worker* User defined statistics reporting via 61*d9f75844SAndroid Build Coastguard Worker *`webrtc::webrtc_pc_e2e::PeerConnectionE2EQualityTestFixture::QualityMetricsReporter`* 62*d9f75844SAndroid Build Coastguard Worker interface 63*d9f75844SAndroid Build Coastguard Worker 64*d9f75844SAndroid Build Coastguard Worker## Exported metrics 65*d9f75844SAndroid Build Coastguard Worker 66*d9f75844SAndroid Build Coastguard Worker### General 67*d9f75844SAndroid Build Coastguard Worker 68*d9f75844SAndroid Build Coastguard Worker* *`<peer_name>_connected`* - peer successfully established connection to 69*d9f75844SAndroid Build Coastguard Worker remote side 70*d9f75844SAndroid Build Coastguard Worker* *`cpu_usage`* - CPU usage excluding video analyzer 71*d9f75844SAndroid Build Coastguard Worker* *`audio_ahead_ms`* - Used to estimate how much audio and video is out of 72*d9f75844SAndroid Build Coastguard Worker sync when the two tracks were from the same source. Stats are polled 73*d9f75844SAndroid Build Coastguard Worker periodically during a call. The metric represents how much earlier was audio 74*d9f75844SAndroid Build Coastguard Worker played out on average over the call. If, during a stats poll, video is 75*d9f75844SAndroid Build Coastguard Worker ahead, then audio_ahead_ms will be equal to 0 for this poll. 76*d9f75844SAndroid Build Coastguard Worker* *`video_ahead_ms`* - Used to estimate how much audio and video is out of 77*d9f75844SAndroid Build Coastguard Worker sync when the two tracks were from the same source. Stats are polled 78*d9f75844SAndroid Build Coastguard Worker periodically during a call. The metric represents how much earlier was video 79*d9f75844SAndroid Build Coastguard Worker played out on average over the call. If, during a stats poll, audio is 80*d9f75844SAndroid Build Coastguard Worker ahead, then video_ahead_ms will be equal to 0 for this poll. 81*d9f75844SAndroid Build Coastguard Worker 82*d9f75844SAndroid Build Coastguard Worker### Video 83*d9f75844SAndroid Build Coastguard Worker 84*d9f75844SAndroid Build Coastguard WorkerSee documentation for 85*d9f75844SAndroid Build Coastguard Worker[*`DefaultVideoQualityAnalyzer`*](default_video_quality_analyzer.md#exported-metrics) 86*d9f75844SAndroid Build Coastguard Worker 87*d9f75844SAndroid Build Coastguard Worker### Audio 88*d9f75844SAndroid Build Coastguard Worker 89*d9f75844SAndroid Build Coastguard Worker* *`accelerate_rate`* - when playout is sped up, this counter is increased by 90*d9f75844SAndroid Build Coastguard Worker the difference between the number of samples received and the number of 91*d9f75844SAndroid Build Coastguard Worker samples played out. If speedup is achieved by removing samples, this will be 92*d9f75844SAndroid Build Coastguard Worker the count of samples removed. Rate is calculated as difference between 93*d9f75844SAndroid Build Coastguard Worker nearby samples divided on sample interval. 94*d9f75844SAndroid Build Coastguard Worker* *`expand_rate`* - the total number of samples that are concealed samples 95*d9f75844SAndroid Build Coastguard Worker over time. A concealed sample is a sample that was replaced with synthesized 96*d9f75844SAndroid Build Coastguard Worker samples generated locally before being played out. Examples of samples that 97*d9f75844SAndroid Build Coastguard Worker have to be concealed are samples from lost packets or samples from packets 98*d9f75844SAndroid Build Coastguard Worker that arrive too late to be played out 99*d9f75844SAndroid Build Coastguard Worker* *`speech_expand_rate`* - the total number of samples that are concealed 100*d9f75844SAndroid Build Coastguard Worker samples minus the total number of concealed samples inserted that are 101*d9f75844SAndroid Build Coastguard Worker "silent" over time. Playing out silent samples results in silence or comfort 102*d9f75844SAndroid Build Coastguard Worker noise. 103*d9f75844SAndroid Build Coastguard Worker* *`preemptive_rate`* - when playout is slowed down, this counter is increased 104*d9f75844SAndroid Build Coastguard Worker by the difference between the number of samples received and the number of 105*d9f75844SAndroid Build Coastguard Worker samples played out. If playout is slowed down by inserting samples, this 106*d9f75844SAndroid Build Coastguard Worker will be the number of inserted samples. Rate is calculated as difference 107*d9f75844SAndroid Build Coastguard Worker between nearby samples divided on sample interval. 108*d9f75844SAndroid Build Coastguard Worker* *`average_jitter_buffer_delay_ms`* - average size of NetEQ jitter buffer. 109*d9f75844SAndroid Build Coastguard Worker* *`preferred_buffer_size_ms`* - preferred size of NetEQ jitter buffer. 110*d9f75844SAndroid Build Coastguard Worker* *`visqol_mos`* - proxy for audio quality itself. 111*d9f75844SAndroid Build Coastguard Worker* *`asdm_samples`* - measure of how much acceleration/deceleration was in the 112*d9f75844SAndroid Build Coastguard Worker signal. 113*d9f75844SAndroid Build Coastguard Worker* *`word_error_rate`* - measure of how intelligible the audio was (percent of 114*d9f75844SAndroid Build Coastguard Worker words that could not be recognized in output audio). 115*d9f75844SAndroid Build Coastguard Worker 116*d9f75844SAndroid Build Coastguard Worker### Network 117*d9f75844SAndroid Build Coastguard Worker 118*d9f75844SAndroid Build Coastguard Worker* *`bytes_sent`* - represents the total number of payload bytes sent on this 119*d9f75844SAndroid Build Coastguard Worker PeerConnection, i.e., not including headers or padding 120*d9f75844SAndroid Build Coastguard Worker* *`packets_sent`* - represents the total number of packets sent over this 121*d9f75844SAndroid Build Coastguard Worker PeerConnection’s transports. 122*d9f75844SAndroid Build Coastguard Worker* *`average_send_rate`* - average send rate calculated on bytes_sent divided 123*d9f75844SAndroid Build Coastguard Worker by test duration. 124*d9f75844SAndroid Build Coastguard Worker* *`payload_bytes_sent`* - total number of bytes sent for all SSRC plus total 125*d9f75844SAndroid Build Coastguard Worker number of RTP header and padding bytes sent for all SSRC. This does not 126*d9f75844SAndroid Build Coastguard Worker include the size of transport layer headers such as IP or UDP. 127*d9f75844SAndroid Build Coastguard Worker* *`sent_packets_loss`* - packets_sent minus corresponding packets_received. 128*d9f75844SAndroid Build Coastguard Worker* *`bytes_received`* - represents the total number of bytes received on this 129*d9f75844SAndroid Build Coastguard Worker PeerConnection, i.e., not including headers or padding. 130*d9f75844SAndroid Build Coastguard Worker* *`packets_received`* - represents the total number of packets received on 131*d9f75844SAndroid Build Coastguard Worker this PeerConnection’s transports. 132*d9f75844SAndroid Build Coastguard Worker* *`average_receive_rate`* - average receive rate calculated on bytes_received 133*d9f75844SAndroid Build Coastguard Worker divided by test duration. 134*d9f75844SAndroid Build Coastguard Worker* *`payload_bytes_received`* - total number of bytes received for all SSRC 135*d9f75844SAndroid Build Coastguard Worker plus total number of RTP header and padding bytes received for all SSRC. 136*d9f75844SAndroid Build Coastguard Worker This does not include the size of transport layer headers such as IP or UDP. 137*d9f75844SAndroid Build Coastguard Worker 138*d9f75844SAndroid Build Coastguard Worker### Framework stability 139*d9f75844SAndroid Build Coastguard Worker 140*d9f75844SAndroid Build Coastguard Worker* *`frames_in_flight`* - amount of frames that were captured but wasn't seen 141*d9f75844SAndroid Build Coastguard Worker on receiver in the way that also all frames after also weren't seen on 142*d9f75844SAndroid Build Coastguard Worker receiver. 143*d9f75844SAndroid Build Coastguard Worker* *`bytes_discarded_no_receiver`* - total number of bytes that were received 144*d9f75844SAndroid Build Coastguard Worker on network interfaces related to the peer, but destination port was closed. 145*d9f75844SAndroid Build Coastguard Worker* *`packets_discarded_no_receiver`* - total number of packets that were 146*d9f75844SAndroid Build Coastguard Worker received on network interfaces related to the peer, but destination port was 147*d9f75844SAndroid Build Coastguard Worker closed. 148*d9f75844SAndroid Build Coastguard Worker 149*d9f75844SAndroid Build Coastguard Worker## Examples 150*d9f75844SAndroid Build Coastguard Worker 151*d9f75844SAndroid Build Coastguard WorkerExamples can be found in 152*d9f75844SAndroid Build Coastguard Worker 153*d9f75844SAndroid Build Coastguard Worker* [peer_connection_e2e_smoke_test.cc][3] 154*d9f75844SAndroid Build Coastguard Worker* [pc_full_stack_tests.cc][4] 155*d9f75844SAndroid Build Coastguard Worker 156*d9f75844SAndroid Build Coastguard Worker## Stats plotting 157*d9f75844SAndroid Build Coastguard Worker 158*d9f75844SAndroid Build Coastguard Worker### Description 159*d9f75844SAndroid Build Coastguard Worker 160*d9f75844SAndroid Build Coastguard WorkerStats plotting provides ability to plot statistic collected during the test. 161*d9f75844SAndroid Build Coastguard WorkerRight now it is used in PeerConnection level framework and give ability to see 162*d9f75844SAndroid Build Coastguard Workerhow video quality metrics changed during test execution. 163*d9f75844SAndroid Build Coastguard Worker 164*d9f75844SAndroid Build Coastguard Worker### Usage 165*d9f75844SAndroid Build Coastguard Worker 166*d9f75844SAndroid Build Coastguard WorkerTo make any metrics plottable you need: 167*d9f75844SAndroid Build Coastguard Worker 168*d9f75844SAndroid Build Coastguard Worker1. Collect metric data with [SamplesStatsCounter][5] which internally will 169*d9f75844SAndroid Build Coastguard Worker store all intermediate points and timestamps when these points were added. 170*d9f75844SAndroid Build Coastguard Worker2. Then you need to report collected data with 171*d9f75844SAndroid Build Coastguard Worker [`webrtc::test::PrintResult(...)`][6]. By using these method you will also 172*d9f75844SAndroid Build Coastguard Worker specify name of the plottable metric. 173*d9f75844SAndroid Build Coastguard Worker 174*d9f75844SAndroid Build Coastguard WorkerAfter these steps it will be possible to export your metric for plotting. There 175*d9f75844SAndroid Build Coastguard Workerare several options how you can do this: 176*d9f75844SAndroid Build Coastguard Worker 177*d9f75844SAndroid Build Coastguard Worker1. Use [`webrtc::TestMain::Create()`][7] as `main` function implementation, for 178*d9f75844SAndroid Build Coastguard Worker example use [`test/test_main.cc`][8] as `main` function for your test. 179*d9f75844SAndroid Build Coastguard Worker 180*d9f75844SAndroid Build Coastguard Worker In such case your binary will have flag `--plot`, where you can provide a 181*d9f75844SAndroid Build Coastguard Worker list of metrics, that you want to plot or specify `all` to plot all 182*d9f75844SAndroid Build Coastguard Worker available metrics. 183*d9f75844SAndroid Build Coastguard Worker 184*d9f75844SAndroid Build Coastguard Worker If `--plot` is specified, the binary will output metrics data into `stdout`. 185*d9f75844SAndroid Build Coastguard Worker Then you need to pipe this `stdout` into python plotter script 186*d9f75844SAndroid Build Coastguard Worker [`rtc_tools/metrics_plotter.py`][9], which will plot data. 187*d9f75844SAndroid Build Coastguard Worker 188*d9f75844SAndroid Build Coastguard Worker Examples: 189*d9f75844SAndroid Build Coastguard Worker 190*d9f75844SAndroid Build Coastguard Worker ```shell 191*d9f75844SAndroid Build Coastguard Worker $ ./out/Default/test_support_unittests \ 192*d9f75844SAndroid Build Coastguard Worker --gtest_filter=PeerConnectionE2EQualityTestSmokeTest.Svc \ 193*d9f75844SAndroid Build Coastguard Worker --nologs \ 194*d9f75844SAndroid Build Coastguard Worker --plot=all \ 195*d9f75844SAndroid Build Coastguard Worker | python rtc_tools/metrics_plotter.py 196*d9f75844SAndroid Build Coastguard Worker ``` 197*d9f75844SAndroid Build Coastguard Worker 198*d9f75844SAndroid Build Coastguard Worker ```shell 199*d9f75844SAndroid Build Coastguard Worker $ ./out/Default/test_support_unittests \ 200*d9f75844SAndroid Build Coastguard Worker --gtest_filter=PeerConnectionE2EQualityTestSmokeTest.Svc \ 201*d9f75844SAndroid Build Coastguard Worker --nologs \ 202*d9f75844SAndroid Build Coastguard Worker --plot=psnr,ssim \ 203*d9f75844SAndroid Build Coastguard Worker | python rtc_tools/metrics_plotter.py 204*d9f75844SAndroid Build Coastguard Worker ``` 205*d9f75844SAndroid Build Coastguard Worker 206*d9f75844SAndroid Build Coastguard Worker Example chart:  207*d9f75844SAndroid Build Coastguard Worker 208*d9f75844SAndroid Build Coastguard Worker2. Use API from [`test/testsupport/perf_test.h`][10] directly by invoking 209*d9f75844SAndroid Build Coastguard Worker `webrtc::test::PrintPlottableResults(const std::vector<std::string>& 210*d9f75844SAndroid Build Coastguard Worker desired_graphs)` to print plottable metrics to stdout. Then as in previous 211*d9f75844SAndroid Build Coastguard Worker option you need to pipe result into plotter script. 212*d9f75844SAndroid Build Coastguard Worker 213*d9f75844SAndroid Build Coastguard Worker[1]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/api/test/peerconnection_quality_test_fixture.h;drc=cbe6e8a2589a925d4c91a2ac2c69201f03de9c39 214*d9f75844SAndroid Build Coastguard Worker[2]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/api/test/create_peerconnection_quality_test_fixture.h;drc=cbe6e8a2589a925d4c91a2ac2c69201f03de9c39 215*d9f75844SAndroid Build Coastguard Worker[3]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/test/pc/e2e/peer_connection_e2e_smoke_test.cc;drc=cbe6e8a2589a925d4c91a2ac2c69201f03de9c39 216*d9f75844SAndroid Build Coastguard Worker[4]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/video/pc_full_stack_tests.cc;drc=cbe6e8a2589a925d4c91a2ac2c69201f03de9c39 217*d9f75844SAndroid Build Coastguard Worker[5]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/api/numerics/samples_stats_counter.h;drc=cbe6e8a2589a925d4c91a2ac2c69201f03de9c39 218*d9f75844SAndroid Build Coastguard Worker[6]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/test/testsupport/perf_test.h;l=86;drc=0710b401b1e5b500b8e84946fb657656ba1b58b7 219*d9f75844SAndroid Build Coastguard Worker[7]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/test/test_main_lib.h;l=23;drc=bcb42f1e4be136c390986a40d9d5cb3ad0de260b 220*d9f75844SAndroid Build Coastguard Worker[8]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/test/test_main.cc;drc=bcb42f1e4be136c390986a40d9d5cb3ad0de260b 221*d9f75844SAndroid Build Coastguard Worker[9]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/rtc_tools/metrics_plotter.py;drc=8cc6695652307929edfc877cd64b75cd9ec2d615 222*d9f75844SAndroid Build Coastguard Worker[10]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/test/testsupport/perf_test.h;l=105;drc=0710b401b1e5b500b8e84946fb657656ba1b58b7 223*d9f75844SAndroid Build Coastguard Worker[11]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/api/test/peerconnection_quality_test_fixture.h;l=272;drc=484acf27231d931dbc99aedce85bc27e06486b96 224