Introduce Metric object for new perf metrics logging system

Bug: b/246095034
Change-Id: I854ee8e5ea93e4046837ae9f54a652a8c92dd1bc
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/274861
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Tomas Gunnarsson <tommi@webrtc.org>
Commit-Queue: Artem Titov <titovartem@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#38078}
diff --git a/BUILD.gn b/BUILD.gn
index 92941f0..4146db8 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -52,6 +52,7 @@
         ":voip_unittests",
         ":webrtc_nonparallel_tests",
         ":webrtc_perf_tests",
+        "api/test/metrics:metrics_unittests",
         "common_audio:common_audio_unittests",
         "common_video:common_video_unittests",
         "examples:examples_unittests",
@@ -475,6 +476,7 @@
       "api/rtc_event_log:rtc_event_log_factory",
       "api/task_queue",
       "api/task_queue:default_task_queue_factory",
+      "api/test/metrics",
       "audio",
       "call",
       "common_audio",
diff --git a/api/test/metrics/BUILD.gn b/api/test/metrics/BUILD.gn
new file mode 100644
index 0000000..0d1ffff
--- /dev/null
+++ b/api/test/metrics/BUILD.gn
@@ -0,0 +1,31 @@
+# Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS.  All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+
+group("metrics") {
+  deps = [ ":metric" ]
+}
+
+if (rtc_include_tests) {
+  group("metrics_unittests") {
+    testonly = true
+
+    deps = []
+  }
+}
+
+rtc_library("metric") {
+  visibility = [ "*" ]
+  sources = [
+    "metric.cc",
+    "metric.h",
+  ]
+  absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+  deps = [ "../../../api/units:timestamp" ]
+}
diff --git a/api/test/metrics/metric.cc b/api/test/metrics/metric.cc
new file mode 100644
index 0000000..7bace78d
--- /dev/null
+++ b/api/test/metrics/metric.cc
@@ -0,0 +1,48 @@
+/*
+ *  Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/test/metrics/metric.h"
+
+#include <string>
+
+namespace webrtc {
+namespace test {
+
+absl::string_view ToString(Unit unit) {
+  switch (unit) {
+    case Unit::kTimeMs:
+      return "TimeMs";
+    case Unit::kPercent:
+      return "Percent";
+    case Unit::kSizeInBytes:
+      return "SizeInBytes";
+    case Unit::kKilobitsPerSecond:
+      return "KilobitsPerSecond";
+    case Unit::kHertz:
+      return "Hertz";
+    case Unit::kUnitless:
+      return "Unitless";
+    case Unit::kCount:
+      return "Count";
+  }
+}
+
+absl::string_view ToString(ImprovementDirection direction) {
+  switch (direction) {
+    case ImprovementDirection::kBiggerIsBetter:
+      return "BiggerIsBetter";
+    case ImprovementDirection::kNeitherIsBetter:
+      return "NeitherIsBetter";
+    case ImprovementDirection::kSmallerIsBetter:
+      return "SmallerIsBetter";
+  }
+}
+
+}  // namespace test
+}  // namespace webrtc
diff --git a/api/test/metrics/metric.h b/api/test/metrics/metric.h
new file mode 100644
index 0000000..bce9e50
--- /dev/null
+++ b/api/test/metrics/metric.h
@@ -0,0 +1,96 @@
+/*
+ *  Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_METRICS_METRIC_H_
+#define API_TEST_METRICS_METRIC_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/units/timestamp.h"
+
+namespace webrtc {
+namespace test {
+
+enum class Unit {
+  kTimeMs,
+  kPercent,
+  kSizeInBytes,
+  kKilobitsPerSecond,
+  kHertz,
+  // General unitless value. Can be used either for dimensionless quantities
+  // (ex ratio) or for units not presented in this enum and too specific to add
+  // to this enum.
+  kUnitless,
+  kCount
+};
+
+absl::string_view ToString(Unit unit);
+
+enum class ImprovementDirection {
+  kBiggerIsBetter,
+  kNeitherIsBetter,
+  kSmallerIsBetter
+};
+
+absl::string_view ToString(ImprovementDirection direction);
+
+struct Metric {
+  struct TimeSeries {
+    struct Sample {
+      // Timestamp in microseconds associated with a sample. For example,
+      // the timestamp when the sample was collected.
+      webrtc::Timestamp timestamp;
+      double value;
+      // Metadata associated with this particular sample.
+      std::map<std::string, std::string> sample_metadata;
+    };
+
+    // All samples collected for this metric. It can be empty if the Metric
+    // object only contains `stats`.
+    std::vector<Sample> samples;
+  };
+
+  // Contains metric's precomputed statistics based on the `time_series` or if
+  // `time_series` is omitted (has 0 samples) contains precomputed statistics
+  // provided by the metric's calculator.
+  struct Stats {
+    // Sample mean of the metric
+    // (https://en.wikipedia.org/wiki/Sample_mean_and_covariance).
+    absl::optional<double> mean;
+    // Standard deviation (https://en.wikipedia.org/wiki/Standard_deviation).
+    // Is undefined if `time_series` contains only a single value.
+    absl::optional<double> stddev;
+    absl::optional<double> min;
+    absl::optional<double> max;
+  };
+
+  // Metric name, for example PSNR, SSIM, decode_time, etc.
+  std::string name;
+  Unit unit;
+  ImprovementDirection improvement_direction;
+  // If the metric is generated by a test, this field can be used to specify
+  // this information.
+  std::string test_case;
+  // Metadata associated with the whole metric.
+  std::map<std::string, std::string> metric_metadata;
+  // Contains all samples of the metric collected during test execution.
+  // It can be empty if the user only stores precomputed statistics into
+  // `stats`.
+  TimeSeries time_series;
+  Stats stats;
+};
+
+}  // namespace test
+}  // namespace webrtc
+
+#endif  // API_TEST_METRICS_METRIC_H_