xref: /aosp_15_r20/external/webrtc/test/pc/e2e/g3doc/architecture.md (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker<?% config.freshness.reviewed = '2021-04-12' %?>
2*d9f75844SAndroid Build Coastguard Worker
3*d9f75844SAndroid Build Coastguard Worker# PeerConnection level framework fixture architecture
4*d9f75844SAndroid Build Coastguard Worker
5*d9f75844SAndroid Build Coastguard Worker## Overview
6*d9f75844SAndroid Build Coastguard Worker
7*d9f75844SAndroid Build Coastguard WorkerThe main implementation of
8*d9f75844SAndroid Build Coastguard Worker[`webrtc::webrtc_pc_e2e::PeerConnectionE2EQualityTestFixture`][1] is
9*d9f75844SAndroid Build Coastguard Worker[`webrtc::webrtc_pc_e2e::PeerConnectionE2EQualityTest`][2]. Internally it owns
10*d9f75844SAndroid Build Coastguard Workerthe next main pieces:
11*d9f75844SAndroid Build Coastguard Worker
12*d9f75844SAndroid Build Coastguard Worker*   [`MediaHelper`][3] - responsible for adding audio and video tracks to the
13*d9f75844SAndroid Build Coastguard Worker    peers.
14*d9f75844SAndroid Build Coastguard Worker*   [`VideoQualityAnalyzerInjectionHelper`][4] and
15*d9f75844SAndroid Build Coastguard Worker    [`SingleProcessEncodedImageDataInjector`][5] - used to inject video quality
16*d9f75844SAndroid Build Coastguard Worker    analysis and properly match captured and rendered video frames. You can read
17*d9f75844SAndroid Build Coastguard Worker    more about it in
18*d9f75844SAndroid Build Coastguard Worker    [DefaultVideoQualityAnalyzer](default_video_quality_analyzer.md) section.
19*d9f75844SAndroid Build Coastguard Worker*   [`AudioQualityAnalyzerInterface`][6] - used to measure audio quality metrics
20*d9f75844SAndroid Build Coastguard Worker*   [`TestActivitiesExecutor`][7] - used to support [`ExecuteAt(...)`][8] and
21*d9f75844SAndroid Build Coastguard Worker    [`ExecuteEvery(...)`][9] API of `PeerConnectionE2EQualityTestFixture` to run
22*d9f75844SAndroid Build Coastguard Worker    any arbitrary action during test execution timely synchronized with a test
23*d9f75844SAndroid Build Coastguard Worker    call.
24*d9f75844SAndroid Build Coastguard Worker*   A vector of [`QualityMetricsReporter`][10] added by the
25*d9f75844SAndroid Build Coastguard Worker    `PeerConnectionE2EQualityTestFixture` user.
26*d9f75844SAndroid Build Coastguard Worker*   Two peers: Alice and Bob represented by instances of [`TestPeer`][11]
27*d9f75844SAndroid Build Coastguard Worker    object.
28*d9f75844SAndroid Build Coastguard Worker
29*d9f75844SAndroid Build Coastguard WorkerAlso it keeps a reference to [`webrtc::TimeController`][12], which is used to
30*d9f75844SAndroid Build Coastguard Workercreate all required threads, task queues, task queue factories and time related
31*d9f75844SAndroid Build Coastguard Workerobjects.
32*d9f75844SAndroid Build Coastguard Worker
33*d9f75844SAndroid Build Coastguard Worker## TestPeer
34*d9f75844SAndroid Build Coastguard Worker
35*d9f75844SAndroid Build Coastguard WorkerCall participants are represented by instances of `TestPeer` object.
36*d9f75844SAndroid Build Coastguard Worker[`TestPeerFactory`][13] is used to create them. `TestPeer` owns all instances
37*d9f75844SAndroid Build Coastguard Workerrelated to the `webrtc::PeerConnection`, including required listeners and
38*d9f75844SAndroid Build Coastguard Workercallbacks. Also it provides an API to do offer/answer exchange and ICE candidate
39*d9f75844SAndroid Build Coastguard Workerexchange. For this purposes internally it uses an instance of
40*d9f75844SAndroid Build Coastguard Worker[`webrtc::PeerConnectionWrapper`][14].
41*d9f75844SAndroid Build Coastguard Worker
42*d9f75844SAndroid Build Coastguard WorkerThe `TestPeer` also owns the `PeerConnection` worker thread. The signaling
43*d9f75844SAndroid Build Coastguard Workerthread for all `PeerConnection`'s is owned by
44*d9f75844SAndroid Build Coastguard Worker`PeerConnectionE2EQualityTestFixture` and shared between all participants in the
45*d9f75844SAndroid Build Coastguard Workercall. The network thread is owned by the network layer (it maybe either emulated
46*d9f75844SAndroid Build Coastguard Workernetwork provided by [Network Emulation Framework][24] or network thread and
47*d9f75844SAndroid Build Coastguard Worker`rtc::NetworkManager` provided by user) and provided when peer is added to the
48*d9f75844SAndroid Build Coastguard Workerfixture via [`AddPeer(...)`][15] API.
49*d9f75844SAndroid Build Coastguard Worker
50*d9f75844SAndroid Build Coastguard Worker## GetStats API based metrics reporters
51*d9f75844SAndroid Build Coastguard Worker
52*d9f75844SAndroid Build Coastguard Worker`PeerConnectionE2EQualityTestFixture` gives the user ability to provide
53*d9f75844SAndroid Build Coastguard Workerdifferent `QualityMetricsReporter`s which will listen for `PeerConnection`
54*d9f75844SAndroid Build Coastguard Worker[`GetStats`][16] API. Then such reporters will be able to report various metrics
55*d9f75844SAndroid Build Coastguard Workerthat user wants to measure.
56*d9f75844SAndroid Build Coastguard Worker
57*d9f75844SAndroid Build Coastguard Worker`PeerConnectionE2EQualityTestFixture` itself also uses this mechanism to
58*d9f75844SAndroid Build Coastguard Workermeasure:
59*d9f75844SAndroid Build Coastguard Worker
60*d9f75844SAndroid Build Coastguard Worker*   Audio quality metrics
61*d9f75844SAndroid Build Coastguard Worker*   Audio/Video sync metrics (with help of [`CrossMediaMetricsReporter`][17])
62*d9f75844SAndroid Build Coastguard Worker
63*d9f75844SAndroid Build Coastguard WorkerAlso framework provides a [`StatsBasedNetworkQualityMetricsReporter`][18] to
64*d9f75844SAndroid Build Coastguard Workermeasure network related WebRTC metrics and print debug raw emulated network
65*d9f75844SAndroid Build Coastguard Workerstatistic. This reporter should be added by user via
66*d9f75844SAndroid Build Coastguard Worker[`AddQualityMetricsReporter(...)`][19] API if requried.
67*d9f75844SAndroid Build Coastguard Worker
68*d9f75844SAndroid Build Coastguard WorkerInternally stats gathering is done by [`StatsPoller`][20]. Stats are requested
69*d9f75844SAndroid Build Coastguard Workeronce per second for each `PeerConnection` and then resulted object is provided
70*d9f75844SAndroid Build Coastguard Workerinto each stats listener.
71*d9f75844SAndroid Build Coastguard Worker
72*d9f75844SAndroid Build Coastguard Worker## Offer/Answer exchange
73*d9f75844SAndroid Build Coastguard Worker
74*d9f75844SAndroid Build Coastguard Worker`PeerConnectionE2EQualityTest` provides ability to test Simulcast and SVC for
75*d9f75844SAndroid Build Coastguard Workervideo. These features aren't supported by P2P call and in general requires a
76*d9f75844SAndroid Build Coastguard WorkerSelective Forwarding Unit (SFU). So special logic is applied to mimic SFU
77*d9f75844SAndroid Build Coastguard Workerbehavior in P2P call. This logic is located inside [`SignalingInterceptor`][21],
78*d9f75844SAndroid Build Coastguard Worker[`QualityAnalyzingVideoEncoder`][22] and [`QualityAnalyzingVideoDecoder`][23]
79*d9f75844SAndroid Build Coastguard Workerand consist of SDP modification during offer/answer exchange and special
80*d9f75844SAndroid Build Coastguard Workerhandling of video frames from unrelated Simulcast/SVC streams during decoding.
81*d9f75844SAndroid Build Coastguard Worker
82*d9f75844SAndroid Build Coastguard Worker### Simulcast
83*d9f75844SAndroid Build Coastguard Worker
84*d9f75844SAndroid Build Coastguard WorkerIn case of Simulcast we have a video track, which internally contains multiple
85*d9f75844SAndroid Build Coastguard Workervideo streams, for example low resolution, medium resolution and high
86*d9f75844SAndroid Build Coastguard Workerresolution. WebRTC client doesn't support receiving an offer with multiple
87*d9f75844SAndroid Build Coastguard Workerstreams in it, because usually SFU will keep only single stream for the client.
88*d9f75844SAndroid Build Coastguard WorkerTo bypass it framework will modify offer by converting a single track with three
89*d9f75844SAndroid Build Coastguard Workervideo streams into three independent video tracks. Then sender will think that
90*d9f75844SAndroid Build Coastguard Workerit send simulcast, but receiver will think that it receives 3 independent
91*d9f75844SAndroid Build Coastguard Workertracks.
92*d9f75844SAndroid Build Coastguard Worker
93*d9f75844SAndroid Build Coastguard WorkerTo achieve such behavior some extra tweaks are required:
94*d9f75844SAndroid Build Coastguard Worker
95*d9f75844SAndroid Build Coastguard Worker*   MID RTP header extension from original offer have to be removed
96*d9f75844SAndroid Build Coastguard Worker*   RID RTP header extension from original offer is replaced with MID RTP header
97*d9f75844SAndroid Build Coastguard Worker    extension, so the ID that sender uses for RID on receiver will be parsed as
98*d9f75844SAndroid Build Coastguard Worker    MID.
99*d9f75844SAndroid Build Coastguard Worker*   Answer have to be modified in the opposite way.
100*d9f75844SAndroid Build Coastguard Worker
101*d9f75844SAndroid Build Coastguard WorkerDescribed modifications are illustrated on the picture below.
102*d9f75844SAndroid Build Coastguard Worker
103*d9f75844SAndroid Build Coastguard Worker![VP8 Simulcast offer modification](vp8_simulcast_offer_modification.png "VP8 Simulcast offer modification")
104*d9f75844SAndroid Build Coastguard Worker
105*d9f75844SAndroid Build Coastguard WorkerThe exchange will look like this:
106*d9f75844SAndroid Build Coastguard Worker
107*d9f75844SAndroid Build Coastguard Worker1.  Alice creates an offer
108*d9f75844SAndroid Build Coastguard Worker2.  Alice sets offer as local description
109*d9f75844SAndroid Build Coastguard Worker3.  Do described offer modification
110*d9f75844SAndroid Build Coastguard Worker4.  Alice sends modified offer to Bob
111*d9f75844SAndroid Build Coastguard Worker5.  Bob sets modified offer as remote description
112*d9f75844SAndroid Build Coastguard Worker6.  Bob creates answer
113*d9f75844SAndroid Build Coastguard Worker7.  Bob sets answer as local description
114*d9f75844SAndroid Build Coastguard Worker8.  Do reverse modifications on answer
115*d9f75844SAndroid Build Coastguard Worker9.  Bob sends modified answer to Alice
116*d9f75844SAndroid Build Coastguard Worker10. Alice sets modified answer as remote description
117*d9f75844SAndroid Build Coastguard Worker
118*d9f75844SAndroid Build Coastguard WorkerSuch mechanism put a constraint that RTX streams are not supported, because they
119*d9f75844SAndroid Build Coastguard Workerdon't have RID RTP header extension in their packets.
120*d9f75844SAndroid Build Coastguard Worker
121*d9f75844SAndroid Build Coastguard Worker### SVC
122*d9f75844SAndroid Build Coastguard Worker
123*d9f75844SAndroid Build Coastguard WorkerIn case of SVC the framework will update the sender's offer before even setting
124*d9f75844SAndroid Build Coastguard Workerit as local description on the sender side. Then no changes to answer will be
125*d9f75844SAndroid Build Coastguard Workerrequired.
126*d9f75844SAndroid Build Coastguard Worker
127*d9f75844SAndroid Build Coastguard Worker`ssrc` is a 32 bit random value that is generated in RTP to denote a specific
128*d9f75844SAndroid Build Coastguard Workersource used to send media in an RTP connection. In original offer video track
129*d9f75844SAndroid Build Coastguard Workersection will look like this:
130*d9f75844SAndroid Build Coastguard Worker
131*d9f75844SAndroid Build Coastguard Worker```
132*d9f75844SAndroid Build Coastguard Workerm=video 9 UDP/TLS/RTP/SAVPF 98 100 99 101
133*d9f75844SAndroid Build Coastguard Worker...
134*d9f75844SAndroid Build Coastguard Workera=ssrc-group:FID <primary ssrc> <retransmission ssrc>
135*d9f75844SAndroid Build Coastguard Workera=ssrc:<primary ssrc> cname:...
136*d9f75844SAndroid Build Coastguard Worker....
137*d9f75844SAndroid Build Coastguard Workera=ssrc:<retransmission ssrc> cname:...
138*d9f75844SAndroid Build Coastguard Worker....
139*d9f75844SAndroid Build Coastguard Worker```
140*d9f75844SAndroid Build Coastguard Worker
141*d9f75844SAndroid Build Coastguard WorkerTo enable SVC for such video track framework will add extra `ssrc`s for each SVC
142*d9f75844SAndroid Build Coastguard Workerstream that is required like this:
143*d9f75844SAndroid Build Coastguard Worker
144*d9f75844SAndroid Build Coastguard Worker```
145*d9f75844SAndroid Build Coastguard Workera=ssrc-group:FID <Low resolution primary ssrc> <Low resolution retransmission ssrc>
146*d9f75844SAndroid Build Coastguard Workera=ssrc:<Low resolution primary ssrc> cname:...
147*d9f75844SAndroid Build Coastguard Worker....
148*d9f75844SAndroid Build Coastguard Workera=ssrc:<Low resolution retransmission ssrc> cname:....
149*d9f75844SAndroid Build Coastguard Worker...
150*d9f75844SAndroid Build Coastguard Workera=ssrc-group:FID <Medium resolution primary ssrc> <Medium resolution retransmission ssrc>
151*d9f75844SAndroid Build Coastguard Workera=ssrc:<Medium resolution primary ssrc> cname:...
152*d9f75844SAndroid Build Coastguard Worker....
153*d9f75844SAndroid Build Coastguard Workera=ssrc:<Medium resolution retransmission ssrc> cname:....
154*d9f75844SAndroid Build Coastguard Worker...
155*d9f75844SAndroid Build Coastguard Workera=ssrc-group:FID <High resolution primary ssrc> <High resolution retransmission ssrc>
156*d9f75844SAndroid Build Coastguard Workera=ssrc:<High resolution primary ssrc> cname:...
157*d9f75844SAndroid Build Coastguard Worker....
158*d9f75844SAndroid Build Coastguard Workera=ssrc:<High resolution retransmission ssrc> cname:....
159*d9f75844SAndroid Build Coastguard Worker...
160*d9f75844SAndroid Build Coastguard Worker```
161*d9f75844SAndroid Build Coastguard Worker
162*d9f75844SAndroid Build Coastguard WorkerThe next line will also be added to the video track section of the offer:
163*d9f75844SAndroid Build Coastguard Worker
164*d9f75844SAndroid Build Coastguard Worker```
165*d9f75844SAndroid Build Coastguard Workera=ssrc-group:SIM <Low resolution primary ssrc> <Medium resolution primary ssrc> <High resolution primary ssrc>
166*d9f75844SAndroid Build Coastguard Worker```
167*d9f75844SAndroid Build Coastguard Worker
168*d9f75844SAndroid Build Coastguard WorkerIt will tell PeerConnection that this track should be configured as SVC. It
169*d9f75844SAndroid Build Coastguard Workerutilize WebRTC Plan B offer structure to achieve SVC behavior, also it modifies
170*d9f75844SAndroid Build Coastguard Workeroffer before setting it as local description which violates WebRTC standard.
171*d9f75844SAndroid Build Coastguard WorkerAlso it adds limitations that on lossy networks only top resolution streams can
172*d9f75844SAndroid Build Coastguard Workerbe analyzed, because WebRTC won't try to restore low resolution streams in case
173*d9f75844SAndroid Build Coastguard Workerof loss, because it still receives higher stream.
174*d9f75844SAndroid Build Coastguard Worker
175*d9f75844SAndroid Build Coastguard Worker### Handling in encoder/decoder
176*d9f75844SAndroid Build Coastguard Worker
177*d9f75844SAndroid Build Coastguard WorkerIn the encoder, the framework for each encoded video frame will propagate
178*d9f75844SAndroid Build Coastguard Workerinformation requried for the fake SFU to know if it belongs to an interesting
179*d9f75844SAndroid Build Coastguard Workersimulcast stream/spatial layer of if it should be "discarded".
180*d9f75844SAndroid Build Coastguard Worker
181*d9f75844SAndroid Build Coastguard WorkerOn the decoder side frames that should be "discarded" by fake SFU will be auto
182*d9f75844SAndroid Build Coastguard Workerdecoded into single pixel images and only the interesting simulcast
183*d9f75844SAndroid Build Coastguard Workerstream/spatial layer will go into real decoder and then will be analyzed.
184*d9f75844SAndroid Build Coastguard Worker
185*d9f75844SAndroid Build Coastguard Worker[1]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/api/test/peerconnection_quality_test_fixture.h;l=55;drc=484acf27231d931dbc99aedce85bc27e06486b96
186*d9f75844SAndroid Build Coastguard Worker[2]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/test/pc/e2e/peer_connection_quality_test.h;l=44;drc=6cc893ad778a0965e2b7a8e614f3c98aa81bee5b
187*d9f75844SAndroid Build Coastguard Worker[3]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/test/pc/e2e/media/media_helper.h;l=27;drc=d46db9f1523ae45909b4a6fdc90a140443068bc6
188*d9f75844SAndroid Build Coastguard Worker[4]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.h;l=38;drc=79020414fd5c71f9ec1f25445ea5f1c8001e1a49
189*d9f75844SAndroid Build Coastguard Worker[5]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/test/pc/e2e/analyzer/video/single_process_encoded_image_data_injector.h;l=40;drc=79020414fd5c71f9ec1f25445ea5f1c8001e1a49
190*d9f75844SAndroid Build Coastguard Worker[6]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/api/test/audio_quality_analyzer_interface.h;l=23;drc=20f45823e37fd7272aa841831c029c21f29742c2
191*d9f75844SAndroid Build Coastguard Worker[7]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/test/pc/e2e/test_activities_executor.h;l=28;drc=6cc893ad778a0965e2b7a8e614f3c98aa81bee5b
192*d9f75844SAndroid Build Coastguard Worker[8]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/api/test/peerconnection_quality_test_fixture.h;l=439;drc=484acf27231d931dbc99aedce85bc27e06486b96
193*d9f75844SAndroid Build Coastguard Worker[9]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/api/test/peerconnection_quality_test_fixture.h;l=445;drc=484acf27231d931dbc99aedce85bc27e06486b96
194*d9f75844SAndroid Build Coastguard Worker[10]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/api/test/peerconnection_quality_test_fixture.h;l=413;drc=9438fb3fff97c803d1ead34c0e4f223db168526f
195*d9f75844SAndroid Build Coastguard Worker[11]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/test/pc/e2e/test_activities_executor.h;l=28;drc=6cc893ad778a0965e2b7a8e614f3c98aa81bee5b
196*d9f75844SAndroid Build Coastguard Worker[12]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/test/pc/e2e/test_activities_executor.h;l=28;drc=6cc893ad778a0965e2b7a8e614f3c98aa81bee5b
197*d9f75844SAndroid Build Coastguard Worker[13]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/test/pc/e2e/test_peer_factory.h;l=46;drc=0ef4a2488a466a24ab97b31fdddde55440d451f9
198*d9f75844SAndroid Build Coastguard Worker[14]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/pc/peer_connection_wrapper.h;l=47;drc=5ab79e62f691875a237ea28ca3975ea1f0ed62ec
199*d9f75844SAndroid Build Coastguard Worker[15]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/api/test/peerconnection_quality_test_fixture.h;l=459;drc=484acf27231d931dbc99aedce85bc27e06486b96
200*d9f75844SAndroid Build Coastguard Worker[16]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/api/peer_connection_interface.h;l=886;drc=9438fb3fff97c803d1ead34c0e4f223db168526f
201*d9f75844SAndroid Build Coastguard Worker[17]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/test/pc/e2e/cross_media_metrics_reporter.h;l=29;drc=9d777620236ec76754cfce19f6e82dd18e52d22c
202*d9f75844SAndroid Build Coastguard Worker[18]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/test/pc/e2e/cross_media_metrics_reporter.h;l=29;drc=9d777620236ec76754cfce19f6e82dd18e52d22c
203*d9f75844SAndroid Build Coastguard Worker[19]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/api/test/peerconnection_quality_test_fixture.h;l=450;drc=484acf27231d931dbc99aedce85bc27e06486b96
204*d9f75844SAndroid Build Coastguard Worker[20]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/test/pc/e2e/stats_poller.h;l=52;drc=9b526180c9e9722d3fc7f8689da6ec094fc7fc0a
205*d9f75844SAndroid Build Coastguard Worker[21]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/test/pc/e2e/sdp/sdp_changer.h;l=79;drc=ee558dcca89fd8b105114ededf9e74d948da85e8
206*d9f75844SAndroid Build Coastguard Worker[22]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.h;l=54;drc=79020414fd5c71f9ec1f25445ea5f1c8001e1a49
207*d9f75844SAndroid Build Coastguard Worker[23]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h;l=50;drc=79020414fd5c71f9ec1f25445ea5f1c8001e1a49
208*d9f75844SAndroid Build Coastguard Worker[24]: /test/network/g3doc/index.md
209