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