# Copyright (c) 2013 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. """Test to probe the video capability.""" import glob, logging, os, sys from autotest_lib.client.bin import test, utils from autotest_lib.client.common_lib import error # The following VA_XXX values are copied from va/va.h # VA profiles that we are interested in VAProfileH264Main = 6 VAProfileH264High = 7 VAProfileH264ConstrainedBaseline = 13 # VA Entrypoint that we are interested in VAEntrypointVLD = 1 # VA_RT_FORMAT that we are interested in VA_RT_FORMAT_YUV420 = 0x01 KEY_DEVICE = 'device' KEY_FORMATS = 'formats' class hardware_VideoDecodeCapable(test.test): """Test class to verify hardware video decoding capability.""" version = 1 REQUESTED_VAAPI_PROFILES = [ VAProfileH264ConstrainedBaseline, VAProfileH264Main, VAProfileH264High] REQUESTED_V4L2_FORMATS = [ # Requested formats for decoding devices {KEY_DEVICE: '/dev/video-dec', KEY_FORMATS: ['cap_fmt_VM12', 'cap_fmt_NM12', 'out_fmt_H264', 'out_fmt_VP80']}, # REQUESTED formats for GSCALER devices {KEY_DEVICE: '/dev/gsc*', KEY_FORMATS: ['cap_fmt_RGB4', 'out_fmt_VM12']}] def assertTrue(self, condition, message = '', *args): """Raises an TestFail when the assertion failed""" if (not condition): raise error.TestFail(message % args) def verifyProfile(self, vaapi, display, profile): """Verifies the given profile satisfies the requirements. 1. It has the VLD entrypoint 2. It supports YUV420 for RT_FORMAT @param vaapi: the vaapi module @param display: the va_display instance @param profile: the profile under test @raise error.TestFail: when verification fails """ entrypoints = vaapi.query_entrypoints(display, profile) logging.info('Entrypoints of profile %s: %s', profile, entrypoints) self.assertTrue(VAEntrypointVLD in entrypoints, 'VAEntrypointVLD is not supported') rt_format = vaapi.get_rt_format(display, profile, VAEntrypointVLD) logging.info('RT_Format: %s', rt_format) self.assertTrue(VA_RT_FORMAT_YUV420 & rt_format, 'VA_RT_FORMAT_YUV420 is not supported') def setup(self): os.chdir(self.srcdir) # Ignores the fail status since vaapi module won't get built on # platforms without VAAPI support (e.g., Daisy). On those platforms # we will test with the v4l2 module. utils.make('v4l2', ignore_status = True) utils.make('vaapi', ignore_status = True) utils.make('vaapi_drm', ignore_status = True) def run_once_vaapi(self): sys.path.append(self.bindir) import vaapi if not utils.is_freon(): # Set the XAUTHORITY for connecting to the X server utils.assert_has_X_server() os.environ.setdefault('XAUTHORITY', '/home/chronos/.Xauthority') display = vaapi.create_display(':0.0') else: display = vaapi.create_display('/dev/dri/card0') supported_profiles = vaapi.query_profiles(display) logging.info('Vaapi Profiles: %s', supported_profiles) for profile in self.REQUESTED_VAAPI_PROFILES: self.assertTrue(profile in supported_profiles, 'Profile:%s is not supported', profile) self.verifyProfile(vaapi, display, profile) def _enum_formats(self, video_device): """Use the v4l2 binary to enum formats. Runs the embedded v4l2 binary to enumerate supported capture formats and output formats. @param video_device: device interrogated (e.g. /dev/video-dec). @return a dict of keyvals reflecting the formats supported. """ sys.path.append(self.bindir) import v4l2 capture_formats = v4l2.enum_capture_formats(video_device) logging.info('%s, capture formats=%s', video_device, capture_formats) output_formats = v4l2.enum_output_formats(video_device) logging.info('%s, output formats=%s', video_device, output_formats) return (['cap_fmt_%s' % fmt for fmt in capture_formats] + ['out_fmt_%s' % fmt for fmt in output_formats]) def run_once_v4l2(self): """Check supported image formats for all expected device nodes """ for rules in self.REQUESTED_V4L2_FORMATS: formats = rules[KEY_FORMATS] devices = glob.glob(rules[KEY_DEVICE]) self.assertTrue(len(devices) > 0, 'No matched devices: %s', rules[KEY_DEVICE]) for device in devices: missed = set(formats) - set(self._enum_formats(device)) self.assertTrue(not missed, 'Formats: %s is not supported for device: %s', missed, device) def run_once(self, type='v4l2'): if type == 'v4l2': self.run_once_v4l2() else: self.run_once_vaapi()