Sebastian Jansson | 9a4f38e | 2018-12-19 13:14:41 +0100 | [diff] [blame] | 1 | /* |
Sebastian Jansson | 7150d8c | 2019-04-09 14:18:09 +0200 | [diff] [blame] | 2 | * Copyright 2019 The WebRTC project authors. All Rights Reserved. |
Sebastian Jansson | 9a4f38e | 2018-12-19 13:14:41 +0100 | [diff] [blame] | 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 | */ |
Sebastian Jansson | 7150d8c | 2019-04-09 14:18:09 +0200 | [diff] [blame] | 10 | #ifndef TEST_SCENARIO_PERFORMANCE_STATS_H_ |
| 11 | #define TEST_SCENARIO_PERFORMANCE_STATS_H_ |
Sebastian Jansson | 9a4f38e | 2018-12-19 13:14:41 +0100 | [diff] [blame] | 12 | |
Sebastian Jansson | 7150d8c | 2019-04-09 14:18:09 +0200 | [diff] [blame] | 13 | #include "api/units/data_rate.h" |
| 14 | #include "api/units/time_delta.h" |
Sebastian Jansson | 9a4f38e | 2018-12-19 13:14:41 +0100 | [diff] [blame] | 15 | #include "api/units/timestamp.h" |
Sebastian Jansson | cf2df2f | 2019-04-02 11:51:28 +0200 | [diff] [blame] | 16 | #include "api/video/video_frame_buffer.h" |
Sebastian Jansson | 9a2ca0a | 2019-04-15 13:18:19 +0200 | [diff] [blame] | 17 | #include "rtc_base/numerics/samples_stats_counter.h" |
Sebastian Jansson | 9a4f38e | 2018-12-19 13:14:41 +0100 | [diff] [blame] | 18 | |
| 19 | namespace webrtc { |
| 20 | namespace test { |
Sebastian Jansson | 7150d8c | 2019-04-09 14:18:09 +0200 | [diff] [blame] | 21 | |
Sebastian Jansson | cf2df2f | 2019-04-02 11:51:28 +0200 | [diff] [blame] | 22 | struct VideoFramePair { |
Sebastian Jansson | 7150d8c | 2019-04-09 14:18:09 +0200 | [diff] [blame] | 23 | rtc::scoped_refptr<VideoFrameBuffer> captured; |
| 24 | rtc::scoped_refptr<VideoFrameBuffer> decoded; |
Sebastian Jansson | cf2df2f | 2019-04-02 11:51:28 +0200 | [diff] [blame] | 25 | Timestamp capture_time = Timestamp::MinusInfinity(); |
Sebastian Jansson | e9cac4f | 2019-06-24 17:10:55 +0200 | [diff] [blame] | 26 | Timestamp decoded_time = Timestamp::PlusInfinity(); |
Sebastian Jansson | cf2df2f | 2019-04-02 11:51:28 +0200 | [diff] [blame] | 27 | Timestamp render_time = Timestamp::PlusInfinity(); |
| 28 | // A unique identifier for the spatial/temporal layer the decoded frame |
| 29 | // belongs to. Note that this does not reflect the id as defined by the |
| 30 | // underlying layer setup. |
| 31 | int layer_id = 0; |
| 32 | int capture_id = 0; |
| 33 | int decode_id = 0; |
| 34 | // Indicates the repeat count for the decoded frame. Meaning that the same |
| 35 | // decoded frame has matched differend captured frames. |
| 36 | int repeated = 0; |
Sebastian Jansson | 9a4f38e | 2018-12-19 13:14:41 +0100 | [diff] [blame] | 37 | }; |
Sebastian Jansson | 7150d8c | 2019-04-09 14:18:09 +0200 | [diff] [blame] | 38 | |
Sebastian Jansson | 9a2ca0a | 2019-04-15 13:18:19 +0200 | [diff] [blame] | 39 | template <typename T> |
| 40 | class SampleStats; |
| 41 | |
| 42 | template <> |
| 43 | class SampleStats<double> : public SamplesStatsCounter { |
| 44 | public: |
| 45 | double Max(); |
| 46 | double Mean(); |
| 47 | double Median(); |
| 48 | double Quantile(double quantile); |
| 49 | double Min(); |
| 50 | double Variance(); |
| 51 | double StandardDeviation(); |
Sebastian Jansson | e9cac4f | 2019-06-24 17:10:55 +0200 | [diff] [blame] | 52 | int Count(); |
Sebastian Jansson | 9a2ca0a | 2019-04-15 13:18:19 +0200 | [diff] [blame] | 53 | }; |
| 54 | |
| 55 | template <> |
| 56 | class SampleStats<TimeDelta> { |
| 57 | public: |
| 58 | void AddSample(TimeDelta delta); |
| 59 | void AddSampleMs(double delta_ms); |
| 60 | void AddSamples(const SampleStats<TimeDelta>& other); |
Sebastian Jansson | 8abcf83 | 2019-05-21 10:13:06 +0200 | [diff] [blame] | 61 | bool IsEmpty(); |
Sebastian Jansson | 9a2ca0a | 2019-04-15 13:18:19 +0200 | [diff] [blame] | 62 | TimeDelta Max(); |
| 63 | TimeDelta Mean(); |
| 64 | TimeDelta Median(); |
| 65 | TimeDelta Quantile(double quantile); |
| 66 | TimeDelta Min(); |
| 67 | TimeDelta Variance(); |
| 68 | TimeDelta StandardDeviation(); |
Sebastian Jansson | e9cac4f | 2019-06-24 17:10:55 +0200 | [diff] [blame] | 69 | int Count(); |
Sebastian Jansson | 9a2ca0a | 2019-04-15 13:18:19 +0200 | [diff] [blame] | 70 | |
| 71 | private: |
| 72 | SampleStats<double> stats_; |
| 73 | }; |
| 74 | |
| 75 | template <> |
| 76 | class SampleStats<DataRate> { |
| 77 | public: |
| 78 | void AddSample(DataRate rate); |
| 79 | void AddSampleBps(double rate_bps); |
| 80 | void AddSamples(const SampleStats<DataRate>& other); |
Sebastian Jansson | 8abcf83 | 2019-05-21 10:13:06 +0200 | [diff] [blame] | 81 | bool IsEmpty(); |
Sebastian Jansson | 9a2ca0a | 2019-04-15 13:18:19 +0200 | [diff] [blame] | 82 | DataRate Max(); |
| 83 | DataRate Mean(); |
| 84 | DataRate Median(); |
| 85 | DataRate Quantile(double quantile); |
| 86 | DataRate Min(); |
| 87 | DataRate Variance(); |
| 88 | DataRate StandardDeviation(); |
Sebastian Jansson | e9cac4f | 2019-06-24 17:10:55 +0200 | [diff] [blame] | 89 | int Count(); |
Sebastian Jansson | 9a2ca0a | 2019-04-15 13:18:19 +0200 | [diff] [blame] | 90 | |
| 91 | private: |
| 92 | SampleStats<double> stats_; |
| 93 | }; |
| 94 | |
| 95 | class EventRateCounter { |
| 96 | public: |
| 97 | void AddEvent(Timestamp event_time); |
| 98 | void AddEvents(EventRateCounter other); |
| 99 | bool IsEmpty() const; |
| 100 | double Rate() const; |
| 101 | SampleStats<TimeDelta>& interval() { return interval_; } |
Evan Shrubsole | 9ddd729 | 2019-10-09 10:37:09 +0200 | [diff] [blame] | 102 | TimeDelta TotalDuration() const; |
Sebastian Jansson | e9cac4f | 2019-06-24 17:10:55 +0200 | [diff] [blame] | 103 | int Count() const { return event_count_; } |
Sebastian Jansson | 9a2ca0a | 2019-04-15 13:18:19 +0200 | [diff] [blame] | 104 | |
| 105 | private: |
| 106 | Timestamp first_time_ = Timestamp::PlusInfinity(); |
| 107 | Timestamp last_time_ = Timestamp::MinusInfinity(); |
| 108 | int64_t event_count_ = 0; |
| 109 | SampleStats<TimeDelta> interval_; |
| 110 | }; |
| 111 | |
| 112 | struct VideoFramesStats { |
| 113 | int count = 0; |
| 114 | SampleStats<double> pixels; |
| 115 | SampleStats<double> resolution; |
| 116 | EventRateCounter frames; |
| 117 | void AddFrameInfo(const VideoFrameBuffer& frame, Timestamp at_time); |
| 118 | void AddStats(const VideoFramesStats& other); |
| 119 | }; |
| 120 | |
Sebastian Jansson | 7150d8c | 2019-04-09 14:18:09 +0200 | [diff] [blame] | 121 | struct VideoQualityStats { |
Sebastian Jansson | 7150d8c | 2019-04-09 14:18:09 +0200 | [diff] [blame] | 122 | int lost_count = 0; |
Sebastian Jansson | 9a2ca0a | 2019-04-15 13:18:19 +0200 | [diff] [blame] | 123 | int freeze_count = 0; |
| 124 | VideoFramesStats capture; |
| 125 | VideoFramesStats render; |
Sebastian Jansson | e9cac4f | 2019-06-24 17:10:55 +0200 | [diff] [blame] | 126 | // Time from frame was captured on device to time frame was delivered from |
| 127 | // decoder. |
| 128 | SampleStats<TimeDelta> capture_to_decoded_delay; |
Sebastian Jansson | 9a2ca0a | 2019-04-15 13:18:19 +0200 | [diff] [blame] | 129 | // Time from frame was captured on device to time frame was displayed on |
| 130 | // device. |
| 131 | SampleStats<TimeDelta> end_to_end_delay; |
Sebastian Jansson | e9cac4f | 2019-06-24 17:10:55 +0200 | [diff] [blame] | 132 | // PSNR for delivered frames. Note that this might go up for a worse |
| 133 | // connection due to frame dropping. |
Sebastian Jansson | 9a2ca0a | 2019-04-15 13:18:19 +0200 | [diff] [blame] | 134 | SampleStats<double> psnr; |
Sebastian Jansson | e9cac4f | 2019-06-24 17:10:55 +0200 | [diff] [blame] | 135 | // PSNR for all frames, dropped or lost frames are compared to the last |
| 136 | // successfully delivered frame |
| 137 | SampleStats<double> psnr_with_freeze; |
Sebastian Jansson | 9a2ca0a | 2019-04-15 13:18:19 +0200 | [diff] [blame] | 138 | // Frames skipped between two nearest. |
| 139 | SampleStats<double> skipped_between_rendered; |
| 140 | // In the next 2 metrics freeze is a pause that is longer, than maximum: |
| 141 | // 1. 150ms |
| 142 | // 2. 3 * average time between two sequential frames. |
| 143 | // Item 1 will cover high fps video and is a duration, that is noticeable by |
| 144 | // human eye. Item 2 will cover low fps video like screen sharing. |
| 145 | SampleStats<TimeDelta> freeze_duration; |
| 146 | // Mean time between one freeze end and next freeze start. |
| 147 | SampleStats<TimeDelta> time_between_freezes; |
| 148 | void AddStats(const VideoQualityStats& other); |
| 149 | }; |
| 150 | |
| 151 | struct CollectedCallStats { |
| 152 | SampleStats<DataRate> target_rate; |
Sebastian Jansson | 72b7524 | 2019-04-15 15:10:18 +0200 | [diff] [blame] | 153 | SampleStats<TimeDelta> pacer_delay; |
| 154 | SampleStats<TimeDelta> round_trip_time; |
Sebastian Jansson | 9a2ca0a | 2019-04-15 13:18:19 +0200 | [diff] [blame] | 155 | SampleStats<double> memory_usage; |
| 156 | }; |
| 157 | |
| 158 | struct CollectedAudioReceiveStats { |
| 159 | SampleStats<double> expand_rate; |
| 160 | SampleStats<double> accelerate_rate; |
| 161 | SampleStats<TimeDelta> jitter_buffer; |
| 162 | }; |
| 163 | struct CollectedVideoSendStats { |
| 164 | SampleStats<double> encode_frame_rate; |
| 165 | SampleStats<TimeDelta> encode_time; |
| 166 | SampleStats<double> encode_usage; |
| 167 | SampleStats<DataRate> media_bitrate; |
| 168 | SampleStats<DataRate> fec_bitrate; |
| 169 | }; |
| 170 | struct CollectedVideoReceiveStats { |
| 171 | SampleStats<TimeDelta> decode_time; |
| 172 | SampleStats<TimeDelta> decode_time_max; |
| 173 | SampleStats<double> decode_pixels; |
| 174 | SampleStats<double> resolution; |
Sebastian Jansson | 7150d8c | 2019-04-09 14:18:09 +0200 | [diff] [blame] | 175 | }; |
| 176 | |
Sebastian Jansson | 9a4f38e | 2018-12-19 13:14:41 +0100 | [diff] [blame] | 177 | } // namespace test |
| 178 | } // namespace webrtc |
Sebastian Jansson | 7150d8c | 2019-04-09 14:18:09 +0200 | [diff] [blame] | 179 | #endif // TEST_SCENARIO_PERFORMANCE_STATS_H_ |