diff options
Diffstat (limited to '')
-rw-r--r-- | third_party/libwebrtc/video/receive_statistics_proxy2.h | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/third_party/libwebrtc/video/receive_statistics_proxy2.h b/third_party/libwebrtc/video/receive_statistics_proxy2.h new file mode 100644 index 0000000000..20139b45e5 --- /dev/null +++ b/third_party/libwebrtc/video/receive_statistics_proxy2.h @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2020 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 VIDEO_RECEIVE_STATISTICS_PROXY2_H_ +#define VIDEO_RECEIVE_STATISTICS_PROXY2_H_ + +#include <map> +#include <memory> +#include <string> +#include <vector> + +#include "absl/types/optional.h" +#include "api/sequence_checker.h" +#include "api/task_queue/pending_task_safety_flag.h" +#include "api/task_queue/task_queue_base.h" +#include "api/units/timestamp.h" +#include "api/video_codecs/video_decoder.h" +#include "call/video_receive_stream.h" +#include "modules/include/module_common_types.h" +#include "modules/video_coding/include/video_coding_defines.h" +#include "rtc_base/numerics/histogram_percentile_counter.h" +#include "rtc_base/numerics/moving_max_counter.h" +#include "rtc_base/numerics/sample_counter.h" +#include "rtc_base/rate_statistics.h" +#include "rtc_base/rate_tracker.h" +#include "rtc_base/system/no_unique_address.h" +#include "rtc_base/thread_annotations.h" +#include "video/quality_threshold.h" +#include "video/stats_counter.h" +#include "video/video_quality_observer2.h" + +namespace webrtc { + +class Clock; +struct CodecSpecificInfo; + +namespace internal { +// Declared in video_receive_stream2.h. +struct VideoFrameMetaData; + +class ReceiveStatisticsProxy : public VCMReceiveStatisticsCallback, + public RtcpCnameCallback, + public RtcpPacketTypeCounterObserver { + public: + ReceiveStatisticsProxy(uint32_t remote_ssrc, + Clock* clock, + TaskQueueBase* worker_thread); + ~ReceiveStatisticsProxy() override; + + VideoReceiveStreamInterface::Stats GetStats() const; + + void OnDecodedFrame(const VideoFrame& frame, + absl::optional<uint8_t> qp, + TimeDelta decode_time, + VideoContentType content_type); + + // Called asyncronously on the worker thread as a result of a call to the + // above OnDecodedFrame method, which is called back on the thread where + // the actual decoding happens. + void OnDecodedFrame(const VideoFrameMetaData& frame_meta, + absl::optional<uint8_t> qp, + TimeDelta decode_time, + TimeDelta processing_delay, + TimeDelta assembly_time, + VideoContentType content_type); + + void OnSyncOffsetUpdated(int64_t video_playout_ntp_ms, + int64_t sync_offset_ms, + double estimated_freq_khz); + void OnRenderedFrame(const VideoFrameMetaData& frame_meta); + void OnIncomingPayloadType(int payload_type); + void OnDecoderInfo(const VideoDecoder::DecoderInfo& decoder_info); + + void OnPreDecode(VideoCodecType codec_type, int qp); + + void OnUniqueFramesCounted(int num_unique_frames); + + // Indicates video stream has been paused (no incoming packets). + void OnStreamInactive(); + + // Overrides VCMReceiveStatisticsCallback. + void OnCompleteFrame(bool is_keyframe, + size_t size_bytes, + VideoContentType content_type) override; + void OnDroppedFrames(uint32_t frames_dropped) override; + void OnDiscardedPackets(uint32_t packets_discarded) override; + void OnFrameBufferTimingsUpdated(int max_decode_ms, + int current_delay_ms, + int target_delay_ms, + int jitter_buffer_ms, + int min_playout_delay_ms, + int render_delay_ms) override; + + void OnTimingFrameInfoUpdated(const TimingFrameInfo& info) override; + + // Overrides RtcpCnameCallback. + void OnCname(uint32_t ssrc, absl::string_view cname) override; + + // Overrides RtcpPacketTypeCounterObserver. + void RtcpPacketTypesCounterUpdated( + uint32_t ssrc, + const RtcpPacketTypeCounter& packet_counter) override; + + void OnRttUpdate(int64_t avg_rtt_ms); + + // Notification methods that are used to check our internal state and validate + // threading assumptions. These are called by VideoReceiveStreamInterface. + void DecoderThreadStarting(); + void DecoderThreadStopped(); + + // Produce histograms. Must be called after DecoderThreadStopped(), typically + // at the end of the call. + void UpdateHistograms(absl::optional<int> fraction_lost, + const StreamDataCounters& rtp_stats, + const StreamDataCounters* rtx_stats); + + private: + struct QpCounters { + rtc::SampleCounter vp8; + }; + + struct ContentSpecificStats { + ContentSpecificStats(); + ~ContentSpecificStats(); + + void Add(const ContentSpecificStats& other); + + rtc::SampleCounter e2e_delay_counter; + rtc::SampleCounter interframe_delay_counter; + int64_t flow_duration_ms = 0; + int64_t total_media_bytes = 0; + rtc::SampleCounter received_width; + rtc::SampleCounter received_height; + rtc::SampleCounter qp_counter; + FrameCounts frame_counts; + rtc::HistogramPercentileCounter interframe_delay_percentiles; + }; + + void QualitySample(Timestamp now); + + // Removes info about old frames and then updates the framerate. + void UpdateFramerate(int64_t now_ms) const; + + absl::optional<int64_t> GetCurrentEstimatedPlayoutNtpTimestampMs( + int64_t now_ms) const; + + Clock* const clock_; + const int64_t start_ms_; + + int64_t last_sample_time_ RTC_GUARDED_BY(main_thread_); + + QualityThreshold fps_threshold_ RTC_GUARDED_BY(main_thread_); + QualityThreshold qp_threshold_ RTC_GUARDED_BY(main_thread_); + QualityThreshold variance_threshold_ RTC_GUARDED_BY(main_thread_); + rtc::SampleCounter qp_sample_ RTC_GUARDED_BY(main_thread_); + int num_bad_states_ RTC_GUARDED_BY(main_thread_); + int num_certain_states_ RTC_GUARDED_BY(main_thread_); + // Note: The `stats_.rtp_stats` member is not used or populated by this class. + mutable VideoReceiveStreamInterface::Stats stats_ + RTC_GUARDED_BY(main_thread_); + // Same as stats_.ssrc, but const (no lock required). + const uint32_t remote_ssrc_; + RateStatistics decode_fps_estimator_ RTC_GUARDED_BY(main_thread_); + RateStatistics renders_fps_estimator_ RTC_GUARDED_BY(main_thread_); + rtc::RateTracker render_fps_tracker_ RTC_GUARDED_BY(main_thread_); + rtc::RateTracker render_pixel_tracker_ RTC_GUARDED_BY(main_thread_); + rtc::SampleCounter sync_offset_counter_ RTC_GUARDED_BY(main_thread_); + rtc::SampleCounter decode_time_counter_ RTC_GUARDED_BY(main_thread_); + rtc::SampleCounter jitter_buffer_delay_counter_ RTC_GUARDED_BY(main_thread_); + rtc::SampleCounter target_delay_counter_ RTC_GUARDED_BY(main_thread_); + rtc::SampleCounter current_delay_counter_ RTC_GUARDED_BY(main_thread_); + rtc::SampleCounter delay_counter_ RTC_GUARDED_BY(main_thread_); + std::unique_ptr<VideoQualityObserver> video_quality_observer_ + RTC_GUARDED_BY(main_thread_); + mutable rtc::MovingMaxCounter<int> interframe_delay_max_moving_ + RTC_GUARDED_BY(main_thread_); + std::map<VideoContentType, ContentSpecificStats> content_specific_stats_ + RTC_GUARDED_BY(main_thread_); + MaxCounter freq_offset_counter_ RTC_GUARDED_BY(main_thread_); + QpCounters qp_counters_ RTC_GUARDED_BY(main_thread_); + int64_t avg_rtt_ms_ RTC_GUARDED_BY(main_thread_) = 0; + mutable std::map<int64_t, size_t> frame_window_ RTC_GUARDED_BY(main_thread_); + VideoContentType last_content_type_ RTC_GUARDED_BY(&main_thread_); + VideoCodecType last_codec_type_ RTC_GUARDED_BY(main_thread_); + absl::optional<int64_t> first_frame_received_time_ms_ + RTC_GUARDED_BY(main_thread_); + absl::optional<int64_t> first_decoded_frame_time_ms_ + RTC_GUARDED_BY(main_thread_); + absl::optional<int64_t> last_decoded_frame_time_ms_ + RTC_GUARDED_BY(main_thread_); + size_t num_delayed_frames_rendered_ RTC_GUARDED_BY(main_thread_); + int64_t sum_missed_render_deadline_ms_ RTC_GUARDED_BY(main_thread_); + // Mutable because calling Max() on MovingMaxCounter is not const. Yet it is + // called from const GetStats(). + mutable rtc::MovingMaxCounter<TimingFrameInfo> timing_frame_info_counter_ + RTC_GUARDED_BY(main_thread_); + absl::optional<int> num_unique_frames_ RTC_GUARDED_BY(main_thread_); + absl::optional<int64_t> last_estimated_playout_ntp_timestamp_ms_ + RTC_GUARDED_BY(main_thread_); + absl::optional<int64_t> last_estimated_playout_time_ms_ + RTC_GUARDED_BY(main_thread_); + + // The thread on which this instance is constructed and some of its main + // methods are invoked on such as GetStats(). + TaskQueueBase* const worker_thread_; + + ScopedTaskSafety task_safety_; + + RTC_NO_UNIQUE_ADDRESS SequenceChecker decode_queue_; + SequenceChecker main_thread_; + RTC_NO_UNIQUE_ADDRESS SequenceChecker incoming_render_queue_; +}; + +} // namespace internal +} // namespace webrtc +#endif // VIDEO_RECEIVE_STATISTICS_PROXY2_H_ |