• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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