• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 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
5import json
6
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
38BROWSER_CPU = u'browserCpuUsage'
39GPU_CPU = u'gpuCpuUsage'
40NUM_PROCESSORS = u'numOfProcessors'
41NACL_EFFECTS_CPU = u'pluginCpuUsage'
42RENDERER_CPU = u'tabCpuUsage'
43TOTAL_CPU = u'totalCpuUsage'
44
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]
69                    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
206        @param cpu_type: Cpu usage type.
207        @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'.
216                    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]))
221        if not data_list:
222            data_list = [0]
223        return data_list
224
225    def GetNumOfProcessors(self):
226        return self.GetCpuUsageList(NUM_PROCESSORS)
227
228    def GetTotalCpuPercentage(self):
229        return self.GetCpuUsageList(TOTAL_CPU)
230
231    def GetBrowserCpuPercentage(self):
232        return self.GetCpuUsageList(BROWSER_CPU)
233
234    def GetGpuCpuPercentage(self):
235        return self.GetCpuUsageList(GPU_CPU)
236
237    def GetNaclEffectsCpuPercentage(self):
238        return self.GetCpuUsageList(NACL_EFFECTS_CPU)
239
240    def GetRendererCpuPercentage(self):
241        return self.GetCpuUsageList(RENDERER_CPU)
242
243    def IsFloat(self, value):
244        try:
245            float(value)
246            return True
247        except TypeError:
248            return False
249