[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:
parent
6783f7f69c
commit
4c4c744818
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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]++;
|
||||
}
|
||||
|
||||
@ -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_);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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_
|
||||
|
||||
@ -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_
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user