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.
5 #ifndef MEDIA_CAST_LOGGING_STATS_EVENT_SUBSCRIBER_H_
6 #define MEDIA_CAST_LOGGING_STATS_EVENT_SUBSCRIBER_H_
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"
17 class DictionaryValue
;
23 class StatsEventSubscriberTest
;
25 // A RawEventSubscriber implementation that subscribes to events,
26 // and aggregates them into stats.
27 class StatsEventSubscriber
: public RawEventSubscriber
{
29 StatsEventSubscriber(EventMediaType event_media_type
,
30 base::TickClock
* clock
,
31 ReceiverTimeOffsetEstimator
* offset_estimator
);
33 virtual ~StatsEventSubscriber();
35 // RawReventSubscriber implementations.
36 virtual void OnReceiveFrameEvent(const FrameEvent
& frame_event
) OVERRIDE
;
37 virtual void OnReceivePacketEvent(const PacketEvent
& packet_event
) OVERRIDE
;
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;
46 // Resets stats in this object.
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
);
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
{
67 base::TimeDelta sum_delay
;
70 struct PacketLogStats
{
78 // Capture frame rate.
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.
88 // Average playout delay in milliseconds, with target delay already
89 // accounted for. Ideally, every frame should have a playout delay of 0.
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.
96 // Encode bitrate in kbps.
98 // Packet transmission bitrate in kbps.
100 // Packet retransmission bitrate in kbps.
102 // Fraction of packet loss.
103 PACKET_LOSS_FRACTION
,
104 // Duration in milliseconds since last receiver response.
105 MS_SINCE_LAST_RECEIVER_RESPONSE
108 typedef std::map
<CastStat
, double> StatsMap
;
109 typedef std::map
<RtpTimestamp
, base::TimeTicks
> FrameEventTimeMap
;
111 std::pair
<RtpTimestamp
, uint16
>,
112 std::pair
<base::TimeTicks
, CastLoggingEvent
> >
114 typedef std::map
<CastLoggingEvent
, FrameLogStats
> FrameStatsMap
;
115 typedef std::map
<CastLoggingEvent
, PacketLogStats
> PacketStatsMap
;
117 static const char* CastStatToString(CastStat stat
);
119 // Assigns |stats_map| with stats data. Used for testing.
120 void GetStatsInternal(StatsMap
* stats_map
) const;
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
);
130 void PopulateFpsStat(base::TimeTicks now
,
131 CastLoggingEvent event
,
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
,
139 StatsMap
* stats_map
) const;
140 void PopulatePacketLossPercentageStat(StatsMap
* stats_map
) const;
142 const EventMediaType event_media_type_
;
144 // Not owned by this class.
145 base::TickClock
* const clock_
;
147 // Not owned by this class.
148 ReceiverTimeOffsetEstimator
* const offset_estimator_
;
150 FrameStatsMap frame_stats_
;
151 PacketStatsMap packet_stats_
;
153 base::TimeDelta total_network_latency_
;
154 int network_latency_datapoints_
;
155 base::TimeDelta total_e2e_latency_
;
156 int e2e_latency_datapoints_
;
158 base::TimeTicks last_response_received_time_
;
160 // Fixed size map to record when recent frames were captured.
161 FrameEventTimeMap frame_captured_times_
;
163 // Fixed size map to record when recent packets were sent.
164 PacketEventTimeMap packet_sent_times_
;
166 // Sender time assigned on creation and |Reset()|.
167 base::TimeTicks start_time_
;
169 base::ThreadChecker thread_checker_
;
170 DISALLOW_COPY_AND_ASSIGN(StatsEventSubscriber
);
176 #endif // MEDIA_CAST_LOGGING_STATS_EVENT_SUBSCRIBER_H_