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 props = cam.override_with_hidden_physical_camera_props(props) 35 its.caps.skip_unless(its.caps.backward_compatible(props)) 36 auto_req = its.objects.auto_capture_request() 37 cap = cam.do_capture(auto_req) 38 md = cap["metadata"] 39 40 print "Hardware level" 41 print " Legacy:", its.caps.legacy(props) 42 print " Limited:", its.caps.limited(props) 43 print " Full or better:", its.caps.full_or_better(props) 44 print "Capabilities" 45 print " Manual sensor:", its.caps.manual_sensor(props) 46 print " Manual post-proc:", its.caps.manual_post_proc(props) 47 print " Raw:", its.caps.raw(props) 48 print " Sensor fusion:", its.caps.sensor_fusion(props) 49 50 # Test: hardware level should be a valid value. 51 check('props.has_key("android.info.supportedHardwareLevel")') 52 check('props["android.info.supportedHardwareLevel"] is not None') 53 check('props["android.info.supportedHardwareLevel"] in [0,1,2,3]') 54 manual_sensor = its.caps.manual_sensor(props) 55 56 # Test: rollingShutterSkew, and frameDuration tags must all be present, 57 # and rollingShutterSkew must be greater than zero and smaller than all 58 # of the possible frame durations. 59 if manual_sensor: 60 check('md.has_key("android.sensor.frameDuration")') 61 check('md["android.sensor.frameDuration"] is not None') 62 check('md.has_key("android.sensor.rollingShutterSkew")') 63 check('md["android.sensor.rollingShutterSkew"] is not None') 64 if manual_sensor: 65 check('md["android.sensor.rollingShutterSkew"] > 0') 66 check('md["android.sensor.frameDuration"] > 0') 67 68 # Test: timestampSource must be a valid value. 69 check('props.has_key("android.sensor.info.timestampSource")') 70 check('props["android.sensor.info.timestampSource"] is not None') 71 check('props["android.sensor.info.timestampSource"] in [0,1]') 72 73 # Test: croppingType must be a valid value, and for full devices, it 74 # must be FREEFORM=1. 75 check('props.has_key("android.scaler.croppingType")') 76 check('props["android.scaler.croppingType"] is not None') 77 check('props["android.scaler.croppingType"] in [0,1]') 78 79 # Test: android.sensor.blackLevelPattern exists for RAW and is not None 80 if its.caps.raw(props): 81 check('props.has_key("android.sensor.blackLevelPattern")') 82 check('props["android.sensor.blackLevelPattern"] is not None') 83 84 assert not failed 85 86 if not its.caps.legacy(props): 87 # Test: pixel_pitch, FOV, and hyperfocal distance are reasonable 88 fmts = props["android.scaler.streamConfigurationMap"]["availableStreamConfigurations"] 89 fmts = sorted(fmts, key=lambda k: k["width"]*k["height"], reverse=True) 90 sensor_size = props["android.sensor.info.physicalSize"] 91 pixel_pitch_h = (sensor_size["height"] / fmts[0]["height"] * 1E3) 92 pixel_pitch_w = (sensor_size["width"] / fmts[0]["width"] * 1E3) 93 print "Assert pixel_pitch WxH: %.2f um, %.2f um" % (pixel_pitch_w, 94 pixel_pitch_h) 95 assert 0.7 <= pixel_pitch_w <= 10 96 assert 0.7 <= pixel_pitch_h <= 10 97 assert 0.333 <= pixel_pitch_w/pixel_pitch_h <= 3.0 98 99 diag = math.sqrt(sensor_size["height"] ** 2 + 100 sensor_size["width"] ** 2) 101 fl = md["android.lens.focalLength"] 102 fov = 2 * math.degrees(math.atan(diag / (2 * fl))) 103 print "Assert field of view: %.1f degrees" % fov 104 assert 10 <= fov <= 130 105 106 if its.caps.lens_approx_calibrated(props): 107 diopter_hyperfocal = props["android.lens.info.hyperfocalDistance"] 108 if diopter_hyperfocal != 0.0: 109 hyperfocal = 1.0 / diopter_hyperfocal 110 print "Assert hyperfocal distance: %.2f m" % hyperfocal 111 assert 0.02 <= hyperfocal 112 113 114def getval(expr, default=None): 115 try: 116 return eval(expr) 117 except: 118 return default 119 120failed = False 121 122 123def check(expr): 124 global md, props, failed 125 try: 126 if eval(expr): 127 print "Passed>", expr 128 else: 129 print "Failed>>", expr 130 failed = True 131 except: 132 print "Failed>>", expr 133 failed = True 134 135if __name__ == '__main__': 136 main() 137 138