xref: /aosp_15_r20/external/webrtc/api/test/video_quality_analyzer_interface.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef API_TEST_VIDEO_QUALITY_ANALYZER_INTERFACE_H_
12 #define API_TEST_VIDEO_QUALITY_ANALYZER_INTERFACE_H_
13 
14 #include <memory>
15 #include <string>
16 
17 #include "absl/strings/string_view.h"
18 #include "absl/types/optional.h"
19 #include "api/array_view.h"
20 #include "api/test/stats_observer_interface.h"
21 #include "api/video/encoded_image.h"
22 #include "api/video/video_frame.h"
23 #include "api/video_codecs/video_encoder.h"
24 
25 namespace webrtc {
26 
27 // API is in development and can be changed without notice.
28 
29 // Base interface for video quality analyzer for peer connection level end-2-end
30 // tests. Interface has only one abstract method, which have to return frame id.
31 // Other methods have empty implementation by default, so user can override only
32 // required parts.
33 //
34 // VideoQualityAnalyzerInterface will be injected into WebRTC pipeline on both
35 // sides of the call. Here is video data flow in WebRTC pipeline
36 //
37 // Alice:
38 //  ___________       ________       _________
39 // |           |     |        |     |         |
40 // |   Frame   |-(A)→| WebRTC |-(B)→| Video   |-(C)┐
41 // | Generator |     | Stack  |     | Decoder |    |
42 //  ¯¯¯¯¯¯¯¯¯¯¯       ¯¯¯¯¯¯¯¯       ¯¯¯¯¯¯¯¯¯     |
43 //                                               __↓________
44 //                                              | Transport |
45 //                                              |     &     |
46 //                                              |  Network  |
47 //                                               ¯¯|¯¯¯¯¯¯¯¯
48 // Bob:                                            |
49 //  _______       ________       _________         |
50 // |       |     |        |     |         |        |
51 // | Video |←(F)-| WebRTC |←(E)-| Video   |←(D)----┘
52 // | Sink  |     | Stack  |     | Decoder |
53 //  ¯¯¯¯¯¯¯       ¯¯¯¯¯¯¯¯       ¯¯¯¯¯¯¯¯¯
54 // The analyzer will be injected in all points from A to F.
55 class VideoQualityAnalyzerInterface
56     : public webrtc_pc_e2e::StatsObserverInterface {
57  public:
58   // Contains extra statistic provided by video encoder.
59   struct EncoderStats {
60     std::string encoder_name = "unknown";
61     // TODO(hbos) https://crbug.com/webrtc/9547,
62     // https://crbug.com/webrtc/11443: improve stats API to make available
63     // there.
64     uint32_t target_encode_bitrate = 0;
65     // Encoder quantizer value.
66     int qp = -1;
67   };
68   // Contains extra statistic provided by video decoder.
69   struct DecoderStats {
70     std::string decoder_name = "unknown";
71     // Decode time provided by decoder itself. If decoder doesn’t produce such
72     // information can be omitted.
73     absl::optional<int32_t> decode_time_ms = absl::nullopt;
74   };
75 
76   ~VideoQualityAnalyzerInterface() override = default;
77 
78   // Will be called by framework before test.
79   // `test_case_name` is name of test case, that should be used to report all
80   // video metrics.
81   // `threads_count` is number of threads that analyzer can use for heavy
82   // calculations. Analyzer can perform simple calculations on the calling
83   // thread in each method, but should remember, that it is the same thread,
84   // that is used in video pipeline.
Start(std::string test_case_name,rtc::ArrayView<const std::string> peer_names,int max_threads_count)85   virtual void Start(std::string test_case_name,
86                      rtc::ArrayView<const std::string> peer_names,
87                      int max_threads_count) {}
88 
89   // Will be called when frame was generated from the input stream.
90   // `peer_name` is name of the peer on which side frame was captured.
91   // Returns frame id, that will be set by framework to the frame.
92   virtual uint16_t OnFrameCaptured(absl::string_view peer_name,
93                                    const std::string& stream_label,
94                                    const VideoFrame& frame) = 0;
95   // Will be called before calling the encoder.
96   // `peer_name` is name of the peer on which side frame came to encoder.
OnFramePreEncode(absl::string_view peer_name,const VideoFrame & frame)97   virtual void OnFramePreEncode(absl::string_view peer_name,
98                                 const VideoFrame& frame) {}
99   // Will be called for each EncodedImage received from encoder. Single
100   // VideoFrame can produce multiple EncodedImages. Each encoded image will
101   // have id from VideoFrame.
102   // `peer_name` is name of the peer on which side frame was encoded.
OnFrameEncoded(absl::string_view peer_name,uint16_t frame_id,const EncodedImage & encoded_image,const EncoderStats & stats,bool discarded)103   virtual void OnFrameEncoded(absl::string_view peer_name,
104                               uint16_t frame_id,
105                               const EncodedImage& encoded_image,
106                               const EncoderStats& stats,
107                               bool discarded) {}
108   // Will be called for each frame dropped by encoder.
109   // `peer_name` is name of the peer on which side frame drop was detected.
OnFrameDropped(absl::string_view peer_name,EncodedImageCallback::DropReason reason)110   virtual void OnFrameDropped(absl::string_view peer_name,
111                               EncodedImageCallback::DropReason reason) {}
112   // Will be called before calling the decoder.
113   // `peer_name` is name of the peer on which side frame was received.
OnFramePreDecode(absl::string_view peer_name,uint16_t frame_id,const EncodedImage & encoded_image)114   virtual void OnFramePreDecode(absl::string_view peer_name,
115                                 uint16_t frame_id,
116                                 const EncodedImage& encoded_image) {}
117   // Will be called after decoding the frame.
118   // `peer_name` is name of the peer on which side frame was decoded.
OnFrameDecoded(absl::string_view peer_name,const VideoFrame & frame,const DecoderStats & stats)119   virtual void OnFrameDecoded(absl::string_view peer_name,
120                               const VideoFrame& frame,
121                               const DecoderStats& stats) {}
122   // Will be called when frame will be obtained from PeerConnection stack.
123   // `peer_name` is name of the peer on which side frame was rendered.
OnFrameRendered(absl::string_view peer_name,const VideoFrame & frame)124   virtual void OnFrameRendered(absl::string_view peer_name,
125                                const VideoFrame& frame) {}
126   // Will be called if encoder return not WEBRTC_VIDEO_CODEC_OK.
127   // All available codes are listed in
128   // modules/video_coding/include/video_error_codes.h
129   // `peer_name` is name of the peer on which side error acquired.
OnEncoderError(absl::string_view peer_name,const VideoFrame & frame,int32_t error_code)130   virtual void OnEncoderError(absl::string_view peer_name,
131                               const VideoFrame& frame,
132                               int32_t error_code) {}
133   // Will be called if decoder return not WEBRTC_VIDEO_CODEC_OK.
134   // All available codes are listed in
135   // modules/video_coding/include/video_error_codes.h
136   // `peer_name` is name of the peer on which side error acquired.
OnDecoderError(absl::string_view peer_name,uint16_t frame_id,int32_t error_code,const DecoderStats & stats)137   virtual void OnDecoderError(absl::string_view peer_name,
138                               uint16_t frame_id,
139                               int32_t error_code,
140                               const DecoderStats& stats) {}
141   // Will be called every time new stats reports are available for the
142   // Peer Connection identified by `pc_label`.
OnStatsReports(absl::string_view pc_label,const rtc::scoped_refptr<const RTCStatsReport> & report)143   void OnStatsReports(
144       absl::string_view pc_label,
145       const rtc::scoped_refptr<const RTCStatsReport>& report) override {}
146 
147   // Will be called before test adds new participant in the middle of a call.
RegisterParticipantInCall(absl::string_view peer_name)148   virtual void RegisterParticipantInCall(absl::string_view peer_name) {}
149   // Will be called after test removed existing participant in the middle of the
150   // call.
UnregisterParticipantInCall(absl::string_view peer_name)151   virtual void UnregisterParticipantInCall(absl::string_view peer_name) {}
152 
153   // Tells analyzer that analysis complete and it should calculate final
154   // statistics.
Stop()155   virtual void Stop() {}
156 
157   // Returns the last stream where this frame was captured. It means that if
158   // frame ids space wraps around, then stream label for frame id may change.
159   // It will crash, if the specified `frame_id` wasn't captured.
160   virtual std::string GetStreamLabel(uint16_t frame_id) = 0;
161 };
162 
163 }  // namespace webrtc
164 
165 #endif  // API_TEST_VIDEO_QUALITY_ANALYZER_INTERFACE_H_
166