blob: 310ee8d7f92ebc5e50e941d277e9b09018e23e29 [file] [log] [blame]
Sebastian Jansson9a4f38e2018-12-19 13:14:41 +01001/*
Sebastian Jansson7150d8c2019-04-09 14:18:09 +02002 * Copyright 2019 The WebRTC project authors. All Rights Reserved.
Sebastian Jansson9a4f38e2018-12-19 13:14:41 +01003 *
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 Jansson7150d8c2019-04-09 14:18:09 +020010#ifndef TEST_SCENARIO_PERFORMANCE_STATS_H_
11#define TEST_SCENARIO_PERFORMANCE_STATS_H_
Sebastian Jansson9a4f38e2018-12-19 13:14:41 +010012
Sebastian Jansson7150d8c2019-04-09 14:18:09 +020013#include "api/units/data_rate.h"
14#include "api/units/time_delta.h"
Sebastian Jansson9a4f38e2018-12-19 13:14:41 +010015#include "api/units/timestamp.h"
Sebastian Janssoncf2df2f2019-04-02 11:51:28 +020016#include "api/video/video_frame_buffer.h"
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +020017#include "rtc_base/numerics/samples_stats_counter.h"
Sebastian Jansson9a4f38e2018-12-19 13:14:41 +010018
19namespace webrtc {
20namespace test {
Sebastian Jansson7150d8c2019-04-09 14:18:09 +020021
Sebastian Janssoncf2df2f2019-04-02 11:51:28 +020022struct VideoFramePair {
Sebastian Jansson7150d8c2019-04-09 14:18:09 +020023 rtc::scoped_refptr<VideoFrameBuffer> captured;
24 rtc::scoped_refptr<VideoFrameBuffer> decoded;
Sebastian Janssoncf2df2f2019-04-02 11:51:28 +020025 Timestamp capture_time = Timestamp::MinusInfinity();
Sebastian Janssone9cac4f2019-06-24 17:10:55 +020026 Timestamp decoded_time = Timestamp::PlusInfinity();
Sebastian Janssoncf2df2f2019-04-02 11:51:28 +020027 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 Jansson9a4f38e2018-12-19 13:14:41 +010037};
Sebastian Jansson7150d8c2019-04-09 14:18:09 +020038
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +020039template <typename T>
40class SampleStats;
41
42template <>
43class 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 Janssone9cac4f2019-06-24 17:10:55 +020052 int Count();
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +020053};
54
55template <>
56class SampleStats<TimeDelta> {
57 public:
58 void AddSample(TimeDelta delta);
59 void AddSampleMs(double delta_ms);
60 void AddSamples(const SampleStats<TimeDelta>& other);
Sebastian Jansson8abcf832019-05-21 10:13:06 +020061 bool IsEmpty();
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +020062 TimeDelta Max();
63 TimeDelta Mean();
64 TimeDelta Median();
65 TimeDelta Quantile(double quantile);
66 TimeDelta Min();
67 TimeDelta Variance();
68 TimeDelta StandardDeviation();
Sebastian Janssone9cac4f2019-06-24 17:10:55 +020069 int Count();
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +020070
71 private:
72 SampleStats<double> stats_;
73};
74
75template <>
76class SampleStats<DataRate> {
77 public:
78 void AddSample(DataRate rate);
79 void AddSampleBps(double rate_bps);
80 void AddSamples(const SampleStats<DataRate>& other);
Sebastian Jansson8abcf832019-05-21 10:13:06 +020081 bool IsEmpty();
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +020082 DataRate Max();
83 DataRate Mean();
84 DataRate Median();
85 DataRate Quantile(double quantile);
86 DataRate Min();
87 DataRate Variance();
88 DataRate StandardDeviation();
Sebastian Janssone9cac4f2019-06-24 17:10:55 +020089 int Count();
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +020090
91 private:
92 SampleStats<double> stats_;
93};
94
95class 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 Shrubsole9ddd7292019-10-09 10:37:09 +0200102 TimeDelta TotalDuration() const;
Sebastian Janssone9cac4f2019-06-24 17:10:55 +0200103 int Count() const { return event_count_; }
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +0200104
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
112struct 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 Jansson7150d8c2019-04-09 14:18:09 +0200121struct VideoQualityStats {
Sebastian Jansson7150d8c2019-04-09 14:18:09 +0200122 int lost_count = 0;
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +0200123 int freeze_count = 0;
124 VideoFramesStats capture;
125 VideoFramesStats render;
Sebastian Janssone9cac4f2019-06-24 17:10:55 +0200126 // Time from frame was captured on device to time frame was delivered from
127 // decoder.
128 SampleStats<TimeDelta> capture_to_decoded_delay;
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +0200129 // Time from frame was captured on device to time frame was displayed on
130 // device.
131 SampleStats<TimeDelta> end_to_end_delay;
Sebastian Janssone9cac4f2019-06-24 17:10:55 +0200132 // PSNR for delivered frames. Note that this might go up for a worse
133 // connection due to frame dropping.
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +0200134 SampleStats<double> psnr;
Sebastian Janssone9cac4f2019-06-24 17:10:55 +0200135 // PSNR for all frames, dropped or lost frames are compared to the last
136 // successfully delivered frame
137 SampleStats<double> psnr_with_freeze;
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +0200138 // 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
151struct CollectedCallStats {
152 SampleStats<DataRate> target_rate;
Sebastian Jansson72b75242019-04-15 15:10:18 +0200153 SampleStats<TimeDelta> pacer_delay;
154 SampleStats<TimeDelta> round_trip_time;
Sebastian Jansson9a2ca0a2019-04-15 13:18:19 +0200155 SampleStats<double> memory_usage;
156};
157
158struct CollectedAudioReceiveStats {
159 SampleStats<double> expand_rate;
160 SampleStats<double> accelerate_rate;
161 SampleStats<TimeDelta> jitter_buffer;
162};
163struct 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};
170struct CollectedVideoReceiveStats {
171 SampleStats<TimeDelta> decode_time;
172 SampleStats<TimeDelta> decode_time_max;
173 SampleStats<double> decode_pixels;
174 SampleStats<double> resolution;
Sebastian Jansson7150d8c2019-04-09 14:18:09 +0200175};
176
Sebastian Jansson9a4f38e2018-12-19 13:14:41 +0100177} // namespace test
178} // namespace webrtc
Sebastian Jansson7150d8c2019-04-09 14:18:09 +0200179#endif // TEST_SCENARIO_PERFORMANCE_STATS_H_