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