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