blob: 3c38d4ee319f4d5b85cf30784a8acfd4daaecc35 [file] [log] [blame]
harpreet6ffd1e42017-01-24 18:24:36 -08001# Copyright (c) 2017 The Chromium OS 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
harpreet16ebb4b2017-01-26 13:41:25 -08005import json
harpreet6ffd1e42017-01-24 18:24:36 -08006
7from autotest_lib.server.cros import cfm_jmidata_helper_base
8
9# Start index in the JSON object that contains Audio/Video streams related info.
10AV_INDEX = 4
11
12SSRC = u'ssrc'
13GLOBAL = u'global'
14
15AUDIO_INPUT = u'audioInputLevel'
16AUDIO_OUTPUT = u'audioOutputLevel'
17BYTES_RECEIVED = u'bytesReceived'
18BYTES_SENT = u'bytesSent'
19ADAPTATION_CHANGES = u'googAdaptationChanges'
20AVERAGE_ENCODE_TIME = u'googAvgEncodeMs'
21BANDWIDTH_LIMITED_RESOLUTION = u'googBandwidthLimitedResolution'
22CPU_LIMITED_RESOLUTION = u'googCpuLimitedResolution'
23VIDEO_ENCODE_CPU_USAGE = u'googEncodeUsagePercent'
24VIDEO_RECEIVED_FRAME_HEIGHT = u'googFrameHeightReceived'
25VIDEO_RECEIVED_FRAME_WIDTH = u'googFrameWidthReceived'
26FRAMERATE_OUTGOING = u'googFrameRateInput'
27FRAMERATE_RECEIVED = u'googFrameRateReceived'
28FRAMERATE_SENT = u'googFrameRateSent'
29FRAMERATE_DECODED = u'googFrameRateDecoded'
30FRAMERATE_OUTPUT = u'googFrameRateOutput'
31FRAME_WIDTH_SENT = u'googFrameWidthSent'
32FRAME_HEIGHT_SENT = u'googFrameHeightSent'
33FRAMES_DECODED = u'framesDecoded'
34FRAMES_ENCODED = u'framesEncoded'
35VIDEO_PACKETS_LOST = u'packetsLost'
36VIDEO_PACKETS_SENT = u'packetsSent'
37
harpreet16ebb4b2017-01-26 13:41:25 -080038BROWSER_CPU = u'browserCpuUsage'
39GPU_CPU = u'gpuCpuUsage'
40NUM_PROCESSORS = u'numOfProcessors'
41NACL_EFFECTS_CPU = u'pluginCpuUsage'
42RENDERER_CPU = u'tabCpuUsage'
43TOTAL_CPU = u'totalCpuUsage'
harpreet6ffd1e42017-01-24 18:24:36 -080044
45
46class JMIDataV3Helper(cfm_jmidata_helper_base.JMIDataHelperBase):
47 """Helper class for JMI data v3 parsing. This class helps in extracting
48 relevant JMI data from javascript log.
49
50 The class takes javascript file as input and extracts jmidata elements from
51 the file that is internally stored as a list. Whenever we need to extract
52 data i.e. audio received bytes we call a method such as
53 getAudioReceivedDataList. This method converts each string element in the
54 internal list to a json object and retrieves the relevant info from it which
55 is then stored and returned as a list.
56 """
57
58 def __init__(self, log_file_content):
59 super(JMIDataV3Helper, self).__init__(log_file_content, 'jmidatav3')
60
61 def _ExtractAllJMIDataPointsWithKey(self, jmi_type, is_audio, key):
62 """Extracts all values from the data points with the given key."""
63 data_list = []
64 for jmi_data_point in self._jmi_list:
65 json_arr = json.loads(jmi_data_point)
66 for i in range(AV_INDEX, len(json_arr)):
67 if json_arr[i] and jmi_type in json_arr[i]:
68 jmi_obj = json_arr[i][jmi_type]
harpreet6ffd1e42017-01-24 18:24:36 -080069 this_is_audio = (AUDIO_INPUT in jmi_obj or
70 AUDIO_OUTPUT in jmi_obj)
71 if this_is_audio == is_audio and key in jmi_obj:
72 if (not isinstance(jmi_obj[key], int) and
73 (jmi_obj[key] == 'false' or
74 jmi_obj[key] == 'true')):
75 jmi_obj[key] = 1 if jmi_obj[key] == 'true' else 0
76 data_list.append(jmi_obj[key])
harpreeteb36ffd2017-08-07 15:23:06 -070077 if not data_list:
78 data_list = [0]
harpreet6ffd1e42017-01-24 18:24:36 -080079 return data_list
80
81 def GetAudioReceivedBytesList(self):
82 return self._ExtractAllJMIDataPointsWithKey(
83 jmi_type=SSRC, is_audio=True, key=BYTES_RECEIVED)
84
85 def GetAudioSentBytesList(self):
86 return self._ExtractAllJMIDataPointsWithKey(
87 jmi_type=SSRC, is_audio=True, key=BYTES_SENT)
88
89 def GetAudioReceivedEnergyList(self):
90 return self._ExtractAllJMIDataPointsWithKey(
91 jmi_type=SSRC, is_audio=True, key=AUDIO_OUTPUT)
92
93 def GetAudioSentEnergyList(self):
94 return self._ExtractAllJMIDataPointsWithKey(
95 jmi_type=SSRC, is_audio=True, key=AUDIO_INPUT)
96
97 def GetVideoSentBytesList(self):
98 return self._ExtractAllJMIDataPointsWithKey(
99 jmi_type=SSRC, is_audio=False, key=BYTES_SENT)
100
101 def GetVideoReceivedBytesList(self):
102 return self._ExtractAllJMIDataPointsWithKey(
103 jmi_type=SSRC, is_audio=False, key=BYTES_RECEIVED)
104
105 def GetVideoIncomingFramerateReceivedList(self):
106 return self._ExtractAllJMIDataPointsWithKey(
107 jmi_type=SSRC, is_audio=False, key=FRAMERATE_RECEIVED)
108
109 def GetVideoOutgoingFramerateSentList(self):
110 return self._ExtractAllJMIDataPointsWithKey(
111 jmi_type=SSRC, is_audio=False, key=FRAMERATE_SENT)
112
113 def GetVideoIncomingFramerateDecodedList(self):
114 return self._ExtractAllJMIDataPointsWithKey(
115 jmi_type=SSRC, is_audio=False, key=FRAMERATE_DECODED)
116
117 def GetVideoIncomingFramerateList(self):
118 return self._ExtractAllJMIDataPointsWithKey(
119 jmi_type=SSRC, is_audio=False, key=FRAMERATE_OUTPUT)
120
121 def GetVideoSentFrameWidthList(self):
122 return self._ExtractAllJMIDataPointsWithKey(
123 jmi_type=SSRC, is_audio=False, key=FRAME_WIDTH_SENT)
124
125 def GetVideoSentFrameHeightList(self):
126 return self._ExtractAllJMIDataPointsWithKey(
127 jmi_type=SSRC, is_audio=False, key=FRAME_HEIGHT_SENT)
128
129 def GetCPULimitedResolutionList(self):
130 return self._ExtractAllJMIDataPointsWithKey(
131 jmi_type=SSRC, is_audio=False, key=CPU_LIMITED_RESOLUTION)
132
133 def GetVideoPacketsSentList(self):
134 return self._ExtractAllJMIDataPointsWithKey(
135 jmi_type=SSRC, is_audio=False, key=VIDEO_PACKETS_SENT)
136
137 def GetVideoPacketsLostList(self):
138 return self._ExtractAllJMIDataPointsWithKey(
139 jmi_type=SSRC, is_audio=False, key=VIDEO_PACKETS_LOST)
140
141 def GetVideoIncomingFramesDecodedList(self):
142 return self._ExtractAllJMIDataPointsWithKey(
143 jmi_type=SSRC, is_audio=False, key=FRAMES_DECODED)
144
145 def GetVideoOutgoingFramesEncodedList(self):
146 return self._ExtractAllJMIDataPointsWithKey(
147 jmi_type=SSRC, is_audio=False, key=FRAMES_ENCODED)
148
149 def GetVideoAdaptationChangeList(self):
150 return self._ExtractAllJMIDataPointsWithKey(
151 jmi_type=SSRC, is_audio=False, key=ADAPTATION_CHANGES)
152
153 def GetVideoEncodeTimeList(self):
154 return self._ExtractAllJMIDataPointsWithKey(
155 jmi_type=SSRC, is_audio=False, key=AVERAGE_ENCODE_TIME)
156
157 def GetBandwidthLimitedResolutionList(self):
158 return self._ExtractAllJMIDataPointsWithKey(
159 jmi_type=SSRC, is_audio=False, key=BANDWIDTH_LIMITED_RESOLUTION)
160
161 def GetVideoReceivedFrameHeightList(self):
162 return self._ExtractAllJMIDataPointsWithKey(
163 jmi_type=SSRC, is_audio=False, key=VIDEO_RECEIVED_FRAME_HEIGHT)
164
165 def GetVideoOutgoingFramerateInputList(self):
166 return self._ExtractAllJMIDataPointsWithKey(
167 jmi_type=SSRC, is_audio=False, key=FRAMERATE_OUTGOING)
168
169 def GetVideoReceivedFrameWidthList(self):
170 return self._ExtractAllJMIDataPointsWithKey(
171 jmi_type=SSRC, is_audio=False, key=VIDEO_RECEIVED_FRAME_WIDTH)
172
173 def GetVideoEncodeCpuUsagePercentList(self):
174 return self._ExtractAllJMIDataPointsWithKey(
175 jmi_type=SSRC, is_audio=False, key=VIDEO_ENCODE_CPU_USAGE)
176
177 def GetNumberOfActiveIncomingVideoStreams(self):
178 """Retrieve number of active incoming video streams."""
179 if not self._jmi_list:
180 # JMI data hasn't started populating yet.
181 return 0
182
183 num_video_streams = []
184
185 # If JMI data has started getting populated and has video stream data.
186 for jmi_data_point in self._jmi_list:
187 json_arr = json.loads(jmi_data_point)
188 video_streams = 0
189 for i in range(AV_INDEX, len(json_arr)):
190 if json_arr[i] and SSRC in json_arr[i]:
191 ssrc_obj = json_arr[i][SSRC]
192 is_audio = ('audioInputLevel' in ssrc_obj or
193 'audioOutputLevel' in ssrc_obj)
194 is_incoming = 'bytesReceived' in ssrc_obj
195 frame_rate_received = 'googFrameRateReceived' in ssrc_obj
196 if ssrc_obj['mediaType'] == 'video' and \
197 frame_rate_received:
198 frame_rate = ssrc_obj['googFrameRateReceived']
199 if (is_incoming and not is_audio) and \
200 frame_rate != 0:
201 video_streams += 1
202 num_video_streams.append(video_streams)
harpreeteb36ffd2017-08-07 15:23:06 -0700203 if not num_video_streams:
204 num_video_streams = [0]
harpreet6ffd1e42017-01-24 18:24:36 -0800205 return num_video_streams
206
207 def GetCpuUsageList(self, cpu_type):
208 """Retrieves cpu usage data from JMI data.
209
harpreet16ebb4b2017-01-26 13:41:25 -0800210 @param cpu_type: Cpu usage type.
harpreet6ffd1e42017-01-24 18:24:36 -0800211 @returns List containing CPU usage data.
212 """
213 data_list = []
214 for jmi_data_point in self._jmi_list:
215 json_arr = json.loads(jmi_data_point)
216 for i in range(AV_INDEX, len(json_arr)):
217 if json_arr[i] and GLOBAL in json_arr[i]:
218 global_obj = json_arr[i][GLOBAL]
219 # Some values in JMIDataV3 are set to 'null'.
harpreet16ebb4b2017-01-26 13:41:25 -0800220 if cpu_type == u'numOfProcessors':
221 return global_obj[cpu_type]
222 elif (cpu_type in global_obj and
223 self.IsFloat(global_obj[cpu_type])):
224 data_list.append(float(global_obj[cpu_type]))
harpreetb527a0f2017-07-14 15:24:44 -0700225 if not data_list:
226 data_list = [0]
harpreet6ffd1e42017-01-24 18:24:36 -0800227 return data_list
228
harpreet16ebb4b2017-01-26 13:41:25 -0800229 def GetNumOfProcessors(self):
230 return self.GetCpuUsageList(NUM_PROCESSORS)
231
232 def GetTotalCpuPercentage(self):
233 return self.GetCpuUsageList(TOTAL_CPU)
234
235 def GetBrowserCpuPercentage(self):
236 return self.GetCpuUsageList(BROWSER_CPU)
237
238 def GetGpuCpuPercentage(self):
239 return self.GetCpuUsageList(GPU_CPU)
240
241 def GetNaclEffectsCpuPercentage(self):
242 return self.GetCpuUsageList(NACL_EFFECTS_CPU)
243
244 def GetRendererCpuPercentage(self):
245 return self.GetCpuUsageList(RENDERER_CPU)
harpreet6ffd1e42017-01-24 18:24:36 -0800246
247 def IsFloat(self, value):
248 try:
249 float(value)
250 return True
251 except TypeError:
252 return False