blob: ec33c422d6db824d524e7428076b1c3204015f5c [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])
77 return data_list
78
79 def GetAudioReceivedBytesList(self):
80 return self._ExtractAllJMIDataPointsWithKey(
81 jmi_type=SSRC, is_audio=True, key=BYTES_RECEIVED)
82
83 def GetAudioSentBytesList(self):
84 return self._ExtractAllJMIDataPointsWithKey(
85 jmi_type=SSRC, is_audio=True, key=BYTES_SENT)
86
87 def GetAudioReceivedEnergyList(self):
88 return self._ExtractAllJMIDataPointsWithKey(
89 jmi_type=SSRC, is_audio=True, key=AUDIO_OUTPUT)
90
91 def GetAudioSentEnergyList(self):
92 return self._ExtractAllJMIDataPointsWithKey(
93 jmi_type=SSRC, is_audio=True, key=AUDIO_INPUT)
94
95 def GetVideoSentBytesList(self):
96 return self._ExtractAllJMIDataPointsWithKey(
97 jmi_type=SSRC, is_audio=False, key=BYTES_SENT)
98
99 def GetVideoReceivedBytesList(self):
100 return self._ExtractAllJMIDataPointsWithKey(
101 jmi_type=SSRC, is_audio=False, key=BYTES_RECEIVED)
102
103 def GetVideoIncomingFramerateReceivedList(self):
104 return self._ExtractAllJMIDataPointsWithKey(
105 jmi_type=SSRC, is_audio=False, key=FRAMERATE_RECEIVED)
106
107 def GetVideoOutgoingFramerateSentList(self):
108 return self._ExtractAllJMIDataPointsWithKey(
109 jmi_type=SSRC, is_audio=False, key=FRAMERATE_SENT)
110
111 def GetVideoIncomingFramerateDecodedList(self):
112 return self._ExtractAllJMIDataPointsWithKey(
113 jmi_type=SSRC, is_audio=False, key=FRAMERATE_DECODED)
114
115 def GetVideoIncomingFramerateList(self):
116 return self._ExtractAllJMIDataPointsWithKey(
117 jmi_type=SSRC, is_audio=False, key=FRAMERATE_OUTPUT)
118
119 def GetVideoSentFrameWidthList(self):
120 return self._ExtractAllJMIDataPointsWithKey(
121 jmi_type=SSRC, is_audio=False, key=FRAME_WIDTH_SENT)
122
123 def GetVideoSentFrameHeightList(self):
124 return self._ExtractAllJMIDataPointsWithKey(
125 jmi_type=SSRC, is_audio=False, key=FRAME_HEIGHT_SENT)
126
127 def GetCPULimitedResolutionList(self):
128 return self._ExtractAllJMIDataPointsWithKey(
129 jmi_type=SSRC, is_audio=False, key=CPU_LIMITED_RESOLUTION)
130
131 def GetVideoPacketsSentList(self):
132 return self._ExtractAllJMIDataPointsWithKey(
133 jmi_type=SSRC, is_audio=False, key=VIDEO_PACKETS_SENT)
134
135 def GetVideoPacketsLostList(self):
136 return self._ExtractAllJMIDataPointsWithKey(
137 jmi_type=SSRC, is_audio=False, key=VIDEO_PACKETS_LOST)
138
139 def GetVideoIncomingFramesDecodedList(self):
140 return self._ExtractAllJMIDataPointsWithKey(
141 jmi_type=SSRC, is_audio=False, key=FRAMES_DECODED)
142
143 def GetVideoOutgoingFramesEncodedList(self):
144 return self._ExtractAllJMIDataPointsWithKey(
145 jmi_type=SSRC, is_audio=False, key=FRAMES_ENCODED)
146
147 def GetVideoAdaptationChangeList(self):
148 return self._ExtractAllJMIDataPointsWithKey(
149 jmi_type=SSRC, is_audio=False, key=ADAPTATION_CHANGES)
150
151 def GetVideoEncodeTimeList(self):
152 return self._ExtractAllJMIDataPointsWithKey(
153 jmi_type=SSRC, is_audio=False, key=AVERAGE_ENCODE_TIME)
154
155 def GetBandwidthLimitedResolutionList(self):
156 return self._ExtractAllJMIDataPointsWithKey(
157 jmi_type=SSRC, is_audio=False, key=BANDWIDTH_LIMITED_RESOLUTION)
158
159 def GetVideoReceivedFrameHeightList(self):
160 return self._ExtractAllJMIDataPointsWithKey(
161 jmi_type=SSRC, is_audio=False, key=VIDEO_RECEIVED_FRAME_HEIGHT)
162
163 def GetVideoOutgoingFramerateInputList(self):
164 return self._ExtractAllJMIDataPointsWithKey(
165 jmi_type=SSRC, is_audio=False, key=FRAMERATE_OUTGOING)
166
167 def GetVideoReceivedFrameWidthList(self):
168 return self._ExtractAllJMIDataPointsWithKey(
169 jmi_type=SSRC, is_audio=False, key=VIDEO_RECEIVED_FRAME_WIDTH)
170
171 def GetVideoEncodeCpuUsagePercentList(self):
172 return self._ExtractAllJMIDataPointsWithKey(
173 jmi_type=SSRC, is_audio=False, key=VIDEO_ENCODE_CPU_USAGE)
174
175 def GetNumberOfActiveIncomingVideoStreams(self):
176 """Retrieve number of active incoming video streams."""
177 if not self._jmi_list:
178 # JMI data hasn't started populating yet.
179 return 0
180
181 num_video_streams = []
182
183 # If JMI data has started getting populated and has video stream data.
184 for jmi_data_point in self._jmi_list:
185 json_arr = json.loads(jmi_data_point)
186 video_streams = 0
187 for i in range(AV_INDEX, len(json_arr)):
188 if json_arr[i] and SSRC in json_arr[i]:
189 ssrc_obj = json_arr[i][SSRC]
190 is_audio = ('audioInputLevel' in ssrc_obj or
191 'audioOutputLevel' in ssrc_obj)
192 is_incoming = 'bytesReceived' in ssrc_obj
193 frame_rate_received = 'googFrameRateReceived' in ssrc_obj
194 if ssrc_obj['mediaType'] == 'video' and \
195 frame_rate_received:
196 frame_rate = ssrc_obj['googFrameRateReceived']
197 if (is_incoming and not is_audio) and \
198 frame_rate != 0:
199 video_streams += 1
200 num_video_streams.append(video_streams)
201 return num_video_streams
202
203 def GetCpuUsageList(self, cpu_type):
204 """Retrieves cpu usage data from JMI data.
205
harpreet16ebb4b2017-01-26 13:41:25 -0800206 @param cpu_type: Cpu usage type.
harpreet6ffd1e42017-01-24 18:24:36 -0800207 @returns List containing CPU usage data.
208 """
209 data_list = []
210 for jmi_data_point in self._jmi_list:
211 json_arr = json.loads(jmi_data_point)
212 for i in range(AV_INDEX, len(json_arr)):
213 if json_arr[i] and GLOBAL in json_arr[i]:
214 global_obj = json_arr[i][GLOBAL]
215 # Some values in JMIDataV3 are set to 'null'.
harpreet16ebb4b2017-01-26 13:41:25 -0800216 if cpu_type == u'numOfProcessors':
217 return global_obj[cpu_type]
218 elif (cpu_type in global_obj and
219 self.IsFloat(global_obj[cpu_type])):
220 data_list.append(float(global_obj[cpu_type]))
harpreet6ffd1e42017-01-24 18:24:36 -0800221 return data_list
222
harpreet16ebb4b2017-01-26 13:41:25 -0800223 def GetNumOfProcessors(self):
224 return self.GetCpuUsageList(NUM_PROCESSORS)
225
226 def GetTotalCpuPercentage(self):
227 return self.GetCpuUsageList(TOTAL_CPU)
228
229 def GetBrowserCpuPercentage(self):
230 return self.GetCpuUsageList(BROWSER_CPU)
231
232 def GetGpuCpuPercentage(self):
233 return self.GetCpuUsageList(GPU_CPU)
234
235 def GetNaclEffectsCpuPercentage(self):
236 return self.GetCpuUsageList(NACL_EFFECTS_CPU)
237
238 def GetRendererCpuPercentage(self):
239 return self.GetCpuUsageList(RENDERER_CPU)
harpreet6ffd1e42017-01-24 18:24:36 -0800240
241 def IsFloat(self, value):
242 try:
243 float(value)
244 return True
245 except TypeError:
246 return False