1 /*
2 * Copyright (c) 2021 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 #include "test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.h"
11
12 #include <algorithm>
13 #include <iterator>
14 #include <ostream>
15 #include <string>
16
17 #include "api/units/timestamp.h"
18 #include "rtc_base/checks.h"
19 #include "rtc_base/strings/string_builder.h"
20
21 namespace webrtc {
22 namespace {
23
24 constexpr int kMicrosPerSecond = 1000000;
25
26 } // namespace
27
ToString() const28 std::string StreamCodecInfo::ToString() const {
29 rtc::StringBuilder out;
30 out << "{codec_name=" << codec_name << "; first_frame_id=" << first_frame_id
31 << "; last_frame_id=" << last_frame_id
32 << "; switched_on_at=" << webrtc::ToString(switched_on_at)
33 << "; switched_from_at=" << webrtc::ToString(switched_from_at) << " }";
34 return out.str();
35 }
36
operator <<(std::ostream & os,const StreamCodecInfo & state)37 std::ostream& operator<<(std::ostream& os, const StreamCodecInfo& state) {
38 return os << state.ToString();
39 }
40
operator <<(rtc::StringBuilder & sb,const StreamCodecInfo & state)41 rtc::StringBuilder& operator<<(rtc::StringBuilder& sb,
42 const StreamCodecInfo& state) {
43 return sb << state.ToString();
44 }
45
operator ==(const StreamCodecInfo & a,const StreamCodecInfo & b)46 bool operator==(const StreamCodecInfo& a, const StreamCodecInfo& b) {
47 return a.codec_name == b.codec_name && a.first_frame_id == b.first_frame_id &&
48 a.last_frame_id == b.last_frame_id &&
49 a.switched_on_at == b.switched_on_at &&
50 a.switched_from_at == b.switched_from_at;
51 }
52
ToString(FrameDropPhase phase)53 std::string ToString(FrameDropPhase phase) {
54 switch (phase) {
55 case FrameDropPhase::kBeforeEncoder:
56 return "kBeforeEncoder";
57 case FrameDropPhase::kByEncoder:
58 return "kByEncoder";
59 case FrameDropPhase::kTransport:
60 return "kTransport";
61 case FrameDropPhase::kByDecoder:
62 return "kByDecoder";
63 case FrameDropPhase::kAfterDecoder:
64 return "kAfterDecoder";
65 case FrameDropPhase::kLastValue:
66 return "kLastValue";
67 }
68 }
69
operator <<(std::ostream & os,FrameDropPhase phase)70 std::ostream& operator<<(std::ostream& os, FrameDropPhase phase) {
71 return os << ToString(phase);
72 }
operator <<(rtc::StringBuilder & sb,FrameDropPhase phase)73 rtc::StringBuilder& operator<<(rtc::StringBuilder& sb, FrameDropPhase phase) {
74 return sb << ToString(phase);
75 }
76
AddEvent(Timestamp event_time)77 void SamplesRateCounter::AddEvent(Timestamp event_time) {
78 if (event_first_time_.IsMinusInfinity()) {
79 event_first_time_ = event_time;
80 }
81 event_last_time_ = event_time;
82 events_count_++;
83 }
84
GetEventsPerSecond() const85 double SamplesRateCounter::GetEventsPerSecond() const {
86 RTC_DCHECK(!IsEmpty());
87 // Divide on us and multiply on kMicrosPerSecond to correctly process cases
88 // where there were too small amount of events, so difference is less then 1
89 // sec. We can use us here, because Timestamp has us resolution.
90 return static_cast<double>(events_count_) /
91 (event_last_time_ - event_first_time_).us() * kMicrosPerSecond;
92 }
93
StreamStats(Timestamp stream_started_time)94 StreamStats::StreamStats(Timestamp stream_started_time)
95 : stream_started_time(stream_started_time) {
96 for (int i = static_cast<int>(FrameDropPhase::kBeforeEncoder);
97 i < static_cast<int>(FrameDropPhase::kLastValue); ++i) {
98 dropped_by_phase.emplace(static_cast<FrameDropPhase>(i), 0);
99 }
100 }
101
ToString() const102 std::string StatsKey::ToString() const {
103 rtc::StringBuilder out;
104 out << stream_label << "_" << receiver;
105 return out.str();
106 }
107
operator <(const StatsKey & a,const StatsKey & b)108 bool operator<(const StatsKey& a, const StatsKey& b) {
109 if (a.stream_label != b.stream_label) {
110 return a.stream_label < b.stream_label;
111 }
112 return a.receiver < b.receiver;
113 }
114
operator ==(const StatsKey & a,const StatsKey & b)115 bool operator==(const StatsKey& a, const StatsKey& b) {
116 return a.stream_label == b.stream_label && a.receiver == b.receiver;
117 }
118
VideoStreamsInfo(std::map<std::string,std::string> stream_to_sender,std::map<std::string,std::set<std::string>> sender_to_streams,std::map<std::string,std::set<std::string>> stream_to_receivers)119 VideoStreamsInfo::VideoStreamsInfo(
120 std::map<std::string, std::string> stream_to_sender,
121 std::map<std::string, std::set<std::string>> sender_to_streams,
122 std::map<std::string, std::set<std::string>> stream_to_receivers)
123 : stream_to_sender_(std::move(stream_to_sender)),
124 sender_to_streams_(std::move(sender_to_streams)),
125 stream_to_receivers_(std::move(stream_to_receivers)) {}
126
GetStatsKeys() const127 std::set<StatsKey> VideoStreamsInfo::GetStatsKeys() const {
128 std::set<StatsKey> out;
129 for (const std::string& stream_label : GetStreams()) {
130 for (const std::string& receiver : GetReceivers(stream_label)) {
131 out.insert(StatsKey(stream_label, receiver));
132 }
133 }
134 return out;
135 }
136
GetStreams() const137 std::set<std::string> VideoStreamsInfo::GetStreams() const {
138 std::set<std::string> out;
139 std::transform(stream_to_sender_.begin(), stream_to_sender_.end(),
140 std::inserter(out, out.end()),
141 [](auto map_entry) { return map_entry.first; });
142 return out;
143 }
144
GetStreams(absl::string_view sender_name) const145 std::set<std::string> VideoStreamsInfo::GetStreams(
146 absl::string_view sender_name) const {
147 auto it = sender_to_streams_.find(std::string(sender_name));
148 if (it == sender_to_streams_.end()) {
149 return {};
150 }
151 return it->second;
152 }
153
GetSender(absl::string_view stream_label) const154 absl::optional<std::string> VideoStreamsInfo::GetSender(
155 absl::string_view stream_label) const {
156 auto it = stream_to_sender_.find(std::string(stream_label));
157 if (it == stream_to_sender_.end()) {
158 return absl::nullopt;
159 }
160 return it->second;
161 }
162
GetReceivers(absl::string_view stream_label) const163 std::set<std::string> VideoStreamsInfo::GetReceivers(
164 absl::string_view stream_label) const {
165 auto it = stream_to_receivers_.find(std::string(stream_label));
166 if (it == stream_to_receivers_.end()) {
167 return {};
168 }
169 return it->second;
170 }
171
172 } // namespace webrtc
173