Home | History | Annotate | Download | only in video_VideoEncodeAccelerator
      1 # Copyright (c) 2014 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 fnmatch
      7 import hashlib
      8 import logging
      9 import os
     10 
     11 from autotest_lib.client.bin import utils
     12 from autotest_lib.client.common_lib import error
     13 from autotest_lib.client.common_lib import file_utils
     14 from autotest_lib.client.cros import chrome_binary_test
     15 from autotest_lib.client.cros.video import helper_logger
     16 
     17 DOWNLOAD_BASE = 'http://commondatastorage.googleapis.com/chromiumos-test-assets-public/'
     18 BINARY = 'video_encode_accelerator_unittest'
     19 
     20 def _remove_if_exists(filepath):
     21     try:
     22         os.remove(filepath)
     23     except OSError, e:
     24         if e.errno != errno.ENOENT: # no such file
     25             raise
     26 
     27 
     28 def _download_video(download_path, local_file):
     29     url = '%s%s' % (DOWNLOAD_BASE, download_path)
     30     logging.info('download "%s" to "%s"', url, local_file)
     31 
     32     file_utils.download_file(url, local_file)
     33 
     34     with open(local_file, 'r') as r:
     35         md5sum = hashlib.md5(r.read()).hexdigest()
     36         if md5sum not in download_path:
     37             raise error.TestError('unmatched md5 sum: %s' % md5sum)
     38 
     39 
     40 class video_VideoEncodeAccelerator(chrome_binary_test.ChromeBinaryTest):
     41     """
     42     This test is a wrapper of the chrome unittest binary:
     43     video_encode_accelerator_unittest.
     44     """
     45 
     46     version = 1
     47 
     48     def get_filter_option(self, profile, size):
     49         """Get option of filtering test.
     50 
     51         @param profile: The profile to encode into.
     52         @param size: The size of test stream in pair format (width, height).
     53         """
     54 
     55         # Profiles used in blacklist to filter test for specific profiles.
     56         H264 = 1
     57         VP8 = 11
     58         VP9 = 12
     59 
     60         blacklist = {
     61                 # (board, profile, size): [tests to skip...]
     62 
     63                 # "board" supports Unix shell-type wildcards.
     64 
     65                 # Use None for "profile" or "size" to indicate no filter on it.
     66 
     67                 # It is possible to match multiple keys for board/profile/size
     68                 # in the blacklist, e.g. veyron_minnie could match both
     69                 # "veyron_*" and "veyron_minnie".
     70 
     71                 # rk3399 doesn't support HW encode for plane sizes not multiple
     72                 # of cache line.
     73                 ('kevin', None, None): ['CacheLineUnalignedInputTest/*'],
     74                 ('bob', None, None): ['CacheLineUnalignedInputTest/*'],
     75 
     76                 # Still high failure rate of VP8 EncoderPerf for veyrons,
     77                 # disable it for now. crbug/720386
     78                 ('veyron_*', VP8, None): ['EncoderPerf/*'],
     79 
     80                 # Disable mid_stream_bitrate_switch test cases for elm/hana.
     81                 # crbug/725087
     82                 ('elm', None, None): ['MidStreamParamSwitchBitrate/*',
     83                                       'MultipleEncoders/*'],
     84                 ('hana', None, None): ['MidStreamParamSwitchBitrate/*',
     85                                        'MultipleEncoders/*'],
     86 
     87                 # Around 40% failure on elm and hana 320x180 test stream.
     88                 # crbug/728906
     89                 ('elm', H264, (320, 180)): ['ForceBitrate/*'],
     90                 ('elm', VP8, (320, 180)): ['ForceBitrate/*'],
     91                 ('hana', H264, (320, 180)): ['ForceBitrate/*'],
     92                 ('hana', VP8, (320, 180)): ['ForceBitrate/*'],
     93                 }
     94 
     95         board = utils.get_current_board()
     96 
     97         filter_list = []
     98         for (board_key, profile_key, size_key), value in blacklist.items():
     99             if (fnmatch.fnmatch(board, board_key) and
    100                 (profile_key is None or profile == profile_key) and
    101                 (size_key is None or size == size_key)):
    102                 filter_list += value
    103 
    104         if filter_list:
    105             return '-' + ':'.join(filter_list)
    106 
    107         return ''
    108 
    109     @helper_logger.video_log_wrapper
    110     @chrome_binary_test.nuke_chrome
    111     def run_once(self, in_cloud, streams, profile, gtest_filter=None):
    112         """Runs video_encode_accelerator_unittest on the streams.
    113 
    114         @param in_cloud: Input file needs to be downloaded first.
    115         @param streams: The test streams for video_encode_accelerator_unittest.
    116         @param profile: The profile to encode into.
    117         @param gtest_filter: test case filter.
    118 
    119         @raises error.TestFail for video_encode_accelerator_unittest failures.
    120         """
    121 
    122         last_test_failure = None
    123         for path, width, height, bit_rate in streams:
    124             if in_cloud:
    125                 input_path = os.path.join(self.tmpdir, path.split('/')[-1])
    126                 _download_video(path, input_path)
    127             else:
    128                 input_path = os.path.join(self.cr_source_dir, path)
    129 
    130             output_path = os.path.join(self.tmpdir,
    131                     '%s.out' % input_path.split('/')[-1])
    132 
    133             cmd_line_list = []
    134             cmd_line_list.append('--test_stream_data="%s:%s:%s:%s:%s:%s"' % (
    135                     input_path, width, height, profile, output_path, bit_rate))
    136             cmd_line_list.append(helper_logger.chrome_vmodule_flag())
    137             cmd_line_list.append('--ozone-platform=gbm')
    138 
    139             # Command line |gtest_filter| can override get_filter_option().
    140             predefined_filter = self.get_filter_option(profile, (width, height))
    141             if gtest_filter and predefined_filter:
    142                 logging.warning('predefined gtest filter is suppressed: %s',
    143                     predefined_filter)
    144                 applied_filter = gtest_filter
    145             else:
    146                 applied_filter = predefined_filter
    147             if applied_filter:
    148                 cmd_line_list.append('--gtest_filter="%s"' % applied_filter)
    149 
    150             cmd_line = ' '.join(cmd_line_list)
    151             try:
    152                 self.run_chrome_test_binary(BINARY, cmd_line, as_chronos=False)
    153             except error.TestFail as test_failure:
    154                 # Continue to run the remaining test streams and raise
    155                 # the last failure after finishing all streams.
    156                 logging.exception('error while encoding %s', input_path)
    157                 last_test_failure = test_failure
    158             finally:
    159                 # Remove the downloaded video
    160                 if in_cloud:
    161                     _remove_if_exists(input_path)
    162                 _remove_if_exists(output_path)
    163 
    164         if last_test_failure:
    165             raise last_test_failure
    166