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/scoped_ptr.h" 10 #include "base/threading/thread_checker.h" 11 #include "base/time/tick_clock.h" 12 #include "media/cast/logging/logging_defines.h" 13 #include "media/cast/logging/raw_event_subscriber.h" 14 #include "media/cast/logging/receiver_time_offset_estimator.h" 15 16 namespace base { 17 class DictionaryValue; 18 } 19 20 namespace media { 21 namespace cast { 22 23 class StatsEventSubscriberTest; 24 25 // A RawEventSubscriber implementation that subscribes to events, 26 // and aggregates them into stats. 27 class StatsEventSubscriber : public RawEventSubscriber { 28 public: 29 StatsEventSubscriber(EventMediaType event_media_type, 30 base::TickClock* clock, 31 ReceiverTimeOffsetEstimator* offset_estimator); 32 33 virtual ~StatsEventSubscriber(); 34 35 // RawReventSubscriber implementations. 36 virtual void OnReceiveFrameEvent(const FrameEvent& frame_event) OVERRIDE; 37 virtual void OnReceivePacketEvent(const PacketEvent& packet_event) OVERRIDE; 38 39 // Returns stats as a DictionaryValue. The dictionary contains one entry - 40 // "audio" or "video" pointing to an inner dictionary. 41 // The inner dictionary consists of string - double entries, where the string 42 // describes the name of the stat, and the double describes 43 // the value of the stat. See CastStat and StatsMap below. 44 scoped_ptr<base::DictionaryValue> GetStats() const; 45 46 // Resets stats in this object. 47 void Reset(); 48 49 private: 50 friend class StatsEventSubscriberTest; 51 FRIEND_TEST_ALL_PREFIXES(StatsEventSubscriberTest, EmptyStats); 52 FRIEND_TEST_ALL_PREFIXES(StatsEventSubscriberTest, Capture); 53 FRIEND_TEST_ALL_PREFIXES(StatsEventSubscriberTest, Encode); 54 FRIEND_TEST_ALL_PREFIXES(StatsEventSubscriberTest, Decode); 55 FRIEND_TEST_ALL_PREFIXES(StatsEventSubscriberTest, PlayoutDelay); 56 FRIEND_TEST_ALL_PREFIXES(StatsEventSubscriberTest, E2ELatency); 57 FRIEND_TEST_ALL_PREFIXES(StatsEventSubscriberTest, Packets); 58 59 // Generic statistics given the raw data. More specific data (e.g. frame rate 60 // and bit rate) can be computed given the basic metrics. 61 // Some of the metrics will only be set when applicable, e.g. delay and size. 62 struct FrameLogStats { 63 FrameLogStats(); 64 ~FrameLogStats(); 65 int event_counter; 66 size_t sum_size; 67 base::TimeDelta sum_delay; 68 }; 69 70 struct PacketLogStats { 71 PacketLogStats(); 72 ~PacketLogStats(); 73 int event_counter; 74 size_t sum_size; 75 }; 76 77 enum CastStat { 78 // Capture frame rate. 79 CAPTURE_FPS, 80 // Encode frame rate. 81 ENCODE_FPS, 82 // Decode frame rate. 83 DECODE_FPS, 84 // Average encode duration in milliseconds. 85 // TODO(imcheng): This stat is not populated yet because we do not have 86 // the time when encode started. Record it in FRAME_ENCODED event. 87 AVG_ENCODE_TIME_MS, 88 // Average playout delay in milliseconds, with target delay already 89 // accounted for. Ideally, every frame should have a playout delay of 0. 90 AVG_PLAYOUT_DELAY_MS, 91 // Duration from when a packet is transmitted to when it is received. 92 // This measures latency from sender to receiver. 93 AVG_NETWORK_LATENCY_MS, 94 // Duration from when a frame is captured to when it should be played out. 95 AVG_E2E_LATENCY_MS, 96 // Encode bitrate in kbps. 97 ENCODE_KBPS, 98 // Packet transmission bitrate in kbps. 99 TRANSMISSION_KBPS, 100 // Packet retransmission bitrate in kbps. 101 RETRANSMISSION_KBPS, 102 // Fraction of packet loss. 103 PACKET_LOSS_FRACTION, 104 // Duration in milliseconds since last receiver response. 105 MS_SINCE_LAST_RECEIVER_RESPONSE 106 }; 107 108 typedef std::map<CastStat, double> StatsMap; 109 typedef std::map<RtpTimestamp, base::TimeTicks> FrameEventTimeMap; 110 typedef std::map< 111 std::pair<RtpTimestamp, uint16>, 112 std::pair<base::TimeTicks, CastLoggingEvent> > 113 PacketEventTimeMap; 114 typedef std::map<CastLoggingEvent, FrameLogStats> FrameStatsMap; 115 typedef std::map<CastLoggingEvent, PacketLogStats> PacketStatsMap; 116 117 static const char* CastStatToString(CastStat stat); 118 119 // Assigns |stats_map| with stats data. Used for testing. 120 void GetStatsInternal(StatsMap* stats_map) const; 121 122 bool GetReceiverOffset(base::TimeDelta* offset); 123 void RecordFrameCapturedTime(const FrameEvent& frame_event); 124 void RecordE2ELatency(const FrameEvent& frame_event); 125 void RecordPacketSentTime(const PacketEvent& packet_event); 126 void ErasePacketSentTime(const PacketEvent& packet_event); 127 void RecordNetworkLatency(const PacketEvent& packet_event); 128 void UpdateLastResponseTime(base::TimeTicks receiver_time); 129 130 void PopulateFpsStat(base::TimeTicks now, 131 CastLoggingEvent event, 132 CastStat stat, 133 StatsMap* stats_map) const; 134 void PopulatePlayoutDelayStat(StatsMap* stats_map) const; 135 void PopulateFrameBitrateStat(base::TimeTicks now, StatsMap* stats_map) const; 136 void PopulatePacketBitrateStat(base::TimeTicks now, 137 CastLoggingEvent event, 138 CastStat stat, 139 StatsMap* stats_map) const; 140 void PopulatePacketLossPercentageStat(StatsMap* stats_map) const; 141 142 const EventMediaType event_media_type_; 143 144 // Not owned by this class. 145 base::TickClock* const clock_; 146 147 // Not owned by this class. 148 ReceiverTimeOffsetEstimator* const offset_estimator_; 149 150 FrameStatsMap frame_stats_; 151 PacketStatsMap packet_stats_; 152 153 base::TimeDelta total_network_latency_; 154 int network_latency_datapoints_; 155 base::TimeDelta total_e2e_latency_; 156 int e2e_latency_datapoints_; 157 158 base::TimeTicks last_response_received_time_; 159 160 // Fixed size map to record when recent frames were captured. 161 FrameEventTimeMap frame_captured_times_; 162 163 // Fixed size map to record when recent packets were sent. 164 PacketEventTimeMap packet_sent_times_; 165 166 // Sender time assigned on creation and |Reset()|. 167 base::TimeTicks start_time_; 168 169 base::ThreadChecker thread_checker_; 170 DISALLOW_COPY_AND_ASSIGN(StatsEventSubscriber); 171 }; 172 173 } // namespace cast 174 } // namespace media 175 176 #endif // MEDIA_CAST_LOGGING_STATS_EVENT_SUBSCRIBER_H_ 177