blob: c4bf324ef7fd251c3d314de016a19e95d5b6eca5 [file] [log] [blame]
/*
* Copyright (c) 2019 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_H_
#define TEST_PC_E2E_ANALYZER_VIDEO_DEFAULT_VIDEO_QUALITY_ANALYZER_H_
#include <atomic>
#include <cstdint>
#include <deque>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
#include "api/array_view.h"
#include "api/test/metrics/metrics_logger.h"
#include "api/test/video_quality_analyzer_interface.h"
#include "api/units/data_size.h"
#include "api/units/timestamp.h"
#include "api/video/encoded_image.h"
#include "api/video/video_frame.h"
#include "rtc_base/synchronization/mutex.h"
#include "rtc_base/thread_annotations.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_frame_in_flight.h"
#include "test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator.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"
#include "test/pc/e2e/analyzer/video/default_video_quality_analyzer_stream_state.h"
#include "test/pc/e2e/analyzer/video/names_collection.h"
namespace webrtc {
class DefaultVideoQualityAnalyzer : public VideoQualityAnalyzerInterface {
public:
DefaultVideoQualityAnalyzer(webrtc::Clock* clock,
test::MetricsLogger* metrics_logger,
DefaultVideoQualityAnalyzerOptions options = {});
~DefaultVideoQualityAnalyzer() override;
void Start(std::string test_case_name,
rtc::ArrayView<const std::string> peer_names,
int max_threads_count) override;
uint16_t OnFrameCaptured(absl::string_view peer_name,
const std::string& stream_label,
const VideoFrame& frame) override;
void OnFramePreEncode(absl::string_view peer_name,
const VideoFrame& frame) override;
void OnFrameEncoded(absl::string_view peer_name,
uint16_t frame_id,
const EncodedImage& encoded_image,
const EncoderStats& stats,
bool discarded) override;
void OnFrameDropped(absl::string_view peer_name,
EncodedImageCallback::DropReason reason) override;
void OnFramePreDecode(absl::string_view peer_name,
uint16_t frame_id,
const EncodedImage& input_image) override;
void OnFrameDecoded(absl::string_view peer_name,
const VideoFrame& frame,
const DecoderStats& stats) override;
void OnFrameRendered(absl::string_view peer_name,
const VideoFrame& frame) override;
void OnEncoderError(absl::string_view peer_name,
const VideoFrame& frame,
int32_t error_code) override;
void OnDecoderError(absl::string_view peer_name,
uint16_t frame_id,
int32_t error_code,
const DecoderStats& stats) override;
void RegisterParticipantInCall(absl::string_view peer_name) override;
void UnregisterParticipantInCall(absl::string_view peer_name) override;
void OnPeerStartedReceiveVideoStream(absl::string_view peer_name,
absl::string_view stream_label) override;
void OnPeerStoppedReceiveVideoStream(absl::string_view peer_name,
absl::string_view stream_label) override;
void Stop() override;
std::string GetStreamLabel(uint16_t frame_id) override;
void OnStatsReports(
absl::string_view pc_label,
const rtc::scoped_refptr<const RTCStatsReport>& report) override {}
// Returns set of stream labels, that were met during test call.
std::set<StatsKey> GetKnownVideoStreams() const;
VideoStreamsInfo GetKnownStreams() const;
FrameCounters GetGlobalCounters() const;
// Returns frame counter for frames received without frame id set.
std::map<std::string, FrameCounters> GetUnknownSenderFrameCounters() const;
// Returns frame counter per stream label. Valid stream labels can be obtained
// by calling GetKnownVideoStreams()
std::map<StatsKey, FrameCounters> GetPerStreamCounters() const;
// Returns video quality stats per stream label. Valid stream labels can be
// obtained by calling GetKnownVideoStreams()
std::map<StatsKey, StreamStats> GetStats() const;
AnalyzerStats GetAnalyzerStats() const;
double GetCpuUsagePercent();
// Returns mapping from the stream label to the history of frames that were
// met in this stream in the order as they were captured.
std::map<std::string, std::vector<uint16_t>> GetStreamFrames() const;
private:
enum State { kNew, kActive, kStopped };
// Returns next frame id to use. Frame ID can't be `VideoFrame::kNotSetId`,
// because this value is reserved by `VideoFrame` as "ID not set".
uint16_t GetNextFrameId() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
void AddExistingFramesInFlightForStreamToComparator(size_t stream_index,
StreamState& stream_state,
size_t peer_index)
RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Processes frames for the peer identified by `peer_index` up to
// `rendered_frame_id` (excluded). Sends each dropped frame for comparison and
// discards superfluous frames (they were not expected to be received by
// `peer_index` and not accounted in the stats).
// Returns number of dropped frames.
int ProcessNotSeenFramesBeforeRendered(size_t peer_index,
uint16_t rendered_frame_id,
const InternalStatsKey& stats_key,
StreamState& state)
RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Report results for all metrics for all streams.
void ReportResults();
void ReportResults(const InternalStatsKey& key,
const StreamStats& stats,
const FrameCounters& frame_counters)
RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Returns name of current test case for reporting.
std::string GetTestCaseName(const std::string& stream_label) const;
Timestamp Now();
StatsKey ToStatsKey(const InternalStatsKey& key) const
RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Returns string representation of stats key for metrics naming. Used for
// backward compatibility by metrics naming for 2 peers cases.
std::string ToMetricName(const InternalStatsKey& key) const
RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
static const uint16_t kStartingFrameId = 1;
const DefaultVideoQualityAnalyzerOptions options_;
webrtc::Clock* const clock_;
test::MetricsLogger* const metrics_logger_;
std::string test_label_;
mutable Mutex mutex_;
uint16_t next_frame_id_ RTC_GUARDED_BY(mutex_) = kStartingFrameId;
std::unique_ptr<NamesCollection> peers_ RTC_GUARDED_BY(mutex_);
State state_ RTC_GUARDED_BY(mutex_) = State::kNew;
Timestamp start_time_ RTC_GUARDED_BY(mutex_) = Timestamp::MinusInfinity();
// Mapping from stream label to unique size_t value to use in stats and avoid
// extra string copying.
NamesCollection streams_ RTC_GUARDED_BY(mutex_);
// Frames that were captured by all streams and still aren't rendered on
// receivers or deemed dropped. Frame with id X can be removed from this map
// if:
// 1. The frame with id X was received in OnFrameRendered by all expected
// receivers.
// 2. The frame with id Y > X was received in OnFrameRendered by all expected
// receivers.
// 3. Next available frame id for newly captured frame is X
// 4. There too many frames in flight for current video stream and X is the
// oldest frame id in this stream. In such case only the frame content
// will be removed, but the map entry will be preserved.
std::map<uint16_t, FrameInFlight> captured_frames_in_flight_
RTC_GUARDED_BY(mutex_);
// Global frames count for all video streams.
FrameCounters frame_counters_ RTC_GUARDED_BY(mutex_);
// Frame counters for received frames without video frame id set.
// Map from peer name to the frame counters.
std::map<std::string, FrameCounters> unknown_sender_frame_counters_
RTC_GUARDED_BY(mutex_);
// Frame counters per each stream per each receiver.
std::map<InternalStatsKey, FrameCounters> stream_frame_counters_
RTC_GUARDED_BY(mutex_);
// Map from stream index in `streams_` to its StreamState.
std::map<size_t, StreamState> stream_states_ RTC_GUARDED_BY(mutex_);
// Map from stream index in `streams_` to sender peer index in `peers_`.
std::map<size_t, size_t> stream_to_sender_ RTC_GUARDED_BY(mutex_);
// Stores history mapping between stream index in `streams_` and frame ids.
// Updated when frame id overlap. It required to properly return stream label
// after 1st frame from simulcast streams was already rendered and last is
// still encoding.
std::map<size_t, std::set<uint16_t>> stream_to_frame_id_history_
RTC_GUARDED_BY(mutex_);
// Map from stream index to the list of frames as they were met in the stream.
std::map<size_t, std::vector<uint16_t>> stream_to_frame_id_full_history_
RTC_GUARDED_BY(mutex_);
AnalyzerStats analyzer_stats_ RTC_GUARDED_BY(mutex_);
DefaultVideoQualityAnalyzerCpuMeasurer cpu_measurer_;
DefaultVideoQualityAnalyzerFramesComparator frames_comparator_;
};
} // namespace webrtc
#endif // TEST_PC_E2E_ANALYZER_VIDEO_DEFAULT_VIDEO_QUALITY_ANALYZER_H_