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