| /* |
| * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #ifndef TEST_PC_E2E_ANALYZER_VIDEO_DEFAULT_VIDEO_QUALITY_ANALYZER_FRAMES_COMPARATOR_H_ |
| #define TEST_PC_E2E_ANALYZER_VIDEO_DEFAULT_VIDEO_QUALITY_ANALYZER_FRAMES_COMPARATOR_H_ |
| |
| #include <deque> |
| #include <map> |
| #include <utility> |
| #include <vector> |
| |
| #include "api/array_view.h" |
| #include "rtc_base/event.h" |
| #include "rtc_base/platform_thread.h" |
| #include "rtc_base/synchronization/mutex.h" |
| #include "system_wrappers/include/clock.h" |
| #include "test/pc/e2e/analyzer/video/default_video_quality_analyzer_cpu_measurer.h" |
| #include "test/pc/e2e/analyzer/video/default_video_quality_analyzer_internal_shared_objects.h" |
| #include "test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.h" |
| |
| namespace webrtc { |
| |
| struct FramesComparatorStats { |
| // Size of analyzer internal comparisons queue, measured when new element |
| // id added to the queue. |
| SamplesStatsCounter comparisons_queue_size; |
| // Number of performed comparisons of 2 video frames from captured and |
| // rendered streams. |
| int64_t comparisons_done = 0; |
| // Number of cpu overloaded comparisons. Comparison is cpu overloaded if it is |
| // queued when there are too many not processed comparisons in the queue. |
| // Overloaded comparison doesn't include metrics like SSIM and PSNR that |
| // require heavy computations. |
| int64_t cpu_overloaded_comparisons_done = 0; |
| // Number of memory overloaded comparisons. Comparison is memory overloaded if |
| // it is queued when its captured frame was already removed due to high memory |
| // usage for that video stream. |
| int64_t memory_overloaded_comparisons_done = 0; |
| }; |
| |
| // Performs comparisons of added frames and tracks frames related statistics. |
| // This class is thread safe. |
| class DefaultVideoQualityAnalyzerFramesComparator { |
| public: |
| // Creates frames comparator. |
| // Frames comparator doesn't use `options.enable_receive_own_stream` for any |
| // purposes, because it's unrelated to its functionality. |
| DefaultVideoQualityAnalyzerFramesComparator( |
| webrtc::Clock* clock, |
| DefaultVideoQualityAnalyzerCpuMeasurer& cpu_measurer, |
| DefaultVideoQualityAnalyzerOptions options = {}) |
| : options_(options), clock_(clock), cpu_measurer_(cpu_measurer) {} |
| ~DefaultVideoQualityAnalyzerFramesComparator() { Stop({}); } |
| |
| // Starts frames comparator. This method must be invoked before calling |
| // any other method on this object. |
| void Start(int max_threads_count); |
| // Stops frames comparator. This method will block until all added frame |
| // comparisons will be processed. After `Stop()` is invoked no more new |
| // comparisons can be added to this frames comparator. |
| // |
| // `last_rendered_frame_time` contains timestamps of last rendered frame for |
| // each (stream, sender, receiver) tuple to properly update time between |
| // freezes: it has include time from the last freeze until and of call. |
| void Stop( |
| const std::map<InternalStatsKey, Timestamp>& last_rendered_frame_times); |
| |
| // Ensures that stream `stream_index` has stats objects created for all |
| // potential receivers. This method must be called before adding any |
| // frames comparison for that stream. |
| void EnsureStatsForStream(size_t stream_index, |
| size_t sender_peer_index, |
| size_t peers_count, |
| Timestamp captured_time, |
| Timestamp start_time); |
| // Ensures that newly added participant will have stream stats objects created |
| // for all streams which they can receive. This method must be called before |
| // any frames comparison will be added for the newly added participant. |
| // |
| // `stream_started_time` - start time of each stream for which stats object |
| // has to be created. |
| // `start_time` - call start time. |
| void RegisterParticipantInCall( |
| rtc::ArrayView<std::pair<InternalStatsKey, Timestamp>> |
| stream_started_time, |
| Timestamp start_time); |
| |
| // `captured` - video frame captured by sender to use for PSNR/SSIM |
| // computation. If `type` is `FrameComparisonType::kRegular` and |
| // `captured` is `absl::nullopt` comparison is assumed to be overloaded |
| // due to memory constraints. |
| // `rendered` - video frame rendered by receiver to use for PSNR/SSIM |
| // computation. Required only if `type` is |
| // `FrameComparisonType::kRegular`, but can still be omitted if |
| // `captured` is `absl::nullopt`. |
| void AddComparison(InternalStatsKey stats_key, |
| absl::optional<VideoFrame> captured, |
| absl::optional<VideoFrame> rendered, |
| FrameComparisonType type, |
| FrameStats frame_stats); |
| // `skipped_between_rendered` - amount of frames dropped on this stream before |
| // last received frame and current frame. |
| void AddComparison(InternalStatsKey stats_key, |
| int skipped_between_rendered, |
| absl::optional<VideoFrame> captured, |
| absl::optional<VideoFrame> rendered, |
| FrameComparisonType type, |
| FrameStats frame_stats); |
| |
| std::map<InternalStatsKey, StreamStats> stream_stats() const { |
| MutexLock lock(&mutex_); |
| return stream_stats_; |
| } |
| FramesComparatorStats frames_comparator_stats() const { |
| MutexLock lock(&mutex_); |
| return frames_comparator_stats_; |
| } |
| |
| private: |
| enum State { kNew, kActive, kStopped }; |
| |
| void AddComparisonInternal(InternalStatsKey stats_key, |
| absl::optional<VideoFrame> captured, |
| absl::optional<VideoFrame> rendered, |
| FrameComparisonType type, |
| FrameStats frame_stats) |
| RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); |
| void ProcessComparisons(); |
| void ProcessComparison(const FrameComparison& comparison); |
| Timestamp Now(); |
| |
| const DefaultVideoQualityAnalyzerOptions options_; |
| webrtc::Clock* const clock_; |
| DefaultVideoQualityAnalyzerCpuMeasurer& cpu_measurer_; |
| |
| mutable Mutex mutex_; |
| State state_ RTC_GUARDED_BY(mutex_) = State::kNew; |
| 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_); |
| FramesComparatorStats frames_comparator_stats_ RTC_GUARDED_BY(mutex_); |
| |
| std::vector<rtc::PlatformThread> thread_pool_; |
| rtc::Event comparison_available_event_; |
| }; |
| |
| } // namespace webrtc |
| |
| #endif // TEST_PC_E2E_ANALYZER_VIDEO_DEFAULT_VIDEO_QUALITY_ANALYZER_FRAMES_COMPARATOR_H_ |