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 namespace webrtc_pc_e2e { 27 28 // API is in development and can be changed without notice. 29 30 // Base interface for video quality analyzer for peer connection level end-2-end 31 // tests. Interface has only one abstract method, which have to return frame id. 32 // Other methods have empty implementation by default, so user can override only 33 // required parts. 34 // 35 // VideoQualityAnalyzerInterface will be injected into WebRTC pipeline on both 36 // sides of the call. Here is video data flow in WebRTC pipeline 37 // 38 // Alice: 39 // ___________ ________ _________ 40 // | | | | | | 41 // | Frame |-(A)→| WebRTC |-(B)→| Video |-(C)┐ 42 // | Generator | | Stack | | Decoder | | 43 // ¯¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯ | 44 // __↓________ 45 // | Transport | 46 // | & | 47 // | Network | 48 // ¯¯|¯¯¯¯¯¯¯¯ 49 // Bob: | 50 // _______ ________ _________ | 51 // | | | | | | | 52 // | Video |←(F)-| WebRTC |←(E)-| Video |←(D)----┘ 53 // | Sink | | Stack | | Decoder | 54 // ¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯ 55 // The analyzer will be injected in all points from A to F. 56 class VideoQualityAnalyzerInterface : public StatsObserverInterface { 57 public: 58 // Contains extra statistic provided by video encoder. 59 struct EncoderStats { 60 // TODO(hbos) https://crbug.com/webrtc/9547, 61 // https://crbug.com/webrtc/11443: improve stats API to make available 62 // there. 63 uint32_t target_encode_bitrate; 64 }; 65 // Contains extra statistic provided by video decoder. 66 struct DecoderStats { 67 // Decode time provided by decoder itself. If decoder doesn’t produce such 68 // information can be omitted. 69 absl::optional<int32_t> decode_time_ms; 70 }; 71 72 ~VideoQualityAnalyzerInterface() override = default; 73 74 // Will be called by framework before test. 75 // |test_case_name| is name of test case, that should be used to report all 76 // video metrics. 77 // |threads_count| is number of threads that analyzer can use for heavy 78 // calculations. Analyzer can perform simple calculations on the calling 79 // thread in each method, but should remember, that it is the same thread, 80 // that is used in video pipeline. Start(std::string test_case_name,rtc::ArrayView<const std::string> peer_names,int max_threads_count)81 virtual void Start(std::string test_case_name, 82 rtc::ArrayView<const std::string> peer_names, 83 int max_threads_count) {} 84 85 // Will be called when frame was generated from the input stream. 86 // |peer_name| is name of the peer on which side frame was captured. 87 // Returns frame id, that will be set by framework to the frame. 88 virtual uint16_t OnFrameCaptured(absl::string_view peer_name, 89 const std::string& stream_label, 90 const VideoFrame& frame) = 0; 91 // Will be called before calling the encoder. 92 // |peer_name| is name of the peer on which side frame came to encoder. OnFramePreEncode(absl::string_view peer_name,const VideoFrame & frame)93 virtual void OnFramePreEncode(absl::string_view peer_name, 94 const VideoFrame& frame) {} 95 // Will be called for each EncodedImage received from encoder. Single 96 // VideoFrame can produce multiple EncodedImages. Each encoded image will 97 // have id from VideoFrame. 98 // |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)99 virtual void OnFrameEncoded(absl::string_view peer_name, 100 uint16_t frame_id, 101 const EncodedImage& encoded_image, 102 const EncoderStats& stats) {} 103 // Will be called for each frame dropped by encoder. 104 // |peer_name| is name of the peer on which side frame drop was detected. OnFrameDropped(absl::string_view peer_name,EncodedImageCallback::DropReason reason)105 virtual void OnFrameDropped(absl::string_view peer_name, 106 EncodedImageCallback::DropReason reason) {} 107 // Will be called before calling the decoder. 108 // |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)109 virtual void OnFramePreDecode(absl::string_view peer_name, 110 uint16_t frame_id, 111 const EncodedImage& encoded_image) {} 112 // Will be called after decoding the frame. 113 // |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)114 virtual void OnFrameDecoded(absl::string_view peer_name, 115 const VideoFrame& frame, 116 const DecoderStats& stats) {} 117 // Will be called when frame will be obtained from PeerConnection stack. 118 // |peer_name| is name of the peer on which side frame was rendered. OnFrameRendered(absl::string_view peer_name,const VideoFrame & frame)119 virtual void OnFrameRendered(absl::string_view peer_name, 120 const VideoFrame& frame) {} 121 // Will be called if encoder return not WEBRTC_VIDEO_CODEC_OK. 122 // All available codes are listed in 123 // modules/video_coding/include/video_error_codes.h 124 // |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)125 virtual void OnEncoderError(absl::string_view peer_name, 126 const VideoFrame& frame, 127 int32_t error_code) {} 128 // Will be called if decoder return not WEBRTC_VIDEO_CODEC_OK. 129 // All available codes are listed in 130 // modules/video_coding/include/video_error_codes.h 131 // |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)132 virtual void OnDecoderError(absl::string_view peer_name, 133 uint16_t frame_id, 134 int32_t error_code) {} 135 // Will be called every time new stats reports are available for the 136 // Peer Connection identified by |pc_label|. OnStatsReports(absl::string_view pc_label,const rtc::scoped_refptr<const RTCStatsReport> & report)137 void OnStatsReports( 138 absl::string_view pc_label, 139 const rtc::scoped_refptr<const RTCStatsReport>& report) override {} 140 141 // Tells analyzer that analysis complete and it should calculate final 142 // statistics. Stop()143 virtual void Stop() {} 144 145 virtual std::string GetStreamLabel(uint16_t frame_id) = 0; 146 }; 147 148 } // namespace webrtc_pc_e2e 149 } // namespace webrtc 150 151 #endif // API_TEST_VIDEO_QUALITY_ANALYZER_INTERFACE_H_ 152