xref: /aosp_15_r20/external/webrtc/test/pc/e2e/g3doc/default_video_quality_analyzer.md (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1<?% config.freshness.reviewed = '2021-02-21' %?>
2
3# DefaultVideoQualityAnalyzer
4
5## Audience
6
7This document is for users of
8[`webrtc::webrtc_pc_e2e::DefaultVideoQualityAnalyzer`][1].
9
10## Overview
11
12`DefaultVideoQualityAnalyzer` implements
13[`webrtc::VideoQualityAnalyzerInterface`][2] and is a main
14implementation of video quality analyzer for WebRTC. To operate correctly it
15requires to receive video frame on each step:
16
171.  On frame captured - analyzer will generate a unique ID for the frame, that
18    caller should attach to the it.
192.  Immediately before frame enter the encoder.
203.  Immediately after the frame was encoded.
214.  After the frame was received and immediately before it entered the decoder.
225.  Immediately after the frame was decoded.
236.  When the frame was rendered.
24
25![VideoQualityAnalyzerInterface pipeline](video_quality_analyzer_pipeline.png "VideoQualityAnalyzerInterface pipeline")
26
27The analyzer updates its internal metrics per frame when it was rendered and
28reports all of them after it was stopped through
29[WebRTC perf results reporting system][10].
30
31To properly inject `DefaultVideoQualityAnalyzer` into pipeline the following helpers can be used:
32
33### VideoQualityAnalyzerInjectionHelper
34
35[`webrtc::webrtc_pc_e2e::VideoQualityAnalyzerInjectionHelper`][3] provides
36factory methods for components, that will be used to inject
37`VideoQualityAnalyzerInterface` into the `PeerConnection` pipeline:
38
39*   Wrappers for [`webrtc::VideoEncoderFactory`][4] and
40    [`webrtc::VideoDecodeFactory`][5] which will properly pass
41    [`webrtc::VideoFrame`][6] and [`webrtc::EncodedImage`][7] into analyzer
42    before and after real video encode and decoder.
43*   [`webrtc::test::TestVideoCapturer::FramePreprocessor`][8] which is used to
44    pass generated frames into analyzer on capturing and then set the returned
45    frame ID. It also configures dumping of captured frames if requried.
46*   [`rtc::VideoSinkInterface<VideoFrame>`][9] which is used to pass frames to
47    the analyzer before they will be rendered to compute per frame metrics. It
48    also configures dumping of rendered video if requried.
49
50Besides factories `VideoQualityAnalyzerInjectionHelper` has method to
51orchestrate `VideoQualityAnalyzerInterface` workflow:
52
53*   `Start` - to start video analyzer, so it will be able to receive and analyze
54    video frames.
55*   `RegisterParticipantInCall` - to add new participants after analyzer was
56    started.
57*   `Stop` - to stop analyzer, compute all metrics for frames that were recevied
58    before and report them.
59
60Also `VideoQualityAnalyzerInjectionHelper` implements
61[`webrtc::webrtc_pc_e2e::StatsObserverInterface`][11] to propagate WebRTC stats
62to `VideoQualityAnalyzerInterface`.
63
64### EncodedImageDataInjector and EncodedImageDataExtractor
65
66[`webrtc::webrtc_pc_e2e::EncodedImageDataInjector`][14] and
67[`webrtc::webrtc_pc_e2e::EncodedImageDataInjector`][15] are used to inject and
68extract data into `webrtc::EncodedImage` to propagate frame ID and other
69required information through the network.
70
71By default [`webrtc::webrtc_pc_e2e::SingleProcessEncodedImageDataInjector`][16]
72is used. It assumes `webrtc::EncodedImage` payload as black box which is
73remaining unchanged from encoder to decoder and stores the information required
74for its work in the last 3 bytes of the payload, replacing the original data
75during injection and restoring it back during extraction. Also
76`SingleProcessEncodedImageDataInjector` requires that sender and receiver were
77inside single process.
78
79![SingleProcessEncodedImageDataInjector](single_process_encoded_image_data_injector.png "SingleProcessEncodedImageDataInjector")
80
81## Exported metrics
82
83Exported metrics are reported to WebRTC perf results reporting system.
84
85### General
86
87*   *`cpu_usage`* - CPU usage excluding video analyzer
88
89### Video
90
91*   *`psnr`* - peak signal-to-noise ratio:
92    [wikipedia](https://en.wikipedia.org/wiki/Peak_signal-to-noise_ratio)
93*   *`ssim`* - structural similarity:
94    [wikipedia](https://en.wikipedia.org/wiki/Structural_similarity).
95*   *`min_psnr`* - minimum value of psnr across all frames of video stream.
96*   *`encode_time`* - time to encode a single frame.
97*   *`decode_time`* - time to decode a single frame.
98*   *`transport_time`* - time from frame encoded to frame received for decoding.
99*   *`receive_to_render_time`* - time from frame received for decoding to frame
100    rendered.
101*   *`total_delay_incl_transport`* - time from frame was captured on device to
102    time when frame was displayed on device.
103*   *`encode_frame_rate`* - frame rate after encoder.
104*   *`harmonic_framerate`* - video duration divided on squared sum of interframe
105    delays. Reflects render frame rate penalized by freezes.
106*   *`time_between_rendered_frames`* - time between frames out to renderer.
107*   *`dropped_frames`* - amount of frames that were sent, but weren't rendered
108    and are known not to be “on the way” from sender to receiver.
109
110Freeze is a pause when no new frames from decoder arrived for 150ms + avg time
111between frames or 3 * avg time between frames.
112
113*   *`time_between_freezes`* - mean time from previous freeze end to new freeze
114    start.
115*   *`freeze_time_ms`* - total freeze time in ms.
116*   *`max_skipped`* - frames skipped between two nearest rendered.
117*   *`pixels_per_frame`* - amount of pixels on frame (width * height).
118*   *`target_encode_bitrate`* - target encode bitrate provided by BWE to
119    encoder.
120*   *`actual_encode_bitrate -`* - actual encode bitrate produced by encoder.
121*   *`available_send_bandwidth -`* - available send bandwidth estimated by BWE.
122*   *`transmission_bitrate`* - bitrate of media in the emulated network, not
123    counting retransmissions FEC, and RTCP messages
124*   *`retransmission_bitrate`* - bitrate of retransmission streams only.
125
126### Framework stability
127
128*   *`frames_in_flight`* - amount of frames that were captured but wasn't seen
129    on receiver.
130
131## Debug metrics
132
133Debug metrics are not reported to WebRTC perf results reporting system, but are
134available through `DefaultVideoQualityAnalyzer` API.
135
136### [FrameCounters][12]
137
138Frame counters consist of next counters:
139
140*   *`captured`* - count of frames, that were passed into WebRTC pipeline by
141    video stream source
142*   *`pre_encoded`* - count of frames that reached video encoder.
143*   *`encoded`* - count of encoded images that were produced by encoder for all
144    requested spatial layers and simulcast streams.
145*   *`received`* - count of encoded images received in decoder for all requested
146    spatial layers and simulcast streams.
147*   *`decoded`* - count of frames that were produced by decoder.
148*   *`rendered`* - count of frames that went out from WebRTC pipeline to video
149    sink.
150*   *`dropped`* - count of frames that were dropped in any point between
151    capturing and rendering.
152
153`DefaultVideoQualityAnalyzer` exports these frame counters:
154
155*   *`GlobalCounters`* - frame counters for frames met on each stage of analysis
156    for all media streams.
157*   *`PerStreamCounters`* - frame counters for frames met on each stage of
158    analysis separated per individual video track (single media section in the
159    SDP offer).
160
161### [AnalyzerStats][13]
162
163Contains metrics about internal state of video analyzer during its work
164
165*   *`comparisons_queue_size`* - size of analyzer internal queue used to perform
166    captured and rendered frames comparisons measured when new element is added
167    to the queue.
168*   *`comparisons_done`* - number of performed comparisons of 2 video frames
169    from captured and rendered streams.
170*   *`cpu_overloaded_comparisons_done`* - number of cpu overloaded comparisons.
171    Comparison is cpu overloaded if it is queued when there are too many not
172    processed comparisons in the queue. Overloaded comparison doesn't include
173    metrics like SSIM and PSNR that require heavy computations.
174*   *`memory_overloaded_comparisons_done`* - number of memory overloaded
175    comparisons. Comparison is memory overloaded if it is queued when its
176    captured frame was already removed due to high memory usage for that video
177    stream.
178*   *`frames_in_flight_left_count`* - count of frames in flight in analyzer
179    measured when new comparison is added and after analyzer was stopped.
180
181[1]: https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h;l=188;drc=08f46909a8735cf181b99ef2f7e1791c5a7531d2
182[2]: https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/api/test/video_quality_analyzer_interface.h;l=56;drc=d7808f1c464a07c8f1e2f97ec7ee92fda998d590
183[3]: https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.h;l=39;drc=08f46909a8735cf181b99ef2f7e1791c5a7531d2
184[4]: https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/api/video_codecs/video_encoder_factory.h;l=27;drc=08f46909a8735cf181b99ef2f7e1791c5a7531d2
185[5]: https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/api/video_codecs/video_decoder_factory.h;l=27;drc=08f46909a8735cf181b99ef2f7e1791c5a7531d2
186[6]: https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/api/video/video_frame.h;l=30;drc=08f46909a8735cf181b99ef2f7e1791c5a7531d2
187[7]: https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/api/video/encoded_image.h;l=71;drc=08f46909a8735cf181b99ef2f7e1791c5a7531d2
188[8]: https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/test/test_video_capturer.h;l=28;drc=08f46909a8735cf181b99ef2f7e1791c5a7531d2
189[9]: https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/api/video/video_sink_interface.h;l=19;drc=08f46909a8735cf181b99ef2f7e1791c5a7531d2
190[10]: https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/test/testsupport/perf_test.h;drc=0710b401b1e5b500b8e84946fb657656ba1b58b7
191[11]: https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/api/test/stats_observer_interface.h;l=21;drc=9b526180c9e9722d3fc7f8689da6ec094fc7fc0a
192[12]: https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h;l=57;drc=08f46909a8735cf181b99ef2f7e1791c5a7531d2
193[13]: https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h;l=113;drc=08f46909a8735cf181b99ef2f7e1791c5a7531d2
194[14]: https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/test/pc/e2e/analyzer/video/encoded_image_data_injector.h;l=23;drc=c57089a97a3df454f4356d882cc8df173e8b3ead
195[15]: https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/test/pc/e2e/analyzer/video/encoded_image_data_injector.h;l=46;drc=c57089a97a3df454f4356d882cc8df173e8b3ead
196[16]: https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/test/pc/e2e/analyzer/video/single_process_encoded_image_data_injector.h;l=40;drc=c57089a97a3df454f4356d882cc8df173e8b3ead
197