| # 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 |
| VAProfileH264Baseline = 5 |
| VAProfileH264Main = 6 |
| VAProfileH264High = 7 |
| |
| # 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 = [ |
| VAProfileH264Baseline, |
| VAProfileH264Main, |
| VAProfileH264High] |
| |
| REQUESTED_V4L2_FORMATS = [ |
| # Requested formats for decoding devices |
| {KEY_DEVICE: '/dev/mfc-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) |
| |
| |
| def run_once_vaapi(self): |
| sys.path.append(self.bindir) |
| import vaapi |
| |
| # Set the XAUTHORITY for connecting to the X server |
| os.environ.setdefault('XAUTHORITY', '/home/chronos/.Xauthority') |
| |
| display = vaapi.create_display(':0.0') |
| 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/mfc-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() |
| |