1 /* Copyright (c) 2012-2017, 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 "QCamera2HWI"
31
32 // To remove
33 #include <cutils/properties.h>
34
35 // System definitions
36 #include <utils/Errors.h>
37 #include <dlfcn.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include "gralloc_priv.h"
41 #include "native_handle.h"
42
43 // Camera definitions
44 #include "android/QCamera2External.h"
45 #include "QCamera2HWI.h"
46 #include "QCameraBufferMaps.h"
47 #include "QCameraFlash.h"
48 #include "QCameraTrace.h"
49
50 extern "C" {
51 #include "mm_camera_dbg.h"
52 }
53
54 #define MAP_TO_DRIVER_COORDINATE(val, base, scale, offset) \
55 ((int32_t)val * (int32_t)scale / (int32_t)base + (int32_t)offset)
56 #define CAMERA_MIN_STREAMING_BUFFERS 3
57 #define EXTRA_ZSL_PREVIEW_STREAM_BUF 2
58 #define CAMERA_MIN_JPEG_ENCODING_BUFFERS 2
59 #define CAMERA_MIN_VIDEO_BUFFERS 9
60 #define CAMERA_MIN_CALLBACK_BUFFERS 5
61 #define CAMERA_LONGSHOT_STAGES 4
62 #define CAMERA_MIN_CAMERA_BATCH_BUFFERS 6
63 #define CAMERA_ISP_PING_PONG_BUFFERS 2
64 #define MIN_UNDEQUEUED_BUFFERS 1 // This is required if preview window is not set
65 #define CAMERA_MIN_DISPLAY_BUFFERS 2
66 #define CAMERA_DEFAULT_FPS 30000
67
68 #define HDR_CONFIDENCE_THRESHOLD 0.4
69
70 #define CAMERA_OPEN_PERF_TIME_OUT 500 // 500 milliseconds
71
72 // Very long wait, just to be sure we don't deadlock
73 #define CAMERA_DEFERRED_THREAD_TIMEOUT 5000000000 // 5 seconds
74 #define CAMERA_DEFERRED_MAP_BUF_TIMEOUT 2000000000 // 2 seconds
75 #define CAMERA_MIN_METADATA_BUFFERS 10 // Need at least 10 for ZSL snapshot
76 #define CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS 5
77 #define CAMERA_MAX_PARAM_APPLY_DELAY 3
78
79 namespace qcamera {
80
81 extern cam_capability_t *gCamCapability[MM_CAMERA_MAX_NUM_SENSORS];
82 extern pthread_mutex_t gCamLock;
83 volatile uint32_t gCamHalLogLevel = 1;
84 extern uint8_t gNumCameraSessions;
85 uint32_t QCamera2HardwareInterface::sNextJobId = 1;
86
87 camera_device_ops_t QCamera2HardwareInterface::mCameraOps = {
88 .set_preview_window = QCamera2HardwareInterface::set_preview_window,
89 .set_callbacks = QCamera2HardwareInterface::set_CallBacks,
90 .enable_msg_type = QCamera2HardwareInterface::enable_msg_type,
91 .disable_msg_type = QCamera2HardwareInterface::disable_msg_type,
92 .msg_type_enabled = QCamera2HardwareInterface::msg_type_enabled,
93
94 .start_preview = QCamera2HardwareInterface::start_preview,
95 .stop_preview = QCamera2HardwareInterface::stop_preview,
96 .preview_enabled = QCamera2HardwareInterface::preview_enabled,
97 .store_meta_data_in_buffers= QCamera2HardwareInterface::store_meta_data_in_buffers,
98
99 .start_recording = QCamera2HardwareInterface::start_recording,
100 .stop_recording = QCamera2HardwareInterface::stop_recording,
101 .recording_enabled = QCamera2HardwareInterface::recording_enabled,
102 .release_recording_frame = QCamera2HardwareInterface::release_recording_frame,
103
104 .auto_focus = QCamera2HardwareInterface::auto_focus,
105 .cancel_auto_focus = QCamera2HardwareInterface::cancel_auto_focus,
106
107 .take_picture = QCamera2HardwareInterface::take_picture,
108 .cancel_picture = QCamera2HardwareInterface::cancel_picture,
109
110 .set_parameters = QCamera2HardwareInterface::set_parameters,
111 .get_parameters = QCamera2HardwareInterface::get_parameters,
112 .put_parameters = QCamera2HardwareInterface::put_parameters,
113 .send_command = QCamera2HardwareInterface::send_command,
114
115 .release = QCamera2HardwareInterface::release,
116 .dump = QCamera2HardwareInterface::dump,
117 };
118
119 /*===========================================================================
120 * FUNCTION : set_preview_window
121 *
122 * DESCRIPTION: set preview window.
123 *
124 * PARAMETERS :
125 * @device : ptr to camera device struct
126 * @window : window ops table
127 *
128 * RETURN : int32_t type of status
129 * NO_ERROR -- success
130 * none-zero failure code
131 *==========================================================================*/
set_preview_window(struct camera_device * device,struct preview_stream_ops * window)132 int QCamera2HardwareInterface::set_preview_window(struct camera_device *device,
133 struct preview_stream_ops *window)
134 {
135 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SET_PREVIEW_WINDOW);
136 int rc = NO_ERROR;
137 QCamera2HardwareInterface *hw =
138 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
139 if (!hw) {
140 LOGE("NULL camera device");
141 return BAD_VALUE;
142 }
143 LOGD("E camera id %d window = %p", hw->getCameraId(), window);
144
145 hw->lockAPI();
146 qcamera_api_result_t apiResult;
147 rc = hw->processAPI(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, (void *)window);
148 if (rc == NO_ERROR) {
149 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PREVIEW_WINDOW, &apiResult);
150 rc = apiResult.status;
151 }
152 hw->unlockAPI();
153 LOGD("X camera id %d", hw->getCameraId());
154
155 return rc;
156 }
157
158 /*===========================================================================
159 * FUNCTION : set_CallBacks
160 *
161 * DESCRIPTION: set callbacks for notify and data
162 *
163 * PARAMETERS :
164 * @device : ptr to camera device struct
165 * @notify_cb : notify cb
166 * @data_cb : data cb
167 * @data_cb_timestamp : video data cd with timestamp
168 * @get_memory : ops table for request gralloc memory
169 * @user : user data ptr
170 *
171 * RETURN : none
172 *==========================================================================*/
set_CallBacks(struct camera_device * device,camera_notify_callback notify_cb,camera_data_callback data_cb,camera_data_timestamp_callback data_cb_timestamp,camera_request_memory get_memory,void * user)173 void QCamera2HardwareInterface::set_CallBacks(struct camera_device *device,
174 camera_notify_callback notify_cb,
175 camera_data_callback data_cb,
176 camera_data_timestamp_callback data_cb_timestamp,
177 camera_request_memory get_memory,
178 void *user)
179 {
180 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SET_CALLBACKS);
181 QCamera2HardwareInterface *hw =
182 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
183 if (!hw) {
184 LOGE("NULL camera device");
185 return;
186 }
187 LOGD("E camera id %d", hw->getCameraId());
188
189 qcamera_sm_evt_setcb_payload_t payload;
190 payload.notify_cb = notify_cb;
191 payload.data_cb = data_cb;
192 payload.data_cb_timestamp = data_cb_timestamp;
193 payload.get_memory = get_memory;
194 payload.user = user;
195
196 hw->lockAPI();
197 qcamera_api_result_t apiResult;
198 int32_t rc = hw->processAPI(QCAMERA_SM_EVT_SET_CALLBACKS, (void *)&payload);
199 if (rc == NO_ERROR) {
200 hw->waitAPIResult(QCAMERA_SM_EVT_SET_CALLBACKS, &apiResult);
201 }
202 hw->unlockAPI();
203 LOGD("X camera id %d", hw->getCameraId());
204
205 }
206
207 /*===========================================================================
208 * FUNCTION : enable_msg_type
209 *
210 * DESCRIPTION: enable certain msg type
211 *
212 * PARAMETERS :
213 * @device : ptr to camera device struct
214 * @msg_type : msg type mask
215 *
216 * RETURN : none
217 *==========================================================================*/
enable_msg_type(struct camera_device * device,int32_t msg_type)218 void QCamera2HardwareInterface::enable_msg_type(struct camera_device *device, int32_t msg_type)
219 {
220 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_ENABLE_MSG_TYPE);
221 QCamera2HardwareInterface *hw =
222 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
223 if (!hw) {
224 LOGE("NULL camera device");
225 return;
226 }
227 LOGD("E camera id %d", hw->getCameraId());
228
229 hw->lockAPI();
230 qcamera_api_result_t apiResult;
231 int32_t rc = hw->processAPI(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, (void *)&msg_type);
232 if (rc == NO_ERROR) {
233 hw->waitAPIResult(QCAMERA_SM_EVT_ENABLE_MSG_TYPE, &apiResult);
234 }
235 hw->unlockAPI();
236 LOGD("X camera id %d", hw->getCameraId());
237
238 }
239
240 /*===========================================================================
241 * FUNCTION : disable_msg_type
242 *
243 * DESCRIPTION: disable certain msg type
244 *
245 * PARAMETERS :
246 * @device : ptr to camera device struct
247 * @msg_type : msg type mask
248 *
249 * RETURN : none
250 *==========================================================================*/
disable_msg_type(struct camera_device * device,int32_t msg_type)251 void QCamera2HardwareInterface::disable_msg_type(struct camera_device *device, int32_t msg_type)
252 {
253 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_DISABLE_MSG_TYPE);
254 QCamera2HardwareInterface *hw =
255 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
256 if (!hw) {
257 LOGE("NULL camera device");
258 return;
259 }
260 LOGD("E camera id %d", hw->getCameraId());
261
262 hw->lockAPI();
263 qcamera_api_result_t apiResult;
264 int32_t rc = hw->processAPI(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, (void *)&msg_type);
265 if (rc == NO_ERROR) {
266 hw->waitAPIResult(QCAMERA_SM_EVT_DISABLE_MSG_TYPE, &apiResult);
267 }
268 hw->unlockAPI();
269 LOGD("X camera id %d", hw->getCameraId());
270
271 }
272
273 /*===========================================================================
274 * FUNCTION : msg_type_enabled
275 *
276 * DESCRIPTION: if certain msg type is enabled
277 *
278 * PARAMETERS :
279 * @device : ptr to camera device struct
280 * @msg_type : msg type mask
281 *
282 * RETURN : 1 -- enabled
283 * 0 -- not enabled
284 *==========================================================================*/
msg_type_enabled(struct camera_device * device,int32_t msg_type)285 int QCamera2HardwareInterface::msg_type_enabled(struct camera_device *device, int32_t msg_type)
286 {
287 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_MSG_TYPE_ENABLED);
288 int ret = NO_ERROR;
289 QCamera2HardwareInterface *hw =
290 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
291 if (!hw) {
292 LOGE("NULL camera device");
293 return BAD_VALUE;
294 }
295 LOGD("E camera id %d", hw->getCameraId());
296
297 hw->lockAPI();
298 qcamera_api_result_t apiResult;
299 ret = hw->processAPI(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, (void *)&msg_type);
300 if (ret == NO_ERROR) {
301 hw->waitAPIResult(QCAMERA_SM_EVT_MSG_TYPE_ENABLED, &apiResult);
302 ret = apiResult.enabled;
303 }
304 hw->unlockAPI();
305 LOGD("X camera id %d", hw->getCameraId());
306
307 return ret;
308 }
309
310 /*===========================================================================
311 * FUNCTION : prepare_preview
312 *
313 * DESCRIPTION: prepare preview
314 *
315 * PARAMETERS :
316 * @device : ptr to camera device struct
317 *
318 * RETURN : int32_t type of status
319 * NO_ERROR -- success
320 * none-zero failure code
321 *==========================================================================*/
prepare_preview(struct camera_device * device)322 int QCamera2HardwareInterface::prepare_preview(struct camera_device *device)
323 {
324 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPARE_PREVIEW);
325 int ret = NO_ERROR;
326 QCamera2HardwareInterface *hw =
327 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
328 if (!hw) {
329 LOGE("NULL camera device");
330 return BAD_VALUE;
331 }
332 LOGH("[KPI Perf]: E PROFILE_PREPARE_PREVIEW camera id %d",
333 hw->getCameraId());
334 hw->lockAPI();
335 qcamera_api_result_t apiResult;
336 qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_PREPARE_PREVIEW;
337 ret = hw->processAPI(evt, NULL);
338 if (ret == NO_ERROR) {
339 hw->waitAPIResult(evt, &apiResult);
340 ret = apiResult.status;
341 }
342 hw->unlockAPI();
343 LOGH("[KPI Perf]: X");
344 return ret;
345 }
346
347
348 /*===========================================================================
349 * FUNCTION : start_preview
350 *
351 * DESCRIPTION: start preview
352 *
353 * PARAMETERS :
354 * @device : ptr to camera device struct
355 *
356 * RETURN : int32_t type of status
357 * NO_ERROR -- success
358 * none-zero failure code
359 *==========================================================================*/
start_preview(struct camera_device * device)360 int QCamera2HardwareInterface::start_preview(struct camera_device *device)
361 {
362 KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_START_PREVIEW);
363 int ret = NO_ERROR;
364 QCamera2HardwareInterface *hw =
365 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
366 if (!hw) {
367 LOGE("NULL camera device");
368 return BAD_VALUE;
369 }
370 LOGI("[KPI Perf]: E PROFILE_START_PREVIEW camera id %d",
371 hw->getCameraId());
372
373 hw->m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_PREVIEW);
374 hw->lockAPI();
375 qcamera_api_result_t apiResult;
376 qcamera_sm_evt_enum_t evt = QCAMERA_SM_EVT_START_PREVIEW;
377 if (hw->isNoDisplayMode()) {
378 evt = QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW;
379 }
380 ret = hw->processAPI(evt, NULL);
381 if (ret == NO_ERROR) {
382 hw->waitAPIResult(evt, &apiResult);
383 ret = apiResult.status;
384 }
385 hw->unlockAPI();
386 hw->m_bPreviewStarted = true;
387 LOGI("[KPI Perf]: X ret = %d", ret);
388 return ret;
389 }
390
391 /*===========================================================================
392 * FUNCTION : stop_preview
393 *
394 * DESCRIPTION: stop preview
395 *
396 * PARAMETERS :
397 * @device : ptr to camera device struct
398 *
399 * RETURN : none
400 *==========================================================================*/
stop_preview(struct camera_device * device)401 void QCamera2HardwareInterface::stop_preview(struct camera_device *device)
402 {
403 KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOP_PREVIEW);
404 QCamera2HardwareInterface *hw =
405 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
406 if (!hw) {
407 LOGE("NULL camera device");
408 return;
409 }
410 LOGI("[KPI Perf]: E PROFILE_STOP_PREVIEW camera id %d",
411 hw->getCameraId());
412
413 // Disable power Hint for preview
414 hw->m_perfLockMgr.releasePerfLock(PERF_LOCK_POWERHINT_PREVIEW);
415
416 hw->m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_PREVIEW);
417
418 hw->lockAPI();
419 qcamera_api_result_t apiResult;
420 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_PREVIEW, NULL);
421 if (ret == NO_ERROR) {
422 hw->waitAPIResult(QCAMERA_SM_EVT_STOP_PREVIEW, &apiResult);
423 }
424 hw->unlockAPI();
425 LOGI("[KPI Perf]: X ret = %d", ret);
426 }
427
428 /*===========================================================================
429 * FUNCTION : preview_enabled
430 *
431 * DESCRIPTION: if preview is running
432 *
433 * PARAMETERS :
434 * @device : ptr to camera device struct
435 *
436 * RETURN : 1 -- running
437 * 0 -- not running
438 *==========================================================================*/
preview_enabled(struct camera_device * device)439 int QCamera2HardwareInterface::preview_enabled(struct camera_device *device)
440 {
441 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREVIEW_ENABLED);
442 int ret = NO_ERROR;
443 QCamera2HardwareInterface *hw =
444 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
445 if (!hw) {
446 LOGE("NULL camera device");
447 return BAD_VALUE;
448 }
449 LOGD("E camera id %d", hw->getCameraId());
450
451 hw->lockAPI();
452 qcamera_api_result_t apiResult;
453 ret = hw->processAPI(QCAMERA_SM_EVT_PREVIEW_ENABLED, NULL);
454 if (ret == NO_ERROR) {
455 hw->waitAPIResult(QCAMERA_SM_EVT_PREVIEW_ENABLED, &apiResult);
456 ret = apiResult.enabled;
457 }
458
459 //if preview enabled, can enable preview callback send
460 if(apiResult.enabled) {
461 hw->m_stateMachine.setPreviewCallbackNeeded(true);
462 }
463 hw->unlockAPI();
464 LOGD("X camera id %d", hw->getCameraId());
465
466 return ret;
467 }
468
469 /*===========================================================================
470 * FUNCTION : store_meta_data_in_buffers
471 *
472 * DESCRIPTION: if need to store meta data in buffers for video frame
473 *
474 * PARAMETERS :
475 * @device : ptr to camera device struct
476 * @enable : flag if enable
477 *
478 * RETURN : int32_t type of status
479 * NO_ERROR -- success
480 * none-zero failure code
481 *==========================================================================*/
store_meta_data_in_buffers(struct camera_device * device,int enable)482 int QCamera2HardwareInterface::store_meta_data_in_buffers(
483 struct camera_device *device, int enable)
484 {
485 int ret = NO_ERROR;
486 QCamera2HardwareInterface *hw =
487 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
488 if (!hw) {
489 LOGE("NULL camera device");
490 return BAD_VALUE;
491 }
492 LOGD("E camera id %d", hw->getCameraId());
493
494 hw->lockAPI();
495 qcamera_api_result_t apiResult;
496 ret = hw->processAPI(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS, (void *)&enable);
497 if (ret == NO_ERROR) {
498 hw->waitAPIResult(QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS, &apiResult);
499 ret = apiResult.status;
500 }
501 hw->unlockAPI();
502 LOGD("X camera id %d", hw->getCameraId());
503
504 return ret;
505 }
506
507 /*===========================================================================
508 * FUNCTION : restart_start_preview
509 *
510 * DESCRIPTION: start preview as part of the restart preview
511 *
512 * PARAMETERS :
513 * @device : ptr to camera device struct
514 *
515 * RETURN : int32_t type of status
516 * NO_ERROR -- success
517 * none-zero failure code
518 *==========================================================================*/
restart_start_preview(struct camera_device * device)519 int QCamera2HardwareInterface::restart_start_preview(struct camera_device *device)
520 {
521 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RESTART_START_PREVIEW);
522 int ret = NO_ERROR;
523 QCamera2HardwareInterface *hw =
524 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
525 if (!hw) {
526 LOGE("NULL camera device");
527 return BAD_VALUE;
528 }
529 LOGI("E camera id %d", hw->getCameraId());
530 hw->lockAPI();
531 qcamera_api_result_t apiResult;
532
533 if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
534 ret = hw->processAPI(QCAMERA_SM_EVT_RESTART_START_PREVIEW, NULL);
535 if (ret == NO_ERROR) {
536 hw->waitAPIResult(QCAMERA_SM_EVT_RESTART_START_PREVIEW, &apiResult);
537 ret = apiResult.status;
538 }
539 } else {
540 LOGE("This function is not supposed to be called in single-camera mode");
541 ret = INVALID_OPERATION;
542 }
543 // Preview restart done, update the mPreviewRestartNeeded flag to false.
544 hw->mPreviewRestartNeeded = false;
545 hw->unlockAPI();
546 LOGI("X camera id %d", hw->getCameraId());
547
548 return ret;
549 }
550
551 /*===========================================================================
552 * FUNCTION : restart_stop_preview
553 *
554 * DESCRIPTION: stop preview as part of the restart preview
555 *
556 * PARAMETERS :
557 * @device : ptr to camera device struct
558 *
559 * RETURN : int32_t type of status
560 * NO_ERROR -- success
561 * none-zero failure code
562 *==========================================================================*/
restart_stop_preview(struct camera_device * device)563 int QCamera2HardwareInterface::restart_stop_preview(struct camera_device *device)
564 {
565 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RESTART_STOP_PREVIEW);
566 int ret = NO_ERROR;
567 QCamera2HardwareInterface *hw =
568 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
569 if (!hw) {
570 LOGE("NULL camera device");
571 return BAD_VALUE;
572 }
573 LOGI("E camera id %d", hw->getCameraId());
574 hw->lockAPI();
575 qcamera_api_result_t apiResult;
576
577 if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
578 ret = hw->processAPI(QCAMERA_SM_EVT_RESTART_STOP_PREVIEW, NULL);
579 if (ret == NO_ERROR) {
580 hw->waitAPIResult(QCAMERA_SM_EVT_RESTART_STOP_PREVIEW, &apiResult);
581 ret = apiResult.status;
582 }
583 } else {
584 LOGE("This function is not supposed to be called in single-camera mode");
585 ret = INVALID_OPERATION;
586 }
587
588 hw->unlockAPI();
589 LOGI("X camera id %d", hw->getCameraId());
590
591 return ret;
592 }
593
594 /*===========================================================================
595 * FUNCTION : pre_start_recording
596 *
597 * DESCRIPTION: prepare for the start recording
598 *
599 * PARAMETERS :
600 * @device : ptr to camera device struct
601 *
602 * RETURN : int32_t type of status
603 * NO_ERROR -- success
604 * none-zero failure code
605 *==========================================================================*/
pre_start_recording(struct camera_device * device)606 int QCamera2HardwareInterface::pre_start_recording(struct camera_device *device)
607 {
608 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PRE_START_RECORDING);
609 int ret = NO_ERROR;
610 QCamera2HardwareInterface *hw =
611 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
612 if (!hw) {
613 LOGE("NULL camera device");
614 return BAD_VALUE;
615 }
616 LOGH("[KPI Perf]: E PROFILE_PRE_START_RECORDING camera id %d",
617 hw->getCameraId());
618 hw->lockAPI();
619 qcamera_api_result_t apiResult;
620 ret = hw->processAPI(QCAMERA_SM_EVT_PRE_START_RECORDING, NULL);
621 if (ret == NO_ERROR) {
622 hw->waitAPIResult(QCAMERA_SM_EVT_PRE_START_RECORDING, &apiResult);
623 ret = apiResult.status;
624 }
625 hw->unlockAPI();
626 LOGH("[KPI Perf]: X");
627 return ret;
628 }
629
630 /*===========================================================================
631 * FUNCTION : start_recording
632 *
633 * DESCRIPTION: start recording
634 *
635 * PARAMETERS :
636 * @device : ptr to camera device struct
637 *
638 * RETURN : int32_t type of status
639 * NO_ERROR -- success
640 * none-zero failure code
641 *==========================================================================*/
start_recording(struct camera_device * device)642 int QCamera2HardwareInterface::start_recording(struct camera_device *device)
643 {
644 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_START_RECORDING);
645 int ret = NO_ERROR;
646 QCamera2HardwareInterface *hw =
647 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
648 if (!hw) {
649 LOGE("NULL camera device");
650 return BAD_VALUE;
651 }
652
653 hw->m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_RECORDING);
654
655 LOGI("[KPI Perf]: E PROFILE_START_RECORDING camera id %d",
656 hw->getCameraId());
657 // Give HWI control to call pre_start_recording in single camera mode.
658 // In dual-cam mode, this control belongs to muxer.
659 if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
660 ret = pre_start_recording(device);
661 if (ret != NO_ERROR) {
662 LOGE("pre_start_recording failed with ret = %d", ret);
663 hw->m_perfLockMgr.releasePerfLock(PERF_LOCK_START_RECORDING);
664 return ret;
665 }
666 }
667
668 hw->lockAPI();
669 qcamera_api_result_t apiResult;
670 ret = hw->processAPI(QCAMERA_SM_EVT_START_RECORDING, NULL);
671 if (ret == NO_ERROR) {
672 hw->waitAPIResult(QCAMERA_SM_EVT_START_RECORDING, &apiResult);
673 ret = apiResult.status;
674 }
675 hw->unlockAPI();
676 hw->m_bRecordStarted = true;
677 LOGI("[KPI Perf]: X ret = %d", ret);
678
679 return ret;
680 }
681
682 /*===========================================================================
683 * FUNCTION : stop_recording
684 *
685 * DESCRIPTION: stop recording
686 *
687 * PARAMETERS :
688 * @device : ptr to camera device struct
689 *
690 * RETURN : none
691 *==========================================================================*/
stop_recording(struct camera_device * device)692 void QCamera2HardwareInterface::stop_recording(struct camera_device *device)
693 {
694 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOP_RECORDING);
695 QCamera2HardwareInterface *hw =
696 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
697 if (!hw) {
698 LOGE("NULL camera device");
699 return;
700 }
701
702 hw->m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_RECORDING);
703
704 LOGI("[KPI Perf]: E PROFILE_STOP_RECORDING camera id %d",
705 hw->getCameraId());
706
707 hw->lockAPI();
708 qcamera_api_result_t apiResult;
709 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_STOP_RECORDING, NULL);
710 if (ret == NO_ERROR) {
711 hw->waitAPIResult(QCAMERA_SM_EVT_STOP_RECORDING, &apiResult);
712 }
713 hw->unlockAPI();
714 LOGI("[KPI Perf]: X ret = %d", ret);
715 }
716
717 /*===========================================================================
718 * FUNCTION : recording_enabled
719 *
720 * DESCRIPTION: if recording is running
721 *
722 * PARAMETERS :
723 * @device : ptr to camera device struct
724 *
725 * RETURN : 1 -- running
726 * 0 -- not running
727 *==========================================================================*/
recording_enabled(struct camera_device * device)728 int QCamera2HardwareInterface::recording_enabled(struct camera_device *device)
729 {
730 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RECORDING_ENABLED);
731 int ret = NO_ERROR;
732 QCamera2HardwareInterface *hw =
733 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
734 if (!hw) {
735 LOGE("NULL camera device");
736 return BAD_VALUE;
737 }
738 LOGD("E camera id %d", hw->getCameraId());
739 hw->lockAPI();
740 qcamera_api_result_t apiResult;
741 ret = hw->processAPI(QCAMERA_SM_EVT_RECORDING_ENABLED, NULL);
742 if (ret == NO_ERROR) {
743 hw->waitAPIResult(QCAMERA_SM_EVT_RECORDING_ENABLED, &apiResult);
744 ret = apiResult.enabled;
745 }
746 hw->unlockAPI();
747 LOGD("X camera id %d", hw->getCameraId());
748
749 return ret;
750 }
751
752 /*===========================================================================
753 * FUNCTION : release_recording_frame
754 *
755 * DESCRIPTION: return recording frame back
756 *
757 * PARAMETERS :
758 * @device : ptr to camera device struct
759 * @opaque : ptr to frame to be returned
760 *
761 * RETURN : none
762 *==========================================================================*/
release_recording_frame(struct camera_device * device,const void * opaque)763 void QCamera2HardwareInterface::release_recording_frame(
764 struct camera_device *device, const void *opaque)
765 {
766 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_REL_REC_FRAME);
767 int32_t ret = NO_ERROR;
768 QCamera2HardwareInterface *hw =
769 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
770 if (!hw) {
771 LOGE("NULL camera device");
772 return;
773 }
774 if (!opaque) {
775 LOGE("Error!! Frame info is NULL");
776 return;
777 }
778 LOGD("E camera id %d", hw->getCameraId());
779
780 hw->lockAPI();
781 qcamera_api_result_t apiResult;
782 ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, (void *)opaque);
783 if (ret == NO_ERROR) {
784 hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, &apiResult);
785 }
786 hw->unlockAPI();
787 LOGD("X camera id %d", hw->getCameraId());
788 }
789
790 /*===========================================================================
791 * FUNCTION : auto_focus
792 *
793 * DESCRIPTION: start auto focus
794 *
795 * PARAMETERS :
796 * @device : ptr to camera device struct
797 *
798 * RETURN : int32_t type of status
799 * NO_ERROR -- success
800 * none-zero failure code
801 *==========================================================================*/
auto_focus(struct camera_device * device)802 int QCamera2HardwareInterface::auto_focus(struct camera_device *device)
803 {
804 KPI_ATRACE_INT("Camera:AutoFocus", 1);
805 int ret = NO_ERROR;
806 QCamera2HardwareInterface *hw =
807 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
808 if (!hw) {
809 LOGE("NULL camera device");
810 return BAD_VALUE;
811 }
812 LOGH("[KPI Perf] : E PROFILE_AUTO_FOCUS camera id %d",
813 hw->getCameraId());
814 hw->lockAPI();
815 qcamera_api_result_t apiResult;
816 ret = hw->processAPI(QCAMERA_SM_EVT_START_AUTO_FOCUS, NULL);
817 if (ret == NO_ERROR) {
818 hw->waitAPIResult(QCAMERA_SM_EVT_START_AUTO_FOCUS, &apiResult);
819 ret = apiResult.status;
820 }
821 hw->unlockAPI();
822 LOGH("[KPI Perf] : X ret = %d", ret);
823
824 return ret;
825 }
826
827 /*===========================================================================
828 * FUNCTION : cancel_auto_focus
829 *
830 * DESCRIPTION: cancel auto focus
831 *
832 * PARAMETERS :
833 * @device : ptr to camera device struct
834 *
835 * RETURN : int32_t type of status
836 * NO_ERROR -- success
837 * none-zero failure code
838 *==========================================================================*/
cancel_auto_focus(struct camera_device * device)839 int QCamera2HardwareInterface::cancel_auto_focus(struct camera_device *device)
840 {
841 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_CANCEL_AF);
842 int ret = NO_ERROR;
843 QCamera2HardwareInterface *hw =
844 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
845 if (!hw) {
846 LOGE("NULL camera device");
847 return BAD_VALUE;
848 }
849 LOGH("[KPI Perf] : E PROFILE_CANCEL_AUTO_FOCUS camera id %d",
850 hw->getCameraId());
851 hw->lockAPI();
852 qcamera_api_result_t apiResult;
853 ret = hw->processAPI(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, NULL);
854 if (ret == NO_ERROR) {
855 hw->waitAPIResult(QCAMERA_SM_EVT_STOP_AUTO_FOCUS, &apiResult);
856 ret = apiResult.status;
857 }
858 hw->unlockAPI();
859 LOGH("[KPI Perf] : X ret = %d", ret);
860 return ret;
861 }
862
863 /*===========================================================================
864 * FUNCTION : pre_take_picture
865 *
866 * DESCRIPTION: pre take picture, restart preview if necessary.
867 *
868 * PARAMETERS :
869 * @device : ptr to camera device struct
870 *
871 * RETURN : int32_t type of status
872 * NO_ERROR -- success
873 * none-zero failure code
874 *==========================================================================*/
pre_take_picture(struct camera_device * device)875 int QCamera2HardwareInterface::pre_take_picture(struct camera_device *device)
876 {
877 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PRE_TAKE_PICTURE);
878 int ret = NO_ERROR;
879 QCamera2HardwareInterface *hw =
880 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
881 if (!hw) {
882 LOGE("NULL camera device");
883 return BAD_VALUE;
884 }
885 LOGH("[KPI Perf]: E PROFILE_PRE_TAKE_PICTURE camera id %d",
886 hw->getCameraId());
887 hw->lockAPI();
888 qcamera_api_result_t apiResult;
889 ret = hw->processAPI(QCAMERA_SM_EVT_PRE_TAKE_PICTURE, NULL);
890 if (ret == NO_ERROR) {
891 hw->waitAPIResult(QCAMERA_SM_EVT_PRE_TAKE_PICTURE, &apiResult);
892 ret = apiResult.status;
893 }
894 hw->unlockAPI();
895 LOGH("[KPI Perf]: X");
896 return ret;
897 }
898
899 /*===========================================================================
900 * FUNCTION : take_picture
901 *
902 * DESCRIPTION: take picture
903 *
904 * PARAMETERS :
905 * @device : ptr to camera device struct
906 *
907 * RETURN : int32_t type of status
908 * NO_ERROR -- success
909 * none-zero failure code
910 *==========================================================================*/
take_picture(struct camera_device * device)911 int QCamera2HardwareInterface::take_picture(struct camera_device *device)
912 {
913 KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_TAKE_PICTURE);
914 int ret = NO_ERROR;
915 QCamera2HardwareInterface *hw =
916 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
917 if (!hw) {
918 LOGE("NULL camera device");
919 return BAD_VALUE;
920 }
921 LOGI("[KPI Perf]: E PROFILE_TAKE_PICTURE camera id %d",
922 hw->getCameraId());
923
924 // Acquire the perf lock for JPEG snapshot only
925 if (hw->mParameters.isJpegPictureFormat()) {
926 hw->m_perfLockMgr.acquirePerfLock(PERF_LOCK_TAKE_SNAPSHOT);
927 }
928
929 qcamera_api_result_t apiResult;
930
931 /** Added support for Retro-active Frames:
932 * takePicture() is called before preparing Snapshot to indicate the
933 * mm-camera-channel to pick up legacy frames even
934 * before LED estimation is triggered.
935 */
936
937 LOGH("isLiveSnap %d, isZSL %d, isHDR %d longshot = %d",
938 hw->isLiveSnapshot(), hw->isZSLMode(), hw->isHDRMode(),
939 hw->isLongshotEnabled());
940
941 // Check for Retro-active Frames
942 if ((hw->mParameters.getNumOfRetroSnapshots() > 0) &&
943 !hw->isLiveSnapshot() && hw->isZSLMode() &&
944 !hw->isHDRMode() && !hw->isLongshotEnabled()) {
945 // Set Retro Picture Mode
946 hw->setRetroPicture(1);
947 hw->m_bLedAfAecLock = 0;
948 LOGL("Retro Enabled");
949
950 // Give HWI control to call pre_take_picture in single camera mode.
951 // In dual-cam mode, this control belongs to muxer.
952 if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
953 ret = pre_take_picture(device);
954 if (ret != NO_ERROR) {
955 LOGE("pre_take_picture failed with ret = %d",ret);
956 return ret;
957 }
958 }
959
960 /* Call take Picture for total number of snapshots required.
961 This includes the number of retro frames and normal frames */
962 hw->lockAPI();
963 ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
964 if (ret == NO_ERROR) {
965 // Wait for retro frames, before calling prepare snapshot
966 LOGD("Wait for Retro frames to be done");
967 hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
968 ret = apiResult.status;
969 }
970 /* Unlock API since it is acquired in prepare snapshot seperately */
971 hw->unlockAPI();
972
973 /* Prepare snapshot in case LED needs to be flashed */
974 LOGD("Start Prepare Snapshot");
975 ret = hw->prepare_snapshot(device);
976 }
977 else {
978 hw->setRetroPicture(0);
979 // Check if prepare snapshot is done
980 if (!hw->mPrepSnapRun) {
981 // Ignore the status from prepare_snapshot
982 hw->prepare_snapshot(device);
983 }
984
985 // Give HWI control to call pre_take_picture in single camera mode.
986 // In dual-cam mode, this control belongs to muxer.
987 if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
988 ret = pre_take_picture(device);
989 if (ret != NO_ERROR) {
990 LOGE("pre_take_picture failed with ret = %d",ret);
991 return ret;
992 }
993 }
994
995 // Regardless what the result value for prepare_snapshot,
996 // go ahead with capture anyway. Just like the way autofocus
997 // is handled in capture case
998 /* capture */
999 LOGL("Capturing normal frames");
1000 hw->lockAPI();
1001 ret = hw->processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
1002 if (ret == NO_ERROR) {
1003 hw->waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
1004 ret = apiResult.status;
1005 }
1006 hw->unlockAPI();
1007 if (!hw->isLongshotEnabled()){
1008 // For longshot mode, we prepare snapshot only once
1009 hw->mPrepSnapRun = false;
1010 }
1011 }
1012 LOGI("[KPI Perf]: X ret = %d", ret);
1013 return ret;
1014 }
1015
1016 /*===========================================================================
1017 * FUNCTION : cancel_picture
1018 *
1019 * DESCRIPTION: cancel current take picture request
1020 *
1021 * PARAMETERS :
1022 * @device : ptr to camera device struct
1023 *
1024 * RETURN : int32_t type of status
1025 * NO_ERROR -- success
1026 * none-zero failure code
1027 *==========================================================================*/
cancel_picture(struct camera_device * device)1028 int QCamera2HardwareInterface::cancel_picture(struct camera_device *device)
1029 {
1030 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_CANCEL_PICTURE);
1031 int ret = NO_ERROR;
1032 QCamera2HardwareInterface *hw =
1033 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1034 if (!hw) {
1035 LOGE("NULL camera device");
1036 return BAD_VALUE;
1037 }
1038 LOGI("[KPI Perf]: E PROFILE_CANCEL_PICTURE camera id %d",
1039 hw->getCameraId());
1040 hw->lockAPI();
1041 qcamera_api_result_t apiResult;
1042 ret = hw->processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
1043 if (ret == NO_ERROR) {
1044 hw->waitAPIResult(QCAMERA_SM_EVT_CANCEL_PICTURE, &apiResult);
1045 ret = apiResult.status;
1046 }
1047 hw->unlockAPI();
1048 LOGI("[KPI Perf]: X camera id %d ret = %d", hw->getCameraId(), ret);
1049
1050 return ret;
1051 }
1052
1053 /*===========================================================================
1054 * FUNCTION : set_parameters
1055 *
1056 * DESCRIPTION: set camera parameters
1057 *
1058 * PARAMETERS :
1059 * @device : ptr to camera device struct
1060 * @parms : string of packed parameters
1061 *
1062 * RETURN : int32_t type of status
1063 * NO_ERROR -- success
1064 * none-zero failure code
1065 *==========================================================================*/
set_parameters(struct camera_device * device,const char * parms)1066 int QCamera2HardwareInterface::set_parameters(struct camera_device *device,
1067 const char *parms)
1068 {
1069 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SET_PARAMETERS);
1070 int ret = NO_ERROR;
1071 QCamera2HardwareInterface *hw =
1072 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1073 if (!hw) {
1074 LOGE("NULL camera device");
1075 return BAD_VALUE;
1076 }
1077 LOGD("E camera id %d", hw->getCameraId());
1078 hw->lockAPI();
1079 qcamera_api_result_t apiResult;
1080 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS, (void *)parms);
1081 if (ret == NO_ERROR) {
1082 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS, &apiResult);
1083 ret = apiResult.status;
1084 }
1085
1086 // Give HWI control to restart (if necessary) after set params
1087 // in single camera mode. In dual-cam mode, this control belongs to muxer.
1088 if (hw->getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
1089 if ((ret == NO_ERROR) && hw->getNeedRestart()) {
1090 LOGD("stopping after param change");
1091 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_STOP, NULL);
1092 if (ret == NO_ERROR) {
1093 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_STOP, &apiResult);
1094 ret = apiResult.status;
1095 }
1096 }
1097
1098 if (ret == NO_ERROR) {
1099 LOGD("committing param change");
1100 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, NULL);
1101 if (ret == NO_ERROR) {
1102 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, &apiResult);
1103 ret = apiResult.status;
1104 }
1105 }
1106
1107 if ((ret == NO_ERROR) && hw->getNeedRestart()) {
1108 LOGD("restarting after param change");
1109 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_RESTART, NULL);
1110 if (ret == NO_ERROR) {
1111 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_RESTART, &apiResult);
1112 ret = apiResult.status;
1113 }
1114 }
1115 }
1116
1117 hw->unlockAPI();
1118 LOGD("X camera id %d ret %d", hw->getCameraId(), ret);
1119
1120 return ret;
1121 }
1122
1123 /*===========================================================================
1124 * FUNCTION : stop_after_set_params
1125 *
1126 * DESCRIPTION: stop after a set param call, if necessary
1127 *
1128 * PARAMETERS :
1129 * @device : ptr to camera device struct
1130 *
1131 * RETURN : int32_t type of status
1132 * NO_ERROR -- success
1133 * none-zero failure code
1134 *==========================================================================*/
stop_after_set_params(struct camera_device * device)1135 int QCamera2HardwareInterface::stop_after_set_params(struct camera_device *device)
1136 {
1137 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOP_AFTER_SET_PARAMS);
1138 int ret = NO_ERROR;
1139 QCamera2HardwareInterface *hw =
1140 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1141 if (!hw) {
1142 LOGE("NULL camera device");
1143 return BAD_VALUE;
1144 }
1145 LOGD("E camera id %d", hw->getCameraId());
1146 hw->lockAPI();
1147 qcamera_api_result_t apiResult;
1148
1149 if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
1150 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_STOP, NULL);
1151 if (ret == NO_ERROR) {
1152 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_STOP, &apiResult);
1153 ret = apiResult.status;
1154 }
1155 } else {
1156 LOGE("is not supposed to be called in single-camera mode");
1157 ret = INVALID_OPERATION;
1158 }
1159
1160 hw->unlockAPI();
1161 LOGD("X camera id %d", hw->getCameraId());
1162
1163 return ret;
1164 }
1165
1166 /*===========================================================================
1167 * FUNCTION : commit_params
1168 *
1169 * DESCRIPTION: commit after a set param call
1170 *
1171 * PARAMETERS :
1172 * @device : ptr to camera device struct
1173 *
1174 * RETURN : int32_t type of status
1175 * NO_ERROR -- success
1176 * none-zero failure code
1177 *==========================================================================*/
commit_params(struct camera_device * device)1178 int QCamera2HardwareInterface::commit_params(struct camera_device *device)
1179 {
1180 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_COMMIT_PARAMS);
1181 int ret = NO_ERROR;
1182 QCamera2HardwareInterface *hw =
1183 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1184 if (!hw) {
1185 LOGE("NULL camera device");
1186 return BAD_VALUE;
1187 }
1188 LOGD("E camera id %d", hw->getCameraId());
1189 hw->lockAPI();
1190 qcamera_api_result_t apiResult;
1191
1192 if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
1193 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, NULL);
1194 if (ret == NO_ERROR) {
1195 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_COMMIT, &apiResult);
1196 ret = apiResult.status;
1197 }
1198 } else {
1199 LOGE("is not supposed to be called in single-camera mode");
1200 ret = INVALID_OPERATION;
1201 }
1202
1203 hw->unlockAPI();
1204 LOGD("X camera id %d", hw->getCameraId());
1205
1206 return ret;
1207 }
1208
1209 /*===========================================================================
1210 * FUNCTION : restart_after_set_params
1211 *
1212 * DESCRIPTION: restart after a set param call, if necessary
1213 *
1214 * PARAMETERS :
1215 * @device : ptr to camera device struct
1216 *
1217 * RETURN : int32_t type of status
1218 * NO_ERROR -- success
1219 * none-zero failure code
1220 *==========================================================================*/
restart_after_set_params(struct camera_device * device)1221 int QCamera2HardwareInterface::restart_after_set_params(struct camera_device *device)
1222 {
1223 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RESTART_AFTER_SET_PARAMS);
1224 int ret = NO_ERROR;
1225 QCamera2HardwareInterface *hw =
1226 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1227 if (!hw) {
1228 LOGE("NULL camera device");
1229 return BAD_VALUE;
1230 }
1231 LOGD("E camera id %d", hw->getCameraId());
1232 hw->lockAPI();
1233 qcamera_api_result_t apiResult;
1234
1235 if (hw->getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
1236 ret = hw->processAPI(QCAMERA_SM_EVT_SET_PARAMS_RESTART, NULL);
1237 if (ret == NO_ERROR) {
1238 hw->waitAPIResult(QCAMERA_SM_EVT_SET_PARAMS_RESTART, &apiResult);
1239 ret = apiResult.status;
1240 }
1241 } else {
1242 LOGE("is not supposed to be called in single-camera mode");
1243 ret = INVALID_OPERATION;
1244 }
1245
1246 hw->unlockAPI();
1247 LOGD("X camera id %d", hw->getCameraId());
1248 return ret;
1249 }
1250
1251 /*===========================================================================
1252 * FUNCTION : get_parameters
1253 *
1254 * DESCRIPTION: query camera parameters
1255 *
1256 * PARAMETERS :
1257 * @device : ptr to camera device struct
1258 *
1259 * RETURN : packed parameters in a string
1260 *==========================================================================*/
get_parameters(struct camera_device * device)1261 char* QCamera2HardwareInterface::get_parameters(struct camera_device *device)
1262 {
1263 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_GET_PARAMETERS);
1264 char *ret = NULL;
1265 QCamera2HardwareInterface *hw =
1266 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1267 if (!hw) {
1268 LOGE("NULL camera device");
1269 return NULL;
1270 }
1271 LOGD("E camera id %d", hw->getCameraId());
1272 hw->lockAPI();
1273 qcamera_api_result_t apiResult;
1274 int32_t rc = hw->processAPI(QCAMERA_SM_EVT_GET_PARAMS, NULL);
1275 if (rc == NO_ERROR) {
1276 hw->waitAPIResult(QCAMERA_SM_EVT_GET_PARAMS, &apiResult);
1277 ret = apiResult.params;
1278 }
1279 hw->unlockAPI();
1280 LOGD("E camera id %d", hw->getCameraId());
1281
1282 return ret;
1283 }
1284
1285 /*===========================================================================
1286 * FUNCTION : put_parameters
1287 *
1288 * DESCRIPTION: return camera parameters string back to HAL
1289 *
1290 * PARAMETERS :
1291 * @device : ptr to camera device struct
1292 * @parm : ptr to parameter string to be returned
1293 *
1294 * RETURN : none
1295 *==========================================================================*/
put_parameters(struct camera_device * device,char * parm)1296 void QCamera2HardwareInterface::put_parameters(struct camera_device *device,
1297 char *parm)
1298 {
1299 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PUT_PARAMETERS);
1300 QCamera2HardwareInterface *hw =
1301 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1302 if (!hw) {
1303 LOGE("NULL camera device");
1304 return;
1305 }
1306 LOGD("E camera id %d", hw->getCameraId());
1307 hw->lockAPI();
1308 qcamera_api_result_t apiResult;
1309 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_PUT_PARAMS, (void *)parm);
1310 if (ret == NO_ERROR) {
1311 hw->waitAPIResult(QCAMERA_SM_EVT_PUT_PARAMS, &apiResult);
1312 }
1313 hw->unlockAPI();
1314 LOGD("E camera id %d", hw->getCameraId());
1315 }
1316
1317 /*===========================================================================
1318 * FUNCTION : send_command
1319 *
1320 * DESCRIPTION: command to be executed
1321 *
1322 * PARAMETERS :
1323 * @device : ptr to camera device struct
1324 * @cmd : cmd to be executed
1325 * @arg1 : ptr to optional argument1
1326 * @arg2 : ptr to optional argument2
1327 *
1328 * RETURN : int32_t type of status
1329 * NO_ERROR -- success
1330 * none-zero failure code
1331 *==========================================================================*/
send_command(struct camera_device * device,int32_t cmd,int32_t arg1,int32_t arg2)1332 int QCamera2HardwareInterface::send_command(struct camera_device *device,
1333 int32_t cmd,
1334 int32_t arg1,
1335 int32_t arg2)
1336 {
1337 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SEND_COMMAND);
1338 int ret = NO_ERROR;
1339 QCamera2HardwareInterface *hw =
1340 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1341 if (!hw) {
1342 LOGE("NULL camera device");
1343 return BAD_VALUE;
1344 }
1345 LOGD("E camera id %d", hw->getCameraId());
1346
1347 qcamera_sm_evt_command_payload_t payload;
1348 memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t));
1349 payload.cmd = cmd;
1350 payload.arg1 = arg1;
1351 payload.arg2 = arg2;
1352 hw->lockAPI();
1353 qcamera_api_result_t apiResult;
1354 ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND, (void *)&payload);
1355 if (ret == NO_ERROR) {
1356 hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND, &apiResult);
1357 ret = apiResult.status;
1358 }
1359 hw->unlockAPI();
1360 LOGD("E camera id %d", hw->getCameraId());
1361
1362 return ret;
1363 }
1364
1365 /*===========================================================================
1366 * FUNCTION : send_command_restart
1367 *
1368 * DESCRIPTION: restart if necessary after a send_command
1369 *
1370 * PARAMETERS :
1371 * @device : ptr to camera device struct
1372 * @cmd : cmd to be executed
1373 * @arg1 : ptr to optional argument1
1374 * @arg2 : ptr to optional argument2
1375 *
1376 * RETURN : int32_t type of status
1377 * NO_ERROR -- success
1378 * none-zero failure code
1379 *==========================================================================*/
send_command_restart(struct camera_device * device,int32_t cmd,int32_t arg1,int32_t arg2)1380 int QCamera2HardwareInterface::send_command_restart(struct camera_device *device,
1381 int32_t cmd,
1382 int32_t arg1,
1383 int32_t arg2)
1384 {
1385 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_SEND_COMMAND_RESTART);
1386 int ret = NO_ERROR;
1387 QCamera2HardwareInterface *hw =
1388 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1389 if (!hw) {
1390 LOGE("NULL camera device");
1391 return BAD_VALUE;
1392 }
1393
1394 qcamera_sm_evt_command_payload_t payload;
1395 memset(&payload, 0, sizeof(qcamera_sm_evt_command_payload_t));
1396 payload.cmd = cmd;
1397 payload.arg1 = arg1;
1398 payload.arg2 = arg2;
1399 hw->lockAPI();
1400 qcamera_api_result_t apiResult;
1401 ret = hw->processAPI(QCAMERA_SM_EVT_SEND_COMMAND_RESTART, (void *)&payload);
1402 if (ret == NO_ERROR) {
1403 hw->waitAPIResult(QCAMERA_SM_EVT_SEND_COMMAND_RESTART, &apiResult);
1404 ret = apiResult.status;
1405 }
1406 hw->unlockAPI();
1407 LOGD("E camera id %d", hw->getCameraId());
1408
1409 return ret;
1410 }
1411
1412 /*===========================================================================
1413 * FUNCTION : release
1414 *
1415 * DESCRIPTION: release camera resource
1416 *
1417 * PARAMETERS :
1418 * @device : ptr to camera device struct
1419 *
1420 * RETURN : none
1421 *==========================================================================*/
release(struct camera_device * device)1422 void QCamera2HardwareInterface::release(struct camera_device *device)
1423 {
1424 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_RELEASE);
1425 QCamera2HardwareInterface *hw =
1426 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1427 if (!hw) {
1428 LOGE("NULL camera device");
1429 return;
1430 }
1431 LOGD("E camera id %d", hw->getCameraId());
1432 hw->lockAPI();
1433 qcamera_api_result_t apiResult;
1434 int32_t ret = hw->processAPI(QCAMERA_SM_EVT_RELEASE, NULL);
1435 if (ret == NO_ERROR) {
1436 hw->waitAPIResult(QCAMERA_SM_EVT_RELEASE, &apiResult);
1437 }
1438 hw->unlockAPI();
1439 LOGD("E camera id %d", hw->getCameraId());
1440 }
1441
1442 /*===========================================================================
1443 * FUNCTION : dump
1444 *
1445 * DESCRIPTION: dump camera status
1446 *
1447 * PARAMETERS :
1448 * @device : ptr to camera device struct
1449 * @fd : fd for status to be dumped to
1450 *
1451 * RETURN : int32_t type of status
1452 * NO_ERROR -- success
1453 * none-zero failure code
1454 *==========================================================================*/
dump(struct camera_device * device,int fd)1455 int QCamera2HardwareInterface::dump(struct camera_device *device, int fd)
1456 {
1457 int ret = NO_ERROR;
1458
1459 //Log level property is read when "adb shell dumpsys media.camera" is
1460 //called so that the log level can be controlled without restarting
1461 //media server
1462 getLogLevel();
1463 QCamera2HardwareInterface *hw =
1464 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1465 if (!hw) {
1466 LOGE("NULL camera device");
1467 return BAD_VALUE;
1468 }
1469 LOGD("E camera id %d", hw->getCameraId());
1470 hw->lockAPI();
1471 qcamera_api_result_t apiResult;
1472 ret = hw->processAPI(QCAMERA_SM_EVT_DUMP, (void *)&fd);
1473 if (ret == NO_ERROR) {
1474 hw->waitAPIResult(QCAMERA_SM_EVT_DUMP, &apiResult);
1475 ret = apiResult.status;
1476 }
1477 hw->unlockAPI();
1478 LOGD("E camera id %d", hw->getCameraId());
1479
1480 return ret;
1481 }
1482
1483 /*===========================================================================
1484 * FUNCTION : close_camera_device
1485 *
1486 * DESCRIPTION: close camera device
1487 *
1488 * PARAMETERS :
1489 * @device : ptr to camera device struct
1490 *
1491 * RETURN : int32_t type of status
1492 * NO_ERROR -- success
1493 * none-zero failure code
1494 *==========================================================================*/
close_camera_device(hw_device_t * hw_dev)1495 int QCamera2HardwareInterface::close_camera_device(hw_device_t *hw_dev)
1496 {
1497 KPI_ATRACE_CAMSCOPE_BEGIN(CAMSCOPE_HAL1_CLOSECAMERA);
1498 int ret = NO_ERROR;
1499
1500 QCamera2HardwareInterface *hw =
1501 reinterpret_cast<QCamera2HardwareInterface *>(
1502 reinterpret_cast<camera_device_t *>(hw_dev)->priv);
1503 if (!hw) {
1504 LOGE("NULL camera device");
1505 return BAD_VALUE;
1506 }
1507 LOGI("[KPI Perf]: E camera id %d", hw->getCameraId());
1508 delete hw;
1509 LOGI("[KPI Perf]: X");
1510 KPI_ATRACE_CAMSCOPE_END(CAMSCOPE_HAL1_CLOSECAMERA);
1511 CAMSCOPE_DESTROY(CAMSCOPE_SECTION_HAL);
1512 return ret;
1513 }
1514
1515 /*===========================================================================
1516 * FUNCTION : register_face_image
1517 *
1518 * DESCRIPTION: register a face image into imaging lib for face authenticatio/
1519 * face recognition
1520 *
1521 * PARAMETERS :
1522 * @device : ptr to camera device struct
1523 * @img_ptr : ptr to image buffer
1524 * @config : ptr to config about input image, i.e., format, dimension, and etc.
1525 *
1526 * RETURN : >=0 unique ID of face registerd.
1527 * <0 failure.
1528 *==========================================================================*/
register_face_image(struct camera_device * device,void * img_ptr,cam_pp_offline_src_config_t * config)1529 int QCamera2HardwareInterface::register_face_image(struct camera_device *device,
1530 void *img_ptr,
1531 cam_pp_offline_src_config_t *config)
1532 {
1533 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_REGISTER_FACE_IMAGE);
1534 int ret = NO_ERROR;
1535 QCamera2HardwareInterface *hw =
1536 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1537 if (!hw) {
1538 LOGE("NULL camera device");
1539 return BAD_VALUE;
1540 }
1541 LOGD("E camera id %d", hw->getCameraId());
1542 qcamera_sm_evt_reg_face_payload_t payload;
1543 memset(&payload, 0, sizeof(qcamera_sm_evt_reg_face_payload_t));
1544 payload.img_ptr = img_ptr;
1545 payload.config = config;
1546 hw->lockAPI();
1547 qcamera_api_result_t apiResult;
1548 ret = hw->processAPI(QCAMERA_SM_EVT_REG_FACE_IMAGE, (void *)&payload);
1549 if (ret == NO_ERROR) {
1550 hw->waitAPIResult(QCAMERA_SM_EVT_REG_FACE_IMAGE, &apiResult);
1551 ret = apiResult.handle;
1552 }
1553 hw->unlockAPI();
1554 LOGD("E camera id %d", hw->getCameraId());
1555
1556 return ret;
1557 }
1558
1559 /*===========================================================================
1560 * FUNCTION : prepare_snapshot
1561 *
1562 * DESCRIPTION: prepares hardware for snapshot
1563 *
1564 * PARAMETERS :
1565 * @device : ptr to camera device struct
1566 *
1567 * RETURN : int32_t type of status
1568 * NO_ERROR -- success
1569 * none-zero failure code
1570 *==========================================================================*/
prepare_snapshot(struct camera_device * device)1571 int QCamera2HardwareInterface::prepare_snapshot(struct camera_device *device)
1572 {
1573 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPARE_SNAPSHOT);
1574 int ret = NO_ERROR;
1575 QCamera2HardwareInterface *hw =
1576 reinterpret_cast<QCamera2HardwareInterface *>(device->priv);
1577 if (!hw) {
1578 LOGE("NULL camera device");
1579 return BAD_VALUE;
1580 }
1581 if (hw->isLongshotEnabled() && hw->mPrepSnapRun == true) {
1582 // For longshot mode, we prepare snapshot only once
1583 LOGH("prepare snapshot only once ");
1584 return NO_ERROR;
1585 }
1586 LOGH("[KPI Perf]: E PROFILE_PREPARE_SNAPSHOT camera id %d",
1587 hw->getCameraId());
1588 hw->lockAPI();
1589 qcamera_api_result_t apiResult;
1590
1591 /* Prepare snapshot in case LED needs to be flashed */
1592 if (hw->mFlashNeeded || hw->mParameters.isChromaFlashEnabled()) {
1593 /* Prepare snapshot in case LED needs to be flashed */
1594 ret = hw->processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
1595 if (ret == NO_ERROR) {
1596 hw->waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult);
1597 ret = apiResult.status;
1598 }
1599 hw->mPrepSnapRun = true;
1600 }
1601 hw->unlockAPI();
1602 LOGH("[KPI Perf]: X, ret: %d", ret);
1603 return ret;
1604 }
1605
1606 /*===========================================================================
1607 * FUNCTION : QCamera2HardwareInterface
1608 *
1609 * DESCRIPTION: constructor of QCamera2HardwareInterface
1610 *
1611 * PARAMETERS :
1612 * @cameraId : camera ID
1613 *
1614 * RETURN : none
1615 *==========================================================================*/
QCamera2HardwareInterface(uint32_t cameraId)1616 QCamera2HardwareInterface::QCamera2HardwareInterface(uint32_t cameraId)
1617 : mCameraId(cameraId),
1618 mCameraHandle(NULL),
1619 mMasterCamera(CAM_TYPE_MAIN),
1620 mCameraOpened(false),
1621 mDualCamera(false),
1622 m_pFovControl(NULL),
1623 m_bRelCamCalibValid(false),
1624 mPreviewWindow(NULL),
1625 mMsgEnabled(0),
1626 mStoreMetaDataInFrame(0),
1627 mJpegCb(NULL),
1628 mCallbackCookie(NULL),
1629 mJpegCallbackCookie(NULL),
1630 m_bMpoEnabled(TRUE),
1631 m_stateMachine(this),
1632 m_smThreadActive(true),
1633 m_postprocessor(this),
1634 m_thermalAdapter(QCameraThermalAdapter::getInstance()),
1635 m_cbNotifier(this),
1636 m_perfLockMgr(),
1637 m_bPreviewStarted(false),
1638 m_bRecordStarted(false),
1639 m_currentFocusState(CAM_AF_STATE_INACTIVE),
1640 mDumpFrmCnt(0U),
1641 mDumpSkipCnt(0U),
1642 mThermalLevel(QCAMERA_THERMAL_NO_ADJUSTMENT),
1643 mActiveAF(false),
1644 m_HDRSceneEnabled(false),
1645 mLongshotEnabled(false),
1646 mLiveSnapshotThread(0),
1647 mIntPicThread(0),
1648 mFlashNeeded(false),
1649 mFlashConfigured(false),
1650 mDeviceRotation(0U),
1651 mCaptureRotation(0U),
1652 mJpegExifRotation(0U),
1653 mUseJpegExifRotation(false),
1654 mIs3ALocked(false),
1655 mPrepSnapRun(false),
1656 mZoomLevel(0),
1657 mPreviewRestartNeeded(false),
1658 mVFrameCount(0),
1659 mVLastFrameCount(0),
1660 mVLastFpsTime(0),
1661 mVFps(0),
1662 mPFrameCount(0),
1663 mPLastFrameCount(0),
1664 mPLastFpsTime(0),
1665 mPFps(0),
1666 mLowLightConfigured(false),
1667 mInstantAecFrameCount(0),
1668 m_bIntJpegEvtPending(false),
1669 m_bIntRawEvtPending(false),
1670 mReprocJob(0),
1671 mJpegJob(0),
1672 mMetadataAllocJob(0),
1673 mInitPProcJob(0),
1674 mParamAllocJob(0),
1675 mParamInitJob(0),
1676 mOutputCount(0),
1677 mInputCount(0),
1678 mAdvancedCaptureConfigured(false),
1679 mHDRBracketingEnabled(false),
1680 mNumPreviewFaces(-1),
1681 mJpegClientHandle(0),
1682 mJpegHandleOwner(false),
1683 mMetadataMem(NULL),
1684 mCACDoneReceived(false),
1685 m_bNeedRestart(false),
1686 mBootToMonoTimestampOffset(0),
1687 bDepthAFCallbacks(true),
1688 m_bNeedHalPP(FALSE)
1689 {
1690 #ifdef TARGET_TS_MAKEUP
1691 memset(&mFaceRect, -1, sizeof(mFaceRect));
1692 #endif
1693 getLogLevel();
1694 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_QCAMERA2HWI);
1695 mCameraDevice.common.tag = HARDWARE_DEVICE_TAG;
1696 mCameraDevice.common.version = HARDWARE_DEVICE_API_VERSION(1, 0);
1697 mCameraDevice.common.close = close_camera_device;
1698 mCameraDevice.ops = &mCameraOps;
1699 mCameraDevice.priv = this;
1700
1701 mDualCamera = is_dual_camera_by_idx(cameraId);
1702
1703 pthread_mutex_init(&m_lock, NULL);
1704 pthread_cond_init(&m_cond, NULL);
1705
1706 m_apiResultList = NULL;
1707
1708 pthread_mutex_init(&m_evtLock, NULL);
1709 pthread_cond_init(&m_evtCond, NULL);
1710 memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
1711
1712
1713 pthread_mutex_init(&m_int_lock, NULL);
1714 pthread_cond_init(&m_int_cond, NULL);
1715
1716 memset(m_channels, 0, sizeof(m_channels));
1717
1718 memset(&mExifParams, 0, sizeof(mm_jpeg_exif_params_t));
1719
1720 memset(m_BackendFileName, 0, QCAMERA_MAX_FILEPATH_LENGTH);
1721
1722 memset(mDefOngoingJobs, 0, sizeof(mDefOngoingJobs));
1723 memset(&mJpegMetadata, 0, sizeof(mJpegMetadata));
1724 memset(&mJpegHandle, 0, sizeof(mJpegHandle));
1725 memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle));
1726
1727 mDeferredWorkThread.launch(deferredWorkRoutine, this);
1728 mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, FALSE);
1729
1730 pthread_mutex_init(&mGrallocLock, NULL);
1731 mEnqueuedBuffers = 0;
1732 mFrameSkipStart = 0;
1733 mFrameSkipEnd = 0;
1734 mLastPreviewFrameID = 0;
1735
1736 //Load and read GPU library.
1737 lib_surface_utils = NULL;
1738 LINK_get_surface_pixel_alignment = NULL;
1739 mSurfaceStridePadding = CAM_PAD_TO_32;
1740 lib_surface_utils = dlopen("libadreno_utils.so", RTLD_NOW);
1741 if (lib_surface_utils) {
1742 *(void **)&LINK_get_surface_pixel_alignment =
1743 dlsym(lib_surface_utils, "get_gpu_pixel_alignment");
1744 if (LINK_get_surface_pixel_alignment) {
1745 mSurfaceStridePadding = LINK_get_surface_pixel_alignment();
1746 }
1747 dlclose(lib_surface_utils);
1748 }
1749 }
1750
1751 /*===========================================================================
1752 * FUNCTION : ~QCamera2HardwareInterface
1753 *
1754 * DESCRIPTION: destructor of QCamera2HardwareInterface
1755 *
1756 * PARAMETERS : none
1757 *
1758 * RETURN : none
1759 *==========================================================================*/
~QCamera2HardwareInterface()1760 QCamera2HardwareInterface::~QCamera2HardwareInterface()
1761 {
1762 LOGH("E");
1763
1764 mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, TRUE, TRUE);
1765 mDeferredWorkThread.exit();
1766
1767 if (mMetadataMem != NULL) {
1768 delete mMetadataMem;
1769 mMetadataMem = NULL;
1770 }
1771
1772 if (m_pFovControl) {
1773 delete m_pFovControl;
1774 m_pFovControl = NULL;
1775 }
1776
1777 m_perfLockMgr.acquirePerfLock(PERF_LOCK_CLOSE_CAMERA);
1778 lockAPI();
1779 m_smThreadActive = false;
1780 unlockAPI();
1781 m_stateMachine.releaseThread();
1782 closeCamera();
1783 m_perfLockMgr.releasePerfLock(PERF_LOCK_CLOSE_CAMERA);
1784
1785 pthread_mutex_destroy(&m_lock);
1786 pthread_cond_destroy(&m_cond);
1787 pthread_mutex_destroy(&m_evtLock);
1788 pthread_cond_destroy(&m_evtCond);
1789 pthread_mutex_destroy(&m_int_lock);
1790 pthread_cond_destroy(&m_int_cond);
1791 pthread_mutex_destroy(&mGrallocLock);
1792 LOGH("X");
1793 }
1794
1795 /*===========================================================================
1796 * FUNCTION : deferPPInit
1797 *
1798 * DESCRIPTION: Queue postproc init task to deferred thread
1799 *
1800 * PARAMETERS : none
1801 *
1802 * RETURN : uint32_t job id of pproc init job
1803 * 0 -- failure
1804 *==========================================================================*/
deferPPInit()1805 uint32_t QCamera2HardwareInterface::deferPPInit()
1806 {
1807 // init pproc
1808 DeferWorkArgs args;
1809 DeferPProcInitArgs pprocInitArgs;
1810
1811 memset(&args, 0, sizeof(DeferWorkArgs));
1812 memset(&pprocInitArgs, 0, sizeof(DeferPProcInitArgs));
1813
1814 pprocInitArgs.jpeg_cb = jpegEvtHandle;
1815 pprocInitArgs.user_data = this;
1816 args.pprocInitArgs = pprocInitArgs;
1817
1818 return queueDeferredWork(CMD_DEF_PPROC_INIT,
1819 args);
1820 }
1821
1822 /*===========================================================================
1823 * FUNCTION : openCamera
1824 *
1825 * DESCRIPTION: open camera
1826 *
1827 * PARAMETERS :
1828 * @hw_device : double ptr for camera device struct
1829 *
1830 * RETURN : int32_t type of status
1831 * NO_ERROR -- success
1832 * none-zero failure code
1833 *==========================================================================*/
openCamera(struct hw_device_t ** hw_device)1834 int QCamera2HardwareInterface::openCamera(struct hw_device_t **hw_device)
1835 {
1836 KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_OPENCAMERA);
1837 int rc = NO_ERROR;
1838 if (mCameraOpened) {
1839 *hw_device = NULL;
1840 LOGE("Permission Denied");
1841 return PERMISSION_DENIED;
1842 }
1843 LOGI("[KPI Perf]: E PROFILE_OPEN_CAMERA camera id %d",
1844 mCameraId);
1845
1846 m_perfLockMgr.acquirePerfLock(PERF_LOCK_OPEN_CAMERA);
1847
1848 rc = openCamera();
1849 if (rc == NO_ERROR){
1850 *hw_device = &mCameraDevice.common;
1851 if (m_thermalAdapter.init(this) != 0) {
1852 LOGW("Init thermal adapter failed");
1853 }
1854 }
1855 else
1856 *hw_device = NULL;
1857
1858 LOGI("[KPI Perf]: X PROFILE_OPEN_CAMERA camera id %d, rc: %d",
1859 mCameraId, rc);
1860
1861 return rc;
1862 }
1863
1864 /*===========================================================================
1865 * FUNCTION : openCamera
1866 *
1867 * DESCRIPTION: open camera
1868 *
1869 * PARAMETERS : none
1870 *
1871 * RETURN : int32_t type of status
1872 * NO_ERROR -- success
1873 * none-zero failure code
1874 *==========================================================================*/
openCamera()1875 int QCamera2HardwareInterface::openCamera()
1876 {
1877 int32_t rc = NO_ERROR;
1878 char value[PROPERTY_VALUE_MAX];
1879
1880 if (mCameraHandle) {
1881 LOGE("Failure: Camera already opened");
1882 return ALREADY_EXISTS;
1883 }
1884
1885 rc = QCameraFlash::getInstance().reserveFlashForCamera(mCameraId);
1886 if (rc < 0) {
1887 LOGE("Failed to reserve flash for camera id: %d",
1888 mCameraId);
1889 return UNKNOWN_ERROR;
1890 }
1891
1892 // alloc param buffer
1893 DeferWorkArgs args;
1894 memset(&args, 0, sizeof(args));
1895 mParamAllocJob = queueDeferredWork(CMD_DEF_PARAM_ALLOC, args);
1896 if (mParamAllocJob == 0) {
1897 LOGE("Failed queueing PARAM_ALLOC job");
1898 return -ENOMEM;
1899 }
1900
1901 if (gCamCapability[mCameraId] != NULL) {
1902 // allocate metadata buffers
1903 DeferWorkArgs args;
1904 DeferMetadataAllocArgs metadataAllocArgs;
1905
1906 memset(&args, 0, sizeof(args));
1907 memset(&metadataAllocArgs, 0, sizeof(metadataAllocArgs));
1908
1909 uint32_t padding =
1910 gCamCapability[mCameraId]->padding_info.plane_padding;
1911 metadataAllocArgs.size = PAD_TO_SIZE(sizeof(metadata_buffer_t),
1912 padding);
1913 metadataAllocArgs.bufferCnt = CAMERA_MIN_METADATA_BUFFERS;
1914 args.metadataAllocArgs = metadataAllocArgs;
1915
1916 mMetadataAllocJob = queueDeferredWork(CMD_DEF_METADATA_ALLOC, args);
1917 if (mMetadataAllocJob == 0) {
1918 LOGE("Failed to allocate metadata buffer");
1919 rc = -ENOMEM;
1920 goto error_exit1;
1921 }
1922
1923 rc = camera_open((uint8_t)mCameraId, &mCameraHandle);
1924 if (rc) {
1925 LOGE("camera_open failed. rc = %d, mCameraHandle = %p",
1926 rc, mCameraHandle);
1927 goto error_exit2;
1928 }
1929
1930 mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
1931 camEvtHandle,
1932 (void *) this);
1933 } else {
1934 LOGH("Capabilities not inited, initializing now.");
1935
1936 rc = camera_open((uint8_t)mCameraId, &mCameraHandle);
1937 if (rc) {
1938 LOGE("camera_open failed. rc = %d, mCameraHandle = %p",
1939 rc, mCameraHandle);
1940 goto error_exit2;
1941 }
1942
1943 if(NO_ERROR != initCapabilities(mCameraId,mCameraHandle)) {
1944 LOGE("initCapabilities failed.");
1945 rc = UNKNOWN_ERROR;
1946 goto error_exit3;
1947 }
1948
1949 mCameraHandle->ops->register_event_notify(mCameraHandle->camera_handle,
1950 camEvtHandle,
1951 (void *) this);
1952 }
1953 mBundledSnapshot = 0;
1954 mActiveCameras = MM_CAMERA_TYPE_MAIN;
1955 if (isDualCamera()) {
1956 mActiveCameras |= MM_CAMERA_TYPE_AUX;
1957
1958 // Create and initialize FOV-control object
1959 m_pFovControl = QCameraFOVControl::create(gCamCapability[mCameraId]->main_cam_cap,
1960 gCamCapability[mCameraId]->aux_cam_cap);
1961 if (m_pFovControl) {
1962 *gCamCapability[mCameraId] = m_pFovControl->consolidateCapabilities(
1963 gCamCapability[mCameraId]->main_cam_cap,
1964 gCamCapability[mCameraId]->aux_cam_cap);
1965 } else {
1966 LOGE("FOV-control: Failed to create an object");
1967 rc = NO_MEMORY;
1968 goto error_exit3;
1969 }
1970 }
1971
1972 // Init params in the background
1973 // 1. It's safe to queue init job, even if alloc job is not yet complete.
1974 // It will be queued to the same thread, so the alloc is guaranteed to
1975 // finish first.
1976 // 2. However, it is not safe to begin param init until after camera is
1977 // open. That is why we wait until after camera open completes to schedule
1978 // this task.
1979 memset(&args, 0, sizeof(args));
1980 mParamInitJob = queueDeferredWork(CMD_DEF_PARAM_INIT, args);
1981 if (mParamInitJob == 0) {
1982 LOGE("Failed queuing PARAM_INIT job");
1983 rc = -ENOMEM;
1984 goto error_exit3;
1985 }
1986
1987 mCameraOpened = true;
1988
1989 //Notify display HAL that a camera session is active.
1990 //But avoid calling the same during bootup because camera service might open/close
1991 //cameras at boot time during its initialization and display service will also internally
1992 //wait for camera service to initialize first while calling this display API, resulting in a
1993 //deadlock situation. Since boot time camera open/close calls are made only to fetch
1994 //capabilities, no need of this display bw optimization.
1995 //Use "service.bootanim.exit" property to know boot status.
1996 property_get("service.bootanim.exit", value, "0");
1997 if (atoi(value) == 1) {
1998 pthread_mutex_lock(&gCamLock);
1999 if (gNumCameraSessions++ == 0) {
2000 setCameraLaunchStatus(true);
2001 }
2002 pthread_mutex_unlock(&gCamLock);
2003 }
2004
2005 // Setprop to decide the time source (whether boottime or monotonic).
2006 // By default, use monotonic time.
2007 property_get("persist.camera.time.monotonic", value, "1");
2008 mBootToMonoTimestampOffset = 0;
2009 if (atoi(value) == 1) {
2010 // if monotonic is set, then need to use time in monotonic.
2011 // So, Measure the clock offset between BOOTTIME and MONOTONIC
2012 // The clock domain source for ISP is BOOTTIME and
2013 // for Video/display is MONOTONIC
2014 // The below offset is used to convert from clock domain of other subsystem
2015 // (video/hardware composer) to that of camera. Assumption is that this
2016 // offset won't change during the life cycle of the camera device. In other
2017 // words, camera device shouldn't be open during CPU suspend.
2018 mBootToMonoTimestampOffset = getBootToMonoTimeOffset();
2019 }
2020 LOGH("mBootToMonoTimestampOffset = %lld", mBootToMonoTimestampOffset);
2021
2022 memset(value, 0, sizeof(value));
2023 property_get("persist.camera.depth.focus.cb", value, "1");
2024 bDepthAFCallbacks = atoi(value);
2025
2026 memset(value, 0, sizeof(value));
2027 property_get("persist.camera.cache.optimize", value, "1");
2028 m_bOptimizeCacheOps = atoi(value);
2029
2030 return NO_ERROR;
2031
2032 error_exit3:
2033 if(mJpegClientHandle) {
2034 deinitJpegHandle();
2035 }
2036 mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
2037 mCameraHandle = NULL;
2038 error_exit2:
2039 waitDeferredWork(mMetadataAllocJob);
2040 error_exit1:
2041 waitDeferredWork(mParamAllocJob);
2042 return rc;
2043
2044 }
2045
2046 /*===========================================================================
2047 * FUNCTION : bundleRelatedCameras
2048 *
2049 * DESCRIPTION: bundle cameras to enable syncing of cameras
2050 *
2051 * PARAMETERS :
2052 * @sync :indicates whether syncing is On or Off
2053 *
2054 * RETURN : int32_t type of status
2055 * NO_ERROR -- success
2056 * none-zero failure code
2057 *==========================================================================*/
bundleRelatedCameras(bool syncOn)2058 int QCamera2HardwareInterface::bundleRelatedCameras(bool syncOn)
2059 {
2060 int32_t rc = mParameters.bundleRelatedCameras(syncOn);
2061 if (rc != NO_ERROR) {
2062 LOGE("bundleRelatedCameras failed %d", rc);
2063 return rc;
2064 }
2065 return rc;
2066 }
2067
2068 /*===========================================================================
2069 * FUNCTION : getCameraSessionId
2070 *
2071 * DESCRIPTION: gets the backend session Id of this HWI instance
2072 *
2073 * PARAMETERS :
2074 * @sessionid : pointer to the output session id
2075 *
2076 * RETURN : int32_t type of status
2077 * NO_ERROR -- success
2078 * none-zero failure code
2079 *==========================================================================*/
getCameraSessionId(uint32_t * session_id)2080 int QCamera2HardwareInterface::getCameraSessionId(uint32_t* session_id)
2081 {
2082 int32_t rc = NO_ERROR;
2083
2084 if(session_id != NULL) {
2085 rc = mCameraHandle->ops->get_session_id(mCameraHandle->camera_handle,
2086 session_id);
2087 LOGD("Getting Camera Session Id %d", *session_id);
2088 } else {
2089 LOGE("Session Id is Null");
2090 return UNKNOWN_ERROR;
2091 }
2092 return rc;
2093 }
2094
2095 /*===========================================================================
2096 * FUNCTION : isFrameSyncEnabled
2097 *
2098 * DESCRIPTION: returns whether frame sync is enabled
2099 *
2100 * PARAMETERS : none
2101 *
2102 * RETURN : bool indicating whether frame sync is enabled
2103 *==========================================================================*/
isFrameSyncEnabled(void)2104 bool QCamera2HardwareInterface::isFrameSyncEnabled(void)
2105 {
2106 return mParameters.isFrameSyncEnabled();
2107 }
2108
2109 /*===========================================================================
2110 * FUNCTION : setFrameSyncEnabled
2111 *
2112 * DESCRIPTION: sets whether frame sync is enabled
2113 *
2114 * PARAMETERS :
2115 * @enable : flag whether to enable or disable frame sync
2116 *
2117 * RETURN : int32_t type of status
2118 * NO_ERROR -- success
2119 * none-zero failure code
2120 *==========================================================================*/
setFrameSyncEnabled(bool enable)2121 int32_t QCamera2HardwareInterface::setFrameSyncEnabled(bool enable)
2122 {
2123 return mParameters.setFrameSyncEnabled(enable);
2124 }
2125
2126 /*===========================================================================
2127 * FUNCTION : getRelatedCamSyncInfo
2128 *
2129 * DESCRIPTION:returns the related cam sync info for this HWI instance
2130 *
2131 * PARAMETERS :none
2132 *
2133 * RETURN : const pointer to cam_sync_related_sensors_event_info_t
2134 *==========================================================================*/
2135 const cam_sync_related_sensors_event_info_t*
getRelatedCamSyncInfo(void)2136 QCamera2HardwareInterface::getRelatedCamSyncInfo(void)
2137 {
2138 return mParameters.getRelatedCamSyncInfo();
2139 }
2140
2141 /*===========================================================================
2142 * FUNCTION : setRelatedCamSyncInfo
2143 *
2144 * DESCRIPTION:sets the related cam sync info for this HWI instance
2145 *
2146 * PARAMETERS :
2147 * @info : ptr to related cam info parameters
2148 *
2149 * RETURN : int32_t type of status
2150 * NO_ERROR -- success
2151 * none-zero failure code
2152 *==========================================================================*/
setRelatedCamSyncInfo(cam_sync_related_sensors_event_info_t * info)2153 int32_t QCamera2HardwareInterface::setRelatedCamSyncInfo(
2154 cam_sync_related_sensors_event_info_t* info)
2155 {
2156 if(info) {
2157 return mParameters.setRelatedCamSyncInfo(info);
2158 } else {
2159 return BAD_TYPE;
2160 }
2161 }
2162
2163 /*===========================================================================
2164 * FUNCTION : getMpoComposition
2165 *
2166 * DESCRIPTION:function to retrieve whether Mpo composition should be enabled
2167 * or not
2168 *
2169 * PARAMETERS :none
2170 *
2171 * RETURN : bool indicates whether mpo composition is enabled or not
2172 *==========================================================================*/
getMpoComposition(void)2173 bool QCamera2HardwareInterface::getMpoComposition(void)
2174 {
2175 LOGH("MpoComposition:%d ", m_bMpoEnabled);
2176 return m_bMpoEnabled;
2177 }
2178
2179 /*===========================================================================
2180 * FUNCTION : setMpoComposition
2181 *
2182 * DESCRIPTION:set if Mpo composition should be enabled for this HWI instance
2183 *
2184 * PARAMETERS :
2185 * @enable : indicates whether Mpo composition enabled or not
2186 *
2187 * RETURN : int32_t type of status
2188 * NO_ERROR -- success
2189 * none-zero failure code
2190 *==========================================================================*/
setMpoComposition(bool enable)2191 int32_t QCamera2HardwareInterface::setMpoComposition(bool enable)
2192 {
2193 // By default set Mpo composition to disable
2194 m_bMpoEnabled = false;
2195
2196 // Enable Mpo composition only if
2197 // 1) frame sync is ON between two cameras and
2198 // 2) any advanced features are not enabled (AOST features) and
2199 // 3) not in recording mode (for liveshot case)
2200 // 4) flash is not needed
2201 if ((getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) &&
2202 !mParameters.isAdvCamFeaturesEnabled() &&
2203 !mParameters.getRecordingHintValue() &&
2204 !mFlashNeeded &&
2205 !isLongshotEnabled()) {
2206 m_bMpoEnabled = enable;
2207 LOGH("MpoComposition:%d ", m_bMpoEnabled);
2208 return NO_ERROR;
2209 } else {
2210 return BAD_TYPE;
2211 }
2212 }
2213
2214 /*===========================================================================
2215 * FUNCTION : getRecordingHintValue
2216 *
2217 * DESCRIPTION:function to retrieve recording hint value
2218 *
2219 * PARAMETERS :none
2220 *
2221 * RETURN : bool indicates whether recording hint is enabled or not
2222 *==========================================================================*/
getRecordingHintValue(void)2223 bool QCamera2HardwareInterface::getRecordingHintValue(void)
2224 {
2225 return mParameters.getRecordingHintValue();
2226 }
2227
2228 /*===========================================================================
2229 * FUNCTION : setRecordingHintValue
2230 *
2231 * DESCRIPTION:set recording hint value
2232 *
2233 * PARAMETERS :
2234 * @enable : video hint value
2235 *
2236 * RETURN : int32_t type of status
2237 * NO_ERROR -- success
2238 * none-zero failure code
2239 *==========================================================================*/
setRecordingHintValue(int32_t value)2240 int32_t QCamera2HardwareInterface::setRecordingHintValue(int32_t value)
2241 {
2242 return mParameters.updateRecordingHintValue(value);
2243 }
2244
2245 /*===========================================================================
2246 * FUNCTION : closeCamera
2247 *
2248 * DESCRIPTION: close camera
2249 *
2250 * PARAMETERS : none
2251 *
2252 * RETURN : int32_t type of status
2253 * NO_ERROR -- success
2254 * none-zero failure code
2255 *==========================================================================*/
closeCamera()2256 int QCamera2HardwareInterface::closeCamera()
2257 {
2258 int rc = NO_ERROR;
2259 int i;
2260 char value[PROPERTY_VALUE_MAX];
2261 LOGI("E");
2262 if (!mCameraOpened) {
2263 return NO_ERROR;
2264 }
2265 LOGI("[KPI Perf]: E PROFILE_CLOSE_CAMERA camera id %d",
2266 mCameraId);
2267
2268 // set open flag to false
2269 mCameraOpened = false;
2270
2271 // Reset Stream config info
2272 mParameters.setStreamConfigure(false, false, true);
2273
2274 // deinit Parameters
2275 mParameters.deinit();
2276
2277 // exit notifier
2278 m_cbNotifier.exit();
2279
2280 // stop and deinit postprocessor
2281 waitDeferredWork(mReprocJob);
2282 // Close the JPEG session
2283 waitDeferredWork(mJpegJob);
2284 m_postprocessor.stop();
2285 deinitJpegHandle();
2286 m_postprocessor.deinit();
2287 mInitPProcJob = 0; // reset job id, so pproc can be reinited later
2288
2289 m_thermalAdapter.deinit();
2290
2291 // delete all channels if not already deleted
2292 for (i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
2293 if (m_channels[i] != NULL) {
2294 m_channels[i]->stop();
2295 delete m_channels[i];
2296 m_channels[i] = NULL;
2297 }
2298 }
2299
2300 //free all pending api results here
2301 if(m_apiResultList != NULL) {
2302 api_result_list *apiResultList = m_apiResultList;
2303 api_result_list *apiResultListNext;
2304 while (apiResultList != NULL) {
2305 apiResultListNext = apiResultList->next;
2306 free(apiResultList);
2307 apiResultList = apiResultListNext;
2308 }
2309 }
2310
2311 rc = mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
2312 mCameraHandle = NULL;
2313
2314 //Notify display HAL that there is no active camera session
2315 //but avoid calling the same during bootup. Refer to openCamera
2316 //for more details.
2317 property_get("service.bootanim.exit", value, "0");
2318 if (atoi(value) == 1) {
2319 pthread_mutex_lock(&gCamLock);
2320 if (--gNumCameraSessions == 0) {
2321 setCameraLaunchStatus(false);
2322 }
2323 pthread_mutex_unlock(&gCamLock);
2324 }
2325
2326 if (mExifParams.debug_params) {
2327 free(mExifParams.debug_params);
2328 mExifParams.debug_params = NULL;
2329 }
2330
2331 if (QCameraFlash::getInstance().releaseFlashFromCamera(mCameraId) != 0) {
2332 LOGD("Failed to release flash for camera id: %d",
2333 mCameraId);
2334 }
2335
2336 LOGI("[KPI Perf]: X PROFILE_CLOSE_CAMERA camera id %d, rc: %d",
2337 mCameraId, rc);
2338
2339 return rc;
2340 }
2341
2342 #define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX )
2343
2344
2345 /*===========================================================================
2346 * FUNCTION : getCapabilities
2347 *
2348 * DESCRIPTION: query camera capability from back-end
2349 *
2350 * PARAMETERS :
2351 * @ops : mm-interface ops structure
2352 * @cam_handle : camera handle for which we need capability
2353 *
2354 * RETURN : ptr type of capability structure
2355 * capability for success
2356 * NULL for failure
2357 *==========================================================================*/
getCapabilities(mm_camera_ops_t * ops,uint32_t cam_handle)2358 cam_capability_t *QCamera2HardwareInterface::getCapabilities(mm_camera_ops_t *ops,
2359 uint32_t cam_handle)
2360 {
2361 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_GET_CAP);
2362 int rc = NO_ERROR;
2363 QCameraHeapMemory *capabilityHeap = NULL;
2364 cam_capability_t *cap_ptr = NULL;
2365
2366 if (ops == NULL) {
2367 LOGE("Invalid arguments");
2368 return NULL;
2369 }
2370
2371 capabilityHeap = new QCameraHeapMemory(1);
2372 if (capabilityHeap == NULL) {
2373 LOGE("creation of capabilityHeap failed");
2374 return NULL;
2375 }
2376
2377 /* Allocate memory for capability buffer */
2378 rc = capabilityHeap->allocate(1, sizeof(cam_capability_t));
2379 if(rc != OK) {
2380 LOGE("No memory for capability");
2381 goto allocate_failed;
2382 }
2383
2384 /* Map memory for capability buffer */
2385 memset(DATA_PTR(capabilityHeap,0), 0, sizeof(cam_capability_t));
2386
2387 cam_buf_map_type_list bufMapList;
2388 rc = QCameraBufferMaps::makeSingletonBufMapList(
2389 CAM_MAPPING_BUF_TYPE_CAPABILITY,
2390 0 /*stream id*/, 0 /*buffer index*/, -1 /*plane index*/,
2391 0 /*cookie*/, capabilityHeap->getFd(0), sizeof(cam_capability_t),
2392 bufMapList, capabilityHeap->getPtr(0));
2393
2394 if (rc == NO_ERROR) {
2395 rc = ops->map_bufs(cam_handle,
2396 &bufMapList);
2397 }
2398 if(rc < 0) {
2399 LOGE("failed to map capability buffer");
2400 goto map_failed;
2401 }
2402
2403 /* Query Capability */
2404 rc = ops->query_capability(cam_handle);
2405 if(rc < 0) {
2406 LOGE("failed to query capability");
2407 rc = FAILED_TRANSACTION;
2408 goto query_failed;
2409 }
2410
2411 cap_ptr = (cam_capability_t *)malloc(sizeof(cam_capability_t));
2412 if (cap_ptr == NULL) {
2413 LOGE("out of memory");
2414 rc = NO_MEMORY;
2415 goto query_failed;
2416 }
2417
2418 memset(cap_ptr, 0, sizeof(cam_capability_t));
2419 memcpy(cap_ptr, DATA_PTR(capabilityHeap, 0), sizeof(cam_capability_t));
2420
2421 int index;
2422 for (index = 0; index < CAM_ANALYSIS_INFO_MAX; index++) {
2423 cam_analysis_info_t *p_analysis_info = &cap_ptr->analysis_info[index];
2424 p_analysis_info->analysis_padding_info.offset_info.offset_x = 0;
2425 p_analysis_info->analysis_padding_info.offset_info.offset_y = 0;
2426 }
2427
2428 query_failed:
2429 ops->unmap_buf(cam_handle, CAM_MAPPING_BUF_TYPE_CAPABILITY);
2430 map_failed:
2431 capabilityHeap->deallocate();
2432 allocate_failed:
2433 delete capabilityHeap;
2434
2435 if (rc != NO_ERROR) {
2436 return NULL;
2437 } else {
2438 return cap_ptr;
2439 }
2440 }
2441
2442 /*===========================================================================
2443 * FUNCTION : initCapabilities
2444 *
2445 * DESCRIPTION: initialize camera capabilities in static data struct
2446 *
2447 * PARAMETERS :
2448 * @cameraId : camera Id
2449 *
2450 * RETURN : int32_t type of status
2451 * NO_ERROR -- success
2452 * none-zero failure code
2453 *==========================================================================*/
initCapabilities(uint32_t cameraId,mm_camera_vtbl_t * cameraHandle)2454 int QCamera2HardwareInterface::initCapabilities(uint32_t cameraId,
2455 mm_camera_vtbl_t *cameraHandle)
2456 {
2457 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_INIT_CAP);
2458 int rc = 0;
2459 uint32_t handle = 0;
2460
2461 rc = camera_open((uint8_t)cameraId, &cameraHandle);
2462 if (rc) {
2463 LOGE("camera_open failed. rc = %d", rc);
2464 goto open_failed;
2465 }
2466 if (!cameraHandle) {
2467 LOGE("camera_open failed. cameraHandle = %p", cameraHandle);
2468 goto open_failed;
2469 }
2470
2471 handle = get_main_camera_handle(cameraHandle->camera_handle);
2472 gCamCapability[cameraId] = getCapabilities(cameraHandle->ops, handle);
2473 if (gCamCapability[cameraId] == NULL) {
2474 rc = FAILED_TRANSACTION;
2475 goto failed_op;
2476 }
2477
2478 gCamCapability[cameraId]->camera_index = cameraId;
2479 if (is_dual_camera_by_idx(cameraId)) {
2480 handle = get_aux_camera_handle(cameraHandle->camera_handle);
2481 gCamCapability[cameraId]->aux_cam_cap =
2482 getCapabilities(cameraHandle->ops, handle);
2483 if (gCamCapability[cameraId]->aux_cam_cap == NULL) {
2484 rc = FAILED_TRANSACTION;
2485 free(gCamCapability[cameraId]);
2486 goto failed_op;
2487 }
2488
2489 // Copy the main camera capability to main_cam_cap struct
2490 gCamCapability[cameraId]->main_cam_cap =
2491 (cam_capability_t *)malloc(sizeof(cam_capability_t));
2492 if (gCamCapability[cameraId]->main_cam_cap == NULL) {
2493 LOGE("out of memory");
2494 rc = NO_MEMORY;
2495 goto failed_op;
2496 }
2497 memcpy(gCamCapability[cameraId]->main_cam_cap, gCamCapability[cameraId],
2498 sizeof(cam_capability_t));
2499 }
2500 failed_op:
2501 cameraHandle->ops->close_camera(cameraHandle->camera_handle);
2502 cameraHandle = NULL;
2503 open_failed:
2504 return rc;
2505 }
2506
2507 /*===========================================================================
2508 * FUNCTION : getCapabilities
2509 *
2510 * DESCRIPTION: query camera capabilities
2511 *
2512 * PARAMETERS :
2513 * @cameraId : camera Id
2514 * @info : camera info struct to be filled in with camera capabilities
2515 *
2516 * RETURN : int type of status
2517 * NO_ERROR -- success
2518 * none-zero failure code
2519 *==========================================================================*/
getCapabilities(uint32_t cameraId,struct camera_info * info,cam_sync_type_t * p_cam_type)2520 int QCamera2HardwareInterface::getCapabilities(uint32_t cameraId,
2521 struct camera_info *info, cam_sync_type_t *p_cam_type)
2522 {
2523 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_GET_CAP);
2524 int rc = NO_ERROR;
2525 struct camera_info *p_info = NULL;
2526 pthread_mutex_lock(&gCamLock);
2527 p_info = get_cam_info(cameraId, p_cam_type);
2528 p_info->device_version = CAMERA_DEVICE_API_VERSION_1_0;
2529 p_info->static_camera_characteristics = NULL;
2530 memcpy(info, p_info, sizeof (struct camera_info));
2531 pthread_mutex_unlock(&gCamLock);
2532 return rc;
2533 }
2534
2535 /*===========================================================================
2536 * FUNCTION : getCamHalCapabilities
2537 *
2538 * DESCRIPTION: get the HAL capabilities structure
2539 *
2540 * PARAMETERS :
2541 * @cameraId : camera Id
2542 *
2543 * RETURN : capability structure of respective camera
2544 *
2545 *==========================================================================*/
getCamHalCapabilities()2546 cam_capability_t* QCamera2HardwareInterface::getCamHalCapabilities()
2547 {
2548 return gCamCapability[mCameraId];
2549 }
2550
2551 /*===========================================================================
2552 * FUNCTION : getBufNumForAux
2553 *
2554 * DESCRIPTION: return number of stream buffers needed for aux camera given stream type
2555 *
2556 * PARAMETERS :
2557 * @stream_type : type of stream
2558 *
2559 * RETURN : number of buffers needed
2560 * NOTE : Based on the use cases and auxillary camera type,
2561 we can decide buffer count
2562 *==========================================================================*/
getBufNumForAux(cam_stream_type_t stream_type)2563 uint8_t QCamera2HardwareInterface::getBufNumForAux(cam_stream_type_t stream_type)
2564 {
2565 if (!isDualCamera()) {
2566 return 0;
2567 }
2568
2569 uint8_t bufferCnt = 1;
2570 switch (stream_type) {
2571 case CAM_STREAM_TYPE_PREVIEW:
2572 case CAM_STREAM_TYPE_VIDEO:
2573 case CAM_STREAM_TYPE_SNAPSHOT:
2574 case CAM_STREAM_TYPE_METADATA:
2575 case CAM_STREAM_TYPE_CALLBACK:
2576 case CAM_STREAM_TYPE_ANALYSIS:
2577 case CAM_STREAM_TYPE_POSTVIEW:
2578 case CAM_STREAM_TYPE_RAW:
2579 case CAM_STREAM_TYPE_OFFLINE_PROC:
2580 case CAM_STREAM_TYPE_DEFAULT:
2581 case CAM_STREAM_TYPE_MAX:
2582 //For wide & tele, we use same buffer count premary and aux streams.
2583 bufferCnt = getBufNumRequired(stream_type);
2584 break;
2585 default:
2586 break;
2587 }
2588 LOGH("Buffer Cnt for Aux Camera : %d", bufferCnt);
2589 return bufferCnt;
2590 }
2591
2592 /*===========================================================================
2593 * FUNCTION : getBufNumRequired
2594 *
2595 * DESCRIPTION: return number of stream buffers needed for given stream type
2596 *
2597 * PARAMETERS :
2598 * @stream_type : type of stream
2599 *
2600 * RETURN : number of buffers needed
2601 *==========================================================================*/
getBufNumRequired(cam_stream_type_t stream_type)2602 uint8_t QCamera2HardwareInterface::getBufNumRequired(cam_stream_type_t stream_type)
2603 {
2604 int bufferCnt = 0;
2605 int minCaptureBuffers = mParameters.getNumOfSnapshots();
2606 char value[PROPERTY_VALUE_MAX];
2607 bool raw_yuv = false;
2608 int persist_cnt = 0;
2609 int minPrevFps, maxPrevFps;
2610
2611 int zslQBuffers = mParameters.getZSLQueueDepth();
2612
2613 int minCircularBufNum = mParameters.getMaxUnmatchedFramesInQueue() +
2614 CAMERA_MIN_JPEG_ENCODING_BUFFERS;
2615
2616 int maxStreamBuf = minCaptureBuffers + mParameters.getMaxUnmatchedFramesInQueue() +
2617 mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2618 mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2619 mParameters.getNumOfExtraBuffersForImageProc() +
2620 EXTRA_ZSL_PREVIEW_STREAM_BUF;
2621
2622 int minUndequeCount = 0;
2623 if (!isNoDisplayMode()) {
2624 if(mPreviewWindow != NULL) {
2625 if (mPreviewWindow->get_min_undequeued_buffer_count(mPreviewWindow,&minUndequeCount)
2626 != 0) {
2627 LOGW("get_min_undequeued_buffer_count failed");
2628 //TODO: hardcoded because MIN_UNDEQUEUED_BUFFERS not defined
2629 //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
2630 minUndequeCount = MIN_UNDEQUEUED_BUFFERS;
2631 }
2632 } else {
2633 //preview window might not be set at this point. So, query directly
2634 //from BufferQueue implementation of gralloc buffers.
2635 //minUndequeCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS;
2636 //hardcoded because MIN_UNDEQUEUED_BUFFERS not defined. REVISIT
2637 minUndequeCount = MIN_UNDEQUEUED_BUFFERS;
2638 }
2639 if (minUndequeCount != MIN_UNDEQUEUED_BUFFERS) {
2640 // minUndequeCount from valid preview window != hardcoded MIN_UNDEQUEUED_BUFFERS
2641 // and so change the MACRO as per minUndequeCount
2642 LOGW("WARNING : minUndequeCount(%d) != hardcoded value(%d)",
2643 minUndequeCount, MIN_UNDEQUEUED_BUFFERS);
2644 }
2645 }
2646
2647 LOGD("minCaptureBuffers = %d zslQBuffers = %d minCircularBufNum = %d"
2648 "maxStreamBuf = %d minUndequeCount = %d",
2649 minCaptureBuffers, zslQBuffers, minCircularBufNum,
2650 maxStreamBuf, minUndequeCount);
2651 // Get buffer count for the particular stream type
2652 switch (stream_type) {
2653 case CAM_STREAM_TYPE_PREVIEW:
2654 {
2655 if (mParameters.isZSLMode()) {
2656 // We need to add two extra streming buffers to add
2657 // flexibility in forming matched super buf in ZSL queue.
2658 // with number being 'zslQBuffers + minCircularBufNum'
2659 // we see preview buffers sometimes get dropped at CPP
2660 // and super buf is not forming in ZSL Q for long time.
2661
2662 bufferCnt = zslQBuffers + minCircularBufNum +
2663 mParameters.getNumOfExtraBuffersForImageProc() +
2664 mParameters.getNumOfExtraBuffersForPreview() +
2665 mParameters.getNumOfExtraHDRInBufsIfNeeded();
2666 if (isDualCamera()) {
2667 bufferCnt += zslQBuffers;
2668 }
2669 } else {
2670 bufferCnt = CAMERA_MIN_STREAMING_BUFFERS +
2671 mParameters.getMaxUnmatchedFramesInQueue() +
2672 mParameters.getNumOfExtraBuffersForPreview();
2673 }
2674 // ISP allocates native preview buffers and so reducing same from HAL allocation
2675 if (bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS )
2676 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
2677
2678 // Extra ZSL preview frames are not needed for HFR case.
2679 // Thumbnail will not be derived from preview for HFR live snapshot case.
2680 if ((mParameters.getRecordingHintValue() == true)
2681 && (!mParameters.isHfrMode())) {
2682 bufferCnt += EXTRA_ZSL_PREVIEW_STREAM_BUF;
2683 }
2684 //Adding Extra preview buffers for 60FPS usecase.
2685 mParameters.getPreviewFpsRange(&minPrevFps, &maxPrevFps);
2686 if (maxPrevFps > CAMERA_DEFAULT_FPS) {
2687 bufferCnt += CAMERA_MIN_DISPLAY_BUFFERS;
2688 }
2689
2690 // Add the display minUndequeCount count on top of camera requirement
2691 bufferCnt += minUndequeCount;
2692
2693 property_get("persist.camera.preview_yuv", value, "0");
2694 persist_cnt = atoi(value);
2695 if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
2696 && (bufferCnt < persist_cnt)) {
2697 bufferCnt = persist_cnt;
2698 }
2699 }
2700 break;
2701 case CAM_STREAM_TYPE_POSTVIEW:
2702 {
2703 bufferCnt = minCaptureBuffers +
2704 mParameters.getMaxUnmatchedFramesInQueue() +
2705 mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2706 mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2707 mParameters.getNumOfExtraBuffersForImageProc();
2708
2709 if (bufferCnt > maxStreamBuf) {
2710 bufferCnt = maxStreamBuf;
2711 }
2712 bufferCnt += minUndequeCount;
2713 }
2714 break;
2715 case CAM_STREAM_TYPE_SNAPSHOT:
2716 {
2717 if (mParameters.isZSLMode() || mLongshotEnabled) {
2718 if ((minCaptureBuffers == 1 || mParameters.isUbiRefocus()) &&
2719 !mLongshotEnabled) {
2720 // Single ZSL snapshot case
2721 bufferCnt = zslQBuffers + CAMERA_MIN_STREAMING_BUFFERS +
2722 mParameters.getNumOfExtraBuffersForImageProc();
2723 } else {
2724 // ZSL Burst or Longshot case
2725 bufferCnt = zslQBuffers + minCircularBufNum +
2726 mParameters.getNumOfExtraBuffersForImageProc();
2727 }
2728 if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) {
2729 //ISP allocates native buffers in YUV case
2730 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
2731 }
2732 if (isDualCamera()) {
2733 bufferCnt += zslQBuffers;
2734 }
2735 } else {
2736 bufferCnt = minCaptureBuffers +
2737 mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2738 mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2739 mParameters.getNumOfExtraBuffersForImageProc();
2740
2741 if (bufferCnt > maxStreamBuf) {
2742 bufferCnt = maxStreamBuf;
2743 }
2744 }
2745 }
2746 break;
2747 case CAM_STREAM_TYPE_RAW:
2748 property_get("persist.camera.raw_yuv", value, "0");
2749 raw_yuv = atoi(value) > 0 ? true : false;
2750
2751 if (isRdiMode() || raw_yuv || isSecureMode()) {
2752 bufferCnt = zslQBuffers + minCircularBufNum;
2753 } else if (mParameters.isZSLMode()) {
2754 bufferCnt = zslQBuffers + minCircularBufNum;
2755 if (getSensorType() == CAM_SENSOR_YUV && bufferCnt > CAMERA_ISP_PING_PONG_BUFFERS) {
2756 //ISP allocates native buffers in YUV case
2757 bufferCnt -= CAMERA_ISP_PING_PONG_BUFFERS;
2758 }
2759
2760 } else {
2761 bufferCnt = minCaptureBuffers +
2762 mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2763 mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2764 mParameters.getNumOfExtraBuffersForImageProc();
2765
2766 if (bufferCnt > maxStreamBuf) {
2767 bufferCnt = maxStreamBuf;
2768 }
2769 }
2770
2771 property_get("persist.camera.preview_raw", value, "0");
2772 persist_cnt = atoi(value);
2773 if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
2774 && (bufferCnt < persist_cnt)) {
2775 bufferCnt = persist_cnt;
2776 }
2777 property_get("persist.camera.video_raw", value, "0");
2778 persist_cnt = atoi(value);
2779 if ((persist_cnt < CAM_MAX_NUM_BUFS_PER_STREAM)
2780 && (bufferCnt < persist_cnt)) {
2781 bufferCnt = persist_cnt;
2782 }
2783
2784 break;
2785 case CAM_STREAM_TYPE_VIDEO:
2786 {
2787 if (mParameters.getBufBatchCount()) {
2788 //Video Buffer in case of HFR or camera batching..
2789 bufferCnt = CAMERA_MIN_CAMERA_BATCH_BUFFERS;
2790 } else if (mParameters.getVideoBatchSize()) {
2791 //Video Buffer count only for HAL to HAL batching.
2792 bufferCnt = (CAMERA_MIN_VIDEO_BATCH_BUFFERS
2793 * mParameters.getVideoBatchSize());
2794 if (bufferCnt < CAMERA_MIN_VIDEO_BUFFERS) {
2795 bufferCnt = CAMERA_MIN_VIDEO_BUFFERS;
2796 }
2797 } else {
2798 // No batching enabled.
2799 bufferCnt = CAMERA_MIN_VIDEO_BUFFERS;
2800 }
2801
2802 bufferCnt += mParameters.getNumOfExtraBuffersForVideo();
2803 //if its 4K encoding usecase, then add extra buffer
2804 cam_dimension_t dim;
2805 mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim);
2806 if (is4k2kResolution(&dim)) {
2807 //get additional buffer count
2808 property_get("vidc.enc.dcvs.extra-buff-count", value, "0");
2809 bufferCnt += atoi(value);
2810 }
2811 }
2812 break;
2813 case CAM_STREAM_TYPE_METADATA:
2814 {
2815 if (mParameters.isZSLMode()) {
2816 // MetaData buffers should be >= (Preview buffers-minUndequeCount)
2817 bufferCnt = zslQBuffers + minCircularBufNum +
2818 mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2819 mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2820 mParameters.getNumOfExtraBuffersForImageProc() +
2821 EXTRA_ZSL_PREVIEW_STREAM_BUF;
2822 if (isDualCamera()) {
2823 bufferCnt += zslQBuffers;
2824 }
2825 } else {
2826 bufferCnt = minCaptureBuffers +
2827 mParameters.getNumOfExtraHDRInBufsIfNeeded() -
2828 mParameters.getNumOfExtraHDROutBufsIfNeeded() +
2829 mParameters.getMaxUnmatchedFramesInQueue() +
2830 CAMERA_MIN_STREAMING_BUFFERS +
2831 mParameters.getNumOfExtraBuffersForImageProc();
2832
2833 if (bufferCnt > zslQBuffers + minCircularBufNum) {
2834 bufferCnt = zslQBuffers + minCircularBufNum;
2835 }
2836 }
2837 if (CAMERA_MIN_METADATA_BUFFERS > bufferCnt) {
2838 bufferCnt = CAMERA_MIN_METADATA_BUFFERS;
2839 }
2840 }
2841 break;
2842 case CAM_STREAM_TYPE_OFFLINE_PROC:
2843 {
2844 bufferCnt = minCaptureBuffers;
2845 // One of the ubifocus buffers is miscellaneous buffer
2846 if (mParameters.isUbiRefocus()) {
2847 bufferCnt -= 1;
2848 }
2849 if (mLongshotEnabled) {
2850 bufferCnt = mParameters.getLongshotStages();
2851 }
2852 }
2853 break;
2854 case CAM_STREAM_TYPE_CALLBACK:
2855 bufferCnt = CAMERA_MIN_CALLBACK_BUFFERS;
2856 break;
2857 case CAM_STREAM_TYPE_ANALYSIS:
2858 case CAM_STREAM_TYPE_DEFAULT:
2859 case CAM_STREAM_TYPE_MAX:
2860 default:
2861 bufferCnt = 0;
2862 break;
2863 }
2864
2865 LOGH("Buffer count = %d for stream type = %d", bufferCnt, stream_type);
2866 if (CAM_MAX_NUM_BUFS_PER_STREAM < bufferCnt) {
2867 LOGW("Buffer count %d for stream type %d exceeds limit %d",
2868 bufferCnt, stream_type, CAM_MAX_NUM_BUFS_PER_STREAM);
2869 return CAM_MAX_NUM_BUFS_PER_STREAM;
2870 }
2871
2872 return (uint8_t)bufferCnt;
2873 }
2874
2875 /*===========================================================================
2876 * FUNCTION : getStreamRefCount
2877 *
2878 * DESCRIPTION: return number of instance of stream of stream type
2879 *
2880 * PARAMETERS :
2881 * @stream_type : type of stream
2882 * @cam_type : Type of camera for this stream
2883 *
2884 * RETURN : number of stream instances
2885 * NOTE : Based on the use cases and auxillary camera type,
2886 we can decide stream reference count.
2887 For example in wide and tele use case, we duplicate all stream
2888 streams from premary to auxillary.
2889 *==========================================================================*/
getStreamRefCount(cam_stream_type_t stream_type,uint32_t cam_type)2890 uint8_t QCamera2HardwareInterface::getStreamRefCount(cam_stream_type_t stream_type,
2891 uint32_t cam_type)
2892 {
2893 uint8_t ref_cnt = 1;
2894
2895 if (cam_type != MM_CAMERA_DUAL_CAM) {
2896 return ref_cnt;
2897 }
2898
2899 switch (stream_type) {
2900 case CAM_STREAM_TYPE_PREVIEW:
2901 case CAM_STREAM_TYPE_SNAPSHOT:
2902 case CAM_STREAM_TYPE_VIDEO:
2903 case CAM_STREAM_TYPE_METADATA:
2904 case CAM_STREAM_TYPE_ANALYSIS:
2905 case CAM_STREAM_TYPE_CALLBACK:
2906 if (isDualCamera()) {
2907 ref_cnt++;
2908 }
2909 break;
2910 case CAM_STREAM_TYPE_POSTVIEW:
2911 case CAM_STREAM_TYPE_RAW:
2912 case CAM_STREAM_TYPE_OFFLINE_PROC:
2913 case CAM_STREAM_TYPE_DEFAULT:
2914 case CAM_STREAM_TYPE_MAX:
2915 default:
2916 break;
2917 }
2918 return ref_cnt;
2919 }
2920
2921 /*===========================================================================
2922 * FUNCTION : getCamHandleForChannel
2923 *
2924 * DESCRIPTION: return actual camera handle based on use case
2925 *
2926 * PARAMETERS :
2927 * @ch_type : type of channel
2928 *
2929 * RETURN : uint32_t type camera handle
2930 * NOTE : Based on the use cases and auxillary camera type, we can decide cam handle for channel.
2931 Incase, we want to avoid any channel for auxillary camera, we can decide here
2932 *==========================================================================*/
getCamHandleForChannel(qcamera_ch_type_enum_t ch_type)2933 uint32_t QCamera2HardwareInterface::getCamHandleForChannel(qcamera_ch_type_enum_t ch_type)
2934 {
2935 uint32_t handle = 0;
2936 if (!isDualCamera()) {
2937 return mCameraHandle->camera_handle;
2938 }
2939
2940 /*Based on the use case, decide camera handle for channel*/
2941 switch (ch_type) {
2942 case QCAMERA_CH_TYPE_ZSL:
2943 case QCAMERA_CH_TYPE_CAPTURE:
2944 case QCAMERA_CH_TYPE_PREVIEW:
2945 case QCAMERA_CH_TYPE_VIDEO:
2946 case QCAMERA_CH_TYPE_SNAPSHOT:
2947 case QCAMERA_CH_TYPE_RAW:
2948 case QCAMERA_CH_TYPE_METADATA:
2949 case QCAMERA_CH_TYPE_ANALYSIS:
2950 case QCAMERA_CH_TYPE_CALLBACK:
2951 case QCAMERA_CH_TYPE_MAX:
2952 default:
2953 handle = mCameraHandle->camera_handle;
2954 break;
2955 case QCAMERA_CH_TYPE_REPROCESSING:
2956 if (!mParameters.isDCmAsymmetricSnapMode()) {
2957 handle = get_main_camera_handle(mCameraHandle->camera_handle);
2958 } else {
2959 /*In Asymmetric mode, we create 2 reproc channels. But
2960 one stream is added per channel */
2961 handle = mCameraHandle->camera_handle;
2962 }
2963 break;
2964 }
2965 return handle;
2966 }
2967
2968 /*===========================================================================
2969 * FUNCTION : allocateStreamBuf
2970 *
2971 * DESCRIPTION: alocate stream buffers
2972 *
2973 * PARAMETERS :
2974 * @stream_type : type of stream
2975 * @size : size of buffer
2976 * @stride : stride of buffer
2977 * @scanline : scanline of buffer
2978 * @bufferCnt : [IN/OUT] minimum num of buffers to be allocated.
2979 * could be modified during allocation if more buffers needed
2980 *
2981 * RETURN : ptr to a memory obj that holds stream buffers.
2982 * NULL if failed
2983 *==========================================================================*/
allocateStreamBuf(cam_stream_type_t stream_type,size_t size,int stride,int scanline,uint8_t & bufferCnt)2984 QCameraMemory *QCamera2HardwareInterface::allocateStreamBuf(
2985 cam_stream_type_t stream_type, size_t size, int stride, int scanline,
2986 uint8_t &bufferCnt)
2987 {
2988 int rc = NO_ERROR;
2989 QCameraMemory *mem = NULL;
2990 bool bCachedMem = QCAMERA_ION_USE_CACHE;
2991 bool bPoolMem = false;
2992 char value[PROPERTY_VALUE_MAX];
2993 property_get("persist.camera.mem.usepool", value, "1");
2994 if (atoi(value) == 1) {
2995 bPoolMem = true;
2996 }
2997
2998 // Allocate stream buffer memory object
2999 switch (stream_type) {
3000 case CAM_STREAM_TYPE_PREVIEW:
3001 {
3002 if (isNoDisplayMode()) {
3003 mem = new QCameraStreamMemory(mGetMemory,
3004 mCallbackCookie,
3005 bCachedMem,
3006 (bPoolMem) ? &m_memoryPool : NULL,
3007 stream_type);
3008 } else {
3009 cam_dimension_t dim;
3010 int minFPS, maxFPS;
3011 QCameraGrallocMemory *grallocMemory = NULL;
3012
3013 if (isSecureMode()) {
3014 grallocMemory = new QCameraGrallocMemory(mGetMemory, mCallbackCookie, QCAMERA_MEM_TYPE_SECURE);
3015 }else {
3016 grallocMemory = new QCameraGrallocMemory(mGetMemory, mCallbackCookie);
3017 }
3018
3019 mParameters.getStreamDimension(stream_type, dim);
3020 /* we are interested only in maxfps here */
3021 mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
3022 int usage = 0;
3023 if(mParameters.isUBWCEnabled()) {
3024 cam_format_t fmt;
3025 mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW,fmt);
3026 if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
3027 usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC ;
3028 }
3029 }
3030 if (grallocMemory) {
3031 grallocMemory->setMappable(
3032 CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS);
3033 grallocMemory->setWindowInfo(mPreviewWindow,
3034 dim.width,dim.height, stride, scanline,
3035 mParameters.getPreviewHalPixelFormat(),
3036 maxFPS, usage);
3037 pthread_mutex_lock(&mGrallocLock);
3038 if (bufferCnt > CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS) {
3039 mEnqueuedBuffers = (bufferCnt -
3040 CAMERA_INITIAL_MAPPABLE_PREVIEW_BUFFERS);
3041 } else {
3042 mEnqueuedBuffers = 0;
3043 }
3044 pthread_mutex_unlock(&mGrallocLock);
3045 }
3046 mem = grallocMemory;
3047 }
3048 }
3049 break;
3050 case CAM_STREAM_TYPE_POSTVIEW:
3051 {
3052 if (isNoDisplayMode() || isPreviewRestartEnabled()) {
3053 mem = new QCameraStreamMemory(mGetMemory, mCallbackCookie, bCachedMem);
3054 } else {
3055 cam_dimension_t dim;
3056 int minFPS, maxFPS;
3057 QCameraGrallocMemory *grallocMemory =
3058 new QCameraGrallocMemory(mGetMemory, mCallbackCookie);
3059
3060 mParameters.getStreamDimension(stream_type, dim);
3061 /* we are interested only in maxfps here */
3062 mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
3063 if (grallocMemory) {
3064 grallocMemory->setWindowInfo(mPreviewWindow, dim.width,
3065 dim.height, stride, scanline,
3066 mParameters.getPreviewHalPixelFormat(), maxFPS);
3067 }
3068 mem = grallocMemory;
3069 }
3070 }
3071 break;
3072 case CAM_STREAM_TYPE_ANALYSIS:
3073 case CAM_STREAM_TYPE_SNAPSHOT:
3074 case CAM_STREAM_TYPE_OFFLINE_PROC:
3075 mem = new QCameraStreamMemory(mGetMemory,
3076 mCallbackCookie,
3077 bCachedMem,
3078 (bPoolMem) ? &m_memoryPool : NULL,
3079 stream_type);
3080 break;
3081 case CAM_STREAM_TYPE_RAW:
3082 if(isSecureMode()) {
3083 mem = new QCameraStreamMemory(mGetMemory,
3084 mCallbackCookie,
3085 bCachedMem,
3086 (bPoolMem) ? &m_memoryPool : NULL,
3087 stream_type,
3088 QCAMERA_MEM_TYPE_SECURE);
3089 LOGH("Allocating %d secure buffers of size %d ", bufferCnt, size);
3090 } else {
3091 mem = new QCameraStreamMemory(mGetMemory,
3092 mCallbackCookie,
3093 bCachedMem,
3094 (bPoolMem) ? &m_memoryPool : NULL,
3095 stream_type);
3096 }
3097 break;
3098 case CAM_STREAM_TYPE_METADATA:
3099 {
3100 if (mMetadataMem == NULL) {
3101 mem = new QCameraMetadataStreamMemory(QCAMERA_ION_USE_CACHE);
3102 } else {
3103 mem = mMetadataMem;
3104 mMetadataMem = NULL;
3105
3106 int32_t numAdditionalBuffers = bufferCnt - mem->getCnt();
3107 if (numAdditionalBuffers > 0) {
3108 rc = mem->allocateMore(numAdditionalBuffers, size);
3109 if (rc != NO_ERROR) {
3110 LOGE("Failed to allocate additional buffers, "
3111 "but attempting to proceed.");
3112 }
3113 }
3114 bufferCnt = mem->getCnt();
3115 // The memory is already allocated and initialized, so
3116 // simply return here.
3117 return mem;
3118 }
3119 }
3120 break;
3121 case CAM_STREAM_TYPE_VIDEO:
3122 {
3123 //Use uncached allocation by default
3124 if (mParameters.isVideoBuffersCached() || mParameters.isSeeMoreEnabled() ||
3125 mParameters.isHighQualityNoiseReductionMode()) {
3126 bCachedMem = QCAMERA_ION_USE_CACHE;
3127 }
3128 else {
3129 bCachedMem = QCAMERA_ION_USE_NOCACHE;
3130 }
3131
3132 QCameraVideoMemory *videoMemory = NULL;
3133 int usage = 0;
3134 cam_format_t fmt;
3135
3136 if (mParameters.getVideoBatchSize()) {
3137 videoMemory = new QCameraVideoMemory(
3138 mGetMemory, mCallbackCookie, FALSE, QCAMERA_MEM_TYPE_BATCH);
3139 if (videoMemory == NULL) {
3140 LOGE("Out of memory for video batching obj");
3141 return NULL;
3142 }
3143 mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO,fmt);
3144 if (mParameters.isUBWCEnabled() &&
3145 (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
3146 usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
3147 }
3148 videoMemory->setVideoInfo(usage, fmt);
3149 /*
3150 * numFDs = BATCH size
3151 * numInts = 5 // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
3152 */
3153 rc = videoMemory->allocateMeta(
3154 CAMERA_MIN_VIDEO_BATCH_BUFFERS,
3155 mParameters.getVideoBatchSize());
3156 if (rc < 0) {
3157 delete videoMemory;
3158 return NULL;
3159 }
3160 } else {
3161 videoMemory =
3162 new QCameraVideoMemory(mGetMemory, mCallbackCookie, bCachedMem);
3163 if (videoMemory == NULL) {
3164 LOGE("Out of memory for video obj");
3165 return NULL;
3166 }
3167 mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO,fmt);
3168 if (mParameters.isUBWCEnabled() &&
3169 (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
3170 usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
3171 }
3172 videoMemory->setVideoInfo(usage, fmt);
3173 }
3174 mem = videoMemory;
3175 }
3176 break;
3177 case CAM_STREAM_TYPE_CALLBACK:
3178 mem = new QCameraStreamMemory(mGetMemory,
3179 mCallbackCookie,
3180 bCachedMem,
3181 (bPoolMem) ? &m_memoryPool : NULL,
3182 stream_type);
3183 break;
3184 case CAM_STREAM_TYPE_DEFAULT:
3185 case CAM_STREAM_TYPE_MAX:
3186 default:
3187 break;
3188 }
3189 if (!mem) {
3190 return NULL;
3191 }
3192
3193 if (bufferCnt > 0) {
3194 rc = mem->allocate(bufferCnt, size);
3195 if (rc < 0) {
3196 delete mem;
3197 return NULL;
3198 }
3199 bufferCnt = mem->getCnt();
3200 }
3201 LOGH("rc = %d type = %d count = %d size = %d cache = %d, pool = %d mEnqueuedBuffers = %d",
3202 rc, stream_type, bufferCnt, size, bCachedMem, bPoolMem, mEnqueuedBuffers);
3203 return mem;
3204 }
3205
3206 /*===========================================================================
3207 * FUNCTION : allocateMoreStreamBuf
3208 *
3209 * DESCRIPTION: alocate more stream buffers from the memory object
3210 *
3211 * PARAMETERS :
3212 * @mem_obj : memory object ptr
3213 * @size : size of buffer
3214 * @bufferCnt : [IN/OUT] additional number of buffers to be allocated.
3215 * output will be the number of total buffers
3216 *
3217 * RETURN : int32_t type of status
3218 * NO_ERROR -- success
3219 * none-zero failure code
3220 *==========================================================================*/
allocateMoreStreamBuf(QCameraMemory * mem_obj,size_t size,uint8_t & bufferCnt)3221 int32_t QCamera2HardwareInterface::allocateMoreStreamBuf(
3222 QCameraMemory *mem_obj, size_t size, uint8_t &bufferCnt)
3223 {
3224 int rc = NO_ERROR;
3225
3226 if (bufferCnt > 0) {
3227 rc = mem_obj->allocateMore(bufferCnt, size);
3228 bufferCnt = mem_obj->getCnt();
3229 }
3230 return rc;
3231 }
3232
3233 /*===========================================================================
3234 * FUNCTION : allocateMiscBuf
3235 *
3236 * DESCRIPTION: alocate miscellaneous buffer
3237 *
3238 * PARAMETERS :
3239 * @streamInfo : stream info
3240 *
3241 * RETURN : ptr to a memory obj that holds stream info buffer.
3242 * NULL if failed
3243 *==========================================================================*/
allocateMiscBuf(cam_stream_info_t * streamInfo)3244 QCameraHeapMemory *QCamera2HardwareInterface::allocateMiscBuf(
3245 cam_stream_info_t *streamInfo)
3246 {
3247 int rc = NO_ERROR;
3248 uint8_t bufNum = 0;
3249 size_t bufSize = 0;
3250 QCameraHeapMemory *miscBuf = NULL;
3251 cam_feature_mask_t feature_mask =
3252 streamInfo->reprocess_config.pp_feature_config.feature_mask;
3253
3254 switch (streamInfo->stream_type) {
3255 case CAM_STREAM_TYPE_OFFLINE_PROC:
3256 if (CAM_QCOM_FEATURE_TRUEPORTRAIT & feature_mask) {
3257 bufNum = 1;
3258 bufSize = mParameters.getTPMaxMetaSize();
3259 } else if (CAM_QCOM_FEATURE_REFOCUS & feature_mask) {
3260 bufNum = 1;
3261 bufSize = mParameters.getRefocusMaxMetaSize();
3262 }
3263 break;
3264 default:
3265 break;
3266 }
3267
3268 if (bufNum && bufSize) {
3269 miscBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
3270
3271 if (!miscBuf) {
3272 LOGE("Unable to allocate miscBuf object");
3273 return NULL;
3274 }
3275
3276 rc = miscBuf->allocate(bufNum, bufSize);
3277 if (rc < 0) {
3278 LOGE("Failed to allocate misc buffer memory");
3279 delete miscBuf;
3280 return NULL;
3281 }
3282 }
3283
3284 return miscBuf;
3285 }
3286
3287 /*===========================================================================
3288 * FUNCTION : initStreamInfoBuf
3289 *
3290 * DESCRIPTION: initialize stream info buffer based on stream type
3291 *
3292 * PARAMETERS :
3293 * @stream_type : type of stream
3294 * @cam_type : Camera type in case of dual camera
3295 *
3296 * RETURN : ptr to a memory obj that holds stream info buffer.
3297 * NULL if failed
3298 *==========================================================================*/
initStreamInfoBuf(cam_stream_type_t stream_type,cam_stream_info_t * streamInfo,uint32_t cam_type)3299 int QCamera2HardwareInterface::initStreamInfoBuf(cam_stream_type_t stream_type,
3300 cam_stream_info_t *streamInfo, uint32_t cam_type)
3301 {
3302 int rc = NO_ERROR;
3303 int32_t dt = 0;
3304 int32_t vc = 0;
3305
3306 memset(streamInfo, 0, sizeof(cam_stream_info_t));
3307 streamInfo->stream_type = stream_type;
3308 rc = mParameters.getStreamFormat(stream_type, streamInfo->fmt);
3309 rc = mParameters.getStreamDimension(stream_type, streamInfo->dim, cam_type);
3310 rc = mParameters.getStreamRotation(stream_type, streamInfo->pp_config, streamInfo->dim);
3311 streamInfo->num_bufs = getBufNumRequired(stream_type);
3312 streamInfo->buf_cnt = streamInfo->num_bufs;
3313 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
3314 streamInfo->is_secure = NON_SECURE;
3315 // Initialize cache ops
3316 if (!m_bOptimizeCacheOps) {
3317 streamInfo->cache_ops = CAM_STREAM_CACHE_OPS_DISABLED;
3318 } else {
3319 streamInfo->cache_ops = CAM_STREAM_CACHE_OPS_HONOUR_FLAGS;
3320 }
3321
3322 switch (stream_type) {
3323 case CAM_STREAM_TYPE_SNAPSHOT:
3324 if ((mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) ||
3325 mLongshotEnabled) {
3326 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
3327 } else {
3328 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
3329 streamInfo->num_of_burst = (uint8_t)
3330 (mParameters.getNumOfSnapshots()
3331 + mParameters.getNumOfExtraHDRInBufsIfNeeded()
3332 - mParameters.getNumOfExtraHDROutBufsIfNeeded()
3333 + mParameters.getNumOfExtraBuffersForImageProc());
3334 }
3335 break;
3336 case CAM_STREAM_TYPE_RAW: {
3337 char value[PROPERTY_VALUE_MAX];
3338 bool raw_yuv = false;
3339 property_get("persist.camera.raw_yuv", value, "0");
3340 raw_yuv = atoi(value) > 0 ? true : false;
3341 if ((mParameters.isZSLMode()) || (isRdiMode()) || (raw_yuv) || isSecureMode()) {
3342 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
3343 } else {
3344 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
3345 streamInfo->num_of_burst = mParameters.getNumOfSnapshots();
3346 }
3347 if (isSecureMode()) {
3348 streamInfo->is_secure = SECURE;
3349 } else {
3350 streamInfo->is_secure = NON_SECURE;
3351 }
3352 }
3353 if (CAM_FORMAT_META_RAW_10BIT == streamInfo->fmt) {
3354 mParameters.updateDtVc(&dt, &vc);
3355 if (dt)
3356 streamInfo->dt = dt;
3357 streamInfo->vc = vc;
3358 }
3359
3360 break;
3361 case CAM_STREAM_TYPE_POSTVIEW:
3362 if (mLongshotEnabled) {
3363 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
3364 } else {
3365 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
3366 streamInfo->num_of_burst = (uint8_t)(mParameters.getNumOfSnapshots()
3367 + mParameters.getNumOfExtraHDRInBufsIfNeeded()
3368 - mParameters.getNumOfExtraHDROutBufsIfNeeded()
3369 + mParameters.getNumOfExtraBuffersForImageProc());
3370 }
3371 break;
3372 case CAM_STREAM_TYPE_VIDEO:
3373 streamInfo->dis_enable = mParameters.isDISEnabled();
3374 if (mParameters.getBufBatchCount()) {
3375 //Update stream info structure with batch mode info
3376 streamInfo->streaming_mode = CAM_STREAMING_MODE_BATCH;
3377 streamInfo->user_buf_info.frame_buf_cnt = mParameters.getBufBatchCount();
3378 streamInfo->user_buf_info.size =
3379 (uint32_t)(sizeof(struct msm_camera_user_buf_cont_t));
3380 cam_fps_range_t pFpsRange;
3381 mParameters.getHfrFps(pFpsRange);
3382 streamInfo->user_buf_info.frameInterval =
3383 (long)((1000/pFpsRange.video_max_fps) * 1000);
3384 LOGH("Video Batch Count = %d, interval = %d",
3385 streamInfo->user_buf_info.frame_buf_cnt,
3386 streamInfo->user_buf_info.frameInterval);
3387 }
3388 if (mParameters.getRecordingHintValue()) {
3389 if(mParameters.isDISEnabled()) {
3390 streamInfo->is_type = mParameters.getVideoISType();
3391 } else {
3392 streamInfo->is_type = IS_TYPE_NONE;
3393 }
3394 }
3395 if (mParameters.isSecureMode()) {
3396 streamInfo->is_secure = SECURE;
3397 }
3398 break;
3399 case CAM_STREAM_TYPE_PREVIEW:
3400 if (mParameters.getRecordingHintValue()) {
3401 if(mParameters.isDISEnabled()) {
3402 streamInfo->is_type = mParameters.getPreviewISType();
3403 } else {
3404 streamInfo->is_type = IS_TYPE_NONE;
3405 }
3406 }
3407 if (isSecureMode()) {
3408 streamInfo->is_secure = SECURE;
3409 } else {
3410 streamInfo->is_secure = NON_SECURE;
3411 }
3412 // If SAT enabled, don't add preview stream to Bundled queue
3413 if (isDualCamera()) {
3414 char prop[PROPERTY_VALUE_MAX];
3415 memset(prop, 0, sizeof(prop));
3416 bool satEnabledFlag = FALSE;
3417 property_get("persist.camera.sat.enable", prop, "0");
3418 satEnabledFlag = atoi(prop);
3419 if (satEnabledFlag) {
3420 streamInfo->noFrameExpected = 1;
3421 }
3422 }
3423 break;
3424 case CAM_STREAM_TYPE_ANALYSIS:
3425 streamInfo->noFrameExpected = 1;
3426 break;
3427 case CAM_STREAM_TYPE_METADATA:
3428 streamInfo->cache_ops = CAM_STREAM_CACHE_OPS_CLEAR_FLAGS;
3429 break;
3430 default:
3431 break;
3432 }
3433
3434 // Update feature mask
3435 mParameters.updatePpFeatureMask(stream_type);
3436
3437 // Get feature mask
3438 mParameters.getStreamPpMask(stream_type, streamInfo->pp_config.feature_mask);
3439
3440 // Update pp config
3441 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_FLIP) {
3442 int flipMode = mParameters.getFlipMode(stream_type);
3443 if (flipMode > 0) {
3444 streamInfo->pp_config.flip = (uint32_t)flipMode;
3445 }
3446 }
3447 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_SHARPNESS) {
3448 streamInfo->pp_config.sharpness = mParameters.getSharpness();
3449 }
3450 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_EFFECT) {
3451 streamInfo->pp_config.effect = mParameters.getEffectValue();
3452 }
3453
3454 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_DENOISE2D) {
3455 streamInfo->pp_config.denoise2d.denoise_enable = 1;
3456 streamInfo->pp_config.denoise2d.process_plates =
3457 mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE);
3458 }
3459
3460 if (!((needReprocess()) && (CAM_STREAM_TYPE_SNAPSHOT == stream_type ||
3461 CAM_STREAM_TYPE_RAW == stream_type))) {
3462 if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
3463 CAM_QCOM_FEATURE_CROP)
3464 streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
3465 if (gCamCapability[mCameraId]->qcom_supported_feature_mask &
3466 CAM_QCOM_FEATURE_SCALE)
3467 streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
3468 }
3469 streamInfo->aux_str_info = NULL;
3470
3471 LOGH("type %d, fmt %d, dim %dx%d, num_bufs %d mask = 0x%x is_type %d\n",
3472 stream_type, streamInfo->fmt, streamInfo->dim.width,
3473 streamInfo->dim.height, streamInfo->num_bufs,
3474 streamInfo->pp_config.feature_mask,
3475 streamInfo->is_type);
3476
3477 return rc;
3478 }
3479
3480 /*===========================================================================
3481 * FUNCTION : allocateStreamInfoBuf
3482 *
3483 * DESCRIPTION: alocate stream info buffer
3484 *
3485 * PARAMETERS :
3486 * @stream_type : type of stream
3487 * @bufCount : stream info buffer count
3488 * @cam_type : Camera type in case of dual camera
3489 *
3490 * RETURN : ptr to a memory obj that holds stream info buffer.
3491 * NULL if failed
3492 *==========================================================================*/
allocateStreamInfoBuf(cam_stream_type_t stream_type,uint8_t bufCount,uint32_t cam_type)3493 QCameraHeapMemory *QCamera2HardwareInterface::allocateStreamInfoBuf(
3494 cam_stream_type_t stream_type, uint8_t bufCount, uint32_t cam_type)
3495 {
3496 int rc = NO_ERROR;
3497
3498 QCameraHeapMemory *streamInfoBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
3499 if (!streamInfoBuf) {
3500 LOGE("allocateStreamInfoBuf: Unable to allocate streamInfo object");
3501 return NULL;
3502 }
3503
3504 if (bufCount > MM_CAMERA_MAX_CAM_CNT) {
3505 LOGE("buffer count should be lesser than max camera : %d", bufCount);
3506 return NULL;
3507 }
3508 rc = streamInfoBuf->allocate(bufCount, sizeof(cam_stream_info_t));
3509 if (rc < 0) {
3510 LOGE("allocateStreamInfoBuf: Failed to allocate stream info memory");
3511 delete streamInfoBuf;
3512 return NULL;
3513 }
3514
3515 for (uint8_t i = 0; i < bufCount; i++) {
3516 cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(i);
3517 memset(streamInfo, 0, sizeof(cam_stream_info_t));
3518 rc = initStreamInfoBuf(stream_type, streamInfo, cam_type);
3519 if (rc < 0) {
3520 LOGE("initStreamInfoBuf failed");
3521 delete streamInfoBuf;
3522 return NULL;
3523 }
3524 }
3525
3526 cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(0);
3527 if (bufCount == MM_CAMERA_MAX_CAM_CNT) {
3528 cam_stream_info_t *s_streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(1);
3529 streamInfo->aux_str_info = s_streamInfo;
3530 }
3531
3532 if (streamInfo->aux_str_info != NULL) {
3533 /*Update StreamInfo for Aux camera*/
3534 streamInfo->aux_str_info->buf_cnt = getBufNumForAux(stream_type);
3535 streamInfo->num_bufs += streamInfo->aux_str_info->buf_cnt;
3536 streamInfo->aux_str_info->num_bufs += streamInfo->aux_str_info->buf_cnt;
3537 }
3538 return streamInfoBuf;
3539 }
3540
3541 /*===========================================================================
3542 * FUNCTION : allocateStreamUserBuf
3543 *
3544 * DESCRIPTION: allocate user ptr for stream buffers
3545 *
3546 * PARAMETERS :
3547 * @streamInfo : stream info structure
3548 *
3549 * RETURN : ptr to a memory obj that holds stream info buffer.
3550 * NULL if failed
3551
3552 *==========================================================================*/
allocateStreamUserBuf(cam_stream_info_t * streamInfo)3553 QCameraMemory *QCamera2HardwareInterface::allocateStreamUserBuf(
3554 cam_stream_info_t *streamInfo)
3555 {
3556 int rc = NO_ERROR;
3557 QCameraMemory *mem = NULL;
3558 int size = 0;
3559
3560 if (streamInfo->streaming_mode != CAM_STREAMING_MODE_BATCH) {
3561 LOGE("Stream is not in BATCH mode. Invalid Stream");
3562 return NULL;
3563 }
3564
3565 // Allocate stream user buffer memory object
3566 switch (streamInfo->stream_type) {
3567 case CAM_STREAM_TYPE_VIDEO: {
3568 QCameraVideoMemory *video_mem = new QCameraVideoMemory(
3569 mGetMemory, mCallbackCookie, FALSE, QCAMERA_MEM_TYPE_BATCH);
3570 if (video_mem == NULL) {
3571 LOGE("Out of memory for video obj");
3572 return NULL;
3573 }
3574
3575 int usage = 0;
3576 cam_format_t fmt;
3577 mParameters.getStreamFormat(CAM_STREAM_TYPE_VIDEO, fmt);
3578 if(mParameters.isUBWCEnabled() && (fmt == CAM_FORMAT_YUV_420_NV12_UBWC)) {
3579 usage = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
3580 }
3581 video_mem->setVideoInfo(usage, fmt);
3582
3583 /*
3584 * numFDs = BATCH size
3585 * numInts = 5 // OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
3586 */
3587 rc = video_mem->allocateMeta(streamInfo->num_bufs,
3588 mParameters.getBufBatchCount());
3589 if (rc < 0) {
3590 LOGE("allocateMeta failed");
3591 delete video_mem;
3592 return NULL;
3593 }
3594 mem = static_cast<QCameraMemory *>(video_mem);
3595 }
3596 break;
3597
3598 case CAM_STREAM_TYPE_PREVIEW:
3599 case CAM_STREAM_TYPE_POSTVIEW:
3600 case CAM_STREAM_TYPE_ANALYSIS:
3601 case CAM_STREAM_TYPE_SNAPSHOT:
3602 case CAM_STREAM_TYPE_RAW:
3603 case CAM_STREAM_TYPE_METADATA:
3604 case CAM_STREAM_TYPE_OFFLINE_PROC:
3605 case CAM_STREAM_TYPE_CALLBACK:
3606 LOGE("Stream type Not supported.for BATCH processing");
3607 break;
3608
3609 case CAM_STREAM_TYPE_DEFAULT:
3610 case CAM_STREAM_TYPE_MAX:
3611 default:
3612 break;
3613 }
3614 if (!mem) {
3615 LOGE("Failed to allocate mem");
3616 return NULL;
3617 }
3618
3619 /*Size of this buffer will be number of batch buffer */
3620 size = PAD_TO_SIZE((streamInfo->num_bufs * streamInfo->user_buf_info.size),
3621 CAM_PAD_TO_4K);
3622
3623 LOGH("Allocating BATCH Buffer count = %d", streamInfo->num_bufs);
3624
3625 if (size > 0) {
3626 // Allocating one buffer for all batch buffers
3627 rc = mem->allocate(1, size);
3628 if (rc < 0) {
3629 delete mem;
3630 return NULL;
3631 }
3632 }
3633 return mem;
3634 }
3635
3636
3637 /*===========================================================================
3638 * FUNCTION : waitForDeferredAlloc
3639 *
3640 * DESCRIPTION: Wait for deferred allocation, if applicable
3641 * (applicable only for metadata buffers so far)
3642 *
3643 * PARAMETERS :
3644 * @stream_type : type of stream to (possibly) wait for
3645 *
3646 * RETURN : None
3647 *==========================================================================*/
waitForDeferredAlloc(cam_stream_type_t stream_type)3648 void QCamera2HardwareInterface::waitForDeferredAlloc(cam_stream_type_t stream_type)
3649 {
3650 if (stream_type == CAM_STREAM_TYPE_METADATA) {
3651 waitDeferredWork(mMetadataAllocJob);
3652 }
3653 }
3654
3655
3656 /*===========================================================================
3657 * FUNCTION : setPreviewWindow
3658 *
3659 * DESCRIPTION: set preview window impl
3660 *
3661 * PARAMETERS :
3662 * @window : ptr to window ops table struct
3663 *
3664 * RETURN : int32_t type of status
3665 * NO_ERROR -- success
3666 * none-zero failure code
3667 *==========================================================================*/
setPreviewWindow(struct preview_stream_ops * window)3668 int QCamera2HardwareInterface::setPreviewWindow(
3669 struct preview_stream_ops *window)
3670 {
3671 mPreviewWindow = window;
3672 return NO_ERROR;
3673 }
3674
3675 /*===========================================================================
3676 * FUNCTION : setCallBacks
3677 *
3678 * DESCRIPTION: set callbacks impl
3679 *
3680 * PARAMETERS :
3681 * @notify_cb : notify cb
3682 * @data_cb : data cb
3683 * @data_cb_timestamp : data cb with time stamp
3684 * @get_memory : request memory ops table
3685 * @user : user data ptr
3686 *
3687 * RETURN : int32_t type of status
3688 * NO_ERROR -- success
3689 * none-zero failure code
3690 *==========================================================================*/
setCallBacks(camera_notify_callback notify_cb,camera_data_callback data_cb,camera_data_timestamp_callback data_cb_timestamp,camera_request_memory get_memory,void * user)3691 int QCamera2HardwareInterface::setCallBacks(camera_notify_callback notify_cb,
3692 camera_data_callback data_cb,
3693 camera_data_timestamp_callback data_cb_timestamp,
3694 camera_request_memory get_memory,
3695 void *user)
3696 {
3697 mNotifyCb = notify_cb;
3698 mDataCb = data_cb;
3699 mDataCbTimestamp = data_cb_timestamp;
3700 mGetMemory = get_memory;
3701 mCallbackCookie = user;
3702 m_cbNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp, user);
3703 return NO_ERROR;
3704 }
3705
3706 /*===========================================================================
3707 * FUNCTION : setJpegCallBacks
3708 *
3709 * DESCRIPTION: set JPEG callbacks impl
3710 *
3711 * PARAMETERS :
3712 * @jpegCb : Jpeg callback method
3713 * @callbackCookie : callback cookie
3714 *
3715 * RETURN : int32_t type of status
3716 * NO_ERROR -- success
3717 * none-zero failure code
3718 *==========================================================================*/
setJpegCallBacks(jpeg_data_callback jpegCb,void * callbackCookie)3719 void QCamera2HardwareInterface::setJpegCallBacks(jpeg_data_callback jpegCb,
3720 void *callbackCookie)
3721 {
3722 LOGH("camera id %d", getCameraId());
3723 mJpegCb = jpegCb;
3724 mJpegCallbackCookie = callbackCookie;
3725 m_cbNotifier.setJpegCallBacks(mJpegCb, mJpegCallbackCookie);
3726 }
3727
3728 /*===========================================================================
3729 * FUNCTION : enableMsgType
3730 *
3731 * DESCRIPTION: enable msg type impl
3732 *
3733 * PARAMETERS :
3734 * @msg_type : msg type mask to be enabled
3735 *
3736 * RETURN : int32_t type of status
3737 * NO_ERROR -- success
3738 * none-zero failure code
3739 *==========================================================================*/
enableMsgType(int32_t msg_type)3740 int QCamera2HardwareInterface::enableMsgType(int32_t msg_type)
3741 {
3742 int32_t rc = NO_ERROR;
3743
3744 if (mParameters.isUBWCEnabled()) {
3745 /*Need Special CALLBACK stream incase application requesting for
3746 Preview callback in UBWC case*/
3747 if (!(msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) &&
3748 (msg_type & CAMERA_MSG_PREVIEW_FRAME)) {
3749 // Start callback channel only when preview/zsl channel is active
3750 QCameraChannel* previewCh = NULL;
3751 if (isZSLMode() && (getRecordingHintValue() != true)) {
3752 previewCh = m_channels[QCAMERA_CH_TYPE_ZSL];
3753 } else {
3754 previewCh = m_channels[QCAMERA_CH_TYPE_PREVIEW];
3755 }
3756 QCameraChannel* callbackCh = m_channels[QCAMERA_CH_TYPE_CALLBACK];
3757 if ((callbackCh != NULL) &&
3758 (previewCh != NULL) && previewCh->isActive()) {
3759 rc = startChannel(QCAMERA_CH_TYPE_CALLBACK);
3760 if (rc != NO_ERROR) {
3761 LOGE("START Callback Channel failed");
3762 }
3763 }
3764 }
3765 }
3766 mMsgEnabled |= msg_type;
3767 LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc);
3768 return rc;
3769 }
3770
3771 /*===========================================================================
3772 * FUNCTION : disableMsgType
3773 *
3774 * DESCRIPTION: disable msg type impl
3775 *
3776 * PARAMETERS :
3777 * @msg_type : msg type mask to be disabled
3778 *
3779 * RETURN : int32_t type of status
3780 * NO_ERROR -- success
3781 * none-zero failure code
3782 *==========================================================================*/
disableMsgType(int32_t msg_type)3783 int QCamera2HardwareInterface::disableMsgType(int32_t msg_type)
3784 {
3785 int32_t rc = NO_ERROR;
3786
3787 if (mParameters.isUBWCEnabled()) {
3788 /*STOP CALLBACK STREAM*/
3789 if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) &&
3790 (msg_type & CAMERA_MSG_PREVIEW_FRAME)) {
3791 // Stop callback channel only if it is active
3792 if ((m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) &&
3793 (m_channels[QCAMERA_CH_TYPE_CALLBACK]->isActive())) {
3794 rc = stopChannel(QCAMERA_CH_TYPE_CALLBACK);
3795 if (rc != NO_ERROR) {
3796 LOGE("STOP Callback Channel failed");
3797 }
3798 }
3799 }
3800 }
3801 mMsgEnabled &= ~msg_type;
3802 LOGH("(0x%x) : mMsgEnabled = 0x%x rc = %d", msg_type , mMsgEnabled, rc);
3803 return rc;
3804 }
3805
3806 /*===========================================================================
3807 * FUNCTION : msgTypeEnabled
3808 *
3809 * DESCRIPTION: impl to determine if certain msg_type is enabled
3810 *
3811 * PARAMETERS :
3812 * @msg_type : msg type mask
3813 *
3814 * RETURN : 0 -- not enabled
3815 * none 0 -- enabled
3816 *==========================================================================*/
msgTypeEnabled(int32_t msg_type)3817 int QCamera2HardwareInterface::msgTypeEnabled(int32_t msg_type)
3818 {
3819 return (mMsgEnabled & msg_type);
3820 }
3821
3822 /*===========================================================================
3823 * FUNCTION : msgTypeEnabledWithLock
3824 *
3825 * DESCRIPTION: impl to determine if certain msg_type is enabled with lock
3826 *
3827 * PARAMETERS :
3828 * @msg_type : msg type mask
3829 *
3830 * RETURN : 0 -- not enabled
3831 * none 0 -- enabled
3832 *==========================================================================*/
msgTypeEnabledWithLock(int32_t msg_type)3833 int QCamera2HardwareInterface::msgTypeEnabledWithLock(int32_t msg_type)
3834 {
3835 int enabled = 0;
3836 lockAPI();
3837 enabled = mMsgEnabled & msg_type;
3838 unlockAPI();
3839 return enabled;
3840 }
3841
3842 /*===========================================================================
3843 * FUNCTION : startPreview
3844 *
3845 * DESCRIPTION: start preview impl
3846 *
3847 * PARAMETERS : none
3848 *
3849 * RETURN : int32_t type of status
3850 * NO_ERROR -- success
3851 * none-zero failure code
3852 *==========================================================================*/
startPreview()3853 int QCamera2HardwareInterface::startPreview()
3854 {
3855 KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STARTPREVIEW);
3856 int32_t rc = NO_ERROR;
3857
3858 LOGI("E ZSL = %d Recording Hint = %d", mParameters.isZSLMode(),
3859 mParameters.getRecordingHintValue());
3860
3861 m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_PREVIEW);
3862
3863 updateThermalLevel((void *)&mThermalLevel);
3864
3865 setDisplayFrameSkip();
3866
3867 // start preview stream
3868 if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
3869 rc = startChannel(QCAMERA_CH_TYPE_ZSL);
3870 } else if (isSecureMode()) {
3871 if (mParameters.getSecureStreamType() == CAM_STREAM_TYPE_RAW) {
3872 rc = startChannel(QCAMERA_CH_TYPE_RAW);
3873 }else {
3874 rc = startChannel(QCAMERA_CH_TYPE_PREVIEW);
3875 }
3876 } else {
3877 rc = startChannel(QCAMERA_CH_TYPE_PREVIEW);
3878 }
3879
3880 if (isDualCamera()) {
3881 if (rc == NO_ERROR) {
3882 mParameters.setDeferCamera(CAM_DEFER_PROCESS);
3883 } else {
3884 mParameters.setDeferCamera(CAM_DEFER_FLUSH);
3885 }
3886 }
3887
3888 if (rc != NO_ERROR) {
3889 LOGE("failed to start channels");
3890 m_perfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW);
3891 return rc;
3892 }
3893
3894 if ((msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME))
3895 && (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL)) {
3896 rc = startChannel(QCAMERA_CH_TYPE_CALLBACK);
3897 if (rc != NO_ERROR) {
3898 LOGE("failed to start callback stream");
3899 stopChannel(QCAMERA_CH_TYPE_ZSL);
3900 stopChannel(QCAMERA_CH_TYPE_PREVIEW);
3901 m_perfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW);
3902 return rc;
3903 }
3904 }
3905
3906 updatePostPreviewParameters();
3907 m_stateMachine.setPreviewCallbackNeeded(true);
3908
3909 // if job id is non-zero, that means the postproc init job is already
3910 // pending or complete
3911 if (mInitPProcJob == 0) {
3912 mInitPProcJob = deferPPInit();
3913 if (mInitPProcJob == 0) {
3914 LOGE("Unable to initialize postprocessor, mCameraHandle = %p",
3915 mCameraHandle);
3916 rc = -ENOMEM;
3917 m_perfLockMgr.releasePerfLock(PERF_LOCK_START_PREVIEW);
3918 return rc;
3919 }
3920 }
3921
3922 LOGI("X rc = %d", rc);
3923 return rc;
3924 }
3925
updatePostPreviewParameters()3926 int32_t QCamera2HardwareInterface::updatePostPreviewParameters() {
3927 // Enable OIS only in Camera mode and 4k2k camcoder mode
3928 int32_t rc = NO_ERROR;
3929 rc = mParameters.updateOisValue(1);
3930 return NO_ERROR;
3931 }
3932
3933 /*===========================================================================
3934 * FUNCTION : stopPreview
3935 *
3936 * DESCRIPTION: stop preview impl
3937 *
3938 * PARAMETERS : none
3939 *
3940 * RETURN : int32_t type of status
3941 * NO_ERROR -- success
3942 * none-zero failure code
3943 *==========================================================================*/
stopPreview()3944 int QCamera2HardwareInterface::stopPreview()
3945 {
3946 KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_STOPPREVIEW);
3947 LOGI("E");
3948 mNumPreviewFaces = -1;
3949 mActiveAF = false;
3950
3951 // Disable power Hint for preview
3952 m_perfLockMgr.releasePerfLock(PERF_LOCK_POWERHINT_PREVIEW);
3953
3954 m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_PREVIEW);
3955
3956 // stop preview stream
3957 stopChannel(QCAMERA_CH_TYPE_CALLBACK);
3958 stopChannel(QCAMERA_CH_TYPE_ZSL);
3959 stopChannel(QCAMERA_CH_TYPE_PREVIEW);
3960 stopChannel(QCAMERA_CH_TYPE_RAW);
3961
3962 m_cbNotifier.flushPreviewNotifications();
3963 //add for ts makeup
3964 #ifdef TARGET_TS_MAKEUP
3965 ts_makeup_finish();
3966 #endif
3967 // delete all channels from preparePreview
3968 unpreparePreview();
3969
3970 m_perfLockMgr.releasePerfLock(PERF_LOCK_STOP_PREVIEW);
3971 LOGI("X");
3972 return NO_ERROR;
3973 }
3974
3975 /*===========================================================================
3976 * FUNCTION : storeMetaDataInBuffers
3977 *
3978 * DESCRIPTION: enable store meta data in buffers for video frames impl
3979 *
3980 * PARAMETERS :
3981 * @enable : flag if need enable
3982 *
3983 * RETURN : int32_t type of status
3984 * NO_ERROR -- success
3985 * none-zero failure code
3986 *==========================================================================*/
storeMetaDataInBuffers(int enable)3987 int QCamera2HardwareInterface::storeMetaDataInBuffers(int enable)
3988 {
3989 mStoreMetaDataInFrame = enable;
3990 return NO_ERROR;
3991 }
3992
3993 /*===========================================================================
3994 * FUNCTION : preStartRecording
3995 *
3996 * DESCRIPTION: Prepare start recording impl
3997 *
3998 * PARAMETERS : none
3999 *
4000 * RETURN : int32_t type of status
4001 * NO_ERROR -- success
4002 * none-zero failure code
4003 *==========================================================================*/
preStartRecording()4004 int QCamera2HardwareInterface::preStartRecording()
4005 {
4006 int32_t rc = NO_ERROR;
4007 LOGH("E");
4008 if (mParameters.getRecordingHintValue() == false) {
4009
4010 // Give HWI control to restart preview only in single camera mode.
4011 // In dual-cam mode, this control belongs to muxer.
4012 if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
4013 LOGH("start recording when hint is false, stop preview first");
4014 stopPreview();
4015
4016 // Set recording hint to TRUE
4017 mParameters.updateRecordingHintValue(TRUE);
4018 rc = preparePreview();
4019 if (rc == NO_ERROR) {
4020 rc = startPreview();
4021 }
4022 }
4023 else
4024 {
4025 // For dual cam mode, update the flag mPreviewRestartNeeded to true
4026 // Restart control will be handled by muxer.
4027 mPreviewRestartNeeded = true;
4028 }
4029 }
4030
4031 LOGH("X rc = %d", rc);
4032 return rc;
4033 }
4034
4035 /*===========================================================================
4036 * FUNCTION : startRecording
4037 *
4038 * DESCRIPTION: start recording impl
4039 *
4040 * PARAMETERS : none
4041 *
4042 * RETURN : int32_t type of status
4043 * NO_ERROR -- success
4044 * none-zero failure code
4045 *==========================================================================*/
startRecording()4046 int QCamera2HardwareInterface::startRecording()
4047 {
4048 int32_t rc = NO_ERROR;
4049
4050 LOGI("E");
4051
4052 m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_START_RECORDING);
4053
4054 //link meta stream with video channel if low power mode.
4055 if (isLowPowerMode()) {
4056 // Find and try to link a metadata stream from preview channel
4057 QCameraChannel *pMetaChannel = NULL;
4058 QCameraStream *pMetaStream = NULL;
4059 QCameraChannel *pVideoChannel = m_channels[QCAMERA_CH_TYPE_VIDEO];
4060
4061 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
4062 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
4063 uint32_t streamNum = pMetaChannel->getNumOfStreams();
4064 QCameraStream *pStream = NULL;
4065 for (uint32_t i = 0 ; i < streamNum ; i++ ) {
4066 pStream = pMetaChannel->getStreamByIndex(i);
4067 if ((NULL != pStream) &&
4068 (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) {
4069 pMetaStream = pStream;
4070 break;
4071 }
4072 }
4073 }
4074
4075 if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
4076 rc = pVideoChannel->linkStream(pMetaChannel, pMetaStream);
4077 if (NO_ERROR != rc) {
4078 LOGW("Metadata stream link failed %d", rc);
4079 }
4080 }
4081 }
4082
4083 if (rc == NO_ERROR) {
4084 rc = startChannel(QCAMERA_CH_TYPE_VIDEO);
4085 }
4086
4087 if (mParameters.isTNRSnapshotEnabled() && !isLowPowerMode()) {
4088 QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
4089 if (!mParameters.is4k2kVideoResolution()) {
4090 // Find and try to link a metadata stream from preview channel
4091 QCameraChannel *pMetaChannel = NULL;
4092 QCameraStream *pMetaStream = NULL;
4093
4094 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
4095 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
4096 uint32_t streamNum = pMetaChannel->getNumOfStreams();
4097 QCameraStream *pStream = NULL;
4098 for (uint32_t i = 0 ; i < streamNum ; i++ ) {
4099 pStream = pMetaChannel->getStreamByIndex(i);
4100 if ((NULL != pStream) &&
4101 (CAM_STREAM_TYPE_METADATA ==
4102 pStream->getMyType())) {
4103 pMetaStream = pStream;
4104 break;
4105 }
4106 }
4107 }
4108
4109 if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
4110 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
4111 if (NO_ERROR != rc) {
4112 LOGW("Metadata stream link failed %d", rc);
4113 }
4114 }
4115 }
4116 LOGH("START snapshot Channel for TNR processing");
4117 rc = pChannel->start();
4118 }
4119
4120 m_perfLockMgr.releasePerfLock(PERF_LOCK_START_RECORDING);
4121
4122 if (rc == NO_ERROR) {
4123 // Set power Hint for video encoding
4124 m_perfLockMgr.acquirePerfLock(PERF_LOCK_POWERHINT_ENCODE, 0);
4125 }
4126
4127 LOGI("X rc = %d", rc);
4128 return rc;
4129 }
4130
4131 /*===========================================================================
4132 * FUNCTION : stopRecording
4133 *
4134 * DESCRIPTION: stop recording impl
4135 *
4136 * PARAMETERS : none
4137 *
4138 * RETURN : int32_t type of status
4139 * NO_ERROR -- success
4140 * none-zero failure code
4141 *==========================================================================*/
stopRecording()4142 int QCamera2HardwareInterface::stopRecording()
4143 {
4144 LOGI("E");
4145
4146 // Disable power hint for video encoding
4147 m_perfLockMgr.releasePerfLock(PERF_LOCK_POWERHINT_ENCODE);
4148
4149 m_perfLockMgr.acquirePerfLockIfExpired(PERF_LOCK_STOP_RECORDING);
4150
4151 // stop snapshot channel
4152 if (mParameters.isTNRSnapshotEnabled()) {
4153 LOGH("STOP snapshot Channel for TNR processing");
4154 stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
4155 }
4156 int rc = stopChannel(QCAMERA_CH_TYPE_VIDEO);
4157
4158 m_cbNotifier.flushVideoNotifications();
4159
4160 m_perfLockMgr.releasePerfLock(PERF_LOCK_STOP_RECORDING);
4161
4162 LOGI("X rc = %d", rc);
4163 return rc;
4164 }
4165
4166 /*===========================================================================
4167 * FUNCTION : releaseRecordingFrame
4168 *
4169 * DESCRIPTION: return video frame impl
4170 *
4171 * PARAMETERS :
4172 * @opaque : ptr to video frame to be returned
4173 *
4174 * RETURN : int32_t type of status
4175 * NO_ERROR -- success
4176 * none-zero failure code
4177 *==========================================================================*/
releaseRecordingFrame(const void * opaque)4178 int QCamera2HardwareInterface::releaseRecordingFrame(const void * opaque)
4179 {
4180 int32_t rc = UNKNOWN_ERROR;
4181 QCameraVideoChannel *pChannel =
4182 (QCameraVideoChannel *)m_channels[QCAMERA_CH_TYPE_VIDEO];
4183 LOGD("opaque data = %p",opaque);
4184
4185 if(pChannel != NULL) {
4186 rc = pChannel->releaseFrame(opaque, mStoreMetaDataInFrame > 0);
4187 }
4188 return rc;
4189 }
4190
4191 /*===========================================================================
4192 * FUNCTION : autoFocus
4193 *
4194 * DESCRIPTION: start auto focus impl
4195 *
4196 * PARAMETERS : none
4197 *
4198 * RETURN : int32_t type of status
4199 * NO_ERROR -- success
4200 * none-zero failure code
4201 *==========================================================================*/
autoFocus()4202 int QCamera2HardwareInterface::autoFocus()
4203 {
4204 int rc = NO_ERROR;
4205 cam_focus_mode_type focusMode = mParameters.getFocusMode();
4206 LOGH("E");
4207
4208 switch (focusMode) {
4209 case CAM_FOCUS_MODE_AUTO:
4210 case CAM_FOCUS_MODE_MACRO:
4211 case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
4212 case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
4213 mActiveAF = true;
4214 LOGI("Send AUTO FOCUS event. focusMode=%d, m_currentFocusState=%d",
4215 focusMode, m_currentFocusState);
4216 rc = mCameraHandle->ops->do_auto_focus(mCameraHandle->camera_handle);
4217 break;
4218 case CAM_FOCUS_MODE_INFINITY:
4219 case CAM_FOCUS_MODE_FIXED:
4220 case CAM_FOCUS_MODE_EDOF:
4221 default:
4222 LOGI("No ops in focusMode (%d)", focusMode);
4223 rc = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0);
4224 break;
4225 }
4226
4227 if (NO_ERROR != rc) {
4228 mActiveAF = false;
4229 }
4230 LOGH("X rc = %d", rc);
4231 return rc;
4232 }
4233
4234 /*===========================================================================
4235 * FUNCTION : cancelAutoFocus
4236 *
4237 * DESCRIPTION: cancel auto focus impl
4238 *
4239 * PARAMETERS : none
4240 *
4241 * RETURN : int32_t type of status
4242 * NO_ERROR -- success
4243 * none-zero failure code
4244 *==========================================================================*/
cancelAutoFocus()4245 int QCamera2HardwareInterface::cancelAutoFocus()
4246 {
4247 int rc = NO_ERROR;
4248 cam_focus_mode_type focusMode = mParameters.getFocusMode();
4249
4250 switch (focusMode) {
4251 case CAM_FOCUS_MODE_AUTO:
4252 case CAM_FOCUS_MODE_MACRO:
4253 case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
4254 case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
4255 mActiveAF = false;
4256 rc = mCameraHandle->ops->cancel_auto_focus(mCameraHandle->camera_handle);
4257 break;
4258 case CAM_FOCUS_MODE_INFINITY:
4259 case CAM_FOCUS_MODE_FIXED:
4260 case CAM_FOCUS_MODE_EDOF:
4261 default:
4262 LOGD("No ops in focusMode (%d)", focusMode);
4263 break;
4264 }
4265 return rc;
4266 }
4267
4268 /*===========================================================================
4269 * FUNCTION : processUFDumps
4270 *
4271 * DESCRIPTION: process UF jpeg dumps for refocus support
4272 *
4273 * PARAMETERS :
4274 * @evt : payload of jpeg event, including information about jpeg encoding
4275 * status, jpeg size and so on.
4276 *
4277 * RETURN : int32_t type of status
4278 * NO_ERROR -- success
4279 * none-zero failure code
4280 *
4281 * NOTE : none
4282 *==========================================================================*/
processUFDumps(qcamera_jpeg_evt_payload_t * evt)4283 bool QCamera2HardwareInterface::processUFDumps(qcamera_jpeg_evt_payload_t *evt)
4284 {
4285 bool ret = true;
4286 if (mParameters.isUbiRefocus()) {
4287 int index = (int)getOutputImageCount();
4288 bool allFocusImage = (index == ((int)mParameters.getRefocusOutputCount() - 1));
4289 char name[FILENAME_MAX];
4290
4291 camera_memory_t *jpeg_mem = NULL;
4292 omx_jpeg_ouput_buf_t *jpeg_out = NULL;
4293 size_t dataLen;
4294 uint8_t *dataPtr;
4295 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
4296 LOGE("Init PProc Deferred work failed");
4297 return false;
4298 }
4299 if (!m_postprocessor.getJpegMemOpt()) {
4300 dataLen = evt->out_data.buf_filled_len;
4301 dataPtr = evt->out_data.buf_vaddr;
4302 } else {
4303 jpeg_out = (omx_jpeg_ouput_buf_t*) evt->out_data.buf_vaddr;
4304 if (!jpeg_out) {
4305 LOGE("Null pointer detected");
4306 return false;
4307 }
4308 jpeg_mem = (camera_memory_t *)jpeg_out->mem_hdl;
4309 if (!jpeg_mem) {
4310 LOGE("Null pointer detected");
4311 return false;
4312 }
4313 dataPtr = (uint8_t *)jpeg_mem->data;
4314 dataLen = jpeg_mem->size;
4315 }
4316
4317 if (allFocusImage) {
4318 snprintf(name, sizeof(name), "AllFocusImage");
4319 index = -1;
4320 } else {
4321 snprintf(name, sizeof(name), "%d", 0);
4322 }
4323 CAM_DUMP_TO_FILE(QCAMERA_DUMP_FRM_LOCATION"ubifocus", name, index, "jpg",
4324 dataPtr, dataLen);
4325 LOGD("Dump the image %d %d allFocusImage %d",
4326 getOutputImageCount(), index, allFocusImage);
4327 setOutputImageCount(getOutputImageCount() + 1);
4328 if (!allFocusImage) {
4329 ret = false;
4330 }
4331 }
4332 return ret;
4333 }
4334
4335 /*===========================================================================
4336 * FUNCTION : unconfigureAdvancedCapture
4337 *
4338 * DESCRIPTION: unconfigure Advanced Capture.
4339 *
4340 * PARAMETERS : none
4341 *
4342 * RETURN : int32_t type of status
4343 * NO_ERROR -- success
4344 * none-zero failure code
4345 *==========================================================================*/
unconfigureAdvancedCapture()4346 int32_t QCamera2HardwareInterface::unconfigureAdvancedCapture()
4347 {
4348 int32_t rc = NO_ERROR;
4349
4350 /*Disable Quadra CFA mode*/
4351 LOGH("Disabling Quadra CFA mode");
4352 mParameters.setQuadraCfaMode(false, true);
4353
4354 if (mAdvancedCaptureConfigured) {
4355
4356 mAdvancedCaptureConfigured = false;
4357
4358 if(mIs3ALocked) {
4359 mParameters.set3ALock(false);
4360 mIs3ALocked = false;
4361 }
4362 if (mParameters.isHDREnabled() || mParameters.isAEBracketEnabled()) {
4363 rc = mParameters.setToneMapMode(true, true);
4364 if (rc != NO_ERROR) {
4365 LOGW("Failed to enable tone map during HDR/AEBracketing");
4366 }
4367 mHDRBracketingEnabled = false;
4368 rc = mParameters.stopAEBracket();
4369 } else if ((mParameters.isChromaFlashEnabled())
4370 || (mFlashConfigured && !mLongshotEnabled)
4371 || (mLowLightConfigured == true)
4372 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
4373 rc = mParameters.resetFrameCapture(TRUE, mLowLightConfigured);
4374 } else if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
4375 rc = configureAFBracketing(false);
4376 } else if (mParameters.isOptiZoomEnabled()) {
4377 rc = mParameters.setAndCommitZoom(mZoomLevel);
4378 setDisplaySkip(FALSE, CAMERA_MAX_PARAM_APPLY_DELAY);
4379 } else if (mParameters.isStillMoreEnabled()) {
4380 cam_still_more_t stillmore_config = mParameters.getStillMoreSettings();
4381 stillmore_config.burst_count = 0;
4382 mParameters.setStillMoreSettings(stillmore_config);
4383
4384 /* If SeeMore is running, it will handle re-enabling tone map */
4385 if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) {
4386 rc = mParameters.setToneMapMode(true, true);
4387 if (rc != NO_ERROR) {
4388 LOGW("Failed to enable tone map during StillMore");
4389 }
4390 }
4391
4392 /* Re-enable Tintless */
4393 mParameters.setTintless(true);
4394 } else {
4395 LOGW("No Advanced Capture feature enabled!!");
4396 rc = BAD_VALUE;
4397 }
4398 }
4399
4400 return rc;
4401 }
4402
4403 /*===========================================================================
4404 * FUNCTION : configureAdvancedCapture
4405 *
4406 * DESCRIPTION: configure Advanced Capture.
4407 *
4408 * PARAMETERS : none
4409 *
4410 * RETURN : int32_t type of status
4411 * NO_ERROR -- success
4412 * none-zero failure code
4413 *==========================================================================*/
configureAdvancedCapture()4414 int32_t QCamera2HardwareInterface::configureAdvancedCapture()
4415 {
4416 LOGH("E");
4417 int32_t rc = NO_ERROR;
4418
4419 rc = mParameters.checkFeatureConcurrency();
4420 if (rc != NO_ERROR) {
4421 LOGE("Cannot support Advanced capture modes");
4422 return rc;
4423 }
4424 /*Enable Quadra CFA mode*/
4425 LOGH("Enabling Quadra CFA mode");
4426 mParameters.setQuadraCfaMode(true, true);
4427
4428 setOutputImageCount(0);
4429 mInputCount = 0;
4430 mAdvancedCaptureConfigured = true;
4431 /* Display should be disabled for advanced modes */
4432 bool bSkipDisplay = true;
4433
4434 if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) {
4435 // no Advance capture settings for Aux camera
4436 LOGH("X Secondary Camera, no need to process!! ");
4437 return rc;
4438 }
4439
4440 /* Do not stop display if in stillmore livesnapshot */
4441 if (mParameters.isStillMoreEnabled() &&
4442 mParameters.isSeeMoreEnabled()) {
4443 bSkipDisplay = false;
4444 }
4445 if (mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
4446 rc = configureAFBracketing();
4447 } else if (mParameters.isOptiZoomEnabled()) {
4448 rc = configureOptiZoom();
4449 } else if(mParameters.isHDREnabled()) {
4450 rc = configureHDRBracketing();
4451 if (mHDRBracketingEnabled) {
4452 rc = mParameters.setToneMapMode(false, true);
4453 if (rc != NO_ERROR) {
4454 LOGW("Failed to disable tone map during HDR");
4455 }
4456 }
4457 } else if (mParameters.isAEBracketEnabled()) {
4458 rc = mParameters.setToneMapMode(false, true);
4459 if (rc != NO_ERROR) {
4460 LOGW("Failed to disable tone map during AEBracketing");
4461 }
4462 rc = configureAEBracketing();
4463 } else if (mParameters.isStillMoreEnabled()) {
4464 bSkipDisplay = false;
4465 rc = configureStillMore();
4466 } else if ((mParameters.isChromaFlashEnabled())
4467 || (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF)
4468 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
4469 rc = mParameters.configFrameCapture(TRUE);
4470 if (mParameters.getLowLightLevel() != CAM_LOW_LIGHT_OFF) {
4471 mLowLightConfigured = true;
4472 }
4473 } else if (mFlashNeeded && !mLongshotEnabled) {
4474 rc = mParameters.configFrameCapture(TRUE);
4475 mFlashConfigured = true;
4476 bSkipDisplay = false;
4477 } else {
4478 LOGH("Advanced Capture feature not enabled!! ");
4479 mAdvancedCaptureConfigured = false;
4480 bSkipDisplay = false;
4481 }
4482
4483 if (m_postprocessor.isHalPPEnabled()) {
4484 LOGH("HALPP is enabled, check if halpp is needed for current snapshot.");
4485 configureHalPostProcess();
4486 }
4487
4488 LOGH("Stop preview temporarily for advanced captures");
4489 setDisplaySkip(bSkipDisplay);
4490
4491 LOGH("X rc = %d", rc);
4492 return rc;
4493 }
4494
4495 /*===========================================================================
4496 * FUNCTION : configureAFBracketing
4497 *
4498 * DESCRIPTION: configure AF Bracketing.
4499 *
4500 * PARAMETERS : none
4501 *
4502 * RETURN : int32_t type of status
4503 * NO_ERROR -- success
4504 * none-zero failure code
4505 *==========================================================================*/
configureAFBracketing(bool enable)4506 int32_t QCamera2HardwareInterface::configureAFBracketing(bool enable)
4507 {
4508 LOGH("E");
4509 int32_t rc = NO_ERROR;
4510 cam_af_bracketing_t *af_bracketing_need;
4511
4512 if (mParameters.isUbiRefocus()) {
4513 af_bracketing_need =
4514 &gCamCapability[mCameraId]->refocus_af_bracketing_need;
4515 } else {
4516 af_bracketing_need =
4517 &gCamCapability[mCameraId]->ubifocus_af_bracketing_need;
4518 }
4519
4520 //Enable AF Bracketing.
4521 cam_af_bracketing_t afBracket;
4522 memset(&afBracket, 0, sizeof(cam_af_bracketing_t));
4523 afBracket.enable = enable;
4524 afBracket.burst_count = af_bracketing_need->burst_count;
4525
4526 for(int8_t i = 0; i < MAX_AF_BRACKETING_VALUES; i++) {
4527 afBracket.focus_steps[i] = af_bracketing_need->focus_steps[i];
4528 LOGH("focus_step[%d] = %d", i, afBracket.focus_steps[i]);
4529 }
4530 //Send cmd to backend to set AF Bracketing for Ubi Focus.
4531 rc = mParameters.commitAFBracket(afBracket);
4532 if ( NO_ERROR != rc ) {
4533 LOGE("cannot configure AF bracketing");
4534 return rc;
4535 }
4536 if (enable) {
4537 mParameters.set3ALock(true);
4538 mIs3ALocked = true;
4539 }
4540 LOGH("X rc = %d", rc);
4541 return rc;
4542 }
4543
4544 /*===========================================================================
4545 * FUNCTION : configureHDRBracketing
4546 *
4547 * DESCRIPTION: configure HDR Bracketing.
4548 *
4549 * PARAMETERS : none
4550 *
4551 * RETURN : int32_t type of status
4552 * NO_ERROR -- success
4553 * none-zero failure code
4554 *==========================================================================*/
configureHDRBracketing()4555 int32_t QCamera2HardwareInterface::configureHDRBracketing()
4556 {
4557 LOGH("E");
4558 int32_t rc = NO_ERROR;
4559
4560 cam_hdr_bracketing_info_t& hdrBracketingSetting =
4561 gCamCapability[mCameraId]->hdr_bracketing_setting;
4562
4563 // 'values' should be in "idx1,idx2,idx3,..." format
4564 uint32_t hdrFrameCount =
4565 hdrBracketingSetting.num_frames;
4566 LOGH("HDR values %d, %d frame count: %u",
4567 (int8_t) hdrBracketingSetting.exp_val.values[0],
4568 (int8_t) hdrBracketingSetting.exp_val.values[1],
4569 hdrFrameCount);
4570
4571 // Enable AE Bracketing for HDR
4572 cam_exp_bracketing_t aeBracket;
4573 memset(&aeBracket, 0, sizeof(cam_exp_bracketing_t));
4574 aeBracket.mode =
4575 hdrBracketingSetting.exp_val.mode;
4576
4577 if (aeBracket.mode == CAM_EXP_BRACKETING_ON) {
4578 mHDRBracketingEnabled = true;
4579 }
4580
4581 String8 tmp;
4582 for (uint32_t i = 0; i < hdrFrameCount; i++) {
4583 tmp.appendFormat("%d",
4584 (int8_t) hdrBracketingSetting.exp_val.values[i]);
4585 tmp.append(",");
4586 }
4587 if (mParameters.isHDR1xFrameEnabled()
4588 && mParameters.isHDR1xExtraBufferNeeded()) {
4589 tmp.appendFormat("%d", 0);
4590 tmp.append(",");
4591 }
4592
4593 if( !tmp.isEmpty() &&
4594 ( MAX_EXP_BRACKETING_LENGTH > tmp.length() ) ) {
4595 //Trim last comma
4596 memset(aeBracket.values, '\0', MAX_EXP_BRACKETING_LENGTH);
4597 memcpy(aeBracket.values, tmp.string(), tmp.length() - 1);
4598 }
4599
4600 LOGH("HDR config values %s",
4601 aeBracket.values);
4602 rc = mParameters.setHDRAEBracket(aeBracket);
4603 if ( NO_ERROR != rc ) {
4604 LOGE("cannot configure HDR bracketing");
4605 return rc;
4606 }
4607 LOGH("X rc = %d", rc);
4608 return rc;
4609 }
4610
4611 /*===========================================================================
4612 * FUNCTION : configureAEBracketing
4613 *
4614 * DESCRIPTION: configure AE Bracketing.
4615 *
4616 * PARAMETERS : none
4617 *
4618 * RETURN : int32_t type of status
4619 * NO_ERROR -- success
4620 * none-zero failure code
4621 *==========================================================================*/
configureAEBracketing()4622 int32_t QCamera2HardwareInterface::configureAEBracketing()
4623 {
4624 LOGH("E");
4625 int32_t rc = NO_ERROR;
4626
4627 rc = mParameters.setAEBracketing();
4628 if ( NO_ERROR != rc ) {
4629 LOGE("cannot configure AE bracketing");
4630 return rc;
4631 }
4632 LOGH("X rc = %d", rc);
4633 return rc;
4634 }
4635
4636 /*===========================================================================
4637 * FUNCTION : configureOptiZoom
4638 *
4639 * DESCRIPTION: configure Opti Zoom.
4640 *
4641 * PARAMETERS : none
4642 *
4643 * RETURN : int32_t type of status
4644 * NO_ERROR -- success
4645 * none-zero failure code
4646 *==========================================================================*/
configureOptiZoom()4647 int32_t QCamera2HardwareInterface::configureOptiZoom()
4648 {
4649 int32_t rc = NO_ERROR;
4650
4651 //store current zoom level.
4652 mZoomLevel = mParameters.getParmZoomLevel();
4653
4654 //set zoom level to 1x;
4655 mParameters.setAndCommitZoom(0);
4656
4657 mParameters.set3ALock(true);
4658 mIs3ALocked = true;
4659
4660 return rc;
4661 }
4662
4663 /*===========================================================================
4664 * FUNCTION : configureStillMore
4665 *
4666 * DESCRIPTION: configure StillMore.
4667 *
4668 * PARAMETERS : none
4669 *
4670 * RETURN : int32_t type of status
4671 * NO_ERROR -- success
4672 * none-zero failure code
4673 *==========================================================================*/
configureStillMore()4674 int32_t QCamera2HardwareInterface::configureStillMore()
4675 {
4676 int32_t rc = NO_ERROR;
4677 uint8_t burst_cnt = 0;
4678 cam_still_more_t stillmore_config;
4679 cam_still_more_t stillmore_cap;
4680
4681 /* Disable Tone Map. If seemore is enabled, it will handle disabling it. */
4682 if (!mParameters.isSeeMoreEnabled() && !mParameters.isLTMForSeeMoreEnabled()) {
4683 rc = mParameters.setToneMapMode(false, true);
4684 if (rc != NO_ERROR) {
4685 LOGW("Failed to disable tone map during StillMore");
4686 }
4687 }
4688
4689 /* Lock 3A */
4690 mParameters.set3ALock(true);
4691 mIs3ALocked = true;
4692
4693 /* Disable Tintless */
4694 mParameters.setTintless(false);
4695
4696 /* Initialize burst count from capability */
4697 stillmore_cap = mParameters.getStillMoreCapability();
4698 burst_cnt = stillmore_cap.max_burst_count;
4699
4700 /* Reconfigure burst count from dynamic scene data */
4701 cam_dyn_img_data_t dynamic_img_data = mParameters.getDynamicImgData();
4702 if (dynamic_img_data.input_count >= stillmore_cap.min_burst_count &&
4703 dynamic_img_data.input_count <= stillmore_cap.max_burst_count) {
4704 burst_cnt = dynamic_img_data.input_count;
4705 }
4706
4707 /* Reconfigure burst count in the case of liveshot */
4708 if (mParameters.isSeeMoreEnabled()) {
4709 burst_cnt = 1;
4710 }
4711
4712 /* Reconfigure burst count from user input */
4713 char prop[PROPERTY_VALUE_MAX];
4714 property_get("persist.camera.imglib.stillmore", prop, "0");
4715 uint8_t burst_setprop = (uint32_t)atoi(prop);
4716 if (burst_setprop != 0) {
4717 if ((burst_setprop < stillmore_cap.min_burst_count) ||
4718 (burst_setprop > stillmore_cap.max_burst_count)) {
4719 burst_cnt = stillmore_cap.max_burst_count;
4720 } else {
4721 burst_cnt = burst_setprop;
4722 }
4723 }
4724
4725 memset(&stillmore_config, 0, sizeof(cam_still_more_t));
4726 stillmore_config.burst_count = burst_cnt;
4727 mParameters.setStillMoreSettings(stillmore_config);
4728
4729 LOGH("Stillmore burst %d", burst_cnt);
4730
4731 return rc;
4732 }
4733
4734 /*===========================================================================
4735 * FUNCTION : configureHalPostProcess
4736 *
4737 * DESCRIPTION: config hal postproc (HALPP) for current snapshot.
4738 *
4739 * PARAMETERS : none
4740 *
4741 * RETURN : int32_t type of status
4742 * NO_ERROR -- success
4743 * none-zero failure code
4744 *==========================================================================*/
configureHalPostProcess()4745 int32_t QCamera2HardwareInterface::configureHalPostProcess()
4746 {
4747 LOGD("E");
4748 int32_t rc = NO_ERROR;
4749
4750 if (!m_postprocessor.isHalPPEnabled()) {
4751 m_bNeedHalPP = FALSE;
4752 return rc;
4753 }
4754
4755 /* check if halpp is needed in dual camera mode */
4756 if (isDualCamera()) {
4757 if (mActiveCameras == MM_CAMERA_DUAL_CAM && mBundledSnapshot == TRUE) {
4758 LOGH("Use HALPP for dual camera bundle snapshot.");
4759 m_bNeedHalPP = TRUE;
4760 }
4761 return rc;
4762 }
4763
4764 return rc;
4765 LOGD("X");
4766 }
4767
4768
4769 /*===========================================================================
4770 * FUNCTION : stopAdvancedCapture
4771 *
4772 * DESCRIPTION: stops advanced capture based on capture type
4773 *
4774 * PARAMETERS :
4775 * @pChannel : channel.
4776 *
4777 * RETURN : int32_t type of status
4778 * NO_ERROR -- success
4779 * none-zero failure code
4780 *==========================================================================*/
stopAdvancedCapture(QCameraPicChannel * pChannel)4781 int32_t QCamera2HardwareInterface::stopAdvancedCapture(
4782 QCameraPicChannel *pChannel)
4783 {
4784 LOGH("stop bracketig");
4785 int32_t rc = NO_ERROR;
4786
4787 if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
4788 rc = pChannel->stopAdvancedCapture(MM_CAMERA_AF_BRACKETING);
4789 } else if (mParameters.isChromaFlashEnabled()
4790 || (mFlashConfigured && !mLongshotEnabled)
4791 || (mLowLightConfigured == true)
4792 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
4793 rc = pChannel->stopAdvancedCapture(MM_CAMERA_FRAME_CAPTURE);
4794 mFlashConfigured = false;
4795 mLowLightConfigured = false;
4796 } else if(mParameters.isHDREnabled()
4797 || mParameters.isAEBracketEnabled()) {
4798 rc = pChannel->stopAdvancedCapture(MM_CAMERA_AE_BRACKETING);
4799 } else if (mParameters.isOptiZoomEnabled()) {
4800 rc = pChannel->stopAdvancedCapture(MM_CAMERA_ZOOM_1X);
4801 } else if (mParameters.isStillMoreEnabled()) {
4802 LOGH("stopAdvancedCapture not needed for StillMore");
4803 } else {
4804 LOGH("No Advanced Capture feature enabled!");
4805 rc = BAD_VALUE;
4806 }
4807
4808 m_bNeedHalPP = FALSE;
4809 return rc;
4810 }
4811
4812 /*===========================================================================
4813 * FUNCTION : startAdvancedCapture
4814 *
4815 * DESCRIPTION: starts advanced capture based on capture type
4816 *
4817 * PARAMETERS :
4818 * @pChannel : channel.
4819 *
4820 * RETURN : int32_t type of status
4821 * NO_ERROR -- success
4822 * none-zero failure code
4823 *==========================================================================*/
startAdvancedCapture(QCameraPicChannel * pChannel)4824 int32_t QCamera2HardwareInterface::startAdvancedCapture(
4825 QCameraPicChannel *pChannel)
4826 {
4827 LOGH("Start bracketing");
4828 int32_t rc = NO_ERROR;
4829
4830 if(mParameters.isUbiFocusEnabled() || mParameters.isUbiRefocus()) {
4831 rc = pChannel->startAdvancedCapture(MM_CAMERA_AF_BRACKETING);
4832 } else if (mParameters.isOptiZoomEnabled()) {
4833 rc = pChannel->startAdvancedCapture(MM_CAMERA_ZOOM_1X);
4834 } else if (mParameters.isStillMoreEnabled()) {
4835 LOGH("startAdvancedCapture not needed for StillMore");
4836 } else if (mParameters.isHDREnabled()
4837 || mParameters.isAEBracketEnabled()) {
4838 rc = pChannel->startAdvancedCapture(MM_CAMERA_AE_BRACKETING);
4839 } else if (mParameters.isChromaFlashEnabled()
4840 || (mFlashNeeded && !mLongshotEnabled)
4841 || (mLowLightConfigured == true)
4842 || (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_2)) {
4843 cam_capture_frame_config_t config = mParameters.getCaptureFrameConfig();
4844 rc = pChannel->startAdvancedCapture(MM_CAMERA_FRAME_CAPTURE, &config);
4845 } else {
4846 LOGE("No Advanced Capture feature enabled!");
4847 rc = BAD_VALUE;
4848 }
4849 return rc;
4850 }
4851
4852 /*===========================================================================
4853 * FUNCTION : preTakePicture
4854 *
4855 * DESCRIPTION: Prepare take picture impl, Restarts preview if necessary
4856 *
4857 * PARAMETERS : none
4858 *
4859 * RETURN : int32_t type of status
4860 * NO_ERROR -- success
4861 * none-zero failure code
4862 *==========================================================================*/
preTakePicture()4863 int QCamera2HardwareInterface::preTakePicture()
4864 {
4865 int32_t rc = NO_ERROR;
4866 LOGH("E");
4867 if (mParameters.getRecordingHintValue() == true) {
4868
4869 // Give HWI control to restart preview only in single camera mode.
4870 // In dual-cam mode, this control belongs to muxer.
4871 if (getRelatedCamSyncInfo()->sync_control != CAM_SYNC_RELATED_SENSORS_ON) {
4872 LOGH("restart preview if rec hint is true and preview is running");
4873 stopPreview();
4874 mParameters.updateRecordingHintValue(FALSE);
4875 // start preview again
4876 rc = preparePreview();
4877 if (rc == NO_ERROR) {
4878 rc = startPreview();
4879 if (rc != NO_ERROR) {
4880 unpreparePreview();
4881 }
4882 }
4883 }
4884 else
4885 {
4886 // For dual cam mode, update the flag mPreviewRestartNeeded to true
4887 // Restart control will be handled by muxer.
4888 mPreviewRestartNeeded = true;
4889 }
4890 }
4891
4892 LOGH("X rc = %d", rc);
4893 return rc;
4894 }
4895
4896 /*===========================================================================
4897 * FUNCTION : takePicture
4898 *
4899 * DESCRIPTION: take picture impl
4900 *
4901 * PARAMETERS : none
4902 *
4903 * RETURN : int32_t type of status
4904 * NO_ERROR -- success
4905 * none-zero failure code
4906 *==========================================================================*/
takePicture()4907 int QCamera2HardwareInterface::takePicture()
4908 {
4909 int rc = NO_ERROR;
4910
4911 // Get total number for snapshots (retro + regular)
4912 uint8_t numSnapshots = mParameters.getNumOfSnapshots();
4913 // Get number of retro-active snapshots
4914 uint8_t numRetroSnapshots = mParameters.getNumOfRetroSnapshots();
4915 LOGH("E");
4916
4917 //Set rotation value from user settings as Jpeg rotation
4918 //to configure back-end modules.
4919 mParameters.setJpegRotation(mParameters.getRotation());
4920
4921 // Check if retro-active snapshots are not enabled
4922 if (!isRetroPicture() || !mParameters.isZSLMode()) {
4923 numRetroSnapshots = 0;
4924 LOGH("Reset retro snaphot count to zero");
4925 }
4926
4927 //Do special configure for advanced capture modes.
4928 rc = configureAdvancedCapture();
4929 if (rc != NO_ERROR) {
4930 LOGE("Unsupported capture call");
4931 return rc;
4932 }
4933
4934 if (mAdvancedCaptureConfigured) {
4935 numSnapshots = mParameters.getBurstCountForAdvancedCapture();
4936 }
4937
4938 if (mActiveCameras == MM_CAMERA_DUAL_CAM && mBundledSnapshot) {
4939 char prop[PROPERTY_VALUE_MAX];
4940 memset(prop, 0, sizeof(prop));
4941 property_get("persist.camera.dualfov.jpegnum", prop, "1");
4942 int dualfov_snap_num = atoi(prop);
4943
4944 memset(prop, 0, sizeof(prop));
4945 property_get("persist.camera.halpp", prop, "0");
4946 int halpp_enabled = atoi(prop);
4947 if(halpp_enabled == 0) {
4948 dualfov_snap_num = MM_CAMERA_MAX_CAM_CNT;
4949 }
4950
4951 dualfov_snap_num = (dualfov_snap_num == 0) ? 1 : dualfov_snap_num;
4952 LOGD("dualfov_snap_num:%d", dualfov_snap_num);
4953 numSnapshots /= dualfov_snap_num;
4954 }
4955
4956 LOGI("snap count = %d zsl = %d advanced = %d, active camera:%d",
4957 numSnapshots, mParameters.isZSLMode(), mAdvancedCaptureConfigured, mActiveCameras);
4958
4959 if (mParameters.isZSLMode()) {
4960 QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
4961 QCameraPicChannel *pPicChannel = (QCameraPicChannel *)pChannel;
4962 if (NULL != pPicChannel) {
4963
4964 if (mParameters.getofflineRAW()) {
4965 startRAWChannel(pPicChannel);
4966 pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW];
4967 if (pPicChannel == NULL) {
4968 LOGE("RAW Channel is NULL in Manual capture mode");
4969 stopRAWChannel();
4970 return UNKNOWN_ERROR;
4971 }
4972 }
4973
4974 rc = configureOnlineRotation(*pPicChannel);
4975 if (rc != NO_ERROR) {
4976 LOGE("online rotation failed");
4977 return rc;
4978 }
4979
4980 // start postprocessor
4981 DeferWorkArgs args;
4982 memset(&args, 0, sizeof(DeferWorkArgs));
4983
4984 args.pprocArgs = pPicChannel;
4985
4986 // No need to wait for mInitPProcJob here, because it was
4987 // queued in startPreview, and will definitely be processed before
4988 // mReprocJob can begin.
4989 mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
4990 args);
4991 if (mReprocJob == 0) {
4992 LOGE("Failure: Unable to start pproc");
4993 return -ENOMEM;
4994 }
4995
4996 // Check if all preview buffers are mapped before creating
4997 // a jpeg session as preview stream buffers are queried during the same
4998 uint8_t numStreams = pChannel->getNumOfStreams();
4999 QCameraStream *pStream = NULL;
5000 QCameraStream *pPreviewStream = NULL;
5001 for (uint8_t i = 0 ; i < numStreams ; i++ ) {
5002 pStream = pChannel->getStreamByIndex(i);
5003 if (!pStream)
5004 continue;
5005 if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) {
5006 pPreviewStream = pStream;
5007 break;
5008 }
5009 }
5010 if (pPreviewStream != NULL) {
5011 Mutex::Autolock l(mMapLock);
5012 QCameraMemory *pMemory = pStream->getStreamBufs();
5013 if (!pMemory) {
5014 LOGE("Error!! pMemory is NULL");
5015 return -ENOMEM;
5016 }
5017
5018 uint8_t waitCnt = 2;
5019 while (!pMemory->checkIfAllBuffersMapped() && (waitCnt > 0)) {
5020 LOGL(" Waiting for preview buffers to be mapped");
5021 mMapCond.waitRelative(
5022 mMapLock, CAMERA_DEFERRED_MAP_BUF_TIMEOUT);
5023 LOGL("Wait completed!!");
5024 waitCnt--;
5025 }
5026 // If all buffers are not mapped after retries, assert
5027 assert(pMemory->checkIfAllBuffersMapped());
5028 } else {
5029 assert(pPreviewStream);
5030 }
5031
5032 // Create JPEG session
5033 mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
5034 args);
5035 if (mJpegJob == 0) {
5036 LOGE("Failed to queue CREATE_JPEG_SESSION");
5037 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5038 LOGE("Reprocess Deferred work was failed");
5039 }
5040 m_postprocessor.stop();
5041 return -ENOMEM;
5042 }
5043
5044 if (mAdvancedCaptureConfigured) {
5045 rc = startAdvancedCapture(pPicChannel);
5046 if (rc != NO_ERROR) {
5047 LOGE("cannot start zsl advanced capture");
5048 return rc;
5049 }
5050 }
5051 if (mLongshotEnabled && mPrepSnapRun) {
5052 mCameraHandle->ops->start_zsl_snapshot(
5053 mCameraHandle->camera_handle,
5054 pPicChannel->getMyHandle());
5055 }
5056 // If frame sync is ON and it is a SECONDARY camera,
5057 // we do not need to send the take picture command to interface
5058 // It will be handled along with PRIMARY camera takePicture request
5059 mm_camera_req_buf_t buf;
5060 memset(&buf, 0x0, sizeof(buf));
5061 if ((!mParameters.isAdvCamFeaturesEnabled() &&
5062 !mFlashNeeded &&
5063 !isLongshotEnabled() &&
5064 isFrameSyncEnabled()) &&
5065 (getRelatedCamSyncInfo()->sync_control ==
5066 CAM_SYNC_RELATED_SENSORS_ON)) {
5067 if (getRelatedCamSyncInfo()->mode == CAM_MODE_PRIMARY) {
5068 buf.type = MM_CAMERA_REQ_FRAME_SYNC_BUF;
5069 buf.num_buf_requested = numSnapshots;
5070 rc = pPicChannel->takePicture(&buf);
5071 if (rc != NO_ERROR) {
5072 LOGE("FS_DBG cannot take ZSL picture, stop pproc");
5073 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5074 LOGE("Reprocess Deferred work failed");
5075 return UNKNOWN_ERROR;
5076 }
5077 if (NO_ERROR != waitDeferredWork(mJpegJob)) {
5078 LOGE("Jpeg Deferred work failed");
5079 return UNKNOWN_ERROR;
5080 }
5081 m_postprocessor.stop();
5082 return rc;
5083 }
5084 LOGI("PRIMARY camera: send frame sync takePicture!!");
5085 }
5086 } else {
5087 buf.type = MM_CAMERA_REQ_SUPER_BUF;
5088 buf.num_buf_requested = numSnapshots;
5089 buf.num_retro_buf_requested = numRetroSnapshots;
5090 rc = pPicChannel->takePicture(&buf);
5091 if (rc != NO_ERROR) {
5092 LOGE("cannot take ZSL picture, stop pproc");
5093 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5094 LOGE("Reprocess Deferred work failed");
5095 return UNKNOWN_ERROR;
5096 }
5097 if (NO_ERROR != waitDeferredWork(mJpegJob)) {
5098 LOGE("Jpeg Deferred work failed");
5099 return UNKNOWN_ERROR;
5100 }
5101 m_postprocessor.stop();
5102 return rc;
5103 }
5104 }
5105 } else {
5106 LOGE("ZSL channel is NULL");
5107 return UNKNOWN_ERROR;
5108 }
5109 } else {
5110
5111 // start snapshot
5112 if (mParameters.isJpegPictureFormat() ||
5113 mParameters.isNV16PictureFormat() ||
5114 mParameters.isNV21PictureFormat()) {
5115
5116 //STOP Preview for Non ZSL use case
5117 stopPreview();
5118
5119 //Config CAPTURE channels
5120 rc = declareSnapshotStreams();
5121 if (NO_ERROR != rc) {
5122 return rc;
5123 }
5124
5125 rc = addCaptureChannel();
5126 if ((rc == NO_ERROR) &&
5127 (NULL != m_channels[QCAMERA_CH_TYPE_CAPTURE])) {
5128
5129 if (!mParameters.getofflineRAW()) {
5130 rc = configureOnlineRotation(
5131 *m_channels[QCAMERA_CH_TYPE_CAPTURE]);
5132 if (rc != NO_ERROR) {
5133 LOGE("online rotation failed");
5134 delChannel(QCAMERA_CH_TYPE_CAPTURE);
5135 return rc;
5136 }
5137 }
5138
5139 DeferWorkArgs args;
5140 memset(&args, 0, sizeof(DeferWorkArgs));
5141
5142 args.pprocArgs = m_channels[QCAMERA_CH_TYPE_CAPTURE];
5143
5144 // No need to wait for mInitPProcJob here, because it was
5145 // queued in startPreview, and will definitely be processed before
5146 // mReprocJob can begin.
5147 mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
5148 args);
5149 if (mReprocJob == 0) {
5150 LOGE("Failure: Unable to start pproc");
5151 return -ENOMEM;
5152 }
5153
5154 // Create JPEG session
5155 mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
5156 args);
5157 if (mJpegJob == 0) {
5158 LOGE("Failed to queue CREATE_JPEG_SESSION");
5159 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5160 LOGE("Reprocess Deferred work was failed");
5161 }
5162 m_postprocessor.stop();
5163 return -ENOMEM;
5164 }
5165
5166 // start catpure channel
5167 rc = m_channels[QCAMERA_CH_TYPE_CAPTURE]->start();
5168 if (rc != NO_ERROR) {
5169 LOGE("cannot start capture channel");
5170 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5171 LOGE("Reprocess Deferred work failed");
5172 return UNKNOWN_ERROR;
5173 }
5174 if (NO_ERROR != waitDeferredWork(mJpegJob)) {
5175 LOGE("Jpeg Deferred work failed");
5176 return UNKNOWN_ERROR;
5177 }
5178 delChannel(QCAMERA_CH_TYPE_CAPTURE);
5179 return rc;
5180 }
5181
5182 QCameraPicChannel *pCapChannel =
5183 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
5184 if (NULL != pCapChannel) {
5185 if (mParameters.isUbiFocusEnabled() ||
5186 mParameters.isUbiRefocus() ||
5187 mParameters.isChromaFlashEnabled()) {
5188 rc = startAdvancedCapture(pCapChannel);
5189 if (rc != NO_ERROR) {
5190 LOGE("cannot start advanced capture");
5191 return rc;
5192 }
5193 }
5194 }
5195 if ( mLongshotEnabled ) {
5196 rc = longShot();
5197 if (NO_ERROR != rc) {
5198 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5199 LOGE("Reprocess Deferred work failed");
5200 return UNKNOWN_ERROR;
5201 }
5202 if (NO_ERROR != waitDeferredWork(mJpegJob)) {
5203 LOGE("Jpeg Deferred work failed");
5204 return UNKNOWN_ERROR;
5205 }
5206 delChannel(QCAMERA_CH_TYPE_CAPTURE);
5207 return rc;
5208 }
5209 }
5210 } else {
5211 LOGE("cannot add capture channel");
5212 delChannel(QCAMERA_CH_TYPE_CAPTURE);
5213 return rc;
5214 }
5215 } else {
5216 // Stop Preview before taking NZSL snapshot
5217 stopPreview();
5218
5219 rc = mParameters.updateRAW(gCamCapability[mCameraId]->raw_dim[0]);
5220 if (NO_ERROR != rc) {
5221 LOGE("Raw dimension update failed %d", rc);
5222 return rc;
5223 }
5224
5225 rc = declareSnapshotStreams();
5226 if (NO_ERROR != rc) {
5227 LOGE("RAW stream info configuration failed %d", rc);
5228 return rc;
5229 }
5230
5231 rc = addChannel(QCAMERA_CH_TYPE_RAW);
5232 if (rc == NO_ERROR) {
5233 // start postprocessor
5234 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
5235 LOGE("Reprocess Deferred work failed");
5236 return UNKNOWN_ERROR;
5237 }
5238
5239 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
5240 if (rc != NO_ERROR) {
5241 LOGE("cannot start postprocessor");
5242 delChannel(QCAMERA_CH_TYPE_RAW);
5243 return rc;
5244 }
5245
5246 rc = startChannel(QCAMERA_CH_TYPE_RAW);
5247 if (rc != NO_ERROR) {
5248 LOGE("cannot start raw channel");
5249 m_postprocessor.stop();
5250 delChannel(QCAMERA_CH_TYPE_RAW);
5251 return rc;
5252 }
5253 } else {
5254 LOGE("cannot add raw channel");
5255 return rc;
5256 }
5257 }
5258 }
5259
5260 //When take picture, stop sending preview callbacks to APP
5261 m_stateMachine.setPreviewCallbackNeeded(false);
5262 LOGI("X rc = %d", rc);
5263 return rc;
5264 }
5265
5266 /*===========================================================================
5267 * FUNCTION : configureOnlineRotation
5268 *
5269 * DESCRIPTION: Configure backend with expected rotation for snapshot stream
5270 *
5271 * PARAMETERS :
5272 * @ch : Channel containing a snapshot stream
5273 *
5274 * RETURN : int32_t type of status
5275 * NO_ERROR -- success
5276 * none-zero failure code
5277 *==========================================================================*/
configureOnlineRotation(QCameraChannel & ch)5278 int32_t QCamera2HardwareInterface::configureOnlineRotation(QCameraChannel &ch)
5279 {
5280 int rc = NO_ERROR;
5281 uint32_t streamId = 0;
5282 QCameraStream *pStream = NULL;
5283
5284 for (uint8_t i = 0; i < ch.getNumOfStreams(); i++) {
5285 QCameraStream *stream = ch.getStreamByIndex(i);
5286 if ((NULL != stream) &&
5287 ((CAM_STREAM_TYPE_SNAPSHOT == stream->getMyType())
5288 || (CAM_STREAM_TYPE_RAW == stream->getMyType()))) {
5289 pStream = stream;
5290 break;
5291 }
5292 }
5293
5294 if (NULL == pStream) {
5295 LOGE("No snapshot stream found!");
5296 return BAD_VALUE;
5297 }
5298
5299 streamId = pStream->getMyServerID();
5300 // Update online rotation configuration
5301 rc = mParameters.addOnlineRotation(mParameters.getJpegRotation(), streamId,
5302 mParameters.getDeviceRotation());
5303 if (rc != NO_ERROR) {
5304 LOGE("addOnlineRotation failed %d", rc);
5305 return rc;
5306 }
5307
5308 return rc;
5309 }
5310
5311 /*===========================================================================
5312 * FUNCTION : declareSnapshotStreams
5313 *
5314 * DESCRIPTION: Configure backend with expected snapshot streams
5315 *
5316 * PARAMETERS : none
5317 *
5318 * RETURN : int32_t type of status
5319 * NO_ERROR -- success
5320 * none-zero failure code
5321 *==========================================================================*/
declareSnapshotStreams()5322 int32_t QCamera2HardwareInterface::declareSnapshotStreams()
5323 {
5324 int rc = NO_ERROR;
5325
5326 // Update stream info configuration
5327 rc = mParameters.setStreamConfigure(true, mLongshotEnabled, false);
5328 if (rc != NO_ERROR) {
5329 LOGE("setStreamConfigure failed %d", rc);
5330 return rc;
5331 }
5332
5333 return rc;
5334 }
5335
5336 /*===========================================================================
5337 * FUNCTION : longShot
5338 *
5339 * DESCRIPTION: Queue one more ZSL frame
5340 * in the longshot pipe.
5341 *
5342 * PARAMETERS : none
5343 *
5344 * RETURN : int32_t type of status
5345 * NO_ERROR -- success
5346 * none-zero failure code
5347 *==========================================================================*/
longShot()5348 int32_t QCamera2HardwareInterface::longShot()
5349 {
5350 int32_t rc = NO_ERROR;
5351 uint8_t numSnapshots = mParameters.getNumOfSnapshots();
5352 QCameraPicChannel *pChannel = NULL;
5353
5354 if (mParameters.isZSLMode()) {
5355 pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
5356 } else {
5357 pChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_CAPTURE];
5358 }
5359
5360 if (NULL != pChannel) {
5361 mm_camera_req_buf_t buf;
5362 memset(&buf, 0x0, sizeof(buf));
5363 buf.type = MM_CAMERA_REQ_SUPER_BUF;
5364 buf.num_buf_requested = numSnapshots;
5365 rc = pChannel->takePicture(&buf);
5366 } else {
5367 LOGE("Capture channel not initialized!");
5368 rc = NO_INIT;
5369 goto end;
5370 }
5371
5372 end:
5373 return rc;
5374 }
5375
5376 /*===========================================================================
5377 * FUNCTION : stopCaptureChannel
5378 *
5379 * DESCRIPTION: Stops capture channel
5380 *
5381 * PARAMETERS :
5382 * @destroy : Set to true to stop and delete camera channel.
5383 * Set to false to only stop capture channel.
5384 *
5385 * RETURN : int32_t type of status
5386 * NO_ERROR -- success
5387 * none-zero failure code
5388 *==========================================================================*/
stopCaptureChannel(bool destroy)5389 int QCamera2HardwareInterface::stopCaptureChannel(bool destroy)
5390 {
5391 int rc = NO_ERROR;
5392 if (mParameters.isJpegPictureFormat() ||
5393 mParameters.isNV16PictureFormat() ||
5394 mParameters.isNV21PictureFormat()) {
5395 mParameters.setQuadraCfaMode(false, true);
5396 rc = stopChannel(QCAMERA_CH_TYPE_CAPTURE);
5397 if (destroy && (NO_ERROR == rc)) {
5398 // Destroy camera channel but dont release context
5399 waitDeferredWork(mJpegJob);
5400 rc = delChannel(QCAMERA_CH_TYPE_CAPTURE, false);
5401 }
5402 }
5403
5404 return rc;
5405 }
5406
5407 /*===========================================================================
5408 * FUNCTION : cancelPicture
5409 *
5410 * DESCRIPTION: cancel picture impl
5411 *
5412 * PARAMETERS : none
5413 *
5414 * RETURN : int32_t type of status
5415 * NO_ERROR -- success
5416 * none-zero failure code
5417 *==========================================================================*/
cancelPicture()5418 int QCamera2HardwareInterface::cancelPicture()
5419 {
5420 waitDeferredWork(mReprocJob);
5421 waitDeferredWork(mJpegJob);
5422
5423 //stop post processor
5424 m_postprocessor.stop();
5425
5426 unconfigureAdvancedCapture();
5427 LOGH("Enable display frames again");
5428 setDisplaySkip(FALSE);
5429
5430 if (mParameters.isZSLMode()) {
5431 QCameraPicChannel *pPicChannel = NULL;
5432 if (mParameters.getofflineRAW()) {
5433 pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_RAW];
5434 } else {
5435 pPicChannel = (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
5436 }
5437 if (NULL != pPicChannel) {
5438 pPicChannel->cancelPicture();
5439 stopRAWChannel();
5440 stopAdvancedCapture(pPicChannel);
5441 }
5442 } else {
5443
5444 // normal capture case
5445 if (mParameters.isJpegPictureFormat() ||
5446 mParameters.isNV16PictureFormat() ||
5447 mParameters.isNV21PictureFormat()) {
5448 stopChannel(QCAMERA_CH_TYPE_CAPTURE);
5449 delChannel(QCAMERA_CH_TYPE_CAPTURE);
5450 } else {
5451 stopChannel(QCAMERA_CH_TYPE_RAW);
5452 delChannel(QCAMERA_CH_TYPE_RAW);
5453 }
5454 }
5455
5456 return NO_ERROR;
5457 }
5458
5459 /*===========================================================================
5460 * FUNCTION : captureDone
5461 *
5462 * DESCRIPTION: Function called when the capture is completed before encoding
5463 *
5464 * PARAMETERS : none
5465 *
5466 * RETURN : none
5467 *==========================================================================*/
captureDone()5468 void QCamera2HardwareInterface::captureDone()
5469 {
5470 qcamera_sm_internal_evt_payload_t *payload =
5471 (qcamera_sm_internal_evt_payload_t *)
5472 malloc(sizeof(qcamera_sm_internal_evt_payload_t));
5473 if (NULL != payload) {
5474 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
5475 payload->evt_type = QCAMERA_INTERNAL_EVT_ZSL_CAPTURE_DONE;
5476 int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
5477 if (rc != NO_ERROR) {
5478 LOGE("processEvt ZSL capture done failed");
5479 free(payload);
5480 payload = NULL;
5481 }
5482 } else {
5483 LOGE("No memory for ZSL capture done event");
5484 }
5485 }
5486
5487 /*===========================================================================
5488 * FUNCTION : Live_Snapshot_thread
5489 *
5490 * DESCRIPTION: Seperate thread for taking live snapshot during recording
5491 *
5492 * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object
5493 *
5494 * RETURN : none
5495 *==========================================================================*/
Live_Snapshot_thread(void * data)5496 void* Live_Snapshot_thread (void* data)
5497 {
5498
5499 QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data);
5500 if (!hw) {
5501 LOGE("take_picture_thread: NULL camera device");
5502 return (void *)BAD_VALUE;
5503 }
5504 if (hw->bLiveSnapshot) {
5505 hw->takeLiveSnapshot_internal();
5506 } else {
5507 hw->cancelLiveSnapshot_internal();
5508 }
5509 return (void* )NULL;
5510 }
5511
5512 /*===========================================================================
5513 * FUNCTION : Int_Pic_thread
5514 *
5515 * DESCRIPTION: Seperate thread for taking snapshot triggered by camera backend
5516 *
5517 * PARAMETERS : @data - pointer to QCamera2HardwareInterface class object
5518 *
5519 * RETURN : none
5520 *==========================================================================*/
Int_Pic_thread(void * data)5521 void* Int_Pic_thread (void* data)
5522 {
5523 int rc = NO_ERROR;
5524
5525 QCamera2HardwareInterface *hw = reinterpret_cast<QCamera2HardwareInterface *>(data);
5526
5527 if (!hw) {
5528 LOGE("take_picture_thread: NULL camera device");
5529 return (void *)BAD_VALUE;
5530 }
5531
5532 bool JpegMemOpt = false;
5533 char raw_format[PROPERTY_VALUE_MAX];
5534
5535 memset(raw_format, 0, sizeof(raw_format));
5536
5537 rc = hw->takeBackendPic_internal(&JpegMemOpt, &raw_format[0]);
5538 if (rc == NO_ERROR) {
5539 hw->checkIntPicPending(JpegMemOpt, &raw_format[0]);
5540 } else {
5541 //Snapshot attempt not successful, we need to do cleanup here
5542 hw->clearIntPendingEvents();
5543 }
5544
5545 return (void* )NULL;
5546 }
5547
5548 /*===========================================================================
5549 * FUNCTION : takeLiveSnapshot
5550 *
5551 * DESCRIPTION: take live snapshot during recording
5552 *
5553 * PARAMETERS : none
5554 *
5555 * RETURN : int32_t type of status
5556 * NO_ERROR -- success
5557 * none-zero failure code
5558 *==========================================================================*/
takeLiveSnapshot()5559 int QCamera2HardwareInterface::takeLiveSnapshot()
5560 {
5561 int rc = NO_ERROR;
5562 if (mLiveSnapshotThread != 0) {
5563 pthread_join(mLiveSnapshotThread,NULL);
5564 mLiveSnapshotThread = 0;
5565 }
5566 bLiveSnapshot = true;
5567 rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this);
5568 if (!rc) {
5569 pthread_setname_np(mLiveSnapshotThread, "CAM_liveSnap");
5570 }
5571 return rc;
5572 }
5573
5574 /*===========================================================================
5575 * FUNCTION : takePictureInternal
5576 *
5577 * DESCRIPTION: take snapshot triggered by backend
5578 *
5579 * PARAMETERS : none
5580 *
5581 * RETURN : int32_t type of status
5582 * NO_ERROR -- success
5583 * none-zero failure code
5584 *==========================================================================*/
takePictureInternal()5585 int QCamera2HardwareInterface::takePictureInternal()
5586 {
5587 int rc = NO_ERROR;
5588 rc= pthread_create(&mIntPicThread, NULL, Int_Pic_thread, (void *) this);
5589 if (!rc) {
5590 pthread_setname_np(mIntPicThread, "CAM_IntPic");
5591 }
5592 return rc;
5593 }
5594
5595 /*===========================================================================
5596 * FUNCTION : checkIntPicPending
5597 *
5598 * DESCRIPTION: timed wait for jpeg completion event, and send
5599 * back completion event to backend
5600 *
5601 * PARAMETERS : none
5602 *
5603 * RETURN : none
5604 *==========================================================================*/
checkIntPicPending(bool JpegMemOpt,char * raw_format)5605 void QCamera2HardwareInterface::checkIntPicPending(bool JpegMemOpt, char *raw_format)
5606 {
5607 bool bSendToBackend = true;
5608 cam_int_evt_params_t params;
5609 int rc = NO_ERROR;
5610
5611 struct timespec ts;
5612 struct timeval tp;
5613 gettimeofday(&tp, NULL);
5614 ts.tv_sec = tp.tv_sec + 5;
5615 ts.tv_nsec = tp.tv_usec * 1000;
5616
5617 if (true == m_bIntJpegEvtPending ||
5618 (true == m_bIntRawEvtPending)) {
5619 //Waiting in HAL for snapshot taken notification
5620 pthread_mutex_lock(&m_int_lock);
5621 rc = pthread_cond_timedwait(&m_int_cond, &m_int_lock, &ts);
5622 if (ETIMEDOUT == rc || 0x0 == m_BackendFileName[0]) {
5623 //Hit a timeout, or some spurious activity
5624 bSendToBackend = false;
5625 }
5626
5627 if (true == m_bIntJpegEvtPending) {
5628 params.event_type = 0;
5629 mParameters.getStreamFormat(CAM_STREAM_TYPE_SNAPSHOT, params.picture_format);
5630 } else if (true == m_bIntRawEvtPending) {
5631 params.event_type = 1;
5632 mParameters.getStreamFormat(CAM_STREAM_TYPE_RAW, params.picture_format);
5633 }
5634 pthread_mutex_unlock(&m_int_lock);
5635
5636 if (true == m_bIntJpegEvtPending) {
5637 //Attempting to restart preview after taking JPEG snapshot
5638 lockAPI();
5639 rc = processAPI(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL);
5640 unlockAPI();
5641 m_postprocessor.setJpegMemOpt(JpegMemOpt);
5642 } else if (true == m_bIntRawEvtPending) {
5643 //Attempting to restart preview after taking RAW snapshot
5644 stopChannel(QCAMERA_CH_TYPE_RAW);
5645 delChannel(QCAMERA_CH_TYPE_RAW);
5646 //restoring the old raw format
5647 property_set("persist.camera.raw.format", raw_format);
5648 }
5649
5650 if (true == bSendToBackend) {
5651 //send event back to server with the file path
5652 params.dim = m_postprocessor.m_dst_dim;
5653 memcpy(¶ms.path[0], &m_BackendFileName[0], QCAMERA_MAX_FILEPATH_LENGTH);
5654 memset(&m_BackendFileName[0], 0x0, QCAMERA_MAX_FILEPATH_LENGTH);
5655 params.size = mBackendFileSize;
5656 rc = mParameters.setIntEvent(params);
5657 }
5658
5659 clearIntPendingEvents();
5660 }
5661
5662 return;
5663 }
5664
5665 /*===========================================================================
5666 * FUNCTION : takeBackendPic_internal
5667 *
5668 * DESCRIPTION: take snapshot triggered by backend
5669 *
5670 * PARAMETERS : none
5671 *
5672 * RETURN : int32_t type of status
5673 * NO_ERROR -- success
5674 * none-zero failure code
5675 *==========================================================================*/
takeBackendPic_internal(bool * JpegMemOpt,char * raw_format)5676 int QCamera2HardwareInterface::takeBackendPic_internal(bool *JpegMemOpt, char *raw_format)
5677 {
5678 int rc = NO_ERROR;
5679 qcamera_api_result_t apiResult;
5680
5681 lockAPI();
5682 //Set rotation value from user settings as Jpeg rotation
5683 //to configure back-end modules.
5684 mParameters.setJpegRotation(mParameters.getRotation());
5685
5686 setRetroPicture(0);
5687 /* Prepare snapshot in case LED needs to be flashed */
5688 if (mFlashNeeded == 1 || mParameters.isChromaFlashEnabled()) {
5689 // Start Preparing for normal Frames
5690 LOGH("Start Prepare Snapshot");
5691 /* Prepare snapshot in case LED needs to be flashed */
5692 rc = processAPI(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, NULL);
5693 if (rc == NO_ERROR) {
5694 waitAPIResult(QCAMERA_SM_EVT_PREPARE_SNAPSHOT, &apiResult);
5695 rc = apiResult.status;
5696 }
5697 LOGH("Prep Snapshot done rc = %d", rc);
5698 mPrepSnapRun = true;
5699 }
5700 unlockAPI();
5701
5702 if (true == m_bIntJpegEvtPending) {
5703 //Attempting to take JPEG snapshot
5704 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
5705 LOGE("Init PProc Deferred work failed");
5706 return UNKNOWN_ERROR;
5707 }
5708 *JpegMemOpt = m_postprocessor.getJpegMemOpt();
5709 m_postprocessor.setJpegMemOpt(false);
5710
5711 /* capture */
5712 lockAPI();
5713 LOGH("Capturing internal snapshot");
5714 rc = processAPI(QCAMERA_SM_EVT_TAKE_PICTURE, NULL);
5715 if (rc == NO_ERROR) {
5716 waitAPIResult(QCAMERA_SM_EVT_TAKE_PICTURE, &apiResult);
5717 rc = apiResult.status;
5718 }
5719 unlockAPI();
5720 } else if (true == m_bIntRawEvtPending) {
5721 //Attempting to take RAW snapshot
5722 (void)JpegMemOpt;
5723 stopPreview();
5724
5725 //getting the existing raw format type
5726 property_get("persist.camera.raw.format", raw_format, "17");
5727 //setting it to a default know value for this task
5728 property_set("persist.camera.raw.format", "18");
5729
5730 rc = addChannel(QCAMERA_CH_TYPE_RAW);
5731 if (rc == NO_ERROR) {
5732 // start postprocessor
5733 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
5734 LOGE("Init PProc Deferred work failed");
5735 return UNKNOWN_ERROR;
5736 }
5737 rc = m_postprocessor.start(m_channels[QCAMERA_CH_TYPE_RAW]);
5738 if (rc != NO_ERROR) {
5739 LOGE("cannot start postprocessor");
5740 delChannel(QCAMERA_CH_TYPE_RAW);
5741 return rc;
5742 }
5743
5744 rc = startChannel(QCAMERA_CH_TYPE_RAW);
5745 if (rc != NO_ERROR) {
5746 LOGE("cannot start raw channel");
5747 m_postprocessor.stop();
5748 delChannel(QCAMERA_CH_TYPE_RAW);
5749 return rc;
5750 }
5751 } else {
5752 LOGE("cannot add raw channel");
5753 return rc;
5754 }
5755 }
5756
5757 return rc;
5758 }
5759
5760 /*===========================================================================
5761 * FUNCTION : clearIntPendingEvents
5762 *
5763 * DESCRIPTION: clear internal pending events pertaining to backend
5764 * snapshot requests
5765 *
5766 * PARAMETERS : none
5767 *
5768 * RETURN : int32_t type of status
5769 * NO_ERROR -- success
5770 * none-zero failure code
5771 *==========================================================================*/
clearIntPendingEvents()5772 void QCamera2HardwareInterface::clearIntPendingEvents()
5773 {
5774 int rc = NO_ERROR;
5775
5776 if (true == m_bIntRawEvtPending) {
5777 preparePreview();
5778 startPreview();
5779 }
5780 if (true == m_bIntJpegEvtPending) {
5781 if (false == mParameters.isZSLMode()) {
5782 lockAPI();
5783 rc = processAPI(QCAMERA_SM_EVT_START_PREVIEW, NULL);
5784 unlockAPI();
5785 }
5786 }
5787
5788 pthread_mutex_lock(&m_int_lock);
5789 if (true == m_bIntJpegEvtPending) {
5790 m_bIntJpegEvtPending = false;
5791 } else if (true == m_bIntRawEvtPending) {
5792 m_bIntRawEvtPending = false;
5793 }
5794 pthread_mutex_unlock(&m_int_lock);
5795 return;
5796 }
5797
5798 /*===========================================================================
5799 * FUNCTION : takeLiveSnapshot_internal
5800 *
5801 * DESCRIPTION: take live snapshot during recording
5802 *
5803 * PARAMETERS : none
5804 *
5805 * RETURN : int32_t type of status
5806 * NO_ERROR -- success
5807 * none-zero failure code
5808 *==========================================================================*/
takeLiveSnapshot_internal()5809 int QCamera2HardwareInterface::takeLiveSnapshot_internal()
5810 {
5811 int rc = NO_ERROR;
5812
5813 QCameraChannel *pChannel = NULL;
5814 QCameraChannel *pPreviewChannel = NULL;
5815 QCameraStream *pPreviewStream = NULL;
5816 QCameraStream *pStream = NULL;
5817
5818 //Set rotation value from user settings as Jpeg rotation
5819 //to configure back-end modules.
5820 mParameters.setJpegRotation(mParameters.getRotation());
5821
5822 // Configure advanced capture
5823 rc = configureAdvancedCapture();
5824 if (rc != NO_ERROR) {
5825 LOGE("Unsupported capture call");
5826 goto end;
5827 }
5828
5829 if (isLowPowerMode()) {
5830 pChannel = m_channels[QCAMERA_CH_TYPE_VIDEO];
5831 } else {
5832 pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
5833 }
5834
5835 if (NULL == pChannel) {
5836 LOGE("Snapshot/Video channel not initialized");
5837 rc = NO_INIT;
5838 goto end;
5839 }
5840
5841 // Check if all preview buffers are mapped before creating
5842 // a jpeg session as preview stream buffers are queried during the same
5843 pPreviewChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
5844 if (pPreviewChannel != NULL) {
5845 uint32_t numStreams = pPreviewChannel->getNumOfStreams();
5846
5847 for (uint8_t i = 0 ; i < numStreams ; i++ ) {
5848 pStream = pPreviewChannel->getStreamByIndex(i);
5849 if (!pStream)
5850 continue;
5851 if (CAM_STREAM_TYPE_PREVIEW == pStream->getMyType()) {
5852 pPreviewStream = pStream;
5853 break;
5854 }
5855 }
5856
5857 if (pPreviewStream != NULL) {
5858 Mutex::Autolock l(mMapLock);
5859 QCameraMemory *pMemory = pStream->getStreamBufs();
5860 if (!pMemory) {
5861 LOGE("Error!! pMemory is NULL");
5862 return -ENOMEM;
5863 }
5864
5865 uint8_t waitCnt = 2;
5866 while (!pMemory->checkIfAllBuffersMapped() && (waitCnt > 0)) {
5867 LOGL(" Waiting for preview buffers to be mapped");
5868 mMapCond.waitRelative(
5869 mMapLock, CAMERA_DEFERRED_MAP_BUF_TIMEOUT);
5870 LOGL("Wait completed!!");
5871 waitCnt--;
5872 }
5873 // If all buffers are not mapped after retries, assert
5874 assert(pMemory->checkIfAllBuffersMapped());
5875 } else {
5876 assert(pPreviewStream);
5877 }
5878 }
5879
5880 DeferWorkArgs args;
5881 memset(&args, 0, sizeof(DeferWorkArgs));
5882
5883 args.pprocArgs = pChannel;
5884
5885 // No need to wait for mInitPProcJob here, because it was
5886 // queued in startPreview, and will definitely be processed before
5887 // mReprocJob can begin.
5888 mReprocJob = queueDeferredWork(CMD_DEF_PPROC_START,
5889 args);
5890 if (mReprocJob == 0) {
5891 LOGE("Failed to queue CMD_DEF_PPROC_START");
5892 rc = -ENOMEM;
5893 goto end;
5894 }
5895
5896 // Create JPEG session
5897 mJpegJob = queueDeferredWork(CMD_DEF_CREATE_JPEG_SESSION,
5898 args);
5899 if (mJpegJob == 0) {
5900 LOGE("Failed to queue CREATE_JPEG_SESSION");
5901 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5902 LOGE("Reprocess Deferred work was failed");
5903 }
5904 m_postprocessor.stop();
5905 rc = -ENOMEM;
5906 goto end;
5907 }
5908
5909 if (isLowPowerMode()) {
5910 mm_camera_req_buf_t buf;
5911 memset(&buf, 0x0, sizeof(buf));
5912 buf.type = MM_CAMERA_REQ_SUPER_BUF;
5913 buf.num_buf_requested = 1;
5914 rc = ((QCameraVideoChannel*)pChannel)->takePicture(&buf);
5915 goto end;
5916 }
5917
5918 //Disable reprocess for 4K liveshot case
5919 if (!mParameters.is4k2kVideoResolution()) {
5920 rc = configureOnlineRotation(*m_channels[QCAMERA_CH_TYPE_SNAPSHOT]);
5921 if (rc != NO_ERROR) {
5922 LOGE("online rotation failed");
5923 if (NO_ERROR != waitDeferredWork(mReprocJob)) {
5924 LOGE("Reprocess Deferred work was failed");
5925 }
5926 if (NO_ERROR != waitDeferredWork(mJpegJob)) {
5927 LOGE("Jpeg Deferred work was failed");
5928 }
5929 m_postprocessor.stop();
5930 return rc;
5931 }
5932 }
5933
5934 if ((NULL != pChannel) && (mParameters.isTNRSnapshotEnabled())) {
5935 QCameraStream *pStream = NULL;
5936 for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) {
5937 pStream = pChannel->getStreamByIndex(i);
5938 if ((NULL != pStream) &&
5939 (CAM_STREAM_TYPE_SNAPSHOT == pStream->getMyType())) {
5940 break;
5941 }
5942 }
5943 if (pStream != NULL) {
5944 LOGD("REQUEST_FRAMES event for TNR snapshot");
5945 cam_stream_parm_buffer_t param;
5946 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
5947 param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES;
5948 param.frameRequest.enableStream = 1;
5949 rc = pStream->setParameter(param);
5950 if (rc != NO_ERROR) {
5951 LOGE("Stream Event REQUEST_FRAMES failed");
5952 }
5953 goto end;
5954 }
5955 }
5956
5957 // start snapshot channel
5958 if ((rc == NO_ERROR) && (NULL != pChannel)) {
5959 // Do not link metadata stream for 4K2k resolution
5960 // as CPP processing would be done on snapshot stream and not
5961 // reprocess stream
5962 if (!mParameters.is4k2kVideoResolution()) {
5963 // Find and try to link a metadata stream from preview channel
5964 QCameraChannel *pMetaChannel = NULL;
5965 QCameraStream *pMetaStream = NULL;
5966 QCameraStream *pPreviewStream = NULL;
5967
5968 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
5969 pMetaChannel = m_channels[QCAMERA_CH_TYPE_PREVIEW];
5970 uint32_t streamNum = pMetaChannel->getNumOfStreams();
5971 QCameraStream *pStream = NULL;
5972 for (uint32_t i = 0 ; i < streamNum ; i++ ) {
5973 pStream = pMetaChannel->getStreamByIndex(i);
5974 if (NULL != pStream) {
5975 if (CAM_STREAM_TYPE_METADATA == pStream->getMyType()) {
5976 pMetaStream = pStream;
5977 } else if ((CAM_STREAM_TYPE_PREVIEW == pStream->getMyType())
5978 && (!mParameters.isHfrMode())
5979 && (mParameters.isLinkPreviewForLiveShot())) {
5980 // Do not link preview stream for
5981 // 1)HFR live snapshot,Thumbnail will not be derived from
5982 // preview for HFR live snapshot.
5983 // 2)persist.camera.linkpreview is 0
5984 pPreviewStream = pStream;
5985 }
5986 }
5987 }
5988 }
5989
5990 if ((NULL != pMetaChannel) && (NULL != pMetaStream)) {
5991 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
5992 if (NO_ERROR != rc) {
5993 LOGE("Metadata stream link failed %d", rc);
5994 }
5995 }
5996 if ((NULL != pMetaChannel) && (NULL != pPreviewStream)) {
5997 rc = pChannel->linkStream(pMetaChannel, pPreviewStream);
5998 if (NO_ERROR != rc) {
5999 LOGE("Preview stream link failed %d", rc);
6000 }
6001 }
6002 }
6003 rc = pChannel->start();
6004 }
6005
6006 end:
6007 if (rc != NO_ERROR) {
6008 rc = processAPI(QCAMERA_SM_EVT_CANCEL_PICTURE, NULL);
6009 rc = sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
6010 }
6011 return rc;
6012 }
6013
6014 /*===========================================================================
6015 * FUNCTION : cancelLiveSnapshot
6016 *
6017 * DESCRIPTION: cancel current live snapshot request
6018 *
6019 * PARAMETERS : none
6020 *
6021 * RETURN : int32_t type of status
6022 * NO_ERROR -- success
6023 * none-zero failure code
6024 *==========================================================================*/
cancelLiveSnapshot()6025 int QCamera2HardwareInterface::cancelLiveSnapshot()
6026 {
6027 int rc = NO_ERROR;
6028 if (mLiveSnapshotThread != 0) {
6029 pthread_join(mLiveSnapshotThread,NULL);
6030 mLiveSnapshotThread = 0;
6031 }
6032 bLiveSnapshot = false;
6033 rc= pthread_create(&mLiveSnapshotThread, NULL, Live_Snapshot_thread, (void *) this);
6034 if (!rc) {
6035 pthread_setname_np(mLiveSnapshotThread, "CAM_cancel_liveSnap");
6036 }
6037 return rc;
6038 }
6039
6040 /*===========================================================================
6041 * FUNCTION : cancelLiveSnapshot_internal
6042 *
6043 * DESCRIPTION: cancel live snapshot during recording
6044 *
6045 * PARAMETERS : none
6046 *
6047 * RETURN : int32_t type of status
6048 * NO_ERROR -- success
6049 * none-zero failure code
6050 *==========================================================================*/
cancelLiveSnapshot_internal()6051 int QCamera2HardwareInterface::cancelLiveSnapshot_internal() {
6052 int rc = NO_ERROR;
6053
6054 unconfigureAdvancedCapture();
6055 LOGH("Enable display frames again");
6056 setDisplaySkip(FALSE);
6057
6058 //wait for deferred (reprocess and jpeg) threads to finish
6059 waitDeferredWork(mReprocJob);
6060 waitDeferredWork(mJpegJob);
6061 //stop post processor
6062 m_postprocessor.stop();
6063
6064 // stop snapshot channel
6065 if (!mParameters.isTNRSnapshotEnabled()) {
6066 rc = stopChannel(QCAMERA_CH_TYPE_SNAPSHOT);
6067 } else {
6068 QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
6069 if (NULL != pChannel) {
6070 QCameraStream *pStream = NULL;
6071 for (uint32_t i = 0 ; i < pChannel->getNumOfStreams(); i++ ) {
6072 pStream = pChannel->getStreamByIndex(i);
6073 if ((NULL != pStream) &&
6074 (CAM_STREAM_TYPE_SNAPSHOT ==
6075 pStream->getMyType())) {
6076 break;
6077 }
6078 }
6079 if (pStream != NULL) {
6080 LOGD("REQUEST_FRAMES event for TNR snapshot");
6081 cam_stream_parm_buffer_t param;
6082 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
6083 param.type = CAM_STREAM_PARAM_TYPE_REQUEST_FRAMES;
6084 param.frameRequest.enableStream = 0;
6085 rc = pStream->setParameter(param);
6086 if (rc != NO_ERROR) {
6087 LOGE("Stream Event REQUEST_FRAMES failed");
6088 }
6089 }
6090 }
6091 }
6092
6093 return rc;
6094 }
6095
6096 /*===========================================================================
6097 * FUNCTION : putParameters
6098 *
6099 * DESCRIPTION: put parameters string impl
6100 *
6101 * PARAMETERS :
6102 * @parms : parameters string to be released
6103 *
6104 * RETURN : int32_t type of status
6105 * NO_ERROR -- success
6106 * none-zero failure code
6107 *==========================================================================*/
putParameters(char * parms)6108 int QCamera2HardwareInterface::putParameters(char *parms)
6109 {
6110 free(parms);
6111 return NO_ERROR;
6112 }
6113
6114 /*===========================================================================
6115 * FUNCTION : sendCommand
6116 *
6117 * DESCRIPTION: send command impl
6118 *
6119 * PARAMETERS :
6120 * @command : command to be executed
6121 * @arg1 : optional argument 1
6122 * @arg2 : optional argument 2
6123 *
6124 * RETURN : int32_t type of status
6125 * NO_ERROR -- success
6126 * none-zero failure code
6127 *==========================================================================*/
sendCommand(int32_t command,__unused int32_t & arg1,__unused int32_t & arg2)6128 int QCamera2HardwareInterface::sendCommand(int32_t command,
6129 __unused int32_t &arg1, __unused int32_t &arg2)
6130 {
6131 int rc = NO_ERROR;
6132
6133 switch (command) {
6134 #ifndef VANILLA_HAL
6135 case CAMERA_CMD_LONGSHOT_ON:
6136 arg1 = arg2 = 0;
6137 // Longshot can only be enabled when image capture
6138 // is not active.
6139 if ( !m_stateMachine.isCaptureRunning() ) {
6140 LOGI("Longshot Enabled");
6141 mLongshotEnabled = true;
6142 rc = mParameters.setLongshotEnable(mLongshotEnabled);
6143
6144 // Due to recent buffer count optimizations
6145 // ZSL might run with considerably less buffers
6146 // when not in longshot mode. Preview needs to
6147 // restart in this case.
6148 if (isZSLMode() && m_stateMachine.isPreviewRunning()) {
6149 QCameraChannel *pChannel = NULL;
6150 QCameraStream *pSnapStream = NULL;
6151 pChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
6152 if (NULL != pChannel) {
6153 QCameraStream *pStream = NULL;
6154 for (uint32_t i = 0; i < pChannel->getNumOfStreams(); i++) {
6155 pStream = pChannel->getStreamByIndex(i);
6156 if (pStream != NULL) {
6157 if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) {
6158 pSnapStream = pStream;
6159 break;
6160 }
6161 }
6162 }
6163 if (NULL != pSnapStream) {
6164 uint8_t required = 0;
6165 required = getBufNumRequired(CAM_STREAM_TYPE_SNAPSHOT);
6166 if (pSnapStream->getBufferCount() < required) {
6167 // We restart here, to reset the FPS and no
6168 // of buffers as per the requirement of longshot usecase.
6169 arg1 = QCAMERA_SM_EVT_RESTART_PERVIEW;
6170 if (getRelatedCamSyncInfo()->sync_control ==
6171 CAM_SYNC_RELATED_SENSORS_ON) {
6172 arg2 = QCAMERA_SM_EVT_DELAYED_RESTART;
6173 }
6174 }
6175 }
6176 }
6177 }
6178 //
6179 mPrepSnapRun = false;
6180 mCACDoneReceived = FALSE;
6181 } else {
6182 rc = NO_INIT;
6183 }
6184 break;
6185 case CAMERA_CMD_LONGSHOT_OFF:
6186 if ( mLongshotEnabled && m_stateMachine.isCaptureRunning() ) {
6187 cancelPicture();
6188 processEvt(QCAMERA_SM_EVT_SNAPSHOT_DONE, NULL);
6189 QCameraChannel *pZSLChannel = m_channels[QCAMERA_CH_TYPE_ZSL];
6190 if (isZSLMode() && (NULL != pZSLChannel) && mPrepSnapRun) {
6191 mCameraHandle->ops->stop_zsl_snapshot(
6192 mCameraHandle->camera_handle,
6193 pZSLChannel->getMyHandle());
6194 }
6195 }
6196 mPrepSnapRun = false;
6197 LOGI("Longshot Disabled");
6198 mLongshotEnabled = false;
6199 rc = mParameters.setLongshotEnable(mLongshotEnabled);
6200 mCACDoneReceived = FALSE;
6201 break;
6202 case CAMERA_CMD_HISTOGRAM_ON:
6203 case CAMERA_CMD_HISTOGRAM_OFF:
6204 rc = setHistogram(command == CAMERA_CMD_HISTOGRAM_ON? true : false);
6205 LOGH("Histogram -> %s",
6206 mParameters.isHistogramEnabled() ? "Enabled" : "Disabled");
6207 break;
6208 #endif
6209 case CAMERA_CMD_START_FACE_DETECTION:
6210 case CAMERA_CMD_STOP_FACE_DETECTION:
6211 mParameters.setFaceDetectionOption(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
6212 rc = setFaceDetection(command == CAMERA_CMD_START_FACE_DETECTION? true : false);
6213 LOGH("FaceDetection -> %s",
6214 mParameters.isFaceDetectionEnabled() ? "Enabled" : "Disabled");
6215 break;
6216 #ifndef VANILLA_HAL
6217 case CAMERA_CMD_HISTOGRAM_SEND_DATA:
6218 #endif
6219 default:
6220 rc = NO_ERROR;
6221 break;
6222 }
6223 return rc;
6224 }
6225
6226 /*===========================================================================
6227 * FUNCTION : registerFaceImage
6228 *
6229 * DESCRIPTION: register face image impl
6230 *
6231 * PARAMETERS :
6232 * @img_ptr : ptr to image buffer
6233 * @config : ptr to config struct about input image info
6234 * @faceID : [OUT] face ID to uniquely identifiy the registered face image
6235 *
6236 * RETURN : int32_t type of status
6237 * NO_ERROR -- success
6238 * none-zero failure code
6239 *==========================================================================*/
registerFaceImage(void * img_ptr,cam_pp_offline_src_config_t * config,int32_t & faceID)6240 int QCamera2HardwareInterface::registerFaceImage(void *img_ptr,
6241 cam_pp_offline_src_config_t *config,
6242 int32_t &faceID)
6243 {
6244 int rc = NO_ERROR;
6245 faceID = -1;
6246
6247 if (img_ptr == NULL || config == NULL) {
6248 LOGE("img_ptr or config is NULL");
6249 return BAD_VALUE;
6250 }
6251
6252 // allocate ion memory for source image
6253 QCameraHeapMemory *imgBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
6254 if (imgBuf == NULL) {
6255 LOGE("Unable to new heap memory obj for image buf");
6256 return NO_MEMORY;
6257 }
6258
6259 rc = imgBuf->allocate(1, config->input_buf_planes.plane_info.frame_len);
6260 if (rc < 0) {
6261 LOGE("Unable to allocate heap memory for image buf");
6262 delete imgBuf;
6263 return NO_MEMORY;
6264 }
6265
6266 void *pBufPtr = imgBuf->getPtr(0);
6267 if (pBufPtr == NULL) {
6268 LOGE("image buf is NULL");
6269 imgBuf->deallocate();
6270 delete imgBuf;
6271 return NO_MEMORY;
6272 }
6273 memcpy(pBufPtr, img_ptr, config->input_buf_planes.plane_info.frame_len);
6274 //Do cache ops before sending for reprocess
6275 imgBuf->cacheOps(0, ION_IOC_CLEAN_INV_CACHES);
6276
6277 cam_pp_feature_config_t pp_feature;
6278 memset(&pp_feature, 0, sizeof(cam_pp_feature_config_t));
6279 pp_feature.feature_mask = CAM_QCOM_FEATURE_REGISTER_FACE;
6280 QCameraReprocessChannel *pChannel =
6281 addOfflineReprocChannel(*config, pp_feature, NULL, NULL);
6282
6283 if (pChannel == NULL) {
6284 LOGE("fail to add offline reprocess channel");
6285 imgBuf->deallocate();
6286 delete imgBuf;
6287 return UNKNOWN_ERROR;
6288 }
6289
6290 rc = pChannel->start();
6291 if (rc != NO_ERROR) {
6292 LOGE("Cannot start reprocess channel");
6293 imgBuf->deallocate();
6294 delete imgBuf;
6295 delete pChannel;
6296 return rc;
6297 }
6298
6299 ssize_t bufSize = imgBuf->getSize(0);
6300 if (BAD_INDEX != bufSize) {
6301 rc = pChannel->doReprocess(imgBuf->getFd(0), imgBuf->getPtr(0),
6302 (size_t)bufSize, faceID);
6303 } else {
6304 LOGE("Failed to retrieve buffer size (bad index)");
6305 return UNKNOWN_ERROR;
6306 }
6307
6308 // done with register face image, free imgbuf and delete reprocess channel
6309 imgBuf->deallocate();
6310 delete imgBuf;
6311 imgBuf = NULL;
6312 pChannel->stop();
6313 delete pChannel;
6314 pChannel = NULL;
6315
6316 return rc;
6317 }
6318
6319 /*===========================================================================
6320 * FUNCTION : release
6321 *
6322 * DESCRIPTION: release camera resource impl
6323 *
6324 * PARAMETERS : none
6325 *
6326 * RETURN : int32_t type of status
6327 * NO_ERROR -- success
6328 * none-zero failure code
6329 *==========================================================================*/
release()6330 int QCamera2HardwareInterface::release()
6331 {
6332 // stop and delete all channels
6333 for (int i = 0; i <QCAMERA_CH_TYPE_MAX ; i++) {
6334 if (m_channels[i] != NULL) {
6335 stopChannel((qcamera_ch_type_enum_t)i);
6336 delChannel((qcamera_ch_type_enum_t)i);
6337 }
6338 }
6339
6340 return NO_ERROR;
6341 }
6342
6343 /*===========================================================================
6344 * FUNCTION : dump
6345 *
6346 * DESCRIPTION: camera status dump impl
6347 *
6348 * PARAMETERS :
6349 * @fd : fd for the buffer to be dumped with camera status
6350 *
6351 * RETURN : int32_t type of status
6352 * NO_ERROR -- success
6353 * none-zero failure code
6354 *==========================================================================*/
dump(int fd)6355 int QCamera2HardwareInterface::dump(int fd)
6356 {
6357 dprintf(fd, "\n Camera HAL information Begin \n");
6358 dprintf(fd, "Camera ID: %d \n", mCameraId);
6359 dprintf(fd, "StoreMetaDataInFrame: %d \n", mStoreMetaDataInFrame);
6360 dprintf(fd, "\n Configuration: %s", mParameters.dump().string());
6361 dprintf(fd, "\n State Information: %s", m_stateMachine.dump().string());
6362 dprintf(fd, "\n Camera HAL information End \n");
6363
6364 /* send UPDATE_DEBUG_LEVEL to the backend so that they can read the
6365 debug level property */
6366 mParameters.updateDebugLevel();
6367 return NO_ERROR;
6368 }
6369
6370 /*===========================================================================
6371 * FUNCTION : processAPI
6372 *
6373 * DESCRIPTION: process API calls from upper layer
6374 *
6375 * PARAMETERS :
6376 * @api : API to be processed
6377 * @api_payload : ptr to API payload if any
6378 *
6379 * RETURN : int32_t type of status
6380 * NO_ERROR -- success
6381 * none-zero failure code
6382 *==========================================================================*/
processAPI(qcamera_sm_evt_enum_t api,void * api_payload)6383 int QCamera2HardwareInterface::processAPI(qcamera_sm_evt_enum_t api, void *api_payload)
6384 {
6385 int ret = DEAD_OBJECT;
6386
6387 if (m_smThreadActive) {
6388 ret = m_stateMachine.procAPI(api, api_payload);
6389 }
6390
6391 return ret;
6392 }
6393
6394 /*===========================================================================
6395 * FUNCTION : processEvt
6396 *
6397 * DESCRIPTION: process Evt from backend via mm-camera-interface
6398 *
6399 * PARAMETERS :
6400 * @evt : event type to be processed
6401 * @evt_payload : ptr to event payload if any
6402 *
6403 * RETURN : int32_t type of status
6404 * NO_ERROR -- success
6405 * none-zero failure code
6406 *==========================================================================*/
processEvt(qcamera_sm_evt_enum_t evt,void * evt_payload)6407 int QCamera2HardwareInterface::processEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
6408 {
6409 return m_stateMachine.procEvt(evt, evt_payload);
6410 }
6411
6412 /*===========================================================================
6413 * FUNCTION : processSyncEvt
6414 *
6415 * DESCRIPTION: process synchronous Evt from backend
6416 *
6417 * PARAMETERS :
6418 * @evt : event type to be processed
6419 * @evt_payload : ptr to event payload if any
6420 *
6421 * RETURN : int32_t type of status
6422 * NO_ERROR -- success
6423 * none-zero failure code
6424 *==========================================================================*/
processSyncEvt(qcamera_sm_evt_enum_t evt,void * evt_payload)6425 int QCamera2HardwareInterface::processSyncEvt(qcamera_sm_evt_enum_t evt, void *evt_payload)
6426 {
6427 int rc = NO_ERROR;
6428
6429 pthread_mutex_lock(&m_evtLock);
6430 rc = processEvt(evt, evt_payload);
6431 if (rc == NO_ERROR) {
6432 memset(&m_evtResult, 0, sizeof(qcamera_api_result_t));
6433 while (m_evtResult.request_api != evt) {
6434 pthread_cond_wait(&m_evtCond, &m_evtLock);
6435 }
6436 rc = m_evtResult.status;
6437 }
6438 pthread_mutex_unlock(&m_evtLock);
6439
6440 return rc;
6441 }
6442
6443 /*===========================================================================
6444 * FUNCTION : evtHandle
6445 *
6446 * DESCRIPTION: Function registerd to mm-camera-interface to handle backend events
6447 *
6448 * PARAMETERS :
6449 * @camera_handle : event type to be processed
6450 * @evt : ptr to event
6451 * @user_data : user data ptr
6452 *
6453 * RETURN : none
6454 *==========================================================================*/
camEvtHandle(uint32_t,mm_camera_event_t * evt,void * user_data)6455 void QCamera2HardwareInterface::camEvtHandle(uint32_t /*camera_handle*/,
6456 mm_camera_event_t *evt,
6457 void *user_data)
6458 {
6459 QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)user_data;
6460 if (obj && evt) {
6461 mm_camera_event_t *payload =
6462 (mm_camera_event_t *)malloc(sizeof(mm_camera_event_t));
6463 if (NULL != payload) {
6464 *payload = *evt;
6465 //peek into the event, if this is an eztune event from server,
6466 //then we don't need to post it to the SM Qs, we shud directly
6467 //spawn a thread and get the job done (jpeg or raw snapshot)
6468 switch (payload->server_event_type) {
6469 case CAM_EVENT_TYPE_INT_TAKE_JPEG:
6470 //Received JPEG trigger from eztune
6471 if (false == obj->m_bIntJpegEvtPending) {
6472 pthread_mutex_lock(&obj->m_int_lock);
6473 obj->m_bIntJpegEvtPending = true;
6474 pthread_mutex_unlock(&obj->m_int_lock);
6475 obj->takePictureInternal();
6476 }
6477 free(payload);
6478 break;
6479 case CAM_EVENT_TYPE_INT_TAKE_RAW:
6480 //Received RAW trigger from eztune
6481 if (false == obj->m_bIntRawEvtPending) {
6482 pthread_mutex_lock(&obj->m_int_lock);
6483 obj->m_bIntRawEvtPending = true;
6484 pthread_mutex_unlock(&obj->m_int_lock);
6485 obj->takePictureInternal();
6486 }
6487 free(payload);
6488 break;
6489 case CAM_EVENT_TYPE_DAEMON_DIED:
6490 {
6491 Mutex::Autolock l(obj->mDefLock);
6492 obj->mDefCond.broadcast();
6493 LOGH("broadcast mDefCond signal\n");
6494 }
6495 default:
6496 obj->processEvt(QCAMERA_SM_EVT_EVT_NOTIFY, payload);
6497 break;
6498 }
6499 }
6500 } else {
6501 LOGE("NULL user_data");
6502 }
6503 }
6504
6505 /*===========================================================================
6506 * FUNCTION : jpegEvtHandle
6507 *
6508 * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events
6509 *
6510 * PARAMETERS :
6511 * @status : status of jpeg job
6512 * @client_hdl: jpeg client handle
6513 * @jobId : jpeg job Id
6514 * @p_ouput : ptr to jpeg output result struct
6515 * @userdata : user data ptr
6516 *
6517 * RETURN : none
6518 *==========================================================================*/
jpegEvtHandle(jpeg_job_status_t status,uint32_t,uint32_t jobId,mm_jpeg_output_t * p_output,void * userdata)6519 void QCamera2HardwareInterface::jpegEvtHandle(jpeg_job_status_t status,
6520 uint32_t /*client_hdl*/,
6521 uint32_t jobId,
6522 mm_jpeg_output_t *p_output,
6523 void *userdata)
6524 {
6525 QCamera2HardwareInterface *obj = (QCamera2HardwareInterface *)userdata;
6526 if (obj) {
6527 qcamera_jpeg_evt_payload_t *payload =
6528 (qcamera_jpeg_evt_payload_t *)malloc(sizeof(qcamera_jpeg_evt_payload_t));
6529 if (NULL != payload) {
6530 memset(payload, 0, sizeof(qcamera_jpeg_evt_payload_t));
6531 payload->status = status;
6532 payload->jobId = jobId;
6533 if (p_output != NULL) {
6534 payload->out_data = *p_output;
6535 }
6536 obj->processEvt(QCAMERA_SM_EVT_JPEG_EVT_NOTIFY, payload);
6537 }
6538 } else {
6539 LOGE("NULL user_data");
6540 }
6541 }
6542
6543 /*===========================================================================
6544 * FUNCTION : thermalEvtHandle
6545 *
6546 * DESCRIPTION: routine to handle thermal event notification
6547 *
6548 * PARAMETERS :
6549 * @level : thermal level
6550 * @userdata : userdata passed in during registration
6551 * @data : opaque data from thermal client
6552 *
6553 * RETURN : int32_t type of status
6554 * NO_ERROR -- success
6555 * none-zero failure code
6556 *==========================================================================*/
thermalEvtHandle(qcamera_thermal_level_enum_t * level,void * userdata,void * data)6557 int QCamera2HardwareInterface::thermalEvtHandle(
6558 qcamera_thermal_level_enum_t *level, void *userdata, void *data)
6559 {
6560 if (!mCameraOpened) {
6561 LOGH("Camera is not opened, no need to handle thermal evt");
6562 return NO_ERROR;
6563 }
6564
6565 // Make sure thermal events are logged
6566 LOGH("level = %d, userdata = %p, data = %p",
6567 *level, userdata, data);
6568 //We don't need to lockAPI, waitAPI here. QCAMERA_SM_EVT_THERMAL_NOTIFY
6569 // becomes an aync call. This also means we can only pass payload
6570 // by value, not by address.
6571 return processAPI(QCAMERA_SM_EVT_THERMAL_NOTIFY, (void *)level);
6572 }
6573
6574 /*===========================================================================
6575 * FUNCTION : sendEvtNotify
6576 *
6577 * DESCRIPTION: send event notify to notify thread
6578 *
6579 * PARAMETERS :
6580 * @msg_type: msg type to be sent
6581 * @ext1 : optional extension1
6582 * @ext2 : optional extension2
6583 *
6584 * RETURN : int32_t type of status
6585 * NO_ERROR -- success
6586 * none-zero failure code
6587 *==========================================================================*/
sendEvtNotify(int32_t msg_type,int32_t ext1,int32_t ext2)6588 int32_t QCamera2HardwareInterface::sendEvtNotify(int32_t msg_type,
6589 int32_t ext1,
6590 int32_t ext2)
6591 {
6592 qcamera_callback_argm_t cbArg;
6593 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
6594 cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
6595 cbArg.msg_type = msg_type;
6596 cbArg.ext1 = ext1;
6597 cbArg.ext2 = ext2;
6598 return m_cbNotifier.notifyCallback(cbArg);
6599 }
6600
6601 /*===========================================================================
6602 * FUNCTION : processAEInfo
6603 *
6604 * DESCRIPTION: process AE updates
6605 *
6606 * PARAMETERS :
6607 * @ae_params: current AE parameters
6608 *
6609 * RETURN : None
6610 *==========================================================================*/
processAEInfo(cam_3a_params_t & ae_params)6611 int32_t QCamera2HardwareInterface::processAEInfo(cam_3a_params_t &ae_params)
6612 {
6613 mParameters.updateAEInfo(ae_params);
6614 if (mParameters.isInstantAECEnabled()) {
6615 // Reset Instant AEC info only if instant aec enabled.
6616 bool bResetInstantAec = false;
6617 if (ae_params.settled) {
6618 // If AEC settled, reset instant AEC
6619 bResetInstantAec = true;
6620 } else if ((mParameters.isInstantCaptureEnabled()) &&
6621 (mInstantAecFrameCount >= mParameters.getAecFrameBoundValue())) {
6622 // if AEC not settled, and instant capture enabled,
6623 // reset instant AEC only when frame count is
6624 // more or equal to AEC frame bound value.
6625 bResetInstantAec = true;
6626 } else if ((mParameters.isInstantAECEnabled()) &&
6627 (mInstantAecFrameCount >= mParameters.getAecSkipDisplayFrameBound())) {
6628 // if AEC not settled, and only instant AEC enabled,
6629 // reset instant AEC only when frame count is
6630 // more or equal to AEC skip display frame bound value.
6631 bResetInstantAec = true;
6632 }
6633
6634 if (bResetInstantAec) {
6635 LOGD("setting instant AEC to false");
6636 mParameters.setInstantAEC(false, true);
6637 mInstantAecFrameCount = 0;
6638 }
6639 }
6640 return NO_ERROR;
6641 }
6642
6643 /*===========================================================================
6644 * FUNCTION : processFocusPositionInfo
6645 *
6646 * DESCRIPTION: process AF updates
6647 *
6648 * PARAMETERS :
6649 * @cur_pos_info: current lens position
6650 *
6651 * RETURN : None
6652 *==========================================================================*/
processFocusPositionInfo(cam_focus_pos_info_t & cur_pos_info)6653 int32_t QCamera2HardwareInterface::processFocusPositionInfo(cam_focus_pos_info_t &cur_pos_info)
6654 {
6655 mParameters.updateCurrentFocusPosition(cur_pos_info);
6656 return NO_ERROR;
6657 }
6658
6659 /*===========================================================================
6660 * FUNCTION : processAutoFocusEvent
6661 *
6662 * DESCRIPTION: process auto focus event
6663 *
6664 * PARAMETERS :
6665 * @focus_data: struct containing auto focus result info
6666 *
6667 * RETURN : int32_t type of status
6668 * NO_ERROR -- success
6669 * none-zero failure code
6670 *==========================================================================*/
processAutoFocusEvent(cam_auto_focus_data_t & focus_data)6671 int32_t QCamera2HardwareInterface::processAutoFocusEvent(cam_auto_focus_data_t &focus_data)
6672 {
6673 int32_t ret = NO_ERROR;
6674 LOGH("E");
6675
6676 if (getRelatedCamSyncInfo()->mode == CAM_MODE_SECONDARY) {
6677 // Ignore focus updates
6678 LOGH("X Secondary Camera, no need to process!! ");
6679 return ret;
6680 }
6681 cam_focus_mode_type focusMode = mParameters.getFocusMode();
6682 LOGH("[AF_DBG] focusMode=%d, focusState=%d isDepth=%d",
6683 focusMode, focus_data.focus_state, focus_data.isDepth);
6684
6685 switch (focusMode) {
6686 case CAM_FOCUS_MODE_AUTO:
6687 case CAM_FOCUS_MODE_MACRO:
6688 // ignore AF event if AF was already cancelled meanwhile
6689 if (!mActiveAF) {
6690 break;
6691 }
6692 // If the HAL focus mode is different from AF INFINITY focus mode, send event to app
6693 if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) &&
6694 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
6695 ret = sendEvtNotify(CAMERA_MSG_FOCUS, true, 0);
6696 mActiveAF = false; // reset the mActiveAF in this special case
6697 break;
6698 }
6699
6700 //while transitioning from CAF->Auto/Macro, we might receive CAF related
6701 //events (PASSIVE_*) due to timing. Ignore such events if any.
6702 if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN) ||
6703 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6704 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED)) {
6705 break;
6706 }
6707
6708 //This is just an intermediate update to HAL indicating focus is in progress. No need
6709 //to send this event to app. Same applies to INACTIVE state as well.
6710 if ((focus_data.focus_state == CAM_AF_STATE_ACTIVE_SCAN) ||
6711 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
6712 break;
6713 }
6714 // update focus distance
6715 mParameters.updateFocusDistances(&focus_data.focus_dist);
6716
6717 //flush any old snapshot frames in ZSL Q which are not focused.
6718 if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) {
6719 QCameraPicChannel *pZSLChannel =
6720 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
6721 if (NULL != pZSLChannel) {
6722 //flush the zsl-buffer
6723 uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx;
6724 LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx);
6725 pZSLChannel->flushSuperbuffer(flush_frame_idx);
6726 }
6727 }
6728
6729 //send event to app finally
6730 LOGI("Send AF DOne event to app");
6731 ret = sendEvtNotify(CAMERA_MSG_FOCUS,
6732 (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED), 0);
6733 break;
6734 case CAM_FOCUS_MODE_CONTINOUS_VIDEO:
6735 case CAM_FOCUS_MODE_CONTINOUS_PICTURE:
6736
6737 // If the HAL focus mode is different from AF INFINITY focus mode, send event to app
6738 if ((focus_data.focus_mode == CAM_FOCUS_MODE_INFINITY) &&
6739 (focus_data.focus_state == CAM_AF_STATE_INACTIVE)) {
6740 ret = sendEvtNotify(CAMERA_MSG_FOCUS, false, 0);
6741 mActiveAF = false; // reset the mActiveAF in this special case
6742 break;
6743 }
6744
6745 //If AutoFocus() is triggered while in CAF mode, ignore all CAF events (PASSIVE_*) and
6746 //process/wait for only ACTIVE_* events.
6747 if (((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6748 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) ||
6749 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN)) && mActiveAF) {
6750 break;
6751 }
6752
6753 if (!bDepthAFCallbacks && focus_data.isDepth &&
6754 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN)) {
6755 LOGD("Skip sending scan state to app, if depth focus");
6756 break;
6757 }
6758
6759 //These are the AF states for which we need to send notification to app in CAF mode.
6760 //This includes both regular CAF (PASSIVE) events as well as ACTIVE events ( in case
6761 //AF is triggered while in CAF mode)
6762 if ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6763 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_UNFOCUSED) ||
6764 (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) ||
6765 (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) {
6766
6767 // update focus distance
6768 mParameters.updateFocusDistances(&focus_data.focus_dist);
6769
6770 if (mParameters.isZSLMode() && focus_data.flush_info.needFlush ) {
6771 QCameraPicChannel *pZSLChannel =
6772 (QCameraPicChannel *)m_channels[QCAMERA_CH_TYPE_ZSL];
6773 if (NULL != pZSLChannel) {
6774 //flush the zsl-buffer
6775 uint32_t flush_frame_idx = focus_data.flush_info.focused_frame_idx;
6776 LOGD("flush the zsl-buffer before frame = %u.", flush_frame_idx);
6777 pZSLChannel->flushSuperbuffer(flush_frame_idx);
6778 }
6779 }
6780
6781 if (mActiveAF) {
6782 LOGI("Send AF Done event to app");
6783 }
6784 ret = sendEvtNotify(CAMERA_MSG_FOCUS,
6785 ((focus_data.focus_state == CAM_AF_STATE_PASSIVE_FOCUSED) ||
6786 (focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED)), 0);
6787 }
6788 ret = sendEvtNotify(CAMERA_MSG_FOCUS_MOVE,
6789 (focus_data.focus_state == CAM_AF_STATE_PASSIVE_SCAN), 0);
6790 break;
6791 case CAM_FOCUS_MODE_INFINITY:
6792 case CAM_FOCUS_MODE_FIXED:
6793 case CAM_FOCUS_MODE_EDOF:
6794 default:
6795 LOGH("no ops for autofocus event in focusmode %d", focusMode);
6796 break;
6797 }
6798
6799 //Reset mActiveAF once we receive focus done event
6800 if ((focus_data.focus_state == CAM_AF_STATE_FOCUSED_LOCKED) ||
6801 (focus_data.focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED)) {
6802 mActiveAF = false;
6803 }
6804
6805 LOGH("X");
6806 return ret;
6807 }
6808
6809 /*===========================================================================
6810 * FUNCTION : processZoomEvent
6811 *
6812 * DESCRIPTION: process zoom event
6813 *
6814 * PARAMETERS :
6815 * @crop_info : crop info as a result of zoom operation
6816 *
6817 * RETURN : int32_t type of status
6818 * NO_ERROR -- success
6819 * none-zero failure code
6820 *==========================================================================*/
processZoomEvent(cam_crop_data_t & crop_info)6821 int32_t QCamera2HardwareInterface::processZoomEvent(cam_crop_data_t &crop_info)
6822 {
6823 int32_t ret = NO_ERROR;
6824
6825 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
6826 if (m_channels[i] != NULL) {
6827 ret = m_channels[i]->processZoomDone(mPreviewWindow, crop_info);
6828 }
6829 }
6830 return ret;
6831 }
6832
6833 /*===========================================================================
6834 * FUNCTION : processZSLCaptureDone
6835 *
6836 * DESCRIPTION: process ZSL capture done events
6837 *
6838 * PARAMETERS : None
6839 *
6840 * RETURN : int32_t type of status
6841 * NO_ERROR -- success
6842 * none-zero failure code
6843 *==========================================================================*/
processZSLCaptureDone()6844 int32_t QCamera2HardwareInterface::processZSLCaptureDone()
6845 {
6846 int rc = NO_ERROR;
6847
6848 if (++mInputCount >= mParameters.getBurstCountForAdvancedCapture()) {
6849 rc = unconfigureAdvancedCapture();
6850 }
6851
6852 return rc;
6853 }
6854
6855 /*===========================================================================
6856 * FUNCTION : processRetroAECUnlock
6857 *
6858 * DESCRIPTION: process retro burst AEC unlock events
6859 *
6860 * PARAMETERS : None
6861 *
6862 * RETURN : int32_t type of status
6863 * NO_ERROR -- success
6864 * none-zero failure code
6865 *==========================================================================*/
processRetroAECUnlock()6866 int32_t QCamera2HardwareInterface::processRetroAECUnlock()
6867 {
6868 int rc = NO_ERROR;
6869
6870 LOGH("LED assisted AF Release AEC Lock");
6871 rc = mParameters.setAecLock("false");
6872 if (NO_ERROR != rc) {
6873 LOGE("Error setting AEC lock");
6874 return rc;
6875 }
6876
6877 rc = mParameters.commitParameters();
6878 if (NO_ERROR != rc) {
6879 LOGE("Error during camera parameter commit");
6880 } else {
6881 m_bLedAfAecLock = FALSE;
6882 }
6883
6884 return rc;
6885 }
6886
6887 /*===========================================================================
6888 * FUNCTION : processHDRData
6889 *
6890 * DESCRIPTION: process HDR scene events
6891 *
6892 * PARAMETERS :
6893 * @hdr_scene : HDR scene event data
6894 *
6895 * RETURN : int32_t type of status
6896 * NO_ERROR -- success
6897 * none-zero failure code
6898 *==========================================================================*/
processHDRData(__unused cam_asd_hdr_scene_data_t hdr_scene)6899 int32_t QCamera2HardwareInterface::processHDRData(
6900 __unused cam_asd_hdr_scene_data_t hdr_scene)
6901 {
6902 int rc = NO_ERROR;
6903
6904 #ifndef VANILLA_HAL
6905 if (hdr_scene.is_hdr_scene &&
6906 (hdr_scene.hdr_confidence > HDR_CONFIDENCE_THRESHOLD) &&
6907 mParameters.isAutoHDREnabled()) {
6908 m_HDRSceneEnabled = true;
6909 } else {
6910 m_HDRSceneEnabled = false;
6911 }
6912 mParameters.setHDRSceneEnable(m_HDRSceneEnabled);
6913
6914 if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) {
6915
6916 size_t data_len = sizeof(int);
6917 size_t buffer_len = 1 *sizeof(int) //meta type
6918 + 1 *sizeof(int) //data len
6919 + 1 *sizeof(int); //data
6920 camera_memory_t *hdrBuffer = mGetMemory(-1,
6921 buffer_len,
6922 1,
6923 mCallbackCookie);
6924 if ( NULL == hdrBuffer ) {
6925 LOGE("Not enough memory for auto HDR data");
6926 return NO_MEMORY;
6927 }
6928
6929 int *pHDRData = (int *)hdrBuffer->data;
6930 if (pHDRData == NULL) {
6931 LOGE("memory data ptr is NULL");
6932 return UNKNOWN_ERROR;
6933 }
6934
6935 pHDRData[0] = CAMERA_META_DATA_HDR;
6936 pHDRData[1] = (int)data_len;
6937 pHDRData[2] = m_HDRSceneEnabled;
6938
6939 qcamera_callback_argm_t cbArg;
6940 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
6941 cbArg.cb_type = QCAMERA_DATA_CALLBACK;
6942 cbArg.msg_type = CAMERA_MSG_META_DATA;
6943 cbArg.data = hdrBuffer;
6944 cbArg.user_data = hdrBuffer;
6945 cbArg.cookie = this;
6946 cbArg.release_cb = releaseCameraMemory;
6947 rc = m_cbNotifier.notifyCallback(cbArg);
6948 if (rc != NO_ERROR) {
6949 LOGE("fail sending auto HDR notification");
6950 hdrBuffer->release(hdrBuffer);
6951 }
6952 }
6953
6954 LOGH("hdr_scene_data: processHDRData: %d %f",
6955 hdr_scene.is_hdr_scene,
6956 hdr_scene.hdr_confidence);
6957
6958 #endif
6959 return rc;
6960 }
6961
6962 /*===========================================================================
6963 * FUNCTION : processLEDCalibration
6964 *
6965 * DESCRIPTION: process LED calibration result
6966 *
6967 * PARAMETERS :
6968 * @value : Calibaration result
6969 *
6970 * RETURN : int32_t type of status
6971 * NO_ERROR -- success
6972 * none-zero failure code
6973 *==========================================================================*/
processLEDCalibration(int32_t value)6974 int32_t QCamera2HardwareInterface::processLEDCalibration(int32_t value)
6975 {
6976 int32_t rc = NO_ERROR;
6977 #ifndef VANILLA_HAL
6978 if (mParameters.getDualLedCalibration()) {
6979 LOGH("Dual LED calibration value = %d", value);
6980 int32_t data_len = sizeof(value);
6981 int32_t buffer_len = sizeof(int) //meta type
6982 + sizeof(int) //data len
6983 + data_len; //data
6984 camera_memory_t *buffer = mGetMemory(-1,
6985 buffer_len, 1, mCallbackCookie);
6986 if ( NULL == buffer ) {
6987 LOGE("Not enough memory for data");
6988 return NO_MEMORY;
6989 }
6990
6991 int *pData = (int *)buffer->data;
6992 if (pData == NULL) {
6993 LOGE("memory data ptr is NULL");
6994 buffer->release(buffer);
6995 return UNKNOWN_ERROR;
6996 }
6997
6998 pData[0] = QCAMERA_METADATA_LED_CALIB;
6999 pData[1] = (int)data_len;
7000 pData[2] = value;
7001
7002 qcamera_callback_argm_t cbArg;
7003 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
7004 cbArg.cb_type = QCAMERA_DATA_CALLBACK;
7005 cbArg.msg_type = CAMERA_MSG_META_DATA;
7006 cbArg.data = buffer;
7007 cbArg.user_data = buffer;
7008 cbArg.cookie = this;
7009 cbArg.release_cb = releaseCameraMemory;
7010 int32_t rc = m_cbNotifier.notifyCallback(cbArg);
7011 if (rc != NO_ERROR) {
7012 LOGE("fail sending notification");
7013 buffer->release(buffer);
7014 }
7015 }
7016 #else
7017 (void)value; // unused
7018 #endif
7019 return rc;
7020 }
7021
7022
7023 /*===========================================================================
7024 * FUNCTION : transAwbMetaToParams
7025 *
7026 * DESCRIPTION: translate awb params from metadata callback to QCameraParametersIntf
7027 *
7028 * PARAMETERS :
7029 * @awb_params : awb params from metadata callback
7030 *
7031 * RETURN : int32_t type of status
7032 * NO_ERROR -- success
7033 * none-zero failure code
7034 *==========================================================================*/
transAwbMetaToParams(cam_awb_params_t & awb_params)7035 int32_t QCamera2HardwareInterface::transAwbMetaToParams(cam_awb_params_t &awb_params)
7036 {
7037 mParameters.updateAWBParams(awb_params);
7038 return NO_ERROR;
7039 }
7040
7041 /*===========================================================================
7042 * FUNCTION : processPrepSnapshotDone
7043 *
7044 * DESCRIPTION: process prep snapshot done event
7045 *
7046 * PARAMETERS :
7047 * @prep_snapshot_state : state of prepare snapshot done. In other words,
7048 * i.e. whether need future frames for capture.
7049 *
7050 * RETURN : int32_t type of status
7051 * NO_ERROR -- success
7052 * none-zero failure code
7053 *==========================================================================*/
processPrepSnapshotDoneEvent(cam_prep_snapshot_state_t prep_snapshot_state)7054 int32_t QCamera2HardwareInterface::processPrepSnapshotDoneEvent(
7055 cam_prep_snapshot_state_t prep_snapshot_state)
7056 {
7057 int32_t ret = NO_ERROR;
7058 LOGI("[KPI Perf]: Received PREPARE SANSPHOT Done event state = %d",
7059 prep_snapshot_state);
7060 if (m_channels[QCAMERA_CH_TYPE_ZSL] &&
7061 prep_snapshot_state == NEED_FUTURE_FRAME) {
7062 LOGH("already handled in mm-camera-intf, no ops here");
7063 if (isRetroPicture()) {
7064 mParameters.setAecLock("true");
7065 mParameters.commitParameters();
7066 m_bLedAfAecLock = TRUE;
7067 }
7068 }
7069 return ret;
7070 }
7071
7072 /*===========================================================================
7073 * FUNCTION : processASDUpdate
7074 *
7075 * DESCRIPTION: process ASD update event
7076 *
7077 * PARAMETERS :
7078 * @scene: selected scene mode
7079 *
7080 * RETURN : int32_t type of status
7081 * NO_ERROR -- success
7082 * none-zero failure code
7083 *==========================================================================*/
processASDUpdate(__unused cam_asd_decision_t asd_decision)7084 int32_t QCamera2HardwareInterface::processASDUpdate(
7085 __unused cam_asd_decision_t asd_decision)
7086 {
7087 #ifndef VANILLA_HAL
7088 if ( msgTypeEnabled(CAMERA_MSG_META_DATA) ) {
7089 size_t data_len = sizeof(cam_auto_scene_t);
7090 size_t buffer_len = 1 *sizeof(int) //meta type
7091 + 1 *sizeof(int) //data len
7092 + data_len; //data
7093 camera_memory_t *asdBuffer = mGetMemory(-1,
7094 buffer_len, 1, mCallbackCookie);
7095 if ( NULL == asdBuffer ) {
7096 LOGE("Not enough memory for histogram data");
7097 return NO_MEMORY;
7098 }
7099
7100 int *pASDData = (int *)asdBuffer->data;
7101 if (pASDData == NULL) {
7102 LOGE("memory data ptr is NULL");
7103 return UNKNOWN_ERROR;
7104 }
7105
7106 pASDData[0] = CAMERA_META_DATA_ASD;
7107 pASDData[1] = (int)data_len;
7108 pASDData[2] = asd_decision.detected_scene;
7109
7110 qcamera_callback_argm_t cbArg;
7111 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
7112 cbArg.cb_type = QCAMERA_DATA_CALLBACK;
7113 cbArg.msg_type = CAMERA_MSG_META_DATA;
7114 cbArg.data = asdBuffer;
7115 cbArg.user_data = asdBuffer;
7116 cbArg.cookie = this;
7117 cbArg.release_cb = releaseCameraMemory;
7118 int32_t rc = m_cbNotifier.notifyCallback(cbArg);
7119 if (rc != NO_ERROR) {
7120 LOGE("fail sending notification");
7121 asdBuffer->release(asdBuffer);
7122 }
7123 }
7124 #endif
7125 return NO_ERROR;
7126 }
7127
7128 /*===========================================================================
7129 * FUNCTION : processJpegNotify
7130 *
7131 * DESCRIPTION: process jpeg event
7132 *
7133 * PARAMETERS :
7134 * @jpeg_evt: ptr to jpeg event payload
7135 *
7136 * RETURN : int32_t type of status
7137 * NO_ERROR -- success
7138 * none-zero failure code
7139 *==========================================================================*/
processJpegNotify(qcamera_jpeg_evt_payload_t * jpeg_evt)7140 int32_t QCamera2HardwareInterface::processJpegNotify(qcamera_jpeg_evt_payload_t *jpeg_evt)
7141 {
7142 return m_postprocessor.processJpegEvt(jpeg_evt);
7143 }
7144
7145
7146 /*===========================================================================
7147 * FUNCTION : processDualCamFovControl
7148 *
7149 * DESCRIPTION: Based on the result collected from FOV control-
7150 * 1. Switch the master camera if needed
7151 * 2. Toggle the Low Power Mode for slave camera
7152 *
7153 * PARAMETERS : none
7154 *
7155 * RETURN : none
7156 *==========================================================================*/
processDualCamFovControl()7157 void QCamera2HardwareInterface::processDualCamFovControl()
7158 {
7159 uint32_t activeCameras;
7160 bool bundledSnapshot;
7161 fov_control_result_t fovControlResult;
7162 cam_sync_type_t camMasterSnapshot;
7163
7164 if (!isDualCamera()) {
7165 return;
7166 }
7167
7168 fovControlResult = m_pFovControl->getFovControlResult();
7169
7170 if (fovControlResult.isValid) {
7171 activeCameras = fovControlResult.activeCameras;
7172 bundledSnapshot = fovControlResult.snapshotPostProcess;
7173 camMasterSnapshot = fovControlResult.camMasterPreview;
7174
7175 processCameraControl(activeCameras, bundledSnapshot);
7176 switchCameraCb(fovControlResult.camMasterPreview);
7177 }
7178 }
7179
7180 /*===========================================================================
7181 * FUNCTION : processCameraControl
7182 *
7183 * DESCRIPTION: Suspend and resume camera
7184 *
7185 * PARAMETERS :
7186 *
7187 * RETURN : int32_t type of status
7188 * NO_ERROR -- success
7189 * none-zero failure code
7190 *==========================================================================*/
processCameraControl(uint32_t activeCameras,bool bundledSnapshot)7191 int32_t QCamera2HardwareInterface::processCameraControl(
7192 uint32_t activeCameras,
7193 bool bundledSnapshot)
7194 {
7195 int32_t ret = NO_ERROR;
7196
7197 //Update camera status to internal channel
7198 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
7199 if (m_channels[i] != NULL && m_channels[i]->isDualChannel()) {
7200 ret = m_channels[i]->processCameraControl(activeCameras, bundledSnapshot);
7201 if (ret != NO_ERROR) {
7202 LOGE("Channel Switch Failed");
7203 break;
7204 }
7205 }
7206 }
7207
7208 if ((activeCameras != mActiveCameras) ||
7209 ((activeCameras == MM_CAMERA_DUAL_CAM) && (bundledSnapshot != mBundledSnapshot))) {
7210
7211 if (activeCameras != mActiveCameras) {
7212 //Set camera controls to parameter and back-end
7213 ret = mParameters.setCameraControls(activeCameras);
7214 }
7215
7216 mParameters.setBundledSnapshot(bundledSnapshot);
7217 mParameters.setNumOfSnapshot();
7218
7219 LOGH("mActiveCameras = %d to %d, bundledSnapshot = %d to %d",
7220 mActiveCameras, activeCameras, mBundledSnapshot, bundledSnapshot);
7221 mActiveCameras = activeCameras;
7222 mBundledSnapshot = bundledSnapshot;
7223 }
7224
7225 return ret;
7226 }
7227
7228 /*===========================================================================
7229 * FUNCTION : switchCameraCb
7230 *
7231 * DESCRIPTION: switch camera's in case of dual camera
7232 *
7233 * PARAMETERS :
7234 * @camMaster : Master camera
7235 *
7236 * RETURN : int32_t type of status
7237 * NO_ERROR -- success
7238 * none-zero failure code
7239 *==========================================================================*/
switchCameraCb(uint32_t camMaster)7240 int32_t QCamera2HardwareInterface::switchCameraCb(uint32_t camMaster)
7241 {
7242 int32_t ret = NO_ERROR;
7243
7244 if (mActiveCameras & camMaster) {
7245 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
7246 if (m_channels[i] != NULL && m_channels[i]->isDualChannel()) {
7247 ret = m_channels[i]->switchChannelCb(camMaster);
7248 if (ret != NO_ERROR) {
7249 LOGE("Channel Switch Failed");
7250 break;
7251 }
7252 }
7253 }
7254
7255 if (mMasterCamera != camMaster) {
7256 if (ret == NO_ERROR) {
7257 //Trigger Event to modules to update Master info
7258 mParameters.setSwitchCamera(camMaster);
7259 }
7260 }
7261 // Update master camera
7262 mMasterCamera = camMaster;
7263 }
7264
7265 return ret;
7266 }
7267
7268 /*===========================================================================
7269 * FUNCTION : lockAPI
7270 *
7271 * DESCRIPTION: lock to process API
7272 *
7273 * PARAMETERS : none
7274 *
7275 * RETURN : none
7276 *==========================================================================*/
lockAPI()7277 void QCamera2HardwareInterface::lockAPI()
7278 {
7279 pthread_mutex_lock(&m_lock);
7280 }
7281
7282 /*===========================================================================
7283 * FUNCTION : waitAPIResult
7284 *
7285 * DESCRIPTION: wait for API result coming back. This is a blocking call, it will
7286 * return only cerntain API event type arrives
7287 *
7288 * PARAMETERS :
7289 * @api_evt : API event type
7290 *
7291 * RETURN : none
7292 *==========================================================================*/
waitAPIResult(qcamera_sm_evt_enum_t api_evt,qcamera_api_result_t * apiResult)7293 void QCamera2HardwareInterface::waitAPIResult(qcamera_sm_evt_enum_t api_evt,
7294 qcamera_api_result_t *apiResult)
7295 {
7296 LOGD("wait for API result of evt (%d)", api_evt);
7297 int resultReceived = 0;
7298 while (!resultReceived) {
7299 pthread_cond_wait(&m_cond, &m_lock);
7300 if (m_apiResultList != NULL) {
7301 api_result_list *apiResultList = m_apiResultList;
7302 api_result_list *apiResultListPrevious = m_apiResultList;
7303 while (apiResultList != NULL) {
7304 if (apiResultList->result.request_api == api_evt) {
7305 resultReceived = 1;
7306 *apiResult = apiResultList->result;
7307 apiResultListPrevious->next = apiResultList->next;
7308 if (apiResultList == m_apiResultList) {
7309 m_apiResultList = apiResultList->next;
7310 }
7311 free(apiResultList);
7312 break;
7313 }
7314 else {
7315 apiResultListPrevious = apiResultList;
7316 apiResultList = apiResultList->next;
7317 }
7318 }
7319 }
7320 }
7321 LOGD("return (%d) from API result wait for evt (%d)",
7322 apiResult->status, api_evt);
7323 }
7324
7325
7326 /*===========================================================================
7327 * FUNCTION : unlockAPI
7328 *
7329 * DESCRIPTION: API processing is done, unlock
7330 *
7331 * PARAMETERS : none
7332 *
7333 * RETURN : none
7334 *==========================================================================*/
unlockAPI()7335 void QCamera2HardwareInterface::unlockAPI()
7336 {
7337 pthread_mutex_unlock(&m_lock);
7338 }
7339
7340 /*===========================================================================
7341 * FUNCTION : signalAPIResult
7342 *
7343 * DESCRIPTION: signal condition viarable that cerntain API event type arrives
7344 *
7345 * PARAMETERS :
7346 * @result : API result
7347 *
7348 * RETURN : none
7349 *==========================================================================*/
signalAPIResult(qcamera_api_result_t * result)7350 void QCamera2HardwareInterface::signalAPIResult(qcamera_api_result_t *result)
7351 {
7352
7353 pthread_mutex_lock(&m_lock);
7354 api_result_list *apiResult = (api_result_list *)malloc(sizeof(api_result_list));
7355 if (apiResult == NULL) {
7356 LOGE("ERROR: malloc for api result failed, Result will not be sent");
7357 goto malloc_failed;
7358 }
7359 apiResult->result = *result;
7360 apiResult->next = NULL;
7361 if (m_apiResultList == NULL) m_apiResultList = apiResult;
7362 else {
7363 api_result_list *apiResultList = m_apiResultList;
7364 while(apiResultList->next != NULL) apiResultList = apiResultList->next;
7365 apiResultList->next = apiResult;
7366 }
7367 malloc_failed:
7368 pthread_cond_broadcast(&m_cond);
7369 pthread_mutex_unlock(&m_lock);
7370 }
7371
7372 /*===========================================================================
7373 * FUNCTION : signalEvtResult
7374 *
7375 * DESCRIPTION: signal condition variable that certain event was processed
7376 *
7377 * PARAMETERS :
7378 * @result : Event result
7379 *
7380 * RETURN : none
7381 *==========================================================================*/
signalEvtResult(qcamera_api_result_t * result)7382 void QCamera2HardwareInterface::signalEvtResult(qcamera_api_result_t *result)
7383 {
7384 pthread_mutex_lock(&m_evtLock);
7385 m_evtResult = *result;
7386 pthread_cond_signal(&m_evtCond);
7387 pthread_mutex_unlock(&m_evtLock);
7388 }
7389
prepareRawStream(QCameraChannel * curChannel)7390 int32_t QCamera2HardwareInterface::prepareRawStream(QCameraChannel *curChannel)
7391 {
7392 int32_t rc = NO_ERROR;
7393 cam_dimension_t str_dim,max_dim;
7394 QCameraChannel *pChannel;
7395
7396 max_dim.width = 0;
7397 max_dim.height = 0;
7398
7399 for (int j = 0; j < QCAMERA_CH_TYPE_MAX; j++) {
7400 if (m_channels[j] != NULL) {
7401 pChannel = m_channels[j];
7402 for (uint8_t i = 0; i < pChannel->getNumOfStreams(); i++) {
7403 QCameraStream *pStream = pChannel->getStreamByIndex(i);
7404 if (pStream != NULL) {
7405 if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
7406 || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) {
7407 continue;
7408 }
7409 pStream->getFrameDimension(str_dim);
7410 if (str_dim.width > max_dim.width) {
7411 max_dim.width = str_dim.width;
7412 }
7413 if (str_dim.height > max_dim.height) {
7414 max_dim.height = str_dim.height;
7415 }
7416 }
7417 }
7418 }
7419 }
7420
7421 for (uint8_t i = 0; i < curChannel->getNumOfStreams(); i++) {
7422 QCameraStream *pStream = curChannel->getStreamByIndex(i);
7423 if (pStream != NULL) {
7424 if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
7425 || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))) {
7426 continue;
7427 }
7428 pStream->getFrameDimension(str_dim);
7429 if (str_dim.width > max_dim.width) {
7430 max_dim.width = str_dim.width;
7431 }
7432 if (str_dim.height > max_dim.height) {
7433 max_dim.height = str_dim.height;
7434 }
7435 }
7436 }
7437 rc = mParameters.updateRAW(max_dim);
7438 return rc;
7439 }
7440
7441 /*===========================================================================
7442 * FUNCTION : getPaddingInfo
7443 *
7444 * DESCRIPTION: calculate padding per stream
7445 *
7446 * PARAMETERS :
7447 * @streamType : type of stream to be added
7448 * @padding_info : Padding info. Output
7449 *
7450 * RETURN : int32_t type of status
7451 * NO_ERROR -- success
7452 * none-zero failure code
7453 *==========================================================================*/
getPaddingInfo(cam_stream_type_t streamType,cam_padding_info_t * padding_info)7454 int32_t QCamera2HardwareInterface::getPaddingInfo(cam_stream_type_t streamType,
7455 cam_padding_info_t *padding_info)
7456 {
7457 int32_t rc = NO_ERROR;
7458 if (streamType == CAM_STREAM_TYPE_ANALYSIS) {
7459 cam_analysis_info_t analysisInfo;
7460 cam_feature_mask_t featureMask;
7461
7462 featureMask = 0;
7463 mParameters.getStreamPpMask(CAM_STREAM_TYPE_ANALYSIS, featureMask);
7464 rc = mParameters.getAnalysisInfo(
7465 ((mParameters.getRecordingHintValue() == true) &&
7466 mParameters.fdModeInVideo()),
7467 featureMask,
7468 &analysisInfo);
7469 if (rc != NO_ERROR) {
7470 LOGE("getAnalysisInfo failed, ret = %d", rc);
7471 return rc;
7472 }
7473
7474 *padding_info = analysisInfo.analysis_padding_info;
7475 } else {
7476 *padding_info =
7477 gCamCapability[mCameraId]->padding_info;
7478 if (streamType == CAM_STREAM_TYPE_PREVIEW || streamType == CAM_STREAM_TYPE_POSTVIEW) {
7479 padding_info->width_padding = mSurfaceStridePadding;
7480 padding_info->height_padding = CAM_PAD_TO_2;
7481 }
7482 if((!needReprocess())
7483 || (streamType != CAM_STREAM_TYPE_SNAPSHOT)
7484 || (!mParameters.isLLNoiseEnabled())) {
7485 padding_info->offset_info.offset_x = 0;
7486 padding_info->offset_info.offset_y = 0;
7487 }
7488 }
7489 return rc;
7490 }
7491
7492 /*===========================================================================
7493 * FUNCTION : addStreamToChannel
7494 *
7495 * DESCRIPTION: add a stream into a channel
7496 *
7497 * PARAMETERS :
7498 * @pChannel : ptr to channel obj
7499 * @streamType : type of stream to be added
7500 * @streamCB : callback of stream
7501 * @userData : user data ptr to callback
7502 *
7503 * RETURN : int32_t type of status
7504 * NO_ERROR -- success
7505 * none-zero failure code
7506 *==========================================================================*/
addStreamToChannel(QCameraChannel * pChannel,cam_stream_type_t streamType,stream_cb_routine streamCB,void * userData)7507 int32_t QCamera2HardwareInterface::addStreamToChannel(QCameraChannel *pChannel,
7508 cam_stream_type_t streamType,
7509 stream_cb_routine streamCB,
7510 void *userData)
7511 {
7512 int32_t rc = NO_ERROR;
7513 QCameraHeapMemory *pStreamInfo = NULL;
7514 uint32_t cam_type = MM_CAMERA_TYPE_MAIN;
7515 bool needAuxStream = FALSE;
7516
7517 if (streamType == CAM_STREAM_TYPE_RAW) {
7518 prepareRawStream(pChannel);
7519 }
7520
7521 if (isDualCamera()) {
7522 if (!((mParameters.isDCmAsymmetricSnapMode()) &&
7523 (streamType == CAM_STREAM_TYPE_SNAPSHOT))) {
7524 cam_type |= MM_CAMERA_TYPE_AUX;
7525 } else {
7526 needAuxStream = TRUE;
7527 }
7528 }
7529
7530 pStreamInfo = allocateStreamInfoBuf(streamType,
7531 getStreamRefCount(streamType, cam_type), cam_type);
7532 if (pStreamInfo == NULL) {
7533 LOGE("no mem for stream info buf");
7534 return NO_MEMORY;
7535 }
7536
7537 bool bDynAllocBuf = false;
7538 if (isZSLMode() && streamType == CAM_STREAM_TYPE_SNAPSHOT) {
7539 bDynAllocBuf = true;
7540 }
7541
7542 cam_padding_info_t padding_info;
7543 getPaddingInfo(streamType, &padding_info);
7544
7545 bool deferAllocation = needDeferred(streamType);
7546 LOGD("deferAllocation = %d bDynAllocBuf = %d, stream type = %d",
7547 deferAllocation, bDynAllocBuf, streamType);
7548 rc = pChannel->addStream(*this,
7549 pStreamInfo, NULL, &padding_info,
7550 streamCB, userData, bDynAllocBuf,
7551 deferAllocation, ROTATE_0, cam_type);
7552
7553 if (rc != NO_ERROR) {
7554 LOGE("add stream type (%d) cam = %d failed, ret = %d",
7555 streamType, cam_type, rc);
7556 return rc;
7557 }
7558
7559 /*Add stream for Asymmetric dual camera use case*/
7560 if (needAuxStream) {
7561 cam_type = MM_CAMERA_TYPE_AUX;
7562 pStreamInfo = allocateStreamInfoBuf(streamType,
7563 getStreamRefCount(streamType, cam_type), cam_type);
7564 if (pStreamInfo == NULL) {
7565 LOGE("no mem for stream info buf");
7566 return NO_MEMORY;
7567 }
7568 rc = pChannel->addStream(*this,
7569 pStreamInfo, NULL, &padding_info,
7570 streamCB, userData, bDynAllocBuf,
7571 deferAllocation, ROTATE_0, cam_type);
7572 if (rc != NO_ERROR) {
7573 LOGE("add stream type (%d) cam = %d failed, ret = %d",
7574 streamType, cam_type, rc);
7575 return rc;
7576 }
7577 }
7578 return rc;
7579 }
7580
7581 /*===========================================================================
7582 * FUNCTION : addPreviewChannel
7583 *
7584 * DESCRIPTION: add a preview channel that contains a preview stream
7585 *
7586 * PARAMETERS : none
7587 *
7588 * RETURN : int32_t type of status
7589 * NO_ERROR -- success
7590 * none-zero failure code
7591 *==========================================================================*/
addPreviewChannel()7592 int32_t QCamera2HardwareInterface::addPreviewChannel()
7593 {
7594 int32_t rc = NO_ERROR;
7595 QCameraChannel *pChannel = NULL;
7596 char value[PROPERTY_VALUE_MAX];
7597 bool raw_yuv = false;
7598
7599
7600 if (m_channels[QCAMERA_CH_TYPE_PREVIEW] != NULL) {
7601 // if we had preview channel before, delete it first
7602 delete m_channels[QCAMERA_CH_TYPE_PREVIEW];
7603 m_channels[QCAMERA_CH_TYPE_PREVIEW] = NULL;
7604 }
7605
7606 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_PREVIEW);
7607 pChannel = new QCameraChannel(handle, mCameraHandle->ops);
7608 if (NULL == pChannel) {
7609 LOGE("no mem for preview channel");
7610 return NO_MEMORY;
7611 }
7612
7613 // preview only channel, don't need bundle attr and cb
7614 rc = pChannel->init(NULL, NULL, NULL);
7615 if (rc != NO_ERROR) {
7616 LOGE("init preview channel failed, ret = %d", rc);
7617 delete pChannel;
7618 return rc;
7619 }
7620
7621 // meta data stream always coexists with preview if applicable
7622 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
7623 metadata_stream_cb_routine, this);
7624 if (rc != NO_ERROR) {
7625 LOGE("add metadata stream failed, ret = %d", rc);
7626 delete pChannel;
7627 return rc;
7628 }
7629
7630 if (isRdiMode()) {
7631 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
7632 rdi_mode_stream_cb_routine, this);
7633 } else {
7634 if (isNoDisplayMode()) {
7635 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7636 nodisplay_preview_stream_cb_routine, this);
7637 } else {
7638 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7639 preview_stream_cb_routine, this);
7640 if (needSyncCB(CAM_STREAM_TYPE_PREVIEW) == TRUE) {
7641 pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
7642 synchronous_stream_cb_routine);
7643 }
7644 }
7645 }
7646
7647 if (rc != NO_ERROR) {
7648 LOGE("add raw/preview stream failed, ret = %d", rc);
7649 delete pChannel;
7650 return rc;
7651 }
7652
7653 if (((mParameters.fdModeInVideo())
7654 || (mParameters.getDcrf() == true)
7655 || (mParameters.getRecordingHintValue() != true))
7656 && (!isSecureMode())) {
7657 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
7658 NULL, this);
7659 if (rc != NO_ERROR) {
7660 LOGE("add Analysis stream failed, ret = %d", rc);
7661 delete pChannel;
7662 return rc;
7663 }
7664 }
7665
7666 property_get("persist.camera.raw_yuv", value, "0");
7667 raw_yuv = atoi(value) > 0 ? true : false;
7668 if ( raw_yuv ) {
7669 rc = addStreamToChannel(pChannel,CAM_STREAM_TYPE_RAW,
7670 preview_raw_stream_cb_routine,this);
7671 if ( rc != NO_ERROR ) {
7672 LOGE("add raw stream failed, ret = %d", __FUNCTION__, rc);
7673 delete pChannel;
7674 return rc;
7675 }
7676 }
7677
7678 if (rc != NO_ERROR) {
7679 LOGE("add preview stream failed, ret = %d", rc);
7680 delete pChannel;
7681 return rc;
7682 }
7683
7684 m_channels[QCAMERA_CH_TYPE_PREVIEW] = pChannel;
7685 return rc;
7686 }
7687
7688 /*===========================================================================
7689 * FUNCTION : addVideoChannel
7690 *
7691 * DESCRIPTION: add a video channel that contains a video stream
7692 *
7693 * PARAMETERS : none
7694 *
7695 * RETURN : int32_t type of status
7696 * NO_ERROR -- success
7697 * none-zero failure code
7698 *==========================================================================*/
addVideoChannel()7699 int32_t QCamera2HardwareInterface::addVideoChannel()
7700 {
7701 int32_t rc = NO_ERROR;
7702 QCameraVideoChannel *pChannel = NULL;
7703
7704 if (m_channels[QCAMERA_CH_TYPE_VIDEO] != NULL) {
7705 // if we had video channel before, delete it first
7706 delete m_channels[QCAMERA_CH_TYPE_VIDEO];
7707 m_channels[QCAMERA_CH_TYPE_VIDEO] = NULL;
7708 }
7709
7710 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_VIDEO);
7711 pChannel = new QCameraVideoChannel(handle, mCameraHandle->ops);
7712 if (NULL == pChannel) {
7713 LOGE("no mem for video channel");
7714 return NO_MEMORY;
7715 }
7716
7717 if (isLowPowerMode()) {
7718 mm_camera_channel_attr_t attr;
7719 memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7720 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
7721 attr.look_back = 0; //wait for future frame for liveshot
7722 attr.post_frame_skip = mParameters.getZSLBurstInterval();
7723 attr.water_mark = 1; //hold min buffers possible in Q
7724 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7725 rc = pChannel->init(&attr, snapshot_channel_cb_routine, this);
7726 } else {
7727 // preview only channel, don't need bundle attr and cb
7728 rc = pChannel->init(NULL, NULL, NULL);
7729 }
7730
7731 if (rc != 0) {
7732 LOGE("init video channel failed, ret = %d", rc);
7733 delete pChannel;
7734 return rc;
7735 }
7736
7737 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_VIDEO,
7738 video_stream_cb_routine, this);
7739
7740 if (rc != NO_ERROR) {
7741 LOGE("add video stream failed, ret = %d", rc);
7742 delete pChannel;
7743 return rc;
7744 }
7745
7746 m_channels[QCAMERA_CH_TYPE_VIDEO] = pChannel;
7747 return rc;
7748 }
7749
7750 /*===========================================================================
7751 * FUNCTION : addSnapshotChannel
7752 *
7753 * DESCRIPTION: add a snapshot channel that contains a snapshot stream
7754 *
7755 * PARAMETERS : none
7756 *
7757 * RETURN : int32_t type of status
7758 * NO_ERROR -- success
7759 * none-zero failure code
7760 * NOTE : Add this channel for live snapshot usecase. Regular capture will
7761 * use addCaptureChannel.
7762 *==========================================================================*/
addSnapshotChannel()7763 int32_t QCamera2HardwareInterface::addSnapshotChannel()
7764 {
7765 int32_t rc = NO_ERROR;
7766 QCameraChannel *pChannel = NULL;
7767
7768 if (m_channels[QCAMERA_CH_TYPE_SNAPSHOT] != NULL) {
7769 // if we had ZSL channel before, delete it first
7770 delete m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
7771 m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = NULL;
7772 }
7773
7774 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_SNAPSHOT);
7775 pChannel = new QCameraChannel(handle, mCameraHandle->ops);
7776 if (NULL == pChannel) {
7777 LOGE("no mem for snapshot channel");
7778 return NO_MEMORY;
7779 }
7780
7781 mm_camera_channel_attr_t attr;
7782 memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7783 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
7784 attr.look_back = 0; //wait for future frame for liveshot
7785 attr.post_frame_skip = mParameters.getZSLBurstInterval();
7786 attr.water_mark = 1; //hold min buffers possible in Q
7787 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7788 attr.priority = MM_CAMERA_SUPER_BUF_PRIORITY_LOW;
7789 rc = pChannel->init(&attr, snapshot_channel_cb_routine, this);
7790 if (rc != NO_ERROR) {
7791 LOGE("init snapshot channel failed, ret = %d", rc);
7792 delete pChannel;
7793 return rc;
7794 }
7795
7796 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
7797 NULL, NULL);
7798 if (rc != NO_ERROR) {
7799 LOGE("add snapshot stream failed, ret = %d", rc);
7800 delete pChannel;
7801 return rc;
7802 }
7803
7804 m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = pChannel;
7805 return rc;
7806 }
7807
7808 /*===========================================================================
7809 * FUNCTION : addRawChannel
7810 *
7811 * DESCRIPTION: add a raw channel that contains a raw image stream
7812 *
7813 * PARAMETERS : none
7814 *
7815 * RETURN : int32_t type of status
7816 * NO_ERROR -- success
7817 * none-zero failure code
7818 *==========================================================================*/
addRawChannel()7819 int32_t QCamera2HardwareInterface::addRawChannel()
7820 {
7821 int32_t rc = NO_ERROR;
7822 QCameraChannel *pChannel = NULL;
7823
7824 if (m_channels[QCAMERA_CH_TYPE_RAW] != NULL) {
7825 // if we had raw channel before, delete it first
7826 delete m_channels[QCAMERA_CH_TYPE_RAW];
7827 m_channels[QCAMERA_CH_TYPE_RAW] = NULL;
7828 }
7829
7830 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_RAW);
7831 pChannel = new QCameraChannel(handle, mCameraHandle->ops);
7832 if (NULL == pChannel) {
7833 LOGE("no mem for raw channel");
7834 return NO_MEMORY;
7835 }
7836
7837 if (mParameters.getofflineRAW()) {
7838 mm_camera_channel_attr_t attr;
7839 memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7840 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
7841 attr.look_back = mParameters.getZSLBackLookCount();
7842 attr.post_frame_skip = mParameters.getZSLBurstInterval();
7843 attr.water_mark = 1;
7844 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7845 rc = pChannel->init(&attr, raw_channel_cb_routine, this);
7846 if (rc != NO_ERROR) {
7847 LOGE("init RAW channel failed, ret = %d", rc);
7848 delete pChannel;
7849 return rc;
7850 }
7851 } else {
7852 rc = pChannel->init(NULL, NULL, NULL);
7853 if (rc != NO_ERROR) {
7854 LOGE("init raw channel failed, ret = %d", rc);
7855 delete pChannel;
7856 return rc;
7857 }
7858 }
7859
7860 if (!mParameters.isZSLMode()) {
7861 // meta data stream always coexists with snapshot in regular RAW capture case
7862 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
7863 metadata_stream_cb_routine, this);
7864 if (rc != NO_ERROR) {
7865 LOGE("add metadata stream failed, ret = %d", rc);
7866 delete pChannel;
7867 return rc;
7868 }
7869 }
7870
7871 if (mParameters.getofflineRAW()) {
7872 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
7873 NULL, this);
7874 } else if(isSecureMode()) {
7875 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
7876 secure_stream_cb_routine, this);
7877 } else {
7878 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
7879 raw_stream_cb_routine, this);
7880 }
7881 if (rc != NO_ERROR) {
7882 LOGE("add snapshot stream failed, ret = %d", rc);
7883 delete pChannel;
7884 return rc;
7885 }
7886 m_channels[QCAMERA_CH_TYPE_RAW] = pChannel;
7887 return rc;
7888 }
7889
7890 /*===========================================================================
7891 * FUNCTION : addZSLChannel
7892 *
7893 * DESCRIPTION: add a ZSL channel that contains a preview stream and
7894 * a snapshot stream
7895 *
7896 * PARAMETERS : none
7897 *
7898 * RETURN : int32_t type of status
7899 * NO_ERROR -- success
7900 * none-zero failure code
7901 *==========================================================================*/
addZSLChannel()7902 int32_t QCamera2HardwareInterface::addZSLChannel()
7903 {
7904 int32_t rc = NO_ERROR;
7905 QCameraPicChannel *pChannel = NULL;
7906 char value[PROPERTY_VALUE_MAX];
7907 bool raw_yuv = false;
7908
7909 if (m_channels[QCAMERA_CH_TYPE_ZSL] != NULL) {
7910 // if we had ZSL channel before, delete it first
7911 delete m_channels[QCAMERA_CH_TYPE_ZSL];
7912 m_channels[QCAMERA_CH_TYPE_ZSL] = NULL;
7913 }
7914
7915 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_ZSL);
7916 pChannel = new QCameraPicChannel(handle,
7917 mCameraHandle->ops);
7918 if (NULL == pChannel) {
7919 LOGE("no mem for ZSL channel");
7920 return NO_MEMORY;
7921 }
7922
7923 // ZSL channel, init with bundle attr and cb
7924 mm_camera_channel_attr_t attr;
7925 memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
7926 if (mParameters.isSceneSelectionEnabled()) {
7927 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
7928 } else {
7929 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
7930 }
7931 attr.look_back = mParameters.getZSLBackLookCount();
7932 attr.post_frame_skip = mParameters.getZSLBurstInterval();
7933 if (mParameters.isOEMFeatEnabled()) {
7934 LOGD("EDGE SMOOTH frameskip enabled");
7935 attr.post_frame_skip += mParameters.isOEMFeatFrameSkipEnabled();
7936 }
7937 attr.water_mark = mParameters.getZSLQueueDepth();
7938 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
7939 attr.user_expected_frame_id =
7940 mParameters.isInstantCaptureEnabled() ? (uint8_t)mParameters.getAecFrameBoundValue() : 0;
7941
7942 //Enabled matched queue
7943 if (isFrameSyncEnabled()) {
7944 LOGH("Enabling frame sync for dual camera, camera Id: %d",
7945 mCameraId);
7946 attr.enable_frame_sync = 1;
7947 }
7948 rc = pChannel->init(&attr,
7949 zsl_channel_cb,
7950 this);
7951 if (rc != 0) {
7952 LOGE("init ZSL channel failed, ret = %d", rc);
7953 delete pChannel;
7954 return rc;
7955 }
7956
7957 // meta data stream always coexists with preview if applicable
7958 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
7959 metadata_stream_cb_routine, this);
7960 if (rc != NO_ERROR) {
7961 LOGE("add metadata stream failed, ret = %d", rc);
7962 delete pChannel;
7963 return rc;
7964 }
7965
7966 if (isNoDisplayMode()) {
7967 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7968 nodisplay_preview_stream_cb_routine, this);
7969 } else {
7970 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
7971 preview_stream_cb_routine, this);
7972 if (needSyncCB(CAM_STREAM_TYPE_PREVIEW) == TRUE) {
7973 pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
7974 synchronous_stream_cb_routine);
7975 }
7976 }
7977 if (rc != NO_ERROR) {
7978 LOGE("add preview stream failed, ret = %d", rc);
7979 delete pChannel;
7980 return rc;
7981 }
7982
7983 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
7984 NULL, this);
7985 if (rc != NO_ERROR) {
7986 LOGE("add snapshot stream failed, ret = %d", rc);
7987 delete pChannel;
7988 return rc;
7989 }
7990
7991 if (!isSecureMode()) {
7992 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
7993 NULL, this);
7994 if (rc != NO_ERROR) {
7995 LOGE("add Analysis stream failed, ret = %d", rc);
7996 delete pChannel;
7997 return rc;
7998 }
7999 }
8000
8001 property_get("persist.camera.raw_yuv", value, "0");
8002 raw_yuv = atoi(value) > 0 ? true : false;
8003 if (raw_yuv) {
8004 rc = addStreamToChannel(pChannel,
8005 CAM_STREAM_TYPE_RAW,
8006 preview_raw_stream_cb_routine,
8007 this);
8008 if (rc != NO_ERROR) {
8009 LOGE("add raw stream failed, ret = %d", rc);
8010 delete pChannel;
8011 return rc;
8012 }
8013 }
8014
8015 m_channels[QCAMERA_CH_TYPE_ZSL] = pChannel;
8016 return rc;
8017 }
8018
8019 /*===========================================================================
8020 * FUNCTION : addCaptureChannel
8021 *
8022 * DESCRIPTION: add a capture channel that contains a snapshot stream
8023 * and a postview stream
8024 *
8025 * PARAMETERS : none
8026 *
8027 * RETURN : int32_t type of status
8028 * NO_ERROR -- success
8029 * none-zero failure code
8030 * NOTE : Add this channel for regular capture usecase.
8031 * For Live snapshot usecase, use addSnapshotChannel.
8032 *==========================================================================*/
addCaptureChannel()8033 int32_t QCamera2HardwareInterface::addCaptureChannel()
8034 {
8035 int32_t rc = NO_ERROR;
8036 QCameraPicChannel *pChannel = NULL;
8037 char value[PROPERTY_VALUE_MAX];
8038 bool raw_yuv = false;
8039
8040 if (m_channels[QCAMERA_CH_TYPE_CAPTURE] != NULL) {
8041 delete m_channels[QCAMERA_CH_TYPE_CAPTURE];
8042 m_channels[QCAMERA_CH_TYPE_CAPTURE] = NULL;
8043 }
8044
8045 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_CAPTURE);
8046 pChannel = new QCameraPicChannel(handle, mCameraHandle->ops);
8047 if (NULL == pChannel) {
8048 LOGE("no mem for capture channel");
8049 return NO_MEMORY;
8050 }
8051
8052 // Capture channel, only need snapshot and postview streams start together
8053 mm_camera_channel_attr_t attr;
8054 memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
8055 if ( mLongshotEnabled ) {
8056 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
8057 attr.look_back = mParameters.getZSLBackLookCount();
8058 attr.water_mark = mParameters.getZSLQueueDepth();
8059 } else {
8060 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
8061 }
8062 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
8063
8064 rc = pChannel->init(&attr,
8065 capture_channel_cb_routine,
8066 this);
8067 if (rc != NO_ERROR) {
8068 LOGE("init capture channel failed, ret = %d", rc);
8069 delete pChannel;
8070 return rc;
8071 }
8072
8073 // meta data stream always coexists with snapshot in regular capture case
8074 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
8075 metadata_stream_cb_routine, this);
8076 if (rc != NO_ERROR) {
8077 LOGE("add metadata stream failed, ret = %d", rc);
8078 delete pChannel;
8079 return rc;
8080 }
8081
8082 if (mLongshotEnabled) {
8083 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
8084 preview_stream_cb_routine, this);
8085 if (rc != NO_ERROR) {
8086 LOGE("add preview stream failed, ret = %d", rc);
8087 delete pChannel;
8088 return rc;
8089 }
8090 if (needSyncCB(CAM_STREAM_TYPE_PREVIEW) == TRUE) {
8091 pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
8092 synchronous_stream_cb_routine);
8093 }
8094 //Not adding the postview stream to the capture channel if Quadra CFA is enabled.
8095 } else if (!mParameters.getQuadraCfa()) {
8096 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_POSTVIEW,
8097 NULL, this);
8098 if (rc != NO_ERROR) {
8099 LOGE("add postview stream failed, ret = %d", rc);
8100 delete pChannel;
8101 return rc;
8102 }
8103 }
8104
8105 if (!mParameters.getofflineRAW()) {
8106 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
8107 NULL, this);
8108 if (rc != NO_ERROR) {
8109 LOGE("add snapshot stream failed, ret = %d", rc);
8110 delete pChannel;
8111 return rc;
8112 }
8113 }
8114
8115 stream_cb_routine stream_cb = NULL;
8116 property_get("persist.camera.raw_yuv", value, "0");
8117 raw_yuv = atoi(value) > 0 ? true : false;
8118
8119 if (raw_yuv) {
8120 stream_cb = snapshot_raw_stream_cb_routine;
8121 }
8122
8123 if ((raw_yuv) || (mParameters.getofflineRAW())) {
8124 rc = addStreamToChannel(pChannel,
8125 CAM_STREAM_TYPE_RAW, stream_cb, this);
8126 if (rc != NO_ERROR) {
8127 LOGE("add raw stream failed, ret = %d", rc);
8128 delete pChannel;
8129 return rc;
8130 }
8131 }
8132
8133 m_channels[QCAMERA_CH_TYPE_CAPTURE] = pChannel;
8134 return rc;
8135 }
8136
8137 /*===========================================================================
8138 * FUNCTION : addMetaDataChannel
8139 *
8140 * DESCRIPTION: add a meta data channel that contains a metadata stream
8141 *
8142 * PARAMETERS : none
8143 *
8144 * RETURN : int32_t type of status
8145 * NO_ERROR -- success
8146 * none-zero failure code
8147 *==========================================================================*/
addMetaDataChannel()8148 int32_t QCamera2HardwareInterface::addMetaDataChannel()
8149 {
8150 int32_t rc = NO_ERROR;
8151 QCameraChannel *pChannel = NULL;
8152
8153 if (m_channels[QCAMERA_CH_TYPE_METADATA] != NULL) {
8154 delete m_channels[QCAMERA_CH_TYPE_METADATA];
8155 m_channels[QCAMERA_CH_TYPE_METADATA] = NULL;
8156 }
8157
8158 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_METADATA);
8159 pChannel = new QCameraChannel(handle, mCameraHandle->ops);
8160 if (NULL == pChannel) {
8161 LOGE("no mem for metadata channel");
8162 return NO_MEMORY;
8163 }
8164
8165 rc = pChannel->init(NULL,
8166 NULL,
8167 NULL);
8168 if (rc != NO_ERROR) {
8169 LOGE("init metadata channel failed, ret = %d", rc);
8170 delete pChannel;
8171 return rc;
8172 }
8173
8174 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
8175 metadata_stream_cb_routine, this);
8176 if (rc != NO_ERROR) {
8177 LOGE("add metadata stream failed, ret = %d", rc);
8178 delete pChannel;
8179 return rc;
8180 }
8181
8182 m_channels[QCAMERA_CH_TYPE_METADATA] = pChannel;
8183 return rc;
8184 }
8185
8186 /*===========================================================================
8187 * FUNCTION : addCallbackChannel
8188 *
8189 * DESCRIPTION: add a callback channel that contains a callback stream
8190 *
8191 * PARAMETERS : none
8192 *
8193 * RETURN : int32_t type of status
8194 * NO_ERROR -- success
8195 * none-zero failure code
8196 *==========================================================================*/
addCallbackChannel()8197 int32_t QCamera2HardwareInterface::addCallbackChannel()
8198 {
8199 int32_t rc = NO_ERROR;
8200 QCameraChannel *pChannel = NULL;
8201
8202 if (m_channels[QCAMERA_CH_TYPE_CALLBACK] != NULL) {
8203 delete m_channels[QCAMERA_CH_TYPE_CALLBACK];
8204 m_channels[QCAMERA_CH_TYPE_CALLBACK] = NULL;
8205 }
8206
8207 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_CALLBACK);
8208 pChannel = new QCameraChannel(handle, mCameraHandle->ops);
8209 if (NULL == pChannel) {
8210 LOGE("no mem for callback channel");
8211 return NO_MEMORY;
8212 }
8213
8214 rc = pChannel->init(NULL, NULL, this);
8215 if (rc != NO_ERROR) {
8216 LOGE("init callback channel failed, ret = %d",
8217 rc);
8218 delete pChannel;
8219 return rc;
8220 }
8221
8222 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_CALLBACK,
8223 callback_stream_cb_routine, this);
8224 if (rc != NO_ERROR) {
8225 LOGE("add callback stream failed, ret = %d", rc);
8226 delete pChannel;
8227 return rc;
8228 }
8229
8230 m_channels[QCAMERA_CH_TYPE_CALLBACK] = pChannel;
8231 return rc;
8232 }
8233
8234
8235 /*===========================================================================
8236 * FUNCTION : addAnalysisChannel
8237 *
8238 * DESCRIPTION: add a analysis channel that contains a analysis stream
8239 *
8240 * PARAMETERS : none
8241 *
8242 * RETURN : int32_t type of status
8243 * NO_ERROR -- success
8244 * none-zero failure code
8245 *==========================================================================*/
addAnalysisChannel()8246 int32_t QCamera2HardwareInterface::addAnalysisChannel()
8247 {
8248 int32_t rc = NO_ERROR;
8249 QCameraChannel *pChannel = NULL;
8250
8251 if (m_channels[QCAMERA_CH_TYPE_ANALYSIS] != NULL) {
8252 delete m_channels[QCAMERA_CH_TYPE_ANALYSIS];
8253 m_channels[QCAMERA_CH_TYPE_ANALYSIS] = NULL;
8254 }
8255
8256 uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_ANALYSIS);
8257 pChannel = new QCameraChannel(handle, mCameraHandle->ops);
8258 if (NULL == pChannel) {
8259 LOGE("no mem for metadata channel");
8260 return NO_MEMORY;
8261 }
8262
8263 rc = pChannel->init(NULL, NULL, this);
8264 if (rc != NO_ERROR) {
8265 LOGE("init Analysis channel failed, ret = %d", rc);
8266 delete pChannel;
8267 return rc;
8268 }
8269
8270 rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
8271 NULL, this);
8272 if (rc != NO_ERROR) {
8273 LOGE("add Analysis stream failed, ret = %d", rc);
8274 delete pChannel;
8275 return rc;
8276 }
8277
8278 m_channels[QCAMERA_CH_TYPE_ANALYSIS] = pChannel;
8279 return rc;
8280 }
8281
8282
8283 /*===========================================================================
8284 * FUNCTION : getPPConfig
8285 *
8286 * DESCRIPTION: get Post processing configaration data
8287 *
8288 * PARAMETERS :
8289 * @pp config: pp config structure pointer,
8290 * @curIndex: current pp channel index
8291 * @multipass: Flag if multipass prcessing enabled.
8292 *
8293 * RETURN : int32_t type of status
8294 * NO_ERROR -- success
8295 * none-zero failure code
8296 *==========================================================================*/
getPPConfig(cam_pp_feature_config_t & pp_config,int8_t curIndex,bool multipass)8297 int32_t QCamera2HardwareInterface::getPPConfig(cam_pp_feature_config_t &pp_config,
8298 int8_t curIndex, bool multipass)
8299 {
8300 int32_t rc = NO_ERROR;
8301 int32_t feature_set = 0;
8302
8303 if (multipass) {
8304 LOGW("Multi pass enabled. Total Pass = %d, cur index = %d",
8305 mParameters.getReprocCount(), curIndex);
8306 }
8307
8308 LOGH("Supported pproc feature mask = %llx",
8309 gCamCapability[mCameraId]->qcom_supported_feature_mask);
8310 cam_feature_mask_t feature_mask = gCamCapability[mCameraId]->qcom_supported_feature_mask;
8311 int32_t zoomLevel = mParameters.getParmZoomLevel();
8312 uint32_t rotation = mParameters.getJpegRotation();
8313 int32_t effect = mParameters.getEffectValue();
8314
8315 pp_config.cur_reproc_count = curIndex + 1;
8316 pp_config.total_reproc_count = mParameters.getReprocCount();
8317
8318 //Checking what feature mask to enable
8319 if (curIndex == 0) {
8320 if (mParameters.getQuadraCfa()) {
8321 feature_set = 2;
8322 } else {
8323 feature_set = 0;
8324 }
8325 } else if (curIndex == 1) {
8326 if (mParameters.getQuadraCfa()) {
8327 feature_set = 0;
8328 } else {
8329 feature_set = 1;
8330 }
8331 }
8332
8333 switch(feature_set) {
8334 case 0:
8335 //Configure feature mask for first pass of reprocessing
8336 //check if any effects are enabled
8337 if ((CAM_EFFECT_MODE_OFF != effect) &&
8338 (feature_mask & CAM_QCOM_FEATURE_EFFECT)) {
8339 pp_config.feature_mask |= CAM_QCOM_FEATURE_EFFECT;
8340 pp_config.effect = effect;
8341 }
8342
8343 //check for features that need to be enabled by default like sharpness
8344 //(if supported by hw).
8345 if ((feature_mask & CAM_QCOM_FEATURE_SHARPNESS) &&
8346 !mParameters.isOptiZoomEnabled()) {
8347 pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS;
8348 pp_config.sharpness = mParameters.getSharpness();
8349 }
8350
8351 //check if zoom is enabled
8352 if ((zoomLevel > 0) && (feature_mask & CAM_QCOM_FEATURE_CROP)) {
8353 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
8354 }
8355
8356 if (mParameters.isWNREnabled() &&
8357 (feature_mask & CAM_QCOM_FEATURE_DENOISE2D)) {
8358 pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D;
8359 pp_config.denoise2d.denoise_enable = 1;
8360 pp_config.denoise2d.process_plates =
8361 mParameters.getDenoiseProcessPlate(CAM_INTF_PARM_WAVELET_DENOISE);
8362 }
8363
8364 if (isCACEnabled()) {
8365 pp_config.feature_mask |= CAM_QCOM_FEATURE_CAC;
8366 }
8367
8368 //check if rotation is required
8369 if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) {
8370 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
8371 if (rotation == 0) {
8372 pp_config.rotation = ROTATE_0;
8373 } else if (rotation == 90) {
8374 pp_config.rotation = ROTATE_90;
8375 } else if (rotation == 180) {
8376 pp_config.rotation = ROTATE_180;
8377 } else if (rotation == 270) {
8378 pp_config.rotation = ROTATE_270;
8379 }
8380 }
8381
8382 if (mParameters.isHDREnabled()){
8383 pp_config.feature_mask |= CAM_QCOM_FEATURE_HDR;
8384 pp_config.hdr_param.hdr_enable = 1;
8385 pp_config.hdr_param.hdr_need_1x = mParameters.isHDR1xFrameEnabled();
8386 pp_config.hdr_param.hdr_mode = CAM_HDR_MODE_MULTIFRAME;
8387 } else {
8388 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_HDR;
8389 pp_config.hdr_param.hdr_enable = 0;
8390 }
8391
8392 //check if scaling is enabled
8393 if ((feature_mask & CAM_QCOM_FEATURE_SCALE) &&
8394 mParameters.isReprocScaleEnabled() &&
8395 mParameters.isUnderReprocScaling()){
8396 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
8397 mParameters.getPicSizeFromAPK(
8398 pp_config.scale_param.output_width,
8399 pp_config.scale_param.output_height);
8400 }
8401
8402 if(mParameters.isUbiFocusEnabled()) {
8403 pp_config.feature_mask |= CAM_QCOM_FEATURE_UBIFOCUS;
8404 } else {
8405 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_UBIFOCUS;
8406 }
8407
8408 if(mParameters.isUbiRefocus()) {
8409 pp_config.feature_mask |= CAM_QCOM_FEATURE_REFOCUS;
8410 pp_config.misc_buf_param.misc_buffer_index = 0;
8411 } else {
8412 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_REFOCUS;
8413 }
8414
8415 if(mParameters.isChromaFlashEnabled()) {
8416 pp_config.feature_mask |= CAM_QCOM_FEATURE_CHROMA_FLASH;
8417 pp_config.flash_value = CAM_FLASH_ON;
8418 } else {
8419 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CHROMA_FLASH;
8420 }
8421
8422 if(mParameters.isOptiZoomEnabled() && (0 <= zoomLevel)) {
8423 pp_config.feature_mask |= CAM_QCOM_FEATURE_OPTIZOOM;
8424 pp_config.zoom_level = (uint8_t) zoomLevel;
8425 } else {
8426 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_OPTIZOOM;
8427 }
8428
8429 if (mParameters.getofflineRAW()) {
8430 pp_config.feature_mask |= CAM_QCOM_FEATURE_RAW_PROCESSING;
8431 }
8432
8433 if (mParameters.isTruePortraitEnabled()) {
8434 pp_config.feature_mask |= CAM_QCOM_FEATURE_TRUEPORTRAIT;
8435 pp_config.misc_buf_param.misc_buffer_index = 0;
8436 } else {
8437 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_TRUEPORTRAIT;
8438 }
8439
8440 if(mParameters.isStillMoreEnabled()) {
8441 pp_config.feature_mask |= CAM_QCOM_FEATURE_STILLMORE;
8442 } else {
8443 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_STILLMORE;
8444 }
8445
8446 if (mParameters.isOEMFeatEnabled()) {
8447 pp_config.feature_mask |= CAM_OEM_FEATURE_1;
8448 }
8449
8450 if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) {
8451 if (feature_mask & CAM_QCOM_FEATURE_DSDN) {
8452 pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN;
8453 } else {
8454 pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS;
8455 }
8456 }
8457
8458 if ((multipass) &&
8459 (m_postprocessor.getPPChannelCount() > 1)
8460 && (!mParameters.getQuadraCfa())) {
8461 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_PP_PASS_2;
8462 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_ROTATION;
8463 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_CDS;
8464 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_DSDN;
8465 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
8466 } else {
8467 pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
8468 }
8469
8470 cam_dimension_t thumb_src_dim;
8471 cam_dimension_t thumb_dst_dim;
8472 mParameters.getThumbnailSize(&(thumb_dst_dim.width), &(thumb_dst_dim.height));
8473 mParameters.getStreamDimension(CAM_STREAM_TYPE_POSTVIEW,thumb_src_dim);
8474 if ((thumb_dst_dim.width != thumb_src_dim.width) ||
8475 (thumb_dst_dim.height != thumb_src_dim.height)) {
8476 if (thumb_dst_dim.width != 0 && thumb_dst_dim.height != 0) {
8477 pp_config.feature_mask |= CAM_QCOM_FEATURE_CROP;
8478 }
8479 }
8480
8481 break;
8482
8483 case 1:
8484 //Configure feature mask for second pass of reprocessing
8485 pp_config.feature_mask |= CAM_QCOM_FEATURE_PP_PASS_2;
8486 if ((feature_mask & CAM_QCOM_FEATURE_ROTATION) && (rotation > 0)) {
8487 pp_config.feature_mask |= CAM_QCOM_FEATURE_ROTATION;
8488 if (rotation == 0) {
8489 pp_config.rotation = ROTATE_0;
8490 } else if (rotation == 90) {
8491 pp_config.rotation = ROTATE_90;
8492 } else if (rotation == 180) {
8493 pp_config.rotation = ROTATE_180;
8494 } else if (rotation == 270) {
8495 pp_config.rotation = ROTATE_270;
8496 }
8497 }
8498 if (mParameters.getCDSMode() != CAM_CDS_MODE_OFF) {
8499 if (feature_mask & CAM_QCOM_FEATURE_DSDN) {
8500 pp_config.feature_mask |= CAM_QCOM_FEATURE_DSDN;
8501 } else {
8502 pp_config.feature_mask |= CAM_QCOM_FEATURE_CDS;
8503 }
8504 }
8505 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_RAW_PROCESSING;
8506 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_METADATA_PROCESSING;
8507 pp_config.feature_mask &= ~CAM_QCOM_FEATURE_METADATA_BYPASS;
8508 break;
8509
8510 case 2:
8511 //Setting feature for Quadra CFA
8512 pp_config.feature_mask |= CAM_QCOM_FEATURE_QUADRA_CFA;
8513 break;
8514
8515 }
8516
8517 LOGH("pproc feature mask set = %llx pass count = %d",
8518 pp_config.feature_mask, curIndex);
8519 return rc;
8520 }
8521
8522 /*===========================================================================
8523 * FUNCTION : addReprocChannel
8524 *
8525 * DESCRIPTION: add a reprocess channel that will do reprocess on frames
8526 * coming from input channel
8527 *
8528 * PARAMETERS :
8529 * @pInputChannel : ptr to input channel whose frames will be post-processed
8530 * @cur_channel_index : Current channel index in multipass
8531 *
8532 * RETURN : Ptr to the newly created channel obj. NULL if failed.
8533 *==========================================================================*/
addReprocChannel(QCameraChannel * pInputChannel,int8_t cur_channel_index)8534 QCameraReprocessChannel *QCamera2HardwareInterface::addReprocChannel(
8535 QCameraChannel *pInputChannel, int8_t cur_channel_index)
8536 {
8537 int32_t rc = NO_ERROR;
8538 QCameraReprocessChannel *pChannel = NULL;
8539 uint32_t burst_cnt = mParameters.getNumOfSnapshots();
8540 uint32_t pHandle = getCamHandleForChannel(QCAMERA_CH_TYPE_REPROCESSING);
8541
8542 if (pInputChannel == NULL) {
8543 LOGE("input channel obj is NULL");
8544 return NULL;
8545 }
8546
8547 pChannel = new QCameraReprocessChannel(pHandle, mCameraHandle->ops);
8548 if (NULL == pChannel) {
8549 LOGE("no mem for reprocess channel");
8550 return NULL;
8551 }
8552
8553 // Capture channel, only need snapshot and postview streams start together
8554 mm_camera_channel_attr_t attr;
8555 memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
8556 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
8557 attr.max_unmatched_frames = mParameters.getMaxUnmatchedFramesInQueue();
8558 rc = pChannel->init(&attr,
8559 postproc_channel_cb_routine,
8560 this);
8561 if (rc != NO_ERROR) {
8562 LOGE("init reprocess channel failed, ret = %d", rc);
8563 delete pChannel;
8564 return NULL;
8565 }
8566
8567 // pp feature config
8568 cam_pp_feature_config_t pp_config;
8569 memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
8570
8571 rc = getPPConfig(pp_config, cur_channel_index,
8572 ((mParameters.getReprocCount() > 1) ? TRUE : FALSE));
8573 if (rc != NO_ERROR){
8574 LOGE("Error while creating PP config");
8575 delete pChannel;
8576 return NULL;
8577 }
8578
8579 uint8_t minStreamBufNum = getBufNumRequired(CAM_STREAM_TYPE_OFFLINE_PROC);
8580
8581 //WNR and HDR happen inline. No extra buffers needed.
8582 cam_feature_mask_t temp_feature_mask = pp_config.feature_mask;
8583 temp_feature_mask &= ~CAM_QCOM_FEATURE_HDR;
8584 if (temp_feature_mask && mParameters.isHDREnabled()) {
8585 minStreamBufNum = (uint8_t)(1 + mParameters.getNumOfExtraHDRInBufsIfNeeded());
8586 }
8587
8588 if (mParameters.isStillMoreEnabled()) {
8589 cam_still_more_t stillmore_config = mParameters.getStillMoreSettings();
8590 pp_config.burst_cnt = stillmore_config.burst_count;
8591 LOGH("Stillmore burst %d", pp_config.burst_cnt);
8592
8593 // getNumOfExtraBuffersForImageProc returns 1 less buffer assuming
8594 // number of capture is already added. In the case of liveshot,
8595 // stillmore burst is 1. This is to account for the premature decrement
8596 if (mParameters.getNumOfExtraBuffersForImageProc() == 0) {
8597 minStreamBufNum += 1;
8598 }
8599 }
8600
8601 if (mParameters.getManualCaptureMode() >= CAM_MANUAL_CAPTURE_TYPE_3) {
8602 minStreamBufNum += mParameters.getReprocCount() - 1;
8603 burst_cnt = mParameters.getReprocCount();
8604 if (cur_channel_index == 0) {
8605 pChannel->setReprocCount(2);
8606 } else {
8607 pChannel->setReprocCount(1);
8608 }
8609 } else {
8610 pChannel->setReprocCount(1);
8611 }
8612
8613 if (isDualCamera() && mBundledSnapshot) {
8614 minStreamBufNum += 1;
8615 }
8616
8617 // Add non inplace image lib buffers only when ppproc is present,
8618 // becuase pproc is non inplace and input buffers for img lib
8619 // are output for pproc and this number of extra buffers is required
8620 // If pproc is not there, input buffers for imglib are from snapshot stream
8621 uint8_t imglib_extra_bufs = mParameters.getNumOfExtraBuffersForImageProc();
8622 if (temp_feature_mask && imglib_extra_bufs) {
8623 // 1 is added because getNumOfExtraBuffersForImageProc returns extra
8624 // buffers assuming number of capture is already added
8625 minStreamBufNum = (uint8_t)(minStreamBufNum + imglib_extra_bufs + 1);
8626 }
8627
8628 //Mask out features that are already processed in snapshot stream.
8629 cam_feature_mask_t snapshot_feature_mask = 0;
8630 mParameters.getStreamPpMask(CAM_STREAM_TYPE_SNAPSHOT, snapshot_feature_mask);
8631
8632 pp_config.feature_mask &= ~snapshot_feature_mask;
8633 LOGH("Snapshot feature mask: 0x%llx, reproc feature mask: 0x%llx minStreamBufNum = %d",
8634 snapshot_feature_mask, pp_config.feature_mask, minStreamBufNum);
8635
8636 bool offlineReproc = needOfflineReprocessing();
8637 if (m_postprocessor.mOfflineDataBufs != NULL) {
8638 offlineReproc = TRUE;
8639 }
8640
8641 cam_padding_info_t paddingInfo = gCamCapability[mCameraId]->padding_info;
8642 paddingInfo.offset_info.offset_x = 0;
8643 paddingInfo.offset_info.offset_y = 0;
8644 rc = pChannel->addReprocStreamsFromSource(*this,
8645 pp_config,
8646 pInputChannel,
8647 minStreamBufNum,
8648 burst_cnt,
8649 &paddingInfo,
8650 mParameters,
8651 mLongshotEnabled,
8652 offlineReproc);
8653 if (rc != NO_ERROR) {
8654 delete pChannel;
8655 return NULL;
8656 }
8657
8658 return pChannel;
8659 }
8660
8661 /*===========================================================================
8662 * FUNCTION : addOfflineReprocChannel
8663 *
8664 * DESCRIPTION: add a offline reprocess channel contains one reproc stream,
8665 * that will do reprocess on frames coming from external images
8666 *
8667 * PARAMETERS :
8668 * @img_config : offline reporcess image info
8669 * @pp_feature : pp feature config
8670 *
8671 * RETURN : int32_t type of status
8672 * NO_ERROR -- success
8673 * none-zero failure code
8674 *==========================================================================*/
addOfflineReprocChannel(cam_pp_offline_src_config_t & img_config,cam_pp_feature_config_t & pp_feature,stream_cb_routine stream_cb,void * userdata)8675 QCameraReprocessChannel *QCamera2HardwareInterface::addOfflineReprocChannel(
8676 cam_pp_offline_src_config_t &img_config,
8677 cam_pp_feature_config_t &pp_feature,
8678 stream_cb_routine stream_cb,
8679 void *userdata)
8680 {
8681 int32_t rc = NO_ERROR;
8682 QCameraReprocessChannel *pChannel = NULL;
8683
8684 pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle,
8685 mCameraHandle->ops);
8686 if (NULL == pChannel) {
8687 LOGE("no mem for reprocess channel");
8688 return NULL;
8689 }
8690
8691 rc = pChannel->init(NULL, NULL, NULL);
8692 if (rc != NO_ERROR) {
8693 LOGE("init reprocess channel failed, ret = %d", rc);
8694 delete pChannel;
8695 return NULL;
8696 }
8697
8698 QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
8699 if (pStreamInfo == NULL) {
8700 LOGE("no mem for stream info buf");
8701 delete pChannel;
8702 return NULL;
8703 }
8704
8705 cam_stream_info_t *streamInfoBuf = (cam_stream_info_t *)pStreamInfo->getPtr(0);
8706 memset(streamInfoBuf, 0, sizeof(cam_stream_info_t));
8707 streamInfoBuf->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
8708 streamInfoBuf->fmt = img_config.input_fmt;
8709 streamInfoBuf->dim = img_config.input_dim;
8710 streamInfoBuf->buf_planes = img_config.input_buf_planes;
8711 streamInfoBuf->streaming_mode = CAM_STREAMING_MODE_BURST;
8712 streamInfoBuf->num_of_burst = img_config.num_of_bufs;
8713
8714 streamInfoBuf->reprocess_config.pp_type = CAM_OFFLINE_REPROCESS_TYPE;
8715 streamInfoBuf->reprocess_config.offline = img_config;
8716 streamInfoBuf->reprocess_config.pp_feature_config = pp_feature;
8717 streamInfoBuf->num_bufs = img_config.num_of_bufs;
8718
8719 rc = pChannel->addStream(*this,
8720 pStreamInfo, NULL,
8721 &gCamCapability[mCameraId]->padding_info,
8722 stream_cb, userdata, false);
8723
8724 if (rc != NO_ERROR) {
8725 LOGE("add reprocess stream failed, ret = %d", rc);
8726 delete pChannel;
8727 return NULL;
8728 }
8729
8730 return pChannel;
8731 }
8732
8733 /*===========================================================================
8734 * FUNCTION : addChannel
8735 *
8736 * DESCRIPTION: add a channel by its type
8737 *
8738 * PARAMETERS :
8739 * @ch_type : channel type
8740 *
8741 * RETURN : int32_t type of status
8742 * NO_ERROR -- success
8743 * none-zero failure code
8744 *==========================================================================*/
addChannel(qcamera_ch_type_enum_t ch_type)8745 int32_t QCamera2HardwareInterface::addChannel(qcamera_ch_type_enum_t ch_type)
8746 {
8747 int32_t rc = UNKNOWN_ERROR;
8748 switch (ch_type) {
8749 case QCAMERA_CH_TYPE_ZSL:
8750 rc = addZSLChannel();
8751 break;
8752 case QCAMERA_CH_TYPE_CAPTURE:
8753 rc = addCaptureChannel();
8754 break;
8755 case QCAMERA_CH_TYPE_PREVIEW:
8756 rc = addPreviewChannel();
8757 break;
8758 case QCAMERA_CH_TYPE_VIDEO:
8759 rc = addVideoChannel();
8760 break;
8761 case QCAMERA_CH_TYPE_SNAPSHOT:
8762 rc = addSnapshotChannel();
8763 break;
8764 case QCAMERA_CH_TYPE_RAW:
8765 rc = addRawChannel();
8766 break;
8767 case QCAMERA_CH_TYPE_METADATA:
8768 rc = addMetaDataChannel();
8769 break;
8770 case QCAMERA_CH_TYPE_CALLBACK:
8771 rc = addCallbackChannel();
8772 break;
8773 case QCAMERA_CH_TYPE_ANALYSIS:
8774 rc = addAnalysisChannel();
8775 break;
8776 default:
8777 break;
8778 }
8779 return rc;
8780 }
8781
8782 /*===========================================================================
8783 * FUNCTION : delChannel
8784 *
8785 * DESCRIPTION: delete a channel by its type
8786 *
8787 * PARAMETERS :
8788 * @ch_type : channel type
8789 * @destroy : delete context as well
8790 *
8791 * RETURN : int32_t type of status
8792 * NO_ERROR -- success
8793 * none-zero failure code
8794 *==========================================================================*/
delChannel(qcamera_ch_type_enum_t ch_type,bool destroy)8795 int32_t QCamera2HardwareInterface::delChannel(qcamera_ch_type_enum_t ch_type,
8796 bool destroy)
8797 {
8798 if (m_channels[ch_type] != NULL) {
8799 if (destroy) {
8800 delete m_channels[ch_type];
8801 m_channels[ch_type] = NULL;
8802 } else {
8803 m_channels[ch_type]->deleteChannel();
8804 }
8805 }
8806
8807 return NO_ERROR;
8808 }
8809
8810 /*===========================================================================
8811 * FUNCTION : startChannel
8812 *
8813 * DESCRIPTION: start a channel by its type
8814 *
8815 * PARAMETERS :
8816 * @ch_type : channel type
8817 *
8818 * RETURN : int32_t type of status
8819 * NO_ERROR -- success
8820 * none-zero failure code
8821 *==========================================================================*/
startChannel(qcamera_ch_type_enum_t ch_type)8822 int32_t QCamera2HardwareInterface::startChannel(qcamera_ch_type_enum_t ch_type)
8823 {
8824 int32_t rc = UNKNOWN_ERROR;
8825 if (m_channels[ch_type] != NULL) {
8826 rc = m_channels[ch_type]->start();
8827 }
8828 return rc;
8829 }
8830
8831 /*===========================================================================
8832 * FUNCTION : stopChannel
8833 *
8834 * DESCRIPTION: stop a channel by its type
8835 *
8836 * PARAMETERS :
8837 * @ch_type : channel type
8838 *
8839 * RETURN : int32_t type of status
8840 * NO_ERROR -- success
8841 * none-zero failure code
8842 *==========================================================================*/
stopChannel(qcamera_ch_type_enum_t ch_type)8843 int32_t QCamera2HardwareInterface::stopChannel(qcamera_ch_type_enum_t ch_type)
8844 {
8845 int32_t rc = UNKNOWN_ERROR;
8846 if (m_channels[ch_type] != NULL) {
8847 rc = m_channels[ch_type]->stop();
8848 }
8849
8850 return rc;
8851 }
8852
8853 /*===========================================================================
8854 * FUNCTION : preparePreview
8855 *
8856 * DESCRIPTION: add channels needed for preview
8857 *
8858 * PARAMETERS : none
8859 *
8860 * RETURN : int32_t type of status
8861 * NO_ERROR -- success
8862 * none-zero failure code
8863 *==========================================================================*/
preparePreview()8864 int32_t QCamera2HardwareInterface::preparePreview()
8865 {
8866 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPAREPREVIEW);
8867 int32_t rc = NO_ERROR;
8868
8869 LOGI("E");
8870 rc = mParameters.setStreamConfigure(false, false, false);
8871 if (rc != NO_ERROR) {
8872 LOGE("setStreamConfigure failed %d", rc);
8873 return rc;
8874 }
8875
8876 //Trigger deferred job second camera
8877 if (isDualCamera()) {
8878 mParameters.setDeferCamera(CAM_DEFER_START);
8879 }
8880
8881 if (mParameters.isZSLMode() && mParameters.getRecordingHintValue() != true) {
8882 rc = addChannel(QCAMERA_CH_TYPE_ZSL);
8883 if (rc != NO_ERROR) {
8884 LOGE("failed!! rc = %d", rc);
8885 return rc;
8886 }
8887
8888 if (mParameters.isUBWCEnabled()) {
8889 cam_format_t fmt;
8890 mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt);
8891 if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
8892 rc = addChannel(QCAMERA_CH_TYPE_CALLBACK);
8893 if (rc != NO_ERROR) {
8894 delChannel(QCAMERA_CH_TYPE_ZSL);
8895 LOGE("failed!! rc = %d", rc);
8896 return rc;
8897 }
8898 }
8899 }
8900
8901 if (mParameters.getofflineRAW() && !mParameters.getQuadraCfa()) {
8902 addChannel(QCAMERA_CH_TYPE_RAW);
8903 }
8904 } else if(isSecureMode()) {
8905 if (mParameters.getSecureStreamType() == CAM_STREAM_TYPE_RAW) {
8906 rc = addChannel(QCAMERA_CH_TYPE_RAW);
8907 } else {
8908 rc = addChannel(QCAMERA_CH_TYPE_PREVIEW);
8909 }
8910 } else {
8911 bool recordingHint = mParameters.getRecordingHintValue();
8912 if(!isRdiMode() && recordingHint) {
8913 //stop face detection,longshot,etc if turned ON in Camera mode
8914 #ifndef VANILLA_HAL
8915 int32_t arg; //dummy arg
8916 if (isLongshotEnabled()) {
8917 sendCommand(CAMERA_CMD_LONGSHOT_OFF, arg, arg);
8918 }
8919 if (mParameters.isFaceDetectionEnabled()
8920 && (!mParameters.fdModeInVideo())) {
8921 sendCommand(CAMERA_CMD_STOP_FACE_DETECTION, arg, arg);
8922 }
8923 if (mParameters.isHistogramEnabled()) {
8924 sendCommand(CAMERA_CMD_HISTOGRAM_OFF, arg, arg);
8925 }
8926 #endif
8927 //Don't create snapshot channel for liveshot, if low power mode is set.
8928 //Use video stream instead.
8929 if (!isLowPowerMode()) {
8930 rc = addChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8931 if (rc != NO_ERROR) {
8932 return rc;
8933 }
8934 }
8935
8936 rc = addChannel(QCAMERA_CH_TYPE_VIDEO);
8937 if (rc != NO_ERROR) {
8938 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8939 LOGE("failed!! rc = %d", rc);
8940 return rc;
8941 }
8942 }
8943
8944 rc = addChannel(QCAMERA_CH_TYPE_PREVIEW);
8945 if (!isRdiMode() && (rc != NO_ERROR)) {
8946 if (recordingHint) {
8947 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8948 delChannel(QCAMERA_CH_TYPE_VIDEO);
8949 }
8950 }
8951
8952 if (mParameters.isUBWCEnabled() && !recordingHint) {
8953 cam_format_t fmt;
8954 mParameters.getStreamFormat(CAM_STREAM_TYPE_PREVIEW, fmt);
8955 if (fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
8956 rc = addChannel(QCAMERA_CH_TYPE_CALLBACK);
8957 if (rc != NO_ERROR) {
8958 delChannel(QCAMERA_CH_TYPE_PREVIEW);
8959 if (!isRdiMode()) {
8960 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
8961 delChannel(QCAMERA_CH_TYPE_VIDEO);
8962 }
8963 LOGE("failed!! rc = %d", rc);
8964 return rc;
8965 }
8966 }
8967 }
8968
8969 if (NO_ERROR != rc) {
8970 delChannel(QCAMERA_CH_TYPE_PREVIEW);
8971 LOGE("failed!! rc = %d", rc);
8972 }
8973 }
8974
8975 if ((rc != NO_ERROR) && (isDualCamera())) {
8976 mParameters.setDeferCamera(CAM_DEFER_FLUSH);
8977 }
8978
8979 LOGI("X rc = %d", rc);
8980 return rc;
8981 }
8982
8983 /*===========================================================================
8984 * FUNCTION : unpreparePreview
8985 *
8986 * DESCRIPTION: delete channels for preview
8987 *
8988 * PARAMETERS : none
8989 *
8990 * RETURN : none
8991 *==========================================================================*/
unpreparePreview()8992 void QCamera2HardwareInterface::unpreparePreview()
8993 {
8994 if (isDualCamera()) {
8995 mParameters.setDeferCamera(CAM_DEFER_FLUSH);
8996 }
8997 delChannel(QCAMERA_CH_TYPE_ZSL);
8998 delChannel(QCAMERA_CH_TYPE_PREVIEW);
8999 delChannel(QCAMERA_CH_TYPE_VIDEO);
9000 delChannel(QCAMERA_CH_TYPE_SNAPSHOT);
9001 delChannel(QCAMERA_CH_TYPE_CALLBACK);
9002 delChannel(QCAMERA_CH_TYPE_RAW);
9003 }
9004
9005 /*===========================================================================
9006 * FUNCTION : playShutter
9007 *
9008 * DESCRIPTION: send request to play shutter sound
9009 *
9010 * PARAMETERS : none
9011 *
9012 * RETURN : none
9013 *==========================================================================*/
playShutter()9014 void QCamera2HardwareInterface::playShutter(){
9015 if (mNotifyCb == NULL ||
9016 msgTypeEnabledWithLock(CAMERA_MSG_SHUTTER) == 0){
9017 LOGD("shutter msg not enabled or NULL cb");
9018 return;
9019 }
9020 LOGH("CAMERA_MSG_SHUTTER ");
9021 qcamera_callback_argm_t cbArg;
9022 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
9023 cbArg.cb_type = QCAMERA_NOTIFY_CALLBACK;
9024 cbArg.msg_type = CAMERA_MSG_SHUTTER;
9025 cbArg.ext1 = 0;
9026 cbArg.ext2 = false;
9027 m_cbNotifier.notifyCallback(cbArg);
9028 }
9029
9030 /*===========================================================================
9031 * FUNCTION : getChannelByHandle
9032 *
9033 * DESCRIPTION: return a channel by its handle
9034 *
9035 * PARAMETERS :
9036 * @channelHandle : channel handle
9037 *
9038 * RETURN : a channel obj if found, NULL if not found
9039 *==========================================================================*/
getChannelByHandle(uint32_t channelHandle)9040 QCameraChannel *QCamera2HardwareInterface::getChannelByHandle(uint32_t channelHandle)
9041 {
9042 for(int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
9043 if (m_channels[i] != NULL &&
9044 (validate_handle(m_channels[i]->getMyHandle(), channelHandle))) {
9045 return m_channels[i];
9046 }
9047 }
9048
9049 return NULL;
9050 }
9051 /*===========================================================================
9052 * FUNCTION : needPreviewFDCallback
9053 *
9054 * DESCRIPTION: decides if needPreviewFDCallback
9055 *
9056 * PARAMETERS :
9057 * @num_faces : number of faces
9058 *
9059 * RETURN : bool type of status
9060 * true -- success
9061 * fale -- failure code
9062 *==========================================================================*/
needPreviewFDCallback(uint8_t num_faces)9063 bool QCamera2HardwareInterface::needPreviewFDCallback(uint8_t num_faces)
9064 {
9065 if (num_faces == 0 && mNumPreviewFaces == 0) {
9066 return false;
9067 }
9068
9069 return true;
9070 }
9071
9072 /*===========================================================================
9073 * FUNCTION : processFaceDetectionReuslt
9074 *
9075 * DESCRIPTION: process face detection reuslt
9076 *
9077 * PARAMETERS :
9078 * @faces_data : ptr to face processing result struct
9079 *
9080 * RETURN : int32_t type of status
9081 * NO_ERROR -- success
9082 * none-zero failure code
9083 *==========================================================================*/
processFaceDetectionResult(cam_faces_data_t * faces_data)9084 int32_t QCamera2HardwareInterface::processFaceDetectionResult(cam_faces_data_t *faces_data)
9085 {
9086 if (!mParameters.isFaceDetectionEnabled()) {
9087 LOGH("FaceDetection not enabled, no ops here");
9088 return NO_ERROR;
9089 }
9090
9091 qcamera_face_detect_type_t fd_type = faces_data->detection_data.fd_type;
9092 cam_face_detection_data_t *detect_data = &(faces_data->detection_data);
9093 if ((NULL == mDataCb) ||
9094 (fd_type == QCAMERA_FD_PREVIEW && !msgTypeEnabled(CAMERA_MSG_PREVIEW_METADATA)) ||
9095 (!needPreviewFDCallback(detect_data->num_faces_detected))
9096 #ifndef VANILLA_HAL
9097 || (fd_type == QCAMERA_FD_SNAPSHOT && !msgTypeEnabled(CAMERA_MSG_META_DATA))
9098 #endif
9099 ) {
9100 LOGH("metadata msgtype not enabled, no ops here");
9101 return NO_ERROR;
9102 }
9103
9104 if ((fd_type == QCAMERA_FD_PREVIEW) && (detect_data->update_flag == FALSE)) {
9105 // Don't send callback to app if this is skipped by fd at backend
9106 return NO_ERROR;
9107 }
9108
9109 cam_dimension_t display_dim;
9110 mParameters.getStreamDimension(CAM_STREAM_TYPE_PREVIEW, display_dim);
9111 if (display_dim.width <= 0 || display_dim.height <= 0) {
9112 LOGE("Invalid preview width or height (%d x %d)",
9113 display_dim.width, display_dim.height);
9114 return UNKNOWN_ERROR;
9115 }
9116
9117 // process face detection result
9118 // need separate face detection in preview or snapshot type
9119 size_t faceResultSize = 0;
9120 size_t data_len = 0;
9121 if(fd_type == QCAMERA_FD_PREVIEW){
9122 //fd for preview frames
9123 faceResultSize = sizeof(camera_frame_metadata_t);
9124 faceResultSize += sizeof(camera_face_t) * MAX_ROI;
9125 }else if(fd_type == QCAMERA_FD_SNAPSHOT){
9126 #ifndef VANILLA_HAL
9127 // fd for snapshot frames
9128 //check if face is detected in this frame
9129 if(detect_data->num_faces_detected > 0){
9130 data_len = sizeof(camera_frame_metadata_t) +
9131 sizeof(camera_face_t) * detect_data->num_faces_detected;
9132 }else{
9133 //no face
9134 data_len = 0;
9135 }
9136 #endif
9137 faceResultSize = 1 *sizeof(int) //meta data type
9138 + 1 *sizeof(int) // meta data len
9139 + data_len; //data
9140 }
9141
9142 camera_memory_t *faceResultBuffer = mGetMemory(-1,
9143 faceResultSize,
9144 1,
9145 mCallbackCookie);
9146 if ( NULL == faceResultBuffer ) {
9147 LOGE("Not enough memory for face result data");
9148 return NO_MEMORY;
9149 }
9150
9151 unsigned char *pFaceResult = ( unsigned char * ) faceResultBuffer->data;
9152 memset(pFaceResult, 0, faceResultSize);
9153 unsigned char *faceData = NULL;
9154 if(fd_type == QCAMERA_FD_PREVIEW){
9155 faceData = pFaceResult;
9156 mNumPreviewFaces = detect_data->num_faces_detected;
9157 }else if(fd_type == QCAMERA_FD_SNAPSHOT){
9158 #ifndef VANILLA_HAL
9159 //need fill meta type and meta data len first
9160 int *data_header = (int* )pFaceResult;
9161 data_header[0] = CAMERA_META_DATA_FD;
9162 data_header[1] = (int)data_len;
9163
9164 if(data_len <= 0){
9165 //if face is not valid or do not have face, return
9166 qcamera_callback_argm_t cbArg;
9167 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
9168 cbArg.cb_type = QCAMERA_DATA_CALLBACK;
9169 cbArg.msg_type = CAMERA_MSG_META_DATA;
9170 cbArg.data = faceResultBuffer;
9171 cbArg.user_data = faceResultBuffer;
9172 cbArg.cookie = this;
9173 cbArg.release_cb = releaseCameraMemory;
9174 int32_t rc = m_cbNotifier.notifyCallback(cbArg);
9175 if (rc != NO_ERROR) {
9176 LOGE("fail sending notification");
9177 faceResultBuffer->release(faceResultBuffer);
9178 }
9179 return rc;
9180 }
9181 #endif
9182 faceData = pFaceResult + 2 *sizeof(int); //skip two int length
9183 }
9184
9185 camera_frame_metadata_t *roiData = (camera_frame_metadata_t * ) faceData;
9186 camera_face_t *faces = (camera_face_t *) ( faceData + sizeof(camera_frame_metadata_t) );
9187
9188 roiData->number_of_faces = detect_data->num_faces_detected;
9189 roiData->faces = faces;
9190 LOGL("FD_DEBUG : Frame[%d] : number_of_faces=%d, display_dim=%d %d",
9191 detect_data->frame_id, detect_data->num_faces_detected,
9192 display_dim.width, display_dim.height);
9193 if (roiData->number_of_faces > 0) {
9194 for (int i = 0; i < roiData->number_of_faces; i++) {
9195 faces[i].id = detect_data->faces[i].face_id;
9196 faces[i].score = detect_data->faces[i].score;
9197
9198 // left
9199 faces[i].rect[0] = MAP_TO_DRIVER_COORDINATE(
9200 detect_data->faces[i].face_boundary.left,
9201 display_dim.width, 2000, -1000);
9202
9203 // top
9204 faces[i].rect[1] = MAP_TO_DRIVER_COORDINATE(
9205 detect_data->faces[i].face_boundary.top,
9206 display_dim.height, 2000, -1000);
9207
9208 // right
9209 faces[i].rect[2] = faces[i].rect[0] +
9210 MAP_TO_DRIVER_COORDINATE(
9211 detect_data->faces[i].face_boundary.width,
9212 display_dim.width, 2000, 0);
9213
9214 // bottom
9215 faces[i].rect[3] = faces[i].rect[1] +
9216 MAP_TO_DRIVER_COORDINATE(
9217 detect_data->faces[i].face_boundary.height,
9218 display_dim.height, 2000, 0);
9219
9220 LOGL("FD_DEBUG : Frame[%d] : Face[%d] : id=%d, score=%d, "
9221 "CAM[left=%d, top=%d, w=%d, h=%d], "
9222 "APP[left=%d, top=%d, right=%d, bottom=%d] ",
9223 detect_data->frame_id, i, faces[i].id, faces[i].score,
9224 detect_data->faces[i].face_boundary.left,
9225 detect_data->faces[i].face_boundary.top,
9226 detect_data->faces[i].face_boundary.width,
9227 detect_data->faces[i].face_boundary.height,
9228 faces[i].rect[0], faces[i].rect[1],
9229 faces[i].rect[2], faces[i].rect[3]);
9230
9231 if (faces_data->landmark_valid) {
9232 // Center of left eye
9233 if (faces_data->landmark_data.face_landmarks[i].is_left_eye_valid) {
9234 faces[i].left_eye[0] = MAP_TO_DRIVER_COORDINATE(
9235 faces_data->landmark_data.face_landmarks[i].left_eye_center.x,
9236 display_dim.width, 2000, -1000);
9237 faces[i].left_eye[1] = MAP_TO_DRIVER_COORDINATE(
9238 faces_data->landmark_data.face_landmarks[i].left_eye_center.y,
9239 display_dim.height, 2000, -1000);
9240 } else {
9241 faces[i].left_eye[0] = FACE_INVALID_POINT;
9242 faces[i].left_eye[1] = FACE_INVALID_POINT;
9243 }
9244
9245 // Center of right eye
9246 if (faces_data->landmark_data.face_landmarks[i].is_right_eye_valid) {
9247 faces[i].right_eye[0] = MAP_TO_DRIVER_COORDINATE(
9248 faces_data->landmark_data.face_landmarks[i].right_eye_center.x,
9249 display_dim.width, 2000, -1000);
9250 faces[i].right_eye[1] = MAP_TO_DRIVER_COORDINATE(
9251 faces_data->landmark_data.face_landmarks[i].right_eye_center.y,
9252 display_dim.height, 2000, -1000);
9253 } else {
9254 faces[i].right_eye[0] = FACE_INVALID_POINT;
9255 faces[i].right_eye[1] = FACE_INVALID_POINT;
9256 }
9257
9258 // Center of mouth
9259 if (faces_data->landmark_data.face_landmarks[i].is_mouth_valid) {
9260 faces[i].mouth[0] = MAP_TO_DRIVER_COORDINATE(
9261 faces_data->landmark_data.face_landmarks[i].mouth_center.x,
9262 display_dim.width, 2000, -1000);
9263 faces[i].mouth[1] = MAP_TO_DRIVER_COORDINATE(
9264 faces_data->landmark_data.face_landmarks[i].mouth_center.y,
9265 display_dim.height, 2000, -1000);
9266 } else {
9267 faces[i].mouth[0] = FACE_INVALID_POINT;
9268 faces[i].mouth[1] = FACE_INVALID_POINT;
9269 }
9270
9271 LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : "
9272 "eye : left(%d, %d) right(%d, %d), mouth(%d, %d)",
9273 detect_data->frame_id, i, faces[i].left_eye[0], faces[i].left_eye[1],
9274 faces[i].right_eye[0], faces[i].right_eye[1],
9275 faces[i].mouth[0], faces[i].mouth[1]);
9276 } else {
9277 // return -2000 if invalid
9278 faces[i].left_eye[0] = FACE_INVALID_POINT;
9279 faces[i].left_eye[1] = FACE_INVALID_POINT;
9280
9281 faces[i].right_eye[0] = FACE_INVALID_POINT;
9282 faces[i].right_eye[1] = FACE_INVALID_POINT;
9283
9284 faces[i].mouth[0] = FACE_INVALID_POINT;
9285 faces[i].mouth[1] = FACE_INVALID_POINT;
9286 }
9287
9288 #ifndef VANILLA_HAL
9289 #ifdef TARGET_TS_MAKEUP
9290 mFaceRect.left = detect_data->faces[i].face_boundary.left;
9291 mFaceRect.top = detect_data->faces[i].face_boundary.top;
9292 mFaceRect.right = detect_data->faces[i].face_boundary.width+mFaceRect.left;
9293 mFaceRect.bottom = detect_data->faces[i].face_boundary.height+mFaceRect.top;
9294 #endif
9295 if (faces_data->smile_valid) {
9296 faces[i].smile_degree = faces_data->smile_data.smile[i].smile_degree;
9297 faces[i].smile_score = faces_data->smile_data.smile[i].smile_confidence;
9298
9299 LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : smile_degree=%d, smile_score=%d",
9300 detect_data->frame_id, i, faces[i].smile_degree, faces[i].smile_score);
9301 }
9302 if (faces_data->blink_valid) {
9303 faces[i].blink_detected = faces_data->blink_data.blink[i].blink_detected;
9304 faces[i].leye_blink = faces_data->blink_data.blink[i].left_blink;
9305 faces[i].reye_blink = faces_data->blink_data.blink[i].right_blink;
9306
9307 LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : "
9308 "blink_detected=%d, leye_blink=%d, reye_blink=%d",
9309 detect_data->frame_id, i, faces[i].blink_detected, faces[i].leye_blink,
9310 faces[i].reye_blink);
9311 }
9312 if (faces_data->recog_valid) {
9313 faces[i].face_recognised = faces_data->recog_data.face_rec[i].face_recognised;
9314
9315 LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : face_recognised=%d",
9316 detect_data->frame_id, i, faces[i].face_recognised);
9317 }
9318 if (faces_data->gaze_valid) {
9319 faces[i].gaze_angle = faces_data->gaze_data.gaze[i].gaze_angle;
9320 faces[i].updown_dir = faces_data->gaze_data.gaze[i].updown_dir;
9321 faces[i].leftright_dir = faces_data->gaze_data.gaze[i].leftright_dir;
9322 faces[i].roll_dir = faces_data->gaze_data.gaze[i].roll_dir;
9323 faces[i].left_right_gaze = faces_data->gaze_data.gaze[i].left_right_gaze;
9324 faces[i].top_bottom_gaze = faces_data->gaze_data.gaze[i].top_bottom_gaze;
9325
9326 LOGL("FD_DEBUG LANDMARK : Frame[%d] : Face[%d] : gaze_angle=%d, updown_dir=%d, "
9327 "leftright_dir=%d,, roll_dir=%d, left_right_gaze=%d, top_bottom_gaze=%d",
9328 detect_data->frame_id, i, faces[i].gaze_angle, faces[i].updown_dir,
9329 faces[i].leftright_dir, faces[i].roll_dir, faces[i].left_right_gaze,
9330 faces[i].top_bottom_gaze);
9331 }
9332 #endif
9333
9334 }
9335 }
9336 else{
9337 #ifdef TARGET_TS_MAKEUP
9338 memset(&mFaceRect,-1,sizeof(mFaceRect));
9339 #endif
9340 }
9341 qcamera_callback_argm_t cbArg;
9342 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
9343 cbArg.cb_type = QCAMERA_DATA_CALLBACK;
9344 if(fd_type == QCAMERA_FD_PREVIEW){
9345 cbArg.msg_type = CAMERA_MSG_PREVIEW_METADATA;
9346 }
9347 #ifndef VANILLA_HAL
9348 else if(fd_type == QCAMERA_FD_SNAPSHOT){
9349 cbArg.msg_type = CAMERA_MSG_META_DATA;
9350 }
9351 #endif
9352 cbArg.data = faceResultBuffer;
9353 cbArg.metadata = roiData;
9354 cbArg.user_data = faceResultBuffer;
9355 cbArg.cookie = this;
9356 cbArg.release_cb = releaseCameraMemory;
9357 int32_t rc = m_cbNotifier.notifyCallback(cbArg);
9358 if (rc != NO_ERROR) {
9359 LOGE("fail sending notification");
9360 faceResultBuffer->release(faceResultBuffer);
9361 }
9362
9363 return rc;
9364 }
9365
9366 /*===========================================================================
9367 * FUNCTION : releaseCameraMemory
9368 *
9369 * DESCRIPTION: releases camera memory objects
9370 *
9371 * PARAMETERS :
9372 * @data : buffer to be released
9373 * @cookie : context data
9374 * @cbStatus: callback status
9375 *
9376 * RETURN : None
9377 *==========================================================================*/
releaseCameraMemory(void * data,void *,int32_t)9378 void QCamera2HardwareInterface::releaseCameraMemory(void *data,
9379 void */*cookie*/,
9380 int32_t /*cbStatus*/)
9381 {
9382 camera_memory_t *mem = ( camera_memory_t * ) data;
9383 if ( NULL != mem ) {
9384 mem->release(mem);
9385 }
9386 }
9387
9388 /*===========================================================================
9389 * FUNCTION : returnStreamBuffer
9390 *
9391 * DESCRIPTION: returns back a stream buffer
9392 *
9393 * PARAMETERS :
9394 * @data : buffer to be released
9395 * @cookie : context data
9396 * @cbStatus: callback status
9397 *
9398 * RETURN : None
9399 *==========================================================================*/
returnStreamBuffer(void * data,void * cookie,int32_t)9400 void QCamera2HardwareInterface::returnStreamBuffer(void *data,
9401 void *cookie,
9402 int32_t /*cbStatus*/)
9403 {
9404 QCameraStream *stream = ( QCameraStream * ) cookie;
9405 int idx = *((int *)data);
9406 if ((NULL != stream) && (0 <= idx)) {
9407 stream->bufDone((uint32_t)idx);
9408 } else {
9409 LOGE("Cannot return buffer %d %p", idx, cookie);
9410 }
9411 }
9412
9413 /*===========================================================================
9414 * FUNCTION : processHistogramStats
9415 *
9416 * DESCRIPTION: process histogram stats
9417 *
9418 * PARAMETERS :
9419 * @hist_data : ptr to histogram stats struct
9420 *
9421 * RETURN : int32_t type of status
9422 * NO_ERROR -- success
9423 * none-zero failure code
9424 *==========================================================================*/
processHistogramStats(__unused cam_hist_stats_t & stats_data)9425 int32_t QCamera2HardwareInterface::processHistogramStats(
9426 __unused cam_hist_stats_t &stats_data)
9427 {
9428 #ifndef VANILLA_HAL
9429 if (!mParameters.isHistogramEnabled()) {
9430 LOGH("Histogram not enabled, no ops here");
9431 return NO_ERROR;
9432 }
9433
9434 camera_memory_t *histBuffer = mGetMemory(-1,
9435 sizeof(cam_histogram_data_t),
9436 1,
9437 mCallbackCookie);
9438 if ( NULL == histBuffer ) {
9439 LOGE("Not enough memory for histogram data");
9440 return NO_MEMORY;
9441 }
9442
9443 cam_histogram_data_t *pHistData = (cam_histogram_data_t *)histBuffer->data;
9444 if (pHistData == NULL) {
9445 LOGE("memory data ptr is NULL");
9446 return UNKNOWN_ERROR;
9447 }
9448
9449 switch (stats_data.type) {
9450 case CAM_HISTOGRAM_TYPE_BAYER:
9451 switch (stats_data.bayer_stats.data_type) {
9452 case CAM_STATS_CHANNEL_Y:
9453 case CAM_STATS_CHANNEL_R:
9454 *pHistData = stats_data.bayer_stats.r_stats;
9455 break;
9456 case CAM_STATS_CHANNEL_GR:
9457 *pHistData = stats_data.bayer_stats.gr_stats;
9458 break;
9459 case CAM_STATS_CHANNEL_GB:
9460 case CAM_STATS_CHANNEL_ALL:
9461 *pHistData = stats_data.bayer_stats.gb_stats;
9462 break;
9463 case CAM_STATS_CHANNEL_B:
9464 *pHistData = stats_data.bayer_stats.b_stats;
9465 break;
9466 default:
9467 *pHistData = stats_data.bayer_stats.r_stats;
9468 break;
9469 }
9470 break;
9471 case CAM_HISTOGRAM_TYPE_YUV:
9472 *pHistData = stats_data.yuv_stats;
9473 break;
9474 }
9475
9476 qcamera_callback_argm_t cbArg;
9477 memset(&cbArg, 0, sizeof(qcamera_callback_argm_t));
9478 cbArg.cb_type = QCAMERA_DATA_CALLBACK;
9479 cbArg.msg_type = CAMERA_MSG_STATS_DATA;
9480 cbArg.data = histBuffer;
9481 cbArg.user_data = histBuffer;
9482 cbArg.cookie = this;
9483 cbArg.release_cb = releaseCameraMemory;
9484 int32_t rc = m_cbNotifier.notifyCallback(cbArg);
9485 if (rc != NO_ERROR) {
9486 LOGE("fail sending notification");
9487 histBuffer->release(histBuffer);
9488 }
9489 #endif
9490 return NO_ERROR;
9491 }
9492
9493 /*===========================================================================
9494 * FUNCTION : calcThermalLevel
9495 *
9496 * DESCRIPTION: Calculates the target fps range depending on
9497 * the thermal level.
9498 * Note that this function can be called from QCameraParametersIntf
9499 * while mutex is held. So it should not call back into
9500 * QCameraParametersIntf causing deadlock.
9501 *
9502 * PARAMETERS :
9503 * @level : received thermal level
9504 * @minFPS : minimum configured fps range
9505 * @maxFPS : maximum configured fps range
9506 * @minVideoFps: minimum configured fps range
9507 * @maxVideoFps: maximum configured fps range
9508 * @adjustedRange : target fps range
9509 * @skipPattern : target skip pattern
9510 * @bRecordingHint : recording hint value
9511 *
9512 * RETURN : int32_t type of status
9513 * NO_ERROR -- success
9514 * none-zero failure code
9515 *==========================================================================*/
calcThermalLevel(qcamera_thermal_level_enum_t level,const int minFPSi,const int maxFPSi,const float & minVideoFps,const float & maxVideoFps,cam_fps_range_t & adjustedRange,enum msm_vfe_frame_skip_pattern & skipPattern,bool bRecordingHint)9516 int QCamera2HardwareInterface::calcThermalLevel(
9517 qcamera_thermal_level_enum_t level,
9518 const int minFPSi,
9519 const int maxFPSi,
9520 const float &minVideoFps,
9521 const float &maxVideoFps,
9522 cam_fps_range_t &adjustedRange,
9523 enum msm_vfe_frame_skip_pattern &skipPattern,
9524 bool bRecordingHint)
9525 {
9526 const float minFPS = (float)minFPSi;
9527 const float maxFPS = (float)maxFPSi;
9528
9529 LOGH("level: %d, preview minfps %f, preview maxfpS %f, "
9530 "video minfps %f, video maxfpS %f",
9531 level, minFPS, maxFPS, minVideoFps, maxVideoFps);
9532
9533 switch(level) {
9534 case QCAMERA_THERMAL_NO_ADJUSTMENT:
9535 {
9536 adjustedRange.min_fps = minFPS / 1000.0f;
9537 adjustedRange.max_fps = maxFPS / 1000.0f;
9538 adjustedRange.video_min_fps = minVideoFps / 1000.0f;
9539 adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
9540 skipPattern = NO_SKIP;
9541 }
9542 break;
9543 case QCAMERA_THERMAL_SLIGHT_ADJUSTMENT:
9544 {
9545 adjustedRange.min_fps = minFPS / 1000.0f;
9546 adjustedRange.max_fps = maxFPS / 1000.0f;
9547 adjustedRange.min_fps -= 0.1f * adjustedRange.min_fps;
9548 adjustedRange.max_fps -= 0.1f * adjustedRange.max_fps;
9549 adjustedRange.video_min_fps = minVideoFps / 1000.0f;
9550 adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
9551 adjustedRange.video_min_fps -= 0.1f * adjustedRange.video_min_fps;
9552 adjustedRange.video_max_fps -= 0.1f * adjustedRange.video_max_fps;
9553 if ( adjustedRange.min_fps < 1 ) {
9554 adjustedRange.min_fps = 1;
9555 }
9556 if ( adjustedRange.max_fps < 1 ) {
9557 adjustedRange.max_fps = 1;
9558 }
9559 if ( adjustedRange.video_min_fps < 1 ) {
9560 adjustedRange.video_min_fps = 1;
9561 }
9562 if ( adjustedRange.video_max_fps < 1 ) {
9563 adjustedRange.video_max_fps = 1;
9564 }
9565 skipPattern = EVERY_2FRAME;
9566 }
9567 break;
9568 case QCAMERA_THERMAL_BIG_ADJUSTMENT:
9569 {
9570 adjustedRange.min_fps = minFPS / 1000.0f;
9571 adjustedRange.max_fps = maxFPS / 1000.0f;
9572 adjustedRange.min_fps -= 0.2f * adjustedRange.min_fps;
9573 adjustedRange.max_fps -= 0.2f * adjustedRange.max_fps;
9574 adjustedRange.video_min_fps = minVideoFps / 1000.0f;
9575 adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
9576 adjustedRange.video_min_fps -= 0.2f * adjustedRange.video_min_fps;
9577 adjustedRange.video_max_fps -= 0.2f * adjustedRange.video_max_fps;
9578 if ( adjustedRange.min_fps < 1 ) {
9579 adjustedRange.min_fps = 1;
9580 }
9581 if ( adjustedRange.max_fps < 1 ) {
9582 adjustedRange.max_fps = 1;
9583 }
9584 if ( adjustedRange.video_min_fps < 1 ) {
9585 adjustedRange.video_min_fps = 1;
9586 }
9587 if ( adjustedRange.video_max_fps < 1 ) {
9588 adjustedRange.video_max_fps = 1;
9589 }
9590 skipPattern = EVERY_4FRAME;
9591 }
9592 break;
9593 case QCAMERA_THERMAL_MAX_ADJUSTMENT:
9594 {
9595 // Stop Preview?
9596 // Set lowest min FPS for now
9597 adjustedRange.min_fps = minFPS/1000.0f;
9598 adjustedRange.max_fps = minFPS/1000.0f;
9599 cam_capability_t *capability = gCamCapability[mCameraId];
9600 for (size_t i = 0;
9601 i < capability->fps_ranges_tbl_cnt;
9602 i++) {
9603 if (capability->fps_ranges_tbl[i].min_fps <
9604 adjustedRange.min_fps) {
9605 adjustedRange.min_fps =
9606 capability->fps_ranges_tbl[i].min_fps;
9607 adjustedRange.max_fps = adjustedRange.min_fps;
9608 }
9609 }
9610 skipPattern = MAX_SKIP;
9611 adjustedRange.video_min_fps = adjustedRange.min_fps;
9612 adjustedRange.video_max_fps = adjustedRange.max_fps;
9613 }
9614 break;
9615 case QCAMERA_THERMAL_SHUTDOWN:
9616 {
9617 // send error notify
9618 LOGE("Received shutdown thermal level. Closing camera");
9619 sendEvtNotify(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
9620 }
9621 break;
9622 default:
9623 {
9624 LOGW("Invalid thermal level %d", level);
9625 return BAD_VALUE;
9626 }
9627 break;
9628 }
9629 if (level >= QCAMERA_THERMAL_NO_ADJUSTMENT && level <= QCAMERA_THERMAL_MAX_ADJUSTMENT) {
9630 if (bRecordingHint) {
9631 adjustedRange.min_fps = minFPS / 1000.0f;
9632 adjustedRange.max_fps = maxFPS / 1000.0f;
9633 adjustedRange.video_min_fps = minVideoFps / 1000.0f;
9634 adjustedRange.video_max_fps = maxVideoFps / 1000.0f;
9635 skipPattern = NO_SKIP;
9636 LOGH("No FPS mitigation in camcorder mode");
9637 }
9638 LOGH("Thermal level %d, FPS [%3.2f,%3.2f, %3.2f,%3.2f], frameskip %d",
9639 level, adjustedRange.min_fps, adjustedRange.max_fps,
9640 adjustedRange.video_min_fps, adjustedRange.video_max_fps, skipPattern);
9641 }
9642
9643 return NO_ERROR;
9644 }
9645
9646 /*===========================================================================
9647 * FUNCTION : recalcFPSRange
9648 *
9649 * DESCRIPTION: adjust the configured fps range regarding
9650 * the last thermal level.
9651 *
9652 * PARAMETERS :
9653 * @minFPS : minimum configured fps range
9654 * @maxFPS : maximum configured fps range
9655 * @minVideoFPS : minimum configured video fps
9656 * @maxVideoFPS : maximum configured video fps
9657 * @adjustedRange : target fps range
9658 * @bRecordingHint : recording hint value
9659 *
9660 * RETURN : int32_t type of status
9661 * NO_ERROR -- success
9662 * none-zero failure code
9663 *==========================================================================*/
recalcFPSRange(int & minFPS,int & maxFPS,const float & minVideoFPS,const float & maxVideoFPS,cam_fps_range_t & adjustedRange,bool bRecordingHint)9664 int QCamera2HardwareInterface::recalcFPSRange(int &minFPS, int &maxFPS,
9665 const float &minVideoFPS, const float &maxVideoFPS,
9666 cam_fps_range_t &adjustedRange, bool bRecordingHint)
9667 {
9668 enum msm_vfe_frame_skip_pattern skipPattern;
9669 calcThermalLevel(mThermalLevel,
9670 minFPS,
9671 maxFPS,
9672 minVideoFPS,
9673 maxVideoFPS,
9674 adjustedRange,
9675 skipPattern,
9676 bRecordingHint);
9677 return NO_ERROR;
9678 }
9679
9680 /*===========================================================================
9681 * FUNCTION : updateThermalLevel
9682 *
9683 * DESCRIPTION: update thermal level depending on thermal events
9684 *
9685 * PARAMETERS :
9686 * @level : thermal level
9687 *
9688 * RETURN : int32_t type of status
9689 * NO_ERROR -- success
9690 * none-zero failure code
9691 *==========================================================================*/
updateThermalLevel(void * thermal_level)9692 int QCamera2HardwareInterface::updateThermalLevel(void *thermal_level)
9693 {
9694 int ret = NO_ERROR;
9695 cam_fps_range_t adjustedRange;
9696 int minFPS, maxFPS;
9697 float minVideoFPS, maxVideoFPS;
9698 enum msm_vfe_frame_skip_pattern skipPattern;
9699 bool value;
9700 qcamera_thermal_level_enum_t level = *(qcamera_thermal_level_enum_t *)thermal_level;
9701
9702
9703 if (!mCameraOpened) {
9704 LOGH("Camera is not opened, no need to update camera parameters");
9705 return NO_ERROR;
9706 }
9707
9708 mParameters.getPreviewFpsRange(&minFPS, &maxFPS);
9709 qcamera_thermal_mode thermalMode = mParameters.getThermalMode();
9710 if (mParameters.isHfrMode()) {
9711 cam_fps_range_t hfrFpsRange;
9712 mParameters.getHfrFps(hfrFpsRange);
9713 minVideoFPS = hfrFpsRange.video_min_fps;
9714 maxVideoFPS = hfrFpsRange.video_max_fps;
9715 } else {
9716 minVideoFPS = minFPS;
9717 maxVideoFPS = maxFPS;
9718 }
9719
9720 value = mParameters.getRecordingHintValue();
9721 calcThermalLevel(level, minFPS, maxFPS, minVideoFPS, maxVideoFPS,
9722 adjustedRange, skipPattern, value );
9723 mThermalLevel = level;
9724
9725 if (thermalMode == QCAMERA_THERMAL_ADJUST_FPS)
9726 ret = mParameters.adjustPreviewFpsRange(&adjustedRange);
9727 else if (thermalMode == QCAMERA_THERMAL_ADJUST_FRAMESKIP)
9728 ret = mParameters.setFrameSkip(skipPattern);
9729 else
9730 LOGW("Incorrect thermal mode %d", thermalMode);
9731
9732 return ret;
9733
9734 }
9735
9736 /*===========================================================================
9737 * FUNCTION : updateParameters
9738 *
9739 * DESCRIPTION: update parameters
9740 *
9741 * PARAMETERS :
9742 * @parms : input parameters string
9743 * @needRestart : output, flag to indicate if preview restart is needed
9744 *
9745 * RETURN : int32_t type of status
9746 * NO_ERROR -- success
9747 * none-zero failure code
9748 *==========================================================================*/
updateParameters(const char * parms,bool & needRestart)9749 int QCamera2HardwareInterface::updateParameters(const char *parms, bool &needRestart)
9750 {
9751 int rc = NO_ERROR;
9752
9753 String8 str = String8(parms);
9754 rc = mParameters.updateParameters(str, needRestart);
9755 setNeedRestart(needRestart);
9756
9757 // update stream based parameter settings
9758 for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
9759 if (m_channels[i] != NULL) {
9760 m_channels[i]->UpdateStreamBasedParameters(mParameters);
9761 }
9762 }
9763
9764 return rc;
9765 }
9766
9767 /*===========================================================================
9768 * FUNCTION : commitParameterChanges
9769 *
9770 * DESCRIPTION: commit parameter changes to the backend to take effect
9771 *
9772 * PARAMETERS : none
9773 *
9774 * RETURN : int32_t type of status
9775 * NO_ERROR -- success
9776 * none-zero failure code
9777 * NOTE : This function must be called after updateParameters.
9778 * Otherwise, no change will be passed to backend to take effect.
9779 *==========================================================================*/
commitParameterChanges()9780 int QCamera2HardwareInterface::commitParameterChanges()
9781 {
9782 int rc = NO_ERROR;
9783 rc = mParameters.commitParameters();
9784 if (rc == NO_ERROR) {
9785 // update number of snapshot based on committed parameters setting
9786 rc = mParameters.setNumOfSnapshot();
9787 }
9788
9789 if (isDualCamera() &&
9790 mParameters.isZoomChanged()) {
9791 // If zoom changes, get the updated FOV-control result and if needed send the dual
9792 // camera parameters to backend
9793 processDualCamFovControl();
9794 }
9795 return rc;
9796 }
9797
9798 /*===========================================================================
9799 * FUNCTION : needDebugFps
9800 *
9801 * DESCRIPTION: if fps log info need to be printed out
9802 *
9803 * PARAMETERS : none
9804 *
9805 * RETURN : true: need print out fps log
9806 * false: no need to print out fps log
9807 *==========================================================================*/
needDebugFps()9808 bool QCamera2HardwareInterface::needDebugFps()
9809 {
9810 bool needFps = false;
9811 needFps = mParameters.isFpsDebugEnabled();
9812 return needFps;
9813 }
9814
9815 /*===========================================================================
9816 * FUNCTION : isCACEnabled
9817 *
9818 * DESCRIPTION: if CAC is enabled
9819 *
9820 * PARAMETERS : none
9821 *
9822 * RETURN : true: needed
9823 * false: no need
9824 *==========================================================================*/
isCACEnabled()9825 bool QCamera2HardwareInterface::isCACEnabled()
9826 {
9827 char prop[PROPERTY_VALUE_MAX];
9828 memset(prop, 0, sizeof(prop));
9829 property_get("persist.camera.feature.cac", prop, "0");
9830 int enableCAC = atoi(prop);
9831 return enableCAC == 1;
9832 }
9833
9834 /*===========================================================================
9835 * FUNCTION : is4k2kResolution
9836 *
9837 * DESCRIPTION: if resolution is 4k x 2k or true 4k x 2k
9838 *
9839 * PARAMETERS : none
9840 *
9841 * RETURN : true: needed
9842 * false: no need
9843 *==========================================================================*/
is4k2kResolution(cam_dimension_t * resolution)9844 bool QCamera2HardwareInterface::is4k2kResolution(cam_dimension_t* resolution)
9845 {
9846 bool enabled = false;
9847 if ((resolution->width == 4096 && resolution->height == 2160) ||
9848 (resolution->width == 3840 && resolution->height == 2160) ) {
9849 enabled = true;
9850 }
9851 return enabled;
9852 }
9853
9854 /*===========================================================================
9855 * FUNCTION : isPreviewRestartEnabled
9856 *
9857 * DESCRIPTION: Check whether preview should be restarted automatically
9858 * during image capture.
9859 *
9860 * PARAMETERS : none
9861 *
9862 * RETURN : true: needed
9863 * false: no need
9864 *==========================================================================*/
isPreviewRestartEnabled()9865 bool QCamera2HardwareInterface::isPreviewRestartEnabled()
9866 {
9867 char prop[PROPERTY_VALUE_MAX];
9868 memset(prop, 0, sizeof(prop));
9869 property_get("persist.camera.feature.restart", prop, "0");
9870 int earlyRestart = atoi(prop);
9871 return earlyRestart == 1;
9872 }
9873
9874 /*===========================================================================
9875 * FUNCTION : needReprocess
9876 *
9877 * DESCRIPTION: if reprocess is needed
9878 *
9879 * PARAMETERS : none
9880 *
9881 * RETURN : true: needed
9882 * false: no need
9883 *==========================================================================*/
needReprocess()9884 bool QCamera2HardwareInterface::needReprocess()
9885 {
9886 bool needReprocess = false;
9887
9888 if (!mParameters.isJpegPictureFormat() &&
9889 !mParameters.isNV21PictureFormat()) {
9890 // RAW image, no need to reprocess
9891 return false;
9892 }
9893
9894 //Disable reprocess for small jpeg size or 4K liveshot case but enable if lowpower mode
9895 if ((mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue()
9896 && !isLowPowerMode()) || mParameters.isSmallJpegSizeEnabled()) {
9897 return false;
9898 }
9899
9900 // pp feature config
9901 cam_pp_feature_config_t pp_config;
9902 memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
9903
9904 //Decide whether to do reprocess or not based on
9905 //ppconfig obtained in the first pass.
9906 getPPConfig(pp_config);
9907
9908 if (pp_config.feature_mask > 0) {
9909 needReprocess = true;
9910 }
9911
9912 LOGH("needReprocess %s", needReprocess ? "true" : "false");
9913 return needReprocess;
9914 }
9915
9916
9917 /*===========================================================================
9918 * FUNCTION : needRotationReprocess
9919 *
9920 * DESCRIPTION: if rotation needs to be done by reprocess in pp
9921 *
9922 * PARAMETERS : none
9923 *
9924 * RETURN : true: needed
9925 * false: no need
9926 *==========================================================================*/
needRotationReprocess()9927 bool QCamera2HardwareInterface::needRotationReprocess()
9928 {
9929 if (!mParameters.isJpegPictureFormat() &&
9930 !mParameters.isNV21PictureFormat()) {
9931 // RAW image, no need to reprocess
9932 return false;
9933 }
9934
9935 //Disable reprocess for 4K liveshot case
9936 if ((mParameters.is4k2kVideoResolution() && mParameters.getRecordingHintValue()
9937 && !isLowPowerMode()) || mParameters.isSmallJpegSizeEnabled()) {
9938 //Disable reprocess for 4K liveshot case or small jpeg size
9939 return false;
9940 }
9941
9942 if ((gCamCapability[mCameraId]->qcom_supported_feature_mask &
9943 CAM_QCOM_FEATURE_ROTATION) > 0 &&
9944 (mParameters.getJpegRotation() > 0)) {
9945 // current rotation is not zero, and pp has the capability to process rotation
9946 LOGH("need to do reprocess for rotation=%d",
9947 mParameters.getJpegRotation());
9948 return true;
9949 }
9950
9951 return false;
9952 }
9953
9954 /*===========================================================================
9955 * FUNCTION : getThumbnailSize
9956 *
9957 * DESCRIPTION: get user set thumbnail size
9958 *
9959 * PARAMETERS :
9960 * @dim : output of thumbnail dimension
9961 *
9962 * RETURN : none
9963 *==========================================================================*/
getThumbnailSize(cam_dimension_t & dim)9964 void QCamera2HardwareInterface::getThumbnailSize(cam_dimension_t &dim)
9965 {
9966 mParameters.getThumbnailSize(&dim.width, &dim.height);
9967 }
9968
9969 /*===========================================================================
9970 * FUNCTION : getJpegQuality
9971 *
9972 * DESCRIPTION: get user set jpeg quality
9973 *
9974 * PARAMETERS : none
9975 *
9976 * RETURN : jpeg quality setting
9977 *==========================================================================*/
getJpegQuality()9978 uint32_t QCamera2HardwareInterface::getJpegQuality()
9979 {
9980 uint32_t quality = 0;
9981 quality = mParameters.getJpegQuality();
9982 return quality;
9983 }
9984
9985 /*===========================================================================
9986 * FUNCTION : getExifData
9987 *
9988 * DESCRIPTION: get exif data to be passed into jpeg encoding
9989 *
9990 * PARAMETERS : none
9991 *
9992 * RETURN : exif data from user setting and GPS
9993 *==========================================================================*/
getExifData()9994 QCameraExif *QCamera2HardwareInterface::getExifData()
9995 {
9996 QCameraExif *exif = new QCameraExif();
9997 if (exif == NULL) {
9998 LOGE("No memory for QCameraExif");
9999 return NULL;
10000 }
10001
10002 int32_t rc = NO_ERROR;
10003
10004 // add exif entries
10005 String8 dateTime, subSecTime;
10006 rc = mParameters.getExifDateTime(dateTime, subSecTime);
10007 if(rc == NO_ERROR) {
10008 exif->addEntry(EXIFTAGID_DATE_TIME, EXIF_ASCII,
10009 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
10010 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, EXIF_ASCII,
10011 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
10012 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_DIGITIZED, EXIF_ASCII,
10013 (uint32_t)(dateTime.length() + 1), (void *)dateTime.string());
10014 exif->addEntry(EXIFTAGID_SUBSEC_TIME, EXIF_ASCII,
10015 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
10016 exif->addEntry(EXIFTAGID_SUBSEC_TIME_ORIGINAL, EXIF_ASCII,
10017 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
10018 exif->addEntry(EXIFTAGID_SUBSEC_TIME_DIGITIZED, EXIF_ASCII,
10019 (uint32_t)(subSecTime.length() + 1), (void *)subSecTime.string());
10020 } else {
10021 LOGW("getExifDateTime failed");
10022 }
10023
10024 rat_t focalLength;
10025 rc = mParameters.getExifFocalLength(&focalLength);
10026 if (rc == NO_ERROR) {
10027 exif->addEntry(EXIFTAGID_FOCAL_LENGTH,
10028 EXIF_RATIONAL,
10029 1,
10030 (void *)&(focalLength));
10031 } else {
10032 LOGW("getExifFocalLength failed");
10033 }
10034
10035 uint16_t isoSpeed = mParameters.getExifIsoSpeed();
10036 if (getSensorType() != CAM_SENSOR_YUV) {
10037 exif->addEntry(EXIFTAGID_ISO_SPEED_RATING,
10038 EXIF_SHORT,
10039 1,
10040 (void *)&(isoSpeed));
10041 }
10042
10043 char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
10044 uint32_t count = 0;
10045
10046 /*gps data might not be available */
10047 rc = mParameters.getExifGpsProcessingMethod(gpsProcessingMethod, count);
10048 if(rc == NO_ERROR) {
10049 exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD,
10050 EXIF_ASCII,
10051 count,
10052 (void *)gpsProcessingMethod);
10053 } else {
10054 LOGW("getExifGpsProcessingMethod failed");
10055 }
10056
10057 rat_t latitude[3];
10058 char latRef[2];
10059 rc = mParameters.getExifLatitude(latitude, latRef);
10060 if(rc == NO_ERROR) {
10061 exif->addEntry(EXIFTAGID_GPS_LATITUDE,
10062 EXIF_RATIONAL,
10063 3,
10064 (void *)latitude);
10065 exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF,
10066 EXIF_ASCII,
10067 2,
10068 (void *)latRef);
10069 } else {
10070 LOGW("getExifLatitude failed");
10071 }
10072
10073 rat_t longitude[3];
10074 char lonRef[2];
10075 rc = mParameters.getExifLongitude(longitude, lonRef);
10076 if(rc == NO_ERROR) {
10077 exif->addEntry(EXIFTAGID_GPS_LONGITUDE,
10078 EXIF_RATIONAL,
10079 3,
10080 (void *)longitude);
10081
10082 exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF,
10083 EXIF_ASCII,
10084 2,
10085 (void *)lonRef);
10086 } else {
10087 LOGW("getExifLongitude failed");
10088 }
10089
10090 rat_t altitude;
10091 char altRef;
10092 rc = mParameters.getExifAltitude(&altitude, &altRef);
10093 if(rc == NO_ERROR) {
10094 exif->addEntry(EXIFTAGID_GPS_ALTITUDE,
10095 EXIF_RATIONAL,
10096 1,
10097 (void *)&(altitude));
10098
10099 exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF,
10100 EXIF_BYTE,
10101 1,
10102 (void *)&altRef);
10103 } else {
10104 LOGW("getExifAltitude failed");
10105 }
10106
10107 char gpsDateStamp[20];
10108 rat_t gpsTimeStamp[3];
10109 rc = mParameters.getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp);
10110 if(rc == NO_ERROR) {
10111 exif->addEntry(EXIFTAGID_GPS_DATESTAMP,
10112 EXIF_ASCII,
10113 (uint32_t)(strlen(gpsDateStamp) + 1),
10114 (void *)gpsDateStamp);
10115
10116 exif->addEntry(EXIFTAGID_GPS_TIMESTAMP,
10117 EXIF_RATIONAL,
10118 3,
10119 (void *)gpsTimeStamp);
10120 } else {
10121 LOGW("getExifGpsDataTimeStamp failed");
10122 }
10123
10124 #ifdef ENABLE_MODEL_INFO_EXIF
10125
10126 char value[PROPERTY_VALUE_MAX];
10127 if (property_get("persist.sys.exif.make", value, "") > 0 ||
10128 property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) {
10129 exif->addEntry(EXIFTAGID_MAKE,
10130 EXIF_ASCII, strlen(value) + 1, (void *)value);
10131 } else {
10132 LOGW("getExifMaker failed");
10133 }
10134
10135 if (property_get("persist.sys.exif.model", value, "") > 0 ||
10136 property_get("ro.product.model", value, "QCAM-AA") > 0) {
10137 exif->addEntry(EXIFTAGID_MODEL,
10138 EXIF_ASCII, strlen(value) + 1, (void *)value);
10139 } else {
10140 LOGW("getExifModel failed");
10141 }
10142
10143 if (property_get("ro.build.description", value, "QCAM-AA") > 0) {
10144 exif->addEntry(EXIFTAGID_SOFTWARE, EXIF_ASCII,
10145 (uint32_t)(strlen(value) + 1), (void *)value);
10146 } else {
10147 LOGW("getExifSoftware failed");
10148 }
10149
10150 #endif
10151
10152 if (mParameters.useJpegExifRotation()) {
10153 int16_t orientation;
10154 switch (mParameters.getJpegExifRotation()) {
10155 case 0:
10156 orientation = 1;
10157 break;
10158 case 90:
10159 orientation = 6;
10160 break;
10161 case 180:
10162 orientation = 3;
10163 break;
10164 case 270:
10165 orientation = 8;
10166 break;
10167 default:
10168 orientation = 1;
10169 break;
10170 }
10171 exif->addEntry(EXIFTAGID_ORIENTATION,
10172 EXIF_SHORT,
10173 1,
10174 (void *)&orientation);
10175 exif->addEntry(EXIFTAGID_TN_ORIENTATION,
10176 EXIF_SHORT,
10177 1,
10178 (void *)&orientation);
10179 }
10180
10181 return exif;
10182 }
10183
10184 /*===========================================================================
10185 * FUNCTION : setHistogram
10186 *
10187 * DESCRIPTION: set if histogram should be enabled
10188 *
10189 * PARAMETERS :
10190 * @histogram_en : bool flag if histogram should be enabled
10191 *
10192 * RETURN : int32_t type of status
10193 * NO_ERROR -- success
10194 * none-zero failure code
10195 *==========================================================================*/
setHistogram(bool histogram_en)10196 int32_t QCamera2HardwareInterface::setHistogram(bool histogram_en)
10197 {
10198 return mParameters.setHistogram(histogram_en);
10199 }
10200
10201 /*===========================================================================
10202 * FUNCTION : setFaceDetection
10203 *
10204 * DESCRIPTION: set if face detection should be enabled
10205 *
10206 * PARAMETERS :
10207 * @enabled : bool flag if face detection should be enabled
10208 *
10209 * RETURN : int32_t type of status
10210 * NO_ERROR -- success
10211 * none-zero failure code
10212 *==========================================================================*/
setFaceDetection(bool enabled)10213 int32_t QCamera2HardwareInterface::setFaceDetection(bool enabled)
10214 {
10215 return mParameters.setFaceDetection(enabled, true);
10216 }
10217
10218 /*===========================================================================
10219 * FUNCTION : isCaptureShutterEnabled
10220 *
10221 * DESCRIPTION: Check whether shutter should be triggered immediately after
10222 * capture
10223 *
10224 * PARAMETERS :
10225 *
10226 * RETURN : true - regular capture
10227 * false - other type of capture
10228 *==========================================================================*/
isCaptureShutterEnabled()10229 bool QCamera2HardwareInterface::isCaptureShutterEnabled()
10230 {
10231 char prop[PROPERTY_VALUE_MAX];
10232 memset(prop, 0, sizeof(prop));
10233 property_get("persist.camera.feature.shutter", prop, "0");
10234 int enableShutter = atoi(prop);
10235 return enableShutter == 1;
10236 }
10237
10238 /*===========================================================================
10239 * FUNCTION : needProcessPreviewFrame
10240 *
10241 * DESCRIPTION: returns whether preview frame need to be displayed
10242 *
10243 * PARAMETERS :
10244 * @frameID : frameID of frame to be processed
10245 *
10246 * RETURN : int32_t type of status
10247 * NO_ERROR -- success
10248 * none-zero failure code
10249 *==========================================================================*/
needProcessPreviewFrame(uint32_t frameID)10250 bool QCamera2HardwareInterface::needProcessPreviewFrame(uint32_t frameID)
10251 {
10252 return (((m_stateMachine.isPreviewRunning()) &&
10253 (!isDisplayFrameToSkip(frameID)) &&
10254 (!mParameters.isInstantAECEnabled())) ||
10255 (isPreviewRestartEnabled()));
10256 }
10257
10258 /*===========================================================================
10259 * FUNCTION : needSendPreviewCallback
10260 *
10261 * DESCRIPTION: returns whether preview frame need to callback to APP
10262 *
10263 * PARAMETERS :
10264 *
10265 * RETURN : true - need preview frame callbck
10266 * false - not send preview frame callback
10267 *==========================================================================*/
needSendPreviewCallback()10268 bool QCamera2HardwareInterface::needSendPreviewCallback()
10269 {
10270 return m_stateMachine.isPreviewRunning()
10271 && (mDataCb != NULL)
10272 && (msgTypeEnabledWithLock(CAMERA_MSG_PREVIEW_FRAME) > 0)
10273 && m_stateMachine.isPreviewCallbackNeeded();
10274 };
10275
10276 /*===========================================================================
10277 * FUNCTION : setDisplaySkip
10278 *
10279 * DESCRIPTION: set range of frames to skip for preview
10280 *
10281 * PARAMETERS :
10282 * @enabled : TRUE to start skipping frame to display
10283 FALSE to stop skipping frame to display
10284 * @skipCnt : Number of frame to skip. 0 by default
10285 *
10286 * RETURN : None
10287 *==========================================================================*/
setDisplaySkip(bool enabled,uint8_t skipCnt)10288 void QCamera2HardwareInterface::setDisplaySkip(bool enabled, uint8_t skipCnt)
10289 {
10290 pthread_mutex_lock(&mGrallocLock);
10291 if (enabled) {
10292 setDisplayFrameSkip();
10293 setDisplayFrameSkip(mLastPreviewFrameID + skipCnt + 1);
10294 } else {
10295 setDisplayFrameSkip(mFrameSkipStart, (mLastPreviewFrameID + skipCnt + 1));
10296 }
10297 pthread_mutex_unlock(&mGrallocLock);
10298 }
10299
10300 /*===========================================================================
10301 * FUNCTION : setDisplayFrameSkip
10302 *
10303 * DESCRIPTION: set range of frames to skip for preview
10304 *
10305 * PARAMETERS :
10306 * @start : frameId to start skip
10307 * @end : frameId to stop skip
10308 *
10309 * RETURN : None
10310 *==========================================================================*/
setDisplayFrameSkip(uint32_t start,uint32_t end)10311 void QCamera2HardwareInterface::setDisplayFrameSkip(uint32_t start,
10312 uint32_t end)
10313 {
10314 if (start == 0) {
10315 mFrameSkipStart = 0;
10316 mFrameSkipEnd = 0;
10317 return;
10318 }
10319 if ((mFrameSkipStart == 0) || (mFrameSkipStart > start)) {
10320 mFrameSkipStart = start;
10321 }
10322 if ((end == 0) || (end > mFrameSkipEnd)) {
10323 mFrameSkipEnd = end;
10324 }
10325 }
10326
10327 /*===========================================================================
10328 * FUNCTION : isDisplayFrameToSkip
10329 *
10330 * DESCRIPTION: function to determin if input frame falls under skip range
10331 *
10332 * PARAMETERS :
10333 * @frameId : frameId to verify
10334 *
10335 * RETURN : true : need to skip
10336 * false: no need to skip
10337 *==========================================================================*/
isDisplayFrameToSkip(uint32_t frameId)10338 bool QCamera2HardwareInterface::isDisplayFrameToSkip(uint32_t frameId)
10339 {
10340 return ((mFrameSkipStart != 0) && (frameId >= mFrameSkipStart) &&
10341 (frameId <= mFrameSkipEnd || mFrameSkipEnd == 0)) ? TRUE : FALSE;
10342 }
10343
10344 /*===========================================================================
10345 * FUNCTION : getSnapshotHandle
10346 *
10347 * DESCRIPTION: Get the camera handle for snapshot based on the bundlesnapshot
10348 * flag and active camera state
10349 *
10350 * PARAMETERS : None
10351 *
10352 * RETURN : camera handle for snapshot
10353 *
10354 *==========================================================================*/
getSnapshotHandle()10355 uint32_t QCamera2HardwareInterface::getSnapshotHandle()
10356 {
10357 uint32_t snapshotHandle = 0;
10358
10359 if ((mActiveCameras == MM_CAMERA_DUAL_CAM) && mBundledSnapshot) {
10360 snapshotHandle = mCameraHandle->camera_handle;
10361 } else {
10362 snapshotHandle = (mMasterCamera == MM_CAMERA_TYPE_MAIN) ?
10363 get_main_camera_handle(mCameraHandle->camera_handle) :
10364 get_aux_camera_handle(mCameraHandle->camera_handle);
10365 }
10366
10367 return snapshotHandle;
10368 }
10369
10370 /*===========================================================================
10371 * FUNCTION : prepareHardwareForSnapshot
10372 *
10373 * DESCRIPTION: prepare hardware for snapshot, such as LED
10374 *
10375 * PARAMETERS :
10376 * @afNeeded: flag indicating if Auto Focus needs to be done during preparation
10377 *
10378 * RETURN : int32_t type of status
10379 * NO_ERROR -- success
10380 * none-zero failure code
10381 *==========================================================================*/
prepareHardwareForSnapshot(int32_t afNeeded)10382 int32_t QCamera2HardwareInterface::prepareHardwareForSnapshot(int32_t afNeeded)
10383 {
10384 ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL1_PREPARE_HW_FOR_SNAPSHOT);
10385 LOGI("[KPI Perf]: Send PREPARE SANSPHOT event");
10386 return mCameraHandle->ops->prepare_snapshot(getSnapshotHandle(),
10387 afNeeded);
10388 }
10389
10390 /*===========================================================================
10391 * FUNCTION : needFDMetadata
10392 *
10393 * DESCRIPTION: check whether we need process Face Detection metadata in this chanel
10394 *
10395 * PARAMETERS :
10396 * @channel_type: channel type
10397 *
10398 * RETURN : true: needed
10399 * false: no need
10400 *==========================================================================*/
needFDMetadata(qcamera_ch_type_enum_t channel_type)10401 bool QCamera2HardwareInterface::needFDMetadata(qcamera_ch_type_enum_t channel_type)
10402 {
10403 //Note: Currently we only process ZSL channel
10404 bool value = false;
10405 if(channel_type == QCAMERA_CH_TYPE_ZSL){
10406 //check if FD requirement is enabled
10407 if(mParameters.isSnapshotFDNeeded() &&
10408 mParameters.isFaceDetectionEnabled()){
10409 value = true;
10410 LOGH("Face Detection metadata is required in ZSL mode.");
10411 }
10412 }
10413
10414 return value;
10415 }
10416
10417 /*===========================================================================
10418 * FUNCTION : deferredWorkRoutine
10419 *
10420 * DESCRIPTION: data process routine that executes deferred tasks
10421 *
10422 * PARAMETERS :
10423 * @data : user data ptr (QCamera2HardwareInterface)
10424 *
10425 * RETURN : None
10426 *==========================================================================*/
deferredWorkRoutine(void * obj)10427 void *QCamera2HardwareInterface::deferredWorkRoutine(void *obj)
10428 {
10429 int running = 1;
10430 int ret;
10431 uint8_t is_active = FALSE;
10432 int32_t job_status = 0;
10433
10434 QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)obj;
10435 QCameraCmdThread *cmdThread = &pme->mDeferredWorkThread;
10436 cmdThread->setName("CAM_defrdWrk");
10437
10438 do {
10439 do {
10440 ret = cam_sem_wait(&cmdThread->cmd_sem);
10441 if (ret != 0 && errno != EINVAL) {
10442 LOGE("cam_sem_wait error (%s)",
10443 strerror(errno));
10444 return NULL;
10445 }
10446 } while (ret != 0);
10447
10448 // we got notified about new cmd avail in cmd queue
10449 camera_cmd_type_t cmd = cmdThread->getCmd();
10450 LOGD("cmd: %d", cmd);
10451 switch (cmd) {
10452 case CAMERA_CMD_TYPE_START_DATA_PROC:
10453 LOGH("start data proc");
10454 is_active = TRUE;
10455 break;
10456 case CAMERA_CMD_TYPE_STOP_DATA_PROC:
10457 LOGH("stop data proc");
10458 is_active = FALSE;
10459 // signal cmd is completed
10460 cam_sem_post(&cmdThread->sync_sem);
10461 break;
10462 case CAMERA_CMD_TYPE_DO_NEXT_JOB:
10463 {
10464 DefWork *dw =
10465 reinterpret_cast<DefWork *>(pme->mCmdQueue.dequeue());
10466
10467 if ( NULL == dw ) {
10468 LOGE("Invalid deferred work");
10469 break;
10470 }
10471
10472 switch( dw->cmd ) {
10473 case CMD_DEF_ALLOCATE_BUFF:
10474 {
10475 QCameraChannel * pChannel = dw->args.allocArgs.ch;
10476
10477 if ( NULL == pChannel ) {
10478 LOGE("Invalid deferred work channel");
10479 job_status = BAD_VALUE;
10480 break;
10481 }
10482
10483 cam_stream_type_t streamType = dw->args.allocArgs.type;
10484 LOGH("Deferred buffer allocation started for stream type: %d",
10485 streamType);
10486
10487 uint32_t iNumOfStreams = pChannel->getNumOfStreams();
10488 QCameraStream *pStream = NULL;
10489 for ( uint32_t i = 0; i < iNumOfStreams; ++i) {
10490 pStream = pChannel->getStreamByIndex(i);
10491
10492 if ( NULL == pStream ) {
10493 job_status = BAD_VALUE;
10494 break;
10495 }
10496
10497 if ( pStream->isTypeOf(streamType)) {
10498 if ( pStream->allocateBuffers() ) {
10499 LOGE("Error allocating buffers !!!");
10500 job_status = NO_MEMORY;
10501 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10502 CAMERA_ERROR_UNKNOWN, 0);
10503 }
10504 break;
10505 }
10506 }
10507 }
10508 break;
10509 case CMD_DEF_PPROC_START:
10510 {
10511 int32_t ret = pme->getDefJobStatus(pme->mInitPProcJob);
10512 if (ret != NO_ERROR) {
10513 job_status = ret;
10514 LOGE("PPROC Start failed");
10515 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10516 CAMERA_ERROR_UNKNOWN, 0);
10517 break;
10518 }
10519 QCameraChannel * pChannel = dw->args.pprocArgs;
10520 assert(pChannel);
10521
10522 if (pme->m_postprocessor.start(pChannel) != NO_ERROR) {
10523 LOGE("cannot start postprocessor");
10524 job_status = BAD_VALUE;
10525 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10526 CAMERA_ERROR_UNKNOWN, 0);
10527 }
10528 }
10529 break;
10530 case CMD_DEF_METADATA_ALLOC:
10531 {
10532 int32_t ret = pme->getDefJobStatus(pme->mParamAllocJob);
10533 if (ret != NO_ERROR) {
10534 job_status = ret;
10535 LOGE("Metadata alloc failed");
10536 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10537 CAMERA_ERROR_UNKNOWN, 0);
10538 break;
10539 }
10540 pme->mMetadataMem = new QCameraMetadataStreamMemory(
10541 QCAMERA_ION_USE_CACHE);
10542
10543 if (pme->mMetadataMem == NULL) {
10544 LOGE("Unable to allocate metadata buffers");
10545 job_status = BAD_VALUE;
10546 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10547 CAMERA_ERROR_UNKNOWN, 0);
10548 } else {
10549 int32_t rc = pme->mMetadataMem->allocate(
10550 dw->args.metadataAllocArgs.bufferCnt,
10551 dw->args.metadataAllocArgs.size);
10552 if (rc < 0) {
10553 delete pme->mMetadataMem;
10554 pme->mMetadataMem = NULL;
10555 }
10556 }
10557 }
10558 break;
10559 case CMD_DEF_CREATE_JPEG_SESSION:
10560 {
10561 QCameraChannel * pChannel = dw->args.pprocArgs;
10562 assert(pChannel);
10563
10564 int32_t ret = pme->getDefJobStatus(pme->mReprocJob);
10565 if (ret != NO_ERROR) {
10566 job_status = ret;
10567 LOGE("Jpeg create failed");
10568 break;
10569 }
10570
10571 if (pme->m_postprocessor.createJpegSession(pChannel)
10572 != NO_ERROR) {
10573 LOGE("cannot create JPEG session");
10574 job_status = UNKNOWN_ERROR;
10575 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10576 CAMERA_ERROR_UNKNOWN, 0);
10577 }
10578 }
10579 break;
10580 case CMD_DEF_PPROC_INIT:
10581 {
10582 int32_t rc = NO_ERROR;
10583
10584 jpeg_encode_callback_t jpegEvtHandle =
10585 dw->args.pprocInitArgs.jpeg_cb;
10586 void* user_data = dw->args.pprocInitArgs.user_data;
10587 QCameraPostProcessor *postProcessor =
10588 &(pme->m_postprocessor);
10589 uint32_t cameraId = pme->mCameraId;
10590 cam_capability_t *capability =
10591 gCamCapability[cameraId];
10592 cam_padding_info_t padding_info;
10593 cam_padding_info_t& cam_capability_padding_info =
10594 capability->padding_info;
10595
10596 if(!pme->mJpegClientHandle) {
10597 rc = pme->initJpegHandle();
10598 if (rc != NO_ERROR) {
10599 LOGE("Error!! creating JPEG handle failed");
10600 job_status = UNKNOWN_ERROR;
10601 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10602 CAMERA_ERROR_UNKNOWN, 0);
10603 break;
10604 }
10605 }
10606 LOGH("mJpegClientHandle : %d", pme->mJpegClientHandle);
10607
10608 rc = postProcessor->setJpegHandle(&pme->mJpegHandle,
10609 &pme->mJpegMpoHandle,
10610 pme->mJpegClientHandle);
10611 if (rc != 0) {
10612 LOGE("Error!! set JPEG handle failed");
10613 job_status = UNKNOWN_ERROR;
10614 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10615 CAMERA_ERROR_UNKNOWN, 0);
10616 break;
10617 }
10618
10619 /* get max pic size for jpeg work buf calculation*/
10620 rc = postProcessor->init(jpegEvtHandle, user_data);
10621
10622 if (rc != NO_ERROR) {
10623 LOGE("cannot init postprocessor");
10624 job_status = UNKNOWN_ERROR;
10625 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10626 CAMERA_ERROR_UNKNOWN, 0);
10627 break;
10628 }
10629
10630 // update padding info from jpeg
10631 postProcessor->getJpegPaddingReq(padding_info);
10632 if (cam_capability_padding_info.width_padding <
10633 padding_info.width_padding) {
10634 cam_capability_padding_info.width_padding =
10635 padding_info.width_padding;
10636 }
10637 if (cam_capability_padding_info.height_padding <
10638 padding_info.height_padding) {
10639 cam_capability_padding_info.height_padding =
10640 padding_info.height_padding;
10641 }
10642 if (cam_capability_padding_info.plane_padding !=
10643 padding_info.plane_padding) {
10644 cam_capability_padding_info.plane_padding =
10645 mm_stream_calc_lcm(
10646 cam_capability_padding_info.plane_padding,
10647 padding_info.plane_padding);
10648 }
10649 if (cam_capability_padding_info.offset_info.offset_x
10650 != padding_info.offset_info.offset_x) {
10651 cam_capability_padding_info.offset_info.offset_x =
10652 mm_stream_calc_lcm (
10653 cam_capability_padding_info.offset_info.offset_x,
10654 padding_info.offset_info.offset_x);
10655 }
10656 if (cam_capability_padding_info.offset_info.offset_y
10657 != padding_info.offset_info.offset_y) {
10658 cam_capability_padding_info.offset_info.offset_y =
10659 mm_stream_calc_lcm (
10660 cam_capability_padding_info.offset_info.offset_y,
10661 padding_info.offset_info.offset_y);
10662 }
10663 }
10664 break;
10665 case CMD_DEF_PARAM_ALLOC:
10666 {
10667 int32_t rc = NO_ERROR;
10668 if (pme->isDualCamera()) {
10669 rc = pme->mParameters.allocate(MM_CAMERA_MAX_CAM_CNT);
10670 } else {
10671 rc = pme->mParameters.allocate();
10672 }
10673 // notify routine would not be initialized by this time.
10674 // So, just update error job status
10675 if (rc != NO_ERROR) {
10676 job_status = rc;
10677 LOGE("Param allocation failed");
10678 break;
10679 }
10680 }
10681 break;
10682 case CMD_DEF_PARAM_INIT:
10683 {
10684 int32_t rc = pme->getDefJobStatus(pme->mParamAllocJob);
10685 if (rc != NO_ERROR) {
10686 job_status = rc;
10687 LOGE("Param init failed");
10688 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10689 CAMERA_ERROR_UNKNOWN, 0);
10690 break;
10691 }
10692
10693 uint32_t camId = pme->mCameraId;
10694 cam_capability_t * cap = gCamCapability[camId];
10695
10696 if (pme->mCameraHandle == NULL) {
10697 LOGE("Camera handle is null");
10698 job_status = BAD_VALUE;
10699 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10700 CAMERA_ERROR_UNKNOWN, 0);
10701 break;
10702 }
10703
10704 // Now PostProc need calibration data as initialization
10705 // time for jpeg_open and calibration data is a
10706 // get param for now, so params needs to be initialized
10707 // before postproc init
10708 rc = pme->mParameters.init(cap,
10709 pme->mCameraHandle,
10710 pme, pme->m_pFovControl);
10711 if (rc != 0) {
10712 job_status = UNKNOWN_ERROR;
10713 LOGE("Parameter Initialization failed");
10714 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10715 CAMERA_ERROR_UNKNOWN, 0);
10716 break;
10717 }
10718
10719 // Get related cam calibration only in
10720 // dual camera mode
10721 if ((pme->getRelatedCamSyncInfo()->sync_control ==
10722 CAM_SYNC_RELATED_SENSORS_ON) || pme->isDualCamera()){
10723 rc = pme->mParameters.getRelatedCamCalibration(
10724 &(pme->mJpegMetadata.otp_calibration_data));
10725 LOGD("Dumping Calibration Data Version Id %f rc %d",
10726 pme->mJpegMetadata.otp_calibration_data.calibration_format_version,
10727 rc);
10728 if (rc != 0) {
10729 job_status = UNKNOWN_ERROR;
10730 LOGE("getRelatedCamCalibration failed");
10731 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10732 CAMERA_ERROR_UNKNOWN, 0);
10733 break;
10734 }
10735 pme->m_bRelCamCalibValid = true;
10736 }
10737
10738 pme->mJpegMetadata.sensor_mount_angle =
10739 cap->sensor_mount_angle;
10740 pme->mJpegMetadata.default_sensor_flip = FLIP_NONE;
10741
10742 pme->mParameters.setMinPpMask(
10743 cap->qcom_supported_feature_mask);
10744 pme->mExifParams.debug_params =
10745 (mm_jpeg_debug_exif_params_t *)
10746 malloc(sizeof(mm_jpeg_debug_exif_params_t));
10747 if (!pme->mExifParams.debug_params) {
10748 LOGE("Out of Memory. Allocation failed for "
10749 "3A debug exif params");
10750 job_status = NO_MEMORY;
10751 pme->sendEvtNotify(CAMERA_MSG_ERROR,
10752 CAMERA_ERROR_UNKNOWN, 0);
10753 break;
10754 }
10755 memset(pme->mExifParams.debug_params, 0,
10756 sizeof(mm_jpeg_debug_exif_params_t));
10757 }
10758 break;
10759 case CMD_DEF_GENERIC:
10760 {
10761 BackgroundTask *bgTask = dw->args.genericArgs;
10762 job_status = bgTask->bgFunction(bgTask->bgArgs);
10763 }
10764 break;
10765 default:
10766 LOGE("Incorrect command : %d", dw->cmd);
10767 }
10768
10769 pme->dequeueDeferredWork(dw, job_status);
10770 }
10771 break;
10772 case CAMERA_CMD_TYPE_EXIT:
10773 running = 0;
10774 break;
10775 default:
10776 break;
10777 }
10778 } while (running);
10779
10780 return NULL;
10781 }
10782
10783 /*===========================================================================
10784 * FUNCTION : queueDeferredWork
10785 *
10786 * DESCRIPTION: function which queues deferred tasks
10787 *
10788 * PARAMETERS :
10789 * @cmd : deferred task
10790 * @args : deferred task arguments
10791 *
10792 * RETURN : job id of deferred job
10793 * : 0 in case of error
10794 *==========================================================================*/
queueDeferredWork(DeferredWorkCmd cmd,DeferWorkArgs args)10795 uint32_t QCamera2HardwareInterface::queueDeferredWork(DeferredWorkCmd cmd,
10796 DeferWorkArgs args)
10797 {
10798 Mutex::Autolock l(mDefLock);
10799 for (int32_t i = 0; i < MAX_ONGOING_JOBS; ++i) {
10800 if (mDefOngoingJobs[i].mDefJobId == 0) {
10801 DefWork *dw = new DefWork(cmd, sNextJobId, args);
10802 if (!dw) {
10803 LOGE("out of memory.");
10804 return 0;
10805 }
10806 if (mCmdQueue.enqueue(dw)) {
10807 mDefOngoingJobs[i].mDefJobId = sNextJobId++;
10808 mDefOngoingJobs[i].mDefJobStatus = 0;
10809 if (sNextJobId == 0) { // handle overflow
10810 sNextJobId = 1;
10811 }
10812 mDeferredWorkThread.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB,
10813 FALSE,
10814 FALSE);
10815 return mDefOngoingJobs[i].mDefJobId;
10816 } else {
10817 LOGD("Command queue not active! cmd = %d", cmd);
10818 delete dw;
10819 return 0;
10820 }
10821 }
10822 }
10823 return 0;
10824 }
10825
10826 /*===========================================================================
10827 * FUNCTION : initJpegHandle
10828 *
10829 * DESCRIPTION: Opens JPEG client and gets a handle.
10830 * Sends Dual cam calibration info if present
10831 *
10832 * RETURN : int32_t type of status
10833 * NO_ERROR -- success
10834 * none-zero failure code
10835 *==========================================================================*/
initJpegHandle()10836 int32_t QCamera2HardwareInterface::initJpegHandle() {
10837 // Check if JPEG client handle is present
10838 LOGH("E");
10839 if(!mJpegClientHandle) {
10840 mm_dimension max_size = {0, 0};
10841 cam_dimension_t size;
10842
10843 mParameters.getMaxPicSize(size);
10844 max_size.w = size.width;
10845 max_size.h = size.height;
10846
10847 if (getRelatedCamSyncInfo()->sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
10848 if (m_bRelCamCalibValid) {
10849 mJpegClientHandle = jpeg_open(&mJpegHandle, &mJpegMpoHandle,
10850 max_size, &mJpegMetadata);
10851 } else {
10852 mJpegClientHandle = jpeg_open(&mJpegHandle, &mJpegMpoHandle,
10853 max_size, NULL);
10854 }
10855 } else {
10856 mJpegClientHandle = jpeg_open(&mJpegHandle, NULL, max_size, NULL);
10857 }
10858 if (!mJpegClientHandle) {
10859 LOGE("Error !! jpeg_open failed!! ");
10860 return UNKNOWN_ERROR;
10861 }
10862 // Set JPEG initialized as true to signify that this camera
10863 // has initialized the handle
10864 mJpegHandleOwner = true;
10865 }
10866 LOGH("X mJpegHandleOwner: %d, mJpegClientHandle: %d camera id: %d",
10867 mJpegHandleOwner, mJpegClientHandle, mCameraId);
10868 return NO_ERROR;
10869 }
10870
10871 /*===========================================================================
10872 * FUNCTION : deinitJpegHandle
10873 *
10874 * DESCRIPTION: Closes JPEG client using handle
10875 *
10876 * RETURN : int32_t type of status
10877 * NO_ERROR -- success
10878 * none-zero failure code
10879 *==========================================================================*/
deinitJpegHandle()10880 int32_t QCamera2HardwareInterface::deinitJpegHandle() {
10881 int32_t rc = NO_ERROR;
10882 LOGH("E");
10883 // Check if JPEG client handle is present and inited by this camera
10884 if(mJpegHandleOwner && mJpegClientHandle) {
10885 rc = mJpegHandle.close(mJpegClientHandle);
10886 if (rc != NO_ERROR) {
10887 LOGE("Error!! Closing mJpegClientHandle: %d failed",
10888 mJpegClientHandle);
10889 }
10890 memset(&mJpegHandle, 0, sizeof(mJpegHandle));
10891 memset(&mJpegMpoHandle, 0, sizeof(mJpegMpoHandle));
10892 mJpegHandleOwner = false;
10893 }
10894 mJpegClientHandle = 0;
10895 LOGH("X rc = %d", rc);
10896 return rc;
10897 }
10898
10899 /*===========================================================================
10900 * FUNCTION : setJpegHandleInfo
10901 *
10902 * DESCRIPTION: sets JPEG client handle info
10903 *
10904 * PARAMETERS:
10905 * @ops : JPEG ops
10906 * @mpo_ops : Jpeg MPO ops
10907 * @pJpegClientHandle : o/p Jpeg Client Handle
10908 *
10909 * RETURN : int32_t type of status
10910 * NO_ERROR -- success
10911 * none-zero failure code
10912 *==========================================================================*/
setJpegHandleInfo(mm_jpeg_ops_t * ops,mm_jpeg_mpo_ops_t * mpo_ops,uint32_t pJpegClientHandle)10913 int32_t QCamera2HardwareInterface::setJpegHandleInfo(mm_jpeg_ops_t *ops,
10914 mm_jpeg_mpo_ops_t *mpo_ops, uint32_t pJpegClientHandle) {
10915
10916 if (pJpegClientHandle && ops && mpo_ops) {
10917 LOGH("Setting JPEG client handle %d",
10918 pJpegClientHandle);
10919 memcpy(&mJpegHandle, ops, sizeof(mm_jpeg_ops_t));
10920 memcpy(&mJpegMpoHandle, mpo_ops, sizeof(mm_jpeg_mpo_ops_t));
10921 mJpegClientHandle = pJpegClientHandle;
10922 return NO_ERROR;
10923 }
10924 else {
10925 LOGE("Error!! No Handle found: %d",
10926 pJpegClientHandle);
10927 return BAD_VALUE;
10928 }
10929 }
10930
10931 /*===========================================================================
10932 * FUNCTION : getJpegHandleInfo
10933 *
10934 * DESCRIPTION: gets JPEG client handle info
10935 *
10936 * PARAMETERS:
10937 * @ops : JPEG ops
10938 * @mpo_ops : Jpeg MPO ops
10939 * @pJpegClientHandle : o/p Jpeg Client Handle
10940 *
10941 * RETURN : int32_t type of status
10942 * NO_ERROR -- success
10943 * none-zero failure code
10944 *==========================================================================*/
getJpegHandleInfo(mm_jpeg_ops_t * ops,mm_jpeg_mpo_ops_t * mpo_ops,uint32_t * pJpegClientHandle)10945 int32_t QCamera2HardwareInterface::getJpegHandleInfo(mm_jpeg_ops_t *ops,
10946 mm_jpeg_mpo_ops_t *mpo_ops, uint32_t *pJpegClientHandle) {
10947
10948 if (NO_ERROR != waitDeferredWork(mInitPProcJob)) {
10949 LOGE("Init PProc Deferred work failed");
10950 return UNKNOWN_ERROR;
10951 }
10952 // Copy JPEG ops if present
10953 if (ops && mpo_ops && pJpegClientHandle) {
10954 memcpy(ops, &mJpegHandle, sizeof(mm_jpeg_ops_t));
10955 memcpy(mpo_ops, &mJpegMpoHandle, sizeof(mm_jpeg_mpo_ops_t));
10956 *pJpegClientHandle = mJpegClientHandle;
10957 LOGH("Getting JPEG client handle %d",
10958 pJpegClientHandle);
10959 return NO_ERROR;
10960 } else {
10961 return BAD_VALUE;
10962 }
10963 }
10964
10965 /*===========================================================================
10966 * FUNCTION : dequeueDeferredWork
10967 *
10968 * DESCRIPTION: function which dequeues deferred tasks
10969 *
10970 * PARAMETERS :
10971 * @dw : deferred work
10972 * @jobStatus: deferred task job status
10973 *
10974 * RETURN : int32_t type of status
10975 * NO_ERROR -- success
10976 * none-zero failure code
10977 *==========================================================================*/
dequeueDeferredWork(DefWork * dw,int32_t jobStatus)10978 uint32_t QCamera2HardwareInterface::dequeueDeferredWork(DefWork* dw, int32_t jobStatus)
10979 {
10980 Mutex::Autolock l(mDefLock);
10981 for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
10982 if (mDefOngoingJobs[i].mDefJobId == dw->id) {
10983 if (jobStatus != NO_ERROR) {
10984 mDefOngoingJobs[i].mDefJobStatus = jobStatus;
10985 LOGH("updating job status %d for id %d",
10986 jobStatus, dw->id);
10987 } else {
10988 mDefOngoingJobs[i].mDefJobId = 0;
10989 mDefOngoingJobs[i].mDefJobStatus = 0;
10990 }
10991 delete dw;
10992 mDefCond.broadcast();
10993 return NO_ERROR;
10994 }
10995 }
10996
10997 return UNKNOWN_ERROR;
10998 }
10999
11000 /*===========================================================================
11001 * FUNCTION : getDefJobStatus
11002 *
11003 * DESCRIPTION: Gets if a deferred task is success/fail
11004 *
11005 * PARAMETERS :
11006 * @job_id : deferred task id
11007 *
11008 * RETURN : NO_ERROR if the job success, otherwise false
11009 *
11010 * PRECONDITION : mDefLock is held by current thread
11011 *==========================================================================*/
getDefJobStatus(uint32_t & job_id)11012 int32_t QCamera2HardwareInterface::getDefJobStatus(uint32_t &job_id)
11013 {
11014 for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
11015 if (mDefOngoingJobs[i].mDefJobId == job_id) {
11016 if ( NO_ERROR != mDefOngoingJobs[i].mDefJobStatus ) {
11017 LOGE("job_id (%d) was failed", job_id);
11018 return mDefOngoingJobs[i].mDefJobStatus;
11019 }
11020 else
11021 return NO_ERROR;
11022 }
11023 }
11024 return NO_ERROR;
11025 }
11026
11027
11028 /*===========================================================================
11029 * FUNCTION : checkDeferredWork
11030 *
11031 * DESCRIPTION: checks if a deferred task is in progress
11032 *
11033 * PARAMETERS :
11034 * @job_id : deferred task id
11035 *
11036 * RETURN : true if the task exists, otherwise false
11037 *
11038 * PRECONDITION : mDefLock is held by current thread
11039 *==========================================================================*/
checkDeferredWork(uint32_t & job_id)11040 bool QCamera2HardwareInterface::checkDeferredWork(uint32_t &job_id)
11041 {
11042 for (uint32_t i = 0; i < MAX_ONGOING_JOBS; i++) {
11043 if (mDefOngoingJobs[i].mDefJobId == job_id) {
11044 return (NO_ERROR == mDefOngoingJobs[i].mDefJobStatus);
11045 }
11046 }
11047 return false;
11048 }
11049
11050 /*===========================================================================
11051 * FUNCTION : waitDeferredWork
11052 *
11053 * DESCRIPTION: waits for a deferred task to finish
11054 *
11055 * PARAMETERS :
11056 * @job_id : deferred task id
11057 *
11058 * RETURN : int32_t type of status
11059 * NO_ERROR -- success
11060 * none-zero failure code
11061 *==========================================================================*/
waitDeferredWork(uint32_t & job_id)11062 int32_t QCamera2HardwareInterface::waitDeferredWork(uint32_t &job_id)
11063 {
11064 Mutex::Autolock l(mDefLock);
11065
11066 if (job_id == 0) {
11067 LOGD("Invalid job id %d", job_id);
11068 return NO_ERROR;
11069 }
11070
11071 while (checkDeferredWork(job_id) == true ) {
11072 mDefCond.waitRelative(mDefLock, CAMERA_DEFERRED_THREAD_TIMEOUT);
11073 }
11074 return getDefJobStatus(job_id);
11075 }
11076
11077 /*===========================================================================
11078 * FUNCTION : scheduleBackgroundTask
11079 *
11080 * DESCRIPTION: Run a requested task in the deferred thread
11081 *
11082 * PARAMETERS :
11083 * @bgTask : Task to perform in the background
11084 *
11085 * RETURN : job id of deferred job
11086 * : 0 in case of error
11087 *==========================================================================*/
scheduleBackgroundTask(BackgroundTask * bgTask)11088 uint32_t QCamera2HardwareInterface::scheduleBackgroundTask(BackgroundTask* bgTask)
11089 {
11090 DeferWorkArgs args;
11091 memset(&args, 0, sizeof(DeferWorkArgs));
11092 args.genericArgs = bgTask;
11093
11094 return queueDeferredWork(CMD_DEF_GENERIC, args);
11095 }
11096
11097 /*===========================================================================
11098 * FUNCTION : waitForBackgroundTask
11099 *
11100 * DESCRIPTION: Wait for a background task to complete
11101 *
11102 * PARAMETERS :
11103 * @taskId : Task id to wait for
11104 *
11105 * RETURN : int32_t type of status
11106 * NO_ERROR -- success
11107 * none-zero failure code
11108 *==========================================================================*/
waitForBackgroundTask(uint32_t & taskId)11109 int32_t QCamera2HardwareInterface::waitForBackgroundTask(uint32_t& taskId)
11110 {
11111 return waitDeferredWork(taskId);
11112 }
11113
11114 /*===========================================================================
11115 * FUNCTION : needDeferedAllocation
11116 *
11117 * DESCRIPTION: Function to decide background task for streams
11118 *
11119 * PARAMETERS :
11120 * @stream_type : stream type
11121 *
11122 * RETURN : true - if background task is needed
11123 * false - if background task is NOT needed
11124 *==========================================================================*/
needDeferred(cam_stream_type_t stream_type)11125 bool QCamera2HardwareInterface::needDeferred(cam_stream_type_t stream_type)
11126 {
11127 if ((stream_type == CAM_STREAM_TYPE_PREVIEW && mPreviewWindow == NULL)
11128 || (stream_type == CAM_STREAM_TYPE_ANALYSIS)) {
11129 return FALSE;
11130 }
11131
11132 if ((stream_type == CAM_STREAM_TYPE_RAW)
11133 && (mParameters.getofflineRAW() && !mParameters.getQuadraCfa())) {
11134 return FALSE;
11135 }
11136
11137 if ((stream_type == CAM_STREAM_TYPE_SNAPSHOT)
11138 && (!mParameters.getRecordingHintValue())){
11139 return TRUE;
11140 }
11141
11142 if ((stream_type == CAM_STREAM_TYPE_PREVIEW)
11143 || (stream_type == CAM_STREAM_TYPE_METADATA)
11144 || (stream_type == CAM_STREAM_TYPE_RAW)
11145 || (stream_type == CAM_STREAM_TYPE_POSTVIEW)) {
11146 return TRUE;
11147 }
11148
11149 if (stream_type == CAM_STREAM_TYPE_VIDEO) {
11150 return FALSE;
11151 }
11152 return FALSE;
11153 }
11154
11155 /*===========================================================================
11156 * FUNCTION : needSyncCB
11157 *
11158 * DESCRIPTION: Decide syncronous callback per stream
11159 *
11160 * PARAMETERS :
11161 * @stream_type: stream type
11162 *
11163 * RETURN : true - if background task is needed
11164 * false - if background task is NOT needed
11165 *==========================================================================*/
needSyncCB(cam_stream_type_t stream_type)11166 bool QCamera2HardwareInterface::needSyncCB(cam_stream_type_t stream_type)
11167 {
11168 #ifdef TARGET_TS_MAKEUP
11169 int whiteLevel, cleanLevel;
11170 if(mParameters.getTsMakeupInfo(whiteLevel, cleanLevel) == TRUE) {
11171 return FALSE;
11172 }
11173 #endif
11174
11175 char value[PROPERTY_VALUE_MAX];
11176 property_get("persist.camera.preview.sync_cb", value, "1");
11177 if ((atoi(value) == 1) && (stream_type == CAM_STREAM_TYPE_PREVIEW)) {
11178 return TRUE;
11179 }
11180 return FALSE;
11181 }
11182
11183 /*===========================================================================
11184 * FUNCTION : isRegularCapture
11185 *
11186 * DESCRIPTION: Check configuration for regular catpure
11187 *
11188 * PARAMETERS :
11189 *
11190 * RETURN : true - regular capture
11191 * false - other type of capture
11192 *==========================================================================*/
isRegularCapture()11193 bool QCamera2HardwareInterface::isRegularCapture()
11194 {
11195 bool ret = false;
11196
11197 if (numOfSnapshotsExpected() == 1 &&
11198 !isLongshotEnabled() &&
11199 !mParameters.isHDREnabled() &&
11200 !mParameters.getRecordingHintValue() &&
11201 !isZSLMode() && (!mParameters.getofflineRAW()|| mParameters.getQuadraCfa())) {
11202 ret = true;
11203 }
11204 return ret;
11205 }
11206
11207 /*===========================================================================
11208 * FUNCTION : needOfflineReprocessing
11209 *
11210 * DESCRIPTION: Check for offline reprocessing
11211 *
11212 * PARAMETERS :
11213 *
11214 * RETURN : true - regular capture
11215 * false - other type of capture
11216 *==========================================================================*/
needOfflineReprocessing()11217 bool QCamera2HardwareInterface::needOfflineReprocessing()
11218 {
11219 bool ret = false;
11220 if (isRegularCapture()
11221 || isDualCamera()) {
11222 ret = true;
11223 }
11224 return ret;
11225 }
11226
11227 /*===========================================================================
11228 * FUNCTION : getLogLevel
11229 *
11230 * DESCRIPTION: Reads the log level property into a variable
11231 *
11232 * PARAMETERS :
11233 * None
11234 *
11235 * RETURN :
11236 * None
11237 *==========================================================================*/
getLogLevel()11238 void QCamera2HardwareInterface::getLogLevel()
11239 {
11240 char prop[PROPERTY_VALUE_MAX];
11241
11242 property_get("persist.camera.kpi.debug", prop, "0");
11243 gKpiDebugLevel = atoi(prop);
11244 return;
11245 }
11246
11247 /*===========================================================================
11248 * FUNCTION : getSensorType
11249 *
11250 * DESCRIPTION: Returns the type of sensor being used whether YUV or Bayer
11251 *
11252 * PARAMETERS :
11253 * None
11254 *
11255 * RETURN : Type of sensor - bayer or YUV
11256 *
11257 *==========================================================================*/
getSensorType()11258 cam_sensor_t QCamera2HardwareInterface::getSensorType()
11259 {
11260 return gCamCapability[mCameraId]->sensor_type.sens_type;
11261 }
11262
11263 /*===========================================================================
11264 * FUNCTION : startRAWChannel
11265 *
11266 * DESCRIPTION: start RAW Channel
11267 *
11268 * PARAMETERS :
11269 * @pChannel : Src channel to link this RAW channel.
11270 *
11271 * RETURN : int32_t type of status
11272 * NO_ERROR -- success
11273 * none-zero failure code
11274 *==========================================================================*/
startRAWChannel(QCameraChannel * pMetaChannel)11275 int32_t QCamera2HardwareInterface::startRAWChannel(QCameraChannel *pMetaChannel)
11276 {
11277 int32_t rc = NO_ERROR;
11278 QCameraChannel *pChannel = m_channels[QCAMERA_CH_TYPE_RAW];
11279 if ((NULL != pChannel) && (mParameters.getofflineRAW())) {
11280 // Find and try to link a metadata stream from preview channel
11281 QCameraStream *pMetaStream = NULL;
11282
11283 if (pMetaChannel != NULL) {
11284 uint32_t streamNum = pMetaChannel->getNumOfStreams();
11285 QCameraStream *pStream = NULL;
11286 for (uint32_t i = 0 ; i < streamNum ; i++ ) {
11287 pStream = pMetaChannel->getStreamByIndex(i);
11288 if ((NULL != pStream) &&
11289 (CAM_STREAM_TYPE_METADATA == pStream->getMyType())) {
11290 pMetaStream = pStream;
11291 break;
11292 }
11293 }
11294
11295 if (NULL != pMetaStream) {
11296 rc = pChannel->linkStream(pMetaChannel, pMetaStream);
11297 if (NO_ERROR != rc) {
11298 LOGE("Metadata stream link failed %d", rc);
11299 }
11300 }
11301 }
11302 rc = pChannel->start();
11303 }
11304 return rc;
11305 }
11306
11307 /*===========================================================================
11308 * FUNCTION : startRecording
11309 *
11310 * DESCRIPTION: start recording impl
11311 *
11312 * PARAMETERS : none
11313 *
11314 * RETURN : int32_t type of status
11315 * NO_ERROR -- success
11316 * none-zero failure code
11317 *==========================================================================*/
stopRAWChannel()11318 int32_t QCamera2HardwareInterface::stopRAWChannel()
11319 {
11320 int32_t rc = NO_ERROR;
11321 rc = stopChannel(QCAMERA_CH_TYPE_RAW);
11322 return rc;
11323 }
11324
11325 /*===========================================================================
11326 * FUNCTION : isLowPowerMode
11327 *
11328 * DESCRIPTION: Returns TRUE if low power mode settings are to be applied for video recording
11329 *
11330 * PARAMETERS :
11331 * None
11332 *
11333 * RETURN : TRUE/FALSE
11334 *
11335 *==========================================================================*/
isLowPowerMode()11336 bool QCamera2HardwareInterface::isLowPowerMode()
11337 {
11338 cam_dimension_t dim;
11339 mParameters.getStreamDimension(CAM_STREAM_TYPE_VIDEO, dim);
11340
11341 char prop[PROPERTY_VALUE_MAX];
11342 property_get("camera.lowpower.record.enable", prop, "0");
11343 int enable = atoi(prop);
11344
11345 //Enable low power mode if :
11346 //1. Video resolution is 2k (2048x1080) or above and
11347 //2. camera.lowpower.record.enable is set
11348
11349 bool isLowpower = mParameters.getRecordingHintValue() && enable
11350 && ((dim.width * dim.height) >= (2048 * 1080));
11351 return isLowpower;
11352 }
11353
11354 /*===========================================================================
11355 * FUNCTION : getBootToMonoTimeOffset
11356 *
11357 * DESCRIPTION: Calculate offset that is used to convert from
11358 * clock domain of boot to monotonic
11359 *
11360 * PARAMETERS :
11361 * None
11362 *
11363 * RETURN : clock offset between boottime and monotonic time.
11364 *
11365 *==========================================================================*/
getBootToMonoTimeOffset()11366 nsecs_t QCamera2HardwareInterface::getBootToMonoTimeOffset()
11367 {
11368 // try three times to get the clock offset, choose the one
11369 // with the minimum gap in measurements.
11370 const int tries = 3;
11371 nsecs_t bestGap, measured;
11372 for (int i = 0; i < tries; ++i) {
11373 const nsecs_t tmono = systemTime(SYSTEM_TIME_MONOTONIC);
11374 const nsecs_t tbase = systemTime(SYSTEM_TIME_BOOTTIME);
11375 const nsecs_t tmono2 = systemTime(SYSTEM_TIME_MONOTONIC);
11376 const nsecs_t gap = tmono2 - tmono;
11377 if (i == 0 || gap < bestGap) {
11378 bestGap = gap;
11379 measured = tbase - ((tmono + tmono2) >> 1);
11380 }
11381 }
11382 return measured;
11383 }
11384
11385 /*===========================================================================
11386 * FUNCTION : fillDualCameraFOVControl
11387 *
11388 * DESCRIPTION: Function to process FOV ctrl event from statemachine thread.
11389 *
11390 * PARAMETERS : none
11391 *
11392 * RETURN : none
11393 *==========================================================================*/
fillDualCameraFOVControl()11394 void QCamera2HardwareInterface::fillDualCameraFOVControl()
11395 {
11396 qcamera_sm_internal_evt_payload_t *payload =
11397 (qcamera_sm_internal_evt_payload_t *)
11398 malloc(sizeof(qcamera_sm_internal_evt_payload_t));
11399 if (NULL != payload) {
11400 memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
11401 payload->evt_type = QCAMERA_INTERNAL_EVT_DUAL_CAMERA_FOV_CONTROL;
11402 int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
11403 if (rc != NO_ERROR) {
11404 LOGE("processEvt Dual camera fill FOV control failed");
11405 free(payload);
11406 payload = NULL;
11407 }
11408 } else {
11409 LOGE("No memory for Dual camera fill FOV control event");
11410 }
11411 }
11412
11413 }; // namespace qcamera
11414