1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker 11*d9f75844SAndroid Build Coastguard Worker #ifndef VIDEO_RECEIVE_STATISTICS_PROXY2_H_ 12*d9f75844SAndroid Build Coastguard Worker #define VIDEO_RECEIVE_STATISTICS_PROXY2_H_ 13*d9f75844SAndroid Build Coastguard Worker 14*d9f75844SAndroid Build Coastguard Worker #include <map> 15*d9f75844SAndroid Build Coastguard Worker #include <memory> 16*d9f75844SAndroid Build Coastguard Worker #include <string> 17*d9f75844SAndroid Build Coastguard Worker #include <vector> 18*d9f75844SAndroid Build Coastguard Worker 19*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h" 20*d9f75844SAndroid Build Coastguard Worker #include "api/sequence_checker.h" 21*d9f75844SAndroid Build Coastguard Worker #include "api/task_queue/pending_task_safety_flag.h" 22*d9f75844SAndroid Build Coastguard Worker #include "api/task_queue/task_queue_base.h" 23*d9f75844SAndroid Build Coastguard Worker #include "api/units/timestamp.h" 24*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/video_decoder.h" 25*d9f75844SAndroid Build Coastguard Worker #include "call/video_receive_stream.h" 26*d9f75844SAndroid Build Coastguard Worker #include "modules/include/module_common_types.h" 27*d9f75844SAndroid Build Coastguard Worker #include "modules/video_coding/include/video_coding_defines.h" 28*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/numerics/histogram_percentile_counter.h" 29*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/numerics/moving_max_counter.h" 30*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/numerics/sample_counter.h" 31*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/rate_statistics.h" 32*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/rate_tracker.h" 33*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/system/no_unique_address.h" 34*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread_annotations.h" 35*d9f75844SAndroid Build Coastguard Worker #include "video/quality_threshold.h" 36*d9f75844SAndroid Build Coastguard Worker #include "video/stats_counter.h" 37*d9f75844SAndroid Build Coastguard Worker #include "video/video_quality_observer2.h" 38*d9f75844SAndroid Build Coastguard Worker 39*d9f75844SAndroid Build Coastguard Worker namespace webrtc { 40*d9f75844SAndroid Build Coastguard Worker 41*d9f75844SAndroid Build Coastguard Worker class Clock; 42*d9f75844SAndroid Build Coastguard Worker struct CodecSpecificInfo; 43*d9f75844SAndroid Build Coastguard Worker 44*d9f75844SAndroid Build Coastguard Worker namespace internal { 45*d9f75844SAndroid Build Coastguard Worker // Declared in video_receive_stream2.h. 46*d9f75844SAndroid Build Coastguard Worker struct VideoFrameMetaData; 47*d9f75844SAndroid Build Coastguard Worker 48*d9f75844SAndroid Build Coastguard Worker class ReceiveStatisticsProxy : public VCMReceiveStatisticsCallback, 49*d9f75844SAndroid Build Coastguard Worker public RtcpCnameCallback, 50*d9f75844SAndroid Build Coastguard Worker public RtcpPacketTypeCounterObserver { 51*d9f75844SAndroid Build Coastguard Worker public: 52*d9f75844SAndroid Build Coastguard Worker ReceiveStatisticsProxy(uint32_t remote_ssrc, 53*d9f75844SAndroid Build Coastguard Worker Clock* clock, 54*d9f75844SAndroid Build Coastguard Worker TaskQueueBase* worker_thread); 55*d9f75844SAndroid Build Coastguard Worker ~ReceiveStatisticsProxy() override; 56*d9f75844SAndroid Build Coastguard Worker 57*d9f75844SAndroid Build Coastguard Worker VideoReceiveStreamInterface::Stats GetStats() const; 58*d9f75844SAndroid Build Coastguard Worker 59*d9f75844SAndroid Build Coastguard Worker void OnDecodedFrame(const VideoFrame& frame, 60*d9f75844SAndroid Build Coastguard Worker absl::optional<uint8_t> qp, 61*d9f75844SAndroid Build Coastguard Worker TimeDelta decode_time, 62*d9f75844SAndroid Build Coastguard Worker VideoContentType content_type); 63*d9f75844SAndroid Build Coastguard Worker 64*d9f75844SAndroid Build Coastguard Worker // Called asyncronously on the worker thread as a result of a call to the 65*d9f75844SAndroid Build Coastguard Worker // above OnDecodedFrame method, which is called back on the thread where 66*d9f75844SAndroid Build Coastguard Worker // the actual decoding happens. 67*d9f75844SAndroid Build Coastguard Worker void OnDecodedFrame(const VideoFrameMetaData& frame_meta, 68*d9f75844SAndroid Build Coastguard Worker absl::optional<uint8_t> qp, 69*d9f75844SAndroid Build Coastguard Worker TimeDelta decode_time, 70*d9f75844SAndroid Build Coastguard Worker TimeDelta processing_delay, 71*d9f75844SAndroid Build Coastguard Worker TimeDelta assembly_time, 72*d9f75844SAndroid Build Coastguard Worker VideoContentType content_type); 73*d9f75844SAndroid Build Coastguard Worker 74*d9f75844SAndroid Build Coastguard Worker void OnSyncOffsetUpdated(int64_t video_playout_ntp_ms, 75*d9f75844SAndroid Build Coastguard Worker int64_t sync_offset_ms, 76*d9f75844SAndroid Build Coastguard Worker double estimated_freq_khz); 77*d9f75844SAndroid Build Coastguard Worker void OnRenderedFrame(const VideoFrameMetaData& frame_meta); 78*d9f75844SAndroid Build Coastguard Worker void OnIncomingPayloadType(int payload_type); 79*d9f75844SAndroid Build Coastguard Worker void OnDecoderInfo(const VideoDecoder::DecoderInfo& decoder_info); 80*d9f75844SAndroid Build Coastguard Worker 81*d9f75844SAndroid Build Coastguard Worker void OnPreDecode(VideoCodecType codec_type, int qp); 82*d9f75844SAndroid Build Coastguard Worker 83*d9f75844SAndroid Build Coastguard Worker void OnUniqueFramesCounted(int num_unique_frames); 84*d9f75844SAndroid Build Coastguard Worker 85*d9f75844SAndroid Build Coastguard Worker // Indicates video stream has been paused (no incoming packets). 86*d9f75844SAndroid Build Coastguard Worker void OnStreamInactive(); 87*d9f75844SAndroid Build Coastguard Worker 88*d9f75844SAndroid Build Coastguard Worker // Overrides VCMReceiveStatisticsCallback. 89*d9f75844SAndroid Build Coastguard Worker void OnCompleteFrame(bool is_keyframe, 90*d9f75844SAndroid Build Coastguard Worker size_t size_bytes, 91*d9f75844SAndroid Build Coastguard Worker VideoContentType content_type) override; 92*d9f75844SAndroid Build Coastguard Worker void OnDroppedFrames(uint32_t frames_dropped) override; 93*d9f75844SAndroid Build Coastguard Worker void OnFrameBufferTimingsUpdated(int max_decode_ms, 94*d9f75844SAndroid Build Coastguard Worker int current_delay_ms, 95*d9f75844SAndroid Build Coastguard Worker int target_delay_ms, 96*d9f75844SAndroid Build Coastguard Worker int jitter_buffer_ms, 97*d9f75844SAndroid Build Coastguard Worker int min_playout_delay_ms, 98*d9f75844SAndroid Build Coastguard Worker int render_delay_ms) override; 99*d9f75844SAndroid Build Coastguard Worker 100*d9f75844SAndroid Build Coastguard Worker void OnTimingFrameInfoUpdated(const TimingFrameInfo& info) override; 101*d9f75844SAndroid Build Coastguard Worker 102*d9f75844SAndroid Build Coastguard Worker // Overrides RtcpCnameCallback. 103*d9f75844SAndroid Build Coastguard Worker void OnCname(uint32_t ssrc, absl::string_view cname) override; 104*d9f75844SAndroid Build Coastguard Worker 105*d9f75844SAndroid Build Coastguard Worker // Overrides RtcpPacketTypeCounterObserver. 106*d9f75844SAndroid Build Coastguard Worker void RtcpPacketTypesCounterUpdated( 107*d9f75844SAndroid Build Coastguard Worker uint32_t ssrc, 108*d9f75844SAndroid Build Coastguard Worker const RtcpPacketTypeCounter& packet_counter) override; 109*d9f75844SAndroid Build Coastguard Worker 110*d9f75844SAndroid Build Coastguard Worker void OnRttUpdate(int64_t avg_rtt_ms); 111*d9f75844SAndroid Build Coastguard Worker 112*d9f75844SAndroid Build Coastguard Worker // Notification methods that are used to check our internal state and validate 113*d9f75844SAndroid Build Coastguard Worker // threading assumptions. These are called by VideoReceiveStreamInterface. 114*d9f75844SAndroid Build Coastguard Worker void DecoderThreadStarting(); 115*d9f75844SAndroid Build Coastguard Worker void DecoderThreadStopped(); 116*d9f75844SAndroid Build Coastguard Worker 117*d9f75844SAndroid Build Coastguard Worker // Produce histograms. Must be called after DecoderThreadStopped(), typically 118*d9f75844SAndroid Build Coastguard Worker // at the end of the call. 119*d9f75844SAndroid Build Coastguard Worker void UpdateHistograms(absl::optional<int> fraction_lost, 120*d9f75844SAndroid Build Coastguard Worker const StreamDataCounters& rtp_stats, 121*d9f75844SAndroid Build Coastguard Worker const StreamDataCounters* rtx_stats); 122*d9f75844SAndroid Build Coastguard Worker 123*d9f75844SAndroid Build Coastguard Worker private: 124*d9f75844SAndroid Build Coastguard Worker struct QpCounters { 125*d9f75844SAndroid Build Coastguard Worker rtc::SampleCounter vp8; 126*d9f75844SAndroid Build Coastguard Worker }; 127*d9f75844SAndroid Build Coastguard Worker 128*d9f75844SAndroid Build Coastguard Worker struct ContentSpecificStats { 129*d9f75844SAndroid Build Coastguard Worker ContentSpecificStats(); 130*d9f75844SAndroid Build Coastguard Worker ~ContentSpecificStats(); 131*d9f75844SAndroid Build Coastguard Worker 132*d9f75844SAndroid Build Coastguard Worker void Add(const ContentSpecificStats& other); 133*d9f75844SAndroid Build Coastguard Worker 134*d9f75844SAndroid Build Coastguard Worker rtc::SampleCounter e2e_delay_counter; 135*d9f75844SAndroid Build Coastguard Worker rtc::SampleCounter interframe_delay_counter; 136*d9f75844SAndroid Build Coastguard Worker int64_t flow_duration_ms = 0; 137*d9f75844SAndroid Build Coastguard Worker int64_t total_media_bytes = 0; 138*d9f75844SAndroid Build Coastguard Worker rtc::SampleCounter received_width; 139*d9f75844SAndroid Build Coastguard Worker rtc::SampleCounter received_height; 140*d9f75844SAndroid Build Coastguard Worker rtc::SampleCounter qp_counter; 141*d9f75844SAndroid Build Coastguard Worker FrameCounts frame_counts; 142*d9f75844SAndroid Build Coastguard Worker rtc::HistogramPercentileCounter interframe_delay_percentiles; 143*d9f75844SAndroid Build Coastguard Worker }; 144*d9f75844SAndroid Build Coastguard Worker 145*d9f75844SAndroid Build Coastguard Worker void QualitySample(Timestamp now); 146*d9f75844SAndroid Build Coastguard Worker 147*d9f75844SAndroid Build Coastguard Worker // Removes info about old frames and then updates the framerate. 148*d9f75844SAndroid Build Coastguard Worker void UpdateFramerate(int64_t now_ms) const; 149*d9f75844SAndroid Build Coastguard Worker 150*d9f75844SAndroid Build Coastguard Worker absl::optional<int64_t> GetCurrentEstimatedPlayoutNtpTimestampMs( 151*d9f75844SAndroid Build Coastguard Worker int64_t now_ms) const; 152*d9f75844SAndroid Build Coastguard Worker 153*d9f75844SAndroid Build Coastguard Worker Clock* const clock_; 154*d9f75844SAndroid Build Coastguard Worker const int64_t start_ms_; 155*d9f75844SAndroid Build Coastguard Worker 156*d9f75844SAndroid Build Coastguard Worker int64_t last_sample_time_ RTC_GUARDED_BY(main_thread_); 157*d9f75844SAndroid Build Coastguard Worker 158*d9f75844SAndroid Build Coastguard Worker QualityThreshold fps_threshold_ RTC_GUARDED_BY(main_thread_); 159*d9f75844SAndroid Build Coastguard Worker QualityThreshold qp_threshold_ RTC_GUARDED_BY(main_thread_); 160*d9f75844SAndroid Build Coastguard Worker QualityThreshold variance_threshold_ RTC_GUARDED_BY(main_thread_); 161*d9f75844SAndroid Build Coastguard Worker rtc::SampleCounter qp_sample_ RTC_GUARDED_BY(main_thread_); 162*d9f75844SAndroid Build Coastguard Worker int num_bad_states_ RTC_GUARDED_BY(main_thread_); 163*d9f75844SAndroid Build Coastguard Worker int num_certain_states_ RTC_GUARDED_BY(main_thread_); 164*d9f75844SAndroid Build Coastguard Worker // Note: The `stats_.rtp_stats` member is not used or populated by this class. 165*d9f75844SAndroid Build Coastguard Worker mutable VideoReceiveStreamInterface::Stats stats_ 166*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(main_thread_); 167*d9f75844SAndroid Build Coastguard Worker // Same as stats_.ssrc, but const (no lock required). 168*d9f75844SAndroid Build Coastguard Worker const uint32_t remote_ssrc_; 169*d9f75844SAndroid Build Coastguard Worker RateStatistics decode_fps_estimator_ RTC_GUARDED_BY(main_thread_); 170*d9f75844SAndroid Build Coastguard Worker RateStatistics renders_fps_estimator_ RTC_GUARDED_BY(main_thread_); 171*d9f75844SAndroid Build Coastguard Worker rtc::RateTracker render_fps_tracker_ RTC_GUARDED_BY(main_thread_); 172*d9f75844SAndroid Build Coastguard Worker rtc::RateTracker render_pixel_tracker_ RTC_GUARDED_BY(main_thread_); 173*d9f75844SAndroid Build Coastguard Worker rtc::SampleCounter sync_offset_counter_ RTC_GUARDED_BY(main_thread_); 174*d9f75844SAndroid Build Coastguard Worker rtc::SampleCounter decode_time_counter_ RTC_GUARDED_BY(main_thread_); 175*d9f75844SAndroid Build Coastguard Worker rtc::SampleCounter jitter_buffer_delay_counter_ RTC_GUARDED_BY(main_thread_); 176*d9f75844SAndroid Build Coastguard Worker rtc::SampleCounter target_delay_counter_ RTC_GUARDED_BY(main_thread_); 177*d9f75844SAndroid Build Coastguard Worker rtc::SampleCounter current_delay_counter_ RTC_GUARDED_BY(main_thread_); 178*d9f75844SAndroid Build Coastguard Worker rtc::SampleCounter delay_counter_ RTC_GUARDED_BY(main_thread_); 179*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<VideoQualityObserver> video_quality_observer_ 180*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(main_thread_); 181*d9f75844SAndroid Build Coastguard Worker mutable rtc::MovingMaxCounter<int> interframe_delay_max_moving_ 182*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(main_thread_); 183*d9f75844SAndroid Build Coastguard Worker std::map<VideoContentType, ContentSpecificStats> content_specific_stats_ 184*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(main_thread_); 185*d9f75844SAndroid Build Coastguard Worker MaxCounter freq_offset_counter_ RTC_GUARDED_BY(main_thread_); 186*d9f75844SAndroid Build Coastguard Worker QpCounters qp_counters_ RTC_GUARDED_BY(main_thread_); 187*d9f75844SAndroid Build Coastguard Worker int64_t avg_rtt_ms_ RTC_GUARDED_BY(main_thread_) = 0; 188*d9f75844SAndroid Build Coastguard Worker mutable std::map<int64_t, size_t> frame_window_ RTC_GUARDED_BY(main_thread_); 189*d9f75844SAndroid Build Coastguard Worker VideoContentType last_content_type_ RTC_GUARDED_BY(&main_thread_); 190*d9f75844SAndroid Build Coastguard Worker VideoCodecType last_codec_type_ RTC_GUARDED_BY(main_thread_); 191*d9f75844SAndroid Build Coastguard Worker absl::optional<int64_t> first_frame_received_time_ms_ 192*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(main_thread_); 193*d9f75844SAndroid Build Coastguard Worker absl::optional<int64_t> first_decoded_frame_time_ms_ 194*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(main_thread_); 195*d9f75844SAndroid Build Coastguard Worker absl::optional<int64_t> last_decoded_frame_time_ms_ 196*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(main_thread_); 197*d9f75844SAndroid Build Coastguard Worker size_t num_delayed_frames_rendered_ RTC_GUARDED_BY(main_thread_); 198*d9f75844SAndroid Build Coastguard Worker int64_t sum_missed_render_deadline_ms_ RTC_GUARDED_BY(main_thread_); 199*d9f75844SAndroid Build Coastguard Worker // Mutable because calling Max() on MovingMaxCounter is not const. Yet it is 200*d9f75844SAndroid Build Coastguard Worker // called from const GetStats(). 201*d9f75844SAndroid Build Coastguard Worker mutable rtc::MovingMaxCounter<TimingFrameInfo> timing_frame_info_counter_ 202*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(main_thread_); 203*d9f75844SAndroid Build Coastguard Worker absl::optional<int> num_unique_frames_ RTC_GUARDED_BY(main_thread_); 204*d9f75844SAndroid Build Coastguard Worker absl::optional<int64_t> last_estimated_playout_ntp_timestamp_ms_ 205*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(main_thread_); 206*d9f75844SAndroid Build Coastguard Worker absl::optional<int64_t> last_estimated_playout_time_ms_ 207*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(main_thread_); 208*d9f75844SAndroid Build Coastguard Worker 209*d9f75844SAndroid Build Coastguard Worker // The thread on which this instance is constructed and some of its main 210*d9f75844SAndroid Build Coastguard Worker // methods are invoked on such as GetStats(). 211*d9f75844SAndroid Build Coastguard Worker TaskQueueBase* const worker_thread_; 212*d9f75844SAndroid Build Coastguard Worker 213*d9f75844SAndroid Build Coastguard Worker ScopedTaskSafety task_safety_; 214*d9f75844SAndroid Build Coastguard Worker 215*d9f75844SAndroid Build Coastguard Worker RTC_NO_UNIQUE_ADDRESS SequenceChecker decode_queue_; 216*d9f75844SAndroid Build Coastguard Worker SequenceChecker main_thread_; 217*d9f75844SAndroid Build Coastguard Worker RTC_NO_UNIQUE_ADDRESS SequenceChecker incoming_render_queue_; 218*d9f75844SAndroid Build Coastguard Worker }; 219*d9f75844SAndroid Build Coastguard Worker 220*d9f75844SAndroid Build Coastguard Worker } // namespace internal 221*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc 222*d9f75844SAndroid Build Coastguard Worker #endif // VIDEO_RECEIVE_STATISTICS_PROXY2_H_ 223