[DVQA] Add a GetSenderPeerName method.

Change-Id: I2b30510911865150881c116abc2f86be7821f34a
Bug: b/277851637
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/301280
Commit-Queue: Jeremy Leconte <jleconte@webrtc.org>
Reviewed-by: Jeremy Leconte <jleconte@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Artem Titov <titovartem@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#39875}
This commit is contained in:
Jeremy Leconte 2023-04-14 15:37:54 +02:00 committed by WebRTC LUCI CQ
parent 6cf12bbe32
commit 4730201454
7 changed files with 85 additions and 13 deletions

View File

@ -474,6 +474,7 @@ rtc_source_set("video_quality_analyzer_api") {
deps = [ deps = [
":array_view", ":array_view",
":stats_observer_interface", ":stats_observer_interface",
"../rtc_base:checks",
"video:encoded_image", "video:encoded_image",
"video:video_frame", "video:video_frame",
"video:video_rtp_headers", "video:video_rtp_headers",

View File

@ -21,6 +21,7 @@
#include "api/video/encoded_image.h" #include "api/video/encoded_image.h"
#include "api/video/video_frame.h" #include "api/video/video_frame.h"
#include "api/video_codecs/video_encoder.h" #include "api/video_codecs/video_encoder.h"
#include "rtc_base/checks.h"
namespace webrtc { namespace webrtc {
@ -170,6 +171,13 @@ class VideoQualityAnalyzerInterface
// frame ids space wraps around, then stream label for frame id may change. // frame ids space wraps around, then stream label for frame id may change.
// It will crash, if the specified `frame_id` wasn't captured. // It will crash, if the specified `frame_id` wasn't captured.
virtual std::string GetStreamLabel(uint16_t frame_id) = 0; virtual std::string GetStreamLabel(uint16_t frame_id) = 0;
// Returns the sender peer name of the last stream where this frame was
// captured. The sender for this frame id may change when the frame ids wrap
// around. Also it will crash, if the specified `frame_id` wasn't captured.
virtual std::string GetSenderPeerName(uint16_t frame_id) const {
RTC_CHECK(false) << "Not implemented.";
}
}; };
} // namespace webrtc } // namespace webrtc

View File

@ -843,19 +843,17 @@ void DefaultVideoQualityAnalyzer::Stop() {
} }
std::string DefaultVideoQualityAnalyzer::GetStreamLabel(uint16_t frame_id) { std::string DefaultVideoQualityAnalyzer::GetStreamLabel(uint16_t frame_id) {
MutexLock lock1(&mutex_); MutexLock lock(&mutex_);
auto it = captured_frames_in_flight_.find(frame_id); return GetStreamLabelInternal(frame_id);
if (it != captured_frames_in_flight_.end()) { }
return streams_.name(it->second.stream());
} std::string DefaultVideoQualityAnalyzer::GetSenderPeerName(
for (auto hist_it = stream_to_frame_id_history_.begin(); uint16_t frame_id) const {
hist_it != stream_to_frame_id_history_.end(); ++hist_it) { MutexLock lock(&mutex_);
auto hist_set_it = hist_it->second.find(frame_id); std::string stream_label = GetStreamLabelInternal(frame_id);
if (hist_set_it != hist_it->second.end()) { size_t stream_index = streams_.index(stream_label);
return streams_.name(hist_it->first); size_t sender_peer_index = stream_states_.at(stream_index).sender();
} return peers_->name(sender_peer_index);
}
RTC_CHECK(false) << "Unknown frame_id=" << frame_id;
} }
std::set<StatsKey> DefaultVideoQualityAnalyzer::GetKnownVideoStreams() const { std::set<StatsKey> DefaultVideoQualityAnalyzer::GetKnownVideoStreams() const {
@ -1321,6 +1319,22 @@ std::string DefaultVideoQualityAnalyzer::ToMetricName(
return out.str(); return out.str();
} }
std::string DefaultVideoQualityAnalyzer::GetStreamLabelInternal(
uint16_t frame_id) const {
auto it = captured_frames_in_flight_.find(frame_id);
if (it != captured_frames_in_flight_.end()) {
return streams_.name(it->second.stream());
}
for (auto hist_it = stream_to_frame_id_history_.begin();
hist_it != stream_to_frame_id_history_.end(); ++hist_it) {
auto hist_set_it = hist_it->second.find(frame_id);
if (hist_set_it != hist_it->second.end()) {
return streams_.name(hist_it->first);
}
}
RTC_CHECK(false) << "Unknown frame_id=" << frame_id;
}
double DefaultVideoQualityAnalyzer::GetCpuUsagePercent() { double DefaultVideoQualityAnalyzer::GetCpuUsagePercent() {
return cpu_measurer_.GetCpuUsagePercent(); return cpu_measurer_.GetCpuUsagePercent();
} }

View File

@ -89,6 +89,7 @@ class DefaultVideoQualityAnalyzer : public VideoQualityAnalyzerInterface {
void Stop() override; void Stop() override;
std::string GetStreamLabel(uint16_t frame_id) override; std::string GetStreamLabel(uint16_t frame_id) override;
std::string GetSenderPeerName(uint16_t frame_id) const override;
void OnStatsReports( void OnStatsReports(
absl::string_view pc_label, absl::string_view pc_label,
const rtc::scoped_refptr<const RTCStatsReport>& report) override {} const rtc::scoped_refptr<const RTCStatsReport>& report) override {}
@ -150,6 +151,8 @@ class DefaultVideoQualityAnalyzer : public VideoQualityAnalyzerInterface {
// backward compatibility by metrics naming for 2 peers cases. // backward compatibility by metrics naming for 2 peers cases.
std::string ToMetricName(const InternalStatsKey& key) const std::string ToMetricName(const InternalStatsKey& key) const
RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
std::string GetStreamLabelInternal(uint16_t frame_id) const
RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
static const uint16_t kStartingFrameId = 1; static const uint16_t kStartingFrameId = 1;

View File

@ -2375,5 +2375,38 @@ TEST_F(DefaultVideoQualityAnalyzerSimulatedTimeTest,
EXPECT_EQ(frame_counters.dropped, 0); EXPECT_EQ(frame_counters.dropped, 0);
} }
TEST(DefaultVideoQualityAnalyzerTest, CheckFrameSenderPeerName) {
constexpr char kAlice[] = "alice";
constexpr char kBob[] = "bob";
constexpr char kAliceStreamLabel[] = "alice-video";
constexpr char kBobStreamLabel[] = "bob-video";
std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
/*type=*/absl::nullopt,
/*num_squares=*/absl::nullopt);
DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(),
test::GetGlobalMetricsLogger(),
AnalyzerOptionsForTest());
analyzer.Start("test_case", std::vector<std::string>{kAlice, kBob},
kAnalyzerMaxThreadsCount);
VideoFrame frame_alice = NextFrame(frame_generator.get(), /*timestamp_us=*/1);
VideoFrame frame_bob = NextFrame(frame_generator.get(), /*timestamp_us=*/2);
frame_alice.set_id(
analyzer.OnFrameCaptured(kAlice, kAliceStreamLabel, frame_alice));
frame_bob.set_id(analyzer.OnFrameCaptured(kBob, kBobStreamLabel, frame_bob));
std::string sender_alice = analyzer.GetSenderPeerName(frame_alice.id());
std::string sender_bob = analyzer.GetSenderPeerName(frame_bob.id());
// Give analyzer some time to process frames on async thread. The computations
// have to be fast (heavy metrics are disabled!), so if doesn't fit 100ms it
// means we have an issue!
SleepMs(100);
analyzer.Stop();
EXPECT_EQ(sender_alice, kAlice);
EXPECT_EQ(sender_bob, kBob);
}
} // namespace } // namespace
} // namespace webrtc } // namespace webrtc

View File

@ -32,6 +32,7 @@ uint16_t ExampleVideoQualityAnalyzer::OnFrameCaptured(
if (frame_id == VideoFrame::kNotSetId) { if (frame_id == VideoFrame::kNotSetId) {
frame_id = next_frame_id_++; frame_id = next_frame_id_++;
} }
stream_label_to_peer_name_[stream_label] = std::string(peer_name);
auto it = frames_in_flight_.find(frame_id); auto it = frames_in_flight_.find(frame_id);
if (it == frames_in_flight_.end()) { if (it == frames_in_flight_.end()) {
frames_in_flight_.insert(frame_id); frames_in_flight_.insert(frame_id);
@ -130,6 +131,15 @@ std::string ExampleVideoQualityAnalyzer::GetStreamLabel(uint16_t frame_id) {
return it->second; return it->second;
} }
std::string ExampleVideoQualityAnalyzer::GetSenderPeerName(
uint16_t frame_id) const {
MutexLock lock(&lock_);
auto it = frames_to_stream_label_.find(frame_id);
RTC_DCHECK(it != frames_to_stream_label_.end())
<< "Unknown frame_id=" << frame_id;
return stream_label_to_peer_name_.at(it->second);
}
uint64_t ExampleVideoQualityAnalyzer::frames_captured() const { uint64_t ExampleVideoQualityAnalyzer::frames_captured() const {
MutexLock lock(&lock_); MutexLock lock(&lock_);
return frames_captured_; return frames_captured_;

View File

@ -65,6 +65,7 @@ class ExampleVideoQualityAnalyzer : public VideoQualityAnalyzerInterface {
const DecoderStats& stats) override; const DecoderStats& stats) override;
void Stop() override; void Stop() override;
std::string GetStreamLabel(uint16_t frame_id) override; std::string GetStreamLabel(uint16_t frame_id) override;
std::string GetSenderPeerName(uint16_t frame_id) const override;
uint64_t frames_captured() const; uint64_t frames_captured() const;
uint64_t frames_pre_encoded() const; uint64_t frames_pre_encoded() const;
@ -86,6 +87,8 @@ class ExampleVideoQualityAnalyzer : public VideoQualityAnalyzerInterface {
// process frame id overlap. // process frame id overlap.
std::set<uint16_t> frames_in_flight_ RTC_GUARDED_BY(lock_); std::set<uint16_t> frames_in_flight_ RTC_GUARDED_BY(lock_);
std::map<uint16_t, std::string> frames_to_stream_label_ RTC_GUARDED_BY(lock_); std::map<uint16_t, std::string> frames_to_stream_label_ RTC_GUARDED_BY(lock_);
std::map<std::string, std::string> stream_label_to_peer_name_
RTC_GUARDED_BY(lock_);
uint16_t next_frame_id_ RTC_GUARDED_BY(lock_) = 1; uint16_t next_frame_id_ RTC_GUARDED_BY(lock_) = 1;
uint64_t frames_captured_ RTC_GUARDED_BY(lock_) = 0; uint64_t frames_captured_ RTC_GUARDED_BY(lock_) = 0;
uint64_t frames_pre_encoded_ RTC_GUARDED_BY(lock_) = 0; uint64_t frames_pre_encoded_ RTC_GUARDED_BY(lock_) = 0;