Home | History | Annotate | Download | only in video_JEAPerf
      1 # Copyright 2018 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 import errno
      6 import logging
      7 import os
      8 from autotest_lib.client.common_lib import file_utils
      9 from autotest_lib.client.cros import chrome_binary_test
     10 from autotest_lib.client.cros.video import device_capability
     11 from autotest_lib.client.cros.video import helper_logger
     12 
     13 DOWNLOAD_BASE = ('http://commondatastorage.googleapis.com/'
     14                  'chromiumos-test-assets-public/')
     15 TEST_LOG = 'test_log'
     16 REPEAT_TIMES = 100
     17 TIME_UNIT = 'millisecond'
     18 HW_ENCODE_LABEL = 'hw_encode_time'
     19 SW_ENCODE_LABEL = 'sw_encode_time'
     20 LATENCY_50_SUFFIX = '.encode_latency.50_percentile'
     21 LATENCY_75_SUFFIX = '.encode_latency.75_percentile'
     22 LATENCY_95_SUFFIX = '.encode_latency.95_percentile'
     23 HW_PREFIX = 'hw_'
     24 SW_PREFIX = 'sw_'
     25 
     26 class video_JEAPerf(chrome_binary_test.ChromeBinaryTest):
     27     """
     28     This test monitors performance metrics reported by Chrome test binary,
     29     jpeg_encode_accelerator_unittest.
     30     """
     31 
     32     version = 1
     33     binary = 'jpeg_encode_accelerator_unittest'
     34 
     35     def report_perf_results(self, test_name, output_path):
     36         hw_times = []
     37         sw_times = []
     38         with open(output_path, 'r') as f:
     39             lines = f.readlines()
     40             lines = [line.strip() for line in lines]
     41             for line in lines:
     42                 key_value = line.split(':')
     43                 if len(key_value) != 2:
     44                     continue
     45                 (key, value) = (key_value[0].strip(), key_value[1].strip())
     46                 if key == HW_ENCODE_LABEL:
     47                     hw_times.append(int(value))
     48                 if key == SW_ENCODE_LABEL:
     49                     sw_times.append(int(value))
     50         hw_times.sort()
     51         sw_times.sort()
     52 
     53         if len(hw_times) > 0:
     54             percentile_50 = len(hw_times) / 2
     55             percentile_75 = len(hw_times) * 3 / 4
     56             percentile_95 = len(hw_times) * 95 / 100
     57             test_title = HW_PREFIX + test_name
     58             self.output_perf_value(description=(test_title + LATENCY_50_SUFFIX),
     59                 value=hw_times[percentile_50],
     60                 units=TIME_UNIT, higher_is_better=False)
     61             self.output_perf_value(description=(test_title + LATENCY_75_SUFFIX),
     62                 value=hw_times[percentile_75],
     63                 units=TIME_UNIT, higher_is_better=False)
     64             self.output_perf_value(description=(test_title + LATENCY_95_SUFFIX),
     65                 value=hw_times[percentile_95],
     66                 units=TIME_UNIT, higher_is_better=False)
     67 
     68         if len(sw_times) > 0:
     69             percentile_50 = len(sw_times) / 2
     70             percentile_75 = len(sw_times) * 3 / 4
     71             percentile_95 = len(sw_times) * 95 / 100
     72             test_title = SW_PREFIX + test_name
     73             self.output_perf_value(description=(test_title + LATENCY_50_SUFFIX),
     74                 value=sw_times[percentile_50],
     75                 units=TIME_UNIT, higher_is_better=False)
     76             self.output_perf_value(description=(test_title + LATENCY_75_SUFFIX),
     77                 value=sw_times[percentile_75],
     78                 units=TIME_UNIT, higher_is_better=False)
     79             self.output_perf_value(description=(test_title + LATENCY_95_SUFFIX),
     80                 value=sw_times[percentile_95],
     81                 units=TIME_UNIT, higher_is_better=False)
     82 
     83     def remove_if_exists(self, file_path):
     84         try:
     85             os.remove(file_path)
     86         except OSError as e:
     87             if e.errno != errno.ENOENT:  # no such file
     88                 raise
     89 
     90     @helper_logger.video_log_wrapper
     91     @chrome_binary_test.nuke_chrome
     92     def run_once(self, test_cases, capability):
     93         """
     94         Runs JpegEncodeAcceleratorTest.SimpleEncode on the device and reports
     95         latency values for HW and SW.
     96 
     97         @param capability: Capability required for executing this test.
     98         """
     99         device_capability.DeviceCapability().ensure_capability(capability)
    100 
    101         for (image_path, width, height) in test_cases:
    102             url = DOWNLOAD_BASE + image_path
    103             file_name = os.path.basename(image_path)
    104             input_path = os.path.join(self.bindir, file_name)
    105             file_utils.download_file(url, input_path)
    106             test_name = ('%s_%dx%d' % (file_name, width, height))
    107             output_path = os.path.join(self.tmpdir, TEST_LOG)
    108 
    109             cmd_line_list = [helper_logger.chrome_vmodule_flag()] + [
    110                 '--gtest_filter=JpegEncodeAcceleratorTest.SimpleEncode',
    111                 ('--output_log=%s' % output_path),
    112                 ('--repeat=%d' % REPEAT_TIMES),
    113                 ('--yuv_filenames="%s:%dx%d"' % (input_path, width, height))
    114             ]
    115             cmd_line = ' '.join(cmd_line_list)
    116             try:
    117                 self.run_chrome_test_binary(self.binary, cmd_line)
    118                 self.report_perf_results(test_name, output_path)
    119             except Exception as last_error:
    120                 # Log the error and continue to the next test case.
    121                 logging.exception(last_error)
    122             finally:
    123                 self.remove_if_exists(input_path)
    124                 self.remove_if_exists(output_path)
    125