You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
259 lines
10 KiB
259 lines
10 KiB
# Lint as: python2, python3
|
|
# Copyright (c) 2017 The Chromium OS Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
from __future__ import absolute_import
|
|
from __future__ import division
|
|
from __future__ import print_function
|
|
|
|
import json
|
|
|
|
from autotest_lib.server.cros import cfm_jmidata_helper_base
|
|
from six.moves import range
|
|
|
|
# Start index in the JSON object that contains Audio/Video streams related info.
|
|
AV_INDEX = 4
|
|
|
|
SSRC = u'ssrc'
|
|
GLOBAL = u'global'
|
|
|
|
AUDIO_INPUT = u'audioInputLevel'
|
|
AUDIO_OUTPUT = u'audioOutputLevel'
|
|
BYTES_RECEIVED = u'bytesReceived'
|
|
BYTES_SENT = u'bytesSent'
|
|
ADAPTATION_CHANGES = u'googAdaptationChanges'
|
|
AVERAGE_ENCODE_TIME = u'googAvgEncodeMs'
|
|
BANDWIDTH_LIMITED_RESOLUTION = u'googBandwidthLimitedResolution'
|
|
CPU_LIMITED_RESOLUTION = u'googCpuLimitedResolution'
|
|
VIDEO_ENCODE_CPU_USAGE = u'googEncodeUsagePercent'
|
|
VIDEO_RECEIVED_FRAME_HEIGHT = u'googFrameHeightReceived'
|
|
VIDEO_RECEIVED_FRAME_WIDTH = u'googFrameWidthReceived'
|
|
FRAMERATE_OUTGOING = u'googFrameRateInput'
|
|
FRAMERATE_RECEIVED = u'googFrameRateReceived'
|
|
FRAMERATE_SENT = u'googFrameRateSent'
|
|
FRAMERATE_DECODED = u'googFrameRateDecoded'
|
|
FRAMERATE_OUTPUT = u'googFrameRateOutput'
|
|
FRAME_WIDTH_SENT = u'googFrameWidthSent'
|
|
FRAME_HEIGHT_SENT = u'googFrameHeightSent'
|
|
FRAMES_DECODED = u'framesDecoded'
|
|
FRAMES_ENCODED = u'framesEncoded'
|
|
VIDEO_PACKETS_LOST = u'packetsLost'
|
|
VIDEO_PACKETS_SENT = u'packetsSent'
|
|
|
|
BROWSER_CPU = u'browserCpuUsage'
|
|
GPU_CPU = u'gpuCpuUsage'
|
|
NUM_PROCESSORS = u'numOfProcessors'
|
|
NACL_EFFECTS_CPU = u'pluginCpuUsage'
|
|
RENDERER_CPU = u'tabCpuUsage'
|
|
TOTAL_CPU = u'totalCpuUsage'
|
|
|
|
|
|
class JMIDataV3Helper(cfm_jmidata_helper_base.JMIDataHelperBase):
|
|
"""Helper class for JMI data v3 parsing. This class helps in extracting
|
|
relevant JMI data from javascript log.
|
|
|
|
The class takes javascript file as input and extracts jmidata elements from
|
|
the file that is internally stored as a list. Whenever we need to extract
|
|
data i.e. audio received bytes we call a method such as
|
|
getAudioReceivedDataList. This method converts each string element in the
|
|
internal list to a json object and retrieves the relevant info from it which
|
|
is then stored and returned as a list.
|
|
"""
|
|
|
|
def __init__(self, log_file_content):
|
|
super(JMIDataV3Helper, self).__init__(log_file_content, 'jmidatav3')
|
|
|
|
def _ExtractAllJMIDataPointsWithKey(self, jmi_type, is_audio, key):
|
|
"""Extracts all values from the data points with the given key."""
|
|
data_list = []
|
|
for jmi_data_point in self._jmi_list:
|
|
json_arr = json.loads(jmi_data_point)
|
|
for i in range(AV_INDEX, len(json_arr)):
|
|
if json_arr[i] and jmi_type in json_arr[i]:
|
|
jmi_obj = json_arr[i][jmi_type]
|
|
this_is_audio = (AUDIO_INPUT in jmi_obj or
|
|
AUDIO_OUTPUT in jmi_obj)
|
|
if this_is_audio == is_audio and key in jmi_obj:
|
|
if (not isinstance(jmi_obj[key], int) and
|
|
(jmi_obj[key] == 'false' or
|
|
jmi_obj[key] == 'true')):
|
|
jmi_obj[key] = 1 if jmi_obj[key] == 'true' else 0
|
|
data_list.append(jmi_obj[key])
|
|
if not data_list:
|
|
data_list = [0]
|
|
return data_list
|
|
|
|
def GetAudioReceivedBytesList(self):
|
|
return self._ExtractAllJMIDataPointsWithKey(
|
|
jmi_type=SSRC, is_audio=True, key=BYTES_RECEIVED)
|
|
|
|
def GetAudioSentBytesList(self):
|
|
return self._ExtractAllJMIDataPointsWithKey(
|
|
jmi_type=SSRC, is_audio=True, key=BYTES_SENT)
|
|
|
|
def GetAudioReceivedEnergyList(self):
|
|
return self._ExtractAllJMIDataPointsWithKey(
|
|
jmi_type=SSRC, is_audio=True, key=AUDIO_OUTPUT)
|
|
|
|
def GetAudioSentEnergyList(self):
|
|
return self._ExtractAllJMIDataPointsWithKey(
|
|
jmi_type=SSRC, is_audio=True, key=AUDIO_INPUT)
|
|
|
|
def GetVideoSentBytesList(self):
|
|
return self._ExtractAllJMIDataPointsWithKey(
|
|
jmi_type=SSRC, is_audio=False, key=BYTES_SENT)
|
|
|
|
def GetVideoReceivedBytesList(self):
|
|
return self._ExtractAllJMIDataPointsWithKey(
|
|
jmi_type=SSRC, is_audio=False, key=BYTES_RECEIVED)
|
|
|
|
def GetVideoIncomingFramerateReceivedList(self):
|
|
return self._ExtractAllJMIDataPointsWithKey(
|
|
jmi_type=SSRC, is_audio=False, key=FRAMERATE_RECEIVED)
|
|
|
|
def GetVideoOutgoingFramerateSentList(self):
|
|
return self._ExtractAllJMIDataPointsWithKey(
|
|
jmi_type=SSRC, is_audio=False, key=FRAMERATE_SENT)
|
|
|
|
def GetVideoIncomingFramerateDecodedList(self):
|
|
return self._ExtractAllJMIDataPointsWithKey(
|
|
jmi_type=SSRC, is_audio=False, key=FRAMERATE_DECODED)
|
|
|
|
def GetVideoIncomingFramerateList(self):
|
|
return self._ExtractAllJMIDataPointsWithKey(
|
|
jmi_type=SSRC, is_audio=False, key=FRAMERATE_OUTPUT)
|
|
|
|
def GetVideoSentFrameWidthList(self):
|
|
return self._ExtractAllJMIDataPointsWithKey(
|
|
jmi_type=SSRC, is_audio=False, key=FRAME_WIDTH_SENT)
|
|
|
|
def GetVideoSentFrameHeightList(self):
|
|
return self._ExtractAllJMIDataPointsWithKey(
|
|
jmi_type=SSRC, is_audio=False, key=FRAME_HEIGHT_SENT)
|
|
|
|
def GetCPULimitedResolutionList(self):
|
|
return self._ExtractAllJMIDataPointsWithKey(
|
|
jmi_type=SSRC, is_audio=False, key=CPU_LIMITED_RESOLUTION)
|
|
|
|
def GetVideoPacketsSentList(self):
|
|
return self._ExtractAllJMIDataPointsWithKey(
|
|
jmi_type=SSRC, is_audio=False, key=VIDEO_PACKETS_SENT)
|
|
|
|
def GetVideoPacketsLostList(self):
|
|
return self._ExtractAllJMIDataPointsWithKey(
|
|
jmi_type=SSRC, is_audio=False, key=VIDEO_PACKETS_LOST)
|
|
|
|
def GetVideoIncomingFramesDecodedList(self):
|
|
return self._ExtractAllJMIDataPointsWithKey(
|
|
jmi_type=SSRC, is_audio=False, key=FRAMES_DECODED)
|
|
|
|
def GetVideoOutgoingFramesEncodedList(self):
|
|
return self._ExtractAllJMIDataPointsWithKey(
|
|
jmi_type=SSRC, is_audio=False, key=FRAMES_ENCODED)
|
|
|
|
def GetVideoAdaptationChangeList(self):
|
|
return self._ExtractAllJMIDataPointsWithKey(
|
|
jmi_type=SSRC, is_audio=False, key=ADAPTATION_CHANGES)
|
|
|
|
def GetVideoEncodeTimeList(self):
|
|
return self._ExtractAllJMIDataPointsWithKey(
|
|
jmi_type=SSRC, is_audio=False, key=AVERAGE_ENCODE_TIME)
|
|
|
|
def GetBandwidthLimitedResolutionList(self):
|
|
return self._ExtractAllJMIDataPointsWithKey(
|
|
jmi_type=SSRC, is_audio=False, key=BANDWIDTH_LIMITED_RESOLUTION)
|
|
|
|
def GetVideoReceivedFrameHeightList(self):
|
|
return self._ExtractAllJMIDataPointsWithKey(
|
|
jmi_type=SSRC, is_audio=False, key=VIDEO_RECEIVED_FRAME_HEIGHT)
|
|
|
|
def GetVideoOutgoingFramerateInputList(self):
|
|
return self._ExtractAllJMIDataPointsWithKey(
|
|
jmi_type=SSRC, is_audio=False, key=FRAMERATE_OUTGOING)
|
|
|
|
def GetVideoReceivedFrameWidthList(self):
|
|
return self._ExtractAllJMIDataPointsWithKey(
|
|
jmi_type=SSRC, is_audio=False, key=VIDEO_RECEIVED_FRAME_WIDTH)
|
|
|
|
def GetVideoEncodeCpuUsagePercentList(self):
|
|
return self._ExtractAllJMIDataPointsWithKey(
|
|
jmi_type=SSRC, is_audio=False, key=VIDEO_ENCODE_CPU_USAGE)
|
|
|
|
def GetNumberOfActiveIncomingVideoStreams(self):
|
|
"""Retrieve number of active incoming video streams."""
|
|
if not self._jmi_list:
|
|
# JMI data hasn't started populating yet.
|
|
return 0
|
|
|
|
num_video_streams = []
|
|
|
|
# If JMI data has started getting populated and has video stream data.
|
|
for jmi_data_point in self._jmi_list:
|
|
json_arr = json.loads(jmi_data_point)
|
|
video_streams = 0
|
|
for i in range(AV_INDEX, len(json_arr)):
|
|
if json_arr[i] and SSRC in json_arr[i]:
|
|
ssrc_obj = json_arr[i][SSRC]
|
|
is_audio = ('audioInputLevel' in ssrc_obj or
|
|
'audioOutputLevel' in ssrc_obj)
|
|
is_incoming = 'bytesReceived' in ssrc_obj
|
|
frame_rate_received = 'googFrameRateReceived' in ssrc_obj
|
|
if ssrc_obj['mediaType'] == 'video' and \
|
|
frame_rate_received:
|
|
frame_rate = ssrc_obj['googFrameRateReceived']
|
|
if (is_incoming and not is_audio) and \
|
|
frame_rate != 0:
|
|
video_streams += 1
|
|
num_video_streams.append(video_streams)
|
|
if not num_video_streams:
|
|
num_video_streams = [0]
|
|
return num_video_streams
|
|
|
|
def GetCpuUsageList(self, cpu_type):
|
|
"""Retrieves cpu usage data from JMI data.
|
|
|
|
@param cpu_type: Cpu usage type.
|
|
@returns List containing CPU usage data.
|
|
"""
|
|
data_list = []
|
|
for jmi_data_point in self._jmi_list:
|
|
json_arr = json.loads(jmi_data_point)
|
|
for i in range(AV_INDEX, len(json_arr)):
|
|
if json_arr[i] and GLOBAL in json_arr[i]:
|
|
global_obj = json_arr[i][GLOBAL]
|
|
# Some values in JMIDataV3 are set to 'null'.
|
|
if cpu_type == u'numOfProcessors':
|
|
return global_obj[cpu_type]
|
|
elif (cpu_type in global_obj and
|
|
self.IsFloat(global_obj[cpu_type])):
|
|
data_list.append(float(global_obj[cpu_type]))
|
|
if not data_list:
|
|
data_list = [0]
|
|
return data_list
|
|
|
|
def GetNumOfProcessors(self):
|
|
return self.GetCpuUsageList(NUM_PROCESSORS)
|
|
|
|
def GetTotalCpuPercentage(self):
|
|
return self.GetCpuUsageList(TOTAL_CPU)
|
|
|
|
def GetBrowserCpuPercentage(self):
|
|
return self.GetCpuUsageList(BROWSER_CPU)
|
|
|
|
def GetGpuCpuPercentage(self):
|
|
return self.GetCpuUsageList(GPU_CPU)
|
|
|
|
def GetNaclEffectsCpuPercentage(self):
|
|
return self.GetCpuUsageList(NACL_EFFECTS_CPU)
|
|
|
|
def GetRendererCpuPercentage(self):
|
|
return self.GetCpuUsageList(RENDERER_CPU)
|
|
|
|
def IsFloat(self, value):
|
|
try:
|
|
float(value)
|
|
return True
|
|
except TypeError:
|
|
return False
|