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/debug/trace_event.h"
6 #include "base/metrics/histogram.h"
7 #include "media/cast/logging/logging_impl.h"
8 #include "net/base/big_endian.h"
9
10 namespace media {
11 namespace cast {
12
LoggingImpl(base::TickClock * clock,scoped_refptr<base::TaskRunner> main_thread_proxy,const CastLoggingConfig & config)13 LoggingImpl::LoggingImpl(base::TickClock* clock,
14 scoped_refptr<base::TaskRunner> main_thread_proxy,
15 const CastLoggingConfig& config)
16 : main_thread_proxy_(main_thread_proxy),
17 config_(config),
18 raw_(clock),
19 stats_(clock) {}
20
~LoggingImpl()21 LoggingImpl::~LoggingImpl() {}
22
InsertFrameEvent(CastLoggingEvent event,uint32 rtp_timestamp,uint32 frame_id)23 void LoggingImpl::InsertFrameEvent(CastLoggingEvent event,
24 uint32 rtp_timestamp,
25 uint32 frame_id) {
26 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread());
27 if (config_.enable_data_collection) {
28 raw_.InsertFrameEvent(event, rtp_timestamp, frame_id);
29 stats_.InsertFrameEvent(event, rtp_timestamp, frame_id);
30 }
31 if (config_.enable_tracing) {
32 std::string event_string = CastLoggingToString(event);
33 TRACE_EVENT_INSTANT2(event_string.c_str(), "FE",
34 TRACE_EVENT_SCOPE_THREAD, "rtp_timestamp", rtp_timestamp, "frame_id",
35 frame_id);
36 }
37 }
38
InsertFrameEventWithSize(CastLoggingEvent event,uint32 rtp_timestamp,uint32 frame_id,int frame_size)39 void LoggingImpl::InsertFrameEventWithSize(CastLoggingEvent event,
40 uint32 rtp_timestamp,
41 uint32 frame_id,
42 int frame_size) {
43 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread());
44 if (config_.enable_data_collection) {
45 raw_.InsertFrameEventWithSize(event, rtp_timestamp, frame_id, frame_size);
46 stats_.InsertFrameEventWithSize(event, rtp_timestamp, frame_id, frame_size);
47 }
48 if (config_.enable_uma_stats) {
49 UMA_HISTOGRAM_COUNTS(CastLoggingToString(event), frame_size);
50 }
51 if (config_.enable_tracing) {
52 std::string event_string = CastLoggingToString(event);
53 TRACE_EVENT_INSTANT2(event_string.c_str(), "FES",
54 TRACE_EVENT_SCOPE_THREAD, "rtp_timestamp", rtp_timestamp, "frame_size",
55 frame_size);
56 }
57 }
58
InsertFrameEventWithDelay(CastLoggingEvent event,uint32 rtp_timestamp,uint32 frame_id,base::TimeDelta delay)59 void LoggingImpl::InsertFrameEventWithDelay(CastLoggingEvent event,
60 uint32 rtp_timestamp,
61 uint32 frame_id,
62 base::TimeDelta delay) {
63 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread());
64 if (config_.enable_data_collection) {
65 raw_.InsertFrameEventWithDelay(event, rtp_timestamp, frame_id, delay);
66 stats_.InsertFrameEventWithDelay(event, rtp_timestamp, frame_id, delay);
67 }
68 if (config_.enable_uma_stats) {
69 UMA_HISTOGRAM_TIMES(CastLoggingToString(event), delay);
70 }
71 if (config_.enable_tracing) {
72 std::string event_string = CastLoggingToString(event);
73 TRACE_EVENT_INSTANT2(event_string.c_str(), "FED",
74 TRACE_EVENT_SCOPE_THREAD, "rtp_timestamp", rtp_timestamp, "delay",
75 delay.InMilliseconds());
76 }
77 }
78
InsertPacketListEvent(CastLoggingEvent event,const PacketList & packets)79 void LoggingImpl::InsertPacketListEvent(CastLoggingEvent event,
80 const PacketList& packets) {
81 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread());
82 for (unsigned int i = 0; i < packets.size(); ++i) {
83 const Packet& packet = packets[i];
84 // Parse basic properties.
85 uint32 rtp_timestamp;
86 uint16 packet_id, max_packet_id;
87 const uint8* packet_data = &packet[0];
88 net::BigEndianReader big_endian_reader(packet_data + 4, 4);
89 big_endian_reader.ReadU32(&rtp_timestamp);
90 net::BigEndianReader cast_big_endian_reader(packet_data + 12 + 2, 4);
91 cast_big_endian_reader.ReadU16(&packet_id);
92 cast_big_endian_reader.ReadU16(&max_packet_id);
93 // rtp_timestamp is enough - no need for frame_id as well.
94 InsertPacketEvent(event, rtp_timestamp, kFrameIdUnknown, packet_id,
95 max_packet_id, packet.size());
96 }
97 }
98
InsertPacketEvent(CastLoggingEvent event,uint32 rtp_timestamp,uint32 frame_id,uint16 packet_id,uint16 max_packet_id,size_t size)99 void LoggingImpl::InsertPacketEvent(CastLoggingEvent event,
100 uint32 rtp_timestamp,
101 uint32 frame_id,
102 uint16 packet_id,
103 uint16 max_packet_id,
104 size_t size) {
105 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread());
106 if (config_.enable_data_collection) {
107 raw_.InsertPacketEvent(event, rtp_timestamp, frame_id, packet_id,
108 max_packet_id, size);
109 stats_.InsertPacketEvent(event, rtp_timestamp, frame_id, packet_id,
110 max_packet_id, size);
111 }
112 if (config_.enable_tracing) {
113 std::string event_string = CastLoggingToString(event);
114 TRACE_EVENT_INSTANT2(event_string.c_str(), "PE",
115 TRACE_EVENT_SCOPE_THREAD, "rtp_timestamp", rtp_timestamp,
116 "packet_id", packet_id);
117 }
118 }
119
InsertGenericEvent(CastLoggingEvent event,int value)120 void LoggingImpl::InsertGenericEvent(CastLoggingEvent event, int value) {
121 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread());
122 if (config_.enable_data_collection) {
123 raw_.InsertGenericEvent(event, value);
124 stats_.InsertGenericEvent(event, value);
125 }
126 if (config_.enable_uma_stats) {
127 UMA_HISTOGRAM_COUNTS(CastLoggingToString(event), value);
128 }
129 if (config_.enable_tracing) {
130 std::string event_string = CastLoggingToString(event);
131 TRACE_EVENT_INSTANT1(event_string.c_str(), "GE",
132 TRACE_EVENT_SCOPE_THREAD, "value", value);
133 }
134 }
135
136 // should just get the entire class, would be much easier.
GetFrameRawData()137 FrameRawMap LoggingImpl::GetFrameRawData() {
138 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread());
139 return raw_.GetFrameData();
140 }
141
GetPacketRawData()142 PacketRawMap LoggingImpl::GetPacketRawData() {
143 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread());
144 return raw_.GetPacketData();
145 }
146
GetGenericRawData()147 GenericRawMap LoggingImpl::GetGenericRawData() {
148 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread());
149 return raw_.GetGenericData();
150 }
151
GetFrameStatsData()152 const FrameStatsMap* LoggingImpl::GetFrameStatsData() {
153 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread());
154 // Get stats data.
155 const FrameStatsMap* stats = stats_.GetFrameStatsData();
156 if (config_.enable_uma_stats) {
157 FrameStatsMap::const_iterator it;
158 for (it = stats->begin(); it != stats->end(); ++it) {
159 // Check for an active event.
160 if (it->second->framerate_fps > 0) {
161 std::string event_string = CastLoggingToString(it->first);
162 UMA_HISTOGRAM_COUNTS(event_string.append("_framerate_fps"),
163 it->second->framerate_fps);
164 } else {
165 // All active frame events trigger framerate computation.
166 continue;
167 }
168 if (it->second->bitrate_kbps > 0) {
169 std::string evnt_string = CastLoggingToString(it->first);
170 UMA_HISTOGRAM_COUNTS(evnt_string.append("_bitrate_kbps"),
171 it->second->framerate_fps);
172 }
173 if (it->second->avg_delay_ms > 0) {
174 std::string event_string = CastLoggingToString(it->first);
175 UMA_HISTOGRAM_COUNTS(event_string.append("_avg_delay_ms"),
176 it->second->avg_delay_ms);
177 UMA_HISTOGRAM_COUNTS(event_string.append("_min_delay_ms"),
178 it->second->min_delay_ms);
179 UMA_HISTOGRAM_COUNTS(event_string.append("_max_delay_ms"),
180 it->second->max_delay_ms);
181 }
182 }
183 }
184 return stats;
185 }
186
GetPacketStatsData()187 const PacketStatsMap* LoggingImpl::GetPacketStatsData() {
188 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread());
189 // Get stats data.
190 const PacketStatsMap* stats = stats_.GetPacketStatsData();
191 if (config_.enable_uma_stats) {
192 PacketStatsMap::const_iterator it;
193 for (it = stats->begin(); it != stats->end(); ++it) {
194 if (it->second > 0) {
195 std::string event_string = CastLoggingToString(it->first);
196 UMA_HISTOGRAM_COUNTS(event_string.append("_bitrate_kbps"), it->second);
197 }
198 }
199 }
200 return stats;
201 }
202
GetGenericStatsData()203 const GenericStatsMap* LoggingImpl::GetGenericStatsData() {
204 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread());
205 // Get stats data.
206 const GenericStatsMap* stats = stats_.GetGenericStatsData();
207 if (config_.enable_uma_stats) {
208 GenericStatsMap::const_iterator it;
209 for (it = stats->begin(); it != stats->end(); ++it) {
210 if (it->second > 0) {
211 UMA_HISTOGRAM_COUNTS(CastLoggingToString(it->first), it->second);
212 }
213 }
214 }
215 return stats;
216 }
217
Reset()218 void LoggingImpl::Reset() {
219 DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread());
220 raw_.Reset();
221 stats_.Reset();
222 }
223
224 } // namespace cast
225 } // namespace media
226