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/debug/trace_event.h" | 5 #include "base/debug/trace_event.h" |
6 #include "base/metrics/histogram.h" | 6 #include "base/metrics/histogram.h" |
7 #include "media/cast/logging/logging_impl.h" | 7 #include "media/cast/logging/logging_impl.h" |
8 #include "net/base/big_endian.h" | 8 #include "net/base/big_endian.h" |
9 | 9 |
10 namespace media { | 10 namespace media { |
11 namespace cast { | 11 namespace cast { |
12 | 12 |
13 LoggingImpl::LoggingImpl(scoped_refptr<base::TaskRunner> main_thread_proxy, | 13 LoggingImpl::LoggingImpl(scoped_refptr<base::TaskRunner> main_thread_proxy, |
14 const CastLoggingConfig& config) | 14 const CastLoggingConfig& config) |
15 : main_thread_proxy_(main_thread_proxy), | 15 : main_thread_proxy_(main_thread_proxy), |
16 config_(config), | 16 config_(config), |
17 raw_(), | 17 raw_(), |
18 stats_() {} | 18 stats_() {} |
19 | 19 |
20 LoggingImpl::~LoggingImpl() {} | 20 LoggingImpl::~LoggingImpl() {} |
21 | 21 |
22 void LoggingImpl::InsertFrameEvent(const base::TimeTicks& time_of_event, | 22 void LoggingImpl::InsertFrameEvent(const base::TimeTicks& time_of_event, |
23 CastLoggingEvent event, | 23 CastLoggingEvent event, |
24 uint32 rtp_timestamp, | 24 uint32 rtp_timestamp, |
25 uint32 frame_id) { | 25 uint32 frame_id) { |
26 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); | 26 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); |
27 if (config_.enable_data_collection) { | 27 if (config_.enable_raw_data_collection) { |
28 raw_.InsertFrameEvent(time_of_event, event, rtp_timestamp, frame_id); | 28 raw_.InsertFrameEvent(time_of_event, event, rtp_timestamp, frame_id); |
29 } | |
30 if (config_.enable_stats_data_collection) { | |
29 stats_.InsertFrameEvent(time_of_event, event, rtp_timestamp, frame_id); | 31 stats_.InsertFrameEvent(time_of_event, event, rtp_timestamp, frame_id); |
30 } | 32 } |
31 if (config_.enable_tracing) { | 33 if (config_.enable_tracing) { |
32 std::string event_string = CastLoggingToString(event); | 34 std::string event_string = CastLoggingToString(event); |
33 TRACE_EVENT_INSTANT2(event_string.c_str(), "FE", | 35 TRACE_EVENT_INSTANT2(event_string.c_str(), "FE", |
34 TRACE_EVENT_SCOPE_THREAD, "rtp_timestamp", rtp_timestamp, "frame_id", | 36 TRACE_EVENT_SCOPE_THREAD, "rtp_timestamp", rtp_timestamp, "frame_id", |
35 frame_id); | 37 frame_id); |
36 } | 38 } |
37 } | 39 } |
38 | 40 |
39 void LoggingImpl::InsertFrameEventWithSize(const base::TimeTicks& time_of_event, | 41 void LoggingImpl::InsertFrameEventWithSize(const base::TimeTicks& time_of_event, |
40 CastLoggingEvent event, | 42 CastLoggingEvent event, |
41 uint32 rtp_timestamp, | 43 uint32 rtp_timestamp, |
42 uint32 frame_id, | 44 uint32 frame_id, |
43 int frame_size) { | 45 int frame_size) { |
44 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); | 46 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); |
45 if (config_.enable_data_collection) { | 47 if (config_.enable_raw_data_collection) { |
46 raw_.InsertFrameEventWithSize(time_of_event, event, rtp_timestamp, frame_id, | 48 raw_.InsertFrameEventWithSize(time_of_event, event, rtp_timestamp, frame_id, |
47 frame_size); | 49 frame_size); |
50 } | |
51 if (config_.enable_stats_data_collection) { | |
48 stats_.InsertFrameEventWithSize(time_of_event, event, rtp_timestamp, | 52 stats_.InsertFrameEventWithSize(time_of_event, event, rtp_timestamp, |
49 frame_id, frame_size); | 53 frame_id, frame_size); |
50 } | 54 } |
51 if (config_.enable_uma_stats) { | 55 if (config_.enable_uma_stats) { |
52 UMA_HISTOGRAM_COUNTS(CastLoggingToString(event), frame_size); | 56 if (event == kAudioFrameEncoded) |
57 UMA_HISTOGRAM_COUNTS("Cast.AudioFrameEncoded", frame_size); | |
58 else if (event == kVideoFrameEncoded) { | |
59 UMA_HISTOGRAM_COUNTS("Cast.VideoFrameEncoded", frame_size); | |
60 } | |
53 } | 61 } |
62 | |
54 if (config_.enable_tracing) { | 63 if (config_.enable_tracing) { |
55 std::string event_string = CastLoggingToString(event); | 64 std::string event_string = CastLoggingToString(event); |
56 TRACE_EVENT_INSTANT2(event_string.c_str(), "FES", | 65 TRACE_EVENT_INSTANT2(event_string.c_str(), "FES", |
57 TRACE_EVENT_SCOPE_THREAD, "rtp_timestamp", rtp_timestamp, "frame_size", | 66 TRACE_EVENT_SCOPE_THREAD, "rtp_timestamp", rtp_timestamp, "frame_size", |
58 frame_size); | 67 frame_size); |
59 } | 68 } |
60 } | 69 } |
61 | 70 |
62 void LoggingImpl::InsertFrameEventWithDelay( | 71 void LoggingImpl::InsertFrameEventWithDelay( |
63 const base::TimeTicks& time_of_event, | 72 const base::TimeTicks& time_of_event, |
64 CastLoggingEvent event, | 73 CastLoggingEvent event, |
65 uint32 rtp_timestamp, | 74 uint32 rtp_timestamp, |
66 uint32 frame_id, | 75 uint32 frame_id, |
67 base::TimeDelta delay) { | 76 base::TimeDelta delay) { |
68 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); | 77 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); |
69 if (config_.enable_data_collection) { | 78 if (config_.enable_raw_data_collection) { |
70 raw_.InsertFrameEventWithDelay(time_of_event, event, rtp_timestamp, | 79 raw_.InsertFrameEventWithDelay(time_of_event, event, rtp_timestamp, |
71 frame_id, delay); | 80 frame_id, delay); |
81 } | |
82 if (config_.enable_stats_data_collection) { | |
72 stats_.InsertFrameEventWithDelay(time_of_event, event, rtp_timestamp, | 83 stats_.InsertFrameEventWithDelay(time_of_event, event, rtp_timestamp, |
73 frame_id, delay); | 84 frame_id, delay); |
74 } | 85 } |
75 if (config_.enable_uma_stats) { | 86 if (config_.enable_uma_stats) { |
76 UMA_HISTOGRAM_TIMES(CastLoggingToString(event), delay); | 87 if (event == kAudioPlayoutDelay) |
88 UMA_HISTOGRAM_TIMES("Cast.AudioPlayoutDelay", delay); | |
89 else if (event == kVideoRenderDelay) { | |
90 UMA_HISTOGRAM_TIMES("Cast.VideoRendertDelay", delay); | |
hguihot
2014/01/13 19:51:10
Typo.
mikhal1
2014/01/14 20:09:58
Done.
| |
91 } | |
77 } | 92 } |
78 if (config_.enable_tracing) { | 93 if (config_.enable_tracing) { |
79 std::string event_string = CastLoggingToString(event); | 94 std::string event_string = CastLoggingToString(event); |
80 TRACE_EVENT_INSTANT2(event_string.c_str(), "FED", | 95 TRACE_EVENT_INSTANT2(event_string.c_str(), "FED", |
81 TRACE_EVENT_SCOPE_THREAD, "rtp_timestamp", rtp_timestamp, "delay", | 96 TRACE_EVENT_SCOPE_THREAD, "rtp_timestamp", rtp_timestamp, "delay", |
82 delay.InMilliseconds()); | 97 delay.InMilliseconds()); |
83 } | 98 } |
84 } | 99 } |
85 | 100 |
86 void LoggingImpl::InsertPacketListEvent(const base::TimeTicks& time_of_event, | 101 void LoggingImpl::InsertPacketListEvent(const base::TimeTicks& time_of_event, |
(...skipping 18 matching lines...) Expand all Loading... | |
105 } | 120 } |
106 | 121 |
107 void LoggingImpl::InsertPacketEvent(const base::TimeTicks& time_of_event, | 122 void LoggingImpl::InsertPacketEvent(const base::TimeTicks& time_of_event, |
108 CastLoggingEvent event, | 123 CastLoggingEvent event, |
109 uint32 rtp_timestamp, | 124 uint32 rtp_timestamp, |
110 uint32 frame_id, | 125 uint32 frame_id, |
111 uint16 packet_id, | 126 uint16 packet_id, |
112 uint16 max_packet_id, | 127 uint16 max_packet_id, |
113 size_t size) { | 128 size_t size) { |
114 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); | 129 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); |
115 if (config_.enable_data_collection) { | 130 if (config_.enable_raw_data_collection) { |
116 raw_.InsertPacketEvent(time_of_event, event, rtp_timestamp, frame_id, | 131 raw_.InsertPacketEvent(time_of_event, event, rtp_timestamp, frame_id, |
117 packet_id, max_packet_id, size); | 132 packet_id, max_packet_id, size); |
133 } | |
134 if (config_.enable_stats_data_collection) { | |
118 stats_.InsertPacketEvent(time_of_event, event, rtp_timestamp, frame_id, | 135 stats_.InsertPacketEvent(time_of_event, event, rtp_timestamp, frame_id, |
119 packet_id, max_packet_id, size); | 136 packet_id, max_packet_id, size); |
120 } | 137 } |
121 if (config_.enable_tracing) { | 138 if (config_.enable_tracing) { |
122 std::string event_string = CastLoggingToString(event); | 139 std::string event_string = CastLoggingToString(event); |
123 TRACE_EVENT_INSTANT2(event_string.c_str(), "PE", | 140 TRACE_EVENT_INSTANT2(event_string.c_str(), "PE", |
124 TRACE_EVENT_SCOPE_THREAD, "rtp_timestamp", rtp_timestamp, | 141 TRACE_EVENT_SCOPE_THREAD, "rtp_timestamp", rtp_timestamp, |
125 "packet_id", packet_id); | 142 "packet_id", packet_id); |
126 } | 143 } |
127 } | 144 } |
128 | 145 |
129 void LoggingImpl::InsertGenericEvent(const base::TimeTicks& time_of_event, | 146 void LoggingImpl::InsertGenericEvent(const base::TimeTicks& time_of_event, |
130 CastLoggingEvent event, int value) { | 147 CastLoggingEvent event, int value) { |
131 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); | 148 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); |
132 if (config_.enable_data_collection) { | 149 if (config_.enable_raw_data_collection) { |
133 raw_.InsertGenericEvent(time_of_event, event, value); | 150 raw_.InsertGenericEvent(time_of_event, event, value); |
151 } | |
152 if (config_.enable_stats_data_collection) { | |
134 stats_.InsertGenericEvent(time_of_event, event, value); | 153 stats_.InsertGenericEvent(time_of_event, event, value); |
135 } | 154 } |
136 if (config_.enable_uma_stats) { | 155 if (config_.enable_uma_stats) { |
137 UMA_HISTOGRAM_COUNTS(CastLoggingToString(event), value); | 156 InsertGenericUmaEvent(event, value); |
138 } | 157 } |
139 if (config_.enable_tracing) { | 158 if (config_.enable_tracing) { |
140 std::string event_string = CastLoggingToString(event); | 159 std::string event_string = CastLoggingToString(event); |
141 TRACE_EVENT_INSTANT1(event_string.c_str(), "GE", | 160 TRACE_EVENT_INSTANT1(event_string.c_str(), "GE", |
142 TRACE_EVENT_SCOPE_THREAD, "value", value); | 161 TRACE_EVENT_SCOPE_THREAD, "value", value); |
143 } | 162 } |
144 } | 163 } |
145 | 164 |
165 void LoggingImpl::InsertGenericUmaEvent(CastLoggingEvent event, int value) { | |
166 switch(event) { | |
167 case kRttMs: | |
168 UMA_HISTOGRAM_COUNTS("Cast.Rtt", value); | |
hguihot
2014/01/13 19:51:10
Cast.RttMs?
(Cast.JitterMs is used below)
mikhal1
2014/01/14 20:09:58
Done.
| |
169 break; | |
170 case kPacketLoss: | |
171 UMA_HISTOGRAM_COUNTS("Cast.PacketLoss", value); | |
172 break; | |
173 case kJitterMs: | |
174 UMA_HISTOGRAM_COUNTS("Cast.JitterMs", value); | |
175 break; | |
176 case kRembBitrate: | |
177 UMA_HISTOGRAM_COUNTS("Cast.RembBitrate", value); | |
178 break; | |
179 default: | |
180 // No-op | |
181 break; | |
182 } | |
183 } | |
184 | |
146 // should just get the entire class, would be much easier. | 185 // should just get the entire class, would be much easier. |
147 FrameRawMap LoggingImpl::GetFrameRawData() { | 186 FrameRawMap LoggingImpl::GetFrameRawData() { |
148 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); | 187 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); |
149 return raw_.GetFrameData(); | 188 return raw_.GetFrameData(); |
150 } | 189 } |
151 | 190 |
152 PacketRawMap LoggingImpl::GetPacketRawData() { | 191 PacketRawMap LoggingImpl::GetPacketRawData() { |
153 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); | 192 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); |
154 return raw_.GetPacketData(); | 193 return raw_.GetPacketData(); |
155 } | 194 } |
156 | 195 |
157 GenericRawMap LoggingImpl::GetGenericRawData() { | 196 GenericRawMap LoggingImpl::GetGenericRawData() { |
158 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); | 197 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); |
159 return raw_.GetGenericData(); | 198 return raw_.GetGenericData(); |
160 } | 199 } |
161 | 200 |
162 const FrameStatsMap* LoggingImpl::GetFrameStatsData( | 201 const FrameStatsMap* LoggingImpl::GetFrameStatsData( |
163 const base::TimeTicks& now) { | 202 const base::TimeTicks& now) { |
164 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); | 203 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); |
165 // Get stats data. | 204 // Get stats data. |
166 const FrameStatsMap* stats = stats_.GetFrameStatsData(now); | 205 const FrameStatsMap* stats = stats_.GetFrameStatsData(now); |
167 if (config_.enable_uma_stats) { | 206 if (config_.enable_uma_stats) { |
168 FrameStatsMap::const_iterator it; | 207 FrameStatsMap::const_iterator it; |
169 for (it = stats->begin(); it != stats->end(); ++it) { | 208 for (it = stats->begin(); it != stats->end(); ++it) { |
170 // Check for an active event. | 209 // Check for an active event. |
171 if (it->second->framerate_fps > 0) { | 210 if (it->second->framerate_fps > 0) { |
172 std::string event_string = CastLoggingToString(it->first); | 211 // The default frame event implies frame rate. |
173 UMA_HISTOGRAM_COUNTS(event_string.append("_framerate_fps"), | 212 UMA_HISTOGRAM_COUNTS(CastLoggingToString(it->first), |
hguihot
2014/01/13 19:51:10
This is not using a constant.
mikhal1
2014/01/14 20:09:58
Done.
| |
174 it->second->framerate_fps); | 213 it->second->framerate_fps); |
175 } else { | 214 } else { |
176 // All active frame events trigger framerate computation. | 215 // All active frame events trigger frame rate computation. |
177 continue; | 216 continue; |
178 } | 217 } |
179 if (it->second->bitrate_kbps > 0) { | 218 // Bit rate should only be provided following encoding for either audio |
180 std::string evnt_string = CastLoggingToString(it->first); | 219 // or video. |
181 UMA_HISTOGRAM_COUNTS(evnt_string.append("_bitrate_kbps"), | 220 if (it->first == kVideoFrameEncoded) { |
182 it->second->framerate_fps); | 221 UMA_HISTOGRAM_COUNTS("Cast.VideoBitRateKbps", |
hguihot
2014/01/13 19:51:10
Bitrate? (no upper case R)
(RembBitrate does not
mikhal1
2014/01/14 20:09:58
Done.
| |
222 it->second->framerate_fps); | |
223 } else if (it->first == kAudioFrameEncoded) { | |
224 UMA_HISTOGRAM_COUNTS("Cast.AudioBitRateKbps", | |
hguihot
2014/01/13 19:51:10
Bitrate?
mikhal1
2014/01/14 20:09:58
Done.
| |
225 it->second->framerate_fps); | |
183 } | 226 } |
184 if (it->second->avg_delay_ms > 0) { | 227 // Delay events. |
185 std::string event_string = CastLoggingToString(it->first); | 228 if (it->first == kAudioPlayoutDelay) { |
186 UMA_HISTOGRAM_COUNTS(event_string.append("_avg_delay_ms"), | 229 UMA_HISTOGRAM_COUNTS("Cast.Stats.AudioPlayoutDelayAvg", |
187 it->second->avg_delay_ms); | 230 it->second->avg_delay_ms); |
188 UMA_HISTOGRAM_COUNTS(event_string.append("_min_delay_ms"), | 231 UMA_HISTOGRAM_COUNTS("Cast.Stats.AudioPlayoutDelayMin", |
189 it->second->min_delay_ms); | 232 it->second->min_delay_ms); |
190 UMA_HISTOGRAM_COUNTS(event_string.append("_max_delay_ms"), | 233 UMA_HISTOGRAM_COUNTS("Cast.Stats.AudioPlayoutDelayMax", |
191 it->second->max_delay_ms); | 234 it->second->max_delay_ms); |
235 } else if (it->first == kVideoRenderDelay) { | |
236 UMA_HISTOGRAM_COUNTS("Cast.Stats.VideoPlayoutDelayAvg", | |
237 it->second->avg_delay_ms); | |
238 UMA_HISTOGRAM_COUNTS("Cast.Stats.VideoPlayoutDelayMin", | |
239 it->second->min_delay_ms); | |
240 UMA_HISTOGRAM_COUNTS("Cast.Stats.VideoPlayoutDelayMax", | |
241 it->second->max_delay_ms); | |
192 } | 242 } |
193 } | 243 } |
194 } | 244 } |
195 return stats; | 245 return stats; |
196 } | 246 } |
197 | 247 |
198 const PacketStatsMap* LoggingImpl::GetPacketStatsData( | 248 const PacketStatsMap* LoggingImpl::GetPacketStatsData( |
199 const base::TimeTicks& now) { | 249 const base::TimeTicks& now) { |
200 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); | 250 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); |
201 // Get stats data. | 251 // Get stats data. |
202 const PacketStatsMap* stats = stats_.GetPacketStatsData(now); | 252 const PacketStatsMap* stats = stats_.GetPacketStatsData(now); |
203 if (config_.enable_uma_stats) { | 253 if (config_.enable_uma_stats) { |
204 PacketStatsMap::const_iterator it; | 254 PacketStatsMap::const_iterator it; |
205 for (it = stats->begin(); it != stats->end(); ++it) { | 255 for (it = stats->begin(); it != stats->end(); ++it) { |
206 if (it->second > 0) { | 256 switch (it->first) { |
hguihot
2014/01/13 19:51:10
Will these histograms make sense considering these
mikhal1
2014/01/14 20:09:58
That is up to the user. I'm assuming the user will
hguihot
2014/01/14 20:15:03
I don't think we can assume that for all receivers
mikhal1
2014/01/22 15:59:57
This implementation will be obsolete once my chang
| |
207 std::string event_string = CastLoggingToString(it->first); | 257 case kPacketSentToPacer: |
208 UMA_HISTOGRAM_COUNTS(event_string.append("_bitrate_kbps"), it->second); | 258 UMA_HISTOGRAM_COUNTS("Cast.Stats.PacketSentToPacer", it->second); |
259 break; | |
260 case kPacketSentToNetwork: | |
261 UMA_HISTOGRAM_COUNTS("Cast.Stats.PacketSentToNetwork", it->second); | |
262 break; | |
263 case kPacketRetransmited: | |
hguihot
2014/01/13 19:51:10
Typo (transmitted).
mikhal1
2014/01/14 20:09:58
Done.
| |
264 UMA_HISTOGRAM_COUNTS("Cast.Stats.PacketRetransmited", it->second); | |
hguihot
2014/01/13 19:51:10
Same typo here too.
mikhal1
2014/01/14 20:09:58
Done.
| |
265 break; | |
266 case kDuplicatePacketReceived: | |
267 UMA_HISTOGRAM_COUNTS("Cast.Stats.DuplicatePacketReceived", | |
268 it->second); | |
269 break; | |
270 default: | |
271 // No-op. | |
272 break; | |
209 } | 273 } |
210 } | 274 } |
211 } | 275 } |
212 return stats; | 276 return stats; |
213 } | 277 } |
214 | 278 |
215 const GenericStatsMap* LoggingImpl::GetGenericStatsData() { | 279 const GenericStatsMap* LoggingImpl::GetGenericStatsData() { |
216 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); | 280 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); |
217 // Get stats data. | 281 // Get stats data. |
218 const GenericStatsMap* stats = stats_.GetGenericStatsData(); | 282 const GenericStatsMap* stats = stats_.GetGenericStatsData(); |
219 if (config_.enable_uma_stats) { | |
220 GenericStatsMap::const_iterator it; | |
221 for (it = stats->begin(); it != stats->end(); ++it) { | |
222 if (it->second > 0) { | |
223 UMA_HISTOGRAM_COUNTS(CastLoggingToString(it->first), it->second); | |
224 } | |
225 } | |
226 } | |
227 return stats; | 283 return stats; |
228 } | 284 } |
229 | 285 |
230 void LoggingImpl::Reset() { | 286 void LoggingImpl::ResetRaw() { |
231 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); | 287 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); |
232 raw_.Reset(); | 288 raw_.Reset(); |
289 } | |
290 | |
291 void LoggingImpl::ResetStats() { | |
292 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); | |
233 stats_.Reset(); | 293 stats_.Reset(); |
234 } | 294 } |
235 | 295 |
236 } // namespace cast | 296 } // namespace cast |
237 } // namespace media | 297 } // namespace media |
OLD | NEW |