Home | History | Annotate | Download | only in logging
      1 // Copyright 2013 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 #include "base/memory/linked_ptr.h"
      6 #include "base/memory/scoped_ptr.h"
      7 #include "media/cast/logging/logging_stats.h"
      8 
      9 namespace media {
     10 namespace cast {
     11 
     12 LoggingStats::LoggingStats(base::TickClock* clock)
     13     : frame_stats_(),
     14       packet_stats_(),
     15       generic_stats_(),
     16       start_time_(),
     17       clock_(clock) {
     18   memset(counts_, 0, sizeof(counts_));
     19   memset(start_time_, 0, sizeof(start_time_));
     20 }
     21 
     22 LoggingStats::~LoggingStats() {}
     23 
     24 void LoggingStats::Reset() {
     25   frame_stats_.clear();
     26   packet_stats_.clear();
     27   generic_stats_.clear();
     28   memset(counts_, 0, sizeof(counts_));
     29 }
     30 
     31 void LoggingStats::InsertFrameEvent(CastLoggingEvent event,
     32                                     uint32 rtp_timestamp,
     33                                     uint32 frame_id) {
     34   InsertBaseFrameEvent(event, frame_id, rtp_timestamp);
     35 }
     36 
     37 void LoggingStats::InsertFrameEventWithSize(CastLoggingEvent event,
     38                                             uint32 rtp_timestamp,
     39                                             uint32 frame_id,
     40                                             int frame_size) {
     41   InsertBaseFrameEvent(event, frame_id, rtp_timestamp);
     42   // Update size.
     43   FrameStatsMap::iterator it = frame_stats_.find(event);
     44   DCHECK(it != frame_stats_.end());
     45   it->second->bitrate_kbps += frame_size;
     46 }
     47 
     48 void LoggingStats::InsertFrameEventWithDelay(CastLoggingEvent event,
     49                                              uint32 rtp_timestamp,
     50                                              uint32 frame_id,
     51                                              base::TimeDelta delay) {
     52   InsertBaseFrameEvent(event, frame_id, rtp_timestamp);
     53   // Update size.
     54   FrameStatsMap::iterator it = frame_stats_.find(event);
     55   DCHECK(it != frame_stats_.end());
     56   // Using the average delay as a counter, will divide by the counter when
     57   // triggered.
     58   it->second->avg_delay_ms += delay.InMilliseconds();
     59   if (delay.InMilliseconds() > it->second->max_delay_ms)
     60     it->second->max_delay_ms = delay.InMilliseconds();
     61   if ((delay.InMilliseconds() < it->second->min_delay_ms) ||
     62       (counts_[event] == 1) )
     63     it->second->min_delay_ms = delay.InMilliseconds();
     64 }
     65 
     66 void LoggingStats::InsertBaseFrameEvent(CastLoggingEvent event,
     67                                         uint32 frame_id,
     68                                         uint32 rtp_timestamp) {
     69   // Does this belong to an existing event?
     70   FrameStatsMap::iterator it = frame_stats_.find(event);
     71   if (it == frame_stats_.end()) {
     72     // New event.
     73     start_time_[event] = clock_->NowTicks();
     74     linked_ptr<FrameLogStats> stats(new FrameLogStats());
     75     frame_stats_.insert(std::make_pair(event, stats));
     76   }
     77 
     78   ++counts_[event];
     79 }
     80 
     81 void LoggingStats::InsertPacketEvent(CastLoggingEvent event,
     82                                      uint32 rtp_timestamp,
     83                                      uint32 frame_id,
     84                                      uint16 packet_id,
     85                                      uint16 max_packet_id,
     86                                      size_t size) {
     87   // Does this packet belong to an existing event?
     88   PacketStatsMap::iterator it = packet_stats_.find(event);
     89   if (it == packet_stats_.end()) {
     90     // New event.
     91     start_time_[event] = clock_->NowTicks();
     92     packet_stats_.insert(std::make_pair(event, size));
     93   } else {
     94     // Add to existing.
     95     it->second += size;
     96   }
     97   ++counts_[event];
     98 }
     99 
    100 void LoggingStats::InsertGenericEvent(CastLoggingEvent event, int value) {
    101   // Does this event belong to an existing event?
    102   GenericStatsMap::iterator it = generic_stats_.find(event);
    103   if (it == generic_stats_.end()) {
    104     // New event.
    105     start_time_[event] = clock_->NowTicks();
    106     generic_stats_.insert(std::make_pair(event, value));
    107   } else {
    108     // Add to existing (will be used to compute average).
    109     it->second += value;
    110   }
    111    ++counts_[event];
    112 }
    113 
    114 const FrameStatsMap* LoggingStats::GetFrameStatsData() {
    115   // Compute framerate and bitrate (when available).
    116   FrameStatsMap::iterator it;
    117   for (it = frame_stats_.begin(); it != frame_stats_.end(); ++it) {
    118     base::TimeDelta time_diff = clock_->NowTicks() - start_time_[it->first];
    119     it->second->framerate_fps = counts_[it->first] / time_diff.InSecondsF();
    120     if (it->second->bitrate_kbps > 0) {
    121       it->second->bitrate_kbps = (8 / 1000) *
    122           it->second->bitrate_kbps / time_diff.InSecondsF();
    123     }
    124     if (it->second->avg_delay_ms > 0)
    125       it->second->avg_delay_ms /= counts_[it->first];
    126   }
    127   return &frame_stats_;
    128 }
    129 
    130 const PacketStatsMap* LoggingStats::GetPacketStatsData() {
    131   PacketStatsMap::iterator it;
    132   for (it = packet_stats_.begin(); it != packet_stats_.end(); ++it) {
    133     if (counts_[it->first] == 0) continue;
    134     base::TimeDelta time_diff = clock_->NowTicks() - start_time_[it->first];
    135     it->second = (8 / 1000) * it->second / time_diff.InSecondsF();
    136   }
    137   return &packet_stats_;
    138 }
    139 
    140 const GenericStatsMap* LoggingStats::GetGenericStatsData() {
    141   // Compute averages.
    142   GenericStatsMap::iterator it;
    143   for (it = generic_stats_.begin(); it != generic_stats_.end(); ++it) {
    144     it->second /= counts_[ it->first];
    145   }
    146   return &generic_stats_;
    147 }
    148 
    149 }  // namespace cast
    150 }  // namespace media
    151