1# Copyright 2014 The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15import math 16 17import its.caps 18import its.device 19import its.objects 20import its.target 21 22 23def main(): 24 """Test the validity of some metadata entries. 25 26 Looks at capture results and at the camera characteristics objects. 27 """ 28 global md, props, failed 29 30 with its.device.ItsSession() as cam: 31 # Arbitrary capture request exposure values; image content is not 32 # important for this test, only the metadata. 33 props = cam.get_camera_properties() 34 auto_req = its.objects.auto_capture_request() 35 cap = cam.do_capture(auto_req) 36 md = cap["metadata"] 37 38 print "Hardware level" 39 print " Legacy:", its.caps.legacy(props) 40 print " Limited:", its.caps.limited(props) 41 print " Full or better:", its.caps.full_or_better(props) 42 print "Capabilities" 43 print " Manual sensor:", its.caps.manual_sensor(props) 44 print " Manual post-proc:", its.caps.manual_post_proc(props) 45 print " Raw:", its.caps.raw(props) 46 print " Sensor fusion:", its.caps.sensor_fusion(props) 47 48 # Test: hardware level should be a valid value. 49 check('props.has_key("android.info.supportedHardwareLevel")') 50 check('props["android.info.supportedHardwareLevel"] is not None') 51 check('props["android.info.supportedHardwareLevel"] in [0,1,2,3]') 52 manual_sensor = its.caps.manual_sensor(props) 53 54 # Test: rollingShutterSkew, and frameDuration tags must all be present, 55 # and rollingShutterSkew must be greater than zero and smaller than all 56 # of the possible frame durations. 57 if manual_sensor: 58 check('md.has_key("android.sensor.frameDuration")') 59 check('md["android.sensor.frameDuration"] is not None') 60 check('md.has_key("android.sensor.rollingShutterSkew")') 61 check('md["android.sensor.rollingShutterSkew"] is not None') 62 if manual_sensor: 63 check('md["android.sensor.frameDuration"] > ' 64 'md["android.sensor.rollingShutterSkew"] > 0') 65 66 # Test: timestampSource must be a valid value. 67 check('props.has_key("android.sensor.info.timestampSource")') 68 check('props["android.sensor.info.timestampSource"] is not None') 69 check('props["android.sensor.info.timestampSource"] in [0,1]') 70 71 # Test: croppingType must be a valid value, and for full devices, it 72 # must be FREEFORM=1. 73 check('props.has_key("android.scaler.croppingType")') 74 check('props["android.scaler.croppingType"] is not None') 75 check('props["android.scaler.croppingType"] in [0,1]') 76 77 # Test: android.sensor.blackLevelPattern exists for RAW and is not None 78 if its.caps.raw(props): 79 check('props.has_key("android.sensor.blackLevelPattern")') 80 check('props["android.sensor.blackLevelPattern"] is not None') 81 82 assert not failed 83 84 if not its.caps.legacy(props): 85 # Test: pixel_pitch, FOV, and hyperfocal distance are reasonable 86 fmts = props["android.scaler.streamConfigurationMap"]["availableStreamConfigurations"] 87 fmts = sorted(fmts, key=lambda k: k["width"]*k["height"], reverse=True) 88 sensor_size = props["android.sensor.info.physicalSize"] 89 pixel_pitch_h = (sensor_size["height"] / fmts[0]["height"] * 1E3) 90 pixel_pitch_w = (sensor_size["width"] / fmts[0]["width"] * 1E3) 91 print "Assert pixel_pitch WxH: %.2f um, %.2f um" % (pixel_pitch_w, 92 pixel_pitch_h) 93 assert 1.0 <= pixel_pitch_w <= 10 94 assert 1.0 <= pixel_pitch_h <= 10 95 assert 0.333 <= pixel_pitch_w/pixel_pitch_h <= 3.0 96 97 diag = math.sqrt(sensor_size["height"] ** 2 + 98 sensor_size["width"] ** 2) 99 fl = md["android.lens.focalLength"] 100 fov = 2 * math.degrees(math.atan(diag / (2 * fl))) 101 print "Assert field of view: %.1f degrees" % fov 102 assert 30 <= fov <= 130 103 104 if its.caps.lens_approx_calibrated(props): 105 diopter_hyperfocal = props["android.lens.info.hyperfocalDistance"] 106 if diopter_hyperfocal != 0.0: 107 hyperfocal = 1.0 / diopter_hyperfocal 108 print "Assert hyperfocal distance: %.2f m" % hyperfocal 109 assert 0.02 <= hyperfocal 110 111 112def getval(expr, default=None): 113 try: 114 return eval(expr) 115 except: 116 return default 117 118failed = False 119 120 121def check(expr): 122 global md, props, failed 123 try: 124 if eval(expr): 125 print "Passed>", expr 126 else: 127 print "Failed>>", expr 128 failed = True 129 except: 130 print "Failed>>", expr 131 failed = True 132 133if __name__ == '__main__': 134 main() 135 136