[DVQA] Move video quality analyzer from webrtc::webrtc_pc_e2e to webrtc

Bug: b/196348200
Change-Id: I581fc25cc29a1384a4f7f298134ee6d0b60e68cd
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/229382
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Artem Titov <titovartem@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34824}
This commit is contained in:
Artem Titov 2021-08-19 22:11:33 +02:00 committed by WebRTC LUCI CQ
parent 6783f7f69c
commit 4c4c744818
14 changed files with 48 additions and 49 deletions

View File

@ -23,7 +23,6 @@
#include "api/video_codecs/video_encoder.h"
namespace webrtc {
namespace webrtc_pc_e2e {
// API is in development and can be changed without notice.
@ -53,7 +52,8 @@ namespace webrtc_pc_e2e {
// | Sink | | Stack | | Decoder |
// ¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯
// The analyzer will be injected in all points from A to F.
class VideoQualityAnalyzerInterface : public StatsObserverInterface {
class VideoQualityAnalyzerInterface
: public webrtc_pc_e2e::StatsObserverInterface {
public:
// Contains extra statistic provided by video encoder.
struct EncoderStats {
@ -150,6 +150,11 @@ class VideoQualityAnalyzerInterface : public StatsObserverInterface {
virtual std::string GetStreamLabel(uint16_t frame_id) = 0;
};
namespace webrtc_pc_e2e {
// Temporary alias to make downstream projects able to migrate.
using VideoQualityAnalyzerInterface = ::webrtc::VideoQualityAnalyzerInterface;
} // namespace webrtc_pc_e2e
} // namespace webrtc

View File

@ -29,7 +29,6 @@
#include "test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.h"
namespace webrtc {
namespace webrtc_pc_e2e {
namespace {
constexpr int kMicrosPerSecond = 1000000;
@ -1082,5 +1081,4 @@ size_t DefaultVideoQualityAnalyzer::NamesCollection::AddIfAbsent(
return out;
}
} // namespace webrtc_pc_e2e
} // namespace webrtc

View File

@ -37,7 +37,6 @@
#include "test/testsupport/perf_test.h"
namespace webrtc {
namespace webrtc_pc_e2e {
class DefaultVideoQualityAnalyzer : public VideoQualityAnalyzerInterface {
public:
@ -369,6 +368,11 @@ class DefaultVideoQualityAnalyzer : public VideoQualityAnalyzerInterface {
DefaultVideoQualityAnalyzerFramesComparator frames_comparator_;
};
namespace webrtc_pc_e2e {
// Temporary alias to make downstream projects able to migrate.
using DefaultVideoQualityAnalyzer = ::webrtc::DefaultVideoQualityAnalyzer;
} // namespace webrtc_pc_e2e
} // namespace webrtc

View File

@ -235,8 +235,7 @@ void DefaultVideoQualityAnalyzerFramesComparator::EnsureStatsForStream(
}
InternalStatsKey stats_key(stream_index, sender_peer_index, i);
if (stream_stats_.find(stats_key) == stream_stats_.end()) {
stream_stats_.insert(
{stats_key, webrtc_pc_e2e::StreamStats(captured_time)});
stream_stats_.insert({stats_key, StreamStats(captured_time)});
// Assume that the first freeze was before first stream frame captured.
// This way time before the first freeze would be counted as time
// between freezes.
@ -261,7 +260,7 @@ void DefaultVideoQualityAnalyzerFramesComparator::RegisterParticipantInCall(
for (const std::pair<InternalStatsKey, Timestamp>& pair :
stream_started_time) {
stream_stats_.insert({pair.first, webrtc_pc_e2e::StreamStats(pair.second)});
stream_stats_.insert({pair.first, StreamStats(pair.second)});
stream_last_freeze_end_time_.insert({pair.first, start_time});
}
}
@ -389,7 +388,7 @@ void DefaultVideoQualityAnalyzerFramesComparator::ProcessComparison(
MutexLock lock(&mutex_);
auto stats_it = stream_stats_.find(comparison.stats_key);
RTC_CHECK(stats_it != stream_stats_.end()) << comparison.stats_key.ToString();
webrtc_pc_e2e::StreamStats* stats = &stats_it->second;
StreamStats* stats = &stats_it->second;
frames_comparator_stats_.comparisons_done++;
if (comparison.overload_reason == OverloadReason::kCpu) {
@ -407,15 +406,15 @@ void DefaultVideoQualityAnalyzerFramesComparator::ProcessComparison(
// Compute dropped phase for dropped frame
if (comparison.type == FrameComparisonType::kDroppedFrame) {
webrtc_pc_e2e::FrameDropPhase dropped_phase;
FrameDropPhase dropped_phase;
if (frame_stats.decode_end_time.IsFinite()) {
dropped_phase = webrtc_pc_e2e::FrameDropPhase::kAfterDecoder;
dropped_phase = FrameDropPhase::kAfterDecoder;
} else if (frame_stats.encoded_time.IsFinite()) {
dropped_phase = webrtc_pc_e2e::FrameDropPhase::kTransport;
dropped_phase = FrameDropPhase::kTransport;
} else if (frame_stats.pre_encode_time.IsFinite()) {
dropped_phase = webrtc_pc_e2e::FrameDropPhase::kByEncoder;
dropped_phase = FrameDropPhase::kByEncoder;
} else {
dropped_phase = webrtc_pc_e2e::FrameDropPhase::kBeforeEncoder;
dropped_phase = FrameDropPhase::kBeforeEncoder;
}
stats->dropped_by_phase[dropped_phase]++;
}

View File

@ -55,7 +55,7 @@ class DefaultVideoQualityAnalyzerFramesComparator {
DefaultVideoQualityAnalyzerFramesComparator(
webrtc::Clock* clock,
DefaultVideoQualityAnalyzerCpuMeasurer& cpu_measurer,
webrtc_pc_e2e::DefaultVideoQualityAnalyzerOptions options = {})
DefaultVideoQualityAnalyzerOptions options = {})
: options_(options), clock_(clock), cpu_measurer_(cpu_measurer) {}
~DefaultVideoQualityAnalyzerFramesComparator() { Stop({}); }
@ -114,7 +114,7 @@ class DefaultVideoQualityAnalyzerFramesComparator {
FrameComparisonType type,
FrameStats frame_stats);
std::map<InternalStatsKey, webrtc_pc_e2e::StreamStats> stream_stats() const {
std::map<InternalStatsKey, StreamStats> stream_stats() const {
MutexLock lock(&mutex_);
return stream_stats_;
}
@ -136,14 +136,13 @@ class DefaultVideoQualityAnalyzerFramesComparator {
void ProcessComparison(const FrameComparison& comparison);
Timestamp Now();
const webrtc_pc_e2e::DefaultVideoQualityAnalyzerOptions options_;
const DefaultVideoQualityAnalyzerOptions options_;
webrtc::Clock* const clock_;
DefaultVideoQualityAnalyzerCpuMeasurer& cpu_measurer_;
mutable Mutex mutex_;
State state_ RTC_GUARDED_BY(mutex_) = State::kNew;
std::map<InternalStatsKey, webrtc_pc_e2e::StreamStats> stream_stats_
RTC_GUARDED_BY(mutex_);
std::map<InternalStatsKey, StreamStats> stream_stats_ RTC_GUARDED_BY(mutex_);
std::map<InternalStatsKey, Timestamp> stream_last_freeze_end_time_
RTC_GUARDED_BY(mutex_);
std::deque<FrameComparison> comparisons_ RTC_GUARDED_BY(mutex_);

View File

@ -29,17 +29,16 @@ using StatsSample = ::webrtc::SamplesStatsCounter::StatsSample;
constexpr int kMaxFramesInFlightPerStream = 10;
webrtc_pc_e2e::DefaultVideoQualityAnalyzerOptions AnalyzerOptionsForTest() {
webrtc_pc_e2e::DefaultVideoQualityAnalyzerOptions options;
DefaultVideoQualityAnalyzerOptions AnalyzerOptionsForTest() {
DefaultVideoQualityAnalyzerOptions options;
options.heavy_metrics_computation_enabled = false;
options.adjust_cropping_before_comparing_frames = false;
options.max_frames_in_flight_per_stream_count = kMaxFramesInFlightPerStream;
return options;
}
webrtc_pc_e2e::StreamCodecInfo Vp8CodecForOneFrame(uint16_t frame_id,
Timestamp time) {
webrtc_pc_e2e::StreamCodecInfo info;
StreamCodecInfo Vp8CodecForOneFrame(uint16_t frame_id, Timestamp time) {
StreamCodecInfo info;
info.codec_name = "VP8";
info.first_frame_id = frame_id;
info.last_frame_id = frame_id;
@ -120,8 +119,7 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
FrameComparisonType::kRegular, frame_stats);
comparator.Stop({});
std::map<InternalStatsKey, webrtc_pc_e2e::StreamStats> stats =
comparator.stream_stats();
std::map<InternalStatsKey, StreamStats> stats = comparator.stream_stats();
EXPECT_DOUBLE_EQ(GetFirstOrDie(stats.at(stats_key).transport_time_ms), 20.0);
EXPECT_DOUBLE_EQ(
GetFirstOrDie(stats.at(stats_key).total_delay_incl_transport_ms), 60.0);
@ -165,8 +163,7 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
FrameComparisonType::kRegular, frame_stats2);
comparator.Stop({});
std::map<InternalStatsKey, webrtc_pc_e2e::StreamStats> stats =
comparator.stream_stats();
std::map<InternalStatsKey, StreamStats> stats = comparator.stream_stats();
EXPECT_DOUBLE_EQ(
GetFirstOrDie(stats.at(stats_key).time_between_rendered_frames_ms), 15.0);
EXPECT_DOUBLE_EQ(stats.at(stats_key).encode_frame_rate.GetEventsPerSecond(),
@ -250,8 +247,7 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
comparator.Stop({});
EXPECT_EQ(comparator.stream_stats().size(), 1lu);
webrtc_pc_e2e::StreamStats result_stats =
comparator.stream_stats().at(stats_key);
StreamStats result_stats = comparator.stream_stats().at(stats_key);
EXPECT_DOUBLE_EQ(result_stats.transport_time_ms.GetAverage(), 20.0)
<< ToString(result_stats.transport_time_ms);

View File

@ -60,9 +60,9 @@ struct FrameStats {
absl::optional<int> rendered_frame_height = absl::nullopt;
// Can be not set if frame was dropped by encoder.
absl::optional<webrtc_pc_e2e::StreamCodecInfo> used_encoder = absl::nullopt;
absl::optional<StreamCodecInfo> used_encoder = absl::nullopt;
// Can be not set if frame was dropped in the network.
absl::optional<webrtc_pc_e2e::StreamCodecInfo> used_decoder = absl::nullopt;
absl::optional<StreamCodecInfo> used_decoder = absl::nullopt;
};
// Describes why comparison was done in overloaded mode (without calculating

View File

@ -14,14 +14,13 @@
#include "rtc_base/strings/string_builder.h"
namespace webrtc {
namespace webrtc_pc_e2e {
namespace {
constexpr int kMicrosPerSecond = 1000000;
} // namespace
void RateCounter::AddEvent(Timestamp event_time) {
void SamplesRateCounter::AddEvent(Timestamp event_time) {
if (event_first_time_.IsMinusInfinity()) {
event_first_time_ = event_time;
}
@ -29,7 +28,7 @@ void RateCounter::AddEvent(Timestamp event_time) {
events_count_++;
}
double RateCounter::GetEventsPerSecond() const {
double SamplesRateCounter::GetEventsPerSecond() const {
RTC_DCHECK(!IsEmpty());
// Divide on us and multiply on kMicrosPerSecond to correctly process cases
// where there were too small amount of events, so difference is less then 1
@ -67,5 +66,4 @@ bool operator==(const StatsKey& a, const StatsKey& b) {
a.receiver == b.receiver;
}
} // namespace webrtc_pc_e2e
} // namespace webrtc

View File

@ -22,14 +22,13 @@
#include "api/units/timestamp.h"
namespace webrtc {
namespace webrtc_pc_e2e {
// WebRTC will request a key frame after 3 seconds if no frames were received.
// We assume max frame rate ~60 fps, so 270 frames will cover max freeze without
// key frame request.
constexpr size_t kDefaultMaxFramesInFlightPerStream = 270;
class RateCounter {
class SamplesRateCounter {
public:
void AddEvent(Timestamp event_time);
@ -106,7 +105,7 @@ struct StreamStats {
SamplesStatsCounter total_delay_incl_transport_ms;
// Time between frames out from renderer.
SamplesStatsCounter time_between_rendered_frames_ms;
RateCounter encode_frame_rate;
SamplesRateCounter encode_frame_rate;
SamplesStatsCounter encode_time_ms;
SamplesStatsCounter decode_time_ms;
// Time from last packet of frame is received until it's sent to the renderer.
@ -199,6 +198,17 @@ struct DefaultVideoQualityAnalyzerOptions {
bool enable_receive_own_stream = false;
};
namespace webrtc_pc_e2e {
// Temporary alias to make downstream projects able to migrate.
using FrameCounters = ::webrtc::FrameCounters;
using StreamCodecInfo = ::webrtc::StreamCodecInfo;
using StreamStats = ::webrtc::StreamStats;
using AnalyzerStats = ::webrtc::AnalyzerStats;
using StatsKey = ::webrtc::StatsKey;
using DefaultVideoQualityAnalyzerOptions =
::webrtc::DefaultVideoQualityAnalyzerOptions;
} // namespace webrtc_pc_e2e
} // namespace webrtc

View File

@ -29,7 +29,6 @@
#include "test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.h"
namespace webrtc {
namespace webrtc_pc_e2e {
namespace {
using StatsSample = ::webrtc::SamplesStatsCounter::StatsSample;
@ -1427,5 +1426,4 @@ TEST(
}
} // namespace
} // namespace webrtc_pc_e2e
} // namespace webrtc

View File

@ -14,7 +14,6 @@
#include "rtc_base/logging.h"
namespace webrtc {
namespace webrtc_pc_e2e {
ExampleVideoQualityAnalyzer::ExampleVideoQualityAnalyzer() = default;
ExampleVideoQualityAnalyzer::~ExampleVideoQualityAnalyzer() = default;
@ -161,5 +160,4 @@ uint64_t ExampleVideoQualityAnalyzer::frames_dropped() const {
return frames_dropped_;
}
} // namespace webrtc_pc_e2e
} // namespace webrtc

View File

@ -23,7 +23,6 @@
#include "rtc_base/synchronization/mutex.h"
namespace webrtc {
namespace webrtc_pc_e2e {
// This class is an example implementation of
// webrtc::VideoQualityAnalyzerInterface and calculates simple metrics
@ -95,7 +94,6 @@ class ExampleVideoQualityAnalyzer : public VideoQualityAnalyzerInterface {
uint64_t frames_dropped_ RTC_GUARDED_BY(lock_) = 0;
};
} // namespace webrtc_pc_e2e
} // namespace webrtc
#endif // TEST_PC_E2E_ANALYZER_VIDEO_EXAMPLE_VIDEO_QUALITY_ANALYZER_H_

View File

@ -19,7 +19,6 @@
#include "rtc_base/checks.h"
namespace webrtc {
namespace webrtc_pc_e2e {
// A queue that allows more than one reader. Readers are independent, and all
// readers will see all elements; an inserted element stays in the queue until
@ -98,7 +97,6 @@ class MultiHeadQueue {
std::vector<std::deque<T>> queues_;
};
} // namespace webrtc_pc_e2e
} // namespace webrtc
#endif // TEST_PC_E2E_ANALYZER_VIDEO_MULTI_HEAD_QUEUE_H_

View File

@ -13,7 +13,6 @@
#include "test/gtest.h"
namespace webrtc {
namespace webrtc_pc_e2e {
namespace {
TEST(MultiHeadQueueTest, GetOnEmpty) {
@ -118,5 +117,4 @@ TEST(MultiHeadQueueTest, HeadCopy) {
}
} // namespace
} // namespace webrtc_pc_e2e
} // namespace webrtc