diff options
Diffstat (limited to '')
-rw-r--r-- | third_party/libwebrtc/rtc_tools/rtc_event_log_visualizer/analyzer_common.h | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/third_party/libwebrtc/rtc_tools/rtc_event_log_visualizer/analyzer_common.h b/third_party/libwebrtc/rtc_tools/rtc_event_log_visualizer/analyzer_common.h new file mode 100644 index 0000000000..b0b556aa62 --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/rtc_event_log_visualizer/analyzer_common.h @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2020 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 RTC_TOOLS_RTC_EVENT_LOG_VISUALIZER_ANALYZER_COMMON_H_ +#define RTC_TOOLS_RTC_EVENT_LOG_VISUALIZER_ANALYZER_COMMON_H_ + +#include <cstdint> +#include <string> + +#include "absl/types/optional.h" +#include "api/function_view.h" +#include "logging/rtc_event_log/rtc_event_log_parser.h" +#include "rtc_tools/rtc_event_log_visualizer/plot_base.h" + +namespace webrtc { + +constexpr int kNumMicrosecsPerSec = 1000000; +constexpr int kNumMillisecsPerSec = 1000; +constexpr float kLeftMargin = 0.01f; +constexpr float kRightMargin = 0.02f; +constexpr float kBottomMargin = 0.02f; +constexpr float kTopMargin = 0.05f; + +class AnalyzerConfig { + public: + float GetCallTimeSec(Timestamp timestamp) const { + Timestamp offset = normalize_time_ ? begin_time_ : Timestamp::Zero(); + return static_cast<float>((timestamp - offset).us()) / 1000000; + } + + float GetCallTimeSecFromMs(int64_t timestamp_ms) const { + return GetCallTimeSec(Timestamp::Millis(timestamp_ms)); + } + + float CallBeginTimeSec() const { return GetCallTimeSec(begin_time_); } + + float CallEndTimeSec() const { return GetCallTimeSec(end_time_); } + + int64_t CallTimeToUtcOffsetMs() { + if (normalize_time_) { + Timestamp utc_begin_time_ = begin_time_ + rtc_to_utc_offset_; + return utc_begin_time_.ms(); + } + return rtc_to_utc_offset_.ms(); + } + + // Window and step size used for calculating moving averages, e.g. bitrate. + // The generated data points will be `step_.ms()` milliseconds apart. + // Only events occurring at most `window_duration_.ms()` milliseconds before + // the current data point will be part of the average. + TimeDelta window_duration_ = TimeDelta::Millis(250); + TimeDelta step_ = TimeDelta::Millis(10); + + // First and last events of the log. + Timestamp begin_time_ = Timestamp::MinusInfinity(); + Timestamp end_time_ = Timestamp::MinusInfinity(); + TimeDelta rtc_to_utc_offset_ = TimeDelta::Zero(); + bool normalize_time_; +}; + +struct LayerDescription { + LayerDescription(uint32_t ssrc, uint8_t spatial_layer, uint8_t temporal_layer) + : ssrc(ssrc), + spatial_layer(spatial_layer), + temporal_layer(temporal_layer) {} + bool operator<(const LayerDescription& other) const { + if (ssrc != other.ssrc) + return ssrc < other.ssrc; + if (spatial_layer != other.spatial_layer) + return spatial_layer < other.spatial_layer; + return temporal_layer < other.temporal_layer; + } + uint32_t ssrc; + uint8_t spatial_layer; + uint8_t temporal_layer; +}; + +bool IsRtxSsrc(const ParsedRtcEventLog& parsed_log, + PacketDirection direction, + uint32_t ssrc); +bool IsVideoSsrc(const ParsedRtcEventLog& parsed_log, + PacketDirection direction, + uint32_t ssrc); +bool IsAudioSsrc(const ParsedRtcEventLog& parsed_log, + PacketDirection direction, + uint32_t ssrc); + +std::string GetStreamName(const ParsedRtcEventLog& parsed_log, + PacketDirection direction, + uint32_t ssrc); +std::string GetLayerName(LayerDescription layer); + +// For each element in data_view, use `f()` to extract a y-coordinate and +// store the result in a TimeSeries. +template <typename DataType, typename IterableType> +void ProcessPoints(rtc::FunctionView<float(const DataType&)> fx, + rtc::FunctionView<absl::optional<float>(const DataType&)> fy, + const IterableType& data_view, + TimeSeries* result) { + for (size_t i = 0; i < data_view.size(); i++) { + const DataType& elem = data_view[i]; + float x = fx(elem); + absl::optional<float> y = fy(elem); + if (y) + result->points.emplace_back(x, *y); + } +} + +// For each pair of adjacent elements in `data`, use `f()` to extract a +// y-coordinate and store the result in a TimeSeries. Note that the x-coordinate +// will be the time of the second element in the pair. +template <typename DataType, typename ResultType, typename IterableType> +void ProcessPairs( + rtc::FunctionView<float(const DataType&)> fx, + rtc::FunctionView<absl::optional<ResultType>(const DataType&, + const DataType&)> fy, + const IterableType& data, + TimeSeries* result) { + for (size_t i = 1; i < data.size(); i++) { + float x = fx(data[i]); + absl::optional<ResultType> y = fy(data[i - 1], data[i]); + if (y) + result->points.emplace_back(x, static_cast<float>(*y)); + } +} + +// For each pair of adjacent elements in `data`, use `f()` to extract a +// y-coordinate and store the result in a TimeSeries. Note that the x-coordinate +// will be the time of the second element in the pair. +template <typename DataType, typename ResultType, typename IterableType> +void AccumulatePairs( + rtc::FunctionView<float(const DataType&)> fx, + rtc::FunctionView<absl::optional<ResultType>(const DataType&, + const DataType&)> fy, + const IterableType& data, + TimeSeries* result) { + ResultType sum = 0; + for (size_t i = 1; i < data.size(); i++) { + float x = fx(data[i]); + absl::optional<ResultType> y = fy(data[i - 1], data[i]); + if (y) { + sum += *y; + result->points.emplace_back(x, static_cast<float>(sum)); + } + } +} + +// Calculates a moving average of `data` and stores the result in a TimeSeries. +// A data point is generated every `step` microseconds from `begin_time` +// to `end_time`. The value of each data point is the average of the data +// during the preceding `window_duration_us` microseconds. +template <typename DataType, typename ResultType, typename IterableType> +void MovingAverage( + rtc::FunctionView<absl::optional<ResultType>(const DataType&)> fy, + const IterableType& data_view, + AnalyzerConfig config, + TimeSeries* result) { + size_t window_index_begin = 0; + size_t window_index_end = 0; + ResultType sum_in_window = 0; + + for (Timestamp t = config.begin_time_; t < config.end_time_ + config.step_; + t += config.step_) { + while (window_index_end < data_view.size() && + data_view[window_index_end].log_time() < t) { + absl::optional<ResultType> value = fy(data_view[window_index_end]); + if (value) + sum_in_window += *value; + ++window_index_end; + } + while (window_index_begin < data_view.size() && + data_view[window_index_begin].log_time() < + t - config.window_duration_) { + absl::optional<ResultType> value = fy(data_view[window_index_begin]); + if (value) + sum_in_window -= *value; + ++window_index_begin; + } + float window_duration_s = + static_cast<float>(config.window_duration_.us()) / kNumMicrosecsPerSec; + float x = config.GetCallTimeSec(t); + float y = sum_in_window / window_duration_s; + result->points.emplace_back(x, y); + } +} + +} // namespace webrtc + +#endif // RTC_TOOLS_RTC_EVENT_LOG_VISUALIZER_ANALYZER_COMMON_H_ |