blob: 9d72278f21e3fdca1506a8e40e742d73e9a8b7ca [file] [log] [blame]
Thierry Strudel3d639192016-09-09 11:52:26 -07001/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
2*
3* Redistribution and use in source and binary forms, with or without
4* modification, are permitted provided that the following conditions are
5* met:
6* * Redistributions of source code must retain the above copyright
7* notice, this list of conditions and the following disclaimer.
8* * Redistributions in binary form must reproduce the above
9* copyright notice, this list of conditions and the following
10* disclaimer in the documentation and/or other materials provided
11* with the distribution.
12* * Neither the name of The Linux Foundation nor the names of its
13* contributors may be used to endorse or promote products derived
14* from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*
28*/
29
30#define LOG_TAG "QCamera3HWI"
31//#define LOG_NDEBUG 0
32
33#define __STDC_LIMIT_MACROS
34
35// To remove
36#include <cutils/properties.h>
37
38// System dependencies
39#include <dlfcn.h>
40#include <fcntl.h>
41#include <stdio.h>
42#include <stdlib.h>
43#include "utils/Timers.h"
44#include "sys/ioctl.h"
Shuzhen Wangf6890e02016-08-12 14:28:54 -070045#include <time.h>
Thierry Strudel3d639192016-09-09 11:52:26 -070046#include <sync/sync.h>
47#include "gralloc_priv.h"
Thierry Strudele80ad7c2016-12-06 10:16:27 -080048#include <map>
Thierry Strudel3d639192016-09-09 11:52:26 -070049
50// Display dependencies
51#include "qdMetaData.h"
52
53// Camera dependencies
54#include "android/QCamera3External.h"
55#include "util/QCameraFlash.h"
56#include "QCamera3HWI.h"
57#include "QCamera3VendorTags.h"
58#include "QCameraTrace.h"
59
Eino-Ville Talvala42d58952018-01-05 16:20:10 -080060// XML parsing
61#include "tinyxml2.h"
62
Chien-Yu Chene687bd02016-12-07 18:30:26 -080063#include "HdrPlusClientUtils.h"
64
Thierry Strudel3d639192016-09-09 11:52:26 -070065extern "C" {
66#include "mm_camera_dbg.h"
67}
Shuzhen Wangfb961e52016-11-28 11:48:02 -080068#include "cam_cond.h"
Thierry Strudel3d639192016-09-09 11:52:26 -070069
Jiyong Parkd4caeb72017-06-12 17:16:36 +090070using ::android::hardware::camera::common::V1_0::helper::CameraMetadata;
Thierry Strudel3d639192016-09-09 11:52:26 -070071using namespace android;
72
73namespace qcamera {
74
75#define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX )
76
77#define EMPTY_PIPELINE_DELAY 2
Chien-Yu Chen0a921f92017-08-27 17:25:33 -070078// mm_camera has 2 partial results: 3A, and final result.
79// HDR+ requests have 3 partial results: postview, next request ready, and final result.
80#define PARTIAL_RESULT_COUNT 3
Thierry Strudel3d639192016-09-09 11:52:26 -070081#define FRAME_SKIP_DELAY 0
82
83#define MAX_VALUE_8BIT ((1<<8)-1)
84#define MAX_VALUE_10BIT ((1<<10)-1)
85#define MAX_VALUE_12BIT ((1<<12)-1)
86
87#define VIDEO_4K_WIDTH 3840
88#define VIDEO_4K_HEIGHT 2160
89
Jason Leeb9e76432017-03-10 17:14:19 -080090#define MAX_EIS_WIDTH 3840
91#define MAX_EIS_HEIGHT 2160
Thierry Strudel3d639192016-09-09 11:52:26 -070092
93#define MAX_RAW_STREAMS 1
94#define MAX_STALLING_STREAMS 1
95#define MAX_PROCESSED_STREAMS 3
96/* Batch mode is enabled only if FPS set is equal to or greater than this */
97#define MIN_FPS_FOR_BATCH_MODE (120)
98#define PREVIEW_FPS_FOR_HFR (30)
99#define DEFAULT_VIDEO_FPS (30.0)
Thierry Strudele80ad7c2016-12-06 10:16:27 -0800100#define TEMPLATE_MAX_PREVIEW_FPS (30.0)
Thierry Strudel3d639192016-09-09 11:52:26 -0700101#define MAX_HFR_BATCH_SIZE (8)
102#define REGIONS_TUPLE_COUNT 5
Thierry Strudel3d639192016-09-09 11:52:26 -0700103// Set a threshold for detection of missing buffers //seconds
Emilian Peev744149a2018-02-22 11:57:11 +0000104#define MISSING_REQUEST_BUF_TIMEOUT 10
Chien-Yu Chene687bd02016-12-07 18:30:26 -0800105#define MISSING_HDRPLUS_REQUEST_BUF_TIMEOUT 30
Thierry Strudel3d639192016-09-09 11:52:26 -0700106#define FLUSH_TIMEOUT 3
107#define METADATA_MAP_SIZE(MAP) (sizeof(MAP)/sizeof(MAP[0]))
108
109#define CAM_QCOM_FEATURE_PP_SUPERSET_HAL3 ( CAM_QCOM_FEATURE_DENOISE2D |\
110 CAM_QCOM_FEATURE_CROP |\
111 CAM_QCOM_FEATURE_ROTATION |\
112 CAM_QCOM_FEATURE_SHARPNESS |\
113 CAM_QCOM_FEATURE_SCALE |\
114 CAM_QCOM_FEATURE_CAC |\
115 CAM_QCOM_FEATURE_CDS )
Thierry Strudel9e74aae2016-09-22 17:10:18 -0700116/* Per configuration size for static metadata length*/
117#define PER_CONFIGURATION_SIZE_3 (3)
Thierry Strudel3d639192016-09-09 11:52:26 -0700118
119#define TIMEOUT_NEVER -1
120
Jason Lee8ce36fa2017-04-19 19:40:37 -0700121/* Face rect indices */
122#define FACE_LEFT 0
123#define FACE_TOP 1
124#define FACE_RIGHT 2
125#define FACE_BOTTOM 3
126#define FACE_WEIGHT 4
127
Thierry Strudel04e026f2016-10-10 11:27:36 -0700128/* Face landmarks indices */
129#define LEFT_EYE_X 0
130#define LEFT_EYE_Y 1
131#define RIGHT_EYE_X 2
132#define RIGHT_EYE_Y 3
133#define MOUTH_X 4
134#define MOUTH_Y 5
135#define TOTAL_LANDMARK_INDICES 6
136
Zhijun He2a5df222017-04-04 18:20:38 -0700137// Max preferred zoom
Zhijun He76870072017-05-08 17:13:17 -0700138#define MAX_PREFERRED_ZOOM_RATIO 7.0
Zhijun He2a5df222017-04-04 18:20:38 -0700139
Eino-Ville Talvala0362b5a2017-05-25 15:47:16 -0700140// Whether to check for the GPU stride padding, or use the default
141//#define CHECK_GPU_PIXEL_ALIGNMENT
142
Thierry Strudel3d639192016-09-09 11:52:26 -0700143cam_capability_t *gCamCapability[MM_CAMERA_MAX_NUM_SENSORS];
144const camera_metadata_t *gStaticMetadata[MM_CAMERA_MAX_NUM_SENSORS];
145extern pthread_mutex_t gCamLock;
146volatile uint32_t gCamHal3LogLevel = 1;
147extern uint8_t gNumCameraSessions;
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -0700148
Chien-Yu Chen27ec9622017-02-23 13:39:41 -0800149// Note that this doesn't support concurrent front and back camera b/35960155.
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -0700150// The following Easel related variables must be protected by gHdrPlusClientLock.
Chien-Yu Chend77a5462017-06-02 18:00:38 -0700151std::unique_ptr<EaselManagerClient> gEaselManagerClient;
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -0700152bool EaselManagerClientOpened = false; // If gEaselManagerClient is opened.
Shuzhen Wang80eed672017-10-12 23:59:31 -0700153int32_t gActiveEaselClient = 0; // The number of active cameras on Easel.
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -0700154std::unique_ptr<HdrPlusClient> gHdrPlusClient = nullptr;
155bool gHdrPlusClientOpening = false; // If HDR+ client is being opened.
Chien-Yu Chen77ccd022017-06-23 12:00:36 -0700156std::condition_variable gHdrPlusClientOpenCond; // Used to synchronize HDR+ client opening.
Chien-Yu Chen509314b2017-04-07 15:27:55 -0700157bool gEaselProfilingEnabled = false; // If Easel profiling is enabled.
Chien-Yu Chen66ec22a2017-04-13 18:00:36 -0700158bool gExposeEnableZslKey = false; // If HAL makes android.control.enableZsl available.
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -0700159
Chien-Yu Chen27ec9622017-02-23 13:39:41 -0800160// If Easel is in bypass only mode. If true, Easel HDR+ won't be enabled.
161bool gEaselBypassOnly;
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -0700162
Chien-Yu Chen77ccd022017-06-23 12:00:36 -0700163std::mutex gHdrPlusClientLock; // Protect above Easel related variables.
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -0700164
Thierry Strudel3d639192016-09-09 11:52:26 -0700165
166const QCamera3HardwareInterface::QCameraPropMap QCamera3HardwareInterface::CDS_MAP [] = {
167 {"On", CAM_CDS_MODE_ON},
168 {"Off", CAM_CDS_MODE_OFF},
169 {"Auto",CAM_CDS_MODE_AUTO}
170};
Thierry Strudel04e026f2016-10-10 11:27:36 -0700171const QCamera3HardwareInterface::QCameraMap<
172 camera_metadata_enum_android_video_hdr_mode_t,
173 cam_video_hdr_mode_t> QCamera3HardwareInterface::VIDEO_HDR_MODES_MAP[] = {
174 { QCAMERA3_VIDEO_HDR_MODE_OFF, CAM_VIDEO_HDR_MODE_OFF },
175 { QCAMERA3_VIDEO_HDR_MODE_ON, CAM_VIDEO_HDR_MODE_ON }
176};
177
Thierry Strudel54dc9782017-02-15 12:12:10 -0800178const QCamera3HardwareInterface::QCameraMap<
179 camera_metadata_enum_android_binning_correction_mode_t,
180 cam_binning_correction_mode_t> QCamera3HardwareInterface::BINNING_CORRECTION_MODES_MAP[] = {
181 { QCAMERA3_BINNING_CORRECTION_MODE_OFF, CAM_BINNING_CORRECTION_MODE_OFF },
182 { QCAMERA3_BINNING_CORRECTION_MODE_ON, CAM_BINNING_CORRECTION_MODE_ON }
183};
Thierry Strudel04e026f2016-10-10 11:27:36 -0700184
185const QCamera3HardwareInterface::QCameraMap<
186 camera_metadata_enum_android_ir_mode_t,
187 cam_ir_mode_type_t> QCamera3HardwareInterface::IR_MODES_MAP [] = {
188 {QCAMERA3_IR_MODE_OFF, CAM_IR_MODE_OFF},
189 {QCAMERA3_IR_MODE_ON, CAM_IR_MODE_ON},
190 {QCAMERA3_IR_MODE_AUTO, CAM_IR_MODE_AUTO}
191};
Thierry Strudel3d639192016-09-09 11:52:26 -0700192
193const QCamera3HardwareInterface::QCameraMap<
194 camera_metadata_enum_android_control_effect_mode_t,
195 cam_effect_mode_type> QCamera3HardwareInterface::EFFECT_MODES_MAP[] = {
196 { ANDROID_CONTROL_EFFECT_MODE_OFF, CAM_EFFECT_MODE_OFF },
197 { ANDROID_CONTROL_EFFECT_MODE_MONO, CAM_EFFECT_MODE_MONO },
198 { ANDROID_CONTROL_EFFECT_MODE_NEGATIVE, CAM_EFFECT_MODE_NEGATIVE },
199 { ANDROID_CONTROL_EFFECT_MODE_SOLARIZE, CAM_EFFECT_MODE_SOLARIZE },
200 { ANDROID_CONTROL_EFFECT_MODE_SEPIA, CAM_EFFECT_MODE_SEPIA },
201 { ANDROID_CONTROL_EFFECT_MODE_POSTERIZE, CAM_EFFECT_MODE_POSTERIZE },
202 { ANDROID_CONTROL_EFFECT_MODE_WHITEBOARD, CAM_EFFECT_MODE_WHITEBOARD },
203 { ANDROID_CONTROL_EFFECT_MODE_BLACKBOARD, CAM_EFFECT_MODE_BLACKBOARD },
204 { ANDROID_CONTROL_EFFECT_MODE_AQUA, CAM_EFFECT_MODE_AQUA }
205};
206
207const QCamera3HardwareInterface::QCameraMap<
208 camera_metadata_enum_android_control_awb_mode_t,
209 cam_wb_mode_type> QCamera3HardwareInterface::WHITE_BALANCE_MODES_MAP[] = {
210 { ANDROID_CONTROL_AWB_MODE_OFF, CAM_WB_MODE_OFF },
211 { ANDROID_CONTROL_AWB_MODE_AUTO, CAM_WB_MODE_AUTO },
212 { ANDROID_CONTROL_AWB_MODE_INCANDESCENT, CAM_WB_MODE_INCANDESCENT },
213 { ANDROID_CONTROL_AWB_MODE_FLUORESCENT, CAM_WB_MODE_FLUORESCENT },
214 { ANDROID_CONTROL_AWB_MODE_WARM_FLUORESCENT,CAM_WB_MODE_WARM_FLUORESCENT},
215 { ANDROID_CONTROL_AWB_MODE_DAYLIGHT, CAM_WB_MODE_DAYLIGHT },
216 { ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT, CAM_WB_MODE_CLOUDY_DAYLIGHT },
217 { ANDROID_CONTROL_AWB_MODE_TWILIGHT, CAM_WB_MODE_TWILIGHT },
218 { ANDROID_CONTROL_AWB_MODE_SHADE, CAM_WB_MODE_SHADE }
219};
220
221const QCamera3HardwareInterface::QCameraMap<
222 camera_metadata_enum_android_control_scene_mode_t,
223 cam_scene_mode_type> QCamera3HardwareInterface::SCENE_MODES_MAP[] = {
224 { ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY, CAM_SCENE_MODE_FACE_PRIORITY },
225 { ANDROID_CONTROL_SCENE_MODE_ACTION, CAM_SCENE_MODE_ACTION },
226 { ANDROID_CONTROL_SCENE_MODE_PORTRAIT, CAM_SCENE_MODE_PORTRAIT },
227 { ANDROID_CONTROL_SCENE_MODE_LANDSCAPE, CAM_SCENE_MODE_LANDSCAPE },
228 { ANDROID_CONTROL_SCENE_MODE_NIGHT, CAM_SCENE_MODE_NIGHT },
229 { ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT, CAM_SCENE_MODE_NIGHT_PORTRAIT },
230 { ANDROID_CONTROL_SCENE_MODE_THEATRE, CAM_SCENE_MODE_THEATRE },
231 { ANDROID_CONTROL_SCENE_MODE_BEACH, CAM_SCENE_MODE_BEACH },
232 { ANDROID_CONTROL_SCENE_MODE_SNOW, CAM_SCENE_MODE_SNOW },
233 { ANDROID_CONTROL_SCENE_MODE_SUNSET, CAM_SCENE_MODE_SUNSET },
234 { ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO, CAM_SCENE_MODE_ANTISHAKE },
235 { ANDROID_CONTROL_SCENE_MODE_FIREWORKS , CAM_SCENE_MODE_FIREWORKS },
236 { ANDROID_CONTROL_SCENE_MODE_SPORTS , CAM_SCENE_MODE_SPORTS },
237 { ANDROID_CONTROL_SCENE_MODE_PARTY, CAM_SCENE_MODE_PARTY },
238 { ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT, CAM_SCENE_MODE_CANDLELIGHT },
Mansoor Aftab58465fa2017-01-26 15:02:44 -0800239 { ANDROID_CONTROL_SCENE_MODE_BARCODE, CAM_SCENE_MODE_BARCODE},
240 { ANDROID_CONTROL_SCENE_MODE_HDR, CAM_SCENE_MODE_HDR}
Thierry Strudel3d639192016-09-09 11:52:26 -0700241};
242
243const QCamera3HardwareInterface::QCameraMap<
244 camera_metadata_enum_android_control_af_mode_t,
245 cam_focus_mode_type> QCamera3HardwareInterface::FOCUS_MODES_MAP[] = {
246 { ANDROID_CONTROL_AF_MODE_OFF, CAM_FOCUS_MODE_OFF },
247 { ANDROID_CONTROL_AF_MODE_OFF, CAM_FOCUS_MODE_FIXED },
248 { ANDROID_CONTROL_AF_MODE_AUTO, CAM_FOCUS_MODE_AUTO },
249 { ANDROID_CONTROL_AF_MODE_MACRO, CAM_FOCUS_MODE_MACRO },
250 { ANDROID_CONTROL_AF_MODE_EDOF, CAM_FOCUS_MODE_EDOF },
251 { ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE, CAM_FOCUS_MODE_CONTINOUS_PICTURE },
252 { ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO, CAM_FOCUS_MODE_CONTINOUS_VIDEO }
253};
254
255const QCamera3HardwareInterface::QCameraMap<
256 camera_metadata_enum_android_color_correction_aberration_mode_t,
257 cam_aberration_mode_t> QCamera3HardwareInterface::COLOR_ABERRATION_MAP[] = {
258 { ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF,
259 CAM_COLOR_CORRECTION_ABERRATION_OFF },
260 { ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST,
261 CAM_COLOR_CORRECTION_ABERRATION_FAST },
262 { ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY,
263 CAM_COLOR_CORRECTION_ABERRATION_HIGH_QUALITY },
264};
265
266const QCamera3HardwareInterface::QCameraMap<
267 camera_metadata_enum_android_control_ae_antibanding_mode_t,
268 cam_antibanding_mode_type> QCamera3HardwareInterface::ANTIBANDING_MODES_MAP[] = {
269 { ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF, CAM_ANTIBANDING_MODE_OFF },
270 { ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ, CAM_ANTIBANDING_MODE_50HZ },
271 { ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ, CAM_ANTIBANDING_MODE_60HZ },
272 { ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO, CAM_ANTIBANDING_MODE_AUTO }
273};
274
275const QCamera3HardwareInterface::QCameraMap<
276 camera_metadata_enum_android_control_ae_mode_t,
277 cam_flash_mode_t> QCamera3HardwareInterface::AE_FLASH_MODE_MAP[] = {
278 { ANDROID_CONTROL_AE_MODE_OFF, CAM_FLASH_MODE_OFF },
279 { ANDROID_CONTROL_AE_MODE_ON, CAM_FLASH_MODE_OFF },
280 { ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH, CAM_FLASH_MODE_AUTO},
281 { ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH, CAM_FLASH_MODE_ON },
Shuzhen Wang3d11a642017-08-18 09:57:29 -0700282 { ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE, CAM_FLASH_MODE_AUTO},
Chien-Yu Chenc5494e52018-01-19 17:53:58 -0800283 { ANDROID_CONTROL_AE_MODE_ON_EXTERNAL_FLASH, CAM_FLASH_MODE_OFF }
Thierry Strudel3d639192016-09-09 11:52:26 -0700284};
285
286const QCamera3HardwareInterface::QCameraMap<
287 camera_metadata_enum_android_flash_mode_t,
288 cam_flash_mode_t> QCamera3HardwareInterface::FLASH_MODES_MAP[] = {
289 { ANDROID_FLASH_MODE_OFF, CAM_FLASH_MODE_OFF },
290 { ANDROID_FLASH_MODE_SINGLE, CAM_FLASH_MODE_SINGLE },
291 { ANDROID_FLASH_MODE_TORCH, CAM_FLASH_MODE_TORCH }
292};
293
294const QCamera3HardwareInterface::QCameraMap<
295 camera_metadata_enum_android_statistics_face_detect_mode_t,
296 cam_face_detect_mode_t> QCamera3HardwareInterface::FACEDETECT_MODES_MAP[] = {
297 { ANDROID_STATISTICS_FACE_DETECT_MODE_OFF, CAM_FACE_DETECT_MODE_OFF },
298 { ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE, CAM_FACE_DETECT_MODE_SIMPLE },
299 { ANDROID_STATISTICS_FACE_DETECT_MODE_FULL, CAM_FACE_DETECT_MODE_FULL }
300};
301
302const QCamera3HardwareInterface::QCameraMap<
303 camera_metadata_enum_android_lens_info_focus_distance_calibration_t,
304 cam_focus_calibration_t> QCamera3HardwareInterface::FOCUS_CALIBRATION_MAP[] = {
305 { ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED,
306 CAM_FOCUS_UNCALIBRATED },
307 { ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE,
308 CAM_FOCUS_APPROXIMATE },
309 { ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED,
310 CAM_FOCUS_CALIBRATED }
311};
312
313const QCamera3HardwareInterface::QCameraMap<
314 camera_metadata_enum_android_lens_state_t,
315 cam_af_lens_state_t> QCamera3HardwareInterface::LENS_STATE_MAP[] = {
316 { ANDROID_LENS_STATE_STATIONARY, CAM_AF_LENS_STATE_STATIONARY},
317 { ANDROID_LENS_STATE_MOVING, CAM_AF_LENS_STATE_MOVING}
318};
319
320const int32_t available_thumbnail_sizes[] = {0, 0,
321 176, 144,
322 240, 144,
323 256, 144,
324 240, 160,
325 256, 154,
326 240, 240,
327 320, 240};
328
329const QCamera3HardwareInterface::QCameraMap<
330 camera_metadata_enum_android_sensor_test_pattern_mode_t,
331 cam_test_pattern_mode_t> QCamera3HardwareInterface::TEST_PATTERN_MAP[] = {
332 { ANDROID_SENSOR_TEST_PATTERN_MODE_OFF, CAM_TEST_PATTERN_OFF },
333 { ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR, CAM_TEST_PATTERN_SOLID_COLOR },
334 { ANDROID_SENSOR_TEST_PATTERN_MODE_COLOR_BARS, CAM_TEST_PATTERN_COLOR_BARS },
335 { ANDROID_SENSOR_TEST_PATTERN_MODE_COLOR_BARS_FADE_TO_GRAY, CAM_TEST_PATTERN_COLOR_BARS_FADE_TO_GRAY },
336 { ANDROID_SENSOR_TEST_PATTERN_MODE_PN9, CAM_TEST_PATTERN_PN9 },
337 { ANDROID_SENSOR_TEST_PATTERN_MODE_CUSTOM1, CAM_TEST_PATTERN_CUSTOM1},
338};
339
340/* Since there is no mapping for all the options some Android enum are not listed.
341 * Also, the order in this list is important because while mapping from HAL to Android it will
342 * traverse from lower to higher index which means that for HAL values that are map to different
343 * Android values, the traverse logic will select the first one found.
344 */
345const QCamera3HardwareInterface::QCameraMap<
346 camera_metadata_enum_android_sensor_reference_illuminant1_t,
347 cam_illuminat_t> QCamera3HardwareInterface::REFERENCE_ILLUMINANT_MAP[] = {
348 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_FLUORESCENT, CAM_AWB_WARM_FLO},
349 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT_FLUORESCENT, CAM_AWB_CUSTOM_DAYLIGHT },
350 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_COOL_WHITE_FLUORESCENT, CAM_AWB_COLD_FLO },
351 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_STANDARD_A, CAM_AWB_A },
352 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_D55, CAM_AWB_NOON },
353 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_D65, CAM_AWB_D65 },
354 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_D75, CAM_AWB_D75 },
355 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_D50, CAM_AWB_D50 },
356 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_ISO_STUDIO_TUNGSTEN, CAM_AWB_CUSTOM_A},
357 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT, CAM_AWB_D50 },
358 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_TUNGSTEN, CAM_AWB_A },
359 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_FINE_WEATHER, CAM_AWB_D50 },
360 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_CLOUDY_WEATHER, CAM_AWB_D65 },
361 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_SHADE, CAM_AWB_D75 },
362 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_DAY_WHITE_FLUORESCENT, CAM_AWB_CUSTOM_DAYLIGHT },
363 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_WHITE_FLUORESCENT, CAM_AWB_COLD_FLO},
364};
365
366const QCamera3HardwareInterface::QCameraMap<
367 int32_t, cam_hfr_mode_t> QCamera3HardwareInterface::HFR_MODE_MAP[] = {
368 { 60, CAM_HFR_MODE_60FPS},
369 { 90, CAM_HFR_MODE_90FPS},
370 { 120, CAM_HFR_MODE_120FPS},
371 { 150, CAM_HFR_MODE_150FPS},
372 { 180, CAM_HFR_MODE_180FPS},
373 { 210, CAM_HFR_MODE_210FPS},
374 { 240, CAM_HFR_MODE_240FPS},
375 { 480, CAM_HFR_MODE_480FPS},
376};
377
Thierry Strudel295a0ca2016-11-03 18:38:47 -0700378const QCamera3HardwareInterface::QCameraMap<
379 qcamera3_ext_instant_aec_mode_t,
380 cam_aec_convergence_type> QCamera3HardwareInterface::INSTANT_AEC_MODES_MAP[] = {
381 { QCAMERA3_INSTANT_AEC_NORMAL_CONVERGENCE, CAM_AEC_NORMAL_CONVERGENCE},
382 { QCAMERA3_INSTANT_AEC_AGGRESSIVE_CONVERGENCE, CAM_AEC_AGGRESSIVE_CONVERGENCE},
383 { QCAMERA3_INSTANT_AEC_FAST_CONVERGENCE, CAM_AEC_FAST_CONVERGENCE},
384};
Thierry Strudel54dc9782017-02-15 12:12:10 -0800385
386const QCamera3HardwareInterface::QCameraMap<
387 qcamera3_ext_exposure_meter_mode_t,
388 cam_auto_exposure_mode_type> QCamera3HardwareInterface::AEC_MODES_MAP[] = {
389 { QCAMERA3_EXP_METER_MODE_FRAME_AVERAGE, CAM_AEC_MODE_FRAME_AVERAGE },
390 { QCAMERA3_EXP_METER_MODE_CENTER_WEIGHTED, CAM_AEC_MODE_CENTER_WEIGHTED },
391 { QCAMERA3_EXP_METER_MODE_SPOT_METERING, CAM_AEC_MODE_SPOT_METERING },
392 { QCAMERA3_EXP_METER_MODE_SMART_METERING, CAM_AEC_MODE_SMART_METERING },
393 { QCAMERA3_EXP_METER_MODE_USER_METERING, CAM_AEC_MODE_USER_METERING },
394 { QCAMERA3_EXP_METER_MODE_SPOT_METERING_ADV, CAM_AEC_MODE_SPOT_METERING_ADV },
395 { QCAMERA3_EXP_METER_MODE_CENTER_WEIGHTED_ADV, CAM_AEC_MODE_CENTER_WEIGHTED_ADV },
396};
397
398const QCamera3HardwareInterface::QCameraMap<
399 qcamera3_ext_iso_mode_t,
400 cam_iso_mode_type> QCamera3HardwareInterface::ISO_MODES_MAP[] = {
401 { QCAMERA3_ISO_MODE_AUTO, CAM_ISO_MODE_AUTO },
402 { QCAMERA3_ISO_MODE_DEBLUR, CAM_ISO_MODE_DEBLUR },
403 { QCAMERA3_ISO_MODE_100, CAM_ISO_MODE_100 },
404 { QCAMERA3_ISO_MODE_200, CAM_ISO_MODE_200 },
405 { QCAMERA3_ISO_MODE_400, CAM_ISO_MODE_400 },
406 { QCAMERA3_ISO_MODE_800, CAM_ISO_MODE_800 },
407 { QCAMERA3_ISO_MODE_1600, CAM_ISO_MODE_1600 },
408 { QCAMERA3_ISO_MODE_3200, CAM_ISO_MODE_3200 },
409};
410
Thierry Strudel3d639192016-09-09 11:52:26 -0700411camera3_device_ops_t QCamera3HardwareInterface::mCameraOps = {
412 .initialize = QCamera3HardwareInterface::initialize,
413 .configure_streams = QCamera3HardwareInterface::configure_streams,
414 .register_stream_buffers = NULL,
415 .construct_default_request_settings = QCamera3HardwareInterface::construct_default_request_settings,
416 .process_capture_request = QCamera3HardwareInterface::process_capture_request,
417 .get_metadata_vendor_tag_ops = NULL,
418 .dump = QCamera3HardwareInterface::dump,
419 .flush = QCamera3HardwareInterface::flush,
420 .reserved = {0},
421};
422
423// initialise to some default value
424uint32_t QCamera3HardwareInterface::sessionId[] = {0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF};
425
Chien-Yu Chen509314b2017-04-07 15:27:55 -0700426static inline void logEaselEvent(const char *tag, const char *event) {
427 if (CC_UNLIKELY(gEaselProfilingEnabled)) {
428 struct timespec ts = {};
429 static int64_t kMsPerSec = 1000;
430 static int64_t kNsPerMs = 1000000;
431 status_t res = clock_gettime(CLOCK_BOOTTIME, &ts);
432 if (res != OK) {
433 ALOGE("[%s] Failed to get boot time for <%s>.", tag, event);
434 } else {
435 int64_t now = static_cast<int64_t>(ts.tv_sec) * kMsPerSec + ts.tv_nsec / kNsPerMs;
436 ALOGI("[%s] %s at %" PRId64 " ms", tag, event, now);
437 }
438 }
439}
440
Thierry Strudel3d639192016-09-09 11:52:26 -0700441/*===========================================================================
442 * FUNCTION : QCamera3HardwareInterface
443 *
444 * DESCRIPTION: constructor of QCamera3HardwareInterface
445 *
446 * PARAMETERS :
447 * @cameraId : camera ID
448 *
449 * RETURN : none
450 *==========================================================================*/
451QCamera3HardwareInterface::QCamera3HardwareInterface(uint32_t cameraId,
452 const camera_module_callbacks_t *callbacks)
453 : mCameraId(cameraId),
454 mCameraHandle(NULL),
455 mCameraInitialized(false),
456 mCallbackOps(NULL),
457 mMetadataChannel(NULL),
458 mPictureChannel(NULL),
459 mRawChannel(NULL),
460 mSupportChannel(NULL),
461 mAnalysisChannel(NULL),
462 mRawDumpChannel(NULL),
Chien-Yu Chen8e599492016-11-01 13:37:46 -0700463 mHdrPlusRawSrcChannel(NULL),
Thierry Strudel3d639192016-09-09 11:52:26 -0700464 mDummyBatchChannel(NULL),
Emilian Peev7650c122017-01-19 08:24:33 -0800465 mDepthChannel(NULL),
Emilian Peev656e4fa2017-06-02 16:47:04 +0100466 mDepthCloudMode(CAM_PD_DATA_SKIP),
Thierry Strudelc2ee3302016-11-17 12:33:12 -0800467 mPerfLockMgr(),
Thierry Strudel3d639192016-09-09 11:52:26 -0700468 mChannelHandle(0),
469 mFirstConfiguration(true),
470 mFlush(false),
471 mFlushPerf(false),
472 mParamHeap(NULL),
473 mParameters(NULL),
474 mPrevParameters(NULL),
Emilian Peev6d4cdc22017-11-16 16:56:23 +0000475 m_ISTypeVideo(IS_TYPE_NONE),
Thierry Strudel3d639192016-09-09 11:52:26 -0700476 m_bIsVideo(false),
477 m_bIs4KVideo(false),
478 m_bEisSupportedSize(false),
479 m_bEisEnable(false),
Thierry Strudel2896d122017-02-23 19:18:03 -0800480 m_bEis3PropertyEnabled(false),
Binhao Lin09245482017-08-31 18:25:29 -0700481 m_bAVTimerEnabled(false),
Thierry Strudel3d639192016-09-09 11:52:26 -0700482 m_MobicatMask(0),
Chien-Yu Chen3f303522017-05-19 15:21:45 -0700483 mShutterDispatcher(this),
484 mOutputBufferDispatcher(this),
Thierry Strudel3d639192016-09-09 11:52:26 -0700485 mMinProcessedFrameDuration(0),
486 mMinJpegFrameDuration(0),
487 mMinRawFrameDuration(0),
Emilian Peev30522a12017-08-03 14:36:33 +0100488 mExpectedFrameDuration(0),
489 mExpectedInflightDuration(0),
Thierry Strudel3d639192016-09-09 11:52:26 -0700490 mMetaFrameCount(0U),
491 mUpdateDebugLevel(false),
492 mCallbacks(callbacks),
493 mCaptureIntent(0),
494 mCacMode(0),
Samuel Ha68ba5172016-12-15 18:41:12 -0800495 /* DevCamDebug metadata internal m control*/
496 mDevCamDebugMetaEnable(0),
497 /* DevCamDebug metadata end */
Thierry Strudel3d639192016-09-09 11:52:26 -0700498 mBatchSize(0),
499 mToBeQueuedVidBufs(0),
500 mHFRVideoFps(DEFAULT_VIDEO_FPS),
501 mOpMode(CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE),
Thierry Strudel54dc9782017-02-15 12:12:10 -0800502 mStreamConfig(false),
Thierry Strudel2896d122017-02-23 19:18:03 -0800503 mCommon(),
Thierry Strudel3d639192016-09-09 11:52:26 -0700504 mFirstFrameNumberInBatch(0),
505 mNeedSensorRestart(false),
Thierry Strudelc2ee3302016-11-17 12:33:12 -0800506 mPreviewStarted(false),
Thierry Strudel9e74aae2016-09-22 17:10:18 -0700507 mMinInFlightRequests(MIN_INFLIGHT_REQUESTS),
508 mMaxInFlightRequests(MAX_INFLIGHT_REQUESTS),
Emilian Peev0f3c3162017-03-15 12:57:46 +0000509 mPDSupported(false),
510 mPDIndex(0),
Thierry Strudel295a0ca2016-11-03 18:38:47 -0700511 mInstantAEC(false),
512 mResetInstantAEC(false),
513 mInstantAECSettledFrameNumber(0),
514 mAecSkipDisplayFrameBound(0),
515 mInstantAecFrameIdxCount(0),
Chien-Yu Chenbc730232017-07-12 14:49:55 -0700516 mLastRequestedLensShadingMapMode(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF),
Chien-Yu Chen21b9e9a2017-09-25 14:34:26 -0700517 mLastRequestedFaceDetectMode(ANDROID_STATISTICS_FACE_DETECT_MODE_OFF),
Chien-Yu Chen7f9a15b2018-01-23 16:13:31 -0800518 mLastRequestedOisDataMode(ANDROID_STATISTICS_OIS_DATA_MODE_OFF),
Thierry Strudel54dc9782017-02-15 12:12:10 -0800519 mCurrFeatureState(0),
Thierry Strudel3d639192016-09-09 11:52:26 -0700520 mLdafCalibExist(false),
Thierry Strudel3d639192016-09-09 11:52:26 -0700521 mLastCustIntentFrmNum(-1),
Shuzhen Wang3c077d72017-04-20 22:48:59 -0700522 mFirstMetadataCallback(true),
Thierry Strudel3d639192016-09-09 11:52:26 -0700523 mState(CLOSED),
524 mIsDeviceLinked(false),
525 mIsMainCamera(true),
526 mLinkedCameraId(0),
Thierry Strudel295a0ca2016-11-03 18:38:47 -0700527 m_pDualCamCmdHeap(NULL),
Mansoor Aftab58465fa2017-01-26 15:02:44 -0800528 m_pDualCamCmdPtr(NULL),
Chien-Yu Chenee335912017-02-09 17:53:20 -0800529 mHdrPlusModeEnabled(false),
Chien-Yu Chen66ec22a2017-04-13 18:00:36 -0700530 mZslEnabled(false),
Chien-Yu Chen153c5172017-09-08 11:33:19 -0700531 mEaselMipiStarted(false),
Chien-Yu Chenee335912017-02-09 17:53:20 -0800532 mIsApInputUsedForHdrPlus(false),
533 mFirstPreviewIntentSeen(false),
Shuzhen Wang181c57b2017-07-21 11:39:44 -0700534 m_bSensorHDREnabled(false),
Shuzhen Wang3569d4a2017-09-04 19:10:28 -0700535 mAfTrigger(),
Shuzhen Wangecb525d2018-04-22 21:32:44 -0700536 mSceneDistance(-1),
537 mLastFocusDistance(0.0)
Thierry Strudel3d639192016-09-09 11:52:26 -0700538{
539 getLogLevel();
Thierry Strudel3d639192016-09-09 11:52:26 -0700540 mCommon.init(gCamCapability[cameraId]);
541 mCameraDevice.common.tag = HARDWARE_DEVICE_TAG;
Thierry Strudel9e74aae2016-09-22 17:10:18 -0700542#ifndef USE_HAL_3_3
Emilian Peev6d4cdc22017-11-16 16:56:23 +0000543 mCameraDevice.common.version = CAMERA_DEVICE_API_VERSION_3_5;
Thierry Strudel9e74aae2016-09-22 17:10:18 -0700544#else
Thierry Strudel3d639192016-09-09 11:52:26 -0700545 mCameraDevice.common.version = CAMERA_DEVICE_API_VERSION_3_3;
Thierry Strudel9e74aae2016-09-22 17:10:18 -0700546#endif
Thierry Strudel3d639192016-09-09 11:52:26 -0700547 mCameraDevice.common.close = close_camera_device;
548 mCameraDevice.ops = &mCameraOps;
549 mCameraDevice.priv = this;
550 gCamCapability[cameraId]->version = CAM_HAL_V3;
551 // TODO: hardcode for now until mctl add support for min_num_pp_bufs
552 //TBD - To see if this hardcoding is needed. Check by printing if this is filled by mctl to 3
553 gCamCapability[cameraId]->min_num_pp_bufs = 3;
554
Shuzhen Wangfb961e52016-11-28 11:48:02 -0800555 PTHREAD_COND_INIT(&mBuffersCond);
Thierry Strudel3d639192016-09-09 11:52:26 -0700556
Shuzhen Wangfb961e52016-11-28 11:48:02 -0800557 PTHREAD_COND_INIT(&mRequestCond);
Thierry Strudel3d639192016-09-09 11:52:26 -0700558 mPendingLiveRequest = 0;
559 mCurrentRequestId = -1;
560 pthread_mutex_init(&mMutex, NULL);
561
562 for (size_t i = 0; i < CAMERA3_TEMPLATE_COUNT; i++)
563 mDefaultMetadata[i] = NULL;
564
565 // Getting system props of different kinds
566 char prop[PROPERTY_VALUE_MAX];
567 memset(prop, 0, sizeof(prop));
568 property_get("persist.camera.raw.dump", prop, "0");
569 mEnableRawDump = atoi(prop);
Thierry Strudele80ad7c2016-12-06 10:16:27 -0800570 property_get("persist.camera.hal3.force.hdr", prop, "0");
571 mForceHdrSnapshot = atoi(prop);
572
Thierry Strudel3d639192016-09-09 11:52:26 -0700573 if (mEnableRawDump)
574 LOGD("Raw dump from Camera HAL enabled");
575
576 memset(&mInputStreamInfo, 0, sizeof(mInputStreamInfo));
577 memset(mLdafCalib, 0, sizeof(mLdafCalib));
578
Arnd Geis082a4d72017-08-24 10:33:07 -0700579 memset(mEaselFwVersion, 0, sizeof(mEaselFwVersion));
Arnd Geis8cbfc182017-09-07 14:46:41 -0700580 mEaselFwUpdated = false;
Arnd Geis082a4d72017-08-24 10:33:07 -0700581
Thierry Strudel3d639192016-09-09 11:52:26 -0700582 memset(prop, 0, sizeof(prop));
583 property_get("persist.camera.tnr.preview", prop, "0");
584 m_bTnrPreview = (uint8_t)atoi(prop);
585
586 memset(prop, 0, sizeof(prop));
Thierry Strudele80ad7c2016-12-06 10:16:27 -0800587 property_get("persist.camera.swtnr.preview", prop, "1");
588 m_bSwTnrPreview = (uint8_t)atoi(prop);
589
590 memset(prop, 0, sizeof(prop));
Binhao Lincdb362a2017-04-20 13:31:54 -0700591 property_get("persist.camera.tnr.video", prop, "1");
Thierry Strudel3d639192016-09-09 11:52:26 -0700592 m_bTnrVideo = (uint8_t)atoi(prop);
593
594 memset(prop, 0, sizeof(prop));
595 property_get("persist.camera.avtimer.debug", prop, "0");
596 m_debug_avtimer = (uint8_t)atoi(prop);
Thierry Strudelc2ee3302016-11-17 12:33:12 -0800597 LOGI("AV timer enabled: %d", m_debug_avtimer);
Thierry Strudel3d639192016-09-09 11:52:26 -0700598
Thierry Strudel54dc9782017-02-15 12:12:10 -0800599 memset(prop, 0, sizeof(prop));
600 property_get("persist.camera.cacmode.disable", prop, "0");
601 m_cacModeDisabled = (uint8_t)atoi(prop);
602
Shuzhen Wangb57ec912017-07-31 13:24:27 -0700603 m_bForceInfinityAf = property_get_bool("persist.camera.af.infinity", 0);
Shuzhen Wang8c276ef2017-08-09 11:12:20 -0700604 m_MobicatMask = (uint8_t)property_get_int32("persist.camera.mobicat", 0);
Shuzhen Wangb57ec912017-07-31 13:24:27 -0700605
Thierry Strudel3d639192016-09-09 11:52:26 -0700606 //Load and read GPU library.
607 lib_surface_utils = NULL;
608 LINK_get_surface_pixel_alignment = NULL;
Eino-Ville Talvala0362b5a2017-05-25 15:47:16 -0700609 mSurfaceStridePadding = CAM_PAD_TO_64;
610#ifdef CHECK_GPU_PIXEL_ALIGNMENT
Thierry Strudel3d639192016-09-09 11:52:26 -0700611 lib_surface_utils = dlopen("libadreno_utils.so", RTLD_NOW);
612 if (lib_surface_utils) {
613 *(void **)&LINK_get_surface_pixel_alignment =
614 dlsym(lib_surface_utils, "get_gpu_pixel_alignment");
615 if (LINK_get_surface_pixel_alignment) {
616 mSurfaceStridePadding = LINK_get_surface_pixel_alignment();
617 }
618 dlclose(lib_surface_utils);
619 }
Eino-Ville Talvala0362b5a2017-05-25 15:47:16 -0700620#endif
Emilian Peev0f3c3162017-03-15 12:57:46 +0000621 mPDIndex = getPDStatIndex(gCamCapability[cameraId]);
622 mPDSupported = (0 <= mPDIndex) ? true : false;
623
Shuzhen Wangf6890e02016-08-12 14:28:54 -0700624 m60HzZone = is60HzZone();
Thierry Strudel3d639192016-09-09 11:52:26 -0700625}
626
627/*===========================================================================
628 * FUNCTION : ~QCamera3HardwareInterface
629 *
630 * DESCRIPTION: destructor of QCamera3HardwareInterface
631 *
632 * PARAMETERS : none
633 *
634 * RETURN : none
635 *==========================================================================*/
636QCamera3HardwareInterface::~QCamera3HardwareInterface()
637{
638 LOGD("E");
639
Thierry Strudelc2ee3302016-11-17 12:33:12 -0800640 int32_t rc = 0;
Thierry Strudel3d639192016-09-09 11:52:26 -0700641
Chien-Yu Chenf8887c02018-04-11 15:29:46 -0700642 // Clean up Easel error future first to avoid Easel error happens during destructor.
643 cleanupEaselErrorFuture();
644
Thierry Strudelc2ee3302016-11-17 12:33:12 -0800645 // Disable power hint and enable the perf lock for close camera
646 mPerfLockMgr.releasePerfLock(PERF_LOCK_POWERHINT_ENCODE);
647 mPerfLockMgr.acquirePerfLock(PERF_LOCK_CLOSE_CAMERA);
648
Chien-Yu Chen153c5172017-09-08 11:33:19 -0700649 // Close HDR+ client first before destroying HAL.
650 {
651 std::unique_lock<std::mutex> l(gHdrPlusClientLock);
652 finishHdrPlusClientOpeningLocked(l);
653 if (gHdrPlusClient != nullptr) {
654 // Disable HDR+ mode.
655 disableHdrPlusModeLocked();
656 // Disconnect Easel if it's connected.
657 gEaselManagerClient->closeHdrPlusClient(std::move(gHdrPlusClient));
658 gHdrPlusClient = nullptr;
659 }
660 }
661
Thierry Strudelc2ee3302016-11-17 12:33:12 -0800662 // unlink of dualcam during close camera
663 if (mIsDeviceLinked) {
664 cam_dual_camera_bundle_info_t *m_pRelCamSyncBuf =
665 &m_pDualCamCmdPtr->bundle_info;
666 m_pDualCamCmdPtr->cmd_type = CAM_DUAL_CAMERA_BUNDLE_INFO;
667 m_pRelCamSyncBuf->sync_control = CAM_SYNC_RELATED_SENSORS_OFF;
668 pthread_mutex_lock(&gCamLock);
669
670 if (mIsMainCamera == 1) {
671 m_pRelCamSyncBuf->mode = CAM_MODE_PRIMARY;
672 m_pRelCamSyncBuf->type = CAM_TYPE_MAIN;
673 m_pRelCamSyncBuf->sync_3a_mode = CAM_3A_SYNC_FOLLOW;
674 // related session id should be session id of linked session
675 m_pRelCamSyncBuf->related_sensor_session_id = sessionId[mLinkedCameraId];
676 } else {
677 m_pRelCamSyncBuf->mode = CAM_MODE_SECONDARY;
678 m_pRelCamSyncBuf->type = CAM_TYPE_AUX;
679 m_pRelCamSyncBuf->sync_3a_mode = CAM_3A_SYNC_FOLLOW;
680 m_pRelCamSyncBuf->related_sensor_session_id = sessionId[mLinkedCameraId];
681 }
Thierry Strudel2896d122017-02-23 19:18:03 -0800682 m_pRelCamSyncBuf->is_hw_sync_enabled = DUALCAM_HW_SYNC_ENABLED;
Thierry Strudelc2ee3302016-11-17 12:33:12 -0800683 pthread_mutex_unlock(&gCamLock);
684
685 rc = mCameraHandle->ops->set_dual_cam_cmd(
686 mCameraHandle->camera_handle);
687 if (rc < 0) {
688 LOGE("Dualcam: Unlink failed, but still proceed to close");
689 }
690 }
Thierry Strudel3d639192016-09-09 11:52:26 -0700691
692 /* We need to stop all streams before deleting any stream */
693 if (mRawDumpChannel) {
694 mRawDumpChannel->stop();
695 }
696
Chien-Yu Chen8e599492016-11-01 13:37:46 -0700697 if (mHdrPlusRawSrcChannel) {
698 mHdrPlusRawSrcChannel->stop();
699 }
700
Thierry Strudel3d639192016-09-09 11:52:26 -0700701 // NOTE: 'camera3_stream_t *' objects are already freed at
702 // this stage by the framework
703 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
704 it != mStreamInfo.end(); it++) {
705 QCamera3ProcessingChannel *channel = (*it)->channel;
706 if (channel) {
707 channel->stop();
708 }
709 }
710 if (mSupportChannel)
711 mSupportChannel->stop();
712
713 if (mAnalysisChannel) {
714 mAnalysisChannel->stop();
715 }
716 if (mMetadataChannel) {
717 mMetadataChannel->stop();
718 }
719 if (mChannelHandle) {
Chien-Yu Chen153c5172017-09-08 11:33:19 -0700720 stopChannelLocked(/*stop_immediately*/false);
Thierry Strudel3d639192016-09-09 11:52:26 -0700721 }
722
723 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
724 it != mStreamInfo.end(); it++) {
725 QCamera3ProcessingChannel *channel = (*it)->channel;
726 if (channel)
727 delete channel;
728 free (*it);
729 }
730 if (mSupportChannel) {
731 delete mSupportChannel;
732 mSupportChannel = NULL;
733 }
734
735 if (mAnalysisChannel) {
736 delete mAnalysisChannel;
737 mAnalysisChannel = NULL;
738 }
739 if (mRawDumpChannel) {
740 delete mRawDumpChannel;
741 mRawDumpChannel = NULL;
742 }
Chien-Yu Chen8e599492016-11-01 13:37:46 -0700743 if (mHdrPlusRawSrcChannel) {
744 delete mHdrPlusRawSrcChannel;
745 mHdrPlusRawSrcChannel = NULL;
746 }
Thierry Strudel3d639192016-09-09 11:52:26 -0700747 if (mDummyBatchChannel) {
748 delete mDummyBatchChannel;
749 mDummyBatchChannel = NULL;
750 }
751
752 mPictureChannel = NULL;
Emilian Peev7650c122017-01-19 08:24:33 -0800753 mDepthChannel = NULL;
Thierry Strudel3d639192016-09-09 11:52:26 -0700754
755 if (mMetadataChannel) {
756 delete mMetadataChannel;
757 mMetadataChannel = NULL;
758 }
759
760 /* Clean up all channels */
761 if (mCameraInitialized) {
762 if(!mFirstConfiguration){
763 //send the last unconfigure
764 cam_stream_size_info_t stream_config_info;
765 memset(&stream_config_info, 0, sizeof(cam_stream_size_info_t));
766 stream_config_info.buffer_info.min_buffers = MIN_INFLIGHT_REQUESTS;
767 stream_config_info.buffer_info.max_buffers =
Thierry Strudel2896d122017-02-23 19:18:03 -0800768 m_bIs4KVideo ? 0 :
Jason Leea46ad5e2017-07-07 15:20:56 -0700769 m_bEis3PropertyEnabled && m_bIsVideo ? MAX_VIDEO_BUFFERS : MAX_INFLIGHT_REQUESTS;
Thierry Strudel9e74aae2016-09-22 17:10:18 -0700770 clear_metadata_buffer(mParameters);
Thierry Strudel3d639192016-09-09 11:52:26 -0700771 ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_META_STREAM_INFO,
772 stream_config_info);
773 int rc = mCameraHandle->ops->set_parms(mCameraHandle->camera_handle, mParameters);
774 if (rc < 0) {
775 LOGE("set_parms failed for unconfigure");
776 }
777 }
778 deinitParameters();
779 }
780
781 if (mChannelHandle) {
782 mCameraHandle->ops->delete_channel(mCameraHandle->camera_handle,
783 mChannelHandle);
784 LOGH("deleting channel %d", mChannelHandle);
785 mChannelHandle = 0;
786 }
787
788 if (mState != CLOSED)
789 closeCamera();
790
791 for (auto &req : mPendingBuffersMap.mPendingBuffersInRequest) {
792 req.mPendingBufferList.clear();
793 }
794 mPendingBuffersMap.mPendingBuffersInRequest.clear();
Thierry Strudel3d639192016-09-09 11:52:26 -0700795 for (pendingRequestIterator i = mPendingRequestsList.begin();
796 i != mPendingRequestsList.end();) {
797 i = erasePendingRequest(i);
798 }
799 for (size_t i = 0; i < CAMERA3_TEMPLATE_COUNT; i++)
800 if (mDefaultMetadata[i])
801 free_camera_metadata(mDefaultMetadata[i]);
802
Thierry Strudelc2ee3302016-11-17 12:33:12 -0800803 mPerfLockMgr.releasePerfLock(PERF_LOCK_CLOSE_CAMERA);
Thierry Strudel3d639192016-09-09 11:52:26 -0700804
805 pthread_cond_destroy(&mRequestCond);
806
807 pthread_cond_destroy(&mBuffersCond);
808
809 pthread_mutex_destroy(&mMutex);
810 LOGD("X");
811}
812
813/*===========================================================================
814 * FUNCTION : erasePendingRequest
815 *
816 * DESCRIPTION: function to erase a desired pending request after freeing any
817 * allocated memory
818 *
819 * PARAMETERS :
820 * @i : iterator pointing to pending request to be erased
821 *
822 * RETURN : iterator pointing to the next request
823 *==========================================================================*/
824QCamera3HardwareInterface::pendingRequestIterator
825 QCamera3HardwareInterface::erasePendingRequest (pendingRequestIterator i)
826{
827 if (i->input_buffer != NULL) {
828 free(i->input_buffer);
829 i->input_buffer = NULL;
830 }
831 if (i->settings != NULL)
832 free_camera_metadata((camera_metadata_t*)i->settings);
Emilian Peev30522a12017-08-03 14:36:33 +0100833
834 mExpectedInflightDuration -= i->expectedFrameDuration;
835 if (mExpectedInflightDuration < 0) {
836 LOGE("Negative expected in-flight duration!");
837 mExpectedInflightDuration = 0;
838 }
839
Thierry Strudel3d639192016-09-09 11:52:26 -0700840 return mPendingRequestsList.erase(i);
841}
842
843/*===========================================================================
844 * FUNCTION : camEvtHandle
845 *
846 * DESCRIPTION: Function registered to mm-camera-interface to handle events
847 *
848 * PARAMETERS :
849 * @camera_handle : interface layer camera handle
850 * @evt : ptr to event
851 * @user_data : user data ptr
852 *
853 * RETURN : none
854 *==========================================================================*/
855void QCamera3HardwareInterface::camEvtHandle(uint32_t /*camera_handle*/,
856 mm_camera_event_t *evt,
857 void *user_data)
858{
859 QCamera3HardwareInterface *obj = (QCamera3HardwareInterface *)user_data;
860 if (obj && evt) {
861 switch(evt->server_event_type) {
862 case CAM_EVENT_TYPE_DAEMON_DIED:
863 pthread_mutex_lock(&obj->mMutex);
864 obj->mState = ERROR;
865 pthread_mutex_unlock(&obj->mMutex);
866 LOGE("Fatal, camera daemon died");
867 break;
868
869 case CAM_EVENT_TYPE_DAEMON_PULL_REQ:
870 LOGD("HAL got request pull from Daemon");
871 pthread_mutex_lock(&obj->mMutex);
872 obj->mWokenUpByDaemon = true;
873 obj->unblockRequestIfNecessary();
874 pthread_mutex_unlock(&obj->mMutex);
875 break;
876
877 default:
878 LOGW("Warning: Unhandled event %d",
879 evt->server_event_type);
880 break;
881 }
882 } else {
883 LOGE("NULL user_data/evt");
884 }
885}
886
887/*===========================================================================
888 * FUNCTION : openCamera
889 *
890 * DESCRIPTION: open camera
891 *
892 * PARAMETERS :
893 * @hw_device : double ptr for camera device struct
894 *
895 * RETURN : int32_t type of status
896 * NO_ERROR -- success
897 * none-zero failure code
898 *==========================================================================*/
899int QCamera3HardwareInterface::openCamera(struct hw_device_t **hw_device)
900{
901 int rc = 0;
902 if (mState != CLOSED) {
903 *hw_device = NULL;
904 return PERMISSION_DENIED;
905 }
906
Chien-Yu Chene96475e2017-04-11 11:53:26 -0700907 logEaselEvent("EASEL_STARTUP_LATENCY", "Camera Open");
Thierry Strudelc2ee3302016-11-17 12:33:12 -0800908 mPerfLockMgr.acquirePerfLock(PERF_LOCK_OPEN_CAMERA);
Thierry Strudel3d639192016-09-09 11:52:26 -0700909 LOGI("[KPI Perf]: E PROFILE_OPEN_CAMERA camera id %d",
910 mCameraId);
911
Chien-Yu Chend8e57982017-05-25 12:10:21 -0700912 if (mCameraHandle) {
913 LOGE("Failure: Camera already opened");
914 return ALREADY_EXISTS;
915 }
916
917 {
Chien-Yu Chen77ccd022017-06-23 12:00:36 -0700918 std::unique_lock<std::mutex> l(gHdrPlusClientLock);
Chien-Yu Chend77a5462017-06-02 18:00:38 -0700919 if (gEaselManagerClient != nullptr && gEaselManagerClient->isEaselPresentOnDevice()) {
Chien-Yu Chend8e57982017-05-25 12:10:21 -0700920 logEaselEvent("EASEL_STARTUP_LATENCY", "Resume");
Shuzhen Wang80eed672017-10-12 23:59:31 -0700921 if (gActiveEaselClient == 0) {
922 rc = gEaselManagerClient->resume(this);
923 if (rc != 0) {
924 ALOGE("%s: Resuming Easel failed: %s (%d)", __FUNCTION__, strerror(-rc), rc);
925 return rc;
926 }
927 mEaselFwUpdated = false;
Chien-Yu Chend8e57982017-05-25 12:10:21 -0700928 }
Shuzhen Wang80eed672017-10-12 23:59:31 -0700929 gActiveEaselClient++;
Chien-Yu Chen6ed36ca2017-10-02 11:22:17 -0700930
931 mQCamera3HdrPlusListenerThread = new QCamera3HdrPlusListenerThread(this);
932 rc = mQCamera3HdrPlusListenerThread->run("QCamera3HdrPlusListenerThread");
933 if (rc != OK) {
934 ALOGE("%s: Starting HDR+ client listener thread failed: %s (%d)", __FUNCTION__,
935 strerror(-rc), rc);
936 return rc;
937 }
Chien-Yu Chend8e57982017-05-25 12:10:21 -0700938 }
939 }
940
Thierry Strudel3d639192016-09-09 11:52:26 -0700941 rc = openCamera();
942 if (rc == 0) {
943 *hw_device = &mCameraDevice.common;
Thierry Strudelc2ee3302016-11-17 12:33:12 -0800944 } else {
Thierry Strudel3d639192016-09-09 11:52:26 -0700945 *hw_device = NULL;
Chien-Yu Chend8e57982017-05-25 12:10:21 -0700946
947 // Suspend Easel because opening camera failed.
948 {
Chien-Yu Chen77ccd022017-06-23 12:00:36 -0700949 std::unique_lock<std::mutex> l(gHdrPlusClientLock);
Chien-Yu Chend77a5462017-06-02 18:00:38 -0700950 if (gEaselManagerClient != nullptr && gEaselManagerClient->isEaselPresentOnDevice()) {
Shuzhen Wang80eed672017-10-12 23:59:31 -0700951 if (gActiveEaselClient == 1) {
952 status_t suspendErr = gEaselManagerClient->suspend();
953 if (suspendErr != 0) {
954 ALOGE("%s: Suspending Easel failed: %s (%d)", __FUNCTION__,
955 strerror(-suspendErr), suspendErr);
956 }
Chien-Yu Chend8e57982017-05-25 12:10:21 -0700957 }
Shuzhen Wang80eed672017-10-12 23:59:31 -0700958 gActiveEaselClient--;
Chien-Yu Chend8e57982017-05-25 12:10:21 -0700959 }
Chien-Yu Chen6ed36ca2017-10-02 11:22:17 -0700960
Emilian Peev4924cc12017-12-06 10:49:25 +0000961 if (mQCamera3HdrPlusListenerThread != nullptr) {
962 mQCamera3HdrPlusListenerThread->requestExit();
963 mQCamera3HdrPlusListenerThread->join();
964 mQCamera3HdrPlusListenerThread = nullptr;
965 }
Chien-Yu Chend8e57982017-05-25 12:10:21 -0700966 }
Thierry Strudelc2ee3302016-11-17 12:33:12 -0800967 }
Thierry Strudel3d639192016-09-09 11:52:26 -0700968
Thierry Strudel3d639192016-09-09 11:52:26 -0700969 LOGI("[KPI Perf]: X PROFILE_OPEN_CAMERA camera id %d, rc: %d",
970 mCameraId, rc);
971
972 if (rc == NO_ERROR) {
973 mState = OPENED;
974 }
Chien-Yu Chen27ec9622017-02-23 13:39:41 -0800975
Thierry Strudel3d639192016-09-09 11:52:26 -0700976 return rc;
977}
978
979/*===========================================================================
980 * FUNCTION : openCamera
981 *
982 * DESCRIPTION: open camera
983 *
984 * PARAMETERS : none
985 *
986 * RETURN : int32_t type of status
987 * NO_ERROR -- success
988 * none-zero failure code
989 *==========================================================================*/
990int QCamera3HardwareInterface::openCamera()
991{
992 int rc = 0;
993 char value[PROPERTY_VALUE_MAX];
994
Thierry Strudele80ad7c2016-12-06 10:16:27 -0800995 KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL3_OPENCAMERA);
Chien-Yu Chen27ec9622017-02-23 13:39:41 -0800996
Thierry Strudel3d639192016-09-09 11:52:26 -0700997 rc = QCameraFlash::getInstance().reserveFlashForCamera(mCameraId);
998 if (rc < 0) {
999 LOGE("Failed to reserve flash for camera id: %d",
1000 mCameraId);
1001 return UNKNOWN_ERROR;
1002 }
1003
1004 rc = camera_open((uint8_t)mCameraId, &mCameraHandle);
1005 if (rc) {
1006 LOGE("camera_open failed. rc = %d, mCameraHandle = %p", rc, mCameraHandle);
1007 return rc;
1008 }
1009
1010 if (!mCameraHandle) {
1011 LOGE("camera_open failed. mCameraHandle = %p", mCameraHandle);
1012 return -ENODEV;
1013 }
1014
1015 rc = mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
1016 camEvtHandle, (void *)this);
1017
1018 if (rc < 0) {
1019 LOGE("Error, failed to register event callback");
1020 /* Not closing camera here since it is already handled in destructor */
1021 return FAILED_TRANSACTION;
1022 }
1023
1024 mExifParams.debug_params =
1025 (mm_jpeg_debug_exif_params_t *) malloc (sizeof(mm_jpeg_debug_exif_params_t));
1026 if (mExifParams.debug_params) {
1027 memset(mExifParams.debug_params, 0, sizeof(mm_jpeg_debug_exif_params_t));
1028 } else {
1029 LOGE("Out of Memory. Allocation failed for 3A debug exif params");
1030 return NO_MEMORY;
1031 }
1032 mFirstConfiguration = true;
1033
1034 //Notify display HAL that a camera session is active.
1035 //But avoid calling the same during bootup because camera service might open/close
1036 //cameras at boot time during its initialization and display service will also internally
1037 //wait for camera service to initialize first while calling this display API, resulting in a
1038 //deadlock situation. Since boot time camera open/close calls are made only to fetch
1039 //capabilities, no need of this display bw optimization.
1040 //Use "service.bootanim.exit" property to know boot status.
1041 property_get("service.bootanim.exit", value, "0");
1042 if (atoi(value) == 1) {
1043 pthread_mutex_lock(&gCamLock);
1044 if (gNumCameraSessions++ == 0) {
1045 setCameraLaunchStatus(true);
1046 }
1047 pthread_mutex_unlock(&gCamLock);
1048 }
1049
1050 //fill the session id needed while linking dual cam
1051 pthread_mutex_lock(&gCamLock);
1052 rc = mCameraHandle->ops->get_session_id(mCameraHandle->camera_handle,
1053 &sessionId[mCameraId]);
1054 pthread_mutex_unlock(&gCamLock);
1055
1056 if (rc < 0) {
1057 LOGE("Error, failed to get sessiion id");
1058 return UNKNOWN_ERROR;
1059 } else {
1060 //Allocate related cam sync buffer
1061 //this is needed for the payload that goes along with bundling cmd for related
1062 //camera use cases
Thierry Strudel295a0ca2016-11-03 18:38:47 -07001063 m_pDualCamCmdHeap = new QCamera3HeapMemory(1);
1064 rc = m_pDualCamCmdHeap->allocate(sizeof(cam_dual_camera_cmd_info_t));
Thierry Strudel3d639192016-09-09 11:52:26 -07001065 if(rc != OK) {
1066 rc = NO_MEMORY;
1067 LOGE("Dualcam: Failed to allocate Related cam sync Heap memory");
1068 return NO_MEMORY;
1069 }
1070
1071 //Map memory for related cam sync buffer
1072 rc = mCameraHandle->ops->map_buf(mCameraHandle->camera_handle,
Thierry Strudel295a0ca2016-11-03 18:38:47 -07001073 CAM_MAPPING_BUF_TYPE_DUAL_CAM_CMD_BUF,
1074 m_pDualCamCmdHeap->getFd(0),
1075 sizeof(cam_dual_camera_cmd_info_t),
1076 m_pDualCamCmdHeap->getPtr(0));
Thierry Strudel3d639192016-09-09 11:52:26 -07001077 if(rc < 0) {
1078 LOGE("Dualcam: failed to map Related cam sync buffer");
1079 rc = FAILED_TRANSACTION;
1080 return NO_MEMORY;
1081 }
Thierry Strudel295a0ca2016-11-03 18:38:47 -07001082 m_pDualCamCmdPtr =
1083 (cam_dual_camera_cmd_info_t*) DATA_PTR(m_pDualCamCmdHeap,0);
Thierry Strudel3d639192016-09-09 11:52:26 -07001084 }
1085
1086 LOGH("mCameraId=%d",mCameraId);
1087
1088 return NO_ERROR;
1089}
1090
1091/*===========================================================================
1092 * FUNCTION : closeCamera
1093 *
1094 * DESCRIPTION: close camera
1095 *
1096 * PARAMETERS : none
1097 *
1098 * RETURN : int32_t type of status
1099 * NO_ERROR -- success
1100 * none-zero failure code
1101 *==========================================================================*/
1102int QCamera3HardwareInterface::closeCamera()
1103{
Thierry Strudele80ad7c2016-12-06 10:16:27 -08001104 KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL3_CLOSECAMERA);
Thierry Strudel3d639192016-09-09 11:52:26 -07001105 int rc = NO_ERROR;
1106 char value[PROPERTY_VALUE_MAX];
1107
1108 LOGI("[KPI Perf]: E PROFILE_CLOSE_CAMERA camera id %d",
1109 mCameraId);
Thierry Strudelcca4d9c2016-10-20 08:25:53 -07001110
1111 // unmap memory for related cam sync buffer
1112 mCameraHandle->ops->unmap_buf(mCameraHandle->camera_handle,
Thierry Strudele80ad7c2016-12-06 10:16:27 -08001113 CAM_MAPPING_BUF_TYPE_DUAL_CAM_CMD_BUF);
Thierry Strudel295a0ca2016-11-03 18:38:47 -07001114 if (NULL != m_pDualCamCmdHeap) {
1115 m_pDualCamCmdHeap->deallocate();
1116 delete m_pDualCamCmdHeap;
1117 m_pDualCamCmdHeap = NULL;
1118 m_pDualCamCmdPtr = NULL;
Thierry Strudelcca4d9c2016-10-20 08:25:53 -07001119 }
1120
Thierry Strudel3d639192016-09-09 11:52:26 -07001121 rc = mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
1122 mCameraHandle = NULL;
1123
1124 //reset session id to some invalid id
1125 pthread_mutex_lock(&gCamLock);
1126 sessionId[mCameraId] = 0xDEADBEEF;
1127 pthread_mutex_unlock(&gCamLock);
1128
1129 //Notify display HAL that there is no active camera session
1130 //but avoid calling the same during bootup. Refer to openCamera
1131 //for more details.
1132 property_get("service.bootanim.exit", value, "0");
1133 if (atoi(value) == 1) {
1134 pthread_mutex_lock(&gCamLock);
1135 if (--gNumCameraSessions == 0) {
1136 setCameraLaunchStatus(false);
1137 }
1138 pthread_mutex_unlock(&gCamLock);
1139 }
1140
Thierry Strudel3d639192016-09-09 11:52:26 -07001141 if (mExifParams.debug_params) {
1142 free(mExifParams.debug_params);
1143 mExifParams.debug_params = NULL;
1144 }
1145 if (QCameraFlash::getInstance().releaseFlashFromCamera(mCameraId) != 0) {
1146 LOGW("Failed to release flash for camera id: %d",
1147 mCameraId);
1148 }
1149 mState = CLOSED;
1150 LOGI("[KPI Perf]: X PROFILE_CLOSE_CAMERA camera id %d, rc: %d",
1151 mCameraId, rc);
Chien-Yu Chen27ec9622017-02-23 13:39:41 -08001152
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -07001153 {
Chien-Yu Chen77ccd022017-06-23 12:00:36 -07001154 std::unique_lock<std::mutex> l(gHdrPlusClientLock);
Chien-Yu Chen5abecb52017-04-06 11:25:21 -07001155 if (EaselManagerClientOpened) {
Shuzhen Wang80eed672017-10-12 23:59:31 -07001156 if (gActiveEaselClient == 1) {
1157 rc = gEaselManagerClient->suspend();
1158 if (rc != 0) {
1159 ALOGE("%s: Suspending Easel failed: %s (%d)", __FUNCTION__, strerror(-rc), rc);
1160 }
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -07001161 }
Shuzhen Wang80eed672017-10-12 23:59:31 -07001162 gActiveEaselClient--;
Chien-Yu Chen27ec9622017-02-23 13:39:41 -08001163 }
Chien-Yu Chen6ed36ca2017-10-02 11:22:17 -07001164
Emilian Peev4924cc12017-12-06 10:49:25 +00001165 if (mQCamera3HdrPlusListenerThread != nullptr) {
1166 mQCamera3HdrPlusListenerThread->requestExit();
1167 mQCamera3HdrPlusListenerThread->join();
1168 mQCamera3HdrPlusListenerThread = nullptr;
1169 }
Chien-Yu Chen27ec9622017-02-23 13:39:41 -08001170 }
1171
Thierry Strudel3d639192016-09-09 11:52:26 -07001172 return rc;
1173}
1174
1175/*===========================================================================
1176 * FUNCTION : initialize
1177 *
1178 * DESCRIPTION: Initialize frameworks callback functions
1179 *
1180 * PARAMETERS :
1181 * @callback_ops : callback function to frameworks
1182 *
1183 * RETURN :
1184 *
1185 *==========================================================================*/
1186int QCamera3HardwareInterface::initialize(
1187 const struct camera3_callback_ops *callback_ops)
1188{
Thierry Strudele80ad7c2016-12-06 10:16:27 -08001189 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL3_INIT);
Thierry Strudel3d639192016-09-09 11:52:26 -07001190 int rc;
1191
1192 LOGI("E :mCameraId = %d mState = %d", mCameraId, mState);
1193 pthread_mutex_lock(&mMutex);
1194
1195 // Validate current state
1196 switch (mState) {
1197 case OPENED:
1198 /* valid state */
1199 break;
1200 default:
1201 LOGE("Invalid state %d", mState);
1202 rc = -ENODEV;
1203 goto err1;
1204 }
1205
1206 rc = initParameters();
1207 if (rc < 0) {
1208 LOGE("initParamters failed %d", rc);
1209 goto err1;
1210 }
1211 mCallbackOps = callback_ops;
1212
1213 mChannelHandle = mCameraHandle->ops->add_channel(
1214 mCameraHandle->camera_handle, NULL, NULL, this);
1215 if (mChannelHandle == 0) {
1216 LOGE("add_channel failed");
1217 rc = -ENOMEM;
1218 pthread_mutex_unlock(&mMutex);
1219 return rc;
1220 }
1221
1222 pthread_mutex_unlock(&mMutex);
1223 mCameraInitialized = true;
1224 mState = INITIALIZED;
1225 LOGI("X");
1226 return 0;
1227
1228err1:
1229 pthread_mutex_unlock(&mMutex);
1230 return rc;
1231}
1232
1233/*===========================================================================
1234 * FUNCTION : validateStreamDimensions
1235 *
1236 * DESCRIPTION: Check if the configuration requested are those advertised
1237 *
1238 * PARAMETERS :
1239 * @stream_list : streams to be configured
1240 *
1241 * RETURN :
1242 *
1243 *==========================================================================*/
1244int QCamera3HardwareInterface::validateStreamDimensions(
1245 camera3_stream_configuration_t *streamList)
1246{
1247 int rc = NO_ERROR;
1248 size_t count = 0;
Emilian Peev0f3c3162017-03-15 12:57:46 +00001249 uint32_t depthWidth = 0;
1250 uint32_t depthHeight = 0;
1251 if (mPDSupported) {
1252 depthWidth = gCamCapability[mCameraId]->raw_meta_dim[mPDIndex].width;
1253 depthHeight = gCamCapability[mCameraId]->raw_meta_dim[mPDIndex].height;
1254 }
Thierry Strudel3d639192016-09-09 11:52:26 -07001255
1256 camera3_stream_t *inputStream = NULL;
1257 /*
1258 * Loop through all streams to find input stream if it exists*
1259 */
1260 for (size_t i = 0; i< streamList->num_streams; i++) {
1261 if (streamList->streams[i]->stream_type == CAMERA3_STREAM_INPUT) {
1262 if (inputStream != NULL) {
1263 LOGE("Error, Multiple input streams requested");
1264 return -EINVAL;
1265 }
1266 inputStream = streamList->streams[i];
1267 }
1268 }
1269 /*
1270 * Loop through all streams requested in configuration
1271 * Check if unsupported sizes have been requested on any of them
1272 */
1273 for (size_t j = 0; j < streamList->num_streams; j++) {
1274 bool sizeFound = false;
1275 camera3_stream_t *newStream = streamList->streams[j];
1276
1277 uint32_t rotatedHeight = newStream->height;
1278 uint32_t rotatedWidth = newStream->width;
1279 if ((newStream->rotation == CAMERA3_STREAM_ROTATION_90) ||
1280 (newStream->rotation == CAMERA3_STREAM_ROTATION_270)) {
1281 rotatedHeight = newStream->width;
1282 rotatedWidth = newStream->height;
1283 }
1284
1285 /*
1286 * Sizes are different for each type of stream format check against
1287 * appropriate table.
1288 */
1289 switch (newStream->format) {
1290 case ANDROID_SCALER_AVAILABLE_FORMATS_RAW16:
1291 case ANDROID_SCALER_AVAILABLE_FORMATS_RAW_OPAQUE:
1292 case HAL_PIXEL_FORMAT_RAW10:
Emilian Peev0f3c3162017-03-15 12:57:46 +00001293 if ((HAL_DATASPACE_DEPTH == newStream->data_space) &&
1294 (ANDROID_SCALER_AVAILABLE_FORMATS_RAW16 == newStream->format) &&
1295 mPDSupported) {
1296 if ((depthWidth == newStream->width) &&
1297 (depthHeight == newStream->height)) {
1298 sizeFound = true;
1299 }
1300 break;
1301 }
Thierry Strudel3d639192016-09-09 11:52:26 -07001302 count = MIN(gCamCapability[mCameraId]->supported_raw_dim_cnt, MAX_SIZES_CNT);
1303 for (size_t i = 0; i < count; i++) {
1304 if ((gCamCapability[mCameraId]->raw_dim[i].width == (int32_t)rotatedWidth) &&
1305 (gCamCapability[mCameraId]->raw_dim[i].height == (int32_t)rotatedHeight)) {
1306 sizeFound = true;
1307 break;
1308 }
1309 }
1310 break;
1311 case HAL_PIXEL_FORMAT_BLOB:
Emilian Peev0f3c3162017-03-15 12:57:46 +00001312 if ((newStream->data_space == HAL_DATASPACE_DEPTH) &&
1313 mPDSupported) {
Emilian Peev7650c122017-01-19 08:24:33 -08001314 //As per spec. depth cloud should be sample count / 16
Emilian Peev0f3c3162017-03-15 12:57:46 +00001315 uint32_t depthSamplesCount = (depthWidth * depthHeight * 2) / 16;
Emilian Peev7650c122017-01-19 08:24:33 -08001316 if ((depthSamplesCount == newStream->width) &&
1317 (1 == newStream->height)) {
1318 sizeFound = true;
1319 }
1320 break;
1321 }
Thierry Strudel3d639192016-09-09 11:52:26 -07001322 count = MIN(gCamCapability[mCameraId]->picture_sizes_tbl_cnt, MAX_SIZES_CNT);
1323 /* Verify set size against generated sizes table */
1324 for (size_t i = 0; i < count; i++) {
1325 if (((int32_t)rotatedWidth ==
1326 gCamCapability[mCameraId]->picture_sizes_tbl[i].width) &&
1327 ((int32_t)rotatedHeight ==
1328 gCamCapability[mCameraId]->picture_sizes_tbl[i].height)) {
1329 sizeFound = true;
1330 break;
1331 }
1332 }
1333 break;
1334 case HAL_PIXEL_FORMAT_YCbCr_420_888:
1335 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
1336 default:
1337 if (newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL
1338 || newStream->stream_type == CAMERA3_STREAM_INPUT
1339 || IS_USAGE_ZSL(newStream->usage)) {
1340 if (((int32_t)rotatedWidth ==
1341 gCamCapability[mCameraId]->active_array_size.width) &&
1342 ((int32_t)rotatedHeight ==
1343 gCamCapability[mCameraId]->active_array_size.height)) {
1344 sizeFound = true;
1345 break;
1346 }
1347 /* We could potentially break here to enforce ZSL stream
1348 * set from frameworks always is full active array size
1349 * but it is not clear from the spc if framework will always
1350 * follow that, also we have logic to override to full array
1351 * size, so keeping the logic lenient at the moment
1352 */
1353 }
1354 count = MIN(gCamCapability[mCameraId]->picture_sizes_tbl_cnt,
1355 MAX_SIZES_CNT);
1356 for (size_t i = 0; i < count; i++) {
1357 if (((int32_t)rotatedWidth ==
1358 gCamCapability[mCameraId]->picture_sizes_tbl[i].width) &&
1359 ((int32_t)rotatedHeight ==
1360 gCamCapability[mCameraId]->picture_sizes_tbl[i].height)) {
1361 sizeFound = true;
1362 break;
1363 }
1364 }
1365 break;
1366 } /* End of switch(newStream->format) */
1367
1368 /* We error out even if a single stream has unsupported size set */
1369 if (!sizeFound) {
1370 LOGE("Error: Unsupported size: %d x %d type: %d array size: %d x %d",
1371 rotatedWidth, rotatedHeight, newStream->format,
1372 gCamCapability[mCameraId]->active_array_size.width,
1373 gCamCapability[mCameraId]->active_array_size.height);
1374 rc = -EINVAL;
1375 break;
1376 }
1377 } /* End of for each stream */
1378 return rc;
1379}
1380
Shuzhen Wangbb03f5c2017-02-17 15:38:24 -08001381/*===========================================================================
1382 * FUNCTION : validateUsageFlags
1383 *
1384 * DESCRIPTION: Check if the configuration usage flags map to same internal format.
1385 *
1386 * PARAMETERS :
1387 * @stream_list : streams to be configured
1388 *
1389 * RETURN :
1390 * NO_ERROR if the usage flags are supported
1391 * error code if usage flags are not supported
1392 *
1393 *==========================================================================*/
1394int QCamera3HardwareInterface::validateUsageFlags(
1395 const camera3_stream_configuration_t* streamList)
1396{
1397 for (size_t j = 0; j < streamList->num_streams; j++) {
1398 const camera3_stream_t *newStream = streamList->streams[j];
1399
1400 if (newStream->format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
1401 (newStream->stream_type != CAMERA3_STREAM_OUTPUT &&
1402 newStream->stream_type != CAMERA3_STREAM_BIDIRECTIONAL)) {
1403 continue;
1404 }
1405
Jason Leec4cf5032017-05-24 18:31:41 -07001406 // Here we only care whether it's EIS3 or not
1407 char is_type_value[PROPERTY_VALUE_MAX];
1408 property_get("persist.camera.is_type", is_type_value, "4");
1409 cam_is_type_t isType = atoi(is_type_value) == IS_TYPE_EIS_3_0 ? IS_TYPE_EIS_3_0 : IS_TYPE_NONE;
1410 if (gCamCapability[mCameraId]->position == CAM_POSITION_FRONT ||
1411 mOpMode == CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE)
1412 isType = IS_TYPE_NONE;
1413
Shuzhen Wangbb03f5c2017-02-17 15:38:24 -08001414 bool isVideo = IS_USAGE_VIDEO(newStream->usage);
1415 bool isPreview = IS_USAGE_PREVIEW(newStream->usage);
1416 bool isZSL = IS_USAGE_ZSL(newStream->usage);
1417 bool forcePreviewUBWC = true;
1418 if (isVideo && !QCameraCommon::isVideoUBWCEnabled()) {
1419 forcePreviewUBWC = false;
1420 }
1421 cam_format_t videoFormat = QCamera3Channel::getStreamDefaultFormat(
Jason Leec4cf5032017-05-24 18:31:41 -07001422 CAM_STREAM_TYPE_VIDEO, newStream->width, newStream->height, forcePreviewUBWC, isType);
Shuzhen Wangbb03f5c2017-02-17 15:38:24 -08001423 cam_format_t previewFormat = QCamera3Channel::getStreamDefaultFormat(
Jason Leec4cf5032017-05-24 18:31:41 -07001424 CAM_STREAM_TYPE_PREVIEW, newStream->width, newStream->height, forcePreviewUBWC, isType);
Shuzhen Wangbb03f5c2017-02-17 15:38:24 -08001425 cam_format_t zslFormat = QCamera3Channel::getStreamDefaultFormat(
Jason Leec4cf5032017-05-24 18:31:41 -07001426 CAM_STREAM_TYPE_SNAPSHOT, newStream->width, newStream->height, forcePreviewUBWC, isType);
Shuzhen Wangbb03f5c2017-02-17 15:38:24 -08001427
1428 // Color space for this camera device is guaranteed to be ITU_R_601_FR.
1429 // So color spaces will always match.
1430
1431 // Check whether underlying formats of shared streams match.
1432 if (isVideo && isPreview && videoFormat != previewFormat) {
1433 LOGE("Combined video and preview usage flag is not supported");
1434 return -EINVAL;
1435 }
1436 if (isPreview && isZSL && previewFormat != zslFormat) {
1437 LOGE("Combined preview and zsl usage flag is not supported");
1438 return -EINVAL;
1439 }
1440 if (isVideo && isZSL && videoFormat != zslFormat) {
1441 LOGE("Combined video and zsl usage flag is not supported");
1442 return -EINVAL;
1443 }
1444 }
1445 return NO_ERROR;
1446}
1447
1448/*===========================================================================
1449 * FUNCTION : validateUsageFlagsForEis
1450 *
1451 * DESCRIPTION: Check if the configuration usage flags conflict with Eis
1452 *
1453 * PARAMETERS :
1454 * @stream_list : streams to be configured
1455 *
1456 * RETURN :
1457 * NO_ERROR if the usage flags are supported
1458 * error code if usage flags are not supported
1459 *
1460 *==========================================================================*/
1461int QCamera3HardwareInterface::validateUsageFlagsForEis(
1462 const camera3_stream_configuration_t* streamList)
1463{
1464 for (size_t j = 0; j < streamList->num_streams; j++) {
1465 const camera3_stream_t *newStream = streamList->streams[j];
1466
1467 bool isVideo = IS_USAGE_VIDEO(newStream->usage);
1468 bool isPreview = IS_USAGE_PREVIEW(newStream->usage);
1469
1470 // Because EIS is "hard-coded" for certain use case, and current
1471 // implementation doesn't support shared preview and video on the same
1472 // stream, return failure if EIS is forced on.
1473 if (isPreview && isVideo && m_bEisEnable && m_bEisSupportedSize) {
1474 LOGE("Combined video and preview usage flag is not supported due to EIS");
1475 return -EINVAL;
1476 }
1477 }
1478 return NO_ERROR;
1479}
1480
Thierry Strudel3d639192016-09-09 11:52:26 -07001481/*==============================================================================
1482 * FUNCTION : isSupportChannelNeeded
1483 *
1484 * DESCRIPTION: Simple heuristic func to determine if support channels is needed
1485 *
1486 * PARAMETERS :
1487 * @stream_list : streams to be configured
1488 * @stream_config_info : the config info for streams to be configured
1489 *
1490 * RETURN : Boolen true/false decision
1491 *
1492 *==========================================================================*/
1493bool QCamera3HardwareInterface::isSupportChannelNeeded(
1494 camera3_stream_configuration_t *streamList,
1495 cam_stream_size_info_t stream_config_info)
1496{
1497 uint32_t i;
1498 bool pprocRequested = false;
1499 /* Check for conditions where PProc pipeline does not have any streams*/
1500 for (i = 0; i < stream_config_info.num_streams; i++) {
1501 if (stream_config_info.type[i] != CAM_STREAM_TYPE_ANALYSIS &&
1502 stream_config_info.postprocess_mask[i] != CAM_QCOM_FEATURE_NONE) {
1503 pprocRequested = true;
1504 break;
1505 }
1506 }
1507
1508 if (pprocRequested == false )
1509 return true;
1510
1511 /* Dummy stream needed if only raw or jpeg streams present */
1512 for (i = 0; i < streamList->num_streams; i++) {
1513 switch(streamList->streams[i]->format) {
1514 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
1515 case HAL_PIXEL_FORMAT_RAW10:
1516 case HAL_PIXEL_FORMAT_RAW16:
1517 case HAL_PIXEL_FORMAT_BLOB:
1518 break;
1519 default:
1520 return false;
1521 }
1522 }
1523 return true;
1524}
1525
1526/*==============================================================================
Chien-Yu Chen8e599492016-11-01 13:37:46 -07001527 * FUNCTION : sensor_mode_info
Thierry Strudel3d639192016-09-09 11:52:26 -07001528 *
Chien-Yu Chen8e599492016-11-01 13:37:46 -07001529 * DESCRIPTION: Get sensor mode information based on current stream configuratoin
Thierry Strudel3d639192016-09-09 11:52:26 -07001530 *
1531 * PARAMETERS :
Chien-Yu Chen8e599492016-11-01 13:37:46 -07001532 * @sensor_mode_info : sensor mode information (output)
Thierry Strudel3d639192016-09-09 11:52:26 -07001533 *
1534 * RETURN : int32_t type of status
1535 * NO_ERROR -- success
1536 * none-zero failure code
1537 *
1538 *==========================================================================*/
Chien-Yu Chen8e599492016-11-01 13:37:46 -07001539int32_t QCamera3HardwareInterface::getSensorModeInfo(cam_sensor_mode_info_t &sensorModeInfo)
Thierry Strudel3d639192016-09-09 11:52:26 -07001540{
1541 int32_t rc = NO_ERROR;
1542
1543 cam_dimension_t max_dim = {0, 0};
1544 for (uint32_t i = 0; i < mStreamConfigInfo.num_streams; i++) {
1545 if (mStreamConfigInfo.stream_sizes[i].width > max_dim.width)
1546 max_dim.width = mStreamConfigInfo.stream_sizes[i].width;
1547 if (mStreamConfigInfo.stream_sizes[i].height > max_dim.height)
1548 max_dim.height = mStreamConfigInfo.stream_sizes[i].height;
1549 }
1550
1551 clear_metadata_buffer(mParameters);
1552
1553 rc = ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_PARM_MAX_DIMENSION,
1554 max_dim);
1555 if (rc != NO_ERROR) {
1556 LOGE("Failed to update table for CAM_INTF_PARM_MAX_DIMENSION");
1557 return rc;
1558 }
1559
1560 rc = mCameraHandle->ops->set_parms(mCameraHandle->camera_handle, mParameters);
1561 if (rc != NO_ERROR) {
1562 LOGE("Failed to set CAM_INTF_PARM_MAX_DIMENSION");
1563 return rc;
1564 }
1565
1566 clear_metadata_buffer(mParameters);
Chien-Yu Chen8e599492016-11-01 13:37:46 -07001567 ADD_GET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_PARM_SENSOR_MODE_INFO);
Thierry Strudel3d639192016-09-09 11:52:26 -07001568
1569 rc = mCameraHandle->ops->get_parms(mCameraHandle->camera_handle,
1570 mParameters);
1571 if (rc != NO_ERROR) {
Chien-Yu Chen8e599492016-11-01 13:37:46 -07001572 LOGE("Failed to get CAM_INTF_PARM_SENSOR_MODE_INFO");
Thierry Strudel3d639192016-09-09 11:52:26 -07001573 return rc;
1574 }
1575
Chien-Yu Chen8e599492016-11-01 13:37:46 -07001576 READ_PARAM_ENTRY(mParameters, CAM_INTF_PARM_SENSOR_MODE_INFO, sensorModeInfo);
Chien-Yu Chenee335912017-02-09 17:53:20 -08001577 LOGH("%s: active array size %dx%d, pixel array size %dx%d, output pixel clock %u, "
1578 "raw bits: %d", __FUNCTION__, sensorModeInfo.active_array_size.width,
1579 sensorModeInfo.active_array_size.height, sensorModeInfo.pixel_array_size.width,
1580 sensorModeInfo.pixel_array_size.height, sensorModeInfo.op_pixel_clk,
1581 sensorModeInfo.num_raw_bits);
Thierry Strudel3d639192016-09-09 11:52:26 -07001582
1583 return rc;
1584}
1585
1586/*==============================================================================
Chien-Yu Chen605c3872017-06-14 11:09:23 -07001587 * FUNCTION : getCurrentSensorModeInfo
1588 *
1589 * DESCRIPTION: Get sensor mode information that is currently selected.
1590 *
1591 * PARAMETERS :
1592 * @sensorModeInfo : sensor mode information (output)
1593 *
1594 * RETURN : int32_t type of status
1595 * NO_ERROR -- success
1596 * none-zero failure code
1597 *
1598 *==========================================================================*/
1599int32_t QCamera3HardwareInterface::getCurrentSensorModeInfo(cam_sensor_mode_info_t &sensorModeInfo)
1600{
1601 int32_t rc = NO_ERROR;
1602
1603 clear_metadata_buffer(mParameters);
1604 ADD_GET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_PARM_CURRENT_SENSOR_MODE_INFO);
1605
1606 rc = mCameraHandle->ops->get_parms(mCameraHandle->camera_handle,
1607 mParameters);
1608 if (rc != NO_ERROR) {
1609 LOGE("Failed to get CAM_INTF_PARM_SENSOR_MODE_INFO");
1610 return rc;
1611 }
1612
1613 READ_PARAM_ENTRY(mParameters, CAM_INTF_PARM_CURRENT_SENSOR_MODE_INFO, sensorModeInfo);
1614 LOGH("%s: active array size %dx%d, pixel array size %dx%d, output pixel clock %u, "
1615 "raw bits: %d", __FUNCTION__, sensorModeInfo.active_array_size.width,
1616 sensorModeInfo.active_array_size.height, sensorModeInfo.pixel_array_size.width,
1617 sensorModeInfo.pixel_array_size.height, sensorModeInfo.op_pixel_clk,
1618 sensorModeInfo.num_raw_bits);
1619
1620 return rc;
1621}
1622
1623/*==============================================================================
Thierry Strudel3d639192016-09-09 11:52:26 -07001624 * FUNCTION : addToPPFeatureMask
1625 *
1626 * DESCRIPTION: add additional features to pp feature mask based on
1627 * stream type and usecase
1628 *
1629 * PARAMETERS :
1630 * @stream_format : stream type for feature mask
1631 * @stream_idx : stream idx within postprocess_mask list to change
1632 *
1633 * RETURN : NULL
1634 *
1635 *==========================================================================*/
1636void QCamera3HardwareInterface::addToPPFeatureMask(int stream_format,
1637 uint32_t stream_idx)
1638{
1639 char feature_mask_value[PROPERTY_VALUE_MAX];
1640 cam_feature_mask_t feature_mask;
1641 int args_converted;
1642 int property_len;
1643
1644 /* Get feature mask from property */
Thierry Strudel269c81a2016-10-12 12:13:59 -07001645#ifdef _LE_CAMERA_
1646 char swtnr_feature_mask_value[PROPERTY_VALUE_MAX];
1647 snprintf(swtnr_feature_mask_value, PROPERTY_VALUE_MAX, "%lld", CAM_QTI_FEATURE_SW_TNR);
1648 property_len = property_get("persist.camera.hal3.feature",
1649 feature_mask_value, swtnr_feature_mask_value);
1650#else
Thierry Strudel3d639192016-09-09 11:52:26 -07001651 property_len = property_get("persist.camera.hal3.feature",
1652 feature_mask_value, "0");
Thierry Strudel269c81a2016-10-12 12:13:59 -07001653#endif
Thierry Strudel3d639192016-09-09 11:52:26 -07001654 if ((property_len > 2) && (feature_mask_value[0] == '0') &&
1655 (feature_mask_value[1] == 'x')) {
1656 args_converted = sscanf(feature_mask_value, "0x%llx", &feature_mask);
1657 } else {
1658 args_converted = sscanf(feature_mask_value, "%lld", &feature_mask);
1659 }
1660 if (1 != args_converted) {
1661 feature_mask = 0;
1662 LOGE("Wrong feature mask %s", feature_mask_value);
1663 return;
1664 }
1665
1666 switch (stream_format) {
1667 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: {
1668 /* Add LLVD to pp feature mask only if video hint is enabled */
1669 if ((m_bIsVideo) && (feature_mask & CAM_QTI_FEATURE_SW_TNR)) {
1670 mStreamConfigInfo.postprocess_mask[stream_idx]
1671 |= CAM_QTI_FEATURE_SW_TNR;
1672 LOGH("Added SW TNR to pp feature mask");
1673 } else if ((m_bIsVideo) && (feature_mask & CAM_QCOM_FEATURE_LLVD)) {
1674 mStreamConfigInfo.postprocess_mask[stream_idx]
1675 |= CAM_QCOM_FEATURE_LLVD;
1676 LOGH("Added LLVD SeeMore to pp feature mask");
1677 }
Thierry Strudele80ad7c2016-12-06 10:16:27 -08001678 if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
1679 CAM_QCOM_FEATURE_STAGGERED_VIDEO_HDR) {
1680 mStreamConfigInfo.postprocess_mask[stream_idx] |= CAM_QCOM_FEATURE_STAGGERED_VIDEO_HDR;
1681 }
Thierry Strudel54dc9782017-02-15 12:12:10 -08001682 if ((m_bIsVideo) && (gCamCapability[mCameraId]->qcom_supported_feature_mask &
1683 CAM_QTI_FEATURE_BINNING_CORRECTION)) {
1684 mStreamConfigInfo.postprocess_mask[stream_idx] |=
1685 CAM_QTI_FEATURE_BINNING_CORRECTION;
1686 }
Thierry Strudel3d639192016-09-09 11:52:26 -07001687 break;
1688 }
1689 default:
1690 break;
1691 }
1692 LOGD("PP feature mask %llx",
1693 mStreamConfigInfo.postprocess_mask[stream_idx]);
1694}
1695
1696/*==============================================================================
1697 * FUNCTION : updateFpsInPreviewBuffer
1698 *
1699 * DESCRIPTION: update FPS information in preview buffer.
1700 *
1701 * PARAMETERS :
1702 * @metadata : pointer to metadata buffer
1703 * @frame_number: frame_number to look for in pending buffer list
1704 *
1705 * RETURN : None
1706 *
1707 *==========================================================================*/
1708void QCamera3HardwareInterface::updateFpsInPreviewBuffer(metadata_buffer_t *metadata,
1709 uint32_t frame_number)
1710{
1711 // Mark all pending buffers for this particular request
1712 // with corresponding framerate information
1713 for (List<PendingBuffersInRequest>::iterator req =
1714 mPendingBuffersMap.mPendingBuffersInRequest.begin();
1715 req != mPendingBuffersMap.mPendingBuffersInRequest.end(); req++) {
1716 for(List<PendingBufferInfo>::iterator j =
1717 req->mPendingBufferList.begin();
1718 j != req->mPendingBufferList.end(); j++) {
1719 QCamera3Channel *channel = (QCamera3Channel *)j->stream->priv;
1720 if ((req->frame_number == frame_number) &&
1721 (channel->getStreamTypeMask() &
1722 (1U << CAM_STREAM_TYPE_PREVIEW))) {
1723 IF_META_AVAILABLE(cam_fps_range_t, float_range,
1724 CAM_INTF_PARM_FPS_RANGE, metadata) {
1725 typeof (MetaData_t::refreshrate) cameraFps = float_range->max_fps;
1726 struct private_handle_t *priv_handle =
1727 (struct private_handle_t *)(*(j->buffer));
1728 setMetaData(priv_handle, UPDATE_REFRESH_RATE, &cameraFps);
1729 }
1730 }
1731 }
1732 }
1733}
1734
Thierry Strudelcca4d9c2016-10-20 08:25:53 -07001735/*==============================================================================
1736 * FUNCTION : updateTimeStampInPendingBuffers
1737 *
1738 * DESCRIPTION: update timestamp in display metadata for all pending buffers
1739 * of a frame number
1740 *
1741 * PARAMETERS :
1742 * @frame_number: frame_number. Timestamp will be set on pending buffers of this frame number
1743 * @timestamp : timestamp to be set
1744 *
1745 * RETURN : None
1746 *
1747 *==========================================================================*/
1748void QCamera3HardwareInterface::updateTimeStampInPendingBuffers(
1749 uint32_t frameNumber, nsecs_t timestamp)
1750{
1751 for (auto req = mPendingBuffersMap.mPendingBuffersInRequest.begin();
1752 req != mPendingBuffersMap.mPendingBuffersInRequest.end(); req++) {
Binhao Lin09245482017-08-31 18:25:29 -07001753 // WAR: save the av_timestamp to the next frame
1754 if(req->frame_number == frameNumber + 1) {
1755 req->av_timestamp = timestamp;
1756 }
1757
Thierry Strudelcca4d9c2016-10-20 08:25:53 -07001758 if (req->frame_number != frameNumber)
1759 continue;
1760
1761 for (auto k = req->mPendingBufferList.begin();
1762 k != req->mPendingBufferList.end(); k++ ) {
Binhao Lin09245482017-08-31 18:25:29 -07001763 // WAR: update timestamp when it's not VT usecase
1764 QCamera3Channel *channel = (QCamera3Channel *)k->stream->priv;
1765 if (!((1U << CAM_STREAM_TYPE_VIDEO) == channel->getStreamTypeMask() &&
1766 m_bAVTimerEnabled)) {
1767 struct private_handle_t *priv_handle =
1768 (struct private_handle_t *) (*(k->buffer));
1769 setMetaData(priv_handle, SET_VT_TIMESTAMP, &timestamp);
1770 }
Thierry Strudelcca4d9c2016-10-20 08:25:53 -07001771 }
1772 }
1773 return;
1774}
1775
Thierry Strudel3d639192016-09-09 11:52:26 -07001776/*===========================================================================
1777 * FUNCTION : configureStreams
1778 *
1779 * DESCRIPTION: Reset HAL camera device processing pipeline and set up new input
1780 * and output streams.
1781 *
1782 * PARAMETERS :
1783 * @stream_list : streams to be configured
1784 *
1785 * RETURN :
1786 *
1787 *==========================================================================*/
1788int QCamera3HardwareInterface::configureStreams(
1789 camera3_stream_configuration_t *streamList)
1790{
Thierry Strudele80ad7c2016-12-06 10:16:27 -08001791 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL3_CFG_STRMS);
Thierry Strudel3d639192016-09-09 11:52:26 -07001792 int rc = 0;
1793
1794 // Acquire perfLock before configure streams
Thierry Strudelc2ee3302016-11-17 12:33:12 -08001795 mPerfLockMgr.acquirePerfLock(PERF_LOCK_START_PREVIEW);
Thierry Strudel3d639192016-09-09 11:52:26 -07001796 rc = configureStreamsPerfLocked(streamList);
Thierry Strudelc2ee3302016-11-17 12:33:12 -08001797 mPerfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW);
Thierry Strudel3d639192016-09-09 11:52:26 -07001798
1799 return rc;
1800}
1801
1802/*===========================================================================
1803 * FUNCTION : configureStreamsPerfLocked
1804 *
1805 * DESCRIPTION: configureStreams while perfLock is held.
1806 *
1807 * PARAMETERS :
1808 * @stream_list : streams to be configured
1809 *
1810 * RETURN : int32_t type of status
1811 * NO_ERROR -- success
1812 * none-zero failure code
1813 *==========================================================================*/
1814int QCamera3HardwareInterface::configureStreamsPerfLocked(
1815 camera3_stream_configuration_t *streamList)
1816{
Thierry Strudele80ad7c2016-12-06 10:16:27 -08001817 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL3_CFG_STRMS_PERF_LKD);
Thierry Strudel3d639192016-09-09 11:52:26 -07001818 int rc = 0;
1819
1820 // Sanity check stream_list
1821 if (streamList == NULL) {
1822 LOGE("NULL stream configuration");
1823 return BAD_VALUE;
1824 }
1825 if (streamList->streams == NULL) {
1826 LOGE("NULL stream list");
1827 return BAD_VALUE;
1828 }
1829
1830 if (streamList->num_streams < 1) {
1831 LOGE("Bad number of streams requested: %d",
1832 streamList->num_streams);
1833 return BAD_VALUE;
1834 }
1835
1836 if (streamList->num_streams >= MAX_NUM_STREAMS) {
1837 LOGE("Maximum number of streams %d exceeded: %d",
1838 MAX_NUM_STREAMS, streamList->num_streams);
1839 return BAD_VALUE;
1840 }
1841
Jason Leec4cf5032017-05-24 18:31:41 -07001842 mOpMode = streamList->operation_mode;
1843 LOGD("mOpMode: %d", mOpMode);
1844
Shuzhen Wangbb03f5c2017-02-17 15:38:24 -08001845 rc = validateUsageFlags(streamList);
1846 if (rc != NO_ERROR) {
1847 return rc;
1848 }
1849
Chien-Yu Chen11c8edc2017-09-11 20:54:24 -07001850 // Disable HDR+ if it's enabled;
Chien-Yu Chen153c5172017-09-08 11:33:19 -07001851 {
1852 std::unique_lock<std::mutex> l(gHdrPlusClientLock);
1853 finishHdrPlusClientOpeningLocked(l);
1854 disableHdrPlusModeLocked();
1855 }
1856
Thierry Strudel3d639192016-09-09 11:52:26 -07001857 /* first invalidate all the steams in the mStreamList
1858 * if they appear again, they will be validated */
1859 for (List<stream_info_t*>::iterator it = mStreamInfo.begin();
1860 it != mStreamInfo.end(); it++) {
1861 QCamera3ProcessingChannel *channel = (QCamera3ProcessingChannel*)(*it)->stream->priv;
1862 if (channel) {
1863 channel->stop();
1864 }
1865 (*it)->status = INVALID;
1866 }
1867
1868 if (mRawDumpChannel) {
1869 mRawDumpChannel->stop();
1870 delete mRawDumpChannel;
1871 mRawDumpChannel = NULL;
1872 }
1873
Chien-Yu Chen8e599492016-11-01 13:37:46 -07001874 if (mHdrPlusRawSrcChannel) {
1875 mHdrPlusRawSrcChannel->stop();
1876 delete mHdrPlusRawSrcChannel;
1877 mHdrPlusRawSrcChannel = NULL;
1878 }
1879
Thierry Strudel3d639192016-09-09 11:52:26 -07001880 if (mSupportChannel)
1881 mSupportChannel->stop();
1882
1883 if (mAnalysisChannel) {
1884 mAnalysisChannel->stop();
1885 }
1886 if (mMetadataChannel) {
1887 /* If content of mStreamInfo is not 0, there is metadata stream */
1888 mMetadataChannel->stop();
1889 }
1890 if (mChannelHandle) {
Chien-Yu Chen153c5172017-09-08 11:33:19 -07001891 stopChannelLocked(/*stop_immediately*/false);
Thierry Strudel3d639192016-09-09 11:52:26 -07001892 }
1893
1894 pthread_mutex_lock(&mMutex);
1895
Chien-Yu Chendeaebad2017-06-30 11:46:34 -07001896 mPictureChannel = NULL;
1897
Thierry Strudel3d639192016-09-09 11:52:26 -07001898 // Check state
1899 switch (mState) {
1900 case INITIALIZED:
1901 case CONFIGURED:
1902 case STARTED:
1903 /* valid state */
1904 break;
1905 default:
1906 LOGE("Invalid state %d", mState);
1907 pthread_mutex_unlock(&mMutex);
1908 return -ENODEV;
1909 }
1910
1911 /* Check whether we have video stream */
1912 m_bIs4KVideo = false;
1913 m_bIsVideo = false;
Shuzhen Wangbdbe9e82017-09-27 12:22:46 -07001914 m_bEisSupportedSize = true;
Thierry Strudel3d639192016-09-09 11:52:26 -07001915 m_bTnrEnabled = false;
Mansoor Aftab93a66e52017-01-26 14:58:25 -08001916 m_bVideoHdrEnabled = false;
Thierry Strudel3d639192016-09-09 11:52:26 -07001917 bool isZsl = false;
Emilian Peev7650c122017-01-19 08:24:33 -08001918 bool depthPresent = false;
Shuzhen Wangbb03f5c2017-02-17 15:38:24 -08001919 bool isPreview = false;
Thierry Strudel3d639192016-09-09 11:52:26 -07001920 uint32_t videoWidth = 0U;
1921 uint32_t videoHeight = 0U;
1922 size_t rawStreamCnt = 0;
1923 size_t stallStreamCnt = 0;
1924 size_t processedStreamCnt = 0;
1925 // Number of streams on ISP encoder path
1926 size_t numStreamsOnEncoder = 0;
1927 size_t numYuv888OnEncoder = 0;
1928 bool bYuv888OverrideJpeg = false;
1929 cam_dimension_t largeYuv888Size = {0, 0};
1930 cam_dimension_t maxViewfinderSize = {0, 0};
1931 bool bJpegExceeds4K = false;
1932 bool bJpegOnEncoder = false;
1933 bool bUseCommonFeatureMask = false;
1934 cam_feature_mask_t commonFeatureMask = 0;
1935 bool bSmallJpegSize = false;
1936 uint32_t width_ratio;
1937 uint32_t height_ratio;
1938 maxViewfinderSize = gCamCapability[mCameraId]->max_viewfinder_size;
1939 camera3_stream_t *inputStream = NULL;
1940 bool isJpeg = false;
1941 cam_dimension_t jpegSize = {0, 0};
Thierry Strudel9ec39c62016-12-28 11:30:05 -08001942 cam_dimension_t previewSize = {0, 0};
Emilian Peev0f3c3162017-03-15 12:57:46 +00001943 size_t pdStatCount = 0;
Thierry Strudel3d639192016-09-09 11:52:26 -07001944
1945 cam_padding_info_t padding_info = gCamCapability[mCameraId]->padding_info;
1946
1947 /*EIS configuration*/
Thierry Strudel3d639192016-09-09 11:52:26 -07001948 uint8_t eis_prop_set;
1949 uint32_t maxEisWidth = 0;
1950 uint32_t maxEisHeight = 0;
1951
Thierry Strudel295a0ca2016-11-03 18:38:47 -07001952 // Initialize all instant AEC related variables
1953 mInstantAEC = false;
1954 mResetInstantAEC = false;
1955 mInstantAECSettledFrameNumber = 0;
1956 mAecSkipDisplayFrameBound = 0;
1957 mInstantAecFrameIdxCount = 0;
Thierry Strudel54dc9782017-02-15 12:12:10 -08001958 mCurrFeatureState = 0;
1959 mStreamConfig = true;
Thierry Strudel295a0ca2016-11-03 18:38:47 -07001960
Binhao Lin09245482017-08-31 18:25:29 -07001961 m_bAVTimerEnabled = false;
1962
Thierry Strudel3d639192016-09-09 11:52:26 -07001963 memset(&mInputStreamInfo, 0, sizeof(mInputStreamInfo));
1964
1965 size_t count = IS_TYPE_MAX;
1966 count = MIN(gCamCapability[mCameraId]->supported_is_types_cnt, count);
1967 for (size_t i = 0; i < count; i++) {
1968 if ((gCamCapability[mCameraId]->supported_is_types[i] == IS_TYPE_EIS_2_0) ||
Thierry Strudel9e74aae2016-09-22 17:10:18 -07001969 (gCamCapability[mCameraId]->supported_is_types[i] == IS_TYPE_EIS_3_0)) {
1970 m_bEisSupported = true;
Thierry Strudel3d639192016-09-09 11:52:26 -07001971 break;
1972 }
1973 }
Thierry Strudel3d639192016-09-09 11:52:26 -07001974
Thierry Strudel9e74aae2016-09-22 17:10:18 -07001975 if (m_bEisSupported) {
Thierry Strudel3d639192016-09-09 11:52:26 -07001976 maxEisWidth = MAX_EIS_WIDTH;
1977 maxEisHeight = MAX_EIS_HEIGHT;
1978 }
1979
1980 /* EIS setprop control */
1981 char eis_prop[PROPERTY_VALUE_MAX];
1982 memset(eis_prop, 0, sizeof(eis_prop));
Thierry Strudel9e74aae2016-09-22 17:10:18 -07001983 property_get("persist.camera.eis.enable", eis_prop, "1");
Thierry Strudel3d639192016-09-09 11:52:26 -07001984 eis_prop_set = (uint8_t)atoi(eis_prop);
1985
Mansoor Aftabb9370df2017-03-15 17:09:34 -07001986 m_bEisEnable = eis_prop_set && m_bEisSupported &&
Shuzhen Wangbdbe9e82017-09-27 12:22:46 -07001987 (mOpMode != CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE) &&
1988 (gCamCapability[mCameraId]->position == CAM_POSITION_BACK ||
1989 gCamCapability[mCameraId]->position == CAM_POSITION_BACK_AUX);
Thierry Strudel3d639192016-09-09 11:52:26 -07001990
Mansoor Aftabb9370df2017-03-15 17:09:34 -07001991 LOGD("m_bEisEnable: %d, eis_prop_set: %d, m_bEisSupported: %d",
1992 m_bEisEnable, eis_prop_set, m_bEisSupported);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07001993
Thierry Strudel3d639192016-09-09 11:52:26 -07001994 /* stream configurations */
1995 for (size_t i = 0; i < streamList->num_streams; i++) {
1996 camera3_stream_t *newStream = streamList->streams[i];
1997 LOGI("stream[%d] type = %d, format = %d, width = %d, "
1998 "height = %d, rotation = %d, usage = 0x%x",
1999 i, newStream->stream_type, newStream->format,
2000 newStream->width, newStream->height, newStream->rotation,
2001 newStream->usage);
2002 if (newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL ||
2003 newStream->stream_type == CAMERA3_STREAM_INPUT){
2004 isZsl = true;
2005 }
Shuzhen Wangbb03f5c2017-02-17 15:38:24 -08002006 if ((HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED == newStream->format) &&
2007 IS_USAGE_PREVIEW(newStream->usage)) {
2008 isPreview = true;
2009 }
2010
Thierry Strudel3d639192016-09-09 11:52:26 -07002011 if (newStream->stream_type == CAMERA3_STREAM_INPUT){
2012 inputStream = newStream;
2013 }
2014
Emilian Peev7650c122017-01-19 08:24:33 -08002015 if ((newStream->format == HAL_PIXEL_FORMAT_BLOB) &&
2016 (newStream->data_space != HAL_DATASPACE_DEPTH)) {
Thierry Strudel3d639192016-09-09 11:52:26 -07002017 isJpeg = true;
2018 jpegSize.width = newStream->width;
2019 jpegSize.height = newStream->height;
2020 if (newStream->width > VIDEO_4K_WIDTH ||
2021 newStream->height > VIDEO_4K_HEIGHT)
2022 bJpegExceeds4K = true;
2023 }
2024
2025 if ((HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED == newStream->format) &&
Shuzhen Wangbdbe9e82017-09-27 12:22:46 -07002026 (IS_USAGE_PREVIEW(newStream->usage) || IS_USAGE_VIDEO(newStream->usage))) {
2027 if (IS_USAGE_VIDEO(newStream->usage)) {
2028 m_bIsVideo = true;
2029 // In HAL3 we can have multiple different video streams.
2030 // The variables video width and height are used below as
2031 // dimensions of the biggest of them
2032 if (videoWidth < newStream->width || videoHeight < newStream->height) {
2033 videoWidth = newStream->width;
2034 videoHeight = newStream->height;
2035 }
2036 if ((VIDEO_4K_WIDTH <= newStream->width) &&
2037 (VIDEO_4K_HEIGHT <= newStream->height)) {
2038 m_bIs4KVideo = true;
2039 }
Thierry Strudel2896d122017-02-23 19:18:03 -08002040 }
Shuzhen Wangbdbe9e82017-09-27 12:22:46 -07002041 m_bEisSupportedSize &= (newStream->width <= maxEisWidth) &&
Thierry Strudel3d639192016-09-09 11:52:26 -07002042 (newStream->height <= maxEisHeight);
2043 }
2044 if (newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL ||
2045 newStream->stream_type == CAMERA3_STREAM_OUTPUT) {
2046 switch (newStream->format) {
2047 case HAL_PIXEL_FORMAT_BLOB:
Emilian Peev7650c122017-01-19 08:24:33 -08002048 if (newStream->data_space == HAL_DATASPACE_DEPTH) {
2049 depthPresent = true;
2050 break;
2051 }
Thierry Strudel3d639192016-09-09 11:52:26 -07002052 stallStreamCnt++;
2053 if (isOnEncoder(maxViewfinderSize, newStream->width,
2054 newStream->height)) {
2055 numStreamsOnEncoder++;
2056 bJpegOnEncoder = true;
2057 }
2058 width_ratio = CEIL_DIVISION(gCamCapability[mCameraId]->active_array_size.width,
2059 newStream->width);
2060 height_ratio = CEIL_DIVISION(gCamCapability[mCameraId]->active_array_size.height,
2061 newStream->height);;
2062 FATAL_IF(gCamCapability[mCameraId]->max_downscale_factor == 0,
2063 "FATAL: max_downscale_factor cannot be zero and so assert");
2064 if ( (width_ratio > gCamCapability[mCameraId]->max_downscale_factor) ||
2065 (height_ratio > gCamCapability[mCameraId]->max_downscale_factor)) {
2066 LOGH("Setting small jpeg size flag to true");
2067 bSmallJpegSize = true;
2068 }
2069 break;
2070 case HAL_PIXEL_FORMAT_RAW10:
2071 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
2072 case HAL_PIXEL_FORMAT_RAW16:
2073 rawStreamCnt++;
Emilian Peev0f3c3162017-03-15 12:57:46 +00002074 if ((HAL_DATASPACE_DEPTH == newStream->data_space) &&
2075 (HAL_PIXEL_FORMAT_RAW16 == newStream->format)) {
2076 pdStatCount++;
2077 }
Thierry Strudel3d639192016-09-09 11:52:26 -07002078 break;
2079 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
2080 processedStreamCnt++;
2081 if (isOnEncoder(maxViewfinderSize, newStream->width,
2082 newStream->height)) {
2083 if (newStream->stream_type != CAMERA3_STREAM_BIDIRECTIONAL &&
2084 !IS_USAGE_ZSL(newStream->usage)) {
2085 commonFeatureMask |= CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
2086 }
2087 numStreamsOnEncoder++;
2088 }
2089 break;
2090 case HAL_PIXEL_FORMAT_YCbCr_420_888:
2091 processedStreamCnt++;
2092 if (isOnEncoder(maxViewfinderSize, newStream->width,
2093 newStream->height)) {
2094 // If Yuv888 size is not greater than 4K, set feature mask
2095 // to SUPERSET so that it support concurrent request on
2096 // YUV and JPEG.
2097 if (newStream->width <= VIDEO_4K_WIDTH &&
2098 newStream->height <= VIDEO_4K_HEIGHT) {
2099 commonFeatureMask |= CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
2100 }
2101 numStreamsOnEncoder++;
2102 numYuv888OnEncoder++;
2103 largeYuv888Size.width = newStream->width;
2104 largeYuv888Size.height = newStream->height;
2105 }
2106 break;
2107 default:
2108 processedStreamCnt++;
2109 if (isOnEncoder(maxViewfinderSize, newStream->width,
2110 newStream->height)) {
2111 commonFeatureMask |= CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
2112 numStreamsOnEncoder++;
2113 }
2114 break;
2115 }
2116
2117 }
2118 }
2119
Shuzhen Wangbb03f5c2017-02-17 15:38:24 -08002120 if (validateUsageFlagsForEis(streamList) != NO_ERROR) {
2121 pthread_mutex_unlock(&mMutex);
2122 return -EINVAL;
2123 }
2124
Thierry Strudel54dc9782017-02-15 12:12:10 -08002125 uint8_t forceEnableTnr = 0;
2126 char tnr_prop[PROPERTY_VALUE_MAX];
2127 memset(tnr_prop, 0, sizeof(tnr_prop));
2128 property_get("debug.camera.tnr.forceenable", tnr_prop, "0");
2129 forceEnableTnr = (uint8_t)atoi(tnr_prop);
2130
Thierry Strudel3d639192016-09-09 11:52:26 -07002131 /* Logic to enable/disable TNR based on specific config size/etc.*/
2132 if ((m_bTnrPreview || m_bTnrVideo) && m_bIsVideo &&
Thierry Strudel3d639192016-09-09 11:52:26 -07002133 (mOpMode != CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE))
2134 m_bTnrEnabled = true;
Thierry Strudel54dc9782017-02-15 12:12:10 -08002135 else if (forceEnableTnr)
2136 m_bTnrEnabled = true;
Thierry Strudel3d639192016-09-09 11:52:26 -07002137
Mansoor Aftab93a66e52017-01-26 14:58:25 -08002138 char videoHdrProp[PROPERTY_VALUE_MAX];
2139 memset(videoHdrProp, 0, sizeof(videoHdrProp));
2140 property_get("persist.camera.hdr.video", videoHdrProp, "0");
2141 uint8_t hdr_mode_prop = (uint8_t)atoi(videoHdrProp);
2142
2143 if (hdr_mode_prop == 1 && m_bIsVideo &&
2144 mOpMode != CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE)
2145 m_bVideoHdrEnabled = true;
2146 else
2147 m_bVideoHdrEnabled = false;
2148
2149
Thierry Strudel3d639192016-09-09 11:52:26 -07002150 /* Check if num_streams is sane */
2151 if (stallStreamCnt > MAX_STALLING_STREAMS ||
2152 rawStreamCnt > MAX_RAW_STREAMS ||
2153 processedStreamCnt > MAX_PROCESSED_STREAMS) {
2154 LOGE("Invalid stream configu: stall: %d, raw: %d, processed %d",
2155 stallStreamCnt, rawStreamCnt, processedStreamCnt);
2156 pthread_mutex_unlock(&mMutex);
2157 return -EINVAL;
2158 }
2159 /* Check whether we have zsl stream or 4k video case */
Thierry Strudel9ec39c62016-12-28 11:30:05 -08002160 if (isZsl && m_bIs4KVideo) {
2161 LOGE("Currently invalid configuration ZSL & 4K Video!");
Thierry Strudel3d639192016-09-09 11:52:26 -07002162 pthread_mutex_unlock(&mMutex);
2163 return -EINVAL;
2164 }
2165 /* Check if stream sizes are sane */
2166 if (numStreamsOnEncoder > 2) {
2167 LOGE("Number of streams on ISP encoder path exceeds limits of 2");
2168 pthread_mutex_unlock(&mMutex);
2169 return -EINVAL;
2170 } else if (1 < numStreamsOnEncoder){
2171 bUseCommonFeatureMask = true;
2172 LOGH("Multiple streams above max viewfinder size, common mask needed");
2173 }
2174
2175 /* Check if BLOB size is greater than 4k in 4k recording case */
2176 if (m_bIs4KVideo && bJpegExceeds4K) {
2177 LOGE("HAL doesn't support Blob size greater than 4k in 4k recording");
2178 pthread_mutex_unlock(&mMutex);
2179 return -EINVAL;
2180 }
2181
Emilian Peev7650c122017-01-19 08:24:33 -08002182 if ((mOpMode == CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE) &&
2183 depthPresent) {
2184 LOGE("HAL doesn't support depth streams in HFR mode!");
2185 pthread_mutex_unlock(&mMutex);
2186 return -EINVAL;
2187 }
2188
Thierry Strudel3d639192016-09-09 11:52:26 -07002189 // When JPEG and preview streams share VFE output, CPP will not apply CAC2
2190 // on JPEG stream. So disable such configurations to ensure CAC2 is applied.
2191 // Don't fail for reprocess configurations. Also don't fail if bJpegExceeds4K
2192 // is not true. Otherwise testMandatoryOutputCombinations will fail with following
2193 // configurations:
2194 // {[PRIV, PREVIEW] [PRIV, RECORD] [JPEG, RECORD]}
2195 // {[PRIV, PREVIEW] [YUV, RECORD] [JPEG, RECORD]}
2196 // (These two configurations will not have CAC2 enabled even in HQ modes.)
2197 if (!isZsl && bJpegOnEncoder && bJpegExceeds4K && bUseCommonFeatureMask) {
2198 ALOGE("%s: Blob size greater than 4k and multiple streams are on encoder output",
2199 __func__);
2200 pthread_mutex_unlock(&mMutex);
2201 return -EINVAL;
2202 }
2203
2204 // If jpeg stream is available, and a YUV 888 stream is on Encoder path, and
2205 // the YUV stream's size is greater or equal to the JPEG size, set common
2206 // postprocess mask to NONE, so that we can take advantage of postproc bypass.
2207 if (numYuv888OnEncoder && isOnEncoder(maxViewfinderSize,
2208 jpegSize.width, jpegSize.height) &&
2209 largeYuv888Size.width > jpegSize.width &&
2210 largeYuv888Size.height > jpegSize.height) {
2211 bYuv888OverrideJpeg = true;
2212 } else if (!isJpeg && numStreamsOnEncoder > 1) {
2213 commonFeatureMask = CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
2214 }
2215
2216 LOGH("max viewfinder width %d height %d isZsl %d bUseCommonFeature %x commonFeatureMask %llx",
2217 maxViewfinderSize.width, maxViewfinderSize.height, isZsl, bUseCommonFeatureMask,
2218 commonFeatureMask);
2219 LOGH("numStreamsOnEncoder %d, processedStreamCnt %d, stallcnt %d bSmallJpegSize %d",
2220 numStreamsOnEncoder, processedStreamCnt, stallStreamCnt, bSmallJpegSize);
2221
2222 rc = validateStreamDimensions(streamList);
2223 if (rc == NO_ERROR) {
2224 rc = validateStreamRotations(streamList);
2225 }
2226 if (rc != NO_ERROR) {
2227 LOGE("Invalid stream configuration requested!");
2228 pthread_mutex_unlock(&mMutex);
2229 return rc;
2230 }
2231
Emilian Peev0f3c3162017-03-15 12:57:46 +00002232 if (1 < pdStatCount) {
2233 LOGE("HAL doesn't support multiple PD streams");
2234 pthread_mutex_unlock(&mMutex);
2235 return -EINVAL;
2236 }
2237
2238 if ((mOpMode == CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE) &&
2239 (1 == pdStatCount)) {
2240 LOGE("HAL doesn't support PD streams in HFR mode!");
2241 pthread_mutex_unlock(&mMutex);
2242 return -EINVAL;
2243 }
2244
Thierry Strudel3d639192016-09-09 11:52:26 -07002245 camera3_stream_t *zslStream = NULL; //Only use this for size and not actual handle!
2246 for (size_t i = 0; i < streamList->num_streams; i++) {
2247 camera3_stream_t *newStream = streamList->streams[i];
2248 LOGH("newStream type = %d, stream format = %d "
2249 "stream size : %d x %d, stream rotation = %d",
2250 newStream->stream_type, newStream->format,
2251 newStream->width, newStream->height, newStream->rotation);
2252 //if the stream is in the mStreamList validate it
2253 bool stream_exists = false;
2254 for (List<stream_info_t*>::iterator it=mStreamInfo.begin();
2255 it != mStreamInfo.end(); it++) {
2256 if ((*it)->stream == newStream) {
2257 QCamera3ProcessingChannel *channel =
2258 (QCamera3ProcessingChannel*)(*it)->stream->priv;
2259 stream_exists = true;
2260 if (channel)
2261 delete channel;
2262 (*it)->status = VALID;
2263 (*it)->stream->priv = NULL;
2264 (*it)->channel = NULL;
2265 }
2266 }
2267 if (!stream_exists && newStream->stream_type != CAMERA3_STREAM_INPUT) {
2268 //new stream
2269 stream_info_t* stream_info;
2270 stream_info = (stream_info_t* )malloc(sizeof(stream_info_t));
2271 if (!stream_info) {
2272 LOGE("Could not allocate stream info");
2273 rc = -ENOMEM;
2274 pthread_mutex_unlock(&mMutex);
2275 return rc;
2276 }
2277 stream_info->stream = newStream;
2278 stream_info->status = VALID;
2279 stream_info->channel = NULL;
Chien-Yu Chen3d836272017-09-20 11:10:21 -07002280 stream_info->id = i; // ID will be re-assigned in cleanAndSortStreamInfo().
Thierry Strudel3d639192016-09-09 11:52:26 -07002281 mStreamInfo.push_back(stream_info);
2282 }
2283 /* Covers Opaque ZSL and API1 F/W ZSL */
2284 if (IS_USAGE_ZSL(newStream->usage)
2285 || newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL ) {
2286 if (zslStream != NULL) {
2287 LOGE("Multiple input/reprocess streams requested!");
2288 pthread_mutex_unlock(&mMutex);
2289 return BAD_VALUE;
2290 }
2291 zslStream = newStream;
2292 }
2293 /* Covers YUV reprocess */
2294 if (inputStream != NULL) {
2295 if (newStream->stream_type == CAMERA3_STREAM_OUTPUT
2296 && newStream->format == HAL_PIXEL_FORMAT_YCbCr_420_888
2297 && inputStream->format == HAL_PIXEL_FORMAT_YCbCr_420_888
2298 && inputStream->width == newStream->width
2299 && inputStream->height == newStream->height) {
2300 if (zslStream != NULL) {
2301 /* This scenario indicates multiple YUV streams with same size
2302 * as input stream have been requested, since zsl stream handle
2303 * is solely use for the purpose of overriding the size of streams
2304 * which share h/w streams we will just make a guess here as to
2305 * which of the stream is a ZSL stream, this will be refactored
2306 * once we make generic logic for streams sharing encoder output
2307 */
2308 LOGH("Warning, Multiple ip/reprocess streams requested!");
2309 }
2310 zslStream = newStream;
2311 }
2312 }
2313 }
2314
2315 /* If a zsl stream is set, we know that we have configured at least one input or
2316 bidirectional stream */
2317 if (NULL != zslStream) {
2318 mInputStreamInfo.dim.width = (int32_t)zslStream->width;
2319 mInputStreamInfo.dim.height = (int32_t)zslStream->height;
2320 mInputStreamInfo.format = zslStream->format;
2321 mInputStreamInfo.usage = zslStream->usage;
2322 LOGD("Input stream configured! %d x %d, format %d, usage %d",
2323 mInputStreamInfo.dim.width,
2324 mInputStreamInfo.dim.height,
2325 mInputStreamInfo.format, mInputStreamInfo.usage);
2326 }
2327
2328 cleanAndSortStreamInfo();
2329 if (mMetadataChannel) {
2330 delete mMetadataChannel;
2331 mMetadataChannel = NULL;
2332 }
2333 if (mSupportChannel) {
2334 delete mSupportChannel;
2335 mSupportChannel = NULL;
2336 }
2337
2338 if (mAnalysisChannel) {
2339 delete mAnalysisChannel;
2340 mAnalysisChannel = NULL;
2341 }
2342
2343 if (mDummyBatchChannel) {
2344 delete mDummyBatchChannel;
2345 mDummyBatchChannel = NULL;
2346 }
2347
Emilian Peev7650c122017-01-19 08:24:33 -08002348 if (mDepthChannel) {
2349 mDepthChannel = NULL;
2350 }
Emilian Peev656e4fa2017-06-02 16:47:04 +01002351 mDepthCloudMode = CAM_PD_DATA_SKIP;
Emilian Peev7650c122017-01-19 08:24:33 -08002352
Chien-Yu Chen3f303522017-05-19 15:21:45 -07002353 mShutterDispatcher.clear();
2354 mOutputBufferDispatcher.clear();
2355
Thierry Strudel2896d122017-02-23 19:18:03 -08002356 char is_type_value[PROPERTY_VALUE_MAX];
2357 property_get("persist.camera.is_type", is_type_value, "4");
2358 m_bEis3PropertyEnabled = (atoi(is_type_value) == IS_TYPE_EIS_3_0);
2359
Binhao Line406f062017-05-03 14:39:44 -07002360 char property_value[PROPERTY_VALUE_MAX];
2361 property_get("persist.camera.gzoom.at", property_value, "0");
2362 int goog_zoom_at = atoi(property_value);
Jason Leec4cf5032017-05-24 18:31:41 -07002363 bool is_goog_zoom_video_enabled = ((goog_zoom_at & 1) > 0) &&
2364 gCamCapability[mCameraId]->position == CAM_POSITION_BACK;
2365 bool is_goog_zoom_preview_enabled = ((goog_zoom_at & 2) > 0) &&
2366 gCamCapability[mCameraId]->position == CAM_POSITION_BACK;
Binhao Line406f062017-05-03 14:39:44 -07002367
2368 property_get("persist.camera.gzoom.4k", property_value, "0");
2369 bool is_goog_zoom_4k_enabled = (atoi(property_value) > 0);
2370
Thierry Strudel3d639192016-09-09 11:52:26 -07002371 //Create metadata channel and initialize it
2372 cam_feature_mask_t metadataFeatureMask = CAM_QCOM_FEATURE_NONE;
2373 setPAAFSupport(metadataFeatureMask, CAM_STREAM_TYPE_METADATA,
2374 gCamCapability[mCameraId]->color_arrangement);
2375 mMetadataChannel = new QCamera3MetadataChannel(mCameraHandle->camera_handle,
2376 mChannelHandle, mCameraHandle->ops, captureResultCb,
Thierry Strudelc2ee3302016-11-17 12:33:12 -08002377 setBufferErrorStatus, &padding_info, metadataFeatureMask, this);
Thierry Strudel3d639192016-09-09 11:52:26 -07002378 if (mMetadataChannel == NULL) {
2379 LOGE("failed to allocate metadata channel");
2380 rc = -ENOMEM;
2381 pthread_mutex_unlock(&mMutex);
2382 return rc;
2383 }
Emilian Peev662c05e2017-05-16 10:00:04 +01002384 mMetadataChannel->enableDepthData(depthPresent);
Thierry Strudel3d639192016-09-09 11:52:26 -07002385 rc = mMetadataChannel->initialize(IS_TYPE_NONE);
2386 if (rc < 0) {
2387 LOGE("metadata channel initialization failed");
2388 delete mMetadataChannel;
2389 mMetadataChannel = NULL;
2390 pthread_mutex_unlock(&mMutex);
2391 return rc;
2392 }
2393
Thierry Strudel2896d122017-02-23 19:18:03 -08002394 cam_feature_mask_t zsl_ppmask = CAM_QCOM_FEATURE_NONE;
Thierry Strudel3d639192016-09-09 11:52:26 -07002395 bool isRawStreamRequested = false;
Thierry Strudel2896d122017-02-23 19:18:03 -08002396 bool onlyRaw = true;
Binhao Lincdb362a2017-04-20 13:31:54 -07002397 // Keep track of preview/video streams indices.
2398 // There could be more than one preview streams, but only one video stream.
2399 int32_t video_stream_idx = -1;
2400 int32_t preview_stream_idx[streamList->num_streams];
2401 size_t preview_stream_cnt = 0;
Jason Leea52b77e2017-06-27 16:16:17 -07002402 bool previewTnr[streamList->num_streams];
2403 memset(previewTnr, 0, sizeof(bool) * streamList->num_streams);
2404 bool isFront = gCamCapability[mCameraId]->position == CAM_POSITION_FRONT;
2405 // Loop through once to determine preview TNR conditions before creating channels.
2406 for (size_t i = 0; i < streamList->num_streams; i++) {
2407 camera3_stream_t *newStream = streamList->streams[i];
2408 uint32_t stream_usage = newStream->usage;
2409 if (newStream->stream_type == CAMERA3_STREAM_OUTPUT &&
2410 newStream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
2411 if (stream_usage & private_handle_t::PRIV_FLAGS_VIDEO_ENCODER)
2412 video_stream_idx = (int32_t)i;
2413 else
2414 preview_stream_idx[preview_stream_cnt++] = (int32_t)i;
2415 }
2416 }
2417 // By default, preview stream TNR is disabled.
2418 // Enable TNR to the preview stream if all conditions below are satisfied:
2419 // 1. preview resolution == video resolution.
2420 // 2. video stream TNR is enabled.
2421 // 3. EIS2.0 OR is front camera (which wouldn't use EIS3 even if it's set)
2422 for (size_t i = 0; i < preview_stream_cnt && video_stream_idx != -1; i++) {
2423 camera3_stream_t *video_stream = streamList->streams[video_stream_idx];
2424 camera3_stream_t *preview_stream = streamList->streams[preview_stream_idx[i]];
2425 if (m_bTnrEnabled && m_bTnrVideo &&
2426 (isFront || (atoi(is_type_value) == IS_TYPE_EIS_2_0)) &&
2427 video_stream->width == preview_stream->width &&
2428 video_stream->height == preview_stream->height) {
2429 previewTnr[preview_stream_idx[i]] = true;
2430 }
2431 }
2432
Thierry Strudel3d639192016-09-09 11:52:26 -07002433 memset(&mStreamConfigInfo, 0, sizeof(cam_stream_size_info_t));
2434 /* Allocate channel objects for the requested streams */
2435 for (size_t i = 0; i < streamList->num_streams; i++) {
Binhao Line406f062017-05-03 14:39:44 -07002436
Thierry Strudel3d639192016-09-09 11:52:26 -07002437 camera3_stream_t *newStream = streamList->streams[i];
2438 uint32_t stream_usage = newStream->usage;
2439 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].width = (int32_t)newStream->width;
2440 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].height = (int32_t)newStream->height;
2441 struct camera_info *p_info = NULL;
2442 pthread_mutex_lock(&gCamLock);
2443 p_info = get_cam_info(mCameraId, &mStreamConfigInfo.sync_type);
2444 pthread_mutex_unlock(&gCamLock);
2445 if ((newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL
2446 || IS_USAGE_ZSL(newStream->usage)) &&
2447 newStream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED){
Thierry Strudel2896d122017-02-23 19:18:03 -08002448 onlyRaw = false; // There is non-raw stream - bypass flag if set
Thierry Strudel3d639192016-09-09 11:52:26 -07002449 mStreamConfigInfo.type[mStreamConfigInfo.num_streams] = CAM_STREAM_TYPE_SNAPSHOT;
Thierry Strudel2896d122017-02-23 19:18:03 -08002450 if (isOnEncoder(maxViewfinderSize, newStream->width, newStream->height)) {
2451 if (bUseCommonFeatureMask)
2452 zsl_ppmask = commonFeatureMask;
2453 else
2454 zsl_ppmask = CAM_QCOM_FEATURE_NONE;
Thierry Strudel3d639192016-09-09 11:52:26 -07002455 } else {
Thierry Strudel2896d122017-02-23 19:18:03 -08002456 if (numStreamsOnEncoder > 0)
2457 zsl_ppmask = CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
2458 else
2459 zsl_ppmask = CAM_QCOM_FEATURE_NONE;
Thierry Strudel3d639192016-09-09 11:52:26 -07002460 }
Thierry Strudel2896d122017-02-23 19:18:03 -08002461 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] = zsl_ppmask;
Thierry Strudel3d639192016-09-09 11:52:26 -07002462 } else if(newStream->stream_type == CAMERA3_STREAM_INPUT) {
Thierry Strudel2896d122017-02-23 19:18:03 -08002463 onlyRaw = false; // There is non-raw stream - bypass flag if set
Thierry Strudel3d639192016-09-09 11:52:26 -07002464 LOGH("Input stream configured, reprocess config");
2465 } else {
2466 //for non zsl streams find out the format
2467 switch (newStream->format) {
2468 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED :
2469 {
Thierry Strudel2896d122017-02-23 19:18:03 -08002470 onlyRaw = false; // There is non-raw stream - bypass flag if set
Thierry Strudel3d639192016-09-09 11:52:26 -07002471 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] =
2472 CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
2473 /* add additional features to pp feature mask */
2474 addToPPFeatureMask(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
2475 mStreamConfigInfo.num_streams);
2476
2477 if (stream_usage & private_handle_t::PRIV_FLAGS_VIDEO_ENCODER) {
2478 mStreamConfigInfo.type[mStreamConfigInfo.num_streams] =
2479 CAM_STREAM_TYPE_VIDEO;
2480 if (m_bTnrEnabled && m_bTnrVideo) {
2481 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] |=
2482 CAM_QCOM_FEATURE_CPP_TNR;
2483 //TNR and CDS are mutually exclusive. So reset CDS from feature mask
2484 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] &=
2485 ~CAM_QCOM_FEATURE_CDS;
2486 }
Thierry Strudel2896d122017-02-23 19:18:03 -08002487 if (m_bEis3PropertyEnabled /* hint for EIS 3 needed here */) {
2488 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] |=
2489 CAM_QTI_FEATURE_PPEISCORE;
2490 }
Binhao Line406f062017-05-03 14:39:44 -07002491 if (is_goog_zoom_video_enabled && (is_goog_zoom_4k_enabled || !m_bIs4KVideo)) {
2492 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] |=
2493 CAM_QCOM_FEATURE_GOOG_ZOOM;
2494 }
Thierry Strudel3d639192016-09-09 11:52:26 -07002495 } else {
2496 mStreamConfigInfo.type[mStreamConfigInfo.num_streams] =
2497 CAM_STREAM_TYPE_PREVIEW;
Jason Leea52b77e2017-06-27 16:16:17 -07002498 if (m_bTnrEnabled && (previewTnr[i] || m_bTnrPreview)) {
Thierry Strudel3d639192016-09-09 11:52:26 -07002499 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] |=
2500 CAM_QCOM_FEATURE_CPP_TNR;
2501 //TNR and CDS are mutually exclusive. So reset CDS from feature mask
2502 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] &=
2503 ~CAM_QCOM_FEATURE_CDS;
2504 }
Thierry Strudele80ad7c2016-12-06 10:16:27 -08002505 if(!m_bSwTnrPreview) {
2506 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] &=
2507 ~CAM_QTI_FEATURE_SW_TNR;
2508 }
Binhao Line406f062017-05-03 14:39:44 -07002509 if (is_goog_zoom_preview_enabled) {
2510 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] |=
2511 CAM_QCOM_FEATURE_GOOG_ZOOM;
2512 }
Thierry Strudel3d639192016-09-09 11:52:26 -07002513 padding_info.width_padding = mSurfaceStridePadding;
2514 padding_info.height_padding = CAM_PAD_TO_2;
Thierry Strudel9ec39c62016-12-28 11:30:05 -08002515 previewSize.width = (int32_t)newStream->width;
2516 previewSize.height = (int32_t)newStream->height;
Thierry Strudel3d639192016-09-09 11:52:26 -07002517 }
2518 if ((newStream->rotation == CAMERA3_STREAM_ROTATION_90) ||
2519 (newStream->rotation == CAMERA3_STREAM_ROTATION_270)) {
2520 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].width =
2521 newStream->height;
2522 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].height =
2523 newStream->width;
2524 }
2525 }
2526 break;
2527 case HAL_PIXEL_FORMAT_YCbCr_420_888:
Thierry Strudel2896d122017-02-23 19:18:03 -08002528 onlyRaw = false; // There is non-raw stream - bypass flag if set
Thierry Strudel3d639192016-09-09 11:52:26 -07002529 mStreamConfigInfo.type[mStreamConfigInfo.num_streams] = CAM_STREAM_TYPE_CALLBACK;
2530 if (isOnEncoder(maxViewfinderSize, newStream->width, newStream->height)) {
2531 if (bUseCommonFeatureMask)
2532 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] =
2533 commonFeatureMask;
2534 else
2535 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] =
2536 CAM_QCOM_FEATURE_NONE;
2537 } else {
2538 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] =
2539 CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
2540 }
2541 break;
2542 case HAL_PIXEL_FORMAT_BLOB:
Thierry Strudel2896d122017-02-23 19:18:03 -08002543 onlyRaw = false; // There is non-raw stream - bypass flag if set
Thierry Strudel3d639192016-09-09 11:52:26 -07002544 mStreamConfigInfo.type[mStreamConfigInfo.num_streams] = CAM_STREAM_TYPE_SNAPSHOT;
2545 // No need to check bSmallJpegSize if ZSL is present since JPEG uses ZSL stream
2546 if ((m_bIs4KVideo && !isZsl) || (bSmallJpegSize && !isZsl)) {
2547 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] =
2548 CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
Thierry Strudel2896d122017-02-23 19:18:03 -08002549 /* Remove rotation if it is not supported
2550 for 4K LiveVideo snapshot case (online processing) */
2551 if (!(gCamCapability[mCameraId]->qcom_supported_feature_mask &
2552 CAM_QCOM_FEATURE_ROTATION)) {
2553 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams]
2554 &= ~CAM_QCOM_FEATURE_ROTATION;
2555 }
Thierry Strudel3d639192016-09-09 11:52:26 -07002556 } else {
2557 if (bUseCommonFeatureMask &&
2558 isOnEncoder(maxViewfinderSize, newStream->width,
2559 newStream->height)) {
2560 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] = commonFeatureMask;
2561 } else {
2562 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] = CAM_QCOM_FEATURE_NONE;
2563 }
2564 }
2565 if (isZsl) {
2566 if (zslStream) {
2567 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].width =
2568 (int32_t)zslStream->width;
2569 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].height =
2570 (int32_t)zslStream->height;
Thierry Strudel2896d122017-02-23 19:18:03 -08002571 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] =
2572 zsl_ppmask;
Thierry Strudel3d639192016-09-09 11:52:26 -07002573 } else {
2574 LOGE("Error, No ZSL stream identified");
2575 pthread_mutex_unlock(&mMutex);
2576 return -EINVAL;
2577 }
2578 } else if (m_bIs4KVideo) {
2579 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].width = (int32_t)videoWidth;
2580 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].height = (int32_t)videoHeight;
2581 } else if (bYuv888OverrideJpeg) {
2582 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].width =
2583 (int32_t)largeYuv888Size.width;
2584 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].height =
2585 (int32_t)largeYuv888Size.height;
2586 }
2587 break;
2588 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
2589 case HAL_PIXEL_FORMAT_RAW16:
2590 case HAL_PIXEL_FORMAT_RAW10:
2591 mStreamConfigInfo.type[mStreamConfigInfo.num_streams] = CAM_STREAM_TYPE_RAW;
2592 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] = CAM_QCOM_FEATURE_NONE;
2593 isRawStreamRequested = true;
Emilian Peev0f3c3162017-03-15 12:57:46 +00002594 if ((HAL_DATASPACE_DEPTH == newStream->data_space) &&
2595 (HAL_PIXEL_FORMAT_RAW16 == newStream->format)) {
2596 mStreamConfigInfo.sub_format_type[mStreamConfigInfo.num_streams] =
2597 gCamCapability[mCameraId]->sub_fmt[mPDIndex];
2598 mStreamConfigInfo.format[mStreamConfigInfo.num_streams] =
2599 gCamCapability[mCameraId]->supported_meta_raw_fmts[mPDIndex];
2600 mStreamConfigInfo.dt[mStreamConfigInfo.num_streams] =
2601 gCamCapability[mCameraId]->dt[mPDIndex];
2602 mStreamConfigInfo.vc[mStreamConfigInfo.num_streams] =
2603 gCamCapability[mCameraId]->vc[mPDIndex];
2604 }
Thierry Strudel3d639192016-09-09 11:52:26 -07002605 break;
2606 default:
Thierry Strudel2896d122017-02-23 19:18:03 -08002607 onlyRaw = false; // There is non-raw stream - bypass flag if set
Thierry Strudel3d639192016-09-09 11:52:26 -07002608 mStreamConfigInfo.type[mStreamConfigInfo.num_streams] = CAM_STREAM_TYPE_DEFAULT;
2609 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] = CAM_QCOM_FEATURE_NONE;
2610 break;
2611 }
2612 }
2613
2614 setPAAFSupport(mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams],
2615 (cam_stream_type_t) mStreamConfigInfo.type[mStreamConfigInfo.num_streams],
2616 gCamCapability[mCameraId]->color_arrangement);
2617
2618 if (newStream->priv == NULL) {
2619 //New stream, construct channel
2620 switch (newStream->stream_type) {
2621 case CAMERA3_STREAM_INPUT:
2622 newStream->usage |= GRALLOC_USAGE_HW_CAMERA_READ;
2623 newStream->usage |= GRALLOC_USAGE_HW_CAMERA_WRITE;//WR for inplace algo's
2624 break;
2625 case CAMERA3_STREAM_BIDIRECTIONAL:
2626 newStream->usage |= GRALLOC_USAGE_HW_CAMERA_READ |
2627 GRALLOC_USAGE_HW_CAMERA_WRITE;
2628 break;
2629 case CAMERA3_STREAM_OUTPUT:
2630 /* For video encoding stream, set read/write rarely
2631 * flag so that they may be set to un-cached */
2632 if (newStream->usage & GRALLOC_USAGE_HW_VIDEO_ENCODER)
2633 newStream->usage |=
2634 (GRALLOC_USAGE_SW_READ_RARELY |
2635 GRALLOC_USAGE_SW_WRITE_RARELY |
2636 GRALLOC_USAGE_HW_CAMERA_WRITE);
2637 else if (IS_USAGE_ZSL(newStream->usage))
2638 {
2639 LOGD("ZSL usage flag skipping");
2640 }
2641 else if (newStream == zslStream
2642 || newStream->format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
2643 newStream->usage |= GRALLOC_USAGE_HW_CAMERA_ZSL;
2644 } else
2645 newStream->usage |= GRALLOC_USAGE_HW_CAMERA_WRITE;
2646 break;
2647 default:
2648 LOGE("Invalid stream_type %d", newStream->stream_type);
2649 break;
2650 }
2651
Shuzhen Wangbb03f5c2017-02-17 15:38:24 -08002652 bool forcePreviewUBWC = true;
Thierry Strudel3d639192016-09-09 11:52:26 -07002653 if (newStream->stream_type == CAMERA3_STREAM_OUTPUT ||
2654 newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL) {
2655 QCamera3ProcessingChannel *channel = NULL;
2656 switch (newStream->format) {
2657 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
2658 if ((newStream->usage &
2659 private_handle_t::PRIV_FLAGS_VIDEO_ENCODER) &&
2660 (streamList->operation_mode ==
2661 CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE)
2662 ) {
2663 channel = new QCamera3RegularChannel(mCameraHandle->camera_handle,
2664 mChannelHandle, mCameraHandle->ops, captureResultCb,
Thierry Strudelc2ee3302016-11-17 12:33:12 -08002665 setBufferErrorStatus, &gCamCapability[mCameraId]->padding_info,
Thierry Strudel3d639192016-09-09 11:52:26 -07002666 this,
2667 newStream,
2668 (cam_stream_type_t)
2669 mStreamConfigInfo.type[mStreamConfigInfo.num_streams],
2670 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams],
2671 mMetadataChannel,
2672 0); //heap buffers are not required for HFR video channel
2673 if (channel == NULL) {
2674 LOGE("allocation of channel failed");
2675 pthread_mutex_unlock(&mMutex);
2676 return -ENOMEM;
2677 }
2678 //channel->getNumBuffers() will return 0 here so use
2679 //MAX_INFLIGH_HFR_REQUESTS
2680 newStream->max_buffers = MAX_INFLIGHT_HFR_REQUESTS;
2681 newStream->priv = channel;
2682 LOGI("num video buffers in HFR mode: %d",
2683 MAX_INFLIGHT_HFR_REQUESTS);
2684 } else {
2685 /* Copy stream contents in HFR preview only case to create
2686 * dummy batch channel so that sensor streaming is in
2687 * HFR mode */
2688 if (!m_bIsVideo && (streamList->operation_mode ==
2689 CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE)) {
2690 mDummyBatchStream = *newStream;
Emilian Peevbc210722017-12-15 15:36:26 +00002691 mDummyBatchStream.usage = GRALLOC_USAGE_HW_VIDEO_ENCODER;
Thierry Strudel3d639192016-09-09 11:52:26 -07002692 }
Thierry Strudel2896d122017-02-23 19:18:03 -08002693 int bufferCount = MAX_INFLIGHT_REQUESTS;
2694 if (mStreamConfigInfo.type[mStreamConfigInfo.num_streams] ==
2695 CAM_STREAM_TYPE_VIDEO) {
Zhijun He6cdf6372017-07-15 14:59:58 -07002696 if (m_bEis3PropertyEnabled /* hint for EIS 3 needed here */) {
2697 // WAR: 4K video can only run <=30fps, reduce the buffer count.
2698 bufferCount = m_bIs4KVideo ?
2699 MAX_30FPS_VIDEO_BUFFERS : MAX_VIDEO_BUFFERS;
2700 }
2701
Thierry Strudel2896d122017-02-23 19:18:03 -08002702 }
Thierry Strudel3d639192016-09-09 11:52:26 -07002703 channel = new QCamera3RegularChannel(mCameraHandle->camera_handle,
2704 mChannelHandle, mCameraHandle->ops, captureResultCb,
Thierry Strudelc2ee3302016-11-17 12:33:12 -08002705 setBufferErrorStatus, &gCamCapability[mCameraId]->padding_info,
Thierry Strudel3d639192016-09-09 11:52:26 -07002706 this,
2707 newStream,
2708 (cam_stream_type_t)
2709 mStreamConfigInfo.type[mStreamConfigInfo.num_streams],
2710 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams],
2711 mMetadataChannel,
Thierry Strudel2896d122017-02-23 19:18:03 -08002712 bufferCount);
Thierry Strudel3d639192016-09-09 11:52:26 -07002713 if (channel == NULL) {
2714 LOGE("allocation of channel failed");
2715 pthread_mutex_unlock(&mMutex);
2716 return -ENOMEM;
2717 }
Thierry Strudel2896d122017-02-23 19:18:03 -08002718 /* disable UBWC for preview, though supported,
2719 * to take advantage of CPP duplication */
Shuzhen Wangbb03f5c2017-02-17 15:38:24 -08002720 if (m_bIsVideo && (!QCameraCommon::isVideoUBWCEnabled()) &&
Thierry Strudel2896d122017-02-23 19:18:03 -08002721 (previewSize.width == (int32_t)videoWidth)&&
2722 (previewSize.height == (int32_t)videoHeight)){
Shuzhen Wangbb03f5c2017-02-17 15:38:24 -08002723 forcePreviewUBWC = false;
Thierry Strudel2896d122017-02-23 19:18:03 -08002724 }
Shuzhen Wangbb03f5c2017-02-17 15:38:24 -08002725 channel->setUBWCEnabled(forcePreviewUBWC);
Binhao Line406f062017-05-03 14:39:44 -07002726 /* When goog_zoom is linked to the preview or video stream,
2727 * disable ubwc to the linked stream */
2728 if ((mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] &
2729 CAM_QCOM_FEATURE_GOOG_ZOOM) != 0) {
2730 channel->setUBWCEnabled(false);
2731 }
Thierry Strudel3d639192016-09-09 11:52:26 -07002732 newStream->max_buffers = channel->getNumBuffers();
2733 newStream->priv = channel;
2734 }
2735 break;
2736 case HAL_PIXEL_FORMAT_YCbCr_420_888: {
2737 channel = new QCamera3YUVChannel(mCameraHandle->camera_handle,
2738 mChannelHandle,
2739 mCameraHandle->ops, captureResultCb,
Thierry Strudelc2ee3302016-11-17 12:33:12 -08002740 setBufferErrorStatus, &padding_info,
Thierry Strudel3d639192016-09-09 11:52:26 -07002741 this,
2742 newStream,
2743 (cam_stream_type_t)
2744 mStreamConfigInfo.type[mStreamConfigInfo.num_streams],
2745 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams],
2746 mMetadataChannel);
2747 if (channel == NULL) {
2748 LOGE("allocation of YUV channel failed");
2749 pthread_mutex_unlock(&mMutex);
2750 return -ENOMEM;
2751 }
2752 newStream->max_buffers = channel->getNumBuffers();
2753 newStream->priv = channel;
2754 break;
2755 }
2756 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
2757 case HAL_PIXEL_FORMAT_RAW16:
Emilian Peev0f3c3162017-03-15 12:57:46 +00002758 case HAL_PIXEL_FORMAT_RAW10: {
2759 bool isRAW16 = ((newStream->format == HAL_PIXEL_FORMAT_RAW16) &&
2760 (HAL_DATASPACE_DEPTH != newStream->data_space))
2761 ? true : false;
Thierry Strudel3d639192016-09-09 11:52:26 -07002762 mRawChannel = new QCamera3RawChannel(
2763 mCameraHandle->camera_handle, mChannelHandle,
2764 mCameraHandle->ops, captureResultCb,
Thierry Strudelc2ee3302016-11-17 12:33:12 -08002765 setBufferErrorStatus, &padding_info,
Thierry Strudel3d639192016-09-09 11:52:26 -07002766 this, newStream,
2767 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams],
Emilian Peev0f3c3162017-03-15 12:57:46 +00002768 mMetadataChannel, isRAW16);
Thierry Strudel3d639192016-09-09 11:52:26 -07002769 if (mRawChannel == NULL) {
2770 LOGE("allocation of raw channel failed");
2771 pthread_mutex_unlock(&mMutex);
2772 return -ENOMEM;
2773 }
2774 newStream->max_buffers = mRawChannel->getNumBuffers();
2775 newStream->priv = (QCamera3ProcessingChannel*)mRawChannel;
2776 break;
Emilian Peev0f3c3162017-03-15 12:57:46 +00002777 }
Thierry Strudel3d639192016-09-09 11:52:26 -07002778 case HAL_PIXEL_FORMAT_BLOB:
Emilian Peev7650c122017-01-19 08:24:33 -08002779 if (newStream->data_space == HAL_DATASPACE_DEPTH) {
2780 mDepthChannel = new QCamera3DepthChannel(
2781 mCameraHandle->camera_handle, mChannelHandle,
2782 mCameraHandle->ops, NULL, NULL, &padding_info,
2783 0, this, MAX_INFLIGHT_REQUESTS, newStream,
2784 mMetadataChannel);
2785 if (NULL == mDepthChannel) {
2786 LOGE("Allocation of depth channel failed");
2787 pthread_mutex_unlock(&mMutex);
2788 return NO_MEMORY;
2789 }
2790 newStream->priv = mDepthChannel;
2791 newStream->max_buffers = MAX_INFLIGHT_REQUESTS;
2792 } else {
2793 // Max live snapshot inflight buffer is 1. This is to mitigate
2794 // frame drop issues for video snapshot. The more buffers being
2795 // allocated, the more frame drops there are.
2796 mPictureChannel = new QCamera3PicChannel(
2797 mCameraHandle->camera_handle, mChannelHandle,
2798 mCameraHandle->ops, captureResultCb,
2799 setBufferErrorStatus, &padding_info, this, newStream,
2800 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams],
2801 m_bIs4KVideo, isZsl, mMetadataChannel,
2802 (m_bIsVideo ? 1 : MAX_INFLIGHT_BLOB));
2803 if (mPictureChannel == NULL) {
2804 LOGE("allocation of channel failed");
2805 pthread_mutex_unlock(&mMutex);
2806 return -ENOMEM;
2807 }
2808 newStream->priv = (QCamera3ProcessingChannel*)mPictureChannel;
2809 newStream->max_buffers = mPictureChannel->getNumBuffers();
2810 mPictureChannel->overrideYuvSize(
2811 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].width,
2812 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].height);
Thierry Strudel3d639192016-09-09 11:52:26 -07002813 }
Thierry Strudel3d639192016-09-09 11:52:26 -07002814 break;
2815
2816 default:
2817 LOGE("not a supported format 0x%x", newStream->format);
Thierry Strudel73e91562017-05-15 09:16:18 -07002818 pthread_mutex_unlock(&mMutex);
2819 return -EINVAL;
Thierry Strudel3d639192016-09-09 11:52:26 -07002820 }
2821 } else if (newStream->stream_type == CAMERA3_STREAM_INPUT) {
2822 newStream->max_buffers = MAX_INFLIGHT_REPROCESS_REQUESTS;
2823 } else {
2824 LOGE("Error, Unknown stream type");
2825 pthread_mutex_unlock(&mMutex);
2826 return -EINVAL;
2827 }
2828
2829 QCamera3Channel *channel = (QCamera3Channel*) newStream->priv;
Shuzhen Wangbb03f5c2017-02-17 15:38:24 -08002830 if (channel != NULL && QCamera3Channel::isUBWCEnabled()) {
Jason Leec4cf5032017-05-24 18:31:41 -07002831 // Here we only care whether it's EIS3 or not
2832 cam_is_type_t isType = m_bEis3PropertyEnabled ? IS_TYPE_EIS_3_0 : IS_TYPE_NONE;
2833 if (gCamCapability[mCameraId]->position == CAM_POSITION_FRONT ||
2834 mOpMode == CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE)
2835 isType = IS_TYPE_NONE;
Shuzhen Wangbb03f5c2017-02-17 15:38:24 -08002836 cam_format_t fmt = QCamera3Channel::getStreamDefaultFormat(
Thierry Strudelcca4d9c2016-10-20 08:25:53 -07002837 mStreamConfigInfo.type[mStreamConfigInfo.num_streams],
Jason Leec4cf5032017-05-24 18:31:41 -07002838 newStream->width, newStream->height, forcePreviewUBWC, isType);
Thierry Strudel3d639192016-09-09 11:52:26 -07002839 if(fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
2840 newStream->usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
2841 }
2842 }
2843
2844 for (List<stream_info_t*>::iterator it=mStreamInfo.begin();
2845 it != mStreamInfo.end(); it++) {
2846 if ((*it)->stream == newStream) {
2847 (*it)->channel = (QCamera3ProcessingChannel*) newStream->priv;
2848 break;
2849 }
2850 }
2851 } else {
2852 // Channel already exists for this stream
2853 // Do nothing for now
2854 }
2855 padding_info = gCamCapability[mCameraId]->padding_info;
2856
Emilian Peev7650c122017-01-19 08:24:33 -08002857 /* Do not add entries for input&depth stream in metastream info
Thierry Strudel3d639192016-09-09 11:52:26 -07002858 * since there is no real stream associated with it
2859 */
Emilian Peev7650c122017-01-19 08:24:33 -08002860 if ((newStream->stream_type != CAMERA3_STREAM_INPUT) &&
Emilian Peev0f3c3162017-03-15 12:57:46 +00002861 !((newStream->data_space == HAL_DATASPACE_DEPTH) &&
2862 (newStream->format == HAL_PIXEL_FORMAT_BLOB))) {
Thierry Strudel3d639192016-09-09 11:52:26 -07002863 mStreamConfigInfo.num_streams++;
Emilian Peev7650c122017-01-19 08:24:33 -08002864 }
Thierry Strudel3d639192016-09-09 11:52:26 -07002865 }
2866
Chien-Yu Chen3f303522017-05-19 15:21:45 -07002867 // Let buffer dispatcher know the configured streams.
2868 mOutputBufferDispatcher.configureStreams(streamList);
2869
Thierry Strudel2896d122017-02-23 19:18:03 -08002870 if (mOpMode != QCAMERA3_VENDOR_STREAM_CONFIGURATION_RAW_ONLY_MODE) {
2871 onlyRaw = false;
2872 }
2873
Thierry Strudel9ec39c62016-12-28 11:30:05 -08002874 // Create analysis stream all the time, even when h/w support is not available
Thierry Strudel2896d122017-02-23 19:18:03 -08002875 if (!onlyRaw) {
Thierry Strudel9ec39c62016-12-28 11:30:05 -08002876 cam_feature_mask_t analysisFeatureMask = CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
Thierry Strudel9ec39c62016-12-28 11:30:05 -08002877 cam_analysis_info_t analysisInfo;
2878 int32_t ret = NO_ERROR;
2879 ret = mCommon.getAnalysisInfo(
2880 FALSE,
2881 analysisFeatureMask,
2882 &analysisInfo);
2883 if (ret == NO_ERROR) {
Shuzhen Wang3b457d92016-08-03 08:46:59 -07002884 cam_color_filter_arrangement_t analysis_color_arrangement =
2885 (analysisInfo.analysis_format == CAM_FORMAT_Y_ONLY ?
2886 CAM_FILTER_ARRANGEMENT_Y :
2887 gCamCapability[mCameraId]->color_arrangement);
2888 setPAAFSupport(analysisFeatureMask, CAM_STREAM_TYPE_ANALYSIS,
2889 analysis_color_arrangement);
Thierry Strudel9ec39c62016-12-28 11:30:05 -08002890 cam_dimension_t analysisDim;
2891 analysisDim = mCommon.getMatchingDimension(previewSize,
2892 analysisInfo.analysis_recommended_res);
2893
2894 mAnalysisChannel = new QCamera3SupportChannel(
2895 mCameraHandle->camera_handle,
2896 mChannelHandle,
2897 mCameraHandle->ops,
2898 &analysisInfo.analysis_padding_info,
2899 analysisFeatureMask,
2900 CAM_STREAM_TYPE_ANALYSIS,
2901 &analysisDim,
2902 (analysisInfo.analysis_format
2903 == CAM_FORMAT_Y_ONLY ? CAM_FORMAT_Y_ONLY
2904 : CAM_FORMAT_YUV_420_NV21),
2905 analysisInfo.hw_analysis_supported,
2906 gCamCapability[mCameraId]->color_arrangement,
2907 this,
2908 0); // force buffer count to 0
2909 } else {
2910 LOGW("getAnalysisInfo failed, ret = %d", ret);
2911 }
2912 if (!mAnalysisChannel) {
2913 LOGW("Analysis channel cannot be created");
2914 }
2915 }
2916
Thierry Strudel3d639192016-09-09 11:52:26 -07002917 //RAW DUMP channel
2918 if (mEnableRawDump && isRawStreamRequested == false){
2919 cam_dimension_t rawDumpSize;
2920 rawDumpSize = getMaxRawSize(mCameraId);
2921 cam_feature_mask_t rawDumpFeatureMask = CAM_QCOM_FEATURE_NONE;
2922 setPAAFSupport(rawDumpFeatureMask,
2923 CAM_STREAM_TYPE_RAW,
2924 gCamCapability[mCameraId]->color_arrangement);
2925 mRawDumpChannel = new QCamera3RawDumpChannel(mCameraHandle->camera_handle,
2926 mChannelHandle,
2927 mCameraHandle->ops,
2928 rawDumpSize,
2929 &padding_info,
2930 this, rawDumpFeatureMask);
2931 if (!mRawDumpChannel) {
2932 LOGE("Raw Dump channel cannot be created");
2933 pthread_mutex_unlock(&mMutex);
2934 return -ENOMEM;
2935 }
2936 }
2937
Thierry Strudel3d639192016-09-09 11:52:26 -07002938 if (mAnalysisChannel) {
2939 cam_analysis_info_t analysisInfo;
2940 memset(&analysisInfo, 0, sizeof(cam_analysis_info_t));
2941 mStreamConfigInfo.type[mStreamConfigInfo.num_streams] =
2942 CAM_STREAM_TYPE_ANALYSIS;
2943 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] =
2944 CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
Thierry Strudel9ec39c62016-12-28 11:30:05 -08002945 rc = mCommon.getAnalysisInfo(FALSE,
Thierry Strudel3d639192016-09-09 11:52:26 -07002946 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams],
2947 &analysisInfo);
2948 if (rc != NO_ERROR) {
2949 LOGE("getAnalysisInfo failed, ret = %d", rc);
2950 pthread_mutex_unlock(&mMutex);
2951 return rc;
2952 }
Shuzhen Wang3b457d92016-08-03 08:46:59 -07002953 cam_color_filter_arrangement_t analysis_color_arrangement =
2954 (analysisInfo.analysis_format == CAM_FORMAT_Y_ONLY ?
2955 CAM_FILTER_ARRANGEMENT_Y :
2956 gCamCapability[mCameraId]->color_arrangement);
2957 setPAAFSupport(mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams],
2958 mStreamConfigInfo.type[mStreamConfigInfo.num_streams],
2959 analysis_color_arrangement);
2960
Thierry Strudel3d639192016-09-09 11:52:26 -07002961 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams] =
Thierry Strudel9ec39c62016-12-28 11:30:05 -08002962 mCommon.getMatchingDimension(previewSize,
2963 analysisInfo.analysis_recommended_res);
Thierry Strudel3d639192016-09-09 11:52:26 -07002964 mStreamConfigInfo.num_streams++;
2965 }
2966
Thierry Strudel2896d122017-02-23 19:18:03 -08002967 if (!onlyRaw && isSupportChannelNeeded(streamList, mStreamConfigInfo)) {
Thierry Strudel3d639192016-09-09 11:52:26 -07002968 cam_analysis_info_t supportInfo;
2969 memset(&supportInfo, 0, sizeof(cam_analysis_info_t));
2970 cam_feature_mask_t callbackFeatureMask = CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
2971 setPAAFSupport(callbackFeatureMask,
2972 CAM_STREAM_TYPE_CALLBACK,
2973 gCamCapability[mCameraId]->color_arrangement);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07002974 int32_t ret = NO_ERROR;
Thierry Strudel9ec39c62016-12-28 11:30:05 -08002975 ret = mCommon.getAnalysisInfo(FALSE, callbackFeatureMask, &supportInfo);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07002976 if (ret != NO_ERROR) {
2977 /* Ignore the error for Mono camera
2978 * because the PAAF bit mask is only set
2979 * for CAM_STREAM_TYPE_ANALYSIS stream type
2980 */
2981 if (gCamCapability[mCameraId]->color_arrangement != CAM_FILTER_ARRANGEMENT_Y) {
2982 LOGW("getAnalysisInfo failed, ret = %d", ret);
2983 }
Thierry Strudel3d639192016-09-09 11:52:26 -07002984 }
2985 mSupportChannel = new QCamera3SupportChannel(
2986 mCameraHandle->camera_handle,
2987 mChannelHandle,
2988 mCameraHandle->ops,
2989 &gCamCapability[mCameraId]->padding_info,
2990 callbackFeatureMask,
2991 CAM_STREAM_TYPE_CALLBACK,
2992 &QCamera3SupportChannel::kDim,
2993 CAM_FORMAT_YUV_420_NV21,
2994 supportInfo.hw_analysis_supported,
2995 gCamCapability[mCameraId]->color_arrangement,
Thierry Strudelc2ee3302016-11-17 12:33:12 -08002996 this, 0);
Thierry Strudel3d639192016-09-09 11:52:26 -07002997 if (!mSupportChannel) {
2998 LOGE("dummy channel cannot be created");
2999 pthread_mutex_unlock(&mMutex);
3000 return -ENOMEM;
3001 }
3002 }
3003
3004 if (mSupportChannel) {
3005 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams] =
3006 QCamera3SupportChannel::kDim;
3007 mStreamConfigInfo.type[mStreamConfigInfo.num_streams] =
3008 CAM_STREAM_TYPE_CALLBACK;
3009 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] =
3010 CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
3011 setPAAFSupport(mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams],
3012 mStreamConfigInfo.type[mStreamConfigInfo.num_streams],
3013 gCamCapability[mCameraId]->color_arrangement);
3014 mStreamConfigInfo.num_streams++;
3015 }
3016
3017 if (mRawDumpChannel) {
3018 cam_dimension_t rawSize;
3019 rawSize = getMaxRawSize(mCameraId);
3020 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams] =
3021 rawSize;
3022 mStreamConfigInfo.type[mStreamConfigInfo.num_streams] =
3023 CAM_STREAM_TYPE_RAW;
3024 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] =
3025 CAM_QCOM_FEATURE_NONE;
3026 setPAAFSupport(mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams],
3027 mStreamConfigInfo.type[mStreamConfigInfo.num_streams],
3028 gCamCapability[mCameraId]->color_arrangement);
3029 mStreamConfigInfo.num_streams++;
3030 }
Chien-Yu Chen8e599492016-11-01 13:37:46 -07003031
3032 if (mHdrPlusRawSrcChannel) {
3033 cam_dimension_t rawSize;
3034 rawSize = getMaxRawSize(mCameraId);
3035 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams] = rawSize;
3036 mStreamConfigInfo.type[mStreamConfigInfo.num_streams] = CAM_STREAM_TYPE_RAW;
3037 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] = CAM_QCOM_FEATURE_NONE;
3038 setPAAFSupport(mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams],
3039 mStreamConfigInfo.type[mStreamConfigInfo.num_streams],
3040 gCamCapability[mCameraId]->color_arrangement);
3041 mStreamConfigInfo.num_streams++;
3042 }
3043
Thierry Strudel3d639192016-09-09 11:52:26 -07003044 /* In HFR mode, if video stream is not added, create a dummy channel so that
3045 * ISP can create a batch mode even for preview only case. This channel is
3046 * never 'start'ed (no stream-on), it is only 'initialized' */
3047 if ((mOpMode == CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE) &&
3048 !m_bIsVideo) {
3049 cam_feature_mask_t dummyFeatureMask = CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
3050 setPAAFSupport(dummyFeatureMask,
3051 CAM_STREAM_TYPE_VIDEO,
3052 gCamCapability[mCameraId]->color_arrangement);
3053 mDummyBatchChannel = new QCamera3RegularChannel(mCameraHandle->camera_handle,
3054 mChannelHandle,
3055 mCameraHandle->ops, captureResultCb,
Thierry Strudelc2ee3302016-11-17 12:33:12 -08003056 setBufferErrorStatus, &gCamCapability[mCameraId]->padding_info,
Thierry Strudel3d639192016-09-09 11:52:26 -07003057 this,
3058 &mDummyBatchStream,
3059 CAM_STREAM_TYPE_VIDEO,
3060 dummyFeatureMask,
3061 mMetadataChannel);
3062 if (NULL == mDummyBatchChannel) {
3063 LOGE("creation of mDummyBatchChannel failed."
3064 "Preview will use non-hfr sensor mode ");
3065 }
3066 }
3067 if (mDummyBatchChannel) {
3068 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].width =
3069 mDummyBatchStream.width;
3070 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].height =
3071 mDummyBatchStream.height;
3072 mStreamConfigInfo.type[mStreamConfigInfo.num_streams] =
3073 CAM_STREAM_TYPE_VIDEO;
3074 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] =
3075 CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
3076 setPAAFSupport(mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams],
3077 mStreamConfigInfo.type[mStreamConfigInfo.num_streams],
3078 gCamCapability[mCameraId]->color_arrangement);
3079 mStreamConfigInfo.num_streams++;
3080 }
3081
3082 mStreamConfigInfo.buffer_info.min_buffers = MIN_INFLIGHT_REQUESTS;
3083 mStreamConfigInfo.buffer_info.max_buffers =
Thierry Strudel2896d122017-02-23 19:18:03 -08003084 m_bIs4KVideo ? 0 :
Jason Leea46ad5e2017-07-07 15:20:56 -07003085 m_bEis3PropertyEnabled && m_bIsVideo ? MAX_VIDEO_BUFFERS : MAX_INFLIGHT_REQUESTS;
Thierry Strudel3d639192016-09-09 11:52:26 -07003086
3087 /* Initialize mPendingRequestInfo and mPendingBuffersMap */
3088 for (pendingRequestIterator i = mPendingRequestsList.begin();
3089 i != mPendingRequestsList.end();) {
3090 i = erasePendingRequest(i);
3091 }
3092 mPendingFrameDropList.clear();
3093 // Initialize/Reset the pending buffers list
3094 for (auto &req : mPendingBuffersMap.mPendingBuffersInRequest) {
3095 req.mPendingBufferList.clear();
3096 }
3097 mPendingBuffersMap.mPendingBuffersInRequest.clear();
Emilian Peev30522a12017-08-03 14:36:33 +01003098 mExpectedInflightDuration = 0;
3099 mExpectedFrameDuration = 0;
Thierry Strudel3d639192016-09-09 11:52:26 -07003100
Thierry Strudel3d639192016-09-09 11:52:26 -07003101 mCurJpegMeta.clear();
3102 //Get min frame duration for this streams configuration
3103 deriveMinFrameDuration();
3104
Chien-Yu Chenee335912017-02-09 17:53:20 -08003105 mFirstPreviewIntentSeen = false;
3106
Thierry Strudel3d639192016-09-09 11:52:26 -07003107 // Update state
3108 mState = CONFIGURED;
3109
Shuzhen Wang3c077d72017-04-20 22:48:59 -07003110 mFirstMetadataCallback = true;
3111
Emilian Peev6d4cdc22017-11-16 16:56:23 +00003112 if (streamList->session_parameters != nullptr) {
3113 CameraMetadata meta;
3114 meta = streamList->session_parameters;
3115
3116 // send an unconfigure to the backend so that the isp
3117 // resources are deallocated
3118 if (!mFirstConfiguration) {
3119 cam_stream_size_info_t stream_config_info;
3120 int32_t hal_version = CAM_HAL_V3;
3121 memset(&stream_config_info, 0, sizeof(cam_stream_size_info_t));
3122 stream_config_info.buffer_info.min_buffers =
3123 MIN_INFLIGHT_REQUESTS;
3124 stream_config_info.buffer_info.max_buffers =
3125 m_bIs4KVideo ? 0 :
3126 m_bEis3PropertyEnabled && m_bIsVideo ? MAX_VIDEO_BUFFERS : MAX_INFLIGHT_REQUESTS;
3127 clear_metadata_buffer(mParameters);
3128 ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters,
3129 CAM_INTF_PARM_HAL_VERSION, hal_version);
3130 ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters,
3131 CAM_INTF_META_STREAM_INFO, stream_config_info);
3132 rc = mCameraHandle->ops->set_parms(mCameraHandle->camera_handle,
3133 mParameters);
3134 if (rc < 0) {
3135 LOGE("set_parms for unconfigure failed");
3136 pthread_mutex_unlock(&mMutex);
3137 return rc;
3138 }
3139
3140 }
3141 /* get eis information for stream configuration */
3142 cam_is_type_t isTypePreview, is_type=IS_TYPE_NONE;
3143 char is_type_value[PROPERTY_VALUE_MAX];
3144 property_get("persist.camera.is_type", is_type_value, "4");
3145 m_ISTypeVideo = static_cast<cam_is_type_t>(atoi(is_type_value));
3146 // Make default value for preview IS_TYPE as IS_TYPE_EIS_2_0
3147 property_get("persist.camera.is_type_preview", is_type_value, "4");
3148 isTypePreview = static_cast<cam_is_type_t>(atoi(is_type_value));
3149 LOGD("isTypeVideo: %d isTypePreview: %d", m_ISTypeVideo, isTypePreview);
3150
3151 int32_t hal_version = CAM_HAL_V3;
3152 clear_metadata_buffer(mParameters);
3153 ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_PARM_HAL_VERSION, hal_version);
3154 ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_META_CAPTURE_INTENT, mCaptureIntent);
3155
3156 if (mFirstConfiguration) {
3157 // configure instant AEC
3158 // Instant AEC is a session based parameter and it is needed only
3159 // once per complete session after open camera.
3160 // i.e. This is set only once for the first capture request, after open camera.
3161 setInstantAEC(meta);
3162 }
3163
3164 bool setEis = isEISEnabled(meta);
3165 int32_t vsMode;
3166 vsMode = (setEis)? DIS_ENABLE: DIS_DISABLE;
3167 if (ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_PARM_DIS_ENABLE, vsMode)) {
3168 rc = BAD_VALUE;
3169 }
3170 LOGD("setEis %d", setEis);
3171 bool eis3Supported = false;
3172 size_t count = IS_TYPE_MAX;
3173 count = MIN(gCamCapability[mCameraId]->supported_is_types_cnt, count);
3174 for (size_t i = 0; i < count; i++) {
3175 if (gCamCapability[mCameraId]->supported_is_types[i] == IS_TYPE_EIS_3_0) {
3176 eis3Supported = true;
3177 break;
3178 }
3179 }
3180
3181 //IS type will be 0 unless EIS is supported. If EIS is supported
3182 //it could either be 4 or 5 depending on the stream and video size
3183 for (uint32_t i = 0; i < mStreamConfigInfo.num_streams; i++) {
3184 if (setEis) {
3185 if (mStreamConfigInfo.type[i] == CAM_STREAM_TYPE_PREVIEW) {
3186 is_type = isTypePreview;
3187 } else if (mStreamConfigInfo.type[i] == CAM_STREAM_TYPE_VIDEO ) {
3188 if ( (m_ISTypeVideo == IS_TYPE_EIS_3_0) && (eis3Supported == FALSE) ) {
3189 LOGW(" EIS_3.0 is not supported and so setting EIS_2.0");
3190 is_type = IS_TYPE_EIS_2_0;
3191 } else {
3192 is_type = m_ISTypeVideo;
3193 }
3194 } else {
3195 is_type = IS_TYPE_NONE;
3196 }
3197 mStreamConfigInfo.is_type[i] = is_type;
3198 } else {
3199 mStreamConfigInfo.is_type[i] = IS_TYPE_NONE;
3200 }
3201 }
3202
3203 ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters,
3204 CAM_INTF_META_STREAM_INFO, mStreamConfigInfo);
3205
3206 char prop[PROPERTY_VALUE_MAX];
3207 //Disable tintless only if the property is set to 0
3208 memset(prop, 0, sizeof(prop));
3209 property_get("persist.camera.tintless.enable", prop, "1");
3210 int32_t tintless_value = atoi(prop);
3211
3212 ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters,
3213 CAM_INTF_PARM_TINTLESS, tintless_value);
3214
3215 //Disable CDS for HFR mode or if DIS/EIS is on.
3216 //CDS is a session parameter in the backend/ISP, so need to be set/reset
3217 //after every configure_stream
3218 if ((CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE == mOpMode) ||
3219 (m_bIsVideo)) {
3220 int32_t cds = CAM_CDS_MODE_OFF;
3221 if (ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters,
3222 CAM_INTF_PARM_CDS_MODE, cds))
3223 LOGE("Failed to disable CDS for HFR mode");
3224
3225 }
3226
3227 if (m_debug_avtimer || meta.exists(QCAMERA3_USE_AV_TIMER)) {
3228 uint8_t* use_av_timer = NULL;
3229
3230 if (m_debug_avtimer){
3231 LOGI(" Enabling AV timer through setprop");
3232 use_av_timer = &m_debug_avtimer;
3233 m_bAVTimerEnabled = true;
3234 }
3235 else{
3236 use_av_timer =
3237 meta.find(QCAMERA3_USE_AV_TIMER).data.u8;
3238 if (use_av_timer) {
3239 m_bAVTimerEnabled = true;
3240 LOGI("Enabling AV timer through Metadata: use_av_timer: %d", *use_av_timer);
3241 }
3242 }
3243
3244 if (ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_META_USE_AV_TIMER, *use_av_timer)) {
3245 rc = BAD_VALUE;
3246 }
3247 }
3248
3249 setMobicat();
3250
3251 /* Set fps and hfr mode while sending meta stream info so that sensor
3252 * can configure appropriate streaming mode */
3253 mHFRVideoFps = DEFAULT_VIDEO_FPS;
3254 mMinInFlightRequests = MIN_INFLIGHT_REQUESTS;
3255 mMaxInFlightRequests = MAX_INFLIGHT_REQUESTS;
3256 if (meta.exists(ANDROID_CONTROL_AE_TARGET_FPS_RANGE)) {
3257 rc = setHalFpsRange(meta, mParameters);
3258 if (rc == NO_ERROR) {
3259 int32_t max_fps =
3260 (int32_t) meta.find(ANDROID_CONTROL_AE_TARGET_FPS_RANGE).data.i32[1];
3261 if (max_fps == 60 || mCaptureIntent == ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD) {
3262 mMinInFlightRequests = MIN_INFLIGHT_60FPS_REQUESTS;
3263 }
3264 /* For HFR, more buffers are dequeued upfront to improve the performance */
3265 if (mBatchSize) {
3266 mMinInFlightRequests = MIN_INFLIGHT_HFR_REQUESTS;
3267 mMaxInFlightRequests = MAX_INFLIGHT_HFR_REQUESTS;
3268 }
3269 }
3270 else {
3271 LOGE("setHalFpsRange failed");
3272 }
3273 }
3274 memset(&mBatchedStreamsArray, 0, sizeof(cam_stream_ID_t));
3275
3276 if (meta.exists(QCAMERA3_VIDEO_HDR_MODE)) {
3277 cam_video_hdr_mode_t vhdr = (cam_video_hdr_mode_t)
3278 meta.find(QCAMERA3_VIDEO_HDR_MODE).data.i32[0];
3279 rc = setVideoHdrMode(mParameters, vhdr);
3280 if (rc != NO_ERROR) {
3281 LOGE("setVideoHDR is failed");
3282 }
3283 }
3284
3285 if (meta.exists(TANGO_MODE_DATA_SENSOR_FULLFOV)) {
3286 uint8_t sensorModeFullFov =
3287 meta.find(TANGO_MODE_DATA_SENSOR_FULLFOV).data.u8[0];
3288 LOGD("SENSOR_MODE_FULLFOV %d" , sensorModeFullFov);
3289 if (ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_META_SENSOR_MODE_FULLFOV,
3290 sensorModeFullFov)) {
3291 rc = BAD_VALUE;
3292 }
3293 }
3294 //TODO: validate the arguments, HSV scenemode should have only the
3295 //advertised fps ranges
3296
3297 /*set the capture intent, hal version, tintless, stream info,
3298 *and disenable parameters to the backend*/
3299 LOGD("set_parms META_STREAM_INFO " );
3300 for (uint32_t i = 0; i < mStreamConfigInfo.num_streams; i++) {
3301 LOGI("STREAM INFO : type %d, wxh: %d x %d, pp_mask: 0x%" PRIx64
3302 ", Format:%d is_type: %d",
3303 mStreamConfigInfo.type[i],
3304 mStreamConfigInfo.stream_sizes[i].width,
3305 mStreamConfigInfo.stream_sizes[i].height,
3306 mStreamConfigInfo.postprocess_mask[i],
3307 mStreamConfigInfo.format[i],
3308 mStreamConfigInfo.is_type[i]);
3309 }
3310
3311 rc = mCameraHandle->ops->set_parms(mCameraHandle->camera_handle,
3312 mParameters);
3313 if (rc < 0) {
3314 LOGE("set_parms failed for hal version, stream info");
3315 }
3316
3317 }
3318
Thierry Strudel3d639192016-09-09 11:52:26 -07003319 pthread_mutex_unlock(&mMutex);
3320
3321 return rc;
3322}
3323
3324/*===========================================================================
Emilian Peev6d4cdc22017-11-16 16:56:23 +00003325 * FUNCTION : isEISEnabled
3326 *
3327 * DESCRIPTION: Decide whether EIS should get enabled or not.
3328 *
3329 * PARAMETERS :
3330 * @meta : request from framework to process
3331 *
3332 * RETURN : true/false Whether EIS should be enabled
3333 *
3334 *==========================================================================*/
3335bool QCamera3HardwareInterface::isEISEnabled(const CameraMetadata& meta) {
3336 uint8_t fwkVideoStabMode = 0;
3337 if (meta.exists(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE)) {
3338 fwkVideoStabMode = meta.find(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE).data.u8[0];
3339 }
3340
3341 // If EIS setprop is enabled then only turn it on for video/preview
3342 return m_bEisEnable && (m_bIsVideo || fwkVideoStabMode) && m_bEisSupportedSize &&
3343 (m_ISTypeVideo >= IS_TYPE_EIS_2_0) && !meta.exists(QCAMERA3_USE_AV_TIMER);
3344}
3345
3346/*===========================================================================
Thierry Strudel3d639192016-09-09 11:52:26 -07003347 * FUNCTION : validateCaptureRequest
3348 *
3349 * DESCRIPTION: validate a capture request from camera service
3350 *
3351 * PARAMETERS :
3352 * @request : request from framework to process
3353 *
3354 * RETURN :
3355 *
3356 *==========================================================================*/
3357int QCamera3HardwareInterface::validateCaptureRequest(
Thierry Strudele80ad7c2016-12-06 10:16:27 -08003358 camera3_capture_request_t *request,
3359 List<InternalRequest> &internallyRequestedStreams)
Thierry Strudel3d639192016-09-09 11:52:26 -07003360{
3361 ssize_t idx = 0;
3362 const camera3_stream_buffer_t *b;
3363 CameraMetadata meta;
3364
3365 /* Sanity check the request */
3366 if (request == NULL) {
3367 LOGE("NULL capture request");
3368 return BAD_VALUE;
3369 }
3370
3371 if ((request->settings == NULL) && (mState == CONFIGURED)) {
3372 /*settings cannot be null for the first request*/
3373 return BAD_VALUE;
3374 }
3375
3376 uint32_t frameNumber = request->frame_number;
Thierry Strudele80ad7c2016-12-06 10:16:27 -08003377 if ((request->num_output_buffers < 1 || request->output_buffers == NULL)
3378 && (internallyRequestedStreams.size() == 0)) {
Thierry Strudel3d639192016-09-09 11:52:26 -07003379 LOGE("Request %d: No output buffers provided!",
3380 __FUNCTION__, frameNumber);
3381 return BAD_VALUE;
3382 }
3383 if (request->num_output_buffers >= MAX_NUM_STREAMS) {
3384 LOGE("Number of buffers %d equals or is greater than maximum number of streams!",
3385 request->num_output_buffers, MAX_NUM_STREAMS);
3386 return BAD_VALUE;
3387 }
3388 if (request->input_buffer != NULL) {
3389 b = request->input_buffer;
3390 if (b->status != CAMERA3_BUFFER_STATUS_OK) {
3391 LOGE("Request %d: Buffer %ld: Status not OK!",
3392 frameNumber, (long)idx);
3393 return BAD_VALUE;
3394 }
3395 if (b->release_fence != -1) {
3396 LOGE("Request %d: Buffer %ld: Has a release fence!",
3397 frameNumber, (long)idx);
3398 return BAD_VALUE;
3399 }
3400 if (b->buffer == NULL) {
3401 LOGE("Request %d: Buffer %ld: NULL buffer handle!",
3402 frameNumber, (long)idx);
3403 return BAD_VALUE;
3404 }
3405 }
3406
3407 // Validate all buffers
3408 b = request->output_buffers;
Thierry Strudel54dc9782017-02-15 12:12:10 -08003409 if (b == NULL) {
3410 return BAD_VALUE;
3411 }
Thierry Strudele80ad7c2016-12-06 10:16:27 -08003412 while (idx < (ssize_t)request->num_output_buffers) {
Thierry Strudel3d639192016-09-09 11:52:26 -07003413 QCamera3ProcessingChannel *channel =
3414 static_cast<QCamera3ProcessingChannel*>(b->stream->priv);
3415 if (channel == NULL) {
3416 LOGE("Request %d: Buffer %ld: Unconfigured stream!",
3417 frameNumber, (long)idx);
3418 return BAD_VALUE;
3419 }
3420 if (b->status != CAMERA3_BUFFER_STATUS_OK) {
3421 LOGE("Request %d: Buffer %ld: Status not OK!",
3422 frameNumber, (long)idx);
3423 return BAD_VALUE;
3424 }
3425 if (b->release_fence != -1) {
3426 LOGE("Request %d: Buffer %ld: Has a release fence!",
3427 frameNumber, (long)idx);
3428 return BAD_VALUE;
3429 }
3430 if (b->buffer == NULL) {
3431 LOGE("Request %d: Buffer %ld: NULL buffer handle!",
3432 frameNumber, (long)idx);
3433 return BAD_VALUE;
3434 }
3435 if (*(b->buffer) == NULL) {
3436 LOGE("Request %d: Buffer %ld: NULL private handle!",
3437 frameNumber, (long)idx);
3438 return BAD_VALUE;
3439 }
3440 idx++;
3441 b = request->output_buffers + idx;
Thierry Strudele80ad7c2016-12-06 10:16:27 -08003442 }
Thierry Strudel3d639192016-09-09 11:52:26 -07003443 return NO_ERROR;
3444}
3445
3446/*===========================================================================
3447 * FUNCTION : deriveMinFrameDuration
3448 *
3449 * DESCRIPTION: derive mininum processed, jpeg, and raw frame durations based
3450 * on currently configured streams.
3451 *
3452 * PARAMETERS : NONE
3453 *
3454 * RETURN : NONE
3455 *
3456 *==========================================================================*/
3457void QCamera3HardwareInterface::deriveMinFrameDuration()
3458{
3459 int32_t maxJpegDim, maxProcessedDim, maxRawDim;
Jason Lee2d0ab112017-06-21 18:03:05 -07003460 bool hasRaw = false;
3461
3462 mMinRawFrameDuration = 0;
3463 mMinJpegFrameDuration = 0;
3464 mMinProcessedFrameDuration = 0;
Thierry Strudel3d639192016-09-09 11:52:26 -07003465
3466 maxJpegDim = 0;
3467 maxProcessedDim = 0;
3468 maxRawDim = 0;
3469
3470 // Figure out maximum jpeg, processed, and raw dimensions
3471 for (List<stream_info_t*>::iterator it = mStreamInfo.begin();
3472 it != mStreamInfo.end(); it++) {
3473
3474 // Input stream doesn't have valid stream_type
3475 if ((*it)->stream->stream_type == CAMERA3_STREAM_INPUT)
3476 continue;
3477
3478 int32_t dimension = (int32_t)((*it)->stream->width * (*it)->stream->height);
3479 if ((*it)->stream->format == HAL_PIXEL_FORMAT_BLOB) {
3480 if (dimension > maxJpegDim)
3481 maxJpegDim = dimension;
3482 } else if ((*it)->stream->format == HAL_PIXEL_FORMAT_RAW_OPAQUE ||
3483 (*it)->stream->format == HAL_PIXEL_FORMAT_RAW10 ||
3484 (*it)->stream->format == HAL_PIXEL_FORMAT_RAW16) {
Jason Lee2d0ab112017-06-21 18:03:05 -07003485 hasRaw = true;
Thierry Strudel3d639192016-09-09 11:52:26 -07003486 if (dimension > maxRawDim)
3487 maxRawDim = dimension;
3488 } else {
3489 if (dimension > maxProcessedDim)
3490 maxProcessedDim = dimension;
3491 }
3492 }
3493
3494 size_t count = MIN(gCamCapability[mCameraId]->supported_raw_dim_cnt,
3495 MAX_SIZES_CNT);
3496
3497 //Assume all jpeg dimensions are in processed dimensions.
3498 if (maxJpegDim > maxProcessedDim)
3499 maxProcessedDim = maxJpegDim;
3500 //Find the smallest raw dimension that is greater or equal to jpeg dimension
Jason Lee2d0ab112017-06-21 18:03:05 -07003501 if (hasRaw && maxProcessedDim > maxRawDim) {
Thierry Strudel3d639192016-09-09 11:52:26 -07003502 maxRawDim = INT32_MAX;
3503
3504 for (size_t i = 0; i < count; i++) {
3505 int32_t dimension = gCamCapability[mCameraId]->raw_dim[i].width *
3506 gCamCapability[mCameraId]->raw_dim[i].height;
3507 if (dimension >= maxProcessedDim && dimension < maxRawDim)
3508 maxRawDim = dimension;
3509 }
3510 }
3511
3512 //Find minimum durations for processed, jpeg, and raw
3513 for (size_t i = 0; i < count; i++) {
3514 if (maxRawDim == gCamCapability[mCameraId]->raw_dim[i].width *
3515 gCamCapability[mCameraId]->raw_dim[i].height) {
3516 mMinRawFrameDuration = gCamCapability[mCameraId]->raw_min_duration[i];
3517 break;
3518 }
3519 }
3520 count = MIN(gCamCapability[mCameraId]->picture_sizes_tbl_cnt, MAX_SIZES_CNT);
3521 for (size_t i = 0; i < count; i++) {
3522 if (maxProcessedDim ==
3523 gCamCapability[mCameraId]->picture_sizes_tbl[i].width *
3524 gCamCapability[mCameraId]->picture_sizes_tbl[i].height) {
3525 mMinProcessedFrameDuration = gCamCapability[mCameraId]->picture_min_duration[i];
3526 mMinJpegFrameDuration = gCamCapability[mCameraId]->picture_min_duration[i];
3527 break;
3528 }
3529 }
3530}
3531
3532/*===========================================================================
3533 * FUNCTION : getMinFrameDuration
3534 *
3535 * DESCRIPTION: get minimum frame draution based on the current maximum frame durations
3536 * and current request configuration.
3537 *
3538 * PARAMETERS : @request: requset sent by the frameworks
3539 *
3540 * RETURN : min farme duration for a particular request
3541 *
3542 *==========================================================================*/
3543int64_t QCamera3HardwareInterface::getMinFrameDuration(const camera3_capture_request_t *request)
3544{
3545 bool hasJpegStream = false;
3546 bool hasRawStream = false;
3547 for (uint32_t i = 0; i < request->num_output_buffers; i ++) {
3548 const camera3_stream_t *stream = request->output_buffers[i].stream;
3549 if (stream->format == HAL_PIXEL_FORMAT_BLOB)
3550 hasJpegStream = true;
3551 else if (stream->format == HAL_PIXEL_FORMAT_RAW_OPAQUE ||
3552 stream->format == HAL_PIXEL_FORMAT_RAW10 ||
3553 stream->format == HAL_PIXEL_FORMAT_RAW16)
3554 hasRawStream = true;
3555 }
3556
3557 if (!hasJpegStream)
3558 return MAX(mMinRawFrameDuration, mMinProcessedFrameDuration);
3559 else
3560 return MAX(MAX(mMinRawFrameDuration, mMinProcessedFrameDuration), mMinJpegFrameDuration);
3561}
3562
3563/*===========================================================================
3564 * FUNCTION : handleBuffersDuringFlushLock
3565 *
3566 * DESCRIPTION: Account for buffers returned from back-end during flush
3567 * This function is executed while mMutex is held by the caller.
3568 *
3569 * PARAMETERS :
3570 * @buffer: image buffer for the callback
3571 *
3572 * RETURN :
3573 *==========================================================================*/
3574void QCamera3HardwareInterface::handleBuffersDuringFlushLock(camera3_stream_buffer_t *buffer)
3575{
3576 bool buffer_found = false;
3577 for (List<PendingBuffersInRequest>::iterator req =
3578 mPendingBuffersMap.mPendingBuffersInRequest.begin();
3579 req != mPendingBuffersMap.mPendingBuffersInRequest.end(); req++) {
3580 for (List<PendingBufferInfo>::iterator i =
3581 req->mPendingBufferList.begin();
3582 i != req->mPendingBufferList.end(); i++) {
3583 if (i->buffer == buffer->buffer) {
3584 mPendingBuffersMap.numPendingBufsAtFlush--;
3585 LOGD("Found buffer %p for Frame %d, numPendingBufsAtFlush = %d",
3586 buffer->buffer, req->frame_number,
3587 mPendingBuffersMap.numPendingBufsAtFlush);
3588 buffer_found = true;
3589 break;
3590 }
3591 }
3592 if (buffer_found) {
3593 break;
3594 }
3595 }
3596 if (mPendingBuffersMap.numPendingBufsAtFlush == 0) {
3597 //signal the flush()
3598 LOGD("All buffers returned to HAL. Continue flush");
3599 pthread_cond_signal(&mBuffersCond);
3600 }
3601}
3602
Thierry Strudel3d639192016-09-09 11:52:26 -07003603/*===========================================================================
3604 * FUNCTION : handleBatchMetadata
3605 *
3606 * DESCRIPTION: Handles metadata buffer callback in batch mode
3607 *
3608 * PARAMETERS : @metadata_buf: metadata buffer
3609 * @free_and_bufdone_meta_buf: Buf done on the meta buf and free
3610 * the meta buf in this method
3611 *
3612 * RETURN :
3613 *
3614 *==========================================================================*/
3615void QCamera3HardwareInterface::handleBatchMetadata(
3616 mm_camera_super_buf_t *metadata_buf, bool free_and_bufdone_meta_buf)
3617{
Thierry Strudele80ad7c2016-12-06 10:16:27 -08003618 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL3_HANDLE_BATCH_METADATA);
Thierry Strudel3d639192016-09-09 11:52:26 -07003619
3620 if (NULL == metadata_buf) {
3621 LOGE("metadata_buf is NULL");
3622 return;
3623 }
3624 /* In batch mode, the metdata will contain the frame number and timestamp of
3625 * the last frame in the batch. Eg: a batch containing buffers from request
3626 * 5,6,7 and 8 will have frame number and timestamp corresponding to 8.
3627 * multiple process_capture_requests => 1 set_param => 1 handleBatchMetata =>
3628 * multiple process_capture_results */
3629 metadata_buffer_t *metadata =
3630 (metadata_buffer_t *)metadata_buf->bufs[0]->buffer;
3631 int32_t frame_number_valid = 0, urgent_frame_number_valid = 0;
3632 uint32_t last_frame_number = 0, last_urgent_frame_number = 0;
3633 uint32_t first_frame_number = 0, first_urgent_frame_number = 0;
3634 uint32_t frame_number = 0, urgent_frame_number = 0;
3635 int64_t last_frame_capture_time = 0, first_frame_capture_time, capture_time;
3636 bool invalid_metadata = false;
3637 size_t urgentFrameNumDiff = 0, frameNumDiff = 0;
3638 size_t loopCount = 1;
Thierry Strudel54dc9782017-02-15 12:12:10 -08003639 bool is_metabuf_queued = false;
Thierry Strudel3d639192016-09-09 11:52:26 -07003640
3641 int32_t *p_frame_number_valid =
3642 POINTER_OF_META(CAM_INTF_META_FRAME_NUMBER_VALID, metadata);
3643 uint32_t *p_frame_number =
3644 POINTER_OF_META(CAM_INTF_META_FRAME_NUMBER, metadata);
3645 int64_t *p_capture_time =
3646 POINTER_OF_META(CAM_INTF_META_SENSOR_TIMESTAMP, metadata);
3647 int32_t *p_urgent_frame_number_valid =
3648 POINTER_OF_META(CAM_INTF_META_URGENT_FRAME_NUMBER_VALID, metadata);
3649 uint32_t *p_urgent_frame_number =
3650 POINTER_OF_META(CAM_INTF_META_URGENT_FRAME_NUMBER, metadata);
3651
3652 if ((NULL == p_frame_number_valid) || (NULL == p_frame_number) ||
3653 (NULL == p_capture_time) || (NULL == p_urgent_frame_number_valid) ||
3654 (NULL == p_urgent_frame_number)) {
3655 LOGE("Invalid metadata");
3656 invalid_metadata = true;
3657 } else {
3658 frame_number_valid = *p_frame_number_valid;
3659 last_frame_number = *p_frame_number;
3660 last_frame_capture_time = *p_capture_time;
3661 urgent_frame_number_valid = *p_urgent_frame_number_valid;
3662 last_urgent_frame_number = *p_urgent_frame_number;
3663 }
3664
3665 /* In batchmode, when no video buffers are requested, set_parms are sent
3666 * for every capture_request. The difference between consecutive urgent
3667 * frame numbers and frame numbers should be used to interpolate the
3668 * corresponding frame numbers and time stamps */
3669 pthread_mutex_lock(&mMutex);
3670 if (urgent_frame_number_valid) {
Thierry Strudel295a0ca2016-11-03 18:38:47 -07003671 ssize_t idx = mPendingBatchMap.indexOfKey(last_urgent_frame_number);
3672 if(idx < 0) {
3673 LOGE("Invalid urgent frame number received: %d. Irrecoverable error",
3674 last_urgent_frame_number);
3675 mState = ERROR;
3676 pthread_mutex_unlock(&mMutex);
3677 return;
3678 }
3679 first_urgent_frame_number = mPendingBatchMap.valueAt(idx);
Thierry Strudel3d639192016-09-09 11:52:26 -07003680 urgentFrameNumDiff = last_urgent_frame_number + 1 -
3681 first_urgent_frame_number;
3682
3683 LOGD("urgent_frm: valid: %d frm_num: %d - %d",
3684 urgent_frame_number_valid,
3685 first_urgent_frame_number, last_urgent_frame_number);
3686 }
3687
3688 if (frame_number_valid) {
Thierry Strudel295a0ca2016-11-03 18:38:47 -07003689 ssize_t idx = mPendingBatchMap.indexOfKey(last_frame_number);
3690 if(idx < 0) {
3691 LOGE("Invalid frame number received: %d. Irrecoverable error",
3692 last_frame_number);
3693 mState = ERROR;
3694 pthread_mutex_unlock(&mMutex);
3695 return;
3696 }
3697 first_frame_number = mPendingBatchMap.valueAt(idx);
Thierry Strudel3d639192016-09-09 11:52:26 -07003698 frameNumDiff = last_frame_number + 1 -
3699 first_frame_number;
3700 mPendingBatchMap.removeItem(last_frame_number);
3701
3702 LOGD("frm: valid: %d frm_num: %d - %d",
3703 frame_number_valid,
3704 first_frame_number, last_frame_number);
3705
3706 }
3707 pthread_mutex_unlock(&mMutex);
3708
3709 if (urgent_frame_number_valid || frame_number_valid) {
3710 loopCount = MAX(urgentFrameNumDiff, frameNumDiff);
3711 if (urgentFrameNumDiff > MAX_HFR_BATCH_SIZE)
3712 LOGE("urgentFrameNumDiff: %d urgentFrameNum: %d",
3713 urgentFrameNumDiff, last_urgent_frame_number);
3714 if (frameNumDiff > MAX_HFR_BATCH_SIZE)
3715 LOGE("frameNumDiff: %d frameNum: %d",
3716 frameNumDiff, last_frame_number);
3717 }
3718
3719 for (size_t i = 0; i < loopCount; i++) {
3720 /* handleMetadataWithLock is called even for invalid_metadata for
3721 * pipeline depth calculation */
3722 if (!invalid_metadata) {
3723 /* Infer frame number. Batch metadata contains frame number of the
3724 * last frame */
3725 if (urgent_frame_number_valid) {
3726 if (i < urgentFrameNumDiff) {
3727 urgent_frame_number =
3728 first_urgent_frame_number + i;
3729 LOGD("inferred urgent frame_number: %d",
3730 urgent_frame_number);
3731 ADD_SET_PARAM_ENTRY_TO_BATCH(metadata,
3732 CAM_INTF_META_URGENT_FRAME_NUMBER, urgent_frame_number);
3733 } else {
3734 /* This is to handle when urgentFrameNumDiff < frameNumDiff */
3735 ADD_SET_PARAM_ENTRY_TO_BATCH(metadata,
3736 CAM_INTF_META_URGENT_FRAME_NUMBER_VALID, 0);
3737 }
3738 }
3739
3740 /* Infer frame number. Batch metadata contains frame number of the
3741 * last frame */
3742 if (frame_number_valid) {
3743 if (i < frameNumDiff) {
3744 frame_number = first_frame_number + i;
3745 LOGD("inferred frame_number: %d", frame_number);
3746 ADD_SET_PARAM_ENTRY_TO_BATCH(metadata,
3747 CAM_INTF_META_FRAME_NUMBER, frame_number);
3748 } else {
3749 /* This is to handle when urgentFrameNumDiff > frameNumDiff */
3750 ADD_SET_PARAM_ENTRY_TO_BATCH(metadata,
3751 CAM_INTF_META_FRAME_NUMBER_VALID, 0);
3752 }
3753 }
3754
3755 if (last_frame_capture_time) {
3756 //Infer timestamp
3757 first_frame_capture_time = last_frame_capture_time -
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003758 (((loopCount - 1) * NSEC_PER_SEC) / (double) mHFRVideoFps);
Thierry Strudel3d639192016-09-09 11:52:26 -07003759 capture_time =
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003760 first_frame_capture_time + (i * NSEC_PER_SEC / (double) mHFRVideoFps);
Thierry Strudel3d639192016-09-09 11:52:26 -07003761 ADD_SET_PARAM_ENTRY_TO_BATCH(metadata,
3762 CAM_INTF_META_SENSOR_TIMESTAMP, capture_time);
3763 LOGD("batch capture_time: %lld, capture_time: %lld",
3764 last_frame_capture_time, capture_time);
3765 }
3766 }
3767 pthread_mutex_lock(&mMutex);
3768 handleMetadataWithLock(metadata_buf,
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003769 false /* free_and_bufdone_meta_buf */,
Shuzhen Wang94ddf072017-03-12 19:47:23 -07003770 (i == urgentFrameNumDiff-1), /* last urgent metadata in the batch */
3771 (i == frameNumDiff-1), /* last metadata in the batch metadata */
Thierry Strudel54dc9782017-02-15 12:12:10 -08003772 &is_metabuf_queued /* if metabuf isqueued or not */);
Thierry Strudel3d639192016-09-09 11:52:26 -07003773 pthread_mutex_unlock(&mMutex);
3774 }
3775
3776 /* BufDone metadata buffer */
Thierry Strudel54dc9782017-02-15 12:12:10 -08003777 if (free_and_bufdone_meta_buf && !is_metabuf_queued) {
Thierry Strudel3d639192016-09-09 11:52:26 -07003778 mMetadataChannel->bufDone(metadata_buf);
3779 free(metadata_buf);
Thierry Strudel54dc9782017-02-15 12:12:10 -08003780 metadata_buf = NULL;
Thierry Strudel3d639192016-09-09 11:52:26 -07003781 }
3782}
3783
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003784void QCamera3HardwareInterface::notifyError(uint32_t frameNumber,
3785 camera3_error_msg_code_t errorCode)
3786{
3787 camera3_notify_msg_t notify_msg;
3788 memset(&notify_msg, 0, sizeof(camera3_notify_msg_t));
3789 notify_msg.type = CAMERA3_MSG_ERROR;
3790 notify_msg.message.error.error_code = errorCode;
3791 notify_msg.message.error.error_stream = NULL;
3792 notify_msg.message.error.frame_number = frameNumber;
Thierry Strudele80ad7c2016-12-06 10:16:27 -08003793 orchestrateNotify(&notify_msg);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003794
3795 return;
3796}
Shuzhen Wang3c077d72017-04-20 22:48:59 -07003797
3798/*===========================================================================
3799 * FUNCTION : sendPartialMetadataWithLock
3800 *
3801 * DESCRIPTION: Send partial capture result callback with mMutex lock held.
3802 *
3803 * PARAMETERS : @metadata: metadata buffer
3804 * @requestIter: The iterator for the pending capture request for
3805 * which the partial result is being sen
3806 * @lastUrgentMetadataInBatch: Boolean to indicate whether this is the
3807 * last urgent metadata in a batch. Always true for non-batch mode
Shuzhen Wang485e2442017-08-02 12:21:08 -07003808 * @isJumpstartMetadata: Whether this is a partial metadata for
3809 * jumpstart, i.e. even though it doesn't map to a valid partial
3810 * frame number, its metadata entries should be kept.
Shuzhen Wang3c077d72017-04-20 22:48:59 -07003811 *
3812 * RETURN :
3813 *
3814 *==========================================================================*/
3815
3816void QCamera3HardwareInterface::sendPartialMetadataWithLock(
3817 metadata_buffer_t *metadata,
3818 const pendingRequestIterator requestIter,
Shuzhen Wang485e2442017-08-02 12:21:08 -07003819 bool lastUrgentMetadataInBatch,
3820 bool isJumpstartMetadata)
Shuzhen Wang3c077d72017-04-20 22:48:59 -07003821{
3822 camera3_capture_result_t result;
3823 memset(&result, 0, sizeof(camera3_capture_result_t));
3824
3825 requestIter->partial_result_cnt++;
3826
3827 // Extract 3A metadata
3828 result.result = translateCbUrgentMetadataToResultMetadata(
Shuzhen Wang485e2442017-08-02 12:21:08 -07003829 metadata, lastUrgentMetadataInBatch, requestIter->frame_number,
3830 isJumpstartMetadata);
Shuzhen Wang3c077d72017-04-20 22:48:59 -07003831 // Populate metadata result
3832 result.frame_number = requestIter->frame_number;
3833 result.num_output_buffers = 0;
3834 result.output_buffers = NULL;
3835 result.partial_result = requestIter->partial_result_cnt;
3836
3837 {
Chien-Yu Chen77ccd022017-06-23 12:00:36 -07003838 std::unique_lock<std::mutex> l(gHdrPlusClientLock);
Shuzhen Wang3c077d72017-04-20 22:48:59 -07003839 if (gHdrPlusClient != nullptr && mHdrPlusModeEnabled) {
3840 // Notify HDR+ client about the partial metadata.
3841 gHdrPlusClient->notifyFrameMetadata(result.frame_number, *result.result,
3842 result.partial_result == PARTIAL_RESULT_COUNT);
3843 }
3844 }
3845
3846 orchestrateResult(&result);
3847 LOGD("urgent frame_number = %u", result.frame_number);
3848 free_camera_metadata((camera_metadata_t *)result.result);
3849}
3850
Thierry Strudel3d639192016-09-09 11:52:26 -07003851/*===========================================================================
3852 * FUNCTION : handleMetadataWithLock
3853 *
3854 * DESCRIPTION: Handles metadata buffer callback with mMutex lock held.
3855 *
3856 * PARAMETERS : @metadata_buf: metadata buffer
3857 * @free_and_bufdone_meta_buf: Buf done on the meta buf and free
3858 * the meta buf in this method
Shuzhen Wang94ddf072017-03-12 19:47:23 -07003859 * @lastUrgentMetadataInBatch: Boolean to indicate whether this is the
3860 * last urgent metadata in a batch. Always true for non-batch mode
3861 * @lastMetadataInBatch: Boolean to indicate whether this is the
3862 * last metadata in a batch. Always true for non-batch mode
Thierry Strudel54dc9782017-02-15 12:12:10 -08003863 * @p_is_metabuf_queued: Pointer to Boolean to check if metadata
3864 * buffer is enqueued or not.
Thierry Strudel3d639192016-09-09 11:52:26 -07003865 *
3866 * RETURN :
3867 *
3868 *==========================================================================*/
3869void QCamera3HardwareInterface::handleMetadataWithLock(
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003870 mm_camera_super_buf_t *metadata_buf, bool free_and_bufdone_meta_buf,
Shuzhen Wang94ddf072017-03-12 19:47:23 -07003871 bool lastUrgentMetadataInBatch, bool lastMetadataInBatch,
3872 bool *p_is_metabuf_queued)
Thierry Strudel3d639192016-09-09 11:52:26 -07003873{
Thierry Strudele80ad7c2016-12-06 10:16:27 -08003874 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL3_HANDLE_METADATA_LKD);
Thierry Strudel3d639192016-09-09 11:52:26 -07003875 if ((mFlushPerf) || (ERROR == mState) || (DEINIT == mState)) {
3876 //during flush do not send metadata from this thread
3877 LOGD("not sending metadata during flush or when mState is error");
3878 if (free_and_bufdone_meta_buf) {
3879 mMetadataChannel->bufDone(metadata_buf);
3880 free(metadata_buf);
3881 }
3882 return;
3883 }
3884
3885 //not in flush
3886 metadata_buffer_t *metadata = (metadata_buffer_t *)metadata_buf->bufs[0]->buffer;
3887 int32_t frame_number_valid, urgent_frame_number_valid;
3888 uint32_t frame_number, urgent_frame_number;
Jason Lee603176d2017-05-31 11:43:27 -07003889 int64_t capture_time, capture_time_av;
Thierry Strudel3d639192016-09-09 11:52:26 -07003890 nsecs_t currentSysTime;
3891
3892 int32_t *p_frame_number_valid =
3893 POINTER_OF_META(CAM_INTF_META_FRAME_NUMBER_VALID, metadata);
3894 uint32_t *p_frame_number = POINTER_OF_META(CAM_INTF_META_FRAME_NUMBER, metadata);
3895 int64_t *p_capture_time = POINTER_OF_META(CAM_INTF_META_SENSOR_TIMESTAMP, metadata);
Jason Lee603176d2017-05-31 11:43:27 -07003896 int64_t *p_capture_time_av = POINTER_OF_META(CAM_INTF_META_SENSOR_TIMESTAMP_AV, metadata);
Thierry Strudel3d639192016-09-09 11:52:26 -07003897 int32_t *p_urgent_frame_number_valid =
3898 POINTER_OF_META(CAM_INTF_META_URGENT_FRAME_NUMBER_VALID, metadata);
3899 uint32_t *p_urgent_frame_number =
3900 POINTER_OF_META(CAM_INTF_META_URGENT_FRAME_NUMBER, metadata);
3901 IF_META_AVAILABLE(cam_stream_ID_t, p_cam_frame_drop, CAM_INTF_META_FRAME_DROPPED,
3902 metadata) {
3903 LOGD("Dropped frame info for frame_number_valid %d, frame_number %d",
3904 *p_frame_number_valid, *p_frame_number);
3905 }
3906
Chien-Yu Chene687bd02016-12-07 18:30:26 -08003907 camera_metadata_t *resultMetadata = nullptr;
3908
Thierry Strudel3d639192016-09-09 11:52:26 -07003909 if ((NULL == p_frame_number_valid) || (NULL == p_frame_number) || (NULL == p_capture_time) ||
3910 (NULL == p_urgent_frame_number_valid) || (NULL == p_urgent_frame_number)) {
3911 LOGE("Invalid metadata");
3912 if (free_and_bufdone_meta_buf) {
3913 mMetadataChannel->bufDone(metadata_buf);
3914 free(metadata_buf);
3915 }
3916 goto done_metadata;
3917 }
3918 frame_number_valid = *p_frame_number_valid;
3919 frame_number = *p_frame_number;
3920 capture_time = *p_capture_time;
Jason Lee603176d2017-05-31 11:43:27 -07003921 capture_time_av = *p_capture_time_av;
Thierry Strudel3d639192016-09-09 11:52:26 -07003922 urgent_frame_number_valid = *p_urgent_frame_number_valid;
3923 urgent_frame_number = *p_urgent_frame_number;
3924 currentSysTime = systemTime(CLOCK_MONOTONIC);
3925
Jason Lee603176d2017-05-31 11:43:27 -07003926 if (!gCamCapability[mCameraId]->timestamp_calibrated) {
3927 const int tries = 3;
3928 nsecs_t bestGap, measured;
3929 for (int i = 0; i < tries; ++i) {
3930 const nsecs_t tmono = systemTime(SYSTEM_TIME_MONOTONIC);
3931 const nsecs_t tbase = systemTime(SYSTEM_TIME_BOOTTIME);
3932 const nsecs_t tmono2 = systemTime(SYSTEM_TIME_MONOTONIC);
3933 const nsecs_t gap = tmono2 - tmono;
3934 if (i == 0 || gap < bestGap) {
3935 bestGap = gap;
3936 measured = tbase - ((tmono + tmono2) >> 1);
3937 }
3938 }
3939 capture_time -= measured;
3940 }
3941
Thierry Strudel3d639192016-09-09 11:52:26 -07003942 // Detect if buffers from any requests are overdue
3943 for (auto &req : mPendingBuffersMap.mPendingBuffersInRequest) {
Chien-Yu Chene687bd02016-12-07 18:30:26 -08003944 int64_t timeout;
3945 {
3946 Mutex::Autolock lock(mHdrPlusPendingRequestsLock);
3947 // If there is a pending HDR+ request, the following requests may be blocked until the
3948 // HDR+ request is done. So allow a longer timeout.
3949 timeout = (mHdrPlusPendingRequests.size() > 0) ?
3950 MISSING_HDRPLUS_REQUEST_BUF_TIMEOUT : MISSING_REQUEST_BUF_TIMEOUT;
Emilian Peev744149a2018-02-22 11:57:11 +00003951 timeout = s2ns(timeout);
Emilian Peev30522a12017-08-03 14:36:33 +01003952 if (timeout < mExpectedInflightDuration) {
3953 timeout = mExpectedInflightDuration;
3954 }
Chien-Yu Chene687bd02016-12-07 18:30:26 -08003955 }
3956
Emilian Peev744149a2018-02-22 11:57:11 +00003957 if ((currentSysTime - req.timestamp) > timeout) {
Thierry Strudel3d639192016-09-09 11:52:26 -07003958 for (auto &missed : req.mPendingBufferList) {
Thierry Strudelc2ee3302016-11-17 12:33:12 -08003959 assert(missed.stream->priv);
3960 if (missed.stream->priv) {
3961 QCamera3Channel *ch = (QCamera3Channel *)(missed.stream->priv);
3962 assert(ch->mStreams[0]);
3963 if (ch->mStreams[0]) {
3964 LOGE("Cancel missing frame = %d, buffer = %p,"
3965 "stream type = %d, stream format = %d",
3966 req.frame_number, missed.buffer,
3967 ch->mStreams[0]->getMyType(), missed.stream->format);
3968 ch->timeoutFrame(req.frame_number);
3969 }
3970 }
Thierry Strudel3d639192016-09-09 11:52:26 -07003971 }
3972 }
3973 }
Shuzhen Wang3c077d72017-04-20 22:48:59 -07003974 //For the very first metadata callback, regardless whether it contains valid
3975 //frame number, send the partial metadata for the jumpstarting requests.
3976 //Note that this has to be done even if the metadata doesn't contain valid
3977 //urgent frame number, because in the case only 1 request is ever submitted
3978 //to HAL, there won't be subsequent valid urgent frame number.
3979 if (mFirstMetadataCallback) {
3980 for (pendingRequestIterator i =
3981 mPendingRequestsList.begin(); i != mPendingRequestsList.end(); i++) {
3982 if (i->bUseFirstPartial) {
Shuzhen Wang485e2442017-08-02 12:21:08 -07003983 sendPartialMetadataWithLock(metadata, i, lastUrgentMetadataInBatch,
3984 true /*isJumpstartMetadata*/);
Shuzhen Wang3c077d72017-04-20 22:48:59 -07003985 }
3986 }
3987 mFirstMetadataCallback = false;
3988 }
3989
Thierry Strudel3d639192016-09-09 11:52:26 -07003990 //Partial result on process_capture_result for timestamp
3991 if (urgent_frame_number_valid) {
Shuzhen Wang3c077d72017-04-20 22:48:59 -07003992 LOGD("valid urgent frame_number = %u", urgent_frame_number);
Thierry Strudel3d639192016-09-09 11:52:26 -07003993
3994 //Recieved an urgent Frame Number, handle it
3995 //using partial results
3996 for (pendingRequestIterator i =
3997 mPendingRequestsList.begin(); i != mPendingRequestsList.end(); i++) {
3998 LOGD("Iterator Frame = %d urgent frame = %d",
3999 i->frame_number, urgent_frame_number);
4000
Chien-Yu Chen29fd1d72017-04-27 18:42:09 -07004001 if ((!i->input_buffer) && (!i->hdrplus) && (i->frame_number < urgent_frame_number) &&
Shuzhen Wanga1d82a92017-09-19 14:39:43 -07004002 (i->partial_result_cnt == 0)) {
Thierry Strudel3d639192016-09-09 11:52:26 -07004003 LOGE("Error: HAL missed urgent metadata for frame number %d",
4004 i->frame_number);
Shuzhen Wanga1d82a92017-09-19 14:39:43 -07004005 i->partialResultDropped = true;
Shuzhen Wang1ee712a2017-03-22 17:51:26 -07004006 i->partial_result_cnt++;
Thierry Strudel3d639192016-09-09 11:52:26 -07004007 }
4008
4009 if (i->frame_number == urgent_frame_number &&
Shuzhen Wang3c077d72017-04-20 22:48:59 -07004010 i->partial_result_cnt == 0) {
Shuzhen Wang485e2442017-08-02 12:21:08 -07004011 sendPartialMetadataWithLock(metadata, i, lastUrgentMetadataInBatch,
4012 false /*isJumpstartMetadata*/);
Thierry Strudel295a0ca2016-11-03 18:38:47 -07004013 if (mResetInstantAEC && mInstantAECSettledFrameNumber == 0) {
4014 // Instant AEC settled for this frame.
4015 LOGH("instant AEC settled for frame number %d", urgent_frame_number);
4016 mInstantAECSettledFrameNumber = urgent_frame_number;
4017 }
Thierry Strudel3d639192016-09-09 11:52:26 -07004018 break;
4019 }
4020 }
4021 }
4022
4023 if (!frame_number_valid) {
4024 LOGD("Not a valid normal frame number, used as SOF only");
4025 if (free_and_bufdone_meta_buf) {
4026 mMetadataChannel->bufDone(metadata_buf);
4027 free(metadata_buf);
4028 }
4029 goto done_metadata;
4030 }
4031 LOGH("valid frame_number = %u, capture_time = %lld",
4032 frame_number, capture_time);
4033
Emilian Peev4e0fe952017-06-30 12:40:09 -07004034 handleDepthDataLocked(metadata->depth_data, frame_number,
4035 metadata->is_depth_data_valid);
Emilian Peev7650c122017-01-19 08:24:33 -08004036
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004037 // Check whether any stream buffer corresponding to this is dropped or not
4038 // If dropped, then send the ERROR_BUFFER for the corresponding stream
4039 // OR check if instant AEC is enabled, then need to drop frames untill AEC is settled.
4040 for (auto & pendingRequest : mPendingRequestsList) {
4041 if (p_cam_frame_drop || (mInstantAEC || pendingRequest.frame_number <
4042 mInstantAECSettledFrameNumber)) {
4043 camera3_notify_msg_t notify_msg = {};
4044 for (auto & buffer : pendingRequest.buffers) {
Thierry Strudel295a0ca2016-11-03 18:38:47 -07004045 bool dropFrame = false;
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004046 QCamera3ProcessingChannel *channel =
4047 (QCamera3ProcessingChannel *)buffer.stream->priv;
Thierry Strudel9e74aae2016-09-22 17:10:18 -07004048 uint32_t streamID = channel->getStreamID(channel->getStreamTypeMask());
Thierry Strudel295a0ca2016-11-03 18:38:47 -07004049 if (p_cam_frame_drop) {
4050 for (uint32_t k = 0; k < p_cam_frame_drop->num_streams; k++) {
Thierry Strudelc2ee3302016-11-17 12:33:12 -08004051 if (streamID == p_cam_frame_drop->stream_request[k].streamID) {
Thierry Strudel295a0ca2016-11-03 18:38:47 -07004052 // Got the stream ID for drop frame.
4053 dropFrame = true;
4054 break;
4055 }
4056 }
4057 } else {
4058 // This is instant AEC case.
4059 // For instant AEC drop the stream untill AEC is settled.
4060 dropFrame = true;
4061 }
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004062
Thierry Strudel295a0ca2016-11-03 18:38:47 -07004063 if (dropFrame) {
4064 // Send Error notify to frameworks with CAMERA3_MSG_ERROR_BUFFER
4065 if (p_cam_frame_drop) {
4066 // Treat msg as error for system buffer drops
Thierry Strudel9e74aae2016-09-22 17:10:18 -07004067 LOGE("Start of reporting error frame#=%u, streamID=%u",
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004068 pendingRequest.frame_number, streamID);
Thierry Strudel295a0ca2016-11-03 18:38:47 -07004069 } else {
4070 // For instant AEC, inform frame drop and frame number
4071 LOGH("Start of reporting error frame#=%u for instant AEC, streamID=%u, "
4072 "AEC settled frame number = %u",
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004073 pendingRequest.frame_number, streamID,
4074 mInstantAECSettledFrameNumber);
Thierry Strudel295a0ca2016-11-03 18:38:47 -07004075 }
4076 notify_msg.type = CAMERA3_MSG_ERROR;
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004077 notify_msg.message.error.frame_number = pendingRequest.frame_number;
Thierry Strudel295a0ca2016-11-03 18:38:47 -07004078 notify_msg.message.error.error_code = CAMERA3_MSG_ERROR_BUFFER ;
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004079 notify_msg.message.error.error_stream = buffer.stream;
Thierry Strudele80ad7c2016-12-06 10:16:27 -08004080 orchestrateNotify(&notify_msg);
Thierry Strudel295a0ca2016-11-03 18:38:47 -07004081 if (p_cam_frame_drop) {
4082 // Treat msg as error for system buffer drops
Thierry Strudel9e74aae2016-09-22 17:10:18 -07004083 LOGE("End of reporting error frame#=%u, streamID=%u",
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004084 pendingRequest.frame_number, streamID);
Thierry Strudel295a0ca2016-11-03 18:38:47 -07004085 } else {
4086 // For instant AEC, inform frame drop and frame number
4087 LOGH("End of reporting error frame#=%u for instant AEC, streamID=%u, "
4088 "AEC settled frame number = %u",
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004089 pendingRequest.frame_number, streamID,
4090 mInstantAECSettledFrameNumber);
Thierry Strudel295a0ca2016-11-03 18:38:47 -07004091 }
4092 PendingFrameDropInfo PendingFrameDrop;
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004093 PendingFrameDrop.frame_number = pendingRequest.frame_number;
Thierry Strudel295a0ca2016-11-03 18:38:47 -07004094 PendingFrameDrop.stream_ID = streamID;
4095 // Add the Frame drop info to mPendingFrameDropList
4096 mPendingFrameDropList.push_back(PendingFrameDrop);
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004097 }
Thierry Strudel3d639192016-09-09 11:52:26 -07004098 }
4099 }
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004100 }
Thierry Strudel3d639192016-09-09 11:52:26 -07004101
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004102 for (auto & pendingRequest : mPendingRequestsList) {
4103 // Find the pending request with the frame number.
Shuzhen Wanga1d82a92017-09-19 14:39:43 -07004104 if (pendingRequest.frame_number < frame_number) {
4105 // Workaround for case where shutter is missing due to dropped
4106 // metadata
Emilian Peev7b0175d2017-09-29 12:57:31 +01004107 if (!pendingRequest.hdrplus && (pendingRequest.input_buffer == nullptr)) {
Chien-Yu Chen0469c9b2017-09-22 13:22:19 -07004108 mShutterDispatcher.markShutterReady(pendingRequest.frame_number, capture_time);
4109 }
Shuzhen Wanga1d82a92017-09-19 14:39:43 -07004110 } else if (pendingRequest.frame_number == frame_number) {
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004111 // Update the sensor timestamp.
4112 pendingRequest.timestamp = capture_time;
Thierry Strudel9e74aae2016-09-22 17:10:18 -07004113
Thierry Strudel3d639192016-09-09 11:52:26 -07004114
Thierry Strudelcca4d9c2016-10-20 08:25:53 -07004115 /* Set the timestamp in display metadata so that clients aware of
4116 private_handle such as VT can use this un-modified timestamps.
4117 Camera framework is unaware of this timestamp and cannot change this */
Jason Lee603176d2017-05-31 11:43:27 -07004118 updateTimeStampInPendingBuffers(pendingRequest.frame_number, capture_time_av);
Thierry Strudelcca4d9c2016-10-20 08:25:53 -07004119
Thierry Strudel3d639192016-09-09 11:52:26 -07004120 // Find channel requiring metadata, meaning internal offline postprocess
4121 // is needed.
4122 //TODO: for now, we don't support two streams requiring metadata at the same time.
4123 // (because we are not making copies, and metadata buffer is not reference counted.
4124 bool internalPproc = false;
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004125 for (pendingBufferIterator iter = pendingRequest.buffers.begin();
4126 iter != pendingRequest.buffers.end(); iter++) {
Thierry Strudel3d639192016-09-09 11:52:26 -07004127 if (iter->need_metadata) {
4128 internalPproc = true;
4129 QCamera3ProcessingChannel *channel =
4130 (QCamera3ProcessingChannel *)iter->stream->priv;
4131 channel->queueReprocMetadata(metadata_buf);
Thierry Strudel54dc9782017-02-15 12:12:10 -08004132 if(p_is_metabuf_queued != NULL) {
4133 *p_is_metabuf_queued = true;
4134 }
Thierry Strudel3d639192016-09-09 11:52:26 -07004135 break;
4136 }
4137 }
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004138 for (auto itr = pendingRequest.internalRequestList.begin();
4139 itr != pendingRequest.internalRequestList.end(); itr++) {
Thierry Strudele80ad7c2016-12-06 10:16:27 -08004140 if (itr->need_metadata) {
4141 internalPproc = true;
4142 QCamera3ProcessingChannel *channel =
4143 (QCamera3ProcessingChannel *)itr->stream->priv;
4144 channel->queueReprocMetadata(metadata_buf);
4145 break;
4146 }
4147 }
4148
Thierry Strudel54dc9782017-02-15 12:12:10 -08004149 saveExifParams(metadata);
Chien-Yu Chen66ec22a2017-04-13 18:00:36 -07004150
4151 bool *enableZsl = nullptr;
4152 if (gExposeEnableZslKey) {
4153 enableZsl = &pendingRequest.enableZsl;
4154 }
4155
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004156 resultMetadata = translateFromHalMetadata(metadata,
Shuzhen Wang181c57b2017-07-21 11:39:44 -07004157 pendingRequest, internalPproc,
Chien-Yu Chen66ec22a2017-04-13 18:00:36 -07004158 lastMetadataInBatch, enableZsl);
Thierry Strudel3d639192016-09-09 11:52:26 -07004159
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004160 updateFpsInPreviewBuffer(metadata, pendingRequest.frame_number);
Thierry Strudel3d639192016-09-09 11:52:26 -07004161
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004162 if (pendingRequest.blob_request) {
4163 //Dump tuning metadata if enabled and available
4164 char prop[PROPERTY_VALUE_MAX];
4165 memset(prop, 0, sizeof(prop));
4166 property_get("persist.camera.dumpmetadata", prop, "0");
4167 int32_t enabled = atoi(prop);
4168 if (enabled && metadata->is_tuning_params_valid) {
4169 dumpMetadataToFile(metadata->tuning_params,
4170 mMetaFrameCount,
4171 enabled,
4172 "Snapshot",
4173 frame_number);
Thierry Strudel3d639192016-09-09 11:52:26 -07004174 }
4175 }
4176
4177 if (!internalPproc) {
4178 LOGD("couldn't find need_metadata for this metadata");
4179 // Return metadata buffer
4180 if (free_and_bufdone_meta_buf) {
4181 mMetadataChannel->bufDone(metadata_buf);
4182 free(metadata_buf);
4183 }
4184 }
Thierry Strudel3d639192016-09-09 11:52:26 -07004185
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004186 break;
Thierry Strudel3d639192016-09-09 11:52:26 -07004187 }
4188 }
4189
Chien-Yu Chen3f303522017-05-19 15:21:45 -07004190 mShutterDispatcher.markShutterReady(frame_number, capture_time);
4191
4192 // Try to send out capture result metadata.
4193 handlePendingResultMetadataWithLock(frame_number, resultMetadata);
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004194 return;
4195
Thierry Strudel3d639192016-09-09 11:52:26 -07004196done_metadata:
4197 for (pendingRequestIterator i = mPendingRequestsList.begin();
4198 i != mPendingRequestsList.end() ;i++) {
4199 i->pipeline_depth++;
4200 }
4201 LOGD("mPendingLiveRequest = %d", mPendingLiveRequest);
4202 unblockRequestIfNecessary();
4203}
4204
4205/*===========================================================================
Emilian Peev7650c122017-01-19 08:24:33 -08004206 * FUNCTION : handleDepthDataWithLock
4207 *
4208 * DESCRIPTION: Handles incoming depth data
4209 *
4210 * PARAMETERS : @depthData : Depth data
4211 * @frameNumber: Frame number of the incoming depth data
Emilian Peev4e0fe952017-06-30 12:40:09 -07004212 * @valid : Valid flag for the incoming data
Emilian Peev7650c122017-01-19 08:24:33 -08004213 *
4214 * RETURN :
4215 *
4216 *==========================================================================*/
4217void QCamera3HardwareInterface::handleDepthDataLocked(
Emilian Peev4e0fe952017-06-30 12:40:09 -07004218 const cam_depth_data_t &depthData, uint32_t frameNumber, uint8_t valid) {
Emilian Peev7650c122017-01-19 08:24:33 -08004219 uint32_t currentFrameNumber;
4220 buffer_handle_t *depthBuffer;
4221
4222 if (nullptr == mDepthChannel) {
Emilian Peev7650c122017-01-19 08:24:33 -08004223 return;
4224 }
4225
4226 camera3_stream_buffer_t resultBuffer =
4227 {.acquire_fence = -1,
4228 .release_fence = -1,
4229 .status = CAMERA3_BUFFER_STATUS_OK,
4230 .buffer = nullptr,
4231 .stream = mDepthChannel->getStream()};
Emilian Peev7650c122017-01-19 08:24:33 -08004232 do {
4233 depthBuffer = mDepthChannel->getOldestFrame(currentFrameNumber);
4234 if (nullptr == depthBuffer) {
4235 break;
4236 }
4237
Emilian Peev7650c122017-01-19 08:24:33 -08004238 resultBuffer.buffer = depthBuffer;
4239 if (currentFrameNumber == frameNumber) {
Emilian Peev4e0fe952017-06-30 12:40:09 -07004240 if (valid) {
4241 int32_t rc = mDepthChannel->populateDepthData(depthData,
4242 frameNumber);
4243 if (NO_ERROR != rc) {
4244 resultBuffer.status = CAMERA3_BUFFER_STATUS_ERROR;
4245 } else {
4246 resultBuffer.status = CAMERA3_BUFFER_STATUS_OK;
4247 }
Emilian Peev7650c122017-01-19 08:24:33 -08004248 } else {
Emilian Peev4e0fe952017-06-30 12:40:09 -07004249 resultBuffer.status = CAMERA3_BUFFER_STATUS_ERROR;
Emilian Peev7650c122017-01-19 08:24:33 -08004250 }
4251 } else if (currentFrameNumber > frameNumber) {
4252 break;
4253 } else {
4254 camera3_notify_msg_t notify_msg = {.type = CAMERA3_MSG_ERROR,
4255 {{currentFrameNumber, mDepthChannel->getStream(),
4256 CAMERA3_MSG_ERROR_BUFFER}}};
4257 orchestrateNotify(&notify_msg);
4258
4259 LOGE("Depth buffer for frame number: %d is missing "
4260 "returning back!", currentFrameNumber);
4261 resultBuffer.status = CAMERA3_BUFFER_STATUS_ERROR;
4262 }
4263 mDepthChannel->unmapBuffer(currentFrameNumber);
Chien-Yu Chen3f303522017-05-19 15:21:45 -07004264 mOutputBufferDispatcher.markBufferReady(currentFrameNumber, resultBuffer);
Emilian Peev7650c122017-01-19 08:24:33 -08004265 } while (currentFrameNumber < frameNumber);
4266}
4267
4268/*===========================================================================
4269 * FUNCTION : notifyErrorFoPendingDepthData
4270 *
4271 * DESCRIPTION: Returns error for any pending depth buffers
4272 *
4273 * PARAMETERS : depthCh - depth channel that needs to get flushed
4274 *
4275 * RETURN :
4276 *
4277 *==========================================================================*/
4278void QCamera3HardwareInterface::notifyErrorFoPendingDepthData(
4279 QCamera3DepthChannel *depthCh) {
4280 uint32_t currentFrameNumber;
4281 buffer_handle_t *depthBuffer;
4282
4283 if (nullptr == depthCh) {
4284 return;
4285 }
4286
4287 camera3_notify_msg_t notify_msg =
4288 {.type = CAMERA3_MSG_ERROR,
4289 {{0, depthCh->getStream(), CAMERA3_MSG_ERROR_BUFFER}}};
4290 camera3_stream_buffer_t resultBuffer =
4291 {.acquire_fence = -1,
4292 .release_fence = -1,
4293 .buffer = nullptr,
4294 .stream = depthCh->getStream(),
4295 .status = CAMERA3_BUFFER_STATUS_ERROR};
Emilian Peev7650c122017-01-19 08:24:33 -08004296
4297 while (nullptr !=
4298 (depthBuffer = depthCh->getOldestFrame(currentFrameNumber))) {
4299 depthCh->unmapBuffer(currentFrameNumber);
4300
4301 notify_msg.message.error.frame_number = currentFrameNumber;
4302 orchestrateNotify(&notify_msg);
4303
Chien-Yu Chen3f303522017-05-19 15:21:45 -07004304 mOutputBufferDispatcher.markBufferReady(currentFrameNumber, resultBuffer);
Emilian Peev7650c122017-01-19 08:24:33 -08004305 };
4306}
4307
4308/*===========================================================================
Thierry Strudel3d639192016-09-09 11:52:26 -07004309 * FUNCTION : hdrPlusPerfLock
4310 *
4311 * DESCRIPTION: perf lock for HDR+ using custom intent
4312 *
4313 * PARAMETERS : @metadata_buf: Metadata super_buf pointer
4314 *
4315 * RETURN : None
4316 *
4317 *==========================================================================*/
4318void QCamera3HardwareInterface::hdrPlusPerfLock(
4319 mm_camera_super_buf_t *metadata_buf)
4320{
4321 if (NULL == metadata_buf) {
4322 LOGE("metadata_buf is NULL");
4323 return;
4324 }
4325 metadata_buffer_t *metadata =
4326 (metadata_buffer_t *)metadata_buf->bufs[0]->buffer;
4327 int32_t *p_frame_number_valid =
4328 POINTER_OF_META(CAM_INTF_META_FRAME_NUMBER_VALID, metadata);
4329 uint32_t *p_frame_number =
4330 POINTER_OF_META(CAM_INTF_META_FRAME_NUMBER, metadata);
4331
4332 if (p_frame_number_valid == NULL || p_frame_number == NULL) {
4333 LOGE("%s: Invalid metadata", __func__);
4334 return;
4335 }
4336
Wei Wang01385482017-08-03 10:49:34 -07004337 //acquire perf lock for 2 secs after the last HDR frame is captured
4338 constexpr uint32_t HDR_PLUS_PERF_TIME_OUT = 2000;
Thierry Strudel3d639192016-09-09 11:52:26 -07004339 if ((p_frame_number_valid != NULL) && *p_frame_number_valid) {
4340 if ((p_frame_number != NULL) &&
4341 (mLastCustIntentFrmNum == (int32_t)*p_frame_number)) {
Thierry Strudelc2ee3302016-11-17 12:33:12 -08004342 mPerfLockMgr.acquirePerfLock(PERF_LOCK_TAKE_SNAPSHOT, HDR_PLUS_PERF_TIME_OUT);
Thierry Strudel3d639192016-09-09 11:52:26 -07004343 }
4344 }
Thierry Strudel3d639192016-09-09 11:52:26 -07004345}
4346
4347/*===========================================================================
4348 * FUNCTION : handleInputBufferWithLock
4349 *
4350 * DESCRIPTION: Handles input buffer and shutter callback with mMutex lock held.
4351 *
4352 * PARAMETERS : @frame_number: frame number of the input buffer
4353 *
4354 * RETURN :
4355 *
4356 *==========================================================================*/
4357void QCamera3HardwareInterface::handleInputBufferWithLock(uint32_t frame_number)
4358{
Thierry Strudele80ad7c2016-12-06 10:16:27 -08004359 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL3_HANDLE_IN_BUF_LKD);
Thierry Strudel3d639192016-09-09 11:52:26 -07004360 pendingRequestIterator i = mPendingRequestsList.begin();
4361 while (i != mPendingRequestsList.end() && i->frame_number != frame_number){
4362 i++;
4363 }
4364 if (i != mPendingRequestsList.end() && i->input_buffer) {
4365 //found the right request
Chien-Yu Chen3f303522017-05-19 15:21:45 -07004366 CameraMetadata settings;
4367 nsecs_t capture_time = systemTime(CLOCK_MONOTONIC);
4368 if(i->settings) {
4369 settings = i->settings;
4370 if (settings.exists(ANDROID_SENSOR_TIMESTAMP)) {
4371 capture_time = settings.find(ANDROID_SENSOR_TIMESTAMP).data.i64[0];
Thierry Strudel3d639192016-09-09 11:52:26 -07004372 } else {
Chien-Yu Chen3f303522017-05-19 15:21:45 -07004373 LOGE("No timestamp in input settings! Using current one.");
Thierry Strudel3d639192016-09-09 11:52:26 -07004374 }
Chien-Yu Chen3f303522017-05-19 15:21:45 -07004375 } else {
4376 LOGE("Input settings missing!");
Thierry Strudel3d639192016-09-09 11:52:26 -07004377 }
4378
Chien-Yu Chen3f303522017-05-19 15:21:45 -07004379 mShutterDispatcher.markShutterReady(frame_number, capture_time);
4380 LOGD("Input request metadata notify frame_number = %u, capture_time = %llu",
4381 i->frame_number, capture_time);
Thierry Strudel3d639192016-09-09 11:52:26 -07004382
4383 camera3_capture_result result;
4384 memset(&result, 0, sizeof(camera3_capture_result));
4385 result.frame_number = frame_number;
4386 result.result = i->settings;
4387 result.input_buffer = i->input_buffer;
4388 result.partial_result = PARTIAL_RESULT_COUNT;
4389
Thierry Strudele80ad7c2016-12-06 10:16:27 -08004390 orchestrateResult(&result);
Thierry Strudel3d639192016-09-09 11:52:26 -07004391 LOGD("Input request metadata and input buffer frame_number = %u",
4392 i->frame_number);
4393 i = erasePendingRequest(i);
Chien-Yu Chen588cc852017-06-23 18:39:51 -07004394
4395 // Dispatch result metadata that may be just unblocked by this reprocess result.
4396 dispatchResultMetadataWithLock(frame_number, /*isLiveRequest*/false);
Thierry Strudel3d639192016-09-09 11:52:26 -07004397 } else {
4398 LOGE("Could not find input request for frame number %d", frame_number);
4399 }
4400}
4401
4402/*===========================================================================
4403 * FUNCTION : handleBufferWithLock
4404 *
4405 * DESCRIPTION: Handles image buffer callback with mMutex lock held.
4406 *
4407 * PARAMETERS : @buffer: image buffer for the callback
4408 * @frame_number: frame number of the image buffer
4409 *
4410 * RETURN :
4411 *
4412 *==========================================================================*/
4413void QCamera3HardwareInterface::handleBufferWithLock(
4414 camera3_stream_buffer_t *buffer, uint32_t frame_number)
4415{
Thierry Strudele80ad7c2016-12-06 10:16:27 -08004416 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL3_HANDLE_BUF_LKD);
Thierry Strudelc2ee3302016-11-17 12:33:12 -08004417
4418 if (buffer->stream->format == HAL_PIXEL_FORMAT_BLOB) {
4419 mPerfLockMgr.releasePerfLock(PERF_LOCK_TAKE_SNAPSHOT);
4420 }
4421
Thierry Strudel3d639192016-09-09 11:52:26 -07004422 /* Nothing to be done during error state */
4423 if ((ERROR == mState) || (DEINIT == mState)) {
4424 return;
4425 }
4426 if (mFlushPerf) {
4427 handleBuffersDuringFlushLock(buffer);
4428 return;
4429 }
4430 //not in flush
4431 // If the frame number doesn't exist in the pending request list,
4432 // directly send the buffer to the frameworks, and update pending buffers map
4433 // Otherwise, book-keep the buffer.
4434 pendingRequestIterator i = mPendingRequestsList.begin();
4435 while (i != mPendingRequestsList.end() && i->frame_number != frame_number){
4436 i++;
4437 }
Thierry Strudel3d639192016-09-09 11:52:26 -07004438
Chien-Yu Chen3f303522017-05-19 15:21:45 -07004439 if (i != mPendingRequestsList.end()) {
Thierry Strudel3d639192016-09-09 11:52:26 -07004440 if (i->input_buffer) {
Chien-Yu Chen3f303522017-05-19 15:21:45 -07004441 // For a reprocessing request, try to send out result metadata.
4442 handlePendingResultMetadataWithLock(frame_number, nullptr);
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004443 }
Thierry Strudel3d639192016-09-09 11:52:26 -07004444 }
Thierry Strudelc2ee3302016-11-17 12:33:12 -08004445
Chien-Yu Chen3f303522017-05-19 15:21:45 -07004446 // Check if this frame was dropped.
4447 for (List<PendingFrameDropInfo>::iterator m = mPendingFrameDropList.begin();
4448 m != mPendingFrameDropList.end(); m++) {
4449 QCamera3Channel *channel = (QCamera3Channel *)buffer->stream->priv;
4450 uint32_t streamID = channel->getStreamID(channel->getStreamTypeMask());
4451 if((m->stream_ID == streamID) && (m->frame_number==frame_number) ) {
4452 buffer->status=CAMERA3_BUFFER_STATUS_ERROR;
4453 LOGD("Stream STATUS_ERROR frame_number=%d, streamID=%d",
4454 frame_number, streamID);
4455 m = mPendingFrameDropList.erase(m);
4456 break;
4457 }
4458 }
4459
Binhao Lin09245482017-08-31 18:25:29 -07004460 // WAR for encoder avtimer timestamp issue
4461 QCamera3Channel *channel = (QCamera3Channel *)buffer->stream->priv;
4462 if ((1U << CAM_STREAM_TYPE_VIDEO) == channel->getStreamTypeMask() &&
4463 m_bAVTimerEnabled) {
4464 for (auto req = mPendingBuffersMap.mPendingBuffersInRequest.begin();
4465 req != mPendingBuffersMap.mPendingBuffersInRequest.end(); req++) {
4466 if (req->frame_number != frame_number)
4467 continue;
4468 if(req->av_timestamp == 0) {
4469 buffer->status |= CAMERA3_BUFFER_STATUS_ERROR;
4470 }
4471 else {
4472 struct private_handle_t *priv_handle =
4473 (struct private_handle_t *) (*(buffer->buffer));
4474 setMetaData(priv_handle, SET_VT_TIMESTAMP, &(req->av_timestamp));
4475 }
4476 }
4477 }
4478
Chien-Yu Chen3f303522017-05-19 15:21:45 -07004479 buffer->status |= mPendingBuffersMap.getBufErrStatus(buffer->buffer);
4480 LOGH("result frame_number = %d, buffer = %p",
4481 frame_number, buffer->buffer);
4482
4483 mPendingBuffersMap.removeBuf(buffer->buffer);
4484 mOutputBufferDispatcher.markBufferReady(frame_number, *buffer);
4485
Thierry Strudelc2ee3302016-11-17 12:33:12 -08004486 if (mPreviewStarted == false) {
4487 QCamera3Channel *channel = (QCamera3Channel *)buffer->stream->priv;
4488 if ((1U << CAM_STREAM_TYPE_PREVIEW) == channel->getStreamTypeMask()) {
Chien-Yu Chen509314b2017-04-07 15:27:55 -07004489 logEaselEvent("EASEL_STARTUP_LATENCY", "Preview Started");
4490
Thierry Strudelc2ee3302016-11-17 12:33:12 -08004491 mPerfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW);
4492 mPerfLockMgr.releasePerfLock(PERF_LOCK_OPEN_CAMERA);
4493 mPreviewStarted = true;
4494
4495 // Set power hint for preview
4496 mPerfLockMgr.acquirePerfLock(PERF_LOCK_POWERHINT_ENCODE, 0);
4497 }
4498 }
Thierry Strudel3d639192016-09-09 11:52:26 -07004499}
4500
Chien-Yu Chen21b9e9a2017-09-25 14:34:26 -07004501void QCamera3HardwareInterface::removeUnrequestedMetadata(pendingRequestIterator requestIter,
4502 camera_metadata_t *resultMetadata) {
4503 CameraMetadata metadata;
4504 metadata.acquire(resultMetadata);
4505
4506 // Remove len shading map if it's not requested.
4507 if (requestIter->requestedLensShadingMapMode == ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF &&
4508 metadata.exists(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE) &&
Shuzhen Wang206360b2018-03-26 12:26:38 -07004509 metadata.find(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE).data.u8[0] !=
4510 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF) {
Chien-Yu Chen21b9e9a2017-09-25 14:34:26 -07004511 metadata.erase(ANDROID_STATISTICS_LENS_SHADING_MAP);
4512 metadata.update(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
4513 &requestIter->requestedLensShadingMapMode, 1);
4514 }
4515
4516 // Remove face information if it's not requested.
4517 if (requestIter->requestedFaceDetectMode == ANDROID_STATISTICS_FACE_DETECT_MODE_OFF &&
4518 metadata.exists(ANDROID_STATISTICS_FACE_DETECT_MODE) &&
4519 metadata.find(ANDROID_STATISTICS_FACE_DETECT_MODE).data.u8[0] !=
4520 ANDROID_STATISTICS_FACE_DETECT_MODE_OFF) {
4521 metadata.erase(ANDROID_STATISTICS_FACE_RECTANGLES);
4522 metadata.update(ANDROID_STATISTICS_FACE_DETECT_MODE,
4523 &requestIter->requestedFaceDetectMode, 1);
4524 }
4525
4526 requestIter->resultMetadata = metadata.release();
4527}
4528
Chien-Yu Chen3f303522017-05-19 15:21:45 -07004529void QCamera3HardwareInterface::handlePendingResultMetadataWithLock(uint32_t frameNumber,
Chien-Yu Chenbc730232017-07-12 14:49:55 -07004530 camera_metadata_t *resultMetadata)
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004531{
4532 // Find the pending request for this result metadata.
4533 auto requestIter = mPendingRequestsList.begin();
4534 while (requestIter != mPendingRequestsList.end() && requestIter->frame_number != frameNumber) {
4535 requestIter++;
4536 }
4537
4538 if (requestIter == mPendingRequestsList.end()) {
4539 ALOGE("%s: Cannot find a pending request for frame number %u.", __FUNCTION__, frameNumber);
4540 return;
4541 }
4542
4543 // Update the result metadata
4544 requestIter->resultMetadata = resultMetadata;
4545
4546 // Check what type of request this is.
4547 bool liveRequest = false;
4548 if (requestIter->hdrplus) {
Chien-Yu Chen9264fe92017-04-29 03:28:46 +00004549 // HDR+ request doesn't have partial results.
4550 requestIter->partial_result_cnt = PARTIAL_RESULT_COUNT;
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004551 } else if (requestIter->input_buffer != nullptr) {
4552 // Reprocessing request result is the same as settings.
4553 requestIter->resultMetadata = requestIter->settings;
4554 // Reprocessing request doesn't have partial results.
4555 requestIter->partial_result_cnt = PARTIAL_RESULT_COUNT;
4556 } else {
4557 liveRequest = true;
Chien-Yu Chen0a921f92017-08-27 17:25:33 -07004558 requestIter->partial_result_cnt = PARTIAL_RESULT_COUNT;
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004559 mPendingLiveRequest--;
4560
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -07004561 {
Chien-Yu Chen77ccd022017-06-23 12:00:36 -07004562 std::unique_lock<std::mutex> l(gHdrPlusClientLock);
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -07004563 // For a live request, send the metadata to HDR+ client.
4564 if (gHdrPlusClient != nullptr && mHdrPlusModeEnabled) {
4565 gHdrPlusClient->notifyFrameMetadata(frameNumber, *resultMetadata,
4566 requestIter->partial_result_cnt == PARTIAL_RESULT_COUNT);
4567 }
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004568 }
4569 }
4570
Chien-Yu Chen21b9e9a2017-09-25 14:34:26 -07004571 if (requestIter->input_buffer == nullptr) {
4572 removeUnrequestedMetadata(requestIter, resultMetadata);
Chien-Yu Chenbc730232017-07-12 14:49:55 -07004573 }
4574
Chien-Yu Chen588cc852017-06-23 18:39:51 -07004575 dispatchResultMetadataWithLock(frameNumber, liveRequest);
4576}
4577
4578void QCamera3HardwareInterface::dispatchResultMetadataWithLock(uint32_t frameNumber,
4579 bool isLiveRequest) {
Chien-Yu Chen3f303522017-05-19 15:21:45 -07004580 // The pending requests are ordered by increasing frame numbers. The result metadata are ready
4581 // to be sent if all previous pending requests are ready to be sent.
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004582 bool readyToSend = true;
4583
Chien-Yu Chen3f303522017-05-19 15:21:45 -07004584 // Iterate through the pending requests to send out result metadata that are ready. Also if
4585 // this result metadata belongs to a live request, notify errors for previous live requests
4586 // that don't have result metadata yet.
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004587 auto iter = mPendingRequestsList.begin();
4588 while (iter != mPendingRequestsList.end()) {
4589 // Check if current pending request is ready. If it's not ready, the following pending
4590 // requests are also not ready.
4591 if (readyToSend && iter->resultMetadata == nullptr) {
4592 readyToSend = false;
4593 }
4594
4595 bool thisLiveRequest = iter->hdrplus == false && iter->input_buffer == nullptr;
Shuzhen Wanga1d82a92017-09-19 14:39:43 -07004596 bool errorResult = false;
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004597
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004598 camera3_capture_result_t result = {};
4599 result.frame_number = iter->frame_number;
4600 result.result = iter->resultMetadata;
4601 result.partial_result = iter->partial_result_cnt;
4602
4603 // If this pending buffer has result metadata, we may be able to send out shutter callback
4604 // and result metadata.
4605 if (iter->resultMetadata != nullptr) {
4606 if (!readyToSend) {
4607 // If any of the previous pending request is not ready, this pending request is
4608 // also not ready to send in order to keep shutter callbacks and result metadata
4609 // in order.
4610 iter++;
4611 continue;
4612 }
Shuzhen Wanga1d82a92017-09-19 14:39:43 -07004613 // Notify ERROR_RESULT if partial result was dropped.
4614 errorResult = iter->partialResultDropped;
Chien-Yu Chen588cc852017-06-23 18:39:51 -07004615 } else if (iter->frame_number < frameNumber && isLiveRequest && thisLiveRequest) {
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004616 // If the result metadata belongs to a live request, notify errors for previous pending
4617 // live requests.
4618 mPendingLiveRequest--;
4619
Shuzhen Wanga1d82a92017-09-19 14:39:43 -07004620 LOGE("Error: HAL missed metadata for frame number %d", iter->frame_number);
4621 errorResult = true;
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004622 } else {
4623 iter++;
4624 continue;
4625 }
4626
Shuzhen Wanga1d82a92017-09-19 14:39:43 -07004627 if (errorResult) {
4628 notifyError(iter->frame_number, CAMERA3_MSG_ERROR_RESULT);
4629 } else {
4630 result.output_buffers = nullptr;
4631 result.num_output_buffers = 0;
4632 orchestrateResult(&result);
4633 }
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004634 // For reprocessing, result metadata is the same as settings so do not free it here to
4635 // avoid double free.
4636 if (result.result != iter->settings) {
4637 free_camera_metadata((camera_metadata_t *)result.result);
4638 }
4639 iter->resultMetadata = nullptr;
4640 iter = erasePendingRequest(iter);
4641 }
4642
Chien-Yu Chen588cc852017-06-23 18:39:51 -07004643 if (isLiveRequest) {
Chien-Yu Chene687bd02016-12-07 18:30:26 -08004644 for (auto &iter : mPendingRequestsList) {
4645 // Increment pipeline depth for the following pending requests.
4646 if (iter.frame_number > frameNumber) {
4647 iter.pipeline_depth++;
4648 }
4649 }
4650 }
4651
4652 unblockRequestIfNecessary();
4653}
4654
Thierry Strudel3d639192016-09-09 11:52:26 -07004655/*===========================================================================
4656 * FUNCTION : unblockRequestIfNecessary
4657 *
4658 * DESCRIPTION: Unblock capture_request if max_buffer hasn't been reached. Note
4659 * that mMutex is held when this function is called.
4660 *
4661 * PARAMETERS :
4662 *
4663 * RETURN :
4664 *
4665 *==========================================================================*/
4666void QCamera3HardwareInterface::unblockRequestIfNecessary()
4667{
4668 // Unblock process_capture_request
4669 pthread_cond_signal(&mRequestCond);
4670}
4671
Thierry Strudele80ad7c2016-12-06 10:16:27 -08004672/*===========================================================================
4673 * FUNCTION : isHdrSnapshotRequest
4674 *
4675 * DESCRIPTION: Function to determine if the request is for a HDR snapshot
4676 *
4677 * PARAMETERS : camera3 request structure
4678 *
4679 * RETURN : boolean decision variable
4680 *
4681 *==========================================================================*/
4682bool QCamera3HardwareInterface::isHdrSnapshotRequest(camera3_capture_request *request)
4683{
4684 if (request == NULL) {
4685 LOGE("Invalid request handle");
4686 assert(0);
4687 return false;
4688 }
4689
4690 if (!mForceHdrSnapshot) {
4691 CameraMetadata frame_settings;
4692 frame_settings = request->settings;
4693
4694 if (frame_settings.exists(ANDROID_CONTROL_MODE)) {
4695 uint8_t metaMode = frame_settings.find(ANDROID_CONTROL_MODE).data.u8[0];
4696 if (metaMode != ANDROID_CONTROL_MODE_USE_SCENE_MODE) {
4697 return false;
4698 }
4699 } else {
4700 return false;
4701 }
4702
4703 if (frame_settings.exists(ANDROID_CONTROL_SCENE_MODE)) {
4704 uint8_t fwk_sceneMode = frame_settings.find(ANDROID_CONTROL_SCENE_MODE).data.u8[0];
4705 if (fwk_sceneMode != ANDROID_CONTROL_SCENE_MODE_HDR) {
4706 return false;
4707 }
4708 } else {
4709 return false;
4710 }
4711 }
4712
4713 for (uint32_t i = 0; i < request->num_output_buffers; i++) {
4714 if (request->output_buffers[i].stream->format
4715 == HAL_PIXEL_FORMAT_BLOB) {
4716 return true;
4717 }
4718 }
4719
4720 return false;
4721}
4722/*===========================================================================
4723 * FUNCTION : orchestrateRequest
4724 *
4725 * DESCRIPTION: Orchestrates a capture request from camera service
4726 *
4727 * PARAMETERS :
4728 * @request : request from framework to process
4729 *
4730 * RETURN : Error status codes
4731 *
4732 *==========================================================================*/
4733int32_t QCamera3HardwareInterface::orchestrateRequest(
4734 camera3_capture_request_t *request)
4735{
4736
4737 uint32_t originalFrameNumber = request->frame_number;
4738 uint32_t originalOutputCount = request->num_output_buffers;
4739 const camera_metadata_t *original_settings = request->settings;
4740 List<InternalRequest> internallyRequestedStreams;
4741 List<InternalRequest> emptyInternalList;
4742
4743 if (isHdrSnapshotRequest(request) && request->input_buffer == NULL) {
4744 LOGD("Framework requested:%d buffers in HDR snapshot", request->num_output_buffers);
4745 uint32_t internalFrameNumber;
4746 CameraMetadata modified_meta;
4747
4748
4749 /* Add Blob channel to list of internally requested streams */
4750 for (uint32_t i = 0; i < request->num_output_buffers; i++) {
4751 if (request->output_buffers[i].stream->format
4752 == HAL_PIXEL_FORMAT_BLOB) {
4753 InternalRequest streamRequested;
4754 streamRequested.meteringOnly = 1;
4755 streamRequested.need_metadata = 0;
4756 streamRequested.stream = request->output_buffers[i].stream;
4757 internallyRequestedStreams.push_back(streamRequested);
4758 }
4759 }
4760 request->num_output_buffers = 0;
4761 auto itr = internallyRequestedStreams.begin();
4762
4763 /* Modify setting to set compensation */
4764 modified_meta = request->settings;
4765 int32_t expCompensation = GB_HDR_HALF_STEP_EV;
4766 uint8_t aeLock = 1;
4767 modified_meta.update(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, &expCompensation, 1);
4768 modified_meta.update(ANDROID_CONTROL_AE_LOCK, &aeLock, 1);
4769 camera_metadata_t *modified_settings = modified_meta.release();
4770 request->settings = modified_settings;
4771
4772 /* Capture Settling & -2x frame */
4773 _orchestrationDb.generateStoreInternalFrameNumber(internalFrameNumber);
4774 request->frame_number = internalFrameNumber;
4775 processCaptureRequest(request, internallyRequestedStreams);
4776
4777 request->num_output_buffers = originalOutputCount;
4778 _orchestrationDb.allocStoreInternalFrameNumber(originalFrameNumber, internalFrameNumber);
4779 request->frame_number = internalFrameNumber;
4780 processCaptureRequest(request, emptyInternalList);
4781 request->num_output_buffers = 0;
4782
4783 modified_meta = modified_settings;
4784 expCompensation = 0;
4785 aeLock = 1;
4786 modified_meta.update(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, &expCompensation, 1);
4787 modified_meta.update(ANDROID_CONTROL_AE_LOCK, &aeLock, 1);
4788 modified_settings = modified_meta.release();
4789 request->settings = modified_settings;
4790
4791 /* Capture Settling & 0X frame */
4792
4793 itr = internallyRequestedStreams.begin();
4794 if (itr == internallyRequestedStreams.end()) {
4795 LOGE("Error Internally Requested Stream list is empty");
4796 assert(0);
4797 } else {
4798 itr->need_metadata = 0;
4799 itr->meteringOnly = 1;
4800 }
4801
4802 _orchestrationDb.generateStoreInternalFrameNumber(internalFrameNumber);
4803 request->frame_number = internalFrameNumber;
4804 processCaptureRequest(request, internallyRequestedStreams);
4805
4806 itr = internallyRequestedStreams.begin();
4807 if (itr == internallyRequestedStreams.end()) {
4808 ALOGE("Error Internally Requested Stream list is empty");
4809 assert(0);
4810 } else {
4811 itr->need_metadata = 1;
4812 itr->meteringOnly = 0;
4813 }
4814
4815 _orchestrationDb.generateStoreInternalFrameNumber(internalFrameNumber);
4816 request->frame_number = internalFrameNumber;
4817 processCaptureRequest(request, internallyRequestedStreams);
4818
4819 /* Capture 2X frame*/
4820 modified_meta = modified_settings;
4821 expCompensation = GB_HDR_2X_STEP_EV;
4822 aeLock = 1;
4823 modified_meta.update(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, &expCompensation, 1);
4824 modified_meta.update(ANDROID_CONTROL_AE_LOCK, &aeLock, 1);
4825 modified_settings = modified_meta.release();
4826 request->settings = modified_settings;
4827
4828 itr = internallyRequestedStreams.begin();
4829 if (itr == internallyRequestedStreams.end()) {
4830 ALOGE("Error Internally Requested Stream list is empty");
4831 assert(0);
4832 } else {
4833 itr->need_metadata = 0;
4834 itr->meteringOnly = 1;
4835 }
4836 _orchestrationDb.generateStoreInternalFrameNumber(internalFrameNumber);
4837 request->frame_number = internalFrameNumber;
4838 processCaptureRequest(request, internallyRequestedStreams);
4839
4840 itr = internallyRequestedStreams.begin();
4841 if (itr == internallyRequestedStreams.end()) {
4842 ALOGE("Error Internally Requested Stream list is empty");
4843 assert(0);
4844 } else {
4845 itr->need_metadata = 1;
4846 itr->meteringOnly = 0;
4847 }
4848
4849 _orchestrationDb.generateStoreInternalFrameNumber(internalFrameNumber);
4850 request->frame_number = internalFrameNumber;
4851 processCaptureRequest(request, internallyRequestedStreams);
4852
4853
4854 /* Capture 2X on original streaming config*/
4855 internallyRequestedStreams.clear();
4856
4857 /* Restore original settings pointer */
4858 request->settings = original_settings;
4859 } else {
4860 uint32_t internalFrameNumber;
4861 _orchestrationDb.allocStoreInternalFrameNumber(request->frame_number, internalFrameNumber);
4862 request->frame_number = internalFrameNumber;
4863 return processCaptureRequest(request, internallyRequestedStreams);
4864 }
4865
4866 return NO_ERROR;
4867}
4868
4869/*===========================================================================
4870 * FUNCTION : orchestrateResult
4871 *
4872 * DESCRIPTION: Orchestrates a capture result to camera service
4873 *
4874 * PARAMETERS :
4875 * @request : request from framework to process
4876 *
4877 * RETURN :
4878 *
4879 *==========================================================================*/
4880void QCamera3HardwareInterface::orchestrateResult(
4881 camera3_capture_result_t *result)
4882{
4883 uint32_t frameworkFrameNumber;
4884 int32_t rc = _orchestrationDb.getFrameworkFrameNumber(result->frame_number,
4885 frameworkFrameNumber);
4886 if (rc != NO_ERROR) {
4887 LOGE("Cannot find translated frameworkFrameNumber");
4888 assert(0);
4889 } else {
4890 if (frameworkFrameNumber == EMPTY_FRAMEWORK_FRAME_NUMBER) {
Thierry Strudel54dc9782017-02-15 12:12:10 -08004891 LOGD("Internal Request drop the result");
Thierry Strudele80ad7c2016-12-06 10:16:27 -08004892 } else {
Binhao Lin9cdfa3f2017-04-19 11:47:45 -07004893 if (result->result != NULL) {
Binhao Lin299ffc92017-04-27 11:22:47 -07004894 camera_metadata_t *metadata = const_cast<camera_metadata_t*>(result->result);
4895 camera_metadata_entry_t entry;
4896 int ret = find_camera_metadata_entry(metadata, ANDROID_SYNC_FRAME_NUMBER, &entry);
4897 if (ret == OK) {
Binhao Lin9cdfa3f2017-04-19 11:47:45 -07004898 int64_t sync_frame_number = frameworkFrameNumber;
Binhao Lin299ffc92017-04-27 11:22:47 -07004899 ret = update_camera_metadata_entry(metadata, entry.index, &sync_frame_number, 1, &entry);
4900 if (ret != OK)
4901 LOGE("Update ANDROID_SYNC_FRAME_NUMBER Error!");
Binhao Lin9cdfa3f2017-04-19 11:47:45 -07004902 }
Binhao Lin9cdfa3f2017-04-19 11:47:45 -07004903 }
Thierry Strudele80ad7c2016-12-06 10:16:27 -08004904 result->frame_number = frameworkFrameNumber;
4905 mCallbackOps->process_capture_result(mCallbackOps, result);
4906 }
4907 }
4908}
4909
4910/*===========================================================================
4911 * FUNCTION : orchestrateNotify
4912 *
4913 * DESCRIPTION: Orchestrates a notify to camera service
4914 *
4915 * PARAMETERS :
4916 * @request : request from framework to process
4917 *
4918 * RETURN :
4919 *
4920 *==========================================================================*/
4921void QCamera3HardwareInterface::orchestrateNotify(camera3_notify_msg_t *notify_msg)
4922{
4923 uint32_t frameworkFrameNumber;
4924 uint32_t internalFrameNumber = notify_msg->message.shutter.frame_number;
Thierry Strudel2896d122017-02-23 19:18:03 -08004925 int32_t rc = NO_ERROR;
4926
4927 rc = _orchestrationDb.getFrameworkFrameNumber(internalFrameNumber,
Thierry Strudele80ad7c2016-12-06 10:16:27 -08004928 frameworkFrameNumber);
Thierry Strudel2896d122017-02-23 19:18:03 -08004929
Thierry Strudele80ad7c2016-12-06 10:16:27 -08004930 if (rc != NO_ERROR) {
Thierry Strudel2896d122017-02-23 19:18:03 -08004931 if (notify_msg->message.error.error_code == CAMERA3_MSG_ERROR_DEVICE) {
4932 LOGD("Sending CAMERA3_MSG_ERROR_DEVICE to framework");
4933 frameworkFrameNumber = 0;
Thierry Strudele80ad7c2016-12-06 10:16:27 -08004934 } else {
Thierry Strudel2896d122017-02-23 19:18:03 -08004935 LOGE("Cannot find translated frameworkFrameNumber");
4936 assert(0);
4937 return;
Thierry Strudele80ad7c2016-12-06 10:16:27 -08004938 }
4939 }
Thierry Strudel2896d122017-02-23 19:18:03 -08004940
4941 if (frameworkFrameNumber == EMPTY_FRAMEWORK_FRAME_NUMBER) {
4942 LOGD("Internal Request drop the notifyCb");
4943 } else {
4944 notify_msg->message.shutter.frame_number = frameworkFrameNumber;
4945 mCallbackOps->notify(mCallbackOps, notify_msg);
4946 }
Thierry Strudele80ad7c2016-12-06 10:16:27 -08004947}
4948
4949/*===========================================================================
4950 * FUNCTION : FrameNumberRegistry
4951 *
4952 * DESCRIPTION: Constructor
4953 *
4954 * PARAMETERS :
4955 *
4956 * RETURN :
4957 *
4958 *==========================================================================*/
4959FrameNumberRegistry::FrameNumberRegistry()
4960{
4961 _nextFreeInternalNumber = INTERNAL_FRAME_STARTING_NUMBER;
4962}
4963
4964/*===========================================================================
4965 * FUNCTION : ~FrameNumberRegistry
4966 *
4967 * DESCRIPTION: Destructor
4968 *
4969 * PARAMETERS :
4970 *
4971 * RETURN :
4972 *
4973 *==========================================================================*/
4974FrameNumberRegistry::~FrameNumberRegistry()
4975{
4976}
4977
4978/*===========================================================================
4979 * FUNCTION : PurgeOldEntriesLocked
4980 *
4981 * DESCRIPTION: Maintainance function to trigger LRU cleanup mechanism
4982 *
4983 * PARAMETERS :
4984 *
4985 * RETURN : NONE
4986 *
4987 *==========================================================================*/
4988void FrameNumberRegistry::purgeOldEntriesLocked()
4989{
4990 while (_register.begin() != _register.end()) {
4991 auto itr = _register.begin();
4992 if (itr->first < (_nextFreeInternalNumber - FRAME_REGISTER_LRU_SIZE)) {
4993 _register.erase(itr);
4994 } else {
4995 return;
4996 }
4997 }
4998}
4999
5000/*===========================================================================
5001 * FUNCTION : allocStoreInternalFrameNumber
5002 *
5003 * DESCRIPTION: Method to note down a framework request and associate a new
5004 * internal request number against it
5005 *
5006 * PARAMETERS :
5007 * @fFrameNumber: Identifier given by framework
5008 * @internalFN : Output parameter which will have the newly generated internal
5009 * entry
5010 *
5011 * RETURN : Error code
5012 *
5013 *==========================================================================*/
5014int32_t FrameNumberRegistry::allocStoreInternalFrameNumber(uint32_t frameworkFrameNumber,
5015 uint32_t &internalFrameNumber)
5016{
5017 Mutex::Autolock lock(mRegistryLock);
5018 internalFrameNumber = _nextFreeInternalNumber++;
5019 LOGD("Storing ff#:%d, with internal:%d", frameworkFrameNumber, internalFrameNumber);
5020 _register.insert(std::pair<uint32_t,uint32_t>(internalFrameNumber, frameworkFrameNumber));
5021 purgeOldEntriesLocked();
5022 return NO_ERROR;
5023}
5024
5025/*===========================================================================
5026 * FUNCTION : generateStoreInternalFrameNumber
5027 *
5028 * DESCRIPTION: Method to associate a new internal request number independent
5029 * of any associate with framework requests
5030 *
5031 * PARAMETERS :
5032 * @internalFrame#: Output parameter which will have the newly generated internal
5033 *
5034 *
5035 * RETURN : Error code
5036 *
5037 *==========================================================================*/
5038int32_t FrameNumberRegistry::generateStoreInternalFrameNumber(uint32_t &internalFrameNumber)
5039{
5040 Mutex::Autolock lock(mRegistryLock);
5041 internalFrameNumber = _nextFreeInternalNumber++;
5042 LOGD("Generated internal framenumber:%d", internalFrameNumber);
5043 _register.insert(std::pair<uint32_t,uint32_t>(internalFrameNumber, EMPTY_FRAMEWORK_FRAME_NUMBER));
5044 purgeOldEntriesLocked();
5045 return NO_ERROR;
5046}
5047
5048/*===========================================================================
5049 * FUNCTION : getFrameworkFrameNumber
5050 *
5051 * DESCRIPTION: Method to query the framework framenumber given an internal #
5052 *
5053 * PARAMETERS :
5054 * @internalFrame#: Internal reference
5055 * @frameworkframenumber: Output parameter holding framework frame entry
5056 *
5057 * RETURN : Error code
5058 *
5059 *==========================================================================*/
5060int32_t FrameNumberRegistry::getFrameworkFrameNumber(uint32_t internalFrameNumber,
5061 uint32_t &frameworkFrameNumber)
5062{
5063 Mutex::Autolock lock(mRegistryLock);
5064 auto itr = _register.find(internalFrameNumber);
5065 if (itr == _register.end()) {
Thierry Strudel54dc9782017-02-15 12:12:10 -08005066 LOGE("Cannot find internal#: %d", internalFrameNumber);
Thierry Strudele80ad7c2016-12-06 10:16:27 -08005067 return -ENOENT;
5068 }
5069
5070 frameworkFrameNumber = itr->second;
5071 purgeOldEntriesLocked();
5072 return NO_ERROR;
5073}
Thierry Strudel3d639192016-09-09 11:52:26 -07005074
Chien-Yu Chen8e599492016-11-01 13:37:46 -07005075status_t QCamera3HardwareInterface::fillPbStreamConfig(
Chien-Yu Chen14d3e392017-07-10 18:27:05 -07005076 pbcamera::StreamConfiguration *config, uint32_t pbStreamId, QCamera3Channel *channel,
5077 uint32_t streamIndex) {
Chien-Yu Chen8e599492016-11-01 13:37:46 -07005078 if (config == nullptr) {
5079 LOGE("%s: config is null", __FUNCTION__);
5080 return BAD_VALUE;
5081 }
5082
5083 if (channel == nullptr) {
5084 LOGE("%s: channel is null", __FUNCTION__);
5085 return BAD_VALUE;
5086 }
5087
5088 QCamera3Stream *stream = channel->getStreamByIndex(streamIndex);
5089 if (stream == nullptr) {
5090 LOGE("%s: Failed to get stream %d in channel.", __FUNCTION__, streamIndex);
5091 return NAME_NOT_FOUND;
5092 }
5093
5094 const cam_stream_info_t* streamInfo = stream->getStreamInfo();
5095 if (streamInfo == nullptr) {
5096 LOGE("%s: Failed to get stream info for stream %d in channel.", __FUNCTION__, streamIndex);
5097 return NAME_NOT_FOUND;
5098 }
5099
5100 config->id = pbStreamId;
5101 config->image.width = streamInfo->dim.width;
5102 config->image.height = streamInfo->dim.height;
5103 config->image.padding = 0;
Chien-Yu Chen14d3e392017-07-10 18:27:05 -07005104
5105 int bytesPerPixel = 0;
5106
5107 switch (streamInfo->fmt) {
5108 case CAM_FORMAT_YUV_420_NV21:
5109 config->image.format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
5110 bytesPerPixel = 1;
5111 break;
5112 case CAM_FORMAT_YUV_420_NV12:
5113 case CAM_FORMAT_YUV_420_NV12_VENUS:
5114 config->image.format = HAL_PIXEL_FORMAT_YCbCr_420_SP;
5115 bytesPerPixel = 1;
5116 break;
5117 default:
5118 ALOGE("%s: Stream format %d not supported.", __FUNCTION__, streamInfo->fmt);
5119 return BAD_VALUE;
5120 }
Chien-Yu Chen8e599492016-11-01 13:37:46 -07005121
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005122 uint32_t totalPlaneSize = 0;
5123
Chien-Yu Chen8e599492016-11-01 13:37:46 -07005124 // Fill plane information.
5125 for (uint32_t i = 0; i < streamInfo->buf_planes.plane_info.num_planes; i++) {
5126 pbcamera::PlaneConfiguration plane;
Chien-Yu Chen14d3e392017-07-10 18:27:05 -07005127 plane.stride = streamInfo->buf_planes.plane_info.mp[i].stride * bytesPerPixel;
Chien-Yu Chen8e599492016-11-01 13:37:46 -07005128 plane.scanline = streamInfo->buf_planes.plane_info.mp[i].scanline;
5129 config->image.planes.push_back(plane);
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005130
5131 totalPlaneSize += (plane.stride * plane.scanline);
Chien-Yu Chen8e599492016-11-01 13:37:46 -07005132 }
5133
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005134 config->image.padding = streamInfo->buf_planes.plane_info.frame_len - totalPlaneSize;
Chien-Yu Chen8e599492016-11-01 13:37:46 -07005135 return OK;
5136}
5137
Thierry Strudel3d639192016-09-09 11:52:26 -07005138/*===========================================================================
5139 * FUNCTION : processCaptureRequest
5140 *
5141 * DESCRIPTION: process a capture request from camera service
5142 *
5143 * PARAMETERS :
5144 * @request : request from framework to process
5145 *
5146 * RETURN :
5147 *
5148 *==========================================================================*/
5149int QCamera3HardwareInterface::processCaptureRequest(
Thierry Strudele80ad7c2016-12-06 10:16:27 -08005150 camera3_capture_request_t *request,
5151 List<InternalRequest> &internallyRequestedStreams)
Thierry Strudel3d639192016-09-09 11:52:26 -07005152{
Thierry Strudele80ad7c2016-12-06 10:16:27 -08005153 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL3_PROC_CAP_REQ);
Thierry Strudel3d639192016-09-09 11:52:26 -07005154 int rc = NO_ERROR;
5155 int32_t request_id;
5156 CameraMetadata meta;
Thierry Strudel3d639192016-09-09 11:52:26 -07005157 bool isVidBufRequested = false;
5158 camera3_stream_buffer_t *pInputBuffer = NULL;
5159
5160 pthread_mutex_lock(&mMutex);
5161
5162 // Validate current state
5163 switch (mState) {
5164 case CONFIGURED:
5165 case STARTED:
5166 /* valid state */
5167 break;
5168
5169 case ERROR:
5170 pthread_mutex_unlock(&mMutex);
5171 handleCameraDeviceError();
5172 return -ENODEV;
5173
5174 default:
5175 LOGE("Invalid state %d", mState);
5176 pthread_mutex_unlock(&mMutex);
5177 return -ENODEV;
5178 }
5179
Thierry Strudele80ad7c2016-12-06 10:16:27 -08005180 rc = validateCaptureRequest(request, internallyRequestedStreams);
Thierry Strudel3d639192016-09-09 11:52:26 -07005181 if (rc != NO_ERROR) {
5182 LOGE("incoming request is not valid");
5183 pthread_mutex_unlock(&mMutex);
5184 return rc;
5185 }
5186
5187 meta = request->settings;
5188
5189 // For first capture request, send capture intent, and
5190 // stream on all streams
5191 if (mState == CONFIGURED) {
Chien-Yu Chene96475e2017-04-11 11:53:26 -07005192 logEaselEvent("EASEL_STARTUP_LATENCY", "First request");
Thierry Strudel3d639192016-09-09 11:52:26 -07005193
Emilian Peev49c4c6b2017-04-24 10:21:34 +01005194 uint8_t nrMode = 0;
5195 if (meta.exists(ANDROID_NOISE_REDUCTION_MODE)) {
5196 nrMode = meta.find(ANDROID_NOISE_REDUCTION_MODE).data.u8[0];
5197 }
5198
Emilian Peev6d4cdc22017-11-16 16:56:23 +00005199 cam_is_type_t is_type = IS_TYPE_NONE;
5200 bool setEis = isEISEnabled(meta);
Chien-Yu Chen605c3872017-06-14 11:09:23 -07005201 cam_sensor_mode_info_t sensorModeInfo = {};
5202 rc = getSensorModeInfo(sensorModeInfo);
Thierry Strudel3d639192016-09-09 11:52:26 -07005203 if (rc != NO_ERROR) {
5204 LOGE("Failed to get sensor output size");
5205 pthread_mutex_unlock(&mMutex);
5206 goto error_exit;
5207 }
5208
5209 mCropRegionMapper.update(gCamCapability[mCameraId]->active_array_size.width,
5210 gCamCapability[mCameraId]->active_array_size.height,
Chien-Yu Chen605c3872017-06-14 11:09:23 -07005211 sensorModeInfo.active_array_size.width,
5212 sensorModeInfo.active_array_size.height);
Thierry Strudel3d639192016-09-09 11:52:26 -07005213
5214 /* Set batchmode before initializing channel. Since registerBuffer
5215 * internally initializes some of the channels, better set batchmode
5216 * even before first register buffer */
5217 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
5218 it != mStreamInfo.end(); it++) {
5219 QCamera3Channel *channel = (QCamera3Channel *)(*it)->stream->priv;
5220 if (((1U << CAM_STREAM_TYPE_VIDEO) == channel->getStreamTypeMask())
5221 && mBatchSize) {
5222 rc = channel->setBatchSize(mBatchSize);
5223 //Disable per frame map unmap for HFR/batchmode case
5224 rc |= channel->setPerFrameMapUnmap(false);
5225 if (NO_ERROR != rc) {
5226 LOGE("Channel init failed %d", rc);
5227 pthread_mutex_unlock(&mMutex);
5228 goto error_exit;
5229 }
5230 }
5231 }
5232
5233 //First initialize all streams
5234 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
5235 it != mStreamInfo.end(); it++) {
5236 QCamera3Channel *channel = (QCamera3Channel *)(*it)->stream->priv;
Emilian Peev49c4c6b2017-04-24 10:21:34 +01005237
5238 /* Initial value of NR mode is needed before stream on */
5239 channel->setNRMode(nrMode);
Thierry Strudel3d639192016-09-09 11:52:26 -07005240 if ((((1U << CAM_STREAM_TYPE_VIDEO) == channel->getStreamTypeMask()) ||
5241 ((1U << CAM_STREAM_TYPE_PREVIEW) == channel->getStreamTypeMask())) &&
Thierry Strudel9e74aae2016-09-22 17:10:18 -07005242 setEis) {
5243 for (size_t i = 0; i < mStreamConfigInfo.num_streams; i++) {
5244 if ( (1U << mStreamConfigInfo.type[i]) == channel->getStreamTypeMask() ) {
5245 is_type = mStreamConfigInfo.is_type[i];
5246 break;
5247 }
5248 }
Thierry Strudel3d639192016-09-09 11:52:26 -07005249 rc = channel->initialize(is_type);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07005250 } else {
Thierry Strudel3d639192016-09-09 11:52:26 -07005251 rc = channel->initialize(IS_TYPE_NONE);
5252 }
5253 if (NO_ERROR != rc) {
5254 LOGE("Channel initialization failed %d", rc);
5255 pthread_mutex_unlock(&mMutex);
5256 goto error_exit;
5257 }
5258 }
5259
5260 if (mRawDumpChannel) {
5261 rc = mRawDumpChannel->initialize(IS_TYPE_NONE);
5262 if (rc != NO_ERROR) {
5263 LOGE("Error: Raw Dump Channel init failed");
5264 pthread_mutex_unlock(&mMutex);
5265 goto error_exit;
5266 }
5267 }
Chien-Yu Chen8e599492016-11-01 13:37:46 -07005268 if (mHdrPlusRawSrcChannel) {
5269 rc = mHdrPlusRawSrcChannel->initialize(IS_TYPE_NONE);
5270 if (rc != NO_ERROR) {
5271 LOGE("Error: HDR+ RAW Source Channel init failed");
5272 pthread_mutex_unlock(&mMutex);
5273 goto error_exit;
5274 }
5275 }
Thierry Strudel3d639192016-09-09 11:52:26 -07005276 if (mSupportChannel) {
5277 rc = mSupportChannel->initialize(IS_TYPE_NONE);
5278 if (rc < 0) {
5279 LOGE("Support channel initialization failed");
5280 pthread_mutex_unlock(&mMutex);
5281 goto error_exit;
5282 }
5283 }
5284 if (mAnalysisChannel) {
5285 rc = mAnalysisChannel->initialize(IS_TYPE_NONE);
5286 if (rc < 0) {
5287 LOGE("Analysis channel initialization failed");
5288 pthread_mutex_unlock(&mMutex);
5289 goto error_exit;
5290 }
5291 }
5292 if (mDummyBatchChannel) {
5293 rc = mDummyBatchChannel->setBatchSize(mBatchSize);
5294 if (rc < 0) {
5295 LOGE("mDummyBatchChannel setBatchSize failed");
5296 pthread_mutex_unlock(&mMutex);
5297 goto error_exit;
5298 }
Thierry Strudel9e74aae2016-09-22 17:10:18 -07005299 rc = mDummyBatchChannel->initialize(IS_TYPE_NONE);
Thierry Strudel3d639192016-09-09 11:52:26 -07005300 if (rc < 0) {
5301 LOGE("mDummyBatchChannel initialization failed");
5302 pthread_mutex_unlock(&mMutex);
5303 goto error_exit;
5304 }
5305 }
5306
5307 // Set bundle info
5308 rc = setBundleInfo();
5309 if (rc < 0) {
5310 LOGE("setBundleInfo failed %d", rc);
5311 pthread_mutex_unlock(&mMutex);
5312 goto error_exit;
5313 }
5314
5315 //update settings from app here
5316 if (meta.exists(QCAMERA3_DUALCAM_LINK_ENABLE)) {
5317 mIsDeviceLinked = meta.find(QCAMERA3_DUALCAM_LINK_ENABLE).data.u8[0];
5318 LOGH("Dualcam: setting On=%d id =%d", mIsDeviceLinked, mCameraId);
5319 }
5320 if (meta.exists(QCAMERA3_DUALCAM_LINK_IS_MAIN)) {
5321 mIsMainCamera = meta.find(QCAMERA3_DUALCAM_LINK_IS_MAIN).data.u8[0];
5322 LOGH("Dualcam: Is this main camera = %d id =%d", mIsMainCamera, mCameraId);
5323 }
5324 if (meta.exists(QCAMERA3_DUALCAM_LINK_RELATED_CAMERA_ID)) {
5325 mLinkedCameraId = meta.find(QCAMERA3_DUALCAM_LINK_RELATED_CAMERA_ID).data.u8[0];
5326 LOGH("Dualcam: Linked camera Id %d id =%d", mLinkedCameraId, mCameraId);
5327
5328 if ( (mLinkedCameraId >= MM_CAMERA_MAX_NUM_SENSORS) &&
5329 (mLinkedCameraId != mCameraId) ) {
5330 LOGE("Dualcam: mLinkedCameraId %d is invalid, current cam id = %d",
5331 mLinkedCameraId, mCameraId);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07005332 pthread_mutex_unlock(&mMutex);
Thierry Strudel3d639192016-09-09 11:52:26 -07005333 goto error_exit;
5334 }
5335 }
5336
5337 // add bundle related cameras
5338 LOGH("%s: Dualcam: id =%d, mIsDeviceLinked=%d", __func__,mCameraId, mIsDeviceLinked);
5339 if (meta.exists(QCAMERA3_DUALCAM_LINK_ENABLE)) {
Thierry Strudel295a0ca2016-11-03 18:38:47 -07005340 cam_dual_camera_bundle_info_t *m_pRelCamSyncBuf =
5341 &m_pDualCamCmdPtr->bundle_info;
5342 m_pDualCamCmdPtr->cmd_type = CAM_DUAL_CAMERA_BUNDLE_INFO;
Thierry Strudel3d639192016-09-09 11:52:26 -07005343 if (mIsDeviceLinked)
5344 m_pRelCamSyncBuf->sync_control = CAM_SYNC_RELATED_SENSORS_ON;
5345 else
5346 m_pRelCamSyncBuf->sync_control = CAM_SYNC_RELATED_SENSORS_OFF;
5347
5348 pthread_mutex_lock(&gCamLock);
5349
5350 if (sessionId[mLinkedCameraId] == 0xDEADBEEF) {
5351 LOGE("Dualcam: Invalid Session Id ");
5352 pthread_mutex_unlock(&gCamLock);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07005353 pthread_mutex_unlock(&mMutex);
Thierry Strudel3d639192016-09-09 11:52:26 -07005354 goto error_exit;
5355 }
5356
5357 if (mIsMainCamera == 1) {
5358 m_pRelCamSyncBuf->mode = CAM_MODE_PRIMARY;
5359 m_pRelCamSyncBuf->type = CAM_TYPE_MAIN;
Thierry Strudel269c81a2016-10-12 12:13:59 -07005360 m_pRelCamSyncBuf->sync_3a_mode = CAM_3A_SYNC_FOLLOW;
Thierry Strudel295a0ca2016-11-03 18:38:47 -07005361 m_pRelCamSyncBuf->cam_role = CAM_ROLE_BAYER;
Thierry Strudel3d639192016-09-09 11:52:26 -07005362 // related session id should be session id of linked session
5363 m_pRelCamSyncBuf->related_sensor_session_id = sessionId[mLinkedCameraId];
5364 } else {
5365 m_pRelCamSyncBuf->mode = CAM_MODE_SECONDARY;
5366 m_pRelCamSyncBuf->type = CAM_TYPE_AUX;
Thierry Strudel269c81a2016-10-12 12:13:59 -07005367 m_pRelCamSyncBuf->sync_3a_mode = CAM_3A_SYNC_FOLLOW;
Thierry Strudel295a0ca2016-11-03 18:38:47 -07005368 m_pRelCamSyncBuf->cam_role = CAM_ROLE_MONO;
Thierry Strudel3d639192016-09-09 11:52:26 -07005369 m_pRelCamSyncBuf->related_sensor_session_id = sessionId[mLinkedCameraId];
5370 }
Thierry Strudel2896d122017-02-23 19:18:03 -08005371 m_pRelCamSyncBuf->is_hw_sync_enabled = DUALCAM_HW_SYNC_ENABLED;
Thierry Strudel3d639192016-09-09 11:52:26 -07005372 pthread_mutex_unlock(&gCamLock);
5373
Thierry Strudel295a0ca2016-11-03 18:38:47 -07005374 rc = mCameraHandle->ops->set_dual_cam_cmd(
5375 mCameraHandle->camera_handle);
Thierry Strudel3d639192016-09-09 11:52:26 -07005376 if (rc < 0) {
5377 LOGE("Dualcam: link failed");
Thierry Strudel9e74aae2016-09-22 17:10:18 -07005378 pthread_mutex_unlock(&mMutex);
Thierry Strudel3d639192016-09-09 11:52:26 -07005379 goto error_exit;
5380 }
5381 }
Thierry Strudel3d639192016-09-09 11:52:26 -07005382 goto no_error;
5383error_exit:
Thierry Strudelc2ee3302016-11-17 12:33:12 -08005384 mPerfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW);
Thierry Strudel3d639192016-09-09 11:52:26 -07005385 return rc;
5386no_error:
Thierry Strudel3d639192016-09-09 11:52:26 -07005387 mWokenUpByDaemon = false;
5388 mPendingLiveRequest = 0;
5389 mFirstConfiguration = false;
Thierry Strudel3d639192016-09-09 11:52:26 -07005390 }
5391
5392 uint32_t frameNumber = request->frame_number;
Thierry Strudelc2ee3302016-11-17 12:33:12 -08005393 cam_stream_ID_t streamsArray;
Thierry Strudel3d639192016-09-09 11:52:26 -07005394
5395 if (mFlushPerf) {
5396 //we cannot accept any requests during flush
5397 LOGE("process_capture_request cannot proceed during flush");
5398 pthread_mutex_unlock(&mMutex);
5399 return NO_ERROR; //should return an error
5400 }
5401
5402 if (meta.exists(ANDROID_REQUEST_ID)) {
5403 request_id = meta.find(ANDROID_REQUEST_ID).data.i32[0];
5404 mCurrentRequestId = request_id;
5405 LOGD("Received request with id: %d", request_id);
5406 } else if (mState == CONFIGURED || mCurrentRequestId == -1){
5407 LOGE("Unable to find request id field, \
5408 & no previous id available");
5409 pthread_mutex_unlock(&mMutex);
5410 return NAME_NOT_FOUND;
5411 } else {
5412 LOGD("Re-using old request id");
5413 request_id = mCurrentRequestId;
5414 }
5415
5416 LOGH("num_output_buffers = %d input_buffer = %p frame_number = %d",
5417 request->num_output_buffers,
5418 request->input_buffer,
5419 frameNumber);
5420 // Acquire all request buffers first
Thierry Strudelc2ee3302016-11-17 12:33:12 -08005421 streamsArray.num_streams = 0;
Thierry Strudel3d639192016-09-09 11:52:26 -07005422 int blob_request = 0;
Emilian Peev7650c122017-01-19 08:24:33 -08005423 bool depthRequestPresent = false;
Thierry Strudel3d639192016-09-09 11:52:26 -07005424 uint32_t snapshotStreamId = 0;
5425 for (size_t i = 0; i < request->num_output_buffers; i++) {
5426 const camera3_stream_buffer_t& output = request->output_buffers[i];
5427 QCamera3Channel *channel = (QCamera3Channel *)output.stream->priv;
5428
Emilian Peev7650c122017-01-19 08:24:33 -08005429 if ((output.stream->format == HAL_PIXEL_FORMAT_BLOB) &&
5430 (output.stream->data_space != HAL_DATASPACE_DEPTH)) {
Thierry Strudele80ad7c2016-12-06 10:16:27 -08005431 //FIXME??:Call function to store local copy of jpeg data for encode params.
Thierry Strudel3d639192016-09-09 11:52:26 -07005432 blob_request = 1;
5433 snapshotStreamId = channel->getStreamID(channel->getStreamTypeMask());
5434 }
5435
5436 if (output.acquire_fence != -1) {
5437 rc = sync_wait(output.acquire_fence, TIMEOUT_NEVER);
5438 close(output.acquire_fence);
5439 if (rc != OK) {
5440 LOGE("sync wait failed %d", rc);
5441 pthread_mutex_unlock(&mMutex);
5442 return rc;
5443 }
5444 }
5445
Emilian Peev0f3c3162017-03-15 12:57:46 +00005446 if ((output.stream->format == HAL_PIXEL_FORMAT_BLOB) &&
5447 (output.stream->data_space == HAL_DATASPACE_DEPTH)) {
Emilian Peev7650c122017-01-19 08:24:33 -08005448 depthRequestPresent = true;
5449 continue;
5450 }
5451
Thierry Strudelc2ee3302016-11-17 12:33:12 -08005452 streamsArray.stream_request[streamsArray.num_streams++].streamID =
Thierry Strudel3d639192016-09-09 11:52:26 -07005453 channel->getStreamID(channel->getStreamTypeMask());
Thierry Strudel3d639192016-09-09 11:52:26 -07005454
5455 if ((1U << CAM_STREAM_TYPE_VIDEO) == channel->getStreamTypeMask()) {
5456 isVidBufRequested = true;
5457 }
5458 }
5459
Thierry Strudele80ad7c2016-12-06 10:16:27 -08005460 //FIXME: Add checks to ensure to dups in validateCaptureRequest
5461 for (auto itr = internallyRequestedStreams.begin(); itr != internallyRequestedStreams.end();
5462 itr++) {
5463 QCamera3Channel *channel = (QCamera3Channel *)(*itr).stream->priv;
5464 streamsArray.stream_request[streamsArray.num_streams++].streamID =
5465 channel->getStreamID(channel->getStreamTypeMask());
5466
5467 if ((1U << CAM_STREAM_TYPE_VIDEO) == channel->getStreamTypeMask()) {
5468 isVidBufRequested = true;
5469 }
5470 }
5471
Thierry Strudel3d639192016-09-09 11:52:26 -07005472 if (blob_request) {
Shuzhen Wang850a7c22017-05-02 14:48:23 -07005473 ATRACE_ASYNC_BEGIN("SNAPSHOT", frameNumber);
Thierry Strudelc2ee3302016-11-17 12:33:12 -08005474 mPerfLockMgr.acquirePerfLock(PERF_LOCK_TAKE_SNAPSHOT);
Thierry Strudel3d639192016-09-09 11:52:26 -07005475 }
5476 if (blob_request && mRawDumpChannel) {
5477 LOGD("Trigger Raw based on blob request if Raw dump is enabled");
Thierry Strudelc2ee3302016-11-17 12:33:12 -08005478 streamsArray.stream_request[streamsArray.num_streams].streamID =
Thierry Strudel3d639192016-09-09 11:52:26 -07005479 mRawDumpChannel->getStreamID(mRawDumpChannel->getStreamTypeMask());
Thierry Strudelc2ee3302016-11-17 12:33:12 -08005480 streamsArray.stream_request[streamsArray.num_streams++].buf_index = CAM_FREERUN_IDX;
Thierry Strudel3d639192016-09-09 11:52:26 -07005481 }
5482
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005483 {
5484 Mutex::Autolock lock(mHdrPlusPendingRequestsLock);
5485 // Request a RAW buffer if
5486 // 1. mHdrPlusRawSrcChannel is valid.
5487 // 2. frameNumber is multiples of kHdrPlusRawPeriod (in order to limit RAW capture rate.)
5488 // 3. There is no pending HDR+ request.
5489 if (mHdrPlusRawSrcChannel && frameNumber % kHdrPlusRawPeriod == 0 &&
5490 mHdrPlusPendingRequests.size() == 0) {
5491 streamsArray.stream_request[streamsArray.num_streams].streamID =
5492 mHdrPlusRawSrcChannel->getStreamID(mHdrPlusRawSrcChannel->getStreamTypeMask());
5493 streamsArray.stream_request[streamsArray.num_streams++].buf_index = CAM_FREERUN_IDX;
5494 }
Chien-Yu Chen8e599492016-11-01 13:37:46 -07005495 }
5496
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005497 //extract capture intent
5498 if (meta.exists(ANDROID_CONTROL_CAPTURE_INTENT)) {
5499 mCaptureIntent =
5500 meta.find(ANDROID_CONTROL_CAPTURE_INTENT).data.u8[0];
5501 }
5502
5503 if (meta.exists(ANDROID_COLOR_CORRECTION_ABERRATION_MODE)) {
5504 mCacMode =
5505 meta.find(ANDROID_COLOR_CORRECTION_ABERRATION_MODE).data.u8[0];
5506 }
5507
Chien-Yu Chenbc730232017-07-12 14:49:55 -07005508 uint8_t requestedLensShadingMapMode;
5509 // Get the shading map mode.
5510 if (meta.exists(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE)) {
5511 mLastRequestedLensShadingMapMode = requestedLensShadingMapMode =
5512 meta.find(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE).data.u8[0];
5513 } else {
5514 requestedLensShadingMapMode = mLastRequestedLensShadingMapMode;
5515 }
5516
Chien-Yu Chen21b9e9a2017-09-25 14:34:26 -07005517 if (meta.exists(ANDROID_STATISTICS_FACE_DETECT_MODE)) {
5518 mLastRequestedFaceDetectMode =
5519 meta.find(ANDROID_STATISTICS_FACE_DETECT_MODE).data.u8[0];
5520 }
5521
Chien-Yu Chen7f9a15b2018-01-23 16:13:31 -08005522 if (meta.exists(ANDROID_STATISTICS_OIS_DATA_MODE)) {
5523 mLastRequestedOisDataMode =
5524 meta.find(ANDROID_STATISTICS_OIS_DATA_MODE).data.u8[0];
5525 }
5526
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005527 bool hdrPlusRequest = false;
Chien-Yu Chen92724a82017-01-06 11:50:30 -08005528 HdrPlusPendingRequest pendingHdrPlusRequest = {};
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005529
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -07005530 {
Chien-Yu Chen77ccd022017-06-23 12:00:36 -07005531 std::unique_lock<std::mutex> l(gHdrPlusClientLock);
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -07005532 // If this request has a still capture intent, try to submit an HDR+ request.
5533 if (gHdrPlusClient != nullptr && mHdrPlusModeEnabled &&
5534 mCaptureIntent == ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE) {
5535 hdrPlusRequest = trySubmittingHdrPlusRequestLocked(&pendingHdrPlusRequest, *request, meta);
5536 }
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005537 }
5538
Chien-Yu Chen92724a82017-01-06 11:50:30 -08005539 if (hdrPlusRequest) {
5540 // For a HDR+ request, just set the frame parameters.
5541 rc = setFrameParameters(request, streamsArray, blob_request, snapshotStreamId);
5542 if (rc < 0) {
5543 LOGE("fail to set frame parameters");
5544 pthread_mutex_unlock(&mMutex);
5545 return rc;
5546 }
5547 } else if(request->input_buffer == NULL) {
Thierry Strudel3d639192016-09-09 11:52:26 -07005548 /* Parse the settings:
5549 * - For every request in NORMAL MODE
5550 * - For every request in HFR mode during preview only case
5551 * - For first request of every batch in HFR mode during video
5552 * recording. In batchmode the same settings except frame number is
5553 * repeated in each request of the batch.
5554 */
5555 if (!mBatchSize ||
5556 (mBatchSize && !isVidBufRequested) ||
5557 (mBatchSize && isVidBufRequested && !mToBeQueuedVidBufs)) {
Thierry Strudelc2ee3302016-11-17 12:33:12 -08005558 rc = setFrameParameters(request, streamsArray, blob_request, snapshotStreamId);
Thierry Strudel3d639192016-09-09 11:52:26 -07005559 if (rc < 0) {
5560 LOGE("fail to set frame parameters");
5561 pthread_mutex_unlock(&mMutex);
5562 return rc;
5563 }
Chien-Yu Chenbc730232017-07-12 14:49:55 -07005564
5565 {
Chien-Yu Chen21b9e9a2017-09-25 14:34:26 -07005566 // If HDR+ mode is enabled, override the following modes so the necessary metadata
5567 // will be included in the result metadata sent to Easel HDR+.
Chien-Yu Chenbc730232017-07-12 14:49:55 -07005568 std::unique_lock<std::mutex> l(gHdrPlusClientLock);
5569 if (mHdrPlusModeEnabled) {
5570 ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_META_LENS_SHADING_MAP_MODE,
5571 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON);
Chien-Yu Chen21b9e9a2017-09-25 14:34:26 -07005572 ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_META_STATS_FACEDETECT_MODE,
5573 ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE);
Chien-Yu Chenbc730232017-07-12 14:49:55 -07005574 }
5575 }
Thierry Strudel3d639192016-09-09 11:52:26 -07005576 }
5577 /* For batchMode HFR, setFrameParameters is not called for every
5578 * request. But only frame number of the latest request is parsed.
5579 * Keep track of first and last frame numbers in a batch so that
5580 * metadata for the frame numbers of batch can be duplicated in
5581 * handleBatchMetadta */
5582 if (mBatchSize) {
5583 if (!mToBeQueuedVidBufs) {
5584 //start of the batch
5585 mFirstFrameNumberInBatch = request->frame_number;
5586 }
5587 if(ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters,
5588 CAM_INTF_META_FRAME_NUMBER, request->frame_number)) {
5589 LOGE("Failed to set the frame number in the parameters");
Thierry Strudel9e74aae2016-09-22 17:10:18 -07005590 pthread_mutex_unlock(&mMutex);
Thierry Strudel3d639192016-09-09 11:52:26 -07005591 return BAD_VALUE;
5592 }
5593 }
5594 if (mNeedSensorRestart) {
5595 /* Unlock the mutex as restartSensor waits on the channels to be
5596 * stopped, which in turn calls stream callback functions -
5597 * handleBufferWithLock and handleMetadataWithLock */
5598 pthread_mutex_unlock(&mMutex);
5599 rc = dynamicUpdateMetaStreamInfo();
5600 if (rc != NO_ERROR) {
5601 LOGE("Restarting the sensor failed");
5602 return BAD_VALUE;
5603 }
5604 mNeedSensorRestart = false;
5605 pthread_mutex_lock(&mMutex);
5606 }
Thierry Strudel295a0ca2016-11-03 18:38:47 -07005607 if(mResetInstantAEC) {
5608 ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters,
5609 CAM_INTF_PARM_INSTANT_AEC, (uint8_t)CAM_AEC_NORMAL_CONVERGENCE);
5610 mResetInstantAEC = false;
5611 }
Chien-Yu Chen92724a82017-01-06 11:50:30 -08005612 } else {
Thierry Strudel3d639192016-09-09 11:52:26 -07005613 if (request->input_buffer->acquire_fence != -1) {
5614 rc = sync_wait(request->input_buffer->acquire_fence, TIMEOUT_NEVER);
5615 close(request->input_buffer->acquire_fence);
5616 if (rc != OK) {
5617 LOGE("input buffer sync wait failed %d", rc);
5618 pthread_mutex_unlock(&mMutex);
5619 return rc;
5620 }
5621 }
5622 }
5623
5624 if (mCaptureIntent == ANDROID_CONTROL_CAPTURE_INTENT_CUSTOM) {
5625 mLastCustIntentFrmNum = frameNumber;
5626 }
5627 /* Update pending request list and pending buffers map */
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005628 PendingRequestInfo pendingRequest = {};
Thierry Strudel3d639192016-09-09 11:52:26 -07005629 pendingRequestIterator latestRequest;
5630 pendingRequest.frame_number = frameNumber;
Emilian Peev7650c122017-01-19 08:24:33 -08005631 pendingRequest.num_buffers = depthRequestPresent ?
5632 (request->num_output_buffers - 1 ) : request->num_output_buffers;
Thierry Strudel3d639192016-09-09 11:52:26 -07005633 pendingRequest.request_id = request_id;
5634 pendingRequest.blob_request = blob_request;
5635 pendingRequest.timestamp = 0;
Chien-Yu Chenbc730232017-07-12 14:49:55 -07005636 pendingRequest.requestedLensShadingMapMode = requestedLensShadingMapMode;
Chien-Yu Chen21b9e9a2017-09-25 14:34:26 -07005637 pendingRequest.requestedFaceDetectMode = mLastRequestedFaceDetectMode;
Chien-Yu Chen7f9a15b2018-01-23 16:13:31 -08005638 pendingRequest.requestedOisDataMode = mLastRequestedOisDataMode;
Thierry Strudel3d639192016-09-09 11:52:26 -07005639 if (request->input_buffer) {
5640 pendingRequest.input_buffer =
5641 (camera3_stream_buffer_t*)malloc(sizeof(camera3_stream_buffer_t));
5642 *(pendingRequest.input_buffer) = *(request->input_buffer);
5643 pInputBuffer = pendingRequest.input_buffer;
5644 } else {
5645 pendingRequest.input_buffer = NULL;
5646 pInputBuffer = NULL;
5647 }
Shuzhen Wang3c077d72017-04-20 22:48:59 -07005648 pendingRequest.bUseFirstPartial = (mState == CONFIGURED && !request->input_buffer);
Thierry Strudel3d639192016-09-09 11:52:26 -07005649
5650 pendingRequest.pipeline_depth = 0;
5651 pendingRequest.partial_result_cnt = 0;
5652 extractJpegMetadata(mCurJpegMeta, request);
5653 pendingRequest.jpegMetadata = mCurJpegMeta;
5654 pendingRequest.settings = saveRequestSettings(mCurJpegMeta, request);
Thierry Strudel3d639192016-09-09 11:52:26 -07005655 pendingRequest.capture_intent = mCaptureIntent;
Shuzhen Wang2abea3d2016-03-31 11:09:27 -07005656 if (meta.exists(NEXUS_EXPERIMENTAL_2016_HYBRID_AE_ENABLE)) {
Shuzhen Wang77b049a2017-08-30 12:24:36 -07005657 pendingRequest.hybrid_ae_enable =
Shuzhen Wang2abea3d2016-03-31 11:09:27 -07005658 meta.find(NEXUS_EXPERIMENTAL_2016_HYBRID_AE_ENABLE).data.u8[0];
5659 }
Chien-Yu Chen98b126c2017-03-14 14:55:32 -07005660
Wei (Alex) Honga90a2142018-01-05 17:36:52 -08005661 if (meta.exists(NEXUS_EXPERIMENTAL_2017_MOTION_DETECTION_ENABLE)) {
5662 pendingRequest.motion_detection_enable =
5663 meta.find(NEXUS_EXPERIMENTAL_2017_MOTION_DETECTION_ENABLE).data.u8[0];
5664 }
5665
Samuel Ha68ba5172016-12-15 18:41:12 -08005666 /* DevCamDebug metadata processCaptureRequest */
5667 if (meta.exists(DEVCAMDEBUG_META_ENABLE)) {
5668 mDevCamDebugMetaEnable =
5669 meta.find(DEVCAMDEBUG_META_ENABLE).data.u8[0];
5670 }
5671 pendingRequest.DevCamDebug_meta_enable = mDevCamDebugMetaEnable;
5672 /* DevCamDebug metadata end */
Thierry Strudel3d639192016-09-09 11:52:26 -07005673
5674 //extract CAC info
5675 if (meta.exists(ANDROID_COLOR_CORRECTION_ABERRATION_MODE)) {
5676 mCacMode =
5677 meta.find(ANDROID_COLOR_CORRECTION_ABERRATION_MODE).data.u8[0];
5678 }
5679 pendingRequest.fwkCacMode = mCacMode;
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005680 pendingRequest.hdrplus = hdrPlusRequest;
Emilian Peev1796a5f2018-04-11 11:08:37 +01005681 // We need to account for several dropped frames initially on sensor side.
5682 pendingRequest.expectedFrameDuration = (mState == CONFIGURED) ? (4 * mExpectedFrameDuration) :
5683 mExpectedFrameDuration;
5684 mExpectedInflightDuration += pendingRequest.expectedFrameDuration;
Thierry Strudel3d639192016-09-09 11:52:26 -07005685
Chien-Yu Chen66ec22a2017-04-13 18:00:36 -07005686 // extract enableZsl info
5687 if (gExposeEnableZslKey) {
5688 if (meta.exists(ANDROID_CONTROL_ENABLE_ZSL)) {
5689 pendingRequest.enableZsl = meta.find(ANDROID_CONTROL_ENABLE_ZSL).data.u8[0];
5690 mZslEnabled = pendingRequest.enableZsl;
5691 } else {
5692 pendingRequest.enableZsl = mZslEnabled;
5693 }
5694 }
5695
Thierry Strudel3d639192016-09-09 11:52:26 -07005696 PendingBuffersInRequest bufsForCurRequest;
5697 bufsForCurRequest.frame_number = frameNumber;
5698 // Mark current timestamp for the new request
5699 bufsForCurRequest.timestamp = systemTime(CLOCK_MONOTONIC);
Binhao Lin09245482017-08-31 18:25:29 -07005700 bufsForCurRequest.av_timestamp = 0;
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005701 bufsForCurRequest.hdrplus = hdrPlusRequest;
Thierry Strudel3d639192016-09-09 11:52:26 -07005702
Chien-Yu Chen92724a82017-01-06 11:50:30 -08005703 if (hdrPlusRequest) {
5704 // Save settings for this request.
5705 pendingHdrPlusRequest.settings = std::make_shared<metadata_buffer_t>();
5706 memcpy(pendingHdrPlusRequest.settings.get(), mParameters, sizeof(metadata_buffer_t));
5707
5708 // Add to pending HDR+ request queue.
5709 Mutex::Autolock lock(mHdrPlusPendingRequestsLock);
5710 mHdrPlusPendingRequests.emplace(frameNumber, pendingHdrPlusRequest);
5711
5712 ALOGD("%s: frame number %u is an HDR+ request.", __FUNCTION__, frameNumber);
5713 }
5714
Thierry Strudel3d639192016-09-09 11:52:26 -07005715 for (size_t i = 0; i < request->num_output_buffers; i++) {
Emilian Peev0f3c3162017-03-15 12:57:46 +00005716 if ((request->output_buffers[i].stream->data_space ==
5717 HAL_DATASPACE_DEPTH) &&
5718 (HAL_PIXEL_FORMAT_BLOB ==
5719 request->output_buffers[i].stream->format)) {
Emilian Peev7650c122017-01-19 08:24:33 -08005720 continue;
5721 }
Thierry Strudel3d639192016-09-09 11:52:26 -07005722 RequestedBufferInfo requestedBuf;
5723 memset(&requestedBuf, 0, sizeof(requestedBuf));
5724 requestedBuf.stream = request->output_buffers[i].stream;
5725 requestedBuf.buffer = NULL;
5726 pendingRequest.buffers.push_back(requestedBuf);
5727
5728 // Add to buffer handle the pending buffers list
5729 PendingBufferInfo bufferInfo;
5730 bufferInfo.buffer = request->output_buffers[i].buffer;
5731 bufferInfo.stream = request->output_buffers[i].stream;
5732 bufsForCurRequest.mPendingBufferList.push_back(bufferInfo);
5733 QCamera3Channel *channel = (QCamera3Channel *)bufferInfo.stream->priv;
5734 LOGD("frame = %d, buffer = %p, streamTypeMask = %d, stream format = %d",
5735 frameNumber, bufferInfo.buffer,
5736 channel->getStreamTypeMask(), bufferInfo.stream->format);
5737 }
5738 // Add this request packet into mPendingBuffersMap
5739 mPendingBuffersMap.mPendingBuffersInRequest.push_back(bufsForCurRequest);
5740 LOGD("mPendingBuffersMap.num_overall_buffers = %d",
5741 mPendingBuffersMap.get_num_overall_buffers());
5742
5743 latestRequest = mPendingRequestsList.insert(
5744 mPendingRequestsList.end(), pendingRequest);
Chien-Yu Chen3f303522017-05-19 15:21:45 -07005745
5746 // Let shutter dispatcher and buffer dispatcher know shutter and output buffers are expected
5747 // for the frame number.
Chien-Yu Chena7f98612017-06-20 16:54:10 -07005748 mShutterDispatcher.expectShutter(frameNumber, request->input_buffer != nullptr);
Chien-Yu Chen3f303522017-05-19 15:21:45 -07005749 for (size_t i = 0; i < request->num_output_buffers; i++) {
5750 mOutputBufferDispatcher.expectBuffer(frameNumber, request->output_buffers[i].stream);
5751 }
5752
Thierry Strudel3d639192016-09-09 11:52:26 -07005753 if(mFlush) {
5754 LOGI("mFlush is true");
5755 pthread_mutex_unlock(&mMutex);
5756 return NO_ERROR;
5757 }
5758
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005759 // If this is not an HDR+ request, send the request to metadata and each output buffer's
5760 // channel.
5761 if (!hdrPlusRequest) {
5762 int indexUsed;
5763 // Notify metadata channel we receive a request
5764 mMetadataChannel->request(NULL, frameNumber, indexUsed);
Thierry Strudel3d639192016-09-09 11:52:26 -07005765
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005766 if(request->input_buffer != NULL){
5767 LOGD("Input request, frame_number %d", frameNumber);
5768 rc = setReprocParameters(request, &mReprocMeta, snapshotStreamId);
5769 if (NO_ERROR != rc) {
5770 LOGE("fail to set reproc parameters");
5771 pthread_mutex_unlock(&mMutex);
5772 return rc;
5773 }
Thierry Strudel3d639192016-09-09 11:52:26 -07005774 }
5775
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005776 // Call request on other streams
5777 uint32_t streams_need_metadata = 0;
5778 pendingBufferIterator pendingBufferIter = latestRequest->buffers.begin();
5779 for (size_t i = 0; i < request->num_output_buffers; i++) {
5780 const camera3_stream_buffer_t& output = request->output_buffers[i];
5781 QCamera3Channel *channel = (QCamera3Channel *)output.stream->priv;
5782
5783 if (channel == NULL) {
5784 LOGW("invalid channel pointer for stream");
5785 continue;
5786 }
5787
5788 if (output.stream->format == HAL_PIXEL_FORMAT_BLOB) {
5789 LOGD("snapshot request with output buffer %p, input buffer %p, frame_number %d",
5790 output.buffer, request->input_buffer, frameNumber);
5791 if(request->input_buffer != NULL){
Thierry Strudel3d639192016-09-09 11:52:26 -07005792 rc = channel->request(output.buffer, frameNumber,
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005793 pInputBuffer, &mReprocMeta, indexUsed, false, false);
5794 if (rc < 0) {
5795 LOGE("Fail to request on picture channel");
5796 pthread_mutex_unlock(&mMutex);
5797 return rc;
5798 }
Thierry Strudel3d639192016-09-09 11:52:26 -07005799 } else {
Emilian Peev7650c122017-01-19 08:24:33 -08005800 if (HAL_DATASPACE_DEPTH == output.stream->data_space) {
5801 assert(NULL != mDepthChannel);
5802 assert(mDepthChannel == output.stream->priv);
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005803
Emilian Peev7650c122017-01-19 08:24:33 -08005804 rc = mDepthChannel->mapBuffer(output.buffer, request->frame_number);
5805 if (rc < 0) {
5806 LOGE("Fail to map on depth buffer");
5807 pthread_mutex_unlock(&mMutex);
5808 return rc;
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005809 }
Emilian Peev4e0fe952017-06-30 12:40:09 -07005810 continue;
Emilian Peev7650c122017-01-19 08:24:33 -08005811 } else {
5812 LOGD("snapshot request with buffer %p, frame_number %d",
5813 output.buffer, frameNumber);
5814 if (!request->settings) {
5815 rc = channel->request(output.buffer, frameNumber,
5816 NULL, mPrevParameters, indexUsed);
5817 } else {
5818 rc = channel->request(output.buffer, frameNumber,
5819 NULL, mParameters, indexUsed);
5820 }
5821 if (rc < 0) {
5822 LOGE("Fail to request on picture channel");
5823 pthread_mutex_unlock(&mMutex);
5824 return rc;
5825 }
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005826
Emilian Peev7650c122017-01-19 08:24:33 -08005827 uint32_t streamId = channel->getStreamID(channel->getStreamTypeMask());
5828 uint32_t j = 0;
5829 for (j = 0; j < streamsArray.num_streams; j++) {
5830 if (streamsArray.stream_request[j].streamID == streamId) {
5831 if (mOpMode == CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE)
5832 streamsArray.stream_request[j].buf_index = CAM_FREERUN_IDX;
5833 else
5834 streamsArray.stream_request[j].buf_index = indexUsed;
5835 break;
5836 }
5837 }
5838 if (j == streamsArray.num_streams) {
5839 LOGE("Did not find matching stream to update index");
5840 assert(0);
5841 }
5842
5843 pendingBufferIter->need_metadata = true;
5844 streams_need_metadata++;
5845 }
Thierry Strudel3d639192016-09-09 11:52:26 -07005846 }
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005847 } else if (output.stream->format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
5848 bool needMetadata = false;
5849 QCamera3YUVChannel *yuvChannel = (QCamera3YUVChannel *)channel;
5850 rc = yuvChannel->request(output.buffer, frameNumber,
5851 pInputBuffer, (pInputBuffer ? &mReprocMeta : mParameters),
5852 needMetadata, indexUsed, false, false);
Thierry Strudel3d639192016-09-09 11:52:26 -07005853 if (rc < 0) {
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005854 LOGE("Fail to request on YUV channel");
Thierry Strudel3d639192016-09-09 11:52:26 -07005855 pthread_mutex_unlock(&mMutex);
5856 return rc;
5857 }
Thierry Strudelc2ee3302016-11-17 12:33:12 -08005858
5859 uint32_t streamId = channel->getStreamID(channel->getStreamTypeMask());
5860 uint32_t j = 0;
5861 for (j = 0; j < streamsArray.num_streams; j++) {
5862 if (streamsArray.stream_request[j].streamID == streamId) {
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005863 if (mOpMode == CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE)
5864 streamsArray.stream_request[j].buf_index = CAM_FREERUN_IDX;
5865 else
5866 streamsArray.stream_request[j].buf_index = indexUsed;
5867 break;
5868 }
5869 }
5870 if (j == streamsArray.num_streams) {
5871 LOGE("Did not find matching stream to update index");
5872 assert(0);
5873 }
5874
5875 pendingBufferIter->need_metadata = needMetadata;
5876 if (needMetadata)
5877 streams_need_metadata += 1;
5878 LOGD("calling YUV channel request, need_metadata is %d",
5879 needMetadata);
5880 } else {
5881 LOGD("request with buffer %p, frame_number %d",
5882 output.buffer, frameNumber);
5883
5884 rc = channel->request(output.buffer, frameNumber, indexUsed);
5885
5886 uint32_t streamId = channel->getStreamID(channel->getStreamTypeMask());
5887 uint32_t j = 0;
5888 for (j = 0; j < streamsArray.num_streams; j++) {
5889 if (streamsArray.stream_request[j].streamID == streamId) {
5890 if (mOpMode == CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE)
5891 streamsArray.stream_request[j].buf_index = CAM_FREERUN_IDX;
5892 else
5893 streamsArray.stream_request[j].buf_index = indexUsed;
5894 break;
5895 }
5896 }
5897 if (j == streamsArray.num_streams) {
5898 LOGE("Did not find matching stream to update index");
5899 assert(0);
5900 }
5901
5902 if (((1U << CAM_STREAM_TYPE_VIDEO) == channel->getStreamTypeMask())
5903 && mBatchSize) {
5904 mToBeQueuedVidBufs++;
5905 if (mToBeQueuedVidBufs == mBatchSize) {
5906 channel->queueBatchBuf();
5907 }
5908 }
5909 if (rc < 0) {
5910 LOGE("request failed");
5911 pthread_mutex_unlock(&mMutex);
5912 return rc;
5913 }
5914 }
5915 pendingBufferIter++;
5916 }
5917
5918 for (auto itr = internallyRequestedStreams.begin(); itr != internallyRequestedStreams.end();
5919 itr++) {
5920 QCamera3Channel *channel = (QCamera3Channel *)(*itr).stream->priv;
5921
5922 if (channel == NULL) {
5923 LOGE("invalid channel pointer for stream");
5924 assert(0);
Shuzhen Wang3a1b92d2017-08-09 13:39:47 -07005925 pthread_mutex_unlock(&mMutex);
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005926 return BAD_VALUE;
5927 }
5928
5929 InternalRequest requestedStream;
5930 requestedStream = (*itr);
5931
5932
5933 if ((*itr).stream->format == HAL_PIXEL_FORMAT_BLOB) {
5934 LOGD("snapshot request internally input buffer %p, frame_number %d",
5935 request->input_buffer, frameNumber);
5936 if(request->input_buffer != NULL){
5937 rc = channel->request(NULL, frameNumber,
5938 pInputBuffer, &mReprocMeta, indexUsed, true,
5939 requestedStream.meteringOnly);
5940 if (rc < 0) {
5941 LOGE("Fail to request on picture channel");
5942 pthread_mutex_unlock(&mMutex);
5943 return rc;
5944 }
5945 } else {
5946 LOGD("snapshot request with frame_number %d", frameNumber);
5947 if (!request->settings) {
5948 rc = channel->request(NULL, frameNumber,
5949 NULL, mPrevParameters, indexUsed, true,
5950 requestedStream.meteringOnly);
5951 } else {
5952 rc = channel->request(NULL, frameNumber,
5953 NULL, mParameters, indexUsed, true, requestedStream.meteringOnly);
5954 }
5955 if (rc < 0) {
5956 LOGE("Fail to request on picture channel");
5957 pthread_mutex_unlock(&mMutex);
5958 return rc;
5959 }
5960
5961 if ((*itr).meteringOnly != 1) {
5962 requestedStream.need_metadata = 1;
5963 streams_need_metadata++;
5964 }
5965 }
5966
5967 uint32_t streamId = channel->getStreamID(channel->getStreamTypeMask());
5968 uint32_t j = 0;
5969 for (j = 0; j < streamsArray.num_streams; j++) {
5970 if (streamsArray.stream_request[j].streamID == streamId) {
Thierry Strudelc2ee3302016-11-17 12:33:12 -08005971 if (mOpMode == CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE)
5972 streamsArray.stream_request[j].buf_index = CAM_FREERUN_IDX;
5973 else
5974 streamsArray.stream_request[j].buf_index = indexUsed;
5975 break;
5976 }
5977 }
5978 if (j == streamsArray.num_streams) {
5979 LOGE("Did not find matching stream to update index");
5980 assert(0);
5981 }
5982
Thierry Strudele80ad7c2016-12-06 10:16:27 -08005983 } else {
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005984 LOGE("Internal requests not supported on this stream type");
Thierry Strudele80ad7c2016-12-06 10:16:27 -08005985 assert(0);
Shuzhen Wang3a1b92d2017-08-09 13:39:47 -07005986 pthread_mutex_unlock(&mMutex);
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005987 return INVALID_OPERATION;
Thierry Strudele80ad7c2016-12-06 10:16:27 -08005988 }
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005989 latestRequest->internalRequestList.push_back(requestedStream);
Thierry Strudele80ad7c2016-12-06 10:16:27 -08005990 }
Thierry Strudele80ad7c2016-12-06 10:16:27 -08005991
Chien-Yu Chene687bd02016-12-07 18:30:26 -08005992 //If 2 streams have need_metadata set to true, fail the request, unless
5993 //we copy/reference count the metadata buffer
5994 if (streams_need_metadata > 1) {
5995 LOGE("not supporting request in which two streams requires"
5996 " 2 HAL metadata for reprocessing");
5997 pthread_mutex_unlock(&mMutex);
5998 return -EINVAL;
5999 }
Thierry Strudel3d639192016-09-09 11:52:26 -07006000
Emilian Peev656e4fa2017-06-02 16:47:04 +01006001 cam_sensor_pd_data_t pdafEnable = (nullptr != mDepthChannel) ?
6002 CAM_PD_DATA_SKIP : CAM_PD_DATA_DISABLED;
6003 if (depthRequestPresent && mDepthChannel) {
6004 if (request->settings) {
6005 camera_metadata_ro_entry entry;
6006 if (find_camera_metadata_ro_entry(request->settings,
6007 NEXUS_EXPERIMENTAL_2017_PD_DATA_ENABLE, &entry) == 0) {
6008 if (entry.data.u8[0]) {
6009 pdafEnable = CAM_PD_DATA_ENABLED;
6010 } else {
6011 pdafEnable = CAM_PD_DATA_SKIP;
6012 }
6013 mDepthCloudMode = pdafEnable;
6014 } else {
6015 pdafEnable = mDepthCloudMode;
6016 }
6017 } else {
6018 pdafEnable = mDepthCloudMode;
6019 }
6020 }
6021
Emilian Peev7650c122017-01-19 08:24:33 -08006022 if (ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters,
6023 CAM_INTF_META_PDAF_DATA_ENABLE, pdafEnable)) {
6024 LOGE("%s: Failed to enable PDAF data in parameters!", __func__);
6025 pthread_mutex_unlock(&mMutex);
6026 return BAD_VALUE;
6027 }
Emilian Peev656e4fa2017-06-02 16:47:04 +01006028
Chien-Yu Chene687bd02016-12-07 18:30:26 -08006029 if (request->input_buffer == NULL) {
6030 /* Set the parameters to backend:
6031 * - For every request in NORMAL MODE
6032 * - For every request in HFR mode during preview only case
6033 * - Once every batch in HFR mode during video recording
6034 */
6035 if (!mBatchSize ||
6036 (mBatchSize && !isVidBufRequested) ||
6037 (mBatchSize && isVidBufRequested && (mToBeQueuedVidBufs == mBatchSize))) {
6038 LOGD("set_parms batchSz: %d IsVidBufReq: %d vidBufTobeQd: %d ",
6039 mBatchSize, isVidBufRequested,
6040 mToBeQueuedVidBufs);
Thierry Strudelc2ee3302016-11-17 12:33:12 -08006041
Chien-Yu Chene687bd02016-12-07 18:30:26 -08006042 if(mBatchSize && isVidBufRequested && (mToBeQueuedVidBufs == mBatchSize)) {
6043 for (uint32_t k = 0; k < streamsArray.num_streams; k++) {
6044 uint32_t m = 0;
6045 for (m = 0; m < mBatchedStreamsArray.num_streams; m++) {
6046 if (streamsArray.stream_request[k].streamID ==
6047 mBatchedStreamsArray.stream_request[m].streamID)
6048 break;
6049 }
6050 if (m == mBatchedStreamsArray.num_streams) {
6051 mBatchedStreamsArray.stream_request\
6052 [mBatchedStreamsArray.num_streams].streamID =
6053 streamsArray.stream_request[k].streamID;
6054 mBatchedStreamsArray.stream_request\
6055 [mBatchedStreamsArray.num_streams].buf_index =
6056 streamsArray.stream_request[k].buf_index;
6057 mBatchedStreamsArray.num_streams =
6058 mBatchedStreamsArray.num_streams + 1;
6059 }
6060 }
6061 streamsArray = mBatchedStreamsArray;
6062 }
6063 /* Update stream id of all the requested buffers */
6064 if (ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_META_STREAM_ID,
6065 streamsArray)) {
6066 LOGE("Failed to set stream type mask in the parameters");
Shuzhen Wang3c077d72017-04-20 22:48:59 -07006067 pthread_mutex_unlock(&mMutex);
Chien-Yu Chene687bd02016-12-07 18:30:26 -08006068 return BAD_VALUE;
6069 }
6070
6071 rc = mCameraHandle->ops->set_parms(mCameraHandle->camera_handle,
6072 mParameters);
6073 if (rc < 0) {
6074 LOGE("set_parms failed");
6075 }
6076 /* reset to zero coz, the batch is queued */
6077 mToBeQueuedVidBufs = 0;
6078 mPendingBatchMap.add(frameNumber, mFirstFrameNumberInBatch);
6079 memset(&mBatchedStreamsArray, 0, sizeof(cam_stream_ID_t));
6080 } else if (mBatchSize && isVidBufRequested && (mToBeQueuedVidBufs != mBatchSize)) {
Thierry Strudelc2ee3302016-11-17 12:33:12 -08006081 for (uint32_t k = 0; k < streamsArray.num_streams; k++) {
6082 uint32_t m = 0;
6083 for (m = 0; m < mBatchedStreamsArray.num_streams; m++) {
6084 if (streamsArray.stream_request[k].streamID ==
6085 mBatchedStreamsArray.stream_request[m].streamID)
6086 break;
Chien-Yu Chene687bd02016-12-07 18:30:26 -08006087 }
6088 if (m == mBatchedStreamsArray.num_streams) {
6089 mBatchedStreamsArray.stream_request[mBatchedStreamsArray.num_streams].
6090 streamID = streamsArray.stream_request[k].streamID;
6091 mBatchedStreamsArray.stream_request[mBatchedStreamsArray.num_streams].
6092 buf_index = streamsArray.stream_request[k].buf_index;
6093 mBatchedStreamsArray.num_streams = mBatchedStreamsArray.num_streams + 1;
6094 }
Thierry Strudelc2ee3302016-11-17 12:33:12 -08006095 }
6096 }
Chien-Yu Chene687bd02016-12-07 18:30:26 -08006097 mPendingLiveRequest++;
Shuzhen Wang3c077d72017-04-20 22:48:59 -07006098
6099 // Start all streams after the first setting is sent, so that the
6100 // setting can be applied sooner: (0 + apply_delay)th frame.
6101 if (mState == CONFIGURED && mChannelHandle) {
6102 //Then start them.
6103 LOGH("Start META Channel");
6104 rc = mMetadataChannel->start();
6105 if (rc < 0) {
6106 LOGE("META channel start failed");
6107 pthread_mutex_unlock(&mMutex);
6108 return rc;
6109 }
6110
6111 if (mAnalysisChannel) {
6112 rc = mAnalysisChannel->start();
6113 if (rc < 0) {
6114 LOGE("Analysis channel start failed");
6115 mMetadataChannel->stop();
6116 pthread_mutex_unlock(&mMutex);
6117 return rc;
6118 }
6119 }
6120
6121 if (mSupportChannel) {
6122 rc = mSupportChannel->start();
6123 if (rc < 0) {
6124 LOGE("Support channel start failed");
6125 mMetadataChannel->stop();
6126 /* Although support and analysis are mutually exclusive today
6127 adding it in anycase for future proofing */
6128 if (mAnalysisChannel) {
6129 mAnalysisChannel->stop();
6130 }
6131 pthread_mutex_unlock(&mMutex);
6132 return rc;
6133 }
6134 }
6135 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
6136 it != mStreamInfo.end(); it++) {
6137 QCamera3Channel *channel = (QCamera3Channel *)(*it)->stream->priv;
6138 LOGH("Start Processing Channel mask=%d",
6139 channel->getStreamTypeMask());
6140 rc = channel->start();
6141 if (rc < 0) {
6142 LOGE("channel start failed");
6143 pthread_mutex_unlock(&mMutex);
6144 return rc;
6145 }
6146 }
6147
6148 if (mRawDumpChannel) {
6149 LOGD("Starting raw dump stream");
6150 rc = mRawDumpChannel->start();
6151 if (rc != NO_ERROR) {
6152 LOGE("Error Starting Raw Dump Channel");
6153 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
6154 it != mStreamInfo.end(); it++) {
6155 QCamera3Channel *channel =
6156 (QCamera3Channel *)(*it)->stream->priv;
6157 LOGH("Stopping Processing Channel mask=%d",
6158 channel->getStreamTypeMask());
6159 channel->stop();
6160 }
6161 if (mSupportChannel)
6162 mSupportChannel->stop();
6163 if (mAnalysisChannel) {
6164 mAnalysisChannel->stop();
6165 }
6166 mMetadataChannel->stop();
6167 pthread_mutex_unlock(&mMutex);
6168 return rc;
6169 }
6170 }
6171
Chien-Yu Chence5b8662017-05-09 17:17:17 -07006172 // Configure modules for stream on.
Chien-Yu Chen153c5172017-09-08 11:33:19 -07006173 rc = startChannelLocked();
Shuzhen Wang3c077d72017-04-20 22:48:59 -07006174 if (rc != NO_ERROR) {
Chien-Yu Chen153c5172017-09-08 11:33:19 -07006175 LOGE("startChannelLocked failed %d", rc);
Chien-Yu Chence5b8662017-05-09 17:17:17 -07006176 pthread_mutex_unlock(&mMutex);
6177 return rc;
6178 }
Shuzhen Wang3c077d72017-04-20 22:48:59 -07006179 }
Thierry Strudel3d639192016-09-09 11:52:26 -07006180 }
Thierry Strudel3d639192016-09-09 11:52:26 -07006181 }
6182
Chien-Yu Chenfadf40e2017-09-15 14:33:57 -07006183 // Enable HDR+ mode for the first PREVIEW_INTENT request that doesn't disable HDR+.
Chenjie Luo4a761802017-06-13 17:35:54 +00006184 {
Chien-Yu Chen77ccd022017-06-23 12:00:36 -07006185 std::unique_lock<std::mutex> l(gHdrPlusClientLock);
Chien-Yu Chend77a5462017-06-02 18:00:38 -07006186 if (gEaselManagerClient != nullptr && gEaselManagerClient->isEaselPresentOnDevice() &&
Chien-Yu Chenfe023bc2017-05-12 17:19:26 -07006187 !gEaselBypassOnly && !mFirstPreviewIntentSeen &&
6188 meta.exists(ANDROID_CONTROL_CAPTURE_INTENT) &&
6189 meta.find(ANDROID_CONTROL_CAPTURE_INTENT).data.u8[0] ==
Chien-Yu Chenfadf40e2017-09-15 14:33:57 -07006190 ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW &&
6191 meta.exists(NEXUS_EXPERIMENTAL_2017_DISABLE_HDRPLUS) &&
6192 meta.find(NEXUS_EXPERIMENTAL_2017_DISABLE_HDRPLUS).data.i32[0] == 0) {
Chien-Yu Chendeaebad2017-06-30 11:46:34 -07006193
6194 if (isSessionHdrPlusModeCompatible()) {
6195 rc = enableHdrPlusModeLocked();
6196 if (rc != OK) {
6197 LOGE("%s: Failed to open HDR+ asynchronously", __FUNCTION__);
6198 pthread_mutex_unlock(&mMutex);
6199 return rc;
6200 }
Chien-Yu Chenfe023bc2017-05-12 17:19:26 -07006201 }
6202
6203 mFirstPreviewIntentSeen = true;
6204 }
6205 }
6206
Thierry Strudel3d639192016-09-09 11:52:26 -07006207 LOGD("mPendingLiveRequest = %d", mPendingLiveRequest);
6208
6209 mState = STARTED;
6210 // Added a timed condition wait
6211 struct timespec ts;
6212 uint8_t isValidTimeout = 1;
Shuzhen Wangfb961e52016-11-28 11:48:02 -08006213 rc = clock_gettime(CLOCK_MONOTONIC, &ts);
Thierry Strudel3d639192016-09-09 11:52:26 -07006214 if (rc < 0) {
6215 isValidTimeout = 0;
6216 LOGE("Error reading the real time clock!!");
6217 }
6218 else {
6219 // Make timeout as 5 sec for request to be honored
Chien-Yu Chene687bd02016-12-07 18:30:26 -08006220 int64_t timeout = 5;
6221 {
6222 Mutex::Autolock lock(mHdrPlusPendingRequestsLock);
6223 // If there is a pending HDR+ request, the following requests may be blocked until the
6224 // HDR+ request is done. So allow a longer timeout.
6225 if (mHdrPlusPendingRequests.size() > 0) {
6226 timeout = MISSING_HDRPLUS_REQUEST_BUF_TIMEOUT;
6227 }
6228 }
6229 ts.tv_sec += timeout;
Thierry Strudel3d639192016-09-09 11:52:26 -07006230 }
6231 //Block on conditional variable
Thierry Strudel9e74aae2016-09-22 17:10:18 -07006232 while ((mPendingLiveRequest >= mMinInFlightRequests) && !pInputBuffer &&
Thierry Strudel3d639192016-09-09 11:52:26 -07006233 (mState != ERROR) && (mState != DEINIT)) {
6234 if (!isValidTimeout) {
6235 LOGD("Blocking on conditional wait");
6236 pthread_cond_wait(&mRequestCond, &mMutex);
6237 }
6238 else {
6239 LOGD("Blocking on timed conditional wait");
6240 rc = pthread_cond_timedwait(&mRequestCond, &mMutex, &ts);
6241 if (rc == ETIMEDOUT) {
6242 rc = -ENODEV;
6243 LOGE("Unblocked on timeout!!!!");
6244 break;
6245 }
6246 }
6247 LOGD("Unblocked");
6248 if (mWokenUpByDaemon) {
6249 mWokenUpByDaemon = false;
Thierry Strudel9e74aae2016-09-22 17:10:18 -07006250 if (mPendingLiveRequest < mMaxInFlightRequests)
Thierry Strudel3d639192016-09-09 11:52:26 -07006251 break;
6252 }
6253 }
6254 pthread_mutex_unlock(&mMutex);
6255
6256 return rc;
6257}
6258
Chien-Yu Chen153c5172017-09-08 11:33:19 -07006259int32_t QCamera3HardwareInterface::startChannelLocked()
6260{
6261 // Configure modules for stream on.
6262 int32_t rc = mCameraHandle->ops->start_channel(mCameraHandle->camera_handle,
6263 mChannelHandle, /*start_sensor_streaming*/false);
6264 if (rc != NO_ERROR) {
6265 LOGE("start_channel failed %d", rc);
6266 return rc;
6267 }
6268
6269 {
6270 // Configure Easel for stream on.
6271 std::unique_lock<std::mutex> l(gHdrPlusClientLock);
Chien-Yu Chen153c5172017-09-08 11:33:19 -07006272 if (EaselManagerClientOpened) {
Zhijun Hec1ebd502017-10-15 13:14:18 -07006273 // Now that sensor mode should have been selected, get the selected sensor mode
6274 // info.
6275 memset(&mSensorModeInfo, 0, sizeof(mSensorModeInfo));
6276 rc = getCurrentSensorModeInfo(mSensorModeInfo);
6277 if (rc != NO_ERROR) {
6278 ALOGE("%s: Get current sensor mode failed, bail out: %s (%d).", __FUNCTION__,
6279 strerror(-rc), rc);
6280 return rc;
6281 }
Chien-Yu Chen153c5172017-09-08 11:33:19 -07006282 logEaselEvent("EASEL_STARTUP_LATENCY", "Starting MIPI");
6283 rc = gEaselManagerClient->startMipi(mCameraId, mSensorModeInfo.op_pixel_clk,
6284 /*enableCapture*/true);
6285 if (rc != OK) {
6286 ALOGE("%s: Failed to start MIPI rate for camera %u to %u", __FUNCTION__,
6287 mCameraId, mSensorModeInfo.op_pixel_clk);
6288 return rc;
6289 }
6290 logEaselEvent("EASEL_STARTUP_LATENCY", "Starting MIPI done");
6291 mEaselMipiStarted = true;
6292 }
6293 }
6294
6295 // Start sensor streaming.
6296 rc = mCameraHandle->ops->start_sensor_streaming(mCameraHandle->camera_handle,
6297 mChannelHandle);
6298 if (rc != NO_ERROR) {
6299 LOGE("start_sensor_stream_on failed %d", rc);
6300 return rc;
6301 }
6302
6303 return 0;
6304}
6305
6306void QCamera3HardwareInterface::stopChannelLocked(bool stopChannelImmediately)
6307{
6308 mCameraHandle->ops->stop_channel(mCameraHandle->camera_handle,
6309 mChannelHandle, stopChannelImmediately);
6310
6311 {
6312 std::unique_lock<std::mutex> l(gHdrPlusClientLock);
6313 if (EaselManagerClientOpened && mEaselMipiStarted) {
6314 int32_t rc = gEaselManagerClient->stopMipi(mCameraId);
6315 if (rc != 0) {
6316 ALOGE("%s: Stopping MIPI failed: %s (%d)", __FUNCTION__, strerror(-rc), rc);
6317 }
6318 mEaselMipiStarted = false;
6319 }
6320 }
6321}
6322
Thierry Strudel3d639192016-09-09 11:52:26 -07006323/*===========================================================================
6324 * FUNCTION : dump
6325 *
6326 * DESCRIPTION:
6327 *
6328 * PARAMETERS :
6329 *
6330 *
6331 * RETURN :
6332 *==========================================================================*/
6333void QCamera3HardwareInterface::dump(int fd)
6334{
6335 pthread_mutex_lock(&mMutex);
6336 dprintf(fd, "\n Camera HAL3 information Begin \n");
6337
6338 dprintf(fd, "\nNumber of pending requests: %zu \n",
6339 mPendingRequestsList.size());
6340 dprintf(fd, "-------+-------------------+-------------+----------+---------------------\n");
6341 dprintf(fd, " Frame | Number of Buffers | Req Id: | Blob Req | Input buffer present\n");
6342 dprintf(fd, "-------+-------------------+-------------+----------+---------------------\n");
6343 for(pendingRequestIterator i = mPendingRequestsList.begin();
6344 i != mPendingRequestsList.end(); i++) {
6345 dprintf(fd, " %5d | %17d | %11d | %8d | %p \n",
6346 i->frame_number, i->num_buffers, i->request_id, i->blob_request,
6347 i->input_buffer);
6348 }
6349 dprintf(fd, "\nPending buffer map: Number of buffers: %u\n",
6350 mPendingBuffersMap.get_num_overall_buffers());
6351 dprintf(fd, "-------+------------------\n");
6352 dprintf(fd, " Frame | Stream type mask \n");
6353 dprintf(fd, "-------+------------------\n");
6354 for(auto &req : mPendingBuffersMap.mPendingBuffersInRequest) {
6355 for(auto &j : req.mPendingBufferList) {
6356 QCamera3Channel *channel = (QCamera3Channel *)(j.stream->priv);
6357 dprintf(fd, " %5d | %11d \n",
6358 req.frame_number, channel->getStreamTypeMask());
6359 }
6360 }
6361 dprintf(fd, "-------+------------------\n");
6362
6363 dprintf(fd, "\nPending frame drop list: %zu\n",
6364 mPendingFrameDropList.size());
6365 dprintf(fd, "-------+-----------\n");
6366 dprintf(fd, " Frame | Stream ID \n");
6367 dprintf(fd, "-------+-----------\n");
6368 for(List<PendingFrameDropInfo>::iterator i = mPendingFrameDropList.begin();
6369 i != mPendingFrameDropList.end(); i++) {
6370 dprintf(fd, " %5d | %9d \n",
6371 i->frame_number, i->stream_ID);
6372 }
6373 dprintf(fd, "-------+-----------\n");
6374
6375 dprintf(fd, "\n Camera HAL3 information End \n");
6376
6377 /* use dumpsys media.camera as trigger to send update debug level event */
6378 mUpdateDebugLevel = true;
6379 pthread_mutex_unlock(&mMutex);
6380 return;
6381}
6382
6383/*===========================================================================
6384 * FUNCTION : flush
6385 *
6386 * DESCRIPTION: Calls stopAllChannels, notifyErrorForPendingRequests and
6387 * conditionally restarts channels
6388 *
6389 * PARAMETERS :
6390 * @ restartChannels: re-start all channels
Chien-Yu Chen09cb28e2017-07-21 13:15:52 -07006391 * @ stopChannelImmediately: stop the channel immediately. This should be used
6392 * when device encountered an error and MIPI may has
6393 * been stopped.
Thierry Strudel3d639192016-09-09 11:52:26 -07006394 *
6395 * RETURN :
6396 * 0 on success
6397 * Error code on failure
6398 *==========================================================================*/
Chien-Yu Chen09cb28e2017-07-21 13:15:52 -07006399int QCamera3HardwareInterface::flush(bool restartChannels, bool stopChannelImmediately)
Thierry Strudel3d639192016-09-09 11:52:26 -07006400{
Thierry Strudel9ec39c62016-12-28 11:30:05 -08006401 KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL3_STOP_PREVIEW);
Thierry Strudel3d639192016-09-09 11:52:26 -07006402 int32_t rc = NO_ERROR;
6403
6404 LOGD("Unblocking Process Capture Request");
6405 pthread_mutex_lock(&mMutex);
6406 mFlush = true;
6407 pthread_mutex_unlock(&mMutex);
6408
Chien-Yu Chen11c8edc2017-09-11 20:54:24 -07006409 // Disable HDR+ if it's enabled;
6410 {
6411 std::unique_lock<std::mutex> l(gHdrPlusClientLock);
6412 finishHdrPlusClientOpeningLocked(l);
6413 disableHdrPlusModeLocked();
6414 }
6415
Thierry Strudel3d639192016-09-09 11:52:26 -07006416 rc = stopAllChannels();
6417 // unlink of dualcam
6418 if (mIsDeviceLinked) {
Thierry Strudel295a0ca2016-11-03 18:38:47 -07006419 cam_dual_camera_bundle_info_t *m_pRelCamSyncBuf =
6420 &m_pDualCamCmdPtr->bundle_info;
6421 m_pDualCamCmdPtr->cmd_type = CAM_DUAL_CAMERA_BUNDLE_INFO;
Thierry Strudel3d639192016-09-09 11:52:26 -07006422 m_pRelCamSyncBuf->sync_control = CAM_SYNC_RELATED_SENSORS_OFF;
6423 pthread_mutex_lock(&gCamLock);
6424
6425 if (mIsMainCamera == 1) {
6426 m_pRelCamSyncBuf->mode = CAM_MODE_PRIMARY;
6427 m_pRelCamSyncBuf->type = CAM_TYPE_MAIN;
Thierry Strudel269c81a2016-10-12 12:13:59 -07006428 m_pRelCamSyncBuf->sync_3a_mode = CAM_3A_SYNC_FOLLOW;
Thierry Strudel3d639192016-09-09 11:52:26 -07006429 // related session id should be session id of linked session
6430 m_pRelCamSyncBuf->related_sensor_session_id = sessionId[mLinkedCameraId];
6431 } else {
6432 m_pRelCamSyncBuf->mode = CAM_MODE_SECONDARY;
6433 m_pRelCamSyncBuf->type = CAM_TYPE_AUX;
Thierry Strudel269c81a2016-10-12 12:13:59 -07006434 m_pRelCamSyncBuf->sync_3a_mode = CAM_3A_SYNC_FOLLOW;
Thierry Strudel3d639192016-09-09 11:52:26 -07006435 m_pRelCamSyncBuf->related_sensor_session_id = sessionId[mLinkedCameraId];
6436 }
Thierry Strudel2896d122017-02-23 19:18:03 -08006437 m_pRelCamSyncBuf->is_hw_sync_enabled = DUALCAM_HW_SYNC_ENABLED;
Thierry Strudel3d639192016-09-09 11:52:26 -07006438 pthread_mutex_unlock(&gCamLock);
6439
Thierry Strudel295a0ca2016-11-03 18:38:47 -07006440 rc = mCameraHandle->ops->set_dual_cam_cmd(
6441 mCameraHandle->camera_handle);
Thierry Strudel3d639192016-09-09 11:52:26 -07006442 if (rc < 0) {
6443 LOGE("Dualcam: Unlink failed, but still proceed to close");
6444 }
6445 }
6446
6447 if (rc < 0) {
6448 LOGE("stopAllChannels failed");
6449 return rc;
6450 }
6451 if (mChannelHandle) {
Chien-Yu Chen153c5172017-09-08 11:33:19 -07006452 stopChannelLocked(stopChannelImmediately);
Thierry Strudel3d639192016-09-09 11:52:26 -07006453 }
6454
6455 // Reset bundle info
6456 rc = setBundleInfo();
6457 if (rc < 0) {
6458 LOGE("setBundleInfo failed %d", rc);
6459 return rc;
6460 }
6461
6462 // Mutex Lock
6463 pthread_mutex_lock(&mMutex);
6464
6465 // Unblock process_capture_request
6466 mPendingLiveRequest = 0;
6467 pthread_cond_signal(&mRequestCond);
6468
6469 rc = notifyErrorForPendingRequests();
6470 if (rc < 0) {
6471 LOGE("notifyErrorForPendingRequests failed");
6472 pthread_mutex_unlock(&mMutex);
6473 return rc;
6474 }
6475
6476 mFlush = false;
6477
6478 // Start the Streams/Channels
6479 if (restartChannels) {
6480 rc = startAllChannels();
6481 if (rc < 0) {
6482 LOGE("startAllChannels failed");
6483 pthread_mutex_unlock(&mMutex);
6484 return rc;
6485 }
Thierry Strudel2896d122017-02-23 19:18:03 -08006486 if (mChannelHandle) {
Chien-Yu Chen153c5172017-09-08 11:33:19 -07006487 // Configure modules for stream on.
6488 rc = startChannelLocked();
Thierry Strudel2896d122017-02-23 19:18:03 -08006489 if (rc < 0) {
Chien-Yu Chen153c5172017-09-08 11:33:19 -07006490 LOGE("startChannelLocked failed");
Thierry Strudel2896d122017-02-23 19:18:03 -08006491 pthread_mutex_unlock(&mMutex);
6492 return rc;
6493 }
Thierry Strudel3d639192016-09-09 11:52:26 -07006494 }
Chien-Yu Chen6ed36ca2017-10-02 11:22:17 -07006495 mFirstPreviewIntentSeen = false;
Thierry Strudel3d639192016-09-09 11:52:26 -07006496 }
Thierry Strudel3d639192016-09-09 11:52:26 -07006497 pthread_mutex_unlock(&mMutex);
6498
6499 return 0;
6500}
6501
6502/*===========================================================================
6503 * FUNCTION : flushPerf
6504 *
6505 * DESCRIPTION: This is the performance optimization version of flush that does
6506 * not use stream off, rather flushes the system
6507 *
6508 * PARAMETERS :
6509 *
6510 *
6511 * RETURN : 0 : success
6512 * -EINVAL: input is malformed (device is not valid)
6513 * -ENODEV: if the device has encountered a serious error
6514 *==========================================================================*/
6515int QCamera3HardwareInterface::flushPerf()
6516{
Thierry Strudel9ec39c62016-12-28 11:30:05 -08006517 KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL3_STOP_PREVIEW);
Thierry Strudel3d639192016-09-09 11:52:26 -07006518 int32_t rc = 0;
6519 struct timespec timeout;
6520 bool timed_wait = false;
6521
6522 pthread_mutex_lock(&mMutex);
6523 mFlushPerf = true;
6524 mPendingBuffersMap.numPendingBufsAtFlush =
6525 mPendingBuffersMap.get_num_overall_buffers();
6526 LOGD("Calling flush. Wait for %d buffers to return",
6527 mPendingBuffersMap.numPendingBufsAtFlush);
6528
6529 /* send the flush event to the backend */
6530 rc = mCameraHandle->ops->flush(mCameraHandle->camera_handle);
6531 if (rc < 0) {
6532 LOGE("Error in flush: IOCTL failure");
6533 mFlushPerf = false;
6534 pthread_mutex_unlock(&mMutex);
6535 return -ENODEV;
6536 }
6537
6538 if (mPendingBuffersMap.numPendingBufsAtFlush == 0) {
6539 LOGD("No pending buffers in HAL, return flush");
6540 mFlushPerf = false;
6541 pthread_mutex_unlock(&mMutex);
6542 return rc;
6543 }
6544
6545 /* wait on a signal that buffers were received */
Shuzhen Wangfb961e52016-11-28 11:48:02 -08006546 rc = clock_gettime(CLOCK_MONOTONIC, &timeout);
Thierry Strudel3d639192016-09-09 11:52:26 -07006547 if (rc < 0) {
6548 LOGE("Error reading the real time clock, cannot use timed wait");
6549 } else {
6550 timeout.tv_sec += FLUSH_TIMEOUT;
6551 timed_wait = true;
6552 }
6553
6554 //Block on conditional variable
6555 while (mPendingBuffersMap.numPendingBufsAtFlush != 0) {
6556 LOGD("Waiting on mBuffersCond");
6557 if (!timed_wait) {
6558 rc = pthread_cond_wait(&mBuffersCond, &mMutex);
6559 if (rc != 0) {
6560 LOGE("pthread_cond_wait failed due to rc = %s",
6561 strerror(rc));
6562 break;
6563 }
6564 } else {
6565 rc = pthread_cond_timedwait(&mBuffersCond, &mMutex, &timeout);
6566 if (rc != 0) {
6567 LOGE("pthread_cond_timedwait failed due to rc = %s",
6568 strerror(rc));
6569 break;
6570 }
6571 }
6572 }
6573 if (rc != 0) {
6574 mFlushPerf = false;
6575 pthread_mutex_unlock(&mMutex);
6576 return -ENODEV;
6577 }
6578
6579 LOGD("Received buffers, now safe to return them");
6580
6581 //make sure the channels handle flush
6582 //currently only required for the picture channel to release snapshot resources
6583 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
6584 it != mStreamInfo.end(); it++) {
6585 QCamera3Channel *channel = (*it)->channel;
6586 if (channel) {
6587 rc = channel->flush();
6588 if (rc) {
6589 LOGE("Flushing the channels failed with error %d", rc);
6590 // even though the channel flush failed we need to continue and
6591 // return the buffers we have to the framework, however the return
6592 // value will be an error
6593 rc = -ENODEV;
6594 }
6595 }
6596 }
6597
6598 /* notify the frameworks and send errored results */
6599 rc = notifyErrorForPendingRequests();
6600 if (rc < 0) {
6601 LOGE("notifyErrorForPendingRequests failed");
6602 pthread_mutex_unlock(&mMutex);
6603 return rc;
6604 }
6605
6606 //unblock process_capture_request
6607 mPendingLiveRequest = 0;
6608 unblockRequestIfNecessary();
6609
6610 mFlushPerf = false;
6611 pthread_mutex_unlock(&mMutex);
6612 LOGD ("Flush Operation complete. rc = %d", rc);
6613 return rc;
6614}
6615
6616/*===========================================================================
6617 * FUNCTION : handleCameraDeviceError
6618 *
6619 * DESCRIPTION: This function calls internal flush and notifies the error to
6620 * framework and updates the state variable.
6621 *
Chien-Yu Chen09cb28e2017-07-21 13:15:52 -07006622 * PARAMETERS :
6623 * @stopChannelImmediately : stop channels immediately without waiting for
6624 * frame boundary.
Thierry Strudel3d639192016-09-09 11:52:26 -07006625 *
6626 * RETURN : NO_ERROR on Success
6627 * Error code on failure
6628 *==========================================================================*/
Chien-Yu Chen09cb28e2017-07-21 13:15:52 -07006629int32_t QCamera3HardwareInterface::handleCameraDeviceError(bool stopChannelImmediately)
Thierry Strudel3d639192016-09-09 11:52:26 -07006630{
6631 int32_t rc = NO_ERROR;
6632
Thierry Strudele80ad7c2016-12-06 10:16:27 -08006633 {
6634 Mutex::Autolock lock(mFlushLock);
6635 pthread_mutex_lock(&mMutex);
6636 if (mState != ERROR) {
6637 //if mState != ERROR, nothing to be done
6638 pthread_mutex_unlock(&mMutex);
6639 return NO_ERROR;
6640 }
Thierry Strudel3d639192016-09-09 11:52:26 -07006641 pthread_mutex_unlock(&mMutex);
Thierry Strudel3d639192016-09-09 11:52:26 -07006642
Chien-Yu Chen09cb28e2017-07-21 13:15:52 -07006643 rc = flush(false /* restart channels */, stopChannelImmediately);
Thierry Strudele80ad7c2016-12-06 10:16:27 -08006644 if (NO_ERROR != rc) {
6645 LOGE("internal flush to handle mState = ERROR failed");
6646 }
Thierry Strudel3d639192016-09-09 11:52:26 -07006647
Thierry Strudele80ad7c2016-12-06 10:16:27 -08006648 pthread_mutex_lock(&mMutex);
6649 mState = DEINIT;
6650 pthread_mutex_unlock(&mMutex);
6651 }
Thierry Strudel3d639192016-09-09 11:52:26 -07006652
6653 camera3_notify_msg_t notify_msg;
6654 memset(&notify_msg, 0, sizeof(camera3_notify_msg_t));
6655 notify_msg.type = CAMERA3_MSG_ERROR;
6656 notify_msg.message.error.error_code = CAMERA3_MSG_ERROR_DEVICE;
6657 notify_msg.message.error.error_stream = NULL;
6658 notify_msg.message.error.frame_number = 0;
Thierry Strudele80ad7c2016-12-06 10:16:27 -08006659 orchestrateNotify(&notify_msg);
Thierry Strudel3d639192016-09-09 11:52:26 -07006660
6661 return rc;
6662}
6663
6664/*===========================================================================
6665 * FUNCTION : captureResultCb
6666 *
6667 * DESCRIPTION: Callback handler for all capture result
6668 * (streams, as well as metadata)
6669 *
6670 * PARAMETERS :
6671 * @metadata : metadata information
6672 * @buffer : actual gralloc buffer to be returned to frameworks.
6673 * NULL if metadata.
6674 *
6675 * RETURN : NONE
6676 *==========================================================================*/
6677void QCamera3HardwareInterface::captureResultCb(mm_camera_super_buf_t *metadata_buf,
6678 camera3_stream_buffer_t *buffer, uint32_t frame_number, bool isInputBuffer)
6679{
6680 if (metadata_buf) {
Thierry Strudel295a0ca2016-11-03 18:38:47 -07006681 pthread_mutex_lock(&mMutex);
6682 uint8_t batchSize = mBatchSize;
6683 pthread_mutex_unlock(&mMutex);
6684 if (batchSize) {
Thierry Strudel3d639192016-09-09 11:52:26 -07006685 handleBatchMetadata(metadata_buf,
6686 true /* free_and_bufdone_meta_buf */);
6687 } else { /* mBatchSize = 0 */
6688 hdrPlusPerfLock(metadata_buf);
6689 pthread_mutex_lock(&mMutex);
6690 handleMetadataWithLock(metadata_buf,
Thierry Strudel9e74aae2016-09-22 17:10:18 -07006691 true /* free_and_bufdone_meta_buf */,
Shuzhen Wang94ddf072017-03-12 19:47:23 -07006692 true /* last urgent frame of batch metadata */,
6693 true /* last frame of batch metadata */,
Thierry Strudel54dc9782017-02-15 12:12:10 -08006694 NULL);
Thierry Strudel3d639192016-09-09 11:52:26 -07006695 pthread_mutex_unlock(&mMutex);
6696 }
6697 } else if (isInputBuffer) {
6698 pthread_mutex_lock(&mMutex);
6699 handleInputBufferWithLock(frame_number);
6700 pthread_mutex_unlock(&mMutex);
6701 } else {
6702 pthread_mutex_lock(&mMutex);
6703 handleBufferWithLock(buffer, frame_number);
6704 pthread_mutex_unlock(&mMutex);
6705 }
6706 return;
6707}
6708
6709/*===========================================================================
6710 * FUNCTION : getReprocessibleOutputStreamId
6711 *
6712 * DESCRIPTION: Get source output stream id for the input reprocess stream
6713 * based on size and format, which would be the largest
6714 * output stream if an input stream exists.
6715 *
6716 * PARAMETERS :
6717 * @id : return the stream id if found
6718 *
6719 * RETURN : int32_t type of status
6720 * NO_ERROR -- success
6721 * none-zero failure code
6722 *==========================================================================*/
6723int32_t QCamera3HardwareInterface::getReprocessibleOutputStreamId(uint32_t &id)
6724{
6725 /* check if any output or bidirectional stream with the same size and format
6726 and return that stream */
6727 if ((mInputStreamInfo.dim.width > 0) &&
6728 (mInputStreamInfo.dim.height > 0)) {
6729 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
6730 it != mStreamInfo.end(); it++) {
6731
6732 camera3_stream_t *stream = (*it)->stream;
6733 if ((stream->width == (uint32_t)mInputStreamInfo.dim.width) &&
6734 (stream->height == (uint32_t)mInputStreamInfo.dim.height) &&
6735 (stream->format == mInputStreamInfo.format)) {
6736 // Usage flag for an input stream and the source output stream
6737 // may be different.
6738 LOGD("Found reprocessible output stream! %p", *it);
6739 LOGD("input stream usage 0x%x, current stream usage 0x%x",
6740 stream->usage, mInputStreamInfo.usage);
6741
6742 QCamera3Channel *channel = (QCamera3Channel *)stream->priv;
6743 if (channel != NULL && channel->mStreams[0]) {
6744 id = channel->mStreams[0]->getMyServerID();
6745 return NO_ERROR;
6746 }
6747 }
6748 }
6749 } else {
6750 LOGD("No input stream, so no reprocessible output stream");
6751 }
6752 return NAME_NOT_FOUND;
6753}
6754
6755/*===========================================================================
6756 * FUNCTION : lookupFwkName
6757 *
6758 * DESCRIPTION: In case the enum is not same in fwk and backend
6759 * make sure the parameter is correctly propogated
6760 *
6761 * PARAMETERS :
6762 * @arr : map between the two enums
6763 * @len : len of the map
6764 * @hal_name : name of the hal_parm to map
6765 *
6766 * RETURN : int type of status
6767 * fwk_name -- success
6768 * none-zero failure code
6769 *==========================================================================*/
6770template <typename halType, class mapType> int lookupFwkName(const mapType *arr,
6771 size_t len, halType hal_name)
6772{
6773
6774 for (size_t i = 0; i < len; i++) {
6775 if (arr[i].hal_name == hal_name) {
6776 return arr[i].fwk_name;
6777 }
6778 }
6779
6780 /* Not able to find matching framework type is not necessarily
6781 * an error case. This happens when mm-camera supports more attributes
6782 * than the frameworks do */
6783 LOGH("Cannot find matching framework type");
6784 return NAME_NOT_FOUND;
6785}
6786
6787/*===========================================================================
6788 * FUNCTION : lookupHalName
6789 *
6790 * DESCRIPTION: In case the enum is not same in fwk and backend
6791 * make sure the parameter is correctly propogated
6792 *
6793 * PARAMETERS :
6794 * @arr : map between the two enums
6795 * @len : len of the map
6796 * @fwk_name : name of the hal_parm to map
6797 *
6798 * RETURN : int32_t type of status
6799 * hal_name -- success
6800 * none-zero failure code
6801 *==========================================================================*/
6802template <typename fwkType, class mapType> int lookupHalName(const mapType *arr,
6803 size_t len, fwkType fwk_name)
6804{
6805 for (size_t i = 0; i < len; i++) {
6806 if (arr[i].fwk_name == fwk_name) {
6807 return arr[i].hal_name;
6808 }
6809 }
6810
6811 LOGE("Cannot find matching hal type fwk_name=%d", fwk_name);
6812 return NAME_NOT_FOUND;
6813}
6814
6815/*===========================================================================
6816 * FUNCTION : lookupProp
6817 *
6818 * DESCRIPTION: lookup a value by its name
6819 *
6820 * PARAMETERS :
6821 * @arr : map between the two enums
6822 * @len : size of the map
6823 * @name : name to be looked up
6824 *
6825 * RETURN : Value if found
6826 * CAM_CDS_MODE_MAX if not found
6827 *==========================================================================*/
6828template <class mapType> cam_cds_mode_type_t lookupProp(const mapType *arr,
6829 size_t len, const char *name)
6830{
6831 if (name) {
6832 for (size_t i = 0; i < len; i++) {
6833 if (!strcmp(arr[i].desc, name)) {
6834 return arr[i].val;
6835 }
6836 }
6837 }
6838 return CAM_CDS_MODE_MAX;
6839}
6840
6841/*===========================================================================
6842 *
6843 * DESCRIPTION:
6844 *
6845 * PARAMETERS :
6846 * @metadata : metadata information from callback
Shuzhen Wang181c57b2017-07-21 11:39:44 -07006847 * @pendingRequest: pending request for this metadata
Thierry Strudel3d639192016-09-09 11:52:26 -07006848 * @pprocDone: whether internal offline postprocsesing is done
Shuzhen Wang94ddf072017-03-12 19:47:23 -07006849 * @lastMetadataInBatch: Boolean to indicate whether this is the last metadata
6850 * in a batch. Always true for non-batch mode.
Thierry Strudel3d639192016-09-09 11:52:26 -07006851 *
6852 * RETURN : camera_metadata_t*
6853 * metadata in a format specified by fwk
6854 *==========================================================================*/
6855camera_metadata_t*
6856QCamera3HardwareInterface::translateFromHalMetadata(
6857 metadata_buffer_t *metadata,
Shuzhen Wang181c57b2017-07-21 11:39:44 -07006858 const PendingRequestInfo& pendingRequest,
Thierry Strudel3d639192016-09-09 11:52:26 -07006859 bool pprocDone,
Chien-Yu Chen66ec22a2017-04-13 18:00:36 -07006860 bool lastMetadataInBatch,
6861 const bool *enableZsl)
Thierry Strudel3d639192016-09-09 11:52:26 -07006862{
6863 CameraMetadata camMetadata;
6864 camera_metadata_t *resultMetadata;
6865
Shuzhen Wang94ddf072017-03-12 19:47:23 -07006866 if (!lastMetadataInBatch) {
Shuzhen Wang8fe62792017-03-20 16:10:25 -07006867 /* In batch mode, only populate SENSOR_TIMESTAMP if this is not the last in batch.
6868 * Timestamp is needed because it's used for shutter notify calculation.
6869 * */
Shuzhen Wang181c57b2017-07-21 11:39:44 -07006870 camMetadata.update(ANDROID_SENSOR_TIMESTAMP, &pendingRequest.timestamp, 1);
Shuzhen Wang8fe62792017-03-20 16:10:25 -07006871 resultMetadata = camMetadata.release();
Shuzhen Wang94ddf072017-03-12 19:47:23 -07006872 return resultMetadata;
Thierry Strudel9e74aae2016-09-22 17:10:18 -07006873 }
6874
Shuzhen Wang181c57b2017-07-21 11:39:44 -07006875 if (pendingRequest.jpegMetadata.entryCount())
6876 camMetadata.append(pendingRequest.jpegMetadata);
Thierry Strudel3d639192016-09-09 11:52:26 -07006877
Shuzhen Wang181c57b2017-07-21 11:39:44 -07006878 camMetadata.update(ANDROID_SENSOR_TIMESTAMP, &pendingRequest.timestamp, 1);
6879 camMetadata.update(ANDROID_REQUEST_ID, &pendingRequest.request_id, 1);
6880 camMetadata.update(ANDROID_REQUEST_PIPELINE_DEPTH, &pendingRequest.pipeline_depth, 1);
6881 camMetadata.update(ANDROID_CONTROL_CAPTURE_INTENT, &pendingRequest.capture_intent, 1);
6882 camMetadata.update(NEXUS_EXPERIMENTAL_2016_HYBRID_AE_ENABLE, &pendingRequest.hybrid_ae_enable, 1);
Wei (Alex) Honga90a2142018-01-05 17:36:52 -08006883 camMetadata.update(NEXUS_EXPERIMENTAL_2017_MOTION_DETECTION_ENABLE, &pendingRequest.motion_detection_enable, 1);
Samuel Ha68ba5172016-12-15 18:41:12 -08006884 if (mBatchSize == 0) {
6885 // DevCamDebug metadata translateFromHalMetadata. Only update this one for non-HFR mode
Shuzhen Wang181c57b2017-07-21 11:39:44 -07006886 camMetadata.update(DEVCAMDEBUG_META_ENABLE, &pendingRequest.DevCamDebug_meta_enable, 1);
Samuel Ha68ba5172016-12-15 18:41:12 -08006887 }
Thierry Strudel3d639192016-09-09 11:52:26 -07006888
Samuel Ha68ba5172016-12-15 18:41:12 -08006889 // atrace_begin(ATRACE_TAG_ALWAYS, "DevCamDebugInfo");
6890 // Only update DevCameraDebug metadta conditionally: non-HFR mode and it is enabled.
Shuzhen Wang181c57b2017-07-21 11:39:44 -07006891 if (mBatchSize == 0 && pendingRequest.DevCamDebug_meta_enable != 0) {
Samuel Ha68ba5172016-12-15 18:41:12 -08006892 // DevCamDebug metadata translateFromHalMetadata AF
6893 IF_META_AVAILABLE(int32_t, DevCamDebug_af_lens_position,
6894 CAM_INTF_META_DEV_CAM_AF_LENS_POSITION, metadata) {
6895 int32_t fwk_DevCamDebug_af_lens_position = *DevCamDebug_af_lens_position;
6896 camMetadata.update(DEVCAMDEBUG_AF_LENS_POSITION, &fwk_DevCamDebug_af_lens_position, 1);
6897 }
6898 IF_META_AVAILABLE(int32_t, DevCamDebug_af_tof_confidence,
Shuzhen Wang3569d4a2017-09-04 19:10:28 -07006899 CAM_INTF_META_AF_TOF_CONFIDENCE, metadata) {
Samuel Ha68ba5172016-12-15 18:41:12 -08006900 int32_t fwk_DevCamDebug_af_tof_confidence = *DevCamDebug_af_tof_confidence;
6901 camMetadata.update(DEVCAMDEBUG_AF_TOF_CONFIDENCE, &fwk_DevCamDebug_af_tof_confidence, 1);
6902 }
6903 IF_META_AVAILABLE(int32_t, DevCamDebug_af_tof_distance,
Shuzhen Wang3569d4a2017-09-04 19:10:28 -07006904 CAM_INTF_META_AF_TOF_DISTANCE, metadata) {
Samuel Ha68ba5172016-12-15 18:41:12 -08006905 int32_t fwk_DevCamDebug_af_tof_distance = *DevCamDebug_af_tof_distance;
6906 camMetadata.update(DEVCAMDEBUG_AF_TOF_DISTANCE, &fwk_DevCamDebug_af_tof_distance, 1);
6907 }
6908 IF_META_AVAILABLE(int32_t, DevCamDebug_af_luma,
6909 CAM_INTF_META_DEV_CAM_AF_LUMA, metadata) {
6910 int32_t fwk_DevCamDebug_af_luma = *DevCamDebug_af_luma;
6911 camMetadata.update(DEVCAMDEBUG_AF_LUMA, &fwk_DevCamDebug_af_luma, 1);
6912 }
6913 IF_META_AVAILABLE(int32_t, DevCamDebug_af_haf_state,
6914 CAM_INTF_META_DEV_CAM_AF_HAF_STATE, metadata) {
6915 int32_t fwk_DevCamDebug_af_haf_state = *DevCamDebug_af_haf_state;
6916 camMetadata.update(DEVCAMDEBUG_AF_HAF_STATE, &fwk_DevCamDebug_af_haf_state, 1);
6917 }
6918 IF_META_AVAILABLE(int32_t, DevCamDebug_af_monitor_pdaf_target_pos,
6919 CAM_INTF_META_DEV_CAM_AF_MONITOR_PDAF_TARGET_POS, metadata) {
6920 int32_t fwk_DevCamDebug_af_monitor_pdaf_target_pos =
6921 *DevCamDebug_af_monitor_pdaf_target_pos;
6922 camMetadata.update(DEVCAMDEBUG_AF_MONITOR_PDAF_TARGET_POS,
6923 &fwk_DevCamDebug_af_monitor_pdaf_target_pos, 1);
6924 }
6925 IF_META_AVAILABLE(int32_t, DevCamDebug_af_monitor_pdaf_confidence,
6926 CAM_INTF_META_DEV_CAM_AF_MONITOR_PDAF_CONFIDENCE, metadata) {
6927 int32_t fwk_DevCamDebug_af_monitor_pdaf_confidence =
6928 *DevCamDebug_af_monitor_pdaf_confidence;
6929 camMetadata.update(DEVCAMDEBUG_AF_MONITOR_PDAF_CONFIDENCE,
6930 &fwk_DevCamDebug_af_monitor_pdaf_confidence, 1);
6931 }
6932 IF_META_AVAILABLE(int32_t, DevCamDebug_af_monitor_pdaf_refocus,
6933 CAM_INTF_META_DEV_CAM_AF_MONITOR_PDAF_REFOCUS, metadata) {
6934 int32_t fwk_DevCamDebug_af_monitor_pdaf_refocus = *DevCamDebug_af_monitor_pdaf_refocus;
6935 camMetadata.update(DEVCAMDEBUG_AF_MONITOR_PDAF_REFOCUS,
6936 &fwk_DevCamDebug_af_monitor_pdaf_refocus, 1);
6937 }
6938 IF_META_AVAILABLE(int32_t, DevCamDebug_af_monitor_tof_target_pos,
6939 CAM_INTF_META_DEV_CAM_AF_MONITOR_TOF_TARGET_POS, metadata) {
6940 int32_t fwk_DevCamDebug_af_monitor_tof_target_pos =
6941 *DevCamDebug_af_monitor_tof_target_pos;
6942 camMetadata.update(DEVCAMDEBUG_AF_MONITOR_TOF_TARGET_POS,
6943 &fwk_DevCamDebug_af_monitor_tof_target_pos, 1);
6944 }
6945 IF_META_AVAILABLE(int32_t, DevCamDebug_af_monitor_tof_confidence,
6946 CAM_INTF_META_DEV_CAM_AF_MONITOR_TOF_CONFIDENCE, metadata) {
6947 int32_t fwk_DevCamDebug_af_monitor_tof_confidence =
6948 *DevCamDebug_af_monitor_tof_confidence;
6949 camMetadata.update(DEVCAMDEBUG_AF_MONITOR_TOF_CONFIDENCE,
6950 &fwk_DevCamDebug_af_monitor_tof_confidence, 1);
6951 }
6952 IF_META_AVAILABLE(int32_t, DevCamDebug_af_monitor_tof_refocus,
6953 CAM_INTF_META_DEV_CAM_AF_MONITOR_TOF_REFOCUS, metadata) {
6954 int32_t fwk_DevCamDebug_af_monitor_tof_refocus = *DevCamDebug_af_monitor_tof_refocus;
6955 camMetadata.update(DEVCAMDEBUG_AF_MONITOR_TOF_REFOCUS,
6956 &fwk_DevCamDebug_af_monitor_tof_refocus, 1);
6957 }
6958 IF_META_AVAILABLE(int32_t, DevCamDebug_af_monitor_type_select,
6959 CAM_INTF_META_DEV_CAM_AF_MONITOR_TYPE_SELECT, metadata) {
6960 int32_t fwk_DevCamDebug_af_monitor_type_select = *DevCamDebug_af_monitor_type_select;
6961 camMetadata.update(DEVCAMDEBUG_AF_MONITOR_TYPE_SELECT,
6962 &fwk_DevCamDebug_af_monitor_type_select, 1);
6963 }
6964 IF_META_AVAILABLE(int32_t, DevCamDebug_af_monitor_refocus,
6965 CAM_INTF_META_DEV_CAM_AF_MONITOR_REFOCUS, metadata) {
6966 int32_t fwk_DevCamDebug_af_monitor_refocus = *DevCamDebug_af_monitor_refocus;
6967 camMetadata.update(DEVCAMDEBUG_AF_MONITOR_REFOCUS,
6968 &fwk_DevCamDebug_af_monitor_refocus, 1);
6969 }
6970 IF_META_AVAILABLE(int32_t, DevCamDebug_af_monitor_target_pos,
6971 CAM_INTF_META_DEV_CAM_AF_MONITOR_TARGET_POS, metadata) {
6972 int32_t fwk_DevCamDebug_af_monitor_target_pos = *DevCamDebug_af_monitor_target_pos;
6973 camMetadata.update(DEVCAMDEBUG_AF_MONITOR_TARGET_POS,
6974 &fwk_DevCamDebug_af_monitor_target_pos, 1);
6975 }
6976 IF_META_AVAILABLE(int32_t, DevCamDebug_af_search_pdaf_target_pos,
6977 CAM_INTF_META_DEV_CAM_AF_SEARCH_PDAF_TARGET_POS, metadata) {
6978 int32_t fwk_DevCamDebug_af_search_pdaf_target_pos =
6979 *DevCamDebug_af_search_pdaf_target_pos;
6980 camMetadata.update(DEVCAMDEBUG_AF_SEARCH_PDAF_TARGET_POS,
6981 &fwk_DevCamDebug_af_search_pdaf_target_pos, 1);
6982 }
6983 IF_META_AVAILABLE(int32_t, DevCamDebug_af_search_pdaf_next_pos,
6984 CAM_INTF_META_DEV_CAM_AF_SEARCH_PDAF_NEXT_POS, metadata) {
6985 int32_t fwk_DevCamDebug_af_search_pdaf_next_pos = *DevCamDebug_af_search_pdaf_next_pos;
6986 camMetadata.update(DEVCAMDEBUG_AF_SEARCH_PDAF_NEXT_POS,
6987 &fwk_DevCamDebug_af_search_pdaf_next_pos, 1);
6988 }
6989 IF_META_AVAILABLE(int32_t, DevCamDebug_af_search_pdaf_near_pos,
6990 CAM_INTF_META_DEV_CAM_AF_SEARCH_PDAF_NEAR_POS, metadata) {
6991 int32_t fwk_DevCamDebug_af_search_pdaf_near_pos = *DevCamDebug_af_search_pdaf_near_pos;
6992 camMetadata.update(DEVCAMDEBUG_AF_SEARCH_PDAF_NEAR_POS,
6993 &fwk_DevCamDebug_af_search_pdaf_near_pos, 1);
6994 }
6995 IF_META_AVAILABLE(int32_t, DevCamDebug_af_search_pdaf_far_pos,
6996 CAM_INTF_META_DEV_CAM_AF_SEARCH_PDAF_FAR_POS, metadata) {
6997 int32_t fwk_DevCamDebug_af_search_pdaf_far_pos = *DevCamDebug_af_search_pdaf_far_pos;
6998 camMetadata.update(DEVCAMDEBUG_AF_SEARCH_PDAF_FAR_POS,
6999 &fwk_DevCamDebug_af_search_pdaf_far_pos, 1);
7000 }
7001 IF_META_AVAILABLE(int32_t, DevCamDebug_af_search_pdaf_confidence,
7002 CAM_INTF_META_DEV_CAM_AF_SEARCH_PDAF_CONFIDENCE, metadata) {
7003 int32_t fwk_DevCamDebug_af_search_pdaf_confidence = *DevCamDebug_af_search_pdaf_confidence;
7004 camMetadata.update(DEVCAMDEBUG_AF_SEARCH_PDAF_CONFIDENCE,
7005 &fwk_DevCamDebug_af_search_pdaf_confidence, 1);
7006 }
7007 IF_META_AVAILABLE(int32_t, DevCamDebug_af_search_tof_target_pos,
7008 CAM_INTF_META_DEV_CAM_AF_SEARCH_TOF_TARGET_POS, metadata) {
7009 int32_t fwk_DevCamDebug_af_search_tof_target_pos =
7010 *DevCamDebug_af_search_tof_target_pos;
7011 camMetadata.update(DEVCAMDEBUG_AF_SEARCH_TOF_TARGET_POS,
7012 &fwk_DevCamDebug_af_search_tof_target_pos, 1);
7013 }
7014 IF_META_AVAILABLE(int32_t, DevCamDebug_af_search_tof_next_pos,
7015 CAM_INTF_META_DEV_CAM_AF_SEARCH_TOF_NEXT_POS, metadata) {
7016 int32_t fwk_DevCamDebug_af_search_tof_next_pos = *DevCamDebug_af_search_tof_next_pos;
7017 camMetadata.update(DEVCAMDEBUG_AF_SEARCH_TOF_NEXT_POS,
7018 &fwk_DevCamDebug_af_search_tof_next_pos, 1);
7019 }
7020 IF_META_AVAILABLE(int32_t, DevCamDebug_af_search_tof_near_pos,
7021 CAM_INTF_META_DEV_CAM_AF_SEARCH_TOF_NEAR_POS, metadata) {
7022 int32_t fwk_DevCamDebug_af_search_tof_near_pos = *DevCamDebug_af_search_tof_near_pos;
7023 camMetadata.update(DEVCAMDEBUG_AF_SEARCH_TOF_NEAR_POS,
7024 &fwk_DevCamDebug_af_search_tof_near_pos, 1);
7025 }
7026 IF_META_AVAILABLE(int32_t, DevCamDebug_af_search_tof_far_pos,
7027 CAM_INTF_META_DEV_CAM_AF_SEARCH_TOF_FAR_POS, metadata) {
7028 int32_t fwk_DevCamDebug_af_search_tof_far_pos = *DevCamDebug_af_search_tof_far_pos;
7029 camMetadata.update(DEVCAMDEBUG_AF_SEARCH_TOF_FAR_POS,
7030 &fwk_DevCamDebug_af_search_tof_far_pos, 1);
7031 }
7032 IF_META_AVAILABLE(int32_t, DevCamDebug_af_search_tof_confidence,
7033 CAM_INTF_META_DEV_CAM_AF_SEARCH_TOF_CONFIDENCE, metadata) {
7034 int32_t fwk_DevCamDebug_af_search_tof_confidence = *DevCamDebug_af_search_tof_confidence;
7035 camMetadata.update(DEVCAMDEBUG_AF_SEARCH_TOF_CONFIDENCE,
7036 &fwk_DevCamDebug_af_search_tof_confidence, 1);
7037 }
7038 IF_META_AVAILABLE(int32_t, DevCamDebug_af_search_type_select,
7039 CAM_INTF_META_DEV_CAM_AF_SEARCH_TYPE_SELECT, metadata) {
7040 int32_t fwk_DevCamDebug_af_search_type_select = *DevCamDebug_af_search_type_select;
7041 camMetadata.update(DEVCAMDEBUG_AF_SEARCH_TYPE_SELECT,
7042 &fwk_DevCamDebug_af_search_type_select, 1);
7043 }
7044 IF_META_AVAILABLE(int32_t, DevCamDebug_af_search_next_pos,
7045 CAM_INTF_META_DEV_CAM_AF_SEARCH_NEXT_POS, metadata) {
7046 int32_t fwk_DevCamDebug_af_search_next_pos = *DevCamDebug_af_search_next_pos;
7047 camMetadata.update(DEVCAMDEBUG_AF_SEARCH_NEXT_POS,
7048 &fwk_DevCamDebug_af_search_next_pos, 1);
7049 }
7050 IF_META_AVAILABLE(int32_t, DevCamDebug_af_search_target_pos,
7051 CAM_INTF_META_DEV_CAM_AF_SEARCH_TARGET_POS, metadata) {
7052 int32_t fwk_DevCamDebug_af_search_target_pos = *DevCamDebug_af_search_target_pos;
7053 camMetadata.update(DEVCAMDEBUG_AF_SEARCH_TARGET_POS,
7054 &fwk_DevCamDebug_af_search_target_pos, 1);
7055 }
7056 // DevCamDebug metadata translateFromHalMetadata AEC
7057 IF_META_AVAILABLE(int32_t, DevCamDebug_aec_target_luma,
7058 CAM_INTF_META_DEV_CAM_AEC_TARGET_LUMA, metadata) {
7059 int32_t fwk_DevCamDebug_aec_target_luma = *DevCamDebug_aec_target_luma;
7060 camMetadata.update(DEVCAMDEBUG_AEC_TARGET_LUMA, &fwk_DevCamDebug_aec_target_luma, 1);
7061 }
7062 IF_META_AVAILABLE(int32_t, DevCamDebug_aec_comp_luma,
7063 CAM_INTF_META_DEV_CAM_AEC_COMP_LUMA, metadata) {
7064 int32_t fwk_DevCamDebug_aec_comp_luma = *DevCamDebug_aec_comp_luma;
7065 camMetadata.update(DEVCAMDEBUG_AEC_COMP_LUMA, &fwk_DevCamDebug_aec_comp_luma, 1);
7066 }
7067 IF_META_AVAILABLE(int32_t, DevCamDebug_aec_avg_luma,
7068 CAM_INTF_META_DEV_CAM_AEC_AVG_LUMA, metadata) {
7069 int32_t fwk_DevCamDebug_aec_avg_luma = *DevCamDebug_aec_avg_luma;
7070 camMetadata.update(DEVCAMDEBUG_AEC_AVG_LUMA, &fwk_DevCamDebug_aec_avg_luma, 1);
7071 }
7072 IF_META_AVAILABLE(int32_t, DevCamDebug_aec_cur_luma,
7073 CAM_INTF_META_DEV_CAM_AEC_CUR_LUMA, metadata) {
7074 int32_t fwk_DevCamDebug_aec_cur_luma = *DevCamDebug_aec_cur_luma;
7075 camMetadata.update(DEVCAMDEBUG_AEC_CUR_LUMA, &fwk_DevCamDebug_aec_cur_luma, 1);
7076 }
7077 IF_META_AVAILABLE(int32_t, DevCamDebug_aec_linecount,
7078 CAM_INTF_META_DEV_CAM_AEC_LINECOUNT, metadata) {
7079 int32_t fwk_DevCamDebug_aec_linecount = *DevCamDebug_aec_linecount;
7080 camMetadata.update(DEVCAMDEBUG_AEC_LINECOUNT, &fwk_DevCamDebug_aec_linecount, 1);
7081 }
7082 IF_META_AVAILABLE(float, DevCamDebug_aec_real_gain,
7083 CAM_INTF_META_DEV_CAM_AEC_REAL_GAIN, metadata) {
7084 float fwk_DevCamDebug_aec_real_gain = *DevCamDebug_aec_real_gain;
7085 camMetadata.update(DEVCAMDEBUG_AEC_REAL_GAIN, &fwk_DevCamDebug_aec_real_gain, 1);
7086 }
7087 IF_META_AVAILABLE(int32_t, DevCamDebug_aec_exp_index,
7088 CAM_INTF_META_DEV_CAM_AEC_EXP_INDEX, metadata) {
7089 int32_t fwk_DevCamDebug_aec_exp_index = *DevCamDebug_aec_exp_index;
7090 camMetadata.update(DEVCAMDEBUG_AEC_EXP_INDEX, &fwk_DevCamDebug_aec_exp_index, 1);
7091 }
7092 IF_META_AVAILABLE(float, DevCamDebug_aec_lux_idx,
7093 CAM_INTF_META_DEV_CAM_AEC_LUX_IDX, metadata) {
7094 float fwk_DevCamDebug_aec_lux_idx = *DevCamDebug_aec_lux_idx;
7095 camMetadata.update(DEVCAMDEBUG_AEC_LUX_IDX, &fwk_DevCamDebug_aec_lux_idx, 1);
7096 }
Samuel Ha34229982017-02-17 13:51:11 -08007097 // DevCamDebug metadata translateFromHalMetadata zzHDR
7098 IF_META_AVAILABLE(float, DevCamDebug_aec_l_real_gain,
7099 CAM_INTF_META_DEV_CAM_AEC_L_REAL_GAIN, metadata) {
7100 float fwk_DevCamDebug_aec_l_real_gain = *DevCamDebug_aec_l_real_gain;
7101 camMetadata.update(DEVCAMDEBUG_AEC_L_REAL_GAIN, &fwk_DevCamDebug_aec_l_real_gain, 1);
7102 }
7103 IF_META_AVAILABLE(int32_t, DevCamDebug_aec_l_linecount,
7104 CAM_INTF_META_DEV_CAM_AEC_L_LINECOUNT, metadata) {
Samuel Hae80fbd52017-03-29 16:14:46 -07007105 int32_t fwk_DevCamDebug_aec_l_linecount = *DevCamDebug_aec_l_linecount;
Samuel Ha34229982017-02-17 13:51:11 -08007106 camMetadata.update(DEVCAMDEBUG_AEC_L_LINECOUNT, &fwk_DevCamDebug_aec_l_linecount, 1);
7107 }
7108 IF_META_AVAILABLE(float, DevCamDebug_aec_s_real_gain,
7109 CAM_INTF_META_DEV_CAM_AEC_S_REAL_GAIN, metadata) {
7110 float fwk_DevCamDebug_aec_s_real_gain = *DevCamDebug_aec_s_real_gain;
7111 camMetadata.update(DEVCAMDEBUG_AEC_S_REAL_GAIN, &fwk_DevCamDebug_aec_s_real_gain, 1);
7112 }
7113 IF_META_AVAILABLE(int32_t, DevCamDebug_aec_s_linecount,
7114 CAM_INTF_META_DEV_CAM_AEC_S_LINECOUNT, metadata) {
Samuel Hae80fbd52017-03-29 16:14:46 -07007115 int32_t fwk_DevCamDebug_aec_s_linecount = *DevCamDebug_aec_s_linecount;
Samuel Ha34229982017-02-17 13:51:11 -08007116 camMetadata.update(DEVCAMDEBUG_AEC_S_LINECOUNT, &fwk_DevCamDebug_aec_s_linecount, 1);
7117 }
7118 IF_META_AVAILABLE(float, DevCamDebug_aec_hdr_sensitivity_ratio,
7119 CAM_INTF_META_DEV_CAM_AEC_HDR_SENSITIVITY_RATIO, metadata) {
7120 float fwk_DevCamDebug_aec_hdr_sensitivity_ratio =
7121 *DevCamDebug_aec_hdr_sensitivity_ratio;
7122 camMetadata.update(DEVCAMDEBUG_AEC_HDR_SENSITIVITY_RATIO,
7123 &fwk_DevCamDebug_aec_hdr_sensitivity_ratio, 1);
7124 }
7125 IF_META_AVAILABLE(float, DevCamDebug_aec_hdr_exp_time_ratio,
7126 CAM_INTF_META_DEV_CAM_AEC_HDR_EXP_TIME_RATIO, metadata) {
7127 float fwk_DevCamDebug_aec_hdr_exp_time_ratio = *DevCamDebug_aec_hdr_exp_time_ratio;
7128 camMetadata.update(DEVCAMDEBUG_AEC_HDR_EXP_TIME_RATIO,
7129 &fwk_DevCamDebug_aec_hdr_exp_time_ratio, 1);
7130 }
7131 // DevCamDebug metadata translateFromHalMetadata ADRC
7132 IF_META_AVAILABLE(float, DevCamDebug_aec_total_drc_gain,
7133 CAM_INTF_META_DEV_CAM_AEC_TOTAL_DRC_GAIN, metadata) {
7134 float fwk_DevCamDebug_aec_total_drc_gain = *DevCamDebug_aec_total_drc_gain;
7135 camMetadata.update(DEVCAMDEBUG_AEC_TOTAL_DRC_GAIN,
7136 &fwk_DevCamDebug_aec_total_drc_gain, 1);
7137 }
7138 IF_META_AVAILABLE(float, DevCamDebug_aec_color_drc_gain,
7139 CAM_INTF_META_DEV_CAM_AEC_COLOR_DRC_GAIN, metadata) {
7140 float fwk_DevCamDebug_aec_color_drc_gain = *DevCamDebug_aec_color_drc_gain;
7141 camMetadata.update(DEVCAMDEBUG_AEC_COLOR_DRC_GAIN,
7142 &fwk_DevCamDebug_aec_color_drc_gain, 1);
7143 }
7144 IF_META_AVAILABLE(float, DevCamDebug_aec_gtm_ratio,
7145 CAM_INTF_META_DEV_CAM_AEC_GTM_RATIO, metadata) {
7146 float fwk_DevCamDebug_aec_gtm_ratio = *DevCamDebug_aec_gtm_ratio;
7147 camMetadata.update(DEVCAMDEBUG_AEC_GTM_RATIO, &fwk_DevCamDebug_aec_gtm_ratio, 1);
7148 }
7149 IF_META_AVAILABLE(float, DevCamDebug_aec_ltm_ratio,
7150 CAM_INTF_META_DEV_CAM_AEC_LTM_RATIO, metadata) {
7151 float fwk_DevCamDebug_aec_ltm_ratio = *DevCamDebug_aec_ltm_ratio;
7152 camMetadata.update(DEVCAMDEBUG_AEC_LTM_RATIO, &fwk_DevCamDebug_aec_ltm_ratio, 1);
7153 }
7154 IF_META_AVAILABLE(float, DevCamDebug_aec_la_ratio,
7155 CAM_INTF_META_DEV_CAM_AEC_LA_RATIO, metadata) {
7156 float fwk_DevCamDebug_aec_la_ratio = *DevCamDebug_aec_la_ratio;
7157 camMetadata.update(DEVCAMDEBUG_AEC_LA_RATIO, &fwk_DevCamDebug_aec_la_ratio, 1);
7158 }
7159 IF_META_AVAILABLE(float, DevCamDebug_aec_gamma_ratio,
7160 CAM_INTF_META_DEV_CAM_AEC_GAMMA_RATIO, metadata) {
7161 float fwk_DevCamDebug_aec_gamma_ratio = *DevCamDebug_aec_gamma_ratio;
7162 camMetadata.update(DEVCAMDEBUG_AEC_GAMMA_RATIO, &fwk_DevCamDebug_aec_gamma_ratio, 1);
7163 }
Samuel Habdf4fac2017-07-28 17:21:18 -07007164 // DevCamDebug metadata translateFromHalMetadata AEC MOTION
7165 IF_META_AVAILABLE(float, DevCamDebug_aec_camera_motion_dx,
7166 CAM_INTF_META_DEV_CAM_AEC_CAMERA_MOTION_DX, metadata) {
7167 float fwk_DevCamDebug_aec_camera_motion_dx = *DevCamDebug_aec_camera_motion_dx;
7168 camMetadata.update(DEVCAMDEBUG_AEC_CAMERA_MOTION_DX,
7169 &fwk_DevCamDebug_aec_camera_motion_dx, 1);
7170 }
7171 IF_META_AVAILABLE(float, DevCamDebug_aec_camera_motion_dy,
7172 CAM_INTF_META_DEV_CAM_AEC_CAMERA_MOTION_DY, metadata) {
7173 float fwk_DevCamDebug_aec_camera_motion_dy = *DevCamDebug_aec_camera_motion_dy;
7174 camMetadata.update(DEVCAMDEBUG_AEC_CAMERA_MOTION_DY,
7175 &fwk_DevCamDebug_aec_camera_motion_dy, 1);
7176 }
7177 IF_META_AVAILABLE(float, DevCamDebug_aec_subject_motion,
7178 CAM_INTF_META_DEV_CAM_AEC_SUBJECT_MOTION, metadata) {
7179 float fwk_DevCamDebug_aec_subject_motion = *DevCamDebug_aec_subject_motion;
7180 camMetadata.update(DEVCAMDEBUG_AEC_SUBJECT_MOTION,
7181 &fwk_DevCamDebug_aec_subject_motion, 1);
7182 }
Samuel Ha68ba5172016-12-15 18:41:12 -08007183 // DevCamDebug metadata translateFromHalMetadata AWB
7184 IF_META_AVAILABLE(float, DevCamDebug_awb_r_gain,
7185 CAM_INTF_META_DEV_CAM_AWB_R_GAIN, metadata) {
7186 float fwk_DevCamDebug_awb_r_gain = *DevCamDebug_awb_r_gain;
7187 camMetadata.update(DEVCAMDEBUG_AWB_R_GAIN, &fwk_DevCamDebug_awb_r_gain, 1);
7188 }
7189 IF_META_AVAILABLE(float, DevCamDebug_awb_g_gain,
7190 CAM_INTF_META_DEV_CAM_AWB_G_GAIN, metadata) {
7191 float fwk_DevCamDebug_awb_g_gain = *DevCamDebug_awb_g_gain;
7192 camMetadata.update(DEVCAMDEBUG_AWB_G_GAIN, &fwk_DevCamDebug_awb_g_gain, 1);
7193 }
7194 IF_META_AVAILABLE(float, DevCamDebug_awb_b_gain,
7195 CAM_INTF_META_DEV_CAM_AWB_B_GAIN, metadata) {
7196 float fwk_DevCamDebug_awb_b_gain = *DevCamDebug_awb_b_gain;
7197 camMetadata.update(DEVCAMDEBUG_AWB_B_GAIN, &fwk_DevCamDebug_awb_b_gain, 1);
7198 }
7199 IF_META_AVAILABLE(int32_t, DevCamDebug_awb_cct,
7200 CAM_INTF_META_DEV_CAM_AWB_CCT, metadata) {
7201 int32_t fwk_DevCamDebug_awb_cct = *DevCamDebug_awb_cct;
7202 camMetadata.update(DEVCAMDEBUG_AWB_CCT, &fwk_DevCamDebug_awb_cct, 1);
7203 }
7204 IF_META_AVAILABLE(int32_t, DevCamDebug_awb_decision,
7205 CAM_INTF_META_DEV_CAM_AWB_DECISION, metadata) {
7206 int32_t fwk_DevCamDebug_awb_decision = *DevCamDebug_awb_decision;
7207 camMetadata.update(DEVCAMDEBUG_AWB_DECISION, &fwk_DevCamDebug_awb_decision, 1);
7208 }
7209 }
7210 // atrace_end(ATRACE_TAG_ALWAYS);
7211
Thierry Strudel3d639192016-09-09 11:52:26 -07007212 IF_META_AVAILABLE(uint32_t, frame_number, CAM_INTF_META_FRAME_NUMBER, metadata) {
7213 int64_t fwk_frame_number = *frame_number;
7214 camMetadata.update(ANDROID_SYNC_FRAME_NUMBER, &fwk_frame_number, 1);
7215 }
7216
7217 IF_META_AVAILABLE(cam_fps_range_t, float_range, CAM_INTF_PARM_FPS_RANGE, metadata) {
7218 int32_t fps_range[2];
7219 fps_range[0] = (int32_t)float_range->min_fps;
7220 fps_range[1] = (int32_t)float_range->max_fps;
7221 camMetadata.update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
7222 fps_range, 2);
7223 LOGD("urgent Metadata : ANDROID_CONTROL_AE_TARGET_FPS_RANGE [%d, %d]",
7224 fps_range[0], fps_range[1]);
7225 }
7226
7227 IF_META_AVAILABLE(int32_t, expCompensation, CAM_INTF_PARM_EXPOSURE_COMPENSATION, metadata) {
7228 camMetadata.update(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, expCompensation, 1);
7229 }
7230
7231 IF_META_AVAILABLE(uint32_t, sceneMode, CAM_INTF_PARM_BESTSHOT_MODE, metadata) {
7232 int val = (uint8_t)lookupFwkName(SCENE_MODES_MAP,
7233 METADATA_MAP_SIZE(SCENE_MODES_MAP),
7234 *sceneMode);
7235 if (NAME_NOT_FOUND != val) {
7236 uint8_t fwkSceneMode = (uint8_t)val;
7237 camMetadata.update(ANDROID_CONTROL_SCENE_MODE, &fwkSceneMode, 1);
7238 LOGD("urgent Metadata : ANDROID_CONTROL_SCENE_MODE: %d",
7239 fwkSceneMode);
7240 }
7241 }
7242
7243 IF_META_AVAILABLE(uint32_t, ae_lock, CAM_INTF_PARM_AEC_LOCK, metadata) {
7244 uint8_t fwk_ae_lock = (uint8_t) *ae_lock;
7245 camMetadata.update(ANDROID_CONTROL_AE_LOCK, &fwk_ae_lock, 1);
7246 }
7247
7248 IF_META_AVAILABLE(uint32_t, awb_lock, CAM_INTF_PARM_AWB_LOCK, metadata) {
7249 uint8_t fwk_awb_lock = (uint8_t) *awb_lock;
7250 camMetadata.update(ANDROID_CONTROL_AWB_LOCK, &fwk_awb_lock, 1);
7251 }
7252
7253 IF_META_AVAILABLE(uint32_t, color_correct_mode, CAM_INTF_META_COLOR_CORRECT_MODE, metadata) {
7254 uint8_t fwk_color_correct_mode = (uint8_t) *color_correct_mode;
7255 camMetadata.update(ANDROID_COLOR_CORRECTION_MODE, &fwk_color_correct_mode, 1);
7256 }
7257
7258 IF_META_AVAILABLE(cam_edge_application_t, edgeApplication,
7259 CAM_INTF_META_EDGE_MODE, metadata) {
7260 camMetadata.update(ANDROID_EDGE_MODE, &(edgeApplication->edge_mode), 1);
7261 }
7262
7263 IF_META_AVAILABLE(uint32_t, flashPower, CAM_INTF_META_FLASH_POWER, metadata) {
7264 uint8_t fwk_flashPower = (uint8_t) *flashPower;
7265 camMetadata.update(ANDROID_FLASH_FIRING_POWER, &fwk_flashPower, 1);
7266 }
7267
7268 IF_META_AVAILABLE(int64_t, flashFiringTime, CAM_INTF_META_FLASH_FIRING_TIME, metadata) {
7269 camMetadata.update(ANDROID_FLASH_FIRING_TIME, flashFiringTime, 1);
7270 }
7271
7272 IF_META_AVAILABLE(int32_t, flashState, CAM_INTF_META_FLASH_STATE, metadata) {
7273 if (0 <= *flashState) {
7274 uint8_t fwk_flashState = (uint8_t) *flashState;
7275 if (!gCamCapability[mCameraId]->flash_available) {
7276 fwk_flashState = ANDROID_FLASH_STATE_UNAVAILABLE;
7277 }
7278 camMetadata.update(ANDROID_FLASH_STATE, &fwk_flashState, 1);
7279 }
7280 }
7281
7282 IF_META_AVAILABLE(uint32_t, flashMode, CAM_INTF_META_FLASH_MODE, metadata) {
7283 int val = lookupFwkName(FLASH_MODES_MAP, METADATA_MAP_SIZE(FLASH_MODES_MAP), *flashMode);
7284 if (NAME_NOT_FOUND != val) {
7285 uint8_t fwk_flashMode = (uint8_t)val;
7286 camMetadata.update(ANDROID_FLASH_MODE, &fwk_flashMode, 1);
7287 }
7288 }
7289
7290 IF_META_AVAILABLE(uint32_t, hotPixelMode, CAM_INTF_META_HOTPIXEL_MODE, metadata) {
7291 uint8_t fwk_hotPixelMode = (uint8_t) *hotPixelMode;
7292 camMetadata.update(ANDROID_HOT_PIXEL_MODE, &fwk_hotPixelMode, 1);
7293 }
7294
7295 IF_META_AVAILABLE(float, lensAperture, CAM_INTF_META_LENS_APERTURE, metadata) {
7296 camMetadata.update(ANDROID_LENS_APERTURE , lensAperture, 1);
7297 }
7298
7299 IF_META_AVAILABLE(float, filterDensity, CAM_INTF_META_LENS_FILTERDENSITY, metadata) {
7300 camMetadata.update(ANDROID_LENS_FILTER_DENSITY , filterDensity, 1);
7301 }
7302
7303 IF_META_AVAILABLE(float, focalLength, CAM_INTF_META_LENS_FOCAL_LENGTH, metadata) {
7304 camMetadata.update(ANDROID_LENS_FOCAL_LENGTH, focalLength, 1);
7305 }
7306
7307 IF_META_AVAILABLE(uint32_t, opticalStab, CAM_INTF_META_LENS_OPT_STAB_MODE, metadata) {
7308 uint8_t fwk_opticalStab = (uint8_t) *opticalStab;
7309 camMetadata.update(ANDROID_LENS_OPTICAL_STABILIZATION_MODE, &fwk_opticalStab, 1);
7310 }
7311
7312 IF_META_AVAILABLE(uint32_t, videoStab, CAM_INTF_META_VIDEO_STAB_MODE, metadata) {
7313 uint8_t fwk_videoStab = (uint8_t) *videoStab;
7314 LOGD("fwk_videoStab = %d", fwk_videoStab);
7315 camMetadata.update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &fwk_videoStab, 1);
7316 } else {
7317 // Regardless of Video stab supports or not, CTS is expecting the EIS result to be non NULL
7318 // and so hardcoding the Video Stab result to OFF mode.
7319 uint8_t fwkVideoStabMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
7320 camMetadata.update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &fwkVideoStabMode, 1);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007321 LOGD("EIS result default to OFF mode");
Thierry Strudel3d639192016-09-09 11:52:26 -07007322 }
7323
7324 IF_META_AVAILABLE(uint32_t, noiseRedMode, CAM_INTF_META_NOISE_REDUCTION_MODE, metadata) {
7325 uint8_t fwk_noiseRedMode = (uint8_t) *noiseRedMode;
7326 camMetadata.update(ANDROID_NOISE_REDUCTION_MODE, &fwk_noiseRedMode, 1);
7327 }
7328
7329 IF_META_AVAILABLE(float, effectiveExposureFactor, CAM_INTF_META_EFFECTIVE_EXPOSURE_FACTOR, metadata) {
7330 camMetadata.update(ANDROID_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR, effectiveExposureFactor, 1);
7331 }
7332
Thierry Strudel3d639192016-09-09 11:52:26 -07007333 IF_META_AVAILABLE(cam_black_level_metadata_t, blackLevelAppliedPattern,
7334 CAM_INTF_META_BLACK_LEVEL_APPLIED_PATTERN, metadata) {
Shuzhen Wanga5da1022016-07-13 20:18:42 -07007335 float fwk_blackLevelInd[BLACK_LEVEL_PATTERN_CNT];
Thierry Strudel3d639192016-09-09 11:52:26 -07007336
Shuzhen Wanga5da1022016-07-13 20:18:42 -07007337 adjustBlackLevelForCFA(blackLevelAppliedPattern->cam_black_level, fwk_blackLevelInd,
7338 gCamCapability[mCameraId]->color_arrangement);
Thierry Strudel3d639192016-09-09 11:52:26 -07007339
Shuzhen Wanga5da1022016-07-13 20:18:42 -07007340 LOGD("applied dynamicblackLevel in RGGB order = %f %f %f %f",
Thierry Strudel3d639192016-09-09 11:52:26 -07007341 blackLevelAppliedPattern->cam_black_level[0],
7342 blackLevelAppliedPattern->cam_black_level[1],
7343 blackLevelAppliedPattern->cam_black_level[2],
7344 blackLevelAppliedPattern->cam_black_level[3]);
Shuzhen Wanga5da1022016-07-13 20:18:42 -07007345 camMetadata.update(QCAMERA3_SENSOR_DYNAMIC_BLACK_LEVEL_PATTERN, fwk_blackLevelInd,
7346 BLACK_LEVEL_PATTERN_CNT);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007347
7348#ifndef USE_HAL_3_3
7349 // Update the ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL
Jason Lee4f3d96e2017-02-28 19:24:14 +05307350 // Need convert the internal 14 bit depth to sensor 10 bit sensor raw
Zhijun Heb753c672016-06-15 14:50:48 -07007351 // depth space.
Jason Lee4f3d96e2017-02-28 19:24:14 +05307352 fwk_blackLevelInd[0] /= 16.0;
7353 fwk_blackLevelInd[1] /= 16.0;
7354 fwk_blackLevelInd[2] /= 16.0;
7355 fwk_blackLevelInd[3] /= 16.0;
Shuzhen Wanga5da1022016-07-13 20:18:42 -07007356 camMetadata.update(ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL, fwk_blackLevelInd,
7357 BLACK_LEVEL_PATTERN_CNT);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007358#endif
Thierry Strudel3d639192016-09-09 11:52:26 -07007359 }
7360
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007361#ifndef USE_HAL_3_3
7362 // Fixed whitelevel is used by ISP/Sensor
7363 camMetadata.update(ANDROID_SENSOR_DYNAMIC_WHITE_LEVEL,
7364 &gCamCapability[mCameraId]->white_level, 1);
7365#endif
Thierry Strudel3d639192016-09-09 11:52:26 -07007366
7367 IF_META_AVAILABLE(cam_crop_region_t, hScalerCropRegion,
7368 CAM_INTF_META_SCALER_CROP_REGION, metadata) {
7369 int32_t scalerCropRegion[4];
7370 scalerCropRegion[0] = hScalerCropRegion->left;
7371 scalerCropRegion[1] = hScalerCropRegion->top;
7372 scalerCropRegion[2] = hScalerCropRegion->width;
7373 scalerCropRegion[3] = hScalerCropRegion->height;
7374
7375 // Adjust crop region from sensor output coordinate system to active
7376 // array coordinate system.
7377 mCropRegionMapper.toActiveArray(scalerCropRegion[0], scalerCropRegion[1],
7378 scalerCropRegion[2], scalerCropRegion[3]);
7379
7380 camMetadata.update(ANDROID_SCALER_CROP_REGION, scalerCropRegion, 4);
7381 }
7382
7383 IF_META_AVAILABLE(int64_t, sensorExpTime, CAM_INTF_META_SENSOR_EXPOSURE_TIME, metadata) {
7384 LOGD("sensorExpTime = %lld", *sensorExpTime);
7385 camMetadata.update(ANDROID_SENSOR_EXPOSURE_TIME , sensorExpTime, 1);
7386 }
7387
Shuzhen Wang6a1dd612017-08-05 15:03:53 -07007388 IF_META_AVAILABLE(float, expTimeBoost, CAM_INTF_META_EXP_TIME_BOOST, metadata) {
7389 LOGD("expTimeBoost = %f", *expTimeBoost);
7390 camMetadata.update(NEXUS_EXPERIMENTAL_2017_EXP_TIME_BOOST, expTimeBoost, 1);
7391 }
7392
Thierry Strudel3d639192016-09-09 11:52:26 -07007393 IF_META_AVAILABLE(int64_t, sensorFameDuration,
7394 CAM_INTF_META_SENSOR_FRAME_DURATION, metadata) {
7395 LOGD("sensorFameDuration = %lld", *sensorFameDuration);
7396 camMetadata.update(ANDROID_SENSOR_FRAME_DURATION, sensorFameDuration, 1);
7397 }
7398
7399 IF_META_AVAILABLE(int64_t, sensorRollingShutterSkew,
7400 CAM_INTF_META_SENSOR_ROLLING_SHUTTER_SKEW, metadata) {
7401 LOGD("sensorRollingShutterSkew = %lld", *sensorRollingShutterSkew);
7402 camMetadata.update(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
7403 sensorRollingShutterSkew, 1);
7404 }
7405
7406 IF_META_AVAILABLE(int32_t, sensorSensitivity, CAM_INTF_META_SENSOR_SENSITIVITY, metadata) {
7407 LOGD("sensorSensitivity = %d", *sensorSensitivity);
7408 camMetadata.update(ANDROID_SENSOR_SENSITIVITY, sensorSensitivity, 1);
7409
7410 //calculate the noise profile based on sensitivity
7411 double noise_profile_S = computeNoiseModelEntryS(*sensorSensitivity);
7412 double noise_profile_O = computeNoiseModelEntryO(*sensorSensitivity);
7413 double noise_profile[2 * gCamCapability[mCameraId]->num_color_channels];
7414 for (int i = 0; i < 2 * gCamCapability[mCameraId]->num_color_channels; i += 2) {
7415 noise_profile[i] = noise_profile_S;
7416 noise_profile[i+1] = noise_profile_O;
7417 }
7418 LOGD("noise model entry (S, O) is (%f, %f)",
7419 noise_profile_S, noise_profile_O);
7420 camMetadata.update(ANDROID_SENSOR_NOISE_PROFILE, noise_profile,
7421 (size_t) (2 * gCamCapability[mCameraId]->num_color_channels));
7422 }
7423
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007424#ifndef USE_HAL_3_3
Shuzhen Wang6cf631c2016-06-03 15:06:16 -07007425 int32_t fwk_ispSensitivity = 100;
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007426 IF_META_AVAILABLE(int32_t, ispSensitivity, CAM_INTF_META_ISP_SENSITIVITY, metadata) {
Shuzhen Wang6cf631c2016-06-03 15:06:16 -07007427 fwk_ispSensitivity = (int32_t) *ispSensitivity;
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007428 }
Shuzhen Wang6cf631c2016-06-03 15:06:16 -07007429 IF_META_AVAILABLE(float, postStatsSensitivity, CAM_INTF_META_ISP_POST_STATS_SENSITIVITY, metadata) {
7430 fwk_ispSensitivity = (int32_t) (*postStatsSensitivity * fwk_ispSensitivity);
7431 }
7432 camMetadata.update(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST, &fwk_ispSensitivity, 1);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007433#endif
7434
Thierry Strudel3d639192016-09-09 11:52:26 -07007435 IF_META_AVAILABLE(uint32_t, shadingMode, CAM_INTF_META_SHADING_MODE, metadata) {
7436 uint8_t fwk_shadingMode = (uint8_t) *shadingMode;
7437 camMetadata.update(ANDROID_SHADING_MODE, &fwk_shadingMode, 1);
7438 }
7439
7440 IF_META_AVAILABLE(uint32_t, faceDetectMode, CAM_INTF_META_STATS_FACEDETECT_MODE, metadata) {
7441 int val = lookupFwkName(FACEDETECT_MODES_MAP, METADATA_MAP_SIZE(FACEDETECT_MODES_MAP),
7442 *faceDetectMode);
7443 if (NAME_NOT_FOUND != val) {
7444 uint8_t fwk_faceDetectMode = (uint8_t)val;
7445 camMetadata.update(ANDROID_STATISTICS_FACE_DETECT_MODE, &fwk_faceDetectMode, 1);
7446
7447 if (fwk_faceDetectMode != ANDROID_STATISTICS_FACE_DETECT_MODE_OFF) {
7448 IF_META_AVAILABLE(cam_face_detection_data_t, faceDetectionInfo,
7449 CAM_INTF_META_FACE_DETECTION, metadata) {
7450 uint8_t numFaces = MIN(
7451 faceDetectionInfo->num_faces_detected, MAX_ROI);
7452 int32_t faceIds[MAX_ROI];
7453 uint8_t faceScores[MAX_ROI];
7454 int32_t faceRectangles[MAX_ROI * 4];
7455 int32_t faceLandmarks[MAX_ROI * 6];
7456 size_t j = 0, k = 0;
7457
7458 for (size_t i = 0; i < numFaces; i++) {
7459 faceScores[i] = (uint8_t)faceDetectionInfo->faces[i].score;
7460 // Adjust crop region from sensor output coordinate system to active
7461 // array coordinate system.
Shuzhen Wang91c14e82017-08-21 17:56:57 -07007462 cam_rect_t rect = faceDetectionInfo->faces[i].face_boundary;
Thierry Strudel3d639192016-09-09 11:52:26 -07007463 mCropRegionMapper.toActiveArray(rect.left, rect.top,
7464 rect.width, rect.height);
7465
Shuzhen Wang91c14e82017-08-21 17:56:57 -07007466 convertToRegions(rect, faceRectangles+j, -1);
Thierry Strudel3d639192016-09-09 11:52:26 -07007467
Jason Lee8ce36fa2017-04-19 19:40:37 -07007468 LOGL("FD_DEBUG : Frame[%d] Face[%d] : top-left (%d, %d), "
7469 "bottom-right (%d, %d)",
7470 faceDetectionInfo->frame_id, i,
7471 faceRectangles[j + FACE_LEFT], faceRectangles[j + FACE_TOP],
7472 faceRectangles[j + FACE_RIGHT], faceRectangles[j + FACE_BOTTOM]);
7473
Thierry Strudel3d639192016-09-09 11:52:26 -07007474 j+= 4;
7475 }
7476 if (numFaces <= 0) {
7477 memset(faceIds, 0, sizeof(int32_t) * MAX_ROI);
7478 memset(faceScores, 0, sizeof(uint8_t) * MAX_ROI);
7479 memset(faceRectangles, 0, sizeof(int32_t) * MAX_ROI * 4);
7480 memset(faceLandmarks, 0, sizeof(int32_t) * MAX_ROI * 6);
7481 }
7482
7483 camMetadata.update(ANDROID_STATISTICS_FACE_SCORES, faceScores,
7484 numFaces);
7485 camMetadata.update(ANDROID_STATISTICS_FACE_RECTANGLES,
7486 faceRectangles, numFaces * 4U);
7487 if (fwk_faceDetectMode ==
7488 ANDROID_STATISTICS_FACE_DETECT_MODE_FULL) {
7489 IF_META_AVAILABLE(cam_face_landmarks_data_t, landmarks,
7490 CAM_INTF_META_FACE_LANDMARK, metadata) {
7491
7492 for (size_t i = 0; i < numFaces; i++) {
Shuzhen Wang91c14e82017-08-21 17:56:57 -07007493 cam_face_landmarks_info_t face_landmarks = landmarks->face_landmarks[i];
Thierry Strudel3d639192016-09-09 11:52:26 -07007494 // Map the co-ordinate sensor output coordinate system to active
7495 // array coordinate system.
7496 mCropRegionMapper.toActiveArray(
Shuzhen Wang91c14e82017-08-21 17:56:57 -07007497 face_landmarks.left_eye_center.x,
7498 face_landmarks.left_eye_center.y);
Thierry Strudel3d639192016-09-09 11:52:26 -07007499 mCropRegionMapper.toActiveArray(
Shuzhen Wang91c14e82017-08-21 17:56:57 -07007500 face_landmarks.right_eye_center.x,
7501 face_landmarks.right_eye_center.y);
Thierry Strudel3d639192016-09-09 11:52:26 -07007502 mCropRegionMapper.toActiveArray(
Shuzhen Wang91c14e82017-08-21 17:56:57 -07007503 face_landmarks.mouth_center.x,
7504 face_landmarks.mouth_center.y);
Thierry Strudel3d639192016-09-09 11:52:26 -07007505
Shuzhen Wang91c14e82017-08-21 17:56:57 -07007506 convertLandmarks(face_landmarks, faceLandmarks+k);
Jason Lee8ce36fa2017-04-19 19:40:37 -07007507
7508 LOGL("FD_DEBUG LANDMARK : Frame[%d] Face[%d] : "
7509 "left-eye (%d, %d), right-eye (%d, %d), mouth (%d, %d)",
7510 faceDetectionInfo->frame_id, i,
7511 faceLandmarks[k + LEFT_EYE_X],
7512 faceLandmarks[k + LEFT_EYE_Y],
7513 faceLandmarks[k + RIGHT_EYE_X],
7514 faceLandmarks[k + RIGHT_EYE_Y],
7515 faceLandmarks[k + MOUTH_X],
7516 faceLandmarks[k + MOUTH_Y]);
7517
Thierry Strudel04e026f2016-10-10 11:27:36 -07007518 k+= TOTAL_LANDMARK_INDICES;
7519 }
7520 } else {
7521 for (size_t i = 0; i < numFaces; i++) {
7522 setInvalidLandmarks(faceLandmarks+k);
7523 k+= TOTAL_LANDMARK_INDICES;
Thierry Strudel3d639192016-09-09 11:52:26 -07007524 }
7525 }
7526
Jason Lee49619db2017-04-13 12:07:22 -07007527 for (size_t i = 0; i < numFaces; i++) {
7528 faceIds[i] = faceDetectionInfo->faces[i].face_id;
7529
7530 LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : faceIds=%d",
7531 faceDetectionInfo->frame_id, i, faceIds[i]);
7532 }
7533
Thierry Strudel3d639192016-09-09 11:52:26 -07007534 camMetadata.update(ANDROID_STATISTICS_FACE_IDS, faceIds, numFaces);
7535 camMetadata.update(ANDROID_STATISTICS_FACE_LANDMARKS,
7536 faceLandmarks, numFaces * 6U);
Jason Lee49619db2017-04-13 12:07:22 -07007537 }
Thierry Strudel54dc9782017-02-15 12:12:10 -08007538 IF_META_AVAILABLE(cam_face_blink_data_t, blinks,
7539 CAM_INTF_META_FACE_BLINK, metadata) {
7540 uint8_t detected[MAX_ROI];
7541 uint8_t degree[MAX_ROI * 2];
7542 for (size_t i = 0; i < numFaces; i++) {
7543 detected[i] = blinks->blink[i].blink_detected;
7544 degree[2 * i] = blinks->blink[i].left_blink;
7545 degree[2 * i + 1] = blinks->blink[i].right_blink;
Jason Lee8ce36fa2017-04-19 19:40:37 -07007546
Jason Lee49619db2017-04-13 12:07:22 -07007547 LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : "
7548 "blink_detected=%d, leye_blink=%d, reye_blink=%d",
7549 faceDetectionInfo->frame_id, i, detected[i], degree[2 * i],
7550 degree[2 * i + 1]);
Thierry Strudel54dc9782017-02-15 12:12:10 -08007551 }
7552 camMetadata.update(QCAMERA3_STATS_BLINK_DETECTED,
7553 detected, numFaces);
7554 camMetadata.update(QCAMERA3_STATS_BLINK_DEGREE,
7555 degree, numFaces * 2);
7556 }
7557 IF_META_AVAILABLE(cam_face_smile_data_t, smiles,
7558 CAM_INTF_META_FACE_SMILE, metadata) {
7559 uint8_t degree[MAX_ROI];
7560 uint8_t confidence[MAX_ROI];
7561 for (size_t i = 0; i < numFaces; i++) {
7562 degree[i] = smiles->smile[i].smile_degree;
7563 confidence[i] = smiles->smile[i].smile_confidence;
Jason Lee8ce36fa2017-04-19 19:40:37 -07007564
Jason Lee49619db2017-04-13 12:07:22 -07007565 LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : "
7566 "smile_degree=%d, smile_score=%d",
7567 faceDetectionInfo->frame_id, i, degree[i], confidence[i]);
Thierry Strudel54dc9782017-02-15 12:12:10 -08007568 }
7569 camMetadata.update(QCAMERA3_STATS_SMILE_DEGREE,
7570 degree, numFaces);
7571 camMetadata.update(QCAMERA3_STATS_SMILE_CONFIDENCE,
7572 confidence, numFaces);
7573 }
7574 IF_META_AVAILABLE(cam_face_gaze_data_t, gazes,
7575 CAM_INTF_META_FACE_GAZE, metadata) {
7576 int8_t angle[MAX_ROI];
7577 int32_t direction[MAX_ROI * 3];
7578 int8_t degree[MAX_ROI * 2];
7579 for (size_t i = 0; i < numFaces; i++) {
7580 angle[i] = gazes->gaze[i].gaze_angle;
7581 direction[3 * i] = gazes->gaze[i].updown_dir;
7582 direction[3 * i + 1] = gazes->gaze[i].leftright_dir;
7583 direction[3 * i + 2] = gazes->gaze[i].roll_dir;
7584 degree[2 * i] = gazes->gaze[i].left_right_gaze;
7585 degree[2 * i + 1] = gazes->gaze[i].top_bottom_gaze;
Jason Lee8ce36fa2017-04-19 19:40:37 -07007586
7587 LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : gaze_angle=%d, "
7588 "updown_dir=%d, leftright_dir=%d,, roll_dir=%d, "
7589 "left_right_gaze=%d, top_bottom_gaze=%d",
7590 faceDetectionInfo->frame_id, i, angle[i],
7591 direction[3 * i], direction[3 * i + 1],
7592 direction[3 * i + 2],
7593 degree[2 * i], degree[2 * i + 1]);
Thierry Strudel54dc9782017-02-15 12:12:10 -08007594 }
7595 camMetadata.update(QCAMERA3_STATS_GAZE_ANGLE,
7596 (uint8_t *)angle, numFaces);
7597 camMetadata.update(QCAMERA3_STATS_GAZE_DIRECTION,
7598 direction, numFaces * 3);
7599 camMetadata.update(QCAMERA3_STATS_GAZE_DEGREE,
7600 (uint8_t *)degree, numFaces * 2);
7601 }
Thierry Strudel3d639192016-09-09 11:52:26 -07007602 }
7603 }
7604 }
7605 }
7606
7607 IF_META_AVAILABLE(uint32_t, histogramMode, CAM_INTF_META_STATS_HISTOGRAM_MODE, metadata) {
7608 uint8_t fwk_histogramMode = (uint8_t) *histogramMode;
Shuzhen Wang14415f52016-11-16 18:26:18 -08007609 int32_t histogramBins = 0;
Thierry Strudel54dc9782017-02-15 12:12:10 -08007610 camMetadata.update(QCAMERA3_HISTOGRAM_MODE, &fwk_histogramMode, 1);
Shuzhen Wang14415f52016-11-16 18:26:18 -08007611 camMetadata.update(NEXUS_EXPERIMENTAL_2017_HISTOGRAM_ENABLE, &fwk_histogramMode, 1);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007612
Shuzhen Wang14415f52016-11-16 18:26:18 -08007613 IF_META_AVAILABLE(int32_t, histBins, CAM_INTF_META_STATS_HISTOGRAM_BINS, metadata) {
7614 histogramBins = *histBins;
7615 camMetadata.update(NEXUS_EXPERIMENTAL_2017_HISTOGRAM_BINS, &histogramBins, 1);
7616 }
7617
7618 if (fwk_histogramMode == QCAMERA3_HISTOGRAM_MODE_ON && histogramBins > 0) {
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007619 IF_META_AVAILABLE(cam_hist_stats_t, stats_data, CAM_INTF_META_HISTOGRAM, metadata) {
7620 // process histogram statistics info
Shuzhen Wang14415f52016-11-16 18:26:18 -08007621 int32_t* histogramData = NULL;
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007622
7623 switch (stats_data->type) {
7624 case CAM_HISTOGRAM_TYPE_BAYER:
7625 switch (stats_data->bayer_stats.data_type) {
7626 case CAM_STATS_CHANNEL_GR:
Shuzhen Wang14415f52016-11-16 18:26:18 -08007627 histogramData = (int32_t *)stats_data->bayer_stats.gr_stats.hist_buf;
7628 break;
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007629 case CAM_STATS_CHANNEL_GB:
Shuzhen Wang14415f52016-11-16 18:26:18 -08007630 histogramData = (int32_t *)stats_data->bayer_stats.gb_stats.hist_buf;
7631 break;
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007632 case CAM_STATS_CHANNEL_B:
Shuzhen Wang14415f52016-11-16 18:26:18 -08007633 histogramData = (int32_t *)stats_data->bayer_stats.b_stats.hist_buf;
7634 break;
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007635 case CAM_STATS_CHANNEL_Y:
Shuzhen Wang14415f52016-11-16 18:26:18 -08007636 case CAM_STATS_CHANNEL_ALL:
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007637 case CAM_STATS_CHANNEL_R:
7638 default:
Shuzhen Wang14415f52016-11-16 18:26:18 -08007639 histogramData = (int32_t *)stats_data->bayer_stats.r_stats.hist_buf;
7640 break;
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007641 }
7642 break;
7643 case CAM_HISTOGRAM_TYPE_YUV:
Shuzhen Wang14415f52016-11-16 18:26:18 -08007644 histogramData = (int32_t *)stats_data->yuv_stats.hist_buf;
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007645 break;
7646 }
7647
Shuzhen Wang14415f52016-11-16 18:26:18 -08007648 camMetadata.update(NEXUS_EXPERIMENTAL_2017_HISTOGRAM, histogramData, histogramBins);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007649 }
7650 }
Thierry Strudel3d639192016-09-09 11:52:26 -07007651 }
7652
7653 IF_META_AVAILABLE(uint32_t, sharpnessMapMode,
7654 CAM_INTF_META_STATS_SHARPNESS_MAP_MODE, metadata) {
7655 uint8_t fwk_sharpnessMapMode = (uint8_t) *sharpnessMapMode;
7656 camMetadata.update(ANDROID_STATISTICS_SHARPNESS_MAP_MODE, &fwk_sharpnessMapMode, 1);
7657 }
7658
7659 IF_META_AVAILABLE(cam_sharpness_map_t, sharpnessMap,
7660 CAM_INTF_META_STATS_SHARPNESS_MAP, metadata) {
7661 camMetadata.update(ANDROID_STATISTICS_SHARPNESS_MAP, (int32_t *)sharpnessMap->sharpness,
7662 CAM_MAX_MAP_WIDTH * CAM_MAX_MAP_HEIGHT * 3);
7663 }
7664
7665 IF_META_AVAILABLE(cam_lens_shading_map_t, lensShadingMap,
7666 CAM_INTF_META_LENS_SHADING_MAP, metadata) {
7667 size_t map_height = MIN((size_t)gCamCapability[mCameraId]->lens_shading_map_size.height,
7668 CAM_MAX_SHADING_MAP_HEIGHT);
7669 size_t map_width = MIN((size_t)gCamCapability[mCameraId]->lens_shading_map_size.width,
7670 CAM_MAX_SHADING_MAP_WIDTH);
7671 camMetadata.update(ANDROID_STATISTICS_LENS_SHADING_MAP,
7672 lensShadingMap->lens_shading, 4U * map_width * map_height);
7673 }
7674
7675 IF_META_AVAILABLE(uint32_t, toneMapMode, CAM_INTF_META_TONEMAP_MODE, metadata) {
7676 uint8_t fwk_toneMapMode = (uint8_t) *toneMapMode;
7677 camMetadata.update(ANDROID_TONEMAP_MODE, &fwk_toneMapMode, 1);
7678 }
7679
7680 IF_META_AVAILABLE(cam_rgb_tonemap_curves, tonemap, CAM_INTF_META_TONEMAP_CURVES, metadata) {
7681 //Populate CAM_INTF_META_TONEMAP_CURVES
7682 /* ch0 = G, ch 1 = B, ch 2 = R*/
7683 if (tonemap->tonemap_points_cnt > CAM_MAX_TONEMAP_CURVE_SIZE) {
7684 LOGE("Fatal: tonemap_points_cnt %d exceeds max value of %d",
7685 tonemap->tonemap_points_cnt,
7686 CAM_MAX_TONEMAP_CURVE_SIZE);
7687 tonemap->tonemap_points_cnt = CAM_MAX_TONEMAP_CURVE_SIZE;
7688 }
7689
7690 camMetadata.update(ANDROID_TONEMAP_CURVE_GREEN,
7691 &tonemap->curves[0].tonemap_points[0][0],
7692 tonemap->tonemap_points_cnt * 2);
7693
7694 camMetadata.update(ANDROID_TONEMAP_CURVE_BLUE,
7695 &tonemap->curves[1].tonemap_points[0][0],
7696 tonemap->tonemap_points_cnt * 2);
7697
7698 camMetadata.update(ANDROID_TONEMAP_CURVE_RED,
7699 &tonemap->curves[2].tonemap_points[0][0],
7700 tonemap->tonemap_points_cnt * 2);
7701 }
7702
7703 IF_META_AVAILABLE(cam_color_correct_gains_t, colorCorrectionGains,
7704 CAM_INTF_META_COLOR_CORRECT_GAINS, metadata) {
7705 camMetadata.update(ANDROID_COLOR_CORRECTION_GAINS, colorCorrectionGains->gains,
7706 CC_GAIN_MAX);
7707 }
7708
7709 IF_META_AVAILABLE(cam_color_correct_matrix_t, colorCorrectionMatrix,
7710 CAM_INTF_META_COLOR_CORRECT_TRANSFORM, metadata) {
7711 camMetadata.update(ANDROID_COLOR_CORRECTION_TRANSFORM,
7712 (camera_metadata_rational_t *)(void *)colorCorrectionMatrix->transform_matrix,
7713 CC_MATRIX_COLS * CC_MATRIX_ROWS);
7714 }
7715
7716 IF_META_AVAILABLE(cam_profile_tone_curve, toneCurve,
7717 CAM_INTF_META_PROFILE_TONE_CURVE, metadata) {
7718 if (toneCurve->tonemap_points_cnt > CAM_MAX_TONEMAP_CURVE_SIZE) {
7719 LOGE("Fatal: tonemap_points_cnt %d exceeds max value of %d",
7720 toneCurve->tonemap_points_cnt,
7721 CAM_MAX_TONEMAP_CURVE_SIZE);
7722 toneCurve->tonemap_points_cnt = CAM_MAX_TONEMAP_CURVE_SIZE;
7723 }
7724 camMetadata.update(ANDROID_SENSOR_PROFILE_TONE_CURVE,
7725 (float*)toneCurve->curve.tonemap_points,
7726 toneCurve->tonemap_points_cnt * 2);
7727 }
7728
7729 IF_META_AVAILABLE(cam_color_correct_gains_t, predColorCorrectionGains,
7730 CAM_INTF_META_PRED_COLOR_CORRECT_GAINS, metadata) {
7731 camMetadata.update(ANDROID_STATISTICS_PREDICTED_COLOR_GAINS,
7732 predColorCorrectionGains->gains, 4);
7733 }
7734
7735 IF_META_AVAILABLE(cam_color_correct_matrix_t, predColorCorrectionMatrix,
7736 CAM_INTF_META_PRED_COLOR_CORRECT_TRANSFORM, metadata) {
7737 camMetadata.update(ANDROID_STATISTICS_PREDICTED_COLOR_TRANSFORM,
7738 (camera_metadata_rational_t *)(void *)predColorCorrectionMatrix->transform_matrix,
7739 CC_MATRIX_ROWS * CC_MATRIX_COLS);
7740 }
7741
7742 IF_META_AVAILABLE(float, otpWbGrGb, CAM_INTF_META_OTP_WB_GRGB, metadata) {
7743 camMetadata.update(ANDROID_SENSOR_GREEN_SPLIT, otpWbGrGb, 1);
7744 }
7745
7746 IF_META_AVAILABLE(uint32_t, blackLevelLock, CAM_INTF_META_BLACK_LEVEL_LOCK, metadata) {
7747 uint8_t fwk_blackLevelLock = (uint8_t) *blackLevelLock;
7748 camMetadata.update(ANDROID_BLACK_LEVEL_LOCK, &fwk_blackLevelLock, 1);
7749 }
7750
7751 IF_META_AVAILABLE(uint32_t, sceneFlicker, CAM_INTF_META_SCENE_FLICKER, metadata) {
7752 uint8_t fwk_sceneFlicker = (uint8_t) *sceneFlicker;
7753 camMetadata.update(ANDROID_STATISTICS_SCENE_FLICKER, &fwk_sceneFlicker, 1);
7754 }
7755
7756 IF_META_AVAILABLE(uint32_t, effectMode, CAM_INTF_PARM_EFFECT, metadata) {
7757 int val = lookupFwkName(EFFECT_MODES_MAP, METADATA_MAP_SIZE(EFFECT_MODES_MAP),
7758 *effectMode);
7759 if (NAME_NOT_FOUND != val) {
7760 uint8_t fwk_effectMode = (uint8_t)val;
7761 camMetadata.update(ANDROID_CONTROL_EFFECT_MODE, &fwk_effectMode, 1);
7762 }
7763 }
7764
7765 IF_META_AVAILABLE(cam_test_pattern_data_t, testPatternData,
7766 CAM_INTF_META_TEST_PATTERN_DATA, metadata) {
7767 int32_t fwk_testPatternMode = lookupFwkName(TEST_PATTERN_MAP,
7768 METADATA_MAP_SIZE(TEST_PATTERN_MAP), testPatternData->mode);
7769 if (NAME_NOT_FOUND != fwk_testPatternMode) {
7770 camMetadata.update(ANDROID_SENSOR_TEST_PATTERN_MODE, &fwk_testPatternMode, 1);
7771 }
7772 int32_t fwk_testPatternData[4];
7773 fwk_testPatternData[0] = testPatternData->r;
7774 fwk_testPatternData[3] = testPatternData->b;
7775 switch (gCamCapability[mCameraId]->color_arrangement) {
7776 case CAM_FILTER_ARRANGEMENT_RGGB:
7777 case CAM_FILTER_ARRANGEMENT_GRBG:
7778 fwk_testPatternData[1] = testPatternData->gr;
7779 fwk_testPatternData[2] = testPatternData->gb;
7780 break;
7781 case CAM_FILTER_ARRANGEMENT_GBRG:
7782 case CAM_FILTER_ARRANGEMENT_BGGR:
7783 fwk_testPatternData[2] = testPatternData->gr;
7784 fwk_testPatternData[1] = testPatternData->gb;
7785 break;
7786 default:
7787 LOGE("color arrangement %d is not supported",
7788 gCamCapability[mCameraId]->color_arrangement);
7789 break;
7790 }
7791 camMetadata.update(ANDROID_SENSOR_TEST_PATTERN_DATA, fwk_testPatternData, 4);
7792 }
7793
7794 IF_META_AVAILABLE(double, gps_coords, CAM_INTF_META_JPEG_GPS_COORDINATES, metadata) {
7795 camMetadata.update(ANDROID_JPEG_GPS_COORDINATES, gps_coords, 3);
7796 }
7797
7798 IF_META_AVAILABLE(uint8_t, gps_methods, CAM_INTF_META_JPEG_GPS_PROC_METHODS, metadata) {
7799 String8 str((const char *)gps_methods);
7800 camMetadata.update(ANDROID_JPEG_GPS_PROCESSING_METHOD, str);
7801 }
7802
7803 IF_META_AVAILABLE(int64_t, gps_timestamp, CAM_INTF_META_JPEG_GPS_TIMESTAMP, metadata) {
7804 camMetadata.update(ANDROID_JPEG_GPS_TIMESTAMP, gps_timestamp, 1);
7805 }
7806
7807 IF_META_AVAILABLE(int32_t, jpeg_orientation, CAM_INTF_META_JPEG_ORIENTATION, metadata) {
7808 camMetadata.update(ANDROID_JPEG_ORIENTATION, jpeg_orientation, 1);
7809 }
7810
7811 IF_META_AVAILABLE(uint32_t, jpeg_quality, CAM_INTF_META_JPEG_QUALITY, metadata) {
7812 uint8_t fwk_jpeg_quality = (uint8_t) *jpeg_quality;
7813 camMetadata.update(ANDROID_JPEG_QUALITY, &fwk_jpeg_quality, 1);
7814 }
7815
7816 IF_META_AVAILABLE(uint32_t, thumb_quality, CAM_INTF_META_JPEG_THUMB_QUALITY, metadata) {
7817 uint8_t fwk_thumb_quality = (uint8_t) *thumb_quality;
7818 camMetadata.update(ANDROID_JPEG_THUMBNAIL_QUALITY, &fwk_thumb_quality, 1);
7819 }
7820
7821 IF_META_AVAILABLE(cam_dimension_t, thumb_size, CAM_INTF_META_JPEG_THUMB_SIZE, metadata) {
7822 int32_t fwk_thumb_size[2];
7823 fwk_thumb_size[0] = thumb_size->width;
7824 fwk_thumb_size[1] = thumb_size->height;
7825 camMetadata.update(ANDROID_JPEG_THUMBNAIL_SIZE, fwk_thumb_size, 2);
7826 }
7827
Shuzhen Wang2fea89e2017-05-08 17:02:15 -07007828 // Skip reprocess metadata if there is no input stream.
7829 if (mInputStreamInfo.dim.width > 0 && mInputStreamInfo.dim.height > 0) {
7830 IF_META_AVAILABLE(int32_t, privateData, CAM_INTF_META_PRIVATE_DATA, metadata) {
7831 camMetadata.update(QCAMERA3_PRIVATEDATA_REPROCESS,
7832 privateData,
7833 MAX_METADATA_PRIVATE_PAYLOAD_SIZE_IN_BYTES / sizeof(int32_t));
7834 }
Thierry Strudel3d639192016-09-09 11:52:26 -07007835 }
7836
Thierry Strudel295a0ca2016-11-03 18:38:47 -07007837 IF_META_AVAILABLE(int32_t, meteringMode, CAM_INTF_PARM_AEC_ALGO_TYPE, metadata) {
Thierry Strudel54dc9782017-02-15 12:12:10 -08007838 camMetadata.update(QCAMERA3_EXPOSURE_METER,
Thierry Strudel295a0ca2016-11-03 18:38:47 -07007839 meteringMode, 1);
7840 }
7841
Thierry Strudel54dc9782017-02-15 12:12:10 -08007842 IF_META_AVAILABLE(cam_asd_hdr_scene_data_t, hdr_scene_data,
7843 CAM_INTF_META_ASD_HDR_SCENE_DATA, metadata) {
7844 LOGD("hdr_scene_data: %d %f\n",
7845 hdr_scene_data->is_hdr_scene, hdr_scene_data->hdr_confidence);
7846 uint8_t isHdr = hdr_scene_data->is_hdr_scene;
7847 float isHdrConfidence = hdr_scene_data->hdr_confidence;
7848 camMetadata.update(QCAMERA3_STATS_IS_HDR_SCENE,
7849 &isHdr, 1);
7850 camMetadata.update(QCAMERA3_STATS_IS_HDR_SCENE_CONFIDENCE,
7851 &isHdrConfidence, 1);
7852 }
7853
7854
7855
Thierry Strudel3d639192016-09-09 11:52:26 -07007856 if (metadata->is_tuning_params_valid) {
7857 uint8_t tuning_meta_data_blob[sizeof(tuning_params_t)];
7858 uint8_t *data = (uint8_t *)&tuning_meta_data_blob[0];
7859 metadata->tuning_params.tuning_data_version = TUNING_DATA_VERSION;
7860
7861
7862 memcpy(data, ((uint8_t *)&metadata->tuning_params.tuning_data_version),
7863 sizeof(uint32_t));
7864 data += sizeof(uint32_t);
7865
7866 memcpy(data, ((uint8_t *)&metadata->tuning_params.tuning_sensor_data_size),
7867 sizeof(uint32_t));
7868 LOGD("tuning_sensor_data_size %d",(int)(*(int *)data));
7869 data += sizeof(uint32_t);
7870
7871 memcpy(data, ((uint8_t *)&metadata->tuning_params.tuning_vfe_data_size),
7872 sizeof(uint32_t));
7873 LOGD("tuning_vfe_data_size %d",(int)(*(int *)data));
7874 data += sizeof(uint32_t);
7875
7876 memcpy(data, ((uint8_t *)&metadata->tuning_params.tuning_cpp_data_size),
7877 sizeof(uint32_t));
7878 LOGD("tuning_cpp_data_size %d",(int)(*(int *)data));
7879 data += sizeof(uint32_t);
7880
7881 memcpy(data, ((uint8_t *)&metadata->tuning_params.tuning_cac_data_size),
7882 sizeof(uint32_t));
7883 LOGD("tuning_cac_data_size %d",(int)(*(int *)data));
7884 data += sizeof(uint32_t);
7885
7886 metadata->tuning_params.tuning_mod3_data_size = 0;
7887 memcpy(data, ((uint8_t *)&metadata->tuning_params.tuning_mod3_data_size),
7888 sizeof(uint32_t));
7889 LOGD("tuning_mod3_data_size %d",(int)(*(int *)data));
7890 data += sizeof(uint32_t);
7891
7892 size_t count = MIN(metadata->tuning_params.tuning_sensor_data_size,
7893 TUNING_SENSOR_DATA_MAX);
7894 memcpy(data, ((uint8_t *)&metadata->tuning_params.data),
7895 count);
7896 data += count;
7897
7898 count = MIN(metadata->tuning_params.tuning_vfe_data_size,
7899 TUNING_VFE_DATA_MAX);
7900 memcpy(data, ((uint8_t *)&metadata->tuning_params.data[TUNING_VFE_DATA_OFFSET]),
7901 count);
7902 data += count;
7903
7904 count = MIN(metadata->tuning_params.tuning_cpp_data_size,
7905 TUNING_CPP_DATA_MAX);
7906 memcpy(data, ((uint8_t *)&metadata->tuning_params.data[TUNING_CPP_DATA_OFFSET]),
7907 count);
7908 data += count;
7909
7910 count = MIN(metadata->tuning_params.tuning_cac_data_size,
7911 TUNING_CAC_DATA_MAX);
7912 memcpy(data, ((uint8_t *)&metadata->tuning_params.data[TUNING_CAC_DATA_OFFSET]),
7913 count);
7914 data += count;
7915
7916 camMetadata.update(QCAMERA3_TUNING_META_DATA_BLOB,
7917 (int32_t *)(void *)tuning_meta_data_blob,
7918 (size_t)(data-tuning_meta_data_blob) / sizeof(uint32_t));
7919 }
7920
7921 IF_META_AVAILABLE(cam_neutral_col_point_t, neuColPoint,
7922 CAM_INTF_META_NEUTRAL_COL_POINT, metadata) {
7923 camMetadata.update(ANDROID_SENSOR_NEUTRAL_COLOR_POINT,
7924 (camera_metadata_rational_t *)(void *)neuColPoint->neutral_col_point,
7925 NEUTRAL_COL_POINTS);
7926 }
7927
7928 IF_META_AVAILABLE(uint32_t, shadingMapMode, CAM_INTF_META_LENS_SHADING_MAP_MODE, metadata) {
7929 uint8_t fwk_shadingMapMode = (uint8_t) *shadingMapMode;
7930 camMetadata.update(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, &fwk_shadingMapMode, 1);
7931 }
7932
7933 IF_META_AVAILABLE(cam_area_t, hAeRegions, CAM_INTF_META_AEC_ROI, metadata) {
7934 int32_t aeRegions[REGIONS_TUPLE_COUNT];
7935 // Adjust crop region from sensor output coordinate system to active
7936 // array coordinate system.
Shuzhen Wang91c14e82017-08-21 17:56:57 -07007937 cam_rect_t hAeRect = hAeRegions->rect;
7938 mCropRegionMapper.toActiveArray(hAeRect.left, hAeRect.top,
7939 hAeRect.width, hAeRect.height);
Thierry Strudel3d639192016-09-09 11:52:26 -07007940
Shuzhen Wang91c14e82017-08-21 17:56:57 -07007941 convertToRegions(hAeRect, aeRegions, hAeRegions->weight);
Thierry Strudel3d639192016-09-09 11:52:26 -07007942 camMetadata.update(ANDROID_CONTROL_AE_REGIONS, aeRegions,
7943 REGIONS_TUPLE_COUNT);
7944 LOGD("Metadata : ANDROID_CONTROL_AE_REGIONS: FWK: [%d,%d,%d,%d] HAL: [%d,%d,%d,%d]",
7945 aeRegions[0], aeRegions[1], aeRegions[2], aeRegions[3],
Shuzhen Wang91c14e82017-08-21 17:56:57 -07007946 hAeRect.left, hAeRect.top, hAeRect.width,
7947 hAeRect.height);
Thierry Strudel3d639192016-09-09 11:52:26 -07007948 }
7949
Shuzhen Wang181c57b2017-07-21 11:39:44 -07007950 if (!pendingRequest.focusStateSent) {
7951 if (pendingRequest.focusStateValid) {
7952 camMetadata.update(ANDROID_CONTROL_AF_STATE, &pendingRequest.focusState, 1);
7953 LOGD("Metadata : ANDROID_CONTROL_AF_STATE %u", pendingRequest.focusState);
Shuzhen Wang0cb8cdf2016-07-14 11:56:49 -07007954 } else {
Shuzhen Wang181c57b2017-07-21 11:39:44 -07007955 IF_META_AVAILABLE(uint32_t, afState, CAM_INTF_META_AF_STATE, metadata) {
7956 uint8_t fwk_afState = (uint8_t) *afState;
7957 camMetadata.update(ANDROID_CONTROL_AF_STATE, &fwk_afState, 1);
7958 LOGD("Metadata : ANDROID_CONTROL_AF_STATE %u", *afState);
7959 }
Shuzhen Wang0cb8cdf2016-07-14 11:56:49 -07007960 }
7961 }
7962
Thierry Strudel3d639192016-09-09 11:52:26 -07007963 IF_META_AVAILABLE(float, focusDistance, CAM_INTF_META_LENS_FOCUS_DISTANCE, metadata) {
7964 camMetadata.update(ANDROID_LENS_FOCUS_DISTANCE , focusDistance, 1);
Shuzhen Wangecb525d2018-04-22 21:32:44 -07007965 mLastFocusDistance = *focusDistance;
7966 } else {
7967 LOGE("Missing LENS_FOCUS_DISTANCE metadata. Use last known distance of %f",
7968 mLastFocusDistance);
7969 camMetadata.update(ANDROID_LENS_FOCUS_DISTANCE , &mLastFocusDistance, 1);
Thierry Strudel3d639192016-09-09 11:52:26 -07007970 }
7971
7972 IF_META_AVAILABLE(float, focusRange, CAM_INTF_META_LENS_FOCUS_RANGE, metadata) {
7973 camMetadata.update(ANDROID_LENS_FOCUS_RANGE , focusRange, 2);
7974 }
7975
7976 IF_META_AVAILABLE(cam_af_lens_state_t, lensState, CAM_INTF_META_LENS_STATE, metadata) {
7977 uint8_t fwk_lensState = *lensState;
7978 camMetadata.update(ANDROID_LENS_STATE , &fwk_lensState, 1);
7979 }
7980
Thierry Strudel3d639192016-09-09 11:52:26 -07007981 IF_META_AVAILABLE(uint32_t, hal_ab_mode, CAM_INTF_PARM_ANTIBANDING, metadata) {
Shuzhen Wangf6890e02016-08-12 14:28:54 -07007982 uint32_t ab_mode = *hal_ab_mode;
7983 if (ab_mode == CAM_ANTIBANDING_MODE_AUTO_60HZ ||
7984 ab_mode == CAM_ANTIBANDING_MODE_AUTO_50HZ) {
7985 ab_mode = CAM_ANTIBANDING_MODE_AUTO;
7986 }
Thierry Strudel3d639192016-09-09 11:52:26 -07007987 int val = lookupFwkName(ANTIBANDING_MODES_MAP, METADATA_MAP_SIZE(ANTIBANDING_MODES_MAP),
Shuzhen Wangf6890e02016-08-12 14:28:54 -07007988 ab_mode);
Thierry Strudel3d639192016-09-09 11:52:26 -07007989 if (NAME_NOT_FOUND != val) {
7990 uint8_t fwk_ab_mode = (uint8_t)val;
7991 camMetadata.update(ANDROID_CONTROL_AE_ANTIBANDING_MODE, &fwk_ab_mode, 1);
7992 }
7993 }
7994
7995 IF_META_AVAILABLE(uint32_t, bestshotMode, CAM_INTF_PARM_BESTSHOT_MODE, metadata) {
7996 int val = lookupFwkName(SCENE_MODES_MAP,
7997 METADATA_MAP_SIZE(SCENE_MODES_MAP), *bestshotMode);
7998 if (NAME_NOT_FOUND != val) {
7999 uint8_t fwkBestshotMode = (uint8_t)val;
8000 camMetadata.update(ANDROID_CONTROL_SCENE_MODE, &fwkBestshotMode, 1);
8001 LOGD("Metadata : ANDROID_CONTROL_SCENE_MODE");
8002 } else {
8003 LOGH("Metadata not found : ANDROID_CONTROL_SCENE_MODE");
8004 }
8005 }
8006
8007 IF_META_AVAILABLE(uint32_t, mode, CAM_INTF_META_MODE, metadata) {
8008 uint8_t fwk_mode = (uint8_t) *mode;
8009 camMetadata.update(ANDROID_CONTROL_MODE, &fwk_mode, 1);
8010 }
8011
8012 /* Constant metadata values to be update*/
Thierry Strudel3d639192016-09-09 11:52:26 -07008013
8014 uint8_t hotPixelMapMode = ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF;
8015 camMetadata.update(ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE, &hotPixelMapMode, 1);
8016
8017 int32_t hotPixelMap[2];
8018 camMetadata.update(ANDROID_STATISTICS_HOT_PIXEL_MAP, &hotPixelMap[0], 0);
8019
8020 // CDS
8021 IF_META_AVAILABLE(int32_t, cds, CAM_INTF_PARM_CDS_MODE, metadata) {
8022 camMetadata.update(QCAMERA3_CDS_MODE, cds, 1);
8023 }
8024
Thierry Strudel04e026f2016-10-10 11:27:36 -07008025 IF_META_AVAILABLE(cam_sensor_hdr_type_t, vhdr, CAM_INTF_PARM_SENSOR_HDR, metadata) {
8026 int32_t fwk_hdr;
Thierry Strudel54dc9782017-02-15 12:12:10 -08008027 int8_t curr_hdr_state = ((mCurrFeatureState & CAM_QCOM_FEATURE_STAGGERED_VIDEO_HDR) != 0);
Thierry Strudel04e026f2016-10-10 11:27:36 -07008028 if(*vhdr == CAM_SENSOR_HDR_OFF) {
8029 fwk_hdr = QCAMERA3_VIDEO_HDR_MODE_OFF;
8030 } else {
8031 fwk_hdr = QCAMERA3_VIDEO_HDR_MODE_ON;
8032 }
Thierry Strudel54dc9782017-02-15 12:12:10 -08008033
8034 if(fwk_hdr != curr_hdr_state) {
8035 LOGH("PROFILE_META_HDR_TOGGLED value=%d", fwk_hdr);
8036 if(fwk_hdr)
8037 mCurrFeatureState |= CAM_QCOM_FEATURE_STAGGERED_VIDEO_HDR;
8038 else
8039 mCurrFeatureState &= ~CAM_QCOM_FEATURE_STAGGERED_VIDEO_HDR;
8040 }
Thierry Strudel04e026f2016-10-10 11:27:36 -07008041 camMetadata.update(QCAMERA3_VIDEO_HDR_MODE, &fwk_hdr, 1);
8042 }
8043
Thierry Strudel54dc9782017-02-15 12:12:10 -08008044 //binning correction
8045 IF_META_AVAILABLE(cam_binning_correction_mode_t, bin_correction,
8046 CAM_INTF_META_BINNING_CORRECTION_MODE, metadata) {
8047 int32_t fwk_bin_mode = (int32_t) *bin_correction;
8048 camMetadata.update(QCAMERA3_BINNING_CORRECTION_MODE, &fwk_bin_mode, 1);
8049 }
8050
Thierry Strudel04e026f2016-10-10 11:27:36 -07008051 IF_META_AVAILABLE(cam_ir_mode_type_t, ir, CAM_INTF_META_IR_MODE, metadata) {
Thierry Strudelcca4d9c2016-10-20 08:25:53 -07008052 int32_t fwk_ir = (int32_t) *ir;
Thierry Strudel54dc9782017-02-15 12:12:10 -08008053 int8_t curr_ir_state = ((mCurrFeatureState & CAM_QCOM_FEATURE_IR ) != 0);
8054 int8_t is_ir_on = 0;
8055
8056 (fwk_ir > 0) ? (is_ir_on = 1) : (is_ir_on = 0) ;
8057 if(is_ir_on != curr_ir_state) {
8058 LOGH("PROFILE_META_IR_TOGGLED value=%d", fwk_ir);
8059 if(is_ir_on)
8060 mCurrFeatureState |= CAM_QCOM_FEATURE_IR;
8061 else
8062 mCurrFeatureState &= ~CAM_QCOM_FEATURE_IR;
8063 }
Thierry Strudelcca4d9c2016-10-20 08:25:53 -07008064 camMetadata.update(QCAMERA3_IR_MODE, &fwk_ir, 1);
Thierry Strudel04e026f2016-10-10 11:27:36 -07008065 }
8066
Thierry Strudel269c81a2016-10-12 12:13:59 -07008067 // AEC SPEED
8068 IF_META_AVAILABLE(float, aec, CAM_INTF_META_AEC_CONVERGENCE_SPEED, metadata) {
8069 camMetadata.update(QCAMERA3_AEC_CONVERGENCE_SPEED, aec, 1);
8070 }
8071
8072 // AWB SPEED
8073 IF_META_AVAILABLE(float, awb, CAM_INTF_META_AWB_CONVERGENCE_SPEED, metadata) {
8074 camMetadata.update(QCAMERA3_AWB_CONVERGENCE_SPEED, awb, 1);
8075 }
8076
Thierry Strudel3d639192016-09-09 11:52:26 -07008077 // TNR
8078 IF_META_AVAILABLE(cam_denoise_param_t, tnr, CAM_INTF_PARM_TEMPORAL_DENOISE, metadata) {
8079 uint8_t tnr_enable = tnr->denoise_enable;
8080 int32_t tnr_process_type = (int32_t)tnr->process_plates;
Thierry Strudel54dc9782017-02-15 12:12:10 -08008081 int8_t curr_tnr_state = ((mCurrFeatureState & CAM_QTI_FEATURE_SW_TNR) != 0) ;
8082 int8_t is_tnr_on = 0;
8083
8084 (tnr_enable > 0) ? (is_tnr_on = 1) : (is_tnr_on = 0);
8085 if(is_tnr_on != curr_tnr_state) {
8086 LOGH("PROFILE_META_TNR_TOGGLED value=%d", tnr_enable);
8087 if(is_tnr_on)
8088 mCurrFeatureState |= CAM_QTI_FEATURE_SW_TNR;
8089 else
8090 mCurrFeatureState &= ~CAM_QTI_FEATURE_SW_TNR;
8091 }
Thierry Strudel3d639192016-09-09 11:52:26 -07008092
8093 camMetadata.update(QCAMERA3_TEMPORAL_DENOISE_ENABLE, &tnr_enable, 1);
8094 camMetadata.update(QCAMERA3_TEMPORAL_DENOISE_PROCESS_TYPE, &tnr_process_type, 1);
8095 }
8096
8097 // Reprocess crop data
8098 IF_META_AVAILABLE(cam_crop_data_t, crop_data, CAM_INTF_META_CROP_DATA, metadata) {
8099 uint8_t cnt = crop_data->num_of_streams;
8100 if ( (0 >= cnt) || (cnt > MAX_NUM_STREAMS)) {
8101 // mm-qcamera-daemon only posts crop_data for streams
8102 // not linked to pproc. So no valid crop metadata is not
8103 // necessarily an error case.
8104 LOGD("No valid crop metadata entries");
8105 } else {
8106 uint32_t reproc_stream_id;
8107 if ( NO_ERROR != getReprocessibleOutputStreamId(reproc_stream_id)) {
8108 LOGD("No reprocessible stream found, ignore crop data");
8109 } else {
8110 int rc = NO_ERROR;
8111 Vector<int32_t> roi_map;
8112 int32_t *crop = new int32_t[cnt*4];
8113 if (NULL == crop) {
8114 rc = NO_MEMORY;
8115 }
8116 if (NO_ERROR == rc) {
8117 int32_t streams_found = 0;
8118 for (size_t i = 0; i < cnt; i++) {
8119 if (crop_data->crop_info[i].stream_id == reproc_stream_id) {
8120 if (pprocDone) {
8121 // HAL already does internal reprocessing,
8122 // either via reprocessing before JPEG encoding,
8123 // or offline postprocessing for pproc bypass case.
8124 crop[0] = 0;
8125 crop[1] = 0;
8126 crop[2] = mInputStreamInfo.dim.width;
8127 crop[3] = mInputStreamInfo.dim.height;
8128 } else {
8129 crop[0] = crop_data->crop_info[i].crop.left;
8130 crop[1] = crop_data->crop_info[i].crop.top;
8131 crop[2] = crop_data->crop_info[i].crop.width;
8132 crop[3] = crop_data->crop_info[i].crop.height;
8133 }
8134 roi_map.add(crop_data->crop_info[i].roi_map.left);
8135 roi_map.add(crop_data->crop_info[i].roi_map.top);
8136 roi_map.add(crop_data->crop_info[i].roi_map.width);
8137 roi_map.add(crop_data->crop_info[i].roi_map.height);
8138 streams_found++;
8139 LOGD("Adding reprocess crop data for stream %dx%d, %dx%d",
8140 crop[0], crop[1], crop[2], crop[3]);
8141 LOGD("Adding reprocess crop roi map for stream %dx%d, %dx%d",
8142 crop_data->crop_info[i].roi_map.left,
8143 crop_data->crop_info[i].roi_map.top,
8144 crop_data->crop_info[i].roi_map.width,
8145 crop_data->crop_info[i].roi_map.height);
8146 break;
8147
8148 }
8149 }
8150 camMetadata.update(QCAMERA3_CROP_COUNT_REPROCESS,
8151 &streams_found, 1);
8152 camMetadata.update(QCAMERA3_CROP_REPROCESS,
8153 crop, (size_t)(streams_found * 4));
8154 if (roi_map.array()) {
8155 camMetadata.update(QCAMERA3_CROP_ROI_MAP_REPROCESS,
8156 roi_map.array(), roi_map.size());
8157 }
8158 }
8159 if (crop) {
8160 delete [] crop;
8161 }
8162 }
8163 }
8164 }
8165
8166 if (gCamCapability[mCameraId]->aberration_modes_count == 0) {
8167 // Regardless of CAC supports or not, CTS is expecting the CAC result to be non NULL and
8168 // so hardcoding the CAC result to OFF mode.
8169 uint8_t fwkCacMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
8170 camMetadata.update(ANDROID_COLOR_CORRECTION_ABERRATION_MODE, &fwkCacMode, 1);
8171 } else {
8172 IF_META_AVAILABLE(cam_aberration_mode_t, cacMode, CAM_INTF_PARM_CAC, metadata) {
8173 int val = lookupFwkName(COLOR_ABERRATION_MAP, METADATA_MAP_SIZE(COLOR_ABERRATION_MAP),
8174 *cacMode);
8175 if (NAME_NOT_FOUND != val) {
8176 uint8_t resultCacMode = (uint8_t)val;
8177 // check whether CAC result from CB is equal to Framework set CAC mode
8178 // If not equal then set the CAC mode came in corresponding request
Shuzhen Wang181c57b2017-07-21 11:39:44 -07008179 if (pendingRequest.fwkCacMode != resultCacMode) {
8180 resultCacMode = pendingRequest.fwkCacMode;
Thierry Strudel3d639192016-09-09 11:52:26 -07008181 }
Thierry Strudel54dc9782017-02-15 12:12:10 -08008182 //Check if CAC is disabled by property
8183 if (m_cacModeDisabled) {
8184 resultCacMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
8185 }
8186
Shuzhen Wang181c57b2017-07-21 11:39:44 -07008187 LOGD("fwk_cacMode=%d resultCacMode=%d", pendingRequest.fwkCacMode, resultCacMode);
Thierry Strudel3d639192016-09-09 11:52:26 -07008188 camMetadata.update(ANDROID_COLOR_CORRECTION_ABERRATION_MODE, &resultCacMode, 1);
8189 } else {
8190 LOGE("Invalid CAC camera parameter: %d", *cacMode);
8191 }
8192 }
8193 }
8194
8195 // Post blob of cam_cds_data through vendor tag.
8196 IF_META_AVAILABLE(cam_cds_data_t, cdsInfo, CAM_INTF_META_CDS_DATA, metadata) {
8197 uint8_t cnt = cdsInfo->num_of_streams;
8198 cam_cds_data_t cdsDataOverride;
8199 memset(&cdsDataOverride, 0, sizeof(cdsDataOverride));
8200 cdsDataOverride.session_cds_enable = cdsInfo->session_cds_enable;
8201 cdsDataOverride.num_of_streams = 1;
8202 if ((0 < cnt) && (cnt <= MAX_NUM_STREAMS)) {
8203 uint32_t reproc_stream_id;
8204 if ( NO_ERROR != getReprocessibleOutputStreamId(reproc_stream_id)) {
8205 LOGD("No reprocessible stream found, ignore cds data");
8206 } else {
8207 for (size_t i = 0; i < cnt; i++) {
8208 if (cdsInfo->cds_info[i].stream_id ==
8209 reproc_stream_id) {
8210 cdsDataOverride.cds_info[0].cds_enable =
8211 cdsInfo->cds_info[i].cds_enable;
8212 break;
8213 }
8214 }
8215 }
8216 } else {
8217 LOGD("Invalid stream count %d in CDS_DATA", cnt);
8218 }
8219 camMetadata.update(QCAMERA3_CDS_INFO,
8220 (uint8_t *)&cdsDataOverride,
8221 sizeof(cam_cds_data_t));
8222 }
8223
8224 // Ldaf calibration data
8225 if (!mLdafCalibExist) {
8226 IF_META_AVAILABLE(uint32_t, ldafCalib,
8227 CAM_INTF_META_LDAF_EXIF, metadata) {
8228 mLdafCalibExist = true;
8229 mLdafCalib[0] = ldafCalib[0];
8230 mLdafCalib[1] = ldafCalib[1];
8231 LOGD("ldafCalib[0] is %d, ldafCalib[1] is %d",
8232 ldafCalib[0], ldafCalib[1]);
8233 }
8234 }
8235
Thierry Strudel54dc9782017-02-15 12:12:10 -08008236 // EXIF debug data through vendor tag
8237 /*
8238 * Mobicat Mask can assume 3 values:
8239 * 1 refers to Mobicat data,
8240 * 2 refers to Stats Debug and Exif Debug Data
8241 * 3 refers to Mobicat and Stats Debug Data
8242 * We want to make sure that we are sending Exif debug data
8243 * only when Mobicat Mask is 2.
8244 */
8245 if ((mExifParams.debug_params != NULL) && (getMobicatMask() == 2)) {
8246 camMetadata.update(QCAMERA3_HAL_PRIVATEDATA_EXIF_DEBUG_DATA_BLOB,
8247 (uint8_t *)(void *)mExifParams.debug_params,
8248 sizeof(mm_jpeg_debug_exif_params_t));
8249 }
8250
Thierry Strudelcca4d9c2016-10-20 08:25:53 -07008251 // Reprocess and DDM debug data through vendor tag
8252 cam_reprocess_info_t repro_info;
8253 memset(&repro_info, 0, sizeof(cam_reprocess_info_t));
Thierry Strudel3d639192016-09-09 11:52:26 -07008254 IF_META_AVAILABLE(cam_stream_crop_info_t, sensorCropInfo,
8255 CAM_INTF_META_SNAP_CROP_INFO_SENSOR, metadata) {
Thierry Strudelcca4d9c2016-10-20 08:25:53 -07008256 memcpy(&(repro_info.sensor_crop_info), sensorCropInfo, sizeof(cam_stream_crop_info_t));
Thierry Strudel3d639192016-09-09 11:52:26 -07008257 }
8258 IF_META_AVAILABLE(cam_stream_crop_info_t, camifCropInfo,
8259 CAM_INTF_META_SNAP_CROP_INFO_CAMIF, metadata) {
Thierry Strudelcca4d9c2016-10-20 08:25:53 -07008260 memcpy(&(repro_info.camif_crop_info), camifCropInfo, sizeof(cam_stream_crop_info_t));
Thierry Strudel3d639192016-09-09 11:52:26 -07008261 }
8262 IF_META_AVAILABLE(cam_stream_crop_info_t, ispCropInfo,
8263 CAM_INTF_META_SNAP_CROP_INFO_ISP, metadata) {
Thierry Strudelcca4d9c2016-10-20 08:25:53 -07008264 memcpy(&(repro_info.isp_crop_info), ispCropInfo, sizeof(cam_stream_crop_info_t));
Thierry Strudel3d639192016-09-09 11:52:26 -07008265 }
8266 IF_META_AVAILABLE(cam_stream_crop_info_t, cppCropInfo,
8267 CAM_INTF_META_SNAP_CROP_INFO_CPP, metadata) {
Thierry Strudelcca4d9c2016-10-20 08:25:53 -07008268 memcpy(&(repro_info.cpp_crop_info), cppCropInfo, sizeof(cam_stream_crop_info_t));
Thierry Strudel3d639192016-09-09 11:52:26 -07008269 }
8270 IF_META_AVAILABLE(cam_focal_length_ratio_t, ratio,
8271 CAM_INTF_META_AF_FOCAL_LENGTH_RATIO, metadata) {
Thierry Strudelcca4d9c2016-10-20 08:25:53 -07008272 memcpy(&(repro_info.af_focal_length_ratio), ratio, sizeof(cam_focal_length_ratio_t));
Thierry Strudel3d639192016-09-09 11:52:26 -07008273 }
8274 IF_META_AVAILABLE(int32_t, flip, CAM_INTF_PARM_FLIP, metadata) {
Thierry Strudelcca4d9c2016-10-20 08:25:53 -07008275 memcpy(&(repro_info.pipeline_flip), flip, sizeof(int32_t));
Thierry Strudel3d639192016-09-09 11:52:26 -07008276 }
8277 IF_META_AVAILABLE(cam_rotation_info_t, rotationInfo,
8278 CAM_INTF_PARM_ROTATION, metadata) {
Thierry Strudelcca4d9c2016-10-20 08:25:53 -07008279 memcpy(&(repro_info.rotation_info), rotationInfo, sizeof(cam_rotation_info_t));
Thierry Strudel3d639192016-09-09 11:52:26 -07008280 }
Thierry Strudelcca4d9c2016-10-20 08:25:53 -07008281 IF_META_AVAILABLE(cam_area_t, afRoi, CAM_INTF_META_AF_ROI, metadata) {
8282 memcpy(&(repro_info.af_roi), afRoi, sizeof(cam_area_t));
8283 }
8284 IF_META_AVAILABLE(cam_dyn_img_data_t, dynMask, CAM_INTF_META_IMG_DYN_FEAT, metadata) {
8285 memcpy(&(repro_info.dyn_mask), dynMask, sizeof(cam_dyn_img_data_t));
8286 }
8287 camMetadata.update(QCAMERA3_HAL_PRIVATEDATA_REPROCESS_DATA_BLOB,
8288 (uint8_t *)&repro_info, sizeof(cam_reprocess_info_t));
Thierry Strudel3d639192016-09-09 11:52:26 -07008289
Thierry Strudel295a0ca2016-11-03 18:38:47 -07008290 // INSTANT AEC MODE
8291 IF_META_AVAILABLE(uint8_t, instant_aec_mode,
8292 CAM_INTF_PARM_INSTANT_AEC, metadata) {
8293 camMetadata.update(QCAMERA3_INSTANT_AEC_MODE, instant_aec_mode, 1);
8294 }
8295
Shuzhen Wange763e802016-03-31 10:24:29 -07008296 // AF scene change
8297 IF_META_AVAILABLE(uint8_t, afSceneChange, CAM_INTF_META_AF_SCENE_CHANGE, metadata) {
8298 camMetadata.update(NEXUS_EXPERIMENTAL_2016_AF_SCENE_CHANGE, afSceneChange, 1);
Chien-Yu Chenc5494e52018-01-19 17:53:58 -08008299 camMetadata.update(ANDROID_CONTROL_AF_SCENE_CHANGE, afSceneChange, 1);
Shuzhen Wange763e802016-03-31 10:24:29 -07008300 }
8301
Chien-Yu Chen66ec22a2017-04-13 18:00:36 -07008302 // Enable ZSL
8303 if (enableZsl != nullptr) {
8304 uint8_t value = *enableZsl ?
8305 ANDROID_CONTROL_ENABLE_ZSL_TRUE : ANDROID_CONTROL_ENABLE_ZSL_FALSE;
8306 camMetadata.update(ANDROID_CONTROL_ENABLE_ZSL, &value, 1);
8307 }
8308
Chien-Yu Chen7f9a15b2018-01-23 16:13:31 -08008309 camMetadata.update(ANDROID_STATISTICS_OIS_DATA_MODE, &pendingRequest.requestedOisDataMode, 1);
8310
Xu Han821ea9c2017-05-23 09:00:40 -07008311 // OIS Data
8312 IF_META_AVAILABLE(cam_frame_ois_info_t, frame_ois_data, CAM_INTF_META_FRAME_OIS_DATA, metadata) {
Xu Han821ea9c2017-05-23 09:00:40 -07008313 camMetadata.update(NEXUS_EXPERIMENTAL_2017_OIS_FRAME_TIMESTAMP_BOOTTIME,
8314 &(frame_ois_data->frame_sof_timestamp_boottime), 1);
8315 camMetadata.update(NEXUS_EXPERIMENTAL_2017_OIS_TIMESTAMPS_BOOTTIME,
8316 frame_ois_data->ois_sample_timestamp_boottime, frame_ois_data->num_ois_sample);
Xue Tu2c3e9142017-08-18 16:23:52 -07008317 camMetadata.update(NEXUS_EXPERIMENTAL_2017_OIS_SHIFT_PIXEL_X,
8318 frame_ois_data->ois_sample_shift_pixel_x, frame_ois_data->num_ois_sample);
8319 camMetadata.update(NEXUS_EXPERIMENTAL_2017_OIS_SHIFT_PIXEL_Y,
8320 frame_ois_data->ois_sample_shift_pixel_y, frame_ois_data->num_ois_sample);
Chien-Yu Chen7f9a15b2018-01-23 16:13:31 -08008321
8322 if (pendingRequest.requestedOisDataMode == ANDROID_STATISTICS_OIS_DATA_MODE_ON) {
8323 int64_t timeDiff = pendingRequest.timestamp -
8324 frame_ois_data->frame_sof_timestamp_boottime;
8325
8326 std::vector<int64_t> oisTimestamps;
8327
8328 for (int32_t i = 0; i < frame_ois_data->num_ois_sample; i++) {
8329 oisTimestamps.push_back(
8330 frame_ois_data->ois_sample_timestamp_boottime[i] + timeDiff);
8331 }
8332
8333 camMetadata.update(ANDROID_STATISTICS_OIS_TIMESTAMPS,
8334 oisTimestamps.data(), frame_ois_data->num_ois_sample);
8335 camMetadata.update(ANDROID_STATISTICS_OIS_X_SHIFTS,
8336 frame_ois_data->ois_sample_shift_pixel_x, frame_ois_data->num_ois_sample);
8337 camMetadata.update(ANDROID_STATISTICS_OIS_Y_SHIFTS,
8338 frame_ois_data->ois_sample_shift_pixel_y, frame_ois_data->num_ois_sample);
Chien-Yu Chen29a56032018-01-24 16:58:35 -08008339 } else {
8340 // If OIS data mode is OFF, add NULL for OIS keys.
8341 camMetadata.update(ANDROID_STATISTICS_OIS_TIMESTAMPS,
8342 frame_ois_data->ois_sample_timestamp_boottime, 0);
8343 camMetadata.update(ANDROID_STATISTICS_OIS_X_SHIFTS,
8344 frame_ois_data->ois_sample_shift_pixel_x, 0);
8345 camMetadata.update(ANDROID_STATISTICS_OIS_Y_SHIFTS,
8346 frame_ois_data->ois_sample_shift_pixel_y, 0);
Chien-Yu Chen7f9a15b2018-01-23 16:13:31 -08008347 }
Xu Han821ea9c2017-05-23 09:00:40 -07008348 }
8349
Wei (Alex) Honga90a2142018-01-05 17:36:52 -08008350 // DevCamDebug metadata translateFromHalMetadata AEC MOTION
8351 IF_META_AVAILABLE(float, DevCamDebug_aec_camera_motion_dx,
8352 CAM_INTF_META_DEV_CAM_AEC_CAMERA_MOTION_DX, metadata) {
8353 float fwk_DevCamDebug_aec_camera_motion_dx = *DevCamDebug_aec_camera_motion_dx;
8354 camMetadata.update(NEXUS_EXPERIMENTAL_2017_CAMERA_MOTION_X,
8355 &fwk_DevCamDebug_aec_camera_motion_dx, 1);
8356 }
8357 IF_META_AVAILABLE(float, DevCamDebug_aec_camera_motion_dy,
8358 CAM_INTF_META_DEV_CAM_AEC_CAMERA_MOTION_DY, metadata) {
8359 float fwk_DevCamDebug_aec_camera_motion_dy = *DevCamDebug_aec_camera_motion_dy;
8360 camMetadata.update(NEXUS_EXPERIMENTAL_2017_CAMERA_MOTION_Y,
8361 &fwk_DevCamDebug_aec_camera_motion_dy, 1);
8362 }
8363 IF_META_AVAILABLE(float, DevCamDebug_aec_subject_motion,
8364 CAM_INTF_META_DEV_CAM_AEC_SUBJECT_MOTION, metadata) {
8365 float fwk_DevCamDebug_aec_subject_motion = *DevCamDebug_aec_subject_motion;
8366 camMetadata.update(NEXUS_EXPERIMENTAL_2017_SUBJECT_MOTION,
8367 &fwk_DevCamDebug_aec_subject_motion, 1);
8368 }
8369
Eino-Ville Talvalad9221d22018-04-12 16:32:04 -07008370 // Camera lens calibration dynamic fields, for back camera. Same values as for static metadata.
8371 if (mCameraId == 0) {
8372 const camera_metadata_t *staticInfo = gStaticMetadata[mCameraId];
8373 camera_metadata_ro_entry_t rotation, translation, intrinsics, distortion, reference;
8374 int res;
8375 bool fail = false;
8376 res = find_camera_metadata_ro_entry(staticInfo, ANDROID_LENS_POSE_ROTATION,
8377 &rotation);
8378 if (res != 0) {
8379 fail = true;
8380 }
8381 res = find_camera_metadata_ro_entry(staticInfo, ANDROID_LENS_POSE_TRANSLATION,
8382 &translation);
8383 if (res != 0) {
8384 fail = true;
8385 }
8386 res = find_camera_metadata_ro_entry(staticInfo, ANDROID_LENS_INTRINSIC_CALIBRATION,
8387 &intrinsics);
8388 if (res != 0) {
8389 fail = true;
8390 }
8391 res = find_camera_metadata_ro_entry(staticInfo, ANDROID_LENS_DISTORTION,
8392 &distortion);
8393 if (res != 0) {
8394 fail = true;
8395 }
8396 res = find_camera_metadata_ro_entry(staticInfo, ANDROID_LENS_POSE_REFERENCE,
8397 &reference);
8398 if (res != 0) {
8399 fail = true;
8400 }
8401
8402 if (!fail) {
8403 camMetadata.update(ANDROID_LENS_POSE_ROTATION,
8404 rotation.data.f, rotation.count);
8405 camMetadata.update(ANDROID_LENS_POSE_TRANSLATION,
8406 translation.data.f, translation.count);
8407 camMetadata.update(ANDROID_LENS_INTRINSIC_CALIBRATION,
8408 intrinsics.data.f, intrinsics.count);
8409 camMetadata.update(ANDROID_LENS_DISTORTION,
8410 distortion.data.f, distortion.count);
8411 camMetadata.update(ANDROID_LENS_POSE_REFERENCE,
8412 reference.data.u8, reference.count);
8413 }
8414 }
8415
Thierry Strudel3d639192016-09-09 11:52:26 -07008416 resultMetadata = camMetadata.release();
8417 return resultMetadata;
8418}
8419
8420/*===========================================================================
8421 * FUNCTION : saveExifParams
8422 *
8423 * DESCRIPTION:
8424 *
8425 * PARAMETERS :
8426 * @metadata : metadata information from callback
8427 *
8428 * RETURN : none
8429 *
8430 *==========================================================================*/
8431void QCamera3HardwareInterface::saveExifParams(metadata_buffer_t *metadata)
8432{
8433 IF_META_AVAILABLE(cam_ae_exif_debug_t, ae_exif_debug_params,
8434 CAM_INTF_META_EXIF_DEBUG_AE, metadata) {
8435 if (mExifParams.debug_params) {
8436 mExifParams.debug_params->ae_debug_params = *ae_exif_debug_params;
8437 mExifParams.debug_params->ae_debug_params_valid = TRUE;
8438 }
8439 }
8440 IF_META_AVAILABLE(cam_awb_exif_debug_t,awb_exif_debug_params,
8441 CAM_INTF_META_EXIF_DEBUG_AWB, metadata) {
8442 if (mExifParams.debug_params) {
8443 mExifParams.debug_params->awb_debug_params = *awb_exif_debug_params;
8444 mExifParams.debug_params->awb_debug_params_valid = TRUE;
8445 }
8446 }
8447 IF_META_AVAILABLE(cam_af_exif_debug_t,af_exif_debug_params,
8448 CAM_INTF_META_EXIF_DEBUG_AF, metadata) {
8449 if (mExifParams.debug_params) {
8450 mExifParams.debug_params->af_debug_params = *af_exif_debug_params;
8451 mExifParams.debug_params->af_debug_params_valid = TRUE;
8452 }
8453 }
8454 IF_META_AVAILABLE(cam_asd_exif_debug_t, asd_exif_debug_params,
8455 CAM_INTF_META_EXIF_DEBUG_ASD, metadata) {
8456 if (mExifParams.debug_params) {
8457 mExifParams.debug_params->asd_debug_params = *asd_exif_debug_params;
8458 mExifParams.debug_params->asd_debug_params_valid = TRUE;
8459 }
8460 }
8461 IF_META_AVAILABLE(cam_stats_buffer_exif_debug_t,stats_exif_debug_params,
8462 CAM_INTF_META_EXIF_DEBUG_STATS, metadata) {
8463 if (mExifParams.debug_params) {
8464 mExifParams.debug_params->stats_debug_params = *stats_exif_debug_params;
8465 mExifParams.debug_params->stats_debug_params_valid = TRUE;
8466 }
8467 }
8468 IF_META_AVAILABLE(cam_bestats_buffer_exif_debug_t,bestats_exif_debug_params,
8469 CAM_INTF_META_EXIF_DEBUG_BESTATS, metadata) {
8470 if (mExifParams.debug_params) {
8471 mExifParams.debug_params->bestats_debug_params = *bestats_exif_debug_params;
8472 mExifParams.debug_params->bestats_debug_params_valid = TRUE;
8473 }
8474 }
8475 IF_META_AVAILABLE(cam_bhist_buffer_exif_debug_t, bhist_exif_debug_params,
8476 CAM_INTF_META_EXIF_DEBUG_BHIST, metadata) {
8477 if (mExifParams.debug_params) {
8478 mExifParams.debug_params->bhist_debug_params = *bhist_exif_debug_params;
8479 mExifParams.debug_params->bhist_debug_params_valid = TRUE;
8480 }
8481 }
8482 IF_META_AVAILABLE(cam_q3a_tuning_info_t, q3a_tuning_exif_debug_params,
8483 CAM_INTF_META_EXIF_DEBUG_3A_TUNING, metadata) {
8484 if (mExifParams.debug_params) {
8485 mExifParams.debug_params->q3a_tuning_debug_params = *q3a_tuning_exif_debug_params;
8486 mExifParams.debug_params->q3a_tuning_debug_params_valid = TRUE;
8487 }
8488 }
8489}
8490
8491/*===========================================================================
8492 * FUNCTION : get3AExifParams
8493 *
8494 * DESCRIPTION:
8495 *
8496 * PARAMETERS : none
8497 *
8498 *
8499 * RETURN : mm_jpeg_exif_params_t
8500 *
8501 *==========================================================================*/
8502mm_jpeg_exif_params_t QCamera3HardwareInterface::get3AExifParams()
8503{
8504 return mExifParams;
8505}
8506
8507/*===========================================================================
8508 * FUNCTION : translateCbUrgentMetadataToResultMetadata
8509 *
8510 * DESCRIPTION:
8511 *
8512 * PARAMETERS :
8513 * @metadata : metadata information from callback
Shuzhen Wang94ddf072017-03-12 19:47:23 -07008514 * @lastUrgentMetadataInBatch: Boolean to indicate whether this is the last
8515 * urgent metadata in a batch. Always true for
8516 * non-batch mode.
Shuzhen Wang181c57b2017-07-21 11:39:44 -07008517 * @frame_number : frame number for this urgent metadata
Shuzhen Wang485e2442017-08-02 12:21:08 -07008518 * @isJumpstartMetadata: Whether this is a partial metadata for jumpstart,
8519 * i.e. even though it doesn't map to a valid partial
8520 * frame number, its metadata entries should be kept.
Thierry Strudel3d639192016-09-09 11:52:26 -07008521 * RETURN : camera_metadata_t*
8522 * metadata in a format specified by fwk
8523 *==========================================================================*/
8524camera_metadata_t*
8525QCamera3HardwareInterface::translateCbUrgentMetadataToResultMetadata
Shuzhen Wang181c57b2017-07-21 11:39:44 -07008526 (metadata_buffer_t *metadata, bool lastUrgentMetadataInBatch,
Shuzhen Wang485e2442017-08-02 12:21:08 -07008527 uint32_t frame_number, bool isJumpstartMetadata)
Thierry Strudel3d639192016-09-09 11:52:26 -07008528{
8529 CameraMetadata camMetadata;
8530 camera_metadata_t *resultMetadata;
8531
Shuzhen Wang485e2442017-08-02 12:21:08 -07008532 if (!lastUrgentMetadataInBatch && !isJumpstartMetadata) {
Shuzhen Wang94ddf072017-03-12 19:47:23 -07008533 /* In batch mode, use empty metadata if this is not the last in batch
8534 */
8535 resultMetadata = allocate_camera_metadata(0, 0);
8536 return resultMetadata;
8537 }
Thierry Strudel3d639192016-09-09 11:52:26 -07008538
8539 IF_META_AVAILABLE(uint32_t, whiteBalanceState, CAM_INTF_META_AWB_STATE, metadata) {
8540 uint8_t fwk_whiteBalanceState = (uint8_t) *whiteBalanceState;
8541 camMetadata.update(ANDROID_CONTROL_AWB_STATE, &fwk_whiteBalanceState, 1);
8542 LOGD("urgent Metadata : ANDROID_CONTROL_AWB_STATE %u", *whiteBalanceState);
8543 }
8544
8545 IF_META_AVAILABLE(cam_trigger_t, aecTrigger, CAM_INTF_META_AEC_PRECAPTURE_TRIGGER, metadata) {
8546 camMetadata.update(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
8547 &aecTrigger->trigger, 1);
8548 camMetadata.update(ANDROID_CONTROL_AE_PRECAPTURE_ID,
8549 &aecTrigger->trigger_id, 1);
8550 LOGD("urgent Metadata : CAM_INTF_META_AEC_PRECAPTURE_TRIGGER: %d",
8551 aecTrigger->trigger);
8552 LOGD("urgent Metadata : ANDROID_CONTROL_AE_PRECAPTURE_ID: %d",
8553 aecTrigger->trigger_id);
8554 }
8555
8556 IF_META_AVAILABLE(uint32_t, ae_state, CAM_INTF_META_AEC_STATE, metadata) {
8557 uint8_t fwk_ae_state = (uint8_t) *ae_state;
8558 camMetadata.update(ANDROID_CONTROL_AE_STATE, &fwk_ae_state, 1);
8559 LOGD("urgent Metadata : ANDROID_CONTROL_AE_STATE %u", *ae_state);
8560 }
8561
Shuzhen Wang181c57b2017-07-21 11:39:44 -07008562 IF_META_AVAILABLE(uint32_t, focusMode, CAM_INTF_PARM_FOCUS_MODE, metadata) {
8563 int val = lookupFwkName(FOCUS_MODES_MAP, METADATA_MAP_SIZE(FOCUS_MODES_MAP), *focusMode);
8564 if (NAME_NOT_FOUND != val) {
8565 uint8_t fwkAfMode = (uint8_t)val;
8566 camMetadata.update(ANDROID_CONTROL_AF_MODE, &fwkAfMode, 1);
8567 LOGD("urgent Metadata : ANDROID_CONTROL_AF_MODE %d", val);
8568 } else {
8569 LOGH("urgent Metadata not found : ANDROID_CONTROL_AF_MODE %d",
8570 val);
8571 }
Thierry Strudel3d639192016-09-09 11:52:26 -07008572 }
8573
Shuzhen Wang181c57b2017-07-21 11:39:44 -07008574 IF_META_AVAILABLE(cam_trigger_t, af_trigger, CAM_INTF_META_AF_TRIGGER, metadata) {
8575 LOGD("urgent Metadata : CAM_INTF_META_AF_TRIGGER = %d",
8576 af_trigger->trigger);
8577 LOGD("urgent Metadata : ANDROID_CONTROL_AF_TRIGGER_ID = %d",
8578 af_trigger->trigger_id);
8579
8580 IF_META_AVAILABLE(uint32_t, afState, CAM_INTF_META_AF_STATE, metadata) {
8581 mAfTrigger = *af_trigger;
8582 uint32_t fwk_AfState = (uint32_t) *afState;
8583
8584 // If this is the result for a new trigger, check if there is new early
8585 // af state. If there is, use the last af state for all results
8586 // preceding current partial frame number.
8587 for (auto & pendingRequest : mPendingRequestsList) {
8588 if (pendingRequest.frame_number < frame_number) {
8589 pendingRequest.focusStateValid = true;
8590 pendingRequest.focusState = fwk_AfState;
8591 } else if (pendingRequest.frame_number == frame_number) {
8592 IF_META_AVAILABLE(uint32_t, earlyAfState, CAM_INTF_META_EARLY_AF_STATE, metadata) {
8593 // Check if early AF state for trigger exists. If yes, send AF state as
8594 // partial result for better latency.
8595 uint8_t fwkEarlyAfState = (uint8_t) *earlyAfState;
8596 pendingRequest.focusStateSent = true;
8597 camMetadata.update(ANDROID_CONTROL_AF_STATE, &fwkEarlyAfState, 1);
8598 LOGD("urgent Metadata(%d) : ANDROID_CONTROL_AF_STATE %u",
8599 frame_number, fwkEarlyAfState);
8600 }
8601 }
8602 }
8603 }
8604 }
8605 camMetadata.update(ANDROID_CONTROL_AF_TRIGGER,
8606 &mAfTrigger.trigger, 1);
8607 camMetadata.update(ANDROID_CONTROL_AF_TRIGGER_ID, &mAfTrigger.trigger_id, 1);
8608
Shuzhen Wang6ce35e62017-03-27 18:00:41 -07008609 IF_META_AVAILABLE(cam_area_t, hAfRegions, CAM_INTF_META_AF_ROI, metadata) {
8610 /*af regions*/
Shuzhen Wang91c14e82017-08-21 17:56:57 -07008611 cam_rect_t hAfRect = hAfRegions->rect;
Shuzhen Wang6ce35e62017-03-27 18:00:41 -07008612 int32_t afRegions[REGIONS_TUPLE_COUNT];
8613 // Adjust crop region from sensor output coordinate system to active
8614 // array coordinate system.
Shuzhen Wang91c14e82017-08-21 17:56:57 -07008615 mCropRegionMapper.toActiveArray(hAfRect.left, hAfRect.top,
8616 hAfRect.width, hAfRect.height);
Shuzhen Wang6ce35e62017-03-27 18:00:41 -07008617
Shuzhen Wang91c14e82017-08-21 17:56:57 -07008618 convertToRegions(hAfRect, afRegions, hAfRegions->weight);
Shuzhen Wang6ce35e62017-03-27 18:00:41 -07008619 camMetadata.update(ANDROID_CONTROL_AF_REGIONS, afRegions,
8620 REGIONS_TUPLE_COUNT);
8621 LOGD("Metadata : ANDROID_CONTROL_AF_REGIONS: FWK: [%d,%d,%d,%d] HAL: [%d,%d,%d,%d]",
8622 afRegions[0], afRegions[1], afRegions[2], afRegions[3],
Shuzhen Wang91c14e82017-08-21 17:56:57 -07008623 hAfRect.left, hAfRect.top, hAfRect.width,
8624 hAfRect.height);
Shuzhen Wang6ce35e62017-03-27 18:00:41 -07008625 }
8626
Shuzhen Wangcc386c52017-03-29 09:28:08 -07008627 // AF region confidence
8628 IF_META_AVAILABLE(int32_t, afRegionConfidence, CAM_INTF_META_AF_REGIONS_CONFIDENCE, metadata) {
8629 camMetadata.update(NEXUS_EXPERIMENTAL_2017_AF_REGIONS_CONFIDENCE, afRegionConfidence, 1);
8630 }
8631
Thierry Strudel3d639192016-09-09 11:52:26 -07008632 IF_META_AVAILABLE(int32_t, whiteBalance, CAM_INTF_PARM_WHITE_BALANCE, metadata) {
8633 int val = lookupFwkName(WHITE_BALANCE_MODES_MAP,
8634 METADATA_MAP_SIZE(WHITE_BALANCE_MODES_MAP), *whiteBalance);
8635 if (NAME_NOT_FOUND != val) {
8636 uint8_t fwkWhiteBalanceMode = (uint8_t)val;
8637 camMetadata.update(ANDROID_CONTROL_AWB_MODE, &fwkWhiteBalanceMode, 1);
8638 LOGD("urgent Metadata : ANDROID_CONTROL_AWB_MODE %d", val);
8639 } else {
8640 LOGH("urgent Metadata not found : ANDROID_CONTROL_AWB_MODE");
8641 }
8642 }
8643
8644 uint8_t fwk_aeMode = ANDROID_CONTROL_AE_MODE_OFF;
8645 uint32_t aeMode = CAM_AE_MODE_MAX;
8646 int32_t flashMode = CAM_FLASH_MODE_MAX;
8647 int32_t redeye = -1;
8648 IF_META_AVAILABLE(uint32_t, pAeMode, CAM_INTF_META_AEC_MODE, metadata) {
8649 aeMode = *pAeMode;
8650 }
8651 IF_META_AVAILABLE(int32_t, pFlashMode, CAM_INTF_PARM_LED_MODE, metadata) {
8652 flashMode = *pFlashMode;
8653 }
8654 IF_META_AVAILABLE(int32_t, pRedeye, CAM_INTF_PARM_REDEYE_REDUCTION, metadata) {
8655 redeye = *pRedeye;
8656 }
8657
8658 if (1 == redeye) {
8659 fwk_aeMode = ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE;
8660 camMetadata.update(ANDROID_CONTROL_AE_MODE, &fwk_aeMode, 1);
8661 } else if ((CAM_FLASH_MODE_AUTO == flashMode) || (CAM_FLASH_MODE_ON == flashMode)) {
8662 int val = lookupFwkName(AE_FLASH_MODE_MAP, METADATA_MAP_SIZE(AE_FLASH_MODE_MAP),
8663 flashMode);
8664 if (NAME_NOT_FOUND != val) {
8665 fwk_aeMode = (uint8_t)val;
8666 camMetadata.update(ANDROID_CONTROL_AE_MODE, &fwk_aeMode, 1);
8667 } else {
8668 LOGE("Unsupported flash mode %d", flashMode);
8669 }
8670 } else if (aeMode == CAM_AE_MODE_ON) {
8671 fwk_aeMode = ANDROID_CONTROL_AE_MODE_ON;
8672 camMetadata.update(ANDROID_CONTROL_AE_MODE, &fwk_aeMode, 1);
8673 } else if (aeMode == CAM_AE_MODE_OFF) {
8674 fwk_aeMode = ANDROID_CONTROL_AE_MODE_OFF;
8675 camMetadata.update(ANDROID_CONTROL_AE_MODE, &fwk_aeMode, 1);
Eino-Ville Talvalae2de8432017-02-25 11:11:13 -08008676 } else if (aeMode == CAM_AE_MODE_ON_EXTERNAL_FLASH) {
Chien-Yu Chenc5494e52018-01-19 17:53:58 -08008677 fwk_aeMode = ANDROID_CONTROL_AE_MODE_ON_EXTERNAL_FLASH;
Eino-Ville Talvalae2de8432017-02-25 11:11:13 -08008678 camMetadata.update(ANDROID_CONTROL_AE_MODE, &fwk_aeMode, 1);
Thierry Strudel3d639192016-09-09 11:52:26 -07008679 } else {
8680 LOGE("Not enough info to deduce ANDROID_CONTROL_AE_MODE redeye:%d, "
8681 "flashMode:%d, aeMode:%u!!!",
8682 redeye, flashMode, aeMode);
8683 }
Thierry Strudel295a0ca2016-11-03 18:38:47 -07008684 if (mInstantAEC) {
8685 // Increment frame Idx count untill a bound reached for instant AEC.
8686 mInstantAecFrameIdxCount++;
8687 IF_META_AVAILABLE(cam_3a_params_t, ae_params,
8688 CAM_INTF_META_AEC_INFO, metadata) {
8689 LOGH("ae_params->settled = %d",ae_params->settled);
8690 // If AEC settled, or if number of frames reached bound value,
8691 // should reset instant AEC.
8692 if (ae_params->settled ||
8693 (mInstantAecFrameIdxCount > mAecSkipDisplayFrameBound)) {
8694 LOGH("AEC settled or Frames reached instantAEC bound, resetting instantAEC");
8695 mInstantAEC = false;
8696 mResetInstantAEC = true;
8697 mInstantAecFrameIdxCount = 0;
8698 }
8699 }
8700 }
Shuzhen Wang3569d4a2017-09-04 19:10:28 -07008701
8702 IF_META_AVAILABLE(int32_t, af_tof_confidence,
8703 CAM_INTF_META_AF_TOF_CONFIDENCE, metadata) {
8704 IF_META_AVAILABLE(int32_t, af_tof_distance,
8705 CAM_INTF_META_AF_TOF_DISTANCE, metadata) {
8706 int32_t fwk_af_tof_confidence = *af_tof_confidence;
8707 int32_t fwk_af_tof_distance = *af_tof_distance;
8708 if (fwk_af_tof_confidence == 1) {
8709 mSceneDistance = fwk_af_tof_distance;
8710 } else {
8711 mSceneDistance = -1;
8712 }
8713 LOGD("tof_distance %d, tof_confidence %d, mSceneDistance %d",
8714 fwk_af_tof_distance, fwk_af_tof_confidence, mSceneDistance);
8715 }
8716 }
8717 camMetadata.update(NEXUS_EXPERIMENTAL_2017_SCENE_DISTANCE, &mSceneDistance, 1);
8718
Thierry Strudel3d639192016-09-09 11:52:26 -07008719 resultMetadata = camMetadata.release();
8720 return resultMetadata;
8721}
8722
8723/*===========================================================================
8724 * FUNCTION : dumpMetadataToFile
8725 *
8726 * DESCRIPTION: Dumps tuning metadata to file system
8727 *
8728 * PARAMETERS :
8729 * @meta : tuning metadata
8730 * @dumpFrameCount : current dump frame count
8731 * @enabled : Enable mask
8732 *
8733 *==========================================================================*/
8734void QCamera3HardwareInterface::dumpMetadataToFile(tuning_params_t &meta,
8735 uint32_t &dumpFrameCount,
8736 bool enabled,
8737 const char *type,
8738 uint32_t frameNumber)
8739{
8740 //Some sanity checks
8741 if (meta.tuning_sensor_data_size > TUNING_SENSOR_DATA_MAX) {
8742 LOGE("Tuning sensor data size bigger than expected %d: %d",
8743 meta.tuning_sensor_data_size,
8744 TUNING_SENSOR_DATA_MAX);
8745 return;
8746 }
8747
8748 if (meta.tuning_vfe_data_size > TUNING_VFE_DATA_MAX) {
8749 LOGE("Tuning VFE data size bigger than expected %d: %d",
8750 meta.tuning_vfe_data_size,
8751 TUNING_VFE_DATA_MAX);
8752 return;
8753 }
8754
8755 if (meta.tuning_cpp_data_size > TUNING_CPP_DATA_MAX) {
8756 LOGE("Tuning CPP data size bigger than expected %d: %d",
8757 meta.tuning_cpp_data_size,
8758 TUNING_CPP_DATA_MAX);
8759 return;
8760 }
8761
8762 if (meta.tuning_cac_data_size > TUNING_CAC_DATA_MAX) {
8763 LOGE("Tuning CAC data size bigger than expected %d: %d",
8764 meta.tuning_cac_data_size,
8765 TUNING_CAC_DATA_MAX);
8766 return;
8767 }
8768 //
8769
8770 if(enabled){
8771 char timeBuf[FILENAME_MAX];
8772 char buf[FILENAME_MAX];
8773 memset(buf, 0, sizeof(buf));
8774 memset(timeBuf, 0, sizeof(timeBuf));
8775 time_t current_time;
8776 struct tm * timeinfo;
8777 time (&current_time);
8778 timeinfo = localtime (&current_time);
8779 if (timeinfo != NULL) {
8780 strftime (timeBuf, sizeof(timeBuf),
8781 QCAMERA_DUMP_FRM_LOCATION"%Y%m%d%H%M%S", timeinfo);
8782 }
8783 String8 filePath(timeBuf);
8784 snprintf(buf,
8785 sizeof(buf),
8786 "%dm_%s_%d.bin",
8787 dumpFrameCount,
8788 type,
8789 frameNumber);
8790 filePath.append(buf);
8791 int file_fd = open(filePath.string(), O_RDWR | O_CREAT, 0777);
8792 if (file_fd >= 0) {
8793 ssize_t written_len = 0;
8794 meta.tuning_data_version = TUNING_DATA_VERSION;
8795 void *data = (void *)((uint8_t *)&meta.tuning_data_version);
8796 written_len += write(file_fd, data, sizeof(uint32_t));
8797 data = (void *)((uint8_t *)&meta.tuning_sensor_data_size);
8798 LOGD("tuning_sensor_data_size %d",(int)(*(int *)data));
8799 written_len += write(file_fd, data, sizeof(uint32_t));
8800 data = (void *)((uint8_t *)&meta.tuning_vfe_data_size);
8801 LOGD("tuning_vfe_data_size %d",(int)(*(int *)data));
8802 written_len += write(file_fd, data, sizeof(uint32_t));
8803 data = (void *)((uint8_t *)&meta.tuning_cpp_data_size);
8804 LOGD("tuning_cpp_data_size %d",(int)(*(int *)data));
8805 written_len += write(file_fd, data, sizeof(uint32_t));
8806 data = (void *)((uint8_t *)&meta.tuning_cac_data_size);
8807 LOGD("tuning_cac_data_size %d",(int)(*(int *)data));
8808 written_len += write(file_fd, data, sizeof(uint32_t));
8809 meta.tuning_mod3_data_size = 0;
8810 data = (void *)((uint8_t *)&meta.tuning_mod3_data_size);
8811 LOGD("tuning_mod3_data_size %d",(int)(*(int *)data));
8812 written_len += write(file_fd, data, sizeof(uint32_t));
8813 size_t total_size = meta.tuning_sensor_data_size;
8814 data = (void *)((uint8_t *)&meta.data);
8815 written_len += write(file_fd, data, total_size);
8816 total_size = meta.tuning_vfe_data_size;
8817 data = (void *)((uint8_t *)&meta.data[TUNING_VFE_DATA_OFFSET]);
8818 written_len += write(file_fd, data, total_size);
8819 total_size = meta.tuning_cpp_data_size;
8820 data = (void *)((uint8_t *)&meta.data[TUNING_CPP_DATA_OFFSET]);
8821 written_len += write(file_fd, data, total_size);
8822 total_size = meta.tuning_cac_data_size;
8823 data = (void *)((uint8_t *)&meta.data[TUNING_CAC_DATA_OFFSET]);
8824 written_len += write(file_fd, data, total_size);
8825 close(file_fd);
8826 }else {
8827 LOGE("fail to open file for metadata dumping");
8828 }
8829 }
8830}
8831
8832/*===========================================================================
8833 * FUNCTION : cleanAndSortStreamInfo
8834 *
8835 * DESCRIPTION: helper method to clean up invalid streams in stream_info,
8836 * and sort them such that raw stream is at the end of the list
8837 * This is a workaround for camera daemon constraint.
8838 *
8839 * PARAMETERS : None
8840 *
8841 *==========================================================================*/
8842void QCamera3HardwareInterface::cleanAndSortStreamInfo()
8843{
8844 List<stream_info_t *> newStreamInfo;
8845
8846 /*clean up invalid streams*/
8847 for (List<stream_info_t*>::iterator it=mStreamInfo.begin();
8848 it != mStreamInfo.end();) {
8849 if(((*it)->status) == INVALID){
8850 QCamera3Channel *channel = (QCamera3Channel*)(*it)->stream->priv;
8851 delete channel;
8852 free(*it);
8853 it = mStreamInfo.erase(it);
8854 } else {
8855 it++;
8856 }
8857 }
8858
8859 // Move preview/video/callback/snapshot streams into newList
8860 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
8861 it != mStreamInfo.end();) {
8862 if ((*it)->stream->format != HAL_PIXEL_FORMAT_RAW_OPAQUE &&
8863 (*it)->stream->format != HAL_PIXEL_FORMAT_RAW10 &&
8864 (*it)->stream->format != HAL_PIXEL_FORMAT_RAW16) {
8865 newStreamInfo.push_back(*it);
8866 it = mStreamInfo.erase(it);
8867 } else
8868 it++;
8869 }
8870 // Move raw streams into newList
8871 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
8872 it != mStreamInfo.end();) {
8873 newStreamInfo.push_back(*it);
8874 it = mStreamInfo.erase(it);
8875 }
8876
8877 mStreamInfo = newStreamInfo;
Chien-Yu Chen3d836272017-09-20 11:10:21 -07008878
8879 // Make sure that stream IDs are unique.
8880 uint32_t id = 0;
8881 for (auto streamInfo : mStreamInfo) {
8882 streamInfo->id = id++;
8883 }
8884
Thierry Strudel3d639192016-09-09 11:52:26 -07008885}
8886
8887/*===========================================================================
8888 * FUNCTION : extractJpegMetadata
8889 *
8890 * DESCRIPTION: helper method to extract Jpeg metadata from capture request.
8891 * JPEG metadata is cached in HAL, and return as part of capture
8892 * result when metadata is returned from camera daemon.
8893 *
8894 * PARAMETERS : @jpegMetadata: jpeg metadata to be extracted
8895 * @request: capture request
8896 *
8897 *==========================================================================*/
8898void QCamera3HardwareInterface::extractJpegMetadata(
8899 CameraMetadata& jpegMetadata,
8900 const camera3_capture_request_t *request)
8901{
8902 CameraMetadata frame_settings;
8903 frame_settings = request->settings;
8904
8905 if (frame_settings.exists(ANDROID_JPEG_GPS_COORDINATES))
8906 jpegMetadata.update(ANDROID_JPEG_GPS_COORDINATES,
8907 frame_settings.find(ANDROID_JPEG_GPS_COORDINATES).data.d,
8908 frame_settings.find(ANDROID_JPEG_GPS_COORDINATES).count);
8909
8910 if (frame_settings.exists(ANDROID_JPEG_GPS_PROCESSING_METHOD))
8911 jpegMetadata.update(ANDROID_JPEG_GPS_PROCESSING_METHOD,
8912 frame_settings.find(ANDROID_JPEG_GPS_PROCESSING_METHOD).data.u8,
8913 frame_settings.find(ANDROID_JPEG_GPS_PROCESSING_METHOD).count);
8914
8915 if (frame_settings.exists(ANDROID_JPEG_GPS_TIMESTAMP))
8916 jpegMetadata.update(ANDROID_JPEG_GPS_TIMESTAMP,
8917 frame_settings.find(ANDROID_JPEG_GPS_TIMESTAMP).data.i64,
8918 frame_settings.find(ANDROID_JPEG_GPS_TIMESTAMP).count);
8919
8920 if (frame_settings.exists(ANDROID_JPEG_ORIENTATION))
8921 jpegMetadata.update(ANDROID_JPEG_ORIENTATION,
8922 frame_settings.find(ANDROID_JPEG_ORIENTATION).data.i32,
8923 frame_settings.find(ANDROID_JPEG_ORIENTATION).count);
8924
8925 if (frame_settings.exists(ANDROID_JPEG_QUALITY))
8926 jpegMetadata.update(ANDROID_JPEG_QUALITY,
8927 frame_settings.find(ANDROID_JPEG_QUALITY).data.u8,
8928 frame_settings.find(ANDROID_JPEG_QUALITY).count);
8929
8930 if (frame_settings.exists(ANDROID_JPEG_THUMBNAIL_QUALITY))
8931 jpegMetadata.update(ANDROID_JPEG_THUMBNAIL_QUALITY,
8932 frame_settings.find(ANDROID_JPEG_THUMBNAIL_QUALITY).data.u8,
8933 frame_settings.find(ANDROID_JPEG_THUMBNAIL_QUALITY).count);
8934
8935 if (frame_settings.exists(ANDROID_JPEG_THUMBNAIL_SIZE)) {
8936 int32_t thumbnail_size[2];
8937 thumbnail_size[0] = frame_settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[0];
8938 thumbnail_size[1] = frame_settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[1];
8939 if (frame_settings.exists(ANDROID_JPEG_ORIENTATION)) {
8940 int32_t orientation =
8941 frame_settings.find(ANDROID_JPEG_ORIENTATION).data.i32[0];
Thierry Strudel9e74aae2016-09-22 17:10:18 -07008942 if ((!needJpegExifRotation()) && ((orientation == 90) || (orientation == 270))) {
Thierry Strudel3d639192016-09-09 11:52:26 -07008943 //swap thumbnail dimensions for rotations 90 and 270 in jpeg metadata.
8944 int32_t temp;
8945 temp = thumbnail_size[0];
8946 thumbnail_size[0] = thumbnail_size[1];
8947 thumbnail_size[1] = temp;
8948 }
8949 }
8950 jpegMetadata.update(ANDROID_JPEG_THUMBNAIL_SIZE,
8951 thumbnail_size,
8952 frame_settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).count);
8953 }
8954
8955}
8956
8957/*===========================================================================
8958 * FUNCTION : convertToRegions
8959 *
8960 * DESCRIPTION: helper method to convert from cam_rect_t into int32_t array
8961 *
8962 * PARAMETERS :
8963 * @rect : cam_rect_t struct to convert
8964 * @region : int32_t destination array
8965 * @weight : if we are converting from cam_area_t, weight is valid
8966 * else weight = -1
8967 *
8968 *==========================================================================*/
8969void QCamera3HardwareInterface::convertToRegions(cam_rect_t rect,
8970 int32_t *region, int weight)
8971{
Jason Lee8ce36fa2017-04-19 19:40:37 -07008972 region[FACE_LEFT] = rect.left;
8973 region[FACE_TOP] = rect.top;
8974 region[FACE_RIGHT] = rect.left + rect.width;
8975 region[FACE_BOTTOM] = rect.top + rect.height;
Thierry Strudel3d639192016-09-09 11:52:26 -07008976 if (weight > -1) {
Jason Lee8ce36fa2017-04-19 19:40:37 -07008977 region[FACE_WEIGHT] = weight;
Thierry Strudel3d639192016-09-09 11:52:26 -07008978 }
8979}
8980
8981/*===========================================================================
8982 * FUNCTION : convertFromRegions
8983 *
8984 * DESCRIPTION: helper method to convert from array to cam_rect_t
8985 *
8986 * PARAMETERS :
8987 * @rect : cam_rect_t struct to convert
8988 * @region : int32_t destination array
8989 * @weight : if we are converting from cam_area_t, weight is valid
8990 * else weight = -1
8991 *
8992 *==========================================================================*/
8993void QCamera3HardwareInterface::convertFromRegions(cam_area_t &roi,
Chien-Yu Chen92724a82017-01-06 11:50:30 -08008994 const CameraMetadata &frame_settings, uint32_t tag)
Thierry Strudel3d639192016-09-09 11:52:26 -07008995{
Thierry Strudel3d639192016-09-09 11:52:26 -07008996 int32_t x_min = frame_settings.find(tag).data.i32[0];
8997 int32_t y_min = frame_settings.find(tag).data.i32[1];
8998 int32_t x_max = frame_settings.find(tag).data.i32[2];
8999 int32_t y_max = frame_settings.find(tag).data.i32[3];
9000 roi.weight = frame_settings.find(tag).data.i32[4];
9001 roi.rect.left = x_min;
9002 roi.rect.top = y_min;
9003 roi.rect.width = x_max - x_min;
9004 roi.rect.height = y_max - y_min;
9005}
9006
9007/*===========================================================================
9008 * FUNCTION : resetIfNeededROI
9009 *
9010 * DESCRIPTION: helper method to reset the roi if it is greater than scaler
9011 * crop region
9012 *
9013 * PARAMETERS :
9014 * @roi : cam_area_t struct to resize
9015 * @scalerCropRegion : cam_crop_region_t region to compare against
9016 *
9017 *
9018 *==========================================================================*/
9019bool QCamera3HardwareInterface::resetIfNeededROI(cam_area_t* roi,
9020 const cam_crop_region_t* scalerCropRegion)
9021{
9022 int32_t roi_x_max = roi->rect.width + roi->rect.left;
9023 int32_t roi_y_max = roi->rect.height + roi->rect.top;
9024 int32_t crop_x_max = scalerCropRegion->width + scalerCropRegion->left;
9025 int32_t crop_y_max = scalerCropRegion->height + scalerCropRegion->top;
9026
9027 /* According to spec weight = 0 is used to indicate roi needs to be disabled
9028 * without having this check the calculations below to validate if the roi
9029 * is inside scalar crop region will fail resulting in the roi not being
9030 * reset causing algorithm to continue to use stale roi window
9031 */
9032 if (roi->weight == 0) {
9033 return true;
9034 }
9035
9036 if ((roi_x_max < scalerCropRegion->left) ||
9037 // right edge of roi window is left of scalar crop's left edge
9038 (roi_y_max < scalerCropRegion->top) ||
9039 // bottom edge of roi window is above scalar crop's top edge
9040 (roi->rect.left > crop_x_max) ||
9041 // left edge of roi window is beyond(right) of scalar crop's right edge
9042 (roi->rect.top > crop_y_max)){
9043 // top edge of roi windo is above scalar crop's top edge
9044 return false;
9045 }
9046 if (roi->rect.left < scalerCropRegion->left) {
9047 roi->rect.left = scalerCropRegion->left;
9048 }
9049 if (roi->rect.top < scalerCropRegion->top) {
9050 roi->rect.top = scalerCropRegion->top;
9051 }
9052 if (roi_x_max > crop_x_max) {
9053 roi_x_max = crop_x_max;
9054 }
9055 if (roi_y_max > crop_y_max) {
9056 roi_y_max = crop_y_max;
9057 }
9058 roi->rect.width = roi_x_max - roi->rect.left;
9059 roi->rect.height = roi_y_max - roi->rect.top;
9060 return true;
9061}
9062
9063/*===========================================================================
9064 * FUNCTION : convertLandmarks
9065 *
9066 * DESCRIPTION: helper method to extract the landmarks from face detection info
9067 *
9068 * PARAMETERS :
9069 * @landmark_data : input landmark data to be converted
9070 * @landmarks : int32_t destination array
9071 *
9072 *
9073 *==========================================================================*/
9074void QCamera3HardwareInterface::convertLandmarks(
9075 cam_face_landmarks_info_t landmark_data,
9076 int32_t *landmarks)
9077{
Thierry Strudel04e026f2016-10-10 11:27:36 -07009078 if (landmark_data.is_left_eye_valid) {
9079 landmarks[LEFT_EYE_X] = (int32_t)landmark_data.left_eye_center.x;
9080 landmarks[LEFT_EYE_Y] = (int32_t)landmark_data.left_eye_center.y;
9081 } else {
9082 landmarks[LEFT_EYE_X] = FACE_INVALID_POINT;
9083 landmarks[LEFT_EYE_Y] = FACE_INVALID_POINT;
9084 }
9085
9086 if (landmark_data.is_right_eye_valid) {
9087 landmarks[RIGHT_EYE_X] = (int32_t)landmark_data.right_eye_center.x;
9088 landmarks[RIGHT_EYE_Y] = (int32_t)landmark_data.right_eye_center.y;
9089 } else {
9090 landmarks[RIGHT_EYE_X] = FACE_INVALID_POINT;
9091 landmarks[RIGHT_EYE_Y] = FACE_INVALID_POINT;
9092 }
9093
9094 if (landmark_data.is_mouth_valid) {
9095 landmarks[MOUTH_X] = (int32_t)landmark_data.mouth_center.x;
9096 landmarks[MOUTH_Y] = (int32_t)landmark_data.mouth_center.y;
9097 } else {
9098 landmarks[MOUTH_X] = FACE_INVALID_POINT;
9099 landmarks[MOUTH_Y] = FACE_INVALID_POINT;
9100 }
9101}
9102
9103/*===========================================================================
9104 * FUNCTION : setInvalidLandmarks
9105 *
9106 * DESCRIPTION: helper method to set invalid landmarks
9107 *
9108 * PARAMETERS :
9109 * @landmarks : int32_t destination array
9110 *
9111 *
9112 *==========================================================================*/
9113void QCamera3HardwareInterface::setInvalidLandmarks(
9114 int32_t *landmarks)
9115{
9116 landmarks[LEFT_EYE_X] = FACE_INVALID_POINT;
9117 landmarks[LEFT_EYE_Y] = FACE_INVALID_POINT;
9118 landmarks[RIGHT_EYE_X] = FACE_INVALID_POINT;
9119 landmarks[RIGHT_EYE_Y] = FACE_INVALID_POINT;
9120 landmarks[MOUTH_X] = FACE_INVALID_POINT;
9121 landmarks[MOUTH_Y] = FACE_INVALID_POINT;
Thierry Strudel3d639192016-09-09 11:52:26 -07009122}
9123
9124#define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX )
Thierry Strudelcca4d9c2016-10-20 08:25:53 -07009125
9126/*===========================================================================
9127 * FUNCTION : getCapabilities
9128 *
9129 * DESCRIPTION: query camera capability from back-end
9130 *
9131 * PARAMETERS :
9132 * @ops : mm-interface ops structure
9133 * @cam_handle : camera handle for which we need capability
9134 *
9135 * RETURN : ptr type of capability structure
9136 * capability for success
9137 * NULL for failure
9138 *==========================================================================*/
9139cam_capability_t *QCamera3HardwareInterface::getCapabilities(mm_camera_ops_t *ops,
9140 uint32_t cam_handle)
9141{
9142 int rc = NO_ERROR;
9143 QCamera3HeapMemory *capabilityHeap = NULL;
9144 cam_capability_t *cap_ptr = NULL;
9145
9146 if (ops == NULL) {
9147 LOGE("Invalid arguments");
9148 return NULL;
9149 }
9150
9151 capabilityHeap = new QCamera3HeapMemory(1);
9152 if (capabilityHeap == NULL) {
9153 LOGE("creation of capabilityHeap failed");
9154 return NULL;
9155 }
9156
9157 /* Allocate memory for capability buffer */
9158 rc = capabilityHeap->allocate(sizeof(cam_capability_t));
9159 if(rc != OK) {
9160 LOGE("No memory for cappability");
9161 goto allocate_failed;
9162 }
9163
9164 /* Map memory for capability buffer */
9165 memset(DATA_PTR(capabilityHeap,0), 0, sizeof(cam_capability_t));
9166
9167 rc = ops->map_buf(cam_handle,
9168 CAM_MAPPING_BUF_TYPE_CAPABILITY, capabilityHeap->getFd(0),
9169 sizeof(cam_capability_t), capabilityHeap->getPtr(0));
9170 if(rc < 0) {
9171 LOGE("failed to map capability buffer");
9172 rc = FAILED_TRANSACTION;
9173 goto map_failed;
9174 }
9175
9176 /* Query Capability */
9177 rc = ops->query_capability(cam_handle);
9178 if(rc < 0) {
9179 LOGE("failed to query capability");
9180 rc = FAILED_TRANSACTION;
9181 goto query_failed;
9182 }
9183
9184 cap_ptr = (cam_capability_t *)malloc(sizeof(cam_capability_t));
9185 if (cap_ptr == NULL) {
9186 LOGE("out of memory");
9187 rc = NO_MEMORY;
9188 goto query_failed;
9189 }
9190
9191 memset(cap_ptr, 0, sizeof(cam_capability_t));
9192 memcpy(cap_ptr, DATA_PTR(capabilityHeap, 0), sizeof(cam_capability_t));
9193
9194 int index;
9195 for (index = 0; index < CAM_ANALYSIS_INFO_MAX; index++) {
9196 cam_analysis_info_t *p_analysis_info = &cap_ptr->analysis_info[index];
9197 p_analysis_info->analysis_padding_info.offset_info.offset_x = 0;
9198 p_analysis_info->analysis_padding_info.offset_info.offset_y = 0;
9199 }
9200
9201query_failed:
9202 ops->unmap_buf(cam_handle, CAM_MAPPING_BUF_TYPE_CAPABILITY);
9203map_failed:
9204 capabilityHeap->deallocate();
9205allocate_failed:
9206 delete capabilityHeap;
9207
9208 if (rc != NO_ERROR) {
9209 return NULL;
9210 } else {
9211 return cap_ptr;
9212 }
9213}
9214
Thierry Strudel3d639192016-09-09 11:52:26 -07009215/*===========================================================================
9216 * FUNCTION : initCapabilities
9217 *
9218 * DESCRIPTION: initialize camera capabilities in static data struct
9219 *
9220 * PARAMETERS :
9221 * @cameraId : camera Id
9222 *
9223 * RETURN : int32_t type of status
9224 * NO_ERROR -- success
9225 * none-zero failure code
9226 *==========================================================================*/
9227int QCamera3HardwareInterface::initCapabilities(uint32_t cameraId)
9228{
9229 int rc = 0;
9230 mm_camera_vtbl_t *cameraHandle = NULL;
Thierry Strudelcca4d9c2016-10-20 08:25:53 -07009231 uint32_t handle = 0;
Thierry Strudel3d639192016-09-09 11:52:26 -07009232
9233 rc = camera_open((uint8_t)cameraId, &cameraHandle);
9234 if (rc) {
9235 LOGE("camera_open failed. rc = %d", rc);
9236 goto open_failed;
9237 }
9238 if (!cameraHandle) {
9239 LOGE("camera_open failed. cameraHandle = %p", cameraHandle);
9240 goto open_failed;
9241 }
9242
Thierry Strudelcca4d9c2016-10-20 08:25:53 -07009243 handle = get_main_camera_handle(cameraHandle->camera_handle);
9244 gCamCapability[cameraId] = getCapabilities(cameraHandle->ops, handle);
9245 if (gCamCapability[cameraId] == NULL) {
9246 rc = FAILED_TRANSACTION;
9247 goto failed_op;
Thierry Strudel3d639192016-09-09 11:52:26 -07009248 }
9249
Thierry Strudel295a0ca2016-11-03 18:38:47 -07009250 gCamCapability[cameraId]->camera_index = cameraId;
Thierry Strudelcca4d9c2016-10-20 08:25:53 -07009251 if (is_dual_camera_by_idx(cameraId)) {
9252 handle = get_aux_camera_handle(cameraHandle->camera_handle);
9253 gCamCapability[cameraId]->aux_cam_cap =
9254 getCapabilities(cameraHandle->ops, handle);
9255 if (gCamCapability[cameraId]->aux_cam_cap == NULL) {
9256 rc = FAILED_TRANSACTION;
9257 free(gCamCapability[cameraId]);
9258 goto failed_op;
9259 }
Thierry Strudelc2ee3302016-11-17 12:33:12 -08009260
9261 // Copy the main camera capability to main_cam_cap struct
9262 gCamCapability[cameraId]->main_cam_cap =
9263 (cam_capability_t *)malloc(sizeof(cam_capability_t));
9264 if (gCamCapability[cameraId]->main_cam_cap == NULL) {
9265 LOGE("out of memory");
9266 rc = NO_MEMORY;
9267 goto failed_op;
9268 }
9269 memcpy(gCamCapability[cameraId]->main_cam_cap, gCamCapability[cameraId],
9270 sizeof(cam_capability_t));
Thierry Strudel3d639192016-09-09 11:52:26 -07009271 }
Thierry Strudelcca4d9c2016-10-20 08:25:53 -07009272failed_op:
Thierry Strudel3d639192016-09-09 11:52:26 -07009273 cameraHandle->ops->close_camera(cameraHandle->camera_handle);
9274 cameraHandle = NULL;
9275open_failed:
9276 return rc;
9277}
9278
9279/*==========================================================================
9280 * FUNCTION : get3Aversion
9281 *
9282 * DESCRIPTION: get the Q3A S/W version
9283 *
9284 * PARAMETERS :
9285 * @sw_version: Reference of Q3A structure which will hold version info upon
9286 * return
9287 *
9288 * RETURN : None
9289 *
9290 *==========================================================================*/
9291void QCamera3HardwareInterface::get3AVersion(cam_q3a_version_t &sw_version)
9292{
9293 if(gCamCapability[mCameraId])
9294 sw_version = gCamCapability[mCameraId]->q3a_version;
9295 else
9296 LOGE("Capability structure NULL!");
9297}
9298
9299
9300/*===========================================================================
9301 * FUNCTION : initParameters
9302 *
9303 * DESCRIPTION: initialize camera parameters
9304 *
9305 * PARAMETERS :
9306 *
9307 * RETURN : int32_t type of status
9308 * NO_ERROR -- success
9309 * none-zero failure code
9310 *==========================================================================*/
9311int QCamera3HardwareInterface::initParameters()
9312{
9313 int rc = 0;
9314
9315 //Allocate Set Param Buffer
9316 mParamHeap = new QCamera3HeapMemory(1);
9317 rc = mParamHeap->allocate(sizeof(metadata_buffer_t));
9318 if(rc != OK) {
9319 rc = NO_MEMORY;
9320 LOGE("Failed to allocate SETPARM Heap memory");
9321 delete mParamHeap;
9322 mParamHeap = NULL;
9323 return rc;
9324 }
9325
9326 //Map memory for parameters buffer
9327 rc = mCameraHandle->ops->map_buf(mCameraHandle->camera_handle,
9328 CAM_MAPPING_BUF_TYPE_PARM_BUF,
9329 mParamHeap->getFd(0),
9330 sizeof(metadata_buffer_t),
9331 (metadata_buffer_t *) DATA_PTR(mParamHeap,0));
9332 if(rc < 0) {
9333 LOGE("failed to map SETPARM buffer");
9334 rc = FAILED_TRANSACTION;
9335 mParamHeap->deallocate();
9336 delete mParamHeap;
9337 mParamHeap = NULL;
9338 return rc;
9339 }
9340
9341 mParameters = (metadata_buffer_t *) DATA_PTR(mParamHeap,0);
9342
9343 mPrevParameters = (metadata_buffer_t *)malloc(sizeof(metadata_buffer_t));
9344 return rc;
9345}
9346
9347/*===========================================================================
9348 * FUNCTION : deinitParameters
9349 *
9350 * DESCRIPTION: de-initialize camera parameters
9351 *
9352 * PARAMETERS :
9353 *
9354 * RETURN : NONE
9355 *==========================================================================*/
9356void QCamera3HardwareInterface::deinitParameters()
9357{
9358 mCameraHandle->ops->unmap_buf(mCameraHandle->camera_handle,
9359 CAM_MAPPING_BUF_TYPE_PARM_BUF);
9360
9361 mParamHeap->deallocate();
9362 delete mParamHeap;
9363 mParamHeap = NULL;
9364
9365 mParameters = NULL;
9366
9367 free(mPrevParameters);
9368 mPrevParameters = NULL;
9369}
9370
9371/*===========================================================================
9372 * FUNCTION : calcMaxJpegSize
9373 *
9374 * DESCRIPTION: Calculates maximum jpeg size supported by the cameraId
9375 *
9376 * PARAMETERS :
9377 *
9378 * RETURN : max_jpeg_size
9379 *==========================================================================*/
9380size_t QCamera3HardwareInterface::calcMaxJpegSize(uint32_t camera_id)
9381{
9382 size_t max_jpeg_size = 0;
9383 size_t temp_width, temp_height;
9384 size_t count = MIN(gCamCapability[camera_id]->picture_sizes_tbl_cnt,
9385 MAX_SIZES_CNT);
9386 for (size_t i = 0; i < count; i++) {
9387 temp_width = (size_t)gCamCapability[camera_id]->picture_sizes_tbl[i].width;
9388 temp_height = (size_t)gCamCapability[camera_id]->picture_sizes_tbl[i].height;
9389 if (temp_width * temp_height > max_jpeg_size ) {
9390 max_jpeg_size = temp_width * temp_height;
9391 }
9392 }
9393 max_jpeg_size = max_jpeg_size * 3/2 + sizeof(camera3_jpeg_blob_t);
9394 return max_jpeg_size;
9395}
9396
9397/*===========================================================================
9398 * FUNCTION : getMaxRawSize
9399 *
9400 * DESCRIPTION: Fetches maximum raw size supported by the cameraId
9401 *
9402 * PARAMETERS :
9403 *
9404 * RETURN : Largest supported Raw Dimension
9405 *==========================================================================*/
9406cam_dimension_t QCamera3HardwareInterface::getMaxRawSize(uint32_t camera_id)
9407{
9408 int max_width = 0;
9409 cam_dimension_t maxRawSize;
9410
9411 memset(&maxRawSize, 0, sizeof(cam_dimension_t));
9412 for (size_t i = 0; i < gCamCapability[camera_id]->supported_raw_dim_cnt; i++) {
9413 if (max_width < gCamCapability[camera_id]->raw_dim[i].width) {
9414 max_width = gCamCapability[camera_id]->raw_dim[i].width;
9415 maxRawSize = gCamCapability[camera_id]->raw_dim[i];
9416 }
9417 }
9418 return maxRawSize;
9419}
9420
9421
9422/*===========================================================================
9423 * FUNCTION : calcMaxJpegDim
9424 *
9425 * DESCRIPTION: Calculates maximum jpeg dimension supported by the cameraId
9426 *
9427 * PARAMETERS :
9428 *
9429 * RETURN : max_jpeg_dim
9430 *==========================================================================*/
9431cam_dimension_t QCamera3HardwareInterface::calcMaxJpegDim()
9432{
9433 cam_dimension_t max_jpeg_dim;
9434 cam_dimension_t curr_jpeg_dim;
9435 max_jpeg_dim.width = 0;
9436 max_jpeg_dim.height = 0;
9437 curr_jpeg_dim.width = 0;
9438 curr_jpeg_dim.height = 0;
9439 for (size_t i = 0; i < gCamCapability[mCameraId]->picture_sizes_tbl_cnt; i++) {
9440 curr_jpeg_dim.width = gCamCapability[mCameraId]->picture_sizes_tbl[i].width;
9441 curr_jpeg_dim.height = gCamCapability[mCameraId]->picture_sizes_tbl[i].height;
9442 if (curr_jpeg_dim.width * curr_jpeg_dim.height >
9443 max_jpeg_dim.width * max_jpeg_dim.height ) {
9444 max_jpeg_dim.width = curr_jpeg_dim.width;
9445 max_jpeg_dim.height = curr_jpeg_dim.height;
9446 }
9447 }
9448 return max_jpeg_dim;
9449}
9450
9451/*===========================================================================
9452 * FUNCTION : addStreamConfig
9453 *
9454 * DESCRIPTION: adds the stream configuration to the array
9455 *
9456 * PARAMETERS :
9457 * @available_stream_configs : pointer to stream configuration array
9458 * @scalar_format : scalar format
9459 * @dim : configuration dimension
9460 * @config_type : input or output configuration type
9461 *
9462 * RETURN : NONE
9463 *==========================================================================*/
9464void QCamera3HardwareInterface::addStreamConfig(Vector<int32_t> &available_stream_configs,
9465 int32_t scalar_format, const cam_dimension_t &dim, int32_t config_type)
9466{
9467 available_stream_configs.add(scalar_format);
9468 available_stream_configs.add(dim.width);
9469 available_stream_configs.add(dim.height);
9470 available_stream_configs.add(config_type);
9471}
9472
9473/*===========================================================================
9474 * FUNCTION : suppportBurstCapture
9475 *
9476 * DESCRIPTION: Whether a particular camera supports BURST_CAPTURE
9477 *
9478 * PARAMETERS :
9479 * @cameraId : camera Id
9480 *
9481 * RETURN : true if camera supports BURST_CAPTURE
9482 * false otherwise
9483 *==========================================================================*/
9484bool QCamera3HardwareInterface::supportBurstCapture(uint32_t cameraId)
9485{
9486 const int64_t highResDurationBound = 50000000; // 50 ms, 20 fps
9487 const int64_t fullResDurationBound = 100000000; // 100 ms, 10 fps
9488 const int32_t highResWidth = 3264;
9489 const int32_t highResHeight = 2448;
9490
9491 if (gCamCapability[cameraId]->picture_min_duration[0] > fullResDurationBound) {
9492 // Maximum resolution images cannot be captured at >= 10fps
9493 // -> not supporting BURST_CAPTURE
9494 return false;
9495 }
9496
9497 if (gCamCapability[cameraId]->picture_min_duration[0] <= highResDurationBound) {
9498 // Maximum resolution images can be captured at >= 20fps
9499 // --> supporting BURST_CAPTURE
9500 return true;
9501 }
9502
9503 // Find the smallest highRes resolution, or largest resolution if there is none
9504 size_t totalCnt = MIN(gCamCapability[cameraId]->picture_sizes_tbl_cnt,
9505 MAX_SIZES_CNT);
9506 size_t highRes = 0;
9507 while ((highRes + 1 < totalCnt) &&
9508 (gCamCapability[cameraId]->picture_sizes_tbl[highRes+1].width *
9509 gCamCapability[cameraId]->picture_sizes_tbl[highRes+1].height >=
9510 highResWidth * highResHeight)) {
9511 highRes++;
9512 }
9513 if (gCamCapability[cameraId]->picture_min_duration[highRes] <= highResDurationBound) {
9514 return true;
9515 } else {
9516 return false;
9517 }
9518}
9519
9520/*===========================================================================
Emilian Peev0f3c3162017-03-15 12:57:46 +00009521 * FUNCTION : getPDStatIndex
9522 *
9523 * DESCRIPTION: Return the meta raw phase detection statistics index if present
9524 *
9525 * PARAMETERS :
9526 * @caps : camera capabilities
9527 *
9528 * RETURN : int32_t type
9529 * non-negative - on success
9530 * -1 - on failure
9531 *==========================================================================*/
9532int32_t QCamera3HardwareInterface::getPDStatIndex(cam_capability_t *caps) {
9533 if (nullptr == caps) {
9534 return -1;
9535 }
9536
9537 uint32_t metaRawCount = caps->meta_raw_channel_count;
9538 int32_t ret = -1;
9539 for (size_t i = 0; i < metaRawCount; i++) {
9540 if (CAM_FORMAT_SUBTYPE_PDAF_STATS == caps->sub_fmt[i]) {
9541 ret = i;
9542 break;
9543 }
9544 }
9545
9546 return ret;
9547}
9548
9549/*===========================================================================
Thierry Strudel3d639192016-09-09 11:52:26 -07009550 * FUNCTION : initStaticMetadata
9551 *
9552 * DESCRIPTION: initialize the static metadata
9553 *
9554 * PARAMETERS :
9555 * @cameraId : camera Id
9556 *
9557 * RETURN : int32_t type of status
9558 * 0 -- success
9559 * non-zero failure code
9560 *==========================================================================*/
9561int QCamera3HardwareInterface::initStaticMetadata(uint32_t cameraId)
9562{
9563 int rc = 0;
9564 CameraMetadata staticInfo;
9565 size_t count = 0;
9566 bool limitedDevice = false;
9567 char prop[PROPERTY_VALUE_MAX];
9568 bool supportBurst = false;
Emilian Peeve91e9ae2017-09-18 14:40:55 +01009569 Vector<int32_t> available_characteristics_keys;
Thierry Strudel3d639192016-09-09 11:52:26 -07009570
9571 supportBurst = supportBurstCapture(cameraId);
9572
9573 /* If sensor is YUV sensor (no raw support) or if per-frame control is not
9574 * guaranteed or if min fps of max resolution is less than 20 fps, its
9575 * advertised as limited device*/
9576 limitedDevice = gCamCapability[cameraId]->no_per_frame_control_support ||
9577 (CAM_SENSOR_YUV == gCamCapability[cameraId]->sensor_type.sens_type) ||
9578 (CAM_SENSOR_MONO == gCamCapability[cameraId]->sensor_type.sens_type) ||
9579 !supportBurst;
9580
9581 uint8_t supportedHwLvl = limitedDevice ?
9582 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED :
Thierry Strudel9e74aae2016-09-22 17:10:18 -07009583#ifndef USE_HAL_3_3
9584 // LEVEL_3 - This device will support level 3.
9585 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_3;
9586#else
Thierry Strudel3d639192016-09-09 11:52:26 -07009587 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL;
Thierry Strudel9e74aae2016-09-22 17:10:18 -07009588#endif
Thierry Strudel3d639192016-09-09 11:52:26 -07009589
9590 staticInfo.update(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
9591 &supportedHwLvl, 1);
9592
9593 bool facingBack = false;
9594 if ((gCamCapability[cameraId]->position == CAM_POSITION_BACK) ||
9595 (gCamCapability[cameraId]->position == CAM_POSITION_BACK_AUX)) {
9596 facingBack = true;
9597 }
9598 /*HAL 3 only*/
9599 staticInfo.update(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
9600 &gCamCapability[cameraId]->min_focus_distance, 1);
9601
9602 staticInfo.update(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
9603 &gCamCapability[cameraId]->hyper_focal_distance, 1);
9604
9605 /*should be using focal lengths but sensor doesn't provide that info now*/
9606 staticInfo.update(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
9607 &gCamCapability[cameraId]->focal_length,
9608 1);
9609
9610 staticInfo.update(ANDROID_LENS_INFO_AVAILABLE_APERTURES,
9611 gCamCapability[cameraId]->apertures,
9612 MIN(CAM_APERTURES_MAX, gCamCapability[cameraId]->apertures_count));
9613
9614 staticInfo.update(ANDROID_LENS_INFO_AVAILABLE_FILTER_DENSITIES,
9615 gCamCapability[cameraId]->filter_densities,
9616 MIN(CAM_FILTER_DENSITIES_MAX, gCamCapability[cameraId]->filter_densities_count));
9617
9618
Zhijun Hea6ea1d32017-03-10 13:30:00 -08009619 uint8_t available_opt_stab_modes[CAM_OPT_STAB_MAX];
9620 size_t mode_count =
9621 MIN((size_t)CAM_OPT_STAB_MAX, gCamCapability[cameraId]->optical_stab_modes_count);
9622 for (size_t i = 0; i < mode_count; i++) {
9623 available_opt_stab_modes[i] = gCamCapability[cameraId]->optical_stab_modes[i];
9624 }
Thierry Strudel3d639192016-09-09 11:52:26 -07009625 staticInfo.update(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
Zhijun Hea6ea1d32017-03-10 13:30:00 -08009626 available_opt_stab_modes, mode_count);
Thierry Strudel3d639192016-09-09 11:52:26 -07009627
9628 int32_t lens_shading_map_size[] = {
9629 MIN(CAM_MAX_SHADING_MAP_WIDTH, gCamCapability[cameraId]->lens_shading_map_size.width),
9630 MIN(CAM_MAX_SHADING_MAP_HEIGHT, gCamCapability[cameraId]->lens_shading_map_size.height)};
9631 staticInfo.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE,
9632 lens_shading_map_size,
9633 sizeof(lens_shading_map_size)/sizeof(int32_t));
9634
Eino-Ville Talvala42d58952018-01-05 16:20:10 -08009635 // Lens calibration for MOTION_TRACKING, back camera only
9636 if (cameraId == 0) {
9637
9638 float poseRotation[4] = {1.0f, 0.f, 0.f, 0.f}; // quaternion rotation
9639 float poseTranslation[3] = {0.0f, 0.f, 0.f}; // xyz translation, meters
9640 uint8_t poseReference = ANDROID_LENS_POSE_REFERENCE_GYROSCOPE;
9641 // TODO: b/70565622 - these should have better identity values as a fallback
9642 float cameraIntrinsics[5] = {100.f, 100.f, 0.f, 1000, 1000}; // fx,fy,sx,cx,cy
Eino-Ville Talvala7a8eefb2018-03-19 15:22:53 -07009643 float radialDistortion[5] = {0.f, 0.f, 0.f, 0.f, 0.f}; // identity
Eino-Ville Talvala42d58952018-01-05 16:20:10 -08009644
9645 bool success = readSensorCalibration(
9646 gCamCapability[cameraId]->active_array_size.width,
9647 poseRotation, poseTranslation, cameraIntrinsics, radialDistortion);
9648 if (!success) {
9649 ALOGE("Using identity lens calibration values");
9650 }
9651 staticInfo.update(ANDROID_LENS_POSE_ROTATION,
9652 poseRotation, sizeof(poseRotation)/sizeof(float));
9653 staticInfo.update(ANDROID_LENS_POSE_TRANSLATION,
9654 poseTranslation, sizeof(poseTranslation)/sizeof(float));
9655 staticInfo.update(ANDROID_LENS_INTRINSIC_CALIBRATION,
9656 cameraIntrinsics, sizeof(cameraIntrinsics)/sizeof(float));
Eino-Ville Talvala7a8eefb2018-03-19 15:22:53 -07009657 staticInfo.update(ANDROID_LENS_DISTORTION,
Eino-Ville Talvala42d58952018-01-05 16:20:10 -08009658 radialDistortion, sizeof(radialDistortion)/sizeof(float));
9659 staticInfo.update(ANDROID_LENS_POSE_REFERENCE,
9660 &poseReference, sizeof(poseReference));
9661 }
9662
Thierry Strudel3d639192016-09-09 11:52:26 -07009663 staticInfo.update(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
9664 gCamCapability[cameraId]->sensor_physical_size, SENSOR_PHYSICAL_SIZE_CNT);
9665
9666 staticInfo.update(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
9667 gCamCapability[cameraId]->exposure_time_range, EXPOSURE_TIME_RANGE_CNT);
9668
9669 staticInfo.update(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
9670 &gCamCapability[cameraId]->max_frame_duration, 1);
9671
9672 camera_metadata_rational baseGainFactor = {
9673 gCamCapability[cameraId]->base_gain_factor.numerator,
9674 gCamCapability[cameraId]->base_gain_factor.denominator};
9675 staticInfo.update(ANDROID_SENSOR_BASE_GAIN_FACTOR,
9676 &baseGainFactor, 1);
9677
9678 staticInfo.update(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
9679 (uint8_t *)&gCamCapability[cameraId]->color_arrangement, 1);
9680
9681 int32_t pixel_array_size[] = {gCamCapability[cameraId]->pixel_array_size.width,
9682 gCamCapability[cameraId]->pixel_array_size.height};
9683 staticInfo.update(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
9684 pixel_array_size, sizeof(pixel_array_size)/sizeof(pixel_array_size[0]));
9685
9686 int32_t active_array_size[] = {gCamCapability[cameraId]->active_array_size.left,
9687 gCamCapability[cameraId]->active_array_size.top,
9688 gCamCapability[cameraId]->active_array_size.width,
9689 gCamCapability[cameraId]->active_array_size.height};
9690 staticInfo.update(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
9691 active_array_size, sizeof(active_array_size)/sizeof(active_array_size[0]));
9692
9693 staticInfo.update(ANDROID_SENSOR_INFO_WHITE_LEVEL,
9694 &gCamCapability[cameraId]->white_level, 1);
9695
Shuzhen Wanga5da1022016-07-13 20:18:42 -07009696 int32_t adjusted_bl_per_cfa[BLACK_LEVEL_PATTERN_CNT];
9697 adjustBlackLevelForCFA(gCamCapability[cameraId]->black_level_pattern, adjusted_bl_per_cfa,
9698 gCamCapability[cameraId]->color_arrangement);
Thierry Strudel3d639192016-09-09 11:52:26 -07009699 staticInfo.update(ANDROID_SENSOR_BLACK_LEVEL_PATTERN,
Shuzhen Wanga5da1022016-07-13 20:18:42 -07009700 adjusted_bl_per_cfa, BLACK_LEVEL_PATTERN_CNT);
Thierry Strudel3d639192016-09-09 11:52:26 -07009701
Thierry Strudel9e74aae2016-09-22 17:10:18 -07009702#ifndef USE_HAL_3_3
9703 bool hasBlackRegions = false;
9704 if (gCamCapability[cameraId]->optical_black_region_count > MAX_OPTICAL_BLACK_REGIONS) {
9705 LOGW("black_region_count: %d is bounded to %d",
9706 gCamCapability[cameraId]->optical_black_region_count, MAX_OPTICAL_BLACK_REGIONS);
9707 gCamCapability[cameraId]->optical_black_region_count = MAX_OPTICAL_BLACK_REGIONS;
9708 }
9709 if (gCamCapability[cameraId]->optical_black_region_count != 0) {
9710 int32_t opticalBlackRegions[MAX_OPTICAL_BLACK_REGIONS * 4];
9711 for (size_t i = 0; i < gCamCapability[cameraId]->optical_black_region_count * 4; i++) {
9712 opticalBlackRegions[i] = gCamCapability[cameraId]->optical_black_regions[i];
9713 }
9714 staticInfo.update(ANDROID_SENSOR_OPTICAL_BLACK_REGIONS,
9715 opticalBlackRegions, gCamCapability[cameraId]->optical_black_region_count * 4);
9716 hasBlackRegions = true;
9717 }
9718#endif
Thierry Strudel3d639192016-09-09 11:52:26 -07009719 staticInfo.update(ANDROID_FLASH_INFO_CHARGE_DURATION,
9720 &gCamCapability[cameraId]->flash_charge_duration, 1);
9721
9722 staticInfo.update(ANDROID_TONEMAP_MAX_CURVE_POINTS,
9723 &gCamCapability[cameraId]->max_tone_map_curve_points, 1);
9724
Shuzhen Wang98d5efb2016-09-07 18:08:22 -07009725 uint8_t timestampSource = (gCamCapability[cameraId]->timestamp_calibrated ?
9726 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME :
9727 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN);
Thierry Strudel3d639192016-09-09 11:52:26 -07009728 staticInfo.update(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
9729 &timestampSource, 1);
9730
Thierry Strudel54dc9782017-02-15 12:12:10 -08009731 //update histogram vendor data
9732 staticInfo.update(QCAMERA3_HISTOGRAM_BUCKETS,
Thierry Strudel3d639192016-09-09 11:52:26 -07009733 &gCamCapability[cameraId]->histogram_size, 1);
9734
Thierry Strudel54dc9782017-02-15 12:12:10 -08009735 staticInfo.update(QCAMERA3_HISTOGRAM_MAX_COUNT,
Thierry Strudel3d639192016-09-09 11:52:26 -07009736 &gCamCapability[cameraId]->max_histogram_count, 1);
9737
Shuzhen Wang14415f52016-11-16 18:26:18 -08009738 //Set supported bins to be {max_bins, max_bins/2, max_bins/4, ...}
9739 //so that app can request fewer number of bins than the maximum supported.
9740 std::vector<int32_t> histBins;
9741 int32_t maxHistBins = gCamCapability[cameraId]->max_histogram_count;
9742 histBins.push_back(maxHistBins);
9743 while ((maxHistBins >> 1) >= MIN_CAM_HISTOGRAM_STATS_SIZE &&
9744 (maxHistBins & 0x1) == 0) {
9745 histBins.push_back(maxHistBins >> 1);
9746 maxHistBins >>= 1;
9747 }
9748 staticInfo.update(NEXUS_EXPERIMENTAL_2017_HISTOGRAM_SUPPORTED_BINS,
9749 histBins.data(), histBins.size());
Emilian Peeve91e9ae2017-09-18 14:40:55 +01009750 if (!histBins.empty()) {
9751 available_characteristics_keys.add(NEXUS_EXPERIMENTAL_2017_HISTOGRAM_SUPPORTED_BINS);
9752 }
Shuzhen Wang14415f52016-11-16 18:26:18 -08009753
Thierry Strudel3d639192016-09-09 11:52:26 -07009754 int32_t sharpness_map_size[] = {
9755 gCamCapability[cameraId]->sharpness_map_size.width,
9756 gCamCapability[cameraId]->sharpness_map_size.height};
9757
9758 staticInfo.update(ANDROID_STATISTICS_INFO_SHARPNESS_MAP_SIZE,
9759 sharpness_map_size, sizeof(sharpness_map_size)/sizeof(int32_t));
9760
9761 staticInfo.update(ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE,
9762 &gCamCapability[cameraId]->max_sharpness_map_value, 1);
9763
Emilian Peev0f3c3162017-03-15 12:57:46 +00009764 int32_t indexPD = getPDStatIndex(gCamCapability[cameraId]);
9765 if (0 <= indexPD) {
9766 // Advertise PD stats data as part of the Depth capabilities
9767 int32_t depthWidth =
9768 gCamCapability[cameraId]->raw_meta_dim[indexPD].width;
9769 int32_t depthHeight =
9770 gCamCapability[cameraId]->raw_meta_dim[indexPD].height;
Emilian Peev656e4fa2017-06-02 16:47:04 +01009771 int32_t depthStride =
9772 gCamCapability[cameraId]->raw_meta_dim[indexPD].width * 2;
Emilian Peev0f3c3162017-03-15 12:57:46 +00009773 int32_t depthSamplesCount = (depthWidth * depthHeight * 2) / 16;
9774 assert(0 < depthSamplesCount);
9775 staticInfo.update(ANDROID_DEPTH_MAX_DEPTH_SAMPLES,
9776 &depthSamplesCount, 1);
9777
9778 int32_t depthConfigs[] = {HAL_PIXEL_FORMAT_RAW16, depthWidth,
9779 depthHeight,
9780 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
9781 HAL_PIXEL_FORMAT_BLOB, depthSamplesCount, 1,
9782 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT};
9783 staticInfo.update(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
9784 depthConfigs, sizeof(depthConfigs)/sizeof(depthConfigs[0]));
9785
9786 int64_t depthMinDuration[] = {HAL_PIXEL_FORMAT_RAW16, depthWidth,
9787 depthHeight, 33333333,
9788 HAL_PIXEL_FORMAT_BLOB, depthSamplesCount, 1, 33333333};
9789 staticInfo.update(ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS,
9790 depthMinDuration,
9791 sizeof(depthMinDuration) / sizeof(depthMinDuration[0]));
9792
9793 int64_t depthStallDuration[] = {HAL_PIXEL_FORMAT_RAW16, depthWidth,
9794 depthHeight, 0,
9795 HAL_PIXEL_FORMAT_BLOB, depthSamplesCount, 1, 0};
9796 staticInfo.update(ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS,
9797 depthStallDuration,
9798 sizeof(depthStallDuration) / sizeof(depthStallDuration[0]));
9799
9800 uint8_t depthExclusive = ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE_FALSE;
9801 staticInfo.update(ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE, &depthExclusive, 1);
Emilian Peev656e4fa2017-06-02 16:47:04 +01009802
9803 int32_t pd_dimensions [] = {depthWidth, depthHeight, depthStride};
9804 staticInfo.update(NEXUS_EXPERIMENTAL_2017_PD_DATA_DIMENSIONS,
9805 pd_dimensions, sizeof(pd_dimensions) / sizeof(pd_dimensions[0]));
Emilian Peeve91e9ae2017-09-18 14:40:55 +01009806 available_characteristics_keys.add(NEXUS_EXPERIMENTAL_2017_PD_DATA_DIMENSIONS);
Emilian Peev835938b2017-08-31 16:59:54 +01009807
9808 staticInfo.update(NEXUS_EXPERIMENTAL_2017_EEPROM_PDAF_CALIB_RIGHT_GAINS,
9809 reinterpret_cast<uint8_t *>(gCamCapability[cameraId]->pdaf_cal.right_gain_map),
9810 sizeof(gCamCapability[cameraId]->pdaf_cal.right_gain_map));
Emilian Peeve91e9ae2017-09-18 14:40:55 +01009811 available_characteristics_keys.add(NEXUS_EXPERIMENTAL_2017_EEPROM_PDAF_CALIB_RIGHT_GAINS);
Emilian Peev835938b2017-08-31 16:59:54 +01009812
9813 staticInfo.update(NEXUS_EXPERIMENTAL_2017_EEPROM_PDAF_CALIB_LEFT_GAINS,
9814 reinterpret_cast<uint8_t *>(gCamCapability[cameraId]->pdaf_cal.left_gain_map),
9815 sizeof(gCamCapability[cameraId]->pdaf_cal.left_gain_map));
Emilian Peeve91e9ae2017-09-18 14:40:55 +01009816 available_characteristics_keys.add(NEXUS_EXPERIMENTAL_2017_EEPROM_PDAF_CALIB_LEFT_GAINS);
Emilian Peev835938b2017-08-31 16:59:54 +01009817
9818 staticInfo.update(NEXUS_EXPERIMENTAL_2017_EEPROM_PDAF_CALIB_CONV_COEFF,
9819 reinterpret_cast<uint8_t *>(gCamCapability[cameraId]->pdaf_cal.conversion_coeff),
9820 sizeof(gCamCapability[cameraId]->pdaf_cal.conversion_coeff));
Emilian Peeve91e9ae2017-09-18 14:40:55 +01009821 available_characteristics_keys.add(NEXUS_EXPERIMENTAL_2017_EEPROM_PDAF_CALIB_CONV_COEFF);
Emilian Peev0f3c3162017-03-15 12:57:46 +00009822 }
9823
Yun-Ta Tsai838670b2017-11-10 15:07:01 -08009824
9825 staticInfo.update(NEXUS_EXPERIMENTAL_2017_EEPROM_WB_CALIB_NUM_LIGHTS,
9826 &(gCamCapability[cameraId]->wb_cal.num_lights), 1);
9827 available_characteristics_keys.add(NEXUS_EXPERIMENTAL_2017_EEPROM_WB_CALIB_NUM_LIGHTS);
9828
9829 const int32_t num_lights = gCamCapability[cameraId]->wb_cal.num_lights;
9830 staticInfo.update(NEXUS_EXPERIMENTAL_2017_EEPROM_WB_CALIB_R_OVER_G_RATIOS,
9831 gCamCapability[cameraId]->wb_cal.r_over_g, num_lights);
9832 available_characteristics_keys.add(NEXUS_EXPERIMENTAL_2017_EEPROM_WB_CALIB_R_OVER_G_RATIOS);
9833
9834 staticInfo.update(NEXUS_EXPERIMENTAL_2017_EEPROM_WB_CALIB_B_OVER_G_RATIOS,
9835 gCamCapability[cameraId]->wb_cal.b_over_g, num_lights);
9836 available_characteristics_keys.add(NEXUS_EXPERIMENTAL_2017_EEPROM_WB_CALIB_B_OVER_G_RATIOS);
9837
9838 staticInfo.update(NEXUS_EXPERIMENTAL_2017_EEPROM_WB_CALIB_GR_OVER_GB_RATIO,
9839 &(gCamCapability[cameraId]->wb_cal.gr_over_gb), 1);
9840 available_characteristics_keys.add(NEXUS_EXPERIMENTAL_2017_EEPROM_WB_CALIB_GR_OVER_GB_RATIO);
9841
Thierry Strudel3d639192016-09-09 11:52:26 -07009842 int32_t scalar_formats[] = {
9843 ANDROID_SCALER_AVAILABLE_FORMATS_RAW_OPAQUE,
9844 ANDROID_SCALER_AVAILABLE_FORMATS_RAW16,
9845 ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888,
9846 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB,
9847 HAL_PIXEL_FORMAT_RAW10,
9848 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED};
Emilian Peev0f3c3162017-03-15 12:57:46 +00009849 size_t scalar_formats_count = sizeof(scalar_formats) / sizeof(scalar_formats[0]);
9850 staticInfo.update(ANDROID_SCALER_AVAILABLE_FORMATS, scalar_formats,
9851 scalar_formats_count);
Thierry Strudel3d639192016-09-09 11:52:26 -07009852
9853 int32_t available_processed_sizes[MAX_SIZES_CNT * 2];
9854 count = MIN(gCamCapability[cameraId]->picture_sizes_tbl_cnt, MAX_SIZES_CNT);
9855 makeTable(gCamCapability[cameraId]->picture_sizes_tbl,
9856 count, MAX_SIZES_CNT, available_processed_sizes);
9857 staticInfo.update(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES,
9858 available_processed_sizes, count * 2);
9859
9860 int32_t available_raw_sizes[MAX_SIZES_CNT * 2];
9861 count = MIN(gCamCapability[cameraId]->supported_raw_dim_cnt, MAX_SIZES_CNT);
9862 makeTable(gCamCapability[cameraId]->raw_dim,
9863 count, MAX_SIZES_CNT, available_raw_sizes);
9864 staticInfo.update(ANDROID_SCALER_AVAILABLE_RAW_SIZES,
9865 available_raw_sizes, count * 2);
9866
9867 int32_t available_fps_ranges[MAX_SIZES_CNT * 2];
9868 count = MIN(gCamCapability[cameraId]->fps_ranges_tbl_cnt, MAX_SIZES_CNT);
9869 makeFPSTable(gCamCapability[cameraId]->fps_ranges_tbl,
9870 count, MAX_SIZES_CNT, available_fps_ranges);
9871 staticInfo.update(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
9872 available_fps_ranges, count * 2);
9873
9874 camera_metadata_rational exposureCompensationStep = {
9875 gCamCapability[cameraId]->exp_compensation_step.numerator,
9876 gCamCapability[cameraId]->exp_compensation_step.denominator};
9877 staticInfo.update(ANDROID_CONTROL_AE_COMPENSATION_STEP,
9878 &exposureCompensationStep, 1);
9879
9880 Vector<uint8_t> availableVstabModes;
9881 availableVstabModes.add(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF);
9882 char eis_prop[PROPERTY_VALUE_MAX];
Thierry Strudel9e74aae2016-09-22 17:10:18 -07009883 bool eisSupported = false;
Thierry Strudel3d639192016-09-09 11:52:26 -07009884 memset(eis_prop, 0, sizeof(eis_prop));
Thierry Strudel9e74aae2016-09-22 17:10:18 -07009885 property_get("persist.camera.eis.enable", eis_prop, "1");
Thierry Strudel3d639192016-09-09 11:52:26 -07009886 uint8_t eis_prop_set = (uint8_t)atoi(eis_prop);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07009887 count = IS_TYPE_MAX;
9888 count = MIN(gCamCapability[cameraId]->supported_is_types_cnt, count);
9889 for (size_t i = 0; i < count; i++) {
9890 if ((gCamCapability[cameraId]->supported_is_types[i] == IS_TYPE_EIS_2_0) ||
9891 (gCamCapability[cameraId]->supported_is_types[i] == IS_TYPE_EIS_3_0)) {
9892 eisSupported = true;
9893 break;
9894 }
9895 }
9896 if (facingBack && eis_prop_set && eisSupported) {
Thierry Strudel3d639192016-09-09 11:52:26 -07009897 availableVstabModes.add(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON);
9898 }
9899 staticInfo.update(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
9900 availableVstabModes.array(), availableVstabModes.size());
9901
9902 /*HAL 1 and HAL 3 common*/
9903 uint32_t zoomSteps = gCamCapability[cameraId]->zoom_ratio_tbl_cnt;
9904 uint32_t maxZoomStep = gCamCapability[cameraId]->zoom_ratio_tbl[zoomSteps - 1];
9905 uint32_t minZoomStep = 100; //as per HAL1/API1 spec
Zhijun He2a5df222017-04-04 18:20:38 -07009906 // Cap the max zoom to the max preferred value
9907 float maxZoom = MIN(maxZoomStep/minZoomStep, MAX_PREFERRED_ZOOM_RATIO);
Thierry Strudel3d639192016-09-09 11:52:26 -07009908 staticInfo.update(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
9909 &maxZoom, 1);
9910
9911 uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
9912 staticInfo.update(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);
9913
9914 int32_t max3aRegions[3] = {/*AE*/1,/*AWB*/ 0,/*AF*/ 1};
9915 if (gCamCapability[cameraId]->supported_focus_modes_cnt == 1)
9916 max3aRegions[2] = 0; /* AF not supported */
9917 staticInfo.update(ANDROID_CONTROL_MAX_REGIONS,
9918 max3aRegions, 3);
9919
9920 /* 0: OFF, 1: OFF+SIMPLE, 2: OFF+FULL, 3: OFF+SIMPLE+FULL */
9921 memset(prop, 0, sizeof(prop));
9922 property_get("persist.camera.facedetect", prop, "1");
9923 uint8_t supportedFaceDetectMode = (uint8_t)atoi(prop);
9924 LOGD("Support face detection mode: %d",
9925 supportedFaceDetectMode);
9926
9927 int32_t maxFaces = gCamCapability[cameraId]->max_num_roi;
Thierry Strudel04e026f2016-10-10 11:27:36 -07009928 /* support mode should be OFF if max number of face is 0 */
9929 if (maxFaces <= 0) {
9930 supportedFaceDetectMode = 0;
9931 }
Thierry Strudel3d639192016-09-09 11:52:26 -07009932 Vector<uint8_t> availableFaceDetectModes;
9933 availableFaceDetectModes.add(ANDROID_STATISTICS_FACE_DETECT_MODE_OFF);
9934 if (supportedFaceDetectMode == 1) {
9935 availableFaceDetectModes.add(ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE);
9936 } else if (supportedFaceDetectMode == 2) {
9937 availableFaceDetectModes.add(ANDROID_STATISTICS_FACE_DETECT_MODE_FULL);
9938 } else if (supportedFaceDetectMode == 3) {
9939 availableFaceDetectModes.add(ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE);
9940 availableFaceDetectModes.add(ANDROID_STATISTICS_FACE_DETECT_MODE_FULL);
9941 } else {
9942 maxFaces = 0;
9943 }
9944 staticInfo.update(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
9945 availableFaceDetectModes.array(),
9946 availableFaceDetectModes.size());
9947 staticInfo.update(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
9948 (int32_t *)&maxFaces, 1);
Thierry Strudel54dc9782017-02-15 12:12:10 -08009949 uint8_t face_bsgc = gCamCapability[cameraId]->face_bsgc;
9950 staticInfo.update(QCAMERA3_STATS_BSGC_AVAILABLE,
9951 &face_bsgc, 1);
Thierry Strudel3d639192016-09-09 11:52:26 -07009952
9953 int32_t exposureCompensationRange[] = {
9954 gCamCapability[cameraId]->exposure_compensation_min,
9955 gCamCapability[cameraId]->exposure_compensation_max};
9956 staticInfo.update(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
9957 exposureCompensationRange,
9958 sizeof(exposureCompensationRange)/sizeof(int32_t));
9959
9960 uint8_t lensFacing = (facingBack) ?
9961 ANDROID_LENS_FACING_BACK : ANDROID_LENS_FACING_FRONT;
9962 staticInfo.update(ANDROID_LENS_FACING, &lensFacing, 1);
9963
9964 staticInfo.update(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
9965 available_thumbnail_sizes,
9966 sizeof(available_thumbnail_sizes)/sizeof(int32_t));
9967
9968 /*all sizes will be clubbed into this tag*/
9969 count = MIN(gCamCapability[cameraId]->picture_sizes_tbl_cnt, MAX_SIZES_CNT);
9970 /*android.scaler.availableStreamConfigurations*/
9971 Vector<int32_t> available_stream_configs;
9972 cam_dimension_t active_array_dim;
9973 active_array_dim.width = gCamCapability[cameraId]->active_array_size.width;
9974 active_array_dim.height = gCamCapability[cameraId]->active_array_size.height;
Thierry Strudel2896d122017-02-23 19:18:03 -08009975
9976 /*advertise list of input dimensions supported based on below property.
9977 By default all sizes upto 5MP will be advertised.
9978 Note that the setprop resolution format should be WxH.
9979 e.g: adb shell setprop persist.camera.input.minsize 1280x720
9980 To list all supported sizes, setprop needs to be set with "0x0" */
9981 cam_dimension_t minInputSize = {2592,1944}; //5MP
9982 memset(prop, 0, sizeof(prop));
9983 property_get("persist.camera.input.minsize", prop, "2592x1944");
9984 if (strlen(prop) > 0) {
9985 char *saveptr = NULL;
9986 char *token = strtok_r(prop, "x", &saveptr);
9987 if (token != NULL) {
9988 minInputSize.width = atoi(token);
9989 }
9990 token = strtok_r(NULL, "x", &saveptr);
9991 if (token != NULL) {
9992 minInputSize.height = atoi(token);
9993 }
9994 }
9995
Thierry Strudel3d639192016-09-09 11:52:26 -07009996 /* Add input/output stream configurations for each scalar formats*/
9997 for (size_t j = 0; j < scalar_formats_count; j++) {
9998 switch (scalar_formats[j]) {
9999 case ANDROID_SCALER_AVAILABLE_FORMATS_RAW16:
10000 case ANDROID_SCALER_AVAILABLE_FORMATS_RAW_OPAQUE:
10001 case HAL_PIXEL_FORMAT_RAW10:
10002 for (size_t i = 0; i < MIN(MAX_SIZES_CNT,
10003 gCamCapability[cameraId]->supported_raw_dim_cnt); i++) {
10004 addStreamConfig(available_stream_configs, scalar_formats[j],
10005 gCamCapability[cameraId]->raw_dim[i],
10006 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
10007 }
10008 break;
10009 case HAL_PIXEL_FORMAT_BLOB:
10010 for (size_t i = 0; i < MIN(MAX_SIZES_CNT,
10011 gCamCapability[cameraId]->picture_sizes_tbl_cnt); i++) {
10012 addStreamConfig(available_stream_configs, scalar_formats[j],
10013 gCamCapability[cameraId]->picture_sizes_tbl[i],
10014 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
10015 }
10016 break;
10017 case HAL_PIXEL_FORMAT_YCbCr_420_888:
10018 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
10019 default:
10020 cam_dimension_t largest_picture_size;
10021 memset(&largest_picture_size, 0, sizeof(cam_dimension_t));
10022 for (size_t i = 0; i < MIN(MAX_SIZES_CNT,
10023 gCamCapability[cameraId]->picture_sizes_tbl_cnt); i++) {
10024 addStreamConfig(available_stream_configs, scalar_formats[j],
10025 gCamCapability[cameraId]->picture_sizes_tbl[i],
10026 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
Thierry Strudel2896d122017-02-23 19:18:03 -080010027 /*For below 2 formats we also support i/p streams for reprocessing advertise those*/
Zhijun Hee0cc0ae2017-05-19 22:19:27 -070010028 if ((scalar_formats[j] == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
10029 scalar_formats[j] == HAL_PIXEL_FORMAT_YCbCr_420_888) && i == 0) {
Thierry Strudel2896d122017-02-23 19:18:03 -080010030 if ((gCamCapability[cameraId]->picture_sizes_tbl[i].width
10031 >= minInputSize.width) || (gCamCapability[cameraId]->
10032 picture_sizes_tbl[i].height >= minInputSize.height)) {
10033 addStreamConfig(available_stream_configs, scalar_formats[j],
10034 gCamCapability[cameraId]->picture_sizes_tbl[i],
10035 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT);
10036 }
10037 }
Thierry Strudel3d639192016-09-09 11:52:26 -070010038 }
Thierry Strudel2896d122017-02-23 19:18:03 -080010039
Thierry Strudel3d639192016-09-09 11:52:26 -070010040 break;
10041 }
10042 }
10043
10044 staticInfo.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
10045 available_stream_configs.array(), available_stream_configs.size());
Thierry Strudel3d639192016-09-09 11:52:26 -070010046
10047 /* android.scaler.availableMinFrameDurations */
10048 Vector<int64_t> available_min_durations;
10049 for (size_t j = 0; j < scalar_formats_count; j++) {
10050 switch (scalar_formats[j]) {
10051 case ANDROID_SCALER_AVAILABLE_FORMATS_RAW16:
10052 case ANDROID_SCALER_AVAILABLE_FORMATS_RAW_OPAQUE:
10053 case HAL_PIXEL_FORMAT_RAW10:
10054 for (size_t i = 0; i < MIN(MAX_SIZES_CNT,
10055 gCamCapability[cameraId]->supported_raw_dim_cnt); i++) {
10056 available_min_durations.add(scalar_formats[j]);
10057 available_min_durations.add(gCamCapability[cameraId]->raw_dim[i].width);
10058 available_min_durations.add(gCamCapability[cameraId]->raw_dim[i].height);
10059 available_min_durations.add(gCamCapability[cameraId]->raw_min_duration[i]);
10060 }
10061 break;
10062 default:
10063 for (size_t i = 0; i < MIN(MAX_SIZES_CNT,
10064 gCamCapability[cameraId]->picture_sizes_tbl_cnt); i++) {
10065 available_min_durations.add(scalar_formats[j]);
10066 available_min_durations.add(gCamCapability[cameraId]->picture_sizes_tbl[i].width);
10067 available_min_durations.add(gCamCapability[cameraId]->picture_sizes_tbl[i].height);
10068 available_min_durations.add(gCamCapability[cameraId]->picture_min_duration[i]);
10069 }
10070 break;
10071 }
10072 }
10073 staticInfo.update(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
10074 available_min_durations.array(), available_min_durations.size());
10075
10076 Vector<int32_t> available_hfr_configs;
10077 for (size_t i = 0; i < gCamCapability[cameraId]->hfr_tbl_cnt; i++) {
10078 int32_t fps = 0;
10079 switch (gCamCapability[cameraId]->hfr_tbl[i].mode) {
10080 case CAM_HFR_MODE_60FPS:
10081 fps = 60;
10082 break;
10083 case CAM_HFR_MODE_90FPS:
10084 fps = 90;
10085 break;
10086 case CAM_HFR_MODE_120FPS:
10087 fps = 120;
10088 break;
10089 case CAM_HFR_MODE_150FPS:
10090 fps = 150;
10091 break;
10092 case CAM_HFR_MODE_180FPS:
10093 fps = 180;
10094 break;
10095 case CAM_HFR_MODE_210FPS:
10096 fps = 210;
10097 break;
10098 case CAM_HFR_MODE_240FPS:
10099 fps = 240;
10100 break;
10101 case CAM_HFR_MODE_480FPS:
10102 fps = 480;
10103 break;
10104 case CAM_HFR_MODE_OFF:
10105 case CAM_HFR_MODE_MAX:
10106 default:
10107 break;
10108 }
10109
10110 /* Advertise only MIN_FPS_FOR_BATCH_MODE or above as HIGH_SPEED_CONFIGS */
10111 if (fps >= MIN_FPS_FOR_BATCH_MODE) {
10112 /* For each HFR frame rate, need to advertise one variable fps range
10113 * and one fixed fps range per dimension. Eg: for 120 FPS, advertise [30, 120]
10114 * and [120, 120]. While camcorder preview alone is running [30, 120] is
10115 * set by the app. When video recording is started, [120, 120] is
10116 * set. This way sensor configuration does not change when recording
10117 * is started */
10118
10119 /* (width, height, fps_min, fps_max, batch_size_max) */
10120 for (size_t j = 0; j < gCamCapability[cameraId]->hfr_tbl[i].dim_cnt &&
10121 j < MAX_SIZES_CNT; j++) {
10122 available_hfr_configs.add(
10123 gCamCapability[cameraId]->hfr_tbl[i].dim[j].width);
10124 available_hfr_configs.add(
10125 gCamCapability[cameraId]->hfr_tbl[i].dim[j].height);
10126 available_hfr_configs.add(PREVIEW_FPS_FOR_HFR);
10127 available_hfr_configs.add(fps);
10128 available_hfr_configs.add(fps / PREVIEW_FPS_FOR_HFR);
10129
10130 /* (width, height, fps_min, fps_max, batch_size_max) */
10131 available_hfr_configs.add(
10132 gCamCapability[cameraId]->hfr_tbl[i].dim[j].width);
10133 available_hfr_configs.add(
10134 gCamCapability[cameraId]->hfr_tbl[i].dim[j].height);
10135 available_hfr_configs.add(fps);
10136 available_hfr_configs.add(fps);
10137 available_hfr_configs.add(fps / PREVIEW_FPS_FOR_HFR);
10138 }
10139 }
10140 }
10141 //Advertise HFR capability only if the property is set
10142 memset(prop, 0, sizeof(prop));
10143 property_get("persist.camera.hal3hfr.enable", prop, "1");
10144 uint8_t hfrEnable = (uint8_t)atoi(prop);
10145
10146 if(hfrEnable && available_hfr_configs.array()) {
10147 staticInfo.update(
10148 ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS,
10149 available_hfr_configs.array(), available_hfr_configs.size());
10150 }
10151
10152 int32_t max_jpeg_size = (int32_t)calcMaxJpegSize(cameraId);
10153 staticInfo.update(ANDROID_JPEG_MAX_SIZE,
10154 &max_jpeg_size, 1);
10155
10156 uint8_t avail_effects[CAM_EFFECT_MODE_MAX];
10157 size_t size = 0;
10158 count = CAM_EFFECT_MODE_MAX;
10159 count = MIN(gCamCapability[cameraId]->supported_effects_cnt, count);
10160 for (size_t i = 0; i < count; i++) {
10161 int val = lookupFwkName(EFFECT_MODES_MAP, METADATA_MAP_SIZE(EFFECT_MODES_MAP),
10162 gCamCapability[cameraId]->supported_effects[i]);
10163 if (NAME_NOT_FOUND != val) {
10164 avail_effects[size] = (uint8_t)val;
10165 size++;
10166 }
10167 }
10168 staticInfo.update(ANDROID_CONTROL_AVAILABLE_EFFECTS,
10169 avail_effects,
10170 size);
10171
10172 uint8_t avail_scene_modes[CAM_SCENE_MODE_MAX];
10173 uint8_t supported_indexes[CAM_SCENE_MODE_MAX];
10174 size_t supported_scene_modes_cnt = 0;
10175 count = CAM_SCENE_MODE_MAX;
10176 count = MIN(gCamCapability[cameraId]->supported_scene_modes_cnt, count);
10177 for (size_t i = 0; i < count; i++) {
10178 if (gCamCapability[cameraId]->supported_scene_modes[i] !=
10179 CAM_SCENE_MODE_OFF) {
10180 int val = lookupFwkName(SCENE_MODES_MAP,
10181 METADATA_MAP_SIZE(SCENE_MODES_MAP),
10182 gCamCapability[cameraId]->supported_scene_modes[i]);
Mansoor Aftab58465fa2017-01-26 15:02:44 -080010183
Thierry Strudel3d639192016-09-09 11:52:26 -070010184 if (NAME_NOT_FOUND != val) {
10185 avail_scene_modes[supported_scene_modes_cnt] = (uint8_t)val;
10186 supported_indexes[supported_scene_modes_cnt] = (uint8_t)i;
10187 supported_scene_modes_cnt++;
10188 }
10189 }
10190 }
10191 staticInfo.update(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
10192 avail_scene_modes,
10193 supported_scene_modes_cnt);
10194
10195 uint8_t scene_mode_overrides[CAM_SCENE_MODE_MAX * 3];
10196 makeOverridesList(gCamCapability[cameraId]->scene_mode_overrides,
10197 supported_scene_modes_cnt,
10198 CAM_SCENE_MODE_MAX,
10199 scene_mode_overrides,
10200 supported_indexes,
10201 cameraId);
10202
10203 if (supported_scene_modes_cnt == 0) {
10204 supported_scene_modes_cnt = 1;
10205 avail_scene_modes[0] = ANDROID_CONTROL_SCENE_MODE_DISABLED;
10206 }
10207
10208 staticInfo.update(ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
10209 scene_mode_overrides, supported_scene_modes_cnt * 3);
10210
10211 uint8_t available_control_modes[] = {ANDROID_CONTROL_MODE_OFF,
10212 ANDROID_CONTROL_MODE_AUTO,
10213 ANDROID_CONTROL_MODE_USE_SCENE_MODE};
10214 staticInfo.update(ANDROID_CONTROL_AVAILABLE_MODES,
10215 available_control_modes,
10216 3);
10217
10218 uint8_t avail_antibanding_modes[CAM_ANTIBANDING_MODE_MAX];
10219 size = 0;
10220 count = CAM_ANTIBANDING_MODE_MAX;
10221 count = MIN(gCamCapability[cameraId]->supported_antibandings_cnt, count);
10222 for (size_t i = 0; i < count; i++) {
10223 int val = lookupFwkName(ANTIBANDING_MODES_MAP, METADATA_MAP_SIZE(ANTIBANDING_MODES_MAP),
10224 gCamCapability[cameraId]->supported_antibandings[i]);
10225 if (NAME_NOT_FOUND != val) {
10226 avail_antibanding_modes[size] = (uint8_t)val;
10227 size++;
10228 }
10229
10230 }
10231 staticInfo.update(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
10232 avail_antibanding_modes,
10233 size);
10234
10235 uint8_t avail_abberation_modes[] = {
10236 ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF,
10237 ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST,
10238 ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY};
10239 count = CAM_COLOR_CORRECTION_ABERRATION_MAX;
10240 count = MIN(gCamCapability[cameraId]->aberration_modes_count, count);
10241 if (0 == count) {
10242 // If no aberration correction modes are available for a device, this advertise OFF mode
10243 size = 1;
10244 } else {
10245 // If count is not zero then atleast one among the FAST or HIGH quality is supported
10246 // So, advertize all 3 modes if atleast any one mode is supported as per the
10247 // new M requirement
10248 size = 3;
10249 }
10250 staticInfo.update(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
10251 avail_abberation_modes,
10252 size);
10253
10254 uint8_t avail_af_modes[CAM_FOCUS_MODE_MAX];
10255 size = 0;
10256 count = CAM_FOCUS_MODE_MAX;
10257 count = MIN(gCamCapability[cameraId]->supported_focus_modes_cnt, count);
10258 for (size_t i = 0; i < count; i++) {
10259 int val = lookupFwkName(FOCUS_MODES_MAP, METADATA_MAP_SIZE(FOCUS_MODES_MAP),
10260 gCamCapability[cameraId]->supported_focus_modes[i]);
10261 if (NAME_NOT_FOUND != val) {
10262 avail_af_modes[size] = (uint8_t)val;
10263 size++;
10264 }
10265 }
10266 staticInfo.update(ANDROID_CONTROL_AF_AVAILABLE_MODES,
10267 avail_af_modes,
10268 size);
10269
10270 uint8_t avail_awb_modes[CAM_WB_MODE_MAX];
10271 size = 0;
10272 count = CAM_WB_MODE_MAX;
10273 count = MIN(gCamCapability[cameraId]->supported_white_balances_cnt, count);
10274 for (size_t i = 0; i < count; i++) {
10275 int val = lookupFwkName(WHITE_BALANCE_MODES_MAP,
10276 METADATA_MAP_SIZE(WHITE_BALANCE_MODES_MAP),
10277 gCamCapability[cameraId]->supported_white_balances[i]);
10278 if (NAME_NOT_FOUND != val) {
10279 avail_awb_modes[size] = (uint8_t)val;
10280 size++;
10281 }
10282 }
10283 staticInfo.update(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
10284 avail_awb_modes,
10285 size);
10286
10287 uint8_t available_flash_levels[CAM_FLASH_FIRING_LEVEL_MAX];
10288 count = CAM_FLASH_FIRING_LEVEL_MAX;
10289 count = MIN(gCamCapability[cameraId]->supported_flash_firing_level_cnt,
10290 count);
10291 for (size_t i = 0; i < count; i++) {
10292 available_flash_levels[i] =
10293 gCamCapability[cameraId]->supported_firing_levels[i];
10294 }
10295 staticInfo.update(ANDROID_FLASH_FIRING_POWER,
10296 available_flash_levels, count);
10297
10298 uint8_t flashAvailable;
10299 if (gCamCapability[cameraId]->flash_available)
10300 flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_TRUE;
10301 else
10302 flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;
10303 staticInfo.update(ANDROID_FLASH_INFO_AVAILABLE,
10304 &flashAvailable, 1);
10305
10306 Vector<uint8_t> avail_ae_modes;
10307 count = CAM_AE_MODE_MAX;
10308 count = MIN(gCamCapability[cameraId]->supported_ae_modes_cnt, count);
10309 for (size_t i = 0; i < count; i++) {
Eino-Ville Talvalae2de8432017-02-25 11:11:13 -080010310 uint8_t aeMode = gCamCapability[cameraId]->supported_ae_modes[i];
10311 if (aeMode == CAM_AE_MODE_ON_EXTERNAL_FLASH) {
Chien-Yu Chenc5494e52018-01-19 17:53:58 -080010312 aeMode = ANDROID_CONTROL_AE_MODE_ON_EXTERNAL_FLASH;
Eino-Ville Talvalae2de8432017-02-25 11:11:13 -080010313 }
10314 avail_ae_modes.add(aeMode);
Thierry Strudel3d639192016-09-09 11:52:26 -070010315 }
10316 if (flashAvailable) {
10317 avail_ae_modes.add(ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH);
10318 avail_ae_modes.add(ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH);
10319 }
10320 staticInfo.update(ANDROID_CONTROL_AE_AVAILABLE_MODES,
10321 avail_ae_modes.array(),
10322 avail_ae_modes.size());
10323
10324 int32_t sensitivity_range[2];
10325 sensitivity_range[0] = gCamCapability[cameraId]->sensitivity_range.min_sensitivity;
10326 sensitivity_range[1] = gCamCapability[cameraId]->sensitivity_range.max_sensitivity;
10327 staticInfo.update(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
10328 sensitivity_range,
10329 sizeof(sensitivity_range) / sizeof(int32_t));
10330
10331 staticInfo.update(ANDROID_SENSOR_MAX_ANALOG_SENSITIVITY,
10332 &gCamCapability[cameraId]->max_analog_sensitivity,
10333 1);
10334
10335 int32_t sensor_orientation = (int32_t)gCamCapability[cameraId]->sensor_mount_angle;
10336 staticInfo.update(ANDROID_SENSOR_ORIENTATION,
10337 &sensor_orientation,
10338 1);
10339
10340 int32_t max_output_streams[] = {
10341 MAX_STALLING_STREAMS,
10342 MAX_PROCESSED_STREAMS,
10343 MAX_RAW_STREAMS};
10344 staticInfo.update(ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
10345 max_output_streams,
10346 sizeof(max_output_streams)/sizeof(max_output_streams[0]));
10347
10348 uint8_t avail_leds = 0;
10349 staticInfo.update(ANDROID_LED_AVAILABLE_LEDS,
10350 &avail_leds, 0);
10351
10352 uint8_t focus_dist_calibrated;
10353 int val = lookupFwkName(FOCUS_CALIBRATION_MAP, METADATA_MAP_SIZE(FOCUS_CALIBRATION_MAP),
10354 gCamCapability[cameraId]->focus_dist_calibrated);
10355 if (NAME_NOT_FOUND != val) {
10356 focus_dist_calibrated = (uint8_t)val;
10357 staticInfo.update(ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION,
10358 &focus_dist_calibrated, 1);
10359 }
10360
10361 int32_t avail_testpattern_modes[MAX_TEST_PATTERN_CNT];
10362 size = 0;
10363 count = MIN(gCamCapability[cameraId]->supported_test_pattern_modes_cnt,
10364 MAX_TEST_PATTERN_CNT);
10365 for (size_t i = 0; i < count; i++) {
10366 int testpatternMode = lookupFwkName(TEST_PATTERN_MAP, METADATA_MAP_SIZE(TEST_PATTERN_MAP),
10367 gCamCapability[cameraId]->supported_test_pattern_modes[i]);
10368 if (NAME_NOT_FOUND != testpatternMode) {
10369 avail_testpattern_modes[size] = testpatternMode;
10370 size++;
10371 }
10372 }
10373 staticInfo.update(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
10374 avail_testpattern_modes,
10375 size);
10376
10377 uint8_t max_pipeline_depth = (uint8_t)(MAX_INFLIGHT_REQUESTS + EMPTY_PIPELINE_DELAY + FRAME_SKIP_DELAY);
10378 staticInfo.update(ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
10379 &max_pipeline_depth,
10380 1);
10381
10382 int32_t partial_result_count = PARTIAL_RESULT_COUNT;
10383 staticInfo.update(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
10384 &partial_result_count,
10385 1);
10386
10387 int32_t max_stall_duration = MAX_REPROCESS_STALL;
10388 staticInfo.update(ANDROID_REPROCESS_MAX_CAPTURE_STALL, &max_stall_duration, 1);
10389
10390 Vector<uint8_t> available_capabilities;
10391 available_capabilities.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE);
10392 available_capabilities.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR);
10393 available_capabilities.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING);
10394 available_capabilities.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS);
10395 if (supportBurst) {
10396 available_capabilities.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE);
10397 }
10398 available_capabilities.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING);
10399 available_capabilities.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING);
10400 if (hfrEnable && available_hfr_configs.array()) {
10401 available_capabilities.add(
10402 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO);
10403 }
10404
10405 if (CAM_SENSOR_YUV != gCamCapability[cameraId]->sensor_type.sens_type) {
10406 available_capabilities.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW);
10407 }
Eino-Ville Talvala42d58952018-01-05 16:20:10 -080010408 // Only back camera supports MOTION_TRACKING
10409 if (cameraId == 0) {
10410 available_capabilities.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING);
10411 }
10412
Thierry Strudel3d639192016-09-09 11:52:26 -070010413 staticInfo.update(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
10414 available_capabilities.array(),
10415 available_capabilities.size());
10416
10417 //aeLockAvailable to be set to true if capabilities has MANUAL_SENSOR or BURST_CAPTURE
10418 //Assumption is that all bayer cameras support MANUAL_SENSOR.
10419 uint8_t aeLockAvailable = (gCamCapability[cameraId]->sensor_type.sens_type == CAM_SENSOR_RAW) ?
10420 ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE : ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
10421
10422 staticInfo.update(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
10423 &aeLockAvailable, 1);
10424
10425 //awbLockAvailable to be set to true if capabilities has MANUAL_POST_PROCESSING or
10426 //BURST_CAPTURE. Assumption is that all bayer cameras support MANUAL_POST_PROCESSING.
10427 uint8_t awbLockAvailable = (gCamCapability[cameraId]->sensor_type.sens_type == CAM_SENSOR_RAW) ?
10428 ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE : ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
10429
10430 staticInfo.update(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
10431 &awbLockAvailable, 1);
10432
10433 int32_t max_input_streams = 1;
10434 staticInfo.update(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
10435 &max_input_streams,
10436 1);
10437
10438 /* format of the map is : input format, num_output_formats, outputFormat1,..,outputFormatN */
10439 int32_t io_format_map[] = {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, 2,
10440 HAL_PIXEL_FORMAT_BLOB, HAL_PIXEL_FORMAT_YCbCr_420_888,
10441 HAL_PIXEL_FORMAT_YCbCr_420_888, 2, HAL_PIXEL_FORMAT_BLOB,
10442 HAL_PIXEL_FORMAT_YCbCr_420_888};
10443 staticInfo.update(ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP,
10444 io_format_map, sizeof(io_format_map)/sizeof(io_format_map[0]));
10445
10446 int32_t max_latency = ANDROID_SYNC_MAX_LATENCY_PER_FRAME_CONTROL;
10447 staticInfo.update(ANDROID_SYNC_MAX_LATENCY,
10448 &max_latency,
10449 1);
10450
Thierry Strudel9e74aae2016-09-22 17:10:18 -070010451#ifndef USE_HAL_3_3
10452 int32_t isp_sensitivity_range[2];
10453 isp_sensitivity_range[0] =
10454 gCamCapability[cameraId]->isp_sensitivity_range.min_sensitivity;
10455 isp_sensitivity_range[1] =
10456 gCamCapability[cameraId]->isp_sensitivity_range.max_sensitivity;
10457 staticInfo.update(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE,
10458 isp_sensitivity_range,
10459 sizeof(isp_sensitivity_range) / sizeof(isp_sensitivity_range[0]));
10460#endif
10461
Thierry Strudel3d639192016-09-09 11:52:26 -070010462 uint8_t available_hot_pixel_modes[] = {ANDROID_HOT_PIXEL_MODE_FAST,
10463 ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY};
10464 staticInfo.update(ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES,
10465 available_hot_pixel_modes,
10466 sizeof(available_hot_pixel_modes)/sizeof(available_hot_pixel_modes[0]));
10467
10468 uint8_t available_shading_modes[] = {ANDROID_SHADING_MODE_OFF,
10469 ANDROID_SHADING_MODE_FAST,
10470 ANDROID_SHADING_MODE_HIGH_QUALITY};
10471 staticInfo.update(ANDROID_SHADING_AVAILABLE_MODES,
10472 available_shading_modes,
10473 3);
10474
10475 uint8_t available_lens_shading_map_modes[] = {ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF,
10476 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON};
10477 staticInfo.update(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
10478 available_lens_shading_map_modes,
10479 2);
10480
10481 uint8_t available_edge_modes[] = {ANDROID_EDGE_MODE_OFF,
10482 ANDROID_EDGE_MODE_FAST,
10483 ANDROID_EDGE_MODE_HIGH_QUALITY,
10484 ANDROID_EDGE_MODE_ZERO_SHUTTER_LAG};
10485 staticInfo.update(ANDROID_EDGE_AVAILABLE_EDGE_MODES,
10486 available_edge_modes,
10487 sizeof(available_edge_modes)/sizeof(available_edge_modes[0]));
10488
10489 uint8_t available_noise_red_modes[] = {ANDROID_NOISE_REDUCTION_MODE_OFF,
10490 ANDROID_NOISE_REDUCTION_MODE_FAST,
10491 ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY,
10492 ANDROID_NOISE_REDUCTION_MODE_MINIMAL,
10493 ANDROID_NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG};
10494 staticInfo.update(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
10495 available_noise_red_modes,
10496 sizeof(available_noise_red_modes)/sizeof(available_noise_red_modes[0]));
10497
10498 uint8_t available_tonemap_modes[] = {ANDROID_TONEMAP_MODE_CONTRAST_CURVE,
10499 ANDROID_TONEMAP_MODE_FAST,
10500 ANDROID_TONEMAP_MODE_HIGH_QUALITY};
10501 staticInfo.update(ANDROID_TONEMAP_AVAILABLE_TONE_MAP_MODES,
10502 available_tonemap_modes,
10503 sizeof(available_tonemap_modes)/sizeof(available_tonemap_modes[0]));
10504
10505 uint8_t available_hot_pixel_map_modes[] = {ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF};
10506 staticInfo.update(ANDROID_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES,
10507 available_hot_pixel_map_modes,
10508 sizeof(available_hot_pixel_map_modes)/sizeof(available_hot_pixel_map_modes[0]));
10509
10510 val = lookupFwkName(REFERENCE_ILLUMINANT_MAP, METADATA_MAP_SIZE(REFERENCE_ILLUMINANT_MAP),
10511 gCamCapability[cameraId]->reference_illuminant1);
10512 if (NAME_NOT_FOUND != val) {
10513 uint8_t fwkReferenceIlluminant = (uint8_t)val;
10514 staticInfo.update(ANDROID_SENSOR_REFERENCE_ILLUMINANT1, &fwkReferenceIlluminant, 1);
10515 }
10516
10517 val = lookupFwkName(REFERENCE_ILLUMINANT_MAP, METADATA_MAP_SIZE(REFERENCE_ILLUMINANT_MAP),
10518 gCamCapability[cameraId]->reference_illuminant2);
10519 if (NAME_NOT_FOUND != val) {
10520 uint8_t fwkReferenceIlluminant = (uint8_t)val;
10521 staticInfo.update(ANDROID_SENSOR_REFERENCE_ILLUMINANT2, &fwkReferenceIlluminant, 1);
10522 }
10523
10524 staticInfo.update(ANDROID_SENSOR_FORWARD_MATRIX1, (camera_metadata_rational_t *)
10525 (void *)gCamCapability[cameraId]->forward_matrix1,
10526 FORWARD_MATRIX_COLS * FORWARD_MATRIX_ROWS);
10527
10528 staticInfo.update(ANDROID_SENSOR_FORWARD_MATRIX2, (camera_metadata_rational_t *)
10529 (void *)gCamCapability[cameraId]->forward_matrix2,
10530 FORWARD_MATRIX_COLS * FORWARD_MATRIX_ROWS);
10531
10532 staticInfo.update(ANDROID_SENSOR_COLOR_TRANSFORM1, (camera_metadata_rational_t *)
10533 (void *)gCamCapability[cameraId]->color_transform1,
10534 COLOR_TRANSFORM_COLS * COLOR_TRANSFORM_ROWS);
10535
10536 staticInfo.update(ANDROID_SENSOR_COLOR_TRANSFORM2, (camera_metadata_rational_t *)
10537 (void *)gCamCapability[cameraId]->color_transform2,
10538 COLOR_TRANSFORM_COLS * COLOR_TRANSFORM_ROWS);
10539
10540 staticInfo.update(ANDROID_SENSOR_CALIBRATION_TRANSFORM1, (camera_metadata_rational_t *)
10541 (void *)gCamCapability[cameraId]->calibration_transform1,
10542 CAL_TRANSFORM_COLS * CAL_TRANSFORM_ROWS);
10543
10544 staticInfo.update(ANDROID_SENSOR_CALIBRATION_TRANSFORM2, (camera_metadata_rational_t *)
10545 (void *)gCamCapability[cameraId]->calibration_transform2,
10546 CAL_TRANSFORM_COLS * CAL_TRANSFORM_ROWS);
10547
Emilian Peev6d4cdc22017-11-16 16:56:23 +000010548#ifndef USE_HAL_3_3
10549
10550 int32_t session_keys[] = {ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
10551 ANDROID_CONTROL_AE_TARGET_FPS_RANGE, QCAMERA3_INSTANT_AEC_MODE, QCAMERA3_USE_AV_TIMER,
10552 QCAMERA3_VIDEO_HDR_MODE, TANGO_MODE_DATA_SENSOR_FULLFOV};
10553 staticInfo.update(ANDROID_REQUEST_AVAILABLE_SESSION_KEYS, session_keys,
10554 sizeof(session_keys) / sizeof(session_keys[0]));
10555
10556#endif
10557
Thierry Strudel3d639192016-09-09 11:52:26 -070010558 int32_t request_keys_basic[] = {ANDROID_COLOR_CORRECTION_MODE,
10559 ANDROID_COLOR_CORRECTION_TRANSFORM, ANDROID_COLOR_CORRECTION_GAINS,
10560 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
10561 ANDROID_CONTROL_AE_ANTIBANDING_MODE, ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
10562 ANDROID_CONTROL_AE_LOCK, ANDROID_CONTROL_AE_MODE,
10563 ANDROID_CONTROL_AE_REGIONS, ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
10564 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, ANDROID_CONTROL_AF_MODE,
10565 ANDROID_CONTROL_AF_TRIGGER, ANDROID_CONTROL_AWB_LOCK,
10566 ANDROID_CONTROL_AWB_MODE, ANDROID_CONTROL_CAPTURE_INTENT,
10567 ANDROID_CONTROL_EFFECT_MODE, ANDROID_CONTROL_MODE,
10568 ANDROID_CONTROL_SCENE_MODE, ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
10569 ANDROID_DEMOSAIC_MODE, ANDROID_EDGE_MODE,
10570 ANDROID_FLASH_FIRING_POWER, ANDROID_FLASH_FIRING_TIME, ANDROID_FLASH_MODE,
10571 ANDROID_JPEG_GPS_COORDINATES,
10572 ANDROID_JPEG_GPS_PROCESSING_METHOD, ANDROID_JPEG_GPS_TIMESTAMP,
10573 ANDROID_JPEG_ORIENTATION, ANDROID_JPEG_QUALITY, ANDROID_JPEG_THUMBNAIL_QUALITY,
10574 ANDROID_JPEG_THUMBNAIL_SIZE, ANDROID_LENS_APERTURE, ANDROID_LENS_FILTER_DENSITY,
10575 ANDROID_LENS_FOCAL_LENGTH, ANDROID_LENS_FOCUS_DISTANCE,
10576 ANDROID_LENS_OPTICAL_STABILIZATION_MODE, ANDROID_NOISE_REDUCTION_MODE,
10577 ANDROID_REQUEST_ID, ANDROID_REQUEST_TYPE,
10578 ANDROID_SCALER_CROP_REGION, ANDROID_SENSOR_EXPOSURE_TIME,
10579 ANDROID_SENSOR_FRAME_DURATION, ANDROID_HOT_PIXEL_MODE,
10580 ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,
10581 ANDROID_SENSOR_SENSITIVITY, ANDROID_SHADING_MODE,
Thierry Strudel9e74aae2016-09-22 17:10:18 -070010582#ifndef USE_HAL_3_3
10583 ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST,
10584#endif
Thierry Strudel3d639192016-09-09 11:52:26 -070010585 ANDROID_STATISTICS_FACE_DETECT_MODE,
Chien-Yu Chen7f9a15b2018-01-23 16:13:31 -080010586 ANDROID_STATISTICS_SHARPNESS_MAP_MODE, ANDROID_STATISTICS_OIS_DATA_MODE,
Thierry Strudel3d639192016-09-09 11:52:26 -070010587 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, ANDROID_TONEMAP_CURVE_BLUE,
10588 ANDROID_TONEMAP_CURVE_GREEN, ANDROID_TONEMAP_CURVE_RED, ANDROID_TONEMAP_MODE,
Shuzhen Wang2abea3d2016-03-31 11:09:27 -070010589 ANDROID_BLACK_LEVEL_LOCK, NEXUS_EXPERIMENTAL_2016_HYBRID_AE_ENABLE,
Emilian Peeve91e9ae2017-09-18 14:40:55 +010010590 QCAMERA3_PRIVATEDATA_REPROCESS, QCAMERA3_CDS_MODE, QCAMERA3_CDS_INFO,
10591 QCAMERA3_CROP_COUNT_REPROCESS, QCAMERA3_CROP_REPROCESS,
10592 QCAMERA3_CROP_ROI_MAP_REPROCESS, QCAMERA3_TEMPORAL_DENOISE_ENABLE,
10593 QCAMERA3_TEMPORAL_DENOISE_PROCESS_TYPE, QCAMERA3_USE_ISO_EXP_PRIORITY,
10594 QCAMERA3_SELECT_PRIORITY, QCAMERA3_USE_SATURATION,
10595 QCAMERA3_EXPOSURE_METER, QCAMERA3_USE_AV_TIMER,
10596 QCAMERA3_DUALCAM_LINK_ENABLE, QCAMERA3_DUALCAM_LINK_IS_MAIN,
10597 QCAMERA3_DUALCAM_LINK_RELATED_CAMERA_ID,
10598 QCAMERA3_HAL_PRIVATEDATA_REPROCESS_FLAGS,
10599 QCAMERA3_HAL_PRIVATEDATA_REPROCESS_DATA_BLOB,
10600 QCAMERA3_HAL_PRIVATEDATA_EXIF_DEBUG_DATA_BLOB,
10601 QCAMERA3_JPEG_ENCODE_CROP_ENABLE, QCAMERA3_JPEG_ENCODE_CROP_RECT,
10602 QCAMERA3_JPEG_ENCODE_CROP_ROI, QCAMERA3_VIDEO_HDR_MODE,
10603 QCAMERA3_IR_MODE, QCAMERA3_AEC_CONVERGENCE_SPEED,
10604 QCAMERA3_AWB_CONVERGENCE_SPEED, QCAMERA3_INSTANT_AEC_MODE,
10605 QCAMERA3_SHARPNESS_STRENGTH, QCAMERA3_HISTOGRAM_MODE,
10606 QCAMERA3_BINNING_CORRECTION_MODE,
Samuel Ha68ba5172016-12-15 18:41:12 -080010607 /* DevCamDebug metadata request_keys_basic */
10608 DEVCAMDEBUG_META_ENABLE,
10609 /* DevCamDebug metadata end */
Shuzhen Wang14415f52016-11-16 18:26:18 -080010610 NEXUS_EXPERIMENTAL_2017_HISTOGRAM_ENABLE,
Ranjith Kagathi Ananda0533b682017-03-24 17:52:46 -070010611 NEXUS_EXPERIMENTAL_2017_HISTOGRAM_BINS,
Ranjith Kagathi Anandae5df3752017-04-28 11:22:51 -070010612 TANGO_MODE_DATA_SENSOR_FULLFOV,
Shuzhen Wangf1b4ddc2017-04-10 18:22:11 -070010613 NEXUS_EXPERIMENTAL_2017_TRACKING_AF_TRIGGER,
Emilian Peev656e4fa2017-06-02 16:47:04 +010010614 NEXUS_EXPERIMENTAL_2017_PD_DATA_ENABLE,
Wei (Alex) Honga90a2142018-01-05 17:36:52 -080010615 NEXUS_EXPERIMENTAL_2017_EXIF_MAKERNOTE,
10616 NEXUS_EXPERIMENTAL_2017_MOTION_DETECTION_ENABLE,
Samuel Ha68ba5172016-12-15 18:41:12 -080010617 };
Thierry Strudel3d639192016-09-09 11:52:26 -070010618
10619 size_t request_keys_cnt =
10620 sizeof(request_keys_basic)/sizeof(request_keys_basic[0]);
10621 Vector<int32_t> available_request_keys;
10622 available_request_keys.appendArray(request_keys_basic, request_keys_cnt);
10623 if (gCamCapability[cameraId]->supported_focus_modes_cnt > 1) {
10624 available_request_keys.add(ANDROID_CONTROL_AF_REGIONS);
10625 }
10626
Chien-Yu Chen66ec22a2017-04-13 18:00:36 -070010627 if (gExposeEnableZslKey) {
Chenjie Luo4a761802017-06-13 17:35:54 +000010628 available_request_keys.add(ANDROID_CONTROL_ENABLE_ZSL);
Chien-Yu Chen0a921f92017-08-27 17:25:33 -070010629 available_request_keys.add(NEXUS_EXPERIMENTAL_2017_POSTVIEW);
Chien-Yu Chenb0981e32017-08-28 19:27:35 -070010630 available_request_keys.add(NEXUS_EXPERIMENTAL_2017_CONTINUOUS_ZSL_CAPTURE);
Chien-Yu Chenec328c82017-08-30 16:41:08 -070010631 available_request_keys.add(NEXUS_EXPERIMENTAL_2017_DISABLE_HDRPLUS);
Chien-Yu Chen66ec22a2017-04-13 18:00:36 -070010632 }
10633
Thierry Strudel3d639192016-09-09 11:52:26 -070010634 staticInfo.update(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
10635 available_request_keys.array(), available_request_keys.size());
10636
10637 int32_t result_keys_basic[] = {ANDROID_COLOR_CORRECTION_TRANSFORM,
10638 ANDROID_COLOR_CORRECTION_GAINS, ANDROID_CONTROL_AE_MODE, ANDROID_CONTROL_AE_REGIONS,
10639 ANDROID_CONTROL_AE_STATE, ANDROID_CONTROL_AF_MODE,
10640 ANDROID_CONTROL_AF_STATE, ANDROID_CONTROL_AWB_MODE,
Chien-Yu Chenc5494e52018-01-19 17:53:58 -080010641 ANDROID_CONTROL_AF_SCENE_CHANGE,
Thierry Strudel3d639192016-09-09 11:52:26 -070010642 ANDROID_CONTROL_AWB_STATE, ANDROID_CONTROL_MODE, ANDROID_EDGE_MODE,
10643 ANDROID_FLASH_FIRING_POWER, ANDROID_FLASH_FIRING_TIME, ANDROID_FLASH_MODE,
10644 ANDROID_FLASH_STATE, ANDROID_JPEG_GPS_COORDINATES, ANDROID_JPEG_GPS_PROCESSING_METHOD,
10645 ANDROID_JPEG_GPS_TIMESTAMP, ANDROID_JPEG_ORIENTATION, ANDROID_JPEG_QUALITY,
10646 ANDROID_JPEG_THUMBNAIL_QUALITY, ANDROID_JPEG_THUMBNAIL_SIZE, ANDROID_LENS_APERTURE,
10647 ANDROID_LENS_FILTER_DENSITY, ANDROID_LENS_FOCAL_LENGTH, ANDROID_LENS_FOCUS_DISTANCE,
10648 ANDROID_LENS_FOCUS_RANGE, ANDROID_LENS_STATE, ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
10649 ANDROID_NOISE_REDUCTION_MODE, ANDROID_REQUEST_ID,
10650 ANDROID_SCALER_CROP_REGION, ANDROID_SHADING_MODE, ANDROID_SENSOR_EXPOSURE_TIME,
10651 ANDROID_SENSOR_FRAME_DURATION, ANDROID_SENSOR_SENSITIVITY,
10652 ANDROID_SENSOR_TIMESTAMP, ANDROID_SENSOR_NEUTRAL_COLOR_POINT,
10653 ANDROID_SENSOR_PROFILE_TONE_CURVE, ANDROID_BLACK_LEVEL_LOCK, ANDROID_TONEMAP_CURVE_BLUE,
10654 ANDROID_TONEMAP_CURVE_GREEN, ANDROID_TONEMAP_CURVE_RED, ANDROID_TONEMAP_MODE,
Thierry Strudel54dc9782017-02-15 12:12:10 -080010655 ANDROID_STATISTICS_FACE_DETECT_MODE,
Thierry Strudel3d639192016-09-09 11:52:26 -070010656 ANDROID_STATISTICS_SHARPNESS_MAP, ANDROID_STATISTICS_SHARPNESS_MAP_MODE,
10657 ANDROID_STATISTICS_PREDICTED_COLOR_GAINS, ANDROID_STATISTICS_PREDICTED_COLOR_TRANSFORM,
10658 ANDROID_STATISTICS_SCENE_FLICKER, ANDROID_STATISTICS_FACE_RECTANGLES,
Chien-Yu Chen7f9a15b2018-01-23 16:13:31 -080010659 ANDROID_STATISTICS_FACE_SCORES, ANDROID_STATISTICS_OIS_DATA_MODE,
10660 ANDROID_STATISTICS_OIS_TIMESTAMPS, ANDROID_STATISTICS_OIS_X_SHIFTS,
10661 ANDROID_STATISTICS_OIS_Y_SHIFTS,
Thierry Strudel9e74aae2016-09-22 17:10:18 -070010662#ifndef USE_HAL_3_3
10663 ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST,
10664#endif
Shuzhen Wang2abea3d2016-03-31 11:09:27 -070010665 NEXUS_EXPERIMENTAL_2016_HYBRID_AE_ENABLE,
Shuzhen Wange763e802016-03-31 10:24:29 -070010666 NEXUS_EXPERIMENTAL_2016_AF_SCENE_CHANGE,
Emilian Peeve91e9ae2017-09-18 14:40:55 +010010667 QCAMERA3_PRIVATEDATA_REPROCESS, QCAMERA3_CDS_MODE, QCAMERA3_CDS_INFO,
10668 QCAMERA3_CROP_COUNT_REPROCESS, QCAMERA3_CROP_REPROCESS,
10669 QCAMERA3_CROP_ROI_MAP_REPROCESS, QCAMERA3_TUNING_META_DATA_BLOB,
10670 QCAMERA3_TEMPORAL_DENOISE_ENABLE, QCAMERA3_TEMPORAL_DENOISE_PROCESS_TYPE,
10671 QCAMERA3_EXPOSURE_METER, QCAMERA3_SENSOR_DYNAMIC_BLACK_LEVEL_PATTERN,
10672 QCAMERA3_DUALCAM_LINK_ENABLE, QCAMERA3_DUALCAM_LINK_IS_MAIN,
10673 QCAMERA3_DUALCAM_LINK_RELATED_CAMERA_ID,
10674 QCAMERA3_HAL_PRIVATEDATA_REPROCESS_FLAGS,
10675 QCAMERA3_HAL_PRIVATEDATA_REPROCESS_DATA_BLOB,
10676 QCAMERA3_HAL_PRIVATEDATA_EXIF_DEBUG_DATA_BLOB, QCAMERA3_VIDEO_HDR_MODE,
10677 QCAMERA3_IR_MODE, QCAMERA3_AEC_CONVERGENCE_SPEED,
10678 QCAMERA3_AWB_CONVERGENCE_SPEED, QCAMERA3_INSTANT_AEC_MODE,
10679 QCAMERA3_HISTOGRAM_MODE, QCAMERA3_BINNING_CORRECTION_MODE,
10680 QCAMERA3_STATS_IS_HDR_SCENE, QCAMERA3_STATS_IS_HDR_SCENE_CONFIDENCE,
10681 QCAMERA3_STATS_BLINK_DETECTED, QCAMERA3_STATS_BLINK_DEGREE,
10682 QCAMERA3_STATS_SMILE_DEGREE, QCAMERA3_STATS_SMILE_CONFIDENCE,
10683 QCAMERA3_STATS_GAZE_ANGLE, QCAMERA3_STATS_GAZE_DIRECTION,
10684 QCAMERA3_STATS_GAZE_DEGREE,
Samuel Ha68ba5172016-12-15 18:41:12 -080010685 // DevCamDebug metadata result_keys_basic
10686 DEVCAMDEBUG_META_ENABLE,
10687 // DevCamDebug metadata result_keys AF
10688 DEVCAMDEBUG_AF_LENS_POSITION,
10689 DEVCAMDEBUG_AF_TOF_CONFIDENCE,
10690 DEVCAMDEBUG_AF_TOF_DISTANCE,
10691 DEVCAMDEBUG_AF_LUMA,
10692 DEVCAMDEBUG_AF_HAF_STATE,
10693 DEVCAMDEBUG_AF_MONITOR_PDAF_TARGET_POS,
10694 DEVCAMDEBUG_AF_MONITOR_PDAF_CONFIDENCE,
10695 DEVCAMDEBUG_AF_MONITOR_PDAF_REFOCUS,
10696 DEVCAMDEBUG_AF_MONITOR_TOF_TARGET_POS,
10697 DEVCAMDEBUG_AF_MONITOR_TOF_CONFIDENCE,
10698 DEVCAMDEBUG_AF_MONITOR_TOF_REFOCUS,
10699 DEVCAMDEBUG_AF_MONITOR_TYPE_SELECT,
10700 DEVCAMDEBUG_AF_MONITOR_REFOCUS,
10701 DEVCAMDEBUG_AF_MONITOR_TARGET_POS,
10702 DEVCAMDEBUG_AF_SEARCH_PDAF_TARGET_POS,
10703 DEVCAMDEBUG_AF_SEARCH_PDAF_NEXT_POS,
10704 DEVCAMDEBUG_AF_SEARCH_PDAF_NEAR_POS,
10705 DEVCAMDEBUG_AF_SEARCH_PDAF_FAR_POS,
10706 DEVCAMDEBUG_AF_SEARCH_PDAF_CONFIDENCE,
10707 DEVCAMDEBUG_AF_SEARCH_TOF_TARGET_POS,
10708 DEVCAMDEBUG_AF_SEARCH_TOF_NEXT_POS,
10709 DEVCAMDEBUG_AF_SEARCH_TOF_NEAR_POS,
10710 DEVCAMDEBUG_AF_SEARCH_TOF_FAR_POS,
10711 DEVCAMDEBUG_AF_SEARCH_TOF_CONFIDENCE,
10712 DEVCAMDEBUG_AF_SEARCH_TYPE_SELECT,
10713 DEVCAMDEBUG_AF_SEARCH_NEXT_POS,
10714 DEVCAMDEBUG_AF_SEARCH_TARGET_POS,
10715 // DevCamDebug metadata result_keys AEC
10716 DEVCAMDEBUG_AEC_TARGET_LUMA,
10717 DEVCAMDEBUG_AEC_COMP_LUMA,
10718 DEVCAMDEBUG_AEC_AVG_LUMA,
10719 DEVCAMDEBUG_AEC_CUR_LUMA,
10720 DEVCAMDEBUG_AEC_LINECOUNT,
10721 DEVCAMDEBUG_AEC_REAL_GAIN,
10722 DEVCAMDEBUG_AEC_EXP_INDEX,
10723 DEVCAMDEBUG_AEC_LUX_IDX,
Samuel Ha34229982017-02-17 13:51:11 -080010724 // DevCamDebug metadata result_keys zzHDR
10725 DEVCAMDEBUG_AEC_L_REAL_GAIN,
10726 DEVCAMDEBUG_AEC_L_LINECOUNT,
10727 DEVCAMDEBUG_AEC_S_REAL_GAIN,
10728 DEVCAMDEBUG_AEC_S_LINECOUNT,
10729 DEVCAMDEBUG_AEC_HDR_SENSITIVITY_RATIO,
10730 DEVCAMDEBUG_AEC_HDR_EXP_TIME_RATIO,
10731 // DevCamDebug metadata result_keys ADRC
10732 DEVCAMDEBUG_AEC_TOTAL_DRC_GAIN,
10733 DEVCAMDEBUG_AEC_COLOR_DRC_GAIN,
10734 DEVCAMDEBUG_AEC_GTM_RATIO,
10735 DEVCAMDEBUG_AEC_LTM_RATIO,
10736 DEVCAMDEBUG_AEC_LA_RATIO,
10737 DEVCAMDEBUG_AEC_GAMMA_RATIO,
Samuel Habdf4fac2017-07-28 17:21:18 -070010738 // DevCamDebug metadata result_keys AEC MOTION
10739 DEVCAMDEBUG_AEC_CAMERA_MOTION_DX,
10740 DEVCAMDEBUG_AEC_CAMERA_MOTION_DY,
10741 DEVCAMDEBUG_AEC_SUBJECT_MOTION,
Samuel Ha68ba5172016-12-15 18:41:12 -080010742 // DevCamDebug metadata result_keys AWB
10743 DEVCAMDEBUG_AWB_R_GAIN,
10744 DEVCAMDEBUG_AWB_G_GAIN,
10745 DEVCAMDEBUG_AWB_B_GAIN,
10746 DEVCAMDEBUG_AWB_CCT,
10747 DEVCAMDEBUG_AWB_DECISION,
10748 /* DevCamDebug metadata end */
Shuzhen Wang14415f52016-11-16 18:26:18 -080010749 NEXUS_EXPERIMENTAL_2017_HISTOGRAM_ENABLE,
10750 NEXUS_EXPERIMENTAL_2017_HISTOGRAM_BINS,
10751 NEXUS_EXPERIMENTAL_2017_HISTOGRAM,
Shuzhen Wangf1b4ddc2017-04-10 18:22:11 -070010752 NEXUS_EXPERIMENTAL_2017_AF_REGIONS_CONFIDENCE,
Emilian Peeve91e9ae2017-09-18 14:40:55 +010010753 NEXUS_EXPERIMENTAL_2017_TRACKING_AF_TRIGGER,
Shuzhen Wangc89c77e2017-08-07 15:50:12 -070010754 NEXUS_EXPERIMENTAL_2017_EXP_TIME_BOOST,
Shuzhen Wang3569d4a2017-09-04 19:10:28 -070010755 NEXUS_EXPERIMENTAL_2017_SCENE_DISTANCE,
Emilian Peeve91e9ae2017-09-18 14:40:55 +010010756 NEXUS_EXPERIMENTAL_2017_OIS_FRAME_TIMESTAMP_VSYNC,
10757 NEXUS_EXPERIMENTAL_2017_OIS_FRAME_TIMESTAMP_BOOTTIME,
10758 NEXUS_EXPERIMENTAL_2017_OIS_TIMESTAMPS_BOOTTIME,
10759 NEXUS_EXPERIMENTAL_2017_OIS_SHIFT_X,
10760 NEXUS_EXPERIMENTAL_2017_OIS_SHIFT_Y,
10761 NEXUS_EXPERIMENTAL_2017_OIS_SHIFT_PIXEL_X,
Wei (Alex) Honga90a2142018-01-05 17:36:52 -080010762 NEXUS_EXPERIMENTAL_2017_OIS_SHIFT_PIXEL_Y,
10763 NEXUS_EXPERIMENTAL_2017_MOTION_DETECTION_ENABLE,
10764 NEXUS_EXPERIMENTAL_2017_CAMERA_MOTION_X,
10765 NEXUS_EXPERIMENTAL_2017_CAMERA_MOTION_Y,
10766 NEXUS_EXPERIMENTAL_2017_SUBJECT_MOTION
Thierry Strudel9e74aae2016-09-22 17:10:18 -070010767 };
10768
Thierry Strudel3d639192016-09-09 11:52:26 -070010769 size_t result_keys_cnt =
10770 sizeof(result_keys_basic)/sizeof(result_keys_basic[0]);
10771
10772 Vector<int32_t> available_result_keys;
10773 available_result_keys.appendArray(result_keys_basic, result_keys_cnt);
10774 if (gCamCapability[cameraId]->supported_focus_modes_cnt > 1) {
10775 available_result_keys.add(ANDROID_CONTROL_AF_REGIONS);
10776 }
10777 if (CAM_SENSOR_RAW == gCamCapability[cameraId]->sensor_type.sens_type) {
10778 available_result_keys.add(ANDROID_SENSOR_NOISE_PROFILE);
10779 available_result_keys.add(ANDROID_SENSOR_GREEN_SPLIT);
10780 }
10781 if (supportedFaceDetectMode == 1) {
10782 available_result_keys.add(ANDROID_STATISTICS_FACE_RECTANGLES);
10783 available_result_keys.add(ANDROID_STATISTICS_FACE_SCORES);
10784 } else if ((supportedFaceDetectMode == 2) ||
10785 (supportedFaceDetectMode == 3)) {
10786 available_result_keys.add(ANDROID_STATISTICS_FACE_IDS);
10787 available_result_keys.add(ANDROID_STATISTICS_FACE_LANDMARKS);
10788 }
Thierry Strudel9e74aae2016-09-22 17:10:18 -070010789#ifndef USE_HAL_3_3
Shuzhen Wanga1bc9de2017-09-14 16:54:02 -070010790 {
Thierry Strudel9e74aae2016-09-22 17:10:18 -070010791 available_result_keys.add(ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL);
10792 available_result_keys.add(ANDROID_SENSOR_DYNAMIC_WHITE_LEVEL);
10793 }
10794#endif
Chien-Yu Chen66ec22a2017-04-13 18:00:36 -070010795
10796 if (gExposeEnableZslKey) {
10797 available_result_keys.add(ANDROID_CONTROL_ENABLE_ZSL);
Chien-Yu Chendaf68892017-08-25 12:56:40 -070010798 available_result_keys.add(NEXUS_EXPERIMENTAL_2017_NEXT_STILL_INTENT_REQUEST_READY);
Chien-Yu Chen0a921f92017-08-27 17:25:33 -070010799 available_result_keys.add(NEXUS_EXPERIMENTAL_2017_POSTVIEW_CONFIG);
10800 available_result_keys.add(NEXUS_EXPERIMENTAL_2017_POSTVIEW_DATA);
Chien-Yu Chen66ec22a2017-04-13 18:00:36 -070010801 }
10802
Thierry Strudel3d639192016-09-09 11:52:26 -070010803 staticInfo.update(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
10804 available_result_keys.array(), available_result_keys.size());
10805
Thierry Strudel9e74aae2016-09-22 17:10:18 -070010806 int32_t characteristics_keys_basic[] = {ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
Thierry Strudel3d639192016-09-09 11:52:26 -070010807 ANDROID_CONTROL_AE_AVAILABLE_MODES, ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
10808 ANDROID_CONTROL_AE_COMPENSATION_RANGE, ANDROID_CONTROL_AE_COMPENSATION_STEP,
10809 ANDROID_CONTROL_AF_AVAILABLE_MODES, ANDROID_CONTROL_AVAILABLE_EFFECTS,
10810 ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
10811 ANDROID_SCALER_CROPPING_TYPE,
10812 ANDROID_SYNC_MAX_LATENCY,
10813 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
10814 ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
10815 ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
10816 ANDROID_CONTROL_AWB_AVAILABLE_MODES, ANDROID_CONTROL_MAX_REGIONS,
10817 ANDROID_CONTROL_SCENE_MODE_OVERRIDES,ANDROID_FLASH_INFO_AVAILABLE,
10818 ANDROID_FLASH_INFO_CHARGE_DURATION, ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
10819 ANDROID_JPEG_MAX_SIZE, ANDROID_LENS_INFO_AVAILABLE_APERTURES,
10820 ANDROID_LENS_INFO_AVAILABLE_FILTER_DENSITIES,
10821 ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
10822 ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
10823 ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE, ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
10824 ANDROID_LENS_INFO_SHADING_MAP_SIZE, ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION,
10825 ANDROID_LENS_FACING,
10826 ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS, ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
10827 ANDROID_REQUEST_PIPELINE_MAX_DEPTH, ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
10828 ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
10829 ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
10830 ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
10831 ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP,
10832 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
10833 /*ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,*/
10834 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS, ANDROID_SENSOR_FORWARD_MATRIX1,
10835 ANDROID_SENSOR_REFERENCE_ILLUMINANT1, ANDROID_SENSOR_REFERENCE_ILLUMINANT2,
10836 ANDROID_SENSOR_FORWARD_MATRIX2, ANDROID_SENSOR_COLOR_TRANSFORM1,
10837 ANDROID_SENSOR_COLOR_TRANSFORM2, ANDROID_SENSOR_CALIBRATION_TRANSFORM1,
10838 ANDROID_SENSOR_CALIBRATION_TRANSFORM2, ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
10839 ANDROID_SENSOR_INFO_SENSITIVITY_RANGE, ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
10840 ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE, ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
10841 ANDROID_SENSOR_INFO_PHYSICAL_SIZE, ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
10842 ANDROID_SENSOR_INFO_WHITE_LEVEL, ANDROID_SENSOR_BASE_GAIN_FACTOR,
10843 ANDROID_SENSOR_BLACK_LEVEL_PATTERN, ANDROID_SENSOR_MAX_ANALOG_SENSITIVITY,
10844 ANDROID_SENSOR_ORIENTATION, ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
10845 ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
Thierry Strudel54dc9782017-02-15 12:12:10 -080010846 ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
Thierry Strudel3d639192016-09-09 11:52:26 -070010847 ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE,
10848 ANDROID_STATISTICS_INFO_SHARPNESS_MAP_SIZE, ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES,
10849 ANDROID_EDGE_AVAILABLE_EDGE_MODES,
10850 ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
10851 ANDROID_TONEMAP_AVAILABLE_TONE_MAP_MODES,
10852 ANDROID_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES,
10853 ANDROID_TONEMAP_MAX_CURVE_POINTS,
10854 ANDROID_CONTROL_AVAILABLE_MODES,
10855 ANDROID_CONTROL_AE_LOCK_AVAILABLE,
10856 ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
10857 ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
10858 ANDROID_SHADING_AVAILABLE_MODES,
Thierry Strudel9e74aae2016-09-22 17:10:18 -070010859 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
10860#ifndef USE_HAL_3_3
10861 ANDROID_SENSOR_OPAQUE_RAW_SIZE,
10862 ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE,
10863#endif
Emilian Peeve91e9ae2017-09-18 14:40:55 +010010864 QCAMERA3_OPAQUE_RAW_FORMAT, QCAMERA3_EXP_TIME_RANGE,
10865 QCAMERA3_SATURATION_RANGE, QCAMERA3_SENSOR_IS_MONO_ONLY,
10866 QCAMERA3_DUALCAM_CALIB_META_DATA_BLOB,
10867 QCAMERA3_SHARPNESS_RANGE,
10868 QCAMERA3_HISTOGRAM_BUCKETS, QCAMERA3_HISTOGRAM_MAX_COUNT,
10869 QCAMERA3_STATS_BSGC_AVAILABLE
Thierry Strudel9e74aae2016-09-22 17:10:18 -070010870 };
10871
Thierry Strudel9e74aae2016-09-22 17:10:18 -070010872 available_characteristics_keys.appendArray(characteristics_keys_basic,
10873 sizeof(characteristics_keys_basic)/sizeof(int32_t));
10874#ifndef USE_HAL_3_3
10875 if (hasBlackRegions) {
10876 available_characteristics_keys.add(ANDROID_SENSOR_OPTICAL_BLACK_REGIONS);
10877 }
10878#endif
Emilian Peev0f3c3162017-03-15 12:57:46 +000010879
Eino-Ville Talvala42d58952018-01-05 16:20:10 -080010880 if (cameraId == 0) {
10881 int32_t lensCalibrationKeys[] = {
10882 ANDROID_LENS_POSE_ROTATION,
10883 ANDROID_LENS_POSE_TRANSLATION,
10884 ANDROID_LENS_POSE_REFERENCE,
10885 ANDROID_LENS_INTRINSIC_CALIBRATION,
Eino-Ville Talvala7a8eefb2018-03-19 15:22:53 -070010886 ANDROID_LENS_DISTORTION,
Eino-Ville Talvala42d58952018-01-05 16:20:10 -080010887 };
10888 available_characteristics_keys.appendArray(lensCalibrationKeys,
10889 sizeof(lensCalibrationKeys) / sizeof(lensCalibrationKeys[0]));
10890 }
10891
Emilian Peev0f3c3162017-03-15 12:57:46 +000010892 if (0 <= indexPD) {
10893 int32_t depthKeys[] = {
10894 ANDROID_DEPTH_MAX_DEPTH_SAMPLES,
10895 ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
10896 ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS,
10897 ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS,
10898 ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE
10899 };
10900 available_characteristics_keys.appendArray(depthKeys,
10901 sizeof(depthKeys) / sizeof(depthKeys[0]));
10902 }
10903
Thierry Strudel3d639192016-09-09 11:52:26 -070010904 /*available stall durations depend on the hw + sw and will be different for different devices */
10905 /*have to add for raw after implementation*/
10906 int32_t stall_formats[] = {HAL_PIXEL_FORMAT_BLOB, ANDROID_SCALER_AVAILABLE_FORMATS_RAW16};
10907 size_t stall_formats_count = sizeof(stall_formats)/sizeof(int32_t);
10908
10909 Vector<int64_t> available_stall_durations;
10910 for (uint32_t j = 0; j < stall_formats_count; j++) {
10911 if (stall_formats[j] == HAL_PIXEL_FORMAT_BLOB) {
10912 for (uint32_t i = 0; i < MIN(MAX_SIZES_CNT,
10913 gCamCapability[cameraId]->picture_sizes_tbl_cnt); i++) {
10914 available_stall_durations.add(stall_formats[j]);
10915 available_stall_durations.add(gCamCapability[cameraId]->picture_sizes_tbl[i].width);
10916 available_stall_durations.add(gCamCapability[cameraId]->picture_sizes_tbl[i].height);
10917 available_stall_durations.add(gCamCapability[cameraId]->jpeg_stall_durations[i]);
10918 }
10919 } else {
10920 for (uint32_t i = 0; i < MIN(MAX_SIZES_CNT,
10921 gCamCapability[cameraId]->supported_raw_dim_cnt); i++) {
10922 available_stall_durations.add(stall_formats[j]);
10923 available_stall_durations.add(gCamCapability[cameraId]->raw_dim[i].width);
10924 available_stall_durations.add(gCamCapability[cameraId]->raw_dim[i].height);
10925 available_stall_durations.add(gCamCapability[cameraId]->raw16_stall_durations[i]);
10926 }
10927 }
10928 }
10929 staticInfo.update(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
10930 available_stall_durations.array(),
10931 available_stall_durations.size());
10932
10933 //QCAMERA3_OPAQUE_RAW
10934 uint8_t raw_format = QCAMERA3_OPAQUE_RAW_FORMAT_LEGACY;
10935 cam_format_t fmt = CAM_FORMAT_BAYER_QCOM_RAW_10BPP_GBRG;
10936 switch (gCamCapability[cameraId]->opaque_raw_fmt) {
10937 case LEGACY_RAW:
10938 if (gCamCapability[cameraId]->white_level == MAX_VALUE_8BIT)
10939 fmt = CAM_FORMAT_BAYER_QCOM_RAW_8BPP_GBRG;
10940 else if (gCamCapability[cameraId]->white_level == MAX_VALUE_10BIT)
10941 fmt = CAM_FORMAT_BAYER_QCOM_RAW_10BPP_GBRG;
10942 else if (gCamCapability[cameraId]->white_level == MAX_VALUE_12BIT)
10943 fmt = CAM_FORMAT_BAYER_QCOM_RAW_12BPP_GBRG;
10944 raw_format = QCAMERA3_OPAQUE_RAW_FORMAT_LEGACY;
10945 break;
10946 case MIPI_RAW:
10947 if (gCamCapability[cameraId]->white_level == MAX_VALUE_8BIT)
10948 fmt = CAM_FORMAT_BAYER_MIPI_RAW_8BPP_GBRG;
10949 else if (gCamCapability[cameraId]->white_level == MAX_VALUE_10BIT)
10950 fmt = CAM_FORMAT_BAYER_MIPI_RAW_10BPP_GBRG;
10951 else if (gCamCapability[cameraId]->white_level == MAX_VALUE_12BIT)
10952 fmt = CAM_FORMAT_BAYER_MIPI_RAW_12BPP_GBRG;
10953 raw_format = QCAMERA3_OPAQUE_RAW_FORMAT_MIPI;
10954 break;
10955 default:
10956 LOGE("unknown opaque_raw_format %d",
10957 gCamCapability[cameraId]->opaque_raw_fmt);
10958 break;
10959 }
10960 staticInfo.update(QCAMERA3_OPAQUE_RAW_FORMAT, &raw_format, 1);
10961
10962 Vector<int32_t> strides;
10963 for (size_t i = 0; i < MIN(MAX_SIZES_CNT,
10964 gCamCapability[cameraId]->supported_raw_dim_cnt); i++) {
10965 cam_stream_buf_plane_info_t buf_planes;
10966 strides.add(gCamCapability[cameraId]->raw_dim[i].width);
10967 strides.add(gCamCapability[cameraId]->raw_dim[i].height);
10968 mm_stream_calc_offset_raw(fmt, &gCamCapability[cameraId]->raw_dim[i],
10969 &gCamCapability[cameraId]->padding_info, &buf_planes);
10970 strides.add(buf_planes.plane_info.mp[0].stride);
10971 }
Emilian Peeve91e9ae2017-09-18 14:40:55 +010010972
10973 if (!strides.isEmpty()) {
10974 staticInfo.update(QCAMERA3_OPAQUE_RAW_STRIDES, strides.array(),
10975 strides.size());
10976 available_characteristics_keys.add(QCAMERA3_OPAQUE_RAW_STRIDES);
10977 }
Thierry Strudel3d639192016-09-09 11:52:26 -070010978
Mansoor Aftab58465fa2017-01-26 15:02:44 -080010979 //TBD: remove the following line once backend advertises zzHDR in feature mask
10980 gCamCapability[cameraId]->qcom_supported_feature_mask |= CAM_QCOM_FEATURE_ZIGZAG_HDR;
Thierry Strudel04e026f2016-10-10 11:27:36 -070010981 //Video HDR default
10982 if ((gCamCapability[cameraId]->qcom_supported_feature_mask) &
10983 (CAM_QCOM_FEATURE_STAGGERED_VIDEO_HDR |
Mansoor Aftab58465fa2017-01-26 15:02:44 -080010984 CAM_QCOM_FEATURE_ZIGZAG_HDR | CAM_QCOM_FEATURE_SENSOR_HDR)) {
Thierry Strudel04e026f2016-10-10 11:27:36 -070010985 int32_t vhdr_mode[] = {
10986 QCAMERA3_VIDEO_HDR_MODE_OFF,
10987 QCAMERA3_VIDEO_HDR_MODE_ON};
10988
10989 size_t vhdr_mode_count = sizeof(vhdr_mode) / sizeof(int32_t);
10990 staticInfo.update(QCAMERA3_AVAILABLE_VIDEO_HDR_MODES,
10991 vhdr_mode, vhdr_mode_count);
Emilian Peeve91e9ae2017-09-18 14:40:55 +010010992 available_characteristics_keys.add(QCAMERA3_AVAILABLE_VIDEO_HDR_MODES);
Thierry Strudel04e026f2016-10-10 11:27:36 -070010993 }
10994
Thierry Strudel3d639192016-09-09 11:52:26 -070010995 staticInfo.update(QCAMERA3_DUALCAM_CALIB_META_DATA_BLOB,
10996 (const uint8_t*)&gCamCapability[cameraId]->related_cam_calibration,
10997 sizeof(gCamCapability[cameraId]->related_cam_calibration));
10998
10999 uint8_t isMonoOnly =
11000 (gCamCapability[cameraId]->color_arrangement == CAM_FILTER_ARRANGEMENT_Y);
11001 staticInfo.update(QCAMERA3_SENSOR_IS_MONO_ONLY,
11002 &isMonoOnly, 1);
11003
Thierry Strudel9e74aae2016-09-22 17:10:18 -070011004#ifndef USE_HAL_3_3
11005 Vector<int32_t> opaque_size;
11006 for (size_t j = 0; j < scalar_formats_count; j++) {
11007 if (scalar_formats[j] == ANDROID_SCALER_AVAILABLE_FORMATS_RAW_OPAQUE) {
11008 for (size_t i = 0; i < MIN(MAX_SIZES_CNT,
11009 gCamCapability[cameraId]->supported_raw_dim_cnt); i++) {
11010 cam_stream_buf_plane_info_t buf_planes;
11011
11012 rc = mm_stream_calc_offset_raw(fmt, &gCamCapability[cameraId]->raw_dim[i],
11013 &gCamCapability[cameraId]->padding_info, &buf_planes);
11014
11015 if (rc == 0) {
11016 opaque_size.add(gCamCapability[cameraId]->raw_dim[i].width);
11017 opaque_size.add(gCamCapability[cameraId]->raw_dim[i].height);
11018 opaque_size.add(buf_planes.plane_info.frame_len);
11019 }else {
11020 LOGE("raw frame calculation failed!");
11021 }
11022 }
11023 }
11024 }
11025
11026 if ((opaque_size.size() > 0) &&
11027 (opaque_size.size() % PER_CONFIGURATION_SIZE_3 == 0))
11028 staticInfo.update(ANDROID_SENSOR_OPAQUE_RAW_SIZE, opaque_size.array(), opaque_size.size());
11029 else
11030 LOGW("Warning: ANDROID_SENSOR_OPAQUE_RAW_SIZE is using rough estimation(2 bytes/pixel)");
11031#endif
11032
Thierry Strudel04e026f2016-10-10 11:27:36 -070011033 if (gCamCapability[cameraId]->supported_ir_mode_cnt > 0) {
11034 int32_t avail_ir_modes[CAM_IR_MODE_MAX];
11035 size = 0;
11036 count = CAM_IR_MODE_MAX;
11037 count = MIN(gCamCapability[cameraId]->supported_ir_mode_cnt, count);
11038 for (size_t i = 0; i < count; i++) {
11039 int val = lookupFwkName(IR_MODES_MAP, METADATA_MAP_SIZE(IR_MODES_MAP),
11040 gCamCapability[cameraId]->supported_ir_modes[i]);
11041 if (NAME_NOT_FOUND != val) {
11042 avail_ir_modes[size] = (int32_t)val;
11043 size++;
11044 }
11045 }
11046 staticInfo.update(QCAMERA3_IR_AVAILABLE_MODES,
11047 avail_ir_modes, size);
Emilian Peeve91e9ae2017-09-18 14:40:55 +010011048 available_characteristics_keys.add(QCAMERA3_IR_AVAILABLE_MODES);
Thierry Strudel04e026f2016-10-10 11:27:36 -070011049 }
11050
Thierry Strudel295a0ca2016-11-03 18:38:47 -070011051 if (gCamCapability[cameraId]->supported_instant_aec_modes_cnt > 0) {
Emilian Peev6d4cdc22017-11-16 16:56:23 +000011052 uint8_t available_instant_aec_modes[CAM_AEC_CONVERGENCE_MAX];
Thierry Strudel295a0ca2016-11-03 18:38:47 -070011053 size = 0;
11054 count = CAM_AEC_CONVERGENCE_MAX;
11055 count = MIN(gCamCapability[cameraId]->supported_instant_aec_modes_cnt, count);
11056 for (size_t i = 0; i < count; i++) {
11057 int val = lookupFwkName(INSTANT_AEC_MODES_MAP, METADATA_MAP_SIZE(INSTANT_AEC_MODES_MAP),
11058 gCamCapability[cameraId]->supported_instant_aec_modes[i]);
11059 if (NAME_NOT_FOUND != val) {
Emilian Peev6d4cdc22017-11-16 16:56:23 +000011060 available_instant_aec_modes[size] = (uint8_t)val;
Thierry Strudel295a0ca2016-11-03 18:38:47 -070011061 size++;
11062 }
11063 }
11064 staticInfo.update(QCAMERA3_INSTANT_AEC_AVAILABLE_MODES,
11065 available_instant_aec_modes, size);
Emilian Peeve91e9ae2017-09-18 14:40:55 +010011066 available_characteristics_keys.add(QCAMERA3_INSTANT_AEC_AVAILABLE_MODES);
Thierry Strudel295a0ca2016-11-03 18:38:47 -070011067 }
11068
Thierry Strudel54dc9782017-02-15 12:12:10 -080011069 int32_t sharpness_range[] = {
11070 gCamCapability[cameraId]->sharpness_ctrl.min_value,
11071 gCamCapability[cameraId]->sharpness_ctrl.max_value};
11072 staticInfo.update(QCAMERA3_SHARPNESS_RANGE, sharpness_range, 2);
11073
11074 if (gCamCapability[cameraId]->supported_binning_correction_mode_cnt > 0) {
11075 int32_t avail_binning_modes[CAM_BINNING_CORRECTION_MODE_MAX];
11076 size = 0;
11077 count = CAM_BINNING_CORRECTION_MODE_MAX;
11078 count = MIN(gCamCapability[cameraId]->supported_binning_correction_mode_cnt, count);
11079 for (size_t i = 0; i < count; i++) {
11080 int val = lookupFwkName(BINNING_CORRECTION_MODES_MAP,
11081 METADATA_MAP_SIZE(BINNING_CORRECTION_MODES_MAP),
11082 gCamCapability[cameraId]->supported_binning_modes[i]);
11083 if (NAME_NOT_FOUND != val) {
11084 avail_binning_modes[size] = (int32_t)val;
11085 size++;
11086 }
11087 }
11088 staticInfo.update(QCAMERA3_AVAILABLE_BINNING_CORRECTION_MODES,
11089 avail_binning_modes, size);
Emilian Peeve91e9ae2017-09-18 14:40:55 +010011090 available_characteristics_keys.add(QCAMERA3_AVAILABLE_BINNING_CORRECTION_MODES);
Thierry Strudel54dc9782017-02-15 12:12:10 -080011091 }
11092
11093 if (gCamCapability[cameraId]->supported_aec_modes_cnt > 0) {
11094 int32_t available_aec_modes[CAM_AEC_MODE_MAX];
11095 size = 0;
11096 count = MIN(gCamCapability[cameraId]->supported_aec_modes_cnt, CAM_AEC_MODE_MAX);
11097 for (size_t i = 0; i < count; i++) {
11098 int32_t val = lookupFwkName(AEC_MODES_MAP, METADATA_MAP_SIZE(AEC_MODES_MAP),
11099 gCamCapability[cameraId]->supported_aec_modes[i]);
11100 if (NAME_NOT_FOUND != val)
11101 available_aec_modes[size++] = val;
11102 }
11103 staticInfo.update(QCAMERA3_EXPOSURE_METER_AVAILABLE_MODES,
11104 available_aec_modes, size);
Emilian Peeve91e9ae2017-09-18 14:40:55 +010011105 available_characteristics_keys.add(QCAMERA3_EXPOSURE_METER_AVAILABLE_MODES);
Thierry Strudel54dc9782017-02-15 12:12:10 -080011106 }
11107
11108 if (gCamCapability[cameraId]->supported_iso_modes_cnt > 0) {
11109 int32_t available_iso_modes[CAM_ISO_MODE_MAX];
11110 size = 0;
11111 count = MIN(gCamCapability[cameraId]->supported_iso_modes_cnt, CAM_ISO_MODE_MAX);
11112 for (size_t i = 0; i < count; i++) {
11113 int32_t val = lookupFwkName(ISO_MODES_MAP, METADATA_MAP_SIZE(ISO_MODES_MAP),
11114 gCamCapability[cameraId]->supported_iso_modes[i]);
11115 if (NAME_NOT_FOUND != val)
11116 available_iso_modes[size++] = val;
11117 }
11118 staticInfo.update(QCAMERA3_ISO_AVAILABLE_MODES,
11119 available_iso_modes, size);
Emilian Peeve91e9ae2017-09-18 14:40:55 +010011120 available_characteristics_keys.add(QCAMERA3_ISO_AVAILABLE_MODES);
Thierry Strudel54dc9782017-02-15 12:12:10 -080011121 }
11122
11123 int64_t available_exp_time_range[EXPOSURE_TIME_RANGE_CNT];
Jason Lee805955a2017-05-04 10:29:14 -070011124 for (size_t i = 0; i < EXPOSURE_TIME_RANGE_CNT; i++)
Thierry Strudel54dc9782017-02-15 12:12:10 -080011125 available_exp_time_range[i] = gCamCapability[cameraId]->exposure_time_range[i];
11126 staticInfo.update(QCAMERA3_EXP_TIME_RANGE,
11127 available_exp_time_range, EXPOSURE_TIME_RANGE_CNT);
11128
11129 int32_t available_saturation_range[4];
11130 available_saturation_range[0] = gCamCapability[cameraId]->saturation_ctrl.min_value;
11131 available_saturation_range[1] = gCamCapability[cameraId]->saturation_ctrl.max_value;
11132 available_saturation_range[2] = gCamCapability[cameraId]->saturation_ctrl.def_value;
11133 available_saturation_range[3] = gCamCapability[cameraId]->saturation_ctrl.step;
11134 staticInfo.update(QCAMERA3_SATURATION_RANGE,
11135 available_saturation_range, 4);
11136
11137 uint8_t is_hdr_values[2];
11138 is_hdr_values[0] = 0;
11139 is_hdr_values[1] = 1;
11140 staticInfo.update(QCAMERA3_STATS_IS_HDR_SCENE_VALUES,
11141 is_hdr_values, 2);
11142
11143 float is_hdr_confidence_range[2];
11144 is_hdr_confidence_range[0] = 0.0;
11145 is_hdr_confidence_range[1] = 1.0;
11146 staticInfo.update(QCAMERA3_STATS_IS_HDR_SCENE_CONFIDENCE_RANGE,
11147 is_hdr_confidence_range, 2);
11148
Emilian Peev0a972ef2017-03-16 10:25:53 +000011149 size_t eepromLength = strnlen(
11150 reinterpret_cast<const char *>(
11151 gCamCapability[cameraId]->eeprom_version_info),
11152 sizeof(gCamCapability[cameraId]->eeprom_version_info));
11153 if (0 < eepromLength) {
Zhijun Hea557c4c2017-03-16 18:37:53 -070011154 char easelInfo[] = ",E:N";
11155 char *eepromInfo = reinterpret_cast<char *>(gCamCapability[cameraId]->eeprom_version_info);
11156 if (eepromLength + sizeof(easelInfo) < MAX_EEPROM_VERSION_INFO_LEN) {
11157 eepromLength += sizeof(easelInfo);
Chien-Yu Chend77a5462017-06-02 18:00:38 -070011158 strlcat(eepromInfo, ((gEaselManagerClient != nullptr &&
Chien-Yu Chenf1e8b152017-10-20 16:30:07 -070011159 gEaselManagerClient->isEaselPresentOnDevice()) ? ",E-Y" : ",E:N"),
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -070011160 MAX_EEPROM_VERSION_INFO_LEN);
Zhijun Hea557c4c2017-03-16 18:37:53 -070011161 }
Emilian Peev0a972ef2017-03-16 10:25:53 +000011162 staticInfo.update(NEXUS_EXPERIMENTAL_2017_EEPROM_VERSION_INFO,
11163 gCamCapability[cameraId]->eeprom_version_info, eepromLength);
Emilian Peeve91e9ae2017-09-18 14:40:55 +010011164 available_characteristics_keys.add(NEXUS_EXPERIMENTAL_2017_EEPROM_VERSION_INFO);
Chien-Yu Chenc5494e52018-01-19 17:53:58 -080011165
11166 staticInfo.update(ANDROID_INFO_VERSION,
11167 gCamCapability[cameraId]->eeprom_version_info, eepromLength);
11168 available_characteristics_keys.add(ANDROID_INFO_VERSION);
Emilian Peev0a972ef2017-03-16 10:25:53 +000011169 }
11170
Emilian Peeve91e9ae2017-09-18 14:40:55 +010011171 staticInfo.update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
11172 available_characteristics_keys.array(),
11173 available_characteristics_keys.size());
11174
Chien-Yu Chen7f9a15b2018-01-23 16:13:31 -080011175 std::vector<uint8_t> availableOisModes;
11176 availableOisModes.push_back(ANDROID_STATISTICS_OIS_DATA_MODE_OFF);
11177 if (cameraId == 0) {
11178 availableOisModes.push_back(ANDROID_STATISTICS_OIS_DATA_MODE_ON);
11179 }
11180
11181 staticInfo.update(ANDROID_STATISTICS_INFO_AVAILABLE_OIS_DATA_MODES,
11182 availableOisModes.data(),
11183 availableOisModes.size());
11184
Thierry Strudel3d639192016-09-09 11:52:26 -070011185 gStaticMetadata[cameraId] = staticInfo.release();
11186 return rc;
11187}
11188
11189/*===========================================================================
11190 * FUNCTION : makeTable
11191 *
11192 * DESCRIPTION: make a table of sizes
11193 *
11194 * PARAMETERS :
11195 *
11196 *
11197 *==========================================================================*/
11198void QCamera3HardwareInterface::makeTable(cam_dimension_t* dimTable, size_t size,
11199 size_t max_size, int32_t *sizeTable)
11200{
11201 size_t j = 0;
11202 if (size > max_size) {
11203 size = max_size;
11204 }
11205 for (size_t i = 0; i < size; i++) {
11206 sizeTable[j] = dimTable[i].width;
11207 sizeTable[j+1] = dimTable[i].height;
11208 j+=2;
11209 }
11210}
11211
11212/*===========================================================================
11213 * FUNCTION : makeFPSTable
11214 *
11215 * DESCRIPTION: make a table of fps ranges
11216 *
11217 * PARAMETERS :
11218 *
11219 *==========================================================================*/
11220void QCamera3HardwareInterface::makeFPSTable(cam_fps_range_t* fpsTable, size_t size,
11221 size_t max_size, int32_t *fpsRangesTable)
11222{
11223 size_t j = 0;
11224 if (size > max_size) {
11225 size = max_size;
11226 }
11227 for (size_t i = 0; i < size; i++) {
11228 fpsRangesTable[j] = (int32_t)fpsTable[i].min_fps;
11229 fpsRangesTable[j+1] = (int32_t)fpsTable[i].max_fps;
11230 j+=2;
11231 }
11232}
11233
11234/*===========================================================================
11235 * FUNCTION : makeOverridesList
11236 *
11237 * DESCRIPTION: make a list of scene mode overrides
11238 *
11239 * PARAMETERS :
11240 *
11241 *
11242 *==========================================================================*/
11243void QCamera3HardwareInterface::makeOverridesList(
11244 cam_scene_mode_overrides_t* overridesTable, size_t size, size_t max_size,
11245 uint8_t *overridesList, uint8_t *supported_indexes, uint32_t camera_id)
11246{
11247 /*daemon will give a list of overrides for all scene modes.
11248 However we should send the fwk only the overrides for the scene modes
11249 supported by the framework*/
11250 size_t j = 0;
11251 if (size > max_size) {
11252 size = max_size;
11253 }
11254 size_t focus_count = CAM_FOCUS_MODE_MAX;
11255 focus_count = MIN(gCamCapability[camera_id]->supported_focus_modes_cnt,
11256 focus_count);
11257 for (size_t i = 0; i < size; i++) {
11258 bool supt = false;
11259 size_t index = supported_indexes[i];
11260 overridesList[j] = gCamCapability[camera_id]->flash_available ?
11261 ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH : ANDROID_CONTROL_AE_MODE_ON;
11262 int val = lookupFwkName(WHITE_BALANCE_MODES_MAP,
11263 METADATA_MAP_SIZE(WHITE_BALANCE_MODES_MAP),
11264 overridesTable[index].awb_mode);
11265 if (NAME_NOT_FOUND != val) {
11266 overridesList[j+1] = (uint8_t)val;
11267 }
11268 uint8_t focus_override = overridesTable[index].af_mode;
11269 for (size_t k = 0; k < focus_count; k++) {
11270 if (gCamCapability[camera_id]->supported_focus_modes[k] == focus_override) {
11271 supt = true;
11272 break;
11273 }
11274 }
11275 if (supt) {
11276 val = lookupFwkName(FOCUS_MODES_MAP, METADATA_MAP_SIZE(FOCUS_MODES_MAP),
11277 focus_override);
11278 if (NAME_NOT_FOUND != val) {
11279 overridesList[j+2] = (uint8_t)val;
11280 }
11281 } else {
11282 overridesList[j+2] = ANDROID_CONTROL_AF_MODE_OFF;
11283 }
11284 j+=3;
11285 }
11286}
11287
11288/*===========================================================================
11289 * FUNCTION : filterJpegSizes
11290 *
11291 * DESCRIPTION: Returns the supported jpeg sizes based on the max dimension that
11292 * could be downscaled to
11293 *
11294 * PARAMETERS :
11295 *
11296 * RETURN : length of jpegSizes array
11297 *==========================================================================*/
11298
11299size_t QCamera3HardwareInterface::filterJpegSizes(int32_t *jpegSizes, int32_t *processedSizes,
11300 size_t processedSizesCnt, size_t maxCount, cam_rect_t active_array_size,
11301 uint8_t downscale_factor)
11302{
11303 if (0 == downscale_factor) {
11304 downscale_factor = 1;
11305 }
11306
11307 int32_t min_width = active_array_size.width / downscale_factor;
11308 int32_t min_height = active_array_size.height / downscale_factor;
11309 size_t jpegSizesCnt = 0;
11310 if (processedSizesCnt > maxCount) {
11311 processedSizesCnt = maxCount;
11312 }
11313 for (size_t i = 0; i < processedSizesCnt; i+=2) {
11314 if (processedSizes[i] >= min_width && processedSizes[i+1] >= min_height) {
11315 jpegSizes[jpegSizesCnt] = processedSizes[i];
11316 jpegSizes[jpegSizesCnt+1] = processedSizes[i+1];
11317 jpegSizesCnt += 2;
11318 }
11319 }
11320 return jpegSizesCnt;
11321}
11322
11323/*===========================================================================
11324 * FUNCTION : computeNoiseModelEntryS
11325 *
11326 * DESCRIPTION: function to map a given sensitivity to the S noise
11327 * model parameters in the DNG noise model.
11328 *
11329 * PARAMETERS : sens : the sensor sensitivity
11330 *
11331 ** RETURN : S (sensor amplification) noise
11332 *
11333 *==========================================================================*/
11334double QCamera3HardwareInterface::computeNoiseModelEntryS(int32_t sens) {
11335 double s = gCamCapability[mCameraId]->gradient_S * sens +
11336 gCamCapability[mCameraId]->offset_S;
11337 return ((s < 0.0) ? 0.0 : s);
11338}
11339
11340/*===========================================================================
11341 * FUNCTION : computeNoiseModelEntryO
11342 *
11343 * DESCRIPTION: function to map a given sensitivity to the O noise
11344 * model parameters in the DNG noise model.
11345 *
11346 * PARAMETERS : sens : the sensor sensitivity
11347 *
11348 ** RETURN : O (sensor readout) noise
11349 *
11350 *==========================================================================*/
11351double QCamera3HardwareInterface::computeNoiseModelEntryO(int32_t sens) {
11352 int32_t max_analog_sens = gCamCapability[mCameraId]->max_analog_sensitivity;
11353 double digital_gain = (1.0 * sens / max_analog_sens) < 1.0 ?
11354 1.0 : (1.0 * sens / max_analog_sens);
11355 double o = gCamCapability[mCameraId]->gradient_O * sens * sens +
11356 gCamCapability[mCameraId]->offset_O * digital_gain * digital_gain;
11357 return ((o < 0.0) ? 0.0 : o);
11358}
11359
11360/*===========================================================================
11361 * FUNCTION : getSensorSensitivity
11362 *
11363 * DESCRIPTION: convert iso_mode to an integer value
11364 *
11365 * PARAMETERS : iso_mode : the iso_mode supported by sensor
11366 *
11367 ** RETURN : sensitivity supported by sensor
11368 *
11369 *==========================================================================*/
11370int32_t QCamera3HardwareInterface::getSensorSensitivity(int32_t iso_mode)
11371{
11372 int32_t sensitivity;
11373
11374 switch (iso_mode) {
11375 case CAM_ISO_MODE_100:
11376 sensitivity = 100;
11377 break;
11378 case CAM_ISO_MODE_200:
11379 sensitivity = 200;
11380 break;
11381 case CAM_ISO_MODE_400:
11382 sensitivity = 400;
11383 break;
11384 case CAM_ISO_MODE_800:
11385 sensitivity = 800;
11386 break;
11387 case CAM_ISO_MODE_1600:
11388 sensitivity = 1600;
11389 break;
11390 default:
11391 sensitivity = -1;
11392 break;
11393 }
11394 return sensitivity;
11395}
11396
Chien-Yu Chen27ec9622017-02-23 13:39:41 -080011397int QCamera3HardwareInterface::initHdrPlusClientLocked() {
Chien-Yu Chend77a5462017-06-02 18:00:38 -070011398 if (gEaselManagerClient == nullptr) {
11399 gEaselManagerClient = EaselManagerClient::create();
11400 if (gEaselManagerClient == nullptr) {
11401 ALOGE("%s: Failed to create Easel manager client.", __FUNCTION__);
11402 return -ENODEV;
11403 }
11404 }
11405
11406 if (!EaselManagerClientOpened && gEaselManagerClient->isEaselPresentOnDevice()) {
Chien-Yu Chen08309b32017-03-13 17:41:32 -070011407 // Check if HAL should not power on Easel even if it's present. This is to allow HDR+ tests
11408 // to connect to Easel.
11409 bool doNotpowerOnEasel =
11410 property_get_bool("camera.hdrplus.donotpoweroneasel", false);
11411
11412 if (doNotpowerOnEasel) {
Chien-Yu Chen08309b32017-03-13 17:41:32 -070011413 ALOGI("%s: Easel is present but not powered on.", __FUNCTION__);
11414 return OK;
11415 }
11416
Chien-Yu Chen27ec9622017-02-23 13:39:41 -080011417 // If Easel is present, power on Easel and suspend it immediately.
Chien-Yu Chend77a5462017-06-02 18:00:38 -070011418 status_t res = gEaselManagerClient->open();
Chien-Yu Chen27ec9622017-02-23 13:39:41 -080011419 if (res != OK) {
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070011420 ALOGE("%s: Opening Easel manager client failed: %s (%d)", __FUNCTION__, strerror(-res),
11421 res);
Chien-Yu Chen27ec9622017-02-23 13:39:41 -080011422 return res;
11423 }
11424
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -070011425 EaselManagerClientOpened = true;
11426
Chien-Yu Chend77a5462017-06-02 18:00:38 -070011427 res = gEaselManagerClient->suspend();
Chien-Yu Chen27ec9622017-02-23 13:39:41 -080011428 if (res != OK) {
11429 ALOGE("%s: Suspending Easel failed: %s (%d)", __FUNCTION__, strerror(-res), res);
11430 }
11431
Chien-Yu Chen2efcfd52017-11-09 15:49:29 -080011432 gEaselBypassOnly = property_get_bool("persist.camera.hdrplus.disable", false);
Chien-Yu Chen509314b2017-04-07 15:27:55 -070011433 gEaselProfilingEnabled = property_get_bool("persist.camera.hdrplus.profiling", false);
Chien-Yu Chen66ec22a2017-04-13 18:00:36 -070011434
11435 // Expose enableZsl key only when HDR+ mode is enabled.
11436 gExposeEnableZslKey = !gEaselBypassOnly;
Chien-Yu Chen27ec9622017-02-23 13:39:41 -080011437 }
11438
11439 return OK;
11440}
11441
Thierry Strudel3d639192016-09-09 11:52:26 -070011442/*===========================================================================
11443 * FUNCTION : getCamInfo
11444 *
11445 * DESCRIPTION: query camera capabilities
11446 *
11447 * PARAMETERS :
11448 * @cameraId : camera Id
11449 * @info : camera info struct to be filled in with camera capabilities
11450 *
11451 * RETURN : int type of status
11452 * NO_ERROR -- success
11453 * none-zero failure code
11454 *==========================================================================*/
11455int QCamera3HardwareInterface::getCamInfo(uint32_t cameraId,
11456 struct camera_info *info)
11457{
Thierry Strudele80ad7c2016-12-06 10:16:27 -080011458 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL3_GET_CAM_INFO);
Thierry Strudel3d639192016-09-09 11:52:26 -070011459 int rc = 0;
11460
11461 pthread_mutex_lock(&gCamLock);
Zhijun Hea557c4c2017-03-16 18:37:53 -070011462
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -070011463 {
Chien-Yu Chen77ccd022017-06-23 12:00:36 -070011464 std::unique_lock<std::mutex> l(gHdrPlusClientLock);
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -070011465 rc = initHdrPlusClientLocked();
11466 if (rc != OK) {
11467 ALOGE("%s: initHdrPlusClientLocked failed: %s (%d)", __FUNCTION__, strerror(-rc), rc);
11468 pthread_mutex_unlock(&gCamLock);
11469 return rc;
11470 }
Zhijun Hea557c4c2017-03-16 18:37:53 -070011471 }
11472
Thierry Strudel3d639192016-09-09 11:52:26 -070011473 if (NULL == gCamCapability[cameraId]) {
11474 rc = initCapabilities(cameraId);
11475 if (rc < 0) {
11476 pthread_mutex_unlock(&gCamLock);
11477 return rc;
11478 }
11479 }
11480
11481 if (NULL == gStaticMetadata[cameraId]) {
11482 rc = initStaticMetadata(cameraId);
11483 if (rc < 0) {
11484 pthread_mutex_unlock(&gCamLock);
11485 return rc;
11486 }
11487 }
11488
11489 switch(gCamCapability[cameraId]->position) {
11490 case CAM_POSITION_BACK:
11491 case CAM_POSITION_BACK_AUX:
11492 info->facing = CAMERA_FACING_BACK;
11493 break;
11494
11495 case CAM_POSITION_FRONT:
11496 case CAM_POSITION_FRONT_AUX:
11497 info->facing = CAMERA_FACING_FRONT;
11498 break;
11499
11500 default:
11501 LOGE("Unknown position type %d for camera id:%d",
11502 gCamCapability[cameraId]->position, cameraId);
11503 rc = -1;
11504 break;
11505 }
11506
11507
11508 info->orientation = (int)gCamCapability[cameraId]->sensor_mount_angle;
Thierry Strudel9e74aae2016-09-22 17:10:18 -070011509#ifndef USE_HAL_3_3
Emilian Peev6d4cdc22017-11-16 16:56:23 +000011510 info->device_version = CAMERA_DEVICE_API_VERSION_3_5;
Thierry Strudel9e74aae2016-09-22 17:10:18 -070011511#else
Thierry Strudel3d639192016-09-09 11:52:26 -070011512 info->device_version = CAMERA_DEVICE_API_VERSION_3_3;
Thierry Strudel9e74aae2016-09-22 17:10:18 -070011513#endif
Thierry Strudel3d639192016-09-09 11:52:26 -070011514 info->static_camera_characteristics = gStaticMetadata[cameraId];
11515
11516 //For now assume both cameras can operate independently.
11517 info->conflicting_devices = NULL;
11518 info->conflicting_devices_length = 0;
11519
11520 //resource cost is 100 * MIN(1.0, m/M),
11521 //where m is throughput requirement with maximum stream configuration
11522 //and M is CPP maximum throughput.
11523 float max_fps = 0.0;
11524 for (uint32_t i = 0;
11525 i < gCamCapability[cameraId]->fps_ranges_tbl_cnt; i++) {
11526 if (max_fps < gCamCapability[cameraId]->fps_ranges_tbl[i].max_fps)
11527 max_fps = gCamCapability[cameraId]->fps_ranges_tbl[i].max_fps;
11528 }
11529 float ratio = 1.0 * MAX_PROCESSED_STREAMS *
11530 gCamCapability[cameraId]->active_array_size.width *
11531 gCamCapability[cameraId]->active_array_size.height * max_fps /
11532 gCamCapability[cameraId]->max_pixel_bandwidth;
11533 info->resource_cost = 100 * MIN(1.0, ratio);
11534 LOGI("camera %d resource cost is %d", cameraId,
11535 info->resource_cost);
11536
11537 pthread_mutex_unlock(&gCamLock);
11538 return rc;
11539}
11540
11541/*===========================================================================
11542 * FUNCTION : translateCapabilityToMetadata
11543 *
11544 * DESCRIPTION: translate the capability into camera_metadata_t
11545 *
11546 * PARAMETERS : type of the request
11547 *
11548 *
11549 * RETURN : success: camera_metadata_t*
11550 * failure: NULL
11551 *
11552 *==========================================================================*/
11553camera_metadata_t* QCamera3HardwareInterface::translateCapabilityToMetadata(int type)
11554{
11555 if (mDefaultMetadata[type] != NULL) {
11556 return mDefaultMetadata[type];
11557 }
11558 //first time we are handling this request
11559 //fill up the metadata structure using the wrapper class
11560 CameraMetadata settings;
11561 //translate from cam_capability_t to camera_metadata_tag_t
11562 static const uint8_t requestType = ANDROID_REQUEST_TYPE_CAPTURE;
11563 settings.update(ANDROID_REQUEST_TYPE, &requestType, 1);
11564 int32_t defaultRequestID = 0;
11565 settings.update(ANDROID_REQUEST_ID, &defaultRequestID, 1);
11566
11567 /* OIS disable */
11568 char ois_prop[PROPERTY_VALUE_MAX];
11569 memset(ois_prop, 0, sizeof(ois_prop));
11570 property_get("persist.camera.ois.disable", ois_prop, "0");
11571 uint8_t ois_disable = (uint8_t)atoi(ois_prop);
11572
11573 /* Force video to use OIS */
11574 char videoOisProp[PROPERTY_VALUE_MAX];
11575 memset(videoOisProp, 0, sizeof(videoOisProp));
11576 property_get("persist.camera.ois.video", videoOisProp, "1");
11577 uint8_t forceVideoOis = (uint8_t)atoi(videoOisProp);
Shuzhen Wang19463d72016-03-08 11:09:52 -080011578
11579 // Hybrid AE enable/disable
11580 char hybrid_ae_prop[PROPERTY_VALUE_MAX];
11581 memset(hybrid_ae_prop, 0, sizeof(hybrid_ae_prop));
11582 property_get("persist.camera.hybrid_ae.enable", hybrid_ae_prop, "0");
Shuzhen Wang77b049a2017-08-30 12:24:36 -070011583 uint8_t hybrid_ae = (uint8_t)atoi(hybrid_ae_prop);
Shuzhen Wang19463d72016-03-08 11:09:52 -080011584
Thierry Strudel3d639192016-09-09 11:52:26 -070011585 uint8_t controlIntent = 0;
11586 uint8_t focusMode;
11587 uint8_t vsMode;
11588 uint8_t optStabMode;
11589 uint8_t cacMode;
11590 uint8_t edge_mode;
11591 uint8_t noise_red_mode;
Eino-Ville Talvala3ff52c72018-01-19 12:46:23 -080011592 uint8_t shading_mode;
11593 uint8_t hot_pixel_mode;
Thierry Strudel3d639192016-09-09 11:52:26 -070011594 uint8_t tonemap_mode;
11595 bool highQualityModeEntryAvailable = FALSE;
11596 bool fastModeEntryAvailable = FALSE;
Shuzhen Wang14415f52016-11-16 18:26:18 -080011597 uint8_t histogramEnable = false;
Thierry Strudel3d639192016-09-09 11:52:26 -070011598 vsMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
11599 optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
Shuzhen Wang8f66c042016-08-17 14:50:26 -070011600 uint8_t shadingmap_mode = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
Shuzhen Wangcc386c52017-03-29 09:28:08 -070011601 uint8_t trackingAfTrigger = NEXUS_EXPERIMENTAL_2017_TRACKING_AF_TRIGGER_IDLE;
Chien-Yu Chen66ec22a2017-04-13 18:00:36 -070011602 uint8_t enableZsl = ANDROID_CONTROL_ENABLE_ZSL_FALSE;
Mansoor Aftabea39eba2017-01-26 14:58:25 -080011603
Thierry Strudel3d639192016-09-09 11:52:26 -070011604 switch (type) {
11605 case CAMERA3_TEMPLATE_PREVIEW:
11606 controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
11607 focusMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
11608 optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON;
11609 cacMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST;
11610 edge_mode = ANDROID_EDGE_MODE_FAST;
11611 noise_red_mode = ANDROID_NOISE_REDUCTION_MODE_FAST;
Eino-Ville Talvala3ff52c72018-01-19 12:46:23 -080011612 shading_mode = ANDROID_SHADING_MODE_FAST;
11613 hot_pixel_mode = ANDROID_HOT_PIXEL_MODE_FAST;
Thierry Strudel3d639192016-09-09 11:52:26 -070011614 tonemap_mode = ANDROID_TONEMAP_MODE_FAST;
11615 break;
11616 case CAMERA3_TEMPLATE_STILL_CAPTURE:
11617 controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
11618 focusMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
11619 optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON;
11620 edge_mode = ANDROID_EDGE_MODE_HIGH_QUALITY;
11621 noise_red_mode = ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY;
Eino-Ville Talvala3ff52c72018-01-19 12:46:23 -080011622 shading_mode = ANDROID_SHADING_MODE_HIGH_QUALITY;
11623 hot_pixel_mode = ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY;
Thierry Strudel3d639192016-09-09 11:52:26 -070011624 tonemap_mode = ANDROID_TONEMAP_MODE_HIGH_QUALITY;
11625 cacMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
11626 // Order of priority for default CAC is HIGH Quality -> FAST -> OFF
11627 for (size_t i = 0; i < gCamCapability[mCameraId]->aberration_modes_count; i++) {
11628 if (gCamCapability[mCameraId]->aberration_modes[i] ==
11629 CAM_COLOR_CORRECTION_ABERRATION_HIGH_QUALITY) {
11630 highQualityModeEntryAvailable = TRUE;
11631 } else if (gCamCapability[mCameraId]->aberration_modes[i] ==
11632 CAM_COLOR_CORRECTION_ABERRATION_FAST) {
11633 fastModeEntryAvailable = TRUE;
11634 }
11635 }
11636 if (highQualityModeEntryAvailable) {
11637 cacMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY;
11638 } else if (fastModeEntryAvailable) {
11639 cacMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST;
11640 }
Shuzhen Wang8f66c042016-08-17 14:50:26 -070011641 if (CAM_SENSOR_RAW == gCamCapability[mCameraId]->sensor_type.sens_type) {
11642 shadingmap_mode = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON;
11643 }
Chien-Yu Chen66ec22a2017-04-13 18:00:36 -070011644 enableZsl = ANDROID_CONTROL_ENABLE_ZSL_TRUE;
Thierry Strudel3d639192016-09-09 11:52:26 -070011645 break;
11646 case CAMERA3_TEMPLATE_VIDEO_RECORD:
11647 controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
11648 focusMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO;
11649 optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
Thierry Strudel3d639192016-09-09 11:52:26 -070011650 cacMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST;
11651 edge_mode = ANDROID_EDGE_MODE_FAST;
11652 noise_red_mode = ANDROID_NOISE_REDUCTION_MODE_FAST;
Eino-Ville Talvala3ff52c72018-01-19 12:46:23 -080011653 shading_mode = ANDROID_SHADING_MODE_FAST;
11654 hot_pixel_mode = ANDROID_HOT_PIXEL_MODE_FAST;
Thierry Strudel3d639192016-09-09 11:52:26 -070011655 tonemap_mode = ANDROID_TONEMAP_MODE_FAST;
11656 if (forceVideoOis)
11657 optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON;
11658 break;
11659 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
11660 controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
11661 focusMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO;
11662 optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
Thierry Strudel3d639192016-09-09 11:52:26 -070011663 cacMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST;
11664 edge_mode = ANDROID_EDGE_MODE_FAST;
11665 noise_red_mode = ANDROID_NOISE_REDUCTION_MODE_FAST;
Eino-Ville Talvala3ff52c72018-01-19 12:46:23 -080011666 shading_mode = ANDROID_SHADING_MODE_FAST;
11667 hot_pixel_mode = ANDROID_HOT_PIXEL_MODE_FAST;
Thierry Strudel3d639192016-09-09 11:52:26 -070011668 tonemap_mode = ANDROID_TONEMAP_MODE_FAST;
11669 if (forceVideoOis)
11670 optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON;
11671 break;
11672 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
11673 controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG;
11674 focusMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
11675 optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON;
11676 cacMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST;
11677 edge_mode = ANDROID_EDGE_MODE_ZERO_SHUTTER_LAG;
11678 noise_red_mode = ANDROID_NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG;
Eino-Ville Talvala3ff52c72018-01-19 12:46:23 -080011679 shading_mode = ANDROID_SHADING_MODE_FAST;
11680 hot_pixel_mode = ANDROID_HOT_PIXEL_MODE_FAST;
Thierry Strudel3d639192016-09-09 11:52:26 -070011681 tonemap_mode = ANDROID_TONEMAP_MODE_FAST;
11682 break;
11683 case CAMERA3_TEMPLATE_MANUAL:
11684 edge_mode = ANDROID_EDGE_MODE_FAST;
11685 noise_red_mode = ANDROID_NOISE_REDUCTION_MODE_FAST;
Eino-Ville Talvala3ff52c72018-01-19 12:46:23 -080011686 shading_mode = ANDROID_SHADING_MODE_FAST;
11687 hot_pixel_mode = ANDROID_HOT_PIXEL_MODE_FAST;
Thierry Strudel3d639192016-09-09 11:52:26 -070011688 tonemap_mode = ANDROID_TONEMAP_MODE_FAST;
11689 cacMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST;
11690 controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL;
11691 focusMode = ANDROID_CONTROL_AF_MODE_OFF;
11692 optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
11693 break;
11694 default:
11695 edge_mode = ANDROID_EDGE_MODE_FAST;
11696 noise_red_mode = ANDROID_NOISE_REDUCTION_MODE_FAST;
Eino-Ville Talvala3ff52c72018-01-19 12:46:23 -080011697 shading_mode = ANDROID_SHADING_MODE_FAST;
11698 hot_pixel_mode = ANDROID_HOT_PIXEL_MODE_FAST;
Thierry Strudel3d639192016-09-09 11:52:26 -070011699 tonemap_mode = ANDROID_TONEMAP_MODE_FAST;
11700 cacMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST;
11701 controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_CUSTOM;
11702 focusMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
11703 optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
11704 break;
11705 }
Thierry Strudel04e026f2016-10-10 11:27:36 -070011706 // Set CAC to OFF if underlying device doesn't support
11707 if (gCamCapability[mCameraId]->aberration_modes_count == 0) {
11708 cacMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
11709 }
Thierry Strudel3d639192016-09-09 11:52:26 -070011710 settings.update(ANDROID_COLOR_CORRECTION_ABERRATION_MODE, &cacMode, 1);
11711 settings.update(ANDROID_CONTROL_CAPTURE_INTENT, &controlIntent, 1);
11712 settings.update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &vsMode, 1);
11713 if (gCamCapability[mCameraId]->supported_focus_modes_cnt == 1) {
11714 focusMode = ANDROID_CONTROL_AF_MODE_OFF;
11715 }
11716 settings.update(ANDROID_CONTROL_AF_MODE, &focusMode, 1);
Shuzhen Wang14415f52016-11-16 18:26:18 -080011717 settings.update(NEXUS_EXPERIMENTAL_2017_HISTOGRAM_ENABLE, &histogramEnable, 1);
Shuzhen Wangcc386c52017-03-29 09:28:08 -070011718 settings.update(NEXUS_EXPERIMENTAL_2017_TRACKING_AF_TRIGGER, &trackingAfTrigger, 1);
Thierry Strudel3d639192016-09-09 11:52:26 -070011719
11720 if (gCamCapability[mCameraId]->optical_stab_modes_count == 1 &&
11721 gCamCapability[mCameraId]->optical_stab_modes[0] == CAM_OPT_STAB_ON)
11722 optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON;
11723 else if ((gCamCapability[mCameraId]->optical_stab_modes_count == 1 &&
11724 gCamCapability[mCameraId]->optical_stab_modes[0] == CAM_OPT_STAB_OFF)
11725 || ois_disable)
11726 optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
11727 settings.update(ANDROID_LENS_OPTICAL_STABILIZATION_MODE, &optStabMode, 1);
Shuzhen Wang8f66c042016-08-17 14:50:26 -070011728 settings.update(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, &shadingmap_mode, 1);
Thierry Strudel3d639192016-09-09 11:52:26 -070011729
11730 settings.update(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
11731 &gCamCapability[mCameraId]->exposure_compensation_default, 1);
11732
11733 static const uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
11734 settings.update(ANDROID_CONTROL_AE_LOCK, &aeLock, 1);
11735
11736 static const uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
11737 settings.update(ANDROID_CONTROL_AWB_LOCK, &awbLock, 1);
11738
11739 static const uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
11740 settings.update(ANDROID_CONTROL_AWB_MODE, &awbMode, 1);
11741
11742 static const uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
11743 settings.update(ANDROID_CONTROL_MODE, &controlMode, 1);
11744
11745 static const uint8_t effectMode = ANDROID_CONTROL_EFFECT_MODE_OFF;
11746 settings.update(ANDROID_CONTROL_EFFECT_MODE, &effectMode, 1);
11747
11748 static const uint8_t sceneMode = ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY;
11749 settings.update(ANDROID_CONTROL_SCENE_MODE, &sceneMode, 1);
11750
11751 static const uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
11752 settings.update(ANDROID_CONTROL_AE_MODE, &aeMode, 1);
11753
11754 /*flash*/
11755 static const uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
11756 settings.update(ANDROID_FLASH_MODE, &flashMode, 1);
11757
11758 static const uint8_t flashFiringLevel = CAM_FLASH_FIRING_LEVEL_4;
11759 settings.update(ANDROID_FLASH_FIRING_POWER,
11760 &flashFiringLevel, 1);
11761
11762 /* lens */
11763 float default_aperture = gCamCapability[mCameraId]->apertures[0];
11764 settings.update(ANDROID_LENS_APERTURE, &default_aperture, 1);
11765
11766 if (gCamCapability[mCameraId]->filter_densities_count) {
11767 float default_filter_density = gCamCapability[mCameraId]->filter_densities[0];
11768 settings.update(ANDROID_LENS_FILTER_DENSITY, &default_filter_density,
11769 gCamCapability[mCameraId]->filter_densities_count);
11770 }
11771
11772 float default_focal_length = gCamCapability[mCameraId]->focal_length;
11773 settings.update(ANDROID_LENS_FOCAL_LENGTH, &default_focal_length, 1);
11774
Thierry Strudel3d639192016-09-09 11:52:26 -070011775 static const uint8_t demosaicMode = ANDROID_DEMOSAIC_MODE_FAST;
11776 settings.update(ANDROID_DEMOSAIC_MODE, &demosaicMode, 1);
11777
Thierry Strudel3d639192016-09-09 11:52:26 -070011778 static const int32_t testpatternMode = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF;
11779 settings.update(ANDROID_SENSOR_TEST_PATTERN_MODE, &testpatternMode, 1);
11780
11781 /* face detection (default to OFF) */
11782 static const uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
11783 settings.update(ANDROID_STATISTICS_FACE_DETECT_MODE, &faceDetectMode, 1);
11784
Thierry Strudel54dc9782017-02-15 12:12:10 -080011785 static const uint8_t histogramMode = QCAMERA3_HISTOGRAM_MODE_OFF;
11786 settings.update(QCAMERA3_HISTOGRAM_MODE, &histogramMode, 1);
Thierry Strudel3d639192016-09-09 11:52:26 -070011787
11788 static const uint8_t sharpnessMapMode = ANDROID_STATISTICS_SHARPNESS_MAP_MODE_OFF;
11789 settings.update(ANDROID_STATISTICS_SHARPNESS_MAP_MODE, &sharpnessMapMode, 1);
11790
11791 static const uint8_t hotPixelMapMode = ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF;
11792 settings.update(ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE, &hotPixelMapMode, 1);
11793
Thierry Strudel3d639192016-09-09 11:52:26 -070011794
11795 static const uint8_t blackLevelLock = ANDROID_BLACK_LEVEL_LOCK_OFF;
11796 settings.update(ANDROID_BLACK_LEVEL_LOCK, &blackLevelLock, 1);
11797
11798 /* Exposure time(Update the Min Exposure Time)*/
11799 int64_t default_exposure_time = gCamCapability[mCameraId]->exposure_time_range[0];
11800 settings.update(ANDROID_SENSOR_EXPOSURE_TIME, &default_exposure_time, 1);
11801
11802 /* frame duration */
11803 static const int64_t default_frame_duration = NSEC_PER_33MSEC;
11804 settings.update(ANDROID_SENSOR_FRAME_DURATION, &default_frame_duration, 1);
11805
11806 /* sensitivity */
11807 static const int32_t default_sensitivity = 100;
11808 settings.update(ANDROID_SENSOR_SENSITIVITY, &default_sensitivity, 1);
Thierry Strudel9e74aae2016-09-22 17:10:18 -070011809#ifndef USE_HAL_3_3
11810 static const int32_t default_isp_sensitivity =
11811 gCamCapability[mCameraId]->isp_sensitivity_range.min_sensitivity;
11812 settings.update(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST, &default_isp_sensitivity, 1);
11813#endif
Thierry Strudel3d639192016-09-09 11:52:26 -070011814
11815 /*edge mode*/
11816 settings.update(ANDROID_EDGE_MODE, &edge_mode, 1);
11817
11818 /*noise reduction mode*/
11819 settings.update(ANDROID_NOISE_REDUCTION_MODE, &noise_red_mode, 1);
11820
Eino-Ville Talvala3ff52c72018-01-19 12:46:23 -080011821 /*shading mode*/
11822 settings.update(ANDROID_SHADING_MODE, &shading_mode, 1);
11823
11824 /*hot pixel mode*/
11825 settings.update(ANDROID_HOT_PIXEL_MODE, &hot_pixel_mode, 1);
11826
Thierry Strudel3d639192016-09-09 11:52:26 -070011827 /*color correction mode*/
11828 static const uint8_t color_correct_mode = ANDROID_COLOR_CORRECTION_MODE_FAST;
11829 settings.update(ANDROID_COLOR_CORRECTION_MODE, &color_correct_mode, 1);
11830
11831 /*transform matrix mode*/
11832 settings.update(ANDROID_TONEMAP_MODE, &tonemap_mode, 1);
11833
11834 int32_t scaler_crop_region[4];
11835 scaler_crop_region[0] = 0;
11836 scaler_crop_region[1] = 0;
11837 scaler_crop_region[2] = gCamCapability[mCameraId]->active_array_size.width;
11838 scaler_crop_region[3] = gCamCapability[mCameraId]->active_array_size.height;
11839 settings.update(ANDROID_SCALER_CROP_REGION, scaler_crop_region, 4);
11840
11841 static const uint8_t antibanding_mode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
11842 settings.update(ANDROID_CONTROL_AE_ANTIBANDING_MODE, &antibanding_mode, 1);
11843
11844 /*focus distance*/
11845 float focus_distance = 0.0;
11846 settings.update(ANDROID_LENS_FOCUS_DISTANCE, &focus_distance, 1);
11847
11848 /*target fps range: use maximum range for picture, and maximum fixed range for video*/
Thierry Strudele80ad7c2016-12-06 10:16:27 -080011849 /* Restrict template max_fps to 30 */
Thierry Strudel3d639192016-09-09 11:52:26 -070011850 float max_range = 0.0;
11851 float max_fixed_fps = 0.0;
11852 int32_t fps_range[2] = {0, 0};
11853 for (uint32_t i = 0; i < gCamCapability[mCameraId]->fps_ranges_tbl_cnt;
11854 i++) {
Thierry Strudele80ad7c2016-12-06 10:16:27 -080011855 if (gCamCapability[mCameraId]->fps_ranges_tbl[i].max_fps >
11856 TEMPLATE_MAX_PREVIEW_FPS) {
11857 continue;
11858 }
Thierry Strudel3d639192016-09-09 11:52:26 -070011859 float range = gCamCapability[mCameraId]->fps_ranges_tbl[i].max_fps -
11860 gCamCapability[mCameraId]->fps_ranges_tbl[i].min_fps;
11861 if (type == CAMERA3_TEMPLATE_PREVIEW ||
11862 type == CAMERA3_TEMPLATE_STILL_CAPTURE ||
11863 type == CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG) {
11864 if (range > max_range) {
11865 fps_range[0] =
11866 (int32_t)gCamCapability[mCameraId]->fps_ranges_tbl[i].min_fps;
11867 fps_range[1] =
11868 (int32_t)gCamCapability[mCameraId]->fps_ranges_tbl[i].max_fps;
11869 max_range = range;
11870 }
11871 } else {
11872 if (range < 0.01 && max_fixed_fps <
11873 gCamCapability[mCameraId]->fps_ranges_tbl[i].max_fps) {
11874 fps_range[0] =
11875 (int32_t)gCamCapability[mCameraId]->fps_ranges_tbl[i].min_fps;
11876 fps_range[1] =
11877 (int32_t)gCamCapability[mCameraId]->fps_ranges_tbl[i].max_fps;
11878 max_fixed_fps = gCamCapability[mCameraId]->fps_ranges_tbl[i].max_fps;
11879 }
11880 }
11881 }
11882 settings.update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, fps_range, 2);
11883
11884 /*precapture trigger*/
11885 uint8_t precapture_trigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
11886 settings.update(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, &precapture_trigger, 1);
11887
11888 /*af trigger*/
11889 uint8_t af_trigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
11890 settings.update(ANDROID_CONTROL_AF_TRIGGER, &af_trigger, 1);
11891
11892 /* ae & af regions */
11893 int32_t active_region[] = {
11894 gCamCapability[mCameraId]->active_array_size.left,
11895 gCamCapability[mCameraId]->active_array_size.top,
11896 gCamCapability[mCameraId]->active_array_size.left +
11897 gCamCapability[mCameraId]->active_array_size.width,
11898 gCamCapability[mCameraId]->active_array_size.top +
11899 gCamCapability[mCameraId]->active_array_size.height,
11900 0};
11901 settings.update(ANDROID_CONTROL_AE_REGIONS, active_region,
11902 sizeof(active_region) / sizeof(active_region[0]));
11903 settings.update(ANDROID_CONTROL_AF_REGIONS, active_region,
11904 sizeof(active_region) / sizeof(active_region[0]));
11905
11906 /* black level lock */
11907 uint8_t blacklevel_lock = ANDROID_BLACK_LEVEL_LOCK_OFF;
11908 settings.update(ANDROID_BLACK_LEVEL_LOCK, &blacklevel_lock, 1);
11909
Thierry Strudel3d639192016-09-09 11:52:26 -070011910 //special defaults for manual template
11911 if (type == CAMERA3_TEMPLATE_MANUAL) {
11912 static const uint8_t manualControlMode = ANDROID_CONTROL_MODE_OFF;
11913 settings.update(ANDROID_CONTROL_MODE, &manualControlMode, 1);
11914
11915 static const uint8_t manualFocusMode = ANDROID_CONTROL_AF_MODE_OFF;
11916 settings.update(ANDROID_CONTROL_AF_MODE, &manualFocusMode, 1);
11917
11918 static const uint8_t manualAeMode = ANDROID_CONTROL_AE_MODE_OFF;
11919 settings.update(ANDROID_CONTROL_AE_MODE, &manualAeMode, 1);
11920
11921 static const uint8_t manualAwbMode = ANDROID_CONTROL_AWB_MODE_OFF;
11922 settings.update(ANDROID_CONTROL_AWB_MODE, &manualAwbMode, 1);
11923
11924 static const uint8_t manualTonemapMode = ANDROID_TONEMAP_MODE_FAST;
11925 settings.update(ANDROID_TONEMAP_MODE, &manualTonemapMode, 1);
11926
11927 static const uint8_t manualColorCorrectMode = ANDROID_COLOR_CORRECTION_MODE_TRANSFORM_MATRIX;
11928 settings.update(ANDROID_COLOR_CORRECTION_MODE, &manualColorCorrectMode, 1);
11929 }
11930
11931
11932 /* TNR
11933 * We'll use this location to determine which modes TNR will be set.
11934 * We will enable TNR to be on if either of the Preview/Video stream requires TNR
11935 * This is not to be confused with linking on a per stream basis that decision
11936 * is still on per-session basis and will be handled as part of config stream
11937 */
11938 uint8_t tnr_enable = 0;
11939
11940 if (m_bTnrPreview || m_bTnrVideo) {
11941
11942 switch (type) {
11943 case CAMERA3_TEMPLATE_VIDEO_RECORD:
11944 tnr_enable = 1;
11945 break;
11946
11947 default:
11948 tnr_enable = 0;
11949 break;
11950 }
11951
11952 int32_t tnr_process_type = (int32_t)getTemporalDenoiseProcessPlate();
11953 settings.update(QCAMERA3_TEMPORAL_DENOISE_ENABLE, &tnr_enable, 1);
11954 settings.update(QCAMERA3_TEMPORAL_DENOISE_PROCESS_TYPE, &tnr_process_type, 1);
11955
11956 LOGD("TNR:%d with process plate %d for template:%d",
11957 tnr_enable, tnr_process_type, type);
11958 }
11959
11960 //Update Link tags to default
Shuzhen Wang920ea402017-05-03 08:49:39 -070011961 uint8_t sync_type = CAM_TYPE_STANDALONE;
Thierry Strudel3d639192016-09-09 11:52:26 -070011962 settings.update(QCAMERA3_DUALCAM_LINK_ENABLE, &sync_type, 1);
11963
Chien-Yu Chena3bbdc02017-05-05 11:31:47 -070011964 uint8_t is_main = 1;
Thierry Strudel3d639192016-09-09 11:52:26 -070011965 settings.update(QCAMERA3_DUALCAM_LINK_IS_MAIN, &is_main, 1);
11966
Shuzhen Wang920ea402017-05-03 08:49:39 -070011967 uint8_t related_camera_id = mCameraId;
11968 settings.update(QCAMERA3_DUALCAM_LINK_RELATED_CAMERA_ID, &related_camera_id, 1);
Thierry Strudel3d639192016-09-09 11:52:26 -070011969
11970 /* CDS default */
11971 char prop[PROPERTY_VALUE_MAX];
11972 memset(prop, 0, sizeof(prop));
11973 property_get("persist.camera.CDS", prop, "Auto");
11974 cam_cds_mode_type_t cds_mode = CAM_CDS_MODE_AUTO;
11975 cds_mode = lookupProp(CDS_MAP, METADATA_MAP_SIZE(CDS_MAP), prop);
11976 if (CAM_CDS_MODE_MAX == cds_mode) {
11977 cds_mode = CAM_CDS_MODE_AUTO;
11978 }
11979
11980 /* Disabling CDS in templates which have TNR enabled*/
11981 if (tnr_enable)
11982 cds_mode = CAM_CDS_MODE_OFF;
11983
11984 int32_t mode = cds_mode;
11985 settings.update(QCAMERA3_CDS_MODE, &mode, 1);
Thierry Strudel04e026f2016-10-10 11:27:36 -070011986
Thierry Strudel269c81a2016-10-12 12:13:59 -070011987 /* Manual Convergence AEC Speed is disabled by default*/
11988 float default_aec_speed = 0;
11989 settings.update(QCAMERA3_AEC_CONVERGENCE_SPEED, &default_aec_speed, 1);
11990
11991 /* Manual Convergence AWB Speed is disabled by default*/
11992 float default_awb_speed = 0;
11993 settings.update(QCAMERA3_AWB_CONVERGENCE_SPEED, &default_awb_speed, 1);
11994
Thierry Strudel295a0ca2016-11-03 18:38:47 -070011995 // Set instant AEC to normal convergence by default
Emilian Peev6d4cdc22017-11-16 16:56:23 +000011996 uint8_t instant_aec_mode = (uint8_t)QCAMERA3_INSTANT_AEC_NORMAL_CONVERGENCE;
Thierry Strudel295a0ca2016-11-03 18:38:47 -070011997 settings.update(QCAMERA3_INSTANT_AEC_MODE, &instant_aec_mode, 1);
11998
Chien-Yu Chen7f9a15b2018-01-23 16:13:31 -080011999 uint8_t oisDataMode = ANDROID_STATISTICS_OIS_DATA_MODE_OFF;
12000 if (mCameraId == 0) {
12001 oisDataMode = ANDROID_STATISTICS_OIS_DATA_MODE_ON;
12002 }
12003 settings.update(ANDROID_STATISTICS_OIS_DATA_MODE, &oisDataMode, 1);
12004
Chien-Yu Chen66ec22a2017-04-13 18:00:36 -070012005 if (gExposeEnableZslKey) {
12006 settings.update(ANDROID_CONTROL_ENABLE_ZSL, &enableZsl, 1);
Chien-Yu Chen0a921f92017-08-27 17:25:33 -070012007 int32_t postview = 0;
12008 settings.update(NEXUS_EXPERIMENTAL_2017_POSTVIEW, &postview, 1);
Chien-Yu Chenb0981e32017-08-28 19:27:35 -070012009 int32_t continuousZslCapture = 0;
12010 settings.update(NEXUS_EXPERIMENTAL_2017_CONTINUOUS_ZSL_CAPTURE, &continuousZslCapture, 1);
Chien-Yu Chenfadf40e2017-09-15 14:33:57 -070012011 // Disable HDR+ for templates other than CAMERA3_TEMPLATE_STILL_CAPTURE and
12012 // CAMERA3_TEMPLATE_PREVIEW.
12013 int32_t disableHdrplus = (type == CAMERA3_TEMPLATE_STILL_CAPTURE ||
12014 type == CAMERA3_TEMPLATE_PREVIEW) ? 0 : 1;
Chien-Yu Chenec328c82017-08-30 16:41:08 -070012015 settings.update(NEXUS_EXPERIMENTAL_2017_DISABLE_HDRPLUS, &disableHdrplus, 1);
12016
Shuzhen Wang77b049a2017-08-30 12:24:36 -070012017 // Set hybrid_ae tag in PREVIEW and STILL_CAPTURE templates to 1 so that
12018 // hybrid ae is enabled for 3rd party app HDR+.
12019 if (type == CAMERA3_TEMPLATE_PREVIEW ||
12020 type == CAMERA3_TEMPLATE_STILL_CAPTURE) {
12021 hybrid_ae = 1;
12022 }
Chien-Yu Chen66ec22a2017-04-13 18:00:36 -070012023 }
Shuzhen Wang77b049a2017-08-30 12:24:36 -070012024 /* hybrid ae */
12025 settings.update(NEXUS_EXPERIMENTAL_2016_HYBRID_AE_ENABLE, &hybrid_ae, 1);
Chien-Yu Chen66ec22a2017-04-13 18:00:36 -070012026
Emilian Peev6d4cdc22017-11-16 16:56:23 +000012027 int32_t fwk_hdr = QCAMERA3_VIDEO_HDR_MODE_OFF;
12028 settings.update(QCAMERA3_VIDEO_HDR_MODE, &fwk_hdr, 1);
12029
Thierry Strudel3d639192016-09-09 11:52:26 -070012030 mDefaultMetadata[type] = settings.release();
12031
12032 return mDefaultMetadata[type];
12033}
12034
12035/*===========================================================================
Emilian Peev30522a12017-08-03 14:36:33 +010012036 * FUNCTION : getExpectedFrameDuration
12037 *
12038 * DESCRIPTION: Extract the maximum frame duration from either exposure or frame
12039 * duration
12040 *
12041 * PARAMETERS :
12042 * @request : request settings
12043 * @frameDuration : The maximum frame duration in nanoseconds
12044 *
12045 * RETURN : None
12046 *==========================================================================*/
12047void QCamera3HardwareInterface::getExpectedFrameDuration(
12048 const camera_metadata_t *request, nsecs_t *frameDuration /*out*/) {
12049 if (nullptr == frameDuration) {
12050 return;
12051 }
12052
12053 camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
12054 find_camera_metadata_ro_entry(request,
12055 ANDROID_SENSOR_EXPOSURE_TIME,
12056 &e);
12057 if (e.count > 0) {
12058 *frameDuration = e.data.i64[0];
12059 }
12060 find_camera_metadata_ro_entry(request,
12061 ANDROID_SENSOR_FRAME_DURATION,
12062 &e);
12063 if (e.count > 0) {
12064 *frameDuration = std::max(e.data.i64[0], *frameDuration);
12065 }
12066}
12067
12068/*===========================================================================
12069 * FUNCTION : calculateMaxExpectedDuration
12070 *
12071 * DESCRIPTION: Calculate the expected frame duration in nanoseconds given the
12072 * current camera settings.
12073 *
12074 * PARAMETERS :
12075 * @request : request settings
12076 *
12077 * RETURN : Expected frame duration in nanoseconds.
12078 *==========================================================================*/
12079nsecs_t QCamera3HardwareInterface::calculateMaxExpectedDuration(
12080 const camera_metadata_t *request) {
12081 nsecs_t maxExpectedDuration = kDefaultExpectedDuration;
12082 camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
12083 find_camera_metadata_ro_entry(request, ANDROID_CONTROL_MODE, &e);
12084 if (e.count == 0) {
12085 return maxExpectedDuration;
12086 }
12087
12088 if (e.data.u8[0] == ANDROID_CONTROL_MODE_OFF) {
12089 getExpectedFrameDuration(request, &maxExpectedDuration /*out*/);
12090 }
12091
12092 if (e.data.u8[0] != ANDROID_CONTROL_MODE_AUTO) {
12093 return maxExpectedDuration;
12094 }
12095
12096 find_camera_metadata_ro_entry(request, ANDROID_CONTROL_AE_MODE, &e);
12097 if (e.count == 0) {
12098 return maxExpectedDuration;
12099 }
12100
12101 switch (e.data.u8[0]) {
12102 case ANDROID_CONTROL_AE_MODE_OFF:
12103 getExpectedFrameDuration(request, &maxExpectedDuration /*out*/);
12104 break;
12105 default:
12106 find_camera_metadata_ro_entry(request,
12107 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
12108 &e);
12109 if (e.count > 1) {
12110 maxExpectedDuration = 1e9 / e.data.u8[0];
12111 }
12112 break;
12113 }
12114
12115 return maxExpectedDuration;
12116}
12117
12118/*===========================================================================
Thierry Strudel3d639192016-09-09 11:52:26 -070012119 * FUNCTION : setFrameParameters
12120 *
12121 * DESCRIPTION: set parameters per frame as requested in the metadata from
12122 * framework
12123 *
12124 * PARAMETERS :
12125 * @request : request that needs to be serviced
Thierry Strudelc2ee3302016-11-17 12:33:12 -080012126 * @streamsArray : Stream ID of all the requested streams
Thierry Strudel3d639192016-09-09 11:52:26 -070012127 * @blob_request: Whether this request is a blob request or not
12128 *
12129 * RETURN : success: NO_ERROR
12130 * failure:
12131 *==========================================================================*/
12132int QCamera3HardwareInterface::setFrameParameters(
12133 camera3_capture_request_t *request,
Thierry Strudelc2ee3302016-11-17 12:33:12 -080012134 cam_stream_ID_t streamsArray,
Thierry Strudel3d639192016-09-09 11:52:26 -070012135 int blob_request,
12136 uint32_t snapshotStreamId)
12137{
12138 /*translate from camera_metadata_t type to parm_type_t*/
12139 int rc = 0;
12140 int32_t hal_version = CAM_HAL_V3;
12141
12142 clear_metadata_buffer(mParameters);
12143 if (ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_PARM_HAL_VERSION, hal_version)) {
12144 LOGE("Failed to set hal version in the parameters");
12145 return BAD_VALUE;
12146 }
12147
12148 /*we need to update the frame number in the parameters*/
12149 if (ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_META_FRAME_NUMBER,
12150 request->frame_number)) {
12151 LOGE("Failed to set the frame number in the parameters");
12152 return BAD_VALUE;
12153 }
12154
12155 /* Update stream id of all the requested buffers */
Thierry Strudelc2ee3302016-11-17 12:33:12 -080012156 if (ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_META_STREAM_ID, streamsArray)) {
Thierry Strudel3d639192016-09-09 11:52:26 -070012157 LOGE("Failed to set stream type mask in the parameters");
12158 return BAD_VALUE;
12159 }
12160
12161 if (mUpdateDebugLevel) {
12162 uint32_t dummyDebugLevel = 0;
12163 /* The value of dummyDebugLevel is irrelavent. On
12164 * CAM_INTF_PARM_UPDATE_DEBUG_LEVEL, read debug property */
12165 if (ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_PARM_UPDATE_DEBUG_LEVEL,
12166 dummyDebugLevel)) {
12167 LOGE("Failed to set UPDATE_DEBUG_LEVEL");
12168 return BAD_VALUE;
12169 }
12170 mUpdateDebugLevel = false;
12171 }
12172
12173 if(request->settings != NULL){
Emilian Peev30522a12017-08-03 14:36:33 +010012174 mExpectedFrameDuration = calculateMaxExpectedDuration(request->settings);
Thierry Strudel3d639192016-09-09 11:52:26 -070012175 rc = translateToHalMetadata(request, mParameters, snapshotStreamId);
12176 if (blob_request)
12177 memcpy(mPrevParameters, mParameters, sizeof(metadata_buffer_t));
12178 }
12179
12180 return rc;
12181}
12182
12183/*===========================================================================
12184 * FUNCTION : setReprocParameters
12185 *
12186 * DESCRIPTION: Translate frameworks metadata to HAL metadata structure, and
12187 * return it.
12188 *
12189 * PARAMETERS :
12190 * @request : request that needs to be serviced
12191 *
12192 * RETURN : success: NO_ERROR
12193 * failure:
12194 *==========================================================================*/
12195int32_t QCamera3HardwareInterface::setReprocParameters(
12196 camera3_capture_request_t *request, metadata_buffer_t *reprocParam,
12197 uint32_t snapshotStreamId)
12198{
12199 /*translate from camera_metadata_t type to parm_type_t*/
12200 int rc = 0;
12201
12202 if (NULL == request->settings){
12203 LOGE("Reprocess settings cannot be NULL");
12204 return BAD_VALUE;
12205 }
12206
12207 if (NULL == reprocParam) {
12208 LOGE("Invalid reprocessing metadata buffer");
12209 return BAD_VALUE;
12210 }
12211 clear_metadata_buffer(reprocParam);
12212
12213 /*we need to update the frame number in the parameters*/
12214 if (ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_FRAME_NUMBER,
12215 request->frame_number)) {
12216 LOGE("Failed to set the frame number in the parameters");
12217 return BAD_VALUE;
12218 }
12219
12220 rc = translateToHalMetadata(request, reprocParam, snapshotStreamId);
12221 if (rc < 0) {
12222 LOGE("Failed to translate reproc request");
12223 return rc;
12224 }
12225
12226 CameraMetadata frame_settings;
12227 frame_settings = request->settings;
12228 if (frame_settings.exists(QCAMERA3_CROP_COUNT_REPROCESS) &&
12229 frame_settings.exists(QCAMERA3_CROP_REPROCESS)) {
12230 int32_t *crop_count =
12231 frame_settings.find(QCAMERA3_CROP_COUNT_REPROCESS).data.i32;
12232 int32_t *crop_data =
12233 frame_settings.find(QCAMERA3_CROP_REPROCESS).data.i32;
12234 int32_t *roi_map =
12235 frame_settings.find(QCAMERA3_CROP_ROI_MAP_REPROCESS).data.i32;
12236 if ((0 < *crop_count) && (*crop_count < MAX_NUM_STREAMS)) {
12237 cam_crop_data_t crop_meta;
12238 memset(&crop_meta, 0, sizeof(cam_crop_data_t));
12239 crop_meta.num_of_streams = 1;
12240 crop_meta.crop_info[0].crop.left = crop_data[0];
12241 crop_meta.crop_info[0].crop.top = crop_data[1];
12242 crop_meta.crop_info[0].crop.width = crop_data[2];
12243 crop_meta.crop_info[0].crop.height = crop_data[3];
12244
12245 crop_meta.crop_info[0].roi_map.left =
12246 roi_map[0];
12247 crop_meta.crop_info[0].roi_map.top =
12248 roi_map[1];
12249 crop_meta.crop_info[0].roi_map.width =
12250 roi_map[2];
12251 crop_meta.crop_info[0].roi_map.height =
12252 roi_map[3];
12253
12254 if (ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_CROP_DATA, crop_meta)) {
12255 rc = BAD_VALUE;
12256 }
12257 LOGD("Found reprocess crop data for stream %p %dx%d, %dx%d",
12258 request->input_buffer->stream,
12259 crop_meta.crop_info[0].crop.left,
12260 crop_meta.crop_info[0].crop.top,
12261 crop_meta.crop_info[0].crop.width,
12262 crop_meta.crop_info[0].crop.height);
12263 LOGD("Found reprocess roi map data for stream %p %dx%d, %dx%d",
12264 request->input_buffer->stream,
12265 crop_meta.crop_info[0].roi_map.left,
12266 crop_meta.crop_info[0].roi_map.top,
12267 crop_meta.crop_info[0].roi_map.width,
12268 crop_meta.crop_info[0].roi_map.height);
12269 } else {
12270 LOGE("Invalid reprocess crop count %d!", *crop_count);
12271 }
12272 } else {
12273 LOGE("No crop data from matching output stream");
12274 }
12275
12276 /* These settings are not needed for regular requests so handle them specially for
12277 reprocess requests; information needed for EXIF tags */
12278 if (frame_settings.exists(ANDROID_FLASH_MODE)) {
12279 int val = lookupHalName(FLASH_MODES_MAP, METADATA_MAP_SIZE(FLASH_MODES_MAP),
12280 (int)frame_settings.find(ANDROID_FLASH_MODE).data.u8[0]);
12281 if (NAME_NOT_FOUND != val) {
12282 uint32_t flashMode = (uint32_t)val;
12283 if (ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_FLASH_MODE, flashMode)) {
12284 rc = BAD_VALUE;
12285 }
12286 } else {
12287 LOGE("Could not map fwk flash mode %d to correct hal flash mode",
12288 frame_settings.find(ANDROID_FLASH_MODE).data.u8[0]);
12289 }
12290 } else {
12291 LOGH("No flash mode in reprocess settings");
12292 }
12293
12294 if (frame_settings.exists(ANDROID_FLASH_STATE)) {
12295 int32_t flashState = (int32_t)frame_settings.find(ANDROID_FLASH_STATE).data.u8[0];
12296 if (ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_FLASH_STATE, flashState)) {
12297 rc = BAD_VALUE;
12298 }
12299 } else {
12300 LOGH("No flash state in reprocess settings");
12301 }
12302
12303 if (frame_settings.exists(QCAMERA3_HAL_PRIVATEDATA_REPROCESS_FLAGS)) {
12304 uint8_t *reprocessFlags =
12305 frame_settings.find(QCAMERA3_HAL_PRIVATEDATA_REPROCESS_FLAGS).data.u8;
12306 if (ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_REPROCESS_FLAGS,
12307 *reprocessFlags)) {
12308 rc = BAD_VALUE;
12309 }
12310 }
12311
Thierry Strudel54dc9782017-02-15 12:12:10 -080012312 // Add exif debug data to internal metadata
12313 if (frame_settings.exists(QCAMERA3_HAL_PRIVATEDATA_EXIF_DEBUG_DATA_BLOB)) {
12314 mm_jpeg_debug_exif_params_t *debug_params =
12315 (mm_jpeg_debug_exif_params_t *)frame_settings.find
12316 (QCAMERA3_HAL_PRIVATEDATA_EXIF_DEBUG_DATA_BLOB).data.u8;
12317 // AE
12318 if (debug_params->ae_debug_params_valid == TRUE) {
12319 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_EXIF_DEBUG_AE,
12320 debug_params->ae_debug_params);
12321 }
12322 // AWB
12323 if (debug_params->awb_debug_params_valid == TRUE) {
12324 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_EXIF_DEBUG_AWB,
12325 debug_params->awb_debug_params);
12326 }
12327 // AF
12328 if (debug_params->af_debug_params_valid == TRUE) {
12329 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_EXIF_DEBUG_AF,
12330 debug_params->af_debug_params);
12331 }
12332 // ASD
12333 if (debug_params->asd_debug_params_valid == TRUE) {
12334 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_EXIF_DEBUG_ASD,
12335 debug_params->asd_debug_params);
12336 }
12337 // Stats
12338 if (debug_params->stats_debug_params_valid == TRUE) {
12339 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_EXIF_DEBUG_STATS,
12340 debug_params->stats_debug_params);
12341 }
12342 // BE Stats
12343 if (debug_params->bestats_debug_params_valid == TRUE) {
12344 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_EXIF_DEBUG_BESTATS,
12345 debug_params->bestats_debug_params);
12346 }
12347 // BHIST
12348 if (debug_params->bhist_debug_params_valid == TRUE) {
12349 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_EXIF_DEBUG_BHIST,
12350 debug_params->bhist_debug_params);
12351 }
12352 // 3A Tuning
12353 if (debug_params->q3a_tuning_debug_params_valid == TRUE) {
12354 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_EXIF_DEBUG_3A_TUNING,
12355 debug_params->q3a_tuning_debug_params);
12356 }
12357 }
12358
Thierry Strudelcca4d9c2016-10-20 08:25:53 -070012359 // Add metadata which reprocess needs
12360 if (frame_settings.exists(QCAMERA3_HAL_PRIVATEDATA_REPROCESS_DATA_BLOB)) {
12361 cam_reprocess_info_t *repro_info =
12362 (cam_reprocess_info_t *)frame_settings.find
12363 (QCAMERA3_HAL_PRIVATEDATA_REPROCESS_DATA_BLOB).data.u8;
Thierry Strudel3d639192016-09-09 11:52:26 -070012364 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_SNAP_CROP_INFO_SENSOR,
Thierry Strudelcca4d9c2016-10-20 08:25:53 -070012365 repro_info->sensor_crop_info);
Thierry Strudel3d639192016-09-09 11:52:26 -070012366 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_SNAP_CROP_INFO_CAMIF,
Thierry Strudelcca4d9c2016-10-20 08:25:53 -070012367 repro_info->camif_crop_info);
Thierry Strudel3d639192016-09-09 11:52:26 -070012368 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_SNAP_CROP_INFO_ISP,
Thierry Strudelcca4d9c2016-10-20 08:25:53 -070012369 repro_info->isp_crop_info);
Thierry Strudel3d639192016-09-09 11:52:26 -070012370 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_SNAP_CROP_INFO_CPP,
Thierry Strudelcca4d9c2016-10-20 08:25:53 -070012371 repro_info->cpp_crop_info);
Thierry Strudel3d639192016-09-09 11:52:26 -070012372 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_AF_FOCAL_LENGTH_RATIO,
Thierry Strudelcca4d9c2016-10-20 08:25:53 -070012373 repro_info->af_focal_length_ratio);
Thierry Strudel3d639192016-09-09 11:52:26 -070012374 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_PARM_FLIP,
Thierry Strudelcca4d9c2016-10-20 08:25:53 -070012375 repro_info->pipeline_flip);
12376 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_AF_ROI,
12377 repro_info->af_roi);
12378 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_IMG_DYN_FEAT,
12379 repro_info->dyn_mask);
Thierry Strudel3d639192016-09-09 11:52:26 -070012380 /* If there is ANDROID_JPEG_ORIENTATION in frame setting,
12381 CAM_INTF_PARM_ROTATION metadata then has been added in
12382 translateToHalMetadata. HAL need to keep this new rotation
12383 metadata. Otherwise, the old rotation info saved in the vendor tag
12384 would be used */
12385 IF_META_AVAILABLE(cam_rotation_info_t, rotationInfo,
12386 CAM_INTF_PARM_ROTATION, reprocParam) {
12387 LOGD("CAM_INTF_PARM_ROTATION metadata is added in translateToHalMetadata");
12388 } else {
12389 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_PARM_ROTATION,
Thierry Strudelcca4d9c2016-10-20 08:25:53 -070012390 repro_info->rotation_info);
Thierry Strudel3d639192016-09-09 11:52:26 -070012391 }
Thierry Strudel3d639192016-09-09 11:52:26 -070012392 }
12393
12394 /* Add additional JPEG cropping information. App add QCAMERA3_JPEG_ENCODE_CROP_RECT
12395 to ask for cropping and use ROI for downscale/upscale during HW JPEG encoding.
12396 roi.width and roi.height would be the final JPEG size.
12397 For now, HAL only checks this for reprocess request */
12398 if (frame_settings.exists(QCAMERA3_JPEG_ENCODE_CROP_ENABLE) &&
12399 frame_settings.exists(QCAMERA3_JPEG_ENCODE_CROP_RECT)) {
12400 uint8_t *enable =
12401 frame_settings.find(QCAMERA3_JPEG_ENCODE_CROP_ENABLE).data.u8;
12402 if (*enable == TRUE) {
12403 int32_t *crop_data =
12404 frame_settings.find(QCAMERA3_JPEG_ENCODE_CROP_RECT).data.i32;
12405 cam_stream_crop_info_t crop_meta;
12406 memset(&crop_meta, 0, sizeof(cam_stream_crop_info_t));
12407 crop_meta.stream_id = 0;
12408 crop_meta.crop.left = crop_data[0];
12409 crop_meta.crop.top = crop_data[1];
12410 crop_meta.crop.width = crop_data[2];
12411 crop_meta.crop.height = crop_data[3];
Thierry Strudel9e74aae2016-09-22 17:10:18 -070012412 // The JPEG crop roi should match cpp output size
12413 IF_META_AVAILABLE(cam_stream_crop_info_t, cpp_crop,
12414 CAM_INTF_META_SNAP_CROP_INFO_CPP, reprocParam) {
12415 crop_meta.roi_map.left = 0;
12416 crop_meta.roi_map.top = 0;
12417 crop_meta.roi_map.width = cpp_crop->crop.width;
12418 crop_meta.roi_map.height = cpp_crop->crop.height;
Thierry Strudel3d639192016-09-09 11:52:26 -070012419 }
12420 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_PARM_JPEG_ENCODE_CROP,
12421 crop_meta);
Thierry Strudel9e74aae2016-09-22 17:10:18 -070012422 LOGH("Add JPEG encode crop left %d, top %d, width %d, height %d, mCameraId %d",
Thierry Strudel3d639192016-09-09 11:52:26 -070012423 crop_meta.crop.left, crop_meta.crop.top,
Thierry Strudel9e74aae2016-09-22 17:10:18 -070012424 crop_meta.crop.width, crop_meta.crop.height, mCameraId);
12425 LOGH("Add JPEG encode crop ROI left %d, top %d, width %d, height %d, mCameraId %d",
Thierry Strudel3d639192016-09-09 11:52:26 -070012426 crop_meta.roi_map.left, crop_meta.roi_map.top,
Thierry Strudel9e74aae2016-09-22 17:10:18 -070012427 crop_meta.roi_map.width, crop_meta.roi_map.height, mCameraId);
12428
12429 // Add JPEG scale information
12430 cam_dimension_t scale_dim;
12431 memset(&scale_dim, 0, sizeof(cam_dimension_t));
12432 if (frame_settings.exists(QCAMERA3_JPEG_ENCODE_CROP_ROI)) {
12433 int32_t *roi =
12434 frame_settings.find(QCAMERA3_JPEG_ENCODE_CROP_ROI).data.i32;
12435 scale_dim.width = roi[2];
12436 scale_dim.height = roi[3];
12437 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_PARM_JPEG_SCALE_DIMENSION,
12438 scale_dim);
12439 LOGH("Add JPEG encode scale width %d, height %d, mCameraId %d",
12440 scale_dim.width, scale_dim.height, mCameraId);
12441 }
Thierry Strudel3d639192016-09-09 11:52:26 -070012442 }
12443 }
12444
12445 return rc;
12446}
12447
12448/*===========================================================================
12449 * FUNCTION : saveRequestSettings
12450 *
12451 * DESCRIPTION: Add any settings that might have changed to the request settings
12452 * and save the settings to be applied on the frame
12453 *
12454 * PARAMETERS :
12455 * @jpegMetadata : the extracted and/or modified jpeg metadata
12456 * @request : request with initial settings
12457 *
12458 * RETURN :
12459 * camera_metadata_t* : pointer to the saved request settings
12460 *==========================================================================*/
12461camera_metadata_t* QCamera3HardwareInterface::saveRequestSettings(
12462 const CameraMetadata &jpegMetadata,
12463 camera3_capture_request_t *request)
12464{
12465 camera_metadata_t *resultMetadata;
12466 CameraMetadata camMetadata;
12467 camMetadata = request->settings;
12468
12469 if (jpegMetadata.exists(ANDROID_JPEG_THUMBNAIL_SIZE)) {
12470 int32_t thumbnail_size[2];
12471 thumbnail_size[0] = jpegMetadata.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[0];
12472 thumbnail_size[1] = jpegMetadata.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[1];
12473 camMetadata.update(ANDROID_JPEG_THUMBNAIL_SIZE, thumbnail_size,
12474 jpegMetadata.find(ANDROID_JPEG_THUMBNAIL_SIZE).count);
12475 }
12476
12477 if (request->input_buffer != NULL) {
12478 uint8_t reprocessFlags = 1;
12479 camMetadata.update(QCAMERA3_HAL_PRIVATEDATA_REPROCESS_FLAGS,
12480 (uint8_t*)&reprocessFlags,
12481 sizeof(reprocessFlags));
12482 }
12483
12484 resultMetadata = camMetadata.release();
12485 return resultMetadata;
12486}
12487
12488/*===========================================================================
12489 * FUNCTION : setHalFpsRange
12490 *
12491 * DESCRIPTION: set FPS range parameter
12492 *
12493 *
12494 * PARAMETERS :
12495 * @settings : Metadata from framework
12496 * @hal_metadata: Metadata buffer
12497 *
12498 *
12499 * RETURN : success: NO_ERROR
12500 * failure:
12501 *==========================================================================*/
12502int32_t QCamera3HardwareInterface::setHalFpsRange(const CameraMetadata &settings,
12503 metadata_buffer_t *hal_metadata)
12504{
12505 int32_t rc = NO_ERROR;
12506 cam_fps_range_t fps_range;
12507 fps_range.min_fps = (float)
12508 settings.find(ANDROID_CONTROL_AE_TARGET_FPS_RANGE).data.i32[0];
12509 fps_range.max_fps = (float)
12510 settings.find(ANDROID_CONTROL_AE_TARGET_FPS_RANGE).data.i32[1];
12511 fps_range.video_min_fps = fps_range.min_fps;
12512 fps_range.video_max_fps = fps_range.max_fps;
12513
12514 LOGD("aeTargetFpsRange fps: [%f %f]",
12515 fps_range.min_fps, fps_range.max_fps);
12516 /* In CONSTRAINED_HFR_MODE, sensor_fps is derived from aeTargetFpsRange as
12517 * follows:
12518 * ---------------------------------------------------------------|
12519 * Video stream is absent in configure_streams |
12520 * (Camcorder preview before the first video record |
12521 * ---------------------------------------------------------------|
12522 * vid_buf_requested | aeTgtFpsRng | snsrFpsMode | sensorFpsRange |
12523 * | | | vid_min/max_fps|
12524 * ---------------------------------------------------------------|
12525 * NO | [ 30, 240] | 240 | [240, 240] |
12526 * |-------------|-------------|----------------|
12527 * | [240, 240] | 240 | [240, 240] |
12528 * ---------------------------------------------------------------|
12529 * Video stream is present in configure_streams |
12530 * ---------------------------------------------------------------|
12531 * vid_buf_requested | aeTgtFpsRng | snsrFpsMode | sensorFpsRange |
12532 * | | | vid_min/max_fps|
12533 * ---------------------------------------------------------------|
12534 * NO | [ 30, 240] | 240 | [240, 240] |
12535 * (camcorder prev |-------------|-------------|----------------|
12536 * after video rec | [240, 240] | 240 | [240, 240] |
12537 * is stopped) | | | |
12538 * ---------------------------------------------------------------|
12539 * YES | [ 30, 240] | 240 | [240, 240] |
12540 * |-------------|-------------|----------------|
12541 * | [240, 240] | 240 | [240, 240] |
12542 * ---------------------------------------------------------------|
12543 * When Video stream is absent in configure_streams,
12544 * preview fps = sensor_fps / batchsize
12545 * Eg: for 240fps at batchSize 4, preview = 60fps
12546 * for 120fps at batchSize 4, preview = 30fps
12547 *
12548 * When video stream is present in configure_streams, preview fps is as per
12549 * the ratio of preview buffers to video buffers requested in process
12550 * capture request
12551 */
12552 mBatchSize = 0;
12553 if (CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE == mOpMode) {
12554 fps_range.min_fps = fps_range.video_max_fps;
12555 fps_range.video_min_fps = fps_range.video_max_fps;
12556 int val = lookupHalName(HFR_MODE_MAP, METADATA_MAP_SIZE(HFR_MODE_MAP),
12557 fps_range.max_fps);
12558 if (NAME_NOT_FOUND != val) {
12559 cam_hfr_mode_t hfrMode = (cam_hfr_mode_t)val;
12560 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_HFR, hfrMode)) {
12561 return BAD_VALUE;
12562 }
12563
12564 if (fps_range.max_fps >= MIN_FPS_FOR_BATCH_MODE) {
12565 /* If batchmode is currently in progress and the fps changes,
12566 * set the flag to restart the sensor */
12567 if((mHFRVideoFps >= MIN_FPS_FOR_BATCH_MODE) &&
12568 (mHFRVideoFps != fps_range.max_fps)) {
12569 mNeedSensorRestart = true;
12570 }
12571 mHFRVideoFps = fps_range.max_fps;
12572 mBatchSize = mHFRVideoFps / PREVIEW_FPS_FOR_HFR;
12573 if (mBatchSize > MAX_HFR_BATCH_SIZE) {
12574 mBatchSize = MAX_HFR_BATCH_SIZE;
12575 }
12576 }
12577 LOGD("hfrMode: %d batchSize: %d", hfrMode, mBatchSize);
12578
12579 }
12580 } else {
12581 /* HFR mode is session param in backend/ISP. This should be reset when
12582 * in non-HFR mode */
12583 cam_hfr_mode_t hfrMode = CAM_HFR_MODE_OFF;
12584 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_HFR, hfrMode)) {
12585 return BAD_VALUE;
12586 }
12587 }
12588 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_FPS_RANGE, fps_range)) {
12589 return BAD_VALUE;
12590 }
12591 LOGD("fps: [%f %f] vid_fps: [%f %f]", fps_range.min_fps,
12592 fps_range.max_fps, fps_range.video_min_fps, fps_range.video_max_fps);
12593 return rc;
12594}
12595
12596/*===========================================================================
12597 * FUNCTION : translateToHalMetadata
12598 *
12599 * DESCRIPTION: read from the camera_metadata_t and change to parm_type_t
12600 *
12601 *
12602 * PARAMETERS :
12603 * @request : request sent from framework
12604 *
12605 *
12606 * RETURN : success: NO_ERROR
12607 * failure:
12608 *==========================================================================*/
12609int QCamera3HardwareInterface::translateToHalMetadata
12610 (const camera3_capture_request_t *request,
12611 metadata_buffer_t *hal_metadata,
Chien-Yu Chen92724a82017-01-06 11:50:30 -080012612 uint32_t snapshotStreamId) {
12613 if (request == nullptr || hal_metadata == nullptr) {
12614 return BAD_VALUE;
12615 }
12616
12617 int64_t minFrameDuration = getMinFrameDuration(request);
12618
12619 return translateFwkMetadataToHalMetadata(request->settings, hal_metadata, snapshotStreamId,
12620 minFrameDuration);
12621}
12622
12623int QCamera3HardwareInterface::translateFwkMetadataToHalMetadata(
12624 const camera_metadata_t *frameworkMetadata, metadata_buffer_t *hal_metadata,
12625 uint32_t snapshotStreamId, int64_t minFrameDuration) {
12626
Thierry Strudel3d639192016-09-09 11:52:26 -070012627 int rc = 0;
12628 CameraMetadata frame_settings;
Chien-Yu Chen92724a82017-01-06 11:50:30 -080012629 frame_settings = frameworkMetadata;
Thierry Strudel3d639192016-09-09 11:52:26 -070012630
12631 /* Do not change the order of the following list unless you know what you are
12632 * doing.
12633 * The order is laid out in such a way that parameters in the front of the table
12634 * may be used to override the parameters later in the table. Examples are:
12635 * 1. META_MODE should precede AEC/AWB/AF MODE
12636 * 2. AEC MODE should preced EXPOSURE_TIME/SENSITIVITY/FRAME_DURATION
12637 * 3. AWB_MODE should precede COLOR_CORRECTION_MODE
12638 * 4. Any mode should precede it's corresponding settings
12639 */
12640 if (frame_settings.exists(ANDROID_CONTROL_MODE)) {
12641 uint8_t metaMode = frame_settings.find(ANDROID_CONTROL_MODE).data.u8[0];
12642 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_MODE, metaMode)) {
12643 rc = BAD_VALUE;
12644 }
12645 rc = extractSceneMode(frame_settings, metaMode, hal_metadata);
12646 if (rc != NO_ERROR) {
12647 LOGE("extractSceneMode failed");
12648 }
12649 }
12650
12651 if (frame_settings.exists(ANDROID_CONTROL_AE_MODE)) {
12652 uint8_t fwk_aeMode =
12653 frame_settings.find(ANDROID_CONTROL_AE_MODE).data.u8[0];
12654 uint8_t aeMode;
12655 int32_t redeye;
12656
12657 if (fwk_aeMode == ANDROID_CONTROL_AE_MODE_OFF ) {
12658 aeMode = CAM_AE_MODE_OFF;
Chien-Yu Chenc5494e52018-01-19 17:53:58 -080012659 } else if (fwk_aeMode == ANDROID_CONTROL_AE_MODE_ON_EXTERNAL_FLASH) {
Eino-Ville Talvalae2de8432017-02-25 11:11:13 -080012660 aeMode = CAM_AE_MODE_ON_EXTERNAL_FLASH;
Thierry Strudel3d639192016-09-09 11:52:26 -070012661 } else {
12662 aeMode = CAM_AE_MODE_ON;
12663 }
12664 if (fwk_aeMode == ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE) {
12665 redeye = 1;
12666 } else {
12667 redeye = 0;
12668 }
12669
12670 int val = lookupHalName(AE_FLASH_MODE_MAP, METADATA_MAP_SIZE(AE_FLASH_MODE_MAP),
12671 fwk_aeMode);
12672 if (NAME_NOT_FOUND != val) {
12673 int32_t flashMode = (int32_t)val;
12674 ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_LED_MODE, flashMode);
12675 }
12676
12677 ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_AEC_MODE, aeMode);
12678 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_REDEYE_REDUCTION, redeye)) {
12679 rc = BAD_VALUE;
12680 }
12681 }
12682
12683 if (frame_settings.exists(ANDROID_CONTROL_AWB_MODE)) {
12684 uint8_t fwk_whiteLevel = frame_settings.find(ANDROID_CONTROL_AWB_MODE).data.u8[0];
12685 int val = lookupHalName(WHITE_BALANCE_MODES_MAP, METADATA_MAP_SIZE(WHITE_BALANCE_MODES_MAP),
12686 fwk_whiteLevel);
12687 if (NAME_NOT_FOUND != val) {
12688 uint8_t whiteLevel = (uint8_t)val;
12689 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_WHITE_BALANCE, whiteLevel)) {
12690 rc = BAD_VALUE;
12691 }
12692 }
12693 }
12694
12695 if (frame_settings.exists(ANDROID_COLOR_CORRECTION_ABERRATION_MODE)) {
12696 uint8_t fwk_cacMode =
12697 frame_settings.find(
12698 ANDROID_COLOR_CORRECTION_ABERRATION_MODE).data.u8[0];
12699 int val = lookupHalName(COLOR_ABERRATION_MAP, METADATA_MAP_SIZE(COLOR_ABERRATION_MAP),
12700 fwk_cacMode);
12701 if (NAME_NOT_FOUND != val) {
12702 cam_aberration_mode_t cacMode = (cam_aberration_mode_t) val;
12703 bool entryAvailable = FALSE;
12704 // Check whether Frameworks set CAC mode is supported in device or not
12705 for (size_t i = 0; i < gCamCapability[mCameraId]->aberration_modes_count; i++) {
12706 if (gCamCapability[mCameraId]->aberration_modes[i] == cacMode) {
12707 entryAvailable = TRUE;
12708 break;
12709 }
12710 }
12711 LOGD("FrameworksCacMode=%d entryAvailable=%d", cacMode, entryAvailable);
12712 // If entry not found then set the device supported mode instead of frameworks mode i.e,
12713 // Only HW ISP CAC + NO SW CAC : Advertise all 3 with High doing same as fast by ISP
12714 // NO HW ISP CAC + Only SW CAC : Advertise all 3 with Fast doing the same as OFF
12715 if (entryAvailable == FALSE) {
12716 if (gCamCapability[mCameraId]->aberration_modes_count == 0) {
12717 cacMode = CAM_COLOR_CORRECTION_ABERRATION_OFF;
12718 } else {
12719 if (cacMode == CAM_COLOR_CORRECTION_ABERRATION_HIGH_QUALITY) {
12720 // High is not supported and so set the FAST as spec say's underlying
12721 // device implementation can be the same for both modes.
12722 cacMode = CAM_COLOR_CORRECTION_ABERRATION_FAST;
12723 } else if (cacMode == CAM_COLOR_CORRECTION_ABERRATION_FAST) {
12724 // Fast is not supported and so we cannot set HIGH or FAST but choose OFF
12725 // in order to avoid the fps drop due to high quality
12726 cacMode = CAM_COLOR_CORRECTION_ABERRATION_OFF;
12727 } else {
12728 cacMode = CAM_COLOR_CORRECTION_ABERRATION_OFF;
12729 }
12730 }
12731 }
12732 LOGD("Final cacMode is %d", cacMode);
12733 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_CAC, cacMode)) {
12734 rc = BAD_VALUE;
12735 }
12736 } else {
12737 LOGE("Invalid framework CAC mode: %d", fwk_cacMode);
12738 }
12739 }
12740
Jason Lee84ae9972017-02-24 13:24:24 -080012741 uint8_t fwk_focusMode = 0;
Shuzhen Wangb57ec912017-07-31 13:24:27 -070012742 if (m_bForceInfinityAf == 0) {
Thierry Strudel2896d122017-02-23 19:18:03 -080012743 if (frame_settings.exists(ANDROID_CONTROL_AF_MODE)) {
Jason Lee84ae9972017-02-24 13:24:24 -080012744 fwk_focusMode = frame_settings.find(ANDROID_CONTROL_AF_MODE).data.u8[0];
Thierry Strudel2896d122017-02-23 19:18:03 -080012745 int val = lookupHalName(FOCUS_MODES_MAP, METADATA_MAP_SIZE(FOCUS_MODES_MAP),
12746 fwk_focusMode);
12747 if (NAME_NOT_FOUND != val) {
12748 uint8_t focusMode = (uint8_t)val;
12749 LOGD("set focus mode %d", focusMode);
12750 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata,
12751 CAM_INTF_PARM_FOCUS_MODE, focusMode)) {
12752 rc = BAD_VALUE;
12753 }
Thierry Strudel3d639192016-09-09 11:52:26 -070012754 }
Shuzhen Wanga1d82a92017-09-19 14:39:43 -070012755 } else {
12756 LOGE("Fatal: Missing ANDROID_CONTROL_AF_MODE");
Thierry Strudel3d639192016-09-09 11:52:26 -070012757 }
Thierry Strudel2896d122017-02-23 19:18:03 -080012758 } else {
12759 uint8_t focusMode = (uint8_t)CAM_FOCUS_MODE_INFINITY;
12760 LOGE("Focus forced to infinity %d", focusMode);
12761 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_FOCUS_MODE, focusMode)) {
12762 rc = BAD_VALUE;
12763 }
Thierry Strudel3d639192016-09-09 11:52:26 -070012764 }
12765
Jason Lee84ae9972017-02-24 13:24:24 -080012766 if (frame_settings.exists(ANDROID_LENS_FOCUS_DISTANCE) &&
12767 fwk_focusMode == ANDROID_CONTROL_AF_MODE_OFF) {
Thierry Strudel3d639192016-09-09 11:52:26 -070012768 float focalDistance = frame_settings.find(ANDROID_LENS_FOCUS_DISTANCE).data.f[0];
12769 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_LENS_FOCUS_DISTANCE,
12770 focalDistance)) {
12771 rc = BAD_VALUE;
12772 }
12773 }
12774
12775 if (frame_settings.exists(ANDROID_CONTROL_AE_ANTIBANDING_MODE)) {
12776 uint8_t fwk_antibandingMode =
12777 frame_settings.find(ANDROID_CONTROL_AE_ANTIBANDING_MODE).data.u8[0];
12778 int val = lookupHalName(ANTIBANDING_MODES_MAP,
12779 METADATA_MAP_SIZE(ANTIBANDING_MODES_MAP), fwk_antibandingMode);
12780 if (NAME_NOT_FOUND != val) {
12781 uint32_t hal_antibandingMode = (uint32_t)val;
Shuzhen Wangf6890e02016-08-12 14:28:54 -070012782 if (hal_antibandingMode == CAM_ANTIBANDING_MODE_AUTO) {
12783 if (m60HzZone) {
12784 hal_antibandingMode = CAM_ANTIBANDING_MODE_AUTO_60HZ;
12785 } else {
12786 hal_antibandingMode = CAM_ANTIBANDING_MODE_AUTO_50HZ;
12787 }
12788 }
Thierry Strudel3d639192016-09-09 11:52:26 -070012789 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_ANTIBANDING,
12790 hal_antibandingMode)) {
12791 rc = BAD_VALUE;
12792 }
12793 }
12794 }
12795
12796 if (frame_settings.exists(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION)) {
12797 int32_t expCompensation = frame_settings.find(
12798 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION).data.i32[0];
12799 if (expCompensation < gCamCapability[mCameraId]->exposure_compensation_min)
12800 expCompensation = gCamCapability[mCameraId]->exposure_compensation_min;
12801 if (expCompensation > gCamCapability[mCameraId]->exposure_compensation_max)
12802 expCompensation = gCamCapability[mCameraId]->exposure_compensation_max;
Thierry Strudel54dc9782017-02-15 12:12:10 -080012803 LOGD("Setting compensation:%d", expCompensation);
Thierry Strudel3d639192016-09-09 11:52:26 -070012804 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_EXPOSURE_COMPENSATION,
12805 expCompensation)) {
12806 rc = BAD_VALUE;
12807 }
12808 }
12809
12810 if (frame_settings.exists(ANDROID_CONTROL_AE_LOCK)) {
12811 uint8_t aeLock = frame_settings.find(ANDROID_CONTROL_AE_LOCK).data.u8[0];
12812 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_AEC_LOCK, aeLock)) {
12813 rc = BAD_VALUE;
12814 }
12815 }
12816 if (frame_settings.exists(ANDROID_CONTROL_AE_TARGET_FPS_RANGE)) {
12817 rc = setHalFpsRange(frame_settings, hal_metadata);
12818 if (rc != NO_ERROR) {
12819 LOGE("setHalFpsRange failed");
12820 }
12821 }
12822
12823 if (frame_settings.exists(ANDROID_CONTROL_AWB_LOCK)) {
12824 uint8_t awbLock = frame_settings.find(ANDROID_CONTROL_AWB_LOCK).data.u8[0];
12825 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_AWB_LOCK, awbLock)) {
12826 rc = BAD_VALUE;
12827 }
12828 }
12829
12830 if (frame_settings.exists(ANDROID_CONTROL_EFFECT_MODE)) {
12831 uint8_t fwk_effectMode = frame_settings.find(ANDROID_CONTROL_EFFECT_MODE).data.u8[0];
12832 int val = lookupHalName(EFFECT_MODES_MAP, METADATA_MAP_SIZE(EFFECT_MODES_MAP),
12833 fwk_effectMode);
12834 if (NAME_NOT_FOUND != val) {
12835 uint8_t effectMode = (uint8_t)val;
12836 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_EFFECT, effectMode)) {
12837 rc = BAD_VALUE;
12838 }
12839 }
12840 }
12841
12842 if (frame_settings.exists(ANDROID_COLOR_CORRECTION_MODE)) {
12843 uint8_t colorCorrectMode = frame_settings.find(ANDROID_COLOR_CORRECTION_MODE).data.u8[0];
12844 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_COLOR_CORRECT_MODE,
12845 colorCorrectMode)) {
12846 rc = BAD_VALUE;
12847 }
12848 }
12849
12850 if (frame_settings.exists(ANDROID_COLOR_CORRECTION_GAINS)) {
12851 cam_color_correct_gains_t colorCorrectGains;
12852 for (size_t i = 0; i < CC_GAIN_MAX; i++) {
12853 colorCorrectGains.gains[i] =
12854 frame_settings.find(ANDROID_COLOR_CORRECTION_GAINS).data.f[i];
12855 }
12856 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_COLOR_CORRECT_GAINS,
12857 colorCorrectGains)) {
12858 rc = BAD_VALUE;
12859 }
12860 }
12861
12862 if (frame_settings.exists(ANDROID_COLOR_CORRECTION_TRANSFORM)) {
12863 cam_color_correct_matrix_t colorCorrectTransform;
12864 cam_rational_type_t transform_elem;
12865 size_t num = 0;
12866 for (size_t i = 0; i < CC_MATRIX_ROWS; i++) {
12867 for (size_t j = 0; j < CC_MATRIX_COLS; j++) {
12868 transform_elem.numerator =
12869 frame_settings.find(ANDROID_COLOR_CORRECTION_TRANSFORM).data.r[num].numerator;
12870 transform_elem.denominator =
12871 frame_settings.find(ANDROID_COLOR_CORRECTION_TRANSFORM).data.r[num].denominator;
12872 colorCorrectTransform.transform_matrix[i][j] = transform_elem;
12873 num++;
12874 }
12875 }
12876 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_COLOR_CORRECT_TRANSFORM,
12877 colorCorrectTransform)) {
12878 rc = BAD_VALUE;
12879 }
12880 }
12881
12882 cam_trigger_t aecTrigger;
12883 aecTrigger.trigger = CAM_AEC_TRIGGER_IDLE;
12884 aecTrigger.trigger_id = -1;
12885 if (frame_settings.exists(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER)&&
12886 frame_settings.exists(ANDROID_CONTROL_AE_PRECAPTURE_ID)) {
12887 aecTrigger.trigger =
12888 frame_settings.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER).data.u8[0];
12889 aecTrigger.trigger_id =
12890 frame_settings.find(ANDROID_CONTROL_AE_PRECAPTURE_ID).data.i32[0];
12891 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_AEC_PRECAPTURE_TRIGGER,
12892 aecTrigger)) {
12893 rc = BAD_VALUE;
12894 }
12895 LOGD("precaptureTrigger: %d precaptureTriggerID: %d",
12896 aecTrigger.trigger, aecTrigger.trigger_id);
12897 }
12898
12899 /*af_trigger must come with a trigger id*/
12900 if (frame_settings.exists(ANDROID_CONTROL_AF_TRIGGER) &&
12901 frame_settings.exists(ANDROID_CONTROL_AF_TRIGGER_ID)) {
12902 cam_trigger_t af_trigger;
12903 af_trigger.trigger =
12904 frame_settings.find(ANDROID_CONTROL_AF_TRIGGER).data.u8[0];
12905 af_trigger.trigger_id =
12906 frame_settings.find(ANDROID_CONTROL_AF_TRIGGER_ID).data.i32[0];
12907 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_AF_TRIGGER, af_trigger)) {
12908 rc = BAD_VALUE;
12909 }
12910 LOGD("AfTrigger: %d AfTriggerID: %d",
12911 af_trigger.trigger, af_trigger.trigger_id);
12912 }
12913
12914 if (frame_settings.exists(ANDROID_DEMOSAIC_MODE)) {
12915 int32_t demosaic = frame_settings.find(ANDROID_DEMOSAIC_MODE).data.u8[0];
12916 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_DEMOSAIC, demosaic)) {
12917 rc = BAD_VALUE;
12918 }
12919 }
12920 if (frame_settings.exists(ANDROID_EDGE_MODE)) {
12921 cam_edge_application_t edge_application;
12922 edge_application.edge_mode = frame_settings.find(ANDROID_EDGE_MODE).data.u8[0];
Thierry Strudel54dc9782017-02-15 12:12:10 -080012923
Thierry Strudel3d639192016-09-09 11:52:26 -070012924 if (edge_application.edge_mode == CAM_EDGE_MODE_OFF) {
12925 edge_application.sharpness = 0;
12926 } else {
Thierry Strudel54dc9782017-02-15 12:12:10 -080012927 edge_application.sharpness =
12928 gCamCapability[mCameraId]->sharpness_ctrl.def_value; //default
12929 if (frame_settings.exists(QCAMERA3_SHARPNESS_STRENGTH)) {
12930 int32_t sharpness =
12931 frame_settings.find(QCAMERA3_SHARPNESS_STRENGTH).data.i32[0];
12932 if (sharpness >= gCamCapability[mCameraId]->sharpness_ctrl.min_value &&
12933 sharpness <= gCamCapability[mCameraId]->sharpness_ctrl.max_value) {
12934 LOGD("Setting edge mode sharpness %d", sharpness);
12935 edge_application.sharpness = sharpness;
12936 }
12937 }
Thierry Strudel3d639192016-09-09 11:52:26 -070012938 }
12939 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_EDGE_MODE, edge_application)) {
12940 rc = BAD_VALUE;
12941 }
12942 }
12943
12944 if (frame_settings.exists(ANDROID_FLASH_MODE)) {
Donghui Hanfe52aa62017-11-06 18:08:56 -080012945 uint32_t flashMode = (uint32_t)frame_settings.find(ANDROID_FLASH_MODE).data.u8[0];
12946 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_FLASH_MODE, flashMode)) {
12947 rc = BAD_VALUE;
12948 }
12949
Thierry Strudel3d639192016-09-09 11:52:26 -070012950 int32_t respectFlashMode = 1;
12951 if (frame_settings.exists(ANDROID_CONTROL_AE_MODE)) {
12952 uint8_t fwk_aeMode =
12953 frame_settings.find(ANDROID_CONTROL_AE_MODE).data.u8[0];
Eino-Ville Talvalae2de8432017-02-25 11:11:13 -080012954 if (fwk_aeMode == ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH ||
12955 fwk_aeMode == ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH ||
12956 fwk_aeMode == ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE) {
Thierry Strudel3d639192016-09-09 11:52:26 -070012957 respectFlashMode = 0;
12958 LOGH("AE Mode controls flash, ignore android.flash.mode");
12959 }
12960 }
12961 if (respectFlashMode) {
12962 int val = lookupHalName(FLASH_MODES_MAP, METADATA_MAP_SIZE(FLASH_MODES_MAP),
12963 (int)frame_settings.find(ANDROID_FLASH_MODE).data.u8[0]);
12964 LOGH("flash mode after mapping %d", val);
12965 // To check: CAM_INTF_META_FLASH_MODE usage
12966 if (NAME_NOT_FOUND != val) {
Donghui Hanfe52aa62017-11-06 18:08:56 -080012967 uint8_t ledMode = (uint8_t)val;
12968 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_LED_MODE, ledMode)) {
Thierry Strudel3d639192016-09-09 11:52:26 -070012969 rc = BAD_VALUE;
12970 }
12971 }
12972 }
12973 }
12974
Donghui Hanfe52aa62017-11-06 18:08:56 -080012975 if (frame_settings.exists(ANDROID_FLASH_STATE)) {
12976 int32_t flashState = (int32_t)frame_settings.find(ANDROID_FLASH_STATE).data.i32[0];
12977 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_FLASH_STATE, flashState)) {
12978 rc = BAD_VALUE;
12979 }
12980 }
12981
Thierry Strudel3d639192016-09-09 11:52:26 -070012982 if (frame_settings.exists(ANDROID_FLASH_FIRING_POWER)) {
12983 uint8_t flashPower = frame_settings.find(ANDROID_FLASH_FIRING_POWER).data.u8[0];
12984 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_FLASH_POWER, flashPower)) {
12985 rc = BAD_VALUE;
12986 }
12987 }
12988
12989 if (frame_settings.exists(ANDROID_FLASH_FIRING_TIME)) {
12990 int64_t flashFiringTime = frame_settings.find(ANDROID_FLASH_FIRING_TIME).data.i64[0];
12991 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_FLASH_FIRING_TIME,
12992 flashFiringTime)) {
12993 rc = BAD_VALUE;
12994 }
12995 }
12996
12997 if (frame_settings.exists(ANDROID_HOT_PIXEL_MODE)) {
12998 uint8_t hotPixelMode = frame_settings.find(ANDROID_HOT_PIXEL_MODE).data.u8[0];
12999 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_HOTPIXEL_MODE,
13000 hotPixelMode)) {
13001 rc = BAD_VALUE;
13002 }
13003 }
13004
13005 if (frame_settings.exists(ANDROID_LENS_APERTURE)) {
13006 float lensAperture = frame_settings.find( ANDROID_LENS_APERTURE).data.f[0];
13007 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_LENS_APERTURE,
13008 lensAperture)) {
13009 rc = BAD_VALUE;
13010 }
13011 }
13012
13013 if (frame_settings.exists(ANDROID_LENS_FILTER_DENSITY)) {
13014 float filterDensity = frame_settings.find(ANDROID_LENS_FILTER_DENSITY).data.f[0];
13015 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_LENS_FILTERDENSITY,
13016 filterDensity)) {
13017 rc = BAD_VALUE;
13018 }
13019 }
13020
13021 if (frame_settings.exists(ANDROID_LENS_FOCAL_LENGTH)) {
13022 float focalLength = frame_settings.find(ANDROID_LENS_FOCAL_LENGTH).data.f[0];
13023 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_LENS_FOCAL_LENGTH,
13024 focalLength)) {
13025 rc = BAD_VALUE;
13026 }
13027 }
13028
13029 if (frame_settings.exists(ANDROID_LENS_OPTICAL_STABILIZATION_MODE)) {
13030 uint8_t optStabMode =
13031 frame_settings.find(ANDROID_LENS_OPTICAL_STABILIZATION_MODE).data.u8[0];
13032 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_LENS_OPT_STAB_MODE,
13033 optStabMode)) {
13034 rc = BAD_VALUE;
13035 }
13036 }
13037
13038 if (frame_settings.exists(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE)) {
13039 uint8_t videoStabMode =
13040 frame_settings.find(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE).data.u8[0];
13041 LOGD("videoStabMode from APP = %d", videoStabMode);
13042 if (ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_META_VIDEO_STAB_MODE,
13043 videoStabMode)) {
13044 rc = BAD_VALUE;
13045 }
13046 }
13047
13048
13049 if (frame_settings.exists(ANDROID_NOISE_REDUCTION_MODE)) {
13050 uint8_t noiseRedMode = frame_settings.find(ANDROID_NOISE_REDUCTION_MODE).data.u8[0];
13051 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_NOISE_REDUCTION_MODE,
13052 noiseRedMode)) {
13053 rc = BAD_VALUE;
13054 }
13055 }
13056
13057 if (frame_settings.exists(ANDROID_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR)) {
13058 float reprocessEffectiveExposureFactor =
13059 frame_settings.find(ANDROID_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR).data.f[0];
13060 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_EFFECTIVE_EXPOSURE_FACTOR,
13061 reprocessEffectiveExposureFactor)) {
13062 rc = BAD_VALUE;
13063 }
13064 }
13065
13066 cam_crop_region_t scalerCropRegion;
13067 bool scalerCropSet = false;
13068 if (frame_settings.exists(ANDROID_SCALER_CROP_REGION)) {
13069 scalerCropRegion.left = frame_settings.find(ANDROID_SCALER_CROP_REGION).data.i32[0];
13070 scalerCropRegion.top = frame_settings.find(ANDROID_SCALER_CROP_REGION).data.i32[1];
13071 scalerCropRegion.width = frame_settings.find(ANDROID_SCALER_CROP_REGION).data.i32[2];
13072 scalerCropRegion.height = frame_settings.find(ANDROID_SCALER_CROP_REGION).data.i32[3];
13073
13074 // Map coordinate system from active array to sensor output.
13075 mCropRegionMapper.toSensor(scalerCropRegion.left, scalerCropRegion.top,
13076 scalerCropRegion.width, scalerCropRegion.height);
13077
13078 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_SCALER_CROP_REGION,
13079 scalerCropRegion)) {
13080 rc = BAD_VALUE;
13081 }
13082 scalerCropSet = true;
13083 }
13084
13085 if (frame_settings.exists(ANDROID_SENSOR_EXPOSURE_TIME)) {
13086 int64_t sensorExpTime =
13087 frame_settings.find(ANDROID_SENSOR_EXPOSURE_TIME).data.i64[0];
13088 LOGD("setting sensorExpTime %lld", sensorExpTime);
13089 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_SENSOR_EXPOSURE_TIME,
13090 sensorExpTime)) {
13091 rc = BAD_VALUE;
13092 }
13093 }
13094
13095 if (frame_settings.exists(ANDROID_SENSOR_FRAME_DURATION)) {
13096 int64_t sensorFrameDuration =
13097 frame_settings.find(ANDROID_SENSOR_FRAME_DURATION).data.i64[0];
Thierry Strudel3d639192016-09-09 11:52:26 -070013098 sensorFrameDuration = MAX(sensorFrameDuration, minFrameDuration);
13099 if (sensorFrameDuration > gCamCapability[mCameraId]->max_frame_duration)
13100 sensorFrameDuration = gCamCapability[mCameraId]->max_frame_duration;
13101 LOGD("clamp sensorFrameDuration to %lld", sensorFrameDuration);
13102 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_SENSOR_FRAME_DURATION,
13103 sensorFrameDuration)) {
13104 rc = BAD_VALUE;
13105 }
13106 }
13107
13108 if (frame_settings.exists(ANDROID_SENSOR_SENSITIVITY)) {
13109 int32_t sensorSensitivity = frame_settings.find(ANDROID_SENSOR_SENSITIVITY).data.i32[0];
13110 if (sensorSensitivity < gCamCapability[mCameraId]->sensitivity_range.min_sensitivity)
13111 sensorSensitivity = gCamCapability[mCameraId]->sensitivity_range.min_sensitivity;
13112 if (sensorSensitivity > gCamCapability[mCameraId]->sensitivity_range.max_sensitivity)
13113 sensorSensitivity = gCamCapability[mCameraId]->sensitivity_range.max_sensitivity;
13114 LOGD("clamp sensorSensitivity to %d", sensorSensitivity);
13115 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_SENSOR_SENSITIVITY,
13116 sensorSensitivity)) {
13117 rc = BAD_VALUE;
13118 }
13119 }
13120
Thierry Strudel9e74aae2016-09-22 17:10:18 -070013121#ifndef USE_HAL_3_3
13122 if (frame_settings.exists(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST)) {
13123 int32_t ispSensitivity =
13124 frame_settings.find(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST).data.i32[0];
13125 if (ispSensitivity <
13126 gCamCapability[mCameraId]->isp_sensitivity_range.min_sensitivity) {
13127 ispSensitivity =
13128 gCamCapability[mCameraId]->isp_sensitivity_range.min_sensitivity;
13129 LOGD("clamp ispSensitivity to %d", ispSensitivity);
13130 }
13131 if (ispSensitivity >
13132 gCamCapability[mCameraId]->isp_sensitivity_range.max_sensitivity) {
13133 ispSensitivity =
13134 gCamCapability[mCameraId]->isp_sensitivity_range.max_sensitivity;
13135 LOGD("clamp ispSensitivity to %d", ispSensitivity);
13136 }
13137 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_ISP_SENSITIVITY,
13138 ispSensitivity)) {
13139 rc = BAD_VALUE;
13140 }
13141 }
13142#endif
13143
Thierry Strudel3d639192016-09-09 11:52:26 -070013144 if (frame_settings.exists(ANDROID_SHADING_MODE)) {
13145 uint8_t shadingMode = frame_settings.find(ANDROID_SHADING_MODE).data.u8[0];
13146 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_SHADING_MODE, shadingMode)) {
13147 rc = BAD_VALUE;
13148 }
13149 }
13150
13151 if (frame_settings.exists(ANDROID_STATISTICS_FACE_DETECT_MODE)) {
13152 uint8_t fwk_facedetectMode =
13153 frame_settings.find(ANDROID_STATISTICS_FACE_DETECT_MODE).data.u8[0];
13154
13155 int val = lookupHalName(FACEDETECT_MODES_MAP, METADATA_MAP_SIZE(FACEDETECT_MODES_MAP),
13156 fwk_facedetectMode);
13157
13158 if (NAME_NOT_FOUND != val) {
13159 uint8_t facedetectMode = (uint8_t)val;
13160 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_STATS_FACEDETECT_MODE,
13161 facedetectMode)) {
13162 rc = BAD_VALUE;
13163 }
13164 }
13165 }
13166
Thierry Strudel54dc9782017-02-15 12:12:10 -080013167 if (frame_settings.exists(QCAMERA3_HISTOGRAM_MODE)) {
Thierry Strudel3d639192016-09-09 11:52:26 -070013168 uint8_t histogramMode =
Thierry Strudel54dc9782017-02-15 12:12:10 -080013169 frame_settings.find(QCAMERA3_HISTOGRAM_MODE).data.u8[0];
Thierry Strudel3d639192016-09-09 11:52:26 -070013170 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_STATS_HISTOGRAM_MODE,
13171 histogramMode)) {
13172 rc = BAD_VALUE;
13173 }
13174 }
13175
13176 if (frame_settings.exists(ANDROID_STATISTICS_SHARPNESS_MAP_MODE)) {
13177 uint8_t sharpnessMapMode =
13178 frame_settings.find(ANDROID_STATISTICS_SHARPNESS_MAP_MODE).data.u8[0];
13179 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_STATS_SHARPNESS_MAP_MODE,
13180 sharpnessMapMode)) {
13181 rc = BAD_VALUE;
13182 }
13183 }
13184
13185 if (frame_settings.exists(ANDROID_TONEMAP_MODE)) {
13186 uint8_t tonemapMode =
13187 frame_settings.find(ANDROID_TONEMAP_MODE).data.u8[0];
13188 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_TONEMAP_MODE, tonemapMode)) {
13189 rc = BAD_VALUE;
13190 }
13191 }
13192 /* Tonemap curve channels ch0 = G, ch 1 = B, ch 2 = R */
13193 /*All tonemap channels will have the same number of points*/
13194 if (frame_settings.exists(ANDROID_TONEMAP_CURVE_GREEN) &&
13195 frame_settings.exists(ANDROID_TONEMAP_CURVE_BLUE) &&
13196 frame_settings.exists(ANDROID_TONEMAP_CURVE_RED)) {
13197 cam_rgb_tonemap_curves tonemapCurves;
13198 tonemapCurves.tonemap_points_cnt = frame_settings.find(ANDROID_TONEMAP_CURVE_GREEN).count/2;
13199 if (tonemapCurves.tonemap_points_cnt > CAM_MAX_TONEMAP_CURVE_SIZE) {
13200 LOGE("Fatal: tonemap_points_cnt %d exceeds max value of %d",
13201 tonemapCurves.tonemap_points_cnt,
13202 CAM_MAX_TONEMAP_CURVE_SIZE);
13203 tonemapCurves.tonemap_points_cnt = CAM_MAX_TONEMAP_CURVE_SIZE;
13204 }
13205
13206 /* ch0 = G*/
13207 size_t point = 0;
13208 cam_tonemap_curve_t tonemapCurveGreen;
13209 for (size_t i = 0; i < tonemapCurves.tonemap_points_cnt; i++) {
13210 for (size_t j = 0; j < 2; j++) {
13211 tonemapCurveGreen.tonemap_points[i][j] =
13212 frame_settings.find(ANDROID_TONEMAP_CURVE_GREEN).data.f[point];
13213 point++;
13214 }
13215 }
13216 tonemapCurves.curves[0] = tonemapCurveGreen;
13217
13218 /* ch 1 = B */
13219 point = 0;
13220 cam_tonemap_curve_t tonemapCurveBlue;
13221 for (size_t i = 0; i < tonemapCurves.tonemap_points_cnt; i++) {
13222 for (size_t j = 0; j < 2; j++) {
13223 tonemapCurveBlue.tonemap_points[i][j] =
13224 frame_settings.find(ANDROID_TONEMAP_CURVE_BLUE).data.f[point];
13225 point++;
13226 }
13227 }
13228 tonemapCurves.curves[1] = tonemapCurveBlue;
13229
13230 /* ch 2 = R */
13231 point = 0;
13232 cam_tonemap_curve_t tonemapCurveRed;
13233 for (size_t i = 0; i < tonemapCurves.tonemap_points_cnt; i++) {
13234 for (size_t j = 0; j < 2; j++) {
13235 tonemapCurveRed.tonemap_points[i][j] =
13236 frame_settings.find(ANDROID_TONEMAP_CURVE_RED).data.f[point];
13237 point++;
13238 }
13239 }
13240 tonemapCurves.curves[2] = tonemapCurveRed;
13241
13242 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_TONEMAP_CURVES,
13243 tonemapCurves)) {
13244 rc = BAD_VALUE;
13245 }
13246 }
13247
13248 if (frame_settings.exists(ANDROID_CONTROL_CAPTURE_INTENT)) {
13249 uint8_t captureIntent = frame_settings.find(ANDROID_CONTROL_CAPTURE_INTENT).data.u8[0];
13250 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_CAPTURE_INTENT,
13251 captureIntent)) {
13252 rc = BAD_VALUE;
13253 }
13254 }
13255
13256 if (frame_settings.exists(ANDROID_BLACK_LEVEL_LOCK)) {
13257 uint8_t blackLevelLock = frame_settings.find(ANDROID_BLACK_LEVEL_LOCK).data.u8[0];
13258 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_BLACK_LEVEL_LOCK,
13259 blackLevelLock)) {
13260 rc = BAD_VALUE;
13261 }
13262 }
13263
13264 if (frame_settings.exists(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE)) {
13265 uint8_t lensShadingMapMode =
13266 frame_settings.find(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE).data.u8[0];
13267 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_LENS_SHADING_MAP_MODE,
13268 lensShadingMapMode)) {
13269 rc = BAD_VALUE;
13270 }
13271 }
13272
13273 if (frame_settings.exists(ANDROID_CONTROL_AE_REGIONS)) {
13274 cam_area_t roi;
13275 bool reset = true;
Chien-Yu Chen92724a82017-01-06 11:50:30 -080013276 convertFromRegions(roi, frame_settings, ANDROID_CONTROL_AE_REGIONS);
Thierry Strudel3d639192016-09-09 11:52:26 -070013277
13278 // Map coordinate system from active array to sensor output.
13279 mCropRegionMapper.toSensor(roi.rect.left, roi.rect.top, roi.rect.width,
13280 roi.rect.height);
13281
13282 if (scalerCropSet) {
13283 reset = resetIfNeededROI(&roi, &scalerCropRegion);
13284 }
13285 if (reset && ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_AEC_ROI, roi)) {
13286 rc = BAD_VALUE;
13287 }
13288 }
13289
13290 if (frame_settings.exists(ANDROID_CONTROL_AF_REGIONS)) {
13291 cam_area_t roi;
13292 bool reset = true;
Chien-Yu Chen92724a82017-01-06 11:50:30 -080013293 convertFromRegions(roi, frame_settings, ANDROID_CONTROL_AF_REGIONS);
Thierry Strudel3d639192016-09-09 11:52:26 -070013294
13295 // Map coordinate system from active array to sensor output.
13296 mCropRegionMapper.toSensor(roi.rect.left, roi.rect.top, roi.rect.width,
13297 roi.rect.height);
13298
13299 if (scalerCropSet) {
13300 reset = resetIfNeededROI(&roi, &scalerCropRegion);
13301 }
13302 if (reset && ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_AF_ROI, roi)) {
13303 rc = BAD_VALUE;
13304 }
13305 }
13306
13307 // CDS for non-HFR non-video mode
13308 if ((mOpMode != CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE) &&
13309 !(m_bIsVideo) && frame_settings.exists(QCAMERA3_CDS_MODE)) {
13310 int32_t *fwk_cds = frame_settings.find(QCAMERA3_CDS_MODE).data.i32;
13311 if ((CAM_CDS_MODE_MAX <= *fwk_cds) || (0 > *fwk_cds)) {
13312 LOGE("Invalid CDS mode %d!", *fwk_cds);
13313 } else {
13314 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata,
13315 CAM_INTF_PARM_CDS_MODE, *fwk_cds)) {
13316 rc = BAD_VALUE;
13317 }
13318 }
13319 }
13320
Thierry Strudel04e026f2016-10-10 11:27:36 -070013321 // Video HDR
Mansoor Aftab93a66e52017-01-26 14:58:25 -080013322 cam_video_hdr_mode_t vhdr = CAM_VIDEO_HDR_MODE_OFF;
Thierry Strudel04e026f2016-10-10 11:27:36 -070013323 if (frame_settings.exists(QCAMERA3_VIDEO_HDR_MODE)) {
Mansoor Aftab93a66e52017-01-26 14:58:25 -080013324 vhdr = (cam_video_hdr_mode_t) frame_settings.find(QCAMERA3_VIDEO_HDR_MODE).data.i32[0];
13325 }
13326 if (m_bVideoHdrEnabled)
13327 vhdr = CAM_VIDEO_HDR_MODE_ON;
13328
Thierry Strudel54dc9782017-02-15 12:12:10 -080013329 int8_t curr_hdr_state = ((mCurrFeatureState & CAM_QCOM_FEATURE_STAGGERED_VIDEO_HDR) != 0);
13330
13331 if(vhdr != curr_hdr_state)
13332 LOGH("PROFILE_SET_HDR_MODE %d" ,vhdr);
13333
Mansoor Aftab93a66e52017-01-26 14:58:25 -080013334 rc = setVideoHdrMode(mParameters, vhdr);
13335 if (rc != NO_ERROR) {
13336 LOGE("setVideoHDR is failed");
Thierry Strudel04e026f2016-10-10 11:27:36 -070013337 }
13338
13339 //IR
13340 if(frame_settings.exists(QCAMERA3_IR_MODE)) {
13341 cam_ir_mode_type_t fwk_ir = (cam_ir_mode_type_t)
13342 frame_settings.find(QCAMERA3_IR_MODE).data.i32[0];
Thierry Strudel54dc9782017-02-15 12:12:10 -080013343 uint8_t curr_ir_state = ((mCurrFeatureState & CAM_QCOM_FEATURE_IR) != 0);
13344 uint8_t isIRon = 0;
13345
13346 (fwk_ir >0) ? (isIRon = 1) : (isIRon = 0) ;
Thierry Strudel04e026f2016-10-10 11:27:36 -070013347 if ((CAM_IR_MODE_MAX <= fwk_ir) || (0 > fwk_ir)) {
13348 LOGE("Invalid IR mode %d!", fwk_ir);
13349 } else {
Thierry Strudel54dc9782017-02-15 12:12:10 -080013350 if(isIRon != curr_ir_state )
13351 LOGH("PROFILE_SET_IR_MODE %d" ,isIRon);
13352
Thierry Strudel04e026f2016-10-10 11:27:36 -070013353 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata,
13354 CAM_INTF_META_IR_MODE, fwk_ir)) {
13355 rc = BAD_VALUE;
13356 }
13357 }
13358 }
13359
Thierry Strudel54dc9782017-02-15 12:12:10 -080013360 //Binning Correction Mode
13361 if(frame_settings.exists(QCAMERA3_BINNING_CORRECTION_MODE)) {
13362 cam_binning_correction_mode_t fwk_binning_correction = (cam_binning_correction_mode_t)
13363 frame_settings.find(QCAMERA3_BINNING_CORRECTION_MODE).data.i32[0];
13364 if ((CAM_BINNING_CORRECTION_MODE_MAX <= fwk_binning_correction)
13365 || (0 > fwk_binning_correction)) {
13366 LOGE("Invalid binning correction mode %d!", fwk_binning_correction);
13367 } else {
13368 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata,
13369 CAM_INTF_META_BINNING_CORRECTION_MODE, fwk_binning_correction)) {
13370 rc = BAD_VALUE;
13371 }
13372 }
13373 }
13374
Thierry Strudel269c81a2016-10-12 12:13:59 -070013375 if (frame_settings.exists(QCAMERA3_AEC_CONVERGENCE_SPEED)) {
13376 float aec_speed;
13377 aec_speed = frame_settings.find(QCAMERA3_AEC_CONVERGENCE_SPEED).data.f[0];
13378 LOGD("AEC Speed :%f", aec_speed);
13379 if ( aec_speed < 0 ) {
13380 LOGE("Invalid AEC mode %f!", aec_speed);
13381 } else {
13382 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_AEC_CONVERGENCE_SPEED,
13383 aec_speed)) {
13384 rc = BAD_VALUE;
13385 }
13386 }
13387 }
13388
13389 if (frame_settings.exists(QCAMERA3_AWB_CONVERGENCE_SPEED)) {
13390 float awb_speed;
13391 awb_speed = frame_settings.find(QCAMERA3_AWB_CONVERGENCE_SPEED).data.f[0];
13392 LOGD("AWB Speed :%f", awb_speed);
13393 if ( awb_speed < 0 ) {
13394 LOGE("Invalid AWB mode %f!", awb_speed);
13395 } else {
13396 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_AWB_CONVERGENCE_SPEED,
13397 awb_speed)) {
13398 rc = BAD_VALUE;
13399 }
13400 }
13401 }
13402
Thierry Strudel3d639192016-09-09 11:52:26 -070013403 // TNR
13404 if (frame_settings.exists(QCAMERA3_TEMPORAL_DENOISE_ENABLE) &&
13405 frame_settings.exists(QCAMERA3_TEMPORAL_DENOISE_PROCESS_TYPE)) {
13406 uint8_t b_TnrRequested = 0;
Thierry Strudel54dc9782017-02-15 12:12:10 -080013407 uint8_t curr_tnr_state = ((mCurrFeatureState & CAM_QTI_FEATURE_SW_TNR) != 0);
Thierry Strudel3d639192016-09-09 11:52:26 -070013408 cam_denoise_param_t tnr;
13409 tnr.denoise_enable = frame_settings.find(QCAMERA3_TEMPORAL_DENOISE_ENABLE).data.u8[0];
13410 tnr.process_plates =
13411 (cam_denoise_process_type_t)frame_settings.find(
13412 QCAMERA3_TEMPORAL_DENOISE_PROCESS_TYPE).data.i32[0];
13413 b_TnrRequested = tnr.denoise_enable;
Thierry Strudel54dc9782017-02-15 12:12:10 -080013414
13415 if(b_TnrRequested != curr_tnr_state)
13416 LOGH("PROFILE_SET_TNR_MODE %d" ,b_TnrRequested);
13417
Thierry Strudel3d639192016-09-09 11:52:26 -070013418 if (ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_PARM_TEMPORAL_DENOISE, tnr)) {
13419 rc = BAD_VALUE;
13420 }
13421 }
13422
Thierry Strudel54dc9782017-02-15 12:12:10 -080013423 if (frame_settings.exists(QCAMERA3_EXPOSURE_METER)) {
Thierry Strudel295a0ca2016-11-03 18:38:47 -070013424 int32_t* exposure_metering_mode =
Thierry Strudel54dc9782017-02-15 12:12:10 -080013425 frame_settings.find(QCAMERA3_EXPOSURE_METER).data.i32;
Thierry Strudel295a0ca2016-11-03 18:38:47 -070013426 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_AEC_ALGO_TYPE,
13427 *exposure_metering_mode)) {
13428 rc = BAD_VALUE;
13429 }
13430 }
13431
Thierry Strudel3d639192016-09-09 11:52:26 -070013432 if (frame_settings.exists(ANDROID_SENSOR_TEST_PATTERN_MODE)) {
13433 int32_t fwk_testPatternMode =
13434 frame_settings.find(ANDROID_SENSOR_TEST_PATTERN_MODE).data.i32[0];
13435 int testPatternMode = lookupHalName(TEST_PATTERN_MAP,
13436 METADATA_MAP_SIZE(TEST_PATTERN_MAP), fwk_testPatternMode);
13437
13438 if (NAME_NOT_FOUND != testPatternMode) {
13439 cam_test_pattern_data_t testPatternData;
13440 memset(&testPatternData, 0, sizeof(testPatternData));
13441 testPatternData.mode = (cam_test_pattern_mode_t)testPatternMode;
13442 if (testPatternMode == CAM_TEST_PATTERN_SOLID_COLOR &&
13443 frame_settings.exists(ANDROID_SENSOR_TEST_PATTERN_DATA)) {
13444 int32_t *fwk_testPatternData =
13445 frame_settings.find(ANDROID_SENSOR_TEST_PATTERN_DATA).data.i32;
13446 testPatternData.r = fwk_testPatternData[0];
13447 testPatternData.b = fwk_testPatternData[3];
13448 switch (gCamCapability[mCameraId]->color_arrangement) {
13449 case CAM_FILTER_ARRANGEMENT_RGGB:
13450 case CAM_FILTER_ARRANGEMENT_GRBG:
13451 testPatternData.gr = fwk_testPatternData[1];
13452 testPatternData.gb = fwk_testPatternData[2];
13453 break;
13454 case CAM_FILTER_ARRANGEMENT_GBRG:
13455 case CAM_FILTER_ARRANGEMENT_BGGR:
13456 testPatternData.gr = fwk_testPatternData[2];
13457 testPatternData.gb = fwk_testPatternData[1];
13458 break;
13459 default:
13460 LOGE("color arrangement %d is not supported",
13461 gCamCapability[mCameraId]->color_arrangement);
13462 break;
13463 }
13464 }
13465 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_TEST_PATTERN_DATA,
13466 testPatternData)) {
13467 rc = BAD_VALUE;
13468 }
13469 } else {
13470 LOGE("Invalid framework sensor test pattern mode %d",
13471 fwk_testPatternMode);
13472 }
13473 }
13474
13475 if (frame_settings.exists(ANDROID_JPEG_GPS_COORDINATES)) {
13476 size_t count = 0;
13477 camera_metadata_entry_t gps_coords = frame_settings.find(ANDROID_JPEG_GPS_COORDINATES);
13478 ADD_SET_PARAM_ARRAY_TO_BATCH(hal_metadata, CAM_INTF_META_JPEG_GPS_COORDINATES,
13479 gps_coords.data.d, gps_coords.count, count);
13480 if (gps_coords.count != count) {
13481 rc = BAD_VALUE;
13482 }
13483 }
13484
13485 if (frame_settings.exists(ANDROID_JPEG_GPS_PROCESSING_METHOD)) {
13486 char gps_methods[GPS_PROCESSING_METHOD_SIZE];
13487 size_t count = 0;
13488 const char *gps_methods_src = (const char *)
13489 frame_settings.find(ANDROID_JPEG_GPS_PROCESSING_METHOD).data.u8;
13490 memset(gps_methods, '\0', sizeof(gps_methods));
13491 strlcpy(gps_methods, gps_methods_src, sizeof(gps_methods));
13492 ADD_SET_PARAM_ARRAY_TO_BATCH(hal_metadata, CAM_INTF_META_JPEG_GPS_PROC_METHODS,
13493 gps_methods, GPS_PROCESSING_METHOD_SIZE, count);
13494 if (GPS_PROCESSING_METHOD_SIZE != count) {
13495 rc = BAD_VALUE;
13496 }
13497 }
13498
13499 if (frame_settings.exists(ANDROID_JPEG_GPS_TIMESTAMP)) {
13500 int64_t gps_timestamp = frame_settings.find(ANDROID_JPEG_GPS_TIMESTAMP).data.i64[0];
13501 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_JPEG_GPS_TIMESTAMP,
13502 gps_timestamp)) {
13503 rc = BAD_VALUE;
13504 }
13505 }
13506
13507 if (frame_settings.exists(ANDROID_JPEG_ORIENTATION)) {
13508 int32_t orientation = frame_settings.find(ANDROID_JPEG_ORIENTATION).data.i32[0];
13509 cam_rotation_info_t rotation_info;
13510 if (orientation == 0) {
13511 rotation_info.rotation = ROTATE_0;
13512 } else if (orientation == 90) {
13513 rotation_info.rotation = ROTATE_90;
13514 } else if (orientation == 180) {
13515 rotation_info.rotation = ROTATE_180;
13516 } else if (orientation == 270) {
13517 rotation_info.rotation = ROTATE_270;
13518 }
Shuzhen Wang6ec8eac2016-07-28 23:09:23 -070013519 rotation_info.device_rotation = ROTATE_0;
Thierry Strudel3d639192016-09-09 11:52:26 -070013520 rotation_info.streamId = snapshotStreamId;
13521 ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_JPEG_ORIENTATION, orientation);
13522 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_ROTATION, rotation_info)) {
13523 rc = BAD_VALUE;
13524 }
13525 }
13526
13527 if (frame_settings.exists(ANDROID_JPEG_QUALITY)) {
13528 uint32_t quality = (uint32_t) frame_settings.find(ANDROID_JPEG_QUALITY).data.u8[0];
13529 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_JPEG_QUALITY, quality)) {
13530 rc = BAD_VALUE;
13531 }
13532 }
13533
13534 if (frame_settings.exists(ANDROID_JPEG_THUMBNAIL_QUALITY)) {
13535 uint32_t thumb_quality = (uint32_t)
13536 frame_settings.find(ANDROID_JPEG_THUMBNAIL_QUALITY).data.u8[0];
13537 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_JPEG_THUMB_QUALITY,
13538 thumb_quality)) {
13539 rc = BAD_VALUE;
13540 }
13541 }
13542
13543 if (frame_settings.exists(ANDROID_JPEG_THUMBNAIL_SIZE)) {
13544 cam_dimension_t dim;
13545 dim.width = frame_settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[0];
13546 dim.height = frame_settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[1];
13547 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_JPEG_THUMB_SIZE, dim)) {
13548 rc = BAD_VALUE;
13549 }
13550 }
13551
13552 // Internal metadata
13553 if (frame_settings.exists(QCAMERA3_PRIVATEDATA_REPROCESS)) {
13554 size_t count = 0;
13555 camera_metadata_entry_t privatedata = frame_settings.find(QCAMERA3_PRIVATEDATA_REPROCESS);
13556 ADD_SET_PARAM_ARRAY_TO_BATCH(hal_metadata, CAM_INTF_META_PRIVATE_DATA,
13557 privatedata.data.i32, privatedata.count, count);
13558 if (privatedata.count != count) {
13559 rc = BAD_VALUE;
13560 }
13561 }
13562
Thierry Strudel295a0ca2016-11-03 18:38:47 -070013563 // ISO/Exposure Priority
13564 if (frame_settings.exists(QCAMERA3_USE_ISO_EXP_PRIORITY) &&
13565 frame_settings.exists(QCAMERA3_SELECT_PRIORITY)) {
13566 cam_priority_mode_t mode =
13567 (cam_priority_mode_t)frame_settings.find(QCAMERA3_SELECT_PRIORITY).data.i32[0];
13568 if((CAM_ISO_PRIORITY == mode) || (CAM_EXP_PRIORITY == mode)) {
13569 cam_intf_parm_manual_3a_t use_iso_exp_pty;
13570 use_iso_exp_pty.previewOnly = FALSE;
13571 uint64_t* ptr = (uint64_t*)frame_settings.find(QCAMERA3_USE_ISO_EXP_PRIORITY).data.i64;
13572 use_iso_exp_pty.value = *ptr;
13573
13574 if(CAM_ISO_PRIORITY == mode) {
13575 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_ISO,
13576 use_iso_exp_pty)) {
13577 rc = BAD_VALUE;
13578 }
13579 }
13580 else {
13581 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_EXPOSURE_TIME,
13582 use_iso_exp_pty)) {
13583 rc = BAD_VALUE;
13584 }
13585 }
Thierry Strudel54dc9782017-02-15 12:12:10 -080013586
13587 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_ZSL_MODE, 1)) {
13588 rc = BAD_VALUE;
13589 }
13590 }
13591 } else {
13592 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_ZSL_MODE, 0)) {
13593 rc = BAD_VALUE;
Thierry Strudel295a0ca2016-11-03 18:38:47 -070013594 }
13595 }
13596
13597 // Saturation
13598 if (frame_settings.exists(QCAMERA3_USE_SATURATION)) {
13599 int32_t* use_saturation =
13600 frame_settings.find(QCAMERA3_USE_SATURATION).data.i32;
13601 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_SATURATION, *use_saturation)) {
13602 rc = BAD_VALUE;
13603 }
13604 }
13605
Thierry Strudel3d639192016-09-09 11:52:26 -070013606 // EV step
13607 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_EV_STEP,
13608 gCamCapability[mCameraId]->exp_compensation_step)) {
13609 rc = BAD_VALUE;
13610 }
13611
13612 // CDS info
13613 if (frame_settings.exists(QCAMERA3_CDS_INFO)) {
13614 cam_cds_data_t *cdsData = (cam_cds_data_t *)
13615 frame_settings.find(QCAMERA3_CDS_INFO).data.u8;
13616
13617 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata,
13618 CAM_INTF_META_CDS_DATA, *cdsData)) {
13619 rc = BAD_VALUE;
13620 }
13621 }
13622
Shuzhen Wang19463d72016-03-08 11:09:52 -080013623 // Hybrid AE
13624 if (frame_settings.exists(NEXUS_EXPERIMENTAL_2016_HYBRID_AE_ENABLE)) {
13625 uint8_t *hybrid_ae = (uint8_t *)
13626 frame_settings.find(NEXUS_EXPERIMENTAL_2016_HYBRID_AE_ENABLE).data.u8;
Shuzhen Wang5fdb7332018-02-09 12:25:28 -080013627 // Motion tracking intent isn't compatible with hybrid ae.
13628 if (mCaptureIntent == CAM_INTENT_MOTION_TRACKING) {
13629 *hybrid_ae = 0;
13630 }
Shuzhen Wang77b049a2017-08-30 12:24:36 -070013631 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_HYBRID_AE, *hybrid_ae)) {
13632 rc = BAD_VALUE;
13633 }
Shuzhen Wang19463d72016-03-08 11:09:52 -080013634 }
13635
Wei (Alex) Honga90a2142018-01-05 17:36:52 -080013636 // Motion Detection
13637 if (frame_settings.exists(NEXUS_EXPERIMENTAL_2017_MOTION_DETECTION_ENABLE)) {
13638 uint8_t *motion_detection = (uint8_t *)
13639 frame_settings.find(NEXUS_EXPERIMENTAL_2017_MOTION_DETECTION_ENABLE).data.u8;
13640 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_MOTION_DETECTION_ENABLE, *motion_detection)) {
13641 rc = BAD_VALUE;
13642 }
13643 }
13644
Shuzhen Wang14415f52016-11-16 18:26:18 -080013645 // Histogram
13646 if (frame_settings.exists(NEXUS_EXPERIMENTAL_2017_HISTOGRAM_ENABLE)) {
13647 uint8_t histogramMode =
13648 frame_settings.find(NEXUS_EXPERIMENTAL_2017_HISTOGRAM_ENABLE).data.u8[0];
13649 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_STATS_HISTOGRAM_MODE,
13650 histogramMode)) {
13651 rc = BAD_VALUE;
13652 }
13653 }
13654
13655 if (frame_settings.exists(NEXUS_EXPERIMENTAL_2017_HISTOGRAM_BINS)) {
13656 int32_t histogramBins =
13657 frame_settings.find(NEXUS_EXPERIMENTAL_2017_HISTOGRAM_BINS).data.i32[0];
13658 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_STATS_HISTOGRAM_BINS,
13659 histogramBins)) {
13660 rc = BAD_VALUE;
13661 }
13662 }
13663
Shuzhen Wangcc386c52017-03-29 09:28:08 -070013664 // Tracking AF
13665 if (frame_settings.exists(NEXUS_EXPERIMENTAL_2017_TRACKING_AF_TRIGGER)) {
13666 uint8_t trackingAfTrigger =
13667 frame_settings.find(NEXUS_EXPERIMENTAL_2017_TRACKING_AF_TRIGGER).data.u8[0];
13668 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_TRACKING_AF_TRIGGER,
13669 trackingAfTrigger)) {
13670 rc = BAD_VALUE;
13671 }
13672 }
13673
Chien-Yu Chendbd619b2017-08-04 17:50:11 -070013674 // Makernote
13675 camera_metadata_entry entry = frame_settings.find(NEXUS_EXPERIMENTAL_2017_EXIF_MAKERNOTE);
13676 if (entry.count != 0) {
13677 if (entry.count <= MAX_MAKERNOTE_LENGTH) {
13678 cam_makernote_t makernote;
13679 makernote.length = entry.count;
13680 memcpy(makernote.data, entry.data.u8, makernote.length);
13681 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_MAKERNOTE, makernote)) {
13682 rc = BAD_VALUE;
13683 }
13684 } else {
13685 ALOGE("%s: Makernote length %u is larger than %d", __FUNCTION__, entry.count,
13686 MAX_MAKERNOTE_LENGTH);
13687 rc = BAD_VALUE;
13688 }
13689 }
13690
Thierry Strudel3d639192016-09-09 11:52:26 -070013691 return rc;
13692}
13693
13694/*===========================================================================
13695 * FUNCTION : captureResultCb
13696 *
13697 * DESCRIPTION: Callback handler for all channels (streams, as well as metadata)
13698 *
13699 * PARAMETERS :
13700 * @frame : frame information from mm-camera-interface
13701 * @buffer : actual gralloc buffer to be returned to frameworks. NULL if metadata.
13702 * @userdata: userdata
13703 *
13704 * RETURN : NONE
13705 *==========================================================================*/
13706void QCamera3HardwareInterface::captureResultCb(mm_camera_super_buf_t *metadata,
13707 camera3_stream_buffer_t *buffer,
13708 uint32_t frame_number, bool isInputBuffer, void *userdata)
13709{
13710 QCamera3HardwareInterface *hw = (QCamera3HardwareInterface *)userdata;
13711 if (hw == NULL) {
13712 LOGE("Invalid hw %p", hw);
13713 return;
13714 }
13715
13716 hw->captureResultCb(metadata, buffer, frame_number, isInputBuffer);
13717 return;
13718}
13719
Thierry Strudelc2ee3302016-11-17 12:33:12 -080013720/*===========================================================================
13721 * FUNCTION : setBufferErrorStatus
13722 *
13723 * DESCRIPTION: Callback handler for channels to report any buffer errors
13724 *
13725 * PARAMETERS :
13726 * @ch : Channel on which buffer error is reported from
13727 * @frame_number : frame number on which buffer error is reported on
13728 * @buffer_status : buffer error status
13729 * @userdata: userdata
13730 *
13731 * RETURN : NONE
13732 *==========================================================================*/
13733void QCamera3HardwareInterface::setBufferErrorStatus(QCamera3Channel* ch,
13734 uint32_t frame_number, camera3_buffer_status_t err, void *userdata)
13735{
13736 QCamera3HardwareInterface *hw = (QCamera3HardwareInterface *)userdata;
13737 if (hw == NULL) {
13738 LOGE("Invalid hw %p", hw);
13739 return;
13740 }
Thierry Strudel3d639192016-09-09 11:52:26 -070013741
Thierry Strudelc2ee3302016-11-17 12:33:12 -080013742 hw->setBufferErrorStatus(ch, frame_number, err);
13743 return;
13744}
13745
13746void QCamera3HardwareInterface::setBufferErrorStatus(QCamera3Channel* ch,
13747 uint32_t frameNumber, camera3_buffer_status_t err)
13748{
13749 LOGD("channel: %p, frame# %d, buf err: %d", ch, frameNumber, err);
13750 pthread_mutex_lock(&mMutex);
13751
13752 for (auto& req : mPendingBuffersMap.mPendingBuffersInRequest) {
13753 if (req.frame_number != frameNumber)
13754 continue;
13755 for (auto& k : req.mPendingBufferList) {
13756 if(k.stream->priv == ch) {
13757 k.bufStatus = CAMERA3_BUFFER_STATUS_ERROR;
13758 }
13759 }
13760 }
13761
13762 pthread_mutex_unlock(&mMutex);
13763 return;
13764}
Thierry Strudel3d639192016-09-09 11:52:26 -070013765/*===========================================================================
13766 * FUNCTION : initialize
13767 *
13768 * DESCRIPTION: Pass framework callback pointers to HAL
13769 *
13770 * PARAMETERS :
13771 *
13772 *
13773 * RETURN : Success : 0
13774 * Failure: -ENODEV
13775 *==========================================================================*/
13776
13777int QCamera3HardwareInterface::initialize(const struct camera3_device *device,
13778 const camera3_callback_ops_t *callback_ops)
13779{
13780 LOGD("E");
13781 QCamera3HardwareInterface *hw =
13782 reinterpret_cast<QCamera3HardwareInterface *>(device->priv);
13783 if (!hw) {
13784 LOGE("NULL camera device");
13785 return -ENODEV;
13786 }
13787
13788 int rc = hw->initialize(callback_ops);
13789 LOGD("X");
13790 return rc;
13791}
13792
13793/*===========================================================================
13794 * FUNCTION : configure_streams
13795 *
13796 * DESCRIPTION:
13797 *
13798 * PARAMETERS :
13799 *
13800 *
13801 * RETURN : Success: 0
13802 * Failure: -EINVAL (if stream configuration is invalid)
13803 * -ENODEV (fatal error)
13804 *==========================================================================*/
13805
13806int QCamera3HardwareInterface::configure_streams(
13807 const struct camera3_device *device,
13808 camera3_stream_configuration_t *stream_list)
13809{
13810 LOGD("E");
13811 QCamera3HardwareInterface *hw =
13812 reinterpret_cast<QCamera3HardwareInterface *>(device->priv);
13813 if (!hw) {
13814 LOGE("NULL camera device");
13815 return -ENODEV;
13816 }
13817 int rc = hw->configureStreams(stream_list);
13818 LOGD("X");
13819 return rc;
13820}
13821
13822/*===========================================================================
13823 * FUNCTION : construct_default_request_settings
13824 *
13825 * DESCRIPTION: Configure a settings buffer to meet the required use case
13826 *
13827 * PARAMETERS :
13828 *
13829 *
13830 * RETURN : Success: Return valid metadata
13831 * Failure: Return NULL
13832 *==========================================================================*/
13833const camera_metadata_t* QCamera3HardwareInterface::
13834 construct_default_request_settings(const struct camera3_device *device,
13835 int type)
13836{
13837
13838 LOGD("E");
13839 camera_metadata_t* fwk_metadata = NULL;
13840 QCamera3HardwareInterface *hw =
13841 reinterpret_cast<QCamera3HardwareInterface *>(device->priv);
13842 if (!hw) {
13843 LOGE("NULL camera device");
13844 return NULL;
13845 }
13846
13847 fwk_metadata = hw->translateCapabilityToMetadata(type);
13848
13849 LOGD("X");
13850 return fwk_metadata;
13851}
13852
13853/*===========================================================================
13854 * FUNCTION : process_capture_request
13855 *
13856 * DESCRIPTION:
13857 *
13858 * PARAMETERS :
13859 *
13860 *
13861 * RETURN :
13862 *==========================================================================*/
13863int QCamera3HardwareInterface::process_capture_request(
13864 const struct camera3_device *device,
13865 camera3_capture_request_t *request)
13866{
13867 LOGD("E");
Thierry Strudele80ad7c2016-12-06 10:16:27 -080013868 CAMSCOPE_UPDATE_FLAGS(CAMSCOPE_SECTION_HAL, kpi_camscope_flags);
Thierry Strudel3d639192016-09-09 11:52:26 -070013869 QCamera3HardwareInterface *hw =
13870 reinterpret_cast<QCamera3HardwareInterface *>(device->priv);
13871 if (!hw) {
13872 LOGE("NULL camera device");
13873 return -EINVAL;
13874 }
13875
Thierry Strudele80ad7c2016-12-06 10:16:27 -080013876 int rc = hw->orchestrateRequest(request);
Thierry Strudel3d639192016-09-09 11:52:26 -070013877 LOGD("X");
13878 return rc;
13879}
13880
13881/*===========================================================================
13882 * FUNCTION : dump
13883 *
13884 * DESCRIPTION:
13885 *
13886 * PARAMETERS :
13887 *
13888 *
13889 * RETURN :
13890 *==========================================================================*/
13891
13892void QCamera3HardwareInterface::dump(
13893 const struct camera3_device *device, int fd)
13894{
13895 /* Log level property is read when "adb shell dumpsys media.camera" is
13896 called so that the log level can be controlled without restarting
13897 the media server */
13898 getLogLevel();
13899
13900 LOGD("E");
13901 QCamera3HardwareInterface *hw =
13902 reinterpret_cast<QCamera3HardwareInterface *>(device->priv);
13903 if (!hw) {
13904 LOGE("NULL camera device");
13905 return;
13906 }
13907
13908 hw->dump(fd);
13909 LOGD("X");
13910 return;
13911}
13912
13913/*===========================================================================
13914 * FUNCTION : flush
13915 *
13916 * DESCRIPTION:
13917 *
13918 * PARAMETERS :
13919 *
13920 *
13921 * RETURN :
13922 *==========================================================================*/
13923
13924int QCamera3HardwareInterface::flush(
13925 const struct camera3_device *device)
13926{
13927 int rc;
13928 LOGD("E");
13929 QCamera3HardwareInterface *hw =
13930 reinterpret_cast<QCamera3HardwareInterface *>(device->priv);
13931 if (!hw) {
13932 LOGE("NULL camera device");
13933 return -EINVAL;
13934 }
13935
13936 pthread_mutex_lock(&hw->mMutex);
13937 // Validate current state
13938 switch (hw->mState) {
13939 case STARTED:
13940 /* valid state */
13941 break;
13942
13943 case ERROR:
13944 pthread_mutex_unlock(&hw->mMutex);
13945 hw->handleCameraDeviceError();
13946 return -ENODEV;
13947
13948 default:
13949 LOGI("Flush returned during state %d", hw->mState);
13950 pthread_mutex_unlock(&hw->mMutex);
13951 return 0;
13952 }
13953 pthread_mutex_unlock(&hw->mMutex);
13954
13955 rc = hw->flush(true /* restart channels */ );
13956 LOGD("X");
13957 return rc;
13958}
13959
13960/*===========================================================================
13961 * FUNCTION : close_camera_device
13962 *
13963 * DESCRIPTION:
13964 *
13965 * PARAMETERS :
13966 *
13967 *
13968 * RETURN :
13969 *==========================================================================*/
13970int QCamera3HardwareInterface::close_camera_device(struct hw_device_t* device)
13971{
13972 int ret = NO_ERROR;
13973 QCamera3HardwareInterface *hw =
13974 reinterpret_cast<QCamera3HardwareInterface *>(
13975 reinterpret_cast<camera3_device_t *>(device)->priv);
13976 if (!hw) {
13977 LOGE("NULL camera device");
13978 return BAD_VALUE;
13979 }
13980
13981 LOGI("[KPI Perf]: E camera id %d", hw->mCameraId);
13982 delete hw;
13983 LOGI("[KPI Perf]: X");
Thierry Strudele80ad7c2016-12-06 10:16:27 -080013984 CAMSCOPE_DESTROY(CAMSCOPE_SECTION_HAL);
Thierry Strudel3d639192016-09-09 11:52:26 -070013985 return ret;
13986}
13987
13988/*===========================================================================
13989 * FUNCTION : getWaveletDenoiseProcessPlate
13990 *
13991 * DESCRIPTION: query wavelet denoise process plate
13992 *
13993 * PARAMETERS : None
13994 *
13995 * RETURN : WNR prcocess plate value
13996 *==========================================================================*/
13997cam_denoise_process_type_t QCamera3HardwareInterface::getWaveletDenoiseProcessPlate()
13998{
13999 char prop[PROPERTY_VALUE_MAX];
14000 memset(prop, 0, sizeof(prop));
14001 property_get("persist.denoise.process.plates", prop, "0");
14002 int processPlate = atoi(prop);
14003 switch(processPlate) {
14004 case 0:
14005 return CAM_WAVELET_DENOISE_YCBCR_PLANE;
14006 case 1:
14007 return CAM_WAVELET_DENOISE_CBCR_ONLY;
14008 case 2:
14009 return CAM_WAVELET_DENOISE_STREAMLINE_YCBCR;
14010 case 3:
14011 return CAM_WAVELET_DENOISE_STREAMLINED_CBCR;
14012 default:
14013 return CAM_WAVELET_DENOISE_STREAMLINE_YCBCR;
14014 }
14015}
14016
14017
14018/*===========================================================================
14019 * FUNCTION : getTemporalDenoiseProcessPlate
14020 *
14021 * DESCRIPTION: query temporal denoise process plate
14022 *
14023 * PARAMETERS : None
14024 *
14025 * RETURN : TNR prcocess plate value
14026 *==========================================================================*/
14027cam_denoise_process_type_t QCamera3HardwareInterface::getTemporalDenoiseProcessPlate()
14028{
14029 char prop[PROPERTY_VALUE_MAX];
14030 memset(prop, 0, sizeof(prop));
14031 property_get("persist.tnr.process.plates", prop, "0");
14032 int processPlate = atoi(prop);
14033 switch(processPlate) {
14034 case 0:
14035 return CAM_WAVELET_DENOISE_YCBCR_PLANE;
14036 case 1:
14037 return CAM_WAVELET_DENOISE_CBCR_ONLY;
14038 case 2:
14039 return CAM_WAVELET_DENOISE_STREAMLINE_YCBCR;
14040 case 3:
14041 return CAM_WAVELET_DENOISE_STREAMLINED_CBCR;
14042 default:
14043 return CAM_WAVELET_DENOISE_STREAMLINE_YCBCR;
14044 }
14045}
14046
14047
14048/*===========================================================================
14049 * FUNCTION : extractSceneMode
14050 *
14051 * DESCRIPTION: Extract scene mode from frameworks set metadata
14052 *
14053 * PARAMETERS :
14054 * @frame_settings: CameraMetadata reference
14055 * @metaMode: ANDROID_CONTORL_MODE
14056 * @hal_metadata: hal metadata structure
14057 *
14058 * RETURN : None
14059 *==========================================================================*/
14060int32_t QCamera3HardwareInterface::extractSceneMode(
14061 const CameraMetadata &frame_settings, uint8_t metaMode,
14062 metadata_buffer_t *hal_metadata)
14063{
14064 int32_t rc = NO_ERROR;
Mansoor Aftab58465fa2017-01-26 15:02:44 -080014065 uint8_t sceneMode = CAM_SCENE_MODE_OFF;
14066
14067 if (ANDROID_CONTROL_MODE_OFF_KEEP_STATE == metaMode) {
14068 LOGD("Ignoring control mode OFF_KEEP_STATE");
14069 return NO_ERROR;
14070 }
Thierry Strudel3d639192016-09-09 11:52:26 -070014071
14072 if (metaMode == ANDROID_CONTROL_MODE_USE_SCENE_MODE) {
14073 camera_metadata_ro_entry entry =
14074 frame_settings.find(ANDROID_CONTROL_SCENE_MODE);
14075 if (0 == entry.count)
14076 return rc;
14077
14078 uint8_t fwk_sceneMode = entry.data.u8[0];
14079
14080 int val = lookupHalName(SCENE_MODES_MAP,
14081 sizeof(SCENE_MODES_MAP)/sizeof(SCENE_MODES_MAP[0]),
14082 fwk_sceneMode);
14083 if (NAME_NOT_FOUND != val) {
Mansoor Aftab58465fa2017-01-26 15:02:44 -080014084 sceneMode = (uint8_t)val;
Thierry Strudel3d639192016-09-09 11:52:26 -070014085 LOGD("sceneMode: %d", sceneMode);
Thierry Strudel3d639192016-09-09 11:52:26 -070014086 }
Mansoor Aftab58465fa2017-01-26 15:02:44 -080014087 }
Thierry Strudele80ad7c2016-12-06 10:16:27 -080014088
Mansoor Aftab58465fa2017-01-26 15:02:44 -080014089 if ((sceneMode == CAM_SCENE_MODE_HDR) || m_bSensorHDREnabled) {
14090 rc = setSensorHDR(hal_metadata, (sceneMode == CAM_SCENE_MODE_HDR));
14091 }
14092
14093 if ((rc == NO_ERROR) && !m_bSensorHDREnabled) {
14094 if (sceneMode == ANDROID_CONTROL_SCENE_MODE_HDR) {
Thierry Strudele80ad7c2016-12-06 10:16:27 -080014095 cam_hdr_param_t hdr_params;
14096 hdr_params.hdr_enable = 1;
14097 hdr_params.hdr_mode = CAM_HDR_MODE_MULTIFRAME;
14098 hdr_params.hdr_need_1x = false;
14099 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata,
14100 CAM_INTF_PARM_HAL_BRACKETING_HDR, hdr_params)) {
14101 rc = BAD_VALUE;
14102 }
14103 }
Mansoor Aftab58465fa2017-01-26 15:02:44 -080014104
Thierry Strudel3d639192016-09-09 11:52:26 -070014105 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata,
14106 CAM_INTF_PARM_BESTSHOT_MODE, sceneMode)) {
14107 rc = BAD_VALUE;
14108 }
14109 }
Thierry Strudele80ad7c2016-12-06 10:16:27 -080014110
14111 if (mForceHdrSnapshot) {
14112 cam_hdr_param_t hdr_params;
14113 hdr_params.hdr_enable = 1;
14114 hdr_params.hdr_mode = CAM_HDR_MODE_MULTIFRAME;
14115 hdr_params.hdr_need_1x = false;
14116 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata,
14117 CAM_INTF_PARM_HAL_BRACKETING_HDR, hdr_params)) {
14118 rc = BAD_VALUE;
14119 }
14120 }
14121
Thierry Strudel3d639192016-09-09 11:52:26 -070014122 return rc;
14123}
14124
14125/*===========================================================================
Thierry Strudel04e026f2016-10-10 11:27:36 -070014126 * FUNCTION : setVideoHdrMode
14127 *
14128 * DESCRIPTION: Set Video HDR mode from frameworks set metadata
14129 *
14130 * PARAMETERS :
14131 * @hal_metadata: hal metadata structure
14132 * @metaMode: QCAMERA3_VIDEO_HDR_MODE
14133 *
14134 * RETURN : None
14135 *==========================================================================*/
14136int32_t QCamera3HardwareInterface::setVideoHdrMode(
14137 metadata_buffer_t *hal_metadata, cam_video_hdr_mode_t vhdr)
14138{
Mansoor Aftab58465fa2017-01-26 15:02:44 -080014139 if ( (vhdr >= CAM_VIDEO_HDR_MODE_OFF) && (vhdr < CAM_VIDEO_HDR_MODE_MAX)) {
14140 return setSensorHDR(hal_metadata, (vhdr == CAM_VIDEO_HDR_MODE_ON), true);
14141 }
14142
14143 LOGE("Invalid Video HDR mode %d!", vhdr);
14144 return BAD_VALUE;
14145}
14146
14147/*===========================================================================
14148 * FUNCTION : setSensorHDR
14149 *
14150 * DESCRIPTION: Enable/disable sensor HDR.
14151 *
14152 * PARAMETERS :
14153 * @hal_metadata: hal metadata structure
14154 * @enable: boolean whether to enable/disable sensor HDR
14155 *
14156 * RETURN : None
14157 *==========================================================================*/
14158int32_t QCamera3HardwareInterface::setSensorHDR(
14159 metadata_buffer_t *hal_metadata, bool enable, bool isVideoHdrEnable)
14160{
Thierry Strudel04e026f2016-10-10 11:27:36 -070014161 int32_t rc = NO_ERROR;
Mansoor Aftab58465fa2017-01-26 15:02:44 -080014162 cam_sensor_hdr_type_t sensor_hdr = CAM_SENSOR_HDR_OFF;
14163
14164 if (enable) {
14165 char sensor_hdr_prop[PROPERTY_VALUE_MAX];
14166 memset(sensor_hdr_prop, 0, sizeof(sensor_hdr_prop));
14167 #ifdef _LE_CAMERA_
14168 //Default to staggered HDR for IOT
14169 property_get("persist.camera.sensor.hdr", sensor_hdr_prop, "3");
14170 #else
14171 property_get("persist.camera.sensor.hdr", sensor_hdr_prop, "0");
14172 #endif
14173 sensor_hdr = (cam_sensor_hdr_type_t) atoi(sensor_hdr_prop);
14174 }
14175
14176 bool isSupported = false;
14177 switch (sensor_hdr) {
14178 case CAM_SENSOR_HDR_IN_SENSOR:
14179 if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
14180 CAM_QCOM_FEATURE_SENSOR_HDR) {
14181 isSupported = true;
Thierry Strudel04e026f2016-10-10 11:27:36 -070014182 LOGD("Setting HDR mode In Sensor");
Thierry Strudel04e026f2016-10-10 11:27:36 -070014183 }
Mansoor Aftab58465fa2017-01-26 15:02:44 -080014184 break;
14185 case CAM_SENSOR_HDR_ZIGZAG:
14186 if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
14187 CAM_QCOM_FEATURE_ZIGZAG_HDR) {
14188 isSupported = true;
Thierry Strudel04e026f2016-10-10 11:27:36 -070014189 LOGD("Setting HDR mode Zigzag");
Thierry Strudel04e026f2016-10-10 11:27:36 -070014190 }
Mansoor Aftab58465fa2017-01-26 15:02:44 -080014191 break;
14192 case CAM_SENSOR_HDR_STAGGERED:
14193 if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
14194 CAM_QCOM_FEATURE_STAGGERED_VIDEO_HDR) {
14195 isSupported = true;
Thierry Strudel04e026f2016-10-10 11:27:36 -070014196 LOGD("Setting HDR mode Staggered");
Thierry Strudel04e026f2016-10-10 11:27:36 -070014197 }
Mansoor Aftab58465fa2017-01-26 15:02:44 -080014198 break;
14199 case CAM_SENSOR_HDR_OFF:
14200 isSupported = true;
14201 LOGD("Turning off sensor HDR");
14202 break;
14203 default:
14204 LOGE("HDR mode %d not supported", sensor_hdr);
14205 rc = BAD_VALUE;
14206 break;
14207 }
14208
14209 if(isSupported) {
14210 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata,
14211 CAM_INTF_PARM_SENSOR_HDR, sensor_hdr)) {
14212 rc = BAD_VALUE;
14213 } else {
14214 if(!isVideoHdrEnable)
14215 m_bSensorHDREnabled = (sensor_hdr != CAM_SENSOR_HDR_OFF);
Thierry Strudel04e026f2016-10-10 11:27:36 -070014216 }
14217 }
14218 return rc;
14219}
14220
14221/*===========================================================================
Thierry Strudel3d639192016-09-09 11:52:26 -070014222 * FUNCTION : needRotationReprocess
14223 *
14224 * DESCRIPTION: if rotation needs to be done by reprocess in pp
14225 *
14226 * PARAMETERS : none
14227 *
14228 * RETURN : true: needed
14229 * false: no need
14230 *==========================================================================*/
14231bool QCamera3HardwareInterface::needRotationReprocess()
14232{
14233 if ((gCamCapability[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_ROTATION) > 0) {
14234 // current rotation is not zero, and pp has the capability to process rotation
14235 LOGH("need do reprocess for rotation");
14236 return true;
14237 }
14238
14239 return false;
14240}
14241
14242/*===========================================================================
14243 * FUNCTION : needReprocess
14244 *
14245 * DESCRIPTION: if reprocess in needed
14246 *
14247 * PARAMETERS : none
14248 *
14249 * RETURN : true: needed
14250 * false: no need
14251 *==========================================================================*/
14252bool QCamera3HardwareInterface::needReprocess(cam_feature_mask_t postprocess_mask)
14253{
14254 if (gCamCapability[mCameraId]->qcom_supported_feature_mask > 0) {
14255 // TODO: add for ZSL HDR later
14256 // pp module has min requirement for zsl reprocess, or WNR in ZSL mode
14257 if(postprocess_mask == CAM_QCOM_FEATURE_NONE){
14258 LOGH("need do reprocess for ZSL WNR or min PP reprocess");
14259 return true;
14260 } else {
14261 LOGH("already post processed frame");
14262 return false;
14263 }
14264 }
14265 return needRotationReprocess();
14266}
14267
14268/*===========================================================================
14269 * FUNCTION : needJpegExifRotation
14270 *
14271 * DESCRIPTION: if rotation from jpeg is needed
14272 *
14273 * PARAMETERS : none
14274 *
14275 * RETURN : true: needed
14276 * false: no need
14277 *==========================================================================*/
14278bool QCamera3HardwareInterface::needJpegExifRotation()
14279{
Thierry Strudele80ad7c2016-12-06 10:16:27 -080014280 /*If the pp does not have the ability to do rotation, enable jpeg rotation*/
Thierry Strudel3d639192016-09-09 11:52:26 -070014281 if (!(gCamCapability[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_ROTATION)) {
14282 LOGD("Need use Jpeg EXIF Rotation");
14283 return true;
14284 }
14285 return false;
14286}
14287
14288/*===========================================================================
14289 * FUNCTION : addOfflineReprocChannel
14290 *
14291 * DESCRIPTION: add a reprocess channel that will do reprocess on frames
14292 * coming from input channel
14293 *
14294 * PARAMETERS :
14295 * @config : reprocess configuration
14296 * @inputChHandle : pointer to the input (source) channel
14297 *
14298 *
14299 * RETURN : Ptr to the newly created channel obj. NULL if failed.
14300 *==========================================================================*/
14301QCamera3ReprocessChannel *QCamera3HardwareInterface::addOfflineReprocChannel(
14302 const reprocess_config_t &config, QCamera3ProcessingChannel *inputChHandle)
14303{
14304 int32_t rc = NO_ERROR;
14305 QCamera3ReprocessChannel *pChannel = NULL;
14306
14307 pChannel = new QCamera3ReprocessChannel(mCameraHandle->camera_handle,
Thierry Strudelc2ee3302016-11-17 12:33:12 -080014308 mChannelHandle, mCameraHandle->ops, captureResultCb, setBufferErrorStatus,
14309 config.padding, CAM_QCOM_FEATURE_NONE, this, inputChHandle);
Thierry Strudel3d639192016-09-09 11:52:26 -070014310 if (NULL == pChannel) {
14311 LOGE("no mem for reprocess channel");
14312 return NULL;
14313 }
14314
14315 rc = pChannel->initialize(IS_TYPE_NONE);
14316 if (rc != NO_ERROR) {
14317 LOGE("init reprocess channel failed, ret = %d", rc);
14318 delete pChannel;
14319 return NULL;
14320 }
14321
14322 // pp feature config
14323 cam_pp_feature_config_t pp_config;
14324 memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
14325
14326 pp_config.feature_mask |= CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
14327 if (gCamCapability[mCameraId]->qcom_supported_feature_mask
14328 & CAM_QCOM_FEATURE_DSDN) {
14329 //Use CPP CDS incase h/w supports it.
14330 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CDS;
14331 pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN;
14332 }
14333 if (!(gCamCapability[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_ROTATION)) {
14334 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_ROTATION;
14335 }
14336
Thierry Strudele80ad7c2016-12-06 10:16:27 -080014337 if (config.hdr_param.hdr_enable) {
14338 pp_config.feature_mask |= CAM_QCOM_FEATURE_HDR;
14339 pp_config.hdr_param = config.hdr_param;
14340 }
14341
14342 if (mForceHdrSnapshot) {
14343 pp_config.feature_mask |= CAM_QCOM_FEATURE_HDR;
14344 pp_config.hdr_param.hdr_enable = 1;
14345 pp_config.hdr_param.hdr_need_1x = 0;
14346 pp_config.hdr_param.hdr_mode = CAM_HDR_MODE_MULTIFRAME;
14347 }
14348
Thierry Strudel3d639192016-09-09 11:52:26 -070014349 rc = pChannel->addReprocStreamsFromSource(pp_config,
14350 config,
14351 IS_TYPE_NONE,
14352 mMetadataChannel);
14353
14354 if (rc != NO_ERROR) {
14355 delete pChannel;
14356 return NULL;
14357 }
14358 return pChannel;
14359}
14360
14361/*===========================================================================
14362 * FUNCTION : getMobicatMask
14363 *
14364 * DESCRIPTION: returns mobicat mask
14365 *
14366 * PARAMETERS : none
14367 *
14368 * RETURN : mobicat mask
14369 *
14370 *==========================================================================*/
14371uint8_t QCamera3HardwareInterface::getMobicatMask()
14372{
14373 return m_MobicatMask;
14374}
14375
14376/*===========================================================================
14377 * FUNCTION : setMobicat
14378 *
14379 * DESCRIPTION: set Mobicat on/off.
14380 *
14381 * PARAMETERS :
14382 * @params : none
14383 *
14384 * RETURN : int32_t type of status
14385 * NO_ERROR -- success
14386 * none-zero failure code
14387 *==========================================================================*/
14388int32_t QCamera3HardwareInterface::setMobicat()
14389{
Thierry Strudel3d639192016-09-09 11:52:26 -070014390 int32_t ret = NO_ERROR;
Thierry Strudel3d639192016-09-09 11:52:26 -070014391
Shuzhen Wangb57ec912017-07-31 13:24:27 -070014392 if (m_MobicatMask) {
Thierry Strudel3d639192016-09-09 11:52:26 -070014393 tune_cmd_t tune_cmd;
14394 tune_cmd.type = SET_RELOAD_CHROMATIX;
14395 tune_cmd.module = MODULE_ALL;
14396 tune_cmd.value = TRUE;
14397 ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters,
14398 CAM_INTF_PARM_SET_VFE_COMMAND,
14399 tune_cmd);
14400
14401 ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters,
14402 CAM_INTF_PARM_SET_PP_COMMAND,
14403 tune_cmd);
14404 }
Thierry Strudel3d639192016-09-09 11:52:26 -070014405
14406 return ret;
14407}
14408
14409/*===========================================================================
14410* FUNCTION : getLogLevel
14411*
14412* DESCRIPTION: Reads the log level property into a variable
14413*
14414* PARAMETERS :
14415* None
14416*
14417* RETURN :
14418* None
14419*==========================================================================*/
14420void QCamera3HardwareInterface::getLogLevel()
14421{
14422 char prop[PROPERTY_VALUE_MAX];
14423 uint32_t globalLogLevel = 0;
14424
14425 property_get("persist.camera.hal.debug", prop, "0");
14426 int val = atoi(prop);
14427 if (0 <= val) {
14428 gCamHal3LogLevel = (uint32_t)val;
14429 }
14430
Thierry Strudel9ec39c62016-12-28 11:30:05 -080014431 property_get("persist.camera.kpi.debug", prop, "0");
Thierry Strudel3d639192016-09-09 11:52:26 -070014432 gKpiDebugLevel = atoi(prop);
14433
14434 property_get("persist.camera.global.debug", prop, "0");
14435 val = atoi(prop);
14436 if (0 <= val) {
14437 globalLogLevel = (uint32_t)val;
14438 }
14439
14440 /* Highest log level among hal.logs and global.logs is selected */
14441 if (gCamHal3LogLevel < globalLogLevel)
14442 gCamHal3LogLevel = globalLogLevel;
14443
14444 return;
14445}
14446
14447/*===========================================================================
14448 * FUNCTION : validateStreamRotations
14449 *
14450 * DESCRIPTION: Check if the rotations requested are supported
14451 *
14452 * PARAMETERS :
14453 * @stream_list : streams to be configured
14454 *
14455 * RETURN : NO_ERROR on success
14456 * -EINVAL on failure
14457 *
14458 *==========================================================================*/
14459int QCamera3HardwareInterface::validateStreamRotations(
14460 camera3_stream_configuration_t *streamList)
14461{
14462 int rc = NO_ERROR;
14463
14464 /*
14465 * Loop through all streams requested in configuration
14466 * Check if unsupported rotations have been requested on any of them
14467 */
14468 for (size_t j = 0; j < streamList->num_streams; j++){
14469 camera3_stream_t *newStream = streamList->streams[j];
14470
Emilian Peev35ceeed2017-06-29 11:58:56 -070014471 switch(newStream->rotation) {
14472 case CAMERA3_STREAM_ROTATION_0:
14473 case CAMERA3_STREAM_ROTATION_90:
14474 case CAMERA3_STREAM_ROTATION_180:
14475 case CAMERA3_STREAM_ROTATION_270:
14476 //Expected values
14477 break;
14478 default:
14479 ALOGE("%s: Error: Unsupported rotation of %d requested for stream"
14480 "type:%d and stream format:%d", __func__,
14481 newStream->rotation, newStream->stream_type,
14482 newStream->format);
14483 return -EINVAL;
14484 }
14485
Thierry Strudel3d639192016-09-09 11:52:26 -070014486 bool isRotated = (newStream->rotation != CAMERA3_STREAM_ROTATION_0);
14487 bool isImplDef = (newStream->format ==
14488 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
14489 bool isZsl = (newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL &&
14490 isImplDef);
14491
14492 if (isRotated && (!isImplDef || isZsl)) {
14493 LOGE("Error: Unsupported rotation of %d requested for stream"
14494 "type:%d and stream format:%d",
14495 newStream->rotation, newStream->stream_type,
14496 newStream->format);
14497 rc = -EINVAL;
14498 break;
14499 }
14500 }
14501
14502 return rc;
14503}
14504
14505/*===========================================================================
14506* FUNCTION : getFlashInfo
14507*
14508* DESCRIPTION: Retrieve information about whether the device has a flash.
14509*
14510* PARAMETERS :
14511* @cameraId : Camera id to query
14512* @hasFlash : Boolean indicating whether there is a flash device
14513* associated with given camera
14514* @flashNode : If a flash device exists, this will be its device node.
14515*
14516* RETURN :
14517* None
14518*==========================================================================*/
14519void QCamera3HardwareInterface::getFlashInfo(const int cameraId,
14520 bool& hasFlash,
14521 char (&flashNode)[QCAMERA_MAX_FILEPATH_LENGTH])
14522{
14523 cam_capability_t* camCapability = gCamCapability[cameraId];
14524 if (NULL == camCapability) {
14525 hasFlash = false;
14526 flashNode[0] = '\0';
14527 } else {
14528 hasFlash = camCapability->flash_available;
14529 strlcpy(flashNode,
14530 (char*)camCapability->flash_dev_name,
14531 QCAMERA_MAX_FILEPATH_LENGTH);
14532 }
14533}
14534
14535/*===========================================================================
14536* FUNCTION : getEepromVersionInfo
14537*
14538* DESCRIPTION: Retrieve version info of the sensor EEPROM data
14539*
14540* PARAMETERS : None
14541*
14542* RETURN : string describing EEPROM version
14543* "\0" if no such info available
14544*==========================================================================*/
14545const char *QCamera3HardwareInterface::getEepromVersionInfo()
14546{
14547 return (const char *)&gCamCapability[mCameraId]->eeprom_version_info[0];
14548}
14549
14550/*===========================================================================
14551* FUNCTION : getLdafCalib
14552*
14553* DESCRIPTION: Retrieve Laser AF calibration data
14554*
14555* PARAMETERS : None
14556*
14557* RETURN : Two uint32_t describing laser AF calibration data
14558* NULL if none is available.
14559*==========================================================================*/
14560const uint32_t *QCamera3HardwareInterface::getLdafCalib()
14561{
14562 if (mLdafCalibExist) {
14563 return &mLdafCalib[0];
14564 } else {
14565 return NULL;
14566 }
14567}
14568
14569/*===========================================================================
Arnd Geis082a4d72017-08-24 10:33:07 -070014570* FUNCTION : getEaselFwVersion
14571*
14572* DESCRIPTION: Retrieve Easel firmware version
14573*
14574* PARAMETERS : None
14575*
14576* RETURN : string describing Firmware version
Arnd Geis8cbfc182017-09-07 14:46:41 -070014577* "\0" if version is not up to date
Arnd Geis082a4d72017-08-24 10:33:07 -070014578*==========================================================================*/
14579const char *QCamera3HardwareInterface::getEaselFwVersion()
14580{
Arnd Geis8cbfc182017-09-07 14:46:41 -070014581 if (mEaselFwUpdated) {
14582 return (const char *)&mEaselFwVersion[0];
14583 } else {
14584 return NULL;
Arnd Geis082a4d72017-08-24 10:33:07 -070014585 }
Arnd Geis082a4d72017-08-24 10:33:07 -070014586}
14587
14588/*===========================================================================
Thierry Strudel3d639192016-09-09 11:52:26 -070014589 * FUNCTION : dynamicUpdateMetaStreamInfo
14590 *
14591 * DESCRIPTION: This function:
14592 * (1) stops all the channels
14593 * (2) returns error on pending requests and buffers
14594 * (3) sends metastream_info in setparams
14595 * (4) starts all channels
14596 * This is useful when sensor has to be restarted to apply any
14597 * settings such as frame rate from a different sensor mode
14598 *
14599 * PARAMETERS : None
14600 *
14601 * RETURN : NO_ERROR on success
14602 * Error codes on failure
14603 *
14604 *==========================================================================*/
14605int32_t QCamera3HardwareInterface::dynamicUpdateMetaStreamInfo()
14606{
Thierry Strudele80ad7c2016-12-06 10:16:27 -080014607 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL3_DYN_UPDATE_META_STRM_INFO);
Thierry Strudel3d639192016-09-09 11:52:26 -070014608 int rc = NO_ERROR;
14609
14610 LOGD("E");
14611
14612 rc = stopAllChannels();
14613 if (rc < 0) {
14614 LOGE("stopAllChannels failed");
14615 return rc;
14616 }
14617
14618 rc = notifyErrorForPendingRequests();
14619 if (rc < 0) {
14620 LOGE("notifyErrorForPendingRequests failed");
14621 return rc;
14622 }
14623
14624 for (uint32_t i = 0; i < mStreamConfigInfo.num_streams; i++) {
14625 LOGI("STREAM INFO : type %d, wxh: %d x %d, pp_mask: 0x%x"
14626 "Format:%d",
14627 mStreamConfigInfo.type[i],
14628 mStreamConfigInfo.stream_sizes[i].width,
14629 mStreamConfigInfo.stream_sizes[i].height,
14630 mStreamConfigInfo.postprocess_mask[i],
14631 mStreamConfigInfo.format[i]);
14632 }
14633
14634 /* Send meta stream info once again so that ISP can start */
14635 ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters,
14636 CAM_INTF_META_STREAM_INFO, mStreamConfigInfo);
14637 rc = mCameraHandle->ops->set_parms(mCameraHandle->camera_handle,
14638 mParameters);
14639 if (rc < 0) {
14640 LOGE("set Metastreaminfo failed. Sensor mode does not change");
14641 }
14642
14643 rc = startAllChannels();
14644 if (rc < 0) {
14645 LOGE("startAllChannels failed");
14646 return rc;
14647 }
14648
14649 LOGD("X");
14650 return rc;
14651}
14652
14653/*===========================================================================
14654 * FUNCTION : stopAllChannels
14655 *
14656 * DESCRIPTION: This function stops (equivalent to stream-off) all channels
14657 *
14658 * PARAMETERS : None
14659 *
14660 * RETURN : NO_ERROR on success
14661 * Error codes on failure
14662 *
14663 *==========================================================================*/
14664int32_t QCamera3HardwareInterface::stopAllChannels()
14665{
14666 int32_t rc = NO_ERROR;
14667
14668 LOGD("Stopping all channels");
14669 // Stop the Streams/Channels
14670 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
14671 it != mStreamInfo.end(); it++) {
14672 QCamera3Channel *channel = (QCamera3Channel *)(*it)->stream->priv;
14673 if (channel) {
14674 channel->stop();
14675 }
14676 (*it)->status = INVALID;
14677 }
14678
14679 if (mSupportChannel) {
14680 mSupportChannel->stop();
14681 }
14682 if (mAnalysisChannel) {
14683 mAnalysisChannel->stop();
14684 }
14685 if (mRawDumpChannel) {
14686 mRawDumpChannel->stop();
14687 }
Chien-Yu Chen8e599492016-11-01 13:37:46 -070014688 if (mHdrPlusRawSrcChannel) {
14689 mHdrPlusRawSrcChannel->stop();
14690 }
Thierry Strudel3d639192016-09-09 11:52:26 -070014691 if (mMetadataChannel) {
14692 /* If content of mStreamInfo is not 0, there is metadata stream */
14693 mMetadataChannel->stop();
14694 }
14695
14696 LOGD("All channels stopped");
14697 return rc;
14698}
14699
14700/*===========================================================================
14701 * FUNCTION : startAllChannels
14702 *
14703 * DESCRIPTION: This function starts (equivalent to stream-on) all channels
14704 *
14705 * PARAMETERS : None
14706 *
14707 * RETURN : NO_ERROR on success
14708 * Error codes on failure
14709 *
14710 *==========================================================================*/
14711int32_t QCamera3HardwareInterface::startAllChannels()
14712{
14713 int32_t rc = NO_ERROR;
14714
14715 LOGD("Start all channels ");
14716 // Start the Streams/Channels
14717 if (mMetadataChannel) {
14718 /* If content of mStreamInfo is not 0, there is metadata stream */
14719 rc = mMetadataChannel->start();
14720 if (rc < 0) {
14721 LOGE("META channel start failed");
14722 return rc;
14723 }
14724 }
14725 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
14726 it != mStreamInfo.end(); it++) {
14727 QCamera3Channel *channel = (QCamera3Channel *)(*it)->stream->priv;
14728 if (channel) {
14729 rc = channel->start();
14730 if (rc < 0) {
14731 LOGE("channel start failed");
14732 return rc;
14733 }
14734 }
14735 }
14736 if (mAnalysisChannel) {
14737 mAnalysisChannel->start();
14738 }
14739 if (mSupportChannel) {
14740 rc = mSupportChannel->start();
14741 if (rc < 0) {
14742 LOGE("Support channel start failed");
14743 return rc;
14744 }
14745 }
14746 if (mRawDumpChannel) {
14747 rc = mRawDumpChannel->start();
14748 if (rc < 0) {
14749 LOGE("RAW dump channel start failed");
14750 return rc;
14751 }
14752 }
Chien-Yu Chen8e599492016-11-01 13:37:46 -070014753 if (mHdrPlusRawSrcChannel) {
14754 rc = mHdrPlusRawSrcChannel->start();
14755 if (rc < 0) {
14756 LOGE("HDR+ RAW channel start failed");
14757 return rc;
14758 }
14759 }
Thierry Strudel3d639192016-09-09 11:52:26 -070014760
14761 LOGD("All channels started");
14762 return rc;
14763}
14764
14765/*===========================================================================
14766 * FUNCTION : notifyErrorForPendingRequests
14767 *
14768 * DESCRIPTION: This function sends error for all the pending requests/buffers
14769 *
14770 * PARAMETERS : None
14771 *
14772 * RETURN : Error codes
14773 * NO_ERROR on success
14774 *
14775 *==========================================================================*/
14776int32_t QCamera3HardwareInterface::notifyErrorForPendingRequests()
14777{
Emilian Peev7650c122017-01-19 08:24:33 -080014778 notifyErrorFoPendingDepthData(mDepthChannel);
14779
Chien-Yu Chen3f303522017-05-19 15:21:45 -070014780 auto pendingRequest = mPendingRequestsList.begin();
14781 auto pendingBuffer = mPendingBuffersMap.mPendingBuffersInRequest.begin();
Thierry Strudel3d639192016-09-09 11:52:26 -070014782
Chien-Yu Chen3f303522017-05-19 15:21:45 -070014783 // Iterate through pending requests (for which result metadata isn't sent yet) and pending
14784 // buffers (for which buffers aren't sent yet).
14785 while (pendingRequest != mPendingRequestsList.end() ||
14786 pendingBuffer != mPendingBuffersMap.mPendingBuffersInRequest.end()) {
14787 if (pendingRequest == mPendingRequestsList.end() ||
14788 pendingBuffer->frame_number < pendingRequest->frame_number) {
14789 // If metadata for this frame was sent, notify about a buffer error and returns buffers
14790 // with error.
14791 for (auto &info : pendingBuffer->mPendingBufferList) {
14792 // Send a buffer error for this frame number.
Thierry Strudel3d639192016-09-09 11:52:26 -070014793 camera3_notify_msg_t notify_msg;
14794 memset(&notify_msg, 0, sizeof(camera3_notify_msg_t));
14795 notify_msg.type = CAMERA3_MSG_ERROR;
14796 notify_msg.message.error.error_code = CAMERA3_MSG_ERROR_BUFFER;
Chien-Yu Chen3f303522017-05-19 15:21:45 -070014797 notify_msg.message.error.error_stream = info.stream;
14798 notify_msg.message.error.frame_number = pendingBuffer->frame_number;
Thierry Strudele80ad7c2016-12-06 10:16:27 -080014799 orchestrateNotify(&notify_msg);
Chien-Yu Chen3f303522017-05-19 15:21:45 -070014800
14801 camera3_stream_buffer_t buffer = {};
14802 buffer.acquire_fence = -1;
14803 buffer.release_fence = -1;
14804 buffer.buffer = info.buffer;
14805 buffer.status = CAMERA3_BUFFER_STATUS_ERROR;
14806 buffer.stream = info.stream;
14807 mOutputBufferDispatcher.markBufferReady(pendingBuffer->frame_number, buffer);
Thierry Strudel3d639192016-09-09 11:52:26 -070014808 }
14809
Chien-Yu Chen3f303522017-05-19 15:21:45 -070014810 pendingBuffer = mPendingBuffersMap.mPendingBuffersInRequest.erase(pendingBuffer);
14811 } else if (pendingBuffer == mPendingBuffersMap.mPendingBuffersInRequest.end() ||
14812 pendingBuffer->frame_number > pendingRequest->frame_number) {
14813 // If the buffers for this frame were sent already, notify about a result error.
Thierry Strudel3d639192016-09-09 11:52:26 -070014814 camera3_notify_msg_t notify_msg;
14815 memset(&notify_msg, 0, sizeof(camera3_notify_msg_t));
14816 notify_msg.type = CAMERA3_MSG_ERROR;
Chien-Yu Chen3f303522017-05-19 15:21:45 -070014817 notify_msg.message.error.error_code = CAMERA3_MSG_ERROR_RESULT;
14818 notify_msg.message.error.error_stream = nullptr;
14819 notify_msg.message.error.frame_number = pendingRequest->frame_number;
Thierry Strudele80ad7c2016-12-06 10:16:27 -080014820 orchestrateNotify(&notify_msg);
Thierry Strudel3d639192016-09-09 11:52:26 -070014821
Chien-Yu Chen3f303522017-05-19 15:21:45 -070014822 if (pendingRequest->input_buffer != nullptr) {
14823 camera3_capture_result result = {};
14824 result.frame_number = pendingRequest->frame_number;
14825 result.result = nullptr;
14826 result.input_buffer = pendingRequest->input_buffer;
14827 orchestrateResult(&result);
Thierry Strudel3d639192016-09-09 11:52:26 -070014828 }
14829
Chien-Yu Chen3f303522017-05-19 15:21:45 -070014830 mShutterDispatcher.clear(pendingRequest->frame_number);
14831 pendingRequest = mPendingRequestsList.erase(pendingRequest);
14832 } else {
14833 // If both buffers and result metadata weren't sent yet, notify about a request error
14834 // and return buffers with error.
14835 for (auto &info : pendingBuffer->mPendingBufferList) {
14836 camera3_notify_msg_t notify_msg;
14837 memset(&notify_msg, 0, sizeof(camera3_notify_msg_t));
14838 notify_msg.type = CAMERA3_MSG_ERROR;
14839 notify_msg.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
14840 notify_msg.message.error.error_stream = info.stream;
14841 notify_msg.message.error.frame_number = pendingBuffer->frame_number;
14842 orchestrateNotify(&notify_msg);
Thierry Strudel3d639192016-09-09 11:52:26 -070014843
Chien-Yu Chen3f303522017-05-19 15:21:45 -070014844 camera3_stream_buffer_t buffer = {};
14845 buffer.acquire_fence = -1;
14846 buffer.release_fence = -1;
14847 buffer.buffer = info.buffer;
14848 buffer.status = CAMERA3_BUFFER_STATUS_ERROR;
14849 buffer.stream = info.stream;
14850 mOutputBufferDispatcher.markBufferReady(pendingBuffer->frame_number, buffer);
14851 }
14852
14853 if (pendingRequest->input_buffer != nullptr) {
14854 camera3_capture_result result = {};
14855 result.frame_number = pendingRequest->frame_number;
14856 result.result = nullptr;
14857 result.input_buffer = pendingRequest->input_buffer;
14858 orchestrateResult(&result);
14859 }
14860
14861 mShutterDispatcher.clear(pendingRequest->frame_number);
14862 pendingBuffer = mPendingBuffersMap.mPendingBuffersInRequest.erase(pendingBuffer);
14863 pendingRequest = mPendingRequestsList.erase(pendingRequest);
Thierry Strudel3d639192016-09-09 11:52:26 -070014864 }
14865 }
14866
14867 /* Reset pending frame Drop list and requests list */
14868 mPendingFrameDropList.clear();
Chien-Yu Chen3f303522017-05-19 15:21:45 -070014869 mShutterDispatcher.clear();
14870 mOutputBufferDispatcher.clear(/*clearConfiguredStreams*/false);
Thierry Strudel3d639192016-09-09 11:52:26 -070014871 mPendingBuffersMap.mPendingBuffersInRequest.clear();
Emilian Peev30522a12017-08-03 14:36:33 +010014872 mExpectedFrameDuration = 0;
14873 mExpectedInflightDuration = 0;
Thierry Strudel3d639192016-09-09 11:52:26 -070014874 LOGH("Cleared all the pending buffers ");
14875
Chien-Yu Chen3f303522017-05-19 15:21:45 -070014876 return NO_ERROR;
Thierry Strudel3d639192016-09-09 11:52:26 -070014877}
14878
14879bool QCamera3HardwareInterface::isOnEncoder(
14880 const cam_dimension_t max_viewfinder_size,
14881 uint32_t width, uint32_t height)
14882{
Thierry Strudele80ad7c2016-12-06 10:16:27 -080014883 return ((width > (uint32_t)max_viewfinder_size.width) ||
14884 (height > (uint32_t)max_viewfinder_size.height) ||
14885 (width > (uint32_t)VIDEO_4K_WIDTH) ||
14886 (height > (uint32_t)VIDEO_4K_HEIGHT));
Thierry Strudel3d639192016-09-09 11:52:26 -070014887}
14888
14889/*===========================================================================
14890 * FUNCTION : setBundleInfo
14891 *
14892 * DESCRIPTION: Set bundle info for all streams that are bundle.
14893 *
14894 * PARAMETERS : None
14895 *
14896 * RETURN : NO_ERROR on success
14897 * Error codes on failure
14898 *==========================================================================*/
14899int32_t QCamera3HardwareInterface::setBundleInfo()
14900{
14901 int32_t rc = NO_ERROR;
14902
14903 if (mChannelHandle) {
14904 cam_bundle_config_t bundleInfo;
14905 memset(&bundleInfo, 0, sizeof(bundleInfo));
14906 rc = mCameraHandle->ops->get_bundle_info(
14907 mCameraHandle->camera_handle, mChannelHandle, &bundleInfo);
14908 if (rc != NO_ERROR) {
14909 LOGE("get_bundle_info failed");
14910 return rc;
14911 }
14912 if (mAnalysisChannel) {
14913 mAnalysisChannel->setBundleInfo(bundleInfo);
14914 }
14915 if (mSupportChannel) {
14916 mSupportChannel->setBundleInfo(bundleInfo);
14917 }
14918 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
14919 it != mStreamInfo.end(); it++) {
14920 QCamera3Channel *channel = (QCamera3Channel *)(*it)->stream->priv;
14921 channel->setBundleInfo(bundleInfo);
14922 }
14923 if (mRawDumpChannel) {
14924 mRawDumpChannel->setBundleInfo(bundleInfo);
14925 }
Chien-Yu Chen8e599492016-11-01 13:37:46 -070014926 if (mHdrPlusRawSrcChannel) {
14927 mHdrPlusRawSrcChannel->setBundleInfo(bundleInfo);
14928 }
Thierry Strudel3d639192016-09-09 11:52:26 -070014929 }
14930
14931 return rc;
14932}
14933
14934/*===========================================================================
Thierry Strudel295a0ca2016-11-03 18:38:47 -070014935 * FUNCTION : setInstantAEC
14936 *
14937 * DESCRIPTION: Set Instant AEC related params.
14938 *
14939 * PARAMETERS :
14940 * @meta: CameraMetadata reference
14941 *
14942 * RETURN : NO_ERROR on success
14943 * Error codes on failure
14944 *==========================================================================*/
14945int32_t QCamera3HardwareInterface::setInstantAEC(const CameraMetadata &meta)
14946{
14947 int32_t rc = NO_ERROR;
14948 uint8_t val = 0;
14949 char prop[PROPERTY_VALUE_MAX];
14950
14951 // First try to configure instant AEC from framework metadata
14952 if (meta.exists(QCAMERA3_INSTANT_AEC_MODE)) {
Emilian Peev6d4cdc22017-11-16 16:56:23 +000014953 val = meta.find(QCAMERA3_INSTANT_AEC_MODE).data.u8[0];
14954 LOGE("Instant AEC mode set: %d", val);
Thierry Strudel295a0ca2016-11-03 18:38:47 -070014955 }
14956
14957 // If framework did not set this value, try to read from set prop.
14958 if (val == 0) {
14959 memset(prop, 0, sizeof(prop));
14960 property_get("persist.camera.instant.aec", prop, "0");
14961 val = (uint8_t)atoi(prop);
14962 }
14963
14964 if ((val >= (uint8_t)CAM_AEC_NORMAL_CONVERGENCE) &&
14965 ( val < (uint8_t)CAM_AEC_CONVERGENCE_MAX)) {
14966 ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_PARM_INSTANT_AEC, val);
14967 mInstantAEC = val;
14968 mInstantAECSettledFrameNumber = 0;
14969 mInstantAecFrameIdxCount = 0;
14970 LOGH("instantAEC value set %d",val);
14971 if (mInstantAEC) {
14972 memset(prop, 0, sizeof(prop));
14973 property_get("persist.camera.ae.instant.bound", prop, "10");
14974 int32_t aec_frame_skip_cnt = atoi(prop);
14975 if (aec_frame_skip_cnt >= 0) {
14976 mAecSkipDisplayFrameBound = (uint8_t)aec_frame_skip_cnt;
14977 } else {
14978 LOGE("Invalid prop for aec frame bound %d", aec_frame_skip_cnt);
14979 rc = BAD_VALUE;
14980 }
14981 }
14982 } else {
14983 LOGE("Bad instant aec value set %d", val);
14984 rc = BAD_VALUE;
14985 }
14986 return rc;
14987}
14988
14989/*===========================================================================
Thierry Strudel3d639192016-09-09 11:52:26 -070014990 * FUNCTION : get_num_overall_buffers
14991 *
14992 * DESCRIPTION: Estimate number of pending buffers across all requests.
14993 *
14994 * PARAMETERS : None
14995 *
14996 * RETURN : Number of overall pending buffers
14997 *
14998 *==========================================================================*/
14999uint32_t PendingBuffersMap::get_num_overall_buffers()
15000{
15001 uint32_t sum_buffers = 0;
15002 for (auto &req : mPendingBuffersInRequest) {
15003 sum_buffers += req.mPendingBufferList.size();
15004 }
15005 return sum_buffers;
15006}
15007
15008/*===========================================================================
15009 * FUNCTION : removeBuf
15010 *
15011 * DESCRIPTION: Remove a matching buffer from tracker.
15012 *
15013 * PARAMETERS : @buffer: image buffer for the callback
15014 *
15015 * RETURN : None
15016 *
15017 *==========================================================================*/
15018void PendingBuffersMap::removeBuf(buffer_handle_t *buffer)
15019{
15020 bool buffer_found = false;
15021 for (auto req = mPendingBuffersInRequest.begin();
15022 req != mPendingBuffersInRequest.end(); req++) {
15023 for (auto k = req->mPendingBufferList.begin();
15024 k != req->mPendingBufferList.end(); k++ ) {
15025 if (k->buffer == buffer) {
15026 LOGD("Frame %d: Found Frame buffer %p, take it out from mPendingBufferList",
15027 req->frame_number, buffer);
15028 k = req->mPendingBufferList.erase(k);
15029 if (req->mPendingBufferList.empty()) {
15030 // Remove this request from Map
15031 req = mPendingBuffersInRequest.erase(req);
15032 }
15033 buffer_found = true;
15034 break;
15035 }
15036 }
15037 if (buffer_found) {
15038 break;
15039 }
15040 }
15041 LOGD("mPendingBuffersMap.num_overall_buffers = %d",
15042 get_num_overall_buffers());
15043}
15044
15045/*===========================================================================
Thierry Strudelc2ee3302016-11-17 12:33:12 -080015046 * FUNCTION : getBufErrStatus
15047 *
15048 * DESCRIPTION: get buffer error status
15049 *
15050 * PARAMETERS : @buffer: buffer handle
15051 *
15052 * RETURN : Error status
15053 *
15054 *==========================================================================*/
15055int32_t PendingBuffersMap::getBufErrStatus(buffer_handle_t *buffer)
15056{
15057 for (auto& req : mPendingBuffersInRequest) {
15058 for (auto& k : req.mPendingBufferList) {
15059 if (k.buffer == buffer)
15060 return k.bufStatus;
15061 }
15062 }
15063 return CAMERA3_BUFFER_STATUS_OK;
15064}
15065
15066/*===========================================================================
Thierry Strudel3d639192016-09-09 11:52:26 -070015067 * FUNCTION : setPAAFSupport
15068 *
15069 * DESCRIPTION: Set the preview-assisted auto focus support bit in
15070 * feature mask according to stream type and filter
15071 * arrangement
15072 *
15073 * PARAMETERS : @feature_mask: current feature mask, which may be modified
15074 * @stream_type: stream type
15075 * @filter_arrangement: filter arrangement
15076 *
15077 * RETURN : None
15078 *==========================================================================*/
15079void QCamera3HardwareInterface::setPAAFSupport(
15080 cam_feature_mask_t& feature_mask,
15081 cam_stream_type_t stream_type,
15082 cam_color_filter_arrangement_t filter_arrangement)
15083{
Thierry Strudel3d639192016-09-09 11:52:26 -070015084 switch (filter_arrangement) {
15085 case CAM_FILTER_ARRANGEMENT_RGGB:
15086 case CAM_FILTER_ARRANGEMENT_GRBG:
15087 case CAM_FILTER_ARRANGEMENT_GBRG:
15088 case CAM_FILTER_ARRANGEMENT_BGGR:
Thierry Strudele80ad7c2016-12-06 10:16:27 -080015089 if ((stream_type == CAM_STREAM_TYPE_PREVIEW) ||
15090 (stream_type == CAM_STREAM_TYPE_ANALYSIS) ||
Thierry Strudel3d639192016-09-09 11:52:26 -070015091 (stream_type == CAM_STREAM_TYPE_VIDEO)) {
Thierry Strudel2896d122017-02-23 19:18:03 -080015092 if (!(feature_mask & CAM_QTI_FEATURE_PPEISCORE))
15093 feature_mask |= CAM_QCOM_FEATURE_PAAF;
Thierry Strudel3d639192016-09-09 11:52:26 -070015094 }
15095 break;
15096 case CAM_FILTER_ARRANGEMENT_Y:
15097 if (stream_type == CAM_STREAM_TYPE_ANALYSIS) {
15098 feature_mask |= CAM_QCOM_FEATURE_PAAF;
15099 }
15100 break;
15101 default:
15102 break;
15103 }
Shuzhen Wang3b457d92016-08-03 08:46:59 -070015104 LOGD("feature_mask=0x%llx; stream_type=%d, filter_arrangement=%d",
15105 feature_mask, stream_type, filter_arrangement);
15106
15107
Thierry Strudel3d639192016-09-09 11:52:26 -070015108}
15109
15110/*===========================================================================
15111* FUNCTION : getSensorMountAngle
15112*
15113* DESCRIPTION: Retrieve sensor mount angle
15114*
15115* PARAMETERS : None
15116*
15117* RETURN : sensor mount angle in uint32_t
15118*==========================================================================*/
15119uint32_t QCamera3HardwareInterface::getSensorMountAngle()
15120{
15121 return gCamCapability[mCameraId]->sensor_mount_angle;
15122}
15123
15124/*===========================================================================
15125* FUNCTION : getRelatedCalibrationData
15126*
15127* DESCRIPTION: Retrieve related system calibration data
15128*
15129* PARAMETERS : None
15130*
15131* RETURN : Pointer of related system calibration data
15132*==========================================================================*/
15133const cam_related_system_calibration_data_t *QCamera3HardwareInterface::getRelatedCalibrationData()
15134{
15135 return (const cam_related_system_calibration_data_t *)
15136 &(gCamCapability[mCameraId]->related_cam_calibration);
15137}
Shuzhen Wangf6890e02016-08-12 14:28:54 -070015138
15139/*===========================================================================
15140 * FUNCTION : is60HzZone
15141 *
15142 * DESCRIPTION: Whether the phone is in zone with 60hz electricity frequency
15143 *
15144 * PARAMETERS : None
15145 *
15146 * RETURN : True if in 60Hz zone, False otherwise
15147 *==========================================================================*/
15148bool QCamera3HardwareInterface::is60HzZone()
15149{
15150 time_t t = time(NULL);
15151 struct tm lt;
15152
15153 struct tm* r = localtime_r(&t, &lt);
15154
15155 if (r == NULL || lt.tm_gmtoff <= -2*60*60 || lt.tm_gmtoff >= 8*60*60)
15156 return true;
15157 else
15158 return false;
15159}
Shuzhen Wanga5da1022016-07-13 20:18:42 -070015160
15161/*===========================================================================
15162 * FUNCTION : adjustBlackLevelForCFA
15163 *
15164 * DESCRIPTION: Adjust the black level pattern in the order of RGGB to the order
15165 * of bayer CFA (Color Filter Array).
15166 *
15167 * PARAMETERS : @input: black level pattern in the order of RGGB
15168 * @output: black level pattern in the order of CFA
15169 * @color_arrangement: CFA color arrangement
15170 *
15171 * RETURN : None
15172 *==========================================================================*/
15173template<typename T>
15174void QCamera3HardwareInterface::adjustBlackLevelForCFA(
15175 T input[BLACK_LEVEL_PATTERN_CNT],
15176 T output[BLACK_LEVEL_PATTERN_CNT],
15177 cam_color_filter_arrangement_t color_arrangement)
15178{
15179 switch (color_arrangement) {
15180 case CAM_FILTER_ARRANGEMENT_GRBG:
15181 output[0] = input[1];
15182 output[1] = input[0];
15183 output[2] = input[3];
15184 output[3] = input[2];
15185 break;
15186 case CAM_FILTER_ARRANGEMENT_GBRG:
15187 output[0] = input[2];
15188 output[1] = input[3];
15189 output[2] = input[0];
15190 output[3] = input[1];
15191 break;
15192 case CAM_FILTER_ARRANGEMENT_BGGR:
15193 output[0] = input[3];
15194 output[1] = input[2];
15195 output[2] = input[1];
15196 output[3] = input[0];
15197 break;
15198 case CAM_FILTER_ARRANGEMENT_RGGB:
15199 output[0] = input[0];
15200 output[1] = input[1];
15201 output[2] = input[2];
15202 output[3] = input[3];
15203 break;
15204 default:
15205 LOGE("Invalid color arrangement to derive dynamic blacklevel");
15206 break;
15207 }
15208}
Chien-Yu Chen8e599492016-11-01 13:37:46 -070015209
Chien-Yu Chen92724a82017-01-06 11:50:30 -080015210void QCamera3HardwareInterface::updateHdrPlusResultMetadata(
15211 CameraMetadata &resultMetadata,
15212 std::shared_ptr<metadata_buffer_t> settings)
15213{
15214 if (settings == nullptr) {
15215 ALOGE("%s: settings is nullptr.", __FUNCTION__);
15216 return;
15217 }
15218
15219 IF_META_AVAILABLE(double, gps_coords, CAM_INTF_META_JPEG_GPS_COORDINATES, settings) {
15220 resultMetadata.update(ANDROID_JPEG_GPS_COORDINATES, gps_coords, 3);
Chien-Yu Chen4e9a8bd2017-09-21 16:02:55 -070015221 } else {
15222 resultMetadata.erase(ANDROID_JPEG_GPS_COORDINATES);
Chien-Yu Chen92724a82017-01-06 11:50:30 -080015223 }
15224
15225 IF_META_AVAILABLE(uint8_t, gps_methods, CAM_INTF_META_JPEG_GPS_PROC_METHODS, settings) {
15226 String8 str((const char *)gps_methods);
15227 resultMetadata.update(ANDROID_JPEG_GPS_PROCESSING_METHOD, str);
Chien-Yu Chen4e9a8bd2017-09-21 16:02:55 -070015228 } else {
15229 resultMetadata.erase(ANDROID_JPEG_GPS_PROCESSING_METHOD);
Chien-Yu Chen92724a82017-01-06 11:50:30 -080015230 }
15231
15232 IF_META_AVAILABLE(int64_t, gps_timestamp, CAM_INTF_META_JPEG_GPS_TIMESTAMP, settings) {
15233 resultMetadata.update(ANDROID_JPEG_GPS_TIMESTAMP, gps_timestamp, 1);
Chien-Yu Chen4e9a8bd2017-09-21 16:02:55 -070015234 } else {
15235 resultMetadata.erase(ANDROID_JPEG_GPS_TIMESTAMP);
Chien-Yu Chen92724a82017-01-06 11:50:30 -080015236 }
15237
15238 IF_META_AVAILABLE(int32_t, jpeg_orientation, CAM_INTF_META_JPEG_ORIENTATION, settings) {
15239 resultMetadata.update(ANDROID_JPEG_ORIENTATION, jpeg_orientation, 1);
Chien-Yu Chen4e9a8bd2017-09-21 16:02:55 -070015240 } else {
15241 resultMetadata.erase(ANDROID_JPEG_ORIENTATION);
Chien-Yu Chen92724a82017-01-06 11:50:30 -080015242 }
15243
15244 IF_META_AVAILABLE(uint32_t, jpeg_quality, CAM_INTF_META_JPEG_QUALITY, settings) {
15245 uint8_t fwk_jpeg_quality = static_cast<uint8_t>(*jpeg_quality);
15246 resultMetadata.update(ANDROID_JPEG_QUALITY, &fwk_jpeg_quality, 1);
Chien-Yu Chen4e9a8bd2017-09-21 16:02:55 -070015247 } else {
15248 resultMetadata.erase(ANDROID_JPEG_QUALITY);
Chien-Yu Chen92724a82017-01-06 11:50:30 -080015249 }
15250
15251 IF_META_AVAILABLE(uint32_t, thumb_quality, CAM_INTF_META_JPEG_THUMB_QUALITY, settings) {
15252 uint8_t fwk_thumb_quality = static_cast<uint8_t>(*thumb_quality);
15253 resultMetadata.update(ANDROID_JPEG_THUMBNAIL_QUALITY, &fwk_thumb_quality, 1);
Chien-Yu Chen4e9a8bd2017-09-21 16:02:55 -070015254 } else {
15255 resultMetadata.erase(ANDROID_JPEG_THUMBNAIL_QUALITY);
Chien-Yu Chen92724a82017-01-06 11:50:30 -080015256 }
15257
15258 IF_META_AVAILABLE(cam_dimension_t, thumb_size, CAM_INTF_META_JPEG_THUMB_SIZE, settings) {
15259 int32_t fwk_thumb_size[2];
15260 fwk_thumb_size[0] = thumb_size->width;
15261 fwk_thumb_size[1] = thumb_size->height;
15262 resultMetadata.update(ANDROID_JPEG_THUMBNAIL_SIZE, fwk_thumb_size, 2);
Chien-Yu Chen4e9a8bd2017-09-21 16:02:55 -070015263 } else {
15264 resultMetadata.erase(ANDROID_JPEG_THUMBNAIL_SIZE);
Chien-Yu Chen92724a82017-01-06 11:50:30 -080015265 }
15266
15267 IF_META_AVAILABLE(uint32_t, intent, CAM_INTF_META_CAPTURE_INTENT, settings) {
15268 uint8_t fwk_intent = intent[0];
15269 resultMetadata.update(ANDROID_CONTROL_CAPTURE_INTENT, &fwk_intent, 1);
Chien-Yu Chen4e9a8bd2017-09-21 16:02:55 -070015270 } else {
15271 resultMetadata.erase(ANDROID_CONTROL_CAPTURE_INTENT);
Chien-Yu Chen92724a82017-01-06 11:50:30 -080015272 }
15273}
15274
Chien-Yu Chenad9b6632017-08-22 19:09:23 -070015275bool QCamera3HardwareInterface::isRequestHdrPlusCompatible(
15276 const camera3_capture_request_t &request, const CameraMetadata &metadata) {
Chien-Yu Chenec328c82017-08-30 16:41:08 -070015277 if (metadata.exists(NEXUS_EXPERIMENTAL_2017_DISABLE_HDRPLUS) &&
15278 metadata.find(NEXUS_EXPERIMENTAL_2017_DISABLE_HDRPLUS).data.i32[0] == 1) {
15279 ALOGV("%s: NEXUS_EXPERIMENTAL_2017_DISABLE_HDRPLUS is 1", __FUNCTION__);
15280 return false;
15281 }
15282
Chien-Yu Chen200b2ce2017-02-01 15:03:02 -080015283 if (!metadata.exists(ANDROID_NOISE_REDUCTION_MODE) ||
15284 metadata.find(ANDROID_NOISE_REDUCTION_MODE).data.u8[0] !=
15285 ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY) {
Chien-Yu Chenad9b6632017-08-22 19:09:23 -070015286 ALOGV("%s: ANDROID_NOISE_REDUCTION_MODE is not HQ: %d", __FUNCTION__,
Chien-Yu Chenee335912017-02-09 17:53:20 -080015287 metadata.find(ANDROID_NOISE_REDUCTION_MODE).data.u8[0]);
Chien-Yu Chen200b2ce2017-02-01 15:03:02 -080015288 return false;
15289 }
15290
Chien-Yu Chen200b2ce2017-02-01 15:03:02 -080015291 if (!metadata.exists(ANDROID_EDGE_MODE) ||
Chien-Yu Chenad9b6632017-08-22 19:09:23 -070015292 metadata.find(ANDROID_EDGE_MODE).data.u8[0] != ANDROID_EDGE_MODE_HIGH_QUALITY) {
15293 ALOGV("%s: ANDROID_EDGE_MODE is not HQ.", __FUNCTION__);
Chien-Yu Chen200b2ce2017-02-01 15:03:02 -080015294 return false;
15295 }
15296
Chien-Yu Chenad9b6632017-08-22 19:09:23 -070015297 if (!metadata.exists(ANDROID_COLOR_CORRECTION_ABERRATION_MODE) ||
15298 metadata.find(ANDROID_COLOR_CORRECTION_ABERRATION_MODE).data.u8[0] !=
15299 ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY) {
15300 ALOGV("%s: ANDROID_COLOR_CORRECTION_ABERRATION_MODE is not HQ.", __FUNCTION__);
15301 return false;
15302 }
15303
15304 if (!metadata.exists(ANDROID_CONTROL_AE_MODE) ||
15305 (metadata.find(ANDROID_CONTROL_AE_MODE).data.u8[0] != ANDROID_CONTROL_AE_MODE_ON &&
15306 metadata.find(ANDROID_CONTROL_AE_MODE).data.u8[0] !=
15307 ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH)) {
15308 ALOGV("%s: ANDROID_CONTROL_AE_MODE is not ON or ON_AUTO_FLASH.", __FUNCTION__);
15309 return false;
15310 }
15311
15312 if (!metadata.exists(ANDROID_CONTROL_AWB_MODE) ||
15313 metadata.find(ANDROID_CONTROL_AWB_MODE).data.u8[0] != ANDROID_CONTROL_AWB_MODE_AUTO) {
15314 ALOGV("%s: ANDROID_CONTROL_AWB_MODE is not AUTO.", __FUNCTION__);
15315 return false;
15316 }
15317
15318 if (!metadata.exists(ANDROID_CONTROL_EFFECT_MODE) ||
15319 metadata.find(ANDROID_CONTROL_EFFECT_MODE).data.u8[0] !=
15320 ANDROID_CONTROL_EFFECT_MODE_OFF) {
15321 ALOGV("%s: ANDROID_CONTROL_EFFECT_MODE_OFF is not OFF.", __FUNCTION__);
15322 return false;
15323 }
15324
15325 if (!metadata.exists(ANDROID_CONTROL_MODE) ||
15326 (metadata.find(ANDROID_CONTROL_MODE).data.u8[0] != ANDROID_CONTROL_MODE_AUTO &&
15327 metadata.find(ANDROID_CONTROL_MODE).data.u8[0] !=
15328 ANDROID_CONTROL_MODE_USE_SCENE_MODE)) {
15329 ALOGV("%s: ANDROID_CONTROL_MODE is not AUTO or USE_SCENE_MODE.", __FUNCTION__);
15330 return false;
15331 }
15332
15333 // TODO (b/32585046): support non-ZSL.
15334 if (!metadata.exists(ANDROID_CONTROL_ENABLE_ZSL) ||
15335 metadata.find(ANDROID_CONTROL_ENABLE_ZSL).data.u8[0] != ANDROID_CONTROL_ENABLE_ZSL_TRUE) {
15336 ALOGV("%s: ANDROID_CONTROL_ENABLE_ZSL is not true.", __FUNCTION__);
15337 return false;
15338 }
15339
15340 // TODO (b/32586081): support flash.
15341 if (!metadata.exists(ANDROID_FLASH_MODE) ||
15342 metadata.find(ANDROID_FLASH_MODE).data.u8[0] != ANDROID_FLASH_MODE_OFF) {
15343 ALOGV("%s: ANDROID_FLASH_MODE is not OFF.", __FUNCTION__);
15344 return false;
15345 }
15346
Chien-Yu Chenad9b6632017-08-22 19:09:23 -070015347 if (!metadata.exists(ANDROID_TONEMAP_MODE) ||
15348 metadata.find(ANDROID_TONEMAP_MODE).data.u8[0] != ANDROID_TONEMAP_MODE_HIGH_QUALITY) {
15349 ALOGV("%s: ANDROID_TONEMAP_MODE is not HQ.", __FUNCTION__);
15350 return false;
15351 }
15352
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015353 switch (request.output_buffers[0].stream->format) {
15354 case HAL_PIXEL_FORMAT_BLOB:
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015355 case HAL_PIXEL_FORMAT_YCbCr_420_888:
15356 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015357 break;
15358 default:
15359 ALOGV("%s: Not an HDR+ request: Only Jpeg and YUV output is supported.", __FUNCTION__);
15360 for (uint32_t i = 0; i < request.num_output_buffers; i++) {
15361 ALOGV("%s: output_buffers[%u]: %dx%d format %d", __FUNCTION__, i,
15362 request.output_buffers[0].stream->width,
15363 request.output_buffers[0].stream->height,
15364 request.output_buffers[0].stream->format);
15365 }
15366 return false;
15367 }
15368
Chien-Yu Chenad9b6632017-08-22 19:09:23 -070015369 return true;
15370}
15371
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015372void QCamera3HardwareInterface::abortPendingHdrplusRequest(HdrPlusPendingRequest *hdrPlusRequest) {
15373 if (hdrPlusRequest == nullptr) return;
15374
15375 for (auto & outputBufferIter : hdrPlusRequest->outputBuffers) {
15376 // Find the stream for this buffer.
15377 for (auto streamInfo : mStreamInfo) {
15378 if (streamInfo->id == outputBufferIter.first) {
15379 if (streamInfo->channel == mPictureChannel) {
15380 // For picture channel, this buffer is internally allocated so return this
15381 // buffer to picture channel.
15382 mPictureChannel->returnYuvBuffer(outputBufferIter.second.get());
15383 } else {
15384 // Unregister this buffer for other channels.
15385 streamInfo->channel->unregisterBuffer(outputBufferIter.second.get());
15386 }
15387 break;
15388 }
15389 }
15390 }
15391
15392 hdrPlusRequest->outputBuffers.clear();
15393 hdrPlusRequest->frameworkOutputBuffers.clear();
15394}
15395
Chien-Yu Chenad9b6632017-08-22 19:09:23 -070015396bool QCamera3HardwareInterface::trySubmittingHdrPlusRequestLocked(
15397 HdrPlusPendingRequest *hdrPlusRequest, const camera3_capture_request_t &request,
15398 const CameraMetadata &metadata)
15399{
15400 if (hdrPlusRequest == nullptr) return false;
15401 if (!isRequestHdrPlusCompatible(request, metadata)) return false;
15402
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015403 status_t res = OK;
Chien-Yu Chen200b2ce2017-02-01 15:03:02 -080015404 pbcamera::CaptureRequest pbRequest;
15405 pbRequest.id = request.frame_number;
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015406 // Iterate through all requested output buffers and add them to an HDR+ request.
15407 for (uint32_t i = 0; i < request.num_output_buffers; i++) {
15408 // Find the index of the stream in mStreamInfo.
15409 uint32_t pbStreamId = 0;
15410 bool found = false;
15411 for (auto streamInfo : mStreamInfo) {
15412 if (streamInfo->stream == request.output_buffers[i].stream) {
15413 pbStreamId = streamInfo->id;
15414 found = true;
15415 break;
15416 }
15417 }
15418
15419 if (!found) {
15420 ALOGE("%s: requested stream was not configured.", __FUNCTION__);
15421 abortPendingHdrplusRequest(hdrPlusRequest);
15422 return false;
15423 }
15424 auto outBuffer = std::make_shared<mm_camera_buf_def_t>();
15425 switch (request.output_buffers[i].stream->format) {
15426 case HAL_PIXEL_FORMAT_BLOB:
15427 {
15428 // For jpeg output, get a YUV buffer from pic channel.
15429 QCamera3PicChannel *picChannel =
15430 (QCamera3PicChannel*)request.output_buffers[i].stream->priv;
15431 res = picChannel->getYuvBufferForRequest(outBuffer.get(), request.frame_number);
15432 if (res != OK) {
15433 ALOGE("%s: Getting an available YUV buffer from pic channel failed: %s (%d)",
15434 __FUNCTION__, strerror(-res), res);
15435 abortPendingHdrplusRequest(hdrPlusRequest);
15436 return false;
15437 }
15438 break;
15439 }
15440 case HAL_PIXEL_FORMAT_YCbCr_420_888:
15441 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
15442 {
15443 // For YUV output, register the buffer and get the buffer def from the channel.
15444 QCamera3ProcessingChannel *channel =
15445 (QCamera3ProcessingChannel*)request.output_buffers[i].stream->priv;
15446 res = channel->registerBufferAndGetBufDef(request.output_buffers[i].buffer,
15447 outBuffer.get());
15448 if (res != OK) {
15449 ALOGE("%s: Getting the buffer def failed: %s (%d)", __FUNCTION__,
15450 strerror(-res), res);
15451 abortPendingHdrplusRequest(hdrPlusRequest);
15452 return false;
15453 }
15454 break;
15455 }
15456 default:
15457 abortPendingHdrplusRequest(hdrPlusRequest);
15458 return false;
15459 }
15460
15461 pbcamera::StreamBuffer buffer;
15462 buffer.streamId = pbStreamId;
15463 buffer.dmaBufFd = outBuffer->fd;
15464 buffer.data = outBuffer->fd == -1 ? outBuffer->buffer : nullptr;
15465 buffer.dataSize = outBuffer->frame_len;
15466
15467 pbRequest.outputBuffers.push_back(buffer);
15468
15469 hdrPlusRequest->outputBuffers.emplace(pbStreamId, outBuffer);
15470 hdrPlusRequest->frameworkOutputBuffers.emplace(pbStreamId, request.output_buffers[i]);
15471 }
Chien-Yu Chen200b2ce2017-02-01 15:03:02 -080015472
15473 // Submit an HDR+ capture request to HDR+ service.
Chien-Yu Chen17cec362017-07-05 17:10:31 -070015474 res = gHdrPlusClient->submitCaptureRequest(&pbRequest, metadata);
Chien-Yu Chen200b2ce2017-02-01 15:03:02 -080015475 if (res != OK) {
15476 ALOGE("%s: %d: Submitting a capture request failed: %s (%d)", __FUNCTION__, __LINE__,
15477 strerror(-res), res);
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015478 abortPendingHdrplusRequest(hdrPlusRequest);
Chien-Yu Chen200b2ce2017-02-01 15:03:02 -080015479 return false;
15480 }
15481
Chien-Yu Chen200b2ce2017-02-01 15:03:02 -080015482 return true;
15483}
15484
Chien-Yu Chen411e9c52017-05-08 11:58:50 -070015485status_t QCamera3HardwareInterface::openHdrPlusClientAsyncLocked()
15486{
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -070015487 if (gHdrPlusClientOpening || gHdrPlusClient != nullptr) {
15488 return OK;
15489 }
15490
Chien-Yu Chen6ed36ca2017-10-02 11:22:17 -070015491 status_t res = gEaselManagerClient->openHdrPlusClientAsync(mQCamera3HdrPlusListenerThread.get());
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -070015492 if (res != OK) {
15493 ALOGE("%s: Opening HDR+ client asynchronously failed: %s (%d)", __FUNCTION__,
15494 strerror(-res), res);
15495 return res;
15496 }
15497 gHdrPlusClientOpening = true;
15498
15499 return OK;
15500}
15501
Chien-Yu Chenee335912017-02-09 17:53:20 -080015502status_t QCamera3HardwareInterface::enableHdrPlusModeLocked()
15503{
Chien-Yu Chena7fe4ed2017-03-13 16:36:57 -070015504 status_t res;
Chien-Yu Chenee335912017-02-09 17:53:20 -080015505
Chien-Yu Chena6c99062017-05-23 13:45:06 -070015506 if (mHdrPlusModeEnabled) {
15507 return OK;
15508 }
15509
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -070015510 // Check if gHdrPlusClient is opened or being opened.
15511 if (gHdrPlusClient == nullptr) {
15512 if (gHdrPlusClientOpening) {
15513 // HDR+ client is being opened. HDR+ mode will be enabled when it's opened.
15514 return OK;
15515 }
15516
15517 res = openHdrPlusClientAsyncLocked();
Chien-Yu Chena7fe4ed2017-03-13 16:36:57 -070015518 if (res != OK) {
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -070015519 ALOGE("%s: Failed to open HDR+ client asynchronously: %s (%d).", __FUNCTION__,
15520 strerror(-res), res);
Chien-Yu Chena7fe4ed2017-03-13 16:36:57 -070015521 return res;
15522 }
15523
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -070015524 // When opening HDR+ client completes, HDR+ mode will be enabled.
15525 return OK;
15526
Chien-Yu Chenee335912017-02-09 17:53:20 -080015527 }
15528
15529 // Configure stream for HDR+.
15530 res = configureHdrPlusStreamsLocked();
15531 if (res != OK) {
15532 LOGE("%s: Failed to configure HDR+ streams: %s (%d)", __FUNCTION__, strerror(-res), res);
Chien-Yu Chena7fe4ed2017-03-13 16:36:57 -070015533 return res;
15534 }
15535
15536 // Enable HDR+ mode so Easel will start capturing ZSL raw buffers.
15537 res = gHdrPlusClient->setZslHdrPlusMode(true);
15538 if (res != OK) {
15539 LOGE("%s: Failed to enable HDR+ mode: %s (%d)", __FUNCTION__, strerror(-res), res);
Chien-Yu Chenee335912017-02-09 17:53:20 -080015540 return res;
15541 }
15542
15543 mHdrPlusModeEnabled = true;
15544 ALOGD("%s: HDR+ mode enabled", __FUNCTION__);
15545
15546 return OK;
15547}
15548
Chien-Yu Chen77ccd022017-06-23 12:00:36 -070015549void QCamera3HardwareInterface::finishHdrPlusClientOpeningLocked(std::unique_lock<std::mutex> &lock)
15550{
15551 if (gHdrPlusClientOpening) {
15552 gHdrPlusClientOpenCond.wait(lock, [&] { return !gHdrPlusClientOpening; });
15553 }
15554}
15555
Chien-Yu Chenee335912017-02-09 17:53:20 -080015556void QCamera3HardwareInterface::disableHdrPlusModeLocked()
15557{
Chien-Yu Chena7fe4ed2017-03-13 16:36:57 -070015558 // Disable HDR+ mode.
Chien-Yu Chen27ec9622017-02-23 13:39:41 -080015559 if (gHdrPlusClient != nullptr && mHdrPlusModeEnabled) {
Chien-Yu Chena7fe4ed2017-03-13 16:36:57 -070015560 status_t res = gHdrPlusClient->setZslHdrPlusMode(false);
15561 if (res != OK) {
15562 ALOGE("%s: Failed to disable HDR+ mode: %s (%d)", __FUNCTION__, strerror(-res), res);
15563 }
Chien-Yu Chen3b17c672017-04-24 12:49:52 -070015564
15565 // Close HDR+ client so Easel can enter low power mode.
Chien-Yu Chend77a5462017-06-02 18:00:38 -070015566 gEaselManagerClient->closeHdrPlusClient(std::move(gHdrPlusClient));
Chien-Yu Chen3b17c672017-04-24 12:49:52 -070015567 gHdrPlusClient = nullptr;
Chien-Yu Chenee335912017-02-09 17:53:20 -080015568 }
15569
15570 mHdrPlusModeEnabled = false;
15571 ALOGD("%s: HDR+ mode disabled", __FUNCTION__);
15572}
15573
Chien-Yu Chendeaebad2017-06-30 11:46:34 -070015574bool QCamera3HardwareInterface::isSessionHdrPlusModeCompatible()
15575{
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015576 // Check that at least one YUV or one JPEG output is configured.
15577 // TODO: Support RAW (b/36690506)
15578 for (auto streamInfo : mStreamInfo) {
15579 if (streamInfo != nullptr && streamInfo->stream != nullptr) {
15580 if (streamInfo->stream->stream_type == CAMERA3_STREAM_OUTPUT &&
15581 (streamInfo->stream->format == HAL_PIXEL_FORMAT_BLOB ||
15582 streamInfo->stream->format == HAL_PIXEL_FORMAT_YCbCr_420_888 ||
15583 streamInfo->stream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)) {
15584 return true;
15585 }
15586 }
Chien-Yu Chendeaebad2017-06-30 11:46:34 -070015587 }
15588
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015589 return false;
Chien-Yu Chendeaebad2017-06-30 11:46:34 -070015590}
15591
Chien-Yu Chenee335912017-02-09 17:53:20 -080015592status_t QCamera3HardwareInterface::configureHdrPlusStreamsLocked()
Chien-Yu Chen200b2ce2017-02-01 15:03:02 -080015593{
15594 pbcamera::InputConfiguration inputConfig;
15595 std::vector<pbcamera::StreamConfiguration> outputStreamConfigs;
15596 status_t res = OK;
15597
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015598 // Sensor MIPI will send data to Easel.
15599 inputConfig.isSensorInput = true;
15600 inputConfig.sensorMode.cameraId = mCameraId;
15601 inputConfig.sensorMode.pixelArrayWidth = mSensorModeInfo.pixel_array_size.width;
15602 inputConfig.sensorMode.pixelArrayHeight = mSensorModeInfo.pixel_array_size.height;
15603 inputConfig.sensorMode.activeArrayWidth = mSensorModeInfo.active_array_size.width;
15604 inputConfig.sensorMode.activeArrayHeight = mSensorModeInfo.active_array_size.height;
15605 inputConfig.sensorMode.outputPixelClkHz = mSensorModeInfo.op_pixel_clk;
15606 inputConfig.sensorMode.timestampOffsetNs = mSensorModeInfo.timestamp_offset;
Chien-Yu Chenc8b6ad02017-09-15 13:50:26 -070015607 inputConfig.sensorMode.timestampCropOffsetNs = mSensorModeInfo.timestamp_crop_offset;
15608
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015609 if (mSensorModeInfo.num_raw_bits != 10) {
15610 ALOGE("%s: Only RAW10 is supported but this sensor mode has %d raw bits.", __FUNCTION__,
15611 mSensorModeInfo.num_raw_bits);
15612 return BAD_VALUE;
Chien-Yu Chen200b2ce2017-02-01 15:03:02 -080015613 }
15614
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015615 inputConfig.sensorMode.format = HAL_PIXEL_FORMAT_RAW10;
Chien-Yu Chen200b2ce2017-02-01 15:03:02 -080015616
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015617 // Iterate through configured output streams in HAL and configure those streams in HDR+
15618 // service.
15619 for (auto streamInfo : mStreamInfo) {
15620 pbcamera::StreamConfiguration outputConfig;
15621 if (streamInfo->stream->stream_type == CAMERA3_STREAM_OUTPUT) {
15622 switch (streamInfo->stream->format) {
15623 case HAL_PIXEL_FORMAT_BLOB:
15624 case HAL_PIXEL_FORMAT_YCbCr_420_888:
15625 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
15626 res = fillPbStreamConfig(&outputConfig, streamInfo->id,
15627 streamInfo->channel, /*stream index*/0);
15628 if (res != OK) {
15629 LOGE("%s: Failed to get fill stream config for YUV stream: %s (%d)",
15630 __FUNCTION__, strerror(-res), res);
Chien-Yu Chen200b2ce2017-02-01 15:03:02 -080015631
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015632 return res;
15633 }
15634
15635 outputStreamConfigs.push_back(outputConfig);
15636 break;
15637 default:
15638 // TODO: handle RAW16 outputs if mRawChannel was created. (b/36690506)
15639 break;
15640 }
Chien-Yu Chen200b2ce2017-02-01 15:03:02 -080015641 }
Chien-Yu Chen200b2ce2017-02-01 15:03:02 -080015642 }
15643
Chien-Yu Chen27ec9622017-02-23 13:39:41 -080015644 res = gHdrPlusClient->configureStreams(inputConfig, outputStreamConfigs);
Chien-Yu Chen200b2ce2017-02-01 15:03:02 -080015645 if (res != OK) {
15646 LOGE("%d: Failed to configure streams with HDR+ client: %s (%d)", __FUNCTION__,
15647 strerror(-res), res);
15648 return res;
15649 }
15650
15651 return OK;
15652}
15653
Chien-Yu Chene80574b2017-09-08 19:05:20 -070015654void QCamera3HardwareInterface::handleEaselFatalError()
Chien-Yu Chen90f1fc12017-07-14 14:31:53 -070015655{
Chien-Yu Chenf93bbdc2017-10-18 13:27:04 -070015656 {
15657 std::unique_lock<std::mutex> l(gHdrPlusClientLock);
15658 if (gHdrPlusClient != nullptr) {
15659 gHdrPlusClient->nofityEaselFatalError();
15660 }
15661 }
15662
Chien-Yu Chen90f1fc12017-07-14 14:31:53 -070015663 pthread_mutex_lock(&mMutex);
15664 mState = ERROR;
15665 pthread_mutex_unlock(&mMutex);
15666
Chien-Yu Chen09cb28e2017-07-21 13:15:52 -070015667 handleCameraDeviceError(/*stopChannelImmediately*/true);
Chien-Yu Chen90f1fc12017-07-14 14:31:53 -070015668}
15669
Chien-Yu Chenf8887c02018-04-11 15:29:46 -070015670void QCamera3HardwareInterface::cleanupEaselErrorFuture()
15671{
15672 {
15673 std::lock_guard<std::mutex> lock(mEaselErrorFutureLock);
15674 if (!mEaselErrorFuture.valid()) {
15675 // If there is no Easel error, construct a dummy future to wait for.
15676 mEaselErrorFuture = std::async([]() { return; });
15677 }
15678 }
15679
15680 mEaselErrorFuture.wait();
15681}
15682
Chien-Yu Chene80574b2017-09-08 19:05:20 -070015683void QCamera3HardwareInterface::handleEaselFatalErrorAsync()
15684{
Chien-Yu Chenf8887c02018-04-11 15:29:46 -070015685 std::lock_guard<std::mutex> lock(mEaselErrorFutureLock);
15686
Chien-Yu Chene80574b2017-09-08 19:05:20 -070015687 if (mEaselErrorFuture.valid()) {
15688 // The error future has been invoked.
15689 return;
15690 }
15691
15692 // Launch a future to handle the fatal error.
15693 mEaselErrorFuture = std::async(std::launch::async,
15694 &QCamera3HardwareInterface::handleEaselFatalError, this);
15695}
15696
15697void QCamera3HardwareInterface::onEaselFatalError(std::string errMsg)
15698{
15699 ALOGE("%s: Got an Easel fatal error: %s", __FUNCTION__, errMsg.c_str());
15700 handleEaselFatalErrorAsync();
15701}
15702
Chien-Yu Chen411e9c52017-05-08 11:58:50 -070015703void QCamera3HardwareInterface::onOpened(std::unique_ptr<HdrPlusClient> client)
15704{
Arnd Geis8cbfc182017-09-07 14:46:41 -070015705 int rc = NO_ERROR;
15706
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -070015707 if (client == nullptr) {
15708 ALOGE("%s: Opened client is null.", __FUNCTION__);
15709 return;
15710 }
15711
Chien-Yu Chene96475e2017-04-11 11:53:26 -070015712 logEaselEvent("EASEL_STARTUP_LATENCY", "HDR+ client opened.");
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -070015713 ALOGI("%s: HDR+ client opened.", __FUNCTION__);
15714
Chien-Yu Chen77ccd022017-06-23 12:00:36 -070015715 std::unique_lock<std::mutex> l(gHdrPlusClientLock);
Chien-Yu Chen411e9c52017-05-08 11:58:50 -070015716 if (!gHdrPlusClientOpening) {
15717 ALOGW("%s: HDR+ is disabled while HDR+ client is being opened.", __FUNCTION__);
15718 return;
15719 }
15720
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -070015721 gHdrPlusClient = std::move(client);
15722 gHdrPlusClientOpening = false;
Chien-Yu Chen77ccd022017-06-23 12:00:36 -070015723 gHdrPlusClientOpenCond.notify_one();
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -070015724
15725 // Set static metadata.
15726 status_t res = gHdrPlusClient->setStaticMetadata(*gStaticMetadata[mCameraId]);
15727 if (res != OK) {
15728 LOGE("%s: Failed to set static metadata in HDR+ client: %s (%d). Closing HDR+ client.",
15729 __FUNCTION__, strerror(-res), res);
Chien-Yu Chend77a5462017-06-02 18:00:38 -070015730 gEaselManagerClient->closeHdrPlusClient(std::move(gHdrPlusClient));
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -070015731 gHdrPlusClient = nullptr;
15732 return;
15733 }
15734
15735 // Enable HDR+ mode.
15736 res = enableHdrPlusModeLocked();
15737 if (res != OK) {
15738 LOGE("%s: Failed to configure HDR+ streams.", __FUNCTION__);
15739 }
Arnd Geis8cbfc182017-09-07 14:46:41 -070015740
15741 // Get Easel firmware version
15742 if (EaselManagerClientOpened) {
15743 rc = gEaselManagerClient->getFwVersion(mEaselFwVersion);
15744 if (rc != OK) {
15745 ALOGD("%s: Failed to query Easel firmware version", __FUNCTION__);
15746 } else {
15747 mEaselFwUpdated = true;
15748 }
15749 }
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -070015750}
15751
Chien-Yu Chen411e9c52017-05-08 11:58:50 -070015752void QCamera3HardwareInterface::onOpenFailed(status_t err)
15753{
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -070015754 ALOGE("%s: Opening HDR+ client failed: %s (%d)", __FUNCTION__, strerror(-err), err);
Chien-Yu Chen77ccd022017-06-23 12:00:36 -070015755 std::unique_lock<std::mutex> l(gHdrPlusClientLock);
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -070015756 gHdrPlusClientOpening = false;
Chien-Yu Chen77ccd022017-06-23 12:00:36 -070015757 gHdrPlusClientOpenCond.notify_one();
Chien-Yu Chen54c19cb2017-03-31 17:53:18 -070015758}
15759
Chien-Yu Chen411e9c52017-05-08 11:58:50 -070015760void QCamera3HardwareInterface::onFatalError()
15761{
Chien-Yu Chene80574b2017-09-08 19:05:20 -070015762 ALOGE("%s: HDR+ client encountered a fatal error.", __FUNCTION__);
15763 handleEaselFatalErrorAsync();
Chien-Yu Chen411e9c52017-05-08 11:58:50 -070015764}
15765
Chien-Yu Chen29fd1d72017-04-27 18:42:09 -070015766void QCamera3HardwareInterface::onShutter(uint32_t requestId, int64_t apSensorTimestampNs)
15767{
15768 ALOGV("%s: %d: Received a shutter for HDR+ request %d timestamp %" PRId64, __FUNCTION__,
15769 __LINE__, requestId, apSensorTimestampNs);
15770
15771 mShutterDispatcher.markShutterReady(requestId, apSensorTimestampNs);
15772}
15773
Chien-Yu Chendaf68892017-08-25 12:56:40 -070015774void QCamera3HardwareInterface::onNextCaptureReady(uint32_t requestId)
15775{
15776 pthread_mutex_lock(&mMutex);
15777
15778 // Find the pending request for this result metadata.
15779 auto requestIter = mPendingRequestsList.begin();
15780 while (requestIter != mPendingRequestsList.end() && requestIter->frame_number != requestId) {
15781 requestIter++;
15782 }
15783
15784 if (requestIter == mPendingRequestsList.end()) {
15785 ALOGE("%s: Cannot find a pending request for frame number %u.", __FUNCTION__, requestId);
15786 pthread_mutex_unlock(&mMutex);
15787 return;
15788 }
15789
15790 requestIter->partial_result_cnt++;
15791
15792 CameraMetadata metadata;
15793 uint8_t ready = true;
15794 metadata.update(NEXUS_EXPERIMENTAL_2017_NEXT_STILL_INTENT_REQUEST_READY, &ready, 1);
15795
15796 // Send it to framework.
15797 camera3_capture_result_t result = {};
15798
15799 result.result = metadata.getAndLock();
15800 // Populate metadata result
15801 result.frame_number = requestId;
15802 result.num_output_buffers = 0;
15803 result.output_buffers = NULL;
15804 result.partial_result = requestIter->partial_result_cnt;
15805
15806 orchestrateResult(&result);
15807 metadata.unlock(result.result);
15808
15809 pthread_mutex_unlock(&mMutex);
15810}
15811
Chien-Yu Chen0a921f92017-08-27 17:25:33 -070015812void QCamera3HardwareInterface::onPostview(uint32_t requestId,
15813 std::unique_ptr<std::vector<uint8_t>> postview, uint32_t width, uint32_t height,
15814 uint32_t stride, int32_t format)
15815{
15816 if (property_get_bool("persist.camera.hdrplus.dump_postview", false)) {
15817 ALOGI("%s: %d: Received a postview %dx%d for HDR+ request %d", __FUNCTION__,
15818 __LINE__, width, height, requestId);
15819 char buf[FILENAME_MAX] = {};
15820 snprintf(buf, sizeof(buf), QCAMERA_DUMP_FRM_LOCATION"postview_%d_%dx%d.ppm",
15821 requestId, width, height);
15822
15823 pbcamera::StreamConfiguration config = {};
15824 config.image.width = width;
15825 config.image.height = height;
15826 config.image.format = format;
15827
15828 pbcamera::PlaneConfiguration plane = {};
15829 plane.stride = stride;
15830 plane.scanline = height;
15831
15832 config.image.planes.push_back(plane);
15833
15834 pbcamera::StreamBuffer buffer = {};
15835 buffer.streamId = 0;
15836 buffer.dmaBufFd = -1;
15837 buffer.data = postview->data();
15838 buffer.dataSize = postview->size();
15839
15840 hdrplus_client_utils::writePpm(buf, config, buffer);
15841 }
15842
15843 pthread_mutex_lock(&mMutex);
15844
15845 // Find the pending request for this result metadata.
15846 auto requestIter = mPendingRequestsList.begin();
15847 while (requestIter != mPendingRequestsList.end() && requestIter->frame_number != requestId) {
15848 requestIter++;
15849 }
15850
15851 if (requestIter == mPendingRequestsList.end()) {
15852 ALOGE("%s: Cannot find a pending request for frame number %u.", __FUNCTION__, requestId);
15853 pthread_mutex_unlock(&mMutex);
15854 return;
15855 }
15856
15857 requestIter->partial_result_cnt++;
15858
15859 CameraMetadata metadata;
15860 int32_t config[3] = {static_cast<int32_t>(width), static_cast<int32_t>(height),
15861 static_cast<int32_t>(stride)};
15862 metadata.update(NEXUS_EXPERIMENTAL_2017_POSTVIEW_CONFIG, config, 3);
15863 metadata.update(NEXUS_EXPERIMENTAL_2017_POSTVIEW_DATA, postview->data(), postview->size());
15864
15865 // Send it to framework.
15866 camera3_capture_result_t result = {};
15867
15868 result.result = metadata.getAndLock();
15869 // Populate metadata result
15870 result.frame_number = requestId;
15871 result.num_output_buffers = 0;
15872 result.output_buffers = NULL;
15873 result.partial_result = requestIter->partial_result_cnt;
15874
15875 orchestrateResult(&result);
15876 metadata.unlock(result.result);
15877
15878 pthread_mutex_unlock(&mMutex);
15879}
15880
Chien-Yu Chene687bd02016-12-07 18:30:26 -080015881void QCamera3HardwareInterface::onCaptureResult(pbcamera::CaptureResult *result,
Chien-Yu Chen411e9c52017-05-08 11:58:50 -070015882 const camera_metadata_t &resultMetadata)
15883{
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015884 if (result == nullptr) {
15885 ALOGE("%s: result is nullptr.", __FUNCTION__);
15886 return;
15887 }
15888
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015889 // Find the pending HDR+ request.
15890 HdrPlusPendingRequest pendingRequest;
15891 {
15892 Mutex::Autolock lock(mHdrPlusPendingRequestsLock);
15893 auto req = mHdrPlusPendingRequests.find(result->requestId);
15894 pendingRequest = req->second;
15895 }
15896
15897 // Update the result metadata with the settings of the HDR+ still capture request because
15898 // the result metadata belongs to a ZSL buffer.
15899 CameraMetadata metadata;
15900 metadata = &resultMetadata;
15901 updateHdrPlusResultMetadata(metadata, pendingRequest.settings);
15902 camera_metadata_t* updatedResultMetadata = metadata.release();
15903
15904 uint32_t halSnapshotStreamId = 0;
15905 if (mPictureChannel != nullptr) {
15906 halSnapshotStreamId = mPictureChannel->getStreamID(mPictureChannel->getStreamTypeMask());
15907 }
15908
15909 auto halMetadata = std::make_shared<metadata_buffer_t>();
15910 clear_metadata_buffer(halMetadata.get());
15911
15912 // Convert updated result metadata to HAL metadata.
15913 status_t res = translateFwkMetadataToHalMetadata(updatedResultMetadata, halMetadata.get(),
15914 halSnapshotStreamId, /*minFrameDuration*/0);
15915 if (res != 0) {
15916 ALOGE("%s: Translating metadata failed: %s (%d)", __FUNCTION__, strerror(-res), res);
15917 }
15918
15919 for (auto &outputBuffer : result->outputBuffers) {
15920 uint32_t streamId = outputBuffer.streamId;
15921
15922 // Find the framework output buffer in the pending request.
15923 auto frameworkOutputBufferIter = pendingRequest.frameworkOutputBuffers.find(streamId);
15924 if (frameworkOutputBufferIter == pendingRequest.frameworkOutputBuffers.end()) {
15925 ALOGE("%s: Couldn't find framework output buffers for stream id %u", __FUNCTION__,
15926 streamId);
15927 continue;
Chien-Yu Chene687bd02016-12-07 18:30:26 -080015928 }
15929
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015930 camera3_stream_buffer_t *frameworkOutputBuffer = &frameworkOutputBufferIter->second;
15931
15932 // Find the channel for the output buffer.
15933 QCamera3ProcessingChannel *channel =
15934 (QCamera3ProcessingChannel*)frameworkOutputBuffer->stream->priv;
15935
15936 // Find the output buffer def.
15937 auto outputBufferIter = pendingRequest.outputBuffers.find(streamId);
15938 if (outputBufferIter == pendingRequest.outputBuffers.end()) {
15939 ALOGE("%s: Cannot find output buffer", __FUNCTION__);
15940 continue;
Chien-Yu Chene687bd02016-12-07 18:30:26 -080015941 }
15942
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015943 std::shared_ptr<mm_camera_buf_def_t> outputBufferDef = outputBufferIter->second;
Chien-Yu Chendaf68892017-08-25 12:56:40 -070015944
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015945 // Check whether to dump the buffer.
15946 if (frameworkOutputBuffer->stream->format == HAL_PIXEL_FORMAT_YCbCr_420_888 ||
15947 frameworkOutputBuffer->stream->format == HAL_PIXEL_FORMAT_BLOB) {
15948 // If the stream format is YUV or jpeg, check if dumping HDR+ YUV output is enabled.
15949 char prop[PROPERTY_VALUE_MAX];
15950 property_get("persist.camera.hdrplus.dump_yuv", prop, "0");
15951 bool dumpYuvOutput = atoi(prop);
Chien-Yu Chene687bd02016-12-07 18:30:26 -080015952
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015953 if (dumpYuvOutput) {
15954 // Dump yuv buffer to a ppm file.
15955 pbcamera::StreamConfiguration outputConfig;
15956 status_t rc = fillPbStreamConfig(&outputConfig, streamId,
15957 channel, /*stream index*/0);
15958 if (rc == OK) {
15959 char buf[FILENAME_MAX] = {};
15960 snprintf(buf, sizeof(buf), QCAMERA_DUMP_FRM_LOCATION"s_%d_%d_%dx%d.ppm",
15961 result->requestId, streamId,
15962 outputConfig.image.width, outputConfig.image.height);
Chien-Yu Chen92724a82017-01-06 11:50:30 -080015963
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015964 hdrplus_client_utils::writePpm(buf, outputConfig, outputBuffer);
15965 } else {
15966 LOGW("%s: Couldn't dump YUV buffer because getting stream config failed: "
15967 "%s (%d).", __FUNCTION__, strerror(-rc), rc);
15968 }
Chien-Yu Chene687bd02016-12-07 18:30:26 -080015969 }
15970 }
15971
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015972 if (channel == mPictureChannel) {
Chien-Yu Chen92724a82017-01-06 11:50:30 -080015973 // Return the buffer to pic channel for encoding.
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015974 mPictureChannel->returnYuvBufferAndEncode(outputBufferDef.get(),
15975 frameworkOutputBuffer->buffer, result->requestId,
Chien-Yu Chen92724a82017-01-06 11:50:30 -080015976 halMetadata);
15977 } else {
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015978 // Return the buffer to camera framework.
Chien-Yu Chen92724a82017-01-06 11:50:30 -080015979 pthread_mutex_lock(&mMutex);
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015980 handleBufferWithLock(frameworkOutputBuffer, result->requestId);
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015981 channel->unregisterBuffer(outputBufferDef.get());
Chien-Yu Chen0c8eaaa2017-09-19 14:13:14 -070015982 pthread_mutex_unlock(&mMutex);
Chien-Yu Chene687bd02016-12-07 18:30:26 -080015983 }
15984 }
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070015985
15986 // Send HDR+ metadata to framework.
15987 {
15988 pthread_mutex_lock(&mMutex);
15989
15990 // updatedResultMetadata will be freed in handlePendingResultMetadataWithLock.
15991 handlePendingResultMetadataWithLock(result->requestId, updatedResultMetadata);
15992 pthread_mutex_unlock(&mMutex);
15993 }
15994
15995 // Remove the HDR+ pending request.
15996 {
15997 Mutex::Autolock lock(mHdrPlusPendingRequestsLock);
15998 auto req = mHdrPlusPendingRequests.find(result->requestId);
15999 mHdrPlusPendingRequests.erase(req);
16000 }
Chien-Yu Chen8e599492016-11-01 13:37:46 -070016001}
16002
Chien-Yu Chen411e9c52017-05-08 11:58:50 -070016003void QCamera3HardwareInterface::onFailedCaptureResult(pbcamera::CaptureResult *failedResult)
16004{
16005 if (failedResult == nullptr) {
16006 ALOGE("%s: Got an empty failed result.", __FUNCTION__);
16007 return;
16008 }
Chien-Yu Chene687bd02016-12-07 18:30:26 -080016009
Chien-Yu Chen411e9c52017-05-08 11:58:50 -070016010 ALOGE("%s: Got a failed HDR+ result for request %d", __FUNCTION__, failedResult->requestId);
Chien-Yu Chene687bd02016-12-07 18:30:26 -080016011
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070016012 // Find the pending HDR+ request.
16013 HdrPlusPendingRequest pendingRequest;
Chien-Yu Chen411e9c52017-05-08 11:58:50 -070016014 {
16015 Mutex::Autolock lock(mHdrPlusPendingRequestsLock);
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070016016 auto req = mHdrPlusPendingRequests.find(failedResult->requestId);
16017 if (req == mHdrPlusPendingRequests.end()) {
16018 ALOGE("%s: Couldn't find pending request %d", __FUNCTION__, failedResult->requestId);
16019 return;
16020 }
16021 pendingRequest = req->second;
16022 }
Chien-Yu Chen411e9c52017-05-08 11:58:50 -070016023
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070016024 for (auto &outputBuffer : failedResult->outputBuffers) {
16025 uint32_t streamId = outputBuffer.streamId;
Chien-Yu Chen411e9c52017-05-08 11:58:50 -070016026
Chien-Yu Chen14d3e392017-07-10 18:27:05 -070016027 // Find the channel
16028 // Find the framework output buffer in the pending request.
16029 auto frameworkOutputBufferIter = pendingRequest.frameworkOutputBuffers.find(streamId);
16030 if (frameworkOutputBufferIter == pendingRequest.frameworkOutputBuffers.end()) {
16031 ALOGE("%s: Couldn't find framework output buffers for stream id %u", __FUNCTION__,
16032 streamId);
16033 continue;
16034 }
16035
16036 camera3_stream_buffer_t *frameworkOutputBuffer = &frameworkOutputBufferIter->second;
16037
16038 // Find the channel for the output buffer.
16039 QCamera3ProcessingChannel *channel =
16040 (QCamera3ProcessingChannel*)frameworkOutputBuffer->stream->priv;
16041
16042 // Find the output buffer def.
16043 auto outputBufferIter = pendingRequest.outputBuffers.find(streamId);
16044 if (outputBufferIter == pendingRequest.outputBuffers.end()) {
16045 ALOGE("%s: Cannot find output buffer", __FUNCTION__);
16046 continue;
16047 }
16048
16049 std::shared_ptr<mm_camera_buf_def_t> outputBufferDef = outputBufferIter->second;
16050
16051 if (channel == mPictureChannel) {
16052 // Return the buffer to pic channel.
16053 mPictureChannel->returnYuvBuffer(outputBufferDef.get());
16054 } else {
16055 channel->unregisterBuffer(outputBufferDef.get());
16056 }
16057 }
16058
16059 // Remove the HDR+ pending request.
16060 {
16061 Mutex::Autolock lock(mHdrPlusPendingRequestsLock);
16062 auto req = mHdrPlusPendingRequests.find(failedResult->requestId);
16063 mHdrPlusPendingRequests.erase(req);
Chien-Yu Chen411e9c52017-05-08 11:58:50 -070016064 }
16065
16066 pthread_mutex_lock(&mMutex);
16067
16068 // Find the pending buffers.
16069 auto pendingBuffers = mPendingBuffersMap.mPendingBuffersInRequest.begin();
16070 while (pendingBuffers != mPendingBuffersMap.mPendingBuffersInRequest.end()) {
16071 if (pendingBuffers->frame_number == failedResult->requestId) {
16072 break;
16073 }
16074 pendingBuffers++;
16075 }
16076
Chien-Yu Chen4fafc172017-11-13 16:14:50 -080016077 // Send out request errors for the pending buffers.
Chien-Yu Chen411e9c52017-05-08 11:58:50 -070016078 if (pendingBuffers != mPendingBuffersMap.mPendingBuffersInRequest.end()) {
16079 std::vector<camera3_stream_buffer_t> streamBuffers;
16080 for (auto &buffer : pendingBuffers->mPendingBufferList) {
16081 // Prepare a stream buffer.
16082 camera3_stream_buffer_t streamBuffer = {};
16083 streamBuffer.stream = buffer.stream;
16084 streamBuffer.buffer = buffer.buffer;
16085 streamBuffer.status = CAMERA3_BUFFER_STATUS_ERROR;
16086 streamBuffer.acquire_fence = -1;
16087 streamBuffer.release_fence = -1;
16088
Chien-Yu Chen4fafc172017-11-13 16:14:50 -080016089 // Send out request error event.
Chien-Yu Chen411e9c52017-05-08 11:58:50 -070016090 camera3_notify_msg_t notify_msg = {};
16091 notify_msg.type = CAMERA3_MSG_ERROR;
16092 notify_msg.message.error.frame_number = pendingBuffers->frame_number;
Chien-Yu Chen6ed36ca2017-10-02 11:22:17 -070016093 notify_msg.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
Chien-Yu Chen411e9c52017-05-08 11:58:50 -070016094 notify_msg.message.error.error_stream = buffer.stream;
16095
16096 orchestrateNotify(&notify_msg);
Chien-Yu Chen6ed36ca2017-10-02 11:22:17 -070016097 mOutputBufferDispatcher.markBufferReady(pendingBuffers->frame_number, streamBuffer);
Chien-Yu Chen411e9c52017-05-08 11:58:50 -070016098 }
16099
Chien-Yu Chen6ed36ca2017-10-02 11:22:17 -070016100 mShutterDispatcher.clear(pendingBuffers->frame_number);
Chien-Yu Chen411e9c52017-05-08 11:58:50 -070016101
Chien-Yu Chen6ed36ca2017-10-02 11:22:17 -070016102
Chien-Yu Chen411e9c52017-05-08 11:58:50 -070016103
16104 // Remove pending buffers.
16105 mPendingBuffersMap.mPendingBuffersInRequest.erase(pendingBuffers);
16106 }
16107
16108 // Remove pending request.
16109 auto halRequest = mPendingRequestsList.begin();
16110 while (halRequest != mPendingRequestsList.end()) {
16111 if (halRequest->frame_number == failedResult->requestId) {
16112 mPendingRequestsList.erase(halRequest);
16113 break;
16114 }
16115 halRequest++;
16116 }
16117
16118 pthread_mutex_unlock(&mMutex);
Chien-Yu Chen8e599492016-11-01 13:37:46 -070016119}
16120
Eino-Ville Talvala42d58952018-01-05 16:20:10 -080016121bool QCamera3HardwareInterface::readSensorCalibration(
16122 int activeArrayWidth,
16123 float poseRotation[4], float poseTranslation[3],
Eino-Ville Talvala7a8eefb2018-03-19 15:22:53 -070016124 float cameraIntrinsics[5], float radialDistortion[5]) {
Eino-Ville Talvala42d58952018-01-05 16:20:10 -080016125
16126 const char* calibrationPath = "/persist/sensors/calibration/calibration.xml";
16127
16128 using namespace tinyxml2;
16129
16130 XMLDocument calibrationXml;
16131 XMLError err = calibrationXml.LoadFile(calibrationPath);
16132 if (err != XML_SUCCESS) {
16133 ALOGE("Unable to load calibration file '%s'. Error: %s",
16134 calibrationPath, XMLDocument::ErrorIDToName(err));
16135 return false;
16136 }
16137 XMLElement *rig = calibrationXml.FirstChildElement("rig");
16138 if (rig == nullptr) {
16139 ALOGE("No 'rig' in calibration file");
16140 return false;
16141 }
16142 XMLElement *cam = rig->FirstChildElement("camera");
16143 XMLElement *camModel = nullptr;
16144 while (cam != nullptr) {
16145 camModel = cam->FirstChildElement("camera_model");
16146 if (camModel == nullptr) {
16147 ALOGE("No 'camera_model' in calibration file");
16148 return false;
16149 }
16150 int modelIndex = camModel->IntAttribute("index", -1);
16151 // Model index "0" has the calibration we need
16152 if (modelIndex == 0) {
16153 break;
16154 }
16155 cam = cam->NextSiblingElement("camera");
16156 }
16157 if (cam == nullptr) {
16158 ALOGE("No 'camera' in calibration file");
16159 return false;
16160 }
16161 const char *modelType = camModel->Attribute("type");
16162 if (modelType == nullptr || strcmp(modelType,"calibu_fu_fv_u0_v0_k1_k2_k3")) {
16163 ALOGE("Camera model is unknown type %s",
16164 modelType ? modelType : "NULL");
16165 return false;
16166 }
16167 XMLElement *modelWidth = camModel->FirstChildElement("width");
16168 if (modelWidth == nullptr || modelWidth->GetText() == nullptr) {
16169 ALOGE("No camera model width in calibration file");
16170 return false;
16171 }
16172 int width = atoi(modelWidth->GetText());
16173 XMLElement *modelHeight = camModel->FirstChildElement("height");
16174 if (modelHeight == nullptr || modelHeight->GetText() == nullptr) {
16175 ALOGE("No camera model height in calibration file");
16176 return false;
16177 }
16178 int height = atoi(modelHeight->GetText());
16179 if (width <= 0 || height <= 0) {
16180 ALOGE("Bad model width or height in calibration file: %d x %d", width, height);
16181 return false;
16182 }
16183 ALOGI("Width: %d, Height: %d", width, height);
16184
16185 XMLElement *modelParams = camModel->FirstChildElement("params");
16186 if (modelParams == nullptr) {
16187 ALOGE("No camera model params in calibration file");
16188 return false;
16189 }
16190 const char* paramText = modelParams->GetText();
16191 if (paramText == nullptr) {
16192 ALOGE("No parameters in params element in calibration file");
16193 return false;
16194 }
16195 ALOGI("Parameters: %s", paramText);
16196
16197 // Parameter string is of the form "[ float; float; float ...]"
16198 float params[7];
16199 bool success = parseStringArray(paramText, params, 7);
16200 if (!success) {
16201 ALOGE("Malformed camera parameter string in calibration file");
16202 return false;
16203 }
16204
16205 XMLElement *extCalib = rig->FirstChildElement("extrinsic_calibration");
16206 while (extCalib != nullptr) {
16207 int id = extCalib->IntAttribute("frame_B_id", -1);
16208 if (id == 0) {
16209 break;
16210 }
16211 extCalib = extCalib->NextSiblingElement("extrinsic_calibration");
16212 }
16213 if (extCalib == nullptr) {
16214 ALOGE("No 'extrinsic_calibration' in calibration file");
16215 return false;
16216 }
16217
16218 XMLElement *q = extCalib->FirstChildElement("A_q_B");
16219 if (q == nullptr || q->GetText() == nullptr) {
16220 ALOGE("No extrinsic quarternion in calibration file");
16221 return false;
16222 }
16223 float rotation[4];
16224 success = parseStringArray(q->GetText(), rotation, 4);
16225 if (!success) {
16226 ALOGE("Malformed extrinsic quarternion string in calibration file");
16227 return false;
16228 }
16229
16230 XMLElement *p = extCalib->FirstChildElement("A_p_B");
16231 if (p == nullptr || p->GetText() == nullptr) {
16232 ALOGE("No extrinsic translation in calibration file");
16233 return false;
16234 }
16235 float position[3];
16236 success = parseStringArray(p->GetText(), position, 3);
16237 if (!success) {
16238 ALOGE("Malformed extrinsic position string in calibration file");
16239 return false;
16240 }
16241
16242 // Map from width x height to active array
16243 float scaleFactor = static_cast<float>(activeArrayWidth) / width;
16244
16245 cameraIntrinsics[0] = params[0] * scaleFactor; // fu -> f_x
16246 cameraIntrinsics[1] = params[1] * scaleFactor; // fv -> f_y
16247 cameraIntrinsics[2] = params[2] * scaleFactor; // u0 -> c_x
16248 cameraIntrinsics[3] = params[3] * scaleFactor; // v0 -> c_y
16249 cameraIntrinsics[4] = 0; // s = 0
16250
Eino-Ville Talvala7a8eefb2018-03-19 15:22:53 -070016251 radialDistortion[0] = params[4]; // k1 -> k_1
16252 radialDistortion[1] = params[5]; // k2 -> k_2
16253 radialDistortion[2] = params[6]; // k3 -> k_3
16254 radialDistortion[3] = 0; // k_4 = 0
16255 radialDistortion[4] = 0; // k_5 = 0
Eino-Ville Talvala42d58952018-01-05 16:20:10 -080016256
16257 for (int i = 0; i < 4; i++) {
16258 poseRotation[i] = rotation[i];
16259 }
16260 for (int i = 0; i < 3; i++) {
16261 poseTranslation[i] = position[i];
16262 }
16263
16264 ALOGI("Intrinsics: %f, %f, %f, %f, %f", cameraIntrinsics[0],
16265 cameraIntrinsics[1], cameraIntrinsics[2],
16266 cameraIntrinsics[3], cameraIntrinsics[4]);
Eino-Ville Talvala7a8eefb2018-03-19 15:22:53 -070016267 ALOGI("Distortion: %f, %f, %f, %f, %f",
Eino-Ville Talvala42d58952018-01-05 16:20:10 -080016268 radialDistortion[0], radialDistortion[1], radialDistortion[2], radialDistortion[3],
Eino-Ville Talvala7a8eefb2018-03-19 15:22:53 -070016269 radialDistortion[4]);
Eino-Ville Talvala42d58952018-01-05 16:20:10 -080016270 ALOGI("Pose rotation: %f, %f, %f, %f",
16271 poseRotation[0], poseRotation[1], poseRotation[2], poseRotation[3]);
16272 ALOGI("Pose translation: %f, %f, %f",
16273 poseTranslation[0], poseTranslation[1], poseTranslation[2]);
16274
16275 return true;
16276}
16277
16278bool QCamera3HardwareInterface::parseStringArray(const char *str, float *dest, int count) {
16279 size_t idx = 0;
16280 size_t len = strlen(str);
16281 for (; idx < len; idx++) {
16282 if (str[idx] == '[') break;
16283 }
16284 const char *startParam = str + idx + 1;
16285 if (startParam >= str + len) {
16286 ALOGE("Malformed array: %s", str);
16287 return false;
16288 }
16289 char *endParam = nullptr;
16290 for (int i = 0; i < count; i++) {
16291 dest[i] = strtod(startParam, &endParam);
16292 if (startParam == endParam) {
16293 ALOGE("Malformed array, index %d: %s", i, str);
16294 return false;
16295 }
16296 startParam = endParam + 1;
16297 if (startParam >= str + len) {
16298 ALOGE("Malformed array, index %d: %s", i, str);
16299 return false;
16300 }
16301 }
16302 return true;
16303}
16304
Chien-Yu Chen3f303522017-05-19 15:21:45 -070016305ShutterDispatcher::ShutterDispatcher(QCamera3HardwareInterface *parent) :
16306 mParent(parent) {}
16307
Chien-Yu Chena7f98612017-06-20 16:54:10 -070016308void ShutterDispatcher::expectShutter(uint32_t frameNumber, bool isReprocess)
Chien-Yu Chen3f303522017-05-19 15:21:45 -070016309{
16310 std::lock_guard<std::mutex> lock(mLock);
Chien-Yu Chena7f98612017-06-20 16:54:10 -070016311
16312 if (isReprocess) {
16313 mReprocessShutters.emplace(frameNumber, Shutter());
16314 } else {
16315 mShutters.emplace(frameNumber, Shutter());
16316 }
Chien-Yu Chen3f303522017-05-19 15:21:45 -070016317}
16318
16319void ShutterDispatcher::markShutterReady(uint32_t frameNumber, uint64_t timestamp)
16320{
16321 std::lock_guard<std::mutex> lock(mLock);
16322
Chien-Yu Chena7f98612017-06-20 16:54:10 -070016323 std::map<uint32_t, Shutter> *shutters = nullptr;
16324
16325 // Find the shutter entry.
Chien-Yu Chen3f303522017-05-19 15:21:45 -070016326 auto shutter = mShutters.find(frameNumber);
16327 if (shutter == mShutters.end()) {
Chien-Yu Chena7f98612017-06-20 16:54:10 -070016328 shutter = mReprocessShutters.find(frameNumber);
16329 if (shutter == mReprocessShutters.end()) {
16330 // Shutter was already sent.
16331 return;
16332 }
16333 shutters = &mReprocessShutters;
16334 } else {
16335 shutters = &mShutters;
Chien-Yu Chen3f303522017-05-19 15:21:45 -070016336 }
16337
Chien-Yu Chen0469c9b2017-09-22 13:22:19 -070016338 if (shutter->second.ready) {
16339 // If shutter is already ready, don't update timestamp again.
16340 return;
16341 }
16342
Chien-Yu Chena7f98612017-06-20 16:54:10 -070016343 // Make this frame's shutter ready.
Chien-Yu Chen3f303522017-05-19 15:21:45 -070016344 shutter->second.ready = true;
16345 shutter->second.timestamp = timestamp;
16346
16347 // Iterate throught the shutters and send out shuters until the one that's not ready yet.
Chien-Yu Chena7f98612017-06-20 16:54:10 -070016348 shutter = shutters->begin();
16349 while (shutter != shutters->end()) {
Chien-Yu Chen3f303522017-05-19 15:21:45 -070016350 if (!shutter->second.ready) {
16351 // If this shutter is not ready, the following shutters can't be sent.
16352 break;
16353 }
16354
16355 camera3_notify_msg_t msg = {};
16356 msg.type = CAMERA3_MSG_SHUTTER;
16357 msg.message.shutter.frame_number = shutter->first;
16358 msg.message.shutter.timestamp = shutter->second.timestamp;
16359 mParent->orchestrateNotify(&msg);
16360
Chien-Yu Chena7f98612017-06-20 16:54:10 -070016361 shutter = shutters->erase(shutter);
Chien-Yu Chen3f303522017-05-19 15:21:45 -070016362 }
16363}
16364
16365void ShutterDispatcher::clear(uint32_t frameNumber)
16366{
16367 std::lock_guard<std::mutex> lock(mLock);
16368 mShutters.erase(frameNumber);
Chien-Yu Chena7f98612017-06-20 16:54:10 -070016369 mReprocessShutters.erase(frameNumber);
Chien-Yu Chen3f303522017-05-19 15:21:45 -070016370}
16371
16372void ShutterDispatcher::clear()
16373{
16374 std::lock_guard<std::mutex> lock(mLock);
16375
16376 // Log errors for stale shutters.
16377 for (auto &shutter : mShutters) {
16378 ALOGE("%s: stale shutter: frame number %u, ready %d, timestamp %" PRId64,
16379 __FUNCTION__, shutter.first, shutter.second.ready,
16380 shutter.second.timestamp);
16381 }
Chien-Yu Chena7f98612017-06-20 16:54:10 -070016382
16383 // Log errors for stale reprocess shutters.
16384 for (auto &shutter : mReprocessShutters) {
16385 ALOGE("%s: stale reprocess shutter: frame number %u, ready %d, timestamp %" PRId64,
16386 __FUNCTION__, shutter.first, shutter.second.ready,
16387 shutter.second.timestamp);
16388 }
16389
Chien-Yu Chen3f303522017-05-19 15:21:45 -070016390 mShutters.clear();
Chien-Yu Chena7f98612017-06-20 16:54:10 -070016391 mReprocessShutters.clear();
Chien-Yu Chen3f303522017-05-19 15:21:45 -070016392}
16393
16394OutputBufferDispatcher::OutputBufferDispatcher(QCamera3HardwareInterface *parent) :
16395 mParent(parent) {}
16396
16397status_t OutputBufferDispatcher::configureStreams(camera3_stream_configuration_t *streamList)
16398{
16399 std::lock_guard<std::mutex> lock(mLock);
16400 mStreamBuffers.clear();
16401 if (!streamList) {
16402 ALOGE("%s: streamList is nullptr.", __FUNCTION__);
16403 return -EINVAL;
16404 }
16405
16406 // Create a "frame-number -> buffer" map for each stream.
16407 for (uint32_t i = 0; i < streamList->num_streams; i++) {
16408 mStreamBuffers.emplace(streamList->streams[i], std::map<uint32_t, Buffer>());
16409 }
16410
16411 return OK;
16412}
16413
16414status_t OutputBufferDispatcher::expectBuffer(uint32_t frameNumber, camera3_stream_t *stream)
16415{
16416 std::lock_guard<std::mutex> lock(mLock);
16417
16418 // Find the "frame-number -> buffer" map for the stream.
16419 auto buffers = mStreamBuffers.find(stream);
16420 if (buffers == mStreamBuffers.end()) {
16421 ALOGE("%s: Stream %p was not configured.", __FUNCTION__, stream);
16422 return -EINVAL;
16423 }
16424
16425 // Create an unready buffer for this frame number.
16426 buffers->second.emplace(frameNumber, Buffer());
16427 return OK;
16428}
16429
16430void OutputBufferDispatcher::markBufferReady(uint32_t frameNumber,
16431 const camera3_stream_buffer_t &buffer)
16432{
16433 std::lock_guard<std::mutex> lock(mLock);
16434
16435 // Find the frame number -> buffer map for the stream.
16436 auto buffers = mStreamBuffers.find(buffer.stream);
16437 if (buffers == mStreamBuffers.end()) {
16438 ALOGE("%s: Cannot find pending buffers for stream %p.", __FUNCTION__, buffer.stream);
16439 return;
16440 }
16441
16442 // Find the unready buffer this frame number and mark it ready.
16443 auto pendingBuffer = buffers->second.find(frameNumber);
16444 if (pendingBuffer == buffers->second.end()) {
16445 ALOGE("%s: Cannot find the pending buffer for frame number %u.", __FUNCTION__, frameNumber);
16446 return;
16447 }
16448
16449 pendingBuffer->second.ready = true;
16450 pendingBuffer->second.buffer = buffer;
16451
16452 // Iterate through the buffers and send out buffers until the one that's not ready yet.
16453 pendingBuffer = buffers->second.begin();
16454 while (pendingBuffer != buffers->second.end()) {
16455 if (!pendingBuffer->second.ready) {
16456 // If this buffer is not ready, the following buffers can't be sent.
16457 break;
16458 }
16459
16460 camera3_capture_result_t result = {};
16461 result.frame_number = pendingBuffer->first;
16462 result.num_output_buffers = 1;
16463 result.output_buffers = &pendingBuffer->second.buffer;
16464
16465 // Send out result with buffer errors.
16466 mParent->orchestrateResult(&result);
16467
16468 pendingBuffer = buffers->second.erase(pendingBuffer);
16469 }
16470}
16471
16472void OutputBufferDispatcher::clear(bool clearConfiguredStreams)
16473{
16474 std::lock_guard<std::mutex> lock(mLock);
16475
16476 // Log errors for stale buffers.
16477 for (auto &buffers : mStreamBuffers) {
16478 for (auto &buffer : buffers.second) {
16479 ALOGE("%s: stale buffer: stream %p, frame number %u, ready %d",
16480 __FUNCTION__, buffers.first, buffer.first, buffer.second.ready);
16481 }
16482 buffers.second.clear();
16483 }
16484
16485 if (clearConfiguredStreams) {
16486 mStreamBuffers.clear();
16487 }
16488}
16489
Thierry Strudel3d639192016-09-09 11:52:26 -070016490}; //end namespace qcamera