xref: /aosp_15_r20/cts/apps/CameraITS/utils/capture_request_utils.py (revision b7c941bb3fa97aba169d73cee0bed2de8ac964bf)
1*b7c941bbSAndroid Build Coastguard Worker# Copyright 2013 The Android Open Source Project
2*b7c941bbSAndroid Build Coastguard Worker#
3*b7c941bbSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
4*b7c941bbSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
5*b7c941bbSAndroid Build Coastguard Worker# You may obtain a copy of the License at
6*b7c941bbSAndroid Build Coastguard Worker#
7*b7c941bbSAndroid Build Coastguard Worker#      http://www.apache.org/licenses/LICENSE-2.0
8*b7c941bbSAndroid Build Coastguard Worker#
9*b7c941bbSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*b7c941bbSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
11*b7c941bbSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*b7c941bbSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
13*b7c941bbSAndroid Build Coastguard Worker# limitations under the License.
14*b7c941bbSAndroid Build Coastguard Worker"""Utility functions to create custom capture requests."""
15*b7c941bbSAndroid Build Coastguard Worker
16*b7c941bbSAndroid Build Coastguard Worker
17*b7c941bbSAndroid Build Coastguard Workerimport error_util
18*b7c941bbSAndroid Build Coastguard Workerimport logging
19*b7c941bbSAndroid Build Coastguard Workerimport math
20*b7c941bbSAndroid Build Coastguard Worker
21*b7c941bbSAndroid Build Coastguard Worker_AE_MODE_OFF = 0
22*b7c941bbSAndroid Build Coastguard Worker_AE_MODE_ON_AUTO_FLASH = 2
23*b7c941bbSAndroid Build Coastguard Worker_AE_PRECAPTURE_TRIGGER_START = 1
24*b7c941bbSAndroid Build Coastguard Worker_AE_PRECAPTURE_TRIGGER_IDLE = 0
25*b7c941bbSAndroid Build Coastguard Worker_CAPTURE_INTENT_STILL_CAPTURE = 2
26*b7c941bbSAndroid Build Coastguard Worker_CAPTURE_INTENT_PREVIEW = 1
27*b7c941bbSAndroid Build Coastguard Worker_COMMON_IMG_ARS = (4/3, 16/9)
28*b7c941bbSAndroid Build Coastguard Worker_COMMON_IMG_ARS_ATOL = 0.01
29*b7c941bbSAndroid Build Coastguard Worker_FLASH_MODE_SINGLE = 1
30*b7c941bbSAndroid Build Coastguard WorkerFMT_CODE_JPEG = 0x100
31*b7c941bbSAndroid Build Coastguard WorkerFMT_CODE_JPEG_R = 0x1005
32*b7c941bbSAndroid Build Coastguard WorkerFMT_CODE_PRIV = 0x22
33*b7c941bbSAndroid Build Coastguard WorkerFMT_CODE_RAW = 0x20
34*b7c941bbSAndroid Build Coastguard WorkerFMT_CODE_RAW10 = 0x25
35*b7c941bbSAndroid Build Coastguard WorkerFMT_CODE_RAW12 = 0x26
36*b7c941bbSAndroid Build Coastguard WorkerFMT_CODE_YUV = 0x23  # YUV_420_888
37*b7c941bbSAndroid Build Coastguard WorkerFMT_CODE_Y8 = 0x20203859
38*b7c941bbSAndroid Build Coastguard Worker_MAX_YUV_SIZE = (1920, 1080)
39*b7c941bbSAndroid Build Coastguard Worker_MIN_YUV_SIZE = (640, 360)
40*b7c941bbSAndroid Build Coastguard Worker_STATIONARY_LENS_NUM_TRIES = 2  # num of tries to wait for stationary lens
41*b7c941bbSAndroid Build Coastguard Worker_STATIONARY_LENS_NUM_FRAMES = 4  # num of frames to capture for stationay lens
42*b7c941bbSAndroid Build Coastguard Worker_STATIONARY_LENS_STATE = 0
43*b7c941bbSAndroid Build Coastguard Worker_VGA_W, _VGA_H = (640, 480)
44*b7c941bbSAndroid Build Coastguard Worker
45*b7c941bbSAndroid Build Coastguard Worker
46*b7c941bbSAndroid Build Coastguard Workerdef stationary_lens_capture(
47*b7c941bbSAndroid Build Coastguard Worker    cam, req, fmt,
48*b7c941bbSAndroid Build Coastguard Worker    num_frames=_STATIONARY_LENS_NUM_FRAMES,
49*b7c941bbSAndroid Build Coastguard Worker    num_tries=_STATIONARY_LENS_NUM_TRIES):
50*b7c941bbSAndroid Build Coastguard Worker  """Take up to num_tries caps with num_frames & save when lens stationary.
51*b7c941bbSAndroid Build Coastguard Worker
52*b7c941bbSAndroid Build Coastguard Worker  Args:
53*b7c941bbSAndroid Build Coastguard Worker   cam: open device session.
54*b7c941bbSAndroid Build Coastguard Worker   req: capture request.
55*b7c941bbSAndroid Build Coastguard Worker   fmt: format dictionary for capture.
56*b7c941bbSAndroid Build Coastguard Worker   num_frames: int; number of frames per capture.
57*b7c941bbSAndroid Build Coastguard Worker   num_tries: int; number of tries to get lens stationary capture.
58*b7c941bbSAndroid Build Coastguard Worker
59*b7c941bbSAndroid Build Coastguard Worker  Returns:
60*b7c941bbSAndroid Build Coastguard Worker    capture
61*b7c941bbSAndroid Build Coastguard Worker  """
62*b7c941bbSAndroid Build Coastguard Worker  tries = 0
63*b7c941bbSAndroid Build Coastguard Worker  done = False
64*b7c941bbSAndroid Build Coastguard Worker  while not done:
65*b7c941bbSAndroid Build Coastguard Worker    logging.debug('Waiting for lens to move to correct location.')
66*b7c941bbSAndroid Build Coastguard Worker    cap = cam.do_capture([req] * num_frames, fmt)
67*b7c941bbSAndroid Build Coastguard Worker    done = (cap[num_frames - 1]['metadata']['android.lens.state'] ==
68*b7c941bbSAndroid Build Coastguard Worker            _STATIONARY_LENS_STATE)
69*b7c941bbSAndroid Build Coastguard Worker    logging.debug('lens stationary status: %s', done)
70*b7c941bbSAndroid Build Coastguard Worker    if tries == num_tries:
71*b7c941bbSAndroid Build Coastguard Worker      raise error_util.CameraItsError('Cannot settle lens after %d tries!' %
72*b7c941bbSAndroid Build Coastguard Worker                                      tries)
73*b7c941bbSAndroid Build Coastguard Worker    tries += 1
74*b7c941bbSAndroid Build Coastguard Worker  return cap[num_frames - 1]
75*b7c941bbSAndroid Build Coastguard Worker
76*b7c941bbSAndroid Build Coastguard Worker
77*b7c941bbSAndroid Build Coastguard Workerdef is_common_aspect_ratio(size):
78*b7c941bbSAndroid Build Coastguard Worker  """Returns if aspect ratio is a 4:3 or 16:9.
79*b7c941bbSAndroid Build Coastguard Worker
80*b7c941bbSAndroid Build Coastguard Worker  Args:
81*b7c941bbSAndroid Build Coastguard Worker    size: tuple of image (w, h)
82*b7c941bbSAndroid Build Coastguard Worker
83*b7c941bbSAndroid Build Coastguard Worker  Returns:
84*b7c941bbSAndroid Build Coastguard Worker    Boolean
85*b7c941bbSAndroid Build Coastguard Worker  """
86*b7c941bbSAndroid Build Coastguard Worker  for aspect_ratio in _COMMON_IMG_ARS:
87*b7c941bbSAndroid Build Coastguard Worker    if math.isclose(size[0]/size[1], aspect_ratio,
88*b7c941bbSAndroid Build Coastguard Worker                    abs_tol=_COMMON_IMG_ARS_ATOL):
89*b7c941bbSAndroid Build Coastguard Worker      return True
90*b7c941bbSAndroid Build Coastguard Worker  return False
91*b7c941bbSAndroid Build Coastguard Worker
92*b7c941bbSAndroid Build Coastguard Worker
93*b7c941bbSAndroid Build Coastguard Workerdef auto_capture_request(linear_tonemap=False, props=None, do_af=True,
94*b7c941bbSAndroid Build Coastguard Worker                         do_autoframing=False, zoom_ratio=None):
95*b7c941bbSAndroid Build Coastguard Worker  """Returns a capture request with everything set to auto.
96*b7c941bbSAndroid Build Coastguard Worker
97*b7c941bbSAndroid Build Coastguard Worker  Args:
98*b7c941bbSAndroid Build Coastguard Worker   linear_tonemap: [Optional] boolean whether linear tonemap should be used.
99*b7c941bbSAndroid Build Coastguard Worker   props: [Optional] object from its_session_utils.get_camera_properties().
100*b7c941bbSAndroid Build Coastguard Worker          Must present when linear_tonemap is True.
101*b7c941bbSAndroid Build Coastguard Worker   do_af: [Optional] boolean whether af mode should be active.
102*b7c941bbSAndroid Build Coastguard Worker   do_autoframing: [Optional] boolean whether autoframing should be active.
103*b7c941bbSAndroid Build Coastguard Worker   zoom_ratio: [Optional] zoom ratio to be set in the capture request.
104*b7c941bbSAndroid Build Coastguard Worker
105*b7c941bbSAndroid Build Coastguard Worker  Returns:
106*b7c941bbSAndroid Build Coastguard Worker    Auto capture request, ready to be passed to the
107*b7c941bbSAndroid Build Coastguard Worker    its_session_utils.device.do_capture()
108*b7c941bbSAndroid Build Coastguard Worker  """
109*b7c941bbSAndroid Build Coastguard Worker  req = {
110*b7c941bbSAndroid Build Coastguard Worker      'android.control.mode': 1,
111*b7c941bbSAndroid Build Coastguard Worker      'android.control.aeMode': 1,
112*b7c941bbSAndroid Build Coastguard Worker      'android.control.awbMode': 1,
113*b7c941bbSAndroid Build Coastguard Worker      'android.control.afMode': 1 if do_af else 0,
114*b7c941bbSAndroid Build Coastguard Worker      'android.colorCorrection.mode': 1,
115*b7c941bbSAndroid Build Coastguard Worker      'android.shading.mode': 1,
116*b7c941bbSAndroid Build Coastguard Worker      'android.tonemap.mode': 1,
117*b7c941bbSAndroid Build Coastguard Worker      'android.lens.opticalStabilizationMode': 0,
118*b7c941bbSAndroid Build Coastguard Worker      'android.control.videoStabilizationMode': 0,
119*b7c941bbSAndroid Build Coastguard Worker  }
120*b7c941bbSAndroid Build Coastguard Worker  if do_autoframing:
121*b7c941bbSAndroid Build Coastguard Worker    req['android.control.autoframing'] = 1
122*b7c941bbSAndroid Build Coastguard Worker  if not do_af:
123*b7c941bbSAndroid Build Coastguard Worker    req['android.lens.focusDistance'] = 0.0
124*b7c941bbSAndroid Build Coastguard Worker  if zoom_ratio:
125*b7c941bbSAndroid Build Coastguard Worker    req['android.control.zoomRatio'] = zoom_ratio
126*b7c941bbSAndroid Build Coastguard Worker  if linear_tonemap:
127*b7c941bbSAndroid Build Coastguard Worker    if props is None:
128*b7c941bbSAndroid Build Coastguard Worker      raise AssertionError('props is None with linear_tonemap.')
129*b7c941bbSAndroid Build Coastguard Worker    # CONTRAST_CURVE mode
130*b7c941bbSAndroid Build Coastguard Worker    if 0 in props['android.tonemap.availableToneMapModes']:
131*b7c941bbSAndroid Build Coastguard Worker      logging.debug('CONTRAST_CURVE tonemap mode')
132*b7c941bbSAndroid Build Coastguard Worker      req['android.tonemap.mode'] = 0
133*b7c941bbSAndroid Build Coastguard Worker      req['android.tonemap.curve'] = {
134*b7c941bbSAndroid Build Coastguard Worker          'red': [0.0, 0.0, 1.0, 1.0],  # coordinate pairs: x0, y0, x1, y1
135*b7c941bbSAndroid Build Coastguard Worker          'green': [0.0, 0.0, 1.0, 1.0],
136*b7c941bbSAndroid Build Coastguard Worker          'blue': [0.0, 0.0, 1.0, 1.0]
137*b7c941bbSAndroid Build Coastguard Worker      }
138*b7c941bbSAndroid Build Coastguard Worker    # GAMMA_VALUE mode
139*b7c941bbSAndroid Build Coastguard Worker    elif 3 in props['android.tonemap.availableToneMapModes']:
140*b7c941bbSAndroid Build Coastguard Worker      logging.debug('GAMMA_VALUE tonemap mode')
141*b7c941bbSAndroid Build Coastguard Worker      req['android.tonemap.mode'] = 3
142*b7c941bbSAndroid Build Coastguard Worker      req['android.tonemap.gamma'] = 1.0
143*b7c941bbSAndroid Build Coastguard Worker    else:
144*b7c941bbSAndroid Build Coastguard Worker      raise AssertionError('Linear tonemap is not supported')
145*b7c941bbSAndroid Build Coastguard Worker  return req
146*b7c941bbSAndroid Build Coastguard Worker
147*b7c941bbSAndroid Build Coastguard Worker
148*b7c941bbSAndroid Build Coastguard Workerdef manual_capture_request(sensitivity,
149*b7c941bbSAndroid Build Coastguard Worker                           exp_time,
150*b7c941bbSAndroid Build Coastguard Worker                           f_distance=0.0,
151*b7c941bbSAndroid Build Coastguard Worker                           linear_tonemap=False,
152*b7c941bbSAndroid Build Coastguard Worker                           props=None):
153*b7c941bbSAndroid Build Coastguard Worker  """Returns a capture request with everything set to manual.
154*b7c941bbSAndroid Build Coastguard Worker
155*b7c941bbSAndroid Build Coastguard Worker  Uses identity/unit color correction, and the default tonemap curve.
156*b7c941bbSAndroid Build Coastguard Worker  Optionally, the tonemap can be specified as being linear.
157*b7c941bbSAndroid Build Coastguard Worker
158*b7c941bbSAndroid Build Coastguard Worker  Args:
159*b7c941bbSAndroid Build Coastguard Worker   sensitivity: The sensitivity value to populate the request with.
160*b7c941bbSAndroid Build Coastguard Worker   exp_time: The exposure time, in nanoseconds, to populate the request with.
161*b7c941bbSAndroid Build Coastguard Worker   f_distance: The focus distance to populate the request with.
162*b7c941bbSAndroid Build Coastguard Worker   linear_tonemap: [Optional] whether a linear tonemap should be used in this
163*b7c941bbSAndroid Build Coastguard Worker     request.
164*b7c941bbSAndroid Build Coastguard Worker   props: [Optional] the object returned from
165*b7c941bbSAndroid Build Coastguard Worker     its_session_utils.get_camera_properties(). Must present when linear_tonemap
166*b7c941bbSAndroid Build Coastguard Worker     is True.
167*b7c941bbSAndroid Build Coastguard Worker
168*b7c941bbSAndroid Build Coastguard Worker  Returns:
169*b7c941bbSAndroid Build Coastguard Worker    The default manual capture request, ready to be passed to the
170*b7c941bbSAndroid Build Coastguard Worker    its_session_utils.device.do_capture function.
171*b7c941bbSAndroid Build Coastguard Worker  """
172*b7c941bbSAndroid Build Coastguard Worker  req = {
173*b7c941bbSAndroid Build Coastguard Worker      'android.control.captureIntent': 6,
174*b7c941bbSAndroid Build Coastguard Worker      'android.control.mode': 0,
175*b7c941bbSAndroid Build Coastguard Worker      'android.control.aeMode': 0,
176*b7c941bbSAndroid Build Coastguard Worker      'android.control.awbMode': 0,
177*b7c941bbSAndroid Build Coastguard Worker      'android.control.afMode': 0,
178*b7c941bbSAndroid Build Coastguard Worker      'android.control.effectMode': 0,
179*b7c941bbSAndroid Build Coastguard Worker      'android.sensor.sensitivity': sensitivity,
180*b7c941bbSAndroid Build Coastguard Worker      'android.sensor.exposureTime': exp_time,
181*b7c941bbSAndroid Build Coastguard Worker      'android.colorCorrection.mode': 0,
182*b7c941bbSAndroid Build Coastguard Worker      'android.colorCorrection.transform':
183*b7c941bbSAndroid Build Coastguard Worker          int_to_rational([1, 0, 0, 0, 1, 0, 0, 0, 1]),
184*b7c941bbSAndroid Build Coastguard Worker      'android.colorCorrection.gains': [1, 1, 1, 1],
185*b7c941bbSAndroid Build Coastguard Worker      'android.lens.focusDistance': f_distance,
186*b7c941bbSAndroid Build Coastguard Worker      'android.tonemap.mode': 1,
187*b7c941bbSAndroid Build Coastguard Worker      'android.shading.mode': 1,
188*b7c941bbSAndroid Build Coastguard Worker      'android.lens.opticalStabilizationMode': 0,
189*b7c941bbSAndroid Build Coastguard Worker      'android.control.videoStabilizationMode': 0,
190*b7c941bbSAndroid Build Coastguard Worker  }
191*b7c941bbSAndroid Build Coastguard Worker  if linear_tonemap:
192*b7c941bbSAndroid Build Coastguard Worker    if props is None:
193*b7c941bbSAndroid Build Coastguard Worker      raise AssertionError('props is None.')
194*b7c941bbSAndroid Build Coastguard Worker    # CONTRAST_CURVE mode
195*b7c941bbSAndroid Build Coastguard Worker    if 0 in props['android.tonemap.availableToneMapModes']:
196*b7c941bbSAndroid Build Coastguard Worker      logging.debug('CONTRAST_CURVE tonemap mode')
197*b7c941bbSAndroid Build Coastguard Worker      req['android.tonemap.mode'] = 0
198*b7c941bbSAndroid Build Coastguard Worker      req['android.tonemap.curve'] = {
199*b7c941bbSAndroid Build Coastguard Worker          'red': [0.0, 0.0, 1.0, 1.0],
200*b7c941bbSAndroid Build Coastguard Worker          'green': [0.0, 0.0, 1.0, 1.0],
201*b7c941bbSAndroid Build Coastguard Worker          'blue': [0.0, 0.0, 1.0, 1.0]
202*b7c941bbSAndroid Build Coastguard Worker      }
203*b7c941bbSAndroid Build Coastguard Worker    # GAMMA_VALUE mode
204*b7c941bbSAndroid Build Coastguard Worker    elif 3 in props['android.tonemap.availableToneMapModes']:
205*b7c941bbSAndroid Build Coastguard Worker      logging.debug('GAMMA_VALUE tonemap mode')
206*b7c941bbSAndroid Build Coastguard Worker      req['android.tonemap.mode'] = 3
207*b7c941bbSAndroid Build Coastguard Worker      req['android.tonemap.gamma'] = 1.0
208*b7c941bbSAndroid Build Coastguard Worker    else:
209*b7c941bbSAndroid Build Coastguard Worker      raise AssertionError('Linear tonemap is not supported')
210*b7c941bbSAndroid Build Coastguard Worker  return req
211*b7c941bbSAndroid Build Coastguard Worker
212*b7c941bbSAndroid Build Coastguard Worker
213*b7c941bbSAndroid Build Coastguard Workerdef get_available_output_sizes(fmt, props, max_size=None, match_ar_size=None):
214*b7c941bbSAndroid Build Coastguard Worker  """Return a sorted list of available output sizes for a given format.
215*b7c941bbSAndroid Build Coastguard Worker
216*b7c941bbSAndroid Build Coastguard Worker  Args:
217*b7c941bbSAndroid Build Coastguard Worker   fmt: the output format, as a string in ['jpg', 'yuv', 'raw', 'raw10',
218*b7c941bbSAndroid Build Coastguard Worker     'raw12', 'y8'].
219*b7c941bbSAndroid Build Coastguard Worker   props: the object returned from its_session_utils.get_camera_properties().
220*b7c941bbSAndroid Build Coastguard Worker   max_size: (Optional) A (w,h) tuple.Sizes larger than max_size (either w or h)
221*b7c941bbSAndroid Build Coastguard Worker     will be discarded.
222*b7c941bbSAndroid Build Coastguard Worker   match_ar_size: (Optional) A (w,h) tuple.Sizes not matching the aspect ratio
223*b7c941bbSAndroid Build Coastguard Worker     of match_ar_size will be discarded.
224*b7c941bbSAndroid Build Coastguard Worker
225*b7c941bbSAndroid Build Coastguard Worker  Returns:
226*b7c941bbSAndroid Build Coastguard Worker    A sorted list of (w,h) tuples (sorted large-to-small).
227*b7c941bbSAndroid Build Coastguard Worker  """
228*b7c941bbSAndroid Build Coastguard Worker  ar_tolerance = 0.03
229*b7c941bbSAndroid Build Coastguard Worker  fmt_codes = {
230*b7c941bbSAndroid Build Coastguard Worker      'raw': FMT_CODE_RAW,
231*b7c941bbSAndroid Build Coastguard Worker      'raw10': FMT_CODE_RAW10,
232*b7c941bbSAndroid Build Coastguard Worker      'raw12': FMT_CODE_RAW12,
233*b7c941bbSAndroid Build Coastguard Worker      'yuv': FMT_CODE_YUV,
234*b7c941bbSAndroid Build Coastguard Worker      'jpg': FMT_CODE_JPEG,
235*b7c941bbSAndroid Build Coastguard Worker      'jpeg': FMT_CODE_JPEG,
236*b7c941bbSAndroid Build Coastguard Worker      'jpeg_r': FMT_CODE_JPEG_R,
237*b7c941bbSAndroid Build Coastguard Worker      'priv': FMT_CODE_PRIV,
238*b7c941bbSAndroid Build Coastguard Worker      'y8': FMT_CODE_Y8
239*b7c941bbSAndroid Build Coastguard Worker  }
240*b7c941bbSAndroid Build Coastguard Worker  configs = props[
241*b7c941bbSAndroid Build Coastguard Worker      'android.scaler.streamConfigurationMap']['availableStreamConfigurations']
242*b7c941bbSAndroid Build Coastguard Worker  fmt_configs = [cfg for cfg in configs if cfg['format'] == fmt_codes[fmt]]
243*b7c941bbSAndroid Build Coastguard Worker  out_configs = [cfg for cfg in fmt_configs if not cfg['input']]
244*b7c941bbSAndroid Build Coastguard Worker  out_sizes = [(cfg['width'], cfg['height']) for cfg in out_configs]
245*b7c941bbSAndroid Build Coastguard Worker  if max_size:
246*b7c941bbSAndroid Build Coastguard Worker    max_size = [int(i) for i in max_size]
247*b7c941bbSAndroid Build Coastguard Worker    out_sizes = [
248*b7c941bbSAndroid Build Coastguard Worker        s for s in out_sizes if s[0] <= max_size[0] and s[1] <= max_size[1]
249*b7c941bbSAndroid Build Coastguard Worker    ]
250*b7c941bbSAndroid Build Coastguard Worker  if match_ar_size:
251*b7c941bbSAndroid Build Coastguard Worker    ar = match_ar_size[0] / match_ar_size[1]
252*b7c941bbSAndroid Build Coastguard Worker    out_sizes = [
253*b7c941bbSAndroid Build Coastguard Worker        s for s in out_sizes if abs(ar - s[0] / float(s[1])) <= ar_tolerance
254*b7c941bbSAndroid Build Coastguard Worker    ]
255*b7c941bbSAndroid Build Coastguard Worker  out_sizes.sort(reverse=True, key=lambda s: s[0])  # 1st pass, sort by width
256*b7c941bbSAndroid Build Coastguard Worker  out_sizes.sort(reverse=True, key=lambda s: s[0] * s[1])  # sort by area
257*b7c941bbSAndroid Build Coastguard Worker  logging.debug('Available %s output sizes: %s', fmt, out_sizes)
258*b7c941bbSAndroid Build Coastguard Worker  return out_sizes
259*b7c941bbSAndroid Build Coastguard Worker
260*b7c941bbSAndroid Build Coastguard Worker
261*b7c941bbSAndroid Build Coastguard Workerdef float_to_rational(f, denom=128):
262*b7c941bbSAndroid Build Coastguard Worker  """Function to convert Python floats to Camera2 rationals.
263*b7c941bbSAndroid Build Coastguard Worker
264*b7c941bbSAndroid Build Coastguard Worker  Args:
265*b7c941bbSAndroid Build Coastguard Worker    f: python float or list of floats.
266*b7c941bbSAndroid Build Coastguard Worker    denom: (Optional) the denominator to use in the output rationals.
267*b7c941bbSAndroid Build Coastguard Worker
268*b7c941bbSAndroid Build Coastguard Worker  Returns:
269*b7c941bbSAndroid Build Coastguard Worker    Python dictionary or list of dictionaries representing the given
270*b7c941bbSAndroid Build Coastguard Worker    float(s) as rationals.
271*b7c941bbSAndroid Build Coastguard Worker  """
272*b7c941bbSAndroid Build Coastguard Worker  if isinstance(f, list):
273*b7c941bbSAndroid Build Coastguard Worker    return [{'numerator': math.floor(val*denom+0.5), 'denominator': denom}
274*b7c941bbSAndroid Build Coastguard Worker            for val in f]
275*b7c941bbSAndroid Build Coastguard Worker  else:
276*b7c941bbSAndroid Build Coastguard Worker    return {'numerator': math.floor(f*denom+0.5), 'denominator': denom}
277*b7c941bbSAndroid Build Coastguard Worker
278*b7c941bbSAndroid Build Coastguard Worker
279*b7c941bbSAndroid Build Coastguard Workerdef rational_to_float(r):
280*b7c941bbSAndroid Build Coastguard Worker  """Function to convert Camera2 rational objects to Python floats.
281*b7c941bbSAndroid Build Coastguard Worker
282*b7c941bbSAndroid Build Coastguard Worker  Args:
283*b7c941bbSAndroid Build Coastguard Worker   r: Rational or list of rationals, as Python dictionaries.
284*b7c941bbSAndroid Build Coastguard Worker
285*b7c941bbSAndroid Build Coastguard Worker  Returns:
286*b7c941bbSAndroid Build Coastguard Worker   Float or list of floats.
287*b7c941bbSAndroid Build Coastguard Worker  """
288*b7c941bbSAndroid Build Coastguard Worker  if isinstance(r, list):
289*b7c941bbSAndroid Build Coastguard Worker    return [float(val['numerator']) / float(val['denominator']) for val in r]
290*b7c941bbSAndroid Build Coastguard Worker  else:
291*b7c941bbSAndroid Build Coastguard Worker    return float(r['numerator']) / float(r['denominator'])
292*b7c941bbSAndroid Build Coastguard Worker
293*b7c941bbSAndroid Build Coastguard Worker
294*b7c941bbSAndroid Build Coastguard Workerdef get_fastest_manual_capture_settings(props):
295*b7c941bbSAndroid Build Coastguard Worker  """Returns a capture request and format spec for the fastest manual capture.
296*b7c941bbSAndroid Build Coastguard Worker
297*b7c941bbSAndroid Build Coastguard Worker  Args:
298*b7c941bbSAndroid Build Coastguard Worker     props: the object returned from its_session_utils.get_camera_properties().
299*b7c941bbSAndroid Build Coastguard Worker
300*b7c941bbSAndroid Build Coastguard Worker  Returns:
301*b7c941bbSAndroid Build Coastguard Worker    Two values, the first is a capture request, and the second is an output
302*b7c941bbSAndroid Build Coastguard Worker    format specification, for the fastest possible (legal) capture that
303*b7c941bbSAndroid Build Coastguard Worker    can be performed on this device (with the smallest output size).
304*b7c941bbSAndroid Build Coastguard Worker  """
305*b7c941bbSAndroid Build Coastguard Worker  fmt = 'yuv'
306*b7c941bbSAndroid Build Coastguard Worker  size = get_available_output_sizes(fmt, props)[-1]
307*b7c941bbSAndroid Build Coastguard Worker  out_spec = {'format': fmt, 'width': size[0], 'height': size[1]}
308*b7c941bbSAndroid Build Coastguard Worker  s = min(props['android.sensor.info.sensitivityRange'])
309*b7c941bbSAndroid Build Coastguard Worker  e = min(props['android.sensor.info.exposureTimeRange'])
310*b7c941bbSAndroid Build Coastguard Worker  req = manual_capture_request(s, e)
311*b7c941bbSAndroid Build Coastguard Worker
312*b7c941bbSAndroid Build Coastguard Worker  turn_slow_filters_off(props, req)
313*b7c941bbSAndroid Build Coastguard Worker
314*b7c941bbSAndroid Build Coastguard Worker  return req, out_spec
315*b7c941bbSAndroid Build Coastguard Worker
316*b7c941bbSAndroid Build Coastguard Worker
317*b7c941bbSAndroid Build Coastguard Workerdef get_fastest_auto_capture_settings(props):
318*b7c941bbSAndroid Build Coastguard Worker  """Returns a capture request and format spec for the fastest auto capture.
319*b7c941bbSAndroid Build Coastguard Worker
320*b7c941bbSAndroid Build Coastguard Worker  Args:
321*b7c941bbSAndroid Build Coastguard Worker     props: the object returned from its_session_utils.get_camera_properties().
322*b7c941bbSAndroid Build Coastguard Worker
323*b7c941bbSAndroid Build Coastguard Worker  Returns:
324*b7c941bbSAndroid Build Coastguard Worker      Two values, the first is a capture request, and the second is an output
325*b7c941bbSAndroid Build Coastguard Worker      format specification, for the fastest possible (legal) capture that
326*b7c941bbSAndroid Build Coastguard Worker      can be performed on this device (with the smallest output size).
327*b7c941bbSAndroid Build Coastguard Worker  """
328*b7c941bbSAndroid Build Coastguard Worker  fmt = 'yuv'
329*b7c941bbSAndroid Build Coastguard Worker  size = get_available_output_sizes(fmt, props)[-1]
330*b7c941bbSAndroid Build Coastguard Worker  out_spec = {'format': fmt, 'width': size[0], 'height': size[1]}
331*b7c941bbSAndroid Build Coastguard Worker  req = auto_capture_request()
332*b7c941bbSAndroid Build Coastguard Worker
333*b7c941bbSAndroid Build Coastguard Worker  turn_slow_filters_off(props, req)
334*b7c941bbSAndroid Build Coastguard Worker
335*b7c941bbSAndroid Build Coastguard Worker  return req, out_spec
336*b7c941bbSAndroid Build Coastguard Worker
337*b7c941bbSAndroid Build Coastguard Worker
338*b7c941bbSAndroid Build Coastguard Workerdef fastest_auto_capture_request(props):
339*b7c941bbSAndroid Build Coastguard Worker  """Return an auto capture request for the fastest capture.
340*b7c941bbSAndroid Build Coastguard Worker
341*b7c941bbSAndroid Build Coastguard Worker  Args:
342*b7c941bbSAndroid Build Coastguard Worker    props: the object returned from its.device.get_camera_properties().
343*b7c941bbSAndroid Build Coastguard Worker
344*b7c941bbSAndroid Build Coastguard Worker  Returns:
345*b7c941bbSAndroid Build Coastguard Worker    A capture request with everything set to auto and all filters that
346*b7c941bbSAndroid Build Coastguard Worker    may slow down capture set to OFF or FAST if possible
347*b7c941bbSAndroid Build Coastguard Worker  """
348*b7c941bbSAndroid Build Coastguard Worker  req = auto_capture_request()
349*b7c941bbSAndroid Build Coastguard Worker  turn_slow_filters_off(props, req)
350*b7c941bbSAndroid Build Coastguard Worker  return req
351*b7c941bbSAndroid Build Coastguard Worker
352*b7c941bbSAndroid Build Coastguard Worker
353*b7c941bbSAndroid Build Coastguard Workerdef turn_slow_filters_off(props, req):
354*b7c941bbSAndroid Build Coastguard Worker  """Turn filters that may slow FPS down to OFF or FAST in input request.
355*b7c941bbSAndroid Build Coastguard Worker
356*b7c941bbSAndroid Build Coastguard Worker   This function modifies the request argument, such that filters that may
357*b7c941bbSAndroid Build Coastguard Worker   reduce the frames-per-second throughput of the camera device will be set to
358*b7c941bbSAndroid Build Coastguard Worker   OFF or FAST if possible.
359*b7c941bbSAndroid Build Coastguard Worker
360*b7c941bbSAndroid Build Coastguard Worker  Args:
361*b7c941bbSAndroid Build Coastguard Worker    props: the object returned from its_session_utils.get_camera_properties().
362*b7c941bbSAndroid Build Coastguard Worker    req: the input request.
363*b7c941bbSAndroid Build Coastguard Worker
364*b7c941bbSAndroid Build Coastguard Worker  Returns:
365*b7c941bbSAndroid Build Coastguard Worker    Nothing.
366*b7c941bbSAndroid Build Coastguard Worker  """
367*b7c941bbSAndroid Build Coastguard Worker  set_filter_off_or_fast_if_possible(
368*b7c941bbSAndroid Build Coastguard Worker      props, req, 'android.noiseReduction.availableNoiseReductionModes',
369*b7c941bbSAndroid Build Coastguard Worker      'android.noiseReduction.mode')
370*b7c941bbSAndroid Build Coastguard Worker  set_filter_off_or_fast_if_possible(
371*b7c941bbSAndroid Build Coastguard Worker      props, req, 'android.colorCorrection.availableAberrationModes',
372*b7c941bbSAndroid Build Coastguard Worker      'android.colorCorrection.aberrationMode')
373*b7c941bbSAndroid Build Coastguard Worker  if 'camera.characteristics.keys' in props:
374*b7c941bbSAndroid Build Coastguard Worker    chars_keys = props['camera.characteristics.keys']
375*b7c941bbSAndroid Build Coastguard Worker    hot_pixel_modes = 'android.hotPixel.availableHotPixelModes' in chars_keys
376*b7c941bbSAndroid Build Coastguard Worker    edge_modes = 'android.edge.availableEdgeModes' in chars_keys
377*b7c941bbSAndroid Build Coastguard Worker  if 'camera.characteristics.requestKeys' in props:
378*b7c941bbSAndroid Build Coastguard Worker    req_keys = props['camera.characteristics.requestKeys']
379*b7c941bbSAndroid Build Coastguard Worker    hot_pixel_mode = 'android.hotPixel.mode' in req_keys
380*b7c941bbSAndroid Build Coastguard Worker    edge_mode = 'android.edge.mode' in req_keys
381*b7c941bbSAndroid Build Coastguard Worker  if hot_pixel_modes and hot_pixel_mode:
382*b7c941bbSAndroid Build Coastguard Worker    set_filter_off_or_fast_if_possible(
383*b7c941bbSAndroid Build Coastguard Worker        props, req, 'android.hotPixel.availableHotPixelModes',
384*b7c941bbSAndroid Build Coastguard Worker        'android.hotPixel.mode')
385*b7c941bbSAndroid Build Coastguard Worker  if edge_modes and edge_mode:
386*b7c941bbSAndroid Build Coastguard Worker    set_filter_off_or_fast_if_possible(props, req,
387*b7c941bbSAndroid Build Coastguard Worker                                       'android.edge.availableEdgeModes',
388*b7c941bbSAndroid Build Coastguard Worker                                       'android.edge.mode')
389*b7c941bbSAndroid Build Coastguard Worker
390*b7c941bbSAndroid Build Coastguard Worker
391*b7c941bbSAndroid Build Coastguard Workerdef set_filter_off_or_fast_if_possible(props, req, available_modes, filter_key):
392*b7c941bbSAndroid Build Coastguard Worker  """Check and set controlKey to off or fast in req.
393*b7c941bbSAndroid Build Coastguard Worker
394*b7c941bbSAndroid Build Coastguard Worker  Args:
395*b7c941bbSAndroid Build Coastguard Worker    props: the object returned from its.device.get_camera_properties().
396*b7c941bbSAndroid Build Coastguard Worker    req: the input request. filter will be set to OFF or FAST if possible.
397*b7c941bbSAndroid Build Coastguard Worker    available_modes: the key to check available modes.
398*b7c941bbSAndroid Build Coastguard Worker    filter_key: the filter key
399*b7c941bbSAndroid Build Coastguard Worker
400*b7c941bbSAndroid Build Coastguard Worker  Returns:
401*b7c941bbSAndroid Build Coastguard Worker    Nothing.
402*b7c941bbSAndroid Build Coastguard Worker  """
403*b7c941bbSAndroid Build Coastguard Worker  if available_modes in props:
404*b7c941bbSAndroid Build Coastguard Worker    if 0 in props[available_modes]:
405*b7c941bbSAndroid Build Coastguard Worker      req[filter_key] = 0
406*b7c941bbSAndroid Build Coastguard Worker    elif 1 in props[available_modes]:
407*b7c941bbSAndroid Build Coastguard Worker      req[filter_key] = 1
408*b7c941bbSAndroid Build Coastguard Worker
409*b7c941bbSAndroid Build Coastguard Worker
410*b7c941bbSAndroid Build Coastguard Workerdef int_to_rational(i):
411*b7c941bbSAndroid Build Coastguard Worker  """Function to convert Python integers to Camera2 rationals.
412*b7c941bbSAndroid Build Coastguard Worker
413*b7c941bbSAndroid Build Coastguard Worker  Args:
414*b7c941bbSAndroid Build Coastguard Worker   i: Python integer or list of integers.
415*b7c941bbSAndroid Build Coastguard Worker
416*b7c941bbSAndroid Build Coastguard Worker  Returns:
417*b7c941bbSAndroid Build Coastguard Worker    Python dictionary or list of dictionaries representing the given int(s)
418*b7c941bbSAndroid Build Coastguard Worker    as rationals with denominator=1.
419*b7c941bbSAndroid Build Coastguard Worker  """
420*b7c941bbSAndroid Build Coastguard Worker  if isinstance(i, list):
421*b7c941bbSAndroid Build Coastguard Worker    return [{'numerator': val, 'denominator': 1} for val in i]
422*b7c941bbSAndroid Build Coastguard Worker  else:
423*b7c941bbSAndroid Build Coastguard Worker    return {'numerator': i, 'denominator': 1}
424*b7c941bbSAndroid Build Coastguard Worker
425*b7c941bbSAndroid Build Coastguard Worker
426*b7c941bbSAndroid Build Coastguard Workerdef get_smallest_yuv_format(props, match_ar=None):
427*b7c941bbSAndroid Build Coastguard Worker  """Return a capture request and format spec for the smallest yuv size.
428*b7c941bbSAndroid Build Coastguard Worker
429*b7c941bbSAndroid Build Coastguard Worker  Args:
430*b7c941bbSAndroid Build Coastguard Worker    props: object returned from camera_properties_utils.get_camera_properties().
431*b7c941bbSAndroid Build Coastguard Worker    match_ar: (Optional) a (w, h) tuple. Aspect ratio to match during search.
432*b7c941bbSAndroid Build Coastguard Worker
433*b7c941bbSAndroid Build Coastguard Worker  Returns:
434*b7c941bbSAndroid Build Coastguard Worker    fmt:   an output format specification for the smallest possible yuv format
435*b7c941bbSAndroid Build Coastguard Worker           for this device.
436*b7c941bbSAndroid Build Coastguard Worker  """
437*b7c941bbSAndroid Build Coastguard Worker  size = get_available_output_sizes('yuv', props, match_ar_size=match_ar)[-1]
438*b7c941bbSAndroid Build Coastguard Worker  fmt = {'format': 'yuv', 'width': size[0], 'height': size[1]}
439*b7c941bbSAndroid Build Coastguard Worker
440*b7c941bbSAndroid Build Coastguard Worker  return fmt
441*b7c941bbSAndroid Build Coastguard Worker
442*b7c941bbSAndroid Build Coastguard Worker
443*b7c941bbSAndroid Build Coastguard Workerdef get_near_vga_yuv_format(props, match_ar=None):
444*b7c941bbSAndroid Build Coastguard Worker  """Return a capture request and format spec for the smallest yuv size.
445*b7c941bbSAndroid Build Coastguard Worker
446*b7c941bbSAndroid Build Coastguard Worker  Args:
447*b7c941bbSAndroid Build Coastguard Worker    props: object returned from camera_properties_utils.get_camera_properties().
448*b7c941bbSAndroid Build Coastguard Worker    match_ar: (Optional) a (w, h) tuple. Aspect ratio to match during search.
449*b7c941bbSAndroid Build Coastguard Worker
450*b7c941bbSAndroid Build Coastguard Worker  Returns:
451*b7c941bbSAndroid Build Coastguard Worker    fmt: an output format specification for the smallest possible yuv format
452*b7c941bbSAndroid Build Coastguard Worker           for this device.
453*b7c941bbSAndroid Build Coastguard Worker  """
454*b7c941bbSAndroid Build Coastguard Worker  sizes = get_available_output_sizes('yuv', props, match_ar_size=match_ar)
455*b7c941bbSAndroid Build Coastguard Worker  logging.debug('Available YUV sizes: %s', sizes)
456*b7c941bbSAndroid Build Coastguard Worker  max_area = _MAX_YUV_SIZE[1] * _MAX_YUV_SIZE[0]
457*b7c941bbSAndroid Build Coastguard Worker  min_area = _MIN_YUV_SIZE[1] * _MIN_YUV_SIZE[0]
458*b7c941bbSAndroid Build Coastguard Worker
459*b7c941bbSAndroid Build Coastguard Worker  fmt = {'format': 'yuv', 'width': _VGA_W, 'height': _VGA_H}
460*b7c941bbSAndroid Build Coastguard Worker  for size in sizes:
461*b7c941bbSAndroid Build Coastguard Worker    fmt_area = size[0]*size[1]
462*b7c941bbSAndroid Build Coastguard Worker    if fmt_area < min_area or fmt_area > max_area:
463*b7c941bbSAndroid Build Coastguard Worker      continue
464*b7c941bbSAndroid Build Coastguard Worker    fmt['width'], fmt['height'] = size[0], size[1]
465*b7c941bbSAndroid Build Coastguard Worker  logging.debug('YUV format selected: %s', fmt)
466*b7c941bbSAndroid Build Coastguard Worker
467*b7c941bbSAndroid Build Coastguard Worker  return fmt
468*b7c941bbSAndroid Build Coastguard Worker
469*b7c941bbSAndroid Build Coastguard Worker
470*b7c941bbSAndroid Build Coastguard Workerdef get_largest_format(match_fmt, props, match_ar=None):
471*b7c941bbSAndroid Build Coastguard Worker  """Return a capture request and format spec for the largest match_fmt size.
472*b7c941bbSAndroid Build Coastguard Worker
473*b7c941bbSAndroid Build Coastguard Worker  Args:
474*b7c941bbSAndroid Build Coastguard Worker    match_fmt: str; 'yuv', 'jpeg', or 'raw'.
475*b7c941bbSAndroid Build Coastguard Worker    props: object returned from camera_properties_utils.get_camera_properties().
476*b7c941bbSAndroid Build Coastguard Worker    match_ar: (Optional) a (w, h) tuple. Aspect ratio to match during search.
477*b7c941bbSAndroid Build Coastguard Worker
478*b7c941bbSAndroid Build Coastguard Worker  Returns:
479*b7c941bbSAndroid Build Coastguard Worker    fmt:   an output format specification for the largest possible format
480*b7c941bbSAndroid Build Coastguard Worker           for this device of the type match_fmt.
481*b7c941bbSAndroid Build Coastguard Worker  """
482*b7c941bbSAndroid Build Coastguard Worker  size = get_available_output_sizes(match_fmt, props, match_ar_size=match_ar)[0]
483*b7c941bbSAndroid Build Coastguard Worker  fmt = {'format': match_fmt, 'width': size[0], 'height': size[1]}
484*b7c941bbSAndroid Build Coastguard Worker  logging.debug('format selected: %s', fmt)
485*b7c941bbSAndroid Build Coastguard Worker
486*b7c941bbSAndroid Build Coastguard Worker  return fmt
487*b7c941bbSAndroid Build Coastguard Worker
488*b7c941bbSAndroid Build Coastguard Worker
489*b7c941bbSAndroid Build Coastguard Workerdef get_max_digital_zoom(props):
490*b7c941bbSAndroid Build Coastguard Worker  """Returns the maximum amount of zooming possible by the camera device.
491*b7c941bbSAndroid Build Coastguard Worker
492*b7c941bbSAndroid Build Coastguard Worker  Args:
493*b7c941bbSAndroid Build Coastguard Worker    props: the object returned from its.device.get_camera_properties().
494*b7c941bbSAndroid Build Coastguard Worker
495*b7c941bbSAndroid Build Coastguard Worker  Return:
496*b7c941bbSAndroid Build Coastguard Worker    A float indicating the maximum amount of zoom possible by the camera device.
497*b7c941bbSAndroid Build Coastguard Worker  """
498*b7c941bbSAndroid Build Coastguard Worker
499*b7c941bbSAndroid Build Coastguard Worker  max_z = 1.0
500*b7c941bbSAndroid Build Coastguard Worker  if 'android.scaler.availableMaxDigitalZoom' in props:
501*b7c941bbSAndroid Build Coastguard Worker    max_z = props['android.scaler.availableMaxDigitalZoom']
502*b7c941bbSAndroid Build Coastguard Worker
503*b7c941bbSAndroid Build Coastguard Worker  return max_z
504*b7c941bbSAndroid Build Coastguard Worker
505*b7c941bbSAndroid Build Coastguard Worker
506*b7c941bbSAndroid Build Coastguard Workerdef take_captures_with_flash(cam, out_surface):
507*b7c941bbSAndroid Build Coastguard Worker  """Takes capture with auto flash ON.
508*b7c941bbSAndroid Build Coastguard Worker
509*b7c941bbSAndroid Build Coastguard Worker  Runs precapture sequence by setting the aePrecapture trigger to
510*b7c941bbSAndroid Build Coastguard Worker  START and capture intent set to Preview and then take the capture
511*b7c941bbSAndroid Build Coastguard Worker  with flash.
512*b7c941bbSAndroid Build Coastguard Worker  Args:
513*b7c941bbSAndroid Build Coastguard Worker    cam: ItsSession object
514*b7c941bbSAndroid Build Coastguard Worker    out_surface: Specifications of the output image format and
515*b7c941bbSAndroid Build Coastguard Worker      size to use for the capture.
516*b7c941bbSAndroid Build Coastguard Worker
517*b7c941bbSAndroid Build Coastguard Worker  Returns:
518*b7c941bbSAndroid Build Coastguard Worker    cap: An object which contains following fields:
519*b7c941bbSAndroid Build Coastguard Worker      * data: the image data as a numpy array of bytes.
520*b7c941bbSAndroid Build Coastguard Worker      * width: the width of the captured image.
521*b7c941bbSAndroid Build Coastguard Worker      * height: the height of the captured image.
522*b7c941bbSAndroid Build Coastguard Worker      * format: image format
523*b7c941bbSAndroid Build Coastguard Worker      * metadata: the capture result object
524*b7c941bbSAndroid Build Coastguard Worker  """
525*b7c941bbSAndroid Build Coastguard Worker
526*b7c941bbSAndroid Build Coastguard Worker  preview_req_start = auto_capture_request()
527*b7c941bbSAndroid Build Coastguard Worker  preview_req_start[
528*b7c941bbSAndroid Build Coastguard Worker      'android.control.aeMode'] = _AE_MODE_ON_AUTO_FLASH
529*b7c941bbSAndroid Build Coastguard Worker  preview_req_start[
530*b7c941bbSAndroid Build Coastguard Worker      'android.control.captureIntent'] = _CAPTURE_INTENT_PREVIEW
531*b7c941bbSAndroid Build Coastguard Worker  preview_req_start[
532*b7c941bbSAndroid Build Coastguard Worker      'android.control.aePrecaptureTrigger'] = _AE_PRECAPTURE_TRIGGER_START
533*b7c941bbSAndroid Build Coastguard Worker  # Repeat preview requests with aePrecapture set to IDLE
534*b7c941bbSAndroid Build Coastguard Worker  # until AE is converged.
535*b7c941bbSAndroid Build Coastguard Worker  preview_req_idle = auto_capture_request()
536*b7c941bbSAndroid Build Coastguard Worker  preview_req_idle[
537*b7c941bbSAndroid Build Coastguard Worker      'android.control.aeMode'] = _AE_MODE_ON_AUTO_FLASH
538*b7c941bbSAndroid Build Coastguard Worker  preview_req_idle[
539*b7c941bbSAndroid Build Coastguard Worker      'android.control.captureIntent'] = _CAPTURE_INTENT_PREVIEW
540*b7c941bbSAndroid Build Coastguard Worker  preview_req_idle[
541*b7c941bbSAndroid Build Coastguard Worker      'android.control.aePrecaptureTrigger'] = _AE_PRECAPTURE_TRIGGER_IDLE
542*b7c941bbSAndroid Build Coastguard Worker  # Single still capture request.
543*b7c941bbSAndroid Build Coastguard Worker  still_capture_req = auto_capture_request()
544*b7c941bbSAndroid Build Coastguard Worker  still_capture_req[
545*b7c941bbSAndroid Build Coastguard Worker      'android.control.aeMode'] = _AE_MODE_ON_AUTO_FLASH
546*b7c941bbSAndroid Build Coastguard Worker  still_capture_req[
547*b7c941bbSAndroid Build Coastguard Worker      'android.control.captureIntent'] = _CAPTURE_INTENT_STILL_CAPTURE
548*b7c941bbSAndroid Build Coastguard Worker  still_capture_req[
549*b7c941bbSAndroid Build Coastguard Worker      'android.control.aePrecaptureTrigger'] = _AE_PRECAPTURE_TRIGGER_IDLE
550*b7c941bbSAndroid Build Coastguard Worker  cap = cam.do_capture_with_flash(preview_req_start,
551*b7c941bbSAndroid Build Coastguard Worker                                  preview_req_idle,
552*b7c941bbSAndroid Build Coastguard Worker                                  still_capture_req, out_surface)
553*b7c941bbSAndroid Build Coastguard Worker  return cap
554*b7c941bbSAndroid Build Coastguard Worker
555*b7c941bbSAndroid Build Coastguard Worker
556*b7c941bbSAndroid Build Coastguard Workerdef take_captures_with_flash_strength(cam, out_surface, ae_mode, strength):
557*b7c941bbSAndroid Build Coastguard Worker  """Takes capture with desired flash strength.
558*b7c941bbSAndroid Build Coastguard Worker
559*b7c941bbSAndroid Build Coastguard Worker  Runs precapture sequence by setting the aePrecapture trigger to
560*b7c941bbSAndroid Build Coastguard Worker  START and capture intent set to Preview.
561*b7c941bbSAndroid Build Coastguard Worker  Then, take the capture with set flash strength.
562*b7c941bbSAndroid Build Coastguard Worker  Args:
563*b7c941bbSAndroid Build Coastguard Worker    cam: ItsSession object
564*b7c941bbSAndroid Build Coastguard Worker    out_surface: Specifications of the output image format and
565*b7c941bbSAndroid Build Coastguard Worker      size to use for the capture.
566*b7c941bbSAndroid Build Coastguard Worker    ae_mode: AE_mode
567*b7c941bbSAndroid Build Coastguard Worker    strength: flash strength
568*b7c941bbSAndroid Build Coastguard Worker
569*b7c941bbSAndroid Build Coastguard Worker  Returns:
570*b7c941bbSAndroid Build Coastguard Worker    cap: An object which contains following fields:
571*b7c941bbSAndroid Build Coastguard Worker      * data: the image data as a numpy array of bytes.
572*b7c941bbSAndroid Build Coastguard Worker      * width: the width of the captured image.
573*b7c941bbSAndroid Build Coastguard Worker      * height: the height of the captured image.
574*b7c941bbSAndroid Build Coastguard Worker      * format: image format
575*b7c941bbSAndroid Build Coastguard Worker      * metadata: the capture result object
576*b7c941bbSAndroid Build Coastguard Worker  """
577*b7c941bbSAndroid Build Coastguard Worker  preview_req_start = auto_capture_request()
578*b7c941bbSAndroid Build Coastguard Worker  preview_req_start['android.control.aeMode'] = (
579*b7c941bbSAndroid Build Coastguard Worker      _AE_MODE_ON_AUTO_FLASH if ae_mode == _AE_MODE_OFF else ae_mode
580*b7c941bbSAndroid Build Coastguard Worker  )
581*b7c941bbSAndroid Build Coastguard Worker  preview_req_start[
582*b7c941bbSAndroid Build Coastguard Worker      'android.control.captureIntent'] = _CAPTURE_INTENT_PREVIEW
583*b7c941bbSAndroid Build Coastguard Worker  preview_req_start[
584*b7c941bbSAndroid Build Coastguard Worker      'android.control.aePrecaptureTrigger'] = _AE_PRECAPTURE_TRIGGER_START
585*b7c941bbSAndroid Build Coastguard Worker  preview_req_start[
586*b7c941bbSAndroid Build Coastguard Worker      'android.flash.mode'] = _FLASH_MODE_SINGLE
587*b7c941bbSAndroid Build Coastguard Worker  preview_req_start[
588*b7c941bbSAndroid Build Coastguard Worker      'android.flash.strengthLevel'] = strength
589*b7c941bbSAndroid Build Coastguard Worker  # Repeat preview requests with aePrecapture set to IDLE
590*b7c941bbSAndroid Build Coastguard Worker  # until AE is converged.
591*b7c941bbSAndroid Build Coastguard Worker  preview_req_idle = auto_capture_request()
592*b7c941bbSAndroid Build Coastguard Worker  preview_req_idle['android.control.aeMode'] = (
593*b7c941bbSAndroid Build Coastguard Worker      _AE_MODE_ON_AUTO_FLASH if ae_mode == _AE_MODE_OFF else ae_mode
594*b7c941bbSAndroid Build Coastguard Worker  )
595*b7c941bbSAndroid Build Coastguard Worker  preview_req_idle[
596*b7c941bbSAndroid Build Coastguard Worker      'android.control.captureIntent'] = _CAPTURE_INTENT_PREVIEW
597*b7c941bbSAndroid Build Coastguard Worker  preview_req_idle[
598*b7c941bbSAndroid Build Coastguard Worker      'android.control.aePrecaptureTrigger'] = _AE_PRECAPTURE_TRIGGER_IDLE
599*b7c941bbSAndroid Build Coastguard Worker  preview_req_idle[
600*b7c941bbSAndroid Build Coastguard Worker      'android.flash.strengthLevel'] = strength
601*b7c941bbSAndroid Build Coastguard Worker  # Single still capture request.
602*b7c941bbSAndroid Build Coastguard Worker  still_capture_req = auto_capture_request()
603*b7c941bbSAndroid Build Coastguard Worker  still_capture_req[
604*b7c941bbSAndroid Build Coastguard Worker      'android.control.aeMode'] = ae_mode
605*b7c941bbSAndroid Build Coastguard Worker  still_capture_req[
606*b7c941bbSAndroid Build Coastguard Worker      'android.flash.mode'] = _FLASH_MODE_SINGLE
607*b7c941bbSAndroid Build Coastguard Worker  still_capture_req[
608*b7c941bbSAndroid Build Coastguard Worker      'android.control.captureIntent'] = _CAPTURE_INTENT_STILL_CAPTURE
609*b7c941bbSAndroid Build Coastguard Worker  still_capture_req[
610*b7c941bbSAndroid Build Coastguard Worker      'android.control.aePrecaptureTrigger'] = _AE_PRECAPTURE_TRIGGER_IDLE
611*b7c941bbSAndroid Build Coastguard Worker  still_capture_req[
612*b7c941bbSAndroid Build Coastguard Worker      'android.flash.strengthLevel'] = strength
613*b7c941bbSAndroid Build Coastguard Worker  cap = cam.do_capture_with_flash(preview_req_start,
614*b7c941bbSAndroid Build Coastguard Worker                                  preview_req_idle,
615*b7c941bbSAndroid Build Coastguard Worker                                  still_capture_req, out_surface)
616*b7c941bbSAndroid Build Coastguard Worker  return cap
617*b7c941bbSAndroid Build Coastguard Worker
618