• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
LoggingStats(base::TickClock * clock)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 
~LoggingStats()22 LoggingStats::~LoggingStats() {}
23 
Reset()24 void LoggingStats::Reset() {
25   frame_stats_.clear();
26   packet_stats_.clear();
27   generic_stats_.clear();
28   memset(counts_, 0, sizeof(counts_));
29 }
30 
InsertFrameEvent(CastLoggingEvent event,uint32 rtp_timestamp,uint32 frame_id)31 void LoggingStats::InsertFrameEvent(CastLoggingEvent event,
32                                     uint32 rtp_timestamp,
33                                     uint32 frame_id) {
34   InsertBaseFrameEvent(event, frame_id, rtp_timestamp);
35 }
36 
InsertFrameEventWithSize(CastLoggingEvent event,uint32 rtp_timestamp,uint32 frame_id,int frame_size)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 
InsertFrameEventWithDelay(CastLoggingEvent event,uint32 rtp_timestamp,uint32 frame_id,base::TimeDelta delay)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 
InsertBaseFrameEvent(CastLoggingEvent event,uint32 frame_id,uint32 rtp_timestamp)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 
InsertPacketEvent(CastLoggingEvent event,uint32 rtp_timestamp,uint32 frame_id,uint16 packet_id,uint16 max_packet_id,size_t size)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 
InsertGenericEvent(CastLoggingEvent event,int value)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 
GetFrameStatsData()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 
GetPacketStatsData()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 
GetGenericStatsData()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