Artem Titov | b6c6201 | 2019-01-08 14:58:23 +0100 | [diff] [blame] | 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 | |
Artem Titov | d57628f | 2019-03-22 12:34:25 +0100 | [diff] [blame] | 11 | #ifndef API_TEST_VIDEO_QUALITY_ANALYZER_INTERFACE_H_ |
| 12 | #define API_TEST_VIDEO_QUALITY_ANALYZER_INTERFACE_H_ |
Artem Titov | b6c6201 | 2019-01-08 14:58:23 +0100 | [diff] [blame] | 13 | |
| 14 | #include <memory> |
| 15 | #include <string> |
| 16 | |
Artem Titov | 8a0284e | 2020-05-29 15:49:44 +0200 | [diff] [blame] | 17 | #include "absl/strings/string_view.h" |
Artem Titov | b6c6201 | 2019-01-08 14:58:23 +0100 | [diff] [blame] | 18 | #include "absl/types/optional.h" |
Artem Titov | 3b64167 | 2020-06-02 17:18:17 +0200 | [diff] [blame] | 19 | #include "api/array_view.h" |
Artem Titov | d57628f | 2019-03-22 12:34:25 +0100 | [diff] [blame] | 20 | #include "api/test/stats_observer_interface.h" |
Artem Titov | b6c6201 | 2019-01-08 14:58:23 +0100 | [diff] [blame] | 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 { |
Artem Titov | 0b44314 | 2019-03-20 11:11:08 +0100 | [diff] [blame] | 26 | namespace webrtc_pc_e2e { |
Artem Titov | b6c6201 | 2019-01-08 14:58:23 +0100 | [diff] [blame] | 27 | |
Artem Titov | d57628f | 2019-03-22 12:34:25 +0100 | [diff] [blame] | 28 | // API is in development and can be changed without notice. |
| 29 | |
Artem Titov | ebd9770 | 2019-01-09 17:55:36 +0100 | [diff] [blame] | 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. |
Mirko Bonadei | 12ae4f4 | 2019-02-26 15:19:07 +0100 | [diff] [blame] | 56 | class VideoQualityAnalyzerInterface : public StatsObserverInterface { |
Artem Titov | b6c6201 | 2019-01-08 14:58:23 +0100 | [diff] [blame] | 57 | public: |
Artem Titov | d19513f | 2020-03-25 11:53:41 +0100 | [diff] [blame] | 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 | |
Mirko Bonadei | 12ae4f4 | 2019-02-26 15:19:07 +0100 | [diff] [blame] | 72 | ~VideoQualityAnalyzerInterface() override = default; |
Artem Titov | b6c6201 | 2019-01-08 14:58:23 +0100 | [diff] [blame] | 73 | |
Artem Titov | 5983585 | 2019-02-27 17:44:13 +0100 | [diff] [blame] | 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. |
Artem Titov | 3b64167 | 2020-06-02 17:18:17 +0200 | [diff] [blame] | 81 | virtual void Start(std::string test_case_name, |
| 82 | rtc::ArrayView<const std::string> peer_names, |
| 83 | int max_threads_count) {} |
Artem Titov | b6c6201 | 2019-01-08 14:58:23 +0100 | [diff] [blame] | 84 | |
| 85 | // Will be called when frame was generated from the input stream. |
Artem Titov | 8a0284e | 2020-05-29 15:49:44 +0200 | [diff] [blame] | 86 | // |peer_name| is name of the peer on which side frame was captured. |
Artem Titov | b6c6201 | 2019-01-08 14:58:23 +0100 | [diff] [blame] | 87 | // Returns frame id, that will be set by framework to the frame. |
Andrey Logvin | 8d4cdd1 | 2020-12-01 19:32:53 +0000 | [diff] [blame] | 88 | // absl::nullopt is returned if analyzer has ignored the frame. |
| 89 | virtual absl::optional<uint16_t> OnFrameCaptured( |
| 90 | absl::string_view peer_name, |
| 91 | const std::string& stream_label, |
| 92 | const VideoFrame& frame) = 0; |
Artem Titov | ebd9770 | 2019-01-09 17:55:36 +0100 | [diff] [blame] | 93 | // Will be called before calling the encoder. |
Artem Titov | 8a0284e | 2020-05-29 15:49:44 +0200 | [diff] [blame] | 94 | // |peer_name| is name of the peer on which side frame came to encoder. |
| 95 | virtual void OnFramePreEncode(absl::string_view peer_name, |
| 96 | const VideoFrame& frame) {} |
Artem Titov | b6c6201 | 2019-01-08 14:58:23 +0100 | [diff] [blame] | 97 | // Will be called for each EncodedImage received from encoder. Single |
| 98 | // VideoFrame can produce multiple EncodedImages. Each encoded image will |
| 99 | // have id from VideoFrame. |
Artem Titov | 8a0284e | 2020-05-29 15:49:44 +0200 | [diff] [blame] | 100 | // |peer_name| is name of the peer on which side frame was encoded. |
| 101 | virtual void OnFrameEncoded(absl::string_view peer_name, |
| 102 | uint16_t frame_id, |
Artem Titov | d19513f | 2020-03-25 11:53:41 +0100 | [diff] [blame] | 103 | const EncodedImage& encoded_image, |
| 104 | const EncoderStats& stats) {} |
Artem Titov | b6c6201 | 2019-01-08 14:58:23 +0100 | [diff] [blame] | 105 | // Will be called for each frame dropped by encoder. |
Artem Titov | 8a0284e | 2020-05-29 15:49:44 +0200 | [diff] [blame] | 106 | // |peer_name| is name of the peer on which side frame drop was detected. |
| 107 | virtual void OnFrameDropped(absl::string_view peer_name, |
| 108 | EncodedImageCallback::DropReason reason) {} |
Artem Titov | ebd9770 | 2019-01-09 17:55:36 +0100 | [diff] [blame] | 109 | // Will be called before calling the decoder. |
Artem Titov | 8a0284e | 2020-05-29 15:49:44 +0200 | [diff] [blame] | 110 | // |peer_name| is name of the peer on which side frame was received. |
| 111 | virtual void OnFramePreDecode(absl::string_view peer_name, |
| 112 | uint16_t frame_id, |
Johannes Kron | c12db81 | 2019-09-19 13:20:01 +0200 | [diff] [blame] | 113 | const EncodedImage& encoded_image) {} |
Artem Titov | d19513f | 2020-03-25 11:53:41 +0100 | [diff] [blame] | 114 | // Will be called after decoding the frame. |
Artem Titov | 8a0284e | 2020-05-29 15:49:44 +0200 | [diff] [blame] | 115 | // |peer_name| is name of the peer on which side frame was decoded. |
| 116 | virtual void OnFrameDecoded(absl::string_view peer_name, |
| 117 | const VideoFrame& frame, |
Artem Titov | d19513f | 2020-03-25 11:53:41 +0100 | [diff] [blame] | 118 | const DecoderStats& stats) {} |
Artem Titov | b6c6201 | 2019-01-08 14:58:23 +0100 | [diff] [blame] | 119 | // Will be called when frame will be obtained from PeerConnection stack. |
Artem Titov | 8a0284e | 2020-05-29 15:49:44 +0200 | [diff] [blame] | 120 | // |peer_name| is name of the peer on which side frame was rendered. |
| 121 | virtual void OnFrameRendered(absl::string_view peer_name, |
| 122 | const VideoFrame& frame) {} |
Artem Titov | ebd9770 | 2019-01-09 17:55:36 +0100 | [diff] [blame] | 123 | // Will be called if encoder return not WEBRTC_VIDEO_CODEC_OK. |
| 124 | // All available codes are listed in |
| 125 | // modules/video_coding/include/video_error_codes.h |
Artem Titov | 8a0284e | 2020-05-29 15:49:44 +0200 | [diff] [blame] | 126 | // |peer_name| is name of the peer on which side error acquired. |
| 127 | virtual void OnEncoderError(absl::string_view peer_name, |
| 128 | const VideoFrame& frame, |
| 129 | int32_t error_code) {} |
Artem Titov | ebd9770 | 2019-01-09 17:55:36 +0100 | [diff] [blame] | 130 | // Will be called if decoder return not WEBRTC_VIDEO_CODEC_OK. |
| 131 | // All available codes are listed in |
| 132 | // modules/video_coding/include/video_error_codes.h |
Artem Titov | 8a0284e | 2020-05-29 15:49:44 +0200 | [diff] [blame] | 133 | // |peer_name| is name of the peer on which side error acquired. |
| 134 | virtual void OnDecoderError(absl::string_view peer_name, |
| 135 | uint16_t frame_id, |
| 136 | int32_t error_code) {} |
Artem Titov | a854921 | 2019-08-19 14:38:06 +0200 | [diff] [blame] | 137 | // Will be called every time new stats reports are available for the |
Mirko Bonadei | 12ae4f4 | 2019-02-26 15:19:07 +0100 | [diff] [blame] | 138 | // Peer Connection identified by |pc_label|. |
Andrey Logvin | 9b52618 | 2020-06-15 16:14:07 +0000 | [diff] [blame] | 139 | void OnStatsReports( |
| 140 | absl::string_view pc_label, |
| 141 | const rtc::scoped_refptr<const RTCStatsReport>& report) override {} |
Artem Titov | b6c6201 | 2019-01-08 14:58:23 +0100 | [diff] [blame] | 142 | |
Artem Titov | ebd9770 | 2019-01-09 17:55:36 +0100 | [diff] [blame] | 143 | // Tells analyzer that analysis complete and it should calculate final |
Artem Titov | b6c6201 | 2019-01-08 14:58:23 +0100 | [diff] [blame] | 144 | // statistics. |
| 145 | virtual void Stop() {} |
Artem Titov | 32232e9 | 2019-02-20 21:13:14 +0100 | [diff] [blame] | 146 | |
| 147 | virtual std::string GetStreamLabel(uint16_t frame_id) = 0; |
Artem Titov | b6c6201 | 2019-01-08 14:58:23 +0100 | [diff] [blame] | 148 | }; |
| 149 | |
Artem Titov | 0b44314 | 2019-03-20 11:11:08 +0100 | [diff] [blame] | 150 | } // namespace webrtc_pc_e2e |
Artem Titov | b6c6201 | 2019-01-08 14:58:23 +0100 | [diff] [blame] | 151 | } // namespace webrtc |
| 152 | |
Artem Titov | d57628f | 2019-03-22 12:34:25 +0100 | [diff] [blame] | 153 | #endif // API_TEST_VIDEO_QUALITY_ANALYZER_INTERFACE_H_ |