Home | History | Annotate | Download | only in logging
      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