1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef MEDIA_CAST_LOGGING_STATS_EVENT_SUBSCRIBER_H_ 6 #define MEDIA_CAST_LOGGING_STATS_EVENT_SUBSCRIBER_H_ 7 8 #include "base/gtest_prod_util.h" 9 #include "base/memory/linked_ptr.h" 10 #include "base/memory/scoped_ptr.h" 11 #include "base/threading/thread_checker.h" 12 #include "base/time/tick_clock.h" 13 #include "media/cast/logging/logging_defines.h" 14 #include "media/cast/logging/raw_event_subscriber.h" 15 #include "media/cast/logging/receiver_time_offset_estimator.h" 16 17 namespace base { 18 class DictionaryValue; 19 class ListValue; 20 } 21 22 namespace media { 23 namespace cast { 24 25 class StatsEventSubscriberTest; 26 27 // A RawEventSubscriber implementation that subscribes to events, 28 // and aggregates them into stats. 29 class StatsEventSubscriber : public RawEventSubscriber { 30 public: 31 StatsEventSubscriber(EventMediaType event_media_type, 32 base::TickClock* clock, 33 ReceiverTimeOffsetEstimator* offset_estimator); 34 35 virtual ~StatsEventSubscriber(); 36 37 // RawReventSubscriber implementations. 38 virtual void OnReceiveFrameEvent(const FrameEvent& frame_event) OVERRIDE; 39 virtual void OnReceivePacketEvent(const PacketEvent& packet_event) OVERRIDE; 40 41 // Returns stats as a DictionaryValue. The dictionary contains one entry - 42 // "audio" or "video" pointing to an inner dictionary. 43 // The inner dictionary consists of string - double entries, where the string 44 // describes the name of the stat, and the double describes 45 // the value of the stat. See CastStat and StatsMap below. 46 scoped_ptr<base::DictionaryValue> GetStats() const; 47 48 // Resets stats in this object. 49 void Reset(); 50 51 private: 52 friend class StatsEventSubscriberTest; 53 FRIEND_TEST_ALL_PREFIXES(StatsEventSubscriberTest, EmptyStats); 54 FRIEND_TEST_ALL_PREFIXES(StatsEventSubscriberTest, CaptureEncode); 55 FRIEND_TEST_ALL_PREFIXES(StatsEventSubscriberTest, Encode); 56 FRIEND_TEST_ALL_PREFIXES(StatsEventSubscriberTest, Decode); 57 FRIEND_TEST_ALL_PREFIXES(StatsEventSubscriberTest, PlayoutDelay); 58 FRIEND_TEST_ALL_PREFIXES(StatsEventSubscriberTest, E2ELatency); 59 FRIEND_TEST_ALL_PREFIXES(StatsEventSubscriberTest, Packets); 60 61 static const size_t kMaxFrameInfoMapSize = 100; 62 63 // Generic statistics given the raw data. More specific data (e.g. frame rate 64 // and bit rate) can be computed given the basic metrics. 65 // Some of the metrics will only be set when applicable, e.g. delay and size. 66 struct FrameLogStats { 67 FrameLogStats(); 68 ~FrameLogStats(); 69 int event_counter; 70 size_t sum_size; 71 base::TimeDelta sum_delay; 72 }; 73 74 struct PacketLogStats { 75 PacketLogStats(); 76 ~PacketLogStats(); 77 int event_counter; 78 size_t sum_size; 79 }; 80 81 class SimpleHistogram { 82 public: 83 // This will create N+2 buckets where N = (max - min) / width: 84 // Underflow bucket: < min 85 // Bucket 0: [min, min + width - 1] 86 // Bucket 1: [min + width, min + 2 * width - 1] 87 // ... 88 // Bucket N-1: [max - width, max - 1] 89 // Overflow bucket: >= max 90 // |min| must be less than |max|. 91 // |width| must divide |max - min| evenly. 92 SimpleHistogram(int64 min, int64 max, int64 width); 93 94 ~SimpleHistogram(); 95 96 void Add(int64 sample); 97 98 void Reset(); 99 100 scoped_ptr<base::ListValue> GetHistogram() const; 101 102 private: 103 int64 min_; 104 int64 max_; 105 int64 width_; 106 std::vector<int> buckets_; 107 }; 108 109 enum CastStat { 110 // Capture frame rate. 111 CAPTURE_FPS, 112 // Encode frame rate. 113 ENCODE_FPS, 114 // Decode frame rate. 115 DECODE_FPS, 116 // Average encode duration in milliseconds. 117 // TODO(imcheng): This stat is not populated yet because we do not have 118 // the time when encode started. Record it in FRAME_ENCODED event. 119 AVG_ENCODE_TIME_MS, 120 // Average playout delay in milliseconds. 121 AVG_PLAYOUT_DELAY_MS, 122 // Duration from when a packet is transmitted to when it is received. 123 // This measures latency from sender to receiver. 124 AVG_NETWORK_LATENCY_MS, 125 // Duration from when a frame is captured to when it should be played out. 126 AVG_E2E_LATENCY_MS, 127 // Encode bitrate in kbps. 128 ENCODE_KBPS, 129 // Packet transmission bitrate in kbps. 130 TRANSMISSION_KBPS, 131 // Packet retransmission bitrate in kbps. 132 RETRANSMISSION_KBPS, 133 // Fraction of packet loss. 134 PACKET_LOSS_FRACTION, 135 // Duration in milliseconds since last receiver response. 136 MS_SINCE_LAST_RECEIVER_RESPONSE, 137 // Number of frames captured. 138 NUM_FRAMES_CAPTURED, 139 // Number of frames dropped by encoder. 140 NUM_FRAMES_DROPPED_BY_ENCODER, 141 // Number of late frames. 142 NUM_FRAMES_LATE, 143 // Number of packets that were sent (not retransmitted). 144 NUM_PACKETS_SENT, 145 // Number of packets that were retransmitted. 146 NUM_PACKETS_RETRANSMITTED, 147 // Number of packets that had their retransmission cancelled. 148 NUM_PACKETS_RTX_REJECTED, 149 // Unix time in milliseconds of first event since reset. 150 FIRST_EVENT_TIME_MS, 151 // Unix time in milliseconds of last event since reset. 152 LAST_EVENT_TIME_MS, 153 154 // Histograms 155 CAPTURE_LATENCY_MS_HISTO, 156 ENCODE_LATENCY_MS_HISTO, 157 PACKET_LATENCY_MS_HISTO, 158 FRAME_LATENCY_MS_HISTO, 159 PLAYOUT_DELAY_MS_HISTO 160 }; 161 162 struct FrameInfo { 163 FrameInfo(); 164 ~FrameInfo(); 165 166 base::TimeTicks capture_time; 167 base::TimeTicks capture_end_time; 168 base::TimeTicks encode_time; 169 bool encoded; 170 }; 171 172 typedef std::map<CastStat, double> StatsMap; 173 typedef std::map<CastStat, linked_ptr<SimpleHistogram> > HistogramMap; 174 typedef std::map<RtpTimestamp, FrameInfo> FrameInfoMap; 175 typedef std::map< 176 std::pair<RtpTimestamp, uint16>, 177 std::pair<base::TimeTicks, CastLoggingEvent> > 178 PacketEventTimeMap; 179 typedef std::map<CastLoggingEvent, FrameLogStats> FrameStatsMap; 180 typedef std::map<CastLoggingEvent, PacketLogStats> PacketStatsMap; 181 182 static const char* CastStatToString(CastStat stat); 183 184 void InitHistograms(); 185 186 // Assigns |stats_map| with stats data. Used for testing. 187 void GetStatsInternal(StatsMap* stats_map) const; 188 189 void UpdateFirstLastEventTime(base::TimeTicks timestamp, 190 bool is_receiver_event); 191 bool GetReceiverOffset(base::TimeDelta* offset); 192 void MaybeInsertFrameInfo(RtpTimestamp rtp_timestamp, 193 const FrameInfo& frame_info); 194 void RecordFrameCaptureTime(const FrameEvent& frame_event); 195 void RecordCaptureLatency(const FrameEvent& frame_event); 196 void RecordEncodeLatency(const FrameEvent& frame_event); 197 void RecordFrameTxLatency(const FrameEvent& frame_event); 198 void RecordE2ELatency(const FrameEvent& frame_event); 199 void RecordPacketSentTime(const PacketEvent& packet_event); 200 void ErasePacketSentTime(const PacketEvent& packet_event); 201 void RecordNetworkLatency(const PacketEvent& packet_event); 202 void UpdateLastResponseTime(base::TimeTicks receiver_time); 203 204 void PopulateFpsStat(base::TimeTicks now, 205 CastLoggingEvent event, 206 CastStat stat, 207 StatsMap* stats_map) const; 208 void PopulateFrameCountStat(CastLoggingEvent event, 209 CastStat stat, 210 StatsMap* stats_map) const; 211 void PopulatePacketCountStat(CastLoggingEvent event, 212 CastStat stat, 213 StatsMap* stats_map) const; 214 void PopulatePlayoutDelayStat(StatsMap* stats_map) const; 215 void PopulateFrameBitrateStat(base::TimeTicks now, StatsMap* stats_map) const; 216 void PopulatePacketBitrateStat(base::TimeTicks now, 217 CastLoggingEvent event, 218 CastStat stat, 219 StatsMap* stats_map) const; 220 void PopulatePacketLossPercentageStat(StatsMap* stats_map) const; 221 222 const EventMediaType event_media_type_; 223 224 // Not owned by this class. 225 base::TickClock* const clock_; 226 227 // Not owned by this class. 228 ReceiverTimeOffsetEstimator* const offset_estimator_; 229 230 FrameStatsMap frame_stats_; 231 PacketStatsMap packet_stats_; 232 233 base::TimeDelta total_network_latency_; 234 int network_latency_datapoints_; 235 base::TimeDelta total_e2e_latency_; 236 int e2e_latency_datapoints_; 237 238 base::TimeTicks last_response_received_time_; 239 240 int num_frames_dropped_by_encoder_; 241 int num_frames_late_; 242 243 // Fixed size map to record when recent frames were captured and other info. 244 FrameInfoMap recent_frame_infos_; 245 246 // Fixed size map to record when recent packets were sent. 247 PacketEventTimeMap packet_sent_times_; 248 249 // Sender time assigned on creation and |Reset()|. 250 base::TimeTicks start_time_; 251 base::TimeTicks first_event_time_; 252 base::TimeTicks last_event_time_; 253 254 HistogramMap histograms_; 255 256 base::ThreadChecker thread_checker_; 257 DISALLOW_COPY_AND_ASSIGN(StatsEventSubscriber); 258 }; 259 260 } // namespace cast 261 } // namespace media 262 263 #endif // MEDIA_CAST_LOGGING_STATS_EVENT_SUBSCRIBER_H_ 264