blob: 1806e771944982b51d5bbe6906a5af37b09c6014 [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"
45#include <sync/sync.h>
46#include "gralloc_priv.h"
47
48// Display dependencies
49#include "qdMetaData.h"
50
51// Camera dependencies
52#include "android/QCamera3External.h"
53#include "util/QCameraFlash.h"
54#include "QCamera3HWI.h"
55#include "QCamera3VendorTags.h"
56#include "QCameraTrace.h"
57
58extern "C" {
59#include "mm_camera_dbg.h"
60}
61
62using namespace android;
63
64namespace qcamera {
65
66#define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX )
67
68#define EMPTY_PIPELINE_DELAY 2
69#define PARTIAL_RESULT_COUNT 2
70#define FRAME_SKIP_DELAY 0
71
72#define MAX_VALUE_8BIT ((1<<8)-1)
73#define MAX_VALUE_10BIT ((1<<10)-1)
74#define MAX_VALUE_12BIT ((1<<12)-1)
75
76#define VIDEO_4K_WIDTH 3840
77#define VIDEO_4K_HEIGHT 2160
78
79#define MAX_EIS_WIDTH 1920
80#define MAX_EIS_HEIGHT 1080
81
82#define MAX_RAW_STREAMS 1
83#define MAX_STALLING_STREAMS 1
84#define MAX_PROCESSED_STREAMS 3
85/* Batch mode is enabled only if FPS set is equal to or greater than this */
86#define MIN_FPS_FOR_BATCH_MODE (120)
87#define PREVIEW_FPS_FOR_HFR (30)
88#define DEFAULT_VIDEO_FPS (30.0)
89#define MAX_HFR_BATCH_SIZE (8)
90#define REGIONS_TUPLE_COUNT 5
91#define HDR_PLUS_PERF_TIME_OUT (7000) // milliseconds
Thierry Strudel3d639192016-09-09 11:52:26 -070092// Set a threshold for detection of missing buffers //seconds
93#define MISSING_REQUEST_BUF_TIMEOUT 3
94#define FLUSH_TIMEOUT 3
95#define METADATA_MAP_SIZE(MAP) (sizeof(MAP)/sizeof(MAP[0]))
96
97#define CAM_QCOM_FEATURE_PP_SUPERSET_HAL3 ( CAM_QCOM_FEATURE_DENOISE2D |\
98 CAM_QCOM_FEATURE_CROP |\
99 CAM_QCOM_FEATURE_ROTATION |\
100 CAM_QCOM_FEATURE_SHARPNESS |\
101 CAM_QCOM_FEATURE_SCALE |\
102 CAM_QCOM_FEATURE_CAC |\
103 CAM_QCOM_FEATURE_CDS )
Thierry Strudel9e74aae2016-09-22 17:10:18 -0700104/* Per configuration size for static metadata length*/
105#define PER_CONFIGURATION_SIZE_3 (3)
Thierry Strudel3d639192016-09-09 11:52:26 -0700106
107#define TIMEOUT_NEVER -1
108
109cam_capability_t *gCamCapability[MM_CAMERA_MAX_NUM_SENSORS];
110const camera_metadata_t *gStaticMetadata[MM_CAMERA_MAX_NUM_SENSORS];
111extern pthread_mutex_t gCamLock;
112volatile uint32_t gCamHal3LogLevel = 1;
113extern uint8_t gNumCameraSessions;
114
115const QCamera3HardwareInterface::QCameraPropMap QCamera3HardwareInterface::CDS_MAP [] = {
116 {"On", CAM_CDS_MODE_ON},
117 {"Off", CAM_CDS_MODE_OFF},
118 {"Auto",CAM_CDS_MODE_AUTO}
119};
120
121const QCamera3HardwareInterface::QCameraMap<
122 camera_metadata_enum_android_control_effect_mode_t,
123 cam_effect_mode_type> QCamera3HardwareInterface::EFFECT_MODES_MAP[] = {
124 { ANDROID_CONTROL_EFFECT_MODE_OFF, CAM_EFFECT_MODE_OFF },
125 { ANDROID_CONTROL_EFFECT_MODE_MONO, CAM_EFFECT_MODE_MONO },
126 { ANDROID_CONTROL_EFFECT_MODE_NEGATIVE, CAM_EFFECT_MODE_NEGATIVE },
127 { ANDROID_CONTROL_EFFECT_MODE_SOLARIZE, CAM_EFFECT_MODE_SOLARIZE },
128 { ANDROID_CONTROL_EFFECT_MODE_SEPIA, CAM_EFFECT_MODE_SEPIA },
129 { ANDROID_CONTROL_EFFECT_MODE_POSTERIZE, CAM_EFFECT_MODE_POSTERIZE },
130 { ANDROID_CONTROL_EFFECT_MODE_WHITEBOARD, CAM_EFFECT_MODE_WHITEBOARD },
131 { ANDROID_CONTROL_EFFECT_MODE_BLACKBOARD, CAM_EFFECT_MODE_BLACKBOARD },
132 { ANDROID_CONTROL_EFFECT_MODE_AQUA, CAM_EFFECT_MODE_AQUA }
133};
134
135const QCamera3HardwareInterface::QCameraMap<
136 camera_metadata_enum_android_control_awb_mode_t,
137 cam_wb_mode_type> QCamera3HardwareInterface::WHITE_BALANCE_MODES_MAP[] = {
138 { ANDROID_CONTROL_AWB_MODE_OFF, CAM_WB_MODE_OFF },
139 { ANDROID_CONTROL_AWB_MODE_AUTO, CAM_WB_MODE_AUTO },
140 { ANDROID_CONTROL_AWB_MODE_INCANDESCENT, CAM_WB_MODE_INCANDESCENT },
141 { ANDROID_CONTROL_AWB_MODE_FLUORESCENT, CAM_WB_MODE_FLUORESCENT },
142 { ANDROID_CONTROL_AWB_MODE_WARM_FLUORESCENT,CAM_WB_MODE_WARM_FLUORESCENT},
143 { ANDROID_CONTROL_AWB_MODE_DAYLIGHT, CAM_WB_MODE_DAYLIGHT },
144 { ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT, CAM_WB_MODE_CLOUDY_DAYLIGHT },
145 { ANDROID_CONTROL_AWB_MODE_TWILIGHT, CAM_WB_MODE_TWILIGHT },
146 { ANDROID_CONTROL_AWB_MODE_SHADE, CAM_WB_MODE_SHADE }
147};
148
149const QCamera3HardwareInterface::QCameraMap<
150 camera_metadata_enum_android_control_scene_mode_t,
151 cam_scene_mode_type> QCamera3HardwareInterface::SCENE_MODES_MAP[] = {
152 { ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY, CAM_SCENE_MODE_FACE_PRIORITY },
153 { ANDROID_CONTROL_SCENE_MODE_ACTION, CAM_SCENE_MODE_ACTION },
154 { ANDROID_CONTROL_SCENE_MODE_PORTRAIT, CAM_SCENE_MODE_PORTRAIT },
155 { ANDROID_CONTROL_SCENE_MODE_LANDSCAPE, CAM_SCENE_MODE_LANDSCAPE },
156 { ANDROID_CONTROL_SCENE_MODE_NIGHT, CAM_SCENE_MODE_NIGHT },
157 { ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT, CAM_SCENE_MODE_NIGHT_PORTRAIT },
158 { ANDROID_CONTROL_SCENE_MODE_THEATRE, CAM_SCENE_MODE_THEATRE },
159 { ANDROID_CONTROL_SCENE_MODE_BEACH, CAM_SCENE_MODE_BEACH },
160 { ANDROID_CONTROL_SCENE_MODE_SNOW, CAM_SCENE_MODE_SNOW },
161 { ANDROID_CONTROL_SCENE_MODE_SUNSET, CAM_SCENE_MODE_SUNSET },
162 { ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO, CAM_SCENE_MODE_ANTISHAKE },
163 { ANDROID_CONTROL_SCENE_MODE_FIREWORKS , CAM_SCENE_MODE_FIREWORKS },
164 { ANDROID_CONTROL_SCENE_MODE_SPORTS , CAM_SCENE_MODE_SPORTS },
165 { ANDROID_CONTROL_SCENE_MODE_PARTY, CAM_SCENE_MODE_PARTY },
166 { ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT, CAM_SCENE_MODE_CANDLELIGHT },
167 { ANDROID_CONTROL_SCENE_MODE_BARCODE, CAM_SCENE_MODE_BARCODE}
168};
169
170const QCamera3HardwareInterface::QCameraMap<
171 camera_metadata_enum_android_control_af_mode_t,
172 cam_focus_mode_type> QCamera3HardwareInterface::FOCUS_MODES_MAP[] = {
173 { ANDROID_CONTROL_AF_MODE_OFF, CAM_FOCUS_MODE_OFF },
174 { ANDROID_CONTROL_AF_MODE_OFF, CAM_FOCUS_MODE_FIXED },
175 { ANDROID_CONTROL_AF_MODE_AUTO, CAM_FOCUS_MODE_AUTO },
176 { ANDROID_CONTROL_AF_MODE_MACRO, CAM_FOCUS_MODE_MACRO },
177 { ANDROID_CONTROL_AF_MODE_EDOF, CAM_FOCUS_MODE_EDOF },
178 { ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE, CAM_FOCUS_MODE_CONTINOUS_PICTURE },
179 { ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO, CAM_FOCUS_MODE_CONTINOUS_VIDEO }
180};
181
182const QCamera3HardwareInterface::QCameraMap<
183 camera_metadata_enum_android_color_correction_aberration_mode_t,
184 cam_aberration_mode_t> QCamera3HardwareInterface::COLOR_ABERRATION_MAP[] = {
185 { ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF,
186 CAM_COLOR_CORRECTION_ABERRATION_OFF },
187 { ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST,
188 CAM_COLOR_CORRECTION_ABERRATION_FAST },
189 { ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY,
190 CAM_COLOR_CORRECTION_ABERRATION_HIGH_QUALITY },
191};
192
193const QCamera3HardwareInterface::QCameraMap<
194 camera_metadata_enum_android_control_ae_antibanding_mode_t,
195 cam_antibanding_mode_type> QCamera3HardwareInterface::ANTIBANDING_MODES_MAP[] = {
196 { ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF, CAM_ANTIBANDING_MODE_OFF },
197 { ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ, CAM_ANTIBANDING_MODE_50HZ },
198 { ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ, CAM_ANTIBANDING_MODE_60HZ },
199 { ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO, CAM_ANTIBANDING_MODE_AUTO }
200};
201
202const QCamera3HardwareInterface::QCameraMap<
203 camera_metadata_enum_android_control_ae_mode_t,
204 cam_flash_mode_t> QCamera3HardwareInterface::AE_FLASH_MODE_MAP[] = {
205 { ANDROID_CONTROL_AE_MODE_OFF, CAM_FLASH_MODE_OFF },
206 { ANDROID_CONTROL_AE_MODE_ON, CAM_FLASH_MODE_OFF },
207 { ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH, CAM_FLASH_MODE_AUTO},
208 { ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH, CAM_FLASH_MODE_ON },
209 { ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE, CAM_FLASH_MODE_AUTO}
210};
211
212const QCamera3HardwareInterface::QCameraMap<
213 camera_metadata_enum_android_flash_mode_t,
214 cam_flash_mode_t> QCamera3HardwareInterface::FLASH_MODES_MAP[] = {
215 { ANDROID_FLASH_MODE_OFF, CAM_FLASH_MODE_OFF },
216 { ANDROID_FLASH_MODE_SINGLE, CAM_FLASH_MODE_SINGLE },
217 { ANDROID_FLASH_MODE_TORCH, CAM_FLASH_MODE_TORCH }
218};
219
220const QCamera3HardwareInterface::QCameraMap<
221 camera_metadata_enum_android_statistics_face_detect_mode_t,
222 cam_face_detect_mode_t> QCamera3HardwareInterface::FACEDETECT_MODES_MAP[] = {
223 { ANDROID_STATISTICS_FACE_DETECT_MODE_OFF, CAM_FACE_DETECT_MODE_OFF },
224 { ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE, CAM_FACE_DETECT_MODE_SIMPLE },
225 { ANDROID_STATISTICS_FACE_DETECT_MODE_FULL, CAM_FACE_DETECT_MODE_FULL }
226};
227
228const QCamera3HardwareInterface::QCameraMap<
229 camera_metadata_enum_android_lens_info_focus_distance_calibration_t,
230 cam_focus_calibration_t> QCamera3HardwareInterface::FOCUS_CALIBRATION_MAP[] = {
231 { ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED,
232 CAM_FOCUS_UNCALIBRATED },
233 { ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE,
234 CAM_FOCUS_APPROXIMATE },
235 { ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED,
236 CAM_FOCUS_CALIBRATED }
237};
238
239const QCamera3HardwareInterface::QCameraMap<
240 camera_metadata_enum_android_lens_state_t,
241 cam_af_lens_state_t> QCamera3HardwareInterface::LENS_STATE_MAP[] = {
242 { ANDROID_LENS_STATE_STATIONARY, CAM_AF_LENS_STATE_STATIONARY},
243 { ANDROID_LENS_STATE_MOVING, CAM_AF_LENS_STATE_MOVING}
244};
245
246const int32_t available_thumbnail_sizes[] = {0, 0,
247 176, 144,
248 240, 144,
249 256, 144,
250 240, 160,
251 256, 154,
252 240, 240,
253 320, 240};
254
255const QCamera3HardwareInterface::QCameraMap<
256 camera_metadata_enum_android_sensor_test_pattern_mode_t,
257 cam_test_pattern_mode_t> QCamera3HardwareInterface::TEST_PATTERN_MAP[] = {
258 { ANDROID_SENSOR_TEST_PATTERN_MODE_OFF, CAM_TEST_PATTERN_OFF },
259 { ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR, CAM_TEST_PATTERN_SOLID_COLOR },
260 { ANDROID_SENSOR_TEST_PATTERN_MODE_COLOR_BARS, CAM_TEST_PATTERN_COLOR_BARS },
261 { ANDROID_SENSOR_TEST_PATTERN_MODE_COLOR_BARS_FADE_TO_GRAY, CAM_TEST_PATTERN_COLOR_BARS_FADE_TO_GRAY },
262 { ANDROID_SENSOR_TEST_PATTERN_MODE_PN9, CAM_TEST_PATTERN_PN9 },
263 { ANDROID_SENSOR_TEST_PATTERN_MODE_CUSTOM1, CAM_TEST_PATTERN_CUSTOM1},
264};
265
266/* Since there is no mapping for all the options some Android enum are not listed.
267 * Also, the order in this list is important because while mapping from HAL to Android it will
268 * traverse from lower to higher index which means that for HAL values that are map to different
269 * Android values, the traverse logic will select the first one found.
270 */
271const QCamera3HardwareInterface::QCameraMap<
272 camera_metadata_enum_android_sensor_reference_illuminant1_t,
273 cam_illuminat_t> QCamera3HardwareInterface::REFERENCE_ILLUMINANT_MAP[] = {
274 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_FLUORESCENT, CAM_AWB_WARM_FLO},
275 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT_FLUORESCENT, CAM_AWB_CUSTOM_DAYLIGHT },
276 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_COOL_WHITE_FLUORESCENT, CAM_AWB_COLD_FLO },
277 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_STANDARD_A, CAM_AWB_A },
278 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_D55, CAM_AWB_NOON },
279 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_D65, CAM_AWB_D65 },
280 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_D75, CAM_AWB_D75 },
281 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_D50, CAM_AWB_D50 },
282 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_ISO_STUDIO_TUNGSTEN, CAM_AWB_CUSTOM_A},
283 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT, CAM_AWB_D50 },
284 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_TUNGSTEN, CAM_AWB_A },
285 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_FINE_WEATHER, CAM_AWB_D50 },
286 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_CLOUDY_WEATHER, CAM_AWB_D65 },
287 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_SHADE, CAM_AWB_D75 },
288 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_DAY_WHITE_FLUORESCENT, CAM_AWB_CUSTOM_DAYLIGHT },
289 { ANDROID_SENSOR_REFERENCE_ILLUMINANT1_WHITE_FLUORESCENT, CAM_AWB_COLD_FLO},
290};
291
292const QCamera3HardwareInterface::QCameraMap<
293 int32_t, cam_hfr_mode_t> QCamera3HardwareInterface::HFR_MODE_MAP[] = {
294 { 60, CAM_HFR_MODE_60FPS},
295 { 90, CAM_HFR_MODE_90FPS},
296 { 120, CAM_HFR_MODE_120FPS},
297 { 150, CAM_HFR_MODE_150FPS},
298 { 180, CAM_HFR_MODE_180FPS},
299 { 210, CAM_HFR_MODE_210FPS},
300 { 240, CAM_HFR_MODE_240FPS},
301 { 480, CAM_HFR_MODE_480FPS},
302};
303
304camera3_device_ops_t QCamera3HardwareInterface::mCameraOps = {
305 .initialize = QCamera3HardwareInterface::initialize,
306 .configure_streams = QCamera3HardwareInterface::configure_streams,
307 .register_stream_buffers = NULL,
308 .construct_default_request_settings = QCamera3HardwareInterface::construct_default_request_settings,
309 .process_capture_request = QCamera3HardwareInterface::process_capture_request,
310 .get_metadata_vendor_tag_ops = NULL,
311 .dump = QCamera3HardwareInterface::dump,
312 .flush = QCamera3HardwareInterface::flush,
313 .reserved = {0},
314};
315
316// initialise to some default value
317uint32_t QCamera3HardwareInterface::sessionId[] = {0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF};
318
319/*===========================================================================
320 * FUNCTION : QCamera3HardwareInterface
321 *
322 * DESCRIPTION: constructor of QCamera3HardwareInterface
323 *
324 * PARAMETERS :
325 * @cameraId : camera ID
326 *
327 * RETURN : none
328 *==========================================================================*/
329QCamera3HardwareInterface::QCamera3HardwareInterface(uint32_t cameraId,
330 const camera_module_callbacks_t *callbacks)
331 : mCameraId(cameraId),
332 mCameraHandle(NULL),
333 mCameraInitialized(false),
334 mCallbackOps(NULL),
335 mMetadataChannel(NULL),
336 mPictureChannel(NULL),
337 mRawChannel(NULL),
338 mSupportChannel(NULL),
339 mAnalysisChannel(NULL),
340 mRawDumpChannel(NULL),
341 mDummyBatchChannel(NULL),
342 m_perfLock(),
343 mCommon(),
344 mChannelHandle(0),
345 mFirstConfiguration(true),
346 mFlush(false),
347 mFlushPerf(false),
348 mParamHeap(NULL),
349 mParameters(NULL),
350 mPrevParameters(NULL),
351 m_bIsVideo(false),
352 m_bIs4KVideo(false),
353 m_bEisSupportedSize(false),
354 m_bEisEnable(false),
355 m_MobicatMask(0),
356 mMinProcessedFrameDuration(0),
357 mMinJpegFrameDuration(0),
358 mMinRawFrameDuration(0),
359 mMetaFrameCount(0U),
360 mUpdateDebugLevel(false),
361 mCallbacks(callbacks),
362 mCaptureIntent(0),
363 mCacMode(0),
364 mBatchSize(0),
365 mToBeQueuedVidBufs(0),
366 mHFRVideoFps(DEFAULT_VIDEO_FPS),
367 mOpMode(CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE),
368 mFirstFrameNumberInBatch(0),
369 mNeedSensorRestart(false),
Thierry Strudel9e74aae2016-09-22 17:10:18 -0700370 mMinInFlightRequests(MIN_INFLIGHT_REQUESTS),
371 mMaxInFlightRequests(MAX_INFLIGHT_REQUESTS),
Thierry Strudel3d639192016-09-09 11:52:26 -0700372 mLdafCalibExist(false),
373 mPowerHintEnabled(false),
374 mLastCustIntentFrmNum(-1),
375 mState(CLOSED),
376 mIsDeviceLinked(false),
377 mIsMainCamera(true),
378 mLinkedCameraId(0),
379 m_pRelCamSyncHeap(NULL),
380 m_pRelCamSyncBuf(NULL)
381{
382 getLogLevel();
383 m_perfLock.lock_init();
384 mCommon.init(gCamCapability[cameraId]);
385 mCameraDevice.common.tag = HARDWARE_DEVICE_TAG;
Thierry Strudel9e74aae2016-09-22 17:10:18 -0700386#ifndef USE_HAL_3_3
387 mCameraDevice.common.version = CAMERA_DEVICE_API_VERSION_3_4;
388#else
Thierry Strudel3d639192016-09-09 11:52:26 -0700389 mCameraDevice.common.version = CAMERA_DEVICE_API_VERSION_3_3;
Thierry Strudel9e74aae2016-09-22 17:10:18 -0700390#endif
Thierry Strudel3d639192016-09-09 11:52:26 -0700391 mCameraDevice.common.close = close_camera_device;
392 mCameraDevice.ops = &mCameraOps;
393 mCameraDevice.priv = this;
394 gCamCapability[cameraId]->version = CAM_HAL_V3;
395 // TODO: hardcode for now until mctl add support for min_num_pp_bufs
396 //TBD - To see if this hardcoding is needed. Check by printing if this is filled by mctl to 3
397 gCamCapability[cameraId]->min_num_pp_bufs = 3;
398
399 pthread_cond_init(&mBuffersCond, NULL);
400
401 pthread_cond_init(&mRequestCond, NULL);
402 mPendingLiveRequest = 0;
403 mCurrentRequestId = -1;
404 pthread_mutex_init(&mMutex, NULL);
405
406 for (size_t i = 0; i < CAMERA3_TEMPLATE_COUNT; i++)
407 mDefaultMetadata[i] = NULL;
408
409 // Getting system props of different kinds
410 char prop[PROPERTY_VALUE_MAX];
411 memset(prop, 0, sizeof(prop));
412 property_get("persist.camera.raw.dump", prop, "0");
413 mEnableRawDump = atoi(prop);
414 if (mEnableRawDump)
415 LOGD("Raw dump from Camera HAL enabled");
416
417 memset(&mInputStreamInfo, 0, sizeof(mInputStreamInfo));
418 memset(mLdafCalib, 0, sizeof(mLdafCalib));
419
420 memset(prop, 0, sizeof(prop));
421 property_get("persist.camera.tnr.preview", prop, "0");
422 m_bTnrPreview = (uint8_t)atoi(prop);
423
424 memset(prop, 0, sizeof(prop));
425 property_get("persist.camera.tnr.video", prop, "0");
426 m_bTnrVideo = (uint8_t)atoi(prop);
427
428 memset(prop, 0, sizeof(prop));
429 property_get("persist.camera.avtimer.debug", prop, "0");
430 m_debug_avtimer = (uint8_t)atoi(prop);
431
432 //Load and read GPU library.
433 lib_surface_utils = NULL;
434 LINK_get_surface_pixel_alignment = NULL;
435 mSurfaceStridePadding = CAM_PAD_TO_32;
436 lib_surface_utils = dlopen("libadreno_utils.so", RTLD_NOW);
437 if (lib_surface_utils) {
438 *(void **)&LINK_get_surface_pixel_alignment =
439 dlsym(lib_surface_utils, "get_gpu_pixel_alignment");
440 if (LINK_get_surface_pixel_alignment) {
441 mSurfaceStridePadding = LINK_get_surface_pixel_alignment();
442 }
443 dlclose(lib_surface_utils);
444 }
445}
446
447/*===========================================================================
448 * FUNCTION : ~QCamera3HardwareInterface
449 *
450 * DESCRIPTION: destructor of QCamera3HardwareInterface
451 *
452 * PARAMETERS : none
453 *
454 * RETURN : none
455 *==========================================================================*/
456QCamera3HardwareInterface::~QCamera3HardwareInterface()
457{
458 LOGD("E");
459
460 /* Turn off current power hint before acquiring perfLock in case they
461 * conflict with each other */
462 disablePowerHint();
463
464 m_perfLock.lock_acq();
465
466 /* We need to stop all streams before deleting any stream */
467 if (mRawDumpChannel) {
468 mRawDumpChannel->stop();
469 }
470
471 // NOTE: 'camera3_stream_t *' objects are already freed at
472 // this stage by the framework
473 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
474 it != mStreamInfo.end(); it++) {
475 QCamera3ProcessingChannel *channel = (*it)->channel;
476 if (channel) {
477 channel->stop();
478 }
479 }
480 if (mSupportChannel)
481 mSupportChannel->stop();
482
483 if (mAnalysisChannel) {
484 mAnalysisChannel->stop();
485 }
486 if (mMetadataChannel) {
487 mMetadataChannel->stop();
488 }
489 if (mChannelHandle) {
490 mCameraHandle->ops->stop_channel(mCameraHandle->camera_handle,
491 mChannelHandle);
492 LOGD("stopping channel %d", mChannelHandle);
493 }
494
495 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
496 it != mStreamInfo.end(); it++) {
497 QCamera3ProcessingChannel *channel = (*it)->channel;
498 if (channel)
499 delete channel;
500 free (*it);
501 }
502 if (mSupportChannel) {
503 delete mSupportChannel;
504 mSupportChannel = NULL;
505 }
506
507 if (mAnalysisChannel) {
508 delete mAnalysisChannel;
509 mAnalysisChannel = NULL;
510 }
511 if (mRawDumpChannel) {
512 delete mRawDumpChannel;
513 mRawDumpChannel = NULL;
514 }
515 if (mDummyBatchChannel) {
516 delete mDummyBatchChannel;
517 mDummyBatchChannel = NULL;
518 }
519
520 mPictureChannel = NULL;
521
522 if (mMetadataChannel) {
523 delete mMetadataChannel;
524 mMetadataChannel = NULL;
525 }
526
527 /* Clean up all channels */
528 if (mCameraInitialized) {
529 if(!mFirstConfiguration){
530 //send the last unconfigure
531 cam_stream_size_info_t stream_config_info;
532 memset(&stream_config_info, 0, sizeof(cam_stream_size_info_t));
533 stream_config_info.buffer_info.min_buffers = MIN_INFLIGHT_REQUESTS;
534 stream_config_info.buffer_info.max_buffers =
535 m_bIs4KVideo ? 0 : MAX_INFLIGHT_REQUESTS;
Thierry Strudel9e74aae2016-09-22 17:10:18 -0700536 clear_metadata_buffer(mParameters);
Thierry Strudel3d639192016-09-09 11:52:26 -0700537 ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_META_STREAM_INFO,
538 stream_config_info);
539 int rc = mCameraHandle->ops->set_parms(mCameraHandle->camera_handle, mParameters);
540 if (rc < 0) {
541 LOGE("set_parms failed for unconfigure");
542 }
543 }
544 deinitParameters();
545 }
546
547 if (mChannelHandle) {
548 mCameraHandle->ops->delete_channel(mCameraHandle->camera_handle,
549 mChannelHandle);
550 LOGH("deleting channel %d", mChannelHandle);
551 mChannelHandle = 0;
552 }
553
554 if (mState != CLOSED)
555 closeCamera();
556
557 for (auto &req : mPendingBuffersMap.mPendingBuffersInRequest) {
558 req.mPendingBufferList.clear();
559 }
560 mPendingBuffersMap.mPendingBuffersInRequest.clear();
561 mPendingReprocessResultList.clear();
562 for (pendingRequestIterator i = mPendingRequestsList.begin();
563 i != mPendingRequestsList.end();) {
564 i = erasePendingRequest(i);
565 }
566 for (size_t i = 0; i < CAMERA3_TEMPLATE_COUNT; i++)
567 if (mDefaultMetadata[i])
568 free_camera_metadata(mDefaultMetadata[i]);
569
570 m_perfLock.lock_rel();
571 m_perfLock.lock_deinit();
572
573 pthread_cond_destroy(&mRequestCond);
574
575 pthread_cond_destroy(&mBuffersCond);
576
577 pthread_mutex_destroy(&mMutex);
578 LOGD("X");
579}
580
581/*===========================================================================
582 * FUNCTION : erasePendingRequest
583 *
584 * DESCRIPTION: function to erase a desired pending request after freeing any
585 * allocated memory
586 *
587 * PARAMETERS :
588 * @i : iterator pointing to pending request to be erased
589 *
590 * RETURN : iterator pointing to the next request
591 *==========================================================================*/
592QCamera3HardwareInterface::pendingRequestIterator
593 QCamera3HardwareInterface::erasePendingRequest (pendingRequestIterator i)
594{
595 if (i->input_buffer != NULL) {
596 free(i->input_buffer);
597 i->input_buffer = NULL;
598 }
599 if (i->settings != NULL)
600 free_camera_metadata((camera_metadata_t*)i->settings);
601 return mPendingRequestsList.erase(i);
602}
603
604/*===========================================================================
605 * FUNCTION : camEvtHandle
606 *
607 * DESCRIPTION: Function registered to mm-camera-interface to handle events
608 *
609 * PARAMETERS :
610 * @camera_handle : interface layer camera handle
611 * @evt : ptr to event
612 * @user_data : user data ptr
613 *
614 * RETURN : none
615 *==========================================================================*/
616void QCamera3HardwareInterface::camEvtHandle(uint32_t /*camera_handle*/,
617 mm_camera_event_t *evt,
618 void *user_data)
619{
620 QCamera3HardwareInterface *obj = (QCamera3HardwareInterface *)user_data;
621 if (obj && evt) {
622 switch(evt->server_event_type) {
623 case CAM_EVENT_TYPE_DAEMON_DIED:
624 pthread_mutex_lock(&obj->mMutex);
625 obj->mState = ERROR;
626 pthread_mutex_unlock(&obj->mMutex);
627 LOGE("Fatal, camera daemon died");
628 break;
629
630 case CAM_EVENT_TYPE_DAEMON_PULL_REQ:
631 LOGD("HAL got request pull from Daemon");
632 pthread_mutex_lock(&obj->mMutex);
633 obj->mWokenUpByDaemon = true;
634 obj->unblockRequestIfNecessary();
635 pthread_mutex_unlock(&obj->mMutex);
636 break;
637
638 default:
639 LOGW("Warning: Unhandled event %d",
640 evt->server_event_type);
641 break;
642 }
643 } else {
644 LOGE("NULL user_data/evt");
645 }
646}
647
648/*===========================================================================
649 * FUNCTION : openCamera
650 *
651 * DESCRIPTION: open camera
652 *
653 * PARAMETERS :
654 * @hw_device : double ptr for camera device struct
655 *
656 * RETURN : int32_t type of status
657 * NO_ERROR -- success
658 * none-zero failure code
659 *==========================================================================*/
660int QCamera3HardwareInterface::openCamera(struct hw_device_t **hw_device)
661{
662 int rc = 0;
663 if (mState != CLOSED) {
664 *hw_device = NULL;
665 return PERMISSION_DENIED;
666 }
667
668 m_perfLock.lock_acq();
669 LOGI("[KPI Perf]: E PROFILE_OPEN_CAMERA camera id %d",
670 mCameraId);
671
672 rc = openCamera();
673 if (rc == 0) {
674 *hw_device = &mCameraDevice.common;
675 } else
676 *hw_device = NULL;
677
678 m_perfLock.lock_rel();
679 LOGI("[KPI Perf]: X PROFILE_OPEN_CAMERA camera id %d, rc: %d",
680 mCameraId, rc);
681
682 if (rc == NO_ERROR) {
683 mState = OPENED;
684 }
685 return rc;
686}
687
688/*===========================================================================
689 * FUNCTION : openCamera
690 *
691 * DESCRIPTION: open camera
692 *
693 * PARAMETERS : none
694 *
695 * RETURN : int32_t type of status
696 * NO_ERROR -- success
697 * none-zero failure code
698 *==========================================================================*/
699int QCamera3HardwareInterface::openCamera()
700{
701 int rc = 0;
702 char value[PROPERTY_VALUE_MAX];
703
704 KPI_ATRACE_CALL();
705 if (mCameraHandle) {
706 LOGE("Failure: Camera already opened");
707 return ALREADY_EXISTS;
708 }
709
710 rc = QCameraFlash::getInstance().reserveFlashForCamera(mCameraId);
711 if (rc < 0) {
712 LOGE("Failed to reserve flash for camera id: %d",
713 mCameraId);
714 return UNKNOWN_ERROR;
715 }
716
717 rc = camera_open((uint8_t)mCameraId, &mCameraHandle);
718 if (rc) {
719 LOGE("camera_open failed. rc = %d, mCameraHandle = %p", rc, mCameraHandle);
720 return rc;
721 }
722
723 if (!mCameraHandle) {
724 LOGE("camera_open failed. mCameraHandle = %p", mCameraHandle);
725 return -ENODEV;
726 }
727
728 rc = mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
729 camEvtHandle, (void *)this);
730
731 if (rc < 0) {
732 LOGE("Error, failed to register event callback");
733 /* Not closing camera here since it is already handled in destructor */
734 return FAILED_TRANSACTION;
735 }
736
737 mExifParams.debug_params =
738 (mm_jpeg_debug_exif_params_t *) malloc (sizeof(mm_jpeg_debug_exif_params_t));
739 if (mExifParams.debug_params) {
740 memset(mExifParams.debug_params, 0, sizeof(mm_jpeg_debug_exif_params_t));
741 } else {
742 LOGE("Out of Memory. Allocation failed for 3A debug exif params");
743 return NO_MEMORY;
744 }
745 mFirstConfiguration = true;
746
747 //Notify display HAL that a camera session is active.
748 //But avoid calling the same during bootup because camera service might open/close
749 //cameras at boot time during its initialization and display service will also internally
750 //wait for camera service to initialize first while calling this display API, resulting in a
751 //deadlock situation. Since boot time camera open/close calls are made only to fetch
752 //capabilities, no need of this display bw optimization.
753 //Use "service.bootanim.exit" property to know boot status.
754 property_get("service.bootanim.exit", value, "0");
755 if (atoi(value) == 1) {
756 pthread_mutex_lock(&gCamLock);
757 if (gNumCameraSessions++ == 0) {
758 setCameraLaunchStatus(true);
759 }
760 pthread_mutex_unlock(&gCamLock);
761 }
762
763 //fill the session id needed while linking dual cam
764 pthread_mutex_lock(&gCamLock);
765 rc = mCameraHandle->ops->get_session_id(mCameraHandle->camera_handle,
766 &sessionId[mCameraId]);
767 pthread_mutex_unlock(&gCamLock);
768
769 if (rc < 0) {
770 LOGE("Error, failed to get sessiion id");
771 return UNKNOWN_ERROR;
772 } else {
773 //Allocate related cam sync buffer
774 //this is needed for the payload that goes along with bundling cmd for related
775 //camera use cases
776 m_pRelCamSyncHeap = new QCamera3HeapMemory(1);
777 rc = m_pRelCamSyncHeap->allocate(sizeof(cam_sync_related_sensors_event_info_t));
778 if(rc != OK) {
779 rc = NO_MEMORY;
780 LOGE("Dualcam: Failed to allocate Related cam sync Heap memory");
781 return NO_MEMORY;
782 }
783
784 //Map memory for related cam sync buffer
785 rc = mCameraHandle->ops->map_buf(mCameraHandle->camera_handle,
786 CAM_MAPPING_BUF_TYPE_SYNC_RELATED_SENSORS_BUF,
787 m_pRelCamSyncHeap->getFd(0),
788 sizeof(cam_sync_related_sensors_event_info_t),
789 m_pRelCamSyncHeap->getPtr(0));
790 if(rc < 0) {
791 LOGE("Dualcam: failed to map Related cam sync buffer");
792 rc = FAILED_TRANSACTION;
793 return NO_MEMORY;
794 }
795 m_pRelCamSyncBuf =
796 (cam_sync_related_sensors_event_info_t*) DATA_PTR(m_pRelCamSyncHeap,0);
797 }
798
799 LOGH("mCameraId=%d",mCameraId);
800
801 return NO_ERROR;
802}
803
804/*===========================================================================
805 * FUNCTION : closeCamera
806 *
807 * DESCRIPTION: close camera
808 *
809 * PARAMETERS : none
810 *
811 * RETURN : int32_t type of status
812 * NO_ERROR -- success
813 * none-zero failure code
814 *==========================================================================*/
815int QCamera3HardwareInterface::closeCamera()
816{
817 KPI_ATRACE_CALL();
818 int rc = NO_ERROR;
819 char value[PROPERTY_VALUE_MAX];
820
821 LOGI("[KPI Perf]: E PROFILE_CLOSE_CAMERA camera id %d",
822 mCameraId);
823 rc = mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
824 mCameraHandle = NULL;
825
826 //reset session id to some invalid id
827 pthread_mutex_lock(&gCamLock);
828 sessionId[mCameraId] = 0xDEADBEEF;
829 pthread_mutex_unlock(&gCamLock);
830
831 //Notify display HAL that there is no active camera session
832 //but avoid calling the same during bootup. Refer to openCamera
833 //for more details.
834 property_get("service.bootanim.exit", value, "0");
835 if (atoi(value) == 1) {
836 pthread_mutex_lock(&gCamLock);
837 if (--gNumCameraSessions == 0) {
838 setCameraLaunchStatus(false);
839 }
840 pthread_mutex_unlock(&gCamLock);
841 }
842
843 if (NULL != m_pRelCamSyncHeap) {
844 m_pRelCamSyncHeap->deallocate();
845 delete m_pRelCamSyncHeap;
846 m_pRelCamSyncHeap = NULL;
847 m_pRelCamSyncBuf = NULL;
848 }
849
850 if (mExifParams.debug_params) {
851 free(mExifParams.debug_params);
852 mExifParams.debug_params = NULL;
853 }
854 if (QCameraFlash::getInstance().releaseFlashFromCamera(mCameraId) != 0) {
855 LOGW("Failed to release flash for camera id: %d",
856 mCameraId);
857 }
858 mState = CLOSED;
859 LOGI("[KPI Perf]: X PROFILE_CLOSE_CAMERA camera id %d, rc: %d",
860 mCameraId, rc);
861 return rc;
862}
863
864/*===========================================================================
865 * FUNCTION : initialize
866 *
867 * DESCRIPTION: Initialize frameworks callback functions
868 *
869 * PARAMETERS :
870 * @callback_ops : callback function to frameworks
871 *
872 * RETURN :
873 *
874 *==========================================================================*/
875int QCamera3HardwareInterface::initialize(
876 const struct camera3_callback_ops *callback_ops)
877{
878 ATRACE_CALL();
879 int rc;
880
881 LOGI("E :mCameraId = %d mState = %d", mCameraId, mState);
882 pthread_mutex_lock(&mMutex);
883
884 // Validate current state
885 switch (mState) {
886 case OPENED:
887 /* valid state */
888 break;
889 default:
890 LOGE("Invalid state %d", mState);
891 rc = -ENODEV;
892 goto err1;
893 }
894
895 rc = initParameters();
896 if (rc < 0) {
897 LOGE("initParamters failed %d", rc);
898 goto err1;
899 }
900 mCallbackOps = callback_ops;
901
902 mChannelHandle = mCameraHandle->ops->add_channel(
903 mCameraHandle->camera_handle, NULL, NULL, this);
904 if (mChannelHandle == 0) {
905 LOGE("add_channel failed");
906 rc = -ENOMEM;
907 pthread_mutex_unlock(&mMutex);
908 return rc;
909 }
910
911 pthread_mutex_unlock(&mMutex);
912 mCameraInitialized = true;
913 mState = INITIALIZED;
914 LOGI("X");
915 return 0;
916
917err1:
918 pthread_mutex_unlock(&mMutex);
919 return rc;
920}
921
922/*===========================================================================
923 * FUNCTION : validateStreamDimensions
924 *
925 * DESCRIPTION: Check if the configuration requested are those advertised
926 *
927 * PARAMETERS :
928 * @stream_list : streams to be configured
929 *
930 * RETURN :
931 *
932 *==========================================================================*/
933int QCamera3HardwareInterface::validateStreamDimensions(
934 camera3_stream_configuration_t *streamList)
935{
936 int rc = NO_ERROR;
937 size_t count = 0;
938
939 camera3_stream_t *inputStream = NULL;
940 /*
941 * Loop through all streams to find input stream if it exists*
942 */
943 for (size_t i = 0; i< streamList->num_streams; i++) {
944 if (streamList->streams[i]->stream_type == CAMERA3_STREAM_INPUT) {
945 if (inputStream != NULL) {
946 LOGE("Error, Multiple input streams requested");
947 return -EINVAL;
948 }
949 inputStream = streamList->streams[i];
950 }
951 }
952 /*
953 * Loop through all streams requested in configuration
954 * Check if unsupported sizes have been requested on any of them
955 */
956 for (size_t j = 0; j < streamList->num_streams; j++) {
957 bool sizeFound = false;
958 camera3_stream_t *newStream = streamList->streams[j];
959
960 uint32_t rotatedHeight = newStream->height;
961 uint32_t rotatedWidth = newStream->width;
962 if ((newStream->rotation == CAMERA3_STREAM_ROTATION_90) ||
963 (newStream->rotation == CAMERA3_STREAM_ROTATION_270)) {
964 rotatedHeight = newStream->width;
965 rotatedWidth = newStream->height;
966 }
967
968 /*
969 * Sizes are different for each type of stream format check against
970 * appropriate table.
971 */
972 switch (newStream->format) {
973 case ANDROID_SCALER_AVAILABLE_FORMATS_RAW16:
974 case ANDROID_SCALER_AVAILABLE_FORMATS_RAW_OPAQUE:
975 case HAL_PIXEL_FORMAT_RAW10:
976 count = MIN(gCamCapability[mCameraId]->supported_raw_dim_cnt, MAX_SIZES_CNT);
977 for (size_t i = 0; i < count; i++) {
978 if ((gCamCapability[mCameraId]->raw_dim[i].width == (int32_t)rotatedWidth) &&
979 (gCamCapability[mCameraId]->raw_dim[i].height == (int32_t)rotatedHeight)) {
980 sizeFound = true;
981 break;
982 }
983 }
984 break;
985 case HAL_PIXEL_FORMAT_BLOB:
986 count = MIN(gCamCapability[mCameraId]->picture_sizes_tbl_cnt, MAX_SIZES_CNT);
987 /* Verify set size against generated sizes table */
988 for (size_t i = 0; i < count; i++) {
989 if (((int32_t)rotatedWidth ==
990 gCamCapability[mCameraId]->picture_sizes_tbl[i].width) &&
991 ((int32_t)rotatedHeight ==
992 gCamCapability[mCameraId]->picture_sizes_tbl[i].height)) {
993 sizeFound = true;
994 break;
995 }
996 }
997 break;
998 case HAL_PIXEL_FORMAT_YCbCr_420_888:
999 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
1000 default:
1001 if (newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL
1002 || newStream->stream_type == CAMERA3_STREAM_INPUT
1003 || IS_USAGE_ZSL(newStream->usage)) {
1004 if (((int32_t)rotatedWidth ==
1005 gCamCapability[mCameraId]->active_array_size.width) &&
1006 ((int32_t)rotatedHeight ==
1007 gCamCapability[mCameraId]->active_array_size.height)) {
1008 sizeFound = true;
1009 break;
1010 }
1011 /* We could potentially break here to enforce ZSL stream
1012 * set from frameworks always is full active array size
1013 * but it is not clear from the spc if framework will always
1014 * follow that, also we have logic to override to full array
1015 * size, so keeping the logic lenient at the moment
1016 */
1017 }
1018 count = MIN(gCamCapability[mCameraId]->picture_sizes_tbl_cnt,
1019 MAX_SIZES_CNT);
1020 for (size_t i = 0; i < count; i++) {
1021 if (((int32_t)rotatedWidth ==
1022 gCamCapability[mCameraId]->picture_sizes_tbl[i].width) &&
1023 ((int32_t)rotatedHeight ==
1024 gCamCapability[mCameraId]->picture_sizes_tbl[i].height)) {
1025 sizeFound = true;
1026 break;
1027 }
1028 }
1029 break;
1030 } /* End of switch(newStream->format) */
1031
1032 /* We error out even if a single stream has unsupported size set */
1033 if (!sizeFound) {
1034 LOGE("Error: Unsupported size: %d x %d type: %d array size: %d x %d",
1035 rotatedWidth, rotatedHeight, newStream->format,
1036 gCamCapability[mCameraId]->active_array_size.width,
1037 gCamCapability[mCameraId]->active_array_size.height);
1038 rc = -EINVAL;
1039 break;
1040 }
1041 } /* End of for each stream */
1042 return rc;
1043}
1044
1045/*==============================================================================
1046 * FUNCTION : isSupportChannelNeeded
1047 *
1048 * DESCRIPTION: Simple heuristic func to determine if support channels is needed
1049 *
1050 * PARAMETERS :
1051 * @stream_list : streams to be configured
1052 * @stream_config_info : the config info for streams to be configured
1053 *
1054 * RETURN : Boolen true/false decision
1055 *
1056 *==========================================================================*/
1057bool QCamera3HardwareInterface::isSupportChannelNeeded(
1058 camera3_stream_configuration_t *streamList,
1059 cam_stream_size_info_t stream_config_info)
1060{
1061 uint32_t i;
1062 bool pprocRequested = false;
1063 /* Check for conditions where PProc pipeline does not have any streams*/
1064 for (i = 0; i < stream_config_info.num_streams; i++) {
1065 if (stream_config_info.type[i] != CAM_STREAM_TYPE_ANALYSIS &&
1066 stream_config_info.postprocess_mask[i] != CAM_QCOM_FEATURE_NONE) {
1067 pprocRequested = true;
1068 break;
1069 }
1070 }
1071
1072 if (pprocRequested == false )
1073 return true;
1074
1075 /* Dummy stream needed if only raw or jpeg streams present */
1076 for (i = 0; i < streamList->num_streams; i++) {
1077 switch(streamList->streams[i]->format) {
1078 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
1079 case HAL_PIXEL_FORMAT_RAW10:
1080 case HAL_PIXEL_FORMAT_RAW16:
1081 case HAL_PIXEL_FORMAT_BLOB:
1082 break;
1083 default:
1084 return false;
1085 }
1086 }
1087 return true;
1088}
1089
1090/*==============================================================================
1091 * FUNCTION : getSensorOutputSize
1092 *
1093 * DESCRIPTION: Get sensor output size based on current stream configuratoin
1094 *
1095 * PARAMETERS :
1096 * @sensor_dim : sensor output dimension (output)
1097 *
1098 * RETURN : int32_t type of status
1099 * NO_ERROR -- success
1100 * none-zero failure code
1101 *
1102 *==========================================================================*/
1103int32_t QCamera3HardwareInterface::getSensorOutputSize(cam_dimension_t &sensor_dim)
1104{
1105 int32_t rc = NO_ERROR;
1106
1107 cam_dimension_t max_dim = {0, 0};
1108 for (uint32_t i = 0; i < mStreamConfigInfo.num_streams; i++) {
1109 if (mStreamConfigInfo.stream_sizes[i].width > max_dim.width)
1110 max_dim.width = mStreamConfigInfo.stream_sizes[i].width;
1111 if (mStreamConfigInfo.stream_sizes[i].height > max_dim.height)
1112 max_dim.height = mStreamConfigInfo.stream_sizes[i].height;
1113 }
1114
1115 clear_metadata_buffer(mParameters);
1116
1117 rc = ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_PARM_MAX_DIMENSION,
1118 max_dim);
1119 if (rc != NO_ERROR) {
1120 LOGE("Failed to update table for CAM_INTF_PARM_MAX_DIMENSION");
1121 return rc;
1122 }
1123
1124 rc = mCameraHandle->ops->set_parms(mCameraHandle->camera_handle, mParameters);
1125 if (rc != NO_ERROR) {
1126 LOGE("Failed to set CAM_INTF_PARM_MAX_DIMENSION");
1127 return rc;
1128 }
1129
1130 clear_metadata_buffer(mParameters);
1131 ADD_GET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_PARM_RAW_DIMENSION);
1132
1133 rc = mCameraHandle->ops->get_parms(mCameraHandle->camera_handle,
1134 mParameters);
1135 if (rc != NO_ERROR) {
1136 LOGE("Failed to get CAM_INTF_PARM_RAW_DIMENSION");
1137 return rc;
1138 }
1139
1140 READ_PARAM_ENTRY(mParameters, CAM_INTF_PARM_RAW_DIMENSION, sensor_dim);
1141 LOGH("sensor output dimension = %d x %d", sensor_dim.width, sensor_dim.height);
1142
1143 return rc;
1144}
1145
1146/*==============================================================================
1147 * FUNCTION : enablePowerHint
1148 *
1149 * DESCRIPTION: enable single powerhint for preview and different video modes.
1150 *
1151 * PARAMETERS :
1152 *
1153 * RETURN : NULL
1154 *
1155 *==========================================================================*/
1156void QCamera3HardwareInterface::enablePowerHint()
1157{
1158 if (!mPowerHintEnabled) {
1159 m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, true);
1160 mPowerHintEnabled = true;
1161 }
1162}
1163
1164/*==============================================================================
1165 * FUNCTION : disablePowerHint
1166 *
1167 * DESCRIPTION: disable current powerhint.
1168 *
1169 * PARAMETERS :
1170 *
1171 * RETURN : NULL
1172 *
1173 *==========================================================================*/
1174void QCamera3HardwareInterface::disablePowerHint()
1175{
1176 if (mPowerHintEnabled) {
1177 m_perfLock.powerHint(POWER_HINT_VIDEO_ENCODE, false);
1178 mPowerHintEnabled = false;
1179 }
1180}
1181
1182/*==============================================================================
1183 * FUNCTION : addToPPFeatureMask
1184 *
1185 * DESCRIPTION: add additional features to pp feature mask based on
1186 * stream type and usecase
1187 *
1188 * PARAMETERS :
1189 * @stream_format : stream type for feature mask
1190 * @stream_idx : stream idx within postprocess_mask list to change
1191 *
1192 * RETURN : NULL
1193 *
1194 *==========================================================================*/
1195void QCamera3HardwareInterface::addToPPFeatureMask(int stream_format,
1196 uint32_t stream_idx)
1197{
1198 char feature_mask_value[PROPERTY_VALUE_MAX];
1199 cam_feature_mask_t feature_mask;
1200 int args_converted;
1201 int property_len;
1202
1203 /* Get feature mask from property */
1204 property_len = property_get("persist.camera.hal3.feature",
1205 feature_mask_value, "0");
1206 if ((property_len > 2) && (feature_mask_value[0] == '0') &&
1207 (feature_mask_value[1] == 'x')) {
1208 args_converted = sscanf(feature_mask_value, "0x%llx", &feature_mask);
1209 } else {
1210 args_converted = sscanf(feature_mask_value, "%lld", &feature_mask);
1211 }
1212 if (1 != args_converted) {
1213 feature_mask = 0;
1214 LOGE("Wrong feature mask %s", feature_mask_value);
1215 return;
1216 }
1217
1218 switch (stream_format) {
1219 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: {
1220 /* Add LLVD to pp feature mask only if video hint is enabled */
1221 if ((m_bIsVideo) && (feature_mask & CAM_QTI_FEATURE_SW_TNR)) {
1222 mStreamConfigInfo.postprocess_mask[stream_idx]
1223 |= CAM_QTI_FEATURE_SW_TNR;
1224 LOGH("Added SW TNR to pp feature mask");
1225 } else if ((m_bIsVideo) && (feature_mask & CAM_QCOM_FEATURE_LLVD)) {
1226 mStreamConfigInfo.postprocess_mask[stream_idx]
1227 |= CAM_QCOM_FEATURE_LLVD;
1228 LOGH("Added LLVD SeeMore to pp feature mask");
1229 }
1230 break;
1231 }
1232 default:
1233 break;
1234 }
1235 LOGD("PP feature mask %llx",
1236 mStreamConfigInfo.postprocess_mask[stream_idx]);
1237}
1238
1239/*==============================================================================
1240 * FUNCTION : updateFpsInPreviewBuffer
1241 *
1242 * DESCRIPTION: update FPS information in preview buffer.
1243 *
1244 * PARAMETERS :
1245 * @metadata : pointer to metadata buffer
1246 * @frame_number: frame_number to look for in pending buffer list
1247 *
1248 * RETURN : None
1249 *
1250 *==========================================================================*/
1251void QCamera3HardwareInterface::updateFpsInPreviewBuffer(metadata_buffer_t *metadata,
1252 uint32_t frame_number)
1253{
1254 // Mark all pending buffers for this particular request
1255 // with corresponding framerate information
1256 for (List<PendingBuffersInRequest>::iterator req =
1257 mPendingBuffersMap.mPendingBuffersInRequest.begin();
1258 req != mPendingBuffersMap.mPendingBuffersInRequest.end(); req++) {
1259 for(List<PendingBufferInfo>::iterator j =
1260 req->mPendingBufferList.begin();
1261 j != req->mPendingBufferList.end(); j++) {
1262 QCamera3Channel *channel = (QCamera3Channel *)j->stream->priv;
1263 if ((req->frame_number == frame_number) &&
1264 (channel->getStreamTypeMask() &
1265 (1U << CAM_STREAM_TYPE_PREVIEW))) {
1266 IF_META_AVAILABLE(cam_fps_range_t, float_range,
1267 CAM_INTF_PARM_FPS_RANGE, metadata) {
1268 typeof (MetaData_t::refreshrate) cameraFps = float_range->max_fps;
1269 struct private_handle_t *priv_handle =
1270 (struct private_handle_t *)(*(j->buffer));
1271 setMetaData(priv_handle, UPDATE_REFRESH_RATE, &cameraFps);
1272 }
1273 }
1274 }
1275 }
1276}
1277
1278/*===========================================================================
1279 * FUNCTION : configureStreams
1280 *
1281 * DESCRIPTION: Reset HAL camera device processing pipeline and set up new input
1282 * and output streams.
1283 *
1284 * PARAMETERS :
1285 * @stream_list : streams to be configured
1286 *
1287 * RETURN :
1288 *
1289 *==========================================================================*/
1290int QCamera3HardwareInterface::configureStreams(
1291 camera3_stream_configuration_t *streamList)
1292{
1293 ATRACE_CALL();
1294 int rc = 0;
1295
1296 // Acquire perfLock before configure streams
1297 m_perfLock.lock_acq();
1298 rc = configureStreamsPerfLocked(streamList);
1299 m_perfLock.lock_rel();
1300
1301 return rc;
1302}
1303
1304/*===========================================================================
1305 * FUNCTION : configureStreamsPerfLocked
1306 *
1307 * DESCRIPTION: configureStreams while perfLock is held.
1308 *
1309 * PARAMETERS :
1310 * @stream_list : streams to be configured
1311 *
1312 * RETURN : int32_t type of status
1313 * NO_ERROR -- success
1314 * none-zero failure code
1315 *==========================================================================*/
1316int QCamera3HardwareInterface::configureStreamsPerfLocked(
1317 camera3_stream_configuration_t *streamList)
1318{
1319 ATRACE_CALL();
1320 int rc = 0;
1321
1322 // Sanity check stream_list
1323 if (streamList == NULL) {
1324 LOGE("NULL stream configuration");
1325 return BAD_VALUE;
1326 }
1327 if (streamList->streams == NULL) {
1328 LOGE("NULL stream list");
1329 return BAD_VALUE;
1330 }
1331
1332 if (streamList->num_streams < 1) {
1333 LOGE("Bad number of streams requested: %d",
1334 streamList->num_streams);
1335 return BAD_VALUE;
1336 }
1337
1338 if (streamList->num_streams >= MAX_NUM_STREAMS) {
1339 LOGE("Maximum number of streams %d exceeded: %d",
1340 MAX_NUM_STREAMS, streamList->num_streams);
1341 return BAD_VALUE;
1342 }
1343
1344 mOpMode = streamList->operation_mode;
1345 LOGD("mOpMode: %d", mOpMode);
1346
1347 /* first invalidate all the steams in the mStreamList
1348 * if they appear again, they will be validated */
1349 for (List<stream_info_t*>::iterator it = mStreamInfo.begin();
1350 it != mStreamInfo.end(); it++) {
1351 QCamera3ProcessingChannel *channel = (QCamera3ProcessingChannel*)(*it)->stream->priv;
1352 if (channel) {
1353 channel->stop();
1354 }
1355 (*it)->status = INVALID;
1356 }
1357
1358 if (mRawDumpChannel) {
1359 mRawDumpChannel->stop();
1360 delete mRawDumpChannel;
1361 mRawDumpChannel = NULL;
1362 }
1363
1364 if (mSupportChannel)
1365 mSupportChannel->stop();
1366
1367 if (mAnalysisChannel) {
1368 mAnalysisChannel->stop();
1369 }
1370 if (mMetadataChannel) {
1371 /* If content of mStreamInfo is not 0, there is metadata stream */
1372 mMetadataChannel->stop();
1373 }
1374 if (mChannelHandle) {
1375 mCameraHandle->ops->stop_channel(mCameraHandle->camera_handle,
1376 mChannelHandle);
1377 LOGD("stopping channel %d", mChannelHandle);
1378 }
1379
1380 pthread_mutex_lock(&mMutex);
1381
1382 // Check state
1383 switch (mState) {
1384 case INITIALIZED:
1385 case CONFIGURED:
1386 case STARTED:
1387 /* valid state */
1388 break;
1389 default:
1390 LOGE("Invalid state %d", mState);
1391 pthread_mutex_unlock(&mMutex);
1392 return -ENODEV;
1393 }
1394
1395 /* Check whether we have video stream */
1396 m_bIs4KVideo = false;
1397 m_bIsVideo = false;
1398 m_bEisSupportedSize = false;
1399 m_bTnrEnabled = false;
1400 bool isZsl = false;
1401 uint32_t videoWidth = 0U;
1402 uint32_t videoHeight = 0U;
1403 size_t rawStreamCnt = 0;
1404 size_t stallStreamCnt = 0;
1405 size_t processedStreamCnt = 0;
1406 // Number of streams on ISP encoder path
1407 size_t numStreamsOnEncoder = 0;
1408 size_t numYuv888OnEncoder = 0;
1409 bool bYuv888OverrideJpeg = false;
1410 cam_dimension_t largeYuv888Size = {0, 0};
1411 cam_dimension_t maxViewfinderSize = {0, 0};
1412 bool bJpegExceeds4K = false;
1413 bool bJpegOnEncoder = false;
1414 bool bUseCommonFeatureMask = false;
1415 cam_feature_mask_t commonFeatureMask = 0;
1416 bool bSmallJpegSize = false;
1417 uint32_t width_ratio;
1418 uint32_t height_ratio;
1419 maxViewfinderSize = gCamCapability[mCameraId]->max_viewfinder_size;
1420 camera3_stream_t *inputStream = NULL;
1421 bool isJpeg = false;
1422 cam_dimension_t jpegSize = {0, 0};
1423
1424 cam_padding_info_t padding_info = gCamCapability[mCameraId]->padding_info;
1425
1426 /*EIS configuration*/
Thierry Strudel3d639192016-09-09 11:52:26 -07001427 bool oisSupported = false;
Thierry Strudel3d639192016-09-09 11:52:26 -07001428 uint8_t eis_prop_set;
1429 uint32_t maxEisWidth = 0;
1430 uint32_t maxEisHeight = 0;
1431
1432 memset(&mInputStreamInfo, 0, sizeof(mInputStreamInfo));
1433
1434 size_t count = IS_TYPE_MAX;
1435 count = MIN(gCamCapability[mCameraId]->supported_is_types_cnt, count);
1436 for (size_t i = 0; i < count; i++) {
1437 if ((gCamCapability[mCameraId]->supported_is_types[i] == IS_TYPE_EIS_2_0) ||
Thierry Strudel9e74aae2016-09-22 17:10:18 -07001438 (gCamCapability[mCameraId]->supported_is_types[i] == IS_TYPE_EIS_3_0)) {
1439 m_bEisSupported = true;
Thierry Strudel3d639192016-09-09 11:52:26 -07001440 break;
1441 }
1442 }
Thierry Strudel3d639192016-09-09 11:52:26 -07001443 count = CAM_OPT_STAB_MAX;
1444 count = MIN(gCamCapability[mCameraId]->optical_stab_modes_count, count);
1445 for (size_t i = 0; i < count; i++) {
1446 if (gCamCapability[mCameraId]->optical_stab_modes[i] == CAM_OPT_STAB_ON) {
1447 oisSupported = true;
1448 break;
1449 }
1450 }
1451
Thierry Strudel9e74aae2016-09-22 17:10:18 -07001452 if (m_bEisSupported) {
Thierry Strudel3d639192016-09-09 11:52:26 -07001453 maxEisWidth = MAX_EIS_WIDTH;
1454 maxEisHeight = MAX_EIS_HEIGHT;
1455 }
1456
1457 /* EIS setprop control */
1458 char eis_prop[PROPERTY_VALUE_MAX];
1459 memset(eis_prop, 0, sizeof(eis_prop));
Thierry Strudel9e74aae2016-09-22 17:10:18 -07001460 property_get("persist.camera.eis.enable", eis_prop, "1");
Thierry Strudel3d639192016-09-09 11:52:26 -07001461 eis_prop_set = (uint8_t)atoi(eis_prop);
1462
Thierry Strudel9e74aae2016-09-22 17:10:18 -07001463 m_bEisEnable = eis_prop_set && (!oisSupported && m_bEisSupported) &&
Thierry Strudel3d639192016-09-09 11:52:26 -07001464 (mOpMode != CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE);
1465
Thierry Strudel9e74aae2016-09-22 17:10:18 -07001466 LOGD("m_bEisEnable: %d, eis_prop_set: %d, m_bEisSupported: %d, oisSupported:%d ",
1467 m_bEisEnable, eis_prop_set, m_bEisSupported, oisSupported);
1468
Thierry Strudel3d639192016-09-09 11:52:26 -07001469 /* stream configurations */
1470 for (size_t i = 0; i < streamList->num_streams; i++) {
1471 camera3_stream_t *newStream = streamList->streams[i];
1472 LOGI("stream[%d] type = %d, format = %d, width = %d, "
1473 "height = %d, rotation = %d, usage = 0x%x",
1474 i, newStream->stream_type, newStream->format,
1475 newStream->width, newStream->height, newStream->rotation,
1476 newStream->usage);
1477 if (newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL ||
1478 newStream->stream_type == CAMERA3_STREAM_INPUT){
1479 isZsl = true;
1480 }
1481 if (newStream->stream_type == CAMERA3_STREAM_INPUT){
1482 inputStream = newStream;
1483 }
1484
1485 if (newStream->format == HAL_PIXEL_FORMAT_BLOB) {
1486 isJpeg = true;
1487 jpegSize.width = newStream->width;
1488 jpegSize.height = newStream->height;
1489 if (newStream->width > VIDEO_4K_WIDTH ||
1490 newStream->height > VIDEO_4K_HEIGHT)
1491 bJpegExceeds4K = true;
1492 }
1493
1494 if ((HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED == newStream->format) &&
1495 (newStream->usage & private_handle_t::PRIV_FLAGS_VIDEO_ENCODER)) {
1496 m_bIsVideo = true;
1497 videoWidth = newStream->width;
1498 videoHeight = newStream->height;
1499 if ((VIDEO_4K_WIDTH <= newStream->width) &&
1500 (VIDEO_4K_HEIGHT <= newStream->height)) {
1501 m_bIs4KVideo = true;
1502 }
1503 m_bEisSupportedSize = (newStream->width <= maxEisWidth) &&
1504 (newStream->height <= maxEisHeight);
1505 }
1506 if (newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL ||
1507 newStream->stream_type == CAMERA3_STREAM_OUTPUT) {
1508 switch (newStream->format) {
1509 case HAL_PIXEL_FORMAT_BLOB:
1510 stallStreamCnt++;
1511 if (isOnEncoder(maxViewfinderSize, newStream->width,
1512 newStream->height)) {
1513 numStreamsOnEncoder++;
1514 bJpegOnEncoder = true;
1515 }
1516 width_ratio = CEIL_DIVISION(gCamCapability[mCameraId]->active_array_size.width,
1517 newStream->width);
1518 height_ratio = CEIL_DIVISION(gCamCapability[mCameraId]->active_array_size.height,
1519 newStream->height);;
1520 FATAL_IF(gCamCapability[mCameraId]->max_downscale_factor == 0,
1521 "FATAL: max_downscale_factor cannot be zero and so assert");
1522 if ( (width_ratio > gCamCapability[mCameraId]->max_downscale_factor) ||
1523 (height_ratio > gCamCapability[mCameraId]->max_downscale_factor)) {
1524 LOGH("Setting small jpeg size flag to true");
1525 bSmallJpegSize = true;
1526 }
1527 break;
1528 case HAL_PIXEL_FORMAT_RAW10:
1529 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
1530 case HAL_PIXEL_FORMAT_RAW16:
1531 rawStreamCnt++;
1532 break;
1533 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
1534 processedStreamCnt++;
1535 if (isOnEncoder(maxViewfinderSize, newStream->width,
1536 newStream->height)) {
1537 if (newStream->stream_type != CAMERA3_STREAM_BIDIRECTIONAL &&
1538 !IS_USAGE_ZSL(newStream->usage)) {
1539 commonFeatureMask |= CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
1540 }
1541 numStreamsOnEncoder++;
1542 }
1543 break;
1544 case HAL_PIXEL_FORMAT_YCbCr_420_888:
1545 processedStreamCnt++;
1546 if (isOnEncoder(maxViewfinderSize, newStream->width,
1547 newStream->height)) {
1548 // If Yuv888 size is not greater than 4K, set feature mask
1549 // to SUPERSET so that it support concurrent request on
1550 // YUV and JPEG.
1551 if (newStream->width <= VIDEO_4K_WIDTH &&
1552 newStream->height <= VIDEO_4K_HEIGHT) {
1553 commonFeatureMask |= CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
1554 }
1555 numStreamsOnEncoder++;
1556 numYuv888OnEncoder++;
1557 largeYuv888Size.width = newStream->width;
1558 largeYuv888Size.height = newStream->height;
1559 }
1560 break;
1561 default:
1562 processedStreamCnt++;
1563 if (isOnEncoder(maxViewfinderSize, newStream->width,
1564 newStream->height)) {
1565 commonFeatureMask |= CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
1566 numStreamsOnEncoder++;
1567 }
1568 break;
1569 }
1570
1571 }
1572 }
1573
1574 if (gCamCapability[mCameraId]->position == CAM_POSITION_FRONT ||
1575 gCamCapability[mCameraId]->position == CAM_POSITION_FRONT_AUX ||
1576 !m_bIsVideo) {
1577 m_bEisEnable = false;
1578 }
1579
1580 /* Logic to enable/disable TNR based on specific config size/etc.*/
1581 if ((m_bTnrPreview || m_bTnrVideo) && m_bIsVideo &&
1582 ((videoWidth == 1920 && videoHeight == 1080) ||
1583 (videoWidth == 1280 && videoHeight == 720)) &&
1584 (mOpMode != CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE))
1585 m_bTnrEnabled = true;
1586
1587 /* Check if num_streams is sane */
1588 if (stallStreamCnt > MAX_STALLING_STREAMS ||
1589 rawStreamCnt > MAX_RAW_STREAMS ||
1590 processedStreamCnt > MAX_PROCESSED_STREAMS) {
1591 LOGE("Invalid stream configu: stall: %d, raw: %d, processed %d",
1592 stallStreamCnt, rawStreamCnt, processedStreamCnt);
1593 pthread_mutex_unlock(&mMutex);
1594 return -EINVAL;
1595 }
1596 /* Check whether we have zsl stream or 4k video case */
1597 if (isZsl && m_bIsVideo) {
1598 LOGE("Currently invalid configuration ZSL&Video!");
1599 pthread_mutex_unlock(&mMutex);
1600 return -EINVAL;
1601 }
1602 /* Check if stream sizes are sane */
1603 if (numStreamsOnEncoder > 2) {
1604 LOGE("Number of streams on ISP encoder path exceeds limits of 2");
1605 pthread_mutex_unlock(&mMutex);
1606 return -EINVAL;
1607 } else if (1 < numStreamsOnEncoder){
1608 bUseCommonFeatureMask = true;
1609 LOGH("Multiple streams above max viewfinder size, common mask needed");
1610 }
1611
1612 /* Check if BLOB size is greater than 4k in 4k recording case */
1613 if (m_bIs4KVideo && bJpegExceeds4K) {
1614 LOGE("HAL doesn't support Blob size greater than 4k in 4k recording");
1615 pthread_mutex_unlock(&mMutex);
1616 return -EINVAL;
1617 }
1618
1619 // When JPEG and preview streams share VFE output, CPP will not apply CAC2
1620 // on JPEG stream. So disable such configurations to ensure CAC2 is applied.
1621 // Don't fail for reprocess configurations. Also don't fail if bJpegExceeds4K
1622 // is not true. Otherwise testMandatoryOutputCombinations will fail with following
1623 // configurations:
1624 // {[PRIV, PREVIEW] [PRIV, RECORD] [JPEG, RECORD]}
1625 // {[PRIV, PREVIEW] [YUV, RECORD] [JPEG, RECORD]}
1626 // (These two configurations will not have CAC2 enabled even in HQ modes.)
1627 if (!isZsl && bJpegOnEncoder && bJpegExceeds4K && bUseCommonFeatureMask) {
1628 ALOGE("%s: Blob size greater than 4k and multiple streams are on encoder output",
1629 __func__);
1630 pthread_mutex_unlock(&mMutex);
1631 return -EINVAL;
1632 }
1633
1634 // If jpeg stream is available, and a YUV 888 stream is on Encoder path, and
1635 // the YUV stream's size is greater or equal to the JPEG size, set common
1636 // postprocess mask to NONE, so that we can take advantage of postproc bypass.
1637 if (numYuv888OnEncoder && isOnEncoder(maxViewfinderSize,
1638 jpegSize.width, jpegSize.height) &&
1639 largeYuv888Size.width > jpegSize.width &&
1640 largeYuv888Size.height > jpegSize.height) {
1641 bYuv888OverrideJpeg = true;
1642 } else if (!isJpeg && numStreamsOnEncoder > 1) {
1643 commonFeatureMask = CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
1644 }
1645
1646 LOGH("max viewfinder width %d height %d isZsl %d bUseCommonFeature %x commonFeatureMask %llx",
1647 maxViewfinderSize.width, maxViewfinderSize.height, isZsl, bUseCommonFeatureMask,
1648 commonFeatureMask);
1649 LOGH("numStreamsOnEncoder %d, processedStreamCnt %d, stallcnt %d bSmallJpegSize %d",
1650 numStreamsOnEncoder, processedStreamCnt, stallStreamCnt, bSmallJpegSize);
1651
1652 rc = validateStreamDimensions(streamList);
1653 if (rc == NO_ERROR) {
1654 rc = validateStreamRotations(streamList);
1655 }
1656 if (rc != NO_ERROR) {
1657 LOGE("Invalid stream configuration requested!");
1658 pthread_mutex_unlock(&mMutex);
1659 return rc;
1660 }
1661
1662 camera3_stream_t *zslStream = NULL; //Only use this for size and not actual handle!
1663 for (size_t i = 0; i < streamList->num_streams; i++) {
1664 camera3_stream_t *newStream = streamList->streams[i];
1665 LOGH("newStream type = %d, stream format = %d "
1666 "stream size : %d x %d, stream rotation = %d",
1667 newStream->stream_type, newStream->format,
1668 newStream->width, newStream->height, newStream->rotation);
1669 //if the stream is in the mStreamList validate it
1670 bool stream_exists = false;
1671 for (List<stream_info_t*>::iterator it=mStreamInfo.begin();
1672 it != mStreamInfo.end(); it++) {
1673 if ((*it)->stream == newStream) {
1674 QCamera3ProcessingChannel *channel =
1675 (QCamera3ProcessingChannel*)(*it)->stream->priv;
1676 stream_exists = true;
1677 if (channel)
1678 delete channel;
1679 (*it)->status = VALID;
1680 (*it)->stream->priv = NULL;
1681 (*it)->channel = NULL;
1682 }
1683 }
1684 if (!stream_exists && newStream->stream_type != CAMERA3_STREAM_INPUT) {
1685 //new stream
1686 stream_info_t* stream_info;
1687 stream_info = (stream_info_t* )malloc(sizeof(stream_info_t));
1688 if (!stream_info) {
1689 LOGE("Could not allocate stream info");
1690 rc = -ENOMEM;
1691 pthread_mutex_unlock(&mMutex);
1692 return rc;
1693 }
1694 stream_info->stream = newStream;
1695 stream_info->status = VALID;
1696 stream_info->channel = NULL;
1697 mStreamInfo.push_back(stream_info);
1698 }
1699 /* Covers Opaque ZSL and API1 F/W ZSL */
1700 if (IS_USAGE_ZSL(newStream->usage)
1701 || newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL ) {
1702 if (zslStream != NULL) {
1703 LOGE("Multiple input/reprocess streams requested!");
1704 pthread_mutex_unlock(&mMutex);
1705 return BAD_VALUE;
1706 }
1707 zslStream = newStream;
1708 }
1709 /* Covers YUV reprocess */
1710 if (inputStream != NULL) {
1711 if (newStream->stream_type == CAMERA3_STREAM_OUTPUT
1712 && newStream->format == HAL_PIXEL_FORMAT_YCbCr_420_888
1713 && inputStream->format == HAL_PIXEL_FORMAT_YCbCr_420_888
1714 && inputStream->width == newStream->width
1715 && inputStream->height == newStream->height) {
1716 if (zslStream != NULL) {
1717 /* This scenario indicates multiple YUV streams with same size
1718 * as input stream have been requested, since zsl stream handle
1719 * is solely use for the purpose of overriding the size of streams
1720 * which share h/w streams we will just make a guess here as to
1721 * which of the stream is a ZSL stream, this will be refactored
1722 * once we make generic logic for streams sharing encoder output
1723 */
1724 LOGH("Warning, Multiple ip/reprocess streams requested!");
1725 }
1726 zslStream = newStream;
1727 }
1728 }
1729 }
1730
1731 /* If a zsl stream is set, we know that we have configured at least one input or
1732 bidirectional stream */
1733 if (NULL != zslStream) {
1734 mInputStreamInfo.dim.width = (int32_t)zslStream->width;
1735 mInputStreamInfo.dim.height = (int32_t)zslStream->height;
1736 mInputStreamInfo.format = zslStream->format;
1737 mInputStreamInfo.usage = zslStream->usage;
1738 LOGD("Input stream configured! %d x %d, format %d, usage %d",
1739 mInputStreamInfo.dim.width,
1740 mInputStreamInfo.dim.height,
1741 mInputStreamInfo.format, mInputStreamInfo.usage);
1742 }
1743
1744 cleanAndSortStreamInfo();
1745 if (mMetadataChannel) {
1746 delete mMetadataChannel;
1747 mMetadataChannel = NULL;
1748 }
1749 if (mSupportChannel) {
1750 delete mSupportChannel;
1751 mSupportChannel = NULL;
1752 }
1753
1754 if (mAnalysisChannel) {
1755 delete mAnalysisChannel;
1756 mAnalysisChannel = NULL;
1757 }
1758
1759 if (mDummyBatchChannel) {
1760 delete mDummyBatchChannel;
1761 mDummyBatchChannel = NULL;
1762 }
1763
1764 //Create metadata channel and initialize it
1765 cam_feature_mask_t metadataFeatureMask = CAM_QCOM_FEATURE_NONE;
1766 setPAAFSupport(metadataFeatureMask, CAM_STREAM_TYPE_METADATA,
1767 gCamCapability[mCameraId]->color_arrangement);
1768 mMetadataChannel = new QCamera3MetadataChannel(mCameraHandle->camera_handle,
1769 mChannelHandle, mCameraHandle->ops, captureResultCb,
1770 &padding_info, metadataFeatureMask, this);
1771 if (mMetadataChannel == NULL) {
1772 LOGE("failed to allocate metadata channel");
1773 rc = -ENOMEM;
1774 pthread_mutex_unlock(&mMutex);
1775 return rc;
1776 }
1777 rc = mMetadataChannel->initialize(IS_TYPE_NONE);
1778 if (rc < 0) {
1779 LOGE("metadata channel initialization failed");
1780 delete mMetadataChannel;
1781 mMetadataChannel = NULL;
1782 pthread_mutex_unlock(&mMutex);
1783 return rc;
1784 }
1785
1786 // Create analysis stream all the time, even when h/w support is not available
1787 {
1788 cam_feature_mask_t analysisFeatureMask = CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
1789 setPAAFSupport(analysisFeatureMask, CAM_STREAM_TYPE_ANALYSIS,
1790 gCamCapability[mCameraId]->color_arrangement);
1791 cam_analysis_info_t analysisInfo;
Thierry Strudel9e74aae2016-09-22 17:10:18 -07001792 int32_t ret = NO_ERROR;
1793 ret = mCommon.getAnalysisInfo(
Thierry Strudel3d639192016-09-09 11:52:26 -07001794 FALSE,
1795 TRUE,
1796 analysisFeatureMask,
1797 &analysisInfo);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07001798 if (ret == NO_ERROR) {
Thierry Strudel3d639192016-09-09 11:52:26 -07001799 mAnalysisChannel = new QCamera3SupportChannel(
Thierry Strudel9e74aae2016-09-22 17:10:18 -07001800 mCameraHandle->camera_handle,
1801 mChannelHandle,
1802 mCameraHandle->ops,
1803 &analysisInfo.analysis_padding_info,
1804 analysisFeatureMask,
1805 CAM_STREAM_TYPE_ANALYSIS,
1806 &analysisInfo.analysis_max_res,
1807 (analysisInfo.analysis_format
1808 == CAM_FORMAT_Y_ONLY ? CAM_FORMAT_Y_ONLY
1809 : CAM_FORMAT_YUV_420_NV21),
1810 analysisInfo.hw_analysis_supported,
1811 gCamCapability[mCameraId]->color_arrangement,
1812 this,
1813 0); // force buffer count to 0
1814 } else {
1815 LOGW("getAnalysisInfo failed, ret = %d", ret);
1816 }
1817 if (!mAnalysisChannel) {
1818 LOGW("Analysis channel cannot be created");
Thierry Strudel3d639192016-09-09 11:52:26 -07001819 }
1820 }
1821
1822 bool isRawStreamRequested = false;
1823 memset(&mStreamConfigInfo, 0, sizeof(cam_stream_size_info_t));
1824 /* Allocate channel objects for the requested streams */
1825 for (size_t i = 0; i < streamList->num_streams; i++) {
1826 camera3_stream_t *newStream = streamList->streams[i];
1827 uint32_t stream_usage = newStream->usage;
1828 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].width = (int32_t)newStream->width;
1829 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].height = (int32_t)newStream->height;
1830 struct camera_info *p_info = NULL;
1831 pthread_mutex_lock(&gCamLock);
1832 p_info = get_cam_info(mCameraId, &mStreamConfigInfo.sync_type);
1833 pthread_mutex_unlock(&gCamLock);
1834 if ((newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL
1835 || IS_USAGE_ZSL(newStream->usage)) &&
1836 newStream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED){
1837 mStreamConfigInfo.type[mStreamConfigInfo.num_streams] = CAM_STREAM_TYPE_SNAPSHOT;
1838 if (bUseCommonFeatureMask) {
1839 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] =
1840 commonFeatureMask;
1841 } else {
1842 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] =
1843 CAM_QCOM_FEATURE_NONE;
1844 }
1845
1846 } else if(newStream->stream_type == CAMERA3_STREAM_INPUT) {
1847 LOGH("Input stream configured, reprocess config");
1848 } else {
1849 //for non zsl streams find out the format
1850 switch (newStream->format) {
1851 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED :
1852 {
1853 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] =
1854 CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
1855 /* add additional features to pp feature mask */
1856 addToPPFeatureMask(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
1857 mStreamConfigInfo.num_streams);
1858
1859 if (stream_usage & private_handle_t::PRIV_FLAGS_VIDEO_ENCODER) {
1860 mStreamConfigInfo.type[mStreamConfigInfo.num_streams] =
1861 CAM_STREAM_TYPE_VIDEO;
1862 if (m_bTnrEnabled && m_bTnrVideo) {
1863 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] |=
1864 CAM_QCOM_FEATURE_CPP_TNR;
1865 //TNR and CDS are mutually exclusive. So reset CDS from feature mask
1866 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] &=
1867 ~CAM_QCOM_FEATURE_CDS;
1868 }
1869 } else {
1870 mStreamConfigInfo.type[mStreamConfigInfo.num_streams] =
1871 CAM_STREAM_TYPE_PREVIEW;
1872 if (m_bTnrEnabled && m_bTnrPreview) {
1873 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] |=
1874 CAM_QCOM_FEATURE_CPP_TNR;
1875 //TNR and CDS are mutually exclusive. So reset CDS from feature mask
1876 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] &=
1877 ~CAM_QCOM_FEATURE_CDS;
1878 }
1879 padding_info.width_padding = mSurfaceStridePadding;
1880 padding_info.height_padding = CAM_PAD_TO_2;
1881 }
1882 if ((newStream->rotation == CAMERA3_STREAM_ROTATION_90) ||
1883 (newStream->rotation == CAMERA3_STREAM_ROTATION_270)) {
1884 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].width =
1885 newStream->height;
1886 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].height =
1887 newStream->width;
1888 }
1889 }
1890 break;
1891 case HAL_PIXEL_FORMAT_YCbCr_420_888:
1892 mStreamConfigInfo.type[mStreamConfigInfo.num_streams] = CAM_STREAM_TYPE_CALLBACK;
1893 if (isOnEncoder(maxViewfinderSize, newStream->width, newStream->height)) {
1894 if (bUseCommonFeatureMask)
1895 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] =
1896 commonFeatureMask;
1897 else
1898 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] =
1899 CAM_QCOM_FEATURE_NONE;
1900 } else {
1901 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] =
1902 CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
1903 }
1904 break;
1905 case HAL_PIXEL_FORMAT_BLOB:
1906 mStreamConfigInfo.type[mStreamConfigInfo.num_streams] = CAM_STREAM_TYPE_SNAPSHOT;
1907 // No need to check bSmallJpegSize if ZSL is present since JPEG uses ZSL stream
1908 if ((m_bIs4KVideo && !isZsl) || (bSmallJpegSize && !isZsl)) {
1909 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] =
1910 CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
1911 } else {
1912 if (bUseCommonFeatureMask &&
1913 isOnEncoder(maxViewfinderSize, newStream->width,
1914 newStream->height)) {
1915 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] = commonFeatureMask;
1916 } else {
1917 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] = CAM_QCOM_FEATURE_NONE;
1918 }
1919 }
1920 if (isZsl) {
1921 if (zslStream) {
1922 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].width =
1923 (int32_t)zslStream->width;
1924 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].height =
1925 (int32_t)zslStream->height;
1926 } else {
1927 LOGE("Error, No ZSL stream identified");
1928 pthread_mutex_unlock(&mMutex);
1929 return -EINVAL;
1930 }
1931 } else if (m_bIs4KVideo) {
1932 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].width = (int32_t)videoWidth;
1933 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].height = (int32_t)videoHeight;
1934 } else if (bYuv888OverrideJpeg) {
1935 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].width =
1936 (int32_t)largeYuv888Size.width;
1937 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].height =
1938 (int32_t)largeYuv888Size.height;
1939 }
1940 break;
1941 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
1942 case HAL_PIXEL_FORMAT_RAW16:
1943 case HAL_PIXEL_FORMAT_RAW10:
1944 mStreamConfigInfo.type[mStreamConfigInfo.num_streams] = CAM_STREAM_TYPE_RAW;
1945 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] = CAM_QCOM_FEATURE_NONE;
1946 isRawStreamRequested = true;
1947 break;
1948 default:
1949 mStreamConfigInfo.type[mStreamConfigInfo.num_streams] = CAM_STREAM_TYPE_DEFAULT;
1950 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] = CAM_QCOM_FEATURE_NONE;
1951 break;
1952 }
1953 }
1954
1955 setPAAFSupport(mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams],
1956 (cam_stream_type_t) mStreamConfigInfo.type[mStreamConfigInfo.num_streams],
1957 gCamCapability[mCameraId]->color_arrangement);
1958
1959 if (newStream->priv == NULL) {
1960 //New stream, construct channel
1961 switch (newStream->stream_type) {
1962 case CAMERA3_STREAM_INPUT:
1963 newStream->usage |= GRALLOC_USAGE_HW_CAMERA_READ;
1964 newStream->usage |= GRALLOC_USAGE_HW_CAMERA_WRITE;//WR for inplace algo's
1965 break;
1966 case CAMERA3_STREAM_BIDIRECTIONAL:
1967 newStream->usage |= GRALLOC_USAGE_HW_CAMERA_READ |
1968 GRALLOC_USAGE_HW_CAMERA_WRITE;
1969 break;
1970 case CAMERA3_STREAM_OUTPUT:
1971 /* For video encoding stream, set read/write rarely
1972 * flag so that they may be set to un-cached */
1973 if (newStream->usage & GRALLOC_USAGE_HW_VIDEO_ENCODER)
1974 newStream->usage |=
1975 (GRALLOC_USAGE_SW_READ_RARELY |
1976 GRALLOC_USAGE_SW_WRITE_RARELY |
1977 GRALLOC_USAGE_HW_CAMERA_WRITE);
1978 else if (IS_USAGE_ZSL(newStream->usage))
1979 {
1980 LOGD("ZSL usage flag skipping");
1981 }
1982 else if (newStream == zslStream
1983 || newStream->format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
1984 newStream->usage |= GRALLOC_USAGE_HW_CAMERA_ZSL;
1985 } else
1986 newStream->usage |= GRALLOC_USAGE_HW_CAMERA_WRITE;
1987 break;
1988 default:
1989 LOGE("Invalid stream_type %d", newStream->stream_type);
1990 break;
1991 }
1992
1993 if (newStream->stream_type == CAMERA3_STREAM_OUTPUT ||
1994 newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL) {
1995 QCamera3ProcessingChannel *channel = NULL;
1996 switch (newStream->format) {
1997 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
1998 if ((newStream->usage &
1999 private_handle_t::PRIV_FLAGS_VIDEO_ENCODER) &&
2000 (streamList->operation_mode ==
2001 CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE)
2002 ) {
2003 channel = new QCamera3RegularChannel(mCameraHandle->camera_handle,
2004 mChannelHandle, mCameraHandle->ops, captureResultCb,
2005 &gCamCapability[mCameraId]->padding_info,
2006 this,
2007 newStream,
2008 (cam_stream_type_t)
2009 mStreamConfigInfo.type[mStreamConfigInfo.num_streams],
2010 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams],
2011 mMetadataChannel,
2012 0); //heap buffers are not required for HFR video channel
2013 if (channel == NULL) {
2014 LOGE("allocation of channel failed");
2015 pthread_mutex_unlock(&mMutex);
2016 return -ENOMEM;
2017 }
2018 //channel->getNumBuffers() will return 0 here so use
2019 //MAX_INFLIGH_HFR_REQUESTS
2020 newStream->max_buffers = MAX_INFLIGHT_HFR_REQUESTS;
2021 newStream->priv = channel;
2022 LOGI("num video buffers in HFR mode: %d",
2023 MAX_INFLIGHT_HFR_REQUESTS);
2024 } else {
2025 /* Copy stream contents in HFR preview only case to create
2026 * dummy batch channel so that sensor streaming is in
2027 * HFR mode */
2028 if (!m_bIsVideo && (streamList->operation_mode ==
2029 CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE)) {
2030 mDummyBatchStream = *newStream;
2031 }
2032 channel = new QCamera3RegularChannel(mCameraHandle->camera_handle,
2033 mChannelHandle, mCameraHandle->ops, captureResultCb,
2034 &gCamCapability[mCameraId]->padding_info,
2035 this,
2036 newStream,
2037 (cam_stream_type_t)
2038 mStreamConfigInfo.type[mStreamConfigInfo.num_streams],
2039 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams],
2040 mMetadataChannel,
2041 MAX_INFLIGHT_REQUESTS);
2042 if (channel == NULL) {
2043 LOGE("allocation of channel failed");
2044 pthread_mutex_unlock(&mMutex);
2045 return -ENOMEM;
2046 }
2047 newStream->max_buffers = channel->getNumBuffers();
2048 newStream->priv = channel;
2049 }
2050 break;
2051 case HAL_PIXEL_FORMAT_YCbCr_420_888: {
2052 channel = new QCamera3YUVChannel(mCameraHandle->camera_handle,
2053 mChannelHandle,
2054 mCameraHandle->ops, captureResultCb,
2055 &padding_info,
2056 this,
2057 newStream,
2058 (cam_stream_type_t)
2059 mStreamConfigInfo.type[mStreamConfigInfo.num_streams],
2060 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams],
2061 mMetadataChannel);
2062 if (channel == NULL) {
2063 LOGE("allocation of YUV channel failed");
2064 pthread_mutex_unlock(&mMutex);
2065 return -ENOMEM;
2066 }
2067 newStream->max_buffers = channel->getNumBuffers();
2068 newStream->priv = channel;
2069 break;
2070 }
2071 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
2072 case HAL_PIXEL_FORMAT_RAW16:
2073 case HAL_PIXEL_FORMAT_RAW10:
2074 mRawChannel = new QCamera3RawChannel(
2075 mCameraHandle->camera_handle, mChannelHandle,
2076 mCameraHandle->ops, captureResultCb,
2077 &padding_info,
2078 this, newStream,
2079 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams],
2080 mMetadataChannel,
2081 (newStream->format == HAL_PIXEL_FORMAT_RAW16));
2082 if (mRawChannel == NULL) {
2083 LOGE("allocation of raw channel failed");
2084 pthread_mutex_unlock(&mMutex);
2085 return -ENOMEM;
2086 }
2087 newStream->max_buffers = mRawChannel->getNumBuffers();
2088 newStream->priv = (QCamera3ProcessingChannel*)mRawChannel;
2089 break;
2090 case HAL_PIXEL_FORMAT_BLOB:
2091 // Max live snapshot inflight buffer is 1. This is to mitigate
2092 // frame drop issues for video snapshot. The more buffers being
2093 // allocated, the more frame drops there are.
2094 mPictureChannel = new QCamera3PicChannel(
2095 mCameraHandle->camera_handle, mChannelHandle,
2096 mCameraHandle->ops, captureResultCb,
2097 &padding_info, this, newStream,
2098 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams],
2099 m_bIs4KVideo, isZsl, mMetadataChannel,
2100 (m_bIsVideo ? 1 : MAX_INFLIGHT_BLOB));
2101 if (mPictureChannel == NULL) {
2102 LOGE("allocation of channel failed");
2103 pthread_mutex_unlock(&mMutex);
2104 return -ENOMEM;
2105 }
2106 newStream->priv = (QCamera3ProcessingChannel*)mPictureChannel;
2107 newStream->max_buffers = mPictureChannel->getNumBuffers();
2108 mPictureChannel->overrideYuvSize(
2109 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].width,
2110 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].height);
2111 break;
2112
2113 default:
2114 LOGE("not a supported format 0x%x", newStream->format);
2115 break;
2116 }
2117 } else if (newStream->stream_type == CAMERA3_STREAM_INPUT) {
2118 newStream->max_buffers = MAX_INFLIGHT_REPROCESS_REQUESTS;
2119 } else {
2120 LOGE("Error, Unknown stream type");
2121 pthread_mutex_unlock(&mMutex);
2122 return -EINVAL;
2123 }
2124
2125 QCamera3Channel *channel = (QCamera3Channel*) newStream->priv;
2126 if (channel != NULL && channel->isUBWCEnabled()) {
2127 cam_format_t fmt = channel->getStreamDefaultFormat(
2128 mStreamConfigInfo.type[mStreamConfigInfo.num_streams]);
2129 if(fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
2130 newStream->usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
2131 }
2132 }
2133
2134 for (List<stream_info_t*>::iterator it=mStreamInfo.begin();
2135 it != mStreamInfo.end(); it++) {
2136 if ((*it)->stream == newStream) {
2137 (*it)->channel = (QCamera3ProcessingChannel*) newStream->priv;
2138 break;
2139 }
2140 }
2141 } else {
2142 // Channel already exists for this stream
2143 // Do nothing for now
2144 }
2145 padding_info = gCamCapability[mCameraId]->padding_info;
2146
2147 /* Do not add entries for input stream in metastream info
2148 * since there is no real stream associated with it
2149 */
2150 if (newStream->stream_type != CAMERA3_STREAM_INPUT)
2151 mStreamConfigInfo.num_streams++;
2152 }
2153
2154 //RAW DUMP channel
2155 if (mEnableRawDump && isRawStreamRequested == false){
2156 cam_dimension_t rawDumpSize;
2157 rawDumpSize = getMaxRawSize(mCameraId);
2158 cam_feature_mask_t rawDumpFeatureMask = CAM_QCOM_FEATURE_NONE;
2159 setPAAFSupport(rawDumpFeatureMask,
2160 CAM_STREAM_TYPE_RAW,
2161 gCamCapability[mCameraId]->color_arrangement);
2162 mRawDumpChannel = new QCamera3RawDumpChannel(mCameraHandle->camera_handle,
2163 mChannelHandle,
2164 mCameraHandle->ops,
2165 rawDumpSize,
2166 &padding_info,
2167 this, rawDumpFeatureMask);
2168 if (!mRawDumpChannel) {
2169 LOGE("Raw Dump channel cannot be created");
2170 pthread_mutex_unlock(&mMutex);
2171 return -ENOMEM;
2172 }
2173 }
2174
2175
2176 if (mAnalysisChannel) {
2177 cam_analysis_info_t analysisInfo;
2178 memset(&analysisInfo, 0, sizeof(cam_analysis_info_t));
2179 mStreamConfigInfo.type[mStreamConfigInfo.num_streams] =
2180 CAM_STREAM_TYPE_ANALYSIS;
2181 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] =
2182 CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
2183 setPAAFSupport(mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams],
2184 mStreamConfigInfo.type[mStreamConfigInfo.num_streams],
2185 gCamCapability[mCameraId]->color_arrangement);
2186 rc = mCommon.getAnalysisInfo(FALSE, TRUE,
2187 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams],
2188 &analysisInfo);
2189 if (rc != NO_ERROR) {
2190 LOGE("getAnalysisInfo failed, ret = %d", rc);
2191 pthread_mutex_unlock(&mMutex);
2192 return rc;
2193 }
2194 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams] =
2195 analysisInfo.analysis_max_res;
2196 mStreamConfigInfo.num_streams++;
2197 }
2198
2199 if (isSupportChannelNeeded(streamList, mStreamConfigInfo)) {
2200 cam_analysis_info_t supportInfo;
2201 memset(&supportInfo, 0, sizeof(cam_analysis_info_t));
2202 cam_feature_mask_t callbackFeatureMask = CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
2203 setPAAFSupport(callbackFeatureMask,
2204 CAM_STREAM_TYPE_CALLBACK,
2205 gCamCapability[mCameraId]->color_arrangement);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07002206 int32_t ret = NO_ERROR;
2207 ret = mCommon.getAnalysisInfo(FALSE, TRUE, callbackFeatureMask, &supportInfo);
2208 if (ret != NO_ERROR) {
2209 /* Ignore the error for Mono camera
2210 * because the PAAF bit mask is only set
2211 * for CAM_STREAM_TYPE_ANALYSIS stream type
2212 */
2213 if (gCamCapability[mCameraId]->color_arrangement != CAM_FILTER_ARRANGEMENT_Y) {
2214 LOGW("getAnalysisInfo failed, ret = %d", ret);
2215 }
Thierry Strudel3d639192016-09-09 11:52:26 -07002216 }
2217 mSupportChannel = new QCamera3SupportChannel(
2218 mCameraHandle->camera_handle,
2219 mChannelHandle,
2220 mCameraHandle->ops,
2221 &gCamCapability[mCameraId]->padding_info,
2222 callbackFeatureMask,
2223 CAM_STREAM_TYPE_CALLBACK,
2224 &QCamera3SupportChannel::kDim,
2225 CAM_FORMAT_YUV_420_NV21,
2226 supportInfo.hw_analysis_supported,
2227 gCamCapability[mCameraId]->color_arrangement,
2228 this);
2229 if (!mSupportChannel) {
2230 LOGE("dummy channel cannot be created");
2231 pthread_mutex_unlock(&mMutex);
2232 return -ENOMEM;
2233 }
2234 }
2235
2236 if (mSupportChannel) {
2237 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams] =
2238 QCamera3SupportChannel::kDim;
2239 mStreamConfigInfo.type[mStreamConfigInfo.num_streams] =
2240 CAM_STREAM_TYPE_CALLBACK;
2241 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] =
2242 CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
2243 setPAAFSupport(mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams],
2244 mStreamConfigInfo.type[mStreamConfigInfo.num_streams],
2245 gCamCapability[mCameraId]->color_arrangement);
2246 mStreamConfigInfo.num_streams++;
2247 }
2248
2249 if (mRawDumpChannel) {
2250 cam_dimension_t rawSize;
2251 rawSize = getMaxRawSize(mCameraId);
2252 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams] =
2253 rawSize;
2254 mStreamConfigInfo.type[mStreamConfigInfo.num_streams] =
2255 CAM_STREAM_TYPE_RAW;
2256 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] =
2257 CAM_QCOM_FEATURE_NONE;
2258 setPAAFSupport(mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams],
2259 mStreamConfigInfo.type[mStreamConfigInfo.num_streams],
2260 gCamCapability[mCameraId]->color_arrangement);
2261 mStreamConfigInfo.num_streams++;
2262 }
2263 /* In HFR mode, if video stream is not added, create a dummy channel so that
2264 * ISP can create a batch mode even for preview only case. This channel is
2265 * never 'start'ed (no stream-on), it is only 'initialized' */
2266 if ((mOpMode == CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE) &&
2267 !m_bIsVideo) {
2268 cam_feature_mask_t dummyFeatureMask = CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
2269 setPAAFSupport(dummyFeatureMask,
2270 CAM_STREAM_TYPE_VIDEO,
2271 gCamCapability[mCameraId]->color_arrangement);
2272 mDummyBatchChannel = new QCamera3RegularChannel(mCameraHandle->camera_handle,
2273 mChannelHandle,
2274 mCameraHandle->ops, captureResultCb,
2275 &gCamCapability[mCameraId]->padding_info,
2276 this,
2277 &mDummyBatchStream,
2278 CAM_STREAM_TYPE_VIDEO,
2279 dummyFeatureMask,
2280 mMetadataChannel);
2281 if (NULL == mDummyBatchChannel) {
2282 LOGE("creation of mDummyBatchChannel failed."
2283 "Preview will use non-hfr sensor mode ");
2284 }
2285 }
2286 if (mDummyBatchChannel) {
2287 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].width =
2288 mDummyBatchStream.width;
2289 mStreamConfigInfo.stream_sizes[mStreamConfigInfo.num_streams].height =
2290 mDummyBatchStream.height;
2291 mStreamConfigInfo.type[mStreamConfigInfo.num_streams] =
2292 CAM_STREAM_TYPE_VIDEO;
2293 mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams] =
2294 CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
2295 setPAAFSupport(mStreamConfigInfo.postprocess_mask[mStreamConfigInfo.num_streams],
2296 mStreamConfigInfo.type[mStreamConfigInfo.num_streams],
2297 gCamCapability[mCameraId]->color_arrangement);
2298 mStreamConfigInfo.num_streams++;
2299 }
2300
2301 mStreamConfigInfo.buffer_info.min_buffers = MIN_INFLIGHT_REQUESTS;
2302 mStreamConfigInfo.buffer_info.max_buffers =
2303 m_bIs4KVideo ? 0 : MAX_INFLIGHT_REQUESTS;
2304
2305 /* Initialize mPendingRequestInfo and mPendingBuffersMap */
2306 for (pendingRequestIterator i = mPendingRequestsList.begin();
2307 i != mPendingRequestsList.end();) {
2308 i = erasePendingRequest(i);
2309 }
2310 mPendingFrameDropList.clear();
2311 // Initialize/Reset the pending buffers list
2312 for (auto &req : mPendingBuffersMap.mPendingBuffersInRequest) {
2313 req.mPendingBufferList.clear();
2314 }
2315 mPendingBuffersMap.mPendingBuffersInRequest.clear();
2316
2317 mPendingReprocessResultList.clear();
2318
2319 mCurJpegMeta.clear();
2320 //Get min frame duration for this streams configuration
2321 deriveMinFrameDuration();
2322
2323 // Update state
2324 mState = CONFIGURED;
2325
2326 pthread_mutex_unlock(&mMutex);
2327
2328 return rc;
2329}
2330
2331/*===========================================================================
2332 * FUNCTION : validateCaptureRequest
2333 *
2334 * DESCRIPTION: validate a capture request from camera service
2335 *
2336 * PARAMETERS :
2337 * @request : request from framework to process
2338 *
2339 * RETURN :
2340 *
2341 *==========================================================================*/
2342int QCamera3HardwareInterface::validateCaptureRequest(
2343 camera3_capture_request_t *request)
2344{
2345 ssize_t idx = 0;
2346 const camera3_stream_buffer_t *b;
2347 CameraMetadata meta;
2348
2349 /* Sanity check the request */
2350 if (request == NULL) {
2351 LOGE("NULL capture request");
2352 return BAD_VALUE;
2353 }
2354
2355 if ((request->settings == NULL) && (mState == CONFIGURED)) {
2356 /*settings cannot be null for the first request*/
2357 return BAD_VALUE;
2358 }
2359
2360 uint32_t frameNumber = request->frame_number;
2361 if (request->num_output_buffers < 1 || request->output_buffers == NULL) {
2362 LOGE("Request %d: No output buffers provided!",
2363 __FUNCTION__, frameNumber);
2364 return BAD_VALUE;
2365 }
2366 if (request->num_output_buffers >= MAX_NUM_STREAMS) {
2367 LOGE("Number of buffers %d equals or is greater than maximum number of streams!",
2368 request->num_output_buffers, MAX_NUM_STREAMS);
2369 return BAD_VALUE;
2370 }
2371 if (request->input_buffer != NULL) {
2372 b = request->input_buffer;
2373 if (b->status != CAMERA3_BUFFER_STATUS_OK) {
2374 LOGE("Request %d: Buffer %ld: Status not OK!",
2375 frameNumber, (long)idx);
2376 return BAD_VALUE;
2377 }
2378 if (b->release_fence != -1) {
2379 LOGE("Request %d: Buffer %ld: Has a release fence!",
2380 frameNumber, (long)idx);
2381 return BAD_VALUE;
2382 }
2383 if (b->buffer == NULL) {
2384 LOGE("Request %d: Buffer %ld: NULL buffer handle!",
2385 frameNumber, (long)idx);
2386 return BAD_VALUE;
2387 }
2388 }
2389
2390 // Validate all buffers
2391 b = request->output_buffers;
2392 do {
2393 QCamera3ProcessingChannel *channel =
2394 static_cast<QCamera3ProcessingChannel*>(b->stream->priv);
2395 if (channel == NULL) {
2396 LOGE("Request %d: Buffer %ld: Unconfigured stream!",
2397 frameNumber, (long)idx);
2398 return BAD_VALUE;
2399 }
2400 if (b->status != CAMERA3_BUFFER_STATUS_OK) {
2401 LOGE("Request %d: Buffer %ld: Status not OK!",
2402 frameNumber, (long)idx);
2403 return BAD_VALUE;
2404 }
2405 if (b->release_fence != -1) {
2406 LOGE("Request %d: Buffer %ld: Has a release fence!",
2407 frameNumber, (long)idx);
2408 return BAD_VALUE;
2409 }
2410 if (b->buffer == NULL) {
2411 LOGE("Request %d: Buffer %ld: NULL buffer handle!",
2412 frameNumber, (long)idx);
2413 return BAD_VALUE;
2414 }
2415 if (*(b->buffer) == NULL) {
2416 LOGE("Request %d: Buffer %ld: NULL private handle!",
2417 frameNumber, (long)idx);
2418 return BAD_VALUE;
2419 }
2420 idx++;
2421 b = request->output_buffers + idx;
2422 } while (idx < (ssize_t)request->num_output_buffers);
2423
2424 return NO_ERROR;
2425}
2426
2427/*===========================================================================
2428 * FUNCTION : deriveMinFrameDuration
2429 *
2430 * DESCRIPTION: derive mininum processed, jpeg, and raw frame durations based
2431 * on currently configured streams.
2432 *
2433 * PARAMETERS : NONE
2434 *
2435 * RETURN : NONE
2436 *
2437 *==========================================================================*/
2438void QCamera3HardwareInterface::deriveMinFrameDuration()
2439{
2440 int32_t maxJpegDim, maxProcessedDim, maxRawDim;
2441
2442 maxJpegDim = 0;
2443 maxProcessedDim = 0;
2444 maxRawDim = 0;
2445
2446 // Figure out maximum jpeg, processed, and raw dimensions
2447 for (List<stream_info_t*>::iterator it = mStreamInfo.begin();
2448 it != mStreamInfo.end(); it++) {
2449
2450 // Input stream doesn't have valid stream_type
2451 if ((*it)->stream->stream_type == CAMERA3_STREAM_INPUT)
2452 continue;
2453
2454 int32_t dimension = (int32_t)((*it)->stream->width * (*it)->stream->height);
2455 if ((*it)->stream->format == HAL_PIXEL_FORMAT_BLOB) {
2456 if (dimension > maxJpegDim)
2457 maxJpegDim = dimension;
2458 } else if ((*it)->stream->format == HAL_PIXEL_FORMAT_RAW_OPAQUE ||
2459 (*it)->stream->format == HAL_PIXEL_FORMAT_RAW10 ||
2460 (*it)->stream->format == HAL_PIXEL_FORMAT_RAW16) {
2461 if (dimension > maxRawDim)
2462 maxRawDim = dimension;
2463 } else {
2464 if (dimension > maxProcessedDim)
2465 maxProcessedDim = dimension;
2466 }
2467 }
2468
2469 size_t count = MIN(gCamCapability[mCameraId]->supported_raw_dim_cnt,
2470 MAX_SIZES_CNT);
2471
2472 //Assume all jpeg dimensions are in processed dimensions.
2473 if (maxJpegDim > maxProcessedDim)
2474 maxProcessedDim = maxJpegDim;
2475 //Find the smallest raw dimension that is greater or equal to jpeg dimension
2476 if (maxProcessedDim > maxRawDim) {
2477 maxRawDim = INT32_MAX;
2478
2479 for (size_t i = 0; i < count; i++) {
2480 int32_t dimension = gCamCapability[mCameraId]->raw_dim[i].width *
2481 gCamCapability[mCameraId]->raw_dim[i].height;
2482 if (dimension >= maxProcessedDim && dimension < maxRawDim)
2483 maxRawDim = dimension;
2484 }
2485 }
2486
2487 //Find minimum durations for processed, jpeg, and raw
2488 for (size_t i = 0; i < count; i++) {
2489 if (maxRawDim == gCamCapability[mCameraId]->raw_dim[i].width *
2490 gCamCapability[mCameraId]->raw_dim[i].height) {
2491 mMinRawFrameDuration = gCamCapability[mCameraId]->raw_min_duration[i];
2492 break;
2493 }
2494 }
2495 count = MIN(gCamCapability[mCameraId]->picture_sizes_tbl_cnt, MAX_SIZES_CNT);
2496 for (size_t i = 0; i < count; i++) {
2497 if (maxProcessedDim ==
2498 gCamCapability[mCameraId]->picture_sizes_tbl[i].width *
2499 gCamCapability[mCameraId]->picture_sizes_tbl[i].height) {
2500 mMinProcessedFrameDuration = gCamCapability[mCameraId]->picture_min_duration[i];
2501 mMinJpegFrameDuration = gCamCapability[mCameraId]->picture_min_duration[i];
2502 break;
2503 }
2504 }
2505}
2506
2507/*===========================================================================
2508 * FUNCTION : getMinFrameDuration
2509 *
2510 * DESCRIPTION: get minimum frame draution based on the current maximum frame durations
2511 * and current request configuration.
2512 *
2513 * PARAMETERS : @request: requset sent by the frameworks
2514 *
2515 * RETURN : min farme duration for a particular request
2516 *
2517 *==========================================================================*/
2518int64_t QCamera3HardwareInterface::getMinFrameDuration(const camera3_capture_request_t *request)
2519{
2520 bool hasJpegStream = false;
2521 bool hasRawStream = false;
2522 for (uint32_t i = 0; i < request->num_output_buffers; i ++) {
2523 const camera3_stream_t *stream = request->output_buffers[i].stream;
2524 if (stream->format == HAL_PIXEL_FORMAT_BLOB)
2525 hasJpegStream = true;
2526 else if (stream->format == HAL_PIXEL_FORMAT_RAW_OPAQUE ||
2527 stream->format == HAL_PIXEL_FORMAT_RAW10 ||
2528 stream->format == HAL_PIXEL_FORMAT_RAW16)
2529 hasRawStream = true;
2530 }
2531
2532 if (!hasJpegStream)
2533 return MAX(mMinRawFrameDuration, mMinProcessedFrameDuration);
2534 else
2535 return MAX(MAX(mMinRawFrameDuration, mMinProcessedFrameDuration), mMinJpegFrameDuration);
2536}
2537
2538/*===========================================================================
2539 * FUNCTION : handleBuffersDuringFlushLock
2540 *
2541 * DESCRIPTION: Account for buffers returned from back-end during flush
2542 * This function is executed while mMutex is held by the caller.
2543 *
2544 * PARAMETERS :
2545 * @buffer: image buffer for the callback
2546 *
2547 * RETURN :
2548 *==========================================================================*/
2549void QCamera3HardwareInterface::handleBuffersDuringFlushLock(camera3_stream_buffer_t *buffer)
2550{
2551 bool buffer_found = false;
2552 for (List<PendingBuffersInRequest>::iterator req =
2553 mPendingBuffersMap.mPendingBuffersInRequest.begin();
2554 req != mPendingBuffersMap.mPendingBuffersInRequest.end(); req++) {
2555 for (List<PendingBufferInfo>::iterator i =
2556 req->mPendingBufferList.begin();
2557 i != req->mPendingBufferList.end(); i++) {
2558 if (i->buffer == buffer->buffer) {
2559 mPendingBuffersMap.numPendingBufsAtFlush--;
2560 LOGD("Found buffer %p for Frame %d, numPendingBufsAtFlush = %d",
2561 buffer->buffer, req->frame_number,
2562 mPendingBuffersMap.numPendingBufsAtFlush);
2563 buffer_found = true;
2564 break;
2565 }
2566 }
2567 if (buffer_found) {
2568 break;
2569 }
2570 }
2571 if (mPendingBuffersMap.numPendingBufsAtFlush == 0) {
2572 //signal the flush()
2573 LOGD("All buffers returned to HAL. Continue flush");
2574 pthread_cond_signal(&mBuffersCond);
2575 }
2576}
2577
2578
2579/*===========================================================================
2580 * FUNCTION : handlePendingReprocResults
2581 *
2582 * DESCRIPTION: check and notify on any pending reprocess results
2583 *
2584 * PARAMETERS :
2585 * @frame_number : Pending request frame number
2586 *
2587 * RETURN : int32_t type of status
2588 * NO_ERROR -- success
2589 * none-zero failure code
2590 *==========================================================================*/
2591int32_t QCamera3HardwareInterface::handlePendingReprocResults(uint32_t frame_number)
2592{
2593 for (List<PendingReprocessResult>::iterator j = mPendingReprocessResultList.begin();
2594 j != mPendingReprocessResultList.end(); j++) {
2595 if (j->frame_number == frame_number) {
2596 mCallbackOps->notify(mCallbackOps, &j->notify_msg);
2597
2598 LOGD("Delayed reprocess notify %d",
2599 frame_number);
2600
2601 for (pendingRequestIterator k = mPendingRequestsList.begin();
2602 k != mPendingRequestsList.end(); k++) {
2603
2604 if (k->frame_number == j->frame_number) {
2605 LOGD("Found reprocess frame number %d in pending reprocess List "
2606 "Take it out!!",
2607 k->frame_number);
2608
2609 camera3_capture_result result;
2610 memset(&result, 0, sizeof(camera3_capture_result));
2611 result.frame_number = frame_number;
2612 result.num_output_buffers = 1;
2613 result.output_buffers = &j->buffer;
2614 result.input_buffer = k->input_buffer;
2615 result.result = k->settings;
2616 result.partial_result = PARTIAL_RESULT_COUNT;
2617 mCallbackOps->process_capture_result(mCallbackOps, &result);
2618
2619 erasePendingRequest(k);
2620 break;
2621 }
2622 }
2623 mPendingReprocessResultList.erase(j);
2624 break;
2625 }
2626 }
2627 return NO_ERROR;
2628}
2629
2630/*===========================================================================
2631 * FUNCTION : handleBatchMetadata
2632 *
2633 * DESCRIPTION: Handles metadata buffer callback in batch mode
2634 *
2635 * PARAMETERS : @metadata_buf: metadata buffer
2636 * @free_and_bufdone_meta_buf: Buf done on the meta buf and free
2637 * the meta buf in this method
2638 *
2639 * RETURN :
2640 *
2641 *==========================================================================*/
2642void QCamera3HardwareInterface::handleBatchMetadata(
2643 mm_camera_super_buf_t *metadata_buf, bool free_and_bufdone_meta_buf)
2644{
2645 ATRACE_CALL();
2646
2647 if (NULL == metadata_buf) {
2648 LOGE("metadata_buf is NULL");
2649 return;
2650 }
2651 /* In batch mode, the metdata will contain the frame number and timestamp of
2652 * the last frame in the batch. Eg: a batch containing buffers from request
2653 * 5,6,7 and 8 will have frame number and timestamp corresponding to 8.
2654 * multiple process_capture_requests => 1 set_param => 1 handleBatchMetata =>
2655 * multiple process_capture_results */
2656 metadata_buffer_t *metadata =
2657 (metadata_buffer_t *)metadata_buf->bufs[0]->buffer;
2658 int32_t frame_number_valid = 0, urgent_frame_number_valid = 0;
2659 uint32_t last_frame_number = 0, last_urgent_frame_number = 0;
2660 uint32_t first_frame_number = 0, first_urgent_frame_number = 0;
2661 uint32_t frame_number = 0, urgent_frame_number = 0;
2662 int64_t last_frame_capture_time = 0, first_frame_capture_time, capture_time;
2663 bool invalid_metadata = false;
2664 size_t urgentFrameNumDiff = 0, frameNumDiff = 0;
2665 size_t loopCount = 1;
2666
2667 int32_t *p_frame_number_valid =
2668 POINTER_OF_META(CAM_INTF_META_FRAME_NUMBER_VALID, metadata);
2669 uint32_t *p_frame_number =
2670 POINTER_OF_META(CAM_INTF_META_FRAME_NUMBER, metadata);
2671 int64_t *p_capture_time =
2672 POINTER_OF_META(CAM_INTF_META_SENSOR_TIMESTAMP, metadata);
2673 int32_t *p_urgent_frame_number_valid =
2674 POINTER_OF_META(CAM_INTF_META_URGENT_FRAME_NUMBER_VALID, metadata);
2675 uint32_t *p_urgent_frame_number =
2676 POINTER_OF_META(CAM_INTF_META_URGENT_FRAME_NUMBER, metadata);
2677
2678 if ((NULL == p_frame_number_valid) || (NULL == p_frame_number) ||
2679 (NULL == p_capture_time) || (NULL == p_urgent_frame_number_valid) ||
2680 (NULL == p_urgent_frame_number)) {
2681 LOGE("Invalid metadata");
2682 invalid_metadata = true;
2683 } else {
2684 frame_number_valid = *p_frame_number_valid;
2685 last_frame_number = *p_frame_number;
2686 last_frame_capture_time = *p_capture_time;
2687 urgent_frame_number_valid = *p_urgent_frame_number_valid;
2688 last_urgent_frame_number = *p_urgent_frame_number;
2689 }
2690
2691 /* In batchmode, when no video buffers are requested, set_parms are sent
2692 * for every capture_request. The difference between consecutive urgent
2693 * frame numbers and frame numbers should be used to interpolate the
2694 * corresponding frame numbers and time stamps */
2695 pthread_mutex_lock(&mMutex);
2696 if (urgent_frame_number_valid) {
2697 first_urgent_frame_number =
2698 mPendingBatchMap.valueFor(last_urgent_frame_number);
2699 urgentFrameNumDiff = last_urgent_frame_number + 1 -
2700 first_urgent_frame_number;
2701
2702 LOGD("urgent_frm: valid: %d frm_num: %d - %d",
2703 urgent_frame_number_valid,
2704 first_urgent_frame_number, last_urgent_frame_number);
2705 }
2706
2707 if (frame_number_valid) {
2708 first_frame_number = mPendingBatchMap.valueFor(last_frame_number);
2709 frameNumDiff = last_frame_number + 1 -
2710 first_frame_number;
2711 mPendingBatchMap.removeItem(last_frame_number);
2712
2713 LOGD("frm: valid: %d frm_num: %d - %d",
2714 frame_number_valid,
2715 first_frame_number, last_frame_number);
2716
2717 }
2718 pthread_mutex_unlock(&mMutex);
2719
2720 if (urgent_frame_number_valid || frame_number_valid) {
2721 loopCount = MAX(urgentFrameNumDiff, frameNumDiff);
2722 if (urgentFrameNumDiff > MAX_HFR_BATCH_SIZE)
2723 LOGE("urgentFrameNumDiff: %d urgentFrameNum: %d",
2724 urgentFrameNumDiff, last_urgent_frame_number);
2725 if (frameNumDiff > MAX_HFR_BATCH_SIZE)
2726 LOGE("frameNumDiff: %d frameNum: %d",
2727 frameNumDiff, last_frame_number);
2728 }
2729
2730 for (size_t i = 0; i < loopCount; i++) {
2731 /* handleMetadataWithLock is called even for invalid_metadata for
2732 * pipeline depth calculation */
2733 if (!invalid_metadata) {
2734 /* Infer frame number. Batch metadata contains frame number of the
2735 * last frame */
2736 if (urgent_frame_number_valid) {
2737 if (i < urgentFrameNumDiff) {
2738 urgent_frame_number =
2739 first_urgent_frame_number + i;
2740 LOGD("inferred urgent frame_number: %d",
2741 urgent_frame_number);
2742 ADD_SET_PARAM_ENTRY_TO_BATCH(metadata,
2743 CAM_INTF_META_URGENT_FRAME_NUMBER, urgent_frame_number);
2744 } else {
2745 /* This is to handle when urgentFrameNumDiff < frameNumDiff */
2746 ADD_SET_PARAM_ENTRY_TO_BATCH(metadata,
2747 CAM_INTF_META_URGENT_FRAME_NUMBER_VALID, 0);
2748 }
2749 }
2750
2751 /* Infer frame number. Batch metadata contains frame number of the
2752 * last frame */
2753 if (frame_number_valid) {
2754 if (i < frameNumDiff) {
2755 frame_number = first_frame_number + i;
2756 LOGD("inferred frame_number: %d", frame_number);
2757 ADD_SET_PARAM_ENTRY_TO_BATCH(metadata,
2758 CAM_INTF_META_FRAME_NUMBER, frame_number);
2759 } else {
2760 /* This is to handle when urgentFrameNumDiff > frameNumDiff */
2761 ADD_SET_PARAM_ENTRY_TO_BATCH(metadata,
2762 CAM_INTF_META_FRAME_NUMBER_VALID, 0);
2763 }
2764 }
2765
2766 if (last_frame_capture_time) {
2767 //Infer timestamp
2768 first_frame_capture_time = last_frame_capture_time -
Thierry Strudel9e74aae2016-09-22 17:10:18 -07002769 (((loopCount - 1) * NSEC_PER_SEC) / (double) mHFRVideoFps);
Thierry Strudel3d639192016-09-09 11:52:26 -07002770 capture_time =
Thierry Strudel9e74aae2016-09-22 17:10:18 -07002771 first_frame_capture_time + (i * NSEC_PER_SEC / (double) mHFRVideoFps);
Thierry Strudel3d639192016-09-09 11:52:26 -07002772 ADD_SET_PARAM_ENTRY_TO_BATCH(metadata,
2773 CAM_INTF_META_SENSOR_TIMESTAMP, capture_time);
2774 LOGD("batch capture_time: %lld, capture_time: %lld",
2775 last_frame_capture_time, capture_time);
2776 }
2777 }
2778 pthread_mutex_lock(&mMutex);
2779 handleMetadataWithLock(metadata_buf,
Thierry Strudel9e74aae2016-09-22 17:10:18 -07002780 false /* free_and_bufdone_meta_buf */,
2781 (i == 0) /* first metadata in the batch metadata */);
Thierry Strudel3d639192016-09-09 11:52:26 -07002782 pthread_mutex_unlock(&mMutex);
2783 }
2784
2785 /* BufDone metadata buffer */
2786 if (free_and_bufdone_meta_buf) {
2787 mMetadataChannel->bufDone(metadata_buf);
2788 free(metadata_buf);
2789 }
2790}
2791
Thierry Strudel9e74aae2016-09-22 17:10:18 -07002792void QCamera3HardwareInterface::notifyError(uint32_t frameNumber,
2793 camera3_error_msg_code_t errorCode)
2794{
2795 camera3_notify_msg_t notify_msg;
2796 memset(&notify_msg, 0, sizeof(camera3_notify_msg_t));
2797 notify_msg.type = CAMERA3_MSG_ERROR;
2798 notify_msg.message.error.error_code = errorCode;
2799 notify_msg.message.error.error_stream = NULL;
2800 notify_msg.message.error.frame_number = frameNumber;
2801 mCallbackOps->notify(mCallbackOps, &notify_msg);
2802
2803 return;
2804}
Thierry Strudel3d639192016-09-09 11:52:26 -07002805/*===========================================================================
2806 * FUNCTION : handleMetadataWithLock
2807 *
2808 * DESCRIPTION: Handles metadata buffer callback with mMutex lock held.
2809 *
2810 * PARAMETERS : @metadata_buf: metadata buffer
2811 * @free_and_bufdone_meta_buf: Buf done on the meta buf and free
2812 * the meta buf in this method
Thierry Strudel9e74aae2016-09-22 17:10:18 -07002813 * @firstMetadataInBatch: Boolean to indicate whether this is the
2814 * first metadata in a batch. Valid only for batch mode
Thierry Strudel3d639192016-09-09 11:52:26 -07002815 *
2816 * RETURN :
2817 *
2818 *==========================================================================*/
2819void QCamera3HardwareInterface::handleMetadataWithLock(
Thierry Strudel9e74aae2016-09-22 17:10:18 -07002820 mm_camera_super_buf_t *metadata_buf, bool free_and_bufdone_meta_buf,
2821 bool firstMetadataInBatch)
Thierry Strudel3d639192016-09-09 11:52:26 -07002822{
2823 ATRACE_CALL();
2824 if ((mFlushPerf) || (ERROR == mState) || (DEINIT == mState)) {
2825 //during flush do not send metadata from this thread
2826 LOGD("not sending metadata during flush or when mState is error");
2827 if (free_and_bufdone_meta_buf) {
2828 mMetadataChannel->bufDone(metadata_buf);
2829 free(metadata_buf);
2830 }
2831 return;
2832 }
2833
2834 //not in flush
2835 metadata_buffer_t *metadata = (metadata_buffer_t *)metadata_buf->bufs[0]->buffer;
2836 int32_t frame_number_valid, urgent_frame_number_valid;
2837 uint32_t frame_number, urgent_frame_number;
2838 int64_t capture_time;
2839 nsecs_t currentSysTime;
2840
2841 int32_t *p_frame_number_valid =
2842 POINTER_OF_META(CAM_INTF_META_FRAME_NUMBER_VALID, metadata);
2843 uint32_t *p_frame_number = POINTER_OF_META(CAM_INTF_META_FRAME_NUMBER, metadata);
2844 int64_t *p_capture_time = POINTER_OF_META(CAM_INTF_META_SENSOR_TIMESTAMP, metadata);
2845 int32_t *p_urgent_frame_number_valid =
2846 POINTER_OF_META(CAM_INTF_META_URGENT_FRAME_NUMBER_VALID, metadata);
2847 uint32_t *p_urgent_frame_number =
2848 POINTER_OF_META(CAM_INTF_META_URGENT_FRAME_NUMBER, metadata);
2849 IF_META_AVAILABLE(cam_stream_ID_t, p_cam_frame_drop, CAM_INTF_META_FRAME_DROPPED,
2850 metadata) {
2851 LOGD("Dropped frame info for frame_number_valid %d, frame_number %d",
2852 *p_frame_number_valid, *p_frame_number);
2853 }
2854
2855 if ((NULL == p_frame_number_valid) || (NULL == p_frame_number) || (NULL == p_capture_time) ||
2856 (NULL == p_urgent_frame_number_valid) || (NULL == p_urgent_frame_number)) {
2857 LOGE("Invalid metadata");
2858 if (free_and_bufdone_meta_buf) {
2859 mMetadataChannel->bufDone(metadata_buf);
2860 free(metadata_buf);
2861 }
2862 goto done_metadata;
2863 }
2864 frame_number_valid = *p_frame_number_valid;
2865 frame_number = *p_frame_number;
2866 capture_time = *p_capture_time;
2867 urgent_frame_number_valid = *p_urgent_frame_number_valid;
2868 urgent_frame_number = *p_urgent_frame_number;
2869 currentSysTime = systemTime(CLOCK_MONOTONIC);
2870
2871 // Detect if buffers from any requests are overdue
2872 for (auto &req : mPendingBuffersMap.mPendingBuffersInRequest) {
2873 if ( (currentSysTime - req.timestamp) >
2874 s2ns(MISSING_REQUEST_BUF_TIMEOUT) ) {
2875 for (auto &missed : req.mPendingBufferList) {
2876 LOGE("Current frame: %d. Missing: frame = %d, buffer = %p,"
2877 "stream type = %d, stream format = %d",
2878 frame_number, req.frame_number, missed.buffer,
2879 missed.stream->stream_type, missed.stream->format);
2880 }
2881 }
2882 }
2883 //Partial result on process_capture_result for timestamp
2884 if (urgent_frame_number_valid) {
2885 LOGD("valid urgent frame_number = %u, capture_time = %lld",
2886 urgent_frame_number, capture_time);
2887
2888 //Recieved an urgent Frame Number, handle it
2889 //using partial results
2890 for (pendingRequestIterator i =
2891 mPendingRequestsList.begin(); i != mPendingRequestsList.end(); i++) {
2892 LOGD("Iterator Frame = %d urgent frame = %d",
2893 i->frame_number, urgent_frame_number);
2894
2895 if ((!i->input_buffer) && (i->frame_number < urgent_frame_number) &&
2896 (i->partial_result_cnt == 0)) {
2897 LOGE("Error: HAL missed urgent metadata for frame number %d",
2898 i->frame_number);
2899 }
2900
2901 if (i->frame_number == urgent_frame_number &&
2902 i->bUrgentReceived == 0) {
2903
2904 camera3_capture_result_t result;
2905 memset(&result, 0, sizeof(camera3_capture_result_t));
2906
2907 i->partial_result_cnt++;
2908 i->bUrgentReceived = 1;
2909 // Extract 3A metadata
2910 result.result =
2911 translateCbUrgentMetadataToResultMetadata(metadata);
2912 // Populate metadata result
2913 result.frame_number = urgent_frame_number;
2914 result.num_output_buffers = 0;
2915 result.output_buffers = NULL;
2916 result.partial_result = i->partial_result_cnt;
2917
2918 mCallbackOps->process_capture_result(mCallbackOps, &result);
2919 LOGD("urgent frame_number = %u, capture_time = %lld",
2920 result.frame_number, capture_time);
2921 free_camera_metadata((camera_metadata_t *)result.result);
2922 break;
2923 }
2924 }
2925 }
2926
2927 if (!frame_number_valid) {
2928 LOGD("Not a valid normal frame number, used as SOF only");
2929 if (free_and_bufdone_meta_buf) {
2930 mMetadataChannel->bufDone(metadata_buf);
2931 free(metadata_buf);
2932 }
2933 goto done_metadata;
2934 }
2935 LOGH("valid frame_number = %u, capture_time = %lld",
2936 frame_number, capture_time);
2937
2938 for (pendingRequestIterator i = mPendingRequestsList.begin();
2939 i != mPendingRequestsList.end() && i->frame_number <= frame_number;) {
2940 // Flush out all entries with less or equal frame numbers.
2941
2942 camera3_capture_result_t result;
2943 memset(&result, 0, sizeof(camera3_capture_result_t));
2944
2945 LOGD("frame_number in the list is %u", i->frame_number);
2946 i->partial_result_cnt++;
2947 result.partial_result = i->partial_result_cnt;
2948
2949 // Check whether any stream buffer corresponding to this is dropped or not
2950 // If dropped, then send the ERROR_BUFFER for the corresponding stream
Thierry Strudel3d639192016-09-09 11:52:26 -07002951 if (p_cam_frame_drop) {
2952 /* Clear notify_msg structure */
2953 camera3_notify_msg_t notify_msg;
2954 memset(&notify_msg, 0, sizeof(camera3_notify_msg_t));
2955 for (List<RequestedBufferInfo>::iterator j = i->buffers.begin();
2956 j != i->buffers.end(); j++) {
Thierry Strudel9e74aae2016-09-22 17:10:18 -07002957 QCamera3ProcessingChannel *channel = (QCamera3ProcessingChannel *)j->stream->priv;
2958 uint32_t streamID = channel->getStreamID(channel->getStreamTypeMask());
2959 for (uint32_t k = 0; k < p_cam_frame_drop->num_streams; k++) {
2960 if (streamID == p_cam_frame_drop->streamID[k]) {
2961 // Send Error notify to frameworks with CAMERA3_MSG_ERROR_BUFFER
2962 LOGE("Start of reporting error frame#=%u, streamID=%u",
2963 i->frame_number, streamID);
2964 notify_msg.type = CAMERA3_MSG_ERROR;
2965 notify_msg.message.error.frame_number = i->frame_number;
2966 notify_msg.message.error.error_code = CAMERA3_MSG_ERROR_BUFFER ;
2967 notify_msg.message.error.error_stream = j->stream;
2968 mCallbackOps->notify(mCallbackOps, &notify_msg);
2969 LOGE("End of reporting error frame#=%u, streamID=%u",
2970 i->frame_number, streamID);
2971 PendingFrameDropInfo PendingFrameDrop;
2972 PendingFrameDrop.frame_number=i->frame_number;
2973 PendingFrameDrop.stream_ID = streamID;
2974 // Add the Frame drop info to mPendingFrameDropList
2975 mPendingFrameDropList.push_back(PendingFrameDrop);
Thierry Strudel3d639192016-09-09 11:52:26 -07002976 }
Thierry Strudel9e74aae2016-09-22 17:10:18 -07002977 }
Thierry Strudel3d639192016-09-09 11:52:26 -07002978 }
2979 }
2980
2981 // Send empty metadata with already filled buffers for dropped metadata
2982 // and send valid metadata with already filled buffers for current metadata
2983 /* we could hit this case when we either
2984 * 1. have a pending reprocess request or
2985 * 2. miss a metadata buffer callback */
2986 if (i->frame_number < frame_number) {
2987 if (i->input_buffer) {
2988 /* this will be handled in handleInputBufferWithLock */
2989 i++;
2990 continue;
Thierry Strudel9e74aae2016-09-22 17:10:18 -07002991 } else if (mBatchSize) {
2992
2993 mPendingLiveRequest--;
2994
2995 CameraMetadata dummyMetadata;
2996 dummyMetadata.update(ANDROID_REQUEST_ID, &(i->request_id), 1);
2997 result.result = dummyMetadata.release();
2998
2999 notifyError(i->frame_number, CAMERA3_MSG_ERROR_RESULT);
Thierry Strudel3d639192016-09-09 11:52:26 -07003000 } else {
3001 LOGE("Fatal: Missing metadata buffer for frame number %d", i->frame_number);
3002 if (free_and_bufdone_meta_buf) {
3003 mMetadataChannel->bufDone(metadata_buf);
3004 free(metadata_buf);
3005 }
3006 mState = ERROR;
3007 goto done_metadata;
3008 }
3009 } else {
3010 mPendingLiveRequest--;
3011 /* Clear notify_msg structure */
3012 camera3_notify_msg_t notify_msg;
3013 memset(&notify_msg, 0, sizeof(camera3_notify_msg_t));
3014
3015 // Send shutter notify to frameworks
3016 notify_msg.type = CAMERA3_MSG_SHUTTER;
3017 notify_msg.message.shutter.frame_number = i->frame_number;
3018 notify_msg.message.shutter.timestamp = (uint64_t)capture_time;
3019 mCallbackOps->notify(mCallbackOps, &notify_msg);
3020
3021 i->timestamp = capture_time;
3022
3023 // Find channel requiring metadata, meaning internal offline postprocess
3024 // is needed.
3025 //TODO: for now, we don't support two streams requiring metadata at the same time.
3026 // (because we are not making copies, and metadata buffer is not reference counted.
3027 bool internalPproc = false;
3028 for (pendingBufferIterator iter = i->buffers.begin();
3029 iter != i->buffers.end(); iter++) {
3030 if (iter->need_metadata) {
3031 internalPproc = true;
3032 QCamera3ProcessingChannel *channel =
3033 (QCamera3ProcessingChannel *)iter->stream->priv;
3034 channel->queueReprocMetadata(metadata_buf);
3035 break;
3036 }
3037 }
3038
3039 result.result = translateFromHalMetadata(metadata,
3040 i->timestamp, i->request_id, i->jpegMetadata, i->pipeline_depth,
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003041 i->capture_intent, internalPproc, i->fwkCacMode,
3042 firstMetadataInBatch);
Thierry Strudel3d639192016-09-09 11:52:26 -07003043
3044 saveExifParams(metadata);
3045
3046 if (i->blob_request) {
3047 {
3048 //Dump tuning metadata if enabled and available
3049 char prop[PROPERTY_VALUE_MAX];
3050 memset(prop, 0, sizeof(prop));
3051 property_get("persist.camera.dumpmetadata", prop, "0");
3052 int32_t enabled = atoi(prop);
3053 if (enabled && metadata->is_tuning_params_valid) {
3054 dumpMetadataToFile(metadata->tuning_params,
3055 mMetaFrameCount,
3056 enabled,
3057 "Snapshot",
3058 frame_number);
3059 }
3060 }
3061 }
3062
3063 if (!internalPproc) {
3064 LOGD("couldn't find need_metadata for this metadata");
3065 // Return metadata buffer
3066 if (free_and_bufdone_meta_buf) {
3067 mMetadataChannel->bufDone(metadata_buf);
3068 free(metadata_buf);
3069 }
3070 }
3071 }
3072 if (!result.result) {
3073 LOGE("metadata is NULL");
3074 }
3075 result.frame_number = i->frame_number;
3076 result.input_buffer = i->input_buffer;
3077 result.num_output_buffers = 0;
3078 result.output_buffers = NULL;
3079 for (List<RequestedBufferInfo>::iterator j = i->buffers.begin();
3080 j != i->buffers.end(); j++) {
3081 if (j->buffer) {
3082 result.num_output_buffers++;
3083 }
3084 }
3085
3086 updateFpsInPreviewBuffer(metadata, i->frame_number);
3087
3088 if (result.num_output_buffers > 0) {
3089 camera3_stream_buffer_t *result_buffers =
3090 new camera3_stream_buffer_t[result.num_output_buffers];
3091 if (result_buffers != NULL) {
3092 size_t result_buffers_idx = 0;
3093 for (List<RequestedBufferInfo>::iterator j = i->buffers.begin();
3094 j != i->buffers.end(); j++) {
3095 if (j->buffer) {
3096 for (List<PendingFrameDropInfo>::iterator m = mPendingFrameDropList.begin();
3097 m != mPendingFrameDropList.end(); m++) {
3098 QCamera3Channel *channel = (QCamera3Channel *)j->buffer->stream->priv;
3099 uint32_t streamID = channel->getStreamID(channel->getStreamTypeMask());
3100 if((m->stream_ID == streamID) && (m->frame_number==frame_number)) {
3101 j->buffer->status=CAMERA3_BUFFER_STATUS_ERROR;
3102 LOGE("Stream STATUS_ERROR frame_number=%u, streamID=%u",
3103 frame_number, streamID);
3104 m = mPendingFrameDropList.erase(m);
3105 break;
3106 }
3107 }
3108 mPendingBuffersMap.removeBuf(j->buffer->buffer);
3109 result_buffers[result_buffers_idx++] = *(j->buffer);
3110 free(j->buffer);
3111 j->buffer = NULL;
3112 }
3113 }
3114 result.output_buffers = result_buffers;
3115 mCallbackOps->process_capture_result(mCallbackOps, &result);
3116 LOGD("meta frame_number = %u, capture_time = %lld",
3117 result.frame_number, i->timestamp);
3118 free_camera_metadata((camera_metadata_t *)result.result);
3119 delete[] result_buffers;
3120 }else {
3121 LOGE("Fatal error: out of memory");
3122 }
3123 } else {
3124 mCallbackOps->process_capture_result(mCallbackOps, &result);
3125 LOGD("meta frame_number = %u, capture_time = %lld",
3126 result.frame_number, i->timestamp);
3127 free_camera_metadata((camera_metadata_t *)result.result);
3128 }
3129
3130 i = erasePendingRequest(i);
3131
3132 if (!mPendingReprocessResultList.empty()) {
3133 handlePendingReprocResults(frame_number + 1);
3134 }
3135 }
3136
3137done_metadata:
3138 for (pendingRequestIterator i = mPendingRequestsList.begin();
3139 i != mPendingRequestsList.end() ;i++) {
3140 i->pipeline_depth++;
3141 }
3142 LOGD("mPendingLiveRequest = %d", mPendingLiveRequest);
3143 unblockRequestIfNecessary();
3144}
3145
3146/*===========================================================================
3147 * FUNCTION : hdrPlusPerfLock
3148 *
3149 * DESCRIPTION: perf lock for HDR+ using custom intent
3150 *
3151 * PARAMETERS : @metadata_buf: Metadata super_buf pointer
3152 *
3153 * RETURN : None
3154 *
3155 *==========================================================================*/
3156void QCamera3HardwareInterface::hdrPlusPerfLock(
3157 mm_camera_super_buf_t *metadata_buf)
3158{
3159 if (NULL == metadata_buf) {
3160 LOGE("metadata_buf is NULL");
3161 return;
3162 }
3163 metadata_buffer_t *metadata =
3164 (metadata_buffer_t *)metadata_buf->bufs[0]->buffer;
3165 int32_t *p_frame_number_valid =
3166 POINTER_OF_META(CAM_INTF_META_FRAME_NUMBER_VALID, metadata);
3167 uint32_t *p_frame_number =
3168 POINTER_OF_META(CAM_INTF_META_FRAME_NUMBER, metadata);
3169
3170 if (p_frame_number_valid == NULL || p_frame_number == NULL) {
3171 LOGE("%s: Invalid metadata", __func__);
3172 return;
3173 }
3174
3175 //acquire perf lock for 5 sec after the last HDR frame is captured
3176 if ((p_frame_number_valid != NULL) && *p_frame_number_valid) {
3177 if ((p_frame_number != NULL) &&
3178 (mLastCustIntentFrmNum == (int32_t)*p_frame_number)) {
3179 m_perfLock.lock_acq_timed(HDR_PLUS_PERF_TIME_OUT);
3180 }
3181 }
3182
3183 //release lock after perf lock timer is expired. If lock is already released,
3184 //isTimerReset returns false
3185 if (m_perfLock.isTimerReset()) {
3186 mLastCustIntentFrmNum = -1;
3187 m_perfLock.lock_rel_timed();
3188 }
3189}
3190
3191/*===========================================================================
3192 * FUNCTION : handleInputBufferWithLock
3193 *
3194 * DESCRIPTION: Handles input buffer and shutter callback with mMutex lock held.
3195 *
3196 * PARAMETERS : @frame_number: frame number of the input buffer
3197 *
3198 * RETURN :
3199 *
3200 *==========================================================================*/
3201void QCamera3HardwareInterface::handleInputBufferWithLock(uint32_t frame_number)
3202{
3203 ATRACE_CALL();
3204 pendingRequestIterator i = mPendingRequestsList.begin();
3205 while (i != mPendingRequestsList.end() && i->frame_number != frame_number){
3206 i++;
3207 }
3208 if (i != mPendingRequestsList.end() && i->input_buffer) {
3209 //found the right request
3210 if (!i->shutter_notified) {
3211 CameraMetadata settings;
3212 camera3_notify_msg_t notify_msg;
3213 memset(&notify_msg, 0, sizeof(camera3_notify_msg_t));
3214 nsecs_t capture_time = systemTime(CLOCK_MONOTONIC);
3215 if(i->settings) {
3216 settings = i->settings;
3217 if (settings.exists(ANDROID_SENSOR_TIMESTAMP)) {
3218 capture_time = settings.find(ANDROID_SENSOR_TIMESTAMP).data.i64[0];
3219 } else {
3220 LOGE("No timestamp in input settings! Using current one.");
3221 }
3222 } else {
3223 LOGE("Input settings missing!");
3224 }
3225
3226 notify_msg.type = CAMERA3_MSG_SHUTTER;
3227 notify_msg.message.shutter.frame_number = frame_number;
3228 notify_msg.message.shutter.timestamp = (uint64_t)capture_time;
3229 mCallbackOps->notify(mCallbackOps, &notify_msg);
3230 i->shutter_notified = true;
3231 LOGD("Input request metadata notify frame_number = %u, capture_time = %llu",
3232 i->frame_number, notify_msg.message.shutter.timestamp);
3233 }
3234
3235 if (i->input_buffer->release_fence != -1) {
3236 int32_t rc = sync_wait(i->input_buffer->release_fence, TIMEOUT_NEVER);
3237 close(i->input_buffer->release_fence);
3238 if (rc != OK) {
3239 LOGE("input buffer sync wait failed %d", rc);
3240 }
3241 }
3242
3243 camera3_capture_result result;
3244 memset(&result, 0, sizeof(camera3_capture_result));
3245 result.frame_number = frame_number;
3246 result.result = i->settings;
3247 result.input_buffer = i->input_buffer;
3248 result.partial_result = PARTIAL_RESULT_COUNT;
3249
3250 mCallbackOps->process_capture_result(mCallbackOps, &result);
3251 LOGD("Input request metadata and input buffer frame_number = %u",
3252 i->frame_number);
3253 i = erasePendingRequest(i);
3254 } else {
3255 LOGE("Could not find input request for frame number %d", frame_number);
3256 }
3257}
3258
3259/*===========================================================================
3260 * FUNCTION : handleBufferWithLock
3261 *
3262 * DESCRIPTION: Handles image buffer callback with mMutex lock held.
3263 *
3264 * PARAMETERS : @buffer: image buffer for the callback
3265 * @frame_number: frame number of the image buffer
3266 *
3267 * RETURN :
3268 *
3269 *==========================================================================*/
3270void QCamera3HardwareInterface::handleBufferWithLock(
3271 camera3_stream_buffer_t *buffer, uint32_t frame_number)
3272{
3273 ATRACE_CALL();
3274 /* Nothing to be done during error state */
3275 if ((ERROR == mState) || (DEINIT == mState)) {
3276 return;
3277 }
3278 if (mFlushPerf) {
3279 handleBuffersDuringFlushLock(buffer);
3280 return;
3281 }
3282 //not in flush
3283 // If the frame number doesn't exist in the pending request list,
3284 // directly send the buffer to the frameworks, and update pending buffers map
3285 // Otherwise, book-keep the buffer.
3286 pendingRequestIterator i = mPendingRequestsList.begin();
3287 while (i != mPendingRequestsList.end() && i->frame_number != frame_number){
3288 i++;
3289 }
3290 if (i == mPendingRequestsList.end()) {
3291 // Verify all pending requests frame_numbers are greater
3292 for (pendingRequestIterator j = mPendingRequestsList.begin();
3293 j != mPendingRequestsList.end(); j++) {
3294 if ((j->frame_number < frame_number) && !(j->input_buffer)) {
3295 LOGW("Error: pending live frame number %d is smaller than %d",
3296 j->frame_number, frame_number);
3297 }
3298 }
3299 camera3_capture_result_t result;
3300 memset(&result, 0, sizeof(camera3_capture_result_t));
3301 result.result = NULL;
3302 result.frame_number = frame_number;
3303 result.num_output_buffers = 1;
3304 result.partial_result = 0;
3305 for (List<PendingFrameDropInfo>::iterator m = mPendingFrameDropList.begin();
3306 m != mPendingFrameDropList.end(); m++) {
3307 QCamera3Channel *channel = (QCamera3Channel *)buffer->stream->priv;
3308 uint32_t streamID = channel->getStreamID(channel->getStreamTypeMask());
3309 if((m->stream_ID == streamID) && (m->frame_number==frame_number) ) {
3310 buffer->status=CAMERA3_BUFFER_STATUS_ERROR;
3311 LOGD("Stream STATUS_ERROR frame_number=%d, streamID=%d",
3312 frame_number, streamID);
3313 m = mPendingFrameDropList.erase(m);
3314 break;
3315 }
3316 }
3317 result.output_buffers = buffer;
3318 LOGH("result frame_number = %d, buffer = %p",
3319 frame_number, buffer->buffer);
3320
3321 mPendingBuffersMap.removeBuf(buffer->buffer);
3322
3323 mCallbackOps->process_capture_result(mCallbackOps, &result);
3324 } else {
3325 if (i->input_buffer) {
3326 CameraMetadata settings;
3327 camera3_notify_msg_t notify_msg;
3328 memset(&notify_msg, 0, sizeof(camera3_notify_msg_t));
3329 nsecs_t capture_time = systemTime(CLOCK_MONOTONIC);
3330 if(i->settings) {
3331 settings = i->settings;
3332 if (settings.exists(ANDROID_SENSOR_TIMESTAMP)) {
3333 capture_time = settings.find(ANDROID_SENSOR_TIMESTAMP).data.i64[0];
3334 } else {
3335 LOGW("No timestamp in input settings! Using current one.");
3336 }
3337 } else {
3338 LOGE("Input settings missing!");
3339 }
3340
3341 notify_msg.type = CAMERA3_MSG_SHUTTER;
3342 notify_msg.message.shutter.frame_number = frame_number;
3343 notify_msg.message.shutter.timestamp = (uint64_t)capture_time;
3344
3345 if (i->input_buffer->release_fence != -1) {
3346 int32_t rc = sync_wait(i->input_buffer->release_fence, TIMEOUT_NEVER);
3347 close(i->input_buffer->release_fence);
3348 if (rc != OK) {
3349 LOGE("input buffer sync wait failed %d", rc);
3350 }
3351 }
3352 mPendingBuffersMap.removeBuf(buffer->buffer);
3353
3354 bool notifyNow = true;
3355 for (pendingRequestIterator j = mPendingRequestsList.begin();
3356 j != mPendingRequestsList.end(); j++) {
3357 if (j->frame_number < frame_number) {
3358 notifyNow = false;
3359 break;
3360 }
3361 }
3362
3363 if (notifyNow) {
3364 camera3_capture_result result;
3365 memset(&result, 0, sizeof(camera3_capture_result));
3366 result.frame_number = frame_number;
3367 result.result = i->settings;
3368 result.input_buffer = i->input_buffer;
3369 result.num_output_buffers = 1;
3370 result.output_buffers = buffer;
3371 result.partial_result = PARTIAL_RESULT_COUNT;
3372
3373 mCallbackOps->notify(mCallbackOps, &notify_msg);
3374 mCallbackOps->process_capture_result(mCallbackOps, &result);
3375 LOGD("Notify reprocess now %d!", frame_number);
3376 i = erasePendingRequest(i);
3377 } else {
3378 // Cache reprocess result for later
3379 PendingReprocessResult pendingResult;
3380 memset(&pendingResult, 0, sizeof(PendingReprocessResult));
3381 pendingResult.notify_msg = notify_msg;
3382 pendingResult.buffer = *buffer;
3383 pendingResult.frame_number = frame_number;
3384 mPendingReprocessResultList.push_back(pendingResult);
3385 LOGD("Cache reprocess result %d!", frame_number);
3386 }
3387 } else {
3388 for (List<RequestedBufferInfo>::iterator j = i->buffers.begin();
3389 j != i->buffers.end(); j++) {
3390 if (j->stream == buffer->stream) {
3391 if (j->buffer != NULL) {
3392 LOGE("Error: buffer is already set");
3393 } else {
3394 j->buffer = (camera3_stream_buffer_t *)malloc(
3395 sizeof(camera3_stream_buffer_t));
3396 *(j->buffer) = *buffer;
3397 LOGH("cache buffer %p at result frame_number %u",
3398 buffer->buffer, frame_number);
3399 }
3400 }
3401 }
3402 }
3403 }
3404}
3405
3406/*===========================================================================
3407 * FUNCTION : unblockRequestIfNecessary
3408 *
3409 * DESCRIPTION: Unblock capture_request if max_buffer hasn't been reached. Note
3410 * that mMutex is held when this function is called.
3411 *
3412 * PARAMETERS :
3413 *
3414 * RETURN :
3415 *
3416 *==========================================================================*/
3417void QCamera3HardwareInterface::unblockRequestIfNecessary()
3418{
3419 // Unblock process_capture_request
3420 pthread_cond_signal(&mRequestCond);
3421}
3422
3423
3424/*===========================================================================
3425 * FUNCTION : processCaptureRequest
3426 *
3427 * DESCRIPTION: process a capture request from camera service
3428 *
3429 * PARAMETERS :
3430 * @request : request from framework to process
3431 *
3432 * RETURN :
3433 *
3434 *==========================================================================*/
3435int QCamera3HardwareInterface::processCaptureRequest(
3436 camera3_capture_request_t *request)
3437{
3438 ATRACE_CALL();
3439 int rc = NO_ERROR;
3440 int32_t request_id;
3441 CameraMetadata meta;
Thierry Strudel3d639192016-09-09 11:52:26 -07003442 bool isVidBufRequested = false;
3443 camera3_stream_buffer_t *pInputBuffer = NULL;
3444
3445 pthread_mutex_lock(&mMutex);
3446
3447 // Validate current state
3448 switch (mState) {
3449 case CONFIGURED:
3450 case STARTED:
3451 /* valid state */
3452 break;
3453
3454 case ERROR:
3455 pthread_mutex_unlock(&mMutex);
3456 handleCameraDeviceError();
3457 return -ENODEV;
3458
3459 default:
3460 LOGE("Invalid state %d", mState);
3461 pthread_mutex_unlock(&mMutex);
3462 return -ENODEV;
3463 }
3464
3465 rc = validateCaptureRequest(request);
3466 if (rc != NO_ERROR) {
3467 LOGE("incoming request is not valid");
3468 pthread_mutex_unlock(&mMutex);
3469 return rc;
3470 }
3471
3472 meta = request->settings;
3473
3474 // For first capture request, send capture intent, and
3475 // stream on all streams
3476 if (mState == CONFIGURED) {
3477 // send an unconfigure to the backend so that the isp
3478 // resources are deallocated
3479 if (!mFirstConfiguration) {
3480 cam_stream_size_info_t stream_config_info;
3481 int32_t hal_version = CAM_HAL_V3;
3482 memset(&stream_config_info, 0, sizeof(cam_stream_size_info_t));
3483 stream_config_info.buffer_info.min_buffers =
3484 MIN_INFLIGHT_REQUESTS;
3485 stream_config_info.buffer_info.max_buffers =
3486 m_bIs4KVideo ? 0 : MAX_INFLIGHT_REQUESTS;
3487 clear_metadata_buffer(mParameters);
3488 ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters,
3489 CAM_INTF_PARM_HAL_VERSION, hal_version);
3490 ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters,
3491 CAM_INTF_META_STREAM_INFO, stream_config_info);
3492 rc = mCameraHandle->ops->set_parms(mCameraHandle->camera_handle,
3493 mParameters);
3494 if (rc < 0) {
3495 LOGE("set_parms for unconfigure failed");
3496 pthread_mutex_unlock(&mMutex);
3497 return rc;
3498 }
3499 }
3500 m_perfLock.lock_acq();
3501 /* get eis information for stream configuration */
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003502 cam_is_type_t isTypeVideo, isTypePreview, is_type=IS_TYPE_NONE;
Thierry Strudel3d639192016-09-09 11:52:26 -07003503 char is_type_value[PROPERTY_VALUE_MAX];
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003504 property_get("persist.camera.is_type", is_type_value, "4");
3505 isTypeVideo = static_cast<cam_is_type_t>(atoi(is_type_value));
3506 // Make default value for preview IS_TYPE as IS_TYPE_EIS_2_0
3507 property_get("persist.camera.is_type_preview", is_type_value, "4");
3508 isTypePreview = static_cast<cam_is_type_t>(atoi(is_type_value));
3509 LOGD("isTypeVideo: %d isTypePreview: %d", isTypeVideo, isTypePreview);
Thierry Strudel3d639192016-09-09 11:52:26 -07003510
3511 if (meta.exists(ANDROID_CONTROL_CAPTURE_INTENT)) {
3512 int32_t hal_version = CAM_HAL_V3;
3513 uint8_t captureIntent =
3514 meta.find(ANDROID_CONTROL_CAPTURE_INTENT).data.u8[0];
3515 mCaptureIntent = captureIntent;
3516 clear_metadata_buffer(mParameters);
3517 ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_PARM_HAL_VERSION, hal_version);
3518 ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_META_CAPTURE_INTENT, captureIntent);
3519 }
3520
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003521 uint8_t fwkVideoStabMode=0;
3522 if (meta.exists(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE)) {
3523 fwkVideoStabMode = meta.find(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE).data.u8[0];
3524 }
3525
3526 // If EIS setprop is enabled & if first capture setting has EIS enabled then only
3527 // turn it on for video/preview
3528 bool setEis = m_bEisEnable && fwkVideoStabMode && m_bEisSupportedSize &&
3529 (isTypeVideo >= IS_TYPE_EIS_2_0);
Thierry Strudel3d639192016-09-09 11:52:26 -07003530 int32_t vsMode;
3531 vsMode = (setEis)? DIS_ENABLE: DIS_DISABLE;
3532 if (ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_PARM_DIS_ENABLE, vsMode)) {
3533 rc = BAD_VALUE;
3534 }
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003535 LOGD("setEis %d", setEis);
3536 bool eis3Supported = false;
3537 size_t count = IS_TYPE_MAX;
3538 count = MIN(gCamCapability[mCameraId]->supported_is_types_cnt, count);
3539 for (size_t i = 0; i < count; i++) {
3540 if (gCamCapability[mCameraId]->supported_is_types[i] == IS_TYPE_EIS_3_0) {
3541 eis3Supported = true;
3542 break;
3543 }
3544 }
Thierry Strudel3d639192016-09-09 11:52:26 -07003545
3546 //IS type will be 0 unless EIS is supported. If EIS is supported
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003547 //it could either be 4 or 5 depending on the stream and video size
Thierry Strudel3d639192016-09-09 11:52:26 -07003548 for (uint32_t i = 0; i < mStreamConfigInfo.num_streams; i++) {
3549 if (setEis) {
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003550 if (mStreamConfigInfo.type[i] == CAM_STREAM_TYPE_PREVIEW) {
3551 is_type = isTypePreview;
3552 } else if (mStreamConfigInfo.type[i] == CAM_STREAM_TYPE_VIDEO ) {
3553 if ( (isTypeVideo == IS_TYPE_EIS_3_0) && (eis3Supported == FALSE) ) {
3554 LOGW(" EIS_3.0 is not supported and so setting EIS_2.0");
Thierry Strudel3d639192016-09-09 11:52:26 -07003555 is_type = IS_TYPE_EIS_2_0;
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003556 } else {
3557 is_type = isTypeVideo;
Thierry Strudel3d639192016-09-09 11:52:26 -07003558 }
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003559 } else {
3560 is_type = IS_TYPE_NONE;
3561 }
Thierry Strudel3d639192016-09-09 11:52:26 -07003562 mStreamConfigInfo.is_type[i] = is_type;
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003563 } else {
Thierry Strudel3d639192016-09-09 11:52:26 -07003564 mStreamConfigInfo.is_type[i] = IS_TYPE_NONE;
3565 }
3566 }
3567
3568 ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters,
3569 CAM_INTF_META_STREAM_INFO, mStreamConfigInfo);
3570
3571 int32_t tintless_value = 1;
3572 ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters,
3573 CAM_INTF_PARM_TINTLESS, tintless_value);
3574 //Disable CDS for HFR mode or if DIS/EIS is on.
3575 //CDS is a session parameter in the backend/ISP, so need to be set/reset
3576 //after every configure_stream
3577 if ((CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE == mOpMode) ||
3578 (m_bIsVideo)) {
3579 int32_t cds = CAM_CDS_MODE_OFF;
3580 if (ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters,
3581 CAM_INTF_PARM_CDS_MODE, cds))
3582 LOGE("Failed to disable CDS for HFR mode");
3583
3584 }
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003585
3586 if (m_debug_avtimer || meta.exists(QCAMERA3_USE_AV_TIMER)) {
3587 uint8_t* use_av_timer = NULL;
3588
3589 if (m_debug_avtimer){
3590 use_av_timer = &m_debug_avtimer;
3591 }
3592 else{
3593 use_av_timer =
3594 meta.find(QCAMERA3_USE_AV_TIMER).data.u8;
3595 }
3596
3597 if (ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_META_USE_AV_TIMER, *use_av_timer)) {
3598 rc = BAD_VALUE;
3599 }
3600 }
3601
Thierry Strudel3d639192016-09-09 11:52:26 -07003602 setMobicat();
3603
3604 /* Set fps and hfr mode while sending meta stream info so that sensor
3605 * can configure appropriate streaming mode */
3606 mHFRVideoFps = DEFAULT_VIDEO_FPS;
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003607 mMinInFlightRequests = MIN_INFLIGHT_REQUESTS;
3608 mMaxInFlightRequests = MAX_INFLIGHT_REQUESTS;
Thierry Strudel3d639192016-09-09 11:52:26 -07003609 if (meta.exists(ANDROID_CONTROL_AE_TARGET_FPS_RANGE)) {
3610 rc = setHalFpsRange(meta, mParameters);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003611 if (rc == NO_ERROR) {
3612 int32_t max_fps =
3613 (int32_t) meta.find(ANDROID_CONTROL_AE_TARGET_FPS_RANGE).data.i32[1];
3614 if (max_fps == 60) {
3615 mMinInFlightRequests = MIN_INFLIGHT_60FPS_REQUESTS;
3616 }
3617 /* For HFR, more buffers are dequeued upfront to improve the performance */
3618 if (mBatchSize) {
3619 mMinInFlightRequests = MIN_INFLIGHT_HFR_REQUESTS;
3620 mMaxInFlightRequests = MAX_INFLIGHT_HFR_REQUESTS;
3621 }
3622 }
3623 else {
Thierry Strudel3d639192016-09-09 11:52:26 -07003624 LOGE("setHalFpsRange failed");
3625 }
3626 }
3627 if (meta.exists(ANDROID_CONTROL_MODE)) {
3628 uint8_t metaMode = meta.find(ANDROID_CONTROL_MODE).data.u8[0];
3629 rc = extractSceneMode(meta, metaMode, mParameters);
3630 if (rc != NO_ERROR) {
3631 LOGE("extractSceneMode failed");
3632 }
3633 }
3634
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003635
Thierry Strudel3d639192016-09-09 11:52:26 -07003636 //TODO: validate the arguments, HSV scenemode should have only the
3637 //advertised fps ranges
3638
3639 /*set the capture intent, hal version, tintless, stream info,
3640 *and disenable parameters to the backend*/
3641 LOGD("set_parms META_STREAM_INFO " );
3642 for (uint32_t i = 0; i < mStreamConfigInfo.num_streams; i++) {
3643 LOGI("STREAM INFO : type %d, wxh: %d x %d, pp_mask: 0x%x "
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003644 "Format:%d is_type: %d",
Thierry Strudel3d639192016-09-09 11:52:26 -07003645 mStreamConfigInfo.type[i],
3646 mStreamConfigInfo.stream_sizes[i].width,
3647 mStreamConfigInfo.stream_sizes[i].height,
3648 mStreamConfigInfo.postprocess_mask[i],
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003649 mStreamConfigInfo.format[i],
3650 mStreamConfigInfo.is_type[i]);
Thierry Strudel3d639192016-09-09 11:52:26 -07003651 }
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003652
Thierry Strudel3d639192016-09-09 11:52:26 -07003653 rc = mCameraHandle->ops->set_parms(mCameraHandle->camera_handle,
3654 mParameters);
3655 if (rc < 0) {
3656 LOGE("set_parms failed for hal version, stream info");
3657 }
3658
3659 cam_dimension_t sensor_dim;
3660 memset(&sensor_dim, 0, sizeof(sensor_dim));
3661 rc = getSensorOutputSize(sensor_dim);
3662 if (rc != NO_ERROR) {
3663 LOGE("Failed to get sensor output size");
3664 pthread_mutex_unlock(&mMutex);
3665 goto error_exit;
3666 }
3667
3668 mCropRegionMapper.update(gCamCapability[mCameraId]->active_array_size.width,
3669 gCamCapability[mCameraId]->active_array_size.height,
3670 sensor_dim.width, sensor_dim.height);
3671
3672 /* Set batchmode before initializing channel. Since registerBuffer
3673 * internally initializes some of the channels, better set batchmode
3674 * even before first register buffer */
3675 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
3676 it != mStreamInfo.end(); it++) {
3677 QCamera3Channel *channel = (QCamera3Channel *)(*it)->stream->priv;
3678 if (((1U << CAM_STREAM_TYPE_VIDEO) == channel->getStreamTypeMask())
3679 && mBatchSize) {
3680 rc = channel->setBatchSize(mBatchSize);
3681 //Disable per frame map unmap for HFR/batchmode case
3682 rc |= channel->setPerFrameMapUnmap(false);
3683 if (NO_ERROR != rc) {
3684 LOGE("Channel init failed %d", rc);
3685 pthread_mutex_unlock(&mMutex);
3686 goto error_exit;
3687 }
3688 }
3689 }
3690
3691 //First initialize all streams
3692 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
3693 it != mStreamInfo.end(); it++) {
3694 QCamera3Channel *channel = (QCamera3Channel *)(*it)->stream->priv;
3695 if ((((1U << CAM_STREAM_TYPE_VIDEO) == channel->getStreamTypeMask()) ||
3696 ((1U << CAM_STREAM_TYPE_PREVIEW) == channel->getStreamTypeMask())) &&
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003697 setEis) {
3698 for (size_t i = 0; i < mStreamConfigInfo.num_streams; i++) {
3699 if ( (1U << mStreamConfigInfo.type[i]) == channel->getStreamTypeMask() ) {
3700 is_type = mStreamConfigInfo.is_type[i];
3701 break;
3702 }
3703 }
Thierry Strudel3d639192016-09-09 11:52:26 -07003704 rc = channel->initialize(is_type);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003705 } else {
Thierry Strudel3d639192016-09-09 11:52:26 -07003706 rc = channel->initialize(IS_TYPE_NONE);
3707 }
3708 if (NO_ERROR != rc) {
3709 LOGE("Channel initialization failed %d", rc);
3710 pthread_mutex_unlock(&mMutex);
3711 goto error_exit;
3712 }
3713 }
3714
3715 if (mRawDumpChannel) {
3716 rc = mRawDumpChannel->initialize(IS_TYPE_NONE);
3717 if (rc != NO_ERROR) {
3718 LOGE("Error: Raw Dump Channel init failed");
3719 pthread_mutex_unlock(&mMutex);
3720 goto error_exit;
3721 }
3722 }
3723 if (mSupportChannel) {
3724 rc = mSupportChannel->initialize(IS_TYPE_NONE);
3725 if (rc < 0) {
3726 LOGE("Support channel initialization failed");
3727 pthread_mutex_unlock(&mMutex);
3728 goto error_exit;
3729 }
3730 }
3731 if (mAnalysisChannel) {
3732 rc = mAnalysisChannel->initialize(IS_TYPE_NONE);
3733 if (rc < 0) {
3734 LOGE("Analysis channel initialization failed");
3735 pthread_mutex_unlock(&mMutex);
3736 goto error_exit;
3737 }
3738 }
3739 if (mDummyBatchChannel) {
3740 rc = mDummyBatchChannel->setBatchSize(mBatchSize);
3741 if (rc < 0) {
3742 LOGE("mDummyBatchChannel setBatchSize failed");
3743 pthread_mutex_unlock(&mMutex);
3744 goto error_exit;
3745 }
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003746 rc = mDummyBatchChannel->initialize(IS_TYPE_NONE);
Thierry Strudel3d639192016-09-09 11:52:26 -07003747 if (rc < 0) {
3748 LOGE("mDummyBatchChannel initialization failed");
3749 pthread_mutex_unlock(&mMutex);
3750 goto error_exit;
3751 }
3752 }
3753
3754 // Set bundle info
3755 rc = setBundleInfo();
3756 if (rc < 0) {
3757 LOGE("setBundleInfo failed %d", rc);
3758 pthread_mutex_unlock(&mMutex);
3759 goto error_exit;
3760 }
3761
3762 //update settings from app here
3763 if (meta.exists(QCAMERA3_DUALCAM_LINK_ENABLE)) {
3764 mIsDeviceLinked = meta.find(QCAMERA3_DUALCAM_LINK_ENABLE).data.u8[0];
3765 LOGH("Dualcam: setting On=%d id =%d", mIsDeviceLinked, mCameraId);
3766 }
3767 if (meta.exists(QCAMERA3_DUALCAM_LINK_IS_MAIN)) {
3768 mIsMainCamera = meta.find(QCAMERA3_DUALCAM_LINK_IS_MAIN).data.u8[0];
3769 LOGH("Dualcam: Is this main camera = %d id =%d", mIsMainCamera, mCameraId);
3770 }
3771 if (meta.exists(QCAMERA3_DUALCAM_LINK_RELATED_CAMERA_ID)) {
3772 mLinkedCameraId = meta.find(QCAMERA3_DUALCAM_LINK_RELATED_CAMERA_ID).data.u8[0];
3773 LOGH("Dualcam: Linked camera Id %d id =%d", mLinkedCameraId, mCameraId);
3774
3775 if ( (mLinkedCameraId >= MM_CAMERA_MAX_NUM_SENSORS) &&
3776 (mLinkedCameraId != mCameraId) ) {
3777 LOGE("Dualcam: mLinkedCameraId %d is invalid, current cam id = %d",
3778 mLinkedCameraId, mCameraId);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003779 pthread_mutex_unlock(&mMutex);
Thierry Strudel3d639192016-09-09 11:52:26 -07003780 goto error_exit;
3781 }
3782 }
3783
3784 // add bundle related cameras
3785 LOGH("%s: Dualcam: id =%d, mIsDeviceLinked=%d", __func__,mCameraId, mIsDeviceLinked);
3786 if (meta.exists(QCAMERA3_DUALCAM_LINK_ENABLE)) {
3787 if (mIsDeviceLinked)
3788 m_pRelCamSyncBuf->sync_control = CAM_SYNC_RELATED_SENSORS_ON;
3789 else
3790 m_pRelCamSyncBuf->sync_control = CAM_SYNC_RELATED_SENSORS_OFF;
3791
3792 pthread_mutex_lock(&gCamLock);
3793
3794 if (sessionId[mLinkedCameraId] == 0xDEADBEEF) {
3795 LOGE("Dualcam: Invalid Session Id ");
3796 pthread_mutex_unlock(&gCamLock);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003797 pthread_mutex_unlock(&mMutex);
Thierry Strudel3d639192016-09-09 11:52:26 -07003798 goto error_exit;
3799 }
3800
3801 if (mIsMainCamera == 1) {
3802 m_pRelCamSyncBuf->mode = CAM_MODE_PRIMARY;
3803 m_pRelCamSyncBuf->type = CAM_TYPE_MAIN;
3804 // related session id should be session id of linked session
3805 m_pRelCamSyncBuf->related_sensor_session_id = sessionId[mLinkedCameraId];
3806 } else {
3807 m_pRelCamSyncBuf->mode = CAM_MODE_SECONDARY;
3808 m_pRelCamSyncBuf->type = CAM_TYPE_AUX;
3809 m_pRelCamSyncBuf->related_sensor_session_id = sessionId[mLinkedCameraId];
3810 }
3811 pthread_mutex_unlock(&gCamLock);
3812
3813 rc = mCameraHandle->ops->sync_related_sensors(
3814 mCameraHandle->camera_handle, m_pRelCamSyncBuf);
3815 if (rc < 0) {
3816 LOGE("Dualcam: link failed");
Thierry Strudel9e74aae2016-09-22 17:10:18 -07003817 pthread_mutex_unlock(&mMutex);
Thierry Strudel3d639192016-09-09 11:52:26 -07003818 goto error_exit;
3819 }
3820 }
3821
3822 //Then start them.
3823 LOGH("Start META Channel");
3824 rc = mMetadataChannel->start();
3825 if (rc < 0) {
3826 LOGE("META channel start failed");
3827 pthread_mutex_unlock(&mMutex);
3828 goto error_exit;
3829 }
3830
3831 if (mAnalysisChannel) {
3832 rc = mAnalysisChannel->start();
3833 if (rc < 0) {
3834 LOGE("Analysis channel start failed");
3835 mMetadataChannel->stop();
3836 pthread_mutex_unlock(&mMutex);
3837 goto error_exit;
3838 }
3839 }
3840
3841 if (mSupportChannel) {
3842 rc = mSupportChannel->start();
3843 if (rc < 0) {
3844 LOGE("Support channel start failed");
3845 mMetadataChannel->stop();
3846 /* Although support and analysis are mutually exclusive today
3847 adding it in anycase for future proofing */
3848 if (mAnalysisChannel) {
3849 mAnalysisChannel->stop();
3850 }
3851 pthread_mutex_unlock(&mMutex);
3852 goto error_exit;
3853 }
3854 }
3855 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
3856 it != mStreamInfo.end(); it++) {
3857 QCamera3Channel *channel = (QCamera3Channel *)(*it)->stream->priv;
3858 LOGH("Start Processing Channel mask=%d",
3859 channel->getStreamTypeMask());
3860 rc = channel->start();
3861 if (rc < 0) {
3862 LOGE("channel start failed");
3863 pthread_mutex_unlock(&mMutex);
3864 goto error_exit;
3865 }
3866 }
3867
3868 if (mRawDumpChannel) {
3869 LOGD("Starting raw dump stream");
3870 rc = mRawDumpChannel->start();
3871 if (rc != NO_ERROR) {
3872 LOGE("Error Starting Raw Dump Channel");
3873 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
3874 it != mStreamInfo.end(); it++) {
3875 QCamera3Channel *channel =
3876 (QCamera3Channel *)(*it)->stream->priv;
3877 LOGH("Stopping Processing Channel mask=%d",
3878 channel->getStreamTypeMask());
3879 channel->stop();
3880 }
3881 if (mSupportChannel)
3882 mSupportChannel->stop();
3883 if (mAnalysisChannel) {
3884 mAnalysisChannel->stop();
3885 }
3886 mMetadataChannel->stop();
3887 pthread_mutex_unlock(&mMutex);
3888 goto error_exit;
3889 }
3890 }
3891
3892 if (mChannelHandle) {
3893
3894 rc = mCameraHandle->ops->start_channel(mCameraHandle->camera_handle,
3895 mChannelHandle);
3896 if (rc != NO_ERROR) {
3897 LOGE("start_channel failed %d", rc);
3898 pthread_mutex_unlock(&mMutex);
3899 goto error_exit;
3900 }
3901 }
3902
3903 goto no_error;
3904error_exit:
3905 m_perfLock.lock_rel();
3906 return rc;
3907no_error:
3908 m_perfLock.lock_rel();
3909
3910 mWokenUpByDaemon = false;
3911 mPendingLiveRequest = 0;
3912 mFirstConfiguration = false;
3913 enablePowerHint();
3914 }
3915
3916 uint32_t frameNumber = request->frame_number;
3917 cam_stream_ID_t streamID;
3918
3919 if (mFlushPerf) {
3920 //we cannot accept any requests during flush
3921 LOGE("process_capture_request cannot proceed during flush");
3922 pthread_mutex_unlock(&mMutex);
3923 return NO_ERROR; //should return an error
3924 }
3925
3926 if (meta.exists(ANDROID_REQUEST_ID)) {
3927 request_id = meta.find(ANDROID_REQUEST_ID).data.i32[0];
3928 mCurrentRequestId = request_id;
3929 LOGD("Received request with id: %d", request_id);
3930 } else if (mState == CONFIGURED || mCurrentRequestId == -1){
3931 LOGE("Unable to find request id field, \
3932 & no previous id available");
3933 pthread_mutex_unlock(&mMutex);
3934 return NAME_NOT_FOUND;
3935 } else {
3936 LOGD("Re-using old request id");
3937 request_id = mCurrentRequestId;
3938 }
3939
3940 LOGH("num_output_buffers = %d input_buffer = %p frame_number = %d",
3941 request->num_output_buffers,
3942 request->input_buffer,
3943 frameNumber);
3944 // Acquire all request buffers first
3945 streamID.num_streams = 0;
3946 int blob_request = 0;
3947 uint32_t snapshotStreamId = 0;
3948 for (size_t i = 0; i < request->num_output_buffers; i++) {
3949 const camera3_stream_buffer_t& output = request->output_buffers[i];
3950 QCamera3Channel *channel = (QCamera3Channel *)output.stream->priv;
3951
3952 if (output.stream->format == HAL_PIXEL_FORMAT_BLOB) {
3953 //Call function to store local copy of jpeg data for encode params.
3954 blob_request = 1;
3955 snapshotStreamId = channel->getStreamID(channel->getStreamTypeMask());
3956 }
3957
3958 if (output.acquire_fence != -1) {
3959 rc = sync_wait(output.acquire_fence, TIMEOUT_NEVER);
3960 close(output.acquire_fence);
3961 if (rc != OK) {
3962 LOGE("sync wait failed %d", rc);
3963 pthread_mutex_unlock(&mMutex);
3964 return rc;
3965 }
3966 }
3967
3968 streamID.streamID[streamID.num_streams] =
3969 channel->getStreamID(channel->getStreamTypeMask());
3970 streamID.num_streams++;
3971
3972 if ((1U << CAM_STREAM_TYPE_VIDEO) == channel->getStreamTypeMask()) {
3973 isVidBufRequested = true;
3974 }
3975 }
3976
3977 if (blob_request) {
3978 KPI_ATRACE_INT("SNAPSHOT", 1);
3979 }
3980 if (blob_request && mRawDumpChannel) {
3981 LOGD("Trigger Raw based on blob request if Raw dump is enabled");
3982 streamID.streamID[streamID.num_streams] =
3983 mRawDumpChannel->getStreamID(mRawDumpChannel->getStreamTypeMask());
3984 streamID.num_streams++;
3985 }
3986
3987 if(request->input_buffer == NULL) {
3988 /* Parse the settings:
3989 * - For every request in NORMAL MODE
3990 * - For every request in HFR mode during preview only case
3991 * - For first request of every batch in HFR mode during video
3992 * recording. In batchmode the same settings except frame number is
3993 * repeated in each request of the batch.
3994 */
3995 if (!mBatchSize ||
3996 (mBatchSize && !isVidBufRequested) ||
3997 (mBatchSize && isVidBufRequested && !mToBeQueuedVidBufs)) {
3998 rc = setFrameParameters(request, streamID, blob_request, snapshotStreamId);
3999 if (rc < 0) {
4000 LOGE("fail to set frame parameters");
4001 pthread_mutex_unlock(&mMutex);
4002 return rc;
4003 }
4004 }
4005 /* For batchMode HFR, setFrameParameters is not called for every
4006 * request. But only frame number of the latest request is parsed.
4007 * Keep track of first and last frame numbers in a batch so that
4008 * metadata for the frame numbers of batch can be duplicated in
4009 * handleBatchMetadta */
4010 if (mBatchSize) {
4011 if (!mToBeQueuedVidBufs) {
4012 //start of the batch
4013 mFirstFrameNumberInBatch = request->frame_number;
4014 }
4015 if(ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters,
4016 CAM_INTF_META_FRAME_NUMBER, request->frame_number)) {
4017 LOGE("Failed to set the frame number in the parameters");
Thierry Strudel9e74aae2016-09-22 17:10:18 -07004018 pthread_mutex_unlock(&mMutex);
Thierry Strudel3d639192016-09-09 11:52:26 -07004019 return BAD_VALUE;
4020 }
4021 }
4022 if (mNeedSensorRestart) {
4023 /* Unlock the mutex as restartSensor waits on the channels to be
4024 * stopped, which in turn calls stream callback functions -
4025 * handleBufferWithLock and handleMetadataWithLock */
4026 pthread_mutex_unlock(&mMutex);
4027 rc = dynamicUpdateMetaStreamInfo();
4028 if (rc != NO_ERROR) {
4029 LOGE("Restarting the sensor failed");
4030 return BAD_VALUE;
4031 }
4032 mNeedSensorRestart = false;
4033 pthread_mutex_lock(&mMutex);
4034 }
4035 } else {
4036
4037 if (request->input_buffer->acquire_fence != -1) {
4038 rc = sync_wait(request->input_buffer->acquire_fence, TIMEOUT_NEVER);
4039 close(request->input_buffer->acquire_fence);
4040 if (rc != OK) {
4041 LOGE("input buffer sync wait failed %d", rc);
4042 pthread_mutex_unlock(&mMutex);
4043 return rc;
4044 }
4045 }
4046 }
4047
4048 if (mCaptureIntent == ANDROID_CONTROL_CAPTURE_INTENT_CUSTOM) {
4049 mLastCustIntentFrmNum = frameNumber;
4050 }
4051 /* Update pending request list and pending buffers map */
4052 PendingRequestInfo pendingRequest;
4053 pendingRequestIterator latestRequest;
4054 pendingRequest.frame_number = frameNumber;
4055 pendingRequest.num_buffers = request->num_output_buffers;
4056 pendingRequest.request_id = request_id;
4057 pendingRequest.blob_request = blob_request;
4058 pendingRequest.timestamp = 0;
4059 pendingRequest.bUrgentReceived = 0;
4060 if (request->input_buffer) {
4061 pendingRequest.input_buffer =
4062 (camera3_stream_buffer_t*)malloc(sizeof(camera3_stream_buffer_t));
4063 *(pendingRequest.input_buffer) = *(request->input_buffer);
4064 pInputBuffer = pendingRequest.input_buffer;
4065 } else {
4066 pendingRequest.input_buffer = NULL;
4067 pInputBuffer = NULL;
4068 }
4069
4070 pendingRequest.pipeline_depth = 0;
4071 pendingRequest.partial_result_cnt = 0;
4072 extractJpegMetadata(mCurJpegMeta, request);
4073 pendingRequest.jpegMetadata = mCurJpegMeta;
4074 pendingRequest.settings = saveRequestSettings(mCurJpegMeta, request);
4075 pendingRequest.shutter_notified = false;
4076
4077 //extract capture intent
4078 if (meta.exists(ANDROID_CONTROL_CAPTURE_INTENT)) {
4079 mCaptureIntent =
4080 meta.find(ANDROID_CONTROL_CAPTURE_INTENT).data.u8[0];
4081 }
4082 pendingRequest.capture_intent = mCaptureIntent;
4083
4084 //extract CAC info
4085 if (meta.exists(ANDROID_COLOR_CORRECTION_ABERRATION_MODE)) {
4086 mCacMode =
4087 meta.find(ANDROID_COLOR_CORRECTION_ABERRATION_MODE).data.u8[0];
4088 }
4089 pendingRequest.fwkCacMode = mCacMode;
4090
4091 PendingBuffersInRequest bufsForCurRequest;
4092 bufsForCurRequest.frame_number = frameNumber;
4093 // Mark current timestamp for the new request
4094 bufsForCurRequest.timestamp = systemTime(CLOCK_MONOTONIC);
4095
4096 for (size_t i = 0; i < request->num_output_buffers; i++) {
4097 RequestedBufferInfo requestedBuf;
4098 memset(&requestedBuf, 0, sizeof(requestedBuf));
4099 requestedBuf.stream = request->output_buffers[i].stream;
4100 requestedBuf.buffer = NULL;
4101 pendingRequest.buffers.push_back(requestedBuf);
4102
4103 // Add to buffer handle the pending buffers list
4104 PendingBufferInfo bufferInfo;
4105 bufferInfo.buffer = request->output_buffers[i].buffer;
4106 bufferInfo.stream = request->output_buffers[i].stream;
4107 bufsForCurRequest.mPendingBufferList.push_back(bufferInfo);
4108 QCamera3Channel *channel = (QCamera3Channel *)bufferInfo.stream->priv;
4109 LOGD("frame = %d, buffer = %p, streamTypeMask = %d, stream format = %d",
4110 frameNumber, bufferInfo.buffer,
4111 channel->getStreamTypeMask(), bufferInfo.stream->format);
4112 }
4113 // Add this request packet into mPendingBuffersMap
4114 mPendingBuffersMap.mPendingBuffersInRequest.push_back(bufsForCurRequest);
4115 LOGD("mPendingBuffersMap.num_overall_buffers = %d",
4116 mPendingBuffersMap.get_num_overall_buffers());
4117
4118 latestRequest = mPendingRequestsList.insert(
4119 mPendingRequestsList.end(), pendingRequest);
4120 if(mFlush) {
4121 LOGI("mFlush is true");
4122 pthread_mutex_unlock(&mMutex);
4123 return NO_ERROR;
4124 }
4125
4126 // Notify metadata channel we receive a request
4127 mMetadataChannel->request(NULL, frameNumber);
4128
4129 if(request->input_buffer != NULL){
4130 LOGD("Input request, frame_number %d", frameNumber);
4131 rc = setReprocParameters(request, &mReprocMeta, snapshotStreamId);
4132 if (NO_ERROR != rc) {
4133 LOGE("fail to set reproc parameters");
4134 pthread_mutex_unlock(&mMutex);
4135 return rc;
4136 }
4137 }
4138
4139 // Call request on other streams
4140 uint32_t streams_need_metadata = 0;
4141 pendingBufferIterator pendingBufferIter = latestRequest->buffers.begin();
4142 for (size_t i = 0; i < request->num_output_buffers; i++) {
4143 const camera3_stream_buffer_t& output = request->output_buffers[i];
4144 QCamera3Channel *channel = (QCamera3Channel *)output.stream->priv;
4145
4146 if (channel == NULL) {
4147 LOGW("invalid channel pointer for stream");
4148 continue;
4149 }
4150
4151 if (output.stream->format == HAL_PIXEL_FORMAT_BLOB) {
4152 LOGD("snapshot request with output buffer %p, input buffer %p, frame_number %d",
4153 output.buffer, request->input_buffer, frameNumber);
4154 if(request->input_buffer != NULL){
4155 rc = channel->request(output.buffer, frameNumber,
4156 pInputBuffer, &mReprocMeta);
4157 if (rc < 0) {
4158 LOGE("Fail to request on picture channel");
4159 pthread_mutex_unlock(&mMutex);
4160 return rc;
4161 }
4162 } else {
4163 LOGD("snapshot request with buffer %p, frame_number %d",
4164 output.buffer, frameNumber);
4165 if (!request->settings) {
4166 rc = channel->request(output.buffer, frameNumber,
4167 NULL, mPrevParameters);
4168 } else {
4169 rc = channel->request(output.buffer, frameNumber,
4170 NULL, mParameters);
4171 }
4172 if (rc < 0) {
4173 LOGE("Fail to request on picture channel");
4174 pthread_mutex_unlock(&mMutex);
4175 return rc;
4176 }
4177 pendingBufferIter->need_metadata = true;
4178 streams_need_metadata++;
4179 }
4180 } else if (output.stream->format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
4181 bool needMetadata = false;
Thierry Strudel3d639192016-09-09 11:52:26 -07004182 QCamera3YUVChannel *yuvChannel = (QCamera3YUVChannel *)channel;
4183 rc = yuvChannel->request(output.buffer, frameNumber,
4184 pInputBuffer,
4185 (pInputBuffer ? &mReprocMeta : mParameters), needMetadata);
4186 if (rc < 0) {
4187 LOGE("Fail to request on YUV channel");
4188 pthread_mutex_unlock(&mMutex);
4189 return rc;
4190 }
4191 pendingBufferIter->need_metadata = needMetadata;
4192 if (needMetadata)
4193 streams_need_metadata += 1;
4194 LOGD("calling YUV channel request, need_metadata is %d",
4195 needMetadata);
4196 } else {
4197 LOGD("request with buffer %p, frame_number %d",
4198 output.buffer, frameNumber);
Thierry Strudel3d639192016-09-09 11:52:26 -07004199 rc = channel->request(output.buffer, frameNumber);
4200 if (((1U << CAM_STREAM_TYPE_VIDEO) == channel->getStreamTypeMask())
4201 && mBatchSize) {
4202 mToBeQueuedVidBufs++;
4203 if (mToBeQueuedVidBufs == mBatchSize) {
4204 channel->queueBatchBuf();
4205 }
4206 }
4207 if (rc < 0) {
4208 LOGE("request failed");
4209 pthread_mutex_unlock(&mMutex);
4210 return rc;
4211 }
4212 }
4213 pendingBufferIter++;
4214 }
4215
4216 //If 2 streams have need_metadata set to true, fail the request, unless
4217 //we copy/reference count the metadata buffer
4218 if (streams_need_metadata > 1) {
4219 LOGE("not supporting request in which two streams requires"
4220 " 2 HAL metadata for reprocessing");
4221 pthread_mutex_unlock(&mMutex);
4222 return -EINVAL;
4223 }
4224
4225 if(request->input_buffer == NULL) {
4226 /* Set the parameters to backend:
4227 * - For every request in NORMAL MODE
4228 * - For every request in HFR mode during preview only case
4229 * - Once every batch in HFR mode during video recording
4230 */
4231 if (!mBatchSize ||
4232 (mBatchSize && !isVidBufRequested) ||
4233 (mBatchSize && isVidBufRequested && (mToBeQueuedVidBufs == mBatchSize))) {
4234 LOGD("set_parms batchSz: %d IsVidBufReq: %d vidBufTobeQd: %d ",
4235 mBatchSize, isVidBufRequested,
4236 mToBeQueuedVidBufs);
4237 rc = mCameraHandle->ops->set_parms(mCameraHandle->camera_handle,
4238 mParameters);
4239 if (rc < 0) {
4240 LOGE("set_parms failed");
4241 }
4242 /* reset to zero coz, the batch is queued */
4243 mToBeQueuedVidBufs = 0;
4244 mPendingBatchMap.add(frameNumber, mFirstFrameNumberInBatch);
4245 }
4246 mPendingLiveRequest++;
4247 }
4248
4249 LOGD("mPendingLiveRequest = %d", mPendingLiveRequest);
4250
4251 mState = STARTED;
4252 // Added a timed condition wait
4253 struct timespec ts;
4254 uint8_t isValidTimeout = 1;
4255 rc = clock_gettime(CLOCK_REALTIME, &ts);
4256 if (rc < 0) {
4257 isValidTimeout = 0;
4258 LOGE("Error reading the real time clock!!");
4259 }
4260 else {
4261 // Make timeout as 5 sec for request to be honored
4262 ts.tv_sec += 5;
4263 }
4264 //Block on conditional variable
Thierry Strudel9e74aae2016-09-22 17:10:18 -07004265 while ((mPendingLiveRequest >= mMinInFlightRequests) && !pInputBuffer &&
Thierry Strudel3d639192016-09-09 11:52:26 -07004266 (mState != ERROR) && (mState != DEINIT)) {
4267 if (!isValidTimeout) {
4268 LOGD("Blocking on conditional wait");
4269 pthread_cond_wait(&mRequestCond, &mMutex);
4270 }
4271 else {
4272 LOGD("Blocking on timed conditional wait");
4273 rc = pthread_cond_timedwait(&mRequestCond, &mMutex, &ts);
4274 if (rc == ETIMEDOUT) {
4275 rc = -ENODEV;
4276 LOGE("Unblocked on timeout!!!!");
4277 break;
4278 }
4279 }
4280 LOGD("Unblocked");
4281 if (mWokenUpByDaemon) {
4282 mWokenUpByDaemon = false;
Thierry Strudel9e74aae2016-09-22 17:10:18 -07004283 if (mPendingLiveRequest < mMaxInFlightRequests)
Thierry Strudel3d639192016-09-09 11:52:26 -07004284 break;
4285 }
4286 }
4287 pthread_mutex_unlock(&mMutex);
4288
4289 return rc;
4290}
4291
4292/*===========================================================================
4293 * FUNCTION : dump
4294 *
4295 * DESCRIPTION:
4296 *
4297 * PARAMETERS :
4298 *
4299 *
4300 * RETURN :
4301 *==========================================================================*/
4302void QCamera3HardwareInterface::dump(int fd)
4303{
4304 pthread_mutex_lock(&mMutex);
4305 dprintf(fd, "\n Camera HAL3 information Begin \n");
4306
4307 dprintf(fd, "\nNumber of pending requests: %zu \n",
4308 mPendingRequestsList.size());
4309 dprintf(fd, "-------+-------------------+-------------+----------+---------------------\n");
4310 dprintf(fd, " Frame | Number of Buffers | Req Id: | Blob Req | Input buffer present\n");
4311 dprintf(fd, "-------+-------------------+-------------+----------+---------------------\n");
4312 for(pendingRequestIterator i = mPendingRequestsList.begin();
4313 i != mPendingRequestsList.end(); i++) {
4314 dprintf(fd, " %5d | %17d | %11d | %8d | %p \n",
4315 i->frame_number, i->num_buffers, i->request_id, i->blob_request,
4316 i->input_buffer);
4317 }
4318 dprintf(fd, "\nPending buffer map: Number of buffers: %u\n",
4319 mPendingBuffersMap.get_num_overall_buffers());
4320 dprintf(fd, "-------+------------------\n");
4321 dprintf(fd, " Frame | Stream type mask \n");
4322 dprintf(fd, "-------+------------------\n");
4323 for(auto &req : mPendingBuffersMap.mPendingBuffersInRequest) {
4324 for(auto &j : req.mPendingBufferList) {
4325 QCamera3Channel *channel = (QCamera3Channel *)(j.stream->priv);
4326 dprintf(fd, " %5d | %11d \n",
4327 req.frame_number, channel->getStreamTypeMask());
4328 }
4329 }
4330 dprintf(fd, "-------+------------------\n");
4331
4332 dprintf(fd, "\nPending frame drop list: %zu\n",
4333 mPendingFrameDropList.size());
4334 dprintf(fd, "-------+-----------\n");
4335 dprintf(fd, " Frame | Stream ID \n");
4336 dprintf(fd, "-------+-----------\n");
4337 for(List<PendingFrameDropInfo>::iterator i = mPendingFrameDropList.begin();
4338 i != mPendingFrameDropList.end(); i++) {
4339 dprintf(fd, " %5d | %9d \n",
4340 i->frame_number, i->stream_ID);
4341 }
4342 dprintf(fd, "-------+-----------\n");
4343
4344 dprintf(fd, "\n Camera HAL3 information End \n");
4345
4346 /* use dumpsys media.camera as trigger to send update debug level event */
4347 mUpdateDebugLevel = true;
4348 pthread_mutex_unlock(&mMutex);
4349 return;
4350}
4351
4352/*===========================================================================
4353 * FUNCTION : flush
4354 *
4355 * DESCRIPTION: Calls stopAllChannels, notifyErrorForPendingRequests and
4356 * conditionally restarts channels
4357 *
4358 * PARAMETERS :
4359 * @ restartChannels: re-start all channels
4360 *
4361 *
4362 * RETURN :
4363 * 0 on success
4364 * Error code on failure
4365 *==========================================================================*/
4366int QCamera3HardwareInterface::flush(bool restartChannels)
4367{
4368 KPI_ATRACE_CALL();
4369 int32_t rc = NO_ERROR;
4370
4371 LOGD("Unblocking Process Capture Request");
4372 pthread_mutex_lock(&mMutex);
4373 mFlush = true;
4374 pthread_mutex_unlock(&mMutex);
4375
4376 rc = stopAllChannels();
4377 // unlink of dualcam
4378 if (mIsDeviceLinked) {
4379 m_pRelCamSyncBuf->sync_control = CAM_SYNC_RELATED_SENSORS_OFF;
4380 pthread_mutex_lock(&gCamLock);
4381
4382 if (mIsMainCamera == 1) {
4383 m_pRelCamSyncBuf->mode = CAM_MODE_PRIMARY;
4384 m_pRelCamSyncBuf->type = CAM_TYPE_MAIN;
4385 // related session id should be session id of linked session
4386 m_pRelCamSyncBuf->related_sensor_session_id = sessionId[mLinkedCameraId];
4387 } else {
4388 m_pRelCamSyncBuf->mode = CAM_MODE_SECONDARY;
4389 m_pRelCamSyncBuf->type = CAM_TYPE_AUX;
4390 m_pRelCamSyncBuf->related_sensor_session_id = sessionId[mLinkedCameraId];
4391 }
4392 pthread_mutex_unlock(&gCamLock);
4393
4394 rc = mCameraHandle->ops->sync_related_sensors(
4395 mCameraHandle->camera_handle, m_pRelCamSyncBuf);
4396 if (rc < 0) {
4397 LOGE("Dualcam: Unlink failed, but still proceed to close");
4398 }
4399 }
4400
4401 if (rc < 0) {
4402 LOGE("stopAllChannels failed");
4403 return rc;
4404 }
4405 if (mChannelHandle) {
4406 mCameraHandle->ops->stop_channel(mCameraHandle->camera_handle,
4407 mChannelHandle);
4408 }
4409
4410 // Reset bundle info
4411 rc = setBundleInfo();
4412 if (rc < 0) {
4413 LOGE("setBundleInfo failed %d", rc);
4414 return rc;
4415 }
4416
4417 // Mutex Lock
4418 pthread_mutex_lock(&mMutex);
4419
4420 // Unblock process_capture_request
4421 mPendingLiveRequest = 0;
4422 pthread_cond_signal(&mRequestCond);
4423
4424 rc = notifyErrorForPendingRequests();
4425 if (rc < 0) {
4426 LOGE("notifyErrorForPendingRequests failed");
4427 pthread_mutex_unlock(&mMutex);
4428 return rc;
4429 }
4430
4431 mFlush = false;
4432
4433 // Start the Streams/Channels
4434 if (restartChannels) {
4435 rc = startAllChannels();
4436 if (rc < 0) {
4437 LOGE("startAllChannels failed");
4438 pthread_mutex_unlock(&mMutex);
4439 return rc;
4440 }
4441 }
4442
4443 if (mChannelHandle) {
4444 mCameraHandle->ops->start_channel(mCameraHandle->camera_handle,
4445 mChannelHandle);
4446 if (rc < 0) {
4447 LOGE("start_channel failed");
4448 pthread_mutex_unlock(&mMutex);
4449 return rc;
4450 }
4451 }
4452
4453 pthread_mutex_unlock(&mMutex);
4454
4455 return 0;
4456}
4457
4458/*===========================================================================
4459 * FUNCTION : flushPerf
4460 *
4461 * DESCRIPTION: This is the performance optimization version of flush that does
4462 * not use stream off, rather flushes the system
4463 *
4464 * PARAMETERS :
4465 *
4466 *
4467 * RETURN : 0 : success
4468 * -EINVAL: input is malformed (device is not valid)
4469 * -ENODEV: if the device has encountered a serious error
4470 *==========================================================================*/
4471int QCamera3HardwareInterface::flushPerf()
4472{
4473 ATRACE_CALL();
4474 int32_t rc = 0;
4475 struct timespec timeout;
4476 bool timed_wait = false;
4477
4478 pthread_mutex_lock(&mMutex);
4479 mFlushPerf = true;
4480 mPendingBuffersMap.numPendingBufsAtFlush =
4481 mPendingBuffersMap.get_num_overall_buffers();
4482 LOGD("Calling flush. Wait for %d buffers to return",
4483 mPendingBuffersMap.numPendingBufsAtFlush);
4484
4485 /* send the flush event to the backend */
4486 rc = mCameraHandle->ops->flush(mCameraHandle->camera_handle);
4487 if (rc < 0) {
4488 LOGE("Error in flush: IOCTL failure");
4489 mFlushPerf = false;
4490 pthread_mutex_unlock(&mMutex);
4491 return -ENODEV;
4492 }
4493
4494 if (mPendingBuffersMap.numPendingBufsAtFlush == 0) {
4495 LOGD("No pending buffers in HAL, return flush");
4496 mFlushPerf = false;
4497 pthread_mutex_unlock(&mMutex);
4498 return rc;
4499 }
4500
4501 /* wait on a signal that buffers were received */
4502 rc = clock_gettime(CLOCK_REALTIME, &timeout);
4503 if (rc < 0) {
4504 LOGE("Error reading the real time clock, cannot use timed wait");
4505 } else {
4506 timeout.tv_sec += FLUSH_TIMEOUT;
4507 timed_wait = true;
4508 }
4509
4510 //Block on conditional variable
4511 while (mPendingBuffersMap.numPendingBufsAtFlush != 0) {
4512 LOGD("Waiting on mBuffersCond");
4513 if (!timed_wait) {
4514 rc = pthread_cond_wait(&mBuffersCond, &mMutex);
4515 if (rc != 0) {
4516 LOGE("pthread_cond_wait failed due to rc = %s",
4517 strerror(rc));
4518 break;
4519 }
4520 } else {
4521 rc = pthread_cond_timedwait(&mBuffersCond, &mMutex, &timeout);
4522 if (rc != 0) {
4523 LOGE("pthread_cond_timedwait failed due to rc = %s",
4524 strerror(rc));
4525 break;
4526 }
4527 }
4528 }
4529 if (rc != 0) {
4530 mFlushPerf = false;
4531 pthread_mutex_unlock(&mMutex);
4532 return -ENODEV;
4533 }
4534
4535 LOGD("Received buffers, now safe to return them");
4536
4537 //make sure the channels handle flush
4538 //currently only required for the picture channel to release snapshot resources
4539 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
4540 it != mStreamInfo.end(); it++) {
4541 QCamera3Channel *channel = (*it)->channel;
4542 if (channel) {
4543 rc = channel->flush();
4544 if (rc) {
4545 LOGE("Flushing the channels failed with error %d", rc);
4546 // even though the channel flush failed we need to continue and
4547 // return the buffers we have to the framework, however the return
4548 // value will be an error
4549 rc = -ENODEV;
4550 }
4551 }
4552 }
4553
4554 /* notify the frameworks and send errored results */
4555 rc = notifyErrorForPendingRequests();
4556 if (rc < 0) {
4557 LOGE("notifyErrorForPendingRequests failed");
4558 pthread_mutex_unlock(&mMutex);
4559 return rc;
4560 }
4561
4562 //unblock process_capture_request
4563 mPendingLiveRequest = 0;
4564 unblockRequestIfNecessary();
4565
4566 mFlushPerf = false;
4567 pthread_mutex_unlock(&mMutex);
4568 LOGD ("Flush Operation complete. rc = %d", rc);
4569 return rc;
4570}
4571
4572/*===========================================================================
4573 * FUNCTION : handleCameraDeviceError
4574 *
4575 * DESCRIPTION: This function calls internal flush and notifies the error to
4576 * framework and updates the state variable.
4577 *
4578 * PARAMETERS : None
4579 *
4580 * RETURN : NO_ERROR on Success
4581 * Error code on failure
4582 *==========================================================================*/
4583int32_t QCamera3HardwareInterface::handleCameraDeviceError()
4584{
4585 int32_t rc = NO_ERROR;
4586
4587 pthread_mutex_lock(&mMutex);
4588 if (mState != ERROR) {
4589 //if mState != ERROR, nothing to be done
4590 pthread_mutex_unlock(&mMutex);
4591 return NO_ERROR;
4592 }
4593 pthread_mutex_unlock(&mMutex);
4594
4595 rc = flush(false /* restart channels */);
4596 if (NO_ERROR != rc) {
4597 LOGE("internal flush to handle mState = ERROR failed");
4598 }
4599
4600 pthread_mutex_lock(&mMutex);
4601 mState = DEINIT;
4602 pthread_mutex_unlock(&mMutex);
4603
4604 camera3_notify_msg_t notify_msg;
4605 memset(&notify_msg, 0, sizeof(camera3_notify_msg_t));
4606 notify_msg.type = CAMERA3_MSG_ERROR;
4607 notify_msg.message.error.error_code = CAMERA3_MSG_ERROR_DEVICE;
4608 notify_msg.message.error.error_stream = NULL;
4609 notify_msg.message.error.frame_number = 0;
4610 mCallbackOps->notify(mCallbackOps, &notify_msg);
4611
4612 return rc;
4613}
4614
4615/*===========================================================================
4616 * FUNCTION : captureResultCb
4617 *
4618 * DESCRIPTION: Callback handler for all capture result
4619 * (streams, as well as metadata)
4620 *
4621 * PARAMETERS :
4622 * @metadata : metadata information
4623 * @buffer : actual gralloc buffer to be returned to frameworks.
4624 * NULL if metadata.
4625 *
4626 * RETURN : NONE
4627 *==========================================================================*/
4628void QCamera3HardwareInterface::captureResultCb(mm_camera_super_buf_t *metadata_buf,
4629 camera3_stream_buffer_t *buffer, uint32_t frame_number, bool isInputBuffer)
4630{
4631 if (metadata_buf) {
4632 if (mBatchSize) {
4633 handleBatchMetadata(metadata_buf,
4634 true /* free_and_bufdone_meta_buf */);
4635 } else { /* mBatchSize = 0 */
4636 hdrPlusPerfLock(metadata_buf);
4637 pthread_mutex_lock(&mMutex);
4638 handleMetadataWithLock(metadata_buf,
Thierry Strudel9e74aae2016-09-22 17:10:18 -07004639 true /* free_and_bufdone_meta_buf */,
4640 false /* first frame of batch metadata */ );
Thierry Strudel3d639192016-09-09 11:52:26 -07004641 pthread_mutex_unlock(&mMutex);
4642 }
4643 } else if (isInputBuffer) {
4644 pthread_mutex_lock(&mMutex);
4645 handleInputBufferWithLock(frame_number);
4646 pthread_mutex_unlock(&mMutex);
4647 } else {
4648 pthread_mutex_lock(&mMutex);
4649 handleBufferWithLock(buffer, frame_number);
4650 pthread_mutex_unlock(&mMutex);
4651 }
4652 return;
4653}
4654
4655/*===========================================================================
4656 * FUNCTION : getReprocessibleOutputStreamId
4657 *
4658 * DESCRIPTION: Get source output stream id for the input reprocess stream
4659 * based on size and format, which would be the largest
4660 * output stream if an input stream exists.
4661 *
4662 * PARAMETERS :
4663 * @id : return the stream id if found
4664 *
4665 * RETURN : int32_t type of status
4666 * NO_ERROR -- success
4667 * none-zero failure code
4668 *==========================================================================*/
4669int32_t QCamera3HardwareInterface::getReprocessibleOutputStreamId(uint32_t &id)
4670{
4671 /* check if any output or bidirectional stream with the same size and format
4672 and return that stream */
4673 if ((mInputStreamInfo.dim.width > 0) &&
4674 (mInputStreamInfo.dim.height > 0)) {
4675 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
4676 it != mStreamInfo.end(); it++) {
4677
4678 camera3_stream_t *stream = (*it)->stream;
4679 if ((stream->width == (uint32_t)mInputStreamInfo.dim.width) &&
4680 (stream->height == (uint32_t)mInputStreamInfo.dim.height) &&
4681 (stream->format == mInputStreamInfo.format)) {
4682 // Usage flag for an input stream and the source output stream
4683 // may be different.
4684 LOGD("Found reprocessible output stream! %p", *it);
4685 LOGD("input stream usage 0x%x, current stream usage 0x%x",
4686 stream->usage, mInputStreamInfo.usage);
4687
4688 QCamera3Channel *channel = (QCamera3Channel *)stream->priv;
4689 if (channel != NULL && channel->mStreams[0]) {
4690 id = channel->mStreams[0]->getMyServerID();
4691 return NO_ERROR;
4692 }
4693 }
4694 }
4695 } else {
4696 LOGD("No input stream, so no reprocessible output stream");
4697 }
4698 return NAME_NOT_FOUND;
4699}
4700
4701/*===========================================================================
4702 * FUNCTION : lookupFwkName
4703 *
4704 * DESCRIPTION: In case the enum is not same in fwk and backend
4705 * make sure the parameter is correctly propogated
4706 *
4707 * PARAMETERS :
4708 * @arr : map between the two enums
4709 * @len : len of the map
4710 * @hal_name : name of the hal_parm to map
4711 *
4712 * RETURN : int type of status
4713 * fwk_name -- success
4714 * none-zero failure code
4715 *==========================================================================*/
4716template <typename halType, class mapType> int lookupFwkName(const mapType *arr,
4717 size_t len, halType hal_name)
4718{
4719
4720 for (size_t i = 0; i < len; i++) {
4721 if (arr[i].hal_name == hal_name) {
4722 return arr[i].fwk_name;
4723 }
4724 }
4725
4726 /* Not able to find matching framework type is not necessarily
4727 * an error case. This happens when mm-camera supports more attributes
4728 * than the frameworks do */
4729 LOGH("Cannot find matching framework type");
4730 return NAME_NOT_FOUND;
4731}
4732
4733/*===========================================================================
4734 * FUNCTION : lookupHalName
4735 *
4736 * DESCRIPTION: In case the enum is not same in fwk and backend
4737 * make sure the parameter is correctly propogated
4738 *
4739 * PARAMETERS :
4740 * @arr : map between the two enums
4741 * @len : len of the map
4742 * @fwk_name : name of the hal_parm to map
4743 *
4744 * RETURN : int32_t type of status
4745 * hal_name -- success
4746 * none-zero failure code
4747 *==========================================================================*/
4748template <typename fwkType, class mapType> int lookupHalName(const mapType *arr,
4749 size_t len, fwkType fwk_name)
4750{
4751 for (size_t i = 0; i < len; i++) {
4752 if (arr[i].fwk_name == fwk_name) {
4753 return arr[i].hal_name;
4754 }
4755 }
4756
4757 LOGE("Cannot find matching hal type fwk_name=%d", fwk_name);
4758 return NAME_NOT_FOUND;
4759}
4760
4761/*===========================================================================
4762 * FUNCTION : lookupProp
4763 *
4764 * DESCRIPTION: lookup a value by its name
4765 *
4766 * PARAMETERS :
4767 * @arr : map between the two enums
4768 * @len : size of the map
4769 * @name : name to be looked up
4770 *
4771 * RETURN : Value if found
4772 * CAM_CDS_MODE_MAX if not found
4773 *==========================================================================*/
4774template <class mapType> cam_cds_mode_type_t lookupProp(const mapType *arr,
4775 size_t len, const char *name)
4776{
4777 if (name) {
4778 for (size_t i = 0; i < len; i++) {
4779 if (!strcmp(arr[i].desc, name)) {
4780 return arr[i].val;
4781 }
4782 }
4783 }
4784 return CAM_CDS_MODE_MAX;
4785}
4786
4787/*===========================================================================
4788 *
4789 * DESCRIPTION:
4790 *
4791 * PARAMETERS :
4792 * @metadata : metadata information from callback
4793 * @timestamp: metadata buffer timestamp
4794 * @request_id: request id
4795 * @jpegMetadata: additional jpeg metadata
4796 * @pprocDone: whether internal offline postprocsesing is done
4797 *
4798 * RETURN : camera_metadata_t*
4799 * metadata in a format specified by fwk
4800 *==========================================================================*/
4801camera_metadata_t*
4802QCamera3HardwareInterface::translateFromHalMetadata(
4803 metadata_buffer_t *metadata,
4804 nsecs_t timestamp,
4805 int32_t request_id,
4806 const CameraMetadata& jpegMetadata,
4807 uint8_t pipeline_depth,
4808 uint8_t capture_intent,
4809 bool pprocDone,
Thierry Strudel9e74aae2016-09-22 17:10:18 -07004810 uint8_t fwk_cacMode,
4811 bool firstMetadataInBatch)
Thierry Strudel3d639192016-09-09 11:52:26 -07004812{
4813 CameraMetadata camMetadata;
4814 camera_metadata_t *resultMetadata;
4815
Thierry Strudel9e74aae2016-09-22 17:10:18 -07004816 if (mBatchSize && !firstMetadataInBatch) {
4817 /* In batch mode, use cached metadata from the first metadata
4818 in the batch */
4819 camMetadata.clear();
4820 camMetadata = mCachedMetadata;
4821 }
4822
Thierry Strudel3d639192016-09-09 11:52:26 -07004823 if (jpegMetadata.entryCount())
4824 camMetadata.append(jpegMetadata);
4825
4826 camMetadata.update(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);
4827 camMetadata.update(ANDROID_REQUEST_ID, &request_id, 1);
4828 camMetadata.update(ANDROID_REQUEST_PIPELINE_DEPTH, &pipeline_depth, 1);
4829 camMetadata.update(ANDROID_CONTROL_CAPTURE_INTENT, &capture_intent, 1);
4830
Thierry Strudel9e74aae2016-09-22 17:10:18 -07004831 if (mBatchSize && !firstMetadataInBatch) {
4832 /* In batch mode, use cached metadata instead of parsing metadata buffer again */
4833 resultMetadata = camMetadata.release();
4834 return resultMetadata;
4835 }
4836
Thierry Strudel3d639192016-09-09 11:52:26 -07004837 IF_META_AVAILABLE(uint32_t, frame_number, CAM_INTF_META_FRAME_NUMBER, metadata) {
4838 int64_t fwk_frame_number = *frame_number;
4839 camMetadata.update(ANDROID_SYNC_FRAME_NUMBER, &fwk_frame_number, 1);
4840 }
4841
4842 IF_META_AVAILABLE(cam_fps_range_t, float_range, CAM_INTF_PARM_FPS_RANGE, metadata) {
4843 int32_t fps_range[2];
4844 fps_range[0] = (int32_t)float_range->min_fps;
4845 fps_range[1] = (int32_t)float_range->max_fps;
4846 camMetadata.update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
4847 fps_range, 2);
4848 LOGD("urgent Metadata : ANDROID_CONTROL_AE_TARGET_FPS_RANGE [%d, %d]",
4849 fps_range[0], fps_range[1]);
4850 }
4851
4852 IF_META_AVAILABLE(int32_t, expCompensation, CAM_INTF_PARM_EXPOSURE_COMPENSATION, metadata) {
4853 camMetadata.update(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, expCompensation, 1);
4854 }
4855
4856 IF_META_AVAILABLE(uint32_t, sceneMode, CAM_INTF_PARM_BESTSHOT_MODE, metadata) {
4857 int val = (uint8_t)lookupFwkName(SCENE_MODES_MAP,
4858 METADATA_MAP_SIZE(SCENE_MODES_MAP),
4859 *sceneMode);
4860 if (NAME_NOT_FOUND != val) {
4861 uint8_t fwkSceneMode = (uint8_t)val;
4862 camMetadata.update(ANDROID_CONTROL_SCENE_MODE, &fwkSceneMode, 1);
4863 LOGD("urgent Metadata : ANDROID_CONTROL_SCENE_MODE: %d",
4864 fwkSceneMode);
4865 }
4866 }
4867
4868 IF_META_AVAILABLE(uint32_t, ae_lock, CAM_INTF_PARM_AEC_LOCK, metadata) {
4869 uint8_t fwk_ae_lock = (uint8_t) *ae_lock;
4870 camMetadata.update(ANDROID_CONTROL_AE_LOCK, &fwk_ae_lock, 1);
4871 }
4872
4873 IF_META_AVAILABLE(uint32_t, awb_lock, CAM_INTF_PARM_AWB_LOCK, metadata) {
4874 uint8_t fwk_awb_lock = (uint8_t) *awb_lock;
4875 camMetadata.update(ANDROID_CONTROL_AWB_LOCK, &fwk_awb_lock, 1);
4876 }
4877
4878 IF_META_AVAILABLE(uint32_t, color_correct_mode, CAM_INTF_META_COLOR_CORRECT_MODE, metadata) {
4879 uint8_t fwk_color_correct_mode = (uint8_t) *color_correct_mode;
4880 camMetadata.update(ANDROID_COLOR_CORRECTION_MODE, &fwk_color_correct_mode, 1);
4881 }
4882
4883 IF_META_AVAILABLE(cam_edge_application_t, edgeApplication,
4884 CAM_INTF_META_EDGE_MODE, metadata) {
4885 camMetadata.update(ANDROID_EDGE_MODE, &(edgeApplication->edge_mode), 1);
4886 }
4887
4888 IF_META_AVAILABLE(uint32_t, flashPower, CAM_INTF_META_FLASH_POWER, metadata) {
4889 uint8_t fwk_flashPower = (uint8_t) *flashPower;
4890 camMetadata.update(ANDROID_FLASH_FIRING_POWER, &fwk_flashPower, 1);
4891 }
4892
4893 IF_META_AVAILABLE(int64_t, flashFiringTime, CAM_INTF_META_FLASH_FIRING_TIME, metadata) {
4894 camMetadata.update(ANDROID_FLASH_FIRING_TIME, flashFiringTime, 1);
4895 }
4896
4897 IF_META_AVAILABLE(int32_t, flashState, CAM_INTF_META_FLASH_STATE, metadata) {
4898 if (0 <= *flashState) {
4899 uint8_t fwk_flashState = (uint8_t) *flashState;
4900 if (!gCamCapability[mCameraId]->flash_available) {
4901 fwk_flashState = ANDROID_FLASH_STATE_UNAVAILABLE;
4902 }
4903 camMetadata.update(ANDROID_FLASH_STATE, &fwk_flashState, 1);
4904 }
4905 }
4906
4907 IF_META_AVAILABLE(uint32_t, flashMode, CAM_INTF_META_FLASH_MODE, metadata) {
4908 int val = lookupFwkName(FLASH_MODES_MAP, METADATA_MAP_SIZE(FLASH_MODES_MAP), *flashMode);
4909 if (NAME_NOT_FOUND != val) {
4910 uint8_t fwk_flashMode = (uint8_t)val;
4911 camMetadata.update(ANDROID_FLASH_MODE, &fwk_flashMode, 1);
4912 }
4913 }
4914
4915 IF_META_AVAILABLE(uint32_t, hotPixelMode, CAM_INTF_META_HOTPIXEL_MODE, metadata) {
4916 uint8_t fwk_hotPixelMode = (uint8_t) *hotPixelMode;
4917 camMetadata.update(ANDROID_HOT_PIXEL_MODE, &fwk_hotPixelMode, 1);
4918 }
4919
4920 IF_META_AVAILABLE(float, lensAperture, CAM_INTF_META_LENS_APERTURE, metadata) {
4921 camMetadata.update(ANDROID_LENS_APERTURE , lensAperture, 1);
4922 }
4923
4924 IF_META_AVAILABLE(float, filterDensity, CAM_INTF_META_LENS_FILTERDENSITY, metadata) {
4925 camMetadata.update(ANDROID_LENS_FILTER_DENSITY , filterDensity, 1);
4926 }
4927
4928 IF_META_AVAILABLE(float, focalLength, CAM_INTF_META_LENS_FOCAL_LENGTH, metadata) {
4929 camMetadata.update(ANDROID_LENS_FOCAL_LENGTH, focalLength, 1);
4930 }
4931
4932 IF_META_AVAILABLE(uint32_t, opticalStab, CAM_INTF_META_LENS_OPT_STAB_MODE, metadata) {
4933 uint8_t fwk_opticalStab = (uint8_t) *opticalStab;
4934 camMetadata.update(ANDROID_LENS_OPTICAL_STABILIZATION_MODE, &fwk_opticalStab, 1);
4935 }
4936
4937 IF_META_AVAILABLE(uint32_t, videoStab, CAM_INTF_META_VIDEO_STAB_MODE, metadata) {
4938 uint8_t fwk_videoStab = (uint8_t) *videoStab;
4939 LOGD("fwk_videoStab = %d", fwk_videoStab);
4940 camMetadata.update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &fwk_videoStab, 1);
4941 } else {
4942 // Regardless of Video stab supports or not, CTS is expecting the EIS result to be non NULL
4943 // and so hardcoding the Video Stab result to OFF mode.
4944 uint8_t fwkVideoStabMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
4945 camMetadata.update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &fwkVideoStabMode, 1);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07004946 LOGD("EIS result default to OFF mode");
Thierry Strudel3d639192016-09-09 11:52:26 -07004947 }
4948
4949 IF_META_AVAILABLE(uint32_t, noiseRedMode, CAM_INTF_META_NOISE_REDUCTION_MODE, metadata) {
4950 uint8_t fwk_noiseRedMode = (uint8_t) *noiseRedMode;
4951 camMetadata.update(ANDROID_NOISE_REDUCTION_MODE, &fwk_noiseRedMode, 1);
4952 }
4953
4954 IF_META_AVAILABLE(float, effectiveExposureFactor, CAM_INTF_META_EFFECTIVE_EXPOSURE_FACTOR, metadata) {
4955 camMetadata.update(ANDROID_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR, effectiveExposureFactor, 1);
4956 }
4957
4958 IF_META_AVAILABLE(cam_black_level_metadata_t, blackLevelSourcePattern,
4959 CAM_INTF_META_BLACK_LEVEL_SOURCE_PATTERN, metadata) {
4960
4961 LOGD("dynamicblackLevel = %f %f %f %f",
4962 blackLevelSourcePattern->cam_black_level[0],
4963 blackLevelSourcePattern->cam_black_level[1],
4964 blackLevelSourcePattern->cam_black_level[2],
4965 blackLevelSourcePattern->cam_black_level[3]);
4966 }
4967
4968 IF_META_AVAILABLE(cam_black_level_metadata_t, blackLevelAppliedPattern,
4969 CAM_INTF_META_BLACK_LEVEL_APPLIED_PATTERN, metadata) {
4970 float fwk_blackLevelInd[4];
4971
4972 fwk_blackLevelInd[0] = blackLevelAppliedPattern->cam_black_level[0];
4973 fwk_blackLevelInd[1] = blackLevelAppliedPattern->cam_black_level[1];
4974 fwk_blackLevelInd[2] = blackLevelAppliedPattern->cam_black_level[2];
4975 fwk_blackLevelInd[3] = blackLevelAppliedPattern->cam_black_level[3];
4976
4977 LOGD("applied dynamicblackLevel = %f %f %f %f",
4978 blackLevelAppliedPattern->cam_black_level[0],
4979 blackLevelAppliedPattern->cam_black_level[1],
4980 blackLevelAppliedPattern->cam_black_level[2],
4981 blackLevelAppliedPattern->cam_black_level[3]);
4982 camMetadata.update(QCAMERA3_SENSOR_DYNAMIC_BLACK_LEVEL_PATTERN, fwk_blackLevelInd, 4);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07004983
4984#ifndef USE_HAL_3_3
4985 // Update the ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL
4986 // Need convert the internal 16 bit depth to sensor 10 bit sensor raw
4987 // depth space.
4988 fwk_blackLevelInd[0] /= 64.0;
4989 fwk_blackLevelInd[1] /= 64.0;
4990 fwk_blackLevelInd[2] /= 64.0;
4991 fwk_blackLevelInd[3] /= 64.0;
4992 camMetadata.update(ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL, fwk_blackLevelInd, 4);
4993#endif
Thierry Strudel3d639192016-09-09 11:52:26 -07004994 }
4995
Thierry Strudel9e74aae2016-09-22 17:10:18 -07004996#ifndef USE_HAL_3_3
4997 // Fixed whitelevel is used by ISP/Sensor
4998 camMetadata.update(ANDROID_SENSOR_DYNAMIC_WHITE_LEVEL,
4999 &gCamCapability[mCameraId]->white_level, 1);
5000#endif
Thierry Strudel3d639192016-09-09 11:52:26 -07005001
5002 IF_META_AVAILABLE(cam_crop_region_t, hScalerCropRegion,
5003 CAM_INTF_META_SCALER_CROP_REGION, metadata) {
5004 int32_t scalerCropRegion[4];
5005 scalerCropRegion[0] = hScalerCropRegion->left;
5006 scalerCropRegion[1] = hScalerCropRegion->top;
5007 scalerCropRegion[2] = hScalerCropRegion->width;
5008 scalerCropRegion[3] = hScalerCropRegion->height;
5009
5010 // Adjust crop region from sensor output coordinate system to active
5011 // array coordinate system.
5012 mCropRegionMapper.toActiveArray(scalerCropRegion[0], scalerCropRegion[1],
5013 scalerCropRegion[2], scalerCropRegion[3]);
5014
5015 camMetadata.update(ANDROID_SCALER_CROP_REGION, scalerCropRegion, 4);
5016 }
5017
5018 IF_META_AVAILABLE(int64_t, sensorExpTime, CAM_INTF_META_SENSOR_EXPOSURE_TIME, metadata) {
5019 LOGD("sensorExpTime = %lld", *sensorExpTime);
5020 camMetadata.update(ANDROID_SENSOR_EXPOSURE_TIME , sensorExpTime, 1);
5021 }
5022
5023 IF_META_AVAILABLE(int64_t, sensorFameDuration,
5024 CAM_INTF_META_SENSOR_FRAME_DURATION, metadata) {
5025 LOGD("sensorFameDuration = %lld", *sensorFameDuration);
5026 camMetadata.update(ANDROID_SENSOR_FRAME_DURATION, sensorFameDuration, 1);
5027 }
5028
5029 IF_META_AVAILABLE(int64_t, sensorRollingShutterSkew,
5030 CAM_INTF_META_SENSOR_ROLLING_SHUTTER_SKEW, metadata) {
5031 LOGD("sensorRollingShutterSkew = %lld", *sensorRollingShutterSkew);
5032 camMetadata.update(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
5033 sensorRollingShutterSkew, 1);
5034 }
5035
5036 IF_META_AVAILABLE(int32_t, sensorSensitivity, CAM_INTF_META_SENSOR_SENSITIVITY, metadata) {
5037 LOGD("sensorSensitivity = %d", *sensorSensitivity);
5038 camMetadata.update(ANDROID_SENSOR_SENSITIVITY, sensorSensitivity, 1);
5039
5040 //calculate the noise profile based on sensitivity
5041 double noise_profile_S = computeNoiseModelEntryS(*sensorSensitivity);
5042 double noise_profile_O = computeNoiseModelEntryO(*sensorSensitivity);
5043 double noise_profile[2 * gCamCapability[mCameraId]->num_color_channels];
5044 for (int i = 0; i < 2 * gCamCapability[mCameraId]->num_color_channels; i += 2) {
5045 noise_profile[i] = noise_profile_S;
5046 noise_profile[i+1] = noise_profile_O;
5047 }
5048 LOGD("noise model entry (S, O) is (%f, %f)",
5049 noise_profile_S, noise_profile_O);
5050 camMetadata.update(ANDROID_SENSOR_NOISE_PROFILE, noise_profile,
5051 (size_t) (2 * gCamCapability[mCameraId]->num_color_channels));
5052 }
5053
Thierry Strudel9e74aae2016-09-22 17:10:18 -07005054#ifndef USE_HAL_3_3
5055 IF_META_AVAILABLE(int32_t, ispSensitivity, CAM_INTF_META_ISP_SENSITIVITY, metadata) {
5056 int32_t fwk_ispSensitivity = (int32_t) *ispSensitivity;
5057 camMetadata.update(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST, &fwk_ispSensitivity, 1);
5058 }
5059#endif
5060
Thierry Strudel3d639192016-09-09 11:52:26 -07005061 IF_META_AVAILABLE(uint32_t, shadingMode, CAM_INTF_META_SHADING_MODE, metadata) {
5062 uint8_t fwk_shadingMode = (uint8_t) *shadingMode;
5063 camMetadata.update(ANDROID_SHADING_MODE, &fwk_shadingMode, 1);
5064 }
5065
5066 IF_META_AVAILABLE(uint32_t, faceDetectMode, CAM_INTF_META_STATS_FACEDETECT_MODE, metadata) {
5067 int val = lookupFwkName(FACEDETECT_MODES_MAP, METADATA_MAP_SIZE(FACEDETECT_MODES_MAP),
5068 *faceDetectMode);
5069 if (NAME_NOT_FOUND != val) {
5070 uint8_t fwk_faceDetectMode = (uint8_t)val;
5071 camMetadata.update(ANDROID_STATISTICS_FACE_DETECT_MODE, &fwk_faceDetectMode, 1);
5072
5073 if (fwk_faceDetectMode != ANDROID_STATISTICS_FACE_DETECT_MODE_OFF) {
5074 IF_META_AVAILABLE(cam_face_detection_data_t, faceDetectionInfo,
5075 CAM_INTF_META_FACE_DETECTION, metadata) {
5076 uint8_t numFaces = MIN(
5077 faceDetectionInfo->num_faces_detected, MAX_ROI);
5078 int32_t faceIds[MAX_ROI];
5079 uint8_t faceScores[MAX_ROI];
5080 int32_t faceRectangles[MAX_ROI * 4];
5081 int32_t faceLandmarks[MAX_ROI * 6];
5082 size_t j = 0, k = 0;
5083
5084 for (size_t i = 0; i < numFaces; i++) {
5085 faceScores[i] = (uint8_t)faceDetectionInfo->faces[i].score;
5086 // Adjust crop region from sensor output coordinate system to active
5087 // array coordinate system.
5088 cam_rect_t& rect = faceDetectionInfo->faces[i].face_boundary;
5089 mCropRegionMapper.toActiveArray(rect.left, rect.top,
5090 rect.width, rect.height);
5091
5092 convertToRegions(faceDetectionInfo->faces[i].face_boundary,
5093 faceRectangles+j, -1);
5094
5095 j+= 4;
5096 }
5097 if (numFaces <= 0) {
5098 memset(faceIds, 0, sizeof(int32_t) * MAX_ROI);
5099 memset(faceScores, 0, sizeof(uint8_t) * MAX_ROI);
5100 memset(faceRectangles, 0, sizeof(int32_t) * MAX_ROI * 4);
5101 memset(faceLandmarks, 0, sizeof(int32_t) * MAX_ROI * 6);
5102 }
5103
5104 camMetadata.update(ANDROID_STATISTICS_FACE_SCORES, faceScores,
5105 numFaces);
5106 camMetadata.update(ANDROID_STATISTICS_FACE_RECTANGLES,
5107 faceRectangles, numFaces * 4U);
5108 if (fwk_faceDetectMode ==
5109 ANDROID_STATISTICS_FACE_DETECT_MODE_FULL) {
5110 IF_META_AVAILABLE(cam_face_landmarks_data_t, landmarks,
5111 CAM_INTF_META_FACE_LANDMARK, metadata) {
5112
5113 for (size_t i = 0; i < numFaces; i++) {
5114 // Map the co-ordinate sensor output coordinate system to active
5115 // array coordinate system.
5116 mCropRegionMapper.toActiveArray(
5117 landmarks->face_landmarks[i].left_eye_center.x,
5118 landmarks->face_landmarks[i].left_eye_center.y);
5119 mCropRegionMapper.toActiveArray(
5120 landmarks->face_landmarks[i].right_eye_center.x,
5121 landmarks->face_landmarks[i].right_eye_center.y);
5122 mCropRegionMapper.toActiveArray(
5123 landmarks->face_landmarks[i].mouth_center.x,
5124 landmarks->face_landmarks[i].mouth_center.y);
5125
5126 convertLandmarks(landmarks->face_landmarks[i], faceLandmarks+k);
5127 k+= 6;
5128 }
5129 }
5130
5131 camMetadata.update(ANDROID_STATISTICS_FACE_IDS, faceIds, numFaces);
5132 camMetadata.update(ANDROID_STATISTICS_FACE_LANDMARKS,
5133 faceLandmarks, numFaces * 6U);
5134 }
5135 }
5136 }
5137 }
5138 }
5139
5140 IF_META_AVAILABLE(uint32_t, histogramMode, CAM_INTF_META_STATS_HISTOGRAM_MODE, metadata) {
5141 uint8_t fwk_histogramMode = (uint8_t) *histogramMode;
5142 camMetadata.update(ANDROID_STATISTICS_HISTOGRAM_MODE, &fwk_histogramMode, 1);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07005143
5144 if (fwk_histogramMode == ANDROID_STATISTICS_HISTOGRAM_MODE_ON) {
5145 IF_META_AVAILABLE(cam_hist_stats_t, stats_data, CAM_INTF_META_HISTOGRAM, metadata) {
5146 // process histogram statistics info
5147 uint32_t hist_buf[3][CAM_HISTOGRAM_STATS_SIZE];
5148 uint32_t hist_size = sizeof(cam_histogram_data_t::hist_buf);
5149 cam_histogram_data_t rHistData, gHistData, bHistData;
5150 memset(&rHistData, 0, sizeof(rHistData));
5151 memset(&gHistData, 0, sizeof(gHistData));
5152 memset(&bHistData, 0, sizeof(bHistData));
5153
5154 switch (stats_data->type) {
5155 case CAM_HISTOGRAM_TYPE_BAYER:
5156 switch (stats_data->bayer_stats.data_type) {
5157 case CAM_STATS_CHANNEL_GR:
5158 rHistData = gHistData = bHistData = stats_data->bayer_stats.gr_stats;
5159 break;
5160 case CAM_STATS_CHANNEL_GB:
5161 rHistData = gHistData = bHistData = stats_data->bayer_stats.gb_stats;
5162 break;
5163 case CAM_STATS_CHANNEL_B:
5164 rHistData = gHistData = bHistData = stats_data->bayer_stats.b_stats;
5165 break;
5166 case CAM_STATS_CHANNEL_ALL:
5167 rHistData = stats_data->bayer_stats.r_stats;
5168 //Framework expects only 3 channels. So, for now,
5169 //use gb stats for G channel.
5170 gHistData = stats_data->bayer_stats.gb_stats;
5171 bHistData = stats_data->bayer_stats.b_stats;
5172 break;
5173 case CAM_STATS_CHANNEL_Y:
5174 case CAM_STATS_CHANNEL_R:
5175 default:
5176 rHistData = gHistData = bHistData = stats_data->bayer_stats.r_stats;
5177 break;
5178 }
5179 break;
5180 case CAM_HISTOGRAM_TYPE_YUV:
5181 rHistData = gHistData = bHistData = stats_data->yuv_stats;
5182 break;
5183 }
5184
5185 memcpy(hist_buf, rHistData.hist_buf, hist_size);
5186 memcpy(hist_buf[1], gHistData.hist_buf, hist_size);
5187 memcpy(hist_buf[2], bHistData.hist_buf, hist_size);
5188
5189 camMetadata.update(ANDROID_STATISTICS_HISTOGRAM, (int32_t*)hist_buf, hist_size*3);
5190 }
5191 }
Thierry Strudel3d639192016-09-09 11:52:26 -07005192 }
5193
5194 IF_META_AVAILABLE(uint32_t, sharpnessMapMode,
5195 CAM_INTF_META_STATS_SHARPNESS_MAP_MODE, metadata) {
5196 uint8_t fwk_sharpnessMapMode = (uint8_t) *sharpnessMapMode;
5197 camMetadata.update(ANDROID_STATISTICS_SHARPNESS_MAP_MODE, &fwk_sharpnessMapMode, 1);
5198 }
5199
5200 IF_META_AVAILABLE(cam_sharpness_map_t, sharpnessMap,
5201 CAM_INTF_META_STATS_SHARPNESS_MAP, metadata) {
5202 camMetadata.update(ANDROID_STATISTICS_SHARPNESS_MAP, (int32_t *)sharpnessMap->sharpness,
5203 CAM_MAX_MAP_WIDTH * CAM_MAX_MAP_HEIGHT * 3);
5204 }
5205
5206 IF_META_AVAILABLE(cam_lens_shading_map_t, lensShadingMap,
5207 CAM_INTF_META_LENS_SHADING_MAP, metadata) {
5208 size_t map_height = MIN((size_t)gCamCapability[mCameraId]->lens_shading_map_size.height,
5209 CAM_MAX_SHADING_MAP_HEIGHT);
5210 size_t map_width = MIN((size_t)gCamCapability[mCameraId]->lens_shading_map_size.width,
5211 CAM_MAX_SHADING_MAP_WIDTH);
5212 camMetadata.update(ANDROID_STATISTICS_LENS_SHADING_MAP,
5213 lensShadingMap->lens_shading, 4U * map_width * map_height);
5214 }
5215
5216 IF_META_AVAILABLE(uint32_t, toneMapMode, CAM_INTF_META_TONEMAP_MODE, metadata) {
5217 uint8_t fwk_toneMapMode = (uint8_t) *toneMapMode;
5218 camMetadata.update(ANDROID_TONEMAP_MODE, &fwk_toneMapMode, 1);
5219 }
5220
5221 IF_META_AVAILABLE(cam_rgb_tonemap_curves, tonemap, CAM_INTF_META_TONEMAP_CURVES, metadata) {
5222 //Populate CAM_INTF_META_TONEMAP_CURVES
5223 /* ch0 = G, ch 1 = B, ch 2 = R*/
5224 if (tonemap->tonemap_points_cnt > CAM_MAX_TONEMAP_CURVE_SIZE) {
5225 LOGE("Fatal: tonemap_points_cnt %d exceeds max value of %d",
5226 tonemap->tonemap_points_cnt,
5227 CAM_MAX_TONEMAP_CURVE_SIZE);
5228 tonemap->tonemap_points_cnt = CAM_MAX_TONEMAP_CURVE_SIZE;
5229 }
5230
5231 camMetadata.update(ANDROID_TONEMAP_CURVE_GREEN,
5232 &tonemap->curves[0].tonemap_points[0][0],
5233 tonemap->tonemap_points_cnt * 2);
5234
5235 camMetadata.update(ANDROID_TONEMAP_CURVE_BLUE,
5236 &tonemap->curves[1].tonemap_points[0][0],
5237 tonemap->tonemap_points_cnt * 2);
5238
5239 camMetadata.update(ANDROID_TONEMAP_CURVE_RED,
5240 &tonemap->curves[2].tonemap_points[0][0],
5241 tonemap->tonemap_points_cnt * 2);
5242 }
5243
5244 IF_META_AVAILABLE(cam_color_correct_gains_t, colorCorrectionGains,
5245 CAM_INTF_META_COLOR_CORRECT_GAINS, metadata) {
5246 camMetadata.update(ANDROID_COLOR_CORRECTION_GAINS, colorCorrectionGains->gains,
5247 CC_GAIN_MAX);
5248 }
5249
5250 IF_META_AVAILABLE(cam_color_correct_matrix_t, colorCorrectionMatrix,
5251 CAM_INTF_META_COLOR_CORRECT_TRANSFORM, metadata) {
5252 camMetadata.update(ANDROID_COLOR_CORRECTION_TRANSFORM,
5253 (camera_metadata_rational_t *)(void *)colorCorrectionMatrix->transform_matrix,
5254 CC_MATRIX_COLS * CC_MATRIX_ROWS);
5255 }
5256
5257 IF_META_AVAILABLE(cam_profile_tone_curve, toneCurve,
5258 CAM_INTF_META_PROFILE_TONE_CURVE, metadata) {
5259 if (toneCurve->tonemap_points_cnt > CAM_MAX_TONEMAP_CURVE_SIZE) {
5260 LOGE("Fatal: tonemap_points_cnt %d exceeds max value of %d",
5261 toneCurve->tonemap_points_cnt,
5262 CAM_MAX_TONEMAP_CURVE_SIZE);
5263 toneCurve->tonemap_points_cnt = CAM_MAX_TONEMAP_CURVE_SIZE;
5264 }
5265 camMetadata.update(ANDROID_SENSOR_PROFILE_TONE_CURVE,
5266 (float*)toneCurve->curve.tonemap_points,
5267 toneCurve->tonemap_points_cnt * 2);
5268 }
5269
5270 IF_META_AVAILABLE(cam_color_correct_gains_t, predColorCorrectionGains,
5271 CAM_INTF_META_PRED_COLOR_CORRECT_GAINS, metadata) {
5272 camMetadata.update(ANDROID_STATISTICS_PREDICTED_COLOR_GAINS,
5273 predColorCorrectionGains->gains, 4);
5274 }
5275
5276 IF_META_AVAILABLE(cam_color_correct_matrix_t, predColorCorrectionMatrix,
5277 CAM_INTF_META_PRED_COLOR_CORRECT_TRANSFORM, metadata) {
5278 camMetadata.update(ANDROID_STATISTICS_PREDICTED_COLOR_TRANSFORM,
5279 (camera_metadata_rational_t *)(void *)predColorCorrectionMatrix->transform_matrix,
5280 CC_MATRIX_ROWS * CC_MATRIX_COLS);
5281 }
5282
5283 IF_META_AVAILABLE(float, otpWbGrGb, CAM_INTF_META_OTP_WB_GRGB, metadata) {
5284 camMetadata.update(ANDROID_SENSOR_GREEN_SPLIT, otpWbGrGb, 1);
5285 }
5286
5287 IF_META_AVAILABLE(uint32_t, blackLevelLock, CAM_INTF_META_BLACK_LEVEL_LOCK, metadata) {
5288 uint8_t fwk_blackLevelLock = (uint8_t) *blackLevelLock;
5289 camMetadata.update(ANDROID_BLACK_LEVEL_LOCK, &fwk_blackLevelLock, 1);
5290 }
5291
5292 IF_META_AVAILABLE(uint32_t, sceneFlicker, CAM_INTF_META_SCENE_FLICKER, metadata) {
5293 uint8_t fwk_sceneFlicker = (uint8_t) *sceneFlicker;
5294 camMetadata.update(ANDROID_STATISTICS_SCENE_FLICKER, &fwk_sceneFlicker, 1);
5295 }
5296
5297 IF_META_AVAILABLE(uint32_t, effectMode, CAM_INTF_PARM_EFFECT, metadata) {
5298 int val = lookupFwkName(EFFECT_MODES_MAP, METADATA_MAP_SIZE(EFFECT_MODES_MAP),
5299 *effectMode);
5300 if (NAME_NOT_FOUND != val) {
5301 uint8_t fwk_effectMode = (uint8_t)val;
5302 camMetadata.update(ANDROID_CONTROL_EFFECT_MODE, &fwk_effectMode, 1);
5303 }
5304 }
5305
5306 IF_META_AVAILABLE(cam_test_pattern_data_t, testPatternData,
5307 CAM_INTF_META_TEST_PATTERN_DATA, metadata) {
5308 int32_t fwk_testPatternMode = lookupFwkName(TEST_PATTERN_MAP,
5309 METADATA_MAP_SIZE(TEST_PATTERN_MAP), testPatternData->mode);
5310 if (NAME_NOT_FOUND != fwk_testPatternMode) {
5311 camMetadata.update(ANDROID_SENSOR_TEST_PATTERN_MODE, &fwk_testPatternMode, 1);
5312 }
5313 int32_t fwk_testPatternData[4];
5314 fwk_testPatternData[0] = testPatternData->r;
5315 fwk_testPatternData[3] = testPatternData->b;
5316 switch (gCamCapability[mCameraId]->color_arrangement) {
5317 case CAM_FILTER_ARRANGEMENT_RGGB:
5318 case CAM_FILTER_ARRANGEMENT_GRBG:
5319 fwk_testPatternData[1] = testPatternData->gr;
5320 fwk_testPatternData[2] = testPatternData->gb;
5321 break;
5322 case CAM_FILTER_ARRANGEMENT_GBRG:
5323 case CAM_FILTER_ARRANGEMENT_BGGR:
5324 fwk_testPatternData[2] = testPatternData->gr;
5325 fwk_testPatternData[1] = testPatternData->gb;
5326 break;
5327 default:
5328 LOGE("color arrangement %d is not supported",
5329 gCamCapability[mCameraId]->color_arrangement);
5330 break;
5331 }
5332 camMetadata.update(ANDROID_SENSOR_TEST_PATTERN_DATA, fwk_testPatternData, 4);
5333 }
5334
5335 IF_META_AVAILABLE(double, gps_coords, CAM_INTF_META_JPEG_GPS_COORDINATES, metadata) {
5336 camMetadata.update(ANDROID_JPEG_GPS_COORDINATES, gps_coords, 3);
5337 }
5338
5339 IF_META_AVAILABLE(uint8_t, gps_methods, CAM_INTF_META_JPEG_GPS_PROC_METHODS, metadata) {
5340 String8 str((const char *)gps_methods);
5341 camMetadata.update(ANDROID_JPEG_GPS_PROCESSING_METHOD, str);
5342 }
5343
5344 IF_META_AVAILABLE(int64_t, gps_timestamp, CAM_INTF_META_JPEG_GPS_TIMESTAMP, metadata) {
5345 camMetadata.update(ANDROID_JPEG_GPS_TIMESTAMP, gps_timestamp, 1);
5346 }
5347
5348 IF_META_AVAILABLE(int32_t, jpeg_orientation, CAM_INTF_META_JPEG_ORIENTATION, metadata) {
5349 camMetadata.update(ANDROID_JPEG_ORIENTATION, jpeg_orientation, 1);
5350 }
5351
5352 IF_META_AVAILABLE(uint32_t, jpeg_quality, CAM_INTF_META_JPEG_QUALITY, metadata) {
5353 uint8_t fwk_jpeg_quality = (uint8_t) *jpeg_quality;
5354 camMetadata.update(ANDROID_JPEG_QUALITY, &fwk_jpeg_quality, 1);
5355 }
5356
5357 IF_META_AVAILABLE(uint32_t, thumb_quality, CAM_INTF_META_JPEG_THUMB_QUALITY, metadata) {
5358 uint8_t fwk_thumb_quality = (uint8_t) *thumb_quality;
5359 camMetadata.update(ANDROID_JPEG_THUMBNAIL_QUALITY, &fwk_thumb_quality, 1);
5360 }
5361
5362 IF_META_AVAILABLE(cam_dimension_t, thumb_size, CAM_INTF_META_JPEG_THUMB_SIZE, metadata) {
5363 int32_t fwk_thumb_size[2];
5364 fwk_thumb_size[0] = thumb_size->width;
5365 fwk_thumb_size[1] = thumb_size->height;
5366 camMetadata.update(ANDROID_JPEG_THUMBNAIL_SIZE, fwk_thumb_size, 2);
5367 }
5368
5369 IF_META_AVAILABLE(int32_t, privateData, CAM_INTF_META_PRIVATE_DATA, metadata) {
5370 camMetadata.update(QCAMERA3_PRIVATEDATA_REPROCESS,
5371 privateData,
5372 MAX_METADATA_PRIVATE_PAYLOAD_SIZE_IN_BYTES / sizeof(int32_t));
5373 }
5374
5375 if (metadata->is_tuning_params_valid) {
5376 uint8_t tuning_meta_data_blob[sizeof(tuning_params_t)];
5377 uint8_t *data = (uint8_t *)&tuning_meta_data_blob[0];
5378 metadata->tuning_params.tuning_data_version = TUNING_DATA_VERSION;
5379
5380
5381 memcpy(data, ((uint8_t *)&metadata->tuning_params.tuning_data_version),
5382 sizeof(uint32_t));
5383 data += sizeof(uint32_t);
5384
5385 memcpy(data, ((uint8_t *)&metadata->tuning_params.tuning_sensor_data_size),
5386 sizeof(uint32_t));
5387 LOGD("tuning_sensor_data_size %d",(int)(*(int *)data));
5388 data += sizeof(uint32_t);
5389
5390 memcpy(data, ((uint8_t *)&metadata->tuning_params.tuning_vfe_data_size),
5391 sizeof(uint32_t));
5392 LOGD("tuning_vfe_data_size %d",(int)(*(int *)data));
5393 data += sizeof(uint32_t);
5394
5395 memcpy(data, ((uint8_t *)&metadata->tuning_params.tuning_cpp_data_size),
5396 sizeof(uint32_t));
5397 LOGD("tuning_cpp_data_size %d",(int)(*(int *)data));
5398 data += sizeof(uint32_t);
5399
5400 memcpy(data, ((uint8_t *)&metadata->tuning_params.tuning_cac_data_size),
5401 sizeof(uint32_t));
5402 LOGD("tuning_cac_data_size %d",(int)(*(int *)data));
5403 data += sizeof(uint32_t);
5404
5405 metadata->tuning_params.tuning_mod3_data_size = 0;
5406 memcpy(data, ((uint8_t *)&metadata->tuning_params.tuning_mod3_data_size),
5407 sizeof(uint32_t));
5408 LOGD("tuning_mod3_data_size %d",(int)(*(int *)data));
5409 data += sizeof(uint32_t);
5410
5411 size_t count = MIN(metadata->tuning_params.tuning_sensor_data_size,
5412 TUNING_SENSOR_DATA_MAX);
5413 memcpy(data, ((uint8_t *)&metadata->tuning_params.data),
5414 count);
5415 data += count;
5416
5417 count = MIN(metadata->tuning_params.tuning_vfe_data_size,
5418 TUNING_VFE_DATA_MAX);
5419 memcpy(data, ((uint8_t *)&metadata->tuning_params.data[TUNING_VFE_DATA_OFFSET]),
5420 count);
5421 data += count;
5422
5423 count = MIN(metadata->tuning_params.tuning_cpp_data_size,
5424 TUNING_CPP_DATA_MAX);
5425 memcpy(data, ((uint8_t *)&metadata->tuning_params.data[TUNING_CPP_DATA_OFFSET]),
5426 count);
5427 data += count;
5428
5429 count = MIN(metadata->tuning_params.tuning_cac_data_size,
5430 TUNING_CAC_DATA_MAX);
5431 memcpy(data, ((uint8_t *)&metadata->tuning_params.data[TUNING_CAC_DATA_OFFSET]),
5432 count);
5433 data += count;
5434
5435 camMetadata.update(QCAMERA3_TUNING_META_DATA_BLOB,
5436 (int32_t *)(void *)tuning_meta_data_blob,
5437 (size_t)(data-tuning_meta_data_blob) / sizeof(uint32_t));
5438 }
5439
5440 IF_META_AVAILABLE(cam_neutral_col_point_t, neuColPoint,
5441 CAM_INTF_META_NEUTRAL_COL_POINT, metadata) {
5442 camMetadata.update(ANDROID_SENSOR_NEUTRAL_COLOR_POINT,
5443 (camera_metadata_rational_t *)(void *)neuColPoint->neutral_col_point,
5444 NEUTRAL_COL_POINTS);
5445 }
5446
5447 IF_META_AVAILABLE(uint32_t, shadingMapMode, CAM_INTF_META_LENS_SHADING_MAP_MODE, metadata) {
5448 uint8_t fwk_shadingMapMode = (uint8_t) *shadingMapMode;
5449 camMetadata.update(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, &fwk_shadingMapMode, 1);
5450 }
5451
5452 IF_META_AVAILABLE(cam_area_t, hAeRegions, CAM_INTF_META_AEC_ROI, metadata) {
5453 int32_t aeRegions[REGIONS_TUPLE_COUNT];
5454 // Adjust crop region from sensor output coordinate system to active
5455 // array coordinate system.
5456 mCropRegionMapper.toActiveArray(hAeRegions->rect.left, hAeRegions->rect.top,
5457 hAeRegions->rect.width, hAeRegions->rect.height);
5458
5459 convertToRegions(hAeRegions->rect, aeRegions, hAeRegions->weight);
5460 camMetadata.update(ANDROID_CONTROL_AE_REGIONS, aeRegions,
5461 REGIONS_TUPLE_COUNT);
5462 LOGD("Metadata : ANDROID_CONTROL_AE_REGIONS: FWK: [%d,%d,%d,%d] HAL: [%d,%d,%d,%d]",
5463 aeRegions[0], aeRegions[1], aeRegions[2], aeRegions[3],
5464 hAeRegions->rect.left, hAeRegions->rect.top, hAeRegions->rect.width,
5465 hAeRegions->rect.height);
5466 }
5467
5468 IF_META_AVAILABLE(uint32_t, afState, CAM_INTF_META_AF_STATE, metadata) {
5469 uint8_t fwk_afState = (uint8_t) *afState;
5470 camMetadata.update(ANDROID_CONTROL_AF_STATE, &fwk_afState, 1);
5471 LOGD("urgent Metadata : ANDROID_CONTROL_AF_STATE %u", *afState);
5472 }
5473
5474 IF_META_AVAILABLE(float, focusDistance, CAM_INTF_META_LENS_FOCUS_DISTANCE, metadata) {
5475 camMetadata.update(ANDROID_LENS_FOCUS_DISTANCE , focusDistance, 1);
5476 }
5477
5478 IF_META_AVAILABLE(float, focusRange, CAM_INTF_META_LENS_FOCUS_RANGE, metadata) {
5479 camMetadata.update(ANDROID_LENS_FOCUS_RANGE , focusRange, 2);
5480 }
5481
5482 IF_META_AVAILABLE(cam_af_lens_state_t, lensState, CAM_INTF_META_LENS_STATE, metadata) {
5483 uint8_t fwk_lensState = *lensState;
5484 camMetadata.update(ANDROID_LENS_STATE , &fwk_lensState, 1);
5485 }
5486
5487 IF_META_AVAILABLE(cam_area_t, hAfRegions, CAM_INTF_META_AF_ROI, metadata) {
5488 /*af regions*/
5489 int32_t afRegions[REGIONS_TUPLE_COUNT];
5490 // Adjust crop region from sensor output coordinate system to active
5491 // array coordinate system.
5492 mCropRegionMapper.toActiveArray(hAfRegions->rect.left, hAfRegions->rect.top,
5493 hAfRegions->rect.width, hAfRegions->rect.height);
5494
5495 convertToRegions(hAfRegions->rect, afRegions, hAfRegions->weight);
5496 camMetadata.update(ANDROID_CONTROL_AF_REGIONS, afRegions,
5497 REGIONS_TUPLE_COUNT);
5498 LOGD("Metadata : ANDROID_CONTROL_AF_REGIONS: FWK: [%d,%d,%d,%d] HAL: [%d,%d,%d,%d]",
5499 afRegions[0], afRegions[1], afRegions[2], afRegions[3],
5500 hAfRegions->rect.left, hAfRegions->rect.top, hAfRegions->rect.width,
5501 hAfRegions->rect.height);
5502 }
5503
5504 IF_META_AVAILABLE(uint32_t, hal_ab_mode, CAM_INTF_PARM_ANTIBANDING, metadata) {
5505 int val = lookupFwkName(ANTIBANDING_MODES_MAP, METADATA_MAP_SIZE(ANTIBANDING_MODES_MAP),
5506 *hal_ab_mode);
5507 if (NAME_NOT_FOUND != val) {
5508 uint8_t fwk_ab_mode = (uint8_t)val;
5509 camMetadata.update(ANDROID_CONTROL_AE_ANTIBANDING_MODE, &fwk_ab_mode, 1);
5510 }
5511 }
5512
5513 IF_META_AVAILABLE(uint32_t, bestshotMode, CAM_INTF_PARM_BESTSHOT_MODE, metadata) {
5514 int val = lookupFwkName(SCENE_MODES_MAP,
5515 METADATA_MAP_SIZE(SCENE_MODES_MAP), *bestshotMode);
5516 if (NAME_NOT_FOUND != val) {
5517 uint8_t fwkBestshotMode = (uint8_t)val;
5518 camMetadata.update(ANDROID_CONTROL_SCENE_MODE, &fwkBestshotMode, 1);
5519 LOGD("Metadata : ANDROID_CONTROL_SCENE_MODE");
5520 } else {
5521 LOGH("Metadata not found : ANDROID_CONTROL_SCENE_MODE");
5522 }
5523 }
5524
5525 IF_META_AVAILABLE(uint32_t, mode, CAM_INTF_META_MODE, metadata) {
5526 uint8_t fwk_mode = (uint8_t) *mode;
5527 camMetadata.update(ANDROID_CONTROL_MODE, &fwk_mode, 1);
5528 }
5529
5530 /* Constant metadata values to be update*/
5531 uint8_t hotPixelModeFast = ANDROID_HOT_PIXEL_MODE_FAST;
5532 camMetadata.update(ANDROID_HOT_PIXEL_MODE, &hotPixelModeFast, 1);
5533
5534 uint8_t hotPixelMapMode = ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF;
5535 camMetadata.update(ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE, &hotPixelMapMode, 1);
5536
5537 int32_t hotPixelMap[2];
5538 camMetadata.update(ANDROID_STATISTICS_HOT_PIXEL_MAP, &hotPixelMap[0], 0);
5539
5540 // CDS
5541 IF_META_AVAILABLE(int32_t, cds, CAM_INTF_PARM_CDS_MODE, metadata) {
5542 camMetadata.update(QCAMERA3_CDS_MODE, cds, 1);
5543 }
5544
5545 // TNR
5546 IF_META_AVAILABLE(cam_denoise_param_t, tnr, CAM_INTF_PARM_TEMPORAL_DENOISE, metadata) {
5547 uint8_t tnr_enable = tnr->denoise_enable;
5548 int32_t tnr_process_type = (int32_t)tnr->process_plates;
5549
5550 camMetadata.update(QCAMERA3_TEMPORAL_DENOISE_ENABLE, &tnr_enable, 1);
5551 camMetadata.update(QCAMERA3_TEMPORAL_DENOISE_PROCESS_TYPE, &tnr_process_type, 1);
5552 }
5553
5554 // Reprocess crop data
5555 IF_META_AVAILABLE(cam_crop_data_t, crop_data, CAM_INTF_META_CROP_DATA, metadata) {
5556 uint8_t cnt = crop_data->num_of_streams;
5557 if ( (0 >= cnt) || (cnt > MAX_NUM_STREAMS)) {
5558 // mm-qcamera-daemon only posts crop_data for streams
5559 // not linked to pproc. So no valid crop metadata is not
5560 // necessarily an error case.
5561 LOGD("No valid crop metadata entries");
5562 } else {
5563 uint32_t reproc_stream_id;
5564 if ( NO_ERROR != getReprocessibleOutputStreamId(reproc_stream_id)) {
5565 LOGD("No reprocessible stream found, ignore crop data");
5566 } else {
5567 int rc = NO_ERROR;
5568 Vector<int32_t> roi_map;
5569 int32_t *crop = new int32_t[cnt*4];
5570 if (NULL == crop) {
5571 rc = NO_MEMORY;
5572 }
5573 if (NO_ERROR == rc) {
5574 int32_t streams_found = 0;
5575 for (size_t i = 0; i < cnt; i++) {
5576 if (crop_data->crop_info[i].stream_id == reproc_stream_id) {
5577 if (pprocDone) {
5578 // HAL already does internal reprocessing,
5579 // either via reprocessing before JPEG encoding,
5580 // or offline postprocessing for pproc bypass case.
5581 crop[0] = 0;
5582 crop[1] = 0;
5583 crop[2] = mInputStreamInfo.dim.width;
5584 crop[3] = mInputStreamInfo.dim.height;
5585 } else {
5586 crop[0] = crop_data->crop_info[i].crop.left;
5587 crop[1] = crop_data->crop_info[i].crop.top;
5588 crop[2] = crop_data->crop_info[i].crop.width;
5589 crop[3] = crop_data->crop_info[i].crop.height;
5590 }
5591 roi_map.add(crop_data->crop_info[i].roi_map.left);
5592 roi_map.add(crop_data->crop_info[i].roi_map.top);
5593 roi_map.add(crop_data->crop_info[i].roi_map.width);
5594 roi_map.add(crop_data->crop_info[i].roi_map.height);
5595 streams_found++;
5596 LOGD("Adding reprocess crop data for stream %dx%d, %dx%d",
5597 crop[0], crop[1], crop[2], crop[3]);
5598 LOGD("Adding reprocess crop roi map for stream %dx%d, %dx%d",
5599 crop_data->crop_info[i].roi_map.left,
5600 crop_data->crop_info[i].roi_map.top,
5601 crop_data->crop_info[i].roi_map.width,
5602 crop_data->crop_info[i].roi_map.height);
5603 break;
5604
5605 }
5606 }
5607 camMetadata.update(QCAMERA3_CROP_COUNT_REPROCESS,
5608 &streams_found, 1);
5609 camMetadata.update(QCAMERA3_CROP_REPROCESS,
5610 crop, (size_t)(streams_found * 4));
5611 if (roi_map.array()) {
5612 camMetadata.update(QCAMERA3_CROP_ROI_MAP_REPROCESS,
5613 roi_map.array(), roi_map.size());
5614 }
5615 }
5616 if (crop) {
5617 delete [] crop;
5618 }
5619 }
5620 }
5621 }
5622
5623 if (gCamCapability[mCameraId]->aberration_modes_count == 0) {
5624 // Regardless of CAC supports or not, CTS is expecting the CAC result to be non NULL and
5625 // so hardcoding the CAC result to OFF mode.
5626 uint8_t fwkCacMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
5627 camMetadata.update(ANDROID_COLOR_CORRECTION_ABERRATION_MODE, &fwkCacMode, 1);
5628 } else {
5629 IF_META_AVAILABLE(cam_aberration_mode_t, cacMode, CAM_INTF_PARM_CAC, metadata) {
5630 int val = lookupFwkName(COLOR_ABERRATION_MAP, METADATA_MAP_SIZE(COLOR_ABERRATION_MAP),
5631 *cacMode);
5632 if (NAME_NOT_FOUND != val) {
5633 uint8_t resultCacMode = (uint8_t)val;
5634 // check whether CAC result from CB is equal to Framework set CAC mode
5635 // If not equal then set the CAC mode came in corresponding request
5636 if (fwk_cacMode != resultCacMode) {
5637 resultCacMode = fwk_cacMode;
5638 }
5639 LOGD("fwk_cacMode=%d resultCacMode=%d", fwk_cacMode, resultCacMode);
5640 camMetadata.update(ANDROID_COLOR_CORRECTION_ABERRATION_MODE, &resultCacMode, 1);
5641 } else {
5642 LOGE("Invalid CAC camera parameter: %d", *cacMode);
5643 }
5644 }
5645 }
5646
5647 // Post blob of cam_cds_data through vendor tag.
5648 IF_META_AVAILABLE(cam_cds_data_t, cdsInfo, CAM_INTF_META_CDS_DATA, metadata) {
5649 uint8_t cnt = cdsInfo->num_of_streams;
5650 cam_cds_data_t cdsDataOverride;
5651 memset(&cdsDataOverride, 0, sizeof(cdsDataOverride));
5652 cdsDataOverride.session_cds_enable = cdsInfo->session_cds_enable;
5653 cdsDataOverride.num_of_streams = 1;
5654 if ((0 < cnt) && (cnt <= MAX_NUM_STREAMS)) {
5655 uint32_t reproc_stream_id;
5656 if ( NO_ERROR != getReprocessibleOutputStreamId(reproc_stream_id)) {
5657 LOGD("No reprocessible stream found, ignore cds data");
5658 } else {
5659 for (size_t i = 0; i < cnt; i++) {
5660 if (cdsInfo->cds_info[i].stream_id ==
5661 reproc_stream_id) {
5662 cdsDataOverride.cds_info[0].cds_enable =
5663 cdsInfo->cds_info[i].cds_enable;
5664 break;
5665 }
5666 }
5667 }
5668 } else {
5669 LOGD("Invalid stream count %d in CDS_DATA", cnt);
5670 }
5671 camMetadata.update(QCAMERA3_CDS_INFO,
5672 (uint8_t *)&cdsDataOverride,
5673 sizeof(cam_cds_data_t));
5674 }
5675
5676 // Ldaf calibration data
5677 if (!mLdafCalibExist) {
5678 IF_META_AVAILABLE(uint32_t, ldafCalib,
5679 CAM_INTF_META_LDAF_EXIF, metadata) {
5680 mLdafCalibExist = true;
5681 mLdafCalib[0] = ldafCalib[0];
5682 mLdafCalib[1] = ldafCalib[1];
5683 LOGD("ldafCalib[0] is %d, ldafCalib[1] is %d",
5684 ldafCalib[0], ldafCalib[1]);
5685 }
5686 }
5687
5688 // DDM debug data through vendor tag
5689 cam_ddm_info_t ddm_info;
5690 memset(&ddm_info, 0, sizeof(cam_ddm_info_t));
5691 IF_META_AVAILABLE(cam_stream_crop_info_t, sensorCropInfo,
5692 CAM_INTF_META_SNAP_CROP_INFO_SENSOR, metadata) {
5693 memcpy(&(ddm_info.sensor_crop_info), sensorCropInfo, sizeof(cam_stream_crop_info_t));
5694 }
5695 IF_META_AVAILABLE(cam_stream_crop_info_t, camifCropInfo,
5696 CAM_INTF_META_SNAP_CROP_INFO_CAMIF, metadata) {
5697 memcpy(&(ddm_info.camif_crop_info), camifCropInfo, sizeof(cam_stream_crop_info_t));
5698 }
5699 IF_META_AVAILABLE(cam_stream_crop_info_t, ispCropInfo,
5700 CAM_INTF_META_SNAP_CROP_INFO_ISP, metadata) {
5701 memcpy(&(ddm_info.isp_crop_info), ispCropInfo, sizeof(cam_stream_crop_info_t));
5702 }
5703 IF_META_AVAILABLE(cam_stream_crop_info_t, cppCropInfo,
5704 CAM_INTF_META_SNAP_CROP_INFO_CPP, metadata) {
5705 memcpy(&(ddm_info.cpp_crop_info), cppCropInfo, sizeof(cam_stream_crop_info_t));
5706 }
5707 IF_META_AVAILABLE(cam_focal_length_ratio_t, ratio,
5708 CAM_INTF_META_AF_FOCAL_LENGTH_RATIO, metadata) {
5709 memcpy(&(ddm_info.af_focal_length_ratio), ratio, sizeof(cam_focal_length_ratio_t));
5710 }
5711 IF_META_AVAILABLE(int32_t, flip, CAM_INTF_PARM_FLIP, metadata) {
5712 memcpy(&(ddm_info.pipeline_flip), flip, sizeof(int32_t));
5713 }
5714 IF_META_AVAILABLE(cam_rotation_info_t, rotationInfo,
5715 CAM_INTF_PARM_ROTATION, metadata) {
5716 memcpy(&(ddm_info.rotation_info), rotationInfo, sizeof(cam_rotation_info_t));
5717 }
5718 camMetadata.update(QCAMERA3_HAL_PRIVATEDATA_DDM_DATA_BLOB,
5719 (uint8_t *)&ddm_info, sizeof(cam_ddm_info_t));
5720
Thierry Strudel9e74aae2016-09-22 17:10:18 -07005721 /* In batch mode, cache the first metadata in the batch */
5722 if (mBatchSize && firstMetadataInBatch) {
5723 mCachedMetadata.clear();
5724 mCachedMetadata = camMetadata;
5725 }
5726
Thierry Strudel3d639192016-09-09 11:52:26 -07005727 resultMetadata = camMetadata.release();
5728 return resultMetadata;
5729}
5730
5731/*===========================================================================
5732 * FUNCTION : saveExifParams
5733 *
5734 * DESCRIPTION:
5735 *
5736 * PARAMETERS :
5737 * @metadata : metadata information from callback
5738 *
5739 * RETURN : none
5740 *
5741 *==========================================================================*/
5742void QCamera3HardwareInterface::saveExifParams(metadata_buffer_t *metadata)
5743{
5744 IF_META_AVAILABLE(cam_ae_exif_debug_t, ae_exif_debug_params,
5745 CAM_INTF_META_EXIF_DEBUG_AE, metadata) {
5746 if (mExifParams.debug_params) {
5747 mExifParams.debug_params->ae_debug_params = *ae_exif_debug_params;
5748 mExifParams.debug_params->ae_debug_params_valid = TRUE;
5749 }
5750 }
5751 IF_META_AVAILABLE(cam_awb_exif_debug_t,awb_exif_debug_params,
5752 CAM_INTF_META_EXIF_DEBUG_AWB, metadata) {
5753 if (mExifParams.debug_params) {
5754 mExifParams.debug_params->awb_debug_params = *awb_exif_debug_params;
5755 mExifParams.debug_params->awb_debug_params_valid = TRUE;
5756 }
5757 }
5758 IF_META_AVAILABLE(cam_af_exif_debug_t,af_exif_debug_params,
5759 CAM_INTF_META_EXIF_DEBUG_AF, metadata) {
5760 if (mExifParams.debug_params) {
5761 mExifParams.debug_params->af_debug_params = *af_exif_debug_params;
5762 mExifParams.debug_params->af_debug_params_valid = TRUE;
5763 }
5764 }
5765 IF_META_AVAILABLE(cam_asd_exif_debug_t, asd_exif_debug_params,
5766 CAM_INTF_META_EXIF_DEBUG_ASD, metadata) {
5767 if (mExifParams.debug_params) {
5768 mExifParams.debug_params->asd_debug_params = *asd_exif_debug_params;
5769 mExifParams.debug_params->asd_debug_params_valid = TRUE;
5770 }
5771 }
5772 IF_META_AVAILABLE(cam_stats_buffer_exif_debug_t,stats_exif_debug_params,
5773 CAM_INTF_META_EXIF_DEBUG_STATS, metadata) {
5774 if (mExifParams.debug_params) {
5775 mExifParams.debug_params->stats_debug_params = *stats_exif_debug_params;
5776 mExifParams.debug_params->stats_debug_params_valid = TRUE;
5777 }
5778 }
5779 IF_META_AVAILABLE(cam_bestats_buffer_exif_debug_t,bestats_exif_debug_params,
5780 CAM_INTF_META_EXIF_DEBUG_BESTATS, metadata) {
5781 if (mExifParams.debug_params) {
5782 mExifParams.debug_params->bestats_debug_params = *bestats_exif_debug_params;
5783 mExifParams.debug_params->bestats_debug_params_valid = TRUE;
5784 }
5785 }
5786 IF_META_AVAILABLE(cam_bhist_buffer_exif_debug_t, bhist_exif_debug_params,
5787 CAM_INTF_META_EXIF_DEBUG_BHIST, metadata) {
5788 if (mExifParams.debug_params) {
5789 mExifParams.debug_params->bhist_debug_params = *bhist_exif_debug_params;
5790 mExifParams.debug_params->bhist_debug_params_valid = TRUE;
5791 }
5792 }
5793 IF_META_AVAILABLE(cam_q3a_tuning_info_t, q3a_tuning_exif_debug_params,
5794 CAM_INTF_META_EXIF_DEBUG_3A_TUNING, metadata) {
5795 if (mExifParams.debug_params) {
5796 mExifParams.debug_params->q3a_tuning_debug_params = *q3a_tuning_exif_debug_params;
5797 mExifParams.debug_params->q3a_tuning_debug_params_valid = TRUE;
5798 }
5799 }
5800}
5801
5802/*===========================================================================
5803 * FUNCTION : get3AExifParams
5804 *
5805 * DESCRIPTION:
5806 *
5807 * PARAMETERS : none
5808 *
5809 *
5810 * RETURN : mm_jpeg_exif_params_t
5811 *
5812 *==========================================================================*/
5813mm_jpeg_exif_params_t QCamera3HardwareInterface::get3AExifParams()
5814{
5815 return mExifParams;
5816}
5817
5818/*===========================================================================
5819 * FUNCTION : translateCbUrgentMetadataToResultMetadata
5820 *
5821 * DESCRIPTION:
5822 *
5823 * PARAMETERS :
5824 * @metadata : metadata information from callback
5825 *
5826 * RETURN : camera_metadata_t*
5827 * metadata in a format specified by fwk
5828 *==========================================================================*/
5829camera_metadata_t*
5830QCamera3HardwareInterface::translateCbUrgentMetadataToResultMetadata
5831 (metadata_buffer_t *metadata)
5832{
5833 CameraMetadata camMetadata;
5834 camera_metadata_t *resultMetadata;
5835
5836
5837 IF_META_AVAILABLE(uint32_t, whiteBalanceState, CAM_INTF_META_AWB_STATE, metadata) {
5838 uint8_t fwk_whiteBalanceState = (uint8_t) *whiteBalanceState;
5839 camMetadata.update(ANDROID_CONTROL_AWB_STATE, &fwk_whiteBalanceState, 1);
5840 LOGD("urgent Metadata : ANDROID_CONTROL_AWB_STATE %u", *whiteBalanceState);
5841 }
5842
5843 IF_META_AVAILABLE(cam_trigger_t, aecTrigger, CAM_INTF_META_AEC_PRECAPTURE_TRIGGER, metadata) {
5844 camMetadata.update(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
5845 &aecTrigger->trigger, 1);
5846 camMetadata.update(ANDROID_CONTROL_AE_PRECAPTURE_ID,
5847 &aecTrigger->trigger_id, 1);
5848 LOGD("urgent Metadata : CAM_INTF_META_AEC_PRECAPTURE_TRIGGER: %d",
5849 aecTrigger->trigger);
5850 LOGD("urgent Metadata : ANDROID_CONTROL_AE_PRECAPTURE_ID: %d",
5851 aecTrigger->trigger_id);
5852 }
5853
5854 IF_META_AVAILABLE(uint32_t, ae_state, CAM_INTF_META_AEC_STATE, metadata) {
5855 uint8_t fwk_ae_state = (uint8_t) *ae_state;
5856 camMetadata.update(ANDROID_CONTROL_AE_STATE, &fwk_ae_state, 1);
5857 LOGD("urgent Metadata : ANDROID_CONTROL_AE_STATE %u", *ae_state);
5858 }
5859
5860 IF_META_AVAILABLE(uint32_t, focusMode, CAM_INTF_PARM_FOCUS_MODE, metadata) {
5861 int val = lookupFwkName(FOCUS_MODES_MAP, METADATA_MAP_SIZE(FOCUS_MODES_MAP), *focusMode);
5862 if (NAME_NOT_FOUND != val) {
5863 uint8_t fwkAfMode = (uint8_t)val;
5864 camMetadata.update(ANDROID_CONTROL_AF_MODE, &fwkAfMode, 1);
5865 LOGD("urgent Metadata : ANDROID_CONTROL_AF_MODE %d", val);
5866 } else {
5867 LOGH("urgent Metadata not found : ANDROID_CONTROL_AF_MODE %d",
5868 val);
5869 }
5870 }
5871
5872 IF_META_AVAILABLE(cam_trigger_t, af_trigger, CAM_INTF_META_AF_TRIGGER, metadata) {
5873 camMetadata.update(ANDROID_CONTROL_AF_TRIGGER,
5874 &af_trigger->trigger, 1);
5875 LOGD("urgent Metadata : CAM_INTF_META_AF_TRIGGER = %d",
5876 af_trigger->trigger);
5877 camMetadata.update(ANDROID_CONTROL_AF_TRIGGER_ID, &af_trigger->trigger_id, 1);
5878 LOGD("urgent Metadata : ANDROID_CONTROL_AF_TRIGGER_ID = %d",
5879 af_trigger->trigger_id);
5880 }
5881
5882 IF_META_AVAILABLE(int32_t, whiteBalance, CAM_INTF_PARM_WHITE_BALANCE, metadata) {
5883 int val = lookupFwkName(WHITE_BALANCE_MODES_MAP,
5884 METADATA_MAP_SIZE(WHITE_BALANCE_MODES_MAP), *whiteBalance);
5885 if (NAME_NOT_FOUND != val) {
5886 uint8_t fwkWhiteBalanceMode = (uint8_t)val;
5887 camMetadata.update(ANDROID_CONTROL_AWB_MODE, &fwkWhiteBalanceMode, 1);
5888 LOGD("urgent Metadata : ANDROID_CONTROL_AWB_MODE %d", val);
5889 } else {
5890 LOGH("urgent Metadata not found : ANDROID_CONTROL_AWB_MODE");
5891 }
5892 }
5893
5894 uint8_t fwk_aeMode = ANDROID_CONTROL_AE_MODE_OFF;
5895 uint32_t aeMode = CAM_AE_MODE_MAX;
5896 int32_t flashMode = CAM_FLASH_MODE_MAX;
5897 int32_t redeye = -1;
5898 IF_META_AVAILABLE(uint32_t, pAeMode, CAM_INTF_META_AEC_MODE, metadata) {
5899 aeMode = *pAeMode;
5900 }
5901 IF_META_AVAILABLE(int32_t, pFlashMode, CAM_INTF_PARM_LED_MODE, metadata) {
5902 flashMode = *pFlashMode;
5903 }
5904 IF_META_AVAILABLE(int32_t, pRedeye, CAM_INTF_PARM_REDEYE_REDUCTION, metadata) {
5905 redeye = *pRedeye;
5906 }
5907
5908 if (1 == redeye) {
5909 fwk_aeMode = ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE;
5910 camMetadata.update(ANDROID_CONTROL_AE_MODE, &fwk_aeMode, 1);
5911 } else if ((CAM_FLASH_MODE_AUTO == flashMode) || (CAM_FLASH_MODE_ON == flashMode)) {
5912 int val = lookupFwkName(AE_FLASH_MODE_MAP, METADATA_MAP_SIZE(AE_FLASH_MODE_MAP),
5913 flashMode);
5914 if (NAME_NOT_FOUND != val) {
5915 fwk_aeMode = (uint8_t)val;
5916 camMetadata.update(ANDROID_CONTROL_AE_MODE, &fwk_aeMode, 1);
5917 } else {
5918 LOGE("Unsupported flash mode %d", flashMode);
5919 }
5920 } else if (aeMode == CAM_AE_MODE_ON) {
5921 fwk_aeMode = ANDROID_CONTROL_AE_MODE_ON;
5922 camMetadata.update(ANDROID_CONTROL_AE_MODE, &fwk_aeMode, 1);
5923 } else if (aeMode == CAM_AE_MODE_OFF) {
5924 fwk_aeMode = ANDROID_CONTROL_AE_MODE_OFF;
5925 camMetadata.update(ANDROID_CONTROL_AE_MODE, &fwk_aeMode, 1);
5926 } else {
5927 LOGE("Not enough info to deduce ANDROID_CONTROL_AE_MODE redeye:%d, "
5928 "flashMode:%d, aeMode:%u!!!",
5929 redeye, flashMode, aeMode);
5930 }
5931
5932 resultMetadata = camMetadata.release();
5933 return resultMetadata;
5934}
5935
5936/*===========================================================================
5937 * FUNCTION : dumpMetadataToFile
5938 *
5939 * DESCRIPTION: Dumps tuning metadata to file system
5940 *
5941 * PARAMETERS :
5942 * @meta : tuning metadata
5943 * @dumpFrameCount : current dump frame count
5944 * @enabled : Enable mask
5945 *
5946 *==========================================================================*/
5947void QCamera3HardwareInterface::dumpMetadataToFile(tuning_params_t &meta,
5948 uint32_t &dumpFrameCount,
5949 bool enabled,
5950 const char *type,
5951 uint32_t frameNumber)
5952{
5953 //Some sanity checks
5954 if (meta.tuning_sensor_data_size > TUNING_SENSOR_DATA_MAX) {
5955 LOGE("Tuning sensor data size bigger than expected %d: %d",
5956 meta.tuning_sensor_data_size,
5957 TUNING_SENSOR_DATA_MAX);
5958 return;
5959 }
5960
5961 if (meta.tuning_vfe_data_size > TUNING_VFE_DATA_MAX) {
5962 LOGE("Tuning VFE data size bigger than expected %d: %d",
5963 meta.tuning_vfe_data_size,
5964 TUNING_VFE_DATA_MAX);
5965 return;
5966 }
5967
5968 if (meta.tuning_cpp_data_size > TUNING_CPP_DATA_MAX) {
5969 LOGE("Tuning CPP data size bigger than expected %d: %d",
5970 meta.tuning_cpp_data_size,
5971 TUNING_CPP_DATA_MAX);
5972 return;
5973 }
5974
5975 if (meta.tuning_cac_data_size > TUNING_CAC_DATA_MAX) {
5976 LOGE("Tuning CAC data size bigger than expected %d: %d",
5977 meta.tuning_cac_data_size,
5978 TUNING_CAC_DATA_MAX);
5979 return;
5980 }
5981 //
5982
5983 if(enabled){
5984 char timeBuf[FILENAME_MAX];
5985 char buf[FILENAME_MAX];
5986 memset(buf, 0, sizeof(buf));
5987 memset(timeBuf, 0, sizeof(timeBuf));
5988 time_t current_time;
5989 struct tm * timeinfo;
5990 time (&current_time);
5991 timeinfo = localtime (&current_time);
5992 if (timeinfo != NULL) {
5993 strftime (timeBuf, sizeof(timeBuf),
5994 QCAMERA_DUMP_FRM_LOCATION"%Y%m%d%H%M%S", timeinfo);
5995 }
5996 String8 filePath(timeBuf);
5997 snprintf(buf,
5998 sizeof(buf),
5999 "%dm_%s_%d.bin",
6000 dumpFrameCount,
6001 type,
6002 frameNumber);
6003 filePath.append(buf);
6004 int file_fd = open(filePath.string(), O_RDWR | O_CREAT, 0777);
6005 if (file_fd >= 0) {
6006 ssize_t written_len = 0;
6007 meta.tuning_data_version = TUNING_DATA_VERSION;
6008 void *data = (void *)((uint8_t *)&meta.tuning_data_version);
6009 written_len += write(file_fd, data, sizeof(uint32_t));
6010 data = (void *)((uint8_t *)&meta.tuning_sensor_data_size);
6011 LOGD("tuning_sensor_data_size %d",(int)(*(int *)data));
6012 written_len += write(file_fd, data, sizeof(uint32_t));
6013 data = (void *)((uint8_t *)&meta.tuning_vfe_data_size);
6014 LOGD("tuning_vfe_data_size %d",(int)(*(int *)data));
6015 written_len += write(file_fd, data, sizeof(uint32_t));
6016 data = (void *)((uint8_t *)&meta.tuning_cpp_data_size);
6017 LOGD("tuning_cpp_data_size %d",(int)(*(int *)data));
6018 written_len += write(file_fd, data, sizeof(uint32_t));
6019 data = (void *)((uint8_t *)&meta.tuning_cac_data_size);
6020 LOGD("tuning_cac_data_size %d",(int)(*(int *)data));
6021 written_len += write(file_fd, data, sizeof(uint32_t));
6022 meta.tuning_mod3_data_size = 0;
6023 data = (void *)((uint8_t *)&meta.tuning_mod3_data_size);
6024 LOGD("tuning_mod3_data_size %d",(int)(*(int *)data));
6025 written_len += write(file_fd, data, sizeof(uint32_t));
6026 size_t total_size = meta.tuning_sensor_data_size;
6027 data = (void *)((uint8_t *)&meta.data);
6028 written_len += write(file_fd, data, total_size);
6029 total_size = meta.tuning_vfe_data_size;
6030 data = (void *)((uint8_t *)&meta.data[TUNING_VFE_DATA_OFFSET]);
6031 written_len += write(file_fd, data, total_size);
6032 total_size = meta.tuning_cpp_data_size;
6033 data = (void *)((uint8_t *)&meta.data[TUNING_CPP_DATA_OFFSET]);
6034 written_len += write(file_fd, data, total_size);
6035 total_size = meta.tuning_cac_data_size;
6036 data = (void *)((uint8_t *)&meta.data[TUNING_CAC_DATA_OFFSET]);
6037 written_len += write(file_fd, data, total_size);
6038 close(file_fd);
6039 }else {
6040 LOGE("fail to open file for metadata dumping");
6041 }
6042 }
6043}
6044
6045/*===========================================================================
6046 * FUNCTION : cleanAndSortStreamInfo
6047 *
6048 * DESCRIPTION: helper method to clean up invalid streams in stream_info,
6049 * and sort them such that raw stream is at the end of the list
6050 * This is a workaround for camera daemon constraint.
6051 *
6052 * PARAMETERS : None
6053 *
6054 *==========================================================================*/
6055void QCamera3HardwareInterface::cleanAndSortStreamInfo()
6056{
6057 List<stream_info_t *> newStreamInfo;
6058
6059 /*clean up invalid streams*/
6060 for (List<stream_info_t*>::iterator it=mStreamInfo.begin();
6061 it != mStreamInfo.end();) {
6062 if(((*it)->status) == INVALID){
6063 QCamera3Channel *channel = (QCamera3Channel*)(*it)->stream->priv;
6064 delete channel;
6065 free(*it);
6066 it = mStreamInfo.erase(it);
6067 } else {
6068 it++;
6069 }
6070 }
6071
6072 // Move preview/video/callback/snapshot streams into newList
6073 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
6074 it != mStreamInfo.end();) {
6075 if ((*it)->stream->format != HAL_PIXEL_FORMAT_RAW_OPAQUE &&
6076 (*it)->stream->format != HAL_PIXEL_FORMAT_RAW10 &&
6077 (*it)->stream->format != HAL_PIXEL_FORMAT_RAW16) {
6078 newStreamInfo.push_back(*it);
6079 it = mStreamInfo.erase(it);
6080 } else
6081 it++;
6082 }
6083 // Move raw streams into newList
6084 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
6085 it != mStreamInfo.end();) {
6086 newStreamInfo.push_back(*it);
6087 it = mStreamInfo.erase(it);
6088 }
6089
6090 mStreamInfo = newStreamInfo;
6091}
6092
6093/*===========================================================================
6094 * FUNCTION : extractJpegMetadata
6095 *
6096 * DESCRIPTION: helper method to extract Jpeg metadata from capture request.
6097 * JPEG metadata is cached in HAL, and return as part of capture
6098 * result when metadata is returned from camera daemon.
6099 *
6100 * PARAMETERS : @jpegMetadata: jpeg metadata to be extracted
6101 * @request: capture request
6102 *
6103 *==========================================================================*/
6104void QCamera3HardwareInterface::extractJpegMetadata(
6105 CameraMetadata& jpegMetadata,
6106 const camera3_capture_request_t *request)
6107{
6108 CameraMetadata frame_settings;
6109 frame_settings = request->settings;
6110
6111 if (frame_settings.exists(ANDROID_JPEG_GPS_COORDINATES))
6112 jpegMetadata.update(ANDROID_JPEG_GPS_COORDINATES,
6113 frame_settings.find(ANDROID_JPEG_GPS_COORDINATES).data.d,
6114 frame_settings.find(ANDROID_JPEG_GPS_COORDINATES).count);
6115
6116 if (frame_settings.exists(ANDROID_JPEG_GPS_PROCESSING_METHOD))
6117 jpegMetadata.update(ANDROID_JPEG_GPS_PROCESSING_METHOD,
6118 frame_settings.find(ANDROID_JPEG_GPS_PROCESSING_METHOD).data.u8,
6119 frame_settings.find(ANDROID_JPEG_GPS_PROCESSING_METHOD).count);
6120
6121 if (frame_settings.exists(ANDROID_JPEG_GPS_TIMESTAMP))
6122 jpegMetadata.update(ANDROID_JPEG_GPS_TIMESTAMP,
6123 frame_settings.find(ANDROID_JPEG_GPS_TIMESTAMP).data.i64,
6124 frame_settings.find(ANDROID_JPEG_GPS_TIMESTAMP).count);
6125
6126 if (frame_settings.exists(ANDROID_JPEG_ORIENTATION))
6127 jpegMetadata.update(ANDROID_JPEG_ORIENTATION,
6128 frame_settings.find(ANDROID_JPEG_ORIENTATION).data.i32,
6129 frame_settings.find(ANDROID_JPEG_ORIENTATION).count);
6130
6131 if (frame_settings.exists(ANDROID_JPEG_QUALITY))
6132 jpegMetadata.update(ANDROID_JPEG_QUALITY,
6133 frame_settings.find(ANDROID_JPEG_QUALITY).data.u8,
6134 frame_settings.find(ANDROID_JPEG_QUALITY).count);
6135
6136 if (frame_settings.exists(ANDROID_JPEG_THUMBNAIL_QUALITY))
6137 jpegMetadata.update(ANDROID_JPEG_THUMBNAIL_QUALITY,
6138 frame_settings.find(ANDROID_JPEG_THUMBNAIL_QUALITY).data.u8,
6139 frame_settings.find(ANDROID_JPEG_THUMBNAIL_QUALITY).count);
6140
6141 if (frame_settings.exists(ANDROID_JPEG_THUMBNAIL_SIZE)) {
6142 int32_t thumbnail_size[2];
6143 thumbnail_size[0] = frame_settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[0];
6144 thumbnail_size[1] = frame_settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[1];
6145 if (frame_settings.exists(ANDROID_JPEG_ORIENTATION)) {
6146 int32_t orientation =
6147 frame_settings.find(ANDROID_JPEG_ORIENTATION).data.i32[0];
Thierry Strudel9e74aae2016-09-22 17:10:18 -07006148 if ((!needJpegExifRotation()) && ((orientation == 90) || (orientation == 270))) {
Thierry Strudel3d639192016-09-09 11:52:26 -07006149 //swap thumbnail dimensions for rotations 90 and 270 in jpeg metadata.
6150 int32_t temp;
6151 temp = thumbnail_size[0];
6152 thumbnail_size[0] = thumbnail_size[1];
6153 thumbnail_size[1] = temp;
6154 }
6155 }
6156 jpegMetadata.update(ANDROID_JPEG_THUMBNAIL_SIZE,
6157 thumbnail_size,
6158 frame_settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).count);
6159 }
6160
6161}
6162
6163/*===========================================================================
6164 * FUNCTION : convertToRegions
6165 *
6166 * DESCRIPTION: helper method to convert from cam_rect_t into int32_t array
6167 *
6168 * PARAMETERS :
6169 * @rect : cam_rect_t struct to convert
6170 * @region : int32_t destination array
6171 * @weight : if we are converting from cam_area_t, weight is valid
6172 * else weight = -1
6173 *
6174 *==========================================================================*/
6175void QCamera3HardwareInterface::convertToRegions(cam_rect_t rect,
6176 int32_t *region, int weight)
6177{
6178 region[0] = rect.left;
6179 region[1] = rect.top;
6180 region[2] = rect.left + rect.width;
6181 region[3] = rect.top + rect.height;
6182 if (weight > -1) {
6183 region[4] = weight;
6184 }
6185}
6186
6187/*===========================================================================
6188 * FUNCTION : convertFromRegions
6189 *
6190 * DESCRIPTION: helper method to convert from array to cam_rect_t
6191 *
6192 * PARAMETERS :
6193 * @rect : cam_rect_t struct to convert
6194 * @region : int32_t destination array
6195 * @weight : if we are converting from cam_area_t, weight is valid
6196 * else weight = -1
6197 *
6198 *==========================================================================*/
6199void QCamera3HardwareInterface::convertFromRegions(cam_area_t &roi,
6200 const camera_metadata_t *settings, uint32_t tag)
6201{
6202 CameraMetadata frame_settings;
6203 frame_settings = settings;
6204 int32_t x_min = frame_settings.find(tag).data.i32[0];
6205 int32_t y_min = frame_settings.find(tag).data.i32[1];
6206 int32_t x_max = frame_settings.find(tag).data.i32[2];
6207 int32_t y_max = frame_settings.find(tag).data.i32[3];
6208 roi.weight = frame_settings.find(tag).data.i32[4];
6209 roi.rect.left = x_min;
6210 roi.rect.top = y_min;
6211 roi.rect.width = x_max - x_min;
6212 roi.rect.height = y_max - y_min;
6213}
6214
6215/*===========================================================================
6216 * FUNCTION : resetIfNeededROI
6217 *
6218 * DESCRIPTION: helper method to reset the roi if it is greater than scaler
6219 * crop region
6220 *
6221 * PARAMETERS :
6222 * @roi : cam_area_t struct to resize
6223 * @scalerCropRegion : cam_crop_region_t region to compare against
6224 *
6225 *
6226 *==========================================================================*/
6227bool QCamera3HardwareInterface::resetIfNeededROI(cam_area_t* roi,
6228 const cam_crop_region_t* scalerCropRegion)
6229{
6230 int32_t roi_x_max = roi->rect.width + roi->rect.left;
6231 int32_t roi_y_max = roi->rect.height + roi->rect.top;
6232 int32_t crop_x_max = scalerCropRegion->width + scalerCropRegion->left;
6233 int32_t crop_y_max = scalerCropRegion->height + scalerCropRegion->top;
6234
6235 /* According to spec weight = 0 is used to indicate roi needs to be disabled
6236 * without having this check the calculations below to validate if the roi
6237 * is inside scalar crop region will fail resulting in the roi not being
6238 * reset causing algorithm to continue to use stale roi window
6239 */
6240 if (roi->weight == 0) {
6241 return true;
6242 }
6243
6244 if ((roi_x_max < scalerCropRegion->left) ||
6245 // right edge of roi window is left of scalar crop's left edge
6246 (roi_y_max < scalerCropRegion->top) ||
6247 // bottom edge of roi window is above scalar crop's top edge
6248 (roi->rect.left > crop_x_max) ||
6249 // left edge of roi window is beyond(right) of scalar crop's right edge
6250 (roi->rect.top > crop_y_max)){
6251 // top edge of roi windo is above scalar crop's top edge
6252 return false;
6253 }
6254 if (roi->rect.left < scalerCropRegion->left) {
6255 roi->rect.left = scalerCropRegion->left;
6256 }
6257 if (roi->rect.top < scalerCropRegion->top) {
6258 roi->rect.top = scalerCropRegion->top;
6259 }
6260 if (roi_x_max > crop_x_max) {
6261 roi_x_max = crop_x_max;
6262 }
6263 if (roi_y_max > crop_y_max) {
6264 roi_y_max = crop_y_max;
6265 }
6266 roi->rect.width = roi_x_max - roi->rect.left;
6267 roi->rect.height = roi_y_max - roi->rect.top;
6268 return true;
6269}
6270
6271/*===========================================================================
6272 * FUNCTION : convertLandmarks
6273 *
6274 * DESCRIPTION: helper method to extract the landmarks from face detection info
6275 *
6276 * PARAMETERS :
6277 * @landmark_data : input landmark data to be converted
6278 * @landmarks : int32_t destination array
6279 *
6280 *
6281 *==========================================================================*/
6282void QCamera3HardwareInterface::convertLandmarks(
6283 cam_face_landmarks_info_t landmark_data,
6284 int32_t *landmarks)
6285{
6286 landmarks[0] = (int32_t)landmark_data.left_eye_center.x;
6287 landmarks[1] = (int32_t)landmark_data.left_eye_center.y;
6288 landmarks[2] = (int32_t)landmark_data.right_eye_center.x;
6289 landmarks[3] = (int32_t)landmark_data.right_eye_center.y;
6290 landmarks[4] = (int32_t)landmark_data.mouth_center.x;
6291 landmarks[5] = (int32_t)landmark_data.mouth_center.y;
6292}
6293
6294#define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX )
6295/*===========================================================================
6296 * FUNCTION : initCapabilities
6297 *
6298 * DESCRIPTION: initialize camera capabilities in static data struct
6299 *
6300 * PARAMETERS :
6301 * @cameraId : camera Id
6302 *
6303 * RETURN : int32_t type of status
6304 * NO_ERROR -- success
6305 * none-zero failure code
6306 *==========================================================================*/
6307int QCamera3HardwareInterface::initCapabilities(uint32_t cameraId)
6308{
6309 int rc = 0;
6310 mm_camera_vtbl_t *cameraHandle = NULL;
6311 QCamera3HeapMemory *capabilityHeap = NULL;
6312
6313 rc = camera_open((uint8_t)cameraId, &cameraHandle);
6314 if (rc) {
6315 LOGE("camera_open failed. rc = %d", rc);
6316 goto open_failed;
6317 }
6318 if (!cameraHandle) {
6319 LOGE("camera_open failed. cameraHandle = %p", cameraHandle);
6320 goto open_failed;
6321 }
6322
6323 capabilityHeap = new QCamera3HeapMemory(1);
6324 if (capabilityHeap == NULL) {
6325 LOGE("creation of capabilityHeap failed");
6326 goto heap_creation_failed;
6327 }
6328 /* Allocate memory for capability buffer */
6329 rc = capabilityHeap->allocate(sizeof(cam_capability_t));
6330 if(rc != OK) {
6331 LOGE("No memory for cappability");
6332 goto allocate_failed;
6333 }
6334
6335 /* Map memory for capability buffer */
6336 memset(DATA_PTR(capabilityHeap,0), 0, sizeof(cam_capability_t));
6337 rc = cameraHandle->ops->map_buf(cameraHandle->camera_handle,
6338 CAM_MAPPING_BUF_TYPE_CAPABILITY,
6339 capabilityHeap->getFd(0),
6340 sizeof(cam_capability_t),
6341 capabilityHeap->getPtr(0));
6342 if(rc < 0) {
6343 LOGE("failed to map capability buffer");
6344 goto map_failed;
6345 }
6346
6347 /* Query Capability */
6348 rc = cameraHandle->ops->query_capability(cameraHandle->camera_handle);
6349 if(rc < 0) {
6350 LOGE("failed to query capability");
6351 goto query_failed;
6352 }
6353 gCamCapability[cameraId] = (cam_capability_t *)malloc(sizeof(cam_capability_t));
6354 if (!gCamCapability[cameraId]) {
6355 LOGE("out of memory");
6356 goto query_failed;
6357 }
6358 memcpy(gCamCapability[cameraId], DATA_PTR(capabilityHeap,0),
6359 sizeof(cam_capability_t));
6360
6361 int index;
6362 for (index = 0; index < CAM_ANALYSIS_INFO_MAX; index++) {
6363 cam_analysis_info_t *p_analysis_info =
6364 &gCamCapability[cameraId]->analysis_info[index];
6365 p_analysis_info->analysis_padding_info.offset_info.offset_x = 0;
6366 p_analysis_info->analysis_padding_info.offset_info.offset_y = 0;
6367 }
6368 rc = 0;
6369
6370query_failed:
6371 cameraHandle->ops->unmap_buf(cameraHandle->camera_handle,
6372 CAM_MAPPING_BUF_TYPE_CAPABILITY);
6373map_failed:
6374 capabilityHeap->deallocate();
6375allocate_failed:
6376 delete capabilityHeap;
6377heap_creation_failed:
6378 cameraHandle->ops->close_camera(cameraHandle->camera_handle);
6379 cameraHandle = NULL;
6380open_failed:
6381 return rc;
6382}
6383
6384/*==========================================================================
6385 * FUNCTION : get3Aversion
6386 *
6387 * DESCRIPTION: get the Q3A S/W version
6388 *
6389 * PARAMETERS :
6390 * @sw_version: Reference of Q3A structure which will hold version info upon
6391 * return
6392 *
6393 * RETURN : None
6394 *
6395 *==========================================================================*/
6396void QCamera3HardwareInterface::get3AVersion(cam_q3a_version_t &sw_version)
6397{
6398 if(gCamCapability[mCameraId])
6399 sw_version = gCamCapability[mCameraId]->q3a_version;
6400 else
6401 LOGE("Capability structure NULL!");
6402}
6403
6404
6405/*===========================================================================
6406 * FUNCTION : initParameters
6407 *
6408 * DESCRIPTION: initialize camera parameters
6409 *
6410 * PARAMETERS :
6411 *
6412 * RETURN : int32_t type of status
6413 * NO_ERROR -- success
6414 * none-zero failure code
6415 *==========================================================================*/
6416int QCamera3HardwareInterface::initParameters()
6417{
6418 int rc = 0;
6419
6420 //Allocate Set Param Buffer
6421 mParamHeap = new QCamera3HeapMemory(1);
6422 rc = mParamHeap->allocate(sizeof(metadata_buffer_t));
6423 if(rc != OK) {
6424 rc = NO_MEMORY;
6425 LOGE("Failed to allocate SETPARM Heap memory");
6426 delete mParamHeap;
6427 mParamHeap = NULL;
6428 return rc;
6429 }
6430
6431 //Map memory for parameters buffer
6432 rc = mCameraHandle->ops->map_buf(mCameraHandle->camera_handle,
6433 CAM_MAPPING_BUF_TYPE_PARM_BUF,
6434 mParamHeap->getFd(0),
6435 sizeof(metadata_buffer_t),
6436 (metadata_buffer_t *) DATA_PTR(mParamHeap,0));
6437 if(rc < 0) {
6438 LOGE("failed to map SETPARM buffer");
6439 rc = FAILED_TRANSACTION;
6440 mParamHeap->deallocate();
6441 delete mParamHeap;
6442 mParamHeap = NULL;
6443 return rc;
6444 }
6445
6446 mParameters = (metadata_buffer_t *) DATA_PTR(mParamHeap,0);
6447
6448 mPrevParameters = (metadata_buffer_t *)malloc(sizeof(metadata_buffer_t));
6449 return rc;
6450}
6451
6452/*===========================================================================
6453 * FUNCTION : deinitParameters
6454 *
6455 * DESCRIPTION: de-initialize camera parameters
6456 *
6457 * PARAMETERS :
6458 *
6459 * RETURN : NONE
6460 *==========================================================================*/
6461void QCamera3HardwareInterface::deinitParameters()
6462{
6463 mCameraHandle->ops->unmap_buf(mCameraHandle->camera_handle,
6464 CAM_MAPPING_BUF_TYPE_PARM_BUF);
6465
6466 mParamHeap->deallocate();
6467 delete mParamHeap;
6468 mParamHeap = NULL;
6469
6470 mParameters = NULL;
6471
6472 free(mPrevParameters);
6473 mPrevParameters = NULL;
6474}
6475
6476/*===========================================================================
6477 * FUNCTION : calcMaxJpegSize
6478 *
6479 * DESCRIPTION: Calculates maximum jpeg size supported by the cameraId
6480 *
6481 * PARAMETERS :
6482 *
6483 * RETURN : max_jpeg_size
6484 *==========================================================================*/
6485size_t QCamera3HardwareInterface::calcMaxJpegSize(uint32_t camera_id)
6486{
6487 size_t max_jpeg_size = 0;
6488 size_t temp_width, temp_height;
6489 size_t count = MIN(gCamCapability[camera_id]->picture_sizes_tbl_cnt,
6490 MAX_SIZES_CNT);
6491 for (size_t i = 0; i < count; i++) {
6492 temp_width = (size_t)gCamCapability[camera_id]->picture_sizes_tbl[i].width;
6493 temp_height = (size_t)gCamCapability[camera_id]->picture_sizes_tbl[i].height;
6494 if (temp_width * temp_height > max_jpeg_size ) {
6495 max_jpeg_size = temp_width * temp_height;
6496 }
6497 }
6498 max_jpeg_size = max_jpeg_size * 3/2 + sizeof(camera3_jpeg_blob_t);
6499 return max_jpeg_size;
6500}
6501
6502/*===========================================================================
6503 * FUNCTION : getMaxRawSize
6504 *
6505 * DESCRIPTION: Fetches maximum raw size supported by the cameraId
6506 *
6507 * PARAMETERS :
6508 *
6509 * RETURN : Largest supported Raw Dimension
6510 *==========================================================================*/
6511cam_dimension_t QCamera3HardwareInterface::getMaxRawSize(uint32_t camera_id)
6512{
6513 int max_width = 0;
6514 cam_dimension_t maxRawSize;
6515
6516 memset(&maxRawSize, 0, sizeof(cam_dimension_t));
6517 for (size_t i = 0; i < gCamCapability[camera_id]->supported_raw_dim_cnt; i++) {
6518 if (max_width < gCamCapability[camera_id]->raw_dim[i].width) {
6519 max_width = gCamCapability[camera_id]->raw_dim[i].width;
6520 maxRawSize = gCamCapability[camera_id]->raw_dim[i];
6521 }
6522 }
6523 return maxRawSize;
6524}
6525
6526
6527/*===========================================================================
6528 * FUNCTION : calcMaxJpegDim
6529 *
6530 * DESCRIPTION: Calculates maximum jpeg dimension supported by the cameraId
6531 *
6532 * PARAMETERS :
6533 *
6534 * RETURN : max_jpeg_dim
6535 *==========================================================================*/
6536cam_dimension_t QCamera3HardwareInterface::calcMaxJpegDim()
6537{
6538 cam_dimension_t max_jpeg_dim;
6539 cam_dimension_t curr_jpeg_dim;
6540 max_jpeg_dim.width = 0;
6541 max_jpeg_dim.height = 0;
6542 curr_jpeg_dim.width = 0;
6543 curr_jpeg_dim.height = 0;
6544 for (size_t i = 0; i < gCamCapability[mCameraId]->picture_sizes_tbl_cnt; i++) {
6545 curr_jpeg_dim.width = gCamCapability[mCameraId]->picture_sizes_tbl[i].width;
6546 curr_jpeg_dim.height = gCamCapability[mCameraId]->picture_sizes_tbl[i].height;
6547 if (curr_jpeg_dim.width * curr_jpeg_dim.height >
6548 max_jpeg_dim.width * max_jpeg_dim.height ) {
6549 max_jpeg_dim.width = curr_jpeg_dim.width;
6550 max_jpeg_dim.height = curr_jpeg_dim.height;
6551 }
6552 }
6553 return max_jpeg_dim;
6554}
6555
6556/*===========================================================================
6557 * FUNCTION : addStreamConfig
6558 *
6559 * DESCRIPTION: adds the stream configuration to the array
6560 *
6561 * PARAMETERS :
6562 * @available_stream_configs : pointer to stream configuration array
6563 * @scalar_format : scalar format
6564 * @dim : configuration dimension
6565 * @config_type : input or output configuration type
6566 *
6567 * RETURN : NONE
6568 *==========================================================================*/
6569void QCamera3HardwareInterface::addStreamConfig(Vector<int32_t> &available_stream_configs,
6570 int32_t scalar_format, const cam_dimension_t &dim, int32_t config_type)
6571{
6572 available_stream_configs.add(scalar_format);
6573 available_stream_configs.add(dim.width);
6574 available_stream_configs.add(dim.height);
6575 available_stream_configs.add(config_type);
6576}
6577
6578/*===========================================================================
6579 * FUNCTION : suppportBurstCapture
6580 *
6581 * DESCRIPTION: Whether a particular camera supports BURST_CAPTURE
6582 *
6583 * PARAMETERS :
6584 * @cameraId : camera Id
6585 *
6586 * RETURN : true if camera supports BURST_CAPTURE
6587 * false otherwise
6588 *==========================================================================*/
6589bool QCamera3HardwareInterface::supportBurstCapture(uint32_t cameraId)
6590{
6591 const int64_t highResDurationBound = 50000000; // 50 ms, 20 fps
6592 const int64_t fullResDurationBound = 100000000; // 100 ms, 10 fps
6593 const int32_t highResWidth = 3264;
6594 const int32_t highResHeight = 2448;
6595
6596 if (gCamCapability[cameraId]->picture_min_duration[0] > fullResDurationBound) {
6597 // Maximum resolution images cannot be captured at >= 10fps
6598 // -> not supporting BURST_CAPTURE
6599 return false;
6600 }
6601
6602 if (gCamCapability[cameraId]->picture_min_duration[0] <= highResDurationBound) {
6603 // Maximum resolution images can be captured at >= 20fps
6604 // --> supporting BURST_CAPTURE
6605 return true;
6606 }
6607
6608 // Find the smallest highRes resolution, or largest resolution if there is none
6609 size_t totalCnt = MIN(gCamCapability[cameraId]->picture_sizes_tbl_cnt,
6610 MAX_SIZES_CNT);
6611 size_t highRes = 0;
6612 while ((highRes + 1 < totalCnt) &&
6613 (gCamCapability[cameraId]->picture_sizes_tbl[highRes+1].width *
6614 gCamCapability[cameraId]->picture_sizes_tbl[highRes+1].height >=
6615 highResWidth * highResHeight)) {
6616 highRes++;
6617 }
6618 if (gCamCapability[cameraId]->picture_min_duration[highRes] <= highResDurationBound) {
6619 return true;
6620 } else {
6621 return false;
6622 }
6623}
6624
6625/*===========================================================================
6626 * FUNCTION : initStaticMetadata
6627 *
6628 * DESCRIPTION: initialize the static metadata
6629 *
6630 * PARAMETERS :
6631 * @cameraId : camera Id
6632 *
6633 * RETURN : int32_t type of status
6634 * 0 -- success
6635 * non-zero failure code
6636 *==========================================================================*/
6637int QCamera3HardwareInterface::initStaticMetadata(uint32_t cameraId)
6638{
6639 int rc = 0;
6640 CameraMetadata staticInfo;
6641 size_t count = 0;
6642 bool limitedDevice = false;
6643 char prop[PROPERTY_VALUE_MAX];
6644 bool supportBurst = false;
6645
6646 supportBurst = supportBurstCapture(cameraId);
6647
6648 /* If sensor is YUV sensor (no raw support) or if per-frame control is not
6649 * guaranteed or if min fps of max resolution is less than 20 fps, its
6650 * advertised as limited device*/
6651 limitedDevice = gCamCapability[cameraId]->no_per_frame_control_support ||
6652 (CAM_SENSOR_YUV == gCamCapability[cameraId]->sensor_type.sens_type) ||
6653 (CAM_SENSOR_MONO == gCamCapability[cameraId]->sensor_type.sens_type) ||
6654 !supportBurst;
6655
6656 uint8_t supportedHwLvl = limitedDevice ?
6657 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED :
Thierry Strudel9e74aae2016-09-22 17:10:18 -07006658#ifndef USE_HAL_3_3
6659 // LEVEL_3 - This device will support level 3.
6660 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_3;
6661#else
Thierry Strudel3d639192016-09-09 11:52:26 -07006662 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL;
Thierry Strudel9e74aae2016-09-22 17:10:18 -07006663#endif
Thierry Strudel3d639192016-09-09 11:52:26 -07006664
6665 staticInfo.update(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
6666 &supportedHwLvl, 1);
6667
6668 bool facingBack = false;
6669 if ((gCamCapability[cameraId]->position == CAM_POSITION_BACK) ||
6670 (gCamCapability[cameraId]->position == CAM_POSITION_BACK_AUX)) {
6671 facingBack = true;
6672 }
6673 /*HAL 3 only*/
6674 staticInfo.update(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
6675 &gCamCapability[cameraId]->min_focus_distance, 1);
6676
6677 staticInfo.update(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
6678 &gCamCapability[cameraId]->hyper_focal_distance, 1);
6679
6680 /*should be using focal lengths but sensor doesn't provide that info now*/
6681 staticInfo.update(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
6682 &gCamCapability[cameraId]->focal_length,
6683 1);
6684
6685 staticInfo.update(ANDROID_LENS_INFO_AVAILABLE_APERTURES,
6686 gCamCapability[cameraId]->apertures,
6687 MIN(CAM_APERTURES_MAX, gCamCapability[cameraId]->apertures_count));
6688
6689 staticInfo.update(ANDROID_LENS_INFO_AVAILABLE_FILTER_DENSITIES,
6690 gCamCapability[cameraId]->filter_densities,
6691 MIN(CAM_FILTER_DENSITIES_MAX, gCamCapability[cameraId]->filter_densities_count));
6692
6693
6694 staticInfo.update(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
6695 (uint8_t *)gCamCapability[cameraId]->optical_stab_modes,
6696 MIN((size_t)CAM_OPT_STAB_MAX, gCamCapability[cameraId]->optical_stab_modes_count));
6697
6698 int32_t lens_shading_map_size[] = {
6699 MIN(CAM_MAX_SHADING_MAP_WIDTH, gCamCapability[cameraId]->lens_shading_map_size.width),
6700 MIN(CAM_MAX_SHADING_MAP_HEIGHT, gCamCapability[cameraId]->lens_shading_map_size.height)};
6701 staticInfo.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE,
6702 lens_shading_map_size,
6703 sizeof(lens_shading_map_size)/sizeof(int32_t));
6704
6705 staticInfo.update(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
6706 gCamCapability[cameraId]->sensor_physical_size, SENSOR_PHYSICAL_SIZE_CNT);
6707
6708 staticInfo.update(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
6709 gCamCapability[cameraId]->exposure_time_range, EXPOSURE_TIME_RANGE_CNT);
6710
6711 staticInfo.update(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
6712 &gCamCapability[cameraId]->max_frame_duration, 1);
6713
6714 camera_metadata_rational baseGainFactor = {
6715 gCamCapability[cameraId]->base_gain_factor.numerator,
6716 gCamCapability[cameraId]->base_gain_factor.denominator};
6717 staticInfo.update(ANDROID_SENSOR_BASE_GAIN_FACTOR,
6718 &baseGainFactor, 1);
6719
6720 staticInfo.update(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
6721 (uint8_t *)&gCamCapability[cameraId]->color_arrangement, 1);
6722
6723 int32_t pixel_array_size[] = {gCamCapability[cameraId]->pixel_array_size.width,
6724 gCamCapability[cameraId]->pixel_array_size.height};
6725 staticInfo.update(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
6726 pixel_array_size, sizeof(pixel_array_size)/sizeof(pixel_array_size[0]));
6727
6728 int32_t active_array_size[] = {gCamCapability[cameraId]->active_array_size.left,
6729 gCamCapability[cameraId]->active_array_size.top,
6730 gCamCapability[cameraId]->active_array_size.width,
6731 gCamCapability[cameraId]->active_array_size.height};
6732 staticInfo.update(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
6733 active_array_size, sizeof(active_array_size)/sizeof(active_array_size[0]));
6734
6735 staticInfo.update(ANDROID_SENSOR_INFO_WHITE_LEVEL,
6736 &gCamCapability[cameraId]->white_level, 1);
6737
6738 staticInfo.update(ANDROID_SENSOR_BLACK_LEVEL_PATTERN,
6739 gCamCapability[cameraId]->black_level_pattern, BLACK_LEVEL_PATTERN_CNT);
6740
Thierry Strudel9e74aae2016-09-22 17:10:18 -07006741#ifndef USE_HAL_3_3
6742 bool hasBlackRegions = false;
6743 if (gCamCapability[cameraId]->optical_black_region_count > MAX_OPTICAL_BLACK_REGIONS) {
6744 LOGW("black_region_count: %d is bounded to %d",
6745 gCamCapability[cameraId]->optical_black_region_count, MAX_OPTICAL_BLACK_REGIONS);
6746 gCamCapability[cameraId]->optical_black_region_count = MAX_OPTICAL_BLACK_REGIONS;
6747 }
6748 if (gCamCapability[cameraId]->optical_black_region_count != 0) {
6749 int32_t opticalBlackRegions[MAX_OPTICAL_BLACK_REGIONS * 4];
6750 for (size_t i = 0; i < gCamCapability[cameraId]->optical_black_region_count * 4; i++) {
6751 opticalBlackRegions[i] = gCamCapability[cameraId]->optical_black_regions[i];
6752 }
6753 staticInfo.update(ANDROID_SENSOR_OPTICAL_BLACK_REGIONS,
6754 opticalBlackRegions, gCamCapability[cameraId]->optical_black_region_count * 4);
6755 hasBlackRegions = true;
6756 }
6757#endif
Thierry Strudel3d639192016-09-09 11:52:26 -07006758 staticInfo.update(ANDROID_FLASH_INFO_CHARGE_DURATION,
6759 &gCamCapability[cameraId]->flash_charge_duration, 1);
6760
6761 staticInfo.update(ANDROID_TONEMAP_MAX_CURVE_POINTS,
6762 &gCamCapability[cameraId]->max_tone_map_curve_points, 1);
6763
6764 uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
6765 staticInfo.update(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
6766 &timestampSource, 1);
6767
6768 staticInfo.update(ANDROID_STATISTICS_INFO_HISTOGRAM_BUCKET_COUNT,
6769 &gCamCapability[cameraId]->histogram_size, 1);
6770
6771 staticInfo.update(ANDROID_STATISTICS_INFO_MAX_HISTOGRAM_COUNT,
6772 &gCamCapability[cameraId]->max_histogram_count, 1);
6773
6774 int32_t sharpness_map_size[] = {
6775 gCamCapability[cameraId]->sharpness_map_size.width,
6776 gCamCapability[cameraId]->sharpness_map_size.height};
6777
6778 staticInfo.update(ANDROID_STATISTICS_INFO_SHARPNESS_MAP_SIZE,
6779 sharpness_map_size, sizeof(sharpness_map_size)/sizeof(int32_t));
6780
6781 staticInfo.update(ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE,
6782 &gCamCapability[cameraId]->max_sharpness_map_value, 1);
6783
6784 int32_t scalar_formats[] = {
6785 ANDROID_SCALER_AVAILABLE_FORMATS_RAW_OPAQUE,
6786 ANDROID_SCALER_AVAILABLE_FORMATS_RAW16,
6787 ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888,
6788 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB,
6789 HAL_PIXEL_FORMAT_RAW10,
6790 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED};
6791 size_t scalar_formats_count = sizeof(scalar_formats) / sizeof(int32_t);
6792 staticInfo.update(ANDROID_SCALER_AVAILABLE_FORMATS,
6793 scalar_formats,
6794 scalar_formats_count);
6795
6796 int32_t available_processed_sizes[MAX_SIZES_CNT * 2];
6797 count = MIN(gCamCapability[cameraId]->picture_sizes_tbl_cnt, MAX_SIZES_CNT);
6798 makeTable(gCamCapability[cameraId]->picture_sizes_tbl,
6799 count, MAX_SIZES_CNT, available_processed_sizes);
6800 staticInfo.update(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES,
6801 available_processed_sizes, count * 2);
6802
6803 int32_t available_raw_sizes[MAX_SIZES_CNT * 2];
6804 count = MIN(gCamCapability[cameraId]->supported_raw_dim_cnt, MAX_SIZES_CNT);
6805 makeTable(gCamCapability[cameraId]->raw_dim,
6806 count, MAX_SIZES_CNT, available_raw_sizes);
6807 staticInfo.update(ANDROID_SCALER_AVAILABLE_RAW_SIZES,
6808 available_raw_sizes, count * 2);
6809
6810 int32_t available_fps_ranges[MAX_SIZES_CNT * 2];
6811 count = MIN(gCamCapability[cameraId]->fps_ranges_tbl_cnt, MAX_SIZES_CNT);
6812 makeFPSTable(gCamCapability[cameraId]->fps_ranges_tbl,
6813 count, MAX_SIZES_CNT, available_fps_ranges);
6814 staticInfo.update(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
6815 available_fps_ranges, count * 2);
6816
6817 camera_metadata_rational exposureCompensationStep = {
6818 gCamCapability[cameraId]->exp_compensation_step.numerator,
6819 gCamCapability[cameraId]->exp_compensation_step.denominator};
6820 staticInfo.update(ANDROID_CONTROL_AE_COMPENSATION_STEP,
6821 &exposureCompensationStep, 1);
6822
6823 Vector<uint8_t> availableVstabModes;
6824 availableVstabModes.add(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF);
6825 char eis_prop[PROPERTY_VALUE_MAX];
Thierry Strudel9e74aae2016-09-22 17:10:18 -07006826 bool eisSupported = false;
Thierry Strudel3d639192016-09-09 11:52:26 -07006827 memset(eis_prop, 0, sizeof(eis_prop));
Thierry Strudel9e74aae2016-09-22 17:10:18 -07006828 property_get("persist.camera.eis.enable", eis_prop, "1");
Thierry Strudel3d639192016-09-09 11:52:26 -07006829 uint8_t eis_prop_set = (uint8_t)atoi(eis_prop);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07006830 count = IS_TYPE_MAX;
6831 count = MIN(gCamCapability[cameraId]->supported_is_types_cnt, count);
6832 for (size_t i = 0; i < count; i++) {
6833 if ((gCamCapability[cameraId]->supported_is_types[i] == IS_TYPE_EIS_2_0) ||
6834 (gCamCapability[cameraId]->supported_is_types[i] == IS_TYPE_EIS_3_0)) {
6835 eisSupported = true;
6836 break;
6837 }
6838 }
6839 if (facingBack && eis_prop_set && eisSupported) {
Thierry Strudel3d639192016-09-09 11:52:26 -07006840 availableVstabModes.add(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON);
6841 }
6842 staticInfo.update(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
6843 availableVstabModes.array(), availableVstabModes.size());
6844
6845 /*HAL 1 and HAL 3 common*/
6846 uint32_t zoomSteps = gCamCapability[cameraId]->zoom_ratio_tbl_cnt;
6847 uint32_t maxZoomStep = gCamCapability[cameraId]->zoom_ratio_tbl[zoomSteps - 1];
6848 uint32_t minZoomStep = 100; //as per HAL1/API1 spec
6849 float maxZoom = maxZoomStep/minZoomStep;
6850 staticInfo.update(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
6851 &maxZoom, 1);
6852
6853 uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
6854 staticInfo.update(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);
6855
6856 int32_t max3aRegions[3] = {/*AE*/1,/*AWB*/ 0,/*AF*/ 1};
6857 if (gCamCapability[cameraId]->supported_focus_modes_cnt == 1)
6858 max3aRegions[2] = 0; /* AF not supported */
6859 staticInfo.update(ANDROID_CONTROL_MAX_REGIONS,
6860 max3aRegions, 3);
6861
6862 /* 0: OFF, 1: OFF+SIMPLE, 2: OFF+FULL, 3: OFF+SIMPLE+FULL */
6863 memset(prop, 0, sizeof(prop));
6864 property_get("persist.camera.facedetect", prop, "1");
6865 uint8_t supportedFaceDetectMode = (uint8_t)atoi(prop);
6866 LOGD("Support face detection mode: %d",
6867 supportedFaceDetectMode);
6868
6869 int32_t maxFaces = gCamCapability[cameraId]->max_num_roi;
6870 Vector<uint8_t> availableFaceDetectModes;
6871 availableFaceDetectModes.add(ANDROID_STATISTICS_FACE_DETECT_MODE_OFF);
6872 if (supportedFaceDetectMode == 1) {
6873 availableFaceDetectModes.add(ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE);
6874 } else if (supportedFaceDetectMode == 2) {
6875 availableFaceDetectModes.add(ANDROID_STATISTICS_FACE_DETECT_MODE_FULL);
6876 } else if (supportedFaceDetectMode == 3) {
6877 availableFaceDetectModes.add(ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE);
6878 availableFaceDetectModes.add(ANDROID_STATISTICS_FACE_DETECT_MODE_FULL);
6879 } else {
6880 maxFaces = 0;
6881 }
6882 staticInfo.update(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
6883 availableFaceDetectModes.array(),
6884 availableFaceDetectModes.size());
6885 staticInfo.update(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
6886 (int32_t *)&maxFaces, 1);
6887
6888 int32_t exposureCompensationRange[] = {
6889 gCamCapability[cameraId]->exposure_compensation_min,
6890 gCamCapability[cameraId]->exposure_compensation_max};
6891 staticInfo.update(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
6892 exposureCompensationRange,
6893 sizeof(exposureCompensationRange)/sizeof(int32_t));
6894
6895 uint8_t lensFacing = (facingBack) ?
6896 ANDROID_LENS_FACING_BACK : ANDROID_LENS_FACING_FRONT;
6897 staticInfo.update(ANDROID_LENS_FACING, &lensFacing, 1);
6898
6899 staticInfo.update(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
6900 available_thumbnail_sizes,
6901 sizeof(available_thumbnail_sizes)/sizeof(int32_t));
6902
6903 /*all sizes will be clubbed into this tag*/
6904 count = MIN(gCamCapability[cameraId]->picture_sizes_tbl_cnt, MAX_SIZES_CNT);
6905 /*android.scaler.availableStreamConfigurations*/
6906 Vector<int32_t> available_stream_configs;
6907 cam_dimension_t active_array_dim;
6908 active_array_dim.width = gCamCapability[cameraId]->active_array_size.width;
6909 active_array_dim.height = gCamCapability[cameraId]->active_array_size.height;
6910 /* Add input/output stream configurations for each scalar formats*/
6911 for (size_t j = 0; j < scalar_formats_count; j++) {
6912 switch (scalar_formats[j]) {
6913 case ANDROID_SCALER_AVAILABLE_FORMATS_RAW16:
6914 case ANDROID_SCALER_AVAILABLE_FORMATS_RAW_OPAQUE:
6915 case HAL_PIXEL_FORMAT_RAW10:
6916 for (size_t i = 0; i < MIN(MAX_SIZES_CNT,
6917 gCamCapability[cameraId]->supported_raw_dim_cnt); i++) {
6918 addStreamConfig(available_stream_configs, scalar_formats[j],
6919 gCamCapability[cameraId]->raw_dim[i],
6920 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
6921 }
6922 break;
6923 case HAL_PIXEL_FORMAT_BLOB:
6924 for (size_t i = 0; i < MIN(MAX_SIZES_CNT,
6925 gCamCapability[cameraId]->picture_sizes_tbl_cnt); i++) {
6926 addStreamConfig(available_stream_configs, scalar_formats[j],
6927 gCamCapability[cameraId]->picture_sizes_tbl[i],
6928 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
6929 }
6930 break;
6931 case HAL_PIXEL_FORMAT_YCbCr_420_888:
6932 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
6933 default:
6934 cam_dimension_t largest_picture_size;
6935 memset(&largest_picture_size, 0, sizeof(cam_dimension_t));
6936 for (size_t i = 0; i < MIN(MAX_SIZES_CNT,
6937 gCamCapability[cameraId]->picture_sizes_tbl_cnt); i++) {
6938 addStreamConfig(available_stream_configs, scalar_formats[j],
6939 gCamCapability[cameraId]->picture_sizes_tbl[i],
6940 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
6941 /* Book keep largest */
6942 if (gCamCapability[cameraId]->picture_sizes_tbl[i].width
6943 >= largest_picture_size.width &&
6944 gCamCapability[cameraId]->picture_sizes_tbl[i].height
6945 >= largest_picture_size.height)
6946 largest_picture_size = gCamCapability[cameraId]->picture_sizes_tbl[i];
6947 }
6948 /*For below 2 formats we also support i/p streams for reprocessing advertise those*/
6949 if (scalar_formats[j] == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
6950 scalar_formats[j] == HAL_PIXEL_FORMAT_YCbCr_420_888) {
6951 addStreamConfig(available_stream_configs, scalar_formats[j],
6952 largest_picture_size,
6953 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT);
6954 }
6955 break;
6956 }
6957 }
6958
6959 staticInfo.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
6960 available_stream_configs.array(), available_stream_configs.size());
6961 static const uint8_t hotpixelMode = ANDROID_HOT_PIXEL_MODE_FAST;
6962 staticInfo.update(ANDROID_HOT_PIXEL_MODE, &hotpixelMode, 1);
6963
6964 static const uint8_t hotPixelMapMode = ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF;
6965 staticInfo.update(ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE, &hotPixelMapMode, 1);
6966
6967 /* android.scaler.availableMinFrameDurations */
6968 Vector<int64_t> available_min_durations;
6969 for (size_t j = 0; j < scalar_formats_count; j++) {
6970 switch (scalar_formats[j]) {
6971 case ANDROID_SCALER_AVAILABLE_FORMATS_RAW16:
6972 case ANDROID_SCALER_AVAILABLE_FORMATS_RAW_OPAQUE:
6973 case HAL_PIXEL_FORMAT_RAW10:
6974 for (size_t i = 0; i < MIN(MAX_SIZES_CNT,
6975 gCamCapability[cameraId]->supported_raw_dim_cnt); i++) {
6976 available_min_durations.add(scalar_formats[j]);
6977 available_min_durations.add(gCamCapability[cameraId]->raw_dim[i].width);
6978 available_min_durations.add(gCamCapability[cameraId]->raw_dim[i].height);
6979 available_min_durations.add(gCamCapability[cameraId]->raw_min_duration[i]);
6980 }
6981 break;
6982 default:
6983 for (size_t i = 0; i < MIN(MAX_SIZES_CNT,
6984 gCamCapability[cameraId]->picture_sizes_tbl_cnt); i++) {
6985 available_min_durations.add(scalar_formats[j]);
6986 available_min_durations.add(gCamCapability[cameraId]->picture_sizes_tbl[i].width);
6987 available_min_durations.add(gCamCapability[cameraId]->picture_sizes_tbl[i].height);
6988 available_min_durations.add(gCamCapability[cameraId]->picture_min_duration[i]);
6989 }
6990 break;
6991 }
6992 }
6993 staticInfo.update(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
6994 available_min_durations.array(), available_min_durations.size());
6995
6996 Vector<int32_t> available_hfr_configs;
6997 for (size_t i = 0; i < gCamCapability[cameraId]->hfr_tbl_cnt; i++) {
6998 int32_t fps = 0;
6999 switch (gCamCapability[cameraId]->hfr_tbl[i].mode) {
7000 case CAM_HFR_MODE_60FPS:
7001 fps = 60;
7002 break;
7003 case CAM_HFR_MODE_90FPS:
7004 fps = 90;
7005 break;
7006 case CAM_HFR_MODE_120FPS:
7007 fps = 120;
7008 break;
7009 case CAM_HFR_MODE_150FPS:
7010 fps = 150;
7011 break;
7012 case CAM_HFR_MODE_180FPS:
7013 fps = 180;
7014 break;
7015 case CAM_HFR_MODE_210FPS:
7016 fps = 210;
7017 break;
7018 case CAM_HFR_MODE_240FPS:
7019 fps = 240;
7020 break;
7021 case CAM_HFR_MODE_480FPS:
7022 fps = 480;
7023 break;
7024 case CAM_HFR_MODE_OFF:
7025 case CAM_HFR_MODE_MAX:
7026 default:
7027 break;
7028 }
7029
7030 /* Advertise only MIN_FPS_FOR_BATCH_MODE or above as HIGH_SPEED_CONFIGS */
7031 if (fps >= MIN_FPS_FOR_BATCH_MODE) {
7032 /* For each HFR frame rate, need to advertise one variable fps range
7033 * and one fixed fps range per dimension. Eg: for 120 FPS, advertise [30, 120]
7034 * and [120, 120]. While camcorder preview alone is running [30, 120] is
7035 * set by the app. When video recording is started, [120, 120] is
7036 * set. This way sensor configuration does not change when recording
7037 * is started */
7038
7039 /* (width, height, fps_min, fps_max, batch_size_max) */
7040 for (size_t j = 0; j < gCamCapability[cameraId]->hfr_tbl[i].dim_cnt &&
7041 j < MAX_SIZES_CNT; j++) {
7042 available_hfr_configs.add(
7043 gCamCapability[cameraId]->hfr_tbl[i].dim[j].width);
7044 available_hfr_configs.add(
7045 gCamCapability[cameraId]->hfr_tbl[i].dim[j].height);
7046 available_hfr_configs.add(PREVIEW_FPS_FOR_HFR);
7047 available_hfr_configs.add(fps);
7048 available_hfr_configs.add(fps / PREVIEW_FPS_FOR_HFR);
7049
7050 /* (width, height, fps_min, fps_max, batch_size_max) */
7051 available_hfr_configs.add(
7052 gCamCapability[cameraId]->hfr_tbl[i].dim[j].width);
7053 available_hfr_configs.add(
7054 gCamCapability[cameraId]->hfr_tbl[i].dim[j].height);
7055 available_hfr_configs.add(fps);
7056 available_hfr_configs.add(fps);
7057 available_hfr_configs.add(fps / PREVIEW_FPS_FOR_HFR);
7058 }
7059 }
7060 }
7061 //Advertise HFR capability only if the property is set
7062 memset(prop, 0, sizeof(prop));
7063 property_get("persist.camera.hal3hfr.enable", prop, "1");
7064 uint8_t hfrEnable = (uint8_t)atoi(prop);
7065
7066 if(hfrEnable && available_hfr_configs.array()) {
7067 staticInfo.update(
7068 ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS,
7069 available_hfr_configs.array(), available_hfr_configs.size());
7070 }
7071
7072 int32_t max_jpeg_size = (int32_t)calcMaxJpegSize(cameraId);
7073 staticInfo.update(ANDROID_JPEG_MAX_SIZE,
7074 &max_jpeg_size, 1);
7075
7076 uint8_t avail_effects[CAM_EFFECT_MODE_MAX];
7077 size_t size = 0;
7078 count = CAM_EFFECT_MODE_MAX;
7079 count = MIN(gCamCapability[cameraId]->supported_effects_cnt, count);
7080 for (size_t i = 0; i < count; i++) {
7081 int val = lookupFwkName(EFFECT_MODES_MAP, METADATA_MAP_SIZE(EFFECT_MODES_MAP),
7082 gCamCapability[cameraId]->supported_effects[i]);
7083 if (NAME_NOT_FOUND != val) {
7084 avail_effects[size] = (uint8_t)val;
7085 size++;
7086 }
7087 }
7088 staticInfo.update(ANDROID_CONTROL_AVAILABLE_EFFECTS,
7089 avail_effects,
7090 size);
7091
7092 uint8_t avail_scene_modes[CAM_SCENE_MODE_MAX];
7093 uint8_t supported_indexes[CAM_SCENE_MODE_MAX];
7094 size_t supported_scene_modes_cnt = 0;
7095 count = CAM_SCENE_MODE_MAX;
7096 count = MIN(gCamCapability[cameraId]->supported_scene_modes_cnt, count);
7097 for (size_t i = 0; i < count; i++) {
7098 if (gCamCapability[cameraId]->supported_scene_modes[i] !=
7099 CAM_SCENE_MODE_OFF) {
7100 int val = lookupFwkName(SCENE_MODES_MAP,
7101 METADATA_MAP_SIZE(SCENE_MODES_MAP),
7102 gCamCapability[cameraId]->supported_scene_modes[i]);
7103 if (NAME_NOT_FOUND != val) {
7104 avail_scene_modes[supported_scene_modes_cnt] = (uint8_t)val;
7105 supported_indexes[supported_scene_modes_cnt] = (uint8_t)i;
7106 supported_scene_modes_cnt++;
7107 }
7108 }
7109 }
7110 staticInfo.update(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
7111 avail_scene_modes,
7112 supported_scene_modes_cnt);
7113
7114 uint8_t scene_mode_overrides[CAM_SCENE_MODE_MAX * 3];
7115 makeOverridesList(gCamCapability[cameraId]->scene_mode_overrides,
7116 supported_scene_modes_cnt,
7117 CAM_SCENE_MODE_MAX,
7118 scene_mode_overrides,
7119 supported_indexes,
7120 cameraId);
7121
7122 if (supported_scene_modes_cnt == 0) {
7123 supported_scene_modes_cnt = 1;
7124 avail_scene_modes[0] = ANDROID_CONTROL_SCENE_MODE_DISABLED;
7125 }
7126
7127 staticInfo.update(ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
7128 scene_mode_overrides, supported_scene_modes_cnt * 3);
7129
7130 uint8_t available_control_modes[] = {ANDROID_CONTROL_MODE_OFF,
7131 ANDROID_CONTROL_MODE_AUTO,
7132 ANDROID_CONTROL_MODE_USE_SCENE_MODE};
7133 staticInfo.update(ANDROID_CONTROL_AVAILABLE_MODES,
7134 available_control_modes,
7135 3);
7136
7137 uint8_t avail_antibanding_modes[CAM_ANTIBANDING_MODE_MAX];
7138 size = 0;
7139 count = CAM_ANTIBANDING_MODE_MAX;
7140 count = MIN(gCamCapability[cameraId]->supported_antibandings_cnt, count);
7141 for (size_t i = 0; i < count; i++) {
7142 int val = lookupFwkName(ANTIBANDING_MODES_MAP, METADATA_MAP_SIZE(ANTIBANDING_MODES_MAP),
7143 gCamCapability[cameraId]->supported_antibandings[i]);
7144 if (NAME_NOT_FOUND != val) {
7145 avail_antibanding_modes[size] = (uint8_t)val;
7146 size++;
7147 }
7148
7149 }
7150 staticInfo.update(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
7151 avail_antibanding_modes,
7152 size);
7153
7154 uint8_t avail_abberation_modes[] = {
7155 ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF,
7156 ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST,
7157 ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY};
7158 count = CAM_COLOR_CORRECTION_ABERRATION_MAX;
7159 count = MIN(gCamCapability[cameraId]->aberration_modes_count, count);
7160 if (0 == count) {
7161 // If no aberration correction modes are available for a device, this advertise OFF mode
7162 size = 1;
7163 } else {
7164 // If count is not zero then atleast one among the FAST or HIGH quality is supported
7165 // So, advertize all 3 modes if atleast any one mode is supported as per the
7166 // new M requirement
7167 size = 3;
7168 }
7169 staticInfo.update(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
7170 avail_abberation_modes,
7171 size);
7172
7173 uint8_t avail_af_modes[CAM_FOCUS_MODE_MAX];
7174 size = 0;
7175 count = CAM_FOCUS_MODE_MAX;
7176 count = MIN(gCamCapability[cameraId]->supported_focus_modes_cnt, count);
7177 for (size_t i = 0; i < count; i++) {
7178 int val = lookupFwkName(FOCUS_MODES_MAP, METADATA_MAP_SIZE(FOCUS_MODES_MAP),
7179 gCamCapability[cameraId]->supported_focus_modes[i]);
7180 if (NAME_NOT_FOUND != val) {
7181 avail_af_modes[size] = (uint8_t)val;
7182 size++;
7183 }
7184 }
7185 staticInfo.update(ANDROID_CONTROL_AF_AVAILABLE_MODES,
7186 avail_af_modes,
7187 size);
7188
7189 uint8_t avail_awb_modes[CAM_WB_MODE_MAX];
7190 size = 0;
7191 count = CAM_WB_MODE_MAX;
7192 count = MIN(gCamCapability[cameraId]->supported_white_balances_cnt, count);
7193 for (size_t i = 0; i < count; i++) {
7194 int val = lookupFwkName(WHITE_BALANCE_MODES_MAP,
7195 METADATA_MAP_SIZE(WHITE_BALANCE_MODES_MAP),
7196 gCamCapability[cameraId]->supported_white_balances[i]);
7197 if (NAME_NOT_FOUND != val) {
7198 avail_awb_modes[size] = (uint8_t)val;
7199 size++;
7200 }
7201 }
7202 staticInfo.update(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
7203 avail_awb_modes,
7204 size);
7205
7206 uint8_t available_flash_levels[CAM_FLASH_FIRING_LEVEL_MAX];
7207 count = CAM_FLASH_FIRING_LEVEL_MAX;
7208 count = MIN(gCamCapability[cameraId]->supported_flash_firing_level_cnt,
7209 count);
7210 for (size_t i = 0; i < count; i++) {
7211 available_flash_levels[i] =
7212 gCamCapability[cameraId]->supported_firing_levels[i];
7213 }
7214 staticInfo.update(ANDROID_FLASH_FIRING_POWER,
7215 available_flash_levels, count);
7216
7217 uint8_t flashAvailable;
7218 if (gCamCapability[cameraId]->flash_available)
7219 flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_TRUE;
7220 else
7221 flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;
7222 staticInfo.update(ANDROID_FLASH_INFO_AVAILABLE,
7223 &flashAvailable, 1);
7224
7225 Vector<uint8_t> avail_ae_modes;
7226 count = CAM_AE_MODE_MAX;
7227 count = MIN(gCamCapability[cameraId]->supported_ae_modes_cnt, count);
7228 for (size_t i = 0; i < count; i++) {
7229 avail_ae_modes.add(gCamCapability[cameraId]->supported_ae_modes[i]);
7230 }
7231 if (flashAvailable) {
7232 avail_ae_modes.add(ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH);
7233 avail_ae_modes.add(ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH);
7234 }
7235 staticInfo.update(ANDROID_CONTROL_AE_AVAILABLE_MODES,
7236 avail_ae_modes.array(),
7237 avail_ae_modes.size());
7238
7239 int32_t sensitivity_range[2];
7240 sensitivity_range[0] = gCamCapability[cameraId]->sensitivity_range.min_sensitivity;
7241 sensitivity_range[1] = gCamCapability[cameraId]->sensitivity_range.max_sensitivity;
7242 staticInfo.update(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
7243 sensitivity_range,
7244 sizeof(sensitivity_range) / sizeof(int32_t));
7245
7246 staticInfo.update(ANDROID_SENSOR_MAX_ANALOG_SENSITIVITY,
7247 &gCamCapability[cameraId]->max_analog_sensitivity,
7248 1);
7249
7250 int32_t sensor_orientation = (int32_t)gCamCapability[cameraId]->sensor_mount_angle;
7251 staticInfo.update(ANDROID_SENSOR_ORIENTATION,
7252 &sensor_orientation,
7253 1);
7254
7255 int32_t max_output_streams[] = {
7256 MAX_STALLING_STREAMS,
7257 MAX_PROCESSED_STREAMS,
7258 MAX_RAW_STREAMS};
7259 staticInfo.update(ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
7260 max_output_streams,
7261 sizeof(max_output_streams)/sizeof(max_output_streams[0]));
7262
7263 uint8_t avail_leds = 0;
7264 staticInfo.update(ANDROID_LED_AVAILABLE_LEDS,
7265 &avail_leds, 0);
7266
7267 uint8_t focus_dist_calibrated;
7268 int val = lookupFwkName(FOCUS_CALIBRATION_MAP, METADATA_MAP_SIZE(FOCUS_CALIBRATION_MAP),
7269 gCamCapability[cameraId]->focus_dist_calibrated);
7270 if (NAME_NOT_FOUND != val) {
7271 focus_dist_calibrated = (uint8_t)val;
7272 staticInfo.update(ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION,
7273 &focus_dist_calibrated, 1);
7274 }
7275
7276 int32_t avail_testpattern_modes[MAX_TEST_PATTERN_CNT];
7277 size = 0;
7278 count = MIN(gCamCapability[cameraId]->supported_test_pattern_modes_cnt,
7279 MAX_TEST_PATTERN_CNT);
7280 for (size_t i = 0; i < count; i++) {
7281 int testpatternMode = lookupFwkName(TEST_PATTERN_MAP, METADATA_MAP_SIZE(TEST_PATTERN_MAP),
7282 gCamCapability[cameraId]->supported_test_pattern_modes[i]);
7283 if (NAME_NOT_FOUND != testpatternMode) {
7284 avail_testpattern_modes[size] = testpatternMode;
7285 size++;
7286 }
7287 }
7288 staticInfo.update(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
7289 avail_testpattern_modes,
7290 size);
7291
7292 uint8_t max_pipeline_depth = (uint8_t)(MAX_INFLIGHT_REQUESTS + EMPTY_PIPELINE_DELAY + FRAME_SKIP_DELAY);
7293 staticInfo.update(ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
7294 &max_pipeline_depth,
7295 1);
7296
7297 int32_t partial_result_count = PARTIAL_RESULT_COUNT;
7298 staticInfo.update(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
7299 &partial_result_count,
7300 1);
7301
7302 int32_t max_stall_duration = MAX_REPROCESS_STALL;
7303 staticInfo.update(ANDROID_REPROCESS_MAX_CAPTURE_STALL, &max_stall_duration, 1);
7304
7305 Vector<uint8_t> available_capabilities;
7306 available_capabilities.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE);
7307 available_capabilities.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR);
7308 available_capabilities.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING);
7309 available_capabilities.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS);
7310 if (supportBurst) {
7311 available_capabilities.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE);
7312 }
7313 available_capabilities.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING);
7314 available_capabilities.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING);
7315 if (hfrEnable && available_hfr_configs.array()) {
7316 available_capabilities.add(
7317 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO);
7318 }
7319
7320 if (CAM_SENSOR_YUV != gCamCapability[cameraId]->sensor_type.sens_type) {
7321 available_capabilities.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW);
7322 }
7323 staticInfo.update(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
7324 available_capabilities.array(),
7325 available_capabilities.size());
7326
7327 //aeLockAvailable to be set to true if capabilities has MANUAL_SENSOR or BURST_CAPTURE
7328 //Assumption is that all bayer cameras support MANUAL_SENSOR.
7329 uint8_t aeLockAvailable = (gCamCapability[cameraId]->sensor_type.sens_type == CAM_SENSOR_RAW) ?
7330 ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE : ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
7331
7332 staticInfo.update(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
7333 &aeLockAvailable, 1);
7334
7335 //awbLockAvailable to be set to true if capabilities has MANUAL_POST_PROCESSING or
7336 //BURST_CAPTURE. Assumption is that all bayer cameras support MANUAL_POST_PROCESSING.
7337 uint8_t awbLockAvailable = (gCamCapability[cameraId]->sensor_type.sens_type == CAM_SENSOR_RAW) ?
7338 ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE : ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
7339
7340 staticInfo.update(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
7341 &awbLockAvailable, 1);
7342
7343 int32_t max_input_streams = 1;
7344 staticInfo.update(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
7345 &max_input_streams,
7346 1);
7347
7348 /* format of the map is : input format, num_output_formats, outputFormat1,..,outputFormatN */
7349 int32_t io_format_map[] = {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, 2,
7350 HAL_PIXEL_FORMAT_BLOB, HAL_PIXEL_FORMAT_YCbCr_420_888,
7351 HAL_PIXEL_FORMAT_YCbCr_420_888, 2, HAL_PIXEL_FORMAT_BLOB,
7352 HAL_PIXEL_FORMAT_YCbCr_420_888};
7353 staticInfo.update(ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP,
7354 io_format_map, sizeof(io_format_map)/sizeof(io_format_map[0]));
7355
7356 int32_t max_latency = ANDROID_SYNC_MAX_LATENCY_PER_FRAME_CONTROL;
7357 staticInfo.update(ANDROID_SYNC_MAX_LATENCY,
7358 &max_latency,
7359 1);
7360
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007361#ifndef USE_HAL_3_3
7362 int32_t isp_sensitivity_range[2];
7363 isp_sensitivity_range[0] =
7364 gCamCapability[cameraId]->isp_sensitivity_range.min_sensitivity;
7365 isp_sensitivity_range[1] =
7366 gCamCapability[cameraId]->isp_sensitivity_range.max_sensitivity;
7367 staticInfo.update(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE,
7368 isp_sensitivity_range,
7369 sizeof(isp_sensitivity_range) / sizeof(isp_sensitivity_range[0]));
7370#endif
7371
Thierry Strudel3d639192016-09-09 11:52:26 -07007372 uint8_t available_hot_pixel_modes[] = {ANDROID_HOT_PIXEL_MODE_FAST,
7373 ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY};
7374 staticInfo.update(ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES,
7375 available_hot_pixel_modes,
7376 sizeof(available_hot_pixel_modes)/sizeof(available_hot_pixel_modes[0]));
7377
7378 uint8_t available_shading_modes[] = {ANDROID_SHADING_MODE_OFF,
7379 ANDROID_SHADING_MODE_FAST,
7380 ANDROID_SHADING_MODE_HIGH_QUALITY};
7381 staticInfo.update(ANDROID_SHADING_AVAILABLE_MODES,
7382 available_shading_modes,
7383 3);
7384
7385 uint8_t available_lens_shading_map_modes[] = {ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF,
7386 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON};
7387 staticInfo.update(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
7388 available_lens_shading_map_modes,
7389 2);
7390
7391 uint8_t available_edge_modes[] = {ANDROID_EDGE_MODE_OFF,
7392 ANDROID_EDGE_MODE_FAST,
7393 ANDROID_EDGE_MODE_HIGH_QUALITY,
7394 ANDROID_EDGE_MODE_ZERO_SHUTTER_LAG};
7395 staticInfo.update(ANDROID_EDGE_AVAILABLE_EDGE_MODES,
7396 available_edge_modes,
7397 sizeof(available_edge_modes)/sizeof(available_edge_modes[0]));
7398
7399 uint8_t available_noise_red_modes[] = {ANDROID_NOISE_REDUCTION_MODE_OFF,
7400 ANDROID_NOISE_REDUCTION_MODE_FAST,
7401 ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY,
7402 ANDROID_NOISE_REDUCTION_MODE_MINIMAL,
7403 ANDROID_NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG};
7404 staticInfo.update(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
7405 available_noise_red_modes,
7406 sizeof(available_noise_red_modes)/sizeof(available_noise_red_modes[0]));
7407
7408 uint8_t available_tonemap_modes[] = {ANDROID_TONEMAP_MODE_CONTRAST_CURVE,
7409 ANDROID_TONEMAP_MODE_FAST,
7410 ANDROID_TONEMAP_MODE_HIGH_QUALITY};
7411 staticInfo.update(ANDROID_TONEMAP_AVAILABLE_TONE_MAP_MODES,
7412 available_tonemap_modes,
7413 sizeof(available_tonemap_modes)/sizeof(available_tonemap_modes[0]));
7414
7415 uint8_t available_hot_pixel_map_modes[] = {ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF};
7416 staticInfo.update(ANDROID_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES,
7417 available_hot_pixel_map_modes,
7418 sizeof(available_hot_pixel_map_modes)/sizeof(available_hot_pixel_map_modes[0]));
7419
7420 val = lookupFwkName(REFERENCE_ILLUMINANT_MAP, METADATA_MAP_SIZE(REFERENCE_ILLUMINANT_MAP),
7421 gCamCapability[cameraId]->reference_illuminant1);
7422 if (NAME_NOT_FOUND != val) {
7423 uint8_t fwkReferenceIlluminant = (uint8_t)val;
7424 staticInfo.update(ANDROID_SENSOR_REFERENCE_ILLUMINANT1, &fwkReferenceIlluminant, 1);
7425 }
7426
7427 val = lookupFwkName(REFERENCE_ILLUMINANT_MAP, METADATA_MAP_SIZE(REFERENCE_ILLUMINANT_MAP),
7428 gCamCapability[cameraId]->reference_illuminant2);
7429 if (NAME_NOT_FOUND != val) {
7430 uint8_t fwkReferenceIlluminant = (uint8_t)val;
7431 staticInfo.update(ANDROID_SENSOR_REFERENCE_ILLUMINANT2, &fwkReferenceIlluminant, 1);
7432 }
7433
7434 staticInfo.update(ANDROID_SENSOR_FORWARD_MATRIX1, (camera_metadata_rational_t *)
7435 (void *)gCamCapability[cameraId]->forward_matrix1,
7436 FORWARD_MATRIX_COLS * FORWARD_MATRIX_ROWS);
7437
7438 staticInfo.update(ANDROID_SENSOR_FORWARD_MATRIX2, (camera_metadata_rational_t *)
7439 (void *)gCamCapability[cameraId]->forward_matrix2,
7440 FORWARD_MATRIX_COLS * FORWARD_MATRIX_ROWS);
7441
7442 staticInfo.update(ANDROID_SENSOR_COLOR_TRANSFORM1, (camera_metadata_rational_t *)
7443 (void *)gCamCapability[cameraId]->color_transform1,
7444 COLOR_TRANSFORM_COLS * COLOR_TRANSFORM_ROWS);
7445
7446 staticInfo.update(ANDROID_SENSOR_COLOR_TRANSFORM2, (camera_metadata_rational_t *)
7447 (void *)gCamCapability[cameraId]->color_transform2,
7448 COLOR_TRANSFORM_COLS * COLOR_TRANSFORM_ROWS);
7449
7450 staticInfo.update(ANDROID_SENSOR_CALIBRATION_TRANSFORM1, (camera_metadata_rational_t *)
7451 (void *)gCamCapability[cameraId]->calibration_transform1,
7452 CAL_TRANSFORM_COLS * CAL_TRANSFORM_ROWS);
7453
7454 staticInfo.update(ANDROID_SENSOR_CALIBRATION_TRANSFORM2, (camera_metadata_rational_t *)
7455 (void *)gCamCapability[cameraId]->calibration_transform2,
7456 CAL_TRANSFORM_COLS * CAL_TRANSFORM_ROWS);
7457
7458 int32_t request_keys_basic[] = {ANDROID_COLOR_CORRECTION_MODE,
7459 ANDROID_COLOR_CORRECTION_TRANSFORM, ANDROID_COLOR_CORRECTION_GAINS,
7460 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
7461 ANDROID_CONTROL_AE_ANTIBANDING_MODE, ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
7462 ANDROID_CONTROL_AE_LOCK, ANDROID_CONTROL_AE_MODE,
7463 ANDROID_CONTROL_AE_REGIONS, ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
7464 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, ANDROID_CONTROL_AF_MODE,
7465 ANDROID_CONTROL_AF_TRIGGER, ANDROID_CONTROL_AWB_LOCK,
7466 ANDROID_CONTROL_AWB_MODE, ANDROID_CONTROL_CAPTURE_INTENT,
7467 ANDROID_CONTROL_EFFECT_MODE, ANDROID_CONTROL_MODE,
7468 ANDROID_CONTROL_SCENE_MODE, ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
7469 ANDROID_DEMOSAIC_MODE, ANDROID_EDGE_MODE,
7470 ANDROID_FLASH_FIRING_POWER, ANDROID_FLASH_FIRING_TIME, ANDROID_FLASH_MODE,
7471 ANDROID_JPEG_GPS_COORDINATES,
7472 ANDROID_JPEG_GPS_PROCESSING_METHOD, ANDROID_JPEG_GPS_TIMESTAMP,
7473 ANDROID_JPEG_ORIENTATION, ANDROID_JPEG_QUALITY, ANDROID_JPEG_THUMBNAIL_QUALITY,
7474 ANDROID_JPEG_THUMBNAIL_SIZE, ANDROID_LENS_APERTURE, ANDROID_LENS_FILTER_DENSITY,
7475 ANDROID_LENS_FOCAL_LENGTH, ANDROID_LENS_FOCUS_DISTANCE,
7476 ANDROID_LENS_OPTICAL_STABILIZATION_MODE, ANDROID_NOISE_REDUCTION_MODE,
7477 ANDROID_REQUEST_ID, ANDROID_REQUEST_TYPE,
7478 ANDROID_SCALER_CROP_REGION, ANDROID_SENSOR_EXPOSURE_TIME,
7479 ANDROID_SENSOR_FRAME_DURATION, ANDROID_HOT_PIXEL_MODE,
7480 ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,
7481 ANDROID_SENSOR_SENSITIVITY, ANDROID_SHADING_MODE,
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007482#ifndef USE_HAL_3_3
7483 ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST,
7484#endif
Thierry Strudel3d639192016-09-09 11:52:26 -07007485 ANDROID_STATISTICS_FACE_DETECT_MODE,
7486 ANDROID_STATISTICS_HISTOGRAM_MODE, ANDROID_STATISTICS_SHARPNESS_MAP_MODE,
7487 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, ANDROID_TONEMAP_CURVE_BLUE,
7488 ANDROID_TONEMAP_CURVE_GREEN, ANDROID_TONEMAP_CURVE_RED, ANDROID_TONEMAP_MODE,
7489 ANDROID_BLACK_LEVEL_LOCK };
7490
7491 size_t request_keys_cnt =
7492 sizeof(request_keys_basic)/sizeof(request_keys_basic[0]);
7493 Vector<int32_t> available_request_keys;
7494 available_request_keys.appendArray(request_keys_basic, request_keys_cnt);
7495 if (gCamCapability[cameraId]->supported_focus_modes_cnt > 1) {
7496 available_request_keys.add(ANDROID_CONTROL_AF_REGIONS);
7497 }
7498
7499 staticInfo.update(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
7500 available_request_keys.array(), available_request_keys.size());
7501
7502 int32_t result_keys_basic[] = {ANDROID_COLOR_CORRECTION_TRANSFORM,
7503 ANDROID_COLOR_CORRECTION_GAINS, ANDROID_CONTROL_AE_MODE, ANDROID_CONTROL_AE_REGIONS,
7504 ANDROID_CONTROL_AE_STATE, ANDROID_CONTROL_AF_MODE,
7505 ANDROID_CONTROL_AF_STATE, ANDROID_CONTROL_AWB_MODE,
7506 ANDROID_CONTROL_AWB_STATE, ANDROID_CONTROL_MODE, ANDROID_EDGE_MODE,
7507 ANDROID_FLASH_FIRING_POWER, ANDROID_FLASH_FIRING_TIME, ANDROID_FLASH_MODE,
7508 ANDROID_FLASH_STATE, ANDROID_JPEG_GPS_COORDINATES, ANDROID_JPEG_GPS_PROCESSING_METHOD,
7509 ANDROID_JPEG_GPS_TIMESTAMP, ANDROID_JPEG_ORIENTATION, ANDROID_JPEG_QUALITY,
7510 ANDROID_JPEG_THUMBNAIL_QUALITY, ANDROID_JPEG_THUMBNAIL_SIZE, ANDROID_LENS_APERTURE,
7511 ANDROID_LENS_FILTER_DENSITY, ANDROID_LENS_FOCAL_LENGTH, ANDROID_LENS_FOCUS_DISTANCE,
7512 ANDROID_LENS_FOCUS_RANGE, ANDROID_LENS_STATE, ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
7513 ANDROID_NOISE_REDUCTION_MODE, ANDROID_REQUEST_ID,
7514 ANDROID_SCALER_CROP_REGION, ANDROID_SHADING_MODE, ANDROID_SENSOR_EXPOSURE_TIME,
7515 ANDROID_SENSOR_FRAME_DURATION, ANDROID_SENSOR_SENSITIVITY,
7516 ANDROID_SENSOR_TIMESTAMP, ANDROID_SENSOR_NEUTRAL_COLOR_POINT,
7517 ANDROID_SENSOR_PROFILE_TONE_CURVE, ANDROID_BLACK_LEVEL_LOCK, ANDROID_TONEMAP_CURVE_BLUE,
7518 ANDROID_TONEMAP_CURVE_GREEN, ANDROID_TONEMAP_CURVE_RED, ANDROID_TONEMAP_MODE,
7519 ANDROID_STATISTICS_FACE_DETECT_MODE, ANDROID_STATISTICS_HISTOGRAM_MODE,
7520 ANDROID_STATISTICS_SHARPNESS_MAP, ANDROID_STATISTICS_SHARPNESS_MAP_MODE,
7521 ANDROID_STATISTICS_PREDICTED_COLOR_GAINS, ANDROID_STATISTICS_PREDICTED_COLOR_TRANSFORM,
7522 ANDROID_STATISTICS_SCENE_FLICKER, ANDROID_STATISTICS_FACE_RECTANGLES,
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007523 ANDROID_STATISTICS_FACE_SCORES,
7524#ifndef USE_HAL_3_3
7525 ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST,
7526#endif
7527 };
7528
Thierry Strudel3d639192016-09-09 11:52:26 -07007529 size_t result_keys_cnt =
7530 sizeof(result_keys_basic)/sizeof(result_keys_basic[0]);
7531
7532 Vector<int32_t> available_result_keys;
7533 available_result_keys.appendArray(result_keys_basic, result_keys_cnt);
7534 if (gCamCapability[cameraId]->supported_focus_modes_cnt > 1) {
7535 available_result_keys.add(ANDROID_CONTROL_AF_REGIONS);
7536 }
7537 if (CAM_SENSOR_RAW == gCamCapability[cameraId]->sensor_type.sens_type) {
7538 available_result_keys.add(ANDROID_SENSOR_NOISE_PROFILE);
7539 available_result_keys.add(ANDROID_SENSOR_GREEN_SPLIT);
7540 }
7541 if (supportedFaceDetectMode == 1) {
7542 available_result_keys.add(ANDROID_STATISTICS_FACE_RECTANGLES);
7543 available_result_keys.add(ANDROID_STATISTICS_FACE_SCORES);
7544 } else if ((supportedFaceDetectMode == 2) ||
7545 (supportedFaceDetectMode == 3)) {
7546 available_result_keys.add(ANDROID_STATISTICS_FACE_IDS);
7547 available_result_keys.add(ANDROID_STATISTICS_FACE_LANDMARKS);
7548 }
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007549#ifndef USE_HAL_3_3
7550 if (hasBlackRegions) {
7551 available_result_keys.add(ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL);
7552 available_result_keys.add(ANDROID_SENSOR_DYNAMIC_WHITE_LEVEL);
7553 }
7554#endif
Thierry Strudel3d639192016-09-09 11:52:26 -07007555 staticInfo.update(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
7556 available_result_keys.array(), available_result_keys.size());
7557
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007558 int32_t characteristics_keys_basic[] = {ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
Thierry Strudel3d639192016-09-09 11:52:26 -07007559 ANDROID_CONTROL_AE_AVAILABLE_MODES, ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
7560 ANDROID_CONTROL_AE_COMPENSATION_RANGE, ANDROID_CONTROL_AE_COMPENSATION_STEP,
7561 ANDROID_CONTROL_AF_AVAILABLE_MODES, ANDROID_CONTROL_AVAILABLE_EFFECTS,
7562 ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
7563 ANDROID_SCALER_CROPPING_TYPE,
7564 ANDROID_SYNC_MAX_LATENCY,
7565 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
7566 ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
7567 ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
7568 ANDROID_CONTROL_AWB_AVAILABLE_MODES, ANDROID_CONTROL_MAX_REGIONS,
7569 ANDROID_CONTROL_SCENE_MODE_OVERRIDES,ANDROID_FLASH_INFO_AVAILABLE,
7570 ANDROID_FLASH_INFO_CHARGE_DURATION, ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
7571 ANDROID_JPEG_MAX_SIZE, ANDROID_LENS_INFO_AVAILABLE_APERTURES,
7572 ANDROID_LENS_INFO_AVAILABLE_FILTER_DENSITIES,
7573 ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
7574 ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
7575 ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE, ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
7576 ANDROID_LENS_INFO_SHADING_MAP_SIZE, ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION,
7577 ANDROID_LENS_FACING,
7578 ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS, ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
7579 ANDROID_REQUEST_PIPELINE_MAX_DEPTH, ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
7580 ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
7581 ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
7582 ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
7583 ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP,
7584 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
7585 /*ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,*/
7586 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS, ANDROID_SENSOR_FORWARD_MATRIX1,
7587 ANDROID_SENSOR_REFERENCE_ILLUMINANT1, ANDROID_SENSOR_REFERENCE_ILLUMINANT2,
7588 ANDROID_SENSOR_FORWARD_MATRIX2, ANDROID_SENSOR_COLOR_TRANSFORM1,
7589 ANDROID_SENSOR_COLOR_TRANSFORM2, ANDROID_SENSOR_CALIBRATION_TRANSFORM1,
7590 ANDROID_SENSOR_CALIBRATION_TRANSFORM2, ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
7591 ANDROID_SENSOR_INFO_SENSITIVITY_RANGE, ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
7592 ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE, ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
7593 ANDROID_SENSOR_INFO_PHYSICAL_SIZE, ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
7594 ANDROID_SENSOR_INFO_WHITE_LEVEL, ANDROID_SENSOR_BASE_GAIN_FACTOR,
7595 ANDROID_SENSOR_BLACK_LEVEL_PATTERN, ANDROID_SENSOR_MAX_ANALOG_SENSITIVITY,
7596 ANDROID_SENSOR_ORIENTATION, ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
7597 ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
7598 ANDROID_STATISTICS_INFO_HISTOGRAM_BUCKET_COUNT,
7599 ANDROID_STATISTICS_INFO_MAX_FACE_COUNT, ANDROID_STATISTICS_INFO_MAX_HISTOGRAM_COUNT,
7600 ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE,
7601 ANDROID_STATISTICS_INFO_SHARPNESS_MAP_SIZE, ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES,
7602 ANDROID_EDGE_AVAILABLE_EDGE_MODES,
7603 ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
7604 ANDROID_TONEMAP_AVAILABLE_TONE_MAP_MODES,
7605 ANDROID_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES,
7606 ANDROID_TONEMAP_MAX_CURVE_POINTS,
7607 ANDROID_CONTROL_AVAILABLE_MODES,
7608 ANDROID_CONTROL_AE_LOCK_AVAILABLE,
7609 ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
7610 ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
7611 ANDROID_SHADING_AVAILABLE_MODES,
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007612 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
7613#ifndef USE_HAL_3_3
7614 ANDROID_SENSOR_OPAQUE_RAW_SIZE,
7615 ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE,
7616#endif
7617 };
7618
7619 Vector<int32_t> available_characteristics_keys;
7620 available_characteristics_keys.appendArray(characteristics_keys_basic,
7621 sizeof(characteristics_keys_basic)/sizeof(int32_t));
7622#ifndef USE_HAL_3_3
7623 if (hasBlackRegions) {
7624 available_characteristics_keys.add(ANDROID_SENSOR_OPTICAL_BLACK_REGIONS);
7625 }
7626#endif
Thierry Strudel3d639192016-09-09 11:52:26 -07007627 staticInfo.update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007628 available_characteristics_keys.array(),
7629 available_characteristics_keys.size());
Thierry Strudel3d639192016-09-09 11:52:26 -07007630
7631 /*available stall durations depend on the hw + sw and will be different for different devices */
7632 /*have to add for raw after implementation*/
7633 int32_t stall_formats[] = {HAL_PIXEL_FORMAT_BLOB, ANDROID_SCALER_AVAILABLE_FORMATS_RAW16};
7634 size_t stall_formats_count = sizeof(stall_formats)/sizeof(int32_t);
7635
7636 Vector<int64_t> available_stall_durations;
7637 for (uint32_t j = 0; j < stall_formats_count; j++) {
7638 if (stall_formats[j] == HAL_PIXEL_FORMAT_BLOB) {
7639 for (uint32_t i = 0; i < MIN(MAX_SIZES_CNT,
7640 gCamCapability[cameraId]->picture_sizes_tbl_cnt); i++) {
7641 available_stall_durations.add(stall_formats[j]);
7642 available_stall_durations.add(gCamCapability[cameraId]->picture_sizes_tbl[i].width);
7643 available_stall_durations.add(gCamCapability[cameraId]->picture_sizes_tbl[i].height);
7644 available_stall_durations.add(gCamCapability[cameraId]->jpeg_stall_durations[i]);
7645 }
7646 } else {
7647 for (uint32_t i = 0; i < MIN(MAX_SIZES_CNT,
7648 gCamCapability[cameraId]->supported_raw_dim_cnt); i++) {
7649 available_stall_durations.add(stall_formats[j]);
7650 available_stall_durations.add(gCamCapability[cameraId]->raw_dim[i].width);
7651 available_stall_durations.add(gCamCapability[cameraId]->raw_dim[i].height);
7652 available_stall_durations.add(gCamCapability[cameraId]->raw16_stall_durations[i]);
7653 }
7654 }
7655 }
7656 staticInfo.update(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
7657 available_stall_durations.array(),
7658 available_stall_durations.size());
7659
7660 //QCAMERA3_OPAQUE_RAW
7661 uint8_t raw_format = QCAMERA3_OPAQUE_RAW_FORMAT_LEGACY;
7662 cam_format_t fmt = CAM_FORMAT_BAYER_QCOM_RAW_10BPP_GBRG;
7663 switch (gCamCapability[cameraId]->opaque_raw_fmt) {
7664 case LEGACY_RAW:
7665 if (gCamCapability[cameraId]->white_level == MAX_VALUE_8BIT)
7666 fmt = CAM_FORMAT_BAYER_QCOM_RAW_8BPP_GBRG;
7667 else if (gCamCapability[cameraId]->white_level == MAX_VALUE_10BIT)
7668 fmt = CAM_FORMAT_BAYER_QCOM_RAW_10BPP_GBRG;
7669 else if (gCamCapability[cameraId]->white_level == MAX_VALUE_12BIT)
7670 fmt = CAM_FORMAT_BAYER_QCOM_RAW_12BPP_GBRG;
7671 raw_format = QCAMERA3_OPAQUE_RAW_FORMAT_LEGACY;
7672 break;
7673 case MIPI_RAW:
7674 if (gCamCapability[cameraId]->white_level == MAX_VALUE_8BIT)
7675 fmt = CAM_FORMAT_BAYER_MIPI_RAW_8BPP_GBRG;
7676 else if (gCamCapability[cameraId]->white_level == MAX_VALUE_10BIT)
7677 fmt = CAM_FORMAT_BAYER_MIPI_RAW_10BPP_GBRG;
7678 else if (gCamCapability[cameraId]->white_level == MAX_VALUE_12BIT)
7679 fmt = CAM_FORMAT_BAYER_MIPI_RAW_12BPP_GBRG;
7680 raw_format = QCAMERA3_OPAQUE_RAW_FORMAT_MIPI;
7681 break;
7682 default:
7683 LOGE("unknown opaque_raw_format %d",
7684 gCamCapability[cameraId]->opaque_raw_fmt);
7685 break;
7686 }
7687 staticInfo.update(QCAMERA3_OPAQUE_RAW_FORMAT, &raw_format, 1);
7688
7689 Vector<int32_t> strides;
7690 for (size_t i = 0; i < MIN(MAX_SIZES_CNT,
7691 gCamCapability[cameraId]->supported_raw_dim_cnt); i++) {
7692 cam_stream_buf_plane_info_t buf_planes;
7693 strides.add(gCamCapability[cameraId]->raw_dim[i].width);
7694 strides.add(gCamCapability[cameraId]->raw_dim[i].height);
7695 mm_stream_calc_offset_raw(fmt, &gCamCapability[cameraId]->raw_dim[i],
7696 &gCamCapability[cameraId]->padding_info, &buf_planes);
7697 strides.add(buf_planes.plane_info.mp[0].stride);
7698 }
7699 staticInfo.update(QCAMERA3_OPAQUE_RAW_STRIDES, strides.array(),
7700 strides.size());
7701
7702 staticInfo.update(QCAMERA3_DUALCAM_CALIB_META_DATA_BLOB,
7703 (const uint8_t*)&gCamCapability[cameraId]->related_cam_calibration,
7704 sizeof(gCamCapability[cameraId]->related_cam_calibration));
7705
7706 uint8_t isMonoOnly =
7707 (gCamCapability[cameraId]->color_arrangement == CAM_FILTER_ARRANGEMENT_Y);
7708 staticInfo.update(QCAMERA3_SENSOR_IS_MONO_ONLY,
7709 &isMonoOnly, 1);
7710
Thierry Strudel9e74aae2016-09-22 17:10:18 -07007711#ifndef USE_HAL_3_3
7712 Vector<int32_t> opaque_size;
7713 for (size_t j = 0; j < scalar_formats_count; j++) {
7714 if (scalar_formats[j] == ANDROID_SCALER_AVAILABLE_FORMATS_RAW_OPAQUE) {
7715 for (size_t i = 0; i < MIN(MAX_SIZES_CNT,
7716 gCamCapability[cameraId]->supported_raw_dim_cnt); i++) {
7717 cam_stream_buf_plane_info_t buf_planes;
7718
7719 rc = mm_stream_calc_offset_raw(fmt, &gCamCapability[cameraId]->raw_dim[i],
7720 &gCamCapability[cameraId]->padding_info, &buf_planes);
7721
7722 if (rc == 0) {
7723 opaque_size.add(gCamCapability[cameraId]->raw_dim[i].width);
7724 opaque_size.add(gCamCapability[cameraId]->raw_dim[i].height);
7725 opaque_size.add(buf_planes.plane_info.frame_len);
7726 }else {
7727 LOGE("raw frame calculation failed!");
7728 }
7729 }
7730 }
7731 }
7732
7733 if ((opaque_size.size() > 0) &&
7734 (opaque_size.size() % PER_CONFIGURATION_SIZE_3 == 0))
7735 staticInfo.update(ANDROID_SENSOR_OPAQUE_RAW_SIZE, opaque_size.array(), opaque_size.size());
7736 else
7737 LOGW("Warning: ANDROID_SENSOR_OPAQUE_RAW_SIZE is using rough estimation(2 bytes/pixel)");
7738#endif
7739
Thierry Strudel3d639192016-09-09 11:52:26 -07007740 gStaticMetadata[cameraId] = staticInfo.release();
7741 return rc;
7742}
7743
7744/*===========================================================================
7745 * FUNCTION : makeTable
7746 *
7747 * DESCRIPTION: make a table of sizes
7748 *
7749 * PARAMETERS :
7750 *
7751 *
7752 *==========================================================================*/
7753void QCamera3HardwareInterface::makeTable(cam_dimension_t* dimTable, size_t size,
7754 size_t max_size, int32_t *sizeTable)
7755{
7756 size_t j = 0;
7757 if (size > max_size) {
7758 size = max_size;
7759 }
7760 for (size_t i = 0; i < size; i++) {
7761 sizeTable[j] = dimTable[i].width;
7762 sizeTable[j+1] = dimTable[i].height;
7763 j+=2;
7764 }
7765}
7766
7767/*===========================================================================
7768 * FUNCTION : makeFPSTable
7769 *
7770 * DESCRIPTION: make a table of fps ranges
7771 *
7772 * PARAMETERS :
7773 *
7774 *==========================================================================*/
7775void QCamera3HardwareInterface::makeFPSTable(cam_fps_range_t* fpsTable, size_t size,
7776 size_t max_size, int32_t *fpsRangesTable)
7777{
7778 size_t j = 0;
7779 if (size > max_size) {
7780 size = max_size;
7781 }
7782 for (size_t i = 0; i < size; i++) {
7783 fpsRangesTable[j] = (int32_t)fpsTable[i].min_fps;
7784 fpsRangesTable[j+1] = (int32_t)fpsTable[i].max_fps;
7785 j+=2;
7786 }
7787}
7788
7789/*===========================================================================
7790 * FUNCTION : makeOverridesList
7791 *
7792 * DESCRIPTION: make a list of scene mode overrides
7793 *
7794 * PARAMETERS :
7795 *
7796 *
7797 *==========================================================================*/
7798void QCamera3HardwareInterface::makeOverridesList(
7799 cam_scene_mode_overrides_t* overridesTable, size_t size, size_t max_size,
7800 uint8_t *overridesList, uint8_t *supported_indexes, uint32_t camera_id)
7801{
7802 /*daemon will give a list of overrides for all scene modes.
7803 However we should send the fwk only the overrides for the scene modes
7804 supported by the framework*/
7805 size_t j = 0;
7806 if (size > max_size) {
7807 size = max_size;
7808 }
7809 size_t focus_count = CAM_FOCUS_MODE_MAX;
7810 focus_count = MIN(gCamCapability[camera_id]->supported_focus_modes_cnt,
7811 focus_count);
7812 for (size_t i = 0; i < size; i++) {
7813 bool supt = false;
7814 size_t index = supported_indexes[i];
7815 overridesList[j] = gCamCapability[camera_id]->flash_available ?
7816 ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH : ANDROID_CONTROL_AE_MODE_ON;
7817 int val = lookupFwkName(WHITE_BALANCE_MODES_MAP,
7818 METADATA_MAP_SIZE(WHITE_BALANCE_MODES_MAP),
7819 overridesTable[index].awb_mode);
7820 if (NAME_NOT_FOUND != val) {
7821 overridesList[j+1] = (uint8_t)val;
7822 }
7823 uint8_t focus_override = overridesTable[index].af_mode;
7824 for (size_t k = 0; k < focus_count; k++) {
7825 if (gCamCapability[camera_id]->supported_focus_modes[k] == focus_override) {
7826 supt = true;
7827 break;
7828 }
7829 }
7830 if (supt) {
7831 val = lookupFwkName(FOCUS_MODES_MAP, METADATA_MAP_SIZE(FOCUS_MODES_MAP),
7832 focus_override);
7833 if (NAME_NOT_FOUND != val) {
7834 overridesList[j+2] = (uint8_t)val;
7835 }
7836 } else {
7837 overridesList[j+2] = ANDROID_CONTROL_AF_MODE_OFF;
7838 }
7839 j+=3;
7840 }
7841}
7842
7843/*===========================================================================
7844 * FUNCTION : filterJpegSizes
7845 *
7846 * DESCRIPTION: Returns the supported jpeg sizes based on the max dimension that
7847 * could be downscaled to
7848 *
7849 * PARAMETERS :
7850 *
7851 * RETURN : length of jpegSizes array
7852 *==========================================================================*/
7853
7854size_t QCamera3HardwareInterface::filterJpegSizes(int32_t *jpegSizes, int32_t *processedSizes,
7855 size_t processedSizesCnt, size_t maxCount, cam_rect_t active_array_size,
7856 uint8_t downscale_factor)
7857{
7858 if (0 == downscale_factor) {
7859 downscale_factor = 1;
7860 }
7861
7862 int32_t min_width = active_array_size.width / downscale_factor;
7863 int32_t min_height = active_array_size.height / downscale_factor;
7864 size_t jpegSizesCnt = 0;
7865 if (processedSizesCnt > maxCount) {
7866 processedSizesCnt = maxCount;
7867 }
7868 for (size_t i = 0; i < processedSizesCnt; i+=2) {
7869 if (processedSizes[i] >= min_width && processedSizes[i+1] >= min_height) {
7870 jpegSizes[jpegSizesCnt] = processedSizes[i];
7871 jpegSizes[jpegSizesCnt+1] = processedSizes[i+1];
7872 jpegSizesCnt += 2;
7873 }
7874 }
7875 return jpegSizesCnt;
7876}
7877
7878/*===========================================================================
7879 * FUNCTION : computeNoiseModelEntryS
7880 *
7881 * DESCRIPTION: function to map a given sensitivity to the S noise
7882 * model parameters in the DNG noise model.
7883 *
7884 * PARAMETERS : sens : the sensor sensitivity
7885 *
7886 ** RETURN : S (sensor amplification) noise
7887 *
7888 *==========================================================================*/
7889double QCamera3HardwareInterface::computeNoiseModelEntryS(int32_t sens) {
7890 double s = gCamCapability[mCameraId]->gradient_S * sens +
7891 gCamCapability[mCameraId]->offset_S;
7892 return ((s < 0.0) ? 0.0 : s);
7893}
7894
7895/*===========================================================================
7896 * FUNCTION : computeNoiseModelEntryO
7897 *
7898 * DESCRIPTION: function to map a given sensitivity to the O noise
7899 * model parameters in the DNG noise model.
7900 *
7901 * PARAMETERS : sens : the sensor sensitivity
7902 *
7903 ** RETURN : O (sensor readout) noise
7904 *
7905 *==========================================================================*/
7906double QCamera3HardwareInterface::computeNoiseModelEntryO(int32_t sens) {
7907 int32_t max_analog_sens = gCamCapability[mCameraId]->max_analog_sensitivity;
7908 double digital_gain = (1.0 * sens / max_analog_sens) < 1.0 ?
7909 1.0 : (1.0 * sens / max_analog_sens);
7910 double o = gCamCapability[mCameraId]->gradient_O * sens * sens +
7911 gCamCapability[mCameraId]->offset_O * digital_gain * digital_gain;
7912 return ((o < 0.0) ? 0.0 : o);
7913}
7914
7915/*===========================================================================
7916 * FUNCTION : getSensorSensitivity
7917 *
7918 * DESCRIPTION: convert iso_mode to an integer value
7919 *
7920 * PARAMETERS : iso_mode : the iso_mode supported by sensor
7921 *
7922 ** RETURN : sensitivity supported by sensor
7923 *
7924 *==========================================================================*/
7925int32_t QCamera3HardwareInterface::getSensorSensitivity(int32_t iso_mode)
7926{
7927 int32_t sensitivity;
7928
7929 switch (iso_mode) {
7930 case CAM_ISO_MODE_100:
7931 sensitivity = 100;
7932 break;
7933 case CAM_ISO_MODE_200:
7934 sensitivity = 200;
7935 break;
7936 case CAM_ISO_MODE_400:
7937 sensitivity = 400;
7938 break;
7939 case CAM_ISO_MODE_800:
7940 sensitivity = 800;
7941 break;
7942 case CAM_ISO_MODE_1600:
7943 sensitivity = 1600;
7944 break;
7945 default:
7946 sensitivity = -1;
7947 break;
7948 }
7949 return sensitivity;
7950}
7951
7952/*===========================================================================
7953 * FUNCTION : getCamInfo
7954 *
7955 * DESCRIPTION: query camera capabilities
7956 *
7957 * PARAMETERS :
7958 * @cameraId : camera Id
7959 * @info : camera info struct to be filled in with camera capabilities
7960 *
7961 * RETURN : int type of status
7962 * NO_ERROR -- success
7963 * none-zero failure code
7964 *==========================================================================*/
7965int QCamera3HardwareInterface::getCamInfo(uint32_t cameraId,
7966 struct camera_info *info)
7967{
7968 ATRACE_CALL();
7969 int rc = 0;
7970
7971 pthread_mutex_lock(&gCamLock);
7972 if (NULL == gCamCapability[cameraId]) {
7973 rc = initCapabilities(cameraId);
7974 if (rc < 0) {
7975 pthread_mutex_unlock(&gCamLock);
7976 return rc;
7977 }
7978 }
7979
7980 if (NULL == gStaticMetadata[cameraId]) {
7981 rc = initStaticMetadata(cameraId);
7982 if (rc < 0) {
7983 pthread_mutex_unlock(&gCamLock);
7984 return rc;
7985 }
7986 }
7987
7988 switch(gCamCapability[cameraId]->position) {
7989 case CAM_POSITION_BACK:
7990 case CAM_POSITION_BACK_AUX:
7991 info->facing = CAMERA_FACING_BACK;
7992 break;
7993
7994 case CAM_POSITION_FRONT:
7995 case CAM_POSITION_FRONT_AUX:
7996 info->facing = CAMERA_FACING_FRONT;
7997 break;
7998
7999 default:
8000 LOGE("Unknown position type %d for camera id:%d",
8001 gCamCapability[cameraId]->position, cameraId);
8002 rc = -1;
8003 break;
8004 }
8005
8006
8007 info->orientation = (int)gCamCapability[cameraId]->sensor_mount_angle;
Thierry Strudel9e74aae2016-09-22 17:10:18 -07008008#ifndef USE_HAL_3_3
8009 info->device_version = CAMERA_DEVICE_API_VERSION_3_4;
8010#else
Thierry Strudel3d639192016-09-09 11:52:26 -07008011 info->device_version = CAMERA_DEVICE_API_VERSION_3_3;
Thierry Strudel9e74aae2016-09-22 17:10:18 -07008012#endif
Thierry Strudel3d639192016-09-09 11:52:26 -07008013 info->static_camera_characteristics = gStaticMetadata[cameraId];
8014
8015 //For now assume both cameras can operate independently.
8016 info->conflicting_devices = NULL;
8017 info->conflicting_devices_length = 0;
8018
8019 //resource cost is 100 * MIN(1.0, m/M),
8020 //where m is throughput requirement with maximum stream configuration
8021 //and M is CPP maximum throughput.
8022 float max_fps = 0.0;
8023 for (uint32_t i = 0;
8024 i < gCamCapability[cameraId]->fps_ranges_tbl_cnt; i++) {
8025 if (max_fps < gCamCapability[cameraId]->fps_ranges_tbl[i].max_fps)
8026 max_fps = gCamCapability[cameraId]->fps_ranges_tbl[i].max_fps;
8027 }
8028 float ratio = 1.0 * MAX_PROCESSED_STREAMS *
8029 gCamCapability[cameraId]->active_array_size.width *
8030 gCamCapability[cameraId]->active_array_size.height * max_fps /
8031 gCamCapability[cameraId]->max_pixel_bandwidth;
8032 info->resource_cost = 100 * MIN(1.0, ratio);
8033 LOGI("camera %d resource cost is %d", cameraId,
8034 info->resource_cost);
8035
8036 pthread_mutex_unlock(&gCamLock);
8037 return rc;
8038}
8039
8040/*===========================================================================
8041 * FUNCTION : translateCapabilityToMetadata
8042 *
8043 * DESCRIPTION: translate the capability into camera_metadata_t
8044 *
8045 * PARAMETERS : type of the request
8046 *
8047 *
8048 * RETURN : success: camera_metadata_t*
8049 * failure: NULL
8050 *
8051 *==========================================================================*/
8052camera_metadata_t* QCamera3HardwareInterface::translateCapabilityToMetadata(int type)
8053{
8054 if (mDefaultMetadata[type] != NULL) {
8055 return mDefaultMetadata[type];
8056 }
8057 //first time we are handling this request
8058 //fill up the metadata structure using the wrapper class
8059 CameraMetadata settings;
8060 //translate from cam_capability_t to camera_metadata_tag_t
8061 static const uint8_t requestType = ANDROID_REQUEST_TYPE_CAPTURE;
8062 settings.update(ANDROID_REQUEST_TYPE, &requestType, 1);
8063 int32_t defaultRequestID = 0;
8064 settings.update(ANDROID_REQUEST_ID, &defaultRequestID, 1);
8065
8066 /* OIS disable */
8067 char ois_prop[PROPERTY_VALUE_MAX];
8068 memset(ois_prop, 0, sizeof(ois_prop));
8069 property_get("persist.camera.ois.disable", ois_prop, "0");
8070 uint8_t ois_disable = (uint8_t)atoi(ois_prop);
8071
8072 /* Force video to use OIS */
8073 char videoOisProp[PROPERTY_VALUE_MAX];
8074 memset(videoOisProp, 0, sizeof(videoOisProp));
8075 property_get("persist.camera.ois.video", videoOisProp, "1");
8076 uint8_t forceVideoOis = (uint8_t)atoi(videoOisProp);
Thierry Strudel3d639192016-09-09 11:52:26 -07008077 uint8_t controlIntent = 0;
8078 uint8_t focusMode;
8079 uint8_t vsMode;
8080 uint8_t optStabMode;
8081 uint8_t cacMode;
8082 uint8_t edge_mode;
8083 uint8_t noise_red_mode;
8084 uint8_t tonemap_mode;
8085 bool highQualityModeEntryAvailable = FALSE;
8086 bool fastModeEntryAvailable = FALSE;
8087 vsMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
8088 optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
8089 switch (type) {
8090 case CAMERA3_TEMPLATE_PREVIEW:
8091 controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
8092 focusMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
8093 optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON;
8094 cacMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST;
8095 edge_mode = ANDROID_EDGE_MODE_FAST;
8096 noise_red_mode = ANDROID_NOISE_REDUCTION_MODE_FAST;
8097 tonemap_mode = ANDROID_TONEMAP_MODE_FAST;
8098 break;
8099 case CAMERA3_TEMPLATE_STILL_CAPTURE:
8100 controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
8101 focusMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
8102 optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON;
8103 edge_mode = ANDROID_EDGE_MODE_HIGH_QUALITY;
8104 noise_red_mode = ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY;
8105 tonemap_mode = ANDROID_TONEMAP_MODE_HIGH_QUALITY;
8106 cacMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
8107 // Order of priority for default CAC is HIGH Quality -> FAST -> OFF
8108 for (size_t i = 0; i < gCamCapability[mCameraId]->aberration_modes_count; i++) {
8109 if (gCamCapability[mCameraId]->aberration_modes[i] ==
8110 CAM_COLOR_CORRECTION_ABERRATION_HIGH_QUALITY) {
8111 highQualityModeEntryAvailable = TRUE;
8112 } else if (gCamCapability[mCameraId]->aberration_modes[i] ==
8113 CAM_COLOR_CORRECTION_ABERRATION_FAST) {
8114 fastModeEntryAvailable = TRUE;
8115 }
8116 }
8117 if (highQualityModeEntryAvailable) {
8118 cacMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY;
8119 } else if (fastModeEntryAvailable) {
8120 cacMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST;
8121 }
8122 break;
8123 case CAMERA3_TEMPLATE_VIDEO_RECORD:
8124 controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
8125 focusMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO;
8126 optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
Thierry Strudel3d639192016-09-09 11:52:26 -07008127 cacMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST;
8128 edge_mode = ANDROID_EDGE_MODE_FAST;
8129 noise_red_mode = ANDROID_NOISE_REDUCTION_MODE_FAST;
8130 tonemap_mode = ANDROID_TONEMAP_MODE_FAST;
8131 if (forceVideoOis)
8132 optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON;
8133 break;
8134 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
8135 controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
8136 focusMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO;
8137 optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
Thierry Strudel3d639192016-09-09 11:52:26 -07008138 cacMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST;
8139 edge_mode = ANDROID_EDGE_MODE_FAST;
8140 noise_red_mode = ANDROID_NOISE_REDUCTION_MODE_FAST;
8141 tonemap_mode = ANDROID_TONEMAP_MODE_FAST;
8142 if (forceVideoOis)
8143 optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON;
8144 break;
8145 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
8146 controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG;
8147 focusMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
8148 optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON;
8149 cacMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST;
8150 edge_mode = ANDROID_EDGE_MODE_ZERO_SHUTTER_LAG;
8151 noise_red_mode = ANDROID_NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG;
8152 tonemap_mode = ANDROID_TONEMAP_MODE_FAST;
8153 break;
8154 case CAMERA3_TEMPLATE_MANUAL:
8155 edge_mode = ANDROID_EDGE_MODE_FAST;
8156 noise_red_mode = ANDROID_NOISE_REDUCTION_MODE_FAST;
8157 tonemap_mode = ANDROID_TONEMAP_MODE_FAST;
8158 cacMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST;
8159 controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL;
8160 focusMode = ANDROID_CONTROL_AF_MODE_OFF;
8161 optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
8162 break;
8163 default:
8164 edge_mode = ANDROID_EDGE_MODE_FAST;
8165 noise_red_mode = ANDROID_NOISE_REDUCTION_MODE_FAST;
8166 tonemap_mode = ANDROID_TONEMAP_MODE_FAST;
8167 cacMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST;
8168 controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_CUSTOM;
8169 focusMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
8170 optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
8171 break;
8172 }
8173 settings.update(ANDROID_COLOR_CORRECTION_ABERRATION_MODE, &cacMode, 1);
8174 settings.update(ANDROID_CONTROL_CAPTURE_INTENT, &controlIntent, 1);
8175 settings.update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &vsMode, 1);
8176 if (gCamCapability[mCameraId]->supported_focus_modes_cnt == 1) {
8177 focusMode = ANDROID_CONTROL_AF_MODE_OFF;
8178 }
8179 settings.update(ANDROID_CONTROL_AF_MODE, &focusMode, 1);
8180
8181 if (gCamCapability[mCameraId]->optical_stab_modes_count == 1 &&
8182 gCamCapability[mCameraId]->optical_stab_modes[0] == CAM_OPT_STAB_ON)
8183 optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON;
8184 else if ((gCamCapability[mCameraId]->optical_stab_modes_count == 1 &&
8185 gCamCapability[mCameraId]->optical_stab_modes[0] == CAM_OPT_STAB_OFF)
8186 || ois_disable)
8187 optStabMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
8188 settings.update(ANDROID_LENS_OPTICAL_STABILIZATION_MODE, &optStabMode, 1);
8189
8190 settings.update(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
8191 &gCamCapability[mCameraId]->exposure_compensation_default, 1);
8192
8193 static const uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
8194 settings.update(ANDROID_CONTROL_AE_LOCK, &aeLock, 1);
8195
8196 static const uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
8197 settings.update(ANDROID_CONTROL_AWB_LOCK, &awbLock, 1);
8198
8199 static const uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
8200 settings.update(ANDROID_CONTROL_AWB_MODE, &awbMode, 1);
8201
8202 static const uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
8203 settings.update(ANDROID_CONTROL_MODE, &controlMode, 1);
8204
8205 static const uint8_t effectMode = ANDROID_CONTROL_EFFECT_MODE_OFF;
8206 settings.update(ANDROID_CONTROL_EFFECT_MODE, &effectMode, 1);
8207
8208 static const uint8_t sceneMode = ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY;
8209 settings.update(ANDROID_CONTROL_SCENE_MODE, &sceneMode, 1);
8210
8211 static const uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
8212 settings.update(ANDROID_CONTROL_AE_MODE, &aeMode, 1);
8213
8214 /*flash*/
8215 static const uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
8216 settings.update(ANDROID_FLASH_MODE, &flashMode, 1);
8217
8218 static const uint8_t flashFiringLevel = CAM_FLASH_FIRING_LEVEL_4;
8219 settings.update(ANDROID_FLASH_FIRING_POWER,
8220 &flashFiringLevel, 1);
8221
8222 /* lens */
8223 float default_aperture = gCamCapability[mCameraId]->apertures[0];
8224 settings.update(ANDROID_LENS_APERTURE, &default_aperture, 1);
8225
8226 if (gCamCapability[mCameraId]->filter_densities_count) {
8227 float default_filter_density = gCamCapability[mCameraId]->filter_densities[0];
8228 settings.update(ANDROID_LENS_FILTER_DENSITY, &default_filter_density,
8229 gCamCapability[mCameraId]->filter_densities_count);
8230 }
8231
8232 float default_focal_length = gCamCapability[mCameraId]->focal_length;
8233 settings.update(ANDROID_LENS_FOCAL_LENGTH, &default_focal_length, 1);
8234
8235 if (focusMode == ANDROID_CONTROL_AF_MODE_OFF) {
8236 float default_focus_distance = 0;
8237 settings.update(ANDROID_LENS_FOCUS_DISTANCE, &default_focus_distance, 1);
8238 }
8239
8240 static const uint8_t demosaicMode = ANDROID_DEMOSAIC_MODE_FAST;
8241 settings.update(ANDROID_DEMOSAIC_MODE, &demosaicMode, 1);
8242
8243 static const uint8_t hotpixelMode = ANDROID_HOT_PIXEL_MODE_FAST;
8244 settings.update(ANDROID_HOT_PIXEL_MODE, &hotpixelMode, 1);
8245
8246 static const int32_t testpatternMode = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF;
8247 settings.update(ANDROID_SENSOR_TEST_PATTERN_MODE, &testpatternMode, 1);
8248
8249 /* face detection (default to OFF) */
8250 static const uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
8251 settings.update(ANDROID_STATISTICS_FACE_DETECT_MODE, &faceDetectMode, 1);
8252
8253 static const uint8_t histogramMode = ANDROID_STATISTICS_HISTOGRAM_MODE_OFF;
8254 settings.update(ANDROID_STATISTICS_HISTOGRAM_MODE, &histogramMode, 1);
8255
8256 static const uint8_t sharpnessMapMode = ANDROID_STATISTICS_SHARPNESS_MAP_MODE_OFF;
8257 settings.update(ANDROID_STATISTICS_SHARPNESS_MAP_MODE, &sharpnessMapMode, 1);
8258
8259 static const uint8_t hotPixelMapMode = ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF;
8260 settings.update(ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE, &hotPixelMapMode, 1);
8261
8262 static const uint8_t lensShadingMode = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
8263 settings.update(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, &lensShadingMode, 1);
8264
8265 static const uint8_t blackLevelLock = ANDROID_BLACK_LEVEL_LOCK_OFF;
8266 settings.update(ANDROID_BLACK_LEVEL_LOCK, &blackLevelLock, 1);
8267
8268 /* Exposure time(Update the Min Exposure Time)*/
8269 int64_t default_exposure_time = gCamCapability[mCameraId]->exposure_time_range[0];
8270 settings.update(ANDROID_SENSOR_EXPOSURE_TIME, &default_exposure_time, 1);
8271
8272 /* frame duration */
8273 static const int64_t default_frame_duration = NSEC_PER_33MSEC;
8274 settings.update(ANDROID_SENSOR_FRAME_DURATION, &default_frame_duration, 1);
8275
8276 /* sensitivity */
8277 static const int32_t default_sensitivity = 100;
8278 settings.update(ANDROID_SENSOR_SENSITIVITY, &default_sensitivity, 1);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07008279#ifndef USE_HAL_3_3
8280 static const int32_t default_isp_sensitivity =
8281 gCamCapability[mCameraId]->isp_sensitivity_range.min_sensitivity;
8282 settings.update(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST, &default_isp_sensitivity, 1);
8283#endif
Thierry Strudel3d639192016-09-09 11:52:26 -07008284
8285 /*edge mode*/
8286 settings.update(ANDROID_EDGE_MODE, &edge_mode, 1);
8287
8288 /*noise reduction mode*/
8289 settings.update(ANDROID_NOISE_REDUCTION_MODE, &noise_red_mode, 1);
8290
8291 /*color correction mode*/
8292 static const uint8_t color_correct_mode = ANDROID_COLOR_CORRECTION_MODE_FAST;
8293 settings.update(ANDROID_COLOR_CORRECTION_MODE, &color_correct_mode, 1);
8294
8295 /*transform matrix mode*/
8296 settings.update(ANDROID_TONEMAP_MODE, &tonemap_mode, 1);
8297
8298 int32_t scaler_crop_region[4];
8299 scaler_crop_region[0] = 0;
8300 scaler_crop_region[1] = 0;
8301 scaler_crop_region[2] = gCamCapability[mCameraId]->active_array_size.width;
8302 scaler_crop_region[3] = gCamCapability[mCameraId]->active_array_size.height;
8303 settings.update(ANDROID_SCALER_CROP_REGION, scaler_crop_region, 4);
8304
8305 static const uint8_t antibanding_mode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
8306 settings.update(ANDROID_CONTROL_AE_ANTIBANDING_MODE, &antibanding_mode, 1);
8307
8308 /*focus distance*/
8309 float focus_distance = 0.0;
8310 settings.update(ANDROID_LENS_FOCUS_DISTANCE, &focus_distance, 1);
8311
8312 /*target fps range: use maximum range for picture, and maximum fixed range for video*/
8313 float max_range = 0.0;
8314 float max_fixed_fps = 0.0;
8315 int32_t fps_range[2] = {0, 0};
8316 for (uint32_t i = 0; i < gCamCapability[mCameraId]->fps_ranges_tbl_cnt;
8317 i++) {
8318 float range = gCamCapability[mCameraId]->fps_ranges_tbl[i].max_fps -
8319 gCamCapability[mCameraId]->fps_ranges_tbl[i].min_fps;
8320 if (type == CAMERA3_TEMPLATE_PREVIEW ||
8321 type == CAMERA3_TEMPLATE_STILL_CAPTURE ||
8322 type == CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG) {
8323 if (range > max_range) {
8324 fps_range[0] =
8325 (int32_t)gCamCapability[mCameraId]->fps_ranges_tbl[i].min_fps;
8326 fps_range[1] =
8327 (int32_t)gCamCapability[mCameraId]->fps_ranges_tbl[i].max_fps;
8328 max_range = range;
8329 }
8330 } else {
8331 if (range < 0.01 && max_fixed_fps <
8332 gCamCapability[mCameraId]->fps_ranges_tbl[i].max_fps) {
8333 fps_range[0] =
8334 (int32_t)gCamCapability[mCameraId]->fps_ranges_tbl[i].min_fps;
8335 fps_range[1] =
8336 (int32_t)gCamCapability[mCameraId]->fps_ranges_tbl[i].max_fps;
8337 max_fixed_fps = gCamCapability[mCameraId]->fps_ranges_tbl[i].max_fps;
8338 }
8339 }
8340 }
8341 settings.update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, fps_range, 2);
8342
8343 /*precapture trigger*/
8344 uint8_t precapture_trigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
8345 settings.update(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, &precapture_trigger, 1);
8346
8347 /*af trigger*/
8348 uint8_t af_trigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
8349 settings.update(ANDROID_CONTROL_AF_TRIGGER, &af_trigger, 1);
8350
8351 /* ae & af regions */
8352 int32_t active_region[] = {
8353 gCamCapability[mCameraId]->active_array_size.left,
8354 gCamCapability[mCameraId]->active_array_size.top,
8355 gCamCapability[mCameraId]->active_array_size.left +
8356 gCamCapability[mCameraId]->active_array_size.width,
8357 gCamCapability[mCameraId]->active_array_size.top +
8358 gCamCapability[mCameraId]->active_array_size.height,
8359 0};
8360 settings.update(ANDROID_CONTROL_AE_REGIONS, active_region,
8361 sizeof(active_region) / sizeof(active_region[0]));
8362 settings.update(ANDROID_CONTROL_AF_REGIONS, active_region,
8363 sizeof(active_region) / sizeof(active_region[0]));
8364
8365 /* black level lock */
8366 uint8_t blacklevel_lock = ANDROID_BLACK_LEVEL_LOCK_OFF;
8367 settings.update(ANDROID_BLACK_LEVEL_LOCK, &blacklevel_lock, 1);
8368
8369 /* lens shading map mode */
8370 uint8_t shadingmap_mode = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
8371 if (CAM_SENSOR_RAW == gCamCapability[mCameraId]->sensor_type.sens_type) {
8372 shadingmap_mode = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON;
8373 }
8374 settings.update(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, &shadingmap_mode, 1);
8375
8376 //special defaults for manual template
8377 if (type == CAMERA3_TEMPLATE_MANUAL) {
8378 static const uint8_t manualControlMode = ANDROID_CONTROL_MODE_OFF;
8379 settings.update(ANDROID_CONTROL_MODE, &manualControlMode, 1);
8380
8381 static const uint8_t manualFocusMode = ANDROID_CONTROL_AF_MODE_OFF;
8382 settings.update(ANDROID_CONTROL_AF_MODE, &manualFocusMode, 1);
8383
8384 static const uint8_t manualAeMode = ANDROID_CONTROL_AE_MODE_OFF;
8385 settings.update(ANDROID_CONTROL_AE_MODE, &manualAeMode, 1);
8386
8387 static const uint8_t manualAwbMode = ANDROID_CONTROL_AWB_MODE_OFF;
8388 settings.update(ANDROID_CONTROL_AWB_MODE, &manualAwbMode, 1);
8389
8390 static const uint8_t manualTonemapMode = ANDROID_TONEMAP_MODE_FAST;
8391 settings.update(ANDROID_TONEMAP_MODE, &manualTonemapMode, 1);
8392
8393 static const uint8_t manualColorCorrectMode = ANDROID_COLOR_CORRECTION_MODE_TRANSFORM_MATRIX;
8394 settings.update(ANDROID_COLOR_CORRECTION_MODE, &manualColorCorrectMode, 1);
8395 }
8396
8397
8398 /* TNR
8399 * We'll use this location to determine which modes TNR will be set.
8400 * We will enable TNR to be on if either of the Preview/Video stream requires TNR
8401 * This is not to be confused with linking on a per stream basis that decision
8402 * is still on per-session basis and will be handled as part of config stream
8403 */
8404 uint8_t tnr_enable = 0;
8405
8406 if (m_bTnrPreview || m_bTnrVideo) {
8407
8408 switch (type) {
8409 case CAMERA3_TEMPLATE_VIDEO_RECORD:
8410 tnr_enable = 1;
8411 break;
8412
8413 default:
8414 tnr_enable = 0;
8415 break;
8416 }
8417
8418 int32_t tnr_process_type = (int32_t)getTemporalDenoiseProcessPlate();
8419 settings.update(QCAMERA3_TEMPORAL_DENOISE_ENABLE, &tnr_enable, 1);
8420 settings.update(QCAMERA3_TEMPORAL_DENOISE_PROCESS_TYPE, &tnr_process_type, 1);
8421
8422 LOGD("TNR:%d with process plate %d for template:%d",
8423 tnr_enable, tnr_process_type, type);
8424 }
8425
8426 //Update Link tags to default
8427 int32_t sync_type = CAM_TYPE_STANDALONE;
8428 settings.update(QCAMERA3_DUALCAM_LINK_ENABLE, &sync_type, 1);
8429
8430 int32_t is_main = 0; //this doesn't matter as app should overwrite
8431 settings.update(QCAMERA3_DUALCAM_LINK_IS_MAIN, &is_main, 1);
8432
8433 settings.update(QCAMERA3_DUALCAM_LINK_RELATED_CAMERA_ID, &is_main, 1);
8434
8435 /* CDS default */
8436 char prop[PROPERTY_VALUE_MAX];
8437 memset(prop, 0, sizeof(prop));
8438 property_get("persist.camera.CDS", prop, "Auto");
8439 cam_cds_mode_type_t cds_mode = CAM_CDS_MODE_AUTO;
8440 cds_mode = lookupProp(CDS_MAP, METADATA_MAP_SIZE(CDS_MAP), prop);
8441 if (CAM_CDS_MODE_MAX == cds_mode) {
8442 cds_mode = CAM_CDS_MODE_AUTO;
8443 }
8444
8445 /* Disabling CDS in templates which have TNR enabled*/
8446 if (tnr_enable)
8447 cds_mode = CAM_CDS_MODE_OFF;
8448
8449 int32_t mode = cds_mode;
8450 settings.update(QCAMERA3_CDS_MODE, &mode, 1);
8451 mDefaultMetadata[type] = settings.release();
8452
8453 return mDefaultMetadata[type];
8454}
8455
8456/*===========================================================================
8457 * FUNCTION : setFrameParameters
8458 *
8459 * DESCRIPTION: set parameters per frame as requested in the metadata from
8460 * framework
8461 *
8462 * PARAMETERS :
8463 * @request : request that needs to be serviced
8464 * @streamID : Stream ID of all the requested streams
8465 * @blob_request: Whether this request is a blob request or not
8466 *
8467 * RETURN : success: NO_ERROR
8468 * failure:
8469 *==========================================================================*/
8470int QCamera3HardwareInterface::setFrameParameters(
8471 camera3_capture_request_t *request,
8472 cam_stream_ID_t streamID,
8473 int blob_request,
8474 uint32_t snapshotStreamId)
8475{
8476 /*translate from camera_metadata_t type to parm_type_t*/
8477 int rc = 0;
8478 int32_t hal_version = CAM_HAL_V3;
8479
8480 clear_metadata_buffer(mParameters);
8481 if (ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_PARM_HAL_VERSION, hal_version)) {
8482 LOGE("Failed to set hal version in the parameters");
8483 return BAD_VALUE;
8484 }
8485
8486 /*we need to update the frame number in the parameters*/
8487 if (ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_META_FRAME_NUMBER,
8488 request->frame_number)) {
8489 LOGE("Failed to set the frame number in the parameters");
8490 return BAD_VALUE;
8491 }
8492
8493 /* Update stream id of all the requested buffers */
8494 if (ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_META_STREAM_ID, streamID)) {
8495 LOGE("Failed to set stream type mask in the parameters");
8496 return BAD_VALUE;
8497 }
8498
8499 if (mUpdateDebugLevel) {
8500 uint32_t dummyDebugLevel = 0;
8501 /* The value of dummyDebugLevel is irrelavent. On
8502 * CAM_INTF_PARM_UPDATE_DEBUG_LEVEL, read debug property */
8503 if (ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_PARM_UPDATE_DEBUG_LEVEL,
8504 dummyDebugLevel)) {
8505 LOGE("Failed to set UPDATE_DEBUG_LEVEL");
8506 return BAD_VALUE;
8507 }
8508 mUpdateDebugLevel = false;
8509 }
8510
8511 if(request->settings != NULL){
8512 rc = translateToHalMetadata(request, mParameters, snapshotStreamId);
8513 if (blob_request)
8514 memcpy(mPrevParameters, mParameters, sizeof(metadata_buffer_t));
8515 }
8516
8517 return rc;
8518}
8519
8520/*===========================================================================
8521 * FUNCTION : setReprocParameters
8522 *
8523 * DESCRIPTION: Translate frameworks metadata to HAL metadata structure, and
8524 * return it.
8525 *
8526 * PARAMETERS :
8527 * @request : request that needs to be serviced
8528 *
8529 * RETURN : success: NO_ERROR
8530 * failure:
8531 *==========================================================================*/
8532int32_t QCamera3HardwareInterface::setReprocParameters(
8533 camera3_capture_request_t *request, metadata_buffer_t *reprocParam,
8534 uint32_t snapshotStreamId)
8535{
8536 /*translate from camera_metadata_t type to parm_type_t*/
8537 int rc = 0;
8538
8539 if (NULL == request->settings){
8540 LOGE("Reprocess settings cannot be NULL");
8541 return BAD_VALUE;
8542 }
8543
8544 if (NULL == reprocParam) {
8545 LOGE("Invalid reprocessing metadata buffer");
8546 return BAD_VALUE;
8547 }
8548 clear_metadata_buffer(reprocParam);
8549
8550 /*we need to update the frame number in the parameters*/
8551 if (ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_FRAME_NUMBER,
8552 request->frame_number)) {
8553 LOGE("Failed to set the frame number in the parameters");
8554 return BAD_VALUE;
8555 }
8556
8557 rc = translateToHalMetadata(request, reprocParam, snapshotStreamId);
8558 if (rc < 0) {
8559 LOGE("Failed to translate reproc request");
8560 return rc;
8561 }
8562
8563 CameraMetadata frame_settings;
8564 frame_settings = request->settings;
8565 if (frame_settings.exists(QCAMERA3_CROP_COUNT_REPROCESS) &&
8566 frame_settings.exists(QCAMERA3_CROP_REPROCESS)) {
8567 int32_t *crop_count =
8568 frame_settings.find(QCAMERA3_CROP_COUNT_REPROCESS).data.i32;
8569 int32_t *crop_data =
8570 frame_settings.find(QCAMERA3_CROP_REPROCESS).data.i32;
8571 int32_t *roi_map =
8572 frame_settings.find(QCAMERA3_CROP_ROI_MAP_REPROCESS).data.i32;
8573 if ((0 < *crop_count) && (*crop_count < MAX_NUM_STREAMS)) {
8574 cam_crop_data_t crop_meta;
8575 memset(&crop_meta, 0, sizeof(cam_crop_data_t));
8576 crop_meta.num_of_streams = 1;
8577 crop_meta.crop_info[0].crop.left = crop_data[0];
8578 crop_meta.crop_info[0].crop.top = crop_data[1];
8579 crop_meta.crop_info[0].crop.width = crop_data[2];
8580 crop_meta.crop_info[0].crop.height = crop_data[3];
8581
8582 crop_meta.crop_info[0].roi_map.left =
8583 roi_map[0];
8584 crop_meta.crop_info[0].roi_map.top =
8585 roi_map[1];
8586 crop_meta.crop_info[0].roi_map.width =
8587 roi_map[2];
8588 crop_meta.crop_info[0].roi_map.height =
8589 roi_map[3];
8590
8591 if (ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_CROP_DATA, crop_meta)) {
8592 rc = BAD_VALUE;
8593 }
8594 LOGD("Found reprocess crop data for stream %p %dx%d, %dx%d",
8595 request->input_buffer->stream,
8596 crop_meta.crop_info[0].crop.left,
8597 crop_meta.crop_info[0].crop.top,
8598 crop_meta.crop_info[0].crop.width,
8599 crop_meta.crop_info[0].crop.height);
8600 LOGD("Found reprocess roi map data for stream %p %dx%d, %dx%d",
8601 request->input_buffer->stream,
8602 crop_meta.crop_info[0].roi_map.left,
8603 crop_meta.crop_info[0].roi_map.top,
8604 crop_meta.crop_info[0].roi_map.width,
8605 crop_meta.crop_info[0].roi_map.height);
8606 } else {
8607 LOGE("Invalid reprocess crop count %d!", *crop_count);
8608 }
8609 } else {
8610 LOGE("No crop data from matching output stream");
8611 }
8612
8613 /* These settings are not needed for regular requests so handle them specially for
8614 reprocess requests; information needed for EXIF tags */
8615 if (frame_settings.exists(ANDROID_FLASH_MODE)) {
8616 int val = lookupHalName(FLASH_MODES_MAP, METADATA_MAP_SIZE(FLASH_MODES_MAP),
8617 (int)frame_settings.find(ANDROID_FLASH_MODE).data.u8[0]);
8618 if (NAME_NOT_FOUND != val) {
8619 uint32_t flashMode = (uint32_t)val;
8620 if (ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_FLASH_MODE, flashMode)) {
8621 rc = BAD_VALUE;
8622 }
8623 } else {
8624 LOGE("Could not map fwk flash mode %d to correct hal flash mode",
8625 frame_settings.find(ANDROID_FLASH_MODE).data.u8[0]);
8626 }
8627 } else {
8628 LOGH("No flash mode in reprocess settings");
8629 }
8630
8631 if (frame_settings.exists(ANDROID_FLASH_STATE)) {
8632 int32_t flashState = (int32_t)frame_settings.find(ANDROID_FLASH_STATE).data.u8[0];
8633 if (ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_FLASH_STATE, flashState)) {
8634 rc = BAD_VALUE;
8635 }
8636 } else {
8637 LOGH("No flash state in reprocess settings");
8638 }
8639
8640 if (frame_settings.exists(QCAMERA3_HAL_PRIVATEDATA_REPROCESS_FLAGS)) {
8641 uint8_t *reprocessFlags =
8642 frame_settings.find(QCAMERA3_HAL_PRIVATEDATA_REPROCESS_FLAGS).data.u8;
8643 if (ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_REPROCESS_FLAGS,
8644 *reprocessFlags)) {
8645 rc = BAD_VALUE;
8646 }
8647 }
8648
8649 // Add metadata which DDM needs
8650 if (frame_settings.exists(QCAMERA3_HAL_PRIVATEDATA_DDM_DATA_BLOB)) {
8651 cam_ddm_info_t *ddm_info =
8652 (cam_ddm_info_t *)frame_settings.find
8653 (QCAMERA3_HAL_PRIVATEDATA_DDM_DATA_BLOB).data.u8;
8654 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_SNAP_CROP_INFO_SENSOR,
8655 ddm_info->sensor_crop_info);
8656 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_SNAP_CROP_INFO_CAMIF,
8657 ddm_info->camif_crop_info);
8658 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_SNAP_CROP_INFO_ISP,
8659 ddm_info->isp_crop_info);
8660 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_SNAP_CROP_INFO_CPP,
8661 ddm_info->cpp_crop_info);
8662 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_AF_FOCAL_LENGTH_RATIO,
8663 ddm_info->af_focal_length_ratio);
8664 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_PARM_FLIP,
8665 ddm_info->pipeline_flip);
8666 /* If there is ANDROID_JPEG_ORIENTATION in frame setting,
8667 CAM_INTF_PARM_ROTATION metadata then has been added in
8668 translateToHalMetadata. HAL need to keep this new rotation
8669 metadata. Otherwise, the old rotation info saved in the vendor tag
8670 would be used */
8671 IF_META_AVAILABLE(cam_rotation_info_t, rotationInfo,
8672 CAM_INTF_PARM_ROTATION, reprocParam) {
8673 LOGD("CAM_INTF_PARM_ROTATION metadata is added in translateToHalMetadata");
8674 } else {
8675 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_PARM_ROTATION,
8676 ddm_info->rotation_info);
8677 }
Thierry Strudel3d639192016-09-09 11:52:26 -07008678 }
8679
8680 /* Add additional JPEG cropping information. App add QCAMERA3_JPEG_ENCODE_CROP_RECT
8681 to ask for cropping and use ROI for downscale/upscale during HW JPEG encoding.
8682 roi.width and roi.height would be the final JPEG size.
8683 For now, HAL only checks this for reprocess request */
8684 if (frame_settings.exists(QCAMERA3_JPEG_ENCODE_CROP_ENABLE) &&
8685 frame_settings.exists(QCAMERA3_JPEG_ENCODE_CROP_RECT)) {
8686 uint8_t *enable =
8687 frame_settings.find(QCAMERA3_JPEG_ENCODE_CROP_ENABLE).data.u8;
8688 if (*enable == TRUE) {
8689 int32_t *crop_data =
8690 frame_settings.find(QCAMERA3_JPEG_ENCODE_CROP_RECT).data.i32;
8691 cam_stream_crop_info_t crop_meta;
8692 memset(&crop_meta, 0, sizeof(cam_stream_crop_info_t));
8693 crop_meta.stream_id = 0;
8694 crop_meta.crop.left = crop_data[0];
8695 crop_meta.crop.top = crop_data[1];
8696 crop_meta.crop.width = crop_data[2];
8697 crop_meta.crop.height = crop_data[3];
Thierry Strudel9e74aae2016-09-22 17:10:18 -07008698 // The JPEG crop roi should match cpp output size
8699 IF_META_AVAILABLE(cam_stream_crop_info_t, cpp_crop,
8700 CAM_INTF_META_SNAP_CROP_INFO_CPP, reprocParam) {
8701 crop_meta.roi_map.left = 0;
8702 crop_meta.roi_map.top = 0;
8703 crop_meta.roi_map.width = cpp_crop->crop.width;
8704 crop_meta.roi_map.height = cpp_crop->crop.height;
Thierry Strudel3d639192016-09-09 11:52:26 -07008705 }
8706 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_PARM_JPEG_ENCODE_CROP,
8707 crop_meta);
Thierry Strudel9e74aae2016-09-22 17:10:18 -07008708 LOGH("Add JPEG encode crop left %d, top %d, width %d, height %d, mCameraId %d",
Thierry Strudel3d639192016-09-09 11:52:26 -07008709 crop_meta.crop.left, crop_meta.crop.top,
Thierry Strudel9e74aae2016-09-22 17:10:18 -07008710 crop_meta.crop.width, crop_meta.crop.height, mCameraId);
8711 LOGH("Add JPEG encode crop ROI left %d, top %d, width %d, height %d, mCameraId %d",
Thierry Strudel3d639192016-09-09 11:52:26 -07008712 crop_meta.roi_map.left, crop_meta.roi_map.top,
Thierry Strudel9e74aae2016-09-22 17:10:18 -07008713 crop_meta.roi_map.width, crop_meta.roi_map.height, mCameraId);
8714
8715 // Add JPEG scale information
8716 cam_dimension_t scale_dim;
8717 memset(&scale_dim, 0, sizeof(cam_dimension_t));
8718 if (frame_settings.exists(QCAMERA3_JPEG_ENCODE_CROP_ROI)) {
8719 int32_t *roi =
8720 frame_settings.find(QCAMERA3_JPEG_ENCODE_CROP_ROI).data.i32;
8721 scale_dim.width = roi[2];
8722 scale_dim.height = roi[3];
8723 ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_PARM_JPEG_SCALE_DIMENSION,
8724 scale_dim);
8725 LOGH("Add JPEG encode scale width %d, height %d, mCameraId %d",
8726 scale_dim.width, scale_dim.height, mCameraId);
8727 }
Thierry Strudel3d639192016-09-09 11:52:26 -07008728 }
8729 }
8730
8731 return rc;
8732}
8733
8734/*===========================================================================
8735 * FUNCTION : saveRequestSettings
8736 *
8737 * DESCRIPTION: Add any settings that might have changed to the request settings
8738 * and save the settings to be applied on the frame
8739 *
8740 * PARAMETERS :
8741 * @jpegMetadata : the extracted and/or modified jpeg metadata
8742 * @request : request with initial settings
8743 *
8744 * RETURN :
8745 * camera_metadata_t* : pointer to the saved request settings
8746 *==========================================================================*/
8747camera_metadata_t* QCamera3HardwareInterface::saveRequestSettings(
8748 const CameraMetadata &jpegMetadata,
8749 camera3_capture_request_t *request)
8750{
8751 camera_metadata_t *resultMetadata;
8752 CameraMetadata camMetadata;
8753 camMetadata = request->settings;
8754
8755 if (jpegMetadata.exists(ANDROID_JPEG_THUMBNAIL_SIZE)) {
8756 int32_t thumbnail_size[2];
8757 thumbnail_size[0] = jpegMetadata.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[0];
8758 thumbnail_size[1] = jpegMetadata.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[1];
8759 camMetadata.update(ANDROID_JPEG_THUMBNAIL_SIZE, thumbnail_size,
8760 jpegMetadata.find(ANDROID_JPEG_THUMBNAIL_SIZE).count);
8761 }
8762
8763 if (request->input_buffer != NULL) {
8764 uint8_t reprocessFlags = 1;
8765 camMetadata.update(QCAMERA3_HAL_PRIVATEDATA_REPROCESS_FLAGS,
8766 (uint8_t*)&reprocessFlags,
8767 sizeof(reprocessFlags));
8768 }
8769
8770 resultMetadata = camMetadata.release();
8771 return resultMetadata;
8772}
8773
8774/*===========================================================================
8775 * FUNCTION : setHalFpsRange
8776 *
8777 * DESCRIPTION: set FPS range parameter
8778 *
8779 *
8780 * PARAMETERS :
8781 * @settings : Metadata from framework
8782 * @hal_metadata: Metadata buffer
8783 *
8784 *
8785 * RETURN : success: NO_ERROR
8786 * failure:
8787 *==========================================================================*/
8788int32_t QCamera3HardwareInterface::setHalFpsRange(const CameraMetadata &settings,
8789 metadata_buffer_t *hal_metadata)
8790{
8791 int32_t rc = NO_ERROR;
8792 cam_fps_range_t fps_range;
8793 fps_range.min_fps = (float)
8794 settings.find(ANDROID_CONTROL_AE_TARGET_FPS_RANGE).data.i32[0];
8795 fps_range.max_fps = (float)
8796 settings.find(ANDROID_CONTROL_AE_TARGET_FPS_RANGE).data.i32[1];
8797 fps_range.video_min_fps = fps_range.min_fps;
8798 fps_range.video_max_fps = fps_range.max_fps;
8799
8800 LOGD("aeTargetFpsRange fps: [%f %f]",
8801 fps_range.min_fps, fps_range.max_fps);
8802 /* In CONSTRAINED_HFR_MODE, sensor_fps is derived from aeTargetFpsRange as
8803 * follows:
8804 * ---------------------------------------------------------------|
8805 * Video stream is absent in configure_streams |
8806 * (Camcorder preview before the first video record |
8807 * ---------------------------------------------------------------|
8808 * vid_buf_requested | aeTgtFpsRng | snsrFpsMode | sensorFpsRange |
8809 * | | | vid_min/max_fps|
8810 * ---------------------------------------------------------------|
8811 * NO | [ 30, 240] | 240 | [240, 240] |
8812 * |-------------|-------------|----------------|
8813 * | [240, 240] | 240 | [240, 240] |
8814 * ---------------------------------------------------------------|
8815 * Video stream is present in configure_streams |
8816 * ---------------------------------------------------------------|
8817 * vid_buf_requested | aeTgtFpsRng | snsrFpsMode | sensorFpsRange |
8818 * | | | vid_min/max_fps|
8819 * ---------------------------------------------------------------|
8820 * NO | [ 30, 240] | 240 | [240, 240] |
8821 * (camcorder prev |-------------|-------------|----------------|
8822 * after video rec | [240, 240] | 240 | [240, 240] |
8823 * is stopped) | | | |
8824 * ---------------------------------------------------------------|
8825 * YES | [ 30, 240] | 240 | [240, 240] |
8826 * |-------------|-------------|----------------|
8827 * | [240, 240] | 240 | [240, 240] |
8828 * ---------------------------------------------------------------|
8829 * When Video stream is absent in configure_streams,
8830 * preview fps = sensor_fps / batchsize
8831 * Eg: for 240fps at batchSize 4, preview = 60fps
8832 * for 120fps at batchSize 4, preview = 30fps
8833 *
8834 * When video stream is present in configure_streams, preview fps is as per
8835 * the ratio of preview buffers to video buffers requested in process
8836 * capture request
8837 */
8838 mBatchSize = 0;
8839 if (CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE == mOpMode) {
8840 fps_range.min_fps = fps_range.video_max_fps;
8841 fps_range.video_min_fps = fps_range.video_max_fps;
8842 int val = lookupHalName(HFR_MODE_MAP, METADATA_MAP_SIZE(HFR_MODE_MAP),
8843 fps_range.max_fps);
8844 if (NAME_NOT_FOUND != val) {
8845 cam_hfr_mode_t hfrMode = (cam_hfr_mode_t)val;
8846 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_HFR, hfrMode)) {
8847 return BAD_VALUE;
8848 }
8849
8850 if (fps_range.max_fps >= MIN_FPS_FOR_BATCH_MODE) {
8851 /* If batchmode is currently in progress and the fps changes,
8852 * set the flag to restart the sensor */
8853 if((mHFRVideoFps >= MIN_FPS_FOR_BATCH_MODE) &&
8854 (mHFRVideoFps != fps_range.max_fps)) {
8855 mNeedSensorRestart = true;
8856 }
8857 mHFRVideoFps = fps_range.max_fps;
8858 mBatchSize = mHFRVideoFps / PREVIEW_FPS_FOR_HFR;
8859 if (mBatchSize > MAX_HFR_BATCH_SIZE) {
8860 mBatchSize = MAX_HFR_BATCH_SIZE;
8861 }
8862 }
8863 LOGD("hfrMode: %d batchSize: %d", hfrMode, mBatchSize);
8864
8865 }
8866 } else {
8867 /* HFR mode is session param in backend/ISP. This should be reset when
8868 * in non-HFR mode */
8869 cam_hfr_mode_t hfrMode = CAM_HFR_MODE_OFF;
8870 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_HFR, hfrMode)) {
8871 return BAD_VALUE;
8872 }
8873 }
8874 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_FPS_RANGE, fps_range)) {
8875 return BAD_VALUE;
8876 }
8877 LOGD("fps: [%f %f] vid_fps: [%f %f]", fps_range.min_fps,
8878 fps_range.max_fps, fps_range.video_min_fps, fps_range.video_max_fps);
8879 return rc;
8880}
8881
8882/*===========================================================================
8883 * FUNCTION : translateToHalMetadata
8884 *
8885 * DESCRIPTION: read from the camera_metadata_t and change to parm_type_t
8886 *
8887 *
8888 * PARAMETERS :
8889 * @request : request sent from framework
8890 *
8891 *
8892 * RETURN : success: NO_ERROR
8893 * failure:
8894 *==========================================================================*/
8895int QCamera3HardwareInterface::translateToHalMetadata
8896 (const camera3_capture_request_t *request,
8897 metadata_buffer_t *hal_metadata,
8898 uint32_t snapshotStreamId)
8899{
8900 int rc = 0;
8901 CameraMetadata frame_settings;
8902 frame_settings = request->settings;
8903
8904 /* Do not change the order of the following list unless you know what you are
8905 * doing.
8906 * The order is laid out in such a way that parameters in the front of the table
8907 * may be used to override the parameters later in the table. Examples are:
8908 * 1. META_MODE should precede AEC/AWB/AF MODE
8909 * 2. AEC MODE should preced EXPOSURE_TIME/SENSITIVITY/FRAME_DURATION
8910 * 3. AWB_MODE should precede COLOR_CORRECTION_MODE
8911 * 4. Any mode should precede it's corresponding settings
8912 */
8913 if (frame_settings.exists(ANDROID_CONTROL_MODE)) {
8914 uint8_t metaMode = frame_settings.find(ANDROID_CONTROL_MODE).data.u8[0];
8915 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_MODE, metaMode)) {
8916 rc = BAD_VALUE;
8917 }
8918 rc = extractSceneMode(frame_settings, metaMode, hal_metadata);
8919 if (rc != NO_ERROR) {
8920 LOGE("extractSceneMode failed");
8921 }
8922 }
8923
8924 if (frame_settings.exists(ANDROID_CONTROL_AE_MODE)) {
8925 uint8_t fwk_aeMode =
8926 frame_settings.find(ANDROID_CONTROL_AE_MODE).data.u8[0];
8927 uint8_t aeMode;
8928 int32_t redeye;
8929
8930 if (fwk_aeMode == ANDROID_CONTROL_AE_MODE_OFF ) {
8931 aeMode = CAM_AE_MODE_OFF;
8932 } else {
8933 aeMode = CAM_AE_MODE_ON;
8934 }
8935 if (fwk_aeMode == ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE) {
8936 redeye = 1;
8937 } else {
8938 redeye = 0;
8939 }
8940
8941 int val = lookupHalName(AE_FLASH_MODE_MAP, METADATA_MAP_SIZE(AE_FLASH_MODE_MAP),
8942 fwk_aeMode);
8943 if (NAME_NOT_FOUND != val) {
8944 int32_t flashMode = (int32_t)val;
8945 ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_LED_MODE, flashMode);
8946 }
8947
8948 ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_AEC_MODE, aeMode);
8949 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_REDEYE_REDUCTION, redeye)) {
8950 rc = BAD_VALUE;
8951 }
8952 }
8953
8954 if (frame_settings.exists(ANDROID_CONTROL_AWB_MODE)) {
8955 uint8_t fwk_whiteLevel = frame_settings.find(ANDROID_CONTROL_AWB_MODE).data.u8[0];
8956 int val = lookupHalName(WHITE_BALANCE_MODES_MAP, METADATA_MAP_SIZE(WHITE_BALANCE_MODES_MAP),
8957 fwk_whiteLevel);
8958 if (NAME_NOT_FOUND != val) {
8959 uint8_t whiteLevel = (uint8_t)val;
8960 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_WHITE_BALANCE, whiteLevel)) {
8961 rc = BAD_VALUE;
8962 }
8963 }
8964 }
8965
8966 if (frame_settings.exists(ANDROID_COLOR_CORRECTION_ABERRATION_MODE)) {
8967 uint8_t fwk_cacMode =
8968 frame_settings.find(
8969 ANDROID_COLOR_CORRECTION_ABERRATION_MODE).data.u8[0];
8970 int val = lookupHalName(COLOR_ABERRATION_MAP, METADATA_MAP_SIZE(COLOR_ABERRATION_MAP),
8971 fwk_cacMode);
8972 if (NAME_NOT_FOUND != val) {
8973 cam_aberration_mode_t cacMode = (cam_aberration_mode_t) val;
8974 bool entryAvailable = FALSE;
8975 // Check whether Frameworks set CAC mode is supported in device or not
8976 for (size_t i = 0; i < gCamCapability[mCameraId]->aberration_modes_count; i++) {
8977 if (gCamCapability[mCameraId]->aberration_modes[i] == cacMode) {
8978 entryAvailable = TRUE;
8979 break;
8980 }
8981 }
8982 LOGD("FrameworksCacMode=%d entryAvailable=%d", cacMode, entryAvailable);
8983 // If entry not found then set the device supported mode instead of frameworks mode i.e,
8984 // Only HW ISP CAC + NO SW CAC : Advertise all 3 with High doing same as fast by ISP
8985 // NO HW ISP CAC + Only SW CAC : Advertise all 3 with Fast doing the same as OFF
8986 if (entryAvailable == FALSE) {
8987 if (gCamCapability[mCameraId]->aberration_modes_count == 0) {
8988 cacMode = CAM_COLOR_CORRECTION_ABERRATION_OFF;
8989 } else {
8990 if (cacMode == CAM_COLOR_CORRECTION_ABERRATION_HIGH_QUALITY) {
8991 // High is not supported and so set the FAST as spec say's underlying
8992 // device implementation can be the same for both modes.
8993 cacMode = CAM_COLOR_CORRECTION_ABERRATION_FAST;
8994 } else if (cacMode == CAM_COLOR_CORRECTION_ABERRATION_FAST) {
8995 // Fast is not supported and so we cannot set HIGH or FAST but choose OFF
8996 // in order to avoid the fps drop due to high quality
8997 cacMode = CAM_COLOR_CORRECTION_ABERRATION_OFF;
8998 } else {
8999 cacMode = CAM_COLOR_CORRECTION_ABERRATION_OFF;
9000 }
9001 }
9002 }
9003 LOGD("Final cacMode is %d", cacMode);
9004 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_CAC, cacMode)) {
9005 rc = BAD_VALUE;
9006 }
9007 } else {
9008 LOGE("Invalid framework CAC mode: %d", fwk_cacMode);
9009 }
9010 }
9011
9012 if (frame_settings.exists(ANDROID_CONTROL_AF_MODE)) {
9013 uint8_t fwk_focusMode = frame_settings.find(ANDROID_CONTROL_AF_MODE).data.u8[0];
9014 int val = lookupHalName(FOCUS_MODES_MAP, METADATA_MAP_SIZE(FOCUS_MODES_MAP),
9015 fwk_focusMode);
9016 if (NAME_NOT_FOUND != val) {
9017 uint8_t focusMode = (uint8_t)val;
9018 LOGD("set focus mode %d", focusMode);
9019 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_FOCUS_MODE, focusMode)) {
9020 rc = BAD_VALUE;
9021 }
9022 }
9023 }
9024
9025 if (frame_settings.exists(ANDROID_LENS_FOCUS_DISTANCE)) {
9026 float focalDistance = frame_settings.find(ANDROID_LENS_FOCUS_DISTANCE).data.f[0];
9027 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_LENS_FOCUS_DISTANCE,
9028 focalDistance)) {
9029 rc = BAD_VALUE;
9030 }
9031 }
9032
9033 if (frame_settings.exists(ANDROID_CONTROL_AE_ANTIBANDING_MODE)) {
9034 uint8_t fwk_antibandingMode =
9035 frame_settings.find(ANDROID_CONTROL_AE_ANTIBANDING_MODE).data.u8[0];
9036 int val = lookupHalName(ANTIBANDING_MODES_MAP,
9037 METADATA_MAP_SIZE(ANTIBANDING_MODES_MAP), fwk_antibandingMode);
9038 if (NAME_NOT_FOUND != val) {
9039 uint32_t hal_antibandingMode = (uint32_t)val;
9040 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_ANTIBANDING,
9041 hal_antibandingMode)) {
9042 rc = BAD_VALUE;
9043 }
9044 }
9045 }
9046
9047 if (frame_settings.exists(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION)) {
9048 int32_t expCompensation = frame_settings.find(
9049 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION).data.i32[0];
9050 if (expCompensation < gCamCapability[mCameraId]->exposure_compensation_min)
9051 expCompensation = gCamCapability[mCameraId]->exposure_compensation_min;
9052 if (expCompensation > gCamCapability[mCameraId]->exposure_compensation_max)
9053 expCompensation = gCamCapability[mCameraId]->exposure_compensation_max;
9054 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_EXPOSURE_COMPENSATION,
9055 expCompensation)) {
9056 rc = BAD_VALUE;
9057 }
9058 }
9059
9060 if (frame_settings.exists(ANDROID_CONTROL_AE_LOCK)) {
9061 uint8_t aeLock = frame_settings.find(ANDROID_CONTROL_AE_LOCK).data.u8[0];
9062 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_AEC_LOCK, aeLock)) {
9063 rc = BAD_VALUE;
9064 }
9065 }
9066 if (frame_settings.exists(ANDROID_CONTROL_AE_TARGET_FPS_RANGE)) {
9067 rc = setHalFpsRange(frame_settings, hal_metadata);
9068 if (rc != NO_ERROR) {
9069 LOGE("setHalFpsRange failed");
9070 }
9071 }
9072
9073 if (frame_settings.exists(ANDROID_CONTROL_AWB_LOCK)) {
9074 uint8_t awbLock = frame_settings.find(ANDROID_CONTROL_AWB_LOCK).data.u8[0];
9075 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_AWB_LOCK, awbLock)) {
9076 rc = BAD_VALUE;
9077 }
9078 }
9079
9080 if (frame_settings.exists(ANDROID_CONTROL_EFFECT_MODE)) {
9081 uint8_t fwk_effectMode = frame_settings.find(ANDROID_CONTROL_EFFECT_MODE).data.u8[0];
9082 int val = lookupHalName(EFFECT_MODES_MAP, METADATA_MAP_SIZE(EFFECT_MODES_MAP),
9083 fwk_effectMode);
9084 if (NAME_NOT_FOUND != val) {
9085 uint8_t effectMode = (uint8_t)val;
9086 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_EFFECT, effectMode)) {
9087 rc = BAD_VALUE;
9088 }
9089 }
9090 }
9091
9092 if (frame_settings.exists(ANDROID_COLOR_CORRECTION_MODE)) {
9093 uint8_t colorCorrectMode = frame_settings.find(ANDROID_COLOR_CORRECTION_MODE).data.u8[0];
9094 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_COLOR_CORRECT_MODE,
9095 colorCorrectMode)) {
9096 rc = BAD_VALUE;
9097 }
9098 }
9099
9100 if (frame_settings.exists(ANDROID_COLOR_CORRECTION_GAINS)) {
9101 cam_color_correct_gains_t colorCorrectGains;
9102 for (size_t i = 0; i < CC_GAIN_MAX; i++) {
9103 colorCorrectGains.gains[i] =
9104 frame_settings.find(ANDROID_COLOR_CORRECTION_GAINS).data.f[i];
9105 }
9106 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_COLOR_CORRECT_GAINS,
9107 colorCorrectGains)) {
9108 rc = BAD_VALUE;
9109 }
9110 }
9111
9112 if (frame_settings.exists(ANDROID_COLOR_CORRECTION_TRANSFORM)) {
9113 cam_color_correct_matrix_t colorCorrectTransform;
9114 cam_rational_type_t transform_elem;
9115 size_t num = 0;
9116 for (size_t i = 0; i < CC_MATRIX_ROWS; i++) {
9117 for (size_t j = 0; j < CC_MATRIX_COLS; j++) {
9118 transform_elem.numerator =
9119 frame_settings.find(ANDROID_COLOR_CORRECTION_TRANSFORM).data.r[num].numerator;
9120 transform_elem.denominator =
9121 frame_settings.find(ANDROID_COLOR_CORRECTION_TRANSFORM).data.r[num].denominator;
9122 colorCorrectTransform.transform_matrix[i][j] = transform_elem;
9123 num++;
9124 }
9125 }
9126 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_COLOR_CORRECT_TRANSFORM,
9127 colorCorrectTransform)) {
9128 rc = BAD_VALUE;
9129 }
9130 }
9131
9132 cam_trigger_t aecTrigger;
9133 aecTrigger.trigger = CAM_AEC_TRIGGER_IDLE;
9134 aecTrigger.trigger_id = -1;
9135 if (frame_settings.exists(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER)&&
9136 frame_settings.exists(ANDROID_CONTROL_AE_PRECAPTURE_ID)) {
9137 aecTrigger.trigger =
9138 frame_settings.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER).data.u8[0];
9139 aecTrigger.trigger_id =
9140 frame_settings.find(ANDROID_CONTROL_AE_PRECAPTURE_ID).data.i32[0];
9141 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_AEC_PRECAPTURE_TRIGGER,
9142 aecTrigger)) {
9143 rc = BAD_VALUE;
9144 }
9145 LOGD("precaptureTrigger: %d precaptureTriggerID: %d",
9146 aecTrigger.trigger, aecTrigger.trigger_id);
9147 }
9148
9149 /*af_trigger must come with a trigger id*/
9150 if (frame_settings.exists(ANDROID_CONTROL_AF_TRIGGER) &&
9151 frame_settings.exists(ANDROID_CONTROL_AF_TRIGGER_ID)) {
9152 cam_trigger_t af_trigger;
9153 af_trigger.trigger =
9154 frame_settings.find(ANDROID_CONTROL_AF_TRIGGER).data.u8[0];
9155 af_trigger.trigger_id =
9156 frame_settings.find(ANDROID_CONTROL_AF_TRIGGER_ID).data.i32[0];
9157 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_AF_TRIGGER, af_trigger)) {
9158 rc = BAD_VALUE;
9159 }
9160 LOGD("AfTrigger: %d AfTriggerID: %d",
9161 af_trigger.trigger, af_trigger.trigger_id);
9162 }
9163
9164 if (frame_settings.exists(ANDROID_DEMOSAIC_MODE)) {
9165 int32_t demosaic = frame_settings.find(ANDROID_DEMOSAIC_MODE).data.u8[0];
9166 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_DEMOSAIC, demosaic)) {
9167 rc = BAD_VALUE;
9168 }
9169 }
9170 if (frame_settings.exists(ANDROID_EDGE_MODE)) {
9171 cam_edge_application_t edge_application;
9172 edge_application.edge_mode = frame_settings.find(ANDROID_EDGE_MODE).data.u8[0];
9173 if (edge_application.edge_mode == CAM_EDGE_MODE_OFF) {
9174 edge_application.sharpness = 0;
9175 } else {
9176 edge_application.sharpness = gCamCapability[mCameraId]->sharpness_ctrl.def_value; //default
9177 }
9178 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_EDGE_MODE, edge_application)) {
9179 rc = BAD_VALUE;
9180 }
9181 }
9182
9183 if (frame_settings.exists(ANDROID_FLASH_MODE)) {
9184 int32_t respectFlashMode = 1;
9185 if (frame_settings.exists(ANDROID_CONTROL_AE_MODE)) {
9186 uint8_t fwk_aeMode =
9187 frame_settings.find(ANDROID_CONTROL_AE_MODE).data.u8[0];
9188 if (fwk_aeMode > ANDROID_CONTROL_AE_MODE_ON) {
9189 respectFlashMode = 0;
9190 LOGH("AE Mode controls flash, ignore android.flash.mode");
9191 }
9192 }
9193 if (respectFlashMode) {
9194 int val = lookupHalName(FLASH_MODES_MAP, METADATA_MAP_SIZE(FLASH_MODES_MAP),
9195 (int)frame_settings.find(ANDROID_FLASH_MODE).data.u8[0]);
9196 LOGH("flash mode after mapping %d", val);
9197 // To check: CAM_INTF_META_FLASH_MODE usage
9198 if (NAME_NOT_FOUND != val) {
9199 uint8_t flashMode = (uint8_t)val;
9200 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_LED_MODE, flashMode)) {
9201 rc = BAD_VALUE;
9202 }
9203 }
9204 }
9205 }
9206
9207 if (frame_settings.exists(ANDROID_FLASH_FIRING_POWER)) {
9208 uint8_t flashPower = frame_settings.find(ANDROID_FLASH_FIRING_POWER).data.u8[0];
9209 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_FLASH_POWER, flashPower)) {
9210 rc = BAD_VALUE;
9211 }
9212 }
9213
9214 if (frame_settings.exists(ANDROID_FLASH_FIRING_TIME)) {
9215 int64_t flashFiringTime = frame_settings.find(ANDROID_FLASH_FIRING_TIME).data.i64[0];
9216 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_FLASH_FIRING_TIME,
9217 flashFiringTime)) {
9218 rc = BAD_VALUE;
9219 }
9220 }
9221
9222 if (frame_settings.exists(ANDROID_HOT_PIXEL_MODE)) {
9223 uint8_t hotPixelMode = frame_settings.find(ANDROID_HOT_PIXEL_MODE).data.u8[0];
9224 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_HOTPIXEL_MODE,
9225 hotPixelMode)) {
9226 rc = BAD_VALUE;
9227 }
9228 }
9229
9230 if (frame_settings.exists(ANDROID_LENS_APERTURE)) {
9231 float lensAperture = frame_settings.find( ANDROID_LENS_APERTURE).data.f[0];
9232 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_LENS_APERTURE,
9233 lensAperture)) {
9234 rc = BAD_VALUE;
9235 }
9236 }
9237
9238 if (frame_settings.exists(ANDROID_LENS_FILTER_DENSITY)) {
9239 float filterDensity = frame_settings.find(ANDROID_LENS_FILTER_DENSITY).data.f[0];
9240 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_LENS_FILTERDENSITY,
9241 filterDensity)) {
9242 rc = BAD_VALUE;
9243 }
9244 }
9245
9246 if (frame_settings.exists(ANDROID_LENS_FOCAL_LENGTH)) {
9247 float focalLength = frame_settings.find(ANDROID_LENS_FOCAL_LENGTH).data.f[0];
9248 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_LENS_FOCAL_LENGTH,
9249 focalLength)) {
9250 rc = BAD_VALUE;
9251 }
9252 }
9253
9254 if (frame_settings.exists(ANDROID_LENS_OPTICAL_STABILIZATION_MODE)) {
9255 uint8_t optStabMode =
9256 frame_settings.find(ANDROID_LENS_OPTICAL_STABILIZATION_MODE).data.u8[0];
9257 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_LENS_OPT_STAB_MODE,
9258 optStabMode)) {
9259 rc = BAD_VALUE;
9260 }
9261 }
9262
9263 if (frame_settings.exists(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE)) {
9264 uint8_t videoStabMode =
9265 frame_settings.find(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE).data.u8[0];
9266 LOGD("videoStabMode from APP = %d", videoStabMode);
9267 if (ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_META_VIDEO_STAB_MODE,
9268 videoStabMode)) {
9269 rc = BAD_VALUE;
9270 }
9271 }
9272
9273
9274 if (frame_settings.exists(ANDROID_NOISE_REDUCTION_MODE)) {
9275 uint8_t noiseRedMode = frame_settings.find(ANDROID_NOISE_REDUCTION_MODE).data.u8[0];
9276 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_NOISE_REDUCTION_MODE,
9277 noiseRedMode)) {
9278 rc = BAD_VALUE;
9279 }
9280 }
9281
9282 if (frame_settings.exists(ANDROID_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR)) {
9283 float reprocessEffectiveExposureFactor =
9284 frame_settings.find(ANDROID_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR).data.f[0];
9285 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_EFFECTIVE_EXPOSURE_FACTOR,
9286 reprocessEffectiveExposureFactor)) {
9287 rc = BAD_VALUE;
9288 }
9289 }
9290
9291 cam_crop_region_t scalerCropRegion;
9292 bool scalerCropSet = false;
9293 if (frame_settings.exists(ANDROID_SCALER_CROP_REGION)) {
9294 scalerCropRegion.left = frame_settings.find(ANDROID_SCALER_CROP_REGION).data.i32[0];
9295 scalerCropRegion.top = frame_settings.find(ANDROID_SCALER_CROP_REGION).data.i32[1];
9296 scalerCropRegion.width = frame_settings.find(ANDROID_SCALER_CROP_REGION).data.i32[2];
9297 scalerCropRegion.height = frame_settings.find(ANDROID_SCALER_CROP_REGION).data.i32[3];
9298
9299 // Map coordinate system from active array to sensor output.
9300 mCropRegionMapper.toSensor(scalerCropRegion.left, scalerCropRegion.top,
9301 scalerCropRegion.width, scalerCropRegion.height);
9302
9303 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_SCALER_CROP_REGION,
9304 scalerCropRegion)) {
9305 rc = BAD_VALUE;
9306 }
9307 scalerCropSet = true;
9308 }
9309
9310 if (frame_settings.exists(ANDROID_SENSOR_EXPOSURE_TIME)) {
9311 int64_t sensorExpTime =
9312 frame_settings.find(ANDROID_SENSOR_EXPOSURE_TIME).data.i64[0];
9313 LOGD("setting sensorExpTime %lld", sensorExpTime);
9314 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_SENSOR_EXPOSURE_TIME,
9315 sensorExpTime)) {
9316 rc = BAD_VALUE;
9317 }
9318 }
9319
9320 if (frame_settings.exists(ANDROID_SENSOR_FRAME_DURATION)) {
9321 int64_t sensorFrameDuration =
9322 frame_settings.find(ANDROID_SENSOR_FRAME_DURATION).data.i64[0];
9323 int64_t minFrameDuration = getMinFrameDuration(request);
9324 sensorFrameDuration = MAX(sensorFrameDuration, minFrameDuration);
9325 if (sensorFrameDuration > gCamCapability[mCameraId]->max_frame_duration)
9326 sensorFrameDuration = gCamCapability[mCameraId]->max_frame_duration;
9327 LOGD("clamp sensorFrameDuration to %lld", sensorFrameDuration);
9328 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_SENSOR_FRAME_DURATION,
9329 sensorFrameDuration)) {
9330 rc = BAD_VALUE;
9331 }
9332 }
9333
9334 if (frame_settings.exists(ANDROID_SENSOR_SENSITIVITY)) {
9335 int32_t sensorSensitivity = frame_settings.find(ANDROID_SENSOR_SENSITIVITY).data.i32[0];
9336 if (sensorSensitivity < gCamCapability[mCameraId]->sensitivity_range.min_sensitivity)
9337 sensorSensitivity = gCamCapability[mCameraId]->sensitivity_range.min_sensitivity;
9338 if (sensorSensitivity > gCamCapability[mCameraId]->sensitivity_range.max_sensitivity)
9339 sensorSensitivity = gCamCapability[mCameraId]->sensitivity_range.max_sensitivity;
9340 LOGD("clamp sensorSensitivity to %d", sensorSensitivity);
9341 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_SENSOR_SENSITIVITY,
9342 sensorSensitivity)) {
9343 rc = BAD_VALUE;
9344 }
9345 }
9346
Thierry Strudel9e74aae2016-09-22 17:10:18 -07009347#ifndef USE_HAL_3_3
9348 if (frame_settings.exists(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST)) {
9349 int32_t ispSensitivity =
9350 frame_settings.find(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST).data.i32[0];
9351 if (ispSensitivity <
9352 gCamCapability[mCameraId]->isp_sensitivity_range.min_sensitivity) {
9353 ispSensitivity =
9354 gCamCapability[mCameraId]->isp_sensitivity_range.min_sensitivity;
9355 LOGD("clamp ispSensitivity to %d", ispSensitivity);
9356 }
9357 if (ispSensitivity >
9358 gCamCapability[mCameraId]->isp_sensitivity_range.max_sensitivity) {
9359 ispSensitivity =
9360 gCamCapability[mCameraId]->isp_sensitivity_range.max_sensitivity;
9361 LOGD("clamp ispSensitivity to %d", ispSensitivity);
9362 }
9363 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_ISP_SENSITIVITY,
9364 ispSensitivity)) {
9365 rc = BAD_VALUE;
9366 }
9367 }
9368#endif
9369
Thierry Strudel3d639192016-09-09 11:52:26 -07009370 if (frame_settings.exists(ANDROID_SHADING_MODE)) {
9371 uint8_t shadingMode = frame_settings.find(ANDROID_SHADING_MODE).data.u8[0];
9372 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_SHADING_MODE, shadingMode)) {
9373 rc = BAD_VALUE;
9374 }
9375 }
9376
9377 if (frame_settings.exists(ANDROID_STATISTICS_FACE_DETECT_MODE)) {
9378 uint8_t fwk_facedetectMode =
9379 frame_settings.find(ANDROID_STATISTICS_FACE_DETECT_MODE).data.u8[0];
9380
9381 int val = lookupHalName(FACEDETECT_MODES_MAP, METADATA_MAP_SIZE(FACEDETECT_MODES_MAP),
9382 fwk_facedetectMode);
9383
9384 if (NAME_NOT_FOUND != val) {
9385 uint8_t facedetectMode = (uint8_t)val;
9386 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_STATS_FACEDETECT_MODE,
9387 facedetectMode)) {
9388 rc = BAD_VALUE;
9389 }
9390 }
9391 }
9392
9393 if (frame_settings.exists(ANDROID_STATISTICS_HISTOGRAM_MODE)) {
9394 uint8_t histogramMode =
9395 frame_settings.find(ANDROID_STATISTICS_HISTOGRAM_MODE).data.u8[0];
9396 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_STATS_HISTOGRAM_MODE,
9397 histogramMode)) {
9398 rc = BAD_VALUE;
9399 }
9400 }
9401
9402 if (frame_settings.exists(ANDROID_STATISTICS_SHARPNESS_MAP_MODE)) {
9403 uint8_t sharpnessMapMode =
9404 frame_settings.find(ANDROID_STATISTICS_SHARPNESS_MAP_MODE).data.u8[0];
9405 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_STATS_SHARPNESS_MAP_MODE,
9406 sharpnessMapMode)) {
9407 rc = BAD_VALUE;
9408 }
9409 }
9410
9411 if (frame_settings.exists(ANDROID_TONEMAP_MODE)) {
9412 uint8_t tonemapMode =
9413 frame_settings.find(ANDROID_TONEMAP_MODE).data.u8[0];
9414 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_TONEMAP_MODE, tonemapMode)) {
9415 rc = BAD_VALUE;
9416 }
9417 }
9418 /* Tonemap curve channels ch0 = G, ch 1 = B, ch 2 = R */
9419 /*All tonemap channels will have the same number of points*/
9420 if (frame_settings.exists(ANDROID_TONEMAP_CURVE_GREEN) &&
9421 frame_settings.exists(ANDROID_TONEMAP_CURVE_BLUE) &&
9422 frame_settings.exists(ANDROID_TONEMAP_CURVE_RED)) {
9423 cam_rgb_tonemap_curves tonemapCurves;
9424 tonemapCurves.tonemap_points_cnt = frame_settings.find(ANDROID_TONEMAP_CURVE_GREEN).count/2;
9425 if (tonemapCurves.tonemap_points_cnt > CAM_MAX_TONEMAP_CURVE_SIZE) {
9426 LOGE("Fatal: tonemap_points_cnt %d exceeds max value of %d",
9427 tonemapCurves.tonemap_points_cnt,
9428 CAM_MAX_TONEMAP_CURVE_SIZE);
9429 tonemapCurves.tonemap_points_cnt = CAM_MAX_TONEMAP_CURVE_SIZE;
9430 }
9431
9432 /* ch0 = G*/
9433 size_t point = 0;
9434 cam_tonemap_curve_t tonemapCurveGreen;
9435 for (size_t i = 0; i < tonemapCurves.tonemap_points_cnt; i++) {
9436 for (size_t j = 0; j < 2; j++) {
9437 tonemapCurveGreen.tonemap_points[i][j] =
9438 frame_settings.find(ANDROID_TONEMAP_CURVE_GREEN).data.f[point];
9439 point++;
9440 }
9441 }
9442 tonemapCurves.curves[0] = tonemapCurveGreen;
9443
9444 /* ch 1 = B */
9445 point = 0;
9446 cam_tonemap_curve_t tonemapCurveBlue;
9447 for (size_t i = 0; i < tonemapCurves.tonemap_points_cnt; i++) {
9448 for (size_t j = 0; j < 2; j++) {
9449 tonemapCurveBlue.tonemap_points[i][j] =
9450 frame_settings.find(ANDROID_TONEMAP_CURVE_BLUE).data.f[point];
9451 point++;
9452 }
9453 }
9454 tonemapCurves.curves[1] = tonemapCurveBlue;
9455
9456 /* ch 2 = R */
9457 point = 0;
9458 cam_tonemap_curve_t tonemapCurveRed;
9459 for (size_t i = 0; i < tonemapCurves.tonemap_points_cnt; i++) {
9460 for (size_t j = 0; j < 2; j++) {
9461 tonemapCurveRed.tonemap_points[i][j] =
9462 frame_settings.find(ANDROID_TONEMAP_CURVE_RED).data.f[point];
9463 point++;
9464 }
9465 }
9466 tonemapCurves.curves[2] = tonemapCurveRed;
9467
9468 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_TONEMAP_CURVES,
9469 tonemapCurves)) {
9470 rc = BAD_VALUE;
9471 }
9472 }
9473
9474 if (frame_settings.exists(ANDROID_CONTROL_CAPTURE_INTENT)) {
9475 uint8_t captureIntent = frame_settings.find(ANDROID_CONTROL_CAPTURE_INTENT).data.u8[0];
9476 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_CAPTURE_INTENT,
9477 captureIntent)) {
9478 rc = BAD_VALUE;
9479 }
9480 }
9481
9482 if (frame_settings.exists(ANDROID_BLACK_LEVEL_LOCK)) {
9483 uint8_t blackLevelLock = frame_settings.find(ANDROID_BLACK_LEVEL_LOCK).data.u8[0];
9484 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_BLACK_LEVEL_LOCK,
9485 blackLevelLock)) {
9486 rc = BAD_VALUE;
9487 }
9488 }
9489
9490 if (frame_settings.exists(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE)) {
9491 uint8_t lensShadingMapMode =
9492 frame_settings.find(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE).data.u8[0];
9493 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_LENS_SHADING_MAP_MODE,
9494 lensShadingMapMode)) {
9495 rc = BAD_VALUE;
9496 }
9497 }
9498
9499 if (frame_settings.exists(ANDROID_CONTROL_AE_REGIONS)) {
9500 cam_area_t roi;
9501 bool reset = true;
9502 convertFromRegions(roi, request->settings, ANDROID_CONTROL_AE_REGIONS);
9503
9504 // Map coordinate system from active array to sensor output.
9505 mCropRegionMapper.toSensor(roi.rect.left, roi.rect.top, roi.rect.width,
9506 roi.rect.height);
9507
9508 if (scalerCropSet) {
9509 reset = resetIfNeededROI(&roi, &scalerCropRegion);
9510 }
9511 if (reset && ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_AEC_ROI, roi)) {
9512 rc = BAD_VALUE;
9513 }
9514 }
9515
9516 if (frame_settings.exists(ANDROID_CONTROL_AF_REGIONS)) {
9517 cam_area_t roi;
9518 bool reset = true;
9519 convertFromRegions(roi, request->settings, ANDROID_CONTROL_AF_REGIONS);
9520
9521 // Map coordinate system from active array to sensor output.
9522 mCropRegionMapper.toSensor(roi.rect.left, roi.rect.top, roi.rect.width,
9523 roi.rect.height);
9524
9525 if (scalerCropSet) {
9526 reset = resetIfNeededROI(&roi, &scalerCropRegion);
9527 }
9528 if (reset && ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_AF_ROI, roi)) {
9529 rc = BAD_VALUE;
9530 }
9531 }
9532
9533 // CDS for non-HFR non-video mode
9534 if ((mOpMode != CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE) &&
9535 !(m_bIsVideo) && frame_settings.exists(QCAMERA3_CDS_MODE)) {
9536 int32_t *fwk_cds = frame_settings.find(QCAMERA3_CDS_MODE).data.i32;
9537 if ((CAM_CDS_MODE_MAX <= *fwk_cds) || (0 > *fwk_cds)) {
9538 LOGE("Invalid CDS mode %d!", *fwk_cds);
9539 } else {
9540 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata,
9541 CAM_INTF_PARM_CDS_MODE, *fwk_cds)) {
9542 rc = BAD_VALUE;
9543 }
9544 }
9545 }
9546
9547 // TNR
9548 if (frame_settings.exists(QCAMERA3_TEMPORAL_DENOISE_ENABLE) &&
9549 frame_settings.exists(QCAMERA3_TEMPORAL_DENOISE_PROCESS_TYPE)) {
9550 uint8_t b_TnrRequested = 0;
9551 cam_denoise_param_t tnr;
9552 tnr.denoise_enable = frame_settings.find(QCAMERA3_TEMPORAL_DENOISE_ENABLE).data.u8[0];
9553 tnr.process_plates =
9554 (cam_denoise_process_type_t)frame_settings.find(
9555 QCAMERA3_TEMPORAL_DENOISE_PROCESS_TYPE).data.i32[0];
9556 b_TnrRequested = tnr.denoise_enable;
9557 if (ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters, CAM_INTF_PARM_TEMPORAL_DENOISE, tnr)) {
9558 rc = BAD_VALUE;
9559 }
9560 }
9561
9562 if (frame_settings.exists(ANDROID_SENSOR_TEST_PATTERN_MODE)) {
9563 int32_t fwk_testPatternMode =
9564 frame_settings.find(ANDROID_SENSOR_TEST_PATTERN_MODE).data.i32[0];
9565 int testPatternMode = lookupHalName(TEST_PATTERN_MAP,
9566 METADATA_MAP_SIZE(TEST_PATTERN_MAP), fwk_testPatternMode);
9567
9568 if (NAME_NOT_FOUND != testPatternMode) {
9569 cam_test_pattern_data_t testPatternData;
9570 memset(&testPatternData, 0, sizeof(testPatternData));
9571 testPatternData.mode = (cam_test_pattern_mode_t)testPatternMode;
9572 if (testPatternMode == CAM_TEST_PATTERN_SOLID_COLOR &&
9573 frame_settings.exists(ANDROID_SENSOR_TEST_PATTERN_DATA)) {
9574 int32_t *fwk_testPatternData =
9575 frame_settings.find(ANDROID_SENSOR_TEST_PATTERN_DATA).data.i32;
9576 testPatternData.r = fwk_testPatternData[0];
9577 testPatternData.b = fwk_testPatternData[3];
9578 switch (gCamCapability[mCameraId]->color_arrangement) {
9579 case CAM_FILTER_ARRANGEMENT_RGGB:
9580 case CAM_FILTER_ARRANGEMENT_GRBG:
9581 testPatternData.gr = fwk_testPatternData[1];
9582 testPatternData.gb = fwk_testPatternData[2];
9583 break;
9584 case CAM_FILTER_ARRANGEMENT_GBRG:
9585 case CAM_FILTER_ARRANGEMENT_BGGR:
9586 testPatternData.gr = fwk_testPatternData[2];
9587 testPatternData.gb = fwk_testPatternData[1];
9588 break;
9589 default:
9590 LOGE("color arrangement %d is not supported",
9591 gCamCapability[mCameraId]->color_arrangement);
9592 break;
9593 }
9594 }
9595 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_TEST_PATTERN_DATA,
9596 testPatternData)) {
9597 rc = BAD_VALUE;
9598 }
9599 } else {
9600 LOGE("Invalid framework sensor test pattern mode %d",
9601 fwk_testPatternMode);
9602 }
9603 }
9604
9605 if (frame_settings.exists(ANDROID_JPEG_GPS_COORDINATES)) {
9606 size_t count = 0;
9607 camera_metadata_entry_t gps_coords = frame_settings.find(ANDROID_JPEG_GPS_COORDINATES);
9608 ADD_SET_PARAM_ARRAY_TO_BATCH(hal_metadata, CAM_INTF_META_JPEG_GPS_COORDINATES,
9609 gps_coords.data.d, gps_coords.count, count);
9610 if (gps_coords.count != count) {
9611 rc = BAD_VALUE;
9612 }
9613 }
9614
9615 if (frame_settings.exists(ANDROID_JPEG_GPS_PROCESSING_METHOD)) {
9616 char gps_methods[GPS_PROCESSING_METHOD_SIZE];
9617 size_t count = 0;
9618 const char *gps_methods_src = (const char *)
9619 frame_settings.find(ANDROID_JPEG_GPS_PROCESSING_METHOD).data.u8;
9620 memset(gps_methods, '\0', sizeof(gps_methods));
9621 strlcpy(gps_methods, gps_methods_src, sizeof(gps_methods));
9622 ADD_SET_PARAM_ARRAY_TO_BATCH(hal_metadata, CAM_INTF_META_JPEG_GPS_PROC_METHODS,
9623 gps_methods, GPS_PROCESSING_METHOD_SIZE, count);
9624 if (GPS_PROCESSING_METHOD_SIZE != count) {
9625 rc = BAD_VALUE;
9626 }
9627 }
9628
9629 if (frame_settings.exists(ANDROID_JPEG_GPS_TIMESTAMP)) {
9630 int64_t gps_timestamp = frame_settings.find(ANDROID_JPEG_GPS_TIMESTAMP).data.i64[0];
9631 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_JPEG_GPS_TIMESTAMP,
9632 gps_timestamp)) {
9633 rc = BAD_VALUE;
9634 }
9635 }
9636
9637 if (frame_settings.exists(ANDROID_JPEG_ORIENTATION)) {
9638 int32_t orientation = frame_settings.find(ANDROID_JPEG_ORIENTATION).data.i32[0];
9639 cam_rotation_info_t rotation_info;
9640 if (orientation == 0) {
9641 rotation_info.rotation = ROTATE_0;
9642 } else if (orientation == 90) {
9643 rotation_info.rotation = ROTATE_90;
9644 } else if (orientation == 180) {
9645 rotation_info.rotation = ROTATE_180;
9646 } else if (orientation == 270) {
9647 rotation_info.rotation = ROTATE_270;
9648 }
9649 rotation_info.streamId = snapshotStreamId;
9650 ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_JPEG_ORIENTATION, orientation);
9651 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_ROTATION, rotation_info)) {
9652 rc = BAD_VALUE;
9653 }
9654 }
9655
9656 if (frame_settings.exists(ANDROID_JPEG_QUALITY)) {
9657 uint32_t quality = (uint32_t) frame_settings.find(ANDROID_JPEG_QUALITY).data.u8[0];
9658 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_JPEG_QUALITY, quality)) {
9659 rc = BAD_VALUE;
9660 }
9661 }
9662
9663 if (frame_settings.exists(ANDROID_JPEG_THUMBNAIL_QUALITY)) {
9664 uint32_t thumb_quality = (uint32_t)
9665 frame_settings.find(ANDROID_JPEG_THUMBNAIL_QUALITY).data.u8[0];
9666 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_JPEG_THUMB_QUALITY,
9667 thumb_quality)) {
9668 rc = BAD_VALUE;
9669 }
9670 }
9671
9672 if (frame_settings.exists(ANDROID_JPEG_THUMBNAIL_SIZE)) {
9673 cam_dimension_t dim;
9674 dim.width = frame_settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[0];
9675 dim.height = frame_settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[1];
9676 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_JPEG_THUMB_SIZE, dim)) {
9677 rc = BAD_VALUE;
9678 }
9679 }
9680
9681 // Internal metadata
9682 if (frame_settings.exists(QCAMERA3_PRIVATEDATA_REPROCESS)) {
9683 size_t count = 0;
9684 camera_metadata_entry_t privatedata = frame_settings.find(QCAMERA3_PRIVATEDATA_REPROCESS);
9685 ADD_SET_PARAM_ARRAY_TO_BATCH(hal_metadata, CAM_INTF_META_PRIVATE_DATA,
9686 privatedata.data.i32, privatedata.count, count);
9687 if (privatedata.count != count) {
9688 rc = BAD_VALUE;
9689 }
9690 }
9691
Thierry Strudel3d639192016-09-09 11:52:26 -07009692 // EV step
9693 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_PARM_EV_STEP,
9694 gCamCapability[mCameraId]->exp_compensation_step)) {
9695 rc = BAD_VALUE;
9696 }
9697
9698 // CDS info
9699 if (frame_settings.exists(QCAMERA3_CDS_INFO)) {
9700 cam_cds_data_t *cdsData = (cam_cds_data_t *)
9701 frame_settings.find(QCAMERA3_CDS_INFO).data.u8;
9702
9703 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata,
9704 CAM_INTF_META_CDS_DATA, *cdsData)) {
9705 rc = BAD_VALUE;
9706 }
9707 }
9708
9709 return rc;
9710}
9711
9712/*===========================================================================
9713 * FUNCTION : captureResultCb
9714 *
9715 * DESCRIPTION: Callback handler for all channels (streams, as well as metadata)
9716 *
9717 * PARAMETERS :
9718 * @frame : frame information from mm-camera-interface
9719 * @buffer : actual gralloc buffer to be returned to frameworks. NULL if metadata.
9720 * @userdata: userdata
9721 *
9722 * RETURN : NONE
9723 *==========================================================================*/
9724void QCamera3HardwareInterface::captureResultCb(mm_camera_super_buf_t *metadata,
9725 camera3_stream_buffer_t *buffer,
9726 uint32_t frame_number, bool isInputBuffer, void *userdata)
9727{
9728 QCamera3HardwareInterface *hw = (QCamera3HardwareInterface *)userdata;
9729 if (hw == NULL) {
9730 LOGE("Invalid hw %p", hw);
9731 return;
9732 }
9733
9734 hw->captureResultCb(metadata, buffer, frame_number, isInputBuffer);
9735 return;
9736}
9737
9738
9739/*===========================================================================
9740 * FUNCTION : initialize
9741 *
9742 * DESCRIPTION: Pass framework callback pointers to HAL
9743 *
9744 * PARAMETERS :
9745 *
9746 *
9747 * RETURN : Success : 0
9748 * Failure: -ENODEV
9749 *==========================================================================*/
9750
9751int QCamera3HardwareInterface::initialize(const struct camera3_device *device,
9752 const camera3_callback_ops_t *callback_ops)
9753{
9754 LOGD("E");
9755 QCamera3HardwareInterface *hw =
9756 reinterpret_cast<QCamera3HardwareInterface *>(device->priv);
9757 if (!hw) {
9758 LOGE("NULL camera device");
9759 return -ENODEV;
9760 }
9761
9762 int rc = hw->initialize(callback_ops);
9763 LOGD("X");
9764 return rc;
9765}
9766
9767/*===========================================================================
9768 * FUNCTION : configure_streams
9769 *
9770 * DESCRIPTION:
9771 *
9772 * PARAMETERS :
9773 *
9774 *
9775 * RETURN : Success: 0
9776 * Failure: -EINVAL (if stream configuration is invalid)
9777 * -ENODEV (fatal error)
9778 *==========================================================================*/
9779
9780int QCamera3HardwareInterface::configure_streams(
9781 const struct camera3_device *device,
9782 camera3_stream_configuration_t *stream_list)
9783{
9784 LOGD("E");
9785 QCamera3HardwareInterface *hw =
9786 reinterpret_cast<QCamera3HardwareInterface *>(device->priv);
9787 if (!hw) {
9788 LOGE("NULL camera device");
9789 return -ENODEV;
9790 }
9791 int rc = hw->configureStreams(stream_list);
9792 LOGD("X");
9793 return rc;
9794}
9795
9796/*===========================================================================
9797 * FUNCTION : construct_default_request_settings
9798 *
9799 * DESCRIPTION: Configure a settings buffer to meet the required use case
9800 *
9801 * PARAMETERS :
9802 *
9803 *
9804 * RETURN : Success: Return valid metadata
9805 * Failure: Return NULL
9806 *==========================================================================*/
9807const camera_metadata_t* QCamera3HardwareInterface::
9808 construct_default_request_settings(const struct camera3_device *device,
9809 int type)
9810{
9811
9812 LOGD("E");
9813 camera_metadata_t* fwk_metadata = NULL;
9814 QCamera3HardwareInterface *hw =
9815 reinterpret_cast<QCamera3HardwareInterface *>(device->priv);
9816 if (!hw) {
9817 LOGE("NULL camera device");
9818 return NULL;
9819 }
9820
9821 fwk_metadata = hw->translateCapabilityToMetadata(type);
9822
9823 LOGD("X");
9824 return fwk_metadata;
9825}
9826
9827/*===========================================================================
9828 * FUNCTION : process_capture_request
9829 *
9830 * DESCRIPTION:
9831 *
9832 * PARAMETERS :
9833 *
9834 *
9835 * RETURN :
9836 *==========================================================================*/
9837int QCamera3HardwareInterface::process_capture_request(
9838 const struct camera3_device *device,
9839 camera3_capture_request_t *request)
9840{
9841 LOGD("E");
9842 QCamera3HardwareInterface *hw =
9843 reinterpret_cast<QCamera3HardwareInterface *>(device->priv);
9844 if (!hw) {
9845 LOGE("NULL camera device");
9846 return -EINVAL;
9847 }
9848
9849 int rc = hw->processCaptureRequest(request);
9850 LOGD("X");
9851 return rc;
9852}
9853
9854/*===========================================================================
9855 * FUNCTION : dump
9856 *
9857 * DESCRIPTION:
9858 *
9859 * PARAMETERS :
9860 *
9861 *
9862 * RETURN :
9863 *==========================================================================*/
9864
9865void QCamera3HardwareInterface::dump(
9866 const struct camera3_device *device, int fd)
9867{
9868 /* Log level property is read when "adb shell dumpsys media.camera" is
9869 called so that the log level can be controlled without restarting
9870 the media server */
9871 getLogLevel();
9872
9873 LOGD("E");
9874 QCamera3HardwareInterface *hw =
9875 reinterpret_cast<QCamera3HardwareInterface *>(device->priv);
9876 if (!hw) {
9877 LOGE("NULL camera device");
9878 return;
9879 }
9880
9881 hw->dump(fd);
9882 LOGD("X");
9883 return;
9884}
9885
9886/*===========================================================================
9887 * FUNCTION : flush
9888 *
9889 * DESCRIPTION:
9890 *
9891 * PARAMETERS :
9892 *
9893 *
9894 * RETURN :
9895 *==========================================================================*/
9896
9897int QCamera3HardwareInterface::flush(
9898 const struct camera3_device *device)
9899{
9900 int rc;
9901 LOGD("E");
9902 QCamera3HardwareInterface *hw =
9903 reinterpret_cast<QCamera3HardwareInterface *>(device->priv);
9904 if (!hw) {
9905 LOGE("NULL camera device");
9906 return -EINVAL;
9907 }
9908
9909 pthread_mutex_lock(&hw->mMutex);
9910 // Validate current state
9911 switch (hw->mState) {
9912 case STARTED:
9913 /* valid state */
9914 break;
9915
9916 case ERROR:
9917 pthread_mutex_unlock(&hw->mMutex);
9918 hw->handleCameraDeviceError();
9919 return -ENODEV;
9920
9921 default:
9922 LOGI("Flush returned during state %d", hw->mState);
9923 pthread_mutex_unlock(&hw->mMutex);
9924 return 0;
9925 }
9926 pthread_mutex_unlock(&hw->mMutex);
9927
9928 rc = hw->flush(true /* restart channels */ );
9929 LOGD("X");
9930 return rc;
9931}
9932
9933/*===========================================================================
9934 * FUNCTION : close_camera_device
9935 *
9936 * DESCRIPTION:
9937 *
9938 * PARAMETERS :
9939 *
9940 *
9941 * RETURN :
9942 *==========================================================================*/
9943int QCamera3HardwareInterface::close_camera_device(struct hw_device_t* device)
9944{
9945 int ret = NO_ERROR;
9946 QCamera3HardwareInterface *hw =
9947 reinterpret_cast<QCamera3HardwareInterface *>(
9948 reinterpret_cast<camera3_device_t *>(device)->priv);
9949 if (!hw) {
9950 LOGE("NULL camera device");
9951 return BAD_VALUE;
9952 }
9953
9954 LOGI("[KPI Perf]: E camera id %d", hw->mCameraId);
9955 delete hw;
9956 LOGI("[KPI Perf]: X");
9957 return ret;
9958}
9959
9960/*===========================================================================
9961 * FUNCTION : getWaveletDenoiseProcessPlate
9962 *
9963 * DESCRIPTION: query wavelet denoise process plate
9964 *
9965 * PARAMETERS : None
9966 *
9967 * RETURN : WNR prcocess plate value
9968 *==========================================================================*/
9969cam_denoise_process_type_t QCamera3HardwareInterface::getWaveletDenoiseProcessPlate()
9970{
9971 char prop[PROPERTY_VALUE_MAX];
9972 memset(prop, 0, sizeof(prop));
9973 property_get("persist.denoise.process.plates", prop, "0");
9974 int processPlate = atoi(prop);
9975 switch(processPlate) {
9976 case 0:
9977 return CAM_WAVELET_DENOISE_YCBCR_PLANE;
9978 case 1:
9979 return CAM_WAVELET_DENOISE_CBCR_ONLY;
9980 case 2:
9981 return CAM_WAVELET_DENOISE_STREAMLINE_YCBCR;
9982 case 3:
9983 return CAM_WAVELET_DENOISE_STREAMLINED_CBCR;
9984 default:
9985 return CAM_WAVELET_DENOISE_STREAMLINE_YCBCR;
9986 }
9987}
9988
9989
9990/*===========================================================================
9991 * FUNCTION : getTemporalDenoiseProcessPlate
9992 *
9993 * DESCRIPTION: query temporal denoise process plate
9994 *
9995 * PARAMETERS : None
9996 *
9997 * RETURN : TNR prcocess plate value
9998 *==========================================================================*/
9999cam_denoise_process_type_t QCamera3HardwareInterface::getTemporalDenoiseProcessPlate()
10000{
10001 char prop[PROPERTY_VALUE_MAX];
10002 memset(prop, 0, sizeof(prop));
10003 property_get("persist.tnr.process.plates", prop, "0");
10004 int processPlate = atoi(prop);
10005 switch(processPlate) {
10006 case 0:
10007 return CAM_WAVELET_DENOISE_YCBCR_PLANE;
10008 case 1:
10009 return CAM_WAVELET_DENOISE_CBCR_ONLY;
10010 case 2:
10011 return CAM_WAVELET_DENOISE_STREAMLINE_YCBCR;
10012 case 3:
10013 return CAM_WAVELET_DENOISE_STREAMLINED_CBCR;
10014 default:
10015 return CAM_WAVELET_DENOISE_STREAMLINE_YCBCR;
10016 }
10017}
10018
10019
10020/*===========================================================================
10021 * FUNCTION : extractSceneMode
10022 *
10023 * DESCRIPTION: Extract scene mode from frameworks set metadata
10024 *
10025 * PARAMETERS :
10026 * @frame_settings: CameraMetadata reference
10027 * @metaMode: ANDROID_CONTORL_MODE
10028 * @hal_metadata: hal metadata structure
10029 *
10030 * RETURN : None
10031 *==========================================================================*/
10032int32_t QCamera3HardwareInterface::extractSceneMode(
10033 const CameraMetadata &frame_settings, uint8_t metaMode,
10034 metadata_buffer_t *hal_metadata)
10035{
10036 int32_t rc = NO_ERROR;
10037
10038 if (metaMode == ANDROID_CONTROL_MODE_USE_SCENE_MODE) {
10039 camera_metadata_ro_entry entry =
10040 frame_settings.find(ANDROID_CONTROL_SCENE_MODE);
10041 if (0 == entry.count)
10042 return rc;
10043
10044 uint8_t fwk_sceneMode = entry.data.u8[0];
10045
10046 int val = lookupHalName(SCENE_MODES_MAP,
10047 sizeof(SCENE_MODES_MAP)/sizeof(SCENE_MODES_MAP[0]),
10048 fwk_sceneMode);
10049 if (NAME_NOT_FOUND != val) {
10050 uint8_t sceneMode = (uint8_t)val;
10051 LOGD("sceneMode: %d", sceneMode);
10052 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata,
10053 CAM_INTF_PARM_BESTSHOT_MODE, sceneMode)) {
10054 rc = BAD_VALUE;
10055 }
10056 }
10057 } else if ((ANDROID_CONTROL_MODE_OFF == metaMode) ||
10058 (ANDROID_CONTROL_MODE_AUTO == metaMode)) {
10059 uint8_t sceneMode = CAM_SCENE_MODE_OFF;
10060 LOGD("sceneMode: %d", sceneMode);
10061 if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata,
10062 CAM_INTF_PARM_BESTSHOT_MODE, sceneMode)) {
10063 rc = BAD_VALUE;
10064 }
10065 }
10066 return rc;
10067}
10068
10069/*===========================================================================
10070 * FUNCTION : needRotationReprocess
10071 *
10072 * DESCRIPTION: if rotation needs to be done by reprocess in pp
10073 *
10074 * PARAMETERS : none
10075 *
10076 * RETURN : true: needed
10077 * false: no need
10078 *==========================================================================*/
10079bool QCamera3HardwareInterface::needRotationReprocess()
10080{
10081 if ((gCamCapability[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_ROTATION) > 0) {
10082 // current rotation is not zero, and pp has the capability to process rotation
10083 LOGH("need do reprocess for rotation");
10084 return true;
10085 }
10086
10087 return false;
10088}
10089
10090/*===========================================================================
10091 * FUNCTION : needReprocess
10092 *
10093 * DESCRIPTION: if reprocess in needed
10094 *
10095 * PARAMETERS : none
10096 *
10097 * RETURN : true: needed
10098 * false: no need
10099 *==========================================================================*/
10100bool QCamera3HardwareInterface::needReprocess(cam_feature_mask_t postprocess_mask)
10101{
10102 if (gCamCapability[mCameraId]->qcom_supported_feature_mask > 0) {
10103 // TODO: add for ZSL HDR later
10104 // pp module has min requirement for zsl reprocess, or WNR in ZSL mode
10105 if(postprocess_mask == CAM_QCOM_FEATURE_NONE){
10106 LOGH("need do reprocess for ZSL WNR or min PP reprocess");
10107 return true;
10108 } else {
10109 LOGH("already post processed frame");
10110 return false;
10111 }
10112 }
10113 return needRotationReprocess();
10114}
10115
10116/*===========================================================================
10117 * FUNCTION : needJpegExifRotation
10118 *
10119 * DESCRIPTION: if rotation from jpeg is needed
10120 *
10121 * PARAMETERS : none
10122 *
10123 * RETURN : true: needed
10124 * false: no need
10125 *==========================================================================*/
10126bool QCamera3HardwareInterface::needJpegExifRotation()
10127{
10128 /*If the pp does not have the ability to do rotation, enable jpeg rotation*/
10129 if (!(gCamCapability[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_ROTATION)) {
10130 LOGD("Need use Jpeg EXIF Rotation");
10131 return true;
10132 }
10133 return false;
10134}
10135
10136/*===========================================================================
10137 * FUNCTION : addOfflineReprocChannel
10138 *
10139 * DESCRIPTION: add a reprocess channel that will do reprocess on frames
10140 * coming from input channel
10141 *
10142 * PARAMETERS :
10143 * @config : reprocess configuration
10144 * @inputChHandle : pointer to the input (source) channel
10145 *
10146 *
10147 * RETURN : Ptr to the newly created channel obj. NULL if failed.
10148 *==========================================================================*/
10149QCamera3ReprocessChannel *QCamera3HardwareInterface::addOfflineReprocChannel(
10150 const reprocess_config_t &config, QCamera3ProcessingChannel *inputChHandle)
10151{
10152 int32_t rc = NO_ERROR;
10153 QCamera3ReprocessChannel *pChannel = NULL;
10154
10155 pChannel = new QCamera3ReprocessChannel(mCameraHandle->camera_handle,
10156 mChannelHandle, mCameraHandle->ops, captureResultCb, config.padding,
10157 CAM_QCOM_FEATURE_NONE, this, inputChHandle);
10158 if (NULL == pChannel) {
10159 LOGE("no mem for reprocess channel");
10160 return NULL;
10161 }
10162
10163 rc = pChannel->initialize(IS_TYPE_NONE);
10164 if (rc != NO_ERROR) {
10165 LOGE("init reprocess channel failed, ret = %d", rc);
10166 delete pChannel;
10167 return NULL;
10168 }
10169
10170 // pp feature config
10171 cam_pp_feature_config_t pp_config;
10172 memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
10173
10174 pp_config.feature_mask |= CAM_QCOM_FEATURE_PP_SUPERSET_HAL3;
10175 if (gCamCapability[mCameraId]->qcom_supported_feature_mask
10176 & CAM_QCOM_FEATURE_DSDN) {
10177 //Use CPP CDS incase h/w supports it.
10178 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CDS;
10179 pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN;
10180 }
10181 if (!(gCamCapability[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_ROTATION)) {
10182 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_ROTATION;
10183 }
10184
10185 rc = pChannel->addReprocStreamsFromSource(pp_config,
10186 config,
10187 IS_TYPE_NONE,
10188 mMetadataChannel);
10189
10190 if (rc != NO_ERROR) {
10191 delete pChannel;
10192 return NULL;
10193 }
10194 return pChannel;
10195}
10196
10197/*===========================================================================
10198 * FUNCTION : getMobicatMask
10199 *
10200 * DESCRIPTION: returns mobicat mask
10201 *
10202 * PARAMETERS : none
10203 *
10204 * RETURN : mobicat mask
10205 *
10206 *==========================================================================*/
10207uint8_t QCamera3HardwareInterface::getMobicatMask()
10208{
10209 return m_MobicatMask;
10210}
10211
10212/*===========================================================================
10213 * FUNCTION : setMobicat
10214 *
10215 * DESCRIPTION: set Mobicat on/off.
10216 *
10217 * PARAMETERS :
10218 * @params : none
10219 *
10220 * RETURN : int32_t type of status
10221 * NO_ERROR -- success
10222 * none-zero failure code
10223 *==========================================================================*/
10224int32_t QCamera3HardwareInterface::setMobicat()
10225{
10226 char value [PROPERTY_VALUE_MAX];
10227 property_get("persist.camera.mobicat", value, "0");
10228 int32_t ret = NO_ERROR;
10229 uint8_t enableMobi = (uint8_t)atoi(value);
10230
10231 if (enableMobi) {
10232 tune_cmd_t tune_cmd;
10233 tune_cmd.type = SET_RELOAD_CHROMATIX;
10234 tune_cmd.module = MODULE_ALL;
10235 tune_cmd.value = TRUE;
10236 ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters,
10237 CAM_INTF_PARM_SET_VFE_COMMAND,
10238 tune_cmd);
10239
10240 ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters,
10241 CAM_INTF_PARM_SET_PP_COMMAND,
10242 tune_cmd);
10243 }
10244 m_MobicatMask = enableMobi;
10245
10246 return ret;
10247}
10248
10249/*===========================================================================
10250* FUNCTION : getLogLevel
10251*
10252* DESCRIPTION: Reads the log level property into a variable
10253*
10254* PARAMETERS :
10255* None
10256*
10257* RETURN :
10258* None
10259*==========================================================================*/
10260void QCamera3HardwareInterface::getLogLevel()
10261{
10262 char prop[PROPERTY_VALUE_MAX];
10263 uint32_t globalLogLevel = 0;
10264
10265 property_get("persist.camera.hal.debug", prop, "0");
10266 int val = atoi(prop);
10267 if (0 <= val) {
10268 gCamHal3LogLevel = (uint32_t)val;
10269 }
10270
10271 property_get("persist.camera.kpi.debug", prop, "1");
10272 gKpiDebugLevel = atoi(prop);
10273
10274 property_get("persist.camera.global.debug", prop, "0");
10275 val = atoi(prop);
10276 if (0 <= val) {
10277 globalLogLevel = (uint32_t)val;
10278 }
10279
10280 /* Highest log level among hal.logs and global.logs is selected */
10281 if (gCamHal3LogLevel < globalLogLevel)
10282 gCamHal3LogLevel = globalLogLevel;
10283
10284 return;
10285}
10286
10287/*===========================================================================
10288 * FUNCTION : validateStreamRotations
10289 *
10290 * DESCRIPTION: Check if the rotations requested are supported
10291 *
10292 * PARAMETERS :
10293 * @stream_list : streams to be configured
10294 *
10295 * RETURN : NO_ERROR on success
10296 * -EINVAL on failure
10297 *
10298 *==========================================================================*/
10299int QCamera3HardwareInterface::validateStreamRotations(
10300 camera3_stream_configuration_t *streamList)
10301{
10302 int rc = NO_ERROR;
10303
10304 /*
10305 * Loop through all streams requested in configuration
10306 * Check if unsupported rotations have been requested on any of them
10307 */
10308 for (size_t j = 0; j < streamList->num_streams; j++){
10309 camera3_stream_t *newStream = streamList->streams[j];
10310
10311 bool isRotated = (newStream->rotation != CAMERA3_STREAM_ROTATION_0);
10312 bool isImplDef = (newStream->format ==
10313 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
10314 bool isZsl = (newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL &&
10315 isImplDef);
10316
10317 if (isRotated && (!isImplDef || isZsl)) {
10318 LOGE("Error: Unsupported rotation of %d requested for stream"
10319 "type:%d and stream format:%d",
10320 newStream->rotation, newStream->stream_type,
10321 newStream->format);
10322 rc = -EINVAL;
10323 break;
10324 }
10325 }
10326
10327 return rc;
10328}
10329
10330/*===========================================================================
10331* FUNCTION : getFlashInfo
10332*
10333* DESCRIPTION: Retrieve information about whether the device has a flash.
10334*
10335* PARAMETERS :
10336* @cameraId : Camera id to query
10337* @hasFlash : Boolean indicating whether there is a flash device
10338* associated with given camera
10339* @flashNode : If a flash device exists, this will be its device node.
10340*
10341* RETURN :
10342* None
10343*==========================================================================*/
10344void QCamera3HardwareInterface::getFlashInfo(const int cameraId,
10345 bool& hasFlash,
10346 char (&flashNode)[QCAMERA_MAX_FILEPATH_LENGTH])
10347{
10348 cam_capability_t* camCapability = gCamCapability[cameraId];
10349 if (NULL == camCapability) {
10350 hasFlash = false;
10351 flashNode[0] = '\0';
10352 } else {
10353 hasFlash = camCapability->flash_available;
10354 strlcpy(flashNode,
10355 (char*)camCapability->flash_dev_name,
10356 QCAMERA_MAX_FILEPATH_LENGTH);
10357 }
10358}
10359
10360/*===========================================================================
10361* FUNCTION : getEepromVersionInfo
10362*
10363* DESCRIPTION: Retrieve version info of the sensor EEPROM data
10364*
10365* PARAMETERS : None
10366*
10367* RETURN : string describing EEPROM version
10368* "\0" if no such info available
10369*==========================================================================*/
10370const char *QCamera3HardwareInterface::getEepromVersionInfo()
10371{
10372 return (const char *)&gCamCapability[mCameraId]->eeprom_version_info[0];
10373}
10374
10375/*===========================================================================
10376* FUNCTION : getLdafCalib
10377*
10378* DESCRIPTION: Retrieve Laser AF calibration data
10379*
10380* PARAMETERS : None
10381*
10382* RETURN : Two uint32_t describing laser AF calibration data
10383* NULL if none is available.
10384*==========================================================================*/
10385const uint32_t *QCamera3HardwareInterface::getLdafCalib()
10386{
10387 if (mLdafCalibExist) {
10388 return &mLdafCalib[0];
10389 } else {
10390 return NULL;
10391 }
10392}
10393
10394/*===========================================================================
10395 * FUNCTION : dynamicUpdateMetaStreamInfo
10396 *
10397 * DESCRIPTION: This function:
10398 * (1) stops all the channels
10399 * (2) returns error on pending requests and buffers
10400 * (3) sends metastream_info in setparams
10401 * (4) starts all channels
10402 * This is useful when sensor has to be restarted to apply any
10403 * settings such as frame rate from a different sensor mode
10404 *
10405 * PARAMETERS : None
10406 *
10407 * RETURN : NO_ERROR on success
10408 * Error codes on failure
10409 *
10410 *==========================================================================*/
10411int32_t QCamera3HardwareInterface::dynamicUpdateMetaStreamInfo()
10412{
10413 ATRACE_CALL();
10414 int rc = NO_ERROR;
10415
10416 LOGD("E");
10417
10418 rc = stopAllChannels();
10419 if (rc < 0) {
10420 LOGE("stopAllChannels failed");
10421 return rc;
10422 }
10423
10424 rc = notifyErrorForPendingRequests();
10425 if (rc < 0) {
10426 LOGE("notifyErrorForPendingRequests failed");
10427 return rc;
10428 }
10429
10430 for (uint32_t i = 0; i < mStreamConfigInfo.num_streams; i++) {
10431 LOGI("STREAM INFO : type %d, wxh: %d x %d, pp_mask: 0x%x"
10432 "Format:%d",
10433 mStreamConfigInfo.type[i],
10434 mStreamConfigInfo.stream_sizes[i].width,
10435 mStreamConfigInfo.stream_sizes[i].height,
10436 mStreamConfigInfo.postprocess_mask[i],
10437 mStreamConfigInfo.format[i]);
10438 }
10439
10440 /* Send meta stream info once again so that ISP can start */
10441 ADD_SET_PARAM_ENTRY_TO_BATCH(mParameters,
10442 CAM_INTF_META_STREAM_INFO, mStreamConfigInfo);
10443 rc = mCameraHandle->ops->set_parms(mCameraHandle->camera_handle,
10444 mParameters);
10445 if (rc < 0) {
10446 LOGE("set Metastreaminfo failed. Sensor mode does not change");
10447 }
10448
10449 rc = startAllChannels();
10450 if (rc < 0) {
10451 LOGE("startAllChannels failed");
10452 return rc;
10453 }
10454
10455 LOGD("X");
10456 return rc;
10457}
10458
10459/*===========================================================================
10460 * FUNCTION : stopAllChannels
10461 *
10462 * DESCRIPTION: This function stops (equivalent to stream-off) all channels
10463 *
10464 * PARAMETERS : None
10465 *
10466 * RETURN : NO_ERROR on success
10467 * Error codes on failure
10468 *
10469 *==========================================================================*/
10470int32_t QCamera3HardwareInterface::stopAllChannels()
10471{
10472 int32_t rc = NO_ERROR;
10473
10474 LOGD("Stopping all channels");
10475 // Stop the Streams/Channels
10476 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
10477 it != mStreamInfo.end(); it++) {
10478 QCamera3Channel *channel = (QCamera3Channel *)(*it)->stream->priv;
10479 if (channel) {
10480 channel->stop();
10481 }
10482 (*it)->status = INVALID;
10483 }
10484
10485 if (mSupportChannel) {
10486 mSupportChannel->stop();
10487 }
10488 if (mAnalysisChannel) {
10489 mAnalysisChannel->stop();
10490 }
10491 if (mRawDumpChannel) {
10492 mRawDumpChannel->stop();
10493 }
10494 if (mMetadataChannel) {
10495 /* If content of mStreamInfo is not 0, there is metadata stream */
10496 mMetadataChannel->stop();
10497 }
10498
10499 LOGD("All channels stopped");
10500 return rc;
10501}
10502
10503/*===========================================================================
10504 * FUNCTION : startAllChannels
10505 *
10506 * DESCRIPTION: This function starts (equivalent to stream-on) all channels
10507 *
10508 * PARAMETERS : None
10509 *
10510 * RETURN : NO_ERROR on success
10511 * Error codes on failure
10512 *
10513 *==========================================================================*/
10514int32_t QCamera3HardwareInterface::startAllChannels()
10515{
10516 int32_t rc = NO_ERROR;
10517
10518 LOGD("Start all channels ");
10519 // Start the Streams/Channels
10520 if (mMetadataChannel) {
10521 /* If content of mStreamInfo is not 0, there is metadata stream */
10522 rc = mMetadataChannel->start();
10523 if (rc < 0) {
10524 LOGE("META channel start failed");
10525 return rc;
10526 }
10527 }
10528 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
10529 it != mStreamInfo.end(); it++) {
10530 QCamera3Channel *channel = (QCamera3Channel *)(*it)->stream->priv;
10531 if (channel) {
10532 rc = channel->start();
10533 if (rc < 0) {
10534 LOGE("channel start failed");
10535 return rc;
10536 }
10537 }
10538 }
10539 if (mAnalysisChannel) {
10540 mAnalysisChannel->start();
10541 }
10542 if (mSupportChannel) {
10543 rc = mSupportChannel->start();
10544 if (rc < 0) {
10545 LOGE("Support channel start failed");
10546 return rc;
10547 }
10548 }
10549 if (mRawDumpChannel) {
10550 rc = mRawDumpChannel->start();
10551 if (rc < 0) {
10552 LOGE("RAW dump channel start failed");
10553 return rc;
10554 }
10555 }
10556
10557 LOGD("All channels started");
10558 return rc;
10559}
10560
10561/*===========================================================================
10562 * FUNCTION : notifyErrorForPendingRequests
10563 *
10564 * DESCRIPTION: This function sends error for all the pending requests/buffers
10565 *
10566 * PARAMETERS : None
10567 *
10568 * RETURN : Error codes
10569 * NO_ERROR on success
10570 *
10571 *==========================================================================*/
10572int32_t QCamera3HardwareInterface::notifyErrorForPendingRequests()
10573{
10574 int32_t rc = NO_ERROR;
10575 unsigned int frameNum = 0;
10576 camera3_capture_result_t result;
10577 camera3_stream_buffer_t *pStream_Buf = NULL;
10578
10579 memset(&result, 0, sizeof(camera3_capture_result_t));
10580
10581 if (mPendingRequestsList.size() > 0) {
10582 pendingRequestIterator i = mPendingRequestsList.begin();
10583 frameNum = i->frame_number;
10584 } else {
10585 /* There might still be pending buffers even though there are
10586 no pending requests. Setting the frameNum to MAX so that
10587 all the buffers with smaller frame numbers are returned */
10588 frameNum = UINT_MAX;
10589 }
10590
10591 LOGH("Oldest frame num on mPendingRequestsList = %u",
10592 frameNum);
10593
10594 for (auto req = mPendingBuffersMap.mPendingBuffersInRequest.begin();
10595 req != mPendingBuffersMap.mPendingBuffersInRequest.end(); ) {
10596
10597 if (req->frame_number < frameNum) {
10598 // Send Error notify to frameworks for each buffer for which
10599 // metadata buffer is already sent
10600 LOGH("Sending ERROR BUFFER for frame %d for %d buffer(s)",
10601 req->frame_number, req->mPendingBufferList.size());
10602
10603 pStream_Buf = new camera3_stream_buffer_t[req->mPendingBufferList.size()];
10604 if (NULL == pStream_Buf) {
10605 LOGE("No memory for pending buffers array");
10606 return NO_MEMORY;
10607 }
10608 memset(pStream_Buf, 0,
10609 sizeof(camera3_stream_buffer_t)*req->mPendingBufferList.size());
10610 result.result = NULL;
10611 result.frame_number = req->frame_number;
10612 result.num_output_buffers = req->mPendingBufferList.size();
10613 result.output_buffers = pStream_Buf;
10614
10615 size_t index = 0;
10616 for (auto info = req->mPendingBufferList.begin();
10617 info != req->mPendingBufferList.end(); ) {
10618
10619 camera3_notify_msg_t notify_msg;
10620 memset(&notify_msg, 0, sizeof(camera3_notify_msg_t));
10621 notify_msg.type = CAMERA3_MSG_ERROR;
10622 notify_msg.message.error.error_code = CAMERA3_MSG_ERROR_BUFFER;
10623 notify_msg.message.error.error_stream = info->stream;
10624 notify_msg.message.error.frame_number = req->frame_number;
10625 pStream_Buf[index].acquire_fence = -1;
10626 pStream_Buf[index].release_fence = -1;
10627 pStream_Buf[index].buffer = info->buffer;
10628 pStream_Buf[index].status = CAMERA3_BUFFER_STATUS_ERROR;
10629 pStream_Buf[index].stream = info->stream;
10630 mCallbackOps->notify(mCallbackOps, &notify_msg);
10631 index++;
10632 // Remove buffer from list
10633 info = req->mPendingBufferList.erase(info);
10634 }
10635
10636 // Remove this request from Map
10637 LOGD("Removing request %d. Remaining requests in mPendingBuffersMap: %d",
10638 req->frame_number, mPendingBuffersMap.mPendingBuffersInRequest.size());
10639 req = mPendingBuffersMap.mPendingBuffersInRequest.erase(req);
10640
10641 mCallbackOps->process_capture_result(mCallbackOps, &result);
10642
10643 delete [] pStream_Buf;
10644 } else {
10645
10646 // Go through the pending requests info and send error request to framework
10647 pendingRequestIterator i = mPendingRequestsList.begin(); //make sure i is at the beginning
10648
10649 LOGH("Sending ERROR REQUEST for frame %d", req->frame_number);
10650
10651 // Send error notify to frameworks
10652 camera3_notify_msg_t notify_msg;
10653 memset(&notify_msg, 0, sizeof(camera3_notify_msg_t));
10654 notify_msg.type = CAMERA3_MSG_ERROR;
10655 notify_msg.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
10656 notify_msg.message.error.error_stream = NULL;
10657 notify_msg.message.error.frame_number = req->frame_number;
10658 mCallbackOps->notify(mCallbackOps, &notify_msg);
10659
10660 pStream_Buf = new camera3_stream_buffer_t[req->mPendingBufferList.size()];
10661 if (NULL == pStream_Buf) {
10662 LOGE("No memory for pending buffers array");
10663 return NO_MEMORY;
10664 }
10665 memset(pStream_Buf, 0, sizeof(camera3_stream_buffer_t)*req->mPendingBufferList.size());
10666
10667 result.result = NULL;
10668 result.frame_number = req->frame_number;
10669 result.input_buffer = i->input_buffer;
10670 result.num_output_buffers = req->mPendingBufferList.size();
10671 result.output_buffers = pStream_Buf;
10672
10673 size_t index = 0;
10674 for (auto info = req->mPendingBufferList.begin();
10675 info != req->mPendingBufferList.end(); ) {
10676 pStream_Buf[index].acquire_fence = -1;
10677 pStream_Buf[index].release_fence = -1;
10678 pStream_Buf[index].buffer = info->buffer;
10679 pStream_Buf[index].status = CAMERA3_BUFFER_STATUS_ERROR;
10680 pStream_Buf[index].stream = info->stream;
10681 index++;
10682 // Remove buffer from list
10683 info = req->mPendingBufferList.erase(info);
10684 }
10685
10686 // Remove this request from Map
10687 LOGD("Removing request %d. Remaining requests in mPendingBuffersMap: %d",
10688 req->frame_number, mPendingBuffersMap.mPendingBuffersInRequest.size());
10689 req = mPendingBuffersMap.mPendingBuffersInRequest.erase(req);
10690
10691 mCallbackOps->process_capture_result(mCallbackOps, &result);
10692 delete [] pStream_Buf;
10693 i = erasePendingRequest(i);
10694 }
10695 }
10696
10697 /* Reset pending frame Drop list and requests list */
10698 mPendingFrameDropList.clear();
10699
10700 for (auto &req : mPendingBuffersMap.mPendingBuffersInRequest) {
10701 req.mPendingBufferList.clear();
10702 }
10703 mPendingBuffersMap.mPendingBuffersInRequest.clear();
10704 mPendingReprocessResultList.clear();
10705 LOGH("Cleared all the pending buffers ");
10706
10707 return rc;
10708}
10709
10710bool QCamera3HardwareInterface::isOnEncoder(
10711 const cam_dimension_t max_viewfinder_size,
10712 uint32_t width, uint32_t height)
10713{
10714 return (width > (uint32_t)max_viewfinder_size.width ||
10715 height > (uint32_t)max_viewfinder_size.height);
10716}
10717
10718/*===========================================================================
10719 * FUNCTION : setBundleInfo
10720 *
10721 * DESCRIPTION: Set bundle info for all streams that are bundle.
10722 *
10723 * PARAMETERS : None
10724 *
10725 * RETURN : NO_ERROR on success
10726 * Error codes on failure
10727 *==========================================================================*/
10728int32_t QCamera3HardwareInterface::setBundleInfo()
10729{
10730 int32_t rc = NO_ERROR;
10731
10732 if (mChannelHandle) {
10733 cam_bundle_config_t bundleInfo;
10734 memset(&bundleInfo, 0, sizeof(bundleInfo));
10735 rc = mCameraHandle->ops->get_bundle_info(
10736 mCameraHandle->camera_handle, mChannelHandle, &bundleInfo);
10737 if (rc != NO_ERROR) {
10738 LOGE("get_bundle_info failed");
10739 return rc;
10740 }
10741 if (mAnalysisChannel) {
10742 mAnalysisChannel->setBundleInfo(bundleInfo);
10743 }
10744 if (mSupportChannel) {
10745 mSupportChannel->setBundleInfo(bundleInfo);
10746 }
10747 for (List<stream_info_t *>::iterator it = mStreamInfo.begin();
10748 it != mStreamInfo.end(); it++) {
10749 QCamera3Channel *channel = (QCamera3Channel *)(*it)->stream->priv;
10750 channel->setBundleInfo(bundleInfo);
10751 }
10752 if (mRawDumpChannel) {
10753 mRawDumpChannel->setBundleInfo(bundleInfo);
10754 }
10755 }
10756
10757 return rc;
10758}
10759
10760/*===========================================================================
10761 * FUNCTION : get_num_overall_buffers
10762 *
10763 * DESCRIPTION: Estimate number of pending buffers across all requests.
10764 *
10765 * PARAMETERS : None
10766 *
10767 * RETURN : Number of overall pending buffers
10768 *
10769 *==========================================================================*/
10770uint32_t PendingBuffersMap::get_num_overall_buffers()
10771{
10772 uint32_t sum_buffers = 0;
10773 for (auto &req : mPendingBuffersInRequest) {
10774 sum_buffers += req.mPendingBufferList.size();
10775 }
10776 return sum_buffers;
10777}
10778
10779/*===========================================================================
10780 * FUNCTION : removeBuf
10781 *
10782 * DESCRIPTION: Remove a matching buffer from tracker.
10783 *
10784 * PARAMETERS : @buffer: image buffer for the callback
10785 *
10786 * RETURN : None
10787 *
10788 *==========================================================================*/
10789void PendingBuffersMap::removeBuf(buffer_handle_t *buffer)
10790{
10791 bool buffer_found = false;
10792 for (auto req = mPendingBuffersInRequest.begin();
10793 req != mPendingBuffersInRequest.end(); req++) {
10794 for (auto k = req->mPendingBufferList.begin();
10795 k != req->mPendingBufferList.end(); k++ ) {
10796 if (k->buffer == buffer) {
10797 LOGD("Frame %d: Found Frame buffer %p, take it out from mPendingBufferList",
10798 req->frame_number, buffer);
10799 k = req->mPendingBufferList.erase(k);
10800 if (req->mPendingBufferList.empty()) {
10801 // Remove this request from Map
10802 req = mPendingBuffersInRequest.erase(req);
10803 }
10804 buffer_found = true;
10805 break;
10806 }
10807 }
10808 if (buffer_found) {
10809 break;
10810 }
10811 }
10812 LOGD("mPendingBuffersMap.num_overall_buffers = %d",
10813 get_num_overall_buffers());
10814}
10815
10816/*===========================================================================
10817 * FUNCTION : setPAAFSupport
10818 *
10819 * DESCRIPTION: Set the preview-assisted auto focus support bit in
10820 * feature mask according to stream type and filter
10821 * arrangement
10822 *
10823 * PARAMETERS : @feature_mask: current feature mask, which may be modified
10824 * @stream_type: stream type
10825 * @filter_arrangement: filter arrangement
10826 *
10827 * RETURN : None
10828 *==========================================================================*/
10829void QCamera3HardwareInterface::setPAAFSupport(
10830 cam_feature_mask_t& feature_mask,
10831 cam_stream_type_t stream_type,
10832 cam_color_filter_arrangement_t filter_arrangement)
10833{
10834 LOGD("feature_mask=0x%llx; stream_type=%d, filter_arrangement=%d",
10835 feature_mask, stream_type, filter_arrangement);
10836
10837 switch (filter_arrangement) {
10838 case CAM_FILTER_ARRANGEMENT_RGGB:
10839 case CAM_FILTER_ARRANGEMENT_GRBG:
10840 case CAM_FILTER_ARRANGEMENT_GBRG:
10841 case CAM_FILTER_ARRANGEMENT_BGGR:
10842 if ((stream_type == CAM_STREAM_TYPE_CALLBACK) ||
10843 (stream_type == CAM_STREAM_TYPE_PREVIEW) ||
10844 (stream_type == CAM_STREAM_TYPE_VIDEO)) {
10845 feature_mask |= CAM_QCOM_FEATURE_PAAF;
10846 }
10847 break;
10848 case CAM_FILTER_ARRANGEMENT_Y:
10849 if (stream_type == CAM_STREAM_TYPE_ANALYSIS) {
10850 feature_mask |= CAM_QCOM_FEATURE_PAAF;
10851 }
10852 break;
10853 default:
10854 break;
10855 }
10856}
10857
10858/*===========================================================================
10859* FUNCTION : getSensorMountAngle
10860*
10861* DESCRIPTION: Retrieve sensor mount angle
10862*
10863* PARAMETERS : None
10864*
10865* RETURN : sensor mount angle in uint32_t
10866*==========================================================================*/
10867uint32_t QCamera3HardwareInterface::getSensorMountAngle()
10868{
10869 return gCamCapability[mCameraId]->sensor_mount_angle;
10870}
10871
10872/*===========================================================================
10873* FUNCTION : getRelatedCalibrationData
10874*
10875* DESCRIPTION: Retrieve related system calibration data
10876*
10877* PARAMETERS : None
10878*
10879* RETURN : Pointer of related system calibration data
10880*==========================================================================*/
10881const cam_related_system_calibration_data_t *QCamera3HardwareInterface::getRelatedCalibrationData()
10882{
10883 return (const cam_related_system_calibration_data_t *)
10884 &(gCamCapability[mCameraId]->related_cam_calibration);
10885}
10886}; //end namespace qcamera