• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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    full = getval('props["android.info.supportedHardwareLevel"]') == 1
53    manual_sensor = its.caps.manual_sensor(props)
54
55    # Test: rollingShutterSkew, and frameDuration tags must all be present,
56    # and rollingShutterSkew must be greater than zero and smaller than all
57    # of the possible frame durations.
58    if manual_sensor:
59        check('md.has_key("android.sensor.frameDuration")')
60        check('md["android.sensor.frameDuration"] is not None')
61    check('md.has_key("android.sensor.rollingShutterSkew")')
62    check('md["android.sensor.rollingShutterSkew"] is not None')
63    if manual_sensor:
64        check('md["android.sensor.frameDuration"] > '
65              'md["android.sensor.rollingShutterSkew"] > 0')
66
67    # Test: timestampSource must be a valid value.
68    check('props.has_key("android.sensor.info.timestampSource")')
69    check('props["android.sensor.info.timestampSource"] is not None')
70    check('props["android.sensor.info.timestampSource"] in [0,1]')
71
72    # Test: croppingType must be a valid value, and for full devices, it
73    # must be FREEFORM=1.
74    check('props.has_key("android.scaler.croppingType")')
75    check('props["android.scaler.croppingType"] is not None')
76    check('props["android.scaler.croppingType"] in [0,1]')
77
78    assert(not failed)
79
80    if not its.caps.legacy(props):
81        # Test: pixel_pitch, FOV, and hyperfocal distance are reasonable
82        fmts = props["android.scaler.streamConfigurationMap"]["availableStreamConfigurations"]
83        fmts = sorted(fmts, key=lambda k: k["width"]*k["height"], reverse=True)
84        sensor_size = props["android.sensor.info.physicalSize"]
85        pixel_pitch_h = (sensor_size["height"] / fmts[0]["height"] * 1E3)
86        pixel_pitch_w = (sensor_size["width"] / fmts[0]["width"] * 1E3)
87        print "Assert pixel_pitch WxH: %.2f um, %.2f um" % (pixel_pitch_w,
88                                                            pixel_pitch_h)
89        assert 1.0 <= pixel_pitch_w <= 10
90        assert 1.0 <= pixel_pitch_h <= 10
91        assert 0.333 <= pixel_pitch_w/pixel_pitch_h <= 3.0
92
93        diag = math.sqrt(sensor_size["height"] ** 2 +
94                         sensor_size["width"] ** 2)
95        fl = md["android.lens.focalLength"]
96        fov = 2 * math.degrees(math.atan(diag / (2 * fl)))
97        print "Assert field of view: %.1f degrees" % fov
98        assert 30 <= fov <= 130
99
100        hyperfocal = 1.0 / props["android.lens.info.hyperfocalDistance"]
101        print "Assert hyperfocal distance: %.2f m" % hyperfocal
102        assert 0.02 <= hyperfocal
103
104
105def getval(expr, default=None):
106    try:
107        return eval(expr)
108    except:
109        return default
110
111failed = False
112
113
114def check(expr):
115    global md, props, failed
116    try:
117        if eval(expr):
118            print "Passed>", expr
119        else:
120            print "Failed>>", expr
121            failed = True
122    except:
123        print "Failed>>", expr
124        failed = True
125
126if __name__ == '__main__':
127    main()
128
129