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